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

Commit

Permalink
Merge branch 'dev' into performance-profiling
Browse files Browse the repository at this point in the history
  • Loading branch information
MichaelEstes committed May 21, 2024
2 parents 252981c + cd1eabd commit 9c7f992
Show file tree
Hide file tree
Showing 12 changed files with 135 additions and 148 deletions.
6 changes: 1 addition & 5 deletions e2e/editor/editorScene.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,6 @@ import { EtherealEngineBot } from 'ee-bot/src/bot/bot-class'
import { BotHooks } from 'ee-bot/src/enums/BotHooks'

import { delay } from '@etherealengine/spatial/src/common/functions/delay'
import type { Engine } from '@etherealengine/ecs/src/Engine'
import { EngineState } from '@etherealengine/spatial/src/EngineState'
import { SceneState } from '@etherealengine/engine/src/scene/SceneState'

const domain = process.env.APP_HOST || 'localhost:3000'
const editorUrl = `https://${domain}/editor`
Expand Down Expand Up @@ -37,9 +34,8 @@ describe('Editor Scene Tests', () => {
await bot.awaitHookPromise(BotHooks.SceneLoaded)

const serializedEngine = JSON.parse(await bot.runHook(BotHooks.SerializeEngine)) // as Engine
const engineState = serializedEngine.store.stateMap['engine'] as any as typeof SceneState._TYPE
assert.equal(serializedEngine.isEditor, true)
assert.equal(engineState.sceneLoaded, true)
// assert.equal(engineState.sceneLoaded, true)
})

// it.skip('should unload scene and load second scene', async () => {
Expand Down
4 changes: 1 addition & 3 deletions e2e/editor/xrui.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { EtherealEngineBot } from 'ee-bot/src/bot/bot-class'
import { BotHooks } from 'ee-bot/src/enums/BotHooks'

import { delay } from '@etherealengine/spatial/src/common/functions/delay'
import { SceneState } from '@etherealengine/engine/src/scene/SceneState'

const domain = process.env.APP_HOST || 'localhost:3000'
const editorUrl = `https://${domain}/studio`
Expand Down Expand Up @@ -36,9 +35,8 @@ describe('Editor Scene Tests', () => {
await bot.awaitHookPromise(BotHooks.SceneLoaded)

const serializedEngine = JSON.parse(await bot.runHook(BotHooks.SerializeEngine)) // as Engine
const engineState = serializedEngine.store.stateMap['engine'] as any as typeof SceneState._TYPE
assert.equal(serializedEngine.isEditor, true)
assert.equal(engineState.sceneLoaded, true)
// assert.equal(engineState.sceneLoaded, true)
})

// it.skip('should unload scene and load second scene', async () => {
Expand Down
131 changes: 67 additions & 64 deletions examples/Retargeting.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { useEffect } from 'react'
import { Bone, ConeGeometry, Mesh, MeshBasicMaterial, Quaternion, SkeletonHelper, SphereGeometry, Vector3 } from 'three'
import { AnimationClip, Bone, ConeGeometry, Mesh, MeshBasicMaterial, Quaternion, Scene, SkeletonHelper, SphereGeometry, Vector3 } from 'three'

import { AVATAR_FILE_ALLOWED_EXTENSIONS } from '@etherealengine/common/src/constants/AvatarConstants'
import { Engine } from '@etherealengine/ecs/src/Engine'
Expand All @@ -14,6 +14,9 @@ import { NO_PROXY, defineState, getMutableState, getState, none, useHookstate }

import { Template } from './utils/template'
import { MixamoBoneNames } from '@etherealengine/engine/src/avatar/AvatarBoneMatching'
import { NameComponent } from '@etherealengine/spatial/src/common/NameComponent'
import { MeshComponent } from '@etherealengine/spatial/src/renderer/components/MeshComponent'
import { getComponent } from '@etherealengine/ecs'

const bones = Object.keys(AvatarRigComponent.schema!.rig)
console.log({ bones })
Expand Down Expand Up @@ -152,7 +155,7 @@ const RetargetingDND = () => {
}

