@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.
Files changed (188) hide show
  1. package/dist/animation/animationmask.js +224 -0
  2. package/dist/animation/animationmask.js.map +1 -0
  3. package/dist/animation/animationset.js +268 -67
  4. package/dist/animation/animationset.js.map +1 -1
  5. package/dist/animation/animationtrack.js.map +1 -1
  6. package/dist/animation/eulerrotationtrack.js +3 -0
  7. package/dist/animation/eulerrotationtrack.js.map +1 -1
  8. package/dist/animation/fixed_geometry_cache_track.js +7 -0
  9. package/dist/animation/fixed_geometry_cache_track.js.map +1 -1
  10. package/dist/animation/ik_modifier.js.map +1 -1
  11. package/dist/animation/joint_dynamics/collision.js +6 -4
  12. package/dist/animation/joint_dynamics/collision.js.map +1 -1
  13. package/dist/animation/joint_dynamics/controller.js +390 -43
  14. package/dist/animation/joint_dynamics/controller.js.map +1 -1
  15. package/dist/animation/joint_dynamics/joint_dynamics_system.js +62 -3
  16. package/dist/animation/joint_dynamics/joint_dynamics_system.js.map +1 -1
  17. package/dist/animation/joint_dynamics/solver.js +4 -3
  18. package/dist/animation/joint_dynamics/solver.js.map +1 -1
  19. package/dist/animation/joint_dynamics/types.js.map +1 -1
  20. package/dist/animation/joint_dynamics_modifier.js +2 -0
  21. package/dist/animation/joint_dynamics_modifier.js.map +1 -1
  22. package/dist/animation/morphtarget.js +3 -72
  23. package/dist/animation/morphtarget.js.map +1 -1
  24. package/dist/animation/morphtrack.js +3 -0
  25. package/dist/animation/morphtrack.js.map +1 -1
  26. package/dist/animation/pca_geometry_cache_track.js +3 -0
  27. package/dist/animation/pca_geometry_cache_track.js.map +1 -1
  28. package/dist/animation/proptrack.js +3 -0
  29. package/dist/animation/proptrack.js.map +1 -1
  30. package/dist/animation/rotationtrack.js +3 -0
  31. package/dist/animation/rotationtrack.js.map +1 -1
  32. package/dist/animation/scaletrack.js +3 -0
  33. package/dist/animation/scaletrack.js.map +1 -1
  34. package/dist/animation/skeleton.js +254 -79
  35. package/dist/animation/skeleton.js.map +1 -1
  36. package/dist/animation/skeleton_modifier.js.map +1 -1
  37. package/dist/animation/spring/spring_particle.js +4 -4
  38. package/dist/animation/spring/spring_particle.js.map +1 -1
  39. package/dist/animation/spring_modifier.js.map +1 -1
  40. package/dist/animation/translationtrack.js +3 -0
  41. package/dist/animation/translationtrack.js.map +1 -1
  42. package/dist/app/engine.js +129 -17
  43. package/dist/app/engine.js.map +1 -1
  44. package/dist/app/scriptregistry.js +251 -80
  45. package/dist/app/scriptregistry.js.map +1 -1
  46. package/dist/asset/assetmanager.js +133 -102
  47. package/dist/asset/assetmanager.js.map +1 -1
  48. package/dist/asset/loaders/gltf/gltf_loader.js +18 -14
  49. package/dist/asset/loaders/gltf/gltf_loader.js.map +1 -1
  50. package/dist/asset/loaders/loader.js +1 -6
  51. package/dist/asset/loaders/loader.js.map +1 -1
  52. package/dist/asset/loaders/zabc/zabc_loader.js.map +1 -1
  53. package/dist/asset/model.js +1052 -183
  54. package/dist/asset/model.js.map +1 -1
  55. package/dist/avatar/wardrobe.js +474 -0
  56. package/dist/avatar/wardrobe.js.map +1 -0
  57. package/dist/index.d.ts +1810 -233
  58. package/dist/index.js +13 -3
  59. package/dist/index.js.map +1 -1
  60. package/dist/material/material.js +1 -1
  61. package/dist/material/material.js.map +1 -1
  62. package/dist/material/mixins/lightmodel/pbrmetallicroughness.js +6 -3
  63. package/dist/material/mixins/lightmodel/pbrmetallicroughness.js.map +1 -1
  64. package/dist/material/mixins/pbr/common.js +72 -15
  65. package/dist/material/mixins/pbr/common.js.map +1 -1
  66. package/dist/material/msdf_text.js +180 -0
  67. package/dist/material/msdf_text.js.map +1 -0
  68. package/dist/material/msdf_text_sprite.js +64 -0
  69. package/dist/material/msdf_text_sprite.js.map +1 -0
  70. package/dist/material/pbrblueprint.js +21 -6
  71. package/dist/material/pbrblueprint.js.map +1 -1
  72. package/dist/material/shader/helper.js +277 -277
  73. package/dist/material/shader/helper.js.map +1 -1
  74. package/dist/material/sprite_sdf.js +106 -0
  75. package/dist/material/sprite_sdf.js.map +1 -0
  76. package/dist/posteffect/ssr.js +1 -0
  77. package/dist/posteffect/ssr.js.map +1 -1
  78. package/dist/render/abuffer_oit.js +1 -0
  79. package/dist/render/abuffer_oit.js.map +1 -1
  80. package/dist/render/cluster_light.js.map +1 -1
  81. package/dist/render/cull_visitor.js +28 -0
  82. package/dist/render/cull_visitor.js.map +1 -1
  83. package/dist/render/drawable.js.map +1 -1
  84. package/dist/render/drawable_mixin.js +1 -0
  85. package/dist/render/drawable_mixin.js.map +1 -1
  86. package/dist/render/envlight.js +54 -1
  87. package/dist/render/envlight.js.map +1 -1
  88. package/dist/render/fbm_wavegenerator.js +1 -0
  89. package/dist/render/fbm_wavegenerator.js.map +1 -1
  90. package/dist/render/gerstner_wavegenerator.js +1 -0
  91. package/dist/render/gerstner_wavegenerator.js.map +1 -1
  92. package/dist/render/globalbindgroup_allocator.js +1 -0
  93. package/dist/render/globalbindgroup_allocator.js.map +1 -1
  94. package/dist/render/render_queue.js +1 -0
  95. package/dist/render/render_queue.js.map +1 -1
  96. package/dist/render/sky.js +9 -0
  97. package/dist/render/sky.js.map +1 -1
  98. package/dist/scene/basesprite.js +1 -5
  99. package/dist/scene/basesprite.js.map +1 -1
  100. package/dist/scene/batchgroup.js +18 -8
  101. package/dist/scene/batchgroup.js.map +1 -1
  102. package/dist/scene/environment.js +16 -2
  103. package/dist/scene/environment.js.map +1 -1
  104. package/dist/scene/mesh.js +164 -102
  105. package/dist/scene/mesh.js.map +1 -1
  106. package/dist/scene/meshdrawable.js +96 -0
  107. package/dist/scene/meshdrawable.js.map +1 -0
  108. package/dist/scene/msdftext.js +341 -0
  109. package/dist/scene/msdftext.js.map +1 -0
  110. package/dist/scene/msdftextsprite.js +349 -0
  111. package/dist/scene/msdftextsprite.js.map +1 -0
  112. package/dist/scene/particlesys.js +1 -0
  113. package/dist/scene/particlesys.js.map +1 -1
  114. package/dist/scene/scene.js +2 -0
  115. package/dist/scene/scene.js.map +1 -1
  116. package/dist/scene/scene_node.js +437 -230
  117. package/dist/scene/scene_node.js.map +1 -1
  118. package/dist/scene/sdftextsprite.js +322 -0
  119. package/dist/scene/sdftextsprite.js.map +1 -0
  120. package/dist/scene/terrain-cm/grass.js +1 -0
  121. package/dist/scene/terrain-cm/grass.js.map +1 -1
  122. package/dist/scene/terrain-cm/grassmaterial.js +1 -0
  123. package/dist/scene/terrain-cm/grassmaterial.js.map +1 -1
  124. package/dist/scene/terrain-cm/terrain-cm.js +1 -0
  125. package/dist/scene/terrain-cm/terrain-cm.js.map +1 -1
  126. package/dist/scene/textsprite.js +120 -0
  127. package/dist/scene/textsprite.js.map +1 -0
  128. package/dist/scene/water.js +1 -0
  129. package/dist/scene/water.js.map +1 -1
  130. package/dist/shadow/shader.js +1 -0
  131. package/dist/shadow/shader.js.map +1 -1
  132. package/dist/text/font/font_asset.js +884 -0
  133. package/dist/text/font/font_asset.js.map +1 -0
  134. package/dist/text/font/sfnt_reader.js +43 -0
  135. package/dist/text/font/sfnt_reader.js.map +1 -0
  136. package/dist/text/msdf/generator.js +417 -0
  137. package/dist/text/msdf/generator.js.map +1 -0
  138. package/dist/text/msdf/shape.js +146 -0
  139. package/dist/text/msdf/shape.js.map +1 -0
  140. package/dist/text/runtime/msdf_glyph_atlas.js +146 -0
  141. package/dist/text/runtime/msdf_glyph_atlas.js.map +1 -0
  142. package/dist/text/runtime/msdf_text_atlas_manager.js +50 -0
  143. package/dist/text/runtime/msdf_text_atlas_manager.js.map +1 -0
  144. package/dist/text/runtime/text_layout.js +96 -0
  145. package/dist/text/runtime/text_layout.js.map +1 -0
  146. package/dist/utility/blueprint/material/inputs.js +188 -1
  147. package/dist/utility/blueprint/material/inputs.js.map +1 -1
  148. package/dist/utility/blueprint/material/ir.js +16 -1
  149. package/dist/utility/blueprint/material/ir.js.map +1 -1
  150. package/dist/utility/blueprint/material/pbr.js +32 -0
  151. package/dist/utility/blueprint/material/pbr.js.map +1 -1
  152. package/dist/utility/bounding_volume.js.map +1 -1
  153. package/dist/utility/pmrem.js +34 -8
  154. package/dist/utility/pmrem.js.map +1 -1
  155. package/dist/utility/serialization/manager.js +340 -283
  156. package/dist/utility/serialization/manager.js.map +1 -1
  157. package/dist/utility/serialization/scene/animation.js +702 -7
  158. package/dist/utility/serialization/scene/animation.js.map +1 -1
  159. package/dist/utility/serialization/scene/batch.js +2 -0
  160. package/dist/utility/serialization/scene/batch.js.map +1 -1
  161. package/dist/utility/serialization/scene/camera.js +2 -0
  162. package/dist/utility/serialization/scene/camera.js.map +1 -1
  163. package/dist/utility/serialization/scene/light.js +2 -0
  164. package/dist/utility/serialization/scene/light.js.map +1 -1
  165. package/dist/utility/serialization/scene/material.js +1 -0
  166. package/dist/utility/serialization/scene/material.js.map +1 -1
  167. package/dist/utility/serialization/scene/mesh.js +66 -4
  168. package/dist/utility/serialization/scene/mesh.js.map +1 -1
  169. package/dist/utility/serialization/scene/node.js +189 -8
  170. package/dist/utility/serialization/scene/node.js.map +1 -1
  171. package/dist/utility/serialization/scene/particle.js +2 -0
  172. package/dist/utility/serialization/scene/particle.js.map +1 -1
  173. package/dist/utility/serialization/scene/primitive.js +1 -0
  174. package/dist/utility/serialization/scene/primitive.js.map +1 -1
  175. package/dist/utility/serialization/scene/sprite.js +2 -0
  176. package/dist/utility/serialization/scene/sprite.js.map +1 -1
  177. package/dist/utility/serialization/scene/terrain.js +2 -0
  178. package/dist/utility/serialization/scene/terrain.js.map +1 -1
  179. package/dist/utility/serialization/scene/text.js +516 -0
  180. package/dist/utility/serialization/scene/text.js.map +1 -0
  181. package/dist/utility/serialization/scene/water.js +2 -0
  182. package/dist/utility/serialization/scene/water.js.map +1 -1
  183. package/dist/utility/serialization/types.js.map +1 -1
  184. package/dist/utility/textures/sheenlut.js +138 -0
  185. package/dist/utility/textures/sheenlut.js.map +1 -0
  186. package/dist/values.js +48 -48
  187. package/dist/values.js.map +1 -1
  188. package/package.json +3 -3
