From db76dd2fe8a999e56014f46cb4bb2bbba7ef45dc Mon Sep 17 00:00:00 2001 From: HexaField Date: Fri, 3 May 2024 18:05:15 +1000 Subject: [PATCH 1/9] Physics API Abstraction --- examples/utils/common/loadPhysicsHelpers.ts | 37 ++++++++++----------- 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/examples/utils/common/loadPhysicsHelpers.ts b/examples/utils/common/loadPhysicsHelpers.ts index 9365c0b..3761861 100644 --- a/examples/utils/common/loadPhysicsHelpers.ts +++ b/examples/utils/common/loadPhysicsHelpers.ts @@ -1,15 +1,12 @@ -import { ColliderDesc, RigidBodyDesc } from '@dimforge/rapier3d-compat' import { Vector3 } from 'three' +import { setComponent } from '@etherealengine/ecs/src/ComponentFunctions' import { Entity } from '@etherealengine/ecs/src/Entity' import { createEntity } from '@etherealengine/ecs/src/EntityFunctions' -import { Physics } from '@etherealengine/spatial/src/physics/classes/Physics' +import { ColliderComponent } from '@etherealengine/spatial/src/physics/components/ColliderComponent' +import { RigidBodyComponent } from '@etherealengine/spatial/src/physics/components/RigidBodyComponent' import { CollisionGroups, DefaultCollisionMask } from '@etherealengine/spatial/src/physics/enums/CollisionGroups' -import { getInteractionGroups } from '@etherealengine/spatial/src/physics/functions/getInteractionGroups' import { TransformComponent } from '@etherealengine/spatial/src/transform/components/TransformComponent' -import { getState } from '@etherealengine/hyperflux' -import { PhysicsState } from '@etherealengine/spatial/src/physics/state/PhysicsState' -import { setComponent } from '@etherealengine/ecs/src/ComponentFunctions' export const createPhysicsObjects = (count: number) => { const entities = [] as Entity[] @@ -21,20 +18,20 @@ export const createPhysicsObjects = (count: number) => { export const createPhysicsObject = () => { const entity = createEntity() - setComponent(entity, TransformComponent, { - position: new Vector3(2.5 - Math.random() * 5, 1 + Math.random() * 5, 2.5 - Math.random() * 5) + setComponent(entity, TransformComponent, { + position: new Vector3(2.5 - Math.random() * 5, 1 + Math.random() * 5, 2.5 - Math.random() * 5), + scale: new Vector3().setScalar(0.1) + }) + setComponent(entity, ColliderComponent, { + shape: 'sphere', + friction: 10, + restitution: 1, + collisionLayer: CollisionGroups.Default, + collisionMask: DefaultCollisionMask + }) + setComponent(entity, RigidBodyComponent, { + type: 'dynamic', + canSleep: false }) - - const rigidBodyDesc = RigidBodyDesc.dynamic() - const colliderDesc = ColliderDesc.ball(0.1) - colliderDesc.setCollisionGroups(getInteractionGroups(CollisionGroups.Default, DefaultCollisionMask)) - colliderDesc.setFriction(10).setRestitution(1) - - rigidBodyDesc.setCanSleep(false) - - const physicsWorld = getState(PhysicsState).physicsWorld - const body = Physics.createRigidBody(entity, physicsWorld, rigidBodyDesc) - physicsWorld.createCollider(colliderDesc, body) - return entity } From 4a557662789cac4375b45d7584832d866563babf Mon Sep 17 00:00:00 2001 From: HexaField Date: Sat, 4 May 2024 09:42:59 +1000 Subject: [PATCH 2/9] scene loaded --- examples/physicsBenchmark.tsx | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/examples/physicsBenchmark.tsx b/examples/physicsBenchmark.tsx index fee9243..f338221 100644 --- a/examples/physicsBenchmark.tsx +++ b/examples/physicsBenchmark.tsx @@ -1,8 +1,8 @@ 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 NumericInput from '@etherealengine/editor/src/components/inputs/NumericInput' import { getMutableState, useHookstate } from '@etherealengine/hyperflux' import { SceneState } from '@etherealengine/engine/src/scene/SceneState' @@ -17,10 +17,9 @@ export default function AvatarBenchmarking() { 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 ( <> From eaf01a8b6de5869592be7a9fce80e87d063a449c Mon Sep 17 00:00:00 2001 From: HexaField Date: Sat, 4 May 2024 13:20:49 +1000 Subject: [PATCH 3/9] fix errors in retargeting --- examples/Retargeting.tsx | 125 ++++++++++++++++++++------------------- 1 file changed, 64 insertions(+), 61 deletions(-) diff --git a/examples/Retargeting.tsx b/examples/Retargeting.tsx index 8619e08..2606bc5 100644 --- a/examples/Retargeting.tsx +++ b/examples/Retargeting.tsx @@ -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 }) @@ -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 @@ -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 > From dc809f02061a215f6989cae079de1ec6422fe11b Mon Sep 17 00:00:00 2001 From: HexaField Date: Sun, 5 May 2024 16:11:10 +1000 Subject: [PATCH 4/9] template --- examples/XRLightEstimation.tsx | 2 -- examples/XRMeshes.tsx | 3 --- examples/XRSuite.tsx | 2 -- examples/utils/template.tsx | 2 +- 4 files changed, 1 insertion(+), 8 deletions(-) diff --git a/examples/XRLightEstimation.tsx b/examples/XRLightEstimation.tsx index d80c395..44267c9 100644 --- a/examples/XRLightEstimation.tsx +++ b/examples/XRLightEstimation.tsx @@ -4,7 +4,6 @@ import { Mesh, MeshStandardMaterial, SphereGeometry } from 'three' import { XRLightProbeState } from '@etherealengine/spatial/src/xr/XRLightProbeSystem' import { getMutableState, useHookstate } from '@etherealengine/hyperflux' -import { useLocationSpawnAvatar } from '@etherealengine/client-core/src/components/World/EngineHooks' import { getComponent, setComponent } from '@etherealengine/ecs/src/ComponentFunctions' import { createEntity, removeEntity } from '@etherealengine/ecs/src/EntityFunctions' import { addObjectToGroup } from '@etherealengine/spatial/src/renderer/components/GroupComponent' @@ -42,7 +41,6 @@ export const LightProbe = () => { } export default function XRLightEstimation() { - useLocationSpawnAvatar() return ( <>