Skip to content
This repository has been archived by the owner on Aug 18, 2024. It is now read-only.

Commit

Permalink
simple avatar example
Browse files Browse the repository at this point in the history
  • Loading branch information
HexaField committed Aug 14, 2024
1 parent 84bf314 commit 044787a
Show file tree
Hide file tree
Showing 4 changed files with 115 additions and 3 deletions.
5 changes: 5 additions & 0 deletions src/examples/GLTFs.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,11 @@ export const gltfRoutes = [
description: 'Ethereal Engine Material Extension',
/** @todo currently relies on eepro advanced materials project - replace asset with one that has base custom material */
entry: () => <GLTFViewer src={fileServer + '/projects/ee-development-test-suite/assets/GLTF/double-mat-test.glb'} light />
},
{
name: 'VRM',
description: 'VRM Avatar',
entry: () => <GLTFViewer src={fileServer + '/projects/ee-development-test-suite/assets/GLTF/VRM/VRMTest.vrm'} light />
}
] as RouteData[]

Expand Down
100 changes: 100 additions & 0 deletions src/examples/avatarSimple.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
import { dispatchAction, getMutableState, getState, useHookstate } from '@etherealengine/hyperflux'
import { GLTF } from '@gltf-transform/core'
import { useEffect } from 'react'
import { Cache, Color, Euler, Quaternion } from 'three'

import { AvatarID } from '@etherealengine/common/src/schema.type.module'
import {
Engine,
EntityUUID,
UUIDComponent,
UndefinedEntity,
createEntity,
getComponent,
getMutableComponent,
setComponent,
useOptionalComponent
} from '@etherealengine/ecs'
import { AvatarNetworkAction } from '@etherealengine/engine/src/avatar/state/AvatarNetworkActions'
import { GLTFComponent } from '@etherealengine/engine/src/gltf/GLTFComponent'
import { GLTFAssetState, GLTFSourceState } from '@etherealengine/engine/src/gltf/GLTFState'
import { AmbientLightComponent, DirectionalLightComponent, TransformComponent } from '@etherealengine/spatial'
import { EngineState } from '@etherealengine/spatial/src/EngineState'
import { NameComponent } from '@etherealengine/spatial/src/common/NameComponent'
import { RendererComponent } from '@etherealengine/spatial/src/renderer/WebGLRendererSystem'
import { SceneComponent } from '@etherealengine/spatial/src/renderer/components/SceneComponents'
import { VisibleComponent } from '@etherealengine/spatial/src/renderer/components/VisibleComponent'
import { EntityTreeComponent } from '@etherealengine/spatial/src/transform/components/EntityTree'

// create scene with a rigidbody loaded offset from the origin
const createSceneGLTF = (id: string): GLTF.IGLTF => ({
asset: {
version: '2.0',
generator: 'iR Engine'
},
scenes: [{ nodes: [0] }],
scene: 0,
nodes: [
{
name: 'Ground Plane',
extensions: {
EE_uuid: 'ground-plane',
EE_visible: true,
EE_ground_plane: {}
}
}
],
extensionsUsed: ['EE_uuid', 'EE_visible', 'EE_ground_plane']
})

export default function AvatarSimpleEntry() {
const entity = useHookstate(UndefinedEntity)
const gltfComponent = useOptionalComponent(entity.value, GLTFComponent)

useEffect(() => {
const lightEntity = createEntity()
setComponent(lightEntity, UUIDComponent, 'directional light' as EntityUUID)
setComponent(lightEntity, NameComponent, 'Directional Light')
setComponent(lightEntity, TransformComponent, { rotation: new Quaternion().setFromEuler(new Euler(2, 5, 3)) })
setComponent(lightEntity, EntityTreeComponent, { parentEntity: getState(EngineState).originEntity })
setComponent(lightEntity, VisibleComponent, true)
setComponent(lightEntity, DirectionalLightComponent, { color: new Color('white'), intensity: 0.5 })
setComponent(lightEntity, AmbientLightComponent, { color: new Color('white'), intensity: 0.5 })

const sceneID = `scene`
const gltf = createSceneGLTF(sceneID)

const sceneURL = `/${sceneID}.gltf`

Cache.add(sceneURL, gltf)

const gltfEntity = GLTFSourceState.load(sceneURL, sceneURL as EntityUUID)
getMutableComponent(Engine.instance.viewerEntity, RendererComponent).scenes.merge([gltfEntity])
setComponent(gltfEntity, SceneComponent)
getMutableState(GLTFAssetState)[sceneURL].set(gltfEntity)

entity.set(gltfEntity)

return () => {
GLTFSourceState.unload(gltfEntity)
getMutableState(GLTFAssetState)[sceneURL].set(gltfEntity)
}
}, [])

useEffect(() => {
if (gltfComponent?.progress?.value !== 100) return

const parentUUID = getComponent(entity.value, UUIDComponent)
const entityUUID = Engine.instance.userID
dispatchAction(
AvatarNetworkAction.spawn({
parentUUID,
avatarID: '9cc0a253-aeec-45d6-86cb-ab08f094c09d' as AvatarID,
entityUUID: (entityUUID + '_avatar') as EntityUUID,
name: 'avatar'
})
)
}, [gltfComponent?.progress?.value])

return null
}
3 changes: 2 additions & 1 deletion src/examples/gltfViewer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,12 +29,13 @@ export const metadata = {
}

const loadOldModel = false
const defaultSource = config.client.fileServer + '/projects/default-project/assets/apartment.glb'
// 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 defaultSource = 'https://raw.githubusercontent.com/KhronosGroup/glTF-Sample-Models/main/2.0/UnlitTest/glTF-Binary/UnlitTest.glb'


const GLTF = () => {
Expand Down
10 changes: 8 additions & 2 deletions src/examplesRoute.tsx
Original file line number Diff line number Diff line change
@@ -1,16 +1,17 @@
import React from 'react'

import { useEngineInjection } from '@etherealengine/client-core/src/components/World/EngineHooks'
import '@etherealengine/engine/src/EngineModule'
import { gltfRoutes } from './examples/GLTFs'
import AvatarMocapEntry from './examples/avatarMocap'
import AvatarSimpleEntry from './examples/avatarSimple'
import AvatarTestEntry from './examples/avatarTest'
import ComponentExamplesRoute, { subComponentExamples } from './examples/componentExamples/componentExamples'
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'
import { useEngineInjection } from '@etherealengine/client-core/src/components/World/EngineHooks'

export const examples: RouteCategories = [
{
Expand Down Expand Up @@ -41,6 +42,11 @@ export const examples: RouteCategories = [
{
category: 'Avatar',
routes: [
{
name: 'Simple',
description: 'Avatar simple example',
entry: AvatarSimpleEntry
},
{
name: 'Mocap',
description: 'Avatar mocap example',
Expand Down

0 comments on commit 044787a

Please sign in to comment.