@@ -1,4 +1,4 @@
1
- import { applyMixins, DRef } from '@zephyr3d/base';
1
+ import { castObservable, applyMixins, DRef } from '@zephyr3d/base';
2
2
  import { GraphNode } from './graph_node.js';
3
3
  import { ShaderHelper } from '../material/shader/helper.js';
4
4
  import { LambertMaterial } from '../material/lambert.js';
@@ -17,22 +17,27 @@ import '../material/pbrsg.js';
17
17
  import '../material/pbrblueprint.js';
18
18
  import '../material/sprite.js';
19
19
  import '../material/sprite_std.js';
20
+ import '../material/msdf_text.js';
20
21
  import '../utility/blueprint/material/texture.js';
22
+ import { BoundingBox } from '../utility/bounding_volume.js';
21
23
  import { mixinDrawable } from '../render/drawable_mixin.js';
24
+ import { calculateMorphBoundingBox } from '../animation/morphtarget.js';
22
25
 
23
- /**
24
- * Mesh node
25
- * @public
26
- */ class Mesh extends applyMixins(GraphNode, mixinDrawable) {
26
+ const MeshBase = castObservable(applyMixins(GraphNode, mixinDrawable))();
27
+ /**
28
+ * Mesh node
29
+ * @public
30
+ */ class Mesh extends MeshBase {
27
31
  /** @internal */ _primitive;
28
32
  /** @internal */ _material;
29
33
  /** @internal */ _castShadow;
30
34
  /** @internal */ _skinnedBoundingInfo;
31
35
  /** @internal */ _animatedBoundingBox;
32
- /** @internal */ _skeletonName;
36
+ /** @internal */ _skinBindingName;
33
37
  /** @internal */ _boneMatrices;
34
38
  /** @internal */ _morphData;
35
39
  /** @internal */ _morphInfo;
40
+ /** @internal */ _morphBoundingInfo;
36
41
  /** @internal */ _morphDirty;
37
42
  /** @internal */ _instanceHash;
38
43
  /** @internal */ _batchable;
@@ -43,9 +48,9 @@ import { mixinDrawable } from '../render/drawable_mixin.js';
43
48
  /** @internal */ _materialChangeTag;
44
49
  /** @internal */ _primitiveChangeTag;
45
50
  /** @internal */ _postUpdateCallbacks;
46
- /**
47
- * Creates an instance of mesh node
48
- * @param scene - The scene to which the mesh node belongs
51
+ /**
52
+ * Creates an instance of mesh node
53
+ * @param scene - The scene to which the mesh node belongs
49
54
  */ constructor(scene, primitive, material){
50
55
  super(scene);
51
56
  this._primitive = new DRef();
@@ -56,6 +61,7 @@ import { mixinDrawable } from '../render/drawable_mixin.js';
56
61
  this._boneMatrices = new DRef();
57
62
  this._morphData = null;
58
63
  this._morphInfo = null;
64
+ this._morphBoundingInfo = null;
59
65
  this._morphDirty = false;
60
66
  this._instanceHash = null;
61
67
  this._pickTarget = {
@@ -65,30 +71,25 @@ import { mixinDrawable } from '../render/drawable_mixin.js';
65
71
  this.primitive = primitive ?? null;
66
72
  this.material = material ?? Mesh._getDefaultMaterial();
67
73
  this._suspendSkinning = false;
68
- this._skeletonName = '';
74
+ this._skinBindingName = '';
69
75
  this._renderBundle = {};
70
76
  this._useRenderBundle = true;
71
77
  this._materialChangeTag = null;
72
78
  this._primitiveChangeTag = null;
73
79
  this._postUpdateCallbacks = new Set();
74
80
  }
75
- /**
76
- * {@inheritDoc Drawable.getName}
77
- */ getName() {
78
- return this._name;
79
- }
80
- /**
81
- * Returns the batch instance ID for the current render pass.
81
+ /**
82
+ * Returns the batch instance ID for the current render pass.
82
83
  */ getInstanceId(_renderPass) {
83
84
  return `${this._instanceHash}:${this.worldMatrixDet >= 0}`;
84
85
  }
85
- /**
86
- * Returns the packed instance-uniform buffer used for batching.
86
+ /**
87
+ * Returns the packed instance-uniform buffer used for batching.
87
88
  */ getInstanceUniforms() {
88
89
  return this._material.get().$instanceUniforms;
89
90
  }
90
- /**
91
- * {@inheritDoc Drawable.getPickTarget }
91
+ /**
92
+ * {@inheritDoc Drawable.getPickTarget }
92
93
  */ getPickTarget() {
93
94
  return this._pickTarget;
94
95
  }
@@ -99,11 +100,17 @@ import { mixinDrawable } from '../render/drawable_mixin.js';
99
100
  };
100
101
  }
101
102
  get skeletonName() {
102
- return this._skeletonName;
103
+ return this._skinBindingName;
103
104
  }
104
105
  set skeletonName(name) {
105
- if (name !== this._skeletonName) {
106
- this._skeletonName = name;
106
+ this.skinBindingName = name;
107
+ }
108
+ get skinBindingName() {
109
+ return this._skinBindingName;
110
+ }
111
+ set skinBindingName(name) {
112
+ if (name !== this._skinBindingName) {
113
+ this._skinBindingName = name;
107
114
  this.updateSkeletonState();
108
115
  }
109
116
  }
@@ -123,7 +130,7 @@ import { mixinDrawable } from '../render/drawable_mixin.js';
123
130
  this._castShadow = b;
124
131
  }
125
132
  /** Primitive of the mesh */ get primitive() {
126
- return this._primitive.get();
133
+ return this._primitive?.get() ?? null;
127
134
  }
128
135
  set primitive(prim) {
129
136
  const currentPrimitive = this._primitive.get();
@@ -139,10 +146,11 @@ import { mixinDrawable } from '../render/drawable_mixin.js';
139
146
  this.invalidateBoundingVolume();
140
147
  RenderBundleWrapper.drawableChanged(this);
141
148
  this._primitiveChangeTag = null;
149
+ this.dispatchEvent('primitive_changed', prim);
142
150
  }
143
151
  }