const onSave = async () => {
const scene = assetObject.value?.scene
const scene = assetObject.value?.scene as Scene | undefined
if (!scene) return

const exporter = createGLTFExporter()
Expand All @@ -170,7 +173,7 @@ const RetargetingDND = () => {
binary: !isGLTF,
embedImages: !isGLTF,
includeCustomExtensions: true,
animations: assetObject.get(NO_PROXY)!.animations // this doesnt work for some reason
animations: assetObject.get(NO_PROXY)!.animations as AnimationClip[] // this doesnt work for some reason
}
)
})
Expand All @@ -185,66 +188,66 @@ const RetargetingDND = () => {
document.body.removeChild(link)
}

useEffect(() => {
if (!assetFile.value) return
const url = URL.createObjectURL(assetFile.value) + '#' + assetFile.value.name
AssetLoader.loadAsync(url).then((asset: GLTF) => {
assetObject.set(asset)
console.log(asset)

const rootBone = asset.scene.getObjectByProperty('type', 'Bone')
if (!rootBone) return

asset.scene.animations = asset.animations

if (overrideNames.length > 0) {
let i = 0
rootBone.traverse((bone: Bone) => {
bone.name = overrideNames[i++]
})
}

const clone = rootBone.clone()
Engine.instance.scene.add(clone)
clone.updateMatrixWorld(true)

const helper = new SkeletonHelper(clone)
helper.updateMatrixWorld(true)
Engine.instance.scene.add(helper)

clone.traverse((bone: Bone) => {
/** bones are oriented to the average position direction of their children from their position */
const childAveragePosition = bone.children
.reduce((acc, child) => {
const childPosition = child.getWorldPosition(new Vector3())
return acc.add(childPosition)
}, new Vector3())
.divideScalar(bone.children.length)

const boneLength = bone.getWorldPosition(new Vector3()).distanceTo(childAveragePosition)

const boneDirection = new Quaternion()
.setFromUnitVectors(
bone.getWorldPosition(new Vector3()).sub(childAveragePosition).normalize(),
new Vector3(0, 1, 0)
)
.invert()

const helper = new Mesh(new ConeGeometry(0.1, 1, 8), new MeshBasicMaterial({ color: 'red' }))
helper.geometry.scale(1, -1, 1)
helper.geometry.translate(0, -0.5, 0)
helper.scale.setScalar(boneLength)
bone.getWorldPosition(helper.position)
helper.quaternion.copy(boneDirection)
helper.updateMatrixWorld(true)
helper.name = bone.name + '--helper'
Engine.instance.scene.add(helper)

if (bones.includes(bone.name)) getMutableState(BoneMatchedState)[bone.name].set(true)
})
Engine.instance.scene.add(sphere)
})
}, [assetFile])
// useEffect(() => {
// if (!assetFile.value) return
// const url = URL.createObjectURL(assetFile.value) + '#' + assetFile.value.name
// AssetLoader.loadAsync(url).then((asset: GLTF) => {
// assetObject.set(asset)
// console.log(asset)

// const rootBone = asset.scene.getObjectByProperty('type', 'Bone')
// if (!rootBone) return

// asset.scene.animations = asset.animations

// if (overrideNames.length > 0) {
// let i = 0
// rootBone.traverse((bone: Bone) => {
// bone.name = overrideNames[i++]
// })
// }

// const clone = rootBone.clone()
// Engine.instance.scene.add(clone)
// clone.updateMatrixWorld(true)

// const helper = new SkeletonHelper(clone)
// helper.updateMatrixWorld(true)
// Engine.instance.scene.add(helper)

// clone.traverse((bone: Bone) => {
// /** bones are oriented to the average position direction of their children from their position */
// const childAveragePosition = bone.children
// .reduce((acc, child) => {
// const childPosition = child.getWorldPosition(new Vector3())
// return acc.add(childPosition)
// }, new Vector3())
// .divideScalar(bone.children.length)

// const boneLength = bone.getWorldPosition(new Vector3()).distanceTo(childAveragePosition)

