@zephyr3d/scene 0.9.25 → 0.9.26
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/hair/gpu_hair_simulation.js +1090 -0
- package/dist/animation/hair/gpu_hair_simulation.js.map +1 -0
- package/dist/animation/joint_dynamics/controller.js +7 -5
- package/dist/animation/joint_dynamics/controller.js.map +1 -1
- package/dist/animation/joint_dynamics/joint_dynamics_system.js +81 -5
- package/dist/animation/joint_dynamics/joint_dynamics_system.js.map +1 -1
- package/dist/animation/morphtrack.js +3 -4
- package/dist/animation/morphtrack.js.map +1 -1
- package/dist/animation/skeleton.js +58 -24
- package/dist/animation/skeleton.js.map +1 -1
- package/dist/animation/spring/multi_chain_spring_system.js +577 -179
- package/dist/animation/spring/multi_chain_spring_system.js.map +1 -1
- package/dist/animation/spring/spring_collider.js +4 -3
- package/dist/animation/spring/spring_collider.js.map +1 -1
- package/dist/animation/spring/spring_node_pose_tracker.js +40 -0
- package/dist/animation/spring/spring_node_pose_tracker.js.map +1 -0
- package/dist/animation/spring/spring_particle.js +2 -0
- package/dist/animation/spring/spring_particle.js.map +1 -1
- package/dist/animation/spring/spring_system.js +11 -3
- package/dist/animation/spring/spring_system.js.map +1 -1
- package/dist/animation/spring_modifier.js +10 -0
- package/dist/animation/spring_modifier.js.map +1 -1
- package/dist/app/engine.js +53 -43
- package/dist/app/engine.js.map +1 -1
- package/dist/app/scriptingsystem.js +119 -6
- package/dist/app/scriptingsystem.js.map +1 -1
- package/dist/app/scriptregistry.js +3 -2
- package/dist/app/scriptregistry.js.map +1 -1
- package/dist/asset/assetmanager.js +284 -67
- package/dist/asset/assetmanager.js.map +1 -1
- package/dist/asset/loaders/zhair/zhair_format.js +288 -0
- package/dist/asset/loaders/zhair/zhair_format.js.map +1 -0
- package/dist/asset/loaders/zhair/zhair_loader.js +221 -0
- package/dist/asset/loaders/zhair/zhair_loader.js.map +1 -0
- package/dist/asset/model.js +178 -67
- package/dist/asset/model.js.map +1 -1
- package/dist/camera/camera.js +193 -21
- package/dist/camera/camera.js.map +1 -1
- package/dist/camera/perspectivecamera.js +3 -1
- package/dist/camera/perspectivecamera.js.map +1 -1
- package/dist/index.d.ts +4019 -1278
- package/dist/index.js +15 -5
- package/dist/index.js.map +1 -1
- package/dist/material/eye.js +932 -0
- package/dist/material/eye.js.map +1 -0
- package/dist/material/hair.js +917 -0
- package/dist/material/hair.js.map +1 -0
- package/dist/material/hairstrand.js +842 -0
- package/dist/material/hairstrand.js.map +1 -0
- package/dist/material/hairstrand_data.js +162 -0
- package/dist/material/hairstrand_data.js.map +1 -0
- package/dist/material/lambert.js +5 -2
- package/dist/material/lambert.js.map +1 -1
- package/dist/material/material.js +338 -300
- package/dist/material/material.js.map +1 -1
- package/dist/material/meshmaterial.js +120 -19
- package/dist/material/meshmaterial.js.map +1 -1
- package/dist/material/mixins/albedocolor.js +1 -1
- package/dist/material/mixins/albedocolor.js.map +1 -1
- package/dist/material/mixins/lightmodel/blinnphong.js +5 -3
- package/dist/material/mixins/lightmodel/blinnphong.js.map +1 -1
- package/dist/material/mixins/lightmodel/lambert.js +5 -4
- package/dist/material/mixins/lightmodel/lambert.js.map +1 -1
- package/dist/material/mixins/lightmodel/pbrblueprintmixin.js +3 -3
- package/dist/material/mixins/lightmodel/pbrblueprintmixin.js.map +1 -1
- package/dist/material/mixins/lightmodel/pbrmetallicroughness.js +5 -5
- package/dist/material/mixins/lightmodel/pbrmetallicroughness.js.map +1 -1
- package/dist/material/mixins/lightmodel/pbrspecularglossness.js +3 -3
- package/dist/material/mixins/lightmodel/pbrspecularglossness.js.map +1 -1
- package/dist/material/mixins/lit.js +73 -18
- package/dist/material/mixins/lit.js.map +1 -1
- package/dist/material/mixins/pbr/common.js +4 -4
- package/dist/material/mixins/pbr/common.js.map +1 -1
- package/dist/material/mixins/texture.js +48 -11
- package/dist/material/mixins/texture.js.map +1 -1
- package/dist/material/mtoon.js +6 -5
- package/dist/material/mtoon.js.map +1 -1
- package/dist/material/pbrblueprint.js +146 -28
- package/dist/material/pbrblueprint.js.map +1 -1
- package/dist/material/pbrblueprint_instance.js +501 -0
- package/dist/material/pbrblueprint_instance.js.map +1 -0
- package/dist/material/pbrmr.js +15 -16
- package/dist/material/pbrmr.js.map +1 -1
- package/dist/material/shader/helper.js +330 -20
- package/dist/material/shader/helper.js.map +1 -1
- package/dist/material/shader/terrain_blend.js +55 -0
- package/dist/material/shader/terrain_blend.js.map +1 -0
- package/dist/material/skin.js +192 -32
- package/dist/material/skin.js.map +1 -1
- package/dist/material/spriteblueprint.js +16 -1
- package/dist/material/spriteblueprint.js.map +1 -1
- package/dist/material/subsurfaceprofile.js +86 -23
- package/dist/material/subsurfaceprofile.js.map +1 -1
- package/dist/material/water.js +3 -1
- package/dist/material/water.js.map +1 -1
- package/dist/posteffect/bloom.js +167 -7
- package/dist/posteffect/bloom.js.map +1 -1
- package/dist/posteffect/coloradjust.js +2 -1
- package/dist/posteffect/coloradjust.js.map +1 -1
- package/dist/posteffect/compositor.js.map +1 -1
- package/dist/posteffect/fxaa.js +2 -1
- package/dist/posteffect/fxaa.js.map +1 -1
- package/dist/posteffect/grayscale.js +3 -1
- package/dist/posteffect/grayscale.js.map +1 -1
- package/dist/posteffect/motionblur.js +4 -1
- package/dist/posteffect/motionblur.js.map +1 -1
- package/dist/posteffect/posteffect.js.map +1 -1
- package/dist/posteffect/skinsss.js +368 -69
- package/dist/posteffect/skinsss.js.map +1 -1
- package/dist/posteffect/ssgi.js +16 -9
- package/dist/posteffect/ssgi.js.map +1 -1
- package/dist/posteffect/ssr.js +3 -0
- package/dist/posteffect/ssr.js.map +1 -1
- package/dist/posteffect/sss.js +91 -34
- package/dist/posteffect/sss.js.map +1 -1
- package/dist/posteffect/taa.js.map +1 -1
- package/dist/posteffect/tonemap.js +44 -1
- package/dist/posteffect/tonemap.js.map +1 -1
- package/dist/render/abuffer_oit.js +45 -39
- package/dist/render/abuffer_oit.js.map +1 -1
- package/dist/render/cull_visitor.js +19 -0
- package/dist/render/cull_visitor.js.map +1 -1
- package/dist/render/depthpass.js +36 -2
- package/dist/render/depthpass.js.map +1 -1
- package/dist/render/drawable_mixin.js +26 -1
- package/dist/render/drawable_mixin.js.map +1 -1
- package/dist/render/dualdepthpeeling_oit.js +52 -51
- package/dist/render/dualdepthpeeling_oit.js.map +1 -1
- package/dist/render/envlight.js +1 -1
- package/dist/render/envlight.js.map +1 -1
- package/dist/render/fbm_wavegenerator.js +3 -0
- package/dist/render/fbm_wavegenerator.js.map +1 -1
- package/dist/render/gerstner_wavegenerator.js +3 -0
- package/dist/render/gerstner_wavegenerator.js.map +1 -1
- package/dist/render/globalbindgroup_allocator.js +3 -0
- package/dist/render/globalbindgroup_allocator.js.map +1 -1
- package/dist/render/oit.js +29 -0
- package/dist/render/oit.js.map +1 -0
- package/dist/render/render_queue.js +3 -0
- package/dist/render/render_queue.js.map +1 -1
- package/dist/render/rendergraph/device_pool_allocator.js.map +1 -1
- package/dist/render/rendergraph/executor.js +2 -0
- package/dist/render/rendergraph/executor.js.map +1 -1
- package/dist/render/rendergraph/forward_plus_builder.js +61 -1
- package/dist/render/rendergraph/forward_plus_builder.js.map +1 -1
- package/dist/render/rendergraph/rendergraph.js.map +1 -1
- package/dist/render/rendergraph/texture_affinity_cache.js +1 -1
- package/dist/render/rendergraph/texture_affinity_cache.js.map +1 -1
- package/dist/render/rendergraph/types.js.map +1 -1
- package/dist/render/shadow_mask_pass.js +73 -8
- package/dist/render/shadow_mask_pass.js.map +1 -1
- package/dist/render/sky.js +166 -126
- package/dist/render/sky.js.map +1 -1
- package/dist/render/weightedblended_oit.js +36 -35
- package/dist/render/weightedblended_oit.js.map +1 -1
- package/dist/scene/basesprite.js +8 -0
- package/dist/scene/basesprite.js.map +1 -1
- package/dist/scene/batchgroup.js +3 -0
- package/dist/scene/batchgroup.js.map +1 -1
- package/dist/scene/environment.js +4 -1
- package/dist/scene/environment.js.map +1 -1
- package/dist/scene/hair.js +963 -0
- package/dist/scene/hair.js.map +1 -0
- package/dist/scene/light.js +5 -1
- package/dist/scene/light.js.map +1 -1
- package/dist/scene/mesh.js +481 -47
- package/dist/scene/mesh.js.map +1 -1
- package/dist/scene/meshdrawable.js +6 -0
- package/dist/scene/meshdrawable.js.map +1 -1
- package/dist/scene/msdftext.js +3 -0
- package/dist/scene/msdftext.js.map +1 -1
- package/dist/scene/msdftextsprite.js +3 -0
- package/dist/scene/msdftextsprite.js.map +1 -1
- package/dist/scene/particlesys.js +6 -0
- package/dist/scene/particlesys.js.map +1 -1
- package/dist/scene/scene.js +3 -0
- package/dist/scene/scene.js.map +1 -1
- package/dist/scene/scene_node.js +6 -1
- package/dist/scene/scene_node.js.map +1 -1
- package/dist/scene/terrain-cm/grass.js +3 -0
- package/dist/scene/terrain-cm/grass.js.map +1 -1
- package/dist/scene/terrain-cm/grassmaterial.js +3 -0
- package/dist/scene/terrain-cm/grassmaterial.js.map +1 -1
- package/dist/scene/terrain-cm/terrain-cm.js +6 -0
- package/dist/scene/terrain-cm/terrain-cm.js.map +1 -1
- package/dist/scene/terrain-cm/texture_cache.js +309 -0
- package/dist/scene/terrain-cm/texture_cache.js.map +1 -0
- package/dist/scene/water.js +6 -0
- package/dist/scene/water.js.map +1 -1
- package/dist/shaders/atmosphere.js.map +1 -1
- package/dist/shaders/diffusion.js +54 -0
- package/dist/shaders/diffusion.js.map +1 -0
- package/dist/shaders/shadow.js +33 -21
- package/dist/shaders/shadow.js.map +1 -1
- package/dist/shaders/temporal.js +71 -33
- package/dist/shaders/temporal.js.map +1 -1
- package/dist/shadow/dom.js +546 -0
- package/dist/shadow/dom.js.map +1 -0
- package/dist/shadow/pcf_opt.js +3 -5
- package/dist/shadow/pcf_opt.js.map +1 -1
- package/dist/shadow/pcf_pd.js +1 -1
- package/dist/shadow/pcf_pd.js.map +1 -1
- package/dist/shadow/receiver_bias.js +41 -0
- package/dist/shadow/receiver_bias.js.map +1 -0
- package/dist/shadow/shader.js +20 -60
- package/dist/shadow/shader.js.map +1 -1
- package/dist/shadow/shadow_impl.js +89 -0
- package/dist/shadow/shadow_impl.js.map +1 -1
- package/dist/shadow/shadow_region.js +50 -50
- package/dist/shadow/shadow_region.js.map +1 -1
- package/dist/shadow/shadowmapper.js +150 -37
- package/dist/shadow/shadowmapper.js.map +1 -1
- package/dist/shapes/shape.js +11 -2
- package/dist/shapes/shape.js.map +1 -1
- package/dist/shapes/sphere.js +50 -9
- package/dist/shapes/sphere.js.map +1 -1
- package/dist/utility/blueprint/common/constants.js +112 -2
- package/dist/utility/blueprint/common/constants.js.map +1 -1
- package/dist/utility/blueprint/material/func.js +142 -49
- package/dist/utility/blueprint/material/func.js.map +1 -1
- package/dist/utility/blueprint/material/ir.js +490 -25
- package/dist/utility/blueprint/material/ir.js.map +1 -1
- package/dist/utility/blueprint/material/texture.js +898 -4
- package/dist/utility/blueprint/material/texture.js.map +1 -1
- package/dist/utility/serialization/manager.js +431 -100
- package/dist/utility/serialization/manager.js.map +1 -1
- package/dist/utility/serialization/scene/animation.js +370 -3
- package/dist/utility/serialization/scene/animation.js.map +1 -1
- package/dist/utility/serialization/scene/batch.js +4 -0
- package/dist/utility/serialization/scene/batch.js.map +1 -1
- package/dist/utility/serialization/scene/camera.js +133 -1
- package/dist/utility/serialization/scene/camera.js.map +1 -1
- package/dist/utility/serialization/scene/common.js +26 -5
- package/dist/utility/serialization/scene/common.js.map +1 -1
- package/dist/utility/serialization/scene/hair.js +1141 -0
- package/dist/utility/serialization/scene/hair.js.map +1 -0
- package/dist/utility/serialization/scene/light.js +84 -4
- package/dist/utility/serialization/scene/light.js.map +1 -1
- package/dist/utility/serialization/scene/material.js +1867 -166
- package/dist/utility/serialization/scene/material.js.map +1 -1
- package/dist/utility/serialization/scene/mesh.js +231 -14
- package/dist/utility/serialization/scene/mesh.js.map +1 -1
- package/dist/utility/serialization/scene/node.js +141 -7
- package/dist/utility/serialization/scene/node.js.map +1 -1
- package/dist/utility/serialization/scene/particle.js +4 -0
- package/dist/utility/serialization/scene/particle.js.map +1 -1
- package/dist/utility/serialization/scene/primitive.js +18 -0
- package/dist/utility/serialization/scene/primitive.js.map +1 -1
- package/dist/utility/serialization/scene/sprite.js +4 -0
- package/dist/utility/serialization/scene/sprite.js.map +1 -1
- package/dist/utility/serialization/scene/terrain.js +4 -0
- package/dist/utility/serialization/scene/terrain.js.map +1 -1
- package/dist/utility/serialization/scene/text.js +4 -0
- package/dist/utility/serialization/scene/text.js.map +1 -1
- package/dist/utility/serialization/scene/water.js +4 -0
- package/dist/utility/serialization/scene/water.js.map +1 -1
- package/dist/utility/serialization/types.js.map +1 -1
- package/dist/utility/shprojector.js +96 -95
- package/dist/utility/shprojector.js.map +1 -1
- package/dist/values.js +49 -2
- package/dist/values.js.map +1 -1
- package/package.json +3 -3
package/dist/scene/scene.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
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 type { Drawable } 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\nimport {\r\n normalizeScriptAttachmentConfig,\r\n normalizeScriptAttachments,\r\n ScriptAttachment\r\n} from './script_attachment';\r\nimport type { LightingMode } from '../utility/physical';\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 */\r\n protected _drawableUpdateQueue: Drawable[];\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 Lighting unit model used by this scene. */\r\n protected _lightingMode: LightingMode;\r\n /** @internal Number of physical meters represented by one scene unit. */\r\n protected _metersPerUnit: number;\r\n /** @internal User-attached script entries (engine-defined). */\r\n private _scripts: ScriptAttachment[];\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._drawableUpdateQueue = [];\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._lightingMode = 'legacy';\r\n this._metersPerUnit = 1;\r\n this._scripts = [];\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 /** Lighting unit model. Legacy remains the default for backward compatibility. */\r\n get lightingMode() {\r\n return this._lightingMode;\r\n }\r\n set lightingMode(val: LightingMode) {\r\n const mode: LightingMode = val === 'physical' ? 'physical' : 'legacy';\r\n if (mode !== this._lightingMode) {\r\n this._lightingMode = mode;\r\n this.invalidateLightUniforms();\r\n }\r\n }\r\n /** Number of physical meters represented by one scene-space unit. */\r\n get metersPerUnit() {\r\n return this._metersPerUnit;\r\n }\r\n set metersPerUnit(val: number) {\r\n const scale = Number.isFinite(val) ? Math.max(val, 0.000001) : 1;\r\n if (scale !== this._metersPerUnit) {\r\n this._metersPerUnit = scale;\r\n this.invalidateLightUniforms();\r\n }\r\n }\r\n /** @internal */\r\n private invalidateLightUniforms() {\r\n this._rootNode.get()?.iterate((node) => {\r\n if (node.isLight()) {\r\n node.invalidateUniforms();\r\n }\r\n });\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._scripts[0]?.script ?? '';\r\n }\r\n set script(fileName: string) {\r\n const script = fileName ?? '';\r\n if (!script) {\r\n this._scripts.splice(0, 1);\r\n } else if (this._scripts[0]) {\r\n this._scripts[0].script = script;\r\n } else {\r\n this._scripts.unshift(new ScriptAttachment(script));\r\n }\r\n }\r\n /**\r\n * Script component configuration payload used by editor/runtime script components.\r\n */\r\n get scriptConfig() {\r\n return this._scripts[0]?.config ?? null;\r\n }\r\n set scriptConfig(value: Nullable<object | unknown[]>) {\r\n const normalized = normalizeScriptAttachmentConfig(value);\r\n if (this._scripts[0]) {\r\n this._scripts[0].config = normalized;\r\n } else if (normalized != null) {\r\n this._scripts.unshift(new ScriptAttachment('', normalized));\r\n }\r\n if (this._scripts[0] && !this._scripts[0].script && this._scripts[0].config == null) {\r\n this._scripts.splice(0, 1);\r\n }\r\n }\r\n /**\r\n * All script attachments on this scene.\r\n */\r\n get scripts() {\r\n return this._scripts;\r\n }\r\n set scripts(value: ScriptAttachment[]) {\r\n this._scripts = normalizeScriptAttachments(value);\r\n }\r\n /**\r\n * Script configs for all script attachments.\r\n */\r\n get scriptConfigs() {\r\n return this._scripts.map((item) => item.config);\r\n }\r\n set scriptConfigs(value: unknown[]) {\r\n const next = Array.isArray(value) ? value : [];\r\n for (let i = 0; i < Math.max(this._scripts.length, next.length); i++) {\r\n const config = normalizeScriptAttachmentConfig(next[i]);\r\n if (this._scripts[i]) {\r\n this._scripts[i].config = config;\r\n } else if (config != null) {\r\n this._scripts.push(new ScriptAttachment('', config));\r\n }\r\n }\r\n this._scripts = this._scripts.filter((item) => item.script || item.config != null);\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 drawable for a one-shot state update before the next render.\r\n *\r\n * The drawable's `updateState()` will be called during Scene.frameUpdate and then the drawable is removed from the queue.\r\n * @param drawable - Drawable to schedule.\r\n *\r\n * @remarks\r\n * - To update continuously each frame, call `queueUpdateDrawable(this)` from within the drawable's `updateState` method.\r\n * - Duplicate scheduling within the same frame is prevented.\r\n */\r\n queueUpdateDrawable(drawable: Drawable) {\r\n if (drawable && this._drawableUpdateQueue.indexOf(drawable) < 0) {\r\n this._drawableUpdateQueue.push(drawable);\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 this.env.light.radianceMap = this.env.sky.radianceMap;\r\n this.env.light.sheenRadianceMap = this.env.sky.sheenRadianceMap;\r\n this.env.light.irradianceWindow = this.env.sky.shWindowWeights;\r\n this.env.light.irradianceSHFB = this.env.sky.irradianceSHFB;\r\n this.env.light.irradianceSH = null;\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 if (this._drawableUpdateQueue.length > 0) {\r\n for (const drawable of this._drawableUpdateQueue) {\r\n drawable.updateState();\r\n }\r\n this._drawableUpdateQueue = [];\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","_drawableUpdateQueue","_perCameraUpdateQueue","_env","Environment","_updateFrame","_rootNode","DRef","set","SceneNode","get","_metaData","_lightingMode","_metersPerUnit","_scripts","_mainCamera","id","val","mainCamera","camera","rootNode","octree","updateNodePlacement","boundingBox","getRootNode","getBoxLoosed","env","lightingMode","mode","invalidateLightUniforms","metersPerUnit","scale","Number","isFinite","Math","max","iterate","node","isLight","invalidateUniforms","metaData","script","fileName","splice","unshift","ScriptAttachment","scriptConfig","config","value","normalized","normalizeScriptAttachmentConfig","scripts","normalizeScriptAttachments","scriptConfigs","map","item","next","Array","isArray","i","length","push","filter","findNodeById","findNodeByName","raycast","ray","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","findIndex","DWeakRef","queueUpdateDrawable","drawable","indexOf","queuePerCameraUpdateNode","render","invalidateNodePlacement","add","light","type","radianceMap","sky","sheenRadianceMap","irradianceWindow","shWindowWeights","irradianceSHFB","irradianceSH","getRenderer","SceneRenderer","frameUpdate","frameInfo","getDevice","frameCounter","updateEnvLight","dispatchEvent","updateController","elapsedInSeconds","elapsedOverall","deltaInSeconds","elapsedFrame","queue","ref","shift","attached","update","dispose","updateState","frameUpdatePerCamera","updatePerCamera","list","placeNode","disposed","hidden","placeToOctree","removeNode","delete","size","keys"],"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 type { Drawable } 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\nimport {\r\n normalizeScriptAttachmentConfig,\r\n normalizeScriptAttachments,\r\n ScriptAttachment\r\n} from './script_attachment';\r\nimport type { LightingMode } from '../utility/physical';\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 */\r\n protected _drawableUpdateQueue: Drawable[];\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 Lighting unit model used by this scene. */\r\n protected _lightingMode: LightingMode;\r\n /** @internal Number of physical meters represented by one scene unit. */\r\n protected _metersPerUnit: number;\r\n /** @internal User-attached script entries (engine-defined). */\r\n private _scripts: ScriptAttachment[];\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._drawableUpdateQueue = [];\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._lightingMode = 'legacy';\r\n this._metersPerUnit = 1;\r\n this._scripts = [];\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 /** Lighting unit model. Legacy remains the default for backward compatibility. */\r\n get lightingMode() {\r\n return this._lightingMode;\r\n }\r\n set lightingMode(val: LightingMode) {\r\n const mode: LightingMode = val === 'physical' ? 'physical' : 'legacy';\r\n if (mode !== this._lightingMode) {\r\n this._lightingMode = mode;\r\n this.invalidateLightUniforms();\r\n }\r\n }\r\n /** Number of physical meters represented by one scene-space unit. */\r\n get metersPerUnit() {\r\n return this._metersPerUnit;\r\n }\r\n set metersPerUnit(val: number) {\r\n const scale = Number.isFinite(val) ? Math.max(val, 0.000001) : 1;\r\n if (scale !== this._metersPerUnit) {\r\n this._metersPerUnit = scale;\r\n this.invalidateLightUniforms();\r\n }\r\n }\r\n /** @internal */\r\n private invalidateLightUniforms() {\r\n this._rootNode.get()?.iterate((node) => {\r\n if (node.isLight()) {\r\n node.invalidateUniforms();\r\n }\r\n });\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._scripts[0]?.script ?? '';\r\n }\r\n set script(fileName: string) {\r\n const script = fileName ?? '';\r\n if (!script) {\r\n this._scripts.splice(0, 1);\r\n } else if (this._scripts[0]) {\r\n this._scripts[0].script = script;\r\n } else {\r\n this._scripts.unshift(new ScriptAttachment(script));\r\n }\r\n }\r\n /**\r\n * Script component configuration payload used by editor/runtime script components.\r\n */\r\n get scriptConfig() {\r\n return this._scripts[0]?.config ?? null;\r\n }\r\n set scriptConfig(value: Nullable<object | unknown[]>) {\r\n const normalized = normalizeScriptAttachmentConfig(value);\r\n if (this._scripts[0]) {\r\n this._scripts[0].config = normalized;\r\n } else if (normalized != null) {\r\n this._scripts.unshift(new ScriptAttachment('', normalized));\r\n }\r\n if (this._scripts[0] && !this._scripts[0].script && this._scripts[0].config == null) {\r\n this._scripts.splice(0, 1);\r\n }\r\n }\r\n /**\r\n * All script attachments on this scene.\r\n */\r\n get scripts() {\r\n return this._scripts;\r\n }\r\n set scripts(value: ScriptAttachment[]) {\r\n this._scripts = normalizeScriptAttachments(value);\r\n }\r\n /**\r\n * Script configs for all script attachments.\r\n */\r\n get scriptConfigs() {\r\n return this._scripts.map((item) => item.config);\r\n }\r\n set scriptConfigs(value: unknown[]) {\r\n const next = Array.isArray(value) ? value : [];\r\n for (let i = 0; i < Math.max(this._scripts.length, next.length); i++) {\r\n const config = normalizeScriptAttachmentConfig(next[i]);\r\n if (this._scripts[i]) {\r\n this._scripts[i].config = config;\r\n } else if (config != null) {\r\n this._scripts.push(new ScriptAttachment('', config));\r\n }\r\n }\r\n this._scripts = this._scripts.filter((item) => item.script || item.config != null);\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 drawable for a one-shot state update before the next render.\r\n *\r\n * The drawable's `updateState()` will be called during Scene.frameUpdate and then the drawable is removed from the queue.\r\n * @param drawable - Drawable to schedule.\r\n *\r\n * @remarks\r\n * - To update continuously each frame, call `queueUpdateDrawable(this)` from within the drawable's `updateState` method.\r\n * - Duplicate scheduling within the same frame is prevented.\r\n */\r\n queueUpdateDrawable(drawable: Drawable) {\r\n if (drawable && this._drawableUpdateQueue.indexOf(drawable) < 0) {\r\n this._drawableUpdateQueue.push(drawable);\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 this.env.light.radianceMap = this.env.sky.radianceMap;\r\n this.env.light.sheenRadianceMap = this.env.sky.sheenRadianceMap;\r\n this.env.light.irradianceWindow = this.env.sky.shWindowWeights;\r\n this.env.light.irradianceSHFB = this.env.sky.irradianceSHFB;\r\n this.env.light.irradianceSH = null;\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 if (this._drawableUpdateQueue.length > 0) {\r\n for (const drawable of this._drawableUpdateQueue) {\r\n drawable.updateState();\r\n }\r\n this._drawableUpdateQueue = [];\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","_drawableUpdateQueue","_perCameraUpdateQueue","_env","Environment","_updateFrame","_rootNode","DRef","set","SceneNode","get","_metaData","_lightingMode","_metersPerUnit","_scripts","_mainCamera","id","val","mainCamera","camera","rootNode","octree","updateNodePlacement","boundingBox","getRootNode","getBoxLoosed","env","lightingMode","mode","invalidateLightUniforms","metersPerUnit","scale","Number","isFinite","Math","max","iterate","node","isLight","invalidateUniforms","metaData","script","fileName","splice","unshift","ScriptAttachment","scriptConfig","config","value","normalized","normalizeScriptAttachmentConfig","scripts","normalizeScriptAttachments","scriptConfigs","map","item","next","Array","isArray","i","length","push","filter","findNodeById","findNodeByName","raycast","ray","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","findIndex","DWeakRef","queueUpdateDrawable","drawable","indexOf","queuePerCameraUpdateNode","render","invalidateNodePlacement","add","light","type","radianceMap","sky","sheenRadianceMap","irradianceWindow","shWindowWeights","irradianceSHFB","irradianceSH","getRenderer","SceneRenderer","frameUpdate","frameInfo","getDevice","frameCounter","updateEnvLight","dispatchEvent","updateController","elapsedInSeconds","elapsedOverall","deltaInSeconds","elapsedFrame","queue","ref","shift","attached","update","dispose","updateState","frameUpdatePerCamera","updatePerCamera","list","placeNode","disposed","hidden","placeToOctree","removeNode","delete","size","keys"],"mappings":"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"}
|
package/dist/scene/scene_node.js
CHANGED
|
@@ -470,6 +470,9 @@ const sceneMeshAssetBindings = new WeakMap();
|
|
|
470
470
|
/** Type guard: true if this node is a water node. */ isWater() {
|
|
471
471
|
return false;
|
|
472
472
|
}
|
|
473
|
+
/** Type guard: true if this node is a hair node. */ isHair() {
|
|
474
|
+
return false;
|
|
475
|
+
}
|
|
473
476
|
/** Type guard: true if this node is a particle system. */ isParticleSystem() {
|
|
474
477
|
return false;
|
|
475
478
|
}
|
|
@@ -899,7 +902,9 @@ const sceneMeshAssetBindings = new WeakMap();
|
|
|
899
902
|
if (invalidateLocal) {
|
|
900
903
|
this._localMatrix = null;
|
|
901
904
|
}
|
|
902
|
-
|
|
905
|
+
// A synchronized subtree is invalidated recursively below, so each node can
|
|
906
|
+
// update its own placement once instead of rescanning all descendants here.
|
|
907
|
+
this.invalidateWorldBoundingVolume(!this._worldMatrix);
|
|
903
908
|
this.dispatchEvent('transformchanged', this);
|
|
904
909
|
if (this._worldMatrix) {
|
|
905
910
|
this._transformTag++;
|