144
152
  /** Material of the mesh */ get material() {
145
- return this._material.get();
153
+ return this._material?.get() ?? null;
146
154
  }
147
155
  set material(m) {
148
156
  if (this._material.get() !== m) {
@@ -153,28 +161,44 @@ import { mixinDrawable } from '../render/drawable_mixin.js';
153
161
  this._instanceHash = this._primitive.get() && m ? `${this.constructor.name}:${this._scene?.id ?? 0}:${this._primitive.get().id}:${m.instanceId}` : null;
154
162
  RenderBundleWrapper.drawableChanged(this);
155
163
  this._materialChangeTag = null;
164
+ this.dispatchEvent('material_changed', m);
156
165
  }
157
166
  }
158
- /**
159
- * {@inheritDoc SceneNode.isMesh}
167
+ /**
168
+ * {@inheritDoc SceneNode.isMesh}
160
169
  */ isMesh() {
161
170
  return true;
162
171
  }
163
- /**
164
- * Sets the bounding box for animation
165
- * @param bbox - The bounding box for animation
172
+ /**
173
+ * Sets the bounding box for animation
174
+ * @param bbox - The bounding box for animation
166
175
  */ setAnimatedBoundingBox(bbox) {
167
176
  this._animatedBoundingBox = bbox;
168
177
  this.invalidateBoundingVolume();
169
178
  }
