@zephyr3d/scene 0.9.4 → 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 (102) 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_modifier.js.map +1 -1
  38. package/dist/animation/translationtrack.js +3 -0
  39. package/dist/animation/translationtrack.js.map +1 -1
  40. package/dist/app/engine.js +171 -107
  41. package/dist/app/engine.js.map +1 -1
  42. package/dist/app/scriptregistry.js +251 -80
  43. package/dist/app/scriptregistry.js.map +1 -1
  44. package/dist/asset/assetmanager.js +344 -365
  45. package/dist/asset/assetmanager.js.map +1 -1
  46. package/dist/asset/loaders/gltf/gltf_loader.js +17 -14
  47. package/dist/asset/loaders/gltf/gltf_loader.js.map +1 -1
  48. package/dist/asset/loaders/loader.js +1 -6
  49. package/dist/asset/loaders/loader.js.map +1 -1
  50. package/dist/asset/loaders/zabc/zabc_loader.js.map +1 -1
  51. package/dist/asset/model.js +1000 -131
  52. package/dist/asset/model.js.map +1 -1
  53. package/dist/avatar/wardrobe.js +474 -0
  54. package/dist/avatar/wardrobe.js.map +1 -0
  55. package/dist/index.d.ts +1125 -199
  56. package/dist/index.js +3 -2
  57. package/dist/index.js.map +1 -1
  58. package/dist/material/mixins/lightmodel/pbrmetallicroughness.js +6 -3
  59. package/dist/material/mixins/lightmodel/pbrmetallicroughness.js.map +1 -1
  60. package/dist/material/mixins/pbr/common.js +72 -15
  61. package/dist/material/mixins/pbr/common.js.map +1 -1
  62. package/dist/material/msdf_text_sprite.js +4 -4
  63. package/dist/material/msdf_text_sprite.js.map +1 -1
  64. package/dist/material/pbrblueprint.js +102 -102
  65. package/dist/material/pbrblueprint.js.map +1 -1
  66. package/dist/render/envlight.js +54 -1
  67. package/dist/render/envlight.js.map +1 -1
  68. package/dist/render/sky.js +9 -0
  69. package/dist/render/sky.js.map +1 -1
  70. package/dist/scene/batchgroup.js +11 -13
  71. package/dist/scene/batchgroup.js.map +1 -1
  72. package/dist/scene/environment.js +15 -2
  73. package/dist/scene/environment.js.map +1 -1
  74. package/dist/scene/mesh.js +79 -16
  75. package/dist/scene/mesh.js.map +1 -1
  76. package/dist/scene/scene.js +1 -0
  77. package/dist/scene/scene.js.map +1 -1
  78. package/dist/scene/scene_node.js +203 -2
  79. package/dist/scene/scene_node.js.map +1 -1
  80. package/dist/text/font/font_asset.js.map +1 -1
  81. package/dist/text/msdf/generator.js.map +1 -1
  82. package/dist/text/msdf/shape.js +4 -1
  83. package/dist/text/msdf/shape.js.map +1 -1
  84. package/dist/text/runtime/msdf_text_atlas_manager.js +4 -1
  85. package/dist/text/runtime/msdf_text_atlas_manager.js.map +1 -1
  86. package/dist/utility/blueprint/material/inputs.js +1157 -1154
  87. package/dist/utility/blueprint/material/inputs.js.map +1 -1
  88. package/dist/utility/bounding_volume.js.map +1 -1
  89. package/dist/utility/pmrem.js +34 -8
  90. package/dist/utility/pmrem.js.map +1 -1
  91. package/dist/utility/serialization/manager.js +22 -9
  92. package/dist/utility/serialization/manager.js.map +1 -1
  93. package/dist/utility/serialization/scene/animation.js +700 -7
  94. package/dist/utility/serialization/scene/animation.js.map +1 -1
  95. package/dist/utility/serialization/scene/mesh.js +64 -4
  96. package/dist/utility/serialization/scene/mesh.js.map +1 -1
  97. package/dist/utility/serialization/scene/node.js +187 -8
  98. package/dist/utility/serialization/scene/node.js.map +1 -1
  99. package/dist/utility/serialization/types.js.map +1 -1
  100. package/dist/utility/textures/sheenlut.js +138 -0
  101. package/dist/utility/textures/sheenlut.js.map +1 -0
  102. package/package.json +2 -2
@@ -1,10 +1,10 @@
1
- import { Interpolator, base64ToUint8Array, uint8ArrayToBase64, AABB, Vector3, Matrix4x4, Quaternion } from '@zephyr3d/base';
1
+ import { Vector3, Interpolator, base64ToUint8Array, uint8ArrayToBase64, AABB, Matrix4x4, Quaternion, DRef, InterpolatorScalar } from '@zephyr3d/base';
2
2
  import { AnimationClip } from '../../../animation/animation.js';
3
3
  import { NodeRotationTrack } from '../../../animation/rotationtrack.js';
4
4
  import { NodeEulerRotationTrack } from '../../../animation/eulerrotationtrack.js';
5
5
  import { NodeTranslationTrack } from '../../../animation/translationtrack.js';
6
6
  import { NodeScaleTrack } from '../../../animation/scaletrack.js';
7
- import { Skeleton } from '../../../animation/skeleton.js';
7
+ import { Skeleton, SkeletonRig, SkinBinding } from '../../../animation/skeleton.js';
8
8
  import { AnimationTrack } from '../../../animation/animationtrack.js';
9
9
  import { PropertyTrack } from '../../../animation/proptrack.js';
10
10
  import { MorphTargetTrack } from '../../../animation/morphtrack.js';
