@zephyr3d/scene 0.9.3 → 0.9.5
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/animationmask.js +224 -0
- package/dist/animation/animationmask.js.map +1 -0
- package/dist/animation/animationset.js +268 -67
- package/dist/animation/animationset.js.map +1 -1
- package/dist/animation/animationtrack.js.map +1 -1
- package/dist/animation/eulerrotationtrack.js +3 -0
- package/dist/animation/eulerrotationtrack.js.map +1 -1
- package/dist/animation/fixed_geometry_cache_track.js +7 -0
- package/dist/animation/fixed_geometry_cache_track.js.map +1 -1
- package/dist/animation/ik_modifier.js.map +1 -1
- package/dist/animation/joint_dynamics/collision.js +6 -4
- package/dist/animation/joint_dynamics/collision.js.map +1 -1
- package/dist/animation/joint_dynamics/controller.js +390 -43
- package/dist/animation/joint_dynamics/controller.js.map +1 -1
- package/dist/animation/joint_dynamics/joint_dynamics_system.js +62 -3
- package/dist/animation/joint_dynamics/joint_dynamics_system.js.map +1 -1
- package/dist/animation/joint_dynamics/solver.js +4 -3
- package/dist/animation/joint_dynamics/solver.js.map +1 -1
- package/dist/animation/joint_dynamics/types.js.map +1 -1
- package/dist/animation/joint_dynamics_modifier.js +2 -0
- package/dist/animation/joint_dynamics_modifier.js.map +1 -1
- package/dist/animation/morphtarget.js +3 -72
- package/dist/animation/morphtarget.js.map +1 -1
- package/dist/animation/morphtrack.js +3 -0
- package/dist/animation/morphtrack.js.map +1 -1
- package/dist/animation/pca_geometry_cache_track.js +3 -0
- package/dist/animation/pca_geometry_cache_track.js.map +1 -1
- package/dist/animation/proptrack.js +3 -0
- package/dist/animation/proptrack.js.map +1 -1
- package/dist/animation/rotationtrack.js +3 -0
- package/dist/animation/rotationtrack.js.map +1 -1
- package/dist/animation/scaletrack.js +3 -0
- package/dist/animation/scaletrack.js.map +1 -1
- package/dist/animation/skeleton.js +254 -79
- package/dist/animation/skeleton.js.map +1 -1
- package/dist/animation/skeleton_modifier.js.map +1 -1
- package/dist/animation/spring/spring_particle.js +4 -4
- package/dist/animation/spring/spring_particle.js.map +1 -1
- package/dist/animation/spring_modifier.js.map +1 -1
- package/dist/animation/translationtrack.js +3 -0
- package/dist/animation/translationtrack.js.map +1 -1
- package/dist/app/engine.js +129 -17
- package/dist/app/engine.js.map +1 -1
- package/dist/app/scriptregistry.js +251 -80
- package/dist/app/scriptregistry.js.map +1 -1
- package/dist/asset/assetmanager.js +133 -102
- package/dist/asset/assetmanager.js.map +1 -1
- package/dist/asset/loaders/gltf/gltf_loader.js +18 -14
- package/dist/asset/loaders/gltf/gltf_loader.js.map +1 -1
- package/dist/asset/loaders/loader.js +1 -6
- package/dist/asset/loaders/loader.js.map +1 -1
- package/dist/asset/loaders/zabc/zabc_loader.js.map +1 -1
- package/dist/asset/model.js +1052 -183
- package/dist/asset/model.js.map +1 -1
- package/dist/avatar/wardrobe.js +474 -0
- package/dist/avatar/wardrobe.js.map +1 -0
- package/dist/index.d.ts +1810 -233
- package/dist/index.js +13 -3
- package/dist/index.js.map +1 -1
- package/dist/material/material.js +1 -1
- package/dist/material/material.js.map +1 -1
- package/dist/material/mixins/lightmodel/pbrmetallicroughness.js +6 -3
- package/dist/material/mixins/lightmodel/pbrmetallicroughness.js.map +1 -1
- package/dist/material/mixins/pbr/common.js +72 -15
- package/dist/material/mixins/pbr/common.js.map +1 -1
- package/dist/material/msdf_text.js +180 -0
- package/dist/material/msdf_text.js.map +1 -0
- package/dist/material/msdf_text_sprite.js +64 -0
- package/dist/material/msdf_text_sprite.js.map +1 -0
- package/dist/material/pbrblueprint.js +21 -6
- package/dist/material/pbrblueprint.js.map +1 -1
- package/dist/material/shader/helper.js +277 -277
- package/dist/material/shader/helper.js.map +1 -1
- package/dist/material/sprite_sdf.js +106 -0
- package/dist/material/sprite_sdf.js.map +1 -0
- package/dist/posteffect/ssr.js +1 -0
- package/dist/posteffect/ssr.js.map +1 -1
- package/dist/render/abuffer_oit.js +1 -0
- package/dist/render/abuffer_oit.js.map +1 -1
- package/dist/render/cluster_light.js.map +1 -1
- package/dist/render/cull_visitor.js +28 -0
- package/dist/render/cull_visitor.js.map +1 -1
- package/dist/render/drawable.js.map +1 -1
- package/dist/render/drawable_mixin.js +1 -0
- package/dist/render/drawable_mixin.js.map +1 -1
- package/dist/render/envlight.js +54 -1
- package/dist/render/envlight.js.map +1 -1
- package/dist/render/fbm_wavegenerator.js +1 -0
- package/dist/render/fbm_wavegenerator.js.map +1 -1
- package/dist/render/gerstner_wavegenerator.js +1 -0
- package/dist/render/gerstner_wavegenerator.js.map +1 -1
- package/dist/render/globalbindgroup_allocator.js +1 -0
- package/dist/render/globalbindgroup_allocator.js.map +1 -1
- package/dist/render/render_queue.js +1 -0
- package/dist/render/render_queue.js.map +1 -1
- package/dist/render/sky.js +9 -0
- package/dist/render/sky.js.map +1 -1
- package/dist/scene/basesprite.js +1 -5
- package/dist/scene/basesprite.js.map +1 -1
- package/dist/scene/batchgroup.js +18 -8
- package/dist/scene/batchgroup.js.map +1 -1
- package/dist/scene/environment.js +16 -2
- package/dist/scene/environment.js.map +1 -1
- package/dist/scene/mesh.js +164 -102
- package/dist/scene/mesh.js.map +1 -1
- package/dist/scene/meshdrawable.js +96 -0
- package/dist/scene/meshdrawable.js.map +1 -0
- package/dist/scene/msdftext.js +341 -0
- package/dist/scene/msdftext.js.map +1 -0
- package/dist/scene/msdftextsprite.js +349 -0
- package/dist/scene/msdftextsprite.js.map +1 -0
- package/dist/scene/particlesys.js +1 -0
- package/dist/scene/particlesys.js.map +1 -1
- package/dist/scene/scene.js +2 -0
- package/dist/scene/scene.js.map +1 -1
- package/dist/scene/scene_node.js +437 -230
- package/dist/scene/scene_node.js.map +1 -1
- package/dist/scene/sdftextsprite.js +322 -0
- package/dist/scene/sdftextsprite.js.map +1 -0
- package/dist/scene/terrain-cm/grass.js +1 -0
- package/dist/scene/terrain-cm/grass.js.map +1 -1
- package/dist/scene/terrain-cm/grassmaterial.js +1 -0
- package/dist/scene/terrain-cm/grassmaterial.js.map +1 -1
- package/dist/scene/terrain-cm/terrain-cm.js +1 -0
- package/dist/scene/terrain-cm/terrain-cm.js.map +1 -1
- package/dist/scene/textsprite.js +120 -0
- package/dist/scene/textsprite.js.map +1 -0
- package/dist/scene/water.js +1 -0
- package/dist/scene/water.js.map +1 -1
- package/dist/shadow/shader.js +1 -0
- package/dist/shadow/shader.js.map +1 -1
- package/dist/text/font/font_asset.js +884 -0
- package/dist/text/font/font_asset.js.map +1 -0
- package/dist/text/font/sfnt_reader.js +43 -0
- package/dist/text/font/sfnt_reader.js.map +1 -0
- package/dist/text/msdf/generator.js +417 -0
- package/dist/text/msdf/generator.js.map +1 -0
- package/dist/text/msdf/shape.js +146 -0
- package/dist/text/msdf/shape.js.map +1 -0
- package/dist/text/runtime/msdf_glyph_atlas.js +146 -0
- package/dist/text/runtime/msdf_glyph_atlas.js.map +1 -0
- package/dist/text/runtime/msdf_text_atlas_manager.js +50 -0
- package/dist/text/runtime/msdf_text_atlas_manager.js.map +1 -0
- package/dist/text/runtime/text_layout.js +96 -0
- package/dist/text/runtime/text_layout.js.map +1 -0
- package/dist/utility/blueprint/material/inputs.js +188 -1
- package/dist/utility/blueprint/material/inputs.js.map +1 -1
- package/dist/utility/blueprint/material/ir.js +16 -1
- package/dist/utility/blueprint/material/ir.js.map +1 -1
- package/dist/utility/blueprint/material/pbr.js +32 -0
- package/dist/utility/blueprint/material/pbr.js.map +1 -1
- package/dist/utility/bounding_volume.js.map +1 -1
- package/dist/utility/pmrem.js +34 -8
- package/dist/utility/pmrem.js.map +1 -1
- package/dist/utility/serialization/manager.js +340 -283
- package/dist/utility/serialization/manager.js.map +1 -1
- package/dist/utility/serialization/scene/animation.js +702 -7
- package/dist/utility/serialization/scene/animation.js.map +1 -1
- package/dist/utility/serialization/scene/batch.js +2 -0
- package/dist/utility/serialization/scene/batch.js.map +1 -1
- package/dist/utility/serialization/scene/camera.js +2 -0
- package/dist/utility/serialization/scene/camera.js.map +1 -1
- package/dist/utility/serialization/scene/light.js +2 -0
- package/dist/utility/serialization/scene/light.js.map +1 -1
- package/dist/utility/serialization/scene/material.js +1 -0
- package/dist/utility/serialization/scene/material.js.map +1 -1
- package/dist/utility/serialization/scene/mesh.js +66 -4
- package/dist/utility/serialization/scene/mesh.js.map +1 -1
- package/dist/utility/serialization/scene/node.js +189 -8
- package/dist/utility/serialization/scene/node.js.map +1 -1
- package/dist/utility/serialization/scene/particle.js +2 -0
- package/dist/utility/serialization/scene/particle.js.map +1 -1
- package/dist/utility/serialization/scene/primitive.js +1 -0
- package/dist/utility/serialization/scene/primitive.js.map +1 -1
- package/dist/utility/serialization/scene/sprite.js +2 -0
- package/dist/utility/serialization/scene/sprite.js.map +1 -1
- package/dist/utility/serialization/scene/terrain.js +2 -0
- package/dist/utility/serialization/scene/terrain.js.map +1 -1
- package/dist/utility/serialization/scene/text.js +516 -0
- package/dist/utility/serialization/scene/text.js.map +1 -0
- package/dist/utility/serialization/scene/water.js +2 -0
- package/dist/utility/serialization/scene/water.js.map +1 -1
- package/dist/utility/serialization/types.js.map +1 -1
- package/dist/utility/textures/sheenlut.js +138 -0
- package/dist/utility/textures/sheenlut.js.map +1 -0
- package/dist/values.js +48 -48
- package/dist/values.js.map +1 -1
- package/package.json +3 -3
package/dist/scene/scene_node.js
CHANGED
|
@@ -3,33 +3,40 @@ import { AnimationSet } from '../animation/animationset.js';
|
|
|
3
3
|
import { getEngine } from '../app/api.js';
|
|
4
4
|
import { ScriptAttachment, normalizeScriptAttachmentConfig, normalizeScriptAttachments } from './script_attachment.js';
|
|
5
5
|
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
* - `
|
|
21
|
-
* -
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
* -
|
|
25
|
-
*
|
|
26
|
-
*
|
|
6
|
+
const sceneMeshAssetBindings = new WeakMap();
|
|
7
|
+
/** @internal */ function setSceneMeshAssetBinding(mesh, binding) {
|
|
8
|
+
sceneMeshAssetBindings.set(mesh, binding);
|
|
9
|
+
}
|
|
10
|
+
/** @internal */ function getSceneMeshAssetBinding(mesh) {
|
|
11
|
+
return sceneMeshAssetBindings.get(mesh) ?? null;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* The base class of all scene graph objects.
|
|
15
|
+
*
|
|
16
|
+
* @remarks
|
|
17
|
+
* Responsibilities:
|
|
18
|
+
* - Defines hierarchical transform (position, rotation, scale) with lazily computed matrices.
|
|
19
|
+
* - Integrates with the scene graph (parent/children, attachment notifications).
|
|
20
|
+
* - Provides traversal utilities (`iterate`, `iterateBottomToTop`, `traverse`).
|
|
21
|
+
* - Manages visibility state and CPU/GPU picking flags.
|
|
22
|
+
* - Computes and caches local/world bounding volumes, notifies scene for spatial updates.
|
|
23
|
+
* - Supports cloning and shared model instancing.
|
|
24
|
+
* - Emits events on visibility, transform, bounding volume, attachment, and disposal.
|
|
25
|
+
*
|
|
26
|
+
* Performance:
|
|
27
|
+
* - `localMatrix`, `worldMatrix`, and `invWorldMatrix` are cached until invalidated.
|
|
28
|
+
* - Transform mutations and `invalidateBoundingVolume` update caches and spatial structures.
|
|
29
|
+
*
|
|
30
|
+
* Events:
|
|
31
|
+
* - `nodeattached`, `noderemoved`, `visiblechanged`, `transformchanged`, `bvchanged`, `dispose`.
|
|
32
|
+
*
|
|
33
|
+
* @public
|
|
27
34
|
*/ class SceneNode extends makeObservable(Disposable)() {
|
|
28
35
|
static _runTimeId = 1;
|
|
29
|
-
/*
|
|
30
|
-
static readonly PICK_INHERITED = -1;
|
|
31
|
-
static readonly PICK_DISABLED = 0;
|
|
32
|
-
static readonly PICK_ENABLED = 1;
|
|
36
|
+
/*
|
|
37
|
+
static readonly PICK_INHERITED = -1;
|
|
38
|
+
static readonly PICK_DISABLED = 0;
|
|
39
|
+
static readonly PICK_ENABLED = 1;
|
|
33
40
|
*/ /** Bounding-box draw mode inherited from nearest graph ancestor. */ static BBOXDRAW_INHERITED = -1;
|
|
34
41
|
/** Disable bounding-box visualization. */ static BBOXDRAW_DISABLED = 0;
|
|
35
42
|
/** Draw local-space bounding box. */ static BBOXDRAW_LOCAL = 1;
|
|
@@ -39,6 +46,7 @@ import { ScriptAttachment, normalizeScriptAttachmentConfig, normalizeScriptAttac
|
|
|
39
46
|
/** @internal Prefab id */ _prefabId;
|
|
40
47
|
/** @internal Animation set reference. */ _animationSet;
|
|
41
48
|
/** @internal Optional shared model reference for instancing. */ _sharedModel;
|
|
49
|
+
/** @internal Model-level morph target groups bound to runtime meshes. */ _morphTargetGroups;
|
|
42
50
|
/** @internal */ _jointTypeT;
|
|
43
51
|
/** @internal */ _jointTypeS;
|
|
44
52
|
/** @internal */ _jointTypeR;
|
|
@@ -70,14 +78,14 @@ import { ScriptAttachment, normalizeScriptAttachmentConfig, normalizeScriptAttac
|
|
|
70
78
|
/** @internal Arbitrary metadata payload for this node. */ _metaData;
|
|
71
79
|
/** @internal If greater than zero, suppress transform-change callbacks (during bulk updates). */ _disableCallback;
|
|
72
80
|
/** @internal User-attached script entries (engine-defined). */ _scripts;
|
|
73
|
-
/**
|
|
74
|
-
* Construct a scene node.
|
|
75
|
-
*
|
|
76
|
-
* @remarks
|
|
77
|
-
* If a `scene` is provided and this is not the root node, the node is reparented
|
|
78
|
-
* under the scene's root immediately.
|
|
79
|
-
*
|
|
80
|
-
* @param scene - Scene that will own this node.
|
|
81
|
+
/**
|
|
82
|
+
* Construct a scene node.
|
|
83
|
+
*
|
|
84
|
+
* @remarks
|
|
85
|
+
* If a `scene` is provided and this is not the root node, the node is reparented
|
|
86
|
+
* under the scene's root immediately.
|
|
87
|
+
*
|
|
88
|
+
* @param scene - Scene that will own this node.
|
|
81
89
|
*/ constructor(scene){
|
|
82
90
|
super();
|
|
83
91
|
this._runtimeId = SceneNode._runTimeId++;
|
|
@@ -87,6 +95,7 @@ import { ScriptAttachment, normalizeScriptAttachmentConfig, normalizeScriptAttac
|
|
|
87
95
|
this._name = '';
|
|
88
96
|
this._animationSet = new DRef();
|
|
89
97
|
this._sharedModel = new DRef();
|
|
98
|
+
this._morphTargetGroups = [];
|
|
90
99
|
this._jointTypeT = 'none';
|
|
91
100
|
this._jointTypeS = 'none';
|
|
92
101
|
this._jointTypeR = 'none';
|
|
@@ -118,11 +127,11 @@ import { ScriptAttachment, normalizeScriptAttachmentConfig, normalizeScriptAttac
|
|
|
118
127
|
this._parent = null;
|
|
119
128
|
this.reparent(scene?.rootNode ?? null);
|
|
120
129
|
}
|
|
121
|
-
/**
|
|
122
|
-
* Whether the node should be inserted into the scene's spatial structure.
|
|
123
|
-
*
|
|
124
|
-
* @remarks
|
|
125
|
-
* Toggling this hints the scene to (re)place the node in octree/acceleration structures.
|
|
130
|
+
/**
|
|
131
|
+
* Whether the node should be inserted into the scene's spatial structure.
|
|
132
|
+
*
|
|
133
|
+
* @remarks
|
|
134
|
+
* Toggling this hints the scene to (re)place the node in octree/acceleration structures.
|
|
126
135
|
*/ get placeToOctree() {
|
|
127
136
|
return this._placeToOctree;
|
|
128
137
|
}
|
|
@@ -134,88 +143,88 @@ import { ScriptAttachment, normalizeScriptAttachmentConfig, normalizeScriptAttac
|
|
|
134
143
|
}
|
|
135
144
|
}
|
|
136
145
|
}
|
|
137
|
-
/**
|
|
138
|
-
* Node's runtime unique identifier
|
|
146
|
+
/**
|
|
147
|
+
* Node's runtime unique identifier
|
|
139
148
|
*/ get runtimeId() {
|
|
140
149
|
return this._runtimeId;
|
|
141
150
|
}
|
|
142
|
-
/**
|
|
143
|
-
* Node's persistent identifier.
|
|
144
|
-
*
|
|
145
|
-
* @remarks
|
|
146
|
-
* Changing this affects serialization and registry lookup; ensure uniqueness.
|
|
151
|
+
/**
|
|
152
|
+
* Node's persistent identifier.
|
|
153
|
+
*
|
|
154
|
+
* @remarks
|
|
155
|
+
* Changing this affects serialization and registry lookup; ensure uniqueness.
|
|
147
156
|
*/ get persistentId() {
|
|
148
157
|
return this._id;
|
|
149
158
|
}
|
|
150
159
|
set persistentId(id) {
|
|
151
160
|
this._id = id;
|
|
152
161
|
}
|
|
153
|
-
/**
|
|
154
|
-
* If not empty, this node was loaded from a prefab
|
|
155
|
-
*
|
|
156
|
-
* @remarks
|
|
157
|
-
* Internal used for serialization
|
|
162
|
+
/**
|
|
163
|
+
* If not empty, this node was loaded from a prefab
|
|
164
|
+
*
|
|
165
|
+
* @remarks
|
|
166
|
+
* Internal used for serialization
|
|
158
167
|
*/ get prefabId() {
|
|
159
168
|
return this._prefabId;
|
|
160
169
|
}
|
|
161
170
|
set prefabId(id) {
|
|
162
171
|
this._prefabId = id;
|
|
163
172
|
}
|
|
164
|
-
/**
|
|
165
|
-
* Get prefab node this node belongs to, or null if this node does not belongs to any prefab
|
|
166
|
-
* @returns prefab node this node belongs to
|
|
173
|
+
/**
|
|
174
|
+
* Get prefab node this node belongs to, or null if this node does not belongs to any prefab
|
|
175
|
+
* @returns prefab node this node belongs to
|
|
167
176
|
*/ getPrefabNode() {
|
|
168
177
|
return this._prefabId ? this : this.parent?.getPrefabNode() ?? null;
|
|
169
178
|
}
|
|
170
|
-
/**
|
|
171
|
-
* Translation type if this is a joint node of any skeleton
|
|
172
|
-
*
|
|
173
|
-
* @remarks
|
|
174
|
-
* Internal used for serialization
|
|
179
|
+
/**
|
|
180
|
+
* Translation type if this is a joint node of any skeleton
|
|
181
|
+
*
|
|
182
|
+
* @remarks
|
|
183
|
+
* Internal used for serialization
|
|
175
184
|
*/ get jointTypeT() {
|
|
176
185
|
return this._jointTypeT;
|
|
177
186
|
}
|
|
178
187
|
set jointTypeT(val) {
|
|
179
188
|
this._jointTypeT = val;
|
|
180
189
|
}
|
|
181
|
-
/**
|
|
182
|
-
* Scale type if this is a joint node of any skeleton
|
|
183
|
-
*
|
|
184
|
-
* @remarks
|
|
185
|
-
* Internal used for serialization
|
|
190
|
+
/**
|
|
191
|
+
* Scale type if this is a joint node of any skeleton
|
|
192
|
+
*
|
|
193
|
+
* @remarks
|
|
194
|
+
* Internal used for serialization
|
|
186
195
|
*/ get jointTypeS() {
|
|
187
196
|
return this._jointTypeS;
|
|
188
197
|
}
|
|
189
198
|
set jointTypeS(val) {
|
|
190
199
|
this._jointTypeS = val;
|
|
191
200
|
}
|
|
192
|
-
/**
|
|
193
|
-
* Rotation type if this is a joint node of any skeleton
|
|
194
|
-
*
|
|
195
|
-
* @remarks
|
|
196
|
-
* Internal used for serialization
|
|
201
|
+
/**
|
|
202
|
+
* Rotation type if this is a joint node of any skeleton
|
|
203
|
+
*
|
|
204
|
+
* @remarks
|
|
205
|
+
* Internal used for serialization
|
|
197
206
|
*/ get jointTypeR() {
|
|
198
207
|
return this._jointTypeR;
|
|
199
208
|
}
|
|
200
209
|
set jointTypeR(val) {
|
|
201
210
|
this._jointTypeR = val;
|
|
202
211
|
}
|
|
203
|
-
/**
|
|
204
|
-
* Arbitrary metadata associated with this node.
|
|
205
|
-
*
|
|
206
|
-
* @remarks
|
|
207
|
-
* Stored and transported with the node; format is application-defined.
|
|
212
|
+
/**
|
|
213
|
+
* Arbitrary metadata associated with this node.
|
|
214
|
+
*
|
|
215
|
+
* @remarks
|
|
216
|
+
* Stored and transported with the node; format is application-defined.
|
|
208
217
|
*/ get metaData() {
|
|
209
218
|
return this._metaData;
|
|
210
219
|
}
|
|
211
220
|
set metaData(val) {
|
|
212
221
|
this._metaData = val;
|
|
213
222
|
}
|
|
214
|
-
/**
|
|
215
|
-
* Attached script filename or identifier (engine-specific).
|
|
216
|
-
*
|
|
217
|
-
* @remarks
|
|
218
|
-
* Integrates with the engine’s scripting system if available.
|
|
223
|
+
/**
|
|
224
|
+
* Attached script filename or identifier (engine-specific).
|
|
225
|
+
*
|
|
226
|
+
* @remarks
|
|
227
|
+
* Integrates with the engine’s scripting system if available.
|
|
219
228
|
*/ get script() {
|
|
220
229
|
return this._scripts[0]?.script ?? '';
|
|
221
230
|
}
|
|
@@ -229,8 +238,8 @@ import { ScriptAttachment, normalizeScriptAttachmentConfig, normalizeScriptAttac
|
|
|
229
238
|
this._scripts.unshift(new ScriptAttachment(script));
|
|
230
239
|
}
|
|
231
240
|
}
|
|
232
|
-
/**
|
|
233
|
-
* Script component configuration payload used by editor/runtime script components.
|
|
241
|
+
/**
|
|
242
|
+
* Script component configuration payload used by editor/runtime script components.
|
|
234
243
|
*/ get scriptConfig() {
|
|
235
244
|
return this._scripts[0]?.config ?? null;
|
|
236
245
|
}
|
|
@@ -245,16 +254,16 @@ import { ScriptAttachment, normalizeScriptAttachmentConfig, normalizeScriptAttac
|
|
|
245
254
|
this._scripts.splice(0, 1);
|
|
246
255
|
}
|
|
247
256
|
}
|
|
248
|
-
/**
|
|
249
|
-
* All script attachments on this node.
|
|
257
|
+
/**
|
|
258
|
+
* All script attachments on this node.
|
|
250
259
|
*/ get scripts() {
|
|
251
260
|
return this._scripts;
|
|
252
261
|
}
|
|
253
262
|
set scripts(value) {
|
|
254
263
|
this._scripts = normalizeScriptAttachments(value);
|
|
255
264
|
}
|
|
256
|
-
/**
|
|
257
|
-
* Script configs for all script attachments.
|
|
265
|
+
/**
|
|
266
|
+
* Script configs for all script attachments.
|
|
258
267
|
*/ get scriptConfigs() {
|
|
259
268
|
return this._scripts.map((item)=>item.config);
|
|
260
269
|
}
|
|
@@ -270,8 +279,8 @@ import { ScriptAttachment, normalizeScriptAttachmentConfig, normalizeScriptAttac
|
|
|
270
279
|
}
|
|
271
280
|
this._scripts = this._scripts.filter((item)=>item.script || item.config != null);
|
|
272
281
|
}
|
|
273
|
-
/**
|
|
274
|
-
* Display name of the node (for UI/debugging).
|
|
282
|
+
/**
|
|
283
|
+
* Display name of the node (for UI/debugging).
|
|
275
284
|
*/ get name() {
|
|
276
285
|
return this._name;
|
|
277
286
|
}
|
|
@@ -281,8 +290,8 @@ import { ScriptAttachment, normalizeScriptAttachmentConfig, normalizeScriptAttac
|
|
|
281
290
|
/** The owning scene. */ get scene() {
|
|
282
291
|
return this._scene;
|
|
283
292
|
}
|
|
284
|
-
/**
|
|
285
|
-
* Whether this node is currently attached under the scene's root.
|
|
293
|
+
/**
|
|
294
|
+
* Whether this node is currently attached under the scene's root.
|
|
286
295
|
*/ get attached() {
|
|
287
296
|
if (!this._scene) {
|
|
288
297
|
return false;
|
|
@@ -293,20 +302,20 @@ import { ScriptAttachment, normalizeScriptAttachmentConfig, normalizeScriptAttac
|
|
|
293
302
|
}
|
|
294
303
|
return node === this._scene.rootNode;
|
|
295
304
|
}
|
|
296
|
-
/**
|
|
297
|
-
* If true, the node is logically sealed; some operations (like cloning as child)
|
|
298
|
-
* may be restricted by engine policies.
|
|
305
|
+
/**
|
|
306
|
+
* If true, the node is logically sealed; some operations (like cloning as child)
|
|
307
|
+
* may be restricted by engine policies.
|
|
299
308
|
*/ get sealed() {
|
|
300
309
|
return this._sealed;
|
|
301
310
|
}
|
|
302
311
|
set sealed(val) {
|
|
303
312
|
this._sealed = val;
|
|
304
313
|
}
|
|
305
|
-
/**
|
|
306
|
-
* Lazily created animation set for this node.
|
|
307
|
-
*
|
|
308
|
-
* @remarks
|
|
309
|
-
* Accessing this schedules the node for update in the scene.
|
|
314
|
+
/**
|
|
315
|
+
* Lazily created animation set for this node.
|
|
316
|
+
*
|
|
317
|
+
* @remarks
|
|
318
|
+
* Accessing this schedules the node for update in the scene.
|
|
310
319
|
*/ get animationSet() {
|
|
311
320
|
if (!this._animationSet.get()) {
|
|
312
321
|
this._animationSet.set(new AnimationSet(this));
|
|
@@ -314,24 +323,30 @@ import { ScriptAttachment, normalizeScriptAttachmentConfig, normalizeScriptAttac
|
|
|
314
323
|
}
|
|
315
324
|
return this._animationSet.get();
|
|
316
325
|
}
|
|
317
|
-
/**
|
|
318
|
-
* Shared model reference for instancing/streaming systems.
|
|
326
|
+
/**
|
|
327
|
+
* Shared model reference for instancing/streaming systems.
|
|
319
328
|
*/ get sharedModel() {
|
|
320
329
|
return this._sharedModel.get();
|
|
321
330
|
}
|
|
322
331
|
set sharedModel(model) {
|
|
323
332
|
this._sharedModel.set(model);
|
|
324
333
|
}
|
|
325
|
-
/**
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
*
|
|
333
|
-
*
|
|
334
|
-
* @
|
|
334
|
+
/** Runtime morph target groups bound to this model instance. */ get morphTargetGroups() {
|
|
335
|
+
return this._morphTargetGroups;
|
|
336
|
+
}
|
|
337
|
+
set morphTargetGroups(groups) {
|
|
338
|
+
this._morphTargetGroups = (groups ?? []).filter((group)=>!!group?.name && group.bindings.length > 0);
|
|
339
|
+
}
|
|
340
|
+
/**
|
|
341
|
+
* Clone this node.
|
|
342
|
+
*
|
|
343
|
+
* @remarks
|
|
344
|
+
* If a shared model exists, it may create an instanced node. The clone is
|
|
345
|
+
* attached under the same parent; children are cloned based on `method` and `recursive`.
|
|
346
|
+
*
|
|
347
|
+
* @param method - Clone method ('deep' or 'instance').
|
|
348
|
+
* @param recursive - Whether children are cloned recursively.
|
|
349
|
+
* @returns New node instance
|
|
335
350
|
*/ async clone() {
|
|
336
351
|
this.iterate((node)=>{
|
|
337
352
|
if (node.isClipmapTerrain()) {
|
|
@@ -357,53 +372,53 @@ import { ScriptAttachment, normalizeScriptAttachmentConfig, normalizeScriptAttac
|
|
|
357
372
|
}
|
|
358
373
|
return other;
|
|
359
374
|
}
|
|
360
|
-
/**
|
|
361
|
-
* Whether the given node is a direct child of this node.
|
|
362
|
-
* @param child - The node to be checked
|
|
363
|
-
* @returns true if the given node is a direct child of this node, false otherwise
|
|
375
|
+
/**
|
|
376
|
+
* Whether the given node is a direct child of this node.
|
|
377
|
+
* @param child - The node to be checked
|
|
378
|
+
* @returns true if the given node is a direct child of this node, false otherwise
|
|
364
379
|
*/ hasChild(child) {
|
|
365
380
|
return child && child.parent === this;
|
|
366
381
|
}
|
|
367
|
-
/**
|
|
368
|
-
* Remove all children from this node.
|
|
382
|
+
/**
|
|
383
|
+
* Remove all children from this node.
|
|
369
384
|
*/ removeChildren() {
|
|
370
385
|
while(this._children.length){
|
|
371
386
|
this._children[0].get().remove();
|
|
372
387
|
}
|
|
373
388
|
}
|
|
374
|
-
/**
|
|
375
|
-
* Whether this node is an ancestor (direct or indirect) of the given node.
|
|
389
|
+
/**
|
|
390
|
+
* Whether this node is an ancestor (direct or indirect) of the given node.
|
|
376
391
|
*/ isParentOf(child) {
|
|
377
392
|
while(child && child !== this){
|
|
378
393
|
child = child.parent;
|
|
379
394
|
}
|
|
380
395
|
return child === this;
|
|
381
396
|
}
|
|
382
|
-
/**
|
|
383
|
-
* Detach this node from its parent.
|
|
384
|
-
*
|
|
385
|
-
* @returns this
|
|
397
|
+
/**
|
|
398
|
+
* Detach this node from its parent.
|
|
399
|
+
*
|
|
400
|
+
* @returns this
|
|
386
401
|
*/ remove() {
|
|
387
402
|
this.parent = null;
|
|
388
403
|
return this;
|
|
389
404
|
}
|
|
390
|
-
/**
|
|
391
|
-
* Depth-first traversal of this node's subtree (pre-order).
|
|
392
|
-
*
|
|
393
|
-
* @param v - Visitor invoked on each node.
|
|
405
|
+
/**
|
|
406
|
+
* Depth-first traversal of this node's subtree (pre-order).
|
|
407
|
+
*
|
|
408
|
+
* @param v - Visitor invoked on each node.
|
|
394
409
|
*/ traverse(v) {
|
|
395
410
|
v.visit(this);
|
|
396
411
|
for (const child of this._children){
|
|
397
412
|
child.get().traverse(v);
|
|
398
413
|
}
|
|
399
414
|
}
|
|
400
|
-
/**
|
|
401
|
-
* Iterate self and descendants in pre-order.
|
|
402
|
-
*
|
|
403
|
-
* Warning: Do not remove children during this iteration. To allow removal, use `iterateBottomToTop`.
|
|
404
|
-
*
|
|
405
|
-
* @param callback - Called for each node; if returns true, iteration stops.
|
|
406
|
-
* @returns If returns true, the iteration will immediately stop.
|
|
415
|
+
/**
|
|
416
|
+
* Iterate self and descendants in pre-order.
|
|
417
|
+
*
|
|
418
|
+
* Warning: Do not remove children during this iteration. To allow removal, use `iterateBottomToTop`.
|
|
419
|
+
*
|
|
420
|
+
* @param callback - Called for each node; if returns true, iteration stops.
|
|
421
|
+
* @returns If returns true, the iteration will immediately stop.
|
|
407
422
|
*/ iterate(callback) {
|
|
408
423
|
if (callback(this)) {
|
|
409
424
|
return true;
|
|
@@ -415,13 +430,13 @@ import { ScriptAttachment, normalizeScriptAttachmentConfig, normalizeScriptAttac
|
|
|
415
430
|
}
|
|
416
431
|
return false;
|
|
417
432
|
}
|
|
418
|
-
/**
|
|
419
|
-
* Iterate self and descendants in reverse post-order (bottom-to-top).
|
|
420
|
-
*
|
|
421
|
-
* Child nodes can be safely removed during this iteration.
|
|
422
|
-
*
|
|
423
|
-
* @param callback - Called for each node; if returns true, iteration stops.
|
|
424
|
-
* @returns If returns true, the iteration will immediately stop.
|
|
433
|
+
/**
|
|
434
|
+
* Iterate self and descendants in reverse post-order (bottom-to-top).
|
|
435
|
+
*
|
|
436
|
+
* Child nodes can be safely removed during this iteration.
|
|
437
|
+
*
|
|
438
|
+
* @param callback - Called for each node; if returns true, iteration stops.
|
|
439
|
+
* @returns If returns true, the iteration will immediately stop.
|
|
425
440
|
*/ iterateBottomToTop(callback) {
|
|
426
441
|
for(let i = this._children.length - 1; i >= 0; i--){
|
|
427
442
|
const child = this._children[i];
|
|
@@ -446,6 +461,12 @@ import { ScriptAttachment, normalizeScriptAttachmentConfig, normalizeScriptAttac
|
|
|
446
461
|
/** Type guard: true if this node is a sprite */ isSprite() {
|
|
447
462
|
return false;
|
|
448
463
|
}
|
|
464
|
+
/** Type guard: true if this node is a MSDF text sprite */ isMSDFTextSprite() {
|
|
465
|
+
return false;
|
|
466
|
+
}
|
|
467
|
+
/** Type guard: true if this node is a MSDF text sprite */ isMSDFText() {
|
|
468
|
+
return false;
|
|
469
|
+
}
|
|
449
470
|
/** Type guard: true if this node is a water node. */ isWater() {
|
|
450
471
|
return false;
|
|
451
472
|
}
|
|
@@ -464,15 +485,15 @@ import { ScriptAttachment, normalizeScriptAttachmentConfig, normalizeScriptAttac
|
|
|
464
485
|
/** true if this is a punctual light node, false otherwise */ isPunctualLight() {
|
|
465
486
|
return false;
|
|
466
487
|
}
|
|
467
|
-
/**
|
|
468
|
-
* Computes the bounding volume of the node
|
|
469
|
-
* @returns The output bounding volume
|
|
488
|
+
/**
|
|
489
|
+
* Computes the bounding volume of the node
|
|
490
|
+
* @returns The output bounding volume
|
|
470
491
|
*/ computeBoundingVolume() {
|
|
471
492
|
return null;
|
|
472
493
|
}
|
|
473
|
-
/**
|
|
474
|
-
* Gets the bounding volume of the node
|
|
475
|
-
* @returns The bounding volume of the node
|
|
494
|
+
/**
|
|
495
|
+
* Gets the bounding volume of the node
|
|
496
|
+
* @returns The bounding volume of the node
|
|
476
497
|
*/ getBoundingVolume() {
|
|
477
498
|
if (this._bvDirty) {
|
|
478
499
|
this._bv = this.computeBoundingVolume();
|
|
@@ -480,9 +501,9 @@ import { ScriptAttachment, normalizeScriptAttachmentConfig, normalizeScriptAttac
|
|
|
480
501
|
}
|
|
481
502
|
return this._bv;
|
|
482
503
|
}
|
|
483
|
-
/**
|
|
484
|
-
* Sets the bounding volume of the node
|
|
485
|
-
* @param bv - The bounding volume to set
|
|
504
|
+
/**
|
|
505
|
+
* Sets the bounding volume of the node
|
|
506
|
+
* @param bv - The bounding volume to set
|
|
486
507
|
*/ setBoundingVolume(bv) {
|
|
487
508
|
if (bv !== this._bv) {
|
|
488
509
|
this._bv = bv;
|
|
@@ -490,23 +511,23 @@ import { ScriptAttachment, normalizeScriptAttachmentConfig, normalizeScriptAttac
|
|
|
490
511
|
this.invalidateWorldBoundingVolume(false);
|
|
491
512
|
}
|
|
492
513
|
}
|
|
493
|
-
/**
|
|
494
|
-
* Gets the world space bounding volume of the node
|
|
495
|
-
* @returns The world space bounding volume of the node
|
|
514
|
+
/**
|
|
515
|
+
* Gets the world space bounding volume of the node
|
|
516
|
+
* @returns The world space bounding volume of the node
|
|
496
517
|
*/ getWorldBoundingVolume() {
|
|
497
518
|
if (!this._bvWorld) {
|
|
498
519
|
this._bvWorld = this.computeWorldBoundingVolume(this.getBoundingVolume());
|
|
499
520
|
}
|
|
500
521
|
return this._bvWorld;
|
|
501
522
|
}
|
|
502
|
-
/**
|
|
503
|
-
* Computes the world space bounding volume of the node
|
|
504
|
-
* @returns The output bounding volume
|
|
523
|
+
/**
|
|
524
|
+
* Computes the world space bounding volume of the node
|
|
525
|
+
* @returns The output bounding volume
|
|
505
526
|
*/ computeWorldBoundingVolume(localBV) {
|
|
506
527
|
return localBV?.transform(this.worldMatrix) ?? null;
|
|
507
528
|
}
|
|
508
|
-
/**
|
|
509
|
-
* Force the bounding volume to be recalculated
|
|
529
|
+
/**
|
|
530
|
+
* Force the bounding volume to be recalculated
|
|
510
531
|
*/ invalidateBoundingVolume() {
|
|
511
532
|
this._bvDirty = true;
|
|
512
533
|
this.invalidateWorldBoundingVolume(false);
|
|
@@ -571,12 +592,12 @@ import { ScriptAttachment, normalizeScriptAttachmentConfig, normalizeScriptAttac
|
|
|
571
592
|
set gpuPickable(val) {
|
|
572
593
|
this._gpuPickable = !!val;
|
|
573
594
|
}
|
|
574
|
-
/**
|
|
575
|
-
* Finds a scene node by its persistent ID.
|
|
576
|
-
*
|
|
577
|
-
* @typeParam T - Expected node type.
|
|
578
|
-
* @param id - Persistent identifier to match against `SceneNode.persistentId`.
|
|
579
|
-
* @returns The first matching node, or `null` if not found.
|
|
595
|
+
/**
|
|
596
|
+
* Finds a scene node by its persistent ID.
|
|
597
|
+
*
|
|
598
|
+
* @typeParam T - Expected node type.
|
|
599
|
+
* @param id - Persistent identifier to match against `SceneNode.persistentId`.
|
|
600
|
+
* @returns The first matching node, or `null` if not found.
|
|
580
601
|
*/ findNodeById(id) {
|
|
581
602
|
let node = null;
|
|
582
603
|
this.iterate((child)=>{
|
|
@@ -587,11 +608,18 @@ import { ScriptAttachment, normalizeScriptAttachmentConfig, normalizeScriptAttac
|
|
|
587
608
|
});
|
|
588
609
|
return node;
|
|
589
610
|
}
|
|
590
|
-
/**
|
|
591
|
-
* Finds a skeleton object by its persistent ID.
|
|
592
|
-
* @param id - Persistent identifier to match against `Skeleton.persistentId`.
|
|
593
|
-
* @returns The first matchign node, or `null` if not found.
|
|
611
|
+
/**
|
|
612
|
+
* Finds a skeleton object by its persistent ID.
|
|
613
|
+
* @param id - Persistent identifier to match against `Skeleton.persistentId`.
|
|
614
|
+
* @returns The first matchign node, or `null` if not found.
|
|
594
615
|
*/ findSkeletonById(id) {
|
|
616
|
+
return this.findSkinBindingById(id);
|
|
617
|
+
}
|
|
618
|
+
/**
|
|
619
|
+
* Finds a skin binding by its persistent ID.
|
|
620
|
+
* @param id - Persistent identifier to match against `SkinBinding.persistentId`.
|
|
621
|
+
* @returns The first matching binding, or `null` if not found.
|
|
622
|
+
*/ findSkinBindingById(id) {
|
|
595
623
|
const prefabNode = this.getPrefabNode() ?? this;
|
|
596
624
|
let sk = null;
|
|
597
625
|
prefabNode.iterate((node)=>{
|
|
@@ -601,18 +629,31 @@ import { ScriptAttachment, normalizeScriptAttachmentConfig, normalizeScriptAttac
|
|
|
601
629
|
// avoid ts2339 compilation error (maybe a typescript bug?)
|
|
602
630
|
return sk?.get() ?? null;
|
|
603
631
|
}
|
|
604
|
-
/**
|
|
605
|
-
* Finds a
|
|
606
|
-
*
|
|
607
|
-
*
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
632
|
+
/**
|
|
633
|
+
* Finds a shared skeleton rig by its persistent ID.
|
|
634
|
+
* @param id - Persistent identifier to match against `SkeletonRig.persistentId`.
|
|
635
|
+
* @returns The first matching rig, or `null` if not found.
|
|
636
|
+
*/ findSkeletonRigById(id) {
|
|
637
|
+
const prefabNode = this.getPrefabNode() ?? this;
|
|
638
|
+
let rig = null;
|
|
639
|
+
prefabNode.iterate((node)=>{
|
|
640
|
+
rig = node.animationSet.rigs.find((s)=>s.get().persistentId === id) ?? null;
|
|
641
|
+
return !!rig;
|
|
642
|
+
});
|
|
643
|
+
return rig?.get() ?? null;
|
|
644
|
+
}
|
|
645
|
+
/**
|
|
646
|
+
* Finds a scene node by name.
|
|
647
|
+
*
|
|
648
|
+
* If multiple nodes share the same name, returns the first match encountered
|
|
649
|
+
* during traversal.
|
|
650
|
+
*
|
|
651
|
+
* @typeParam T - Expected node type.
|
|
652
|
+
* @param name - Node name to match.
|
|
653
|
+
* @returns The first matching node, or `null` if not found.
|
|
654
|
+
*
|
|
655
|
+
* @remarks
|
|
656
|
+
* Names are not guaranteed unique. Prefer IDs for stable references.
|
|
616
657
|
*/ findNodeByName(name) {
|
|
617
658
|
let node = null;
|
|
618
659
|
this.iterate((child)=>{
|
|
@@ -639,9 +680,175 @@ import { ScriptAttachment, normalizeScriptAttachmentConfig, normalizeScriptAttac
|
|
|
639
680
|
set boundingBoxDrawMode(mode) {
|
|
640
681
|
this._boxDrawMode = mode;
|
|
641
682
|
}
|
|
642
|
-
|
|
683
|
+
/** @internal */ matchesMorphTargetBinding(mesh, binding) {
|
|
684
|
+
const assetBinding = getSceneMeshAssetBinding(mesh);
|
|
685
|
+
if (binding.node && assetBinding?.node !== binding.node) {
|
|
686
|
+
return false;
|
|
687
|
+
}
|
|
688
|
+
if (binding.mesh && binding.mesh !== mesh && assetBinding?.mesh !== binding.mesh) {
|
|
689
|
+
return false;
|
|
690
|
+
}
|
|
691
|
+
return true;
|
|
692
|
+
}
|
|
693
|
+
/** @internal */ applyMorphTargetBindingWeight(mesh, binding, weight) {
|
|
694
|
+
if (!this.matchesMorphTargetBinding(mesh, binding)) {
|
|
695
|
+
return;
|
|
696
|
+
}
|
|
697
|
+
const targetWeight = weight * binding.weight;
|
|
698
|
+
const targetIndex = binding.targetIndex;
|
|
699
|
+
if (typeof targetIndex === 'number' && targetIndex >= 0 && targetIndex < mesh.getNumMorphTargets()) {
|
|
700
|
+
mesh.setMorphWeightByIndex(targetIndex, targetWeight);
|
|
701
|
+
return;
|
|
702
|
+
}
|
|
703
|
+
if (binding.targetName) {
|
|
704
|
+
mesh.setMorphWeight(binding.targetName, targetWeight);
|
|
705
|
+
}
|
|
706
|
+
}
|
|
707
|
+
/** @internal */ getMorphTargetGroupRoot() {
|
|
708
|
+
let node = this;
|
|
709
|
+
while(node){
|
|
710
|
+
if (node._morphTargetGroups.length > 0 || node.sharedModel) {
|
|
711
|
+
return node;
|
|
712
|
+
}
|
|
713
|
+
node = node.parent;
|
|
714
|
+
}
|
|
715
|
+
return this.getPrefabNode() ?? this;
|
|
716
|
+
}
|
|
717
|
+
/** @internal */ applyMorphTargetGroupWeight(group, weight) {
|
|
718
|
+
const root = this.getMorphTargetGroupRoot();
|
|
719
|
+
root.iterate((node)=>{
|
|
720
|
+
if (node.isMesh()) {
|
|
721
|
+
for (const binding of group.bindings){
|
|
722
|
+
this.applyMorphTargetBindingWeight(node, binding, weight);
|
|
723
|
+
}
|
|
724
|
+
}
|
|
725
|
+
});
|
|
726
|
+
}
|
|
727
|
+
/** @internal */ getRuntimeMorphTargetGroup(name) {
|
|
728
|
+
const root = this.getMorphTargetGroupRoot();
|
|
729
|
+
return root._morphTargetGroups.find((group)=>group.name === name) ?? null;
|
|
730
|
+
}
|
|
731
|
+
/** Returns serialized morph target groups for this node. */ getSerializedMorphTargetGroups() {
|
|
732
|
+
return this._morphTargetGroups.map((group)=>({
|
|
733
|
+
name: group.name,
|
|
734
|
+
isBinary: group.isBinary,
|
|
735
|
+
weight: group.weight ?? 0,
|
|
736
|
+
bindings: group.bindings.filter((binding)=>!!binding.mesh).map((binding)=>({
|
|
737
|
+
meshId: binding.mesh.persistentId,
|
|
738
|
+
targetIndex: binding.targetIndex,
|
|
739
|
+
targetName: binding.targetName,
|
|
740
|
+
weight: binding.weight
|
|
741
|
+
}))
|
|
742
|
+
})).filter((group)=>group.bindings.length > 0);
|
|
743
|
+
}
|
|
744
|
+
/** Restores serialized morph target groups for this node. */ setSerializedMorphTargetGroups(groups) {
|
|
745
|
+
const runtimeGroups = [];
|
|
746
|
+
for (const group of groups ?? []){
|
|
747
|
+
if (!group?.name || !Array.isArray(group.bindings)) {
|
|
748
|
+
continue;
|
|
749
|
+
}
|
|
750
|
+
const bindings = [];
|
|
751
|
+
for (const binding of group.bindings){
|
|
752
|
+
const mesh = binding?.meshId ? this.findNodeById(binding.meshId) : null;
|
|
753
|
+
if (mesh?.isMesh()) {
|
|
754
|
+
bindings.push({
|
|
755
|
+
mesh,
|
|
756
|
+
targetIndex: binding.targetIndex,
|
|
757
|
+
targetName: binding.targetName,
|
|
758
|
+
weight: typeof binding.weight === 'number' ? binding.weight : 1
|
|
759
|
+
});
|
|
760
|
+
}
|
|
761
|
+
}
|
|
762
|
+
if (bindings.length > 0) {
|
|
763
|
+
runtimeGroups.push({
|
|
764
|
+
name: group.name,
|
|
765
|
+
bindings,
|
|
766
|
+
isBinary: group.isBinary,
|
|
767
|
+
weight: typeof group.weight === 'number' ? group.weight : 0
|
|
768
|
+
});
|
|
769
|
+
}
|
|
770
|
+
}
|
|
771
|
+
this._morphTargetGroups = runtimeGroups;
|
|
772
|
+
for (const group of this._morphTargetGroups){
|
|
773
|
+
this.applyMorphTargetGroupWeight(group, group.weight ?? 0);
|
|
774
|
+
}
|
|
775
|
+
}
|
|
776
|
+
/**
|
|
777
|
+
* Force transform update and notify descendants.
|
|
778
|
+
* @param invalidateLocal - If true, also invalidate local matrix; otherwise only invalidate world matrix.
|
|
779
|
+
*/ invalidateTransform(invalidateLocal = true) {
|
|
643
780
|
this._onTransformChanged(invalidateLocal);
|
|
644
781
|
}
|
|
782
|
+
/**
|
|
783
|
+
* Set morph target weight by name for all meshes in the subtree.
|
|
784
|
+
* @param name - Morph target name
|
|
785
|
+
* @param weight - Morph target weight
|
|
786
|
+
*/ setMorphTargetWeight(name, weight) {
|
|
787
|
+
const root = this.getPrefabNode() ?? this;
|
|
788
|
+
root.iterate((node)=>{
|
|
789
|
+
if (node.isMesh()) {
|
|
790
|
+
const index = node.getMorphTargetIndexByName(name);
|
|
791
|
+
if (index >= 0) {
|
|
792
|
+
node.setMorphWeightByIndex(index, weight);
|
|
793
|
+
}
|
|
794
|
+
}
|
|
795
|
+
});
|
|
796
|
+
}
|
|
797
|
+
/**
|
|
798
|
+
* Set morph target group weight for the model instance.
|
|
799
|
+
* @param name - Morph target group name
|
|
800
|
+
* @param weight - Group weight
|
|
801
|
+
*/ setMorphTargetGroupWeight(name, weight) {
|
|
802
|
+
const runtimeGroup = this.getRuntimeMorphTargetGroup(name);
|
|
803
|
+
if (runtimeGroup) {
|
|
804
|
+
const groupWeight = runtimeGroup.isBinary ? weight > 0.5 ? 1 : 0 : weight;
|
|
805
|
+
runtimeGroup.weight = groupWeight;
|
|
806
|
+
this.applyMorphTargetGroupWeight(runtimeGroup, groupWeight);
|
|
807
|
+
return;
|
|
808
|
+
}
|
|
809
|
+
const root = this.getMorphTargetGroupRoot();
|
|
810
|
+
const group = root.sharedModel?.getMorphTargetGroup(name);
|
|
811
|
+
if (!group) {
|
|
812
|
+
this.setMorphTargetWeight(name, weight);
|
|
813
|
+
return;
|
|
814
|
+
}
|
|
815
|
+
const groupWeight = group.isBinary ? weight > 0.5 ? 1 : 0 : weight;
|
|
816
|
+
this.applyMorphTargetGroupWeight(group, groupWeight);
|
|
817
|
+
}
|
|
818
|
+
/**
|
|
819
|
+
* Get morph target group weight.
|
|
820
|
+
* @param name - Morph target group name
|
|
821
|
+
* @returns The group weight, or 0 if no group was found
|
|
822
|
+
*/ getMorphTargetGroupWeight(name) {
|
|
823
|
+
const runtimeGroup = this.getRuntimeMorphTargetGroup(name);
|
|
824
|
+
return runtimeGroup?.weight ?? 0;
|
|
825
|
+
}
|
|
826
|
+
/**
|
|
827
|
+
* Collect all morph target names from meshes in the subtree.
|
|
828
|
+
* @returns Array of unique morph target names
|
|
829
|
+
*/ collectMorphTargetNames() {
|
|
830
|
+
const root = this.getPrefabNode() ?? this;
|
|
831
|
+
const names = new Set();
|
|
832
|
+
root.iterate((node)=>{
|
|
833
|
+
if (node.isMesh()) {
|
|
834
|
+
for(let i = 0; i < node.getNumMorphTargets(); i++){
|
|
835
|
+
names.add(node.getMorphTargetName(i));
|
|
836
|
+
}
|
|
837
|
+
}
|
|
838
|
+
});
|
|
839
|
+
return Array.from(names);
|
|
840
|
+
}
|
|
841
|
+
/**
|
|
842
|
+
* Collect all model-level morph target group names.
|
|
843
|
+
* @returns Array of morph target group names
|
|
844
|
+
*/ collectMorphTargetGroupNames() {
|
|
845
|
+
const root = this.getMorphTargetGroupRoot();
|
|
846
|
+
if (root._morphTargetGroups.length > 0) {
|
|
847
|
+
return root._morphTargetGroups.map((group)=>group.name);
|
|
848
|
+
}
|
|
849
|
+
const groups = root.sharedModel?.morphTargetGroups;
|
|
850
|
+
return groups ? groups.map((group)=>group.name) : [];
|
|
851
|
+
}
|
|
645
852
|
/** Get called when the node was just created by cloning from other node */ onPostClone() {}
|
|
646
853
|
/** Disposes the node */ onDispose() {
|
|
647
854
|
super.onDispose();
|
|
@@ -704,11 +911,11 @@ import { ScriptAttachment, normalizeScriptAttachmentConfig, normalizeScriptAttac
|
|
|
704
911
|
}
|
|
705
912
|
}
|
|
706
913
|
}
|
|
707
|
-
/**
|
|
708
|
-
* Get called when this node is attached to scene
|
|
914
|
+
/**
|
|
915
|
+
* Get called when this node is attached to scene
|
|
709
916
|
*/ _onAttached() {}
|
|
710
|
-
/**
|
|
711
|
-
* Get called when this node is detached from scene
|
|
917
|
+
/**
|
|
918
|
+
* Get called when this node is detached from scene
|
|
712
919
|
*/ _onDetached() {}
|
|
713
920
|
/** @internal */ _attached() {
|
|
714
921
|
this.iterate((child)=>{
|
|
@@ -741,24 +948,24 @@ import { ScriptAttachment, normalizeScriptAttachmentConfig, normalizeScriptAttac
|
|
|
741
948
|
/** Children of this xform */ get children() {
|
|
742
949
|
return this._children.map((child)=>child.get());
|
|
743
950
|
}
|
|
744
|
-
/**
|
|
745
|
-
* Position of the xform relative to it's parent
|
|
951
|
+
/**
|
|
952
|
+
* Position of the xform relative to it's parent
|
|
746
953
|
*/ get position() {
|
|
747
954
|
return this._position;
|
|
748
955
|
}
|
|
749
956
|
set position(val) {
|
|
750
957
|
this._position.setXYZ(val[0], val[1], val[2]);
|
|
751
958
|
}
|
|
752
|
-
/**
|
|
753
|
-
* Scaling of the xform
|
|
959
|
+
/**
|
|
960
|
+
* Scaling of the xform
|
|
754
961
|
*/ get scale() {
|
|
755
962
|
return this._scaling;
|
|
756
963
|
}
|
|
757
964
|
set scale(val) {
|
|
758
965
|
this._scaling.setXYZ(val[0], val[1], val[2]);
|
|
759
966
|
}
|
|
760
|
-
/**
|
|
761
|
-
* Rotation of the xform
|
|
967
|
+
/**
|
|
968
|
+
* Rotation of the xform
|
|
762
969
|
*/ get rotation() {
|
|
763
970
|
return this._rotation;
|
|
764
971
|
}
|
|
@@ -793,32 +1000,32 @@ import { ScriptAttachment, normalizeScriptAttachmentConfig, normalizeScriptAttac
|
|
|
793
1000
|
thisToOther(other, v, result) {
|
|
794
1001
|
return other.worldToThis(this.thisToWorld(v, result), result);
|
|
795
1002
|
}
|
|
796
|
-
/**
|
|
797
|
-
* Gets the position of the xform in world space
|
|
798
|
-
* @returns position of the xform in world space
|
|
1003
|
+
/**
|
|
1004
|
+
* Gets the position of the xform in world space
|
|
1005
|
+
* @returns position of the xform in world space
|
|
799
1006
|
*/ getWorldPosition(outPos) {
|
|
800
1007
|
return outPos?.setXYZ(this.worldMatrix.m03, this.worldMatrix.m13, this.worldMatrix.m23) ?? new Vector3(this.worldMatrix.m03, this.worldMatrix.m13, this.worldMatrix.m23);
|
|
801
1008
|
}
|
|
802
|
-
/**
|
|
803
|
-
* Moves the xform by an offset vector
|
|
804
|
-
* @param delta - The offset vector
|
|
805
|
-
* @returns self
|
|
1009
|
+
/**
|
|
1010
|
+
* Moves the xform by an offset vector
|
|
1011
|
+
* @param delta - The offset vector
|
|
1012
|
+
* @returns self
|
|
806
1013
|
*/ moveBy(delta) {
|
|
807
1014
|
this._position.addBy(delta);
|
|
808
1015
|
return this;
|
|
809
1016
|
}
|
|
810
|
-
/**
|
|
811
|
-
* Scales the xform by a given scale factor
|
|
812
|
-
* @param factor - The scale factor
|
|
813
|
-
* @returns self
|
|
1017
|
+
/**
|
|
1018
|
+
* Scales the xform by a given scale factor
|
|
1019
|
+
* @param factor - The scale factor
|
|
1020
|
+
* @returns self
|
|
814
1021
|
*/ scaleBy(factor) {
|
|
815
1022
|
this._scaling.mulBy(factor);
|
|
816
1023
|
return this;
|
|
817
1024
|
}
|
|
818
|
-
/**
|
|
819
|
-
* Sets the local transform matrix of the xform
|
|
820
|
-
* @param matrix - The transform matrix to set
|
|
821
|
-
* @returns self
|
|
1025
|
+
/**
|
|
1026
|
+
* Sets the local transform matrix of the xform
|
|
1027
|
+
* @param matrix - The transform matrix to set
|
|
1028
|
+
* @returns self
|
|
822
1029
|
*/ setLocalTransform(matrix) {
|
|
823
1030
|
this._disableCallback++;
|
|
824
1031
|
matrix.decompose(this._scaling, this._rotation, this._position);
|
|
@@ -848,15 +1055,15 @@ import { ScriptAttachment, normalizeScriptAttachmentConfig, normalizeScriptAttac
|
|
|
848
1055
|
this.syncTransform();
|
|
849
1056
|
return this._invWorldMatrix;
|
|
850
1057
|
}
|
|
851
|
-
/**
|
|
852
|
-
* Calculate local transform matrix
|
|
853
|
-
* @param outMatrix - Matrix object that holds the result of calculation
|
|
1058
|
+
/**
|
|
1059
|
+
* Calculate local transform matrix
|
|
1060
|
+
* @param outMatrix - Matrix object that holds the result of calculation
|
|
854
1061
|
*/ calculateLocalTransform(outMatrix) {
|
|
855
1062
|
outMatrix.compose(this._scaling, this._rotation, this._position);
|
|
856
1063
|
}
|
|
857
|
-
/**
|
|
858
|
-
* Calculate world transform matrix
|
|
859
|
-
* @param outMatrix - Matrix object that holds the result of calculation
|
|
1064
|
+
/**
|
|
1065
|
+
* Calculate world transform matrix
|
|
1066
|
+
* @param outMatrix - Matrix object that holds the result of calculation
|
|
860
1067
|
*/ calculateWorldTransform(outMatrix) {
|
|
861
1068
|
if (this._parent) {
|
|
862
1069
|
Matrix4x4.multiplyAffine(this._parent.worldMatrix, this.localMatrix, outMatrix);
|
|
@@ -864,21 +1071,21 @@ import { ScriptAttachment, normalizeScriptAttachmentConfig, normalizeScriptAttac
|
|
|
864
1071
|
outMatrix.set(this.localMatrix);
|
|
865
1072
|
}
|
|
866
1073
|
}
|
|
867
|
-
/**
|
|
868
|
-
* Sets the local tranformation matrix by a look-at matrix
|
|
869
|
-
* @param eye - The eye position used to make the look-at matrix
|
|
870
|
-
* @param target - The target position used to make the look-at matrix
|
|
871
|
-
* @param up - The up vector used to make the look-at matrix
|
|
872
|
-
* @returns self
|
|
1074
|
+
/**
|
|
1075
|
+
* Sets the local tranformation matrix by a look-at matrix
|
|
1076
|
+
* @param eye - The eye position used to make the look-at matrix
|
|
1077
|
+
* @param target - The target position used to make the look-at matrix
|
|
1078
|
+
* @param up - The up vector used to make the look-at matrix
|
|
1079
|
+
* @returns self
|
|
873
1080
|
*/ lookAt(eye, target, up) {
|
|
874
1081
|
this.setLocalTransform(Matrix4x4.lookAt(eye, target, up));
|
|
875
1082
|
return this;
|
|
876
1083
|
}
|
|
877
|
-
/**
|
|
878
|
-
* Update node state once per-frame
|
|
879
|
-
* @param frameId - Current frame id
|
|
880
|
-
* @param elapsedInSeconds - Elapsed time from game start in seconds
|
|
881
|
-
* @param deltaInSeconds - Elapsed time since previous frame in seconds
|
|
1084
|
+
/**
|
|
1085
|
+
* Update node state once per-frame
|
|
1086
|
+
* @param frameId - Current frame id
|
|
1087
|
+
* @param elapsedInSeconds - Elapsed time from game start in seconds
|
|
1088
|
+
* @param deltaInSeconds - Elapsed time since previous frame in seconds
|
|
882
1089
|
*/ update(frameId, elapsedInSeconds, deltaInSeconds) {
|
|
883
1090
|
if (!this.attached) {
|
|
884
1091
|
return;
|
|
@@ -893,16 +1100,16 @@ import { ScriptAttachment, normalizeScriptAttachmentConfig, normalizeScriptAttac
|
|
|
893
1100
|
}
|
|
894
1101
|
}
|
|
895
1102
|
}
|
|
896
|
-
/**
|
|
897
|
-
* Update node state once per-camera
|
|
898
|
-
* @param _camera - Updates according to which camera
|
|
899
|
-
* @param _elapsedInSeconds - Elapsed time from game start in seconds
|
|
900
|
-
* @param _deltaInSeconds - Elapsed time since previous frame in seconds
|
|
1103
|
+
/**
|
|
1104
|
+
* Update node state once per-camera
|
|
1105
|
+
* @param _camera - Updates according to which camera
|
|
1106
|
+
* @param _elapsedInSeconds - Elapsed time from game start in seconds
|
|
1107
|
+
* @param _deltaInSeconds - Elapsed time since previous frame in seconds
|
|
901
1108
|
*/ updatePerCamera(_camera, _elapsedInSeconds, _deltaInSeconds) {}
|
|
902
|
-
/**
|
|
903
|
-
* Removes this node from it's parent and add this node to another parent node if required
|
|
904
|
-
* @param p - The new parent node that this node should be added to or null
|
|
905
|
-
* @returns self
|
|
1109
|
+
/**
|
|
1110
|
+
* Removes this node from it's parent and add this node to another parent node if required
|
|
1111
|
+
* @param p - The new parent node that this node should be added to or null
|
|
1112
|
+
* @returns self
|
|
906
1113
|
*/ reparent(p) {
|
|
907
1114
|
this.parent = p ?? null;
|
|
908
1115
|
return this;
|
|
@@ -924,5 +1131,5 @@ import { ScriptAttachment, normalizeScriptAttachmentConfig, normalizeScriptAttac
|
|
|
924
1131
|
}
|
|
925
1132
|
}
|
|
926
1133
|
|
|
927
|
-
export { SceneNode };
|
|
1134
|
+
export { SceneNode, setSceneMeshAssetBinding };
|
|
928
1135
|
//# sourceMappingURL=scene_node.js.map
|