170
- /**
171
- * Gets the bounding box for animation
179
+ /**
180
+ * Gets the bounding box for animation
172
181
  */ getAnimatedBoundingBox() {
173
182
  return this._animatedBoundingBox ?? null;
174
183
  }
175
- /**
176
- * Sets the texture that contains the bone matrices for skeletal animation
177
- * @param matrices - The texture that contains the bone matrices
184
+ /**
185
+ * Sets morph target bounding data used to update the animated bounding box when weights change.
186
+ * @param info - Morph target bounding data
187
+ */ setMorphBoundingInfo(info) {
188
+ this._morphBoundingInfo = info ? {
189
+ targetBoxes: info.targetBoxes.map((box)=>box.clone()),
190
+ originBox: info.originBox.clone()
191
+ } : null;
192
+ this.updateMorphBoundingBox();
193
+ }
194
+ /**
195
+ * Gets morph target bounding data.
196
+ */ getMorphBoundingInfo() {
197
+ return this._morphBoundingInfo;
198
+ }
199
+ /**
200
+ * Sets the texture that contains the bone matrices for skeletal animation
201
+ * @param matrices - The texture that contains the bone matrices
178
202
  */ setBoneMatrices(matrices) {
179
203
  if (this._boneMatrices.get() !== matrices) {
180
204
  this._boneMatrices.set(matrices);
@@ -182,9 +206,9 @@ import { mixinDrawable } from '../render/drawable_mixin.js';
182
206
  RenderBundleWrapper.drawableChanged(this);
183
207
  }
184
208
  }