@@ -14,7 +14,8 @@ import { PCAGeometryCacheTrack } from '../../../animation/pca_geometry_cache_tra
14
14
  import '@zephyr3d/device';
15
15
  import '../../../animation/joint_dynamics/collision.js';
16
16
  import '../../../animation/joint_dynamics/solver.js';
17
- import '../../../animation/joint_dynamics/joint_dynamics_system.js';
17
+ import { createTransformAccess, JointDynamicsSystem } from '../../../animation/joint_dynamics/joint_dynamics_system.js';
18
+ import { JointDynamicsModifier } from '../../../animation/joint_dynamics_modifier.js';
18
19
  import { defineProps } from '../types.js';
19
20
  import '../../../scene/scene.js';
20
21
  import '../../../values.js';
@@ -51,6 +52,559 @@ import '../../../scene/terrain-cm/terrain-cm.js';
51
52
  import '../../../scene/terrain-cm/grass.js';
52
53
  import '../../../scene/raycast_visitor.js';
53
54
 
55
+ const jointDynamicsModifierSkeletons = new WeakMap();
56
+ function encodeSkeletonBindPose(bindPose) {
57
+ return uint8ArrayToBase64(new Uint8Array(new Float32Array([
58
+ ...bindPose.position,
59
+ ...bindPose.rotation,
60
+ ...bindPose.scale
61
+ ]).buffer));
62
+ }
63
+ function decodeSkeletonBindPose(encoded) {
64
+ const data = new Float32Array(base64ToUint8Array(encoded).buffer);
65
+ return {
66
+ position: new Vector3(data[0], data[1], data[2]),
67
+ rotation: new Quaternion(data[3], data[4], data[5], data[6]),
68
+ scale: new Vector3(data[7], data[8], data[9])
69
+ };
70
+ }
71
+ function vectorToArray(value) {
72
+ return [
73
+ value.x,
74
+ value.y,
75
+ value.z
76
+ ];
77
+ }
78
+ function vectorFromArray(value, defaultValue = Vector3.zero()) {
79
+ return Array.isArray(value) ? new Vector3(value[0] ?? 0, value[1] ?? 0, value[2] ?? 0) : defaultValue.clone();
80
+ }
81
+ function serializeScalarCurve(value) {
82
+ return {
83
+ mode: value.mode,
84
+ inputs: [
85
+ ...value.inputs
86
+ ],
87
+ outputs: [
88
+ ...value.outputs
89
+ ]
90
+ };
91
+ }
92
+ function deserializeScalarCurve(value) {
93
+ return new InterpolatorScalar(value?.mode ?? 'step', new Float32Array(value?.inputs ?? [
94
+ 0
95
+ ]), new Float32Array(value?.outputs ?? [
96
+ 0
97
+ ]));
98
+ }
99
+ function serializeControllerConfig(value) {
100
+ const curves = {};
101
+ for (const [key, curve] of Object.entries(value.curves)){
102
+ curves[key] = serializeScalarCurve(curve);
103
+ }
104
+ return {
105
+ gravity: vectorToArray(value.gravity),
106
+ windForce: vectorToArray(value.windForce),
107
+ relaxation: value.relaxation,
108
+ subSteps: value.subSteps,
109
+ rootSlideLimit: value.rootSlideLimit,
110
+ rootRotateLimit: value.rootRotateLimit,
111
+ constraintShrinkLimit: value.constraintShrinkLimit,
112
+ blendRatio: value.blendRatio,
113
+ stabilizationFrameRate: value.stabilizationFrameRate,
114
+ isFakeWave: value.isFakeWave,
115
+ fakeWaveSpeed: value.fakeWaveSpeed,
116
+ fakeWavePower: value.fakeWavePower,
117
+ enableSurfaceCollision: value.enableSurfaceCollision,
118
+ enableBroadPhase: value.enableBroadPhase,
119
+ preserveTwist: value.preserveTwist,
120
+ angleLimitConfig: {
121
+ ...value.angleLimitConfig
122
+ },
123
+ curves,
124
+ constraintOptions: {
125
+ ...value.constraintOptions
126
+ }
127
+ };
128
+ }
129
+ function deserializeControllerConfig(value) {
130
+ if (!value) {
131
+ return undefined;
132
+ }
133
+ const curves = Object.fromEntries(Object.entries(value.curves ?? {}).map(([key, curve])=>[
134
+ key,
135
+ deserializeScalarCurve(curve)
136
+ ]));
137
+ const config = {};
138
+ if (value.gravity) {
139
+ config.gravity = vectorFromArray(value.gravity, new Vector3(0, -9.8, 0));
140
+ }
141
+ if (value.windForce) {
142
+ config.windForce = vectorFromArray(value.windForce);
143
+ }
144
+ for (const key of [
145
+ 'relaxation',
146
+ 'subSteps',
147
+ 'rootSlideLimit',
148
+ 'rootRotateLimit',
149
+ 'constraintShrinkLimit',
150
+ 'blendRatio',
151
+ 'stabilizationFrameRate',
152
+ 'isFakeWave',
153
+ 'fakeWaveSpeed',
154
+ 'fakeWavePower',
155
+ 'enableSurfaceCollision',
156
+ 'enableBroadPhase',
157
+ 'preserveTwist'
158
+ ]){
159
+ if (value[key] !== undefined) {
160
+ config[key] = value[key];
161
+ }
162
+ }
163
+ if (value.angleLimitConfig) {
164
+ config.angleLimitConfig = {
165
+ ...value.angleLimitConfig
166
+ };
167
+ }
168
+ if (Object.keys(curves).length > 0) {
169
+ config.curves = curves;
170
+ }
171
+ if (value.constraintOptions) {
172
+ config.constraintOptions = {
173
+ ...value.constraintOptions
174
+ };
175
+ }
176
+ return config;
177
+ }
178
+ function findSerializedNode(root, id) {
179
+ if (!id) {
180
+ return null;
181
+ }
182
+ const prefabNode = root.getPrefabNode() ?? root;
183
+ return prefabNode.findNodeById(id) ?? root.scene?.findNodeById(id) ?? null;
184
+ }
185
+ function setJointDynamicsModifierSkeleton(modifier, skeleton) {
186
+ jointDynamicsModifierSkeletons.set(modifier, skeleton);
187
+ }
188
+ function getJointDynamicsModifierSkeleton(modifier) {
189
+ return jointDynamicsModifierSkeletons.get(modifier) ?? null;
190
+ }
191
+ const jointDynamicsPropOptions = {
192
+ group: 'Joint Dynamics'
193
+ };
194
+ function isJointDynamicsEditorPropPersistent() {
195
+ return false;
196
+ }
197
+ function updateJointDynamicsConfig(modifier, config) {
198
+ modifier.jointDynamicsSystem.controller.updateConfig(config);
199
+ }
200
+ function createJointDynamicsNumberProp(name, key, label, description, type, minValue) {
201
+ return {
202
+ name,
203
+ description,
204
+ type,
205
+ options: {
206
+ ...jointDynamicsPropOptions,
207
+ label,
208
+ ...minValue !== undefined ? {
209
+ minValue
210
+ } : {}
211
+ },
212
+ isPersistent: isJointDynamicsEditorPropPersistent,
213
+ get (value) {
214
+ value.num[0] = this.jointDynamicsSystem.controller.getConfig()[key];
215
+ },
216
+ set (value) {
217
+ updateJointDynamicsConfig(this, {
218
+ [key]: value.num[0]
219
+ });
220
+ }
221
+ };
222
+ }
223
+ function createJointDynamicsBooleanProp(name, key, label, description) {
224
+ return {
225
+ name,
226
+ description,
227
+ type: 'bool',
228
+ options: {
229
+ ...jointDynamicsPropOptions,
230
+ label
231
+ },
232
+ isPersistent: isJointDynamicsEditorPropPersistent,
233
+ get (value) {
234
+ value.bool[0] = this.jointDynamicsSystem.controller.getConfig()[key];
235
+ },
236
+ set (value) {
237
+ updateJointDynamicsConfig(this, {
238
+ [key]: value.bool[0]
239
+ });
240
+ }
241
+ };
242
+ }
243
+ function createJointDynamicsVectorProp(name, key, label, description) {
244
+ return {
245
+ name,
246
+ description,
247
+ type: 'vec3',
248
+ options: {
249
+ ...jointDynamicsPropOptions,
250
+ label
251
+ },
252
+ isPersistent: isJointDynamicsEditorPropPersistent,
253
+ get (value) {
254
+ const v = this.jointDynamicsSystem.controller.getConfig()[key];
255
+ value.num[0] = v.x;
256
+ value.num[1] = v.y;
257
+ value.num[2] = v.z;
258
+ },
259
+ set (value) {
260
+ updateJointDynamicsConfig(this, {
261
+ [key]: new Vector3(value.num[0], value.num[1], value.num[2])
262
+ });
263
+ }
264
+ };
265
+ }
266
+ function createJointDynamicsAngleLimitNumberProp(name, key, label, description) {
267
+ return {
268
+ name,
269
+ description,
270
+ type: 'float',
271
+ options: {
272
+ ...jointDynamicsPropOptions,
273
+ label
274
+ },
275
+ isPersistent: isJointDynamicsEditorPropPersistent,
276
+ get (value) {
277
+ value.num[0] = this.jointDynamicsSystem.controller.getConfig().angleLimitConfig[key];
278
+ },
279
+ set (value) {
280
+ updateJointDynamicsConfig(this, {
281
+ angleLimitConfig: {
282
+ [key]: value.num[0]
283
+ }
284
+ });
285
+ }
286
+ };
287
+ }
288
+ function createJointDynamicsAngleLimitBooleanProp(name, key, label, description) {
289
+ return {
290
+ name,
291
+ description,
292
+ type: 'bool',
293
+ options: {
294
+ ...jointDynamicsPropOptions,
295
+ label
296
+ },
297
+ isPersistent: isJointDynamicsEditorPropPersistent,
298
+ get (value) {
299
+ value.bool[0] = this.jointDynamicsSystem.controller.getConfig().angleLimitConfig[key];
300
+ },
301
+ set (value) {
302
+ updateJointDynamicsConfig(this, {
303
+ angleLimitConfig: {
304
+ [key]: value.bool[0]
305
+ }
306
+ });
307
+ }
308
+ };
309
+ }
310
+ function createJointDynamicsConstraintOptionProp(name, key, label, description) {
311
+ return {
312
+ name,
313
+ description,
314
+ type: 'bool',
315
+ options: {
316
+ ...jointDynamicsPropOptions,
317
+ label
318
+ },
319
+ isPersistent: isJointDynamicsEditorPropPersistent,
320
+ get (value) {
321
+ value.bool[0] = this.jointDynamicsSystem.controller.getConfig().constraintOptions[key];
322
+ },
323
+ set (value) {
324
+ updateJointDynamicsConfig(this, {
325
+ constraintOptions: {
326
+ [key]: value.bool[0]
327
+ }
328
+ });
329
+ }
330
+ };
331
+ }
332
+ function createJointDynamicsCurveProp(name, key, label, description) {
333
+ return {
334
+ name,
335
+ description,
336
+ type: 'float',
337
+ options: {
338
+ ...jointDynamicsPropOptions,
339
+ label
340
+ },
341
+ isPersistent: isJointDynamicsEditorPropPersistent,
342
+ get (value) {
343
+ value.num[0] = this.jointDynamicsSystem.controller.getConfig().curves[key].evaluate(0);
344
+ },
345
+ set (value) {
346
+ const val = value.num[0];
347
+ updateJointDynamicsConfig(this, {
348
+ curves: {
349
+ [key]: InterpolatorScalar.constant(val)
350
+ }
351
+ });
352
+ }
353
+ };
354
+ /*
355
+ return {
356
+ name,
357
+ description,
358
+ type: 'object',
359
+ readonly: true,
360
+ options: {
361
+ ...jointDynamicsPropOptions,
362
+ label,
363
+ objectTypes: [Interpolator],
364
+ edit: 'curve1f' as const
365
+ },
366
+ isPersistent: isJointDynamicsEditorPropPersistent,
367
+ get(this: JointDynamicsModifier, value: Required<Pick<PropertyValue, 'object'>>) {
368
+ value.object[0] = this.jointDynamicsSystem.controller.getConfig().curves[key];
369
+ },
370
+ set(this: JointDynamicsModifier, value: Required<Pick<PropertyValue, 'object'>>) {
371
+ const curve = value.object[0];
372
+ if (curve instanceof InterpolatorScalar) {
373
+ updateJointDynamicsConfig(this, { curves: { [key]: curve } as Partial<ControllerConfig['curves']> });
374
+ } else if (curve instanceof Interpolator && curve.target === 'number') {
375
+ updateJointDynamicsConfig(this, {
376
+ curves: {
377
+ [key]: new InterpolatorScalar(
378
+ curve.mode,
379
+ new Float32Array(curve.inputs),
380
+ new Float32Array(curve.outputs)
381
+ )
382
+ } as Partial<ControllerConfig['curves']>
383
+ });
384
+ }
385
+ }
386
+ };
387
+ */ }
388
+ /** @internal */ function getJointDynamicsModifierClass() {
389
+ return {
390
+ ctor: JointDynamicsModifier,
391
+ name: 'JointDynamicsModifier',
392
+ createFunc (ctx, init) {
393
+ const skeleton = ctx.findSkeletonRigById(init.skeleton) ?? ctx.findSkeletonById(init.skeleton)?.rig ?? null;
394
+ const systemRoot = findSerializedNode(ctx, init.systemRoot);
395
+ if (!skeleton || !systemRoot) {
396
+ return {
397
+ obj: null,
398
+ loadProps: false
399
+ };
400
+ }
401
+ const chains = (init.chains ?? []).map((chain)=>{
402
+ const start = findSerializedNode(ctx, chain.start);
403
+ const end = findSerializedNode(ctx, chain.end);
404
+ return start && end ? {
405
+ start,
406
+ end
407
+ } : null;
408
+ }).filter((chain)=>{
409
+ return !!chain && chain.start.isParentOf(chain.end);
410
+ });
411
+ if (chains.length === 0) {
412
+ return {
413
+ obj: null,
414
+ loadProps: false
415
+ };
416
+ }
417
+ const serializedColliders = init.colliders ?? [];
418
+ const colliders = serializedColliders.map((item)=>{
419
+ const transform = findSerializedNode(ctx, item.transform);
420
+ return {
421
+ r: {
422
+ ...item.collider
423
+ },
424
+ transform: transform ? createTransformAccess(transform) : createTransformAccess(new SceneNode(null), false)
425
+ };
426
+ });
427
+ const serializedGrabbers = init.grabbers ?? [];
428
+ const grabbers = serializedGrabbers.map((item)=>{
429
+ const transform = findSerializedNode(ctx, item.transform);
430
+ return {
431
+ r: {
432
+ ...item.grabber
433
+ },
434
+ transform: transform ? createTransformAccess(transform) : createTransformAccess(new SceneNode(null), false),
435
+ enabled: item.enabled ?? false
436
+ };
437
+ });
438
+ const flatPlanes = (init.flatPlanes ?? []).map((item)=>({
439
+ up: vectorFromArray(item.up, Vector3.axisPY()),
440
+ position: vectorFromArray(item.position),
441
+ enabled: item.enabled ?? true
442
+ }));
443
+ const controllerConfig = deserializeControllerConfig(init.controllerConfig);
444
+ const config = {
445
+ chainConfig: {
446
+ systemRoot,
447
+ chains
448
+ },
449
+ controllerConfig
450
+ };
451
+ const system = new JointDynamicsSystem(config, colliders, grabbers, flatPlanes.map((item)=>({
452
+ up: item.up,
453
+ position: item.position
454
+ })));
455
+ for(let i = 0; i < serializedColliders.length; i++){
456
+ if (serializedColliders[i]?.enabled === false) {
457
+ system.controller.setColliderEnabledAt(i, false);
458
+ }
459
+ }
460
+ for(let i = 0; i < flatPlanes.length; i++){
461
+ if (!flatPlanes[i].enabled) {
462
+ system.controller.setFlatPlaneEnabledAt(i, false);
463
+ }
464
+ }
465
+ const modifier = new JointDynamicsModifier(system);
466
+ modifier.enabled = init.enabled ?? true;
467
+ setJointDynamicsModifierSkeleton(modifier, skeleton);
468
+ return {
469
+ obj: modifier,
470
+ loadProps: false
471
+ };
472
+ },
473
+ getInitParams (obj) {
474
+ const skeleton = getJointDynamicsModifierSkeleton(obj);
475
+ const chainConfig = obj.jointDynamicsSystem.chainConfig;
476
+ const controllerConfig = obj.jointDynamicsSystem.controller.getConfig();
477
+ const init = {
478
+ skeleton: skeleton?.persistentId ?? '',
479
+ systemRoot: chainConfig.systemRoot.persistentId,
480
+ chains: chainConfig.chains.map((chain)=>({
481
+ start: chain.start.persistentId,
482
+ end: chain.end.persistentId
483
+ })),
484
+ controllerConfig: serializeControllerConfig(controllerConfig),
485
+ colliders: obj.jointDynamicsSystem.getColliderSnapshots().map((item)=>({
486
+ collider: {
487
+ ...item.r
488
+ },
489
+ transform: item.transform instanceof SceneNode ? item.transform.persistentId : undefined,
490
+ enabled: item.enabled
491
+ })),
492
+ flatPlanes: obj.jointDynamicsSystem.getFlatPlaneSnapshots().map((item)=>({
493
+ up: vectorToArray(item.up),
494
+ position: vectorToArray(item.position),
495
+ enabled: item.enabled
496
+ })),
497
+ grabbers: obj.jointDynamicsSystem.getGrabberSnapshots().map((item)=>({
498
+ grabber: {
499
+ ...item.r
500
+ },
501
+ transform: item.transform instanceof SceneNode ? item.transform.persistentId : undefined,
502
+ enabled: item.enabled
503
+ })),
504
+ enabled: obj.enabled
505
+ };
506
+ return init;
507
+ },
508
+ getProps () {
509
+ return defineProps([
510
+ {
511
+ name: 'Commands',
512
+ description: 'Reset joint dynamics modifier state',
513
+ type: 'command',
514
+ command () {
515
+ this.reset();
516
+ return false;
517
+ },
518
+ get (value) {
519
+ value.str[0] = 'Reset';
520
+ }
521
+ },
522
+ {
523
+ name: 'Enabled',
524
+ description: 'Whether this joint dynamics modifier is active',
525
+ type: 'bool',
526
+ options: {
527
+ ...jointDynamicsPropOptions,
528
+ label: 'Enabled'
529
+ },
530
+ isPersistent: isJointDynamicsEditorPropPersistent,
531
+ get (value) {
532
+ value.bool[0] = this.enabled;
533
+ },
534
+ set (value) {
535
+ this.enabled = value.bool[0];
536
+ }
537
+ },
538
+ {
539
+ name: 'Weight',
540
+ description: 'Physics blend weight. 0 uses animation only, 1 uses full joint dynamics',
541
+ type: 'float',
542
+ options: {
543
+ ...jointDynamicsPropOptions,
544
+ label: 'Weight',
545
+ minValue: 0,
546
+ maxValue: 1
547
+ },
548
+ isPersistent: isJointDynamicsEditorPropPersistent,
549
+ get (value) {
550
+ value.num[0] = this.weight;
551
+ },
552
+ set (value) {
553
+ this.weight = value.num[0];
554
+ }
555
+ },
556
+ createJointDynamicsVectorProp('Gravity', 'gravity', 'Gravity', 'Global gravity vector'),
557
+ createJointDynamicsVectorProp('WindForce', 'windForce', 'Wind Force', 'Global wind force vector'),
558
+ createJointDynamicsNumberProp('Relaxation', 'relaxation', 'Relaxation', 'Constraint relaxation iterations per substep', 'int', 0),
559
+ createJointDynamicsNumberProp('SubSteps', 'subSteps', 'Sub Steps', 'Simulation substeps per frame', 'int', 1),
560
+ createJointDynamicsNumberProp('RootSlideLimit', 'rootSlideLimit', 'Root Slide Limit', 'Maximum root slide distance per substep. -1 means unlimited', 'float'),
561
+ createJointDynamicsNumberProp('RootRotateLimit', 'rootRotateLimit', 'Root Rotate Limit', 'Maximum root rotation angle per substep. -1 means unlimited', 'float'),
562
+ createJointDynamicsNumberProp('ConstraintShrinkLimit', 'constraintShrinkLimit', 'Shrink Limit', 'Upper limit for horizontal and shear constraint shrink power', 'float', 0),
563
+ createJointDynamicsNumberProp('StabilizationFrameRate', 'stabilizationFrameRate', 'Stabilization FPS', 'Target frame rate used by stabilization logic', 'float', 0),
564
+ createJointDynamicsBooleanProp('FakeWave', 'isFakeWave', 'Fake Wave', 'Enable sinusoidal fake wave on leaf bones'),
565
+ createJointDynamicsNumberProp('FakeWaveSpeed', 'fakeWaveSpeed', 'Fake Wave Speed', 'Global fake wave speed', 'float'),
566
+ createJointDynamicsNumberProp('FakeWavePower', 'fakeWavePower', 'Fake Wave Power', 'Global fake wave amplitude multiplier', 'float'),
567
+ createJointDynamicsBooleanProp('EnableSurfaceCollision', 'enableSurfaceCollision', 'Surface Collision', 'Enable triangle-based surface collision'),
568
+ createJointDynamicsBooleanProp('EnableBroadPhase', 'enableBroadPhase', 'Broad Phase', 'Enable broad-phase pruning before precise collider tests'),
569
+ createJointDynamicsBooleanProp('PreserveTwist', 'preserveTwist', 'Preserve Twist', 'Preserve each joint initial local twist after physics simulation'),
570
+ createJointDynamicsAngleLimitNumberProp('AngleLimit', 'angleLimit', 'Angle Limit', 'Post-simulation parent-child angle limit. -1 disables angle limiting'),
571
+ createJointDynamicsAngleLimitBooleanProp('AngleLimitFromRoot', 'limitFromRoot', 'Limit From Root', 'Apply angle limiting from the chain root'),
572
+ createJointDynamicsConstraintOptionProp('StructuralVertical', 'structuralVertical', 'Structural Vertical', 'Generate parent-child vertical constraints'),
573
+ createJointDynamicsConstraintOptionProp('StructuralHorizontal', 'structuralHorizontal', 'Structural Horizontal', 'Generate same-depth horizontal constraints across chains'),
574
+ createJointDynamicsConstraintOptionProp('Shear', 'shear', 'Shear', 'Generate diagonal cross-bracing constraints'),
575
+ createJointDynamicsConstraintOptionProp('BendingVertical', 'bendingVertical', 'Bending Vertical', 'Generate skip-one vertical bending constraints'),
576
+ createJointDynamicsConstraintOptionProp('BendingHorizontal', 'bendingHorizontal', 'Bending Horizontal', 'Generate skip-one horizontal bending constraints'),
577
+ createJointDynamicsConstraintOptionProp('Loop', 'isLoop', 'Loop', 'Connect the last root point back to the first root point'),
578
+ createJointDynamicsConstraintOptionProp('CollideStructuralVertical', 'collideStructuralVertical', 'Collide Structural V', 'Enable per-constraint collision on structural vertical pairs'),
579
+ createJointDynamicsConstraintOptionProp('CollideStructuralHorizontal', 'collideStructuralHorizontal', 'Collide Structural H', 'Enable per-constraint collision on structural horizontal pairs'),
580
+ createJointDynamicsConstraintOptionProp('CollideShear', 'collideShear', 'Collide Shear', 'Enable per-constraint collision on shear pairs'),
581
+ createJointDynamicsConstraintOptionProp('ConstraintSurfaceCollision', 'enableSurfaceCollision', 'Constraint Surface Collision', 'Enable surface collision in constraint generation'),
582
+ createJointDynamicsCurveProp('MassScale', 'massScale', 'Mass Scale', 'Depth curve that scales point mass'),
583
+ createJointDynamicsCurveProp('GravityScale', 'gravityScale', 'Gravity Scale', 'Depth curve that scales gravity strength'),
584
+ createJointDynamicsCurveProp('WindForceScale', 'windForceScale', 'Wind Force Scale', 'Depth curve that scales wind force'),
585
+ createJointDynamicsCurveProp('Resistance', 'resistance', 'Resistance', 'Depth curve for velocity damping'),
586
+ createJointDynamicsCurveProp('Hardness', 'hardness', 'Hardness', 'Depth curve for restore-to-animation stiffness'),
587
+ createJointDynamicsCurveProp('Friction', 'friction', 'Friction', 'Depth curve for collision friction'),
588
+ createJointDynamicsCurveProp('PointRadius', 'pointRadius', 'Point Radius', 'Depth curve for collision radius'),
589
+ createJointDynamicsCurveProp('SliderJointLength', 'sliderJointLength', 'Slider Joint Length', 'Depth curve for extra horizontal and shear constraint slack'),
590
+ createJointDynamicsCurveProp('AllShrinkScale', 'allShrinkScale', 'All Shrink Scale', 'Depth curve for global shrink stiffness multiplier'),
591
+ createJointDynamicsCurveProp('AllStretchScale', 'allStretchScale', 'All Stretch Scale', 'Depth curve for global stretch stiffness multiplier'),
592
+ createJointDynamicsCurveProp('StructuralShrinkVertical', 'structuralShrinkVertical', 'Structural Shrink V', 'Depth curve for structural vertical shrink stiffness'),
593
+ createJointDynamicsCurveProp('StructuralStretchVertical', 'structuralStretchVertical', 'Structural Stretch V', 'Depth curve for structural vertical stretch stiffness'),
594
+ createJointDynamicsCurveProp('StructuralShrinkHorizontal', 'structuralShrinkHorizontal', 'Structural Shrink H', 'Depth curve for structural horizontal shrink stiffness'),
595
+ createJointDynamicsCurveProp('StructuralStretchHorizontal', 'structuralStretchHorizontal', 'Structural Stretch H', 'Depth curve for structural horizontal stretch stiffness'),
596
+ createJointDynamicsCurveProp('ShearShrink', 'shearShrink', 'Shear Shrink', 'Depth curve for shear shrink stiffness'),
597
+ createJointDynamicsCurveProp('ShearStretch', 'shearStretch', 'Shear Stretch', 'Depth curve for shear stretch stiffness'),
598
+ createJointDynamicsCurveProp('BendingShrinkVertical', 'bendingShrinkVertical', 'Bending Shrink V', 'Depth curve for bending vertical shrink stiffness'),
599
+ createJointDynamicsCurveProp('BendingStretchVertical', 'bendingStretchVertical', 'Bending Stretch V', 'Depth curve for bending vertical stretch stiffness'),
600
+ createJointDynamicsCurveProp('BendingShrinkHorizontal', 'bendingShrinkHorizontal', 'Bending Shrink H', 'Depth curve for bending horizontal shrink stiffness'),
601
+ createJointDynamicsCurveProp('BendingStretchHorizontal', 'bendingStretchHorizontal', 'Bending Stretch H', 'Depth curve for bending horizontal stretch stiffness'),
602
+ createJointDynamicsCurveProp('FakeWavePowerCurve', 'fakeWavePower', 'Fake Wave Power Curve', 'Depth curve for fake wave amplitude'),
603
+ createJointDynamicsCurveProp('FakeWaveFreq', 'fakeWaveFreq', 'Fake Wave Freq', 'Depth curve for fake wave frequency offset')
604
+ ]);
605
+ }
606
+ };
607
+ }
54
608
  /** @internal */ function getInterpolatorClass() {
55
609
  return {
56
610
  ctor: Interpolator,
@@ -788,8 +1342,10 @@ function getPCAGeometryCacheTrackClass() {
788
1342
  node.jointTypeR = 'static';
789
1343
  return node;
790
1344
  });
1345
+ const rootJoint = init.rootJoint ? prefabNode.findNodeById(init.rootJoint) : null;
791
1346
  const inverseBindMatricesArray = new Float32Array(base64ToUint8Array(init.inverseBindMatrices).buffer);
792
1347
  const bindPoseArray = new Float32Array(base64ToUint8Array(init.bindPose ?? init.bindPoseMatrices).buffer);
1348
+ const rootBindPose = init.rootBindPose ? decodeSkeletonBindPose(init.rootBindPose) : undefined;
793
1349
  const inverseBindMatrices = [];
794
1350
  const bindPose = [];
795
1351
  for(let i = 0; i < joints.length; i++){
@@ -811,7 +1367,15 @@ function getPCAGeometryCacheTrackClass() {
811
1367
  });
812
1368
  }
