@zephyr3d/scene 0.7.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/animation/animation.js +4 -33
- package/dist/animation/animation.js.map +1 -1
- package/dist/animation/animationset.js +24 -11
- package/dist/animation/animationset.js.map +1 -1
- package/dist/animation/animationtrack.js +1 -0
- package/dist/animation/animationtrack.js.map +1 -1
- package/dist/animation/eulerrotationtrack.js +0 -1
- package/dist/animation/eulerrotationtrack.js.map +1 -1
- package/dist/animation/ik/ccd_solver.js +372 -0
- package/dist/animation/ik/ccd_solver.js.map +1 -0
- package/dist/animation/ik/fabrik_solver.js +399 -0
- package/dist/animation/ik/fabrik_solver.js.map +1 -0
- package/dist/animation/ik/ik_angle_constraint.js +181 -0
- package/dist/animation/ik/ik_angle_constraint.js.map +1 -0
- package/dist/animation/ik/ik_chain.js +163 -0
- package/dist/animation/ik/ik_chain.js.map +1 -0
- package/dist/animation/ik/ik_chain_builder.js +68 -0
- package/dist/animation/ik/ik_chain_builder.js.map +1 -0
- package/dist/animation/ik/ik_constraint.js +25 -0
- package/dist/animation/ik/ik_constraint.js.map +1 -0
- package/dist/animation/ik/ik_pole_constraint.js +123 -0
- package/dist/animation/ik/ik_pole_constraint.js.map +1 -0
- package/dist/animation/ik/ik_solver.js +48 -0
- package/dist/animation/ik/ik_solver.js.map +1 -0
- package/dist/animation/ik/ik_track.js +96 -0
- package/dist/animation/ik/ik_track.js.map +1 -0
- package/dist/animation/ik/ik_utils.js +270 -0
- package/dist/animation/ik/ik_utils.js.map +1 -0
- package/dist/animation/ik/two_bone_ik_solver.js +332 -0
- package/dist/animation/ik/two_bone_ik_solver.js.map +1 -0
- package/dist/animation/ik_modifier.js +61 -0
- package/dist/animation/ik_modifier.js.map +1 -0
- package/dist/animation/ik_postprocessor.js +71 -0
- package/dist/animation/ik_postprocessor.js.map +1 -0
- package/dist/animation/manual_transform_processor.js +156 -0
- package/dist/animation/manual_transform_processor.js.map +1 -0
- package/dist/animation/morphtarget.js +7 -1
- package/dist/animation/morphtarget.js.map +1 -1
- package/dist/animation/morphtrack.js +3 -3
- package/dist/animation/morphtrack.js.map +1 -1
- package/dist/animation/proptrack.js +37 -41
- package/dist/animation/proptrack.js.map +1 -1
- package/dist/animation/rotationtrack.js +0 -1
- package/dist/animation/rotationtrack.js.map +1 -1
- package/dist/animation/scaletrack.js +0 -1
- package/dist/animation/scaletrack.js.map +1 -1
- package/dist/animation/skeleton.js +57 -60
- package/dist/animation/skeleton.js.map +1 -1
- package/dist/animation/skeleton_modifier.js +38 -0
- package/dist/animation/skeleton_modifier.js.map +1 -0
- package/dist/animation/skeleton_postprocessor.js +50 -0
- package/dist/animation/skeleton_postprocessor.js.map +1 -0
- package/dist/animation/spring/multi_chain_spring_system.js +503 -0
- package/dist/animation/spring/multi_chain_spring_system.js.map +1 -0
- package/dist/animation/spring/spring_chain.js +103 -0
- package/dist/animation/spring/spring_chain.js.map +1 -0
- package/dist/animation/spring/spring_collider.js +247 -0
- package/dist/animation/spring/spring_collider.js.map +1 -0
- package/dist/animation/spring/spring_constraint.js +21 -0
- package/dist/animation/spring/spring_constraint.js.map +1 -0
- package/dist/animation/spring/spring_particle.js +20 -0
- package/dist/animation/spring/spring_particle.js.map +1 -0
- package/dist/animation/spring/spring_system.js +526 -0
- package/dist/animation/spring/spring_system.js.map +1 -0
- package/dist/animation/spring_modifier.js +45 -0
- package/dist/animation/spring_modifier.js.map +1 -0
- package/dist/animation/spring_postprocessor.js +54 -0
- package/dist/animation/spring_postprocessor.js.map +1 -0
- package/dist/animation/translationtrack.js +0 -1
- package/dist/animation/translationtrack.js.map +1 -1
- package/dist/app/api.js +13 -4
- package/dist/app/api.js.map +1 -1
- package/dist/app/app.js +13 -1
- package/dist/app/app.js.map +1 -1
- package/dist/app/engine.js +33 -45
- package/dist/app/engine.js.map +1 -1
- package/dist/app/inputmgr.js.map +1 -1
- package/dist/app/runtimescript.js.map +1 -1
- package/dist/app/screen.js +318 -0
- package/dist/app/screen.js.map +1 -0
- package/dist/app/scriptingsystem.js +10 -6
- package/dist/app/scriptingsystem.js.map +1 -1
- package/dist/app/scriptregistry.js +11 -22
- package/dist/app/scriptregistry.js.map +1 -1
- package/dist/asset/assetmanager.js +79 -58
- package/dist/asset/assetmanager.js.map +1 -1
- package/dist/asset/builtin.js +5 -5
- package/dist/asset/builtin.js.map +1 -1
- package/dist/asset/loaders/dds/dds.js +6 -2
- package/dist/asset/loaders/dds/dds.js.map +1 -1
- package/dist/asset/loaders/dds/dds_loader.js +1 -1
- package/dist/asset/loaders/dds/dds_loader.js.map +1 -1
- package/dist/asset/loaders/gltf/gltf_loader.js +14 -6
- package/dist/asset/loaders/gltf/gltf_loader.js.map +1 -1
- package/dist/asset/loaders/gltf/helpers.js +6 -2
- package/dist/asset/loaders/gltf/helpers.js.map +1 -1
- package/dist/asset/loaders/hdr/hdr.js +22 -15
- package/dist/asset/loaders/hdr/hdr.js.map +1 -1
- package/dist/asset/loaders/image/tga_Loader.js +2 -1
- package/dist/asset/loaders/image/tga_Loader.js.map +1 -1
- package/dist/asset/loaders/image/webimage_loader.js.map +1 -1
- package/dist/asset/loaders/loader.js +2 -2
- package/dist/asset/loaders/loader.js.map +1 -1
- package/dist/asset/model.js +9 -5
- package/dist/asset/model.js.map +1 -1
- package/dist/blitter/bilateralblur.js.map +1 -1
- package/dist/blitter/blitter.js +9 -11
- package/dist/blitter/blitter.js.map +1 -1
- package/dist/blitter/box.js +0 -1
- package/dist/blitter/box.js.map +1 -1
- package/dist/blitter/copy.js.map +1 -1
- package/dist/blitter/gaussianblur.js.map +1 -1
- package/dist/camera/base.js +1 -3
- package/dist/camera/base.js.map +1 -1
- package/dist/camera/camera.js +121 -37
- package/dist/camera/camera.js.map +1 -1
- package/dist/camera/fps.js +19 -17
- package/dist/camera/fps.js.map +1 -1
- package/dist/camera/orbit.js +45 -43
- package/dist/camera/orbit.js.map +1 -1
- package/dist/camera/orthocamera.js +27 -21
- package/dist/camera/orthocamera.js.map +1 -1
- package/dist/camera/perspectivecamera.js +28 -19
- package/dist/camera/perspectivecamera.js.map +1 -1
- package/dist/index.d.ts +15802 -15577
- package/dist/index.js +33 -11
- package/dist/index.js.map +1 -1
- package/dist/material/blinn.js.map +1 -1
- package/dist/material/grassmaterial.js.map +1 -1
- package/dist/material/lambert.js.map +1 -1
- package/dist/material/material.js +11 -5
- package/dist/material/material.js.map +1 -1
- package/dist/material/meshmaterial.js +10 -9
- package/dist/material/meshmaterial.js.map +1 -1
- package/dist/material/mixins/albedocolor.js.map +1 -1
- package/dist/material/mixins/foliage.js.map +1 -1
- package/dist/material/mixins/lightmodel/blinnphong.js +66 -4
- package/dist/material/mixins/lightmodel/blinnphong.js.map +1 -1
- package/dist/material/mixins/lightmodel/lambert.js.map +1 -1
- package/dist/material/mixins/lightmodel/pbrblueprintmixin.js +7 -0
- package/dist/material/mixins/lightmodel/pbrblueprintmixin.js.map +1 -1
- package/dist/material/mixins/lightmodel/pbrmetallicroughness.js.map +1 -1
- package/dist/material/mixins/lightmodel/pbrspecularglossness.js.map +1 -1
- package/dist/material/mixins/lit.js +3 -3
- package/dist/material/mixins/lit.js.map +1 -1
- package/dist/material/mixins/pbr/brdf.js.map +1 -1
- package/dist/material/mixins/pbr/common.js.map +1 -1
- package/dist/material/mixins/texture.js +3 -0
- package/dist/material/mixins/texture.js.map +1 -1
- package/dist/material/mixins/vertexcolor.js.map +1 -1
- package/dist/material/particle.js.map +1 -1
- package/dist/material/pbrblueprint.js +180 -22
- package/dist/material/pbrblueprint.js.map +1 -1
- package/dist/material/pbrmr.js.map +1 -1
- package/dist/material/pbrsg.js.map +1 -1
- package/dist/material/shader/helper.js +41 -56
- package/dist/material/shader/helper.js.map +1 -1
- package/dist/material/sprite.js +301 -0
- package/dist/material/sprite.js.map +1 -0
- package/dist/material/sprite3d.js +301 -0
- package/dist/material/sprite3d.js.map +1 -0
- package/dist/material/sprite3d_std.js +116 -0
- package/dist/material/sprite3d_std.js.map +1 -0
- package/dist/material/sprite3dblueprint.js +235 -0
- package/dist/material/sprite3dblueprint.js.map +1 -0
- package/dist/material/sprite_std.js +116 -0
- package/dist/material/sprite_std.js.map +1 -0
- package/dist/material/spriteblueprint.js +235 -0
- package/dist/material/spriteblueprint.js.map +1 -0
- package/dist/material/terrain-cm.js +0 -1
- package/dist/material/terrain-cm.js.map +1 -1
- package/dist/material/unlit.js.map +1 -1
- package/dist/material/water.js.map +1 -1
- package/dist/posteffect/bloom.js.map +1 -1
- package/dist/posteffect/compositor.js.map +1 -1
- package/dist/posteffect/fxaa.js.map +1 -1
- package/dist/posteffect/grayscale.js.map +1 -1
- package/dist/posteffect/motionblur.js.map +1 -1
- package/dist/posteffect/posteffect.js.map +1 -1
- package/dist/posteffect/sao.js.map +1 -1
- package/dist/posteffect/ssr.js +7 -5
- package/dist/posteffect/ssr.js.map +1 -1
- package/dist/posteffect/taa.js.map +1 -1
- package/dist/posteffect/tonemap.js.map +1 -1
- package/dist/render/abuffer_oit.js +8 -6
- package/dist/render/abuffer_oit.js.map +1 -1
- package/dist/render/clipmap.js +0 -10
- package/dist/render/clipmap.js.map +1 -1
- package/dist/render/cluster_light.js +4 -4
- package/dist/render/cluster_light.js.map +1 -1
- package/dist/render/cull_visitor.js +15 -17
- package/dist/render/cull_visitor.js.map +1 -1
- package/dist/render/depthpass.js +3 -4
- package/dist/render/depthpass.js.map +1 -1
- package/dist/render/drawable.js +15 -0
- package/dist/render/drawable.js.map +1 -0
- package/dist/render/drawable_mixin.js +8 -4
- package/dist/render/drawable_mixin.js.map +1 -1
- package/dist/render/envlight.js.map +1 -1
- package/dist/render/fbm_wavegenerator.js +3 -1
- package/dist/render/fbm_wavegenerator.js.map +1 -1
- package/dist/render/fft_wavegenerator.js +67 -64
- package/dist/render/fft_wavegenerator.js.map +1 -1
- package/dist/render/fullscreenquad.js.map +1 -1
- package/dist/render/gerstner_wavegenerator.js +3 -1
- package/dist/render/gerstner_wavegenerator.js.map +1 -1
- package/dist/render/globalbindgroup_allocator.js +3 -1
- package/dist/render/globalbindgroup_allocator.js.map +1 -1
- package/dist/render/hzb.js +1 -2
- package/dist/render/hzb.js.map +1 -1
- package/dist/render/lightpass.js +13 -13
- package/dist/render/lightpass.js.map +1 -1
- package/dist/render/objectcolorpass.js +4 -7
- package/dist/render/objectcolorpass.js.map +1 -1
- package/dist/render/primitive.js +4 -5
- package/dist/render/primitive.js.map +1 -1
- package/dist/render/render_queue.js +10 -5
- package/dist/render/render_queue.js.map +1 -1
- package/dist/render/renderer.js +16 -22
- package/dist/render/renderer.js.map +1 -1
- package/dist/render/renderpass.js +27 -52
- package/dist/render/renderpass.js.map +1 -1
- package/dist/render/rendertarget.js +5 -0
- package/dist/render/rendertarget.js.map +1 -0
- package/dist/render/screenrendertarget.js +56 -0
- package/dist/render/screenrendertarget.js.map +1 -0
- package/dist/render/shadowmap_pass.js +4 -5
- package/dist/render/shadowmap_pass.js.map +1 -1
- package/dist/render/sky.js +16 -14
- package/dist/render/sky.js.map +1 -1
- package/dist/render/weightedblended_oit.js.map +1 -1
- package/dist/scene/basesprite.js +296 -0
- package/dist/scene/basesprite.js.map +1 -0
- package/dist/scene/batchgroup.js +4 -2
- package/dist/scene/batchgroup.js.map +1 -1
- package/dist/scene/environment.js +9 -10
- package/dist/scene/environment.js.map +1 -1
- package/dist/scene/graph_node.js.map +1 -1
- package/dist/scene/light.js +22 -4
- package/dist/scene/light.js.map +1 -1
- package/dist/scene/mesh.js +96 -26
- package/dist/scene/mesh.js.map +1 -1
- package/dist/scene/octree.js.map +1 -1
- package/dist/scene/particlesys.js +25 -22
- package/dist/scene/particlesys.js.map +1 -1
- package/dist/scene/raycast_visitor.js +0 -16
- package/dist/scene/raycast_visitor.js.map +1 -1
- package/dist/scene/scene.js +7 -4
- package/dist/scene/scene.js.map +1 -1
- package/dist/scene/scene_node.js +20 -35
- package/dist/scene/scene_node.js.map +1 -1
- package/dist/scene/sprite.js +18 -0
- package/dist/scene/sprite.js.map +1 -0
- package/dist/scene/sprite3d.js +18 -0
- package/dist/scene/sprite3d.js.map +1 -0
- package/dist/scene/terrain-cm/grass.js +5 -4
- package/dist/scene/terrain-cm/grass.js.map +1 -1
- package/dist/scene/terrain-cm/grassmaterial.js +3 -1
- package/dist/scene/terrain-cm/grassmaterial.js.map +1 -1
- package/dist/scene/terrain-cm/terrain-cm.js +65 -48
- package/dist/scene/terrain-cm/terrain-cm.js.map +1 -1
- package/dist/scene/water.js +35 -30
- package/dist/scene/water.js.map +1 -1
- package/dist/shaders/atmosphere.js +17 -29
- package/dist/shaders/atmosphere.js.map +1 -1
- package/dist/shaders/fog.js.map +1 -1
- package/dist/shaders/misc.js.map +1 -1
- package/dist/shaders/noise.js.map +1 -1
- package/dist/shaders/pbr.js.map +1 -1
- package/dist/shaders/shadow.js.map +1 -1
- package/dist/shaders/ssr.js.map +1 -1
- package/dist/shaders/temporal.js.map +1 -1
- package/dist/shaders/water.js.map +1 -1
- package/dist/shadow/esm.js +1 -1
- package/dist/shadow/esm.js.map +1 -1
- package/dist/shadow/pcf_opt.js.map +1 -1
- package/dist/shadow/pcf_pd.js.map +1 -1
- package/dist/shadow/shader.js +3 -1
- package/dist/shadow/shader.js.map +1 -1
- package/dist/shadow/shadow_impl.js.map +1 -1
- package/dist/shadow/shadowmapper.js +6 -18
- package/dist/shadow/shadowmapper.js.map +1 -1
- package/dist/shadow/ssm.js.map +1 -1
- package/dist/shadow/vsm.js.map +1 -1
- package/dist/shapes/box.js +9 -3
- package/dist/shapes/box.js.map +1 -1
- package/dist/shapes/cylinder.js +2 -2
- package/dist/shapes/cylinder.js.map +1 -1
- package/dist/shapes/plane.js +2 -2
- package/dist/shapes/plane.js.map +1 -1
- package/dist/shapes/shape.js +2 -1
- package/dist/shapes/shape.js.map +1 -1
- package/dist/shapes/sphere.js +2 -2
- package/dist/shapes/sphere.js.map +1 -1
- package/dist/shapes/tetrahedron.js +5 -6
- package/dist/shapes/tetrahedron.js.map +1 -1
- package/dist/shapes/torus.js +2 -2
- package/dist/shapes/torus.js.map +1 -1
- package/dist/utility/aabbtree.js +1 -1
- package/dist/utility/aabbtree.js.map +1 -1
- package/dist/utility/blueprint/common/constants.js +578 -104
- package/dist/utility/blueprint/common/constants.js.map +1 -1
- package/dist/utility/blueprint/common/math.js +471 -9
- package/dist/utility/blueprint/common/math.js.map +1 -1
- package/dist/utility/blueprint/common.js +1 -1
- package/dist/utility/blueprint/common.js.map +1 -1
- package/dist/utility/blueprint/material/func.js +9 -5
- package/dist/utility/blueprint/material/func.js.map +1 -1
- package/dist/utility/blueprint/material/inputs.js.map +1 -1
- package/dist/utility/blueprint/material/ir.js +288 -80
- package/dist/utility/blueprint/material/ir.js.map +1 -1
- package/dist/utility/blueprint/material/pbr.js +92 -4
- package/dist/utility/blueprint/material/pbr.js.map +1 -1
- package/dist/utility/blueprint/material/texture.js +62 -45
- package/dist/utility/blueprint/material/texture.js.map +1 -1
- package/dist/utility/blueprint/node.js +28 -1
- package/dist/utility/blueprint/node.js.map +1 -1
- package/dist/utility/bounding_volume.js.map +1 -1
- package/dist/utility/debug.js.map +1 -1
- package/dist/utility/draco/decoder.js.map +1 -1
- package/dist/utility/misc.js +1 -1
- package/dist/utility/misc.js.map +1 -1
- package/dist/utility/panorama.js.map +1 -1
- package/dist/utility/pmrem.js.map +1 -1
- package/dist/utility/rendermipmap.js.map +1 -1
- package/dist/utility/serialization/json.js +19 -15
- package/dist/utility/serialization/json.js.map +1 -1
- package/dist/utility/serialization/manager.js +89 -22
- package/dist/utility/serialization/manager.js.map +1 -1
- package/dist/utility/serialization/scene/animation.js +44 -41
- package/dist/utility/serialization/scene/animation.js.map +1 -1
- package/dist/utility/serialization/scene/batch.js +4 -3
- package/dist/utility/serialization/scene/batch.js.map +1 -1
- package/dist/utility/serialization/scene/camera.js +97 -9
- package/dist/utility/serialization/scene/camera.js.map +1 -1
- package/dist/utility/serialization/scene/common.js +102 -28
- package/dist/utility/serialization/scene/common.js.map +1 -1
- package/dist/utility/serialization/scene/light.js +14 -12
- package/dist/utility/serialization/scene/light.js.map +1 -1
- package/dist/utility/serialization/scene/material.js +216 -26
- package/dist/utility/serialization/scene/material.js.map +1 -1
- package/dist/utility/serialization/scene/mesh.js +71 -100
- package/dist/utility/serialization/scene/mesh.js.map +1 -1
- package/dist/utility/serialization/scene/misc.js +3 -2
- package/dist/utility/serialization/scene/misc.js.map +1 -1
- package/dist/utility/serialization/scene/node.js +42 -9
- package/dist/utility/serialization/scene/node.js.map +1 -1
- package/dist/utility/serialization/scene/particle.js +7 -5
- package/dist/utility/serialization/scene/particle.js.map +1 -1
- package/dist/utility/serialization/scene/primitive.js +18 -15
- package/dist/utility/serialization/scene/primitive.js.map +1 -1
- package/dist/utility/serialization/scene/scene.js +3 -2
- package/dist/utility/serialization/scene/scene.js.map +1 -1
- package/dist/utility/serialization/scene/sprite.js +164 -0
- package/dist/utility/serialization/scene/sprite.js.map +1 -0
- package/dist/utility/serialization/scene/terrain.js +8 -6
- package/dist/utility/serialization/scene/terrain.js.map +1 -1
- package/dist/utility/serialization/scene/water.js +11 -9
- package/dist/utility/serialization/scene/water.js.map +1 -1
- package/dist/utility/serialization/types.js +6 -0
- package/dist/utility/serialization/types.js.map +1 -0
- package/dist/utility/shprojector.js.map +1 -1
- package/dist/utility/textures/ggxlut.js.map +1 -1
- package/dist/utility/textures/gradientnoise.js.map +1 -1
- package/dist/utility/textures/randomnoise.js.map +1 -1
- package/dist/values.js +14 -14
- package/dist/values.js.map +1 -1
- package/package.json +80 -80
|
@@ -30,27 +30,11 @@ const tmpV3 = new Vector3();
|
|
|
30
30
|
}
|
|
31
31
|
if (target.isMesh()) {
|
|
32
32
|
return this.visitMesh(target);
|
|
33
|
-
} else if (target.isTerrain()) {
|
|
34
|
-
return this.visitTerrain(target);
|
|
35
33
|
} else if (target.isWater()) {
|
|
36
34
|
return this.visitWater(target);
|
|
37
35
|
}
|
|
38
36
|
return false;
|
|
39
37
|
}
|
|
40
|
-
visitTerrain(node) {
|
|
41
|
-
if (!node.hidden && node.pickable) {
|
|
42
|
-
this._ray.transform(node.invWorldMatrix, this._rayLocal);
|
|
43
|
-
const d = node.rayIntersect(this._rayLocal); // this._rayLocal.bboxIntersectionTestEx(node.getBoundingVolume().toAABB());
|
|
44
|
-
if (this.updateVisitResult(d, node)) {
|
|
45
|
-
this._intersectedDist = d;
|
|
46
|
-
this._intersected = {
|
|
47
|
-
node
|
|
48
|
-
};
|
|
49
|
-
return true;
|
|
50
|
-
}
|
|
51
|
-
}
|
|
52
|
-
return false;
|
|
53
|
-
}
|
|
54
38
|
visitWater(node) {
|
|
55
39
|
if (!node.hidden && node.pickable) {
|
|
56
40
|
const bv = node.getWorldBoundingVolume().toAABB();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"raycast_visitor.js","sources":["../../src/scene/raycast_visitor.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"file":"raycast_visitor.js","sources":["../../src/scene/raycast_visitor.ts"],"sourcesContent":["import type { Nullable } from '@zephyr3d/base';\r\nimport { Ray, Vector3 } from '@zephyr3d/base';\r\nimport { OctreeNode } from './octree';\r\nimport type { Mesh } from './mesh';\r\nimport type { Visitor } from './visitor';\r\nimport type { SceneNode } from './scene_node';\r\nimport type { PickTarget } from '../render';\r\nimport type { Water } from './water';\r\n\r\nconst tmpV3 = new Vector3();\r\n\r\n/** @internal */\r\nexport class RaycastVisitor implements Visitor<SceneNode | OctreeNode> {\r\n /** @internal */\r\n private readonly _ray: Ray;\r\n /** @internal */\r\n private readonly _rayLocal: Ray;\r\n /** @internal */\r\n private _intersected: Nullable<PickTarget>;\r\n /** @internal */\r\n private _intersectedDist: number;\r\n /** @internal */\r\n private readonly _intersectedPoint: Vector3;\r\n constructor(ray: Ray, length: number) {\r\n this._ray = ray;\r\n this._rayLocal = new Ray();\r\n this._intersected = null;\r\n this._intersectedDist = length;\r\n this._intersectedPoint = new Vector3();\r\n }\r\n get intersected() {\r\n return this._intersected;\r\n }\r\n get intersectedDist() {\r\n return this._intersectedDist;\r\n }\r\n get intersectedPoint() {\r\n return this._intersectedPoint;\r\n }\r\n visit(target: SceneNode | OctreeNode) {\r\n if (target instanceof OctreeNode) {\r\n return this.visitOctreeNode(target);\r\n }\r\n if (target.isMesh()) {\r\n return this.visitMesh(target);\r\n } else if (target.isWater()) {\r\n return this.visitWater(target);\r\n }\r\n return false;\r\n }\r\n visitWater(node: Water) {\r\n if (!node.hidden && node.pickable) {\r\n const bv = node.getWorldBoundingVolume()!.toAABB();\r\n const d = this._ray.bboxIntersectionTestEx(bv);\r\n if (this.updateVisitResult(d, node)) {\r\n this._intersectedDist = d!;\r\n this._intersected = node.getPickTarget();\r\n return true;\r\n }\r\n }\r\n return false;\r\n }\r\n visitMesh(node: Mesh) {\r\n if (!node.hidden && node.pickable) {\r\n this._ray.transform(node.invWorldMatrix, this._rayLocal);\r\n const d = node.primitive!.raycast(this._rayLocal);\r\n if (this.updateVisitResult(d, node)) {\r\n this._intersected = node.getPickTarget();\r\n return true;\r\n }\r\n }\r\n return false;\r\n }\r\n visitOctreeNode(node: OctreeNode) {\r\n if (node.getLevel() === 0 || this._ray.bboxIntersectionTest(node.getBoxLoosed()) !== null) {\r\n const nodes = node.getNodes();\r\n for (let i = 0; i < nodes.length; i++) {\r\n this.visit(nodes[i]);\r\n }\r\n return true;\r\n }\r\n return false;\r\n }\r\n private updateVisitResult(d: Nullable<number>, node: SceneNode) {\r\n if (d !== null) {\r\n Vector3.combine(this._rayLocal.origin, this._rayLocal.direction, 1, d, tmpV3);\r\n node.worldMatrix.transformPointAffine(tmpV3, tmpV3);\r\n const dist = Vector3.distance(tmpV3, this._ray.origin);\r\n if (dist < this._intersectedDist) {\r\n this._intersectedDist = dist;\r\n this._intersectedPoint.set(tmpV3);\r\n return true;\r\n }\r\n }\r\n return false;\r\n }\r\n}\r\n"],"names":["tmpV3","Vector3","RaycastVisitor","ray","length","_ray","_rayLocal","Ray","_intersected","_intersectedDist","_intersectedPoint","intersected","intersectedDist","intersectedPoint","visit","target","OctreeNode","visitOctreeNode","isMesh","visitMesh","isWater","visitWater","node","hidden","pickable","bv","getWorldBoundingVolume","toAABB","d","bboxIntersectionTestEx","updateVisitResult","getPickTarget","transform","invWorldMatrix","primitive","raycast","getLevel","bboxIntersectionTest","getBoxLoosed","nodes","getNodes","i","combine","origin","direction","worldMatrix","transformPointAffine","dist","distance","set"],"mappings":"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"}
|
package/dist/scene/scene.js
CHANGED
|
@@ -3,6 +3,7 @@ import { SceneNode } from './scene_node.js';
|
|
|
3
3
|
import { Octree } from './octree.js';
|
|
4
4
|
import { RaycastVisitor } from './raycast_visitor.js';
|
|
5
5
|
import { Environment } from './environment.js';
|
|
6
|
+
import { getDevice } from '../app/api.js';
|
|
6
7
|
import '../values.js';
|
|
7
8
|
import '@zephyr3d/device';
|
|
8
9
|
import '../material/shader/helper.js';
|
|
@@ -10,14 +11,15 @@ import '../material/lambert.js';
|
|
|
10
11
|
import '../material/blinn.js';
|
|
11
12
|
import '../material/unlit.js';
|
|
12
13
|
import '../material/particle.js';
|
|
13
|
-
import { getDevice } from '../app/api.js';
|
|
14
14
|
import '../material/meshmaterial.js';
|
|
15
15
|
import '../material/grassmaterial.js';
|
|
16
|
-
import '../material/terrainmaterial.js';
|
|
17
16
|
import '../material/terrain-cm.js';
|
|
18
17
|
import '../material/pbrmr.js';
|
|
19
18
|
import '../material/pbrsg.js';
|
|
20
19
|
import '../material/pbrblueprint.js';
|
|
20
|
+
import '../material/sprite.js';
|
|
21
|
+
import '../material/sprite_std.js';
|
|
22
|
+
import '../utility/blueprint/material/texture.js';
|
|
21
23
|
import { SceneRenderer } from '../render/renderer.js';
|
|
22
24
|
import '../render/primitive.js';
|
|
23
25
|
import '../render/sky.js';
|
|
@@ -77,7 +79,8 @@ import '../shaders/atmosphere.js';
|
|
|
77
79
|
this._perCameraUpdateQueue = [];
|
|
78
80
|
this._env = new Environment();
|
|
79
81
|
this._updateFrame = -1;
|
|
80
|
-
this._rootNode = new DRef(
|
|
82
|
+
this._rootNode = new DRef();
|
|
83
|
+
this._rootNode.set(new SceneNode(this));
|
|
81
84
|
this._rootNode.get().name = 'Root';
|
|
82
85
|
this._metaData = null;
|
|
83
86
|
this._script = '';
|
|
@@ -107,7 +110,7 @@ import '../shaders/atmosphere.js';
|
|
|
107
110
|
/**
|
|
108
111
|
* Gets the root scene node of the scene
|
|
109
112
|
*/ get rootNode() {
|
|
110
|
-
return this._rootNode
|
|
113
|
+
return this._rootNode.get();
|
|
111
114
|
}
|
|
112
115
|
/**
|
|
113
116
|
* Gets the octree used for spatial organization and queries.
|
package/dist/scene/scene.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"scene.js","sources":["../../src/scene/scene.ts"],"sourcesContent":["import type { Matrix4x4, AABB } from '@zephyr3d/base';\r\nimport { Vector3, Vector4, Ray, DRef, DWeakRef, makeObservable, Disposable } from '@zephyr3d/base';\r\nimport { SceneNode } from './scene_node';\r\nimport { Octree } from './octree';\r\nimport { RaycastVisitor } from './raycast_visitor';\r\nimport { Environment } from './environment';\r\nimport type { GraphNode } from './graph_node';\r\nimport type { Camera } from '../camera/camera';\r\nimport type { PickTarget } from '../render';\r\nimport { SceneRenderer } from '../render';\r\nimport type { Compositor } from '../posteffect';\r\nimport type { Metadata } from 'draco3d';\r\nimport { getDevice } from '../app/api';\r\nimport type { IRenderable } from '../app';\r\n\r\n/**\r\n * Represents a renderable world that manages scene graph, spatial indexing, and environment.\r\n *\r\n * Core responsibilities:\r\n * - Owns the root {@link SceneNode} and maintains a spatial {@link Octree} for culling/raycasting.\r\n * - Manages environment/lighting via {@link Environment}.\r\n * - Provides per-frame update queues (global and per-camera) for scene nodes.\r\n * - Offers utilities like ray construction and raycasting.\r\n * - Emits observable events: `update`, `startrender`, `endrender`.\r\n *\r\n * Performance notes:\r\n * - Octree placement is lazily synchronized on demand before reads (e.g., `octree`, `boundingBox`)\r\n * and during per-frame updates.\r\n * - Update queues use weak references to avoid retaining disposed nodes.\r\n *\r\n * @public\r\n */\r\nexport class Scene\r\n extends makeObservable(Disposable)<{\r\n /** Dispatched once per frame before render-related work. */\r\n update: [Scene];\r\n /** Dispatched immediately before rendering begins for a camera. */\r\n startrender: [Scene, Camera, Compositor];\r\n /** Dispatched immediately after rendering finishes for a camera. */\r\n endrender: [Scene, Camera, Compositor];\r\n }>()\r\n implements IRenderable\r\n{\r\n /** @internal */\r\n private static _nextId = 0;\r\n /** @internal Scene name. */\r\n protected _name: string;\r\n /** @internal Root node reference. */\r\n protected _rootNode: DRef<SceneNode>;\r\n /** @internal Spatial index for placement/culling. */\r\n protected _octree: Octree;\r\n /**\r\n * @internal Pending nodes whose placement in the octree must be updated.\r\n * Populated by {@link Scene.invalidateNodePlacement} and drained by {@link Scene.updateNodePlacement}.\r\n */\r\n protected _nodePlaceList: Set<GraphNode>;\r\n /** @internal Environment data (sky/light/IBL). */\r\n protected _env: Environment;\r\n /** @internal Frame counter that last updated this scene. */\r\n protected _updateFrame: number;\r\n /** @internal Unique scene ID. */\r\n protected _id: number;\r\n /** @internal One-shot per-frame update queue (runs before render). */\r\n protected _nodeUpdateQueue: DWeakRef<SceneNode>[];\r\n /** @internal One-shot per-frame-per-camera update queue. */\r\n protected _perCameraUpdateQueue: DWeakRef<SceneNode>[];\r\n /** @internal Main camera reference. */\r\n protected _mainCamera: DRef<Camera>;\r\n /** @internal Arbitrary metadata loaded with the scene (optional). */\r\n protected _metaData: Metadata;\r\n /** @internal User-attached script entry (engine-defined). */\r\n private _script: string;\r\n /**\r\n * Creates an instance of Scene.\r\n *\r\n * Initializes:\r\n * - Unique ID\r\n * - Empty environment\r\n * - Octree with default depth/leaf capacities\r\n * - Root scene node named \"Root\"\r\n *\r\n * @param name - Optional scene name for diagnostics/UI.\r\n */\r\n constructor(name?: string) {\r\n super();\r\n this._id = ++Scene._nextId;\r\n this._name = name ?? '';\r\n this._octree = new Octree(this, 8, 8);\r\n this._nodePlaceList = new Set();\r\n this._nodeUpdateQueue = [];\r\n this._perCameraUpdateQueue = [];\r\n this._env = new Environment();\r\n this._updateFrame = -1;\r\n this._rootNode = new DRef(new SceneNode(this));\r\n this._rootNode.get().name = 'Root';\r\n this._metaData = null;\r\n this._script = '';\r\n this._mainCamera = new DRef();\r\n }\r\n /**\r\n * Gets the unique identifier of the scene.\r\n */\r\n get id(): number {\r\n return this._id;\r\n }\r\n /**\r\n * Name of the scene\r\n */\r\n get name() {\r\n return this._name;\r\n }\r\n set name(val: string) {\r\n this._name = val ?? '';\r\n }\r\n /**\r\n * Main camera used to render the scene by default.\r\n */\r\n get mainCamera() {\r\n return this._mainCamera.get();\r\n }\r\n set mainCamera(camera: Camera) {\r\n this._mainCamera.set(camera);\r\n }\r\n /**\r\n * Gets the root scene node of the scene\r\n */\r\n get rootNode() {\r\n return this._rootNode?.get() ?? null;\r\n }\r\n /**\r\n * Gets the octree used for spatial organization and queries.\r\n *\r\n * Ensures pending node placements are synchronized before returning.\r\n */\r\n get octree(): Octree {\r\n // Make sure the octree state is up to date\r\n this.updateNodePlacement(this._octree, this._nodePlaceList);\r\n return this._octree;\r\n }\r\n /**\r\n * Gets the world-axis-aligned bounding box of the scene.\r\n *\r\n * Ensures pending node placements are synchronized before computing.\r\n */\r\n get boundingBox(): AABB {\r\n this.updateNodePlacement(this._octree, this._nodePlaceList);\r\n // this._syncBVChangedList();\r\n return this._octree.getRootNode().getBoxLoosed();\r\n }\r\n /**\r\n * The environment (sky, lights, IBL) of the scene.\r\n */\r\n get env(): Environment {\r\n return this._env;\r\n }\r\n /**\r\n * Arbitrary metadata associated with the scene (e.g., imported asset info).\r\n */\r\n get metaData(): Metadata {\r\n return this._metaData;\r\n }\r\n set metaData(val: Metadata) {\r\n this._metaData = val;\r\n }\r\n /**\r\n * Attached script filename or identifier (engine-specific).\r\n *\r\n * @remarks\r\n * Integrates with the engine’s scripting system if available.\r\n */\r\n get script() {\r\n return this._script;\r\n }\r\n set script(fileName: string) {\r\n this._script = fileName ?? '';\r\n }\r\n /**\r\n * Finds a scene node by its persistent ID.\r\n *\r\n * @typeParam T - Expected node type.\r\n * @param id - Persistent identifier to match against `SceneNode.persistentId`.\r\n * @returns The first matching node, or `null` if not found.\r\n */\r\n findNodeById<T extends SceneNode>(id: string) {\r\n return this._rootNode.get().findNodeById<T>(id);\r\n }\r\n /**\r\n * Finds a scene node by name.\r\n *\r\n * If multiple nodes share the same name, returns the first match encountered\r\n * during traversal.\r\n *\r\n * @typeParam T - Expected node type.\r\n * @param name - Node name to match.\r\n * @returns The first matching node, or `null` if not found.\r\n *\r\n * @remarks\r\n * Names are not guaranteed unique. Prefer IDs for stable references.\r\n */\r\n findNodeByName<T extends SceneNode>(name: string) {\r\n return this._rootNode.get().findNodeByName<T>(name);\r\n }\r\n /**\r\n * Casts a ray into the scene and returns the closest intersection, if any.\r\n *\r\n * @param ray - The ray in world space.\r\n * @param length - Maximum ray length. Defaults to `Infinity`.\r\n * @returns Intersection info `{ target, dist, point }`, or `null` if no hit.\r\n *\r\n */\r\n raycast(ray: Ray, length = Infinity): { target: PickTarget; dist: number; point: Vector3 } {\r\n const raycastVisitor = new RaycastVisitor(ray, length);\r\n this.octree.getRootNode().traverse(raycastVisitor);\r\n return raycastVisitor.intersected\r\n ? {\r\n target: raycastVisitor.intersected,\r\n dist: raycastVisitor.intersectedDist,\r\n point: raycastVisitor.intersectedPoint\r\n }\r\n : null;\r\n }\r\n /**\r\n * Constructs a world-space ray from a camera and a screen position.\r\n *\r\n * @param camera - Camera whose projection/view defines the ray.\r\n * @param viewportWidth - Current viewport width in pixels.\r\n * @param viewportHeight - Current viewport height in pixels.\r\n * @param screenX - Screen-space x (pixels).\r\n * @param screenY - Screen-space y (pixels).\r\n * @param invModelMatrix - Optional inverse model matrix to transform the ray into local space.\r\n * @returns The constructed Ray.\r\n *\r\n * @remarks\r\n * Computes NDC from screen coordinates, unprojects using `invViewProjectionMatrix`,\r\n * then forms a ray from the camera world position to the unprojected point.\r\n * If `invModelMatrix` is provided, both origin and direction are transformed.\r\n */\r\n constructRay(\r\n camera: Camera,\r\n viewportWidth: number,\r\n viewportHeight: number,\r\n screenX: number,\r\n screenY: number,\r\n invModelMatrix?: Matrix4x4\r\n ): Ray {\r\n const vClip = new Vector4((2 * screenX) / viewportWidth - 1, 1 - (2 * screenY) / viewportHeight, 1, 1);\r\n const vWorld = camera.invViewProjectionMatrix.transform(vClip);\r\n vWorld.scaleBy(1 / vWorld.w);\r\n let vEye = camera.getWorldPosition();\r\n let vDir = Vector3.sub(vWorld.xyz(), vEye).inplaceNormalize();\r\n if (invModelMatrix) {\r\n vEye = invModelMatrix.transformPointAffine(vEye);\r\n vDir = invModelMatrix.transformVectorAffine(vDir);\r\n }\r\n return new Ray(vEye, vDir);\r\n }\r\n /**\r\n * Queues a node for a one-shot update before the next render.\r\n *\r\n * The node's `update(frame, elapsedSeconds, deltaSeconds)` will be called\r\n * during Scene.frameUpdate and then the node is removed from the queue.\r\n *\r\n * @param node - Node to schedule.\r\n *\r\n * @remarks\r\n * - To update continuously each frame, call `queueUpdateNode(this)` from within the node's `update` method.\r\n * - Duplicate scheduling within the same frame is prevented.\r\n */\r\n queueUpdateNode(node: SceneNode) {\r\n if (node && this._nodeUpdateQueue.findIndex((val) => val.get() === node) < 0) {\r\n this._nodeUpdateQueue.push(new DWeakRef(node));\r\n }\r\n }\r\n /**\r\n * Queues a node for a one-shot per-camera update before render.\r\n *\r\n * The node's `updatePerCamera(camera, elapsedSeconds, deltaSeconds)` will be\r\n * called once for each camera during {@link Scene.frameUpdatePerCamera}, then removed.\r\n *\r\n * @param node - Node to schedule.\r\n *\r\n * @remarks\r\n * - To run per-camera work continuously, re-queue from `updatePerCamera`.\r\n * - Duplicate scheduling within the same frame is prevented.\r\n */\r\n queuePerCameraUpdateNode(node: SceneNode) {\r\n if (node && this._perCameraUpdateQueue.findIndex((val) => val.get() === node) < 0) {\r\n this._perCameraUpdateQueue.push(new DWeakRef(node));\r\n }\r\n }\r\n /**\r\n * Renders this scene using the `mainCamera`, if present.\r\n *\r\n * Equivalent to `mainCamera.render(this)` when `mainCamera` is set.\r\n */\r\n render() {\r\n if (this.mainCamera) {\r\n this.mainCamera.render(this);\r\n }\r\n }\r\n /**\r\n * Marks a graph node as needing placement update in the octree.\r\n *\r\n * Called by nodes when their transform/visibility/attachment changes in a way\r\n * that affects spatial placement.\r\n *\r\n * @internal\r\n */\r\n invalidateNodePlacement(node: GraphNode) {\r\n this._nodePlaceList.add(node);\r\n }\r\n /**\r\n * Synchronizes environment light maps (IBL, SH/FB) with the sky as needed.\r\n *\r\n * Uses device capabilities to decide between Spherical Harmonics floating-point blending (SHFB)\r\n * and classic SH textures, and lazily fills missing environment fields from the sky.\r\n *\r\n * @internal\r\n */\r\n private updateEnvLight() {\r\n if (this.env.light.type === 'ibl') {\r\n const useSHFB =\r\n getDevice().type === 'webgl' || !getDevice().getDeviceCaps().framebufferCaps.supportFloatBlending;\r\n if (!this.env.light.radianceMap) {\r\n this.env.light.radianceMap = this.env.sky.radianceMap;\r\n }\r\n if (useSHFB && !this.env.light.irradianceSHFB) {\r\n this.env.light.irradianceSHFB = this.env.sky.irradianceSHFB;\r\n }\r\n if (!useSHFB && !this.env.light.irradianceSH) {\r\n this.env.light.irradianceSH = this.env.sky.irradianceSH;\r\n }\r\n }\r\n }\r\n /**\r\n * Returns the renderer class used to render the scene.\r\n *\r\n * Override in subclasses to supply a custom renderer.\r\n *\r\n * @internal\r\n */\r\n getRenderer(): typeof SceneRenderer {\r\n return SceneRenderer;\r\n }\r\n /**\r\n * Performs per-frame scene updates, once per device frame.\r\n *\r\n * Steps:\r\n * - Ensure this runs only once per frame (via `frameInfo.frameCounter`).\r\n * - Update environment light synchronization.\r\n * - Dispatch `update` event.\r\n * - Drain the one-shot node update queue and call `node.update(...)`.\r\n * - Apply pending octree placement updates.\r\n *\r\n */\r\n frameUpdate() {\r\n const frameInfo = getDevice().frameInfo;\r\n if (frameInfo.frameCounter !== this._updateFrame) {\r\n this._updateFrame = frameInfo.frameCounter;\r\n this.updateEnvLight();\r\n this.dispatchEvent('update', this);\r\n this.mainCamera?.updateController();\r\n if (this._nodeUpdateQueue.length > 0) {\r\n const elapsedInSeconds = frameInfo.elapsedOverall * 0.001;\r\n const deltaInSeconds = frameInfo.elapsedFrame * 0.001;\r\n const queue = this._nodeUpdateQueue;\r\n this._nodeUpdateQueue = [];\r\n while (queue.length > 0) {\r\n const ref = queue.shift();\r\n const node = ref.get();\r\n if (node?.attached) {\r\n node.update(frameInfo.frameCounter, elapsedInSeconds, deltaInSeconds);\r\n }\r\n ref.dispose();\r\n }\r\n }\r\n this.updateNodePlacement(this._octree, this._nodePlaceList);\r\n }\r\n }\r\n /**\r\n * Performs per-camera scene updates for the current frame.\r\n *\r\n * Steps:\r\n * - Drain the per-camera update queue and call `node.updatePerCamera(camera, ...)`.\r\n * - Apply pending octree placement updates.\r\n *\r\n * @param camera - The camera being updated for.\r\n */\r\n frameUpdatePerCamera(camera: Camera) {\r\n if (this._perCameraUpdateQueue.length > 0) {\r\n const frameInfo = getDevice().frameInfo;\r\n const elapsedInSeconds = frameInfo.elapsedOverall * 0.001;\r\n const deltaInSeconds = frameInfo.elapsedFrame * 0.001;\r\n const queue = this._perCameraUpdateQueue;\r\n this._perCameraUpdateQueue = [];\r\n while (queue.length > 0) {\r\n const ref = queue.shift();\r\n ref.get()?.updatePerCamera(camera, elapsedInSeconds, deltaInSeconds);\r\n ref.dispose();\r\n }\r\n }\r\n this.updateNodePlacement(this._octree, this._nodePlaceList);\r\n }\r\n /**\r\n * Applies placement changes for nodes in `list` to the given `octree`.\r\n *\r\n * Rules:\r\n * - If node is not disposed, attached, not hidden, and `placeToOctree` is true,\r\n * it is placed; otherwise removed.\r\n * - Drains `list` until empty.\r\n *\r\n * @param octree - Target spatial index.\r\n * @param list - Set of nodes awaiting placement evaluation.\r\n */\r\n updateNodePlacement(octree: Octree, list: Set<GraphNode>) {\r\n function placeNode(node: GraphNode) {\r\n if (!node.disposed && node.attached && !node.hidden && node.placeToOctree) {\r\n octree.placeNode(node);\r\n } else {\r\n octree.removeNode(node);\r\n }\r\n list.delete(node);\r\n }\r\n if (list.size > 0) {\r\n while (list.size > 0) {\r\n const node = list.keys().next().value;\r\n if (octree) {\r\n placeNode(node);\r\n } else {\r\n list.delete(node);\r\n }\r\n }\r\n }\r\n }\r\n /**\r\n * Disposes the scene and its owned resources.\r\n *\r\n * Disposes:\r\n * - Environment\r\n * - Root node (and, by extension, its hierarchy)\r\n * - Main camera reference wrapper\r\n *\r\n */\r\n protected onDispose() {\r\n this._env.dispose();\r\n this._rootNode.dispose();\r\n this._mainCamera.dispose();\r\n }\r\n}\r\n"],"names":["Scene","makeObservable","Disposable","_nextId","name","_id","_name","_octree","Octree","_nodePlaceList","Set","_nodeUpdateQueue","_perCameraUpdateQueue","_env","Environment","_updateFrame","_rootNode","DRef","SceneNode","get","_metaData","_script","_mainCamera","id","val","mainCamera","camera","set","rootNode","octree","updateNodePlacement","boundingBox","getRootNode","getBoxLoosed","env","metaData","script","fileName","findNodeById","findNodeByName","raycast","ray","length","Infinity","raycastVisitor","RaycastVisitor","traverse","intersected","target","dist","intersectedDist","point","intersectedPoint","constructRay","viewportWidth","viewportHeight","screenX","screenY","invModelMatrix","vClip","Vector4","vWorld","invViewProjectionMatrix","transform","scaleBy","w","vEye","getWorldPosition","vDir","Vector3","sub","xyz","inplaceNormalize","transformPointAffine","transformVectorAffine","Ray","queueUpdateNode","node","findIndex","push","DWeakRef","queuePerCameraUpdateNode","render","invalidateNodePlacement","add","light","type","useSHFB","getDevice","getDeviceCaps","framebufferCaps","supportFloatBlending","radianceMap","sky","irradianceSHFB","irradianceSH","getRenderer","SceneRenderer","frameUpdate","frameInfo","frameCounter","updateEnvLight","dispatchEvent","updateController","elapsedInSeconds","elapsedOverall","deltaInSeconds","elapsedFrame","queue","ref","shift","attached","update","dispose","frameUpdatePerCamera","updatePerCamera","list","placeNode","disposed","hidden","placeToOctree","removeNode","delete","size","keys","next","value"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"scene.js","sources":["../../src/scene/scene.ts"],"sourcesContent":["import type { Matrix4x4, Nullable } from '@zephyr3d/base';\r\nimport { Vector3, Vector4, Ray, DRef, DWeakRef, makeObservable, Disposable } from '@zephyr3d/base';\r\nimport { SceneNode } from './scene_node';\r\nimport { Octree } from './octree';\r\nimport { RaycastVisitor } from './raycast_visitor';\r\nimport { Environment } from './environment';\r\nimport type { GraphNode } from './graph_node';\r\nimport type { Camera } from '../camera/camera';\r\nimport { SceneRenderer } from '../render';\r\nimport type { Compositor } from '../posteffect';\r\nimport type { Metadata } from 'draco3d';\r\nimport { getDevice } from '../app/api';\r\nimport type { IRenderable } from '../app';\r\n\r\n/**\r\n * Represents a renderable world that manages scene graph, spatial indexing, and environment.\r\n *\r\n * Core responsibilities:\r\n * - Owns the root {@link SceneNode} and maintains a spatial {@link Octree} for culling/raycasting.\r\n * - Manages environment/lighting via {@link Environment}.\r\n * - Provides per-frame update queues (global and per-camera) for scene nodes.\r\n * - Offers utilities like ray construction and raycasting.\r\n * - Emits observable events: `update`, `startrender`, `endrender`.\r\n *\r\n * Performance notes:\r\n * - Octree placement is lazily synchronized on demand before reads (e.g., `octree`, `boundingBox`)\r\n * and during per-frame updates.\r\n * - Update queues use weak references to avoid retaining disposed nodes.\r\n *\r\n * @public\r\n */\r\nexport class Scene\r\n extends makeObservable(Disposable)<{\r\n /** Dispatched once per frame before render-related work. */\r\n update: [Scene];\r\n /** Dispatched immediately before rendering begins for a camera. */\r\n startrender: [Scene, Camera, Compositor];\r\n /** Dispatched immediately after rendering finishes for a camera. */\r\n endrender: [Scene, Camera, Compositor];\r\n }>()\r\n implements IRenderable\r\n{\r\n /** @internal */\r\n private static _nextId = 0;\r\n /** @internal Scene name. */\r\n protected _name: string;\r\n /** @internal Root node reference. */\r\n protected _rootNode: DRef<SceneNode>;\r\n /** @internal Spatial index for placement/culling. */\r\n protected _octree: Octree;\r\n /**\r\n * @internal Pending nodes whose placement in the octree must be updated.\r\n * Populated by {@link Scene.invalidateNodePlacement} and drained by {@link Scene.updateNodePlacement}.\r\n */\r\n protected _nodePlaceList: Set<GraphNode>;\r\n /** @internal Environment data (sky/light/IBL). */\r\n protected _env: Environment;\r\n /** @internal Frame counter that last updated this scene. */\r\n protected _updateFrame: number;\r\n /** @internal Unique scene ID. */\r\n protected _id: number;\r\n /** @internal One-shot per-frame update queue (runs before render). */\r\n protected _nodeUpdateQueue: DWeakRef<SceneNode>[];\r\n /** @internal One-shot per-frame-per-camera update queue. */\r\n protected _perCameraUpdateQueue: DWeakRef<SceneNode>[];\r\n /** @internal Main camera reference. */\r\n protected _mainCamera: DRef<Camera>;\r\n /** @internal Arbitrary metadata loaded with the scene (optional). */\r\n protected _metaData: Nullable<Metadata>;\r\n /** @internal User-attached script entry (engine-defined). */\r\n private _script: string;\r\n /**\r\n * Creates an instance of Scene.\r\n *\r\n * Initializes:\r\n * - Unique ID\r\n * - Empty environment\r\n * - Octree with default depth/leaf capacities\r\n * - Root scene node named \"Root\"\r\n *\r\n * @param name - Optional scene name for diagnostics/UI.\r\n */\r\n constructor(name?: string) {\r\n super();\r\n this._id = ++Scene._nextId;\r\n this._name = name ?? '';\r\n this._octree = new Octree(this, 8, 8);\r\n this._nodePlaceList = new Set();\r\n this._nodeUpdateQueue = [];\r\n this._perCameraUpdateQueue = [];\r\n this._env = new Environment();\r\n this._updateFrame = -1;\r\n this._rootNode = new DRef();\r\n this._rootNode.set(new SceneNode(this));\r\n this._rootNode.get()!.name = 'Root';\r\n this._metaData = null;\r\n this._script = '';\r\n this._mainCamera = new DRef();\r\n }\r\n /**\r\n * Gets the unique identifier of the scene.\r\n */\r\n get id() {\r\n return this._id;\r\n }\r\n /**\r\n * Name of the scene\r\n */\r\n get name() {\r\n return this._name;\r\n }\r\n set name(val: string) {\r\n this._name = val ?? '';\r\n }\r\n /**\r\n * Main camera used to render the scene by default.\r\n */\r\n get mainCamera() {\r\n return this._mainCamera.get();\r\n }\r\n set mainCamera(camera) {\r\n this._mainCamera.set(camera);\r\n }\r\n /**\r\n * Gets the root scene node of the scene\r\n */\r\n get rootNode() {\r\n return this._rootNode.get()!;\r\n }\r\n /**\r\n * Gets the octree used for spatial organization and queries.\r\n *\r\n * Ensures pending node placements are synchronized before returning.\r\n */\r\n get octree() {\r\n // Make sure the octree state is up to date\r\n this.updateNodePlacement(this._octree, this._nodePlaceList);\r\n return this._octree;\r\n }\r\n /**\r\n * Gets the world-axis-aligned bounding box of the scene.\r\n *\r\n * Ensures pending node placements are synchronized before computing.\r\n */\r\n get boundingBox() {\r\n this.updateNodePlacement(this._octree, this._nodePlaceList);\r\n // this._syncBVChangedList();\r\n return this._octree.getRootNode().getBoxLoosed();\r\n }\r\n /**\r\n * The environment (sky, lights, IBL) of the scene.\r\n */\r\n get env() {\r\n return this._env;\r\n }\r\n /**\r\n * Arbitrary metadata associated with the scene (e.g., imported asset info).\r\n */\r\n get metaData() {\r\n return this._metaData;\r\n }\r\n set metaData(val) {\r\n this._metaData = val;\r\n }\r\n /**\r\n * Attached script filename or identifier (engine-specific).\r\n *\r\n * @remarks\r\n * Integrates with the engine’s scripting system if available.\r\n */\r\n get script() {\r\n return this._script;\r\n }\r\n set script(fileName: string) {\r\n this._script = fileName ?? '';\r\n }\r\n /**\r\n * Finds a scene node by its persistent ID.\r\n *\r\n * @typeParam T - Expected node type.\r\n * @param id - Persistent identifier to match against `SceneNode.persistentId`.\r\n * @returns The first matching node, or `null` if not found.\r\n */\r\n findNodeById<T extends SceneNode>(id: string) {\r\n return this._rootNode.get()!.findNodeById<T>(id);\r\n }\r\n /**\r\n * Finds a scene node by name.\r\n *\r\n * If multiple nodes share the same name, returns the first match encountered\r\n * during traversal.\r\n *\r\n * @typeParam T - Expected node type.\r\n * @param name - Node name to match.\r\n * @returns The first matching node, or `null` if not found.\r\n *\r\n * @remarks\r\n * Names are not guaranteed unique. Prefer IDs for stable references.\r\n */\r\n findNodeByName<T extends SceneNode>(name: string) {\r\n return this._rootNode.get()!.findNodeByName<T>(name);\r\n }\r\n /**\r\n * Casts a ray into the scene and returns the closest intersection, if any.\r\n *\r\n * @param ray - The ray in world space.\r\n * @param length - Maximum ray length. Defaults to `Infinity`.\r\n * @returns Intersection info `{ target, dist, point }`, or `null` if no hit.\r\n *\r\n */\r\n raycast(ray: Ray, length = Infinity) {\r\n const raycastVisitor = new RaycastVisitor(ray, length);\r\n this.octree.getRootNode().traverse(raycastVisitor);\r\n return raycastVisitor.intersected\r\n ? {\r\n target: raycastVisitor.intersected,\r\n dist: raycastVisitor.intersectedDist,\r\n point: raycastVisitor.intersectedPoint\r\n }\r\n : null;\r\n }\r\n /**\r\n * Constructs a world-space ray from a camera and a screen position.\r\n *\r\n * @param camera - Camera whose projection/view defines the ray.\r\n * @param viewportWidth - Current viewport width in pixels.\r\n * @param viewportHeight - Current viewport height in pixels.\r\n * @param screenX - Screen-space x (pixels).\r\n * @param screenY - Screen-space y (pixels).\r\n * @param invModelMatrix - Optional inverse model matrix to transform the ray into local space.\r\n * @returns The constructed Ray.\r\n *\r\n * @remarks\r\n * Computes NDC from screen coordinates, unprojects using `invViewProjectionMatrix`,\r\n * then forms a ray from the camera world position to the unprojected point.\r\n * If `invModelMatrix` is provided, both origin and direction are transformed.\r\n */\r\n constructRay(\r\n camera: Camera,\r\n viewportWidth: number,\r\n viewportHeight: number,\r\n screenX: number,\r\n screenY: number,\r\n invModelMatrix?: Matrix4x4\r\n ) {\r\n const vClip = new Vector4((2 * screenX) / viewportWidth - 1, 1 - (2 * screenY) / viewportHeight, 1, 1);\r\n const vWorld = camera.invViewProjectionMatrix.transform(vClip);\r\n vWorld.scaleBy(1 / vWorld.w);\r\n let vEye = camera.getWorldPosition();\r\n let vDir = Vector3.sub(vWorld.xyz(), vEye).inplaceNormalize();\r\n if (invModelMatrix) {\r\n vEye = invModelMatrix.transformPointAffine(vEye);\r\n vDir = invModelMatrix.transformVectorAffine(vDir);\r\n }\r\n return new Ray(vEye, vDir);\r\n }\r\n /**\r\n * Queues a node for a one-shot update before the next render.\r\n *\r\n * The node's `update(frame, elapsedSeconds, deltaSeconds)` will be called\r\n * during Scene.frameUpdate and then the node is removed from the queue.\r\n *\r\n * @param node - Node to schedule.\r\n *\r\n * @remarks\r\n * - To update continuously each frame, call `queueUpdateNode(this)` from within the node's `update` method.\r\n * - Duplicate scheduling within the same frame is prevented.\r\n */\r\n queueUpdateNode(node: SceneNode) {\r\n if (node && this._nodeUpdateQueue.findIndex((val) => val.get() === node) < 0) {\r\n this._nodeUpdateQueue.push(new DWeakRef(node));\r\n }\r\n }\r\n /**\r\n * Queues a node for a one-shot per-camera update before render.\r\n *\r\n * The node's `updatePerCamera(camera, elapsedSeconds, deltaSeconds)` will be\r\n * called once for each camera during {@link Scene.frameUpdatePerCamera}, then removed.\r\n *\r\n * @param node - Node to schedule.\r\n *\r\n * @remarks\r\n * - To run per-camera work continuously, re-queue from `updatePerCamera`.\r\n * - Duplicate scheduling within the same frame is prevented.\r\n */\r\n queuePerCameraUpdateNode(node: SceneNode) {\r\n if (node && this._perCameraUpdateQueue.findIndex((val) => val.get() === node) < 0) {\r\n this._perCameraUpdateQueue.push(new DWeakRef(node));\r\n }\r\n }\r\n /**\r\n * Renders this scene using the `mainCamera`, if present.\r\n *\r\n * Equivalent to `mainCamera.render(this)` when `mainCamera` is set.\r\n */\r\n render() {\r\n if (this.mainCamera) {\r\n this.mainCamera.render(this);\r\n }\r\n }\r\n /**\r\n * Marks a graph node as needing placement update in the octree.\r\n *\r\n * Called by nodes when their transform/visibility/attachment changes in a way\r\n * that affects spatial placement.\r\n *\r\n * @internal\r\n */\r\n invalidateNodePlacement(node: GraphNode) {\r\n this._nodePlaceList.add(node);\r\n }\r\n /**\r\n * Synchronizes environment light maps (IBL, SH/FB) with the sky as needed.\r\n *\r\n * Uses device capabilities to decide between Spherical Harmonics floating-point blending (SHFB)\r\n * and classic SH textures, and lazily fills missing environment fields from the sky.\r\n *\r\n * @internal\r\n */\r\n private updateEnvLight() {\r\n if (this.env.light.type === 'ibl') {\r\n const useSHFB =\r\n getDevice().type === 'webgl' || !getDevice().getDeviceCaps().framebufferCaps.supportFloatBlending;\r\n if (!this.env.light.radianceMap) {\r\n this.env.light.radianceMap = this.env.sky.radianceMap;\r\n }\r\n if (useSHFB && !this.env.light.irradianceSHFB) {\r\n this.env.light.irradianceSHFB = this.env.sky.irradianceSHFB;\r\n }\r\n if (!useSHFB && !this.env.light.irradianceSH) {\r\n this.env.light.irradianceSH = this.env.sky.irradianceSH;\r\n }\r\n }\r\n }\r\n /**\r\n * Returns the renderer class used to render the scene.\r\n *\r\n * Override in subclasses to supply a custom renderer.\r\n *\r\n * @internal\r\n */\r\n getRenderer() {\r\n return SceneRenderer;\r\n }\r\n /**\r\n * Performs per-frame scene updates, once per device frame.\r\n *\r\n * Steps:\r\n * - Ensure this runs only once per frame (via `frameInfo.frameCounter`).\r\n * - Update environment light synchronization.\r\n * - Dispatch `update` event.\r\n * - Drain the one-shot node update queue and call `node.update(...)`.\r\n * - Apply pending octree placement updates.\r\n *\r\n */\r\n frameUpdate() {\r\n const frameInfo = getDevice().frameInfo;\r\n if (frameInfo.frameCounter !== this._updateFrame) {\r\n this._updateFrame = frameInfo.frameCounter;\r\n this.updateEnvLight();\r\n this.dispatchEvent('update', this);\r\n this.mainCamera?.updateController();\r\n if (this._nodeUpdateQueue.length > 0) {\r\n const elapsedInSeconds = frameInfo.elapsedOverall * 0.001;\r\n const deltaInSeconds = frameInfo.elapsedFrame * 0.001;\r\n const queue = this._nodeUpdateQueue;\r\n this._nodeUpdateQueue = [];\r\n while (queue.length > 0) {\r\n const ref = queue.shift()!;\r\n const node = ref.get();\r\n if (node?.attached) {\r\n node.update(frameInfo.frameCounter, elapsedInSeconds, deltaInSeconds);\r\n }\r\n ref.dispose();\r\n }\r\n }\r\n this.updateNodePlacement(this._octree, this._nodePlaceList);\r\n }\r\n }\r\n /**\r\n * Performs per-camera scene updates for the current frame.\r\n *\r\n * Steps:\r\n * - Drain the per-camera update queue and call `node.updatePerCamera(camera, ...)`.\r\n * - Apply pending octree placement updates.\r\n *\r\n * @param camera - The camera being updated for.\r\n */\r\n frameUpdatePerCamera(camera: Camera) {\r\n if (this._perCameraUpdateQueue.length > 0) {\r\n const frameInfo = getDevice().frameInfo;\r\n const elapsedInSeconds = frameInfo.elapsedOverall * 0.001;\r\n const deltaInSeconds = frameInfo.elapsedFrame * 0.001;\r\n const queue = this._perCameraUpdateQueue;\r\n this._perCameraUpdateQueue = [];\r\n while (queue.length > 0) {\r\n const ref = queue.shift()!;\r\n ref.get()?.updatePerCamera(camera, elapsedInSeconds, deltaInSeconds);\r\n ref.dispose();\r\n }\r\n }\r\n this.updateNodePlacement(this._octree, this._nodePlaceList);\r\n }\r\n /**\r\n * Applies placement changes for nodes in `list` to the given `octree`.\r\n *\r\n * Rules:\r\n * - If node is not disposed, attached, not hidden, and `placeToOctree` is true,\r\n * it is placed; otherwise removed.\r\n * - Drains `list` until empty.\r\n *\r\n * @param octree - Target spatial index.\r\n * @param list - Set of nodes awaiting placement evaluation.\r\n */\r\n updateNodePlacement(octree: Octree, list: Set<GraphNode>) {\r\n function placeNode(node: GraphNode) {\r\n if (!node.disposed && node.attached && !node.hidden && node.placeToOctree) {\r\n octree.placeNode(node);\r\n } else {\r\n octree.removeNode(node);\r\n }\r\n list.delete(node);\r\n }\r\n if (list.size > 0) {\r\n while (list.size > 0) {\r\n const node = list.keys().next().value!;\r\n if (octree) {\r\n placeNode(node);\r\n } else {\r\n list.delete(node);\r\n }\r\n }\r\n }\r\n }\r\n /**\r\n * Disposes the scene and its owned resources.\r\n *\r\n * Disposes:\r\n * - Environment\r\n * - Root node (and, by extension, its hierarchy)\r\n * - Main camera reference wrapper\r\n *\r\n */\r\n protected onDispose() {\r\n this._env.dispose();\r\n this._rootNode.dispose();\r\n this._mainCamera.dispose();\r\n }\r\n}\r\n"],"names":["Scene","makeObservable","Disposable","_nextId","name","_id","_name","_octree","Octree","_nodePlaceList","Set","_nodeUpdateQueue","_perCameraUpdateQueue","_env","Environment","_updateFrame","_rootNode","DRef","set","SceneNode","get","_metaData","_script","_mainCamera","id","val","mainCamera","camera","rootNode","octree","updateNodePlacement","boundingBox","getRootNode","getBoxLoosed","env","metaData","script","fileName","findNodeById","findNodeByName","raycast","ray","length","Infinity","raycastVisitor","RaycastVisitor","traverse","intersected","target","dist","intersectedDist","point","intersectedPoint","constructRay","viewportWidth","viewportHeight","screenX","screenY","invModelMatrix","vClip","Vector4","vWorld","invViewProjectionMatrix","transform","scaleBy","w","vEye","getWorldPosition","vDir","Vector3","sub","xyz","inplaceNormalize","transformPointAffine","transformVectorAffine","Ray","queueUpdateNode","node","findIndex","push","DWeakRef","queuePerCameraUpdateNode","render","invalidateNodePlacement","add","light","type","useSHFB","getDevice","getDeviceCaps","framebufferCaps","supportFloatBlending","radianceMap","sky","irradianceSHFB","irradianceSH","getRenderer","SceneRenderer","frameUpdate","frameInfo","frameCounter","updateEnvLight","dispatchEvent","updateController","elapsedInSeconds","elapsedOverall","deltaInSeconds","elapsedFrame","queue","ref","shift","attached","update","dispose","frameUpdatePerCamera","updatePerCamera","list","placeNode","disposed","hidden","placeToOctree","removeNode","delete","size","keys","next","value"],"mappings":"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"}
|
package/dist/scene/scene_node.js
CHANGED
|
@@ -101,16 +101,12 @@ import '../animation/skeleton.js';
|
|
|
101
101
|
this._pickable = false;
|
|
102
102
|
this._gpuPickable = true;
|
|
103
103
|
this._placeToOctree = true;
|
|
104
|
-
this._parent = null;
|
|
105
104
|
this._sealed = false;
|
|
106
105
|
this._children = [];
|
|
107
106
|
this._transformChangeCallback = ()=>this._onTransformChanged(true);
|
|
108
|
-
this._position = new ObservableVector3(0, 0, 0);
|
|
109
|
-
this.
|
|
110
|
-
this.
|
|
111
|
-
this._scaling.callback = this._transformChangeCallback;
|
|
112
|
-
this._rotation = new ObservableQuaternion();
|
|
113
|
-
this._rotation.callback = this._transformChangeCallback;
|
|
107
|
+
this._position = new ObservableVector3(0, 0, 0).setCallback(this._transformChangeCallback);
|
|
108
|
+
this._scaling = new ObservableVector3(1, 1, 1).setCallback(this._transformChangeCallback);
|
|
109
|
+
this._rotation = new ObservableQuaternion().setCallback(this._transformChangeCallback);
|
|
114
110
|
this._worldMatrix = null;
|
|
115
111
|
this._worldMatrixDet = null;
|
|
116
112
|
this._invWorldMatrix = null;
|
|
@@ -121,9 +117,8 @@ import '../animation/skeleton.js';
|
|
|
121
117
|
this._tmpWorldMatrix = Matrix4x4.identity();
|
|
122
118
|
this._script = '';
|
|
123
119
|
this._metaData = null;
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
}
|
|
120
|
+
this._parent = null;
|
|
121
|
+
this.reparent(scene?.rootNode ?? null);
|
|
127
122
|
}
|
|
128
123
|
/**
|
|
129
124
|
* Whether the node should be inserted into the scene's spatial structure.
|
|
@@ -243,6 +238,9 @@ import '../animation/skeleton.js';
|
|
|
243
238
|
/**
|
|
244
239
|
* Whether this node is currently attached under the scene's root.
|
|
245
240
|
*/ get attached() {
|
|
241
|
+
if (!this._scene) {
|
|
242
|
+
return false;
|
|
243
|
+
}
|
|
246
244
|
let node = this;
|
|
247
245
|
while(node && node !== this._scene.rootNode){
|
|
248
246
|
node = node.parent;
|
|
@@ -266,7 +264,7 @@ import '../animation/skeleton.js';
|
|
|
266
264
|
*/ get animationSet() {
|
|
267
265
|
if (!this._animationSet.get()) {
|
|
268
266
|
this._animationSet.set(new AnimationSet(this));
|
|
269
|
-
this.scene
|
|
267
|
+
this.scene?.queueUpdateNode(this);
|
|
270
268
|
}
|
|
271
269
|
return this._animationSet.get();
|
|
272
270
|
}
|
|
@@ -290,7 +288,7 @@ import '../animation/skeleton.js';
|
|
|
290
288
|
* @returns New node instance
|
|
291
289
|
*/ async clone() {
|
|
292
290
|
this.iterate((node)=>{
|
|
293
|
-
if (node.
|
|
291
|
+
if (node.isClipmapTerrain()) {
|
|
294
292
|
throw new Error('Cloning terrain node is not allowed');
|
|
295
293
|
}
|
|
296
294
|
});
|
|
@@ -399,6 +397,9 @@ import '../animation/skeleton.js';
|
|
|
399
397
|
/** Type guard: true if this node is a mesh. */ isMesh() {
|
|
400
398
|
return false;
|
|
401
399
|
}
|
|
400
|
+
/** Type guard: true if this node is a sprite */ isSprite() {
|
|
401
|
+
return false;
|
|
402
|
+
}
|
|
402
403
|
/** Type guard: true if this node is a water node. */ isWater() {
|
|
403
404
|
return false;
|
|
404
405
|
}
|
|
@@ -408,9 +409,6 @@ import '../animation/skeleton.js';
|
|
|
408
409
|
/** Type guard: true if this node is a batch group. */ isBatchGroup() {
|
|
409
410
|
return false;
|
|
410
411
|
}
|
|
411
|
-
/** Type guard: true if this node is a terrain. */ isTerrain() {
|
|
412
|
-
return false;
|
|
413
|
-
}
|
|
414
412
|
/** Type guard: true if this node is a clipmap terrain. */ isClipmapTerrain() {
|
|
415
413
|
return false;
|
|
416
414
|
}
|
|
@@ -551,9 +549,10 @@ import '../animation/skeleton.js';
|
|
|
551
549
|
const prefabNode = this.getPrefabNode() ?? this;
|
|
552
550
|
let sk = null;
|
|
553
551
|
prefabNode.iterate((node)=>{
|
|
554
|
-
sk = node.animationSet.skeletons.find((s)=>s.get().persistentId === id);
|
|
552
|
+
sk = node.animationSet.skeletons.find((s)=>s.get().persistentId === id) ?? null;
|
|
555
553
|
return !!sk;
|
|
556
554
|
});
|
|
555
|
+
// avoid ts2339 compilation error (maybe a typescript bug?)
|
|
557
556
|
return sk?.get() ?? null;
|
|
558
557
|
}
|
|
559
558
|
/**
|
|
@@ -599,10 +598,8 @@ import '../animation/skeleton.js';
|
|
|
599
598
|
super.onDispose();
|
|
600
599
|
this.remove();
|
|
601
600
|
this.removeChildren();
|
|
602
|
-
this._animationSet
|
|
603
|
-
this.
|
|
604
|
-
this._sharedModel?.dispose();
|
|
605
|
-
this._sharedModel = null;
|
|
601
|
+
this._animationSet.dispose();
|
|
602
|
+
this._sharedModel.dispose();
|
|
606
603
|
}
|
|
607
604
|
/** @internal */ _setParent(p) {
|
|
608
605
|
if (p && p._scene !== this._scene) {
|
|
@@ -686,7 +683,6 @@ import '../animation/skeleton.js';
|
|
|
686
683
|
return this._parent;
|
|
687
684
|
}
|
|
688
685
|
set parent(p) {
|
|
689
|
-
p = p || null;
|
|
690
686
|
if (p !== this._parent) {
|
|
691
687
|
this._setParent(p);
|
|
692
688
|
}
|
|
@@ -777,24 +773,13 @@ import '../animation/skeleton.js';
|
|
|
777
773
|
matrix.decompose(this._scaling, this._rotation, this._position);
|
|
778
774
|
this._disableCallback = false;
|
|
779
775
|
this._onTransformChanged(true);
|
|
780
|
-
|
|
781
|
-
this._localMatrix = matrix;
|
|
782
|
-
this._disableCallback = true;
|
|
783
|
-
this._localMatrix.decompose(this._scaling, this._rotation, this._position);
|
|
784
|
-
this._disableCallback = false;
|
|
785
|
-
this._onTransformChanged(false);
|
|
786
|
-
*/ return this;
|
|
776
|
+
return this;
|
|
787
777
|
}
|
|
788
778
|
/** Local transformation matrix of the xform */ get localMatrix() {
|
|
789
779
|
if (!this._localMatrix) {
|
|
790
780
|
this.calculateLocalTransform(this._tmpLocalMatrix);
|
|
791
781
|
this._localMatrix = this._tmpLocalMatrix;
|
|
792
|
-
|
|
793
|
-
this._localMatrix
|
|
794
|
-
.scaling(this._scaling)
|
|
795
|
-
.rotateLeft(new Matrix4x4(this._rotation))
|
|
796
|
-
.translateLeft(this._position);
|
|
797
|
-
*/ }
|
|
782
|
+
}
|
|
798
783
|
return this._localMatrix;
|
|
799
784
|
}
|
|
800
785
|
set localMatrix(matrix) {
|
|
@@ -875,7 +860,7 @@ import '../animation/skeleton.js';
|
|
|
875
860
|
* @param p - The new parent node that this node should be added to or null
|
|
876
861
|
* @returns self
|
|
877
862
|
*/ reparent(p) {
|
|
878
|
-
this.parent = p;
|
|
863
|
+
this.parent = p ?? null;
|
|
879
864
|
return this;
|
|
880
865
|
}
|
|
881
866
|
/** @internal */ get transformTag() {
|