185
- /**
186
- * Sets the texture that contains the morph target data
187
- * @param data - The texture that contains the morph target data
209
+ /**
210
+ * Sets the texture that contains the morph target data
211
+ * @param data - The texture that contains the morph target data
188
212
  */ setMorphData(data) {
189
213
  if (!data) {
190
214
  if (this._morphData) {
@@ -220,20 +244,20 @@ import { mixinDrawable } from '../render/drawable_mixin.js';
220
244
  RenderBundleWrapper.drawableChanged(this);
221
245
  }
222
246
  }
223
- /**
224
- * Sets the skinned bounding info
225
- * @param info - The skinned bounding info
247
+ /**
248
+ * Sets the skinned bounding info
249
+ * @param info - The skinned bounding info
226
250
  */ setSkinnedBoundingInfo(info) {
227
251
  this._skinnedBoundingInfo = info;
228
252
  }
229
- /**
230
- * {@inheritDoc Drawable.getMorphData}
253
+ /**
254
+ * {@inheritDoc Drawable.getMorphData}
231
255
  */ getMorphData() {
232
256
  return this._morphData;
233
257
  }
234
- /**
235
- * Sets the buffer that contains the morph target information
236
- * @param info - The buffer that contains the morph target information
258
+ /**
259
+ * Sets the buffer that contains the morph target information
260
+ * @param info - The buffer that contains the morph target information
237
261
  */ setMorphInfo(info) {
238
262
  if (!info) {
239
263
  if (this._morphInfo) {
@@ -267,27 +291,28 @@ import { mixinDrawable } from '../render/drawable_mixin.js';
267
291
  this._morphInfo.buffer.set(morphUniformBuffer);
268
292
  }
269
293
  this._morphDirty = false;
294
+ this.updateMorphBoundingBox();
270
295
  this._renderBundle = {};
271
296
  RenderBundleWrapper.drawableChanged(this);
272
297
  }
273
298
  }
274
- /**
275
- * {@inheritDoc Drawable.getMorphInfo}
299
+ /**
300
+ * {@inheritDoc Drawable.getMorphInfo}
276
301
  */ getMorphInfo() {
277
302
  return this._morphInfo;
278
303
  }
279
- /**
280
- * Get the number of morph targets
281
- *
282
- * @returns The number of morph targets
304
+ /**
305
+ * Get the number of morph targets
306
+ *
307
+ * @returns The number of morph targets
283
308
  */ getNumMorphTargets() {
284
309
  return this._morphInfo?.data[3] ?? 0;
285
310
  }
286
- /**
287
- * Get the name of the morph target by index
288
- *
289
- * @param index - The index of the morph target
290
- * @returns The name of the morph target, or null if not found
311
+ /**
312
+ * Get the name of the morph target by index
313
+ *
314
+ * @param index - The index of the morph target
315
+ * @returns The name of the morph target, or null if not found
291
316
  */ getMorphTargetName(index) {
292
317
  if (this._morphInfo && index >= 0 && index < this._morphInfo.data[3]) {
293
318
  const name = Object.keys(this._morphInfo.names).find((key)=>this._morphInfo.names[key] === index);
@@ -295,28 +320,46 @@ import { mixinDrawable } from '../render/drawable_mixin.js';
295
320
  }
296
321
  return null;
297
322
  }
298
- /**
299
- * Update morph target weight
300
- *
301
- * @param name - The name of the morph target
302
- * @param weight - The weight of the morph target
323
+ /**
324
+ * Get the index of the morph target by name
325
+ * @param name - The name of the morph target
326
+ * @returns The index of the morph target, or -1 if not found
327
+ */ getMorphTargetIndexByName(name) {
328
+ return this._morphInfo?.names?.[name] ?? -1;
329
+ }
330
+ /**
331
+ * Update morph target weight
332
+ *
333
+ * @param name - The name of the morph target
334
+ * @param weight - The weight of the morph target
303
335
  */ setMorphWeight(name, weight) {
304
- const index = this._morphInfo?.names?.[name];
305
- if (index !== undefined && index >= 0 && index < this._morphInfo.data[3]) {
336
+ const index = this.getMorphTargetIndexByName(name);
337
+ if (index >= 0) {
338
+ this.setMorphWeightByIndex(index, weight);
339
+ }
340
+ }
341
+ /**
342
+ * Update morph target weight by index
343
+ *
344
+ * @param index - The index of the morph target
345
+ * @param weight - The weight of the morph target
346
+ */ setMorphWeightByIndex(index, weight) {
347
+ if (index >= 0 && index < this._morphInfo.data[3]) {
306
348
  if (this._morphInfo.data[4 + index] !== weight) {
307
349
  this._morphInfo.data[4 + index] = weight;
308
350
  this._morphDirty = true;
351
+ this.updateMorphBoundingBox();
309
352
  this.scene.queueUpdateNode(this);
310
353
  }
311
354
  } else {
312
- console.warn(`Morph target ${name} not found`);
355
+ console.warn(`Morph target index out of range: ${index}`);
313
356
  }
314
357
  }
315
- /**
316
- * Get morph target weight
317
- *
318
- * @param name - The name of the morph target
319
- * @returns The weight of the morph target, or 0 if not found
358
+ /**
359
+ * Get morph target weight
360
+ *
361
+ * @param name - The name of the morph target
362
+ * @returns The weight of the morph target, or 0 if not found
320
363
  */ getMorphWeight(name) {
321
364
  const index = this._morphInfo?.names?.[name];
322
365
  if (index !== undefined && index >= 0 && index < this._morphInfo.data[3]) {
@@ -324,14 +367,15 @@ import { mixinDrawable } from '../render/drawable_mixin.js';
324
367
  }
325
368
  return 0;
326
369
  }
327
- /**
328
- * Update morph target weight
329
- *
330
- * @param weight - The morph target weights. The length must not exceed the mesh's morph target count.
370
+ /**
371
+ * Update morph target weights
372
+ *
373
+ * @param weight - The morph target weights. The length must not exceed the mesh's morph target count.
331
374
  */ updateMorphWeights(weight) {
332
375
  if (this._morphInfo && weight && weight.length <= this._morphInfo.data[3]) {
333
376
  this._morphInfo.data.set(weight, 4);
334
377
  this._morphDirty = true;
378
+ this.updateMorphBoundingBox();
335
379
  this.scene.queueUpdateNode(this);
336
380
  }
337
381
  }
@@ -355,35 +399,50 @@ import { mixinDrawable } from '../render/drawable_mixin.js';
355
399
  this._postUpdateCallbacks.delete(callback);
356
400
  }
357
401
  }