813
1369
  }
814
- const skeleton = new Skeleton(joints, inverseBindMatrices, bindPose);
1370
+ let rig = ctx.animationSet.rigs.map((ref)=>ref.get()).find((item)=>!!item && SkeletonRig.getRigKey(item.joints, item.rootJoint) === SkeletonRig.getRigKey(joints, rootJoint)) ?? null;
1371
+ if (!rig) {
1372
+ rig = new SkeletonRig(joints, bindPose, {
1373
+ rootJoint,
1374
+ rootBindPose
1375
+ });
1376
+ ctx.animationSet.rigs.push(new DRef(rig));
1377
+ }
1378
+ const skeleton = new SkinBinding(rig, inverseBindMatrices, joints);
815
1379
  skeleton.persistentId = init.id;
816
1380
  return {
817
1381
  obj: skeleton,
@@ -835,6 +1399,8 @@ function getPCAGeometryCacheTrackClass() {
835
1399
  ], []);
836
1400
  return {
837
1401
  joints: obj.joints.map((joint)=>joint.persistentId),
1402
+ rootJoint: obj.rig.rootJoint?.persistentId ?? '',
1403
+ rootBindPose: encodeSkeletonBindPose(obj.rig.rootBindPose),
838
1404
  inverseBindMatrices: uint8ArrayToBase64(new Uint8Array(new Float32Array(inverseBindMatrices).buffer)),
839
1405
  bindPose: uint8ArrayToBase64(new Uint8Array(new Float32Array(bindPose).buffer)),
840
1406
  id: obj.persistentId
@@ -845,6 +1411,114 @@ function getPCAGeometryCacheTrackClass() {
845
1411
  }
846
1412
  };
