From 1167432f9aded8dea1adc6d21073c1bc1fb02924 Mon Sep 17 00:00:00 2001 From: HexaField Date: Sun, 4 Aug 2024 13:02:34 +1000 Subject: [PATCH] new gltf category --- src/examples/GLTFs.tsx | 131 ++++++++++++++++++++++ src/examples/{gltf.tsx => gltfViewer.tsx} | 6 +- src/examplesRoute.tsx | 7 +- src/sceneRoute.tsx | 13 ++- 4 files changed, 154 insertions(+), 3 deletions(-) create mode 100644 src/examples/GLTFs.tsx rename src/examples/{gltf.tsx => gltfViewer.tsx} (93%) diff --git a/src/examples/GLTFs.tsx b/src/examples/GLTFs.tsx new file mode 100644 index 0000000..48dd27a --- /dev/null +++ b/src/examples/GLTFs.tsx @@ -0,0 +1,131 @@ +import React, { useEffect } from 'react' + +import { getComponent, setComponent } from '@etherealengine/ecs/src/ComponentFunctions' +import { getMutableState, getState } from '@etherealengine/hyperflux' + +import { Engine, EntityUUID, UUIDComponent, createEntity, removeEntity } from '@etherealengine/ecs' + +import config from '@etherealengine/common/src/config' +import { GLTFAssetState } from '@etherealengine/engine/src/gltf/GLTFState' +import { DirectionalLightComponent, TransformComponent } from '@etherealengine/spatial' +import { EngineState } from '@etherealengine/spatial/src/EngineState' +import { CameraComponent } from '@etherealengine/spatial/src/camera/components/CameraComponent' +import { CameraOrbitComponent } from '@etherealengine/spatial/src/camera/components/CameraOrbitComponent' +import { NameComponent } from '@etherealengine/spatial/src/common/NameComponent' +import { InputComponent } from '@etherealengine/spatial/src/input/components/InputComponent' +import { RendererState } from '@etherealengine/spatial/src/renderer/RendererState' +import { VisibleComponent } from '@etherealengine/spatial/src/renderer/components/VisibleComponent' +import { EntityTreeComponent } from '@etherealengine/spatial/src/transform/components/EntityTree' +import { Color, Euler, Quaternion } from 'three' +import { RouteData } from '../sceneRoute' + +export const metadata = { + title: 'GLTF', + description: '' +} + +const CDN_URL = 'https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Models/main/2.0/' + +export const gltfRoutes = [ + { + name: 'Basic', + description: 'Basic Duck', + entry: () => ( + + ) + }, + { + name: 'Binary', + description: 'Binary Duck', + entry: () => ( + + ) + }, + { + name: 'Draco', + description: 'Draco Duck', + entry: () => ( + + ) + }, + { + name: 'Embedded', + description: 'Embedded Duck', + entry: () => ( + + ) + }, + { + name: 'Quantized', + description: 'Quantized Duck', + entry: () => ( + + ) + }, + { + name: 'KHR_materials_unlit', + description: 'Khronos Unlit Material Extension', + entry: () => ( + + ) + } +] as RouteData[] + +// EXTENSIONS.KHR_MATERIALS_UNLIT +// EXTENSIONS.KHR_MATERIALS_EMISSIVE_STRENGTH +// EXTENSIONS.KHR_MATERIALS_CLEARCOAT +// EXTENSIONS.KHR_MATERIALS_IRIDESCENCE +// EXTENSIONS.KHR_MATERIALS_SHEEN +// EXTENSIONS.KHR_MATERIALS_TRANSMISSION +// EXTENSIONS.KHR_MATERIALS_VOLUME +// EXTENSIONS.KHR_MATERIALS_IOR +// EXTENSIONS.KHR_MATERIALS_SPECULAR +// EXTENSIONS.EXT_MATERIALS_BUMP +// EXTENSIONS.KHR_MATERIALS_ANISOTROPY + +export default function GLTFViewer(props: { src: string }) { + useEffect(() => { + const bgColor = document.body.style.backgroundColor + document.body.style.backgroundColor = 'gray' + getMutableState(RendererState).gridVisibility.set(true) + getMutableState(RendererState).physicsDebug.set(true) + const entity = Engine.instance.viewerEntity + setComponent(entity, CameraOrbitComponent) + setComponent(entity, InputComponent) + getComponent(entity, CameraComponent).position.set(0, 3, 4) + + return () => { + document.body.style.backgroundColor = bgColor + } + }, []) + + useEffect(() => { + const entity = createEntity() + setComponent(entity, UUIDComponent, 'directional light' as EntityUUID) + setComponent(entity, NameComponent, 'Directional Light') + setComponent(entity, TransformComponent, { rotation: new Quaternion().setFromEuler(new Euler(2, 5, 3)) }) + setComponent(entity, EntityTreeComponent, { parentEntity: getState(EngineState).originEntity }) + setComponent(entity, VisibleComponent, true) + setComponent(entity, DirectionalLightComponent, { color: new Color('white'), intensity: 1 }) + + const ret = GLTFAssetState.loadScene(props.src, props.src) + return () => { + removeEntity(entity) + ret() + } + }, [props.src]) + + return null +} diff --git a/src/examples/gltf.tsx b/src/examples/gltfViewer.tsx similarity index 93% rename from src/examples/gltf.tsx rename to src/examples/gltfViewer.tsx index 00d8981..26295a6 100644 --- a/src/examples/gltf.tsx +++ b/src/examples/gltfViewer.tsx @@ -22,17 +22,20 @@ import { RendererState } from '@etherealengine/spatial/src/renderer/RendererStat import { VisibleComponent } from '@etherealengine/spatial/src/renderer/components/VisibleComponent' import { EntityTreeComponent } from '@etherealengine/spatial/src/transform/components/EntityTree' import { Color, Euler, Quaternion, Vector3 } from 'three' +import { SceneComponent } from '@etherealengine/spatial/src/renderer/components/SceneComponents' export const metadata = { title: 'GLTF', description: '' } const loadOldModel = false -const defaultSource = config.client.fileServer + '/projects/ee-development-test-suite/assets/GLTF/Duck/basic/Duck.gltf' +// const defaultSource = config.client.fileServer + '/projects/ee-development-test-suite/assets/GLTF/Duck/basic/Duck.gltf' // const defaultSource = config.client.fileServer + '/projects/ee-development-test-suite/assets/GLTF/Duck/binary/Duck.glb' // const defaultSource = config.client.fileServer + '/projects/ee-development-test-suite/assets/GLTF/Duck/draco/Duck.gltf' // const defaultSource = config.client.fileServer + '/projects/ee-development-test-suite/assets/GLTF/Duck/embedded/Duck.gltf' // const defaultSource = config.client.fileServer + '/projects/ee-development-test-suite/assets/GLTF/Duck/quantized/Duck.gltf' +const defaultSource = 'https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Models/main/2.0/UnlitTest/glTF-Binary/UnlitTest.glb' + const GLTF = () => { const filenames = useHookstate([]) @@ -51,6 +54,7 @@ const GLTF = () => { setComponent(modelEntity, EntityTreeComponent, { parentEntity: getState(EngineState).originEntity }) setComponent(modelEntity, VisibleComponent, true) setComponent(modelEntity, ModelComponent, { src: source.value }) + setComponent(modelEntity, SceneComponent) } const entity = createEntity() diff --git a/src/examplesRoute.tsx b/src/examplesRoute.tsx index 3ba1eae..97a094a 100644 --- a/src/examplesRoute.tsx +++ b/src/examplesRoute.tsx @@ -4,11 +4,12 @@ import '@etherealengine/engine/src/EngineModule' import AvatarMocapEntry from './examples/avatarMocap' import AvatarTestEntry from './examples/avatarTest' import ComponentExamplesRoute, { subComponentExamples } from './examples/componentExamples/componentExamples' -import GLTFViewer from './examples/gltf' +import GLTFViewer from './examples/gltfViewer' import ImmersiveAR from './examples/immersiveAR' import ImmersiveVR from './examples/immersiveVR' import MultipleScenesEntry from './examples/multipleScenes' import Routes, { RouteCategories } from './sceneRoute' +import { gltfRoutes } from './examples/GLTFs' export const examples: RouteCategories = [ { @@ -65,6 +66,10 @@ export const examples: RouteCategories = [ entry: MultipleScenesEntry } ] + }, + { + category: 'GLTF', + routes: gltfRoutes } ] diff --git a/src/sceneRoute.tsx b/src/sceneRoute.tsx index 08477f8..9a566dd 100644 --- a/src/sceneRoute.tsx +++ b/src/sceneRoute.tsx @@ -13,8 +13,10 @@ import { Entity, getComponent, setComponent } from '@etherealengine/ecs' import '@etherealengine/engine/src/EngineModule' import { GLTFAssetState } from '@etherealengine/engine/src/gltf/GLTFState' import { + defineState, getMutableState, none, + syncStateWithLocalStorage, useHookstate, useImmediateEffect, useMutableState, @@ -93,11 +95,20 @@ const getPathForRoute = (category: string, name: string) => { return (category.toLowerCase() + '_' + name.toLocaleLowerCase()).replace(' ', '_') } + +const ExampleRouteState = defineState({ + name: 'ExampleRouteState', + initial: { + hidden: false + }, + extension: syncStateWithLocalStorage(['hidden']) +}) + const Routes = (props: { routeCategories: RouteCategories; header: string }) => { const { routeCategories, header } = props const currentRoute = useMutableState(SearchParamState).example.value const categoriesShown = useHookstate({} as Record) - const hidden = useHookstate(false) + const hidden = useMutableState(ExampleRouteState).hidden const [ref, setRef] = useReactiveRef()