358
- /**
359
- * {@inheritDoc Drawable.isBatchable}
402
+ /**
403
+ * {@inheritDoc Drawable.isBatchable}
360
404
  */ isBatchable() {
361
405
  return this._batchable && !this._boneMatrices.get() && !this._morphData && (this._material.get()?.isBatchable() ?? false);
362
406
  }
363
- /**
364
- * {@inheritDoc Drawable.getQueueType}
407
+ /**
408
+ * {@inheritDoc Drawable.getQueueType}
365
409
  */ getQueueType() {
366
410
  return this.material?.getQueueType() ?? QUEUE_OPAQUE;
367
411
  }
368
- /**
369
- * {@inheritDoc Drawable.isUnlit}
412
+ /**
413
+ * {@inheritDoc Drawable.isUnlit}
370
414
  */ isUnlit() {
371
415
  return !this.material?.supportLighting();
372
416
  }
373
- /**
374
- * {@inheritDoc Drawable.needSceneColor}
417
+ /**
418
+ * {@inheritDoc Drawable.needSceneColor}
375
419
  */ needSceneColor() {
376
420
  return this.material?.needSceneColor() ?? false;
377
421
  }
378
- /**
379
- * {@inheritDoc Drawable.needSceneDepth}
422
+ /**
423
+ * {@inheritDoc Drawable.needSceneDepth}
380
424
  */ needSceneDepth() {
381
425
  return this.material?.needSceneDepth() ?? false;
382
426
  }