847
1413
  }
1414
+ /** @internal */ function getSkeletonRigClass() {
1415
+ return {
1416
+ ctor: SkeletonRig,
1417
+ name: 'SkeletonRig',
1418
+ createFunc (ctx, init) {
1419
+ const prefabNode = ctx.getPrefabNode() ?? ctx;
1420
+ const joints = init.joints.map((id)=>prefabNode.findNodeById(id)).map((node)=>{
1421
+ node.jointTypeT = 'static';
1422
+ node.jointTypeS = 'static';
1423
+ node.jointTypeR = 'static';
1424
+ return node;
1425
+ });
1426
+ const rootJoint = init.rootJoint ? prefabNode.findNodeById(init.rootJoint) : null;
1427
+ const rootBindPose = init.rootBindPose ? decodeSkeletonBindPose(init.rootBindPose) : undefined;
1428
+ const bindPoseArray = new Float32Array(base64ToUint8Array(init.bindPose ?? init.bindPoseMatrices).buffer);
1429
+ const bindPose = [];
1430
+ for(let i = 0; i < joints.length; i++){
1431
+ if (!init.bindPose) {
1432
+ const matrix = new Matrix4x4(bindPoseArray.slice(i * 16, i * 16 + 16));
1433
+ const trs = {
1434
+ position: new Vector3(),
1435
+ rotation: new Quaternion(),
1436
+ scale: new Vector3()
1437
+ };
1438
+ matrix.decompose(trs.scale, trs.rotation, trs.position);
1439
+ bindPose.push(trs);
1440
+ } else {
1441
+ bindPose.push({
1442
+ position: new Vector3(bindPoseArray[i * 10 + 0], bindPoseArray[i * 10 + 1], bindPoseArray[i * 10 + 2]),
1443
+ rotation: new Quaternion(bindPoseArray[i * 10 + 3], bindPoseArray[i * 10 + 4], bindPoseArray[i * 10 + 5], bindPoseArray[i * 10 + 6]),
1444
+ scale: new Vector3(bindPoseArray[i * 10 + 7], bindPoseArray[i * 10 + 8], bindPoseArray[i * 10 + 9])
1445
+ });
1446
+ }
1447
+ }
1448
+ const rig = new SkeletonRig(joints, bindPose, {
1449
+ rootJoint,
1450
+ rootBindPose
1451
+ });
1452
+ rig.persistentId = init.id;
1453
+ return {
1454
+ obj: rig,
1455
+ loadProps: false
1456
+ };
1457
+ },
1458
+ getInitParams (obj) {
1459
+ const bindPose = obj.bindPose.map((v)=>[
1460
+ ...v.position,
1461
+ ...v.rotation,
1462
+ ...v.scale
1463
+ ]).reduce((a, b)=>[
1464
+ ...a,
1465
+ ...b
1466
+ ], []);
1467
+ return {
1468
+ joints: obj.joints.map((joint)=>joint.persistentId),
1469
+ rootJoint: obj.rootJoint?.persistentId ?? '',
1470
+ rootBindPose: encodeSkeletonBindPose(obj.rootBindPose),
1471
+ bindPose: uint8ArrayToBase64(new Uint8Array(new Float32Array(bindPose).buffer)),
1472
+ id: obj.persistentId
1473
+ };
1474
+ },
1475
+ getProps () {
1476
+ return [];
1477
+ }
1478
+ };
1479
+ }
1480
+ /** @internal */ function getSkinBindingClass() {
1481
+ return {
1482
+ ctor: SkinBinding,
1483
+ name: 'SkinBinding',
1484
+ createFunc (ctx, init) {
1485
+ const rig = ctx.findSkeletonRigById(init.rig);
1486
+ if (!rig) {
1487
+ throw new Error(`Deserialize SkinBinding failed: skeleton rig '${init.rig}' not found`);
1488
+ }
1489
+ const prefabNode = ctx.getPrefabNode() ?? ctx;
1490
+ const joints = (init.joints ?? rig.joints.map((joint)=>joint.persistentId)).map((id)=>prefabNode.findNodeById(id)).filter((node)=>!!node);
1491
+ const inverseBindMatricesArray = new Float32Array(base64ToUint8Array(init.inverseBindMatrices).buffer);
1492
+ const inverseBindMatrices = [];
1493
+ for(let i = 0; i < joints.length; i++){
1494
+ inverseBindMatrices.push(new Matrix4x4(inverseBindMatricesArray.slice(i * 16, i * 16 + 16)));
1495
+ }
1496
+ const binding = new SkinBinding(rig, inverseBindMatrices, joints);
1497
+ binding.persistentId = init.id;
1498
+ return {
1499
+ obj: binding,
1500
+ loadProps: false
1501
+ };
1502
+ },
1503
+ getInitParams (obj) {
1504
+ const inverseBindMatrices = obj.inverseBindMatrices.map((v)=>[
1505
+ ...v
1506
+ ]).reduce((a, b)=>[
1507
+ ...a,
1508
+ ...b
1509
+ ], []);
1510
+ return {
1511
+ rig: obj.rig.persistentId,
1512
+ joints: obj.joints.map((joint)=>joint.persistentId),
1513
+ inverseBindMatrices: uint8ArrayToBase64(new Uint8Array(new Float32Array(inverseBindMatrices).buffer)),
1514
+ id: obj.persistentId
1515
+ };
1516
+ },
1517
+ getProps () {
1518
+ return [];
1519
+ }
1520
+ };
1521
+ }
848
1522
  /** @internal */ function getAnimationClass(manager) {
849
1523
  return {
850
1524
  ctor: AnimationClip,
@@ -904,8 +1578,8 @@ function getPCAGeometryCacheTrackClass() {
904
1578
  }
905
1579
  },
906
1580
  {
907
- name: 'Skeletons',
908
- description: 'Skeleton references used by this animation clip',
1581
+ name: 'Rigs',
1582
+ description: 'Rig references used by this animation clip',
909
1583
  type: 'object',
910
1584
  isHidden () {
911
1585
  return true;
@@ -924,6 +1598,25 @@ function getPCAGeometryCacheTrackClass() {
924
1598
  }
925
1599
  }
926
1600
  },
1601
+ {
1602
+ name: 'Skeletons',
1603
+ description: 'Legacy skeleton references used by this animation clip',
1604
+ type: 'object',
1605
+ isHidden () {
1606
+ return true;
1607
+ },
1608
+ get (value) {
1609
+ value.object[0] = [];
1610
+ },
1611
+ set (value) {
1612
+ if (!this.skeletons) {
1613
+ this.skeletons = new Set();
1614
+ }
1615
+ for (const val of value.object[0] ?? []){
1616
+ this.skeletons.add(val);
1617
+ }
1618
+ }
1619
+ },
927
1620
  {
928
1621
  name: 'Tracks',
929
1622
  description: 'Animation tracks of this animation clip',
@@ -988,5 +1681,5 @@ function getPCAGeometryCacheTrackClass() {
988
1681
  };
989
1682
  }
990
1683
 
991
- export { getAnimationClass, getFixedGeometryCacheTrackClass, getInterpolatorClass, getMorphTrackClass, getNodeEulerRotationTrackClass, getNodeRotationTrackClass, getNodeScaleTrackClass, getNodeTranslationTrackClass, getPCAGeometryCacheTrackClass, getPropTrackClass, getSkeletonClass };
1684
+ export { getAnimationClass, getFixedGeometryCacheTrackClass, getInterpolatorClass, getJointDynamicsModifierClass, getJointDynamicsModifierSkeleton, getMorphTrackClass, getNodeEulerRotationTrackClass, getNodeRotationTrackClass, getNodeScaleTrackClass, getNodeTranslationTrackClass, getPCAGeometryCacheTrackClass, getPropTrackClass, getSkeletonClass, getSkeletonRigClass, getSkinBindingClass, setJointDynamicsModifierSkeleton };
992
1685
  //# sourceMappingURL=animation.js.map