Skip to content

Commit 40e4f0f

Browse files
authored
fix: nested entities (#925)
* fix: avoid removing nested entities when loading a gltf * fix: spinner position if entity is nested * chore: fix test * fix: get entity absolute position
1 parent 27b57a0 commit 40e4f0f

File tree

4 files changed

+13
-6
lines changed

4 files changed

+13
-6
lines changed

packages/@dcl/inspector/src/lib/babylon/decentraland/EcsEntity.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ describe('EcsEntity', () => {
5555
expect(entity.gltfContainer).toBeUndefined()
5656
expect(entity.gltfAssetContainer).toBeUndefined()
5757
expect(entity.ecsComponentValues).toEqual({})
58-
expect(entity.name).toBe(`ecs-${entityId.toString(16)}`)
58+
expect(entity.name).toBe(`ecs-${entityId}`)
5959
expect(scene.getTransformNodeByID(entity.id)).toBe(entity)
6060
})
6161

packages/@dcl/inspector/src/lib/babylon/decentraland/EcsEntity.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ export class EcsEntity extends BABYLON.TransformNode {
4141
ecsComponentValues: EcsComponents = {}
4242

4343
constructor(public entityId: Entity, public context: WeakRef<SceneContext>, public scene: BABYLON.Scene) {
44-
super(`ecs-${entityId.toString(16)}`, scene)
44+
super(`ecs-${entityId}`, scene)
4545
createDefaultTransform(this)
4646
this.initEventHandlers()
4747
}

packages/@dcl/inspector/src/lib/babylon/decentraland/SceneContext.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import { putNftShapeComponent } from './sdkComponents/nft'
2222
import { putVideoPlayerComponent } from './sdkComponents/video-player'
2323
import { putHideComponent } from './editorComponents/hide'
2424
import { putLockComponent } from './editorComponents/lock'
25+
import { ROOT } from '../../sdk/tree'
2526

2627
export type LoadableScene = {
2728
readonly entity: Readonly<Omit<Schemas.Entity, 'id'>>
@@ -80,7 +81,7 @@ export class SceneContext {
8081
readonly stopped = future<void>()
8182

8283
constructor(public babylon: BABYLON.Engine, public scene: BABYLON.Scene, public loadableScene: LoadableScene) {
83-
this.rootNode = new EcsEntity(0 as Entity, this.#weakThis, scene)
84+
this.rootNode = this.getOrCreateEntity(ROOT)
8485
Object.assign(globalThis, { babylon: this.engine })
8586
}
8687

packages/@dcl/inspector/src/lib/babylon/decentraland/sdkComponents/gltf-container.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -137,9 +137,15 @@ async function tryLoadGltfAsync(sceneId: string, entity: EcsEntity, filePath: st
137137
(assetContainer) => {
138138
processGLTFAssetContainer(assetContainer)
139139

140-
// remove old entities
140+
/*
141+
The purpose of this is to solve the following issue:
142+
When the scene is reloaded, the gltfs are loaded from two places, a useEffect in the Renderer.tsx component, and the CRDT messages coming from the engine.
143+
That could cause GLTFs from being loaded twice in the babylon engine, so in order to avoid that, the loop below empties the entity from any previous GLTF loaded, so if it was loaded twice, the second time would clear the first load and it wouldn't end up duplicated.
144+
The problem with that approach is that it would also remove any other entity that was nested onto the parent, and this would mess up the entity tree when the scene is loaded for the first time, that's why the loop needs to skip any node that is an EcsEntity, so it doesn't remove the entity from the tree.
145+
*/
141146
const prevChildren = entity.getChildren()
142147
for (const child of prevChildren) {
148+
if (child instanceof EcsEntity) continue // skip EcsEntity nodes, only remove gltf related stuff
143149
child.setEnabled(false)
144150
child.dispose(false, true)
145151
}
@@ -387,12 +393,12 @@ function createLoadingSpinner(
387393
const CIRCLE = Math.PI * 2
388394
const LIGHT_GRAY = new BABYLON.Color3(0.9, 0.9, 0.9)
389395
const torusOutline = createSemiTorus(radius, tube, radialSegments, tubularSegments, CIRCLE, LIGHT_GRAY, scene)
390-
torusOutline.position.copyFrom(entity.position)
396+
torusOutline.position.copyFrom(entity.getAbsolutePosition())
391397
torusOutline.position.y += 1
392398
torusOutline.rotation.x = Math.PI
393399
torusOutline.billboardMode = BABYLON.Mesh.BILLBOARDMODE_ALL
394400

395-
const LIGHT_RED = new BABYLON.Color3(1, 0.5, 0.5)
401+
const LIGHT_RED = new BABYLON.Color3(1, 45 / 255, 85 / 255)
396402
const semiTorus = createSemiTorus(radius, tube, radialSegments, tubularSegments, CIRCLE / 4, LIGHT_RED, scene)
397403
semiTorus.position.z += 0.001
398404
semiTorus.parent = torusOutline

0 commit comments

Comments
 (0)