427
+ /** @internal */ updateMorphBoundingBox() {
428
+ if (!this._morphInfo || !this._morphBoundingInfo) {
429
+ return;
430
+ }
431
+ const numTargets = Math.min(this._morphInfo.data[3], this._morphBoundingInfo.targetBoxes.length);
432
+ if (numTargets <= 0) {
433
+ return;
434
+ }
435
+ const weights = this._morphInfo.data instanceof Float32Array ? this._morphInfo.data.subarray(4, 4 + numTargets) : new Float32Array(Array.from(this._morphInfo.data.subarray(4, 4 + numTargets)));
436
+ const bbox = new BoundingBox();
437
+ calculateMorphBoundingBox(bbox, this._morphBoundingInfo.targetBoxes, weights, numTargets);
438
+ bbox.minPoint.addBy(this._morphBoundingInfo.originBox.minPoint);
439
+ bbox.maxPoint.addBy(this._morphBoundingInfo.originBox.maxPoint);
440
+ this.setAnimatedBoundingBox(bbox);
441
+ }
383
442
  /** @internal */ updateMorphState() {
384
443
  if (this._morphInfo && this._morphDirty) {
385
- console.log(`jawOpen: ${this._morphInfo.data[20]}`);
386
444
  this._morphInfo.buffer.get().bufferSubData(4 * 4, this._morphInfo.data, 4, this._morphInfo.data[3]);
445
+ this.updateMorphBoundingBox();
387
446
  this._morphDirty = false;
388
447
  }
389
448
  }