// const boneDirection = new Quaternion()
// .setFromUnitVectors(
// bone.getWorldPosition(new Vector3()).sub(childAveragePosition).normalize(),
// new Vector3(0, 1, 0)
// )
// .invert()

// const helper = new Mesh(new ConeGeometry(0.1, 1, 8), new MeshBasicMaterial({ color: 'red' }))
// helper.geometry.scale(1, -1, 1)
// helper.geometry.translate(0, -0.5, 0)
// helper.scale.setScalar(boneLength)
// bone.getWorldPosition(helper.position)
// helper.quaternion.copy(boneDirection)
// helper.updateMatrixWorld(true)
// helper.name = bone.name + '--helper'
// Engine.instance.scene.add(helper)

// if (bones.includes(bone.name)) getMutableState(BoneMatchedState)[bone.name].set(true)
// })
// Engine.instance.scene.add(sphere)
// })
// }, [assetFile])

const nextUnmatchedBone = (boneName?: MixamoBoneNames) => {
if (boneName && boneState.value[boneName]) return null
Expand All @@ -259,7 +262,7 @@ const RetargetingDND = () => {
const { bone } = props
const boneName = useHookstate(bone.name)

const boneHelper = Engine.instance.scene.getObjectByName(boneName.value + '--helper') as Mesh<
const boneHelper = getComponent(NameComponent.entitiesByName[boneName.value + '--helper'][0], MeshComponent) as Mesh<
ConeGeometry,
MeshBasicMaterial
>
Expand Down
18 changes: 11 additions & 7 deletions examples/XRMeshes.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
import React, { useEffect } from 'react'
import { Mesh, MeshBasicMaterial, MeshNormalMaterial } from 'three'
import { BufferGeometry, Mesh, MeshBasicMaterial, MeshNormalMaterial } from 'three'

import { setComponent, useComponent } from '@etherealengine/ecs/src/ComponentFunctions'
import { useEntityContext } from '@etherealengine/ecs/src/EntityFunctions'
import { addObjectToGroup, removeObjectFromGroup } from '@etherealengine/spatial/src/renderer/components/GroupComponent'
import { NameComponent } from '@etherealengine/spatial/src/common/NameComponent'
import { addObjectToGroup, removeObjectFromGroup } from '@etherealengine/spatial/src/renderer/components/GroupComponent'

import { QueryReactor } from '@etherealengine/ecs/src/QueryFunctions'
import { XRDetectedMeshComponent } from '@etherealengine/spatial/src/xr/XRDetectedMeshComponent'
import { XRDetectedPlaneComponent } from '@etherealengine/spatial/src/xr/XRDetectedPlaneComponent'
import { Template } from './utils/template'
import { QueryReactor } from '@etherealengine/ecs/src/QueryFunctions'

const wireframeMaterial = new MeshBasicMaterial({ wireframe: true })
const normalMaterial = new MeshNormalMaterial({ opacity: 0.5, transparent: true })
Expand All @@ -21,9 +21,13 @@ export const DetectedPlanes = () => {

useEffect(() => {
if (!xrPlane.geometry.value) return
const transparentMesh = new Mesh(xrPlane.geometry.value, normalMaterial)
const transparentMesh = new Mesh(xrPlane.geometry.value as BufferGeometry, normalMaterial)
addObjectToGroup(entity, transparentMesh)
setComponent(entity, NameComponent, 'Plane ' + (xrPlane.plane.value as any).semanticLabel ?? xrPlane.plane.orientation.value)
setComponent(
entity,
NameComponent,
'Plane ' + (xrPlane.plane.value.semanticLabel ?? xrPlane.plane.orientation.value)
)
return () => {
removeObjectFromGroup(entity, transparentMesh)
}
Expand All @@ -39,9 +43,9 @@ export const DetectedMeshes = () => {

useEffect(() => {
if (!xrmesh.geometry.value) return
const outlineMesh = new Mesh(xrmesh.geometry.value, wireframeMaterial)
const outlineMesh = new Mesh(xrmesh.geometry.value as BufferGeometry, wireframeMaterial)
addObjectToGroup(entity, outlineMesh)
setComponent(entity, NameComponent, 'Plane ' + xrmesh.mesh.value.semanticLabel ?? entity)
setComponent(entity, NameComponent, 'Plane ' + (xrmesh.mesh.value.semanticLabel ?? entity))
return () => {
removeObjectFromGroup(entity, outlineMesh)
}
Expand Down
12 changes: 5 additions & 7 deletions examples/avatarMocap.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,19 @@
import React, { useEffect } from 'react'

import { createState, getMutableState, getState, useHookstate } from '@etherealengine/hyperflux'

import { useWorldNetwork } from '@etherealengine/client-core/src/common/services/LocationInstanceConnectionService'
import { avatarPath } from '@etherealengine/common/src/schemas/user/avatar.schema'
import { AvatarType, avatarPath } from '@etherealengine/common/src/schemas/user/avatar.schema'
import { UserID } from '@etherealengine/common/src/schemas/user/user.schema'
import { UUIDComponent } from '@etherealengine/ecs'
import { useOptionalComponent } from '@etherealengine/ecs/src/ComponentFunctions'
import { removeEntity } from '@etherealengine/ecs/src/EntityFunctions'
import { AnimationState } from '@etherealengine/engine/src/avatar/AnimationManager'
import { AvatarRigComponent } from '@etherealengine/engine/src/avatar/components/AvatarAnimationComponent'
import { MotionCaptureResults, mocapDataChannelType } from '@etherealengine/engine/src/mocap/MotionCaptureSystem'
import { createState, getMutableState, getState, useHookstate } from '@etherealengine/hyperflux'
import { DataChannelRegistryState, NetworkState } from '@etherealengine/network'
import { UUIDComponent } from '@etherealengine/ecs'
import { useFind } from '@etherealengine/spatial/src/common/functions/FeathersHooks'
import { RendererState } from '@etherealengine/spatial/src/renderer/RendererState'
import { VisibleComponent, setVisibleComponent } from '@etherealengine/spatial/src/renderer/components/VisibleComponent'
import { encode } from 'msgpackr'
import React, { useEffect } from 'react'
import { loadNetworkAvatar } from './utils/avatar/loadAvatarHelpers'
import { Template } from './utils/template'

Expand Down Expand Up @@ -164,7 +162,7 @@ export default function AvatarMocap() {

useEffect(() => {
if (!network?.ready.value || !avatarList.data.length || !selectedAvatar.value) return
const userid = loadNetworkAvatar(selectedAvatar.value, 0, selectedAvatar.value.id, -1)
const userid = loadNetworkAvatar(selectedAvatar.value as AvatarType, 0, selectedAvatar.value.id, -1)
userID.set(userid)
return () => {
removeEntity(UUIDComponent.entitiesByUUIDState[userid + '_avatar'].value)
Expand Down
9 changes: 2 additions & 7 deletions examples/physicsBenchmark.tsx
Original file line number Diff line number Diff line change
@@ -1,26 +1,21 @@
import React, { useEffect, useState } from 'react'

import NumericInput from '@etherealengine/editor/src/components/inputs/NumericInput'
import { Entity } from '@etherealengine/ecs/src/Entity'
import { removeEntity } from '@etherealengine/ecs/src/EntityFunctions'
import { getMutableState, useHookstate } from '@etherealengine/hyperflux'
import NumericInput from '@etherealengine/editor/src/components/inputs/NumericInput'

import { SceneState } from '@etherealengine/engine/src/scene/SceneState'
import { createPhysicsObjects } from './utils/common/loadPhysicsHelpers'
import { Template } from './utils/template'

export default function AvatarBenchmarking() {
const sceneState = useHookstate(getMutableState(SceneState))

const [count, setCount] = useState(1000)

const [entities, setEntities] = useState([] as Entity[])

useEffect(() => {
if (!sceneState.sceneLoaded.value) return
for (let i = 0; i < entities.length; i++) removeEntity(entities[i])
setEntities(createPhysicsObjects(count))
}, [count, sceneState.sceneLoaded])
}, [count])

return (
<>
Expand Down
Loading

0 comments on commit 9c7f992

Please sign in to comment.