@@ -393,21 +452,23 @@ import { mixinDrawable } from '../render/drawable_mixin.js';
393
452
  this.setAnimatedBoundingBox(null);
394
453
  return;
395
454
  }
396
- const skeleton = this._skeletonName && this.findSkeletonById(this._skeletonName);
397
- if (skeleton) {
398
- this.setBoneMatrices(skeleton.jointTexture);
399
- skeleton.computeBoundingBox(this._skinnedBoundingInfo, this.invWorldMatrix);
455
+ const binding = this._skinBindingName && this.findSkinBindingById(this._skinBindingName);
456
+ if (binding) {
457
+ this.setBoneMatrices(binding.jointTexture);
458
+ binding.computeBoundingBox(this._skinnedBoundingInfo, this.invWorldMatrix);
400
459
  this.setAnimatedBoundingBox(this._skinnedBoundingInfo.boundingBox);
401
460
  } else {
402
461
  this.setBoneMatrices(null);
403
- this.setAnimatedBoundingBox(null);
462
+ if (!this._morphInfo || !this._morphBoundingInfo) {
463
+ this.setAnimatedBoundingBox(null);
464
+ }
404
465
  }
405
- if (this._skeletonName) {
466
+ if (this._skinBindingName) {
406
467
  this.scene.queueUpdateNode(this);
407
468
  }
408
469
  }
409
- /**
410
- * {@inheritDoc Drawable.draw}
470
+ /**
471
+ * {@inheritDoc Drawable.draw}
411
472
  */ draw(ctx, renderQueue, hash) {
412
473
  const material = this.material;
413
474
  const primitive = this.primitive;
@@ -433,23 +494,23 @@ import { mixinDrawable } from '../render/drawable_mixin.js';
433
494
  }
434
495
  }
435
496
  }
436
- /**
437
- * {@inheritDoc Drawable.getMaterial}
497
+ /**
498
+ * {@inheritDoc Drawable.getMaterial}
438
499
  */ getMaterial() {
439
500
  return this.material;
440
501
  }
441
- /**
442
- * {@inheritDoc Drawable.getPrimitive}
502
+ /**
503
+ * {@inheritDoc Drawable.getPrimitive}
443
504
  */ getPrimitive() {
444
505
  return this.primitive;
445
506
  }
446
- /**
447
- * {@inheritDoc Drawable.getBoneMatrices}
507
+ /**
508
+ * {@inheritDoc Drawable.getBoneMatrices}
448
509
  */ getBoneMatrices() {
449
510
  return this._boneMatrices.get();
450
511
  }
451
- /**
452
- * {@inheritDoc Drawable.getNode}
512
+ /**
513
+ * {@inheritDoc Drawable.getNode}
453
514
  */ getNode() {
454
515
  // mesh transform should be ignored when skinned
455
516
  return this;
@@ -471,6 +532,7 @@ import { mixinDrawable } from '../render/drawable_mixin.js';
471
532
  this._boneMatrices.dispose();
472
533
  this.setMorphData(null);
473
534
  this.setMorphInfo(null);
535
+ this.setMorphBoundingInfo(null);
474
536
  this._renderBundle = null;
475
537
  RenderBundleWrapper.drawableChanged(this);
476
538
  }