@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
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { EPSILON } from './types.js';
|
|
2
2
|
import { buildConstraints, buildSurfaceFaces } from './constraints.js';
|
|
3
3
|
import { simulate, applyAngleLimits, applyResult } from './solver.js';
|
|
4
|
-
import { Vector3, Quaternion, Matrix4x4, clamp01 } from '@zephyr3d/base';
|
|
4
|
+
import { Vector3, Quaternion, Matrix4x4, clamp01, InterpolatorScalar } from '@zephyr3d/base';
|
|
5
5
|
|
|
6
6
|
// High-level orchestrator - SPCRJointDynamicsController API
|
|
7
7
|
/**
|
|
@@ -33,6 +33,10 @@ import { Vector3, Quaternion, Matrix4x4, clamp01 } from '@zephyr3d/base';
|
|
|
33
33
|
_previousRootPosition = Vector3.zero();
|
|
34
34
|
_previousRootRotation = Quaternion.identity();
|
|
35
35
|
_rootTransform = null;
|
|
36
|
+
_rootPoints = [];
|
|
37
|
+
_allPoints = [];
|
|
38
|
+
_parentMap = new Map();
|
|
39
|
+
_maxPointDepth = 0;
|
|
36
40
|
_pointTransforms = [];
|
|
37
41
|
_colliderTransforms = [];
|
|
38
42
|
_grabberTransforms = [];
|
|
@@ -42,6 +46,10 @@ import { Vector3, Quaternion, Matrix4x4, clamp01 } from '@zephyr3d/base';
|
|
|
42
46
|
_colliderHandleToIndex = new Map();
|
|
43
47
|
_flatPlaneHandleToIndex = new Map();
|
|
44
48
|
_grabberHandleToIndex = new Map();
|
|
49
|
+
_baseSystemScale = 1;
|
|
50
|
+
_currentSystemScale = 1;
|
|
51
|
+
_basePointParentLengths = [];
|
|
52
|
+
_baseConstraintLengths = [];
|
|
45
53
|
_nextColliderHandleId = 1;
|
|
46
54
|
_nextFlatPlaneHandleId = 1;
|
|
47
55
|
_nextGrabberHandleId = 1;
|
|
@@ -51,7 +59,7 @@ import { Vector3, Quaternion, Matrix4x4, clamp01 } from '@zephyr3d/base';
|
|
|
51
59
|
_fadeTimer = 0;
|
|
52
60
|
_fadeDuration = 0;
|
|
53
61
|
constructor(config){
|
|
54
|
-
this._config = config;
|
|
62
|
+
this._config = this._sanitizeControllerConfig(this._cloneControllerConfig(config));
|
|
55
63
|
}
|
|
56
64
|
/**
|
|
57
65
|
* Initializes the physics system.
|
|
@@ -63,32 +71,34 @@ import { Vector3, Quaternion, Matrix4x4, clamp01 } from '@zephyr3d/base';
|
|
|
63
71
|
* @param flatPlanes - Plane limiters such as the floor to prevent penetration.
|
|
64
72
|
*/ initialize(rootTransform, rootPoints, pointTransforms, colliders, grabbers, flatPlanes) {
|
|
65
73
|
this._rootTransform = rootTransform;
|
|
74
|
+
this._baseSystemScale = this._getSystemUniformScale();
|
|
75
|
+
this._currentSystemScale = this._baseSystemScale;
|
|
76
|
+
this._rootPoints = [
|
|
77
|
+
...rootPoints
|
|
78
|
+
];
|
|
66
79
|
this._pointTransforms = pointTransforms;
|
|
67
80
|
this._colliderTransforms = colliders.map((c)=>c.transform);
|
|
68
81
|
this._grabberTransforms = grabbers.map((g)=>g.transform);
|
|
69
82
|
// Build constraints
|
|
70
|
-
this.
|
|
71
|
-
this.
|
|
83
|
+
this._rebuildConstraints();
|
|
84
|
+
this._baseConstraintLengths = this._constraints.map((constraint)=>constraint.length);
|
|
72
85
|
// Flatten bone hierarchy to point list, build parent map
|
|
73
86
|
const allPoints = [];
|
|
74
|
-
|
|
75
|
-
|
|
87
|
+
this._parentMap = new Map(); // child index -> parent index
|
|
88
|
+
const walk = (node)=>{
|
|
76
89
|
allPoints.push(node);
|
|
77
90
|
for (const c of node.children){
|
|
78
|
-
|
|
91
|
+
this._parentMap.set(c.index, node.index);
|
|
79
92
|
walk(c);
|
|
80
93
|
}
|
|
81
|
-
}
|
|
94
|
+
};
|
|
82
95
|
for (const r of rootPoints){
|
|
83
96
|
walk(r);
|
|
84
97
|
}
|
|
85
|
-
|
|
98
|
+
this._allPoints = allPoints;
|
|
99
|
+
this._maxPointDepth = allPoints.length > 0 ? Math.max(...allPoints.map((p)=>p.depth)) : 0;
|
|
86
100
|
// Compute boneAxis from transforms: local-space direction to first child
|
|
87
101
|
// This is critical for correct bone rotation in skinned meshes
|
|
88
|
-
const indexToNode = new Map();
|
|
89
|
-
for (const p of allPoints){
|
|
90
|
-
indexToNode.set(p.index, p);
|
|
91
|
-
}
|
|
92
102
|
for (const p of allPoints){
|
|
93
103
|
if (!p.boneAxis && p.children.length > 0) {
|
|
94
104
|
const childPos = pointTransforms[p.children[0].index].getWorldPosition();
|
|
@@ -105,7 +115,8 @@ import { Vector3, Quaternion, Matrix4x4, clamp01 } from '@zephyr3d/base';
|
|
|
105
115
|
}
|
|
106
116
|
}
|
|
107
117
|
// Build PointR/RW arrays
|
|
108
|
-
this._pointsR = allPoints.map((p)=>this._createPointR(p
|
|
118
|
+
this._pointsR = allPoints.map((p)=>this._createPointR(p));
|
|
119
|
+
this._basePointParentLengths = this._pointsR.map((point)=>point.parentLength);
|
|
109
120
|
this._pointsRW = allPoints.map(()=>this._createPointRW());
|
|
110
121
|
this._positionsToTransform = new Array(allPoints.length).fill(Vector3.zero());
|
|
111
122
|
// Initialize colliders
|
|
@@ -168,6 +179,7 @@ import { Vector3, Quaternion, Matrix4x4, clamp01 } from '@zephyr3d/base';
|
|
|
168
179
|
}
|
|
169
180
|
}
|
|
170
181
|
const blendRatio = this._computeBlendRatio();
|
|
182
|
+
this._updateScaleDependentParameters();
|
|
171
183
|
// Capture current transforms
|
|
172
184
|
const rootPos = this._rootTransform.getWorldPosition();
|
|
173
185
|
const rootRot = this._rootTransform.getWorldRotation();
|
|
@@ -243,6 +255,189 @@ import { Vector3, Quaternion, Matrix4x4, clamp01 } from '@zephyr3d/base';
|
|
|
243
255
|
}));
|
|
244
256
|
}
|
|
245
257
|
/**
|
|
258
|
+
* Returns a detached snapshot of the current runtime configuration.
|
|
259
|
+
*/ getConfig() {
|
|
260
|
+
return this._cloneControllerConfig(this._config);
|
|
261
|
+
}
|
|
262
|
+
/**
|
|
263
|
+
* Returns detached collider snapshots for persistence.
|
|
264
|
+
*/ getColliderSnapshots() {
|
|
265
|
+
return this._collidersR.map((r, index)=>({
|
|
266
|
+
r: {
|
|
267
|
+
...r
|
|
268
|
+
},
|
|
269
|
+
transform: this._colliderTransforms[index]?.node ?? null,
|
|
270
|
+
enabled: this._collidersRW[index]?.enabled !== 0
|
|
271
|
+
}));
|
|
272
|
+
}
|
|
273
|
+
/**
|
|
274
|
+
* Returns detached flat-plane snapshots for persistence.
|
|
275
|
+
*/ getFlatPlaneSnapshots() {
|
|
276
|
+
return this._flatPlaneAll.map((plane, index)=>({
|
|
277
|
+
up: plane.normal.clone(),
|
|
278
|
+
position: Vector3.scale(plane.normal, -plane.distance),
|
|
279
|
+
enabled: this._flatPlaneEnabled[index] ?? true
|
|
280
|
+
}));
|
|
281
|
+
}
|
|
282
|
+
/**
|
|
283
|
+
* Returns detached grabber snapshots for persistence.
|
|
284
|
+
*/ getGrabberSnapshots() {
|
|
285
|
+
return this._grabbersR.map((r, index)=>({
|
|
286
|
+
r: {
|
|
287
|
+
...r
|
|
288
|
+
},
|
|
289
|
+
transform: this._grabberTransforms[index]?.node ?? null,
|
|
290
|
+
enabled: this._grabbersRW[index]?.enabled !== 0
|
|
291
|
+
}));
|
|
292
|
+
}
|
|
293
|
+
/**
|
|
294
|
+
* Replaces the runtime configuration.
|
|
295
|
+
*
|
|
296
|
+
* If the controller is already initialized, cached per-point parameters and generated
|
|
297
|
+
* constraints are refreshed immediately so editor-driven changes take effect in the next step.
|
|
298
|
+
*
|
|
299
|
+
* @param config - Complete controller configuration to apply.
|
|
300
|
+
*/ setConfig(config) {
|
|
301
|
+
this._config = this._sanitizeControllerConfig(this._cloneControllerConfig(config));
|
|
302
|
+
this._refreshCachedSimulationConfig();
|
|
303
|
+
}
|
|
304
|
+
/**
|
|
305
|
+
* Applies a partial runtime configuration update.
|
|
306
|
+
*
|
|
307
|
+
* This is intended for editor workflows that tweak one or more simulation parameters live.
|
|
308
|
+
* The controller updates only the affected caches: global step parameters are applied directly,
|
|
309
|
+
* per-point curve/gravity changes rebuild cached point coefficients, and constraint option
|
|
310
|
+
* changes rebuild the generated constraints.
|
|
311
|
+
*
|
|
312
|
+
* @param config - Partial configuration update.
|
|
313
|
+
*/ updateConfig(config) {
|
|
314
|
+
let refreshPoints = false;
|
|
315
|
+
let refreshConstraints = false;
|
|
316
|
+
if (config.gravity) {
|
|
317
|
+
this._config.gravity = config.gravity.clone();
|
|
318
|
+
refreshPoints = true;
|
|
319
|
+
}
|
|
320
|
+
if (config.windForce) {
|
|
321
|
+
this._config.windForce = config.windForce.clone();
|
|
322
|
+
}
|
|
323
|
+
if (typeof config.relaxation === 'number') {
|
|
324
|
+
this._config.relaxation = Math.max(0, Math.trunc(config.relaxation));
|
|
325
|
+
}
|
|
326
|
+
if (typeof config.subSteps === 'number') {
|
|
327
|
+
this._config.subSteps = Math.max(1, Math.trunc(config.subSteps));
|
|
328
|
+
}
|
|
329
|
+
if (typeof config.rootSlideLimit === 'number') {
|
|
330
|
+
this._config.rootSlideLimit = config.rootSlideLimit;
|
|
331
|
+
}
|
|
332
|
+
if (typeof config.rootRotateLimit === 'number') {
|
|
333
|
+
this._config.rootRotateLimit = config.rootRotateLimit;
|
|
334
|
+
}
|
|
335
|
+
if (typeof config.constraintShrinkLimit === 'number') {
|
|
336
|
+
this._config.constraintShrinkLimit = Math.max(0, config.constraintShrinkLimit);
|
|
337
|
+
}
|
|
338
|
+
if (typeof config.blendRatio === 'number') {
|
|
339
|
+
this._config.blendRatio = clamp01(config.blendRatio);
|
|
340
|
+
}
|
|
341
|
+
if (typeof config.stabilizationFrameRate === 'number') {
|
|
342
|
+
this._config.stabilizationFrameRate = config.stabilizationFrameRate;
|
|
343
|
+
}
|
|
344
|
+
if (typeof config.isFakeWave === 'boolean') {
|
|
345
|
+
this._config.isFakeWave = config.isFakeWave;
|
|
346
|
+
}
|
|
347
|
+
if (typeof config.fakeWaveSpeed === 'number') {
|
|
348
|
+
this._config.fakeWaveSpeed = config.fakeWaveSpeed;
|
|
349
|
+
}
|
|
350
|
+
if (typeof config.fakeWavePower === 'number') {
|
|
351
|
+
this._config.fakeWavePower = config.fakeWavePower;
|
|
352
|
+
}
|
|
353
|
+
if (typeof config.enableSurfaceCollision === 'boolean') {
|
|
354
|
+
this._config.enableSurfaceCollision = config.enableSurfaceCollision;
|
|
355
|
+
if (!config.constraintOptions || config.constraintOptions.enableSurfaceCollision === undefined) {
|
|
356
|
+
this._config.constraintOptions.enableSurfaceCollision = config.enableSurfaceCollision;
|
|
357
|
+
refreshConstraints = true;
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
if (typeof config.enableBroadPhase === 'boolean') {
|
|
361
|
+
this._config.enableBroadPhase = config.enableBroadPhase;
|
|
362
|
+
}
|
|
363
|
+
if (typeof config.preserveTwist === 'boolean') {
|
|
364
|
+
this._config.preserveTwist = config.preserveTwist;
|
|
365
|
+
}
|
|
366
|
+
if (config.angleLimitConfig) {
|
|
367
|
+
if (typeof config.angleLimitConfig.angleLimit === 'number') {
|
|
368
|
+
this._config.angleLimitConfig.angleLimit = config.angleLimitConfig.angleLimit;
|
|
369
|
+
}
|
|
370
|
+
if (typeof config.angleLimitConfig.limitFromRoot === 'boolean') {
|
|
371
|
+
this._config.angleLimitConfig.limitFromRoot = config.angleLimitConfig.limitFromRoot;
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
if (config.curves) {
|
|
375
|
+
const curveKeys = [
|
|
376
|
+
'massScale',
|
|
377
|
+
'gravityScale',
|
|
378
|
+
'windForceScale',
|
|
379
|
+
'resistance',
|
|
380
|
+
'hardness',
|
|
381
|
+
'friction',
|
|
382
|
+
'pointRadius',
|
|
383
|
+
'sliderJointLength',
|
|
384
|
+
'allShrinkScale',
|
|
385
|
+
'allStretchScale',
|
|
386
|
+
'structuralShrinkVertical',
|
|
387
|
+
'structuralStretchVertical',
|
|
388
|
+
'structuralShrinkHorizontal',
|
|
389
|
+
'structuralStretchHorizontal',
|
|
390
|
+
'shearShrink',
|
|
391
|
+
'shearStretch',
|
|
392
|
+
'bendingShrinkVertical',
|
|
393
|
+
'bendingStretchVertical',
|
|
394
|
+
'bendingShrinkHorizontal',
|
|
395
|
+
'bendingStretchHorizontal',
|
|
396
|
+
'fakeWavePower',
|
|
397
|
+
'fakeWaveFreq'
|
|
398
|
+
];
|
|
399
|
+
for (const key of curveKeys){
|
|
400
|
+
const curve = config.curves[key];
|
|
401
|
+
if (curve !== undefined) {
|
|
402
|
+
this._config.curves[key] = this._cloneInterpolatorScalar(curve);
|
|
403
|
+
refreshPoints = true;
|
|
404
|
+
}
|
|
405
|
+
}
|
|
406
|
+
}
|
|
407
|
+
if (config.constraintOptions) {
|
|
408
|
+
const optionKeys = [
|
|
409
|
+
'structuralVertical',
|
|
410
|
+
'structuralHorizontal',
|
|
411
|
+
'shear',
|
|
412
|
+
'bendingVertical',
|
|
413
|
+
'bendingHorizontal',
|
|
414
|
+
'isLoop',
|
|
415
|
+
'collideStructuralVertical',
|
|
416
|
+
'collideStructuralHorizontal',
|
|
417
|
+
'collideShear',
|
|
418
|
+
'enableSurfaceCollision'
|
|
419
|
+
];
|
|
420
|
+
for (const key of optionKeys){
|
|
421
|
+
const value = config.constraintOptions[key];
|
|
422
|
+
if (value !== undefined) {
|
|
423
|
+
this._config.constraintOptions[key] = value;
|
|
424
|
+
if (key === 'enableSurfaceCollision' && config.enableSurfaceCollision === undefined) {
|
|
425
|
+
this._config.enableSurfaceCollision = value;
|
|
426
|
+
}
|
|
427
|
+
refreshConstraints = true;
|
|
428
|
+
}
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
if (refreshConstraints) {
|
|
432
|
+
this._rebuildConstraints();
|
|
433
|
+
this._baseConstraintLengths = this._constraints.map((constraint)=>constraint.length);
|
|
434
|
+
this._updateScaleDependentParameters(true);
|
|
435
|
+
}
|
|
436
|
+
if (refreshPoints) {
|
|
437
|
+
this._refreshPointParameters();
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
/**
|
|
246
441
|
* Compensates for teleportation by resetting the previous root transform to the current one.
|
|
247
442
|
* Call this after a character warp or teleport to avoid a large root-motion impulse on the
|
|
248
443
|
* next simulation step.
|
|
@@ -326,7 +521,7 @@ import { Vector3, Quaternion, Matrix4x4, clamp01 } from '@zephyr3d/base';
|
|
|
326
521
|
* The final wind contribution is still scaled per point by `windForceScale` and mass.
|
|
327
522
|
* @param wind - Wind vector in world space.
|
|
328
523
|
*/ setWindForce(wind) {
|
|
329
|
-
this._config.windForce = wind;
|
|
524
|
+
this._config.windForce = wind.clone();
|
|
330
525
|
}
|
|
331
526
|
/**
|
|
332
527
|
* Enable/disable broad-phase pruning for runtime performance comparison
|
|
@@ -595,6 +790,10 @@ import { Vector3, Quaternion, Matrix4x4, clamp01 } from '@zephyr3d/base';
|
|
|
595
790
|
}
|
|
596
791
|
return this._config.blendRatio;
|
|
597
792
|
}
|
|
793
|
+
_refreshCachedSimulationConfig() {
|
|
794
|
+
this._rebuildConstraints();
|
|
795
|
+
this._refreshPointParameters();
|
|
796
|
+
}
|
|
598
797
|
_getColliderIndex(handle) {
|
|
599
798
|
if (handle.type !== 'collider') {
|
|
600
799
|
return -1;
|
|
@@ -647,13 +846,61 @@ import { Vector3, Quaternion, Matrix4x4, clamp01 } from '@zephyr3d/base';
|
|
|
647
846
|
this._grabberHandleToIndex.set(this._grabberHandleIds[i], i);
|
|
648
847
|
}
|
|
649
848
|
}
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
849
|
+
_rebuildConstraints() {
|
|
850
|
+
if (this._rootPoints.length === 0) {
|
|
851
|
+
this._constraints = [];
|
|
852
|
+
this._surfaceConstraints = [];
|
|
853
|
+
return;
|
|
854
|
+
}
|
|
855
|
+
this._constraints = buildConstraints(this._rootPoints, this._config.constraintOptions);
|
|
856
|
+
this._surfaceConstraints = buildSurfaceFaces(this._rootPoints, this._config.constraintOptions.isLoop);
|
|
857
|
+
}
|
|
858
|
+
_getSystemUniformScale() {
|
|
859
|
+
if (!this._rootTransform) {
|
|
860
|
+
return 1;
|
|
861
|
+
}
|
|
862
|
+
const scale = this._rootTransform.getWorldScale();
|
|
863
|
+
return Math.max((Math.abs(scale.x) + Math.abs(scale.y) + Math.abs(scale.z)) / 3, EPSILON);
|
|
864
|
+
}
|
|
865
|
+
_updateScaleDependentParameters(force = false) {
|
|
866
|
+
const systemScale = this._getSystemUniformScale();
|
|
867
|
+
const scaleChanged = Math.abs(systemScale - this._currentSystemScale) > EPSILON;
|
|
868
|
+
if (!force && !scaleChanged) {
|
|
869
|
+
return;
|
|
870
|
+
}
|
|
871
|
+
this._currentSystemScale = systemScale;
|
|
872
|
+
const ratio = this._baseSystemScale > EPSILON ? systemScale / this._baseSystemScale : 1;
|
|
873
|
+
for(let i = 0; i < this._pointsR.length; i++){
|
|
874
|
+
this._pointsR[i].parentLength = (this._basePointParentLengths[i] ?? this._pointsR[i].parentLength) * ratio;
|
|
875
|
+
}
|
|
876
|
+
for(let i = 0; i < this._constraints.length; i++){
|
|
877
|
+
this._constraints[i].length = (this._baseConstraintLengths[i] ?? this._constraints[i].length) * ratio;
|
|
878
|
+
}
|
|
879
|
+
this._refreshPointParameters();
|
|
880
|
+
if (scaleChanged) {
|
|
881
|
+
for(let i = 0; i < this._pointsRW.length; i++){
|
|
882
|
+
const pos = this._pointTransforms[i].getWorldPosition();
|
|
883
|
+
this._pointsRW[i].positionCurrent = pos.clone();
|
|
884
|
+
this._pointsRW[i].positionPrevious = pos.clone();
|
|
885
|
+
this._pointsRW[i].positionCurrentTransform = pos.clone();
|
|
886
|
+
this._pointsRW[i].positionPreviousTransform = pos.clone();
|
|
887
|
+
}
|
|
888
|
+
this.warp();
|
|
889
|
+
}
|
|
890
|
+
}
|
|
891
|
+
_refreshPointParameters() {
|
|
892
|
+
if (!this._initialized) {
|
|
893
|
+
return;
|
|
894
|
+
}
|
|
895
|
+
for(let i = 0; i < this._allPoints.length; i++){
|
|
896
|
+
this._applyConfigToPoint(this._pointsR[i], this._allPoints[i]);
|
|
897
|
+
}
|
|
898
|
+
}
|
|
899
|
+
_createPointR(node) {
|
|
900
|
+
const parentIdx = this._parentMap.get(node.index) ?? -1;
|
|
654
901
|
const childIdx = node.children.length > 0 ? node.children[0].index : -1;
|
|
655
902
|
// Capture initial local transform for rotation blending
|
|
656
|
-
const t =
|
|
903
|
+
const t = this._pointTransforms[node.index];
|
|
657
904
|
const initLocalPos = t.getLocalPosition();
|
|
658
905
|
const initLocalRot = t.getLocalRotation();
|
|
659
906
|
const initLocalScale = t.getLocalScale();
|
|
@@ -662,39 +909,39 @@ import { Vector3, Quaternion, Matrix4x4, clamp01 } from '@zephyr3d/base';
|
|
|
662
909
|
// ParentLength: distance to parent
|
|
663
910
|
let parentLength = 0;
|
|
664
911
|
if (parentIdx !== -1) {
|
|
665
|
-
const pPos =
|
|
666
|
-
const cPos =
|
|
912
|
+
const pPos = this._pointTransforms[parentIdx].getWorldPosition();
|
|
913
|
+
const cPos = this._pointTransforms[node.index].getWorldPosition();
|
|
667
914
|
parentLength = Vector3.distance(pPos, cPos);
|
|
668
915
|
}
|
|
669
|
-
|
|
916
|
+
const point = {
|
|
670
917
|
parent: parentIdx,
|
|
671
918
|
child: childIdx,
|
|
672
919
|
applyInvertCollision: 0,
|
|
673
920
|
movableLimitIndex: -1,
|
|
674
921
|
movableLimitRadius: 0,
|
|
675
922
|
weight: node.isFixed ? 0 : 1,
|
|
676
|
-
mass:
|
|
677
|
-
resistance:
|
|
678
|
-
hardness:
|
|
679
|
-
frictionScale:
|
|
680
|
-
sliderJointLength:
|
|
923
|
+
mass: 0,
|
|
924
|
+
resistance: 0,
|
|
925
|
+
hardness: 0,
|
|
926
|
+
frictionScale: 0,
|
|
927
|
+
sliderJointLength: 0,
|
|
681
928
|
parentLength,
|
|
682
|
-
structuralShrinkVertical:
|
|
683
|
-
structuralStretchVertical:
|
|
684
|
-
structuralShrinkHorizontal:
|
|
685
|
-
structuralStretchHorizontal:
|
|
686
|
-
shearShrink:
|
|
687
|
-
shearStretch:
|
|
688
|
-
bendingShrinkVertical:
|
|
689
|
-
bendingStretchVertical:
|
|
690
|
-
bendingShrinkHorizontal:
|
|
691
|
-
bendingStretchHorizontal:
|
|
692
|
-
windForceScale:
|
|
693
|
-
fakeWavePower:
|
|
694
|
-
fakeWaveFreq:
|
|
929
|
+
structuralShrinkVertical: 0,
|
|
930
|
+
structuralStretchVertical: 0,
|
|
931
|
+
structuralShrinkHorizontal: 0,
|
|
932
|
+
structuralStretchHorizontal: 0,
|
|
933
|
+
shearShrink: 0,
|
|
934
|
+
shearStretch: 0,
|
|
935
|
+
bendingShrinkVertical: 0,
|
|
936
|
+
bendingStretchVertical: 0,
|
|
937
|
+
bendingShrinkHorizontal: 0,
|
|
938
|
+
bendingStretchHorizontal: 0,
|
|
939
|
+
windForceScale: 0,
|
|
940
|
+
fakeWavePower: 0,
|
|
941
|
+
fakeWaveFreq: 0,
|
|
695
942
|
forceFadeRatio: 0,
|
|
696
|
-
pointRadius:
|
|
697
|
-
gravity: Vector3.
|
|
943
|
+
pointRadius: 0,
|
|
944
|
+
gravity: Vector3.zero(),
|
|
698
945
|
boneAxis,
|
|
699
946
|
initialLocalScale: initLocalScale,
|
|
700
947
|
initialLocalRotation: initLocalRot,
|
|
@@ -705,6 +952,35 @@ import { Vector3, Quaternion, Matrix4x4, clamp01 } from '@zephyr3d/base';
|
|
|
705
952
|
})(),
|
|
706
953
|
initialLocalPosition: initLocalPos
|
|
707
954
|
};
|
|
955
|
+
this._applyConfigToPoint(point, node);
|
|
956
|
+
return point;
|
|
957
|
+
}
|
|
958
|
+
_applyConfigToPoint(point, node) {
|
|
959
|
+
const rate = this._maxPointDepth > 0 ? node.depth / this._maxPointDepth : 0;
|
|
960
|
+
const c = this._config.curves;
|
|
961
|
+
const allShrinkScale = c.allShrinkScale.evaluate(rate);
|
|
962
|
+
const allStretchScale = c.allStretchScale.evaluate(rate);
|
|
963
|
+
point.mass = c.massScale.evaluate(rate);
|
|
964
|
+
point.resistance = clamp01(c.resistance.evaluate(rate));
|
|
965
|
+
point.hardness = clamp01(c.hardness.evaluate(rate));
|
|
966
|
+
point.frictionScale = c.friction.evaluate(rate);
|
|
967
|
+
point.sliderJointLength = c.sliderJointLength.evaluate(rate);
|
|
968
|
+
point.structuralShrinkVertical = c.structuralShrinkVertical.evaluate(rate) * allShrinkScale * 0.5;
|
|
969
|
+
point.structuralStretchVertical = c.structuralStretchVertical.evaluate(rate) * allStretchScale * 0.5;
|
|
970
|
+
point.structuralShrinkHorizontal = c.structuralShrinkHorizontal.evaluate(rate) * allShrinkScale * 0.5;
|
|
971
|
+
point.structuralStretchHorizontal = c.structuralStretchHorizontal.evaluate(rate) * allStretchScale * 0.5;
|
|
972
|
+
point.shearShrink = c.shearShrink.evaluate(rate) * allShrinkScale * 0.5;
|
|
973
|
+
point.shearStretch = c.shearStretch.evaluate(rate) * allStretchScale * 0.5;
|
|
974
|
+
point.bendingShrinkVertical = c.bendingShrinkVertical.evaluate(rate) * allShrinkScale * 0.5;
|
|
975
|
+
point.bendingStretchVertical = c.bendingStretchVertical.evaluate(rate) * allStretchScale * 0.5;
|
|
976
|
+
point.bendingShrinkHorizontal = c.bendingShrinkHorizontal.evaluate(rate) * allShrinkScale * 0.5;
|
|
977
|
+
point.bendingStretchHorizontal = c.bendingStretchHorizontal.evaluate(rate) * allStretchScale * 0.5;
|
|
978
|
+
point.windForceScale = c.windForceScale.evaluate(rate) * rate;
|
|
979
|
+
point.fakeWavePower = c.fakeWavePower.evaluate(rate);
|
|
980
|
+
point.fakeWaveFreq = c.fakeWaveFreq.evaluate(rate);
|
|
981
|
+
const systemScale = this._currentSystemScale;
|
|
982
|
+
point.pointRadius = Math.max(0, c.pointRadius.evaluate(rate) * systemScale);
|
|
983
|
+
point.gravity = Vector3.scale(this._config.gravity, c.gravityScale.evaluate(rate) * systemScale);
|
|
708
984
|
}
|
|
709
985
|
_createPointRW() {
|
|
710
986
|
return {
|
|
@@ -738,9 +1014,80 @@ import { Vector3, Quaternion, Matrix4x4, clamp01 } from '@zephyr3d/base';
|
|
|
738
1014
|
localBoundsMin: Vector3.zero(),
|
|
739
1015
|
localBoundsMax: Vector3.zero(),
|
|
740
1016
|
radius: 0,
|
|
1017
|
+
height: 0,
|
|
741
1018
|
enabled: 1
|
|
742
1019
|
};
|
|
743
1020
|
}
|
|
1021
|
+
_cloneControllerConfig(config) {
|
|
1022
|
+
const curves = {
|
|
1023
|
+
massScale: this._cloneInterpolatorScalar(config.curves.massScale),
|
|
1024
|
+
gravityScale: this._cloneInterpolatorScalar(config.curves.gravityScale),
|
|
1025
|
+
windForceScale: this._cloneInterpolatorScalar(config.curves.windForceScale),
|
|
1026
|
+
resistance: this._cloneInterpolatorScalar(config.curves.resistance),
|
|
1027
|
+
hardness: this._cloneInterpolatorScalar(config.curves.hardness),
|
|
1028
|
+
friction: this._cloneInterpolatorScalar(config.curves.friction),
|
|
1029
|
+
pointRadius: this._cloneInterpolatorScalar(config.curves.pointRadius),
|
|
1030
|
+
sliderJointLength: this._cloneInterpolatorScalar(config.curves.sliderJointLength),
|
|
1031
|
+
allShrinkScale: this._cloneInterpolatorScalar(config.curves.allShrinkScale),
|
|
1032
|
+
allStretchScale: this._cloneInterpolatorScalar(config.curves.allStretchScale),
|
|
1033
|
+
structuralShrinkVertical: this._cloneInterpolatorScalar(config.curves.structuralShrinkVertical),
|
|
1034
|
+
structuralStretchVertical: this._cloneInterpolatorScalar(config.curves.structuralStretchVertical),
|
|
1035
|
+
structuralShrinkHorizontal: this._cloneInterpolatorScalar(config.curves.structuralShrinkHorizontal),
|
|
1036
|
+
structuralStretchHorizontal: this._cloneInterpolatorScalar(config.curves.structuralStretchHorizontal),
|
|
1037
|
+
shearShrink: this._cloneInterpolatorScalar(config.curves.shearShrink),
|
|
1038
|
+
shearStretch: this._cloneInterpolatorScalar(config.curves.shearStretch),
|
|
1039
|
+
bendingShrinkVertical: this._cloneInterpolatorScalar(config.curves.bendingShrinkVertical),
|
|
1040
|
+
bendingStretchVertical: this._cloneInterpolatorScalar(config.curves.bendingStretchVertical),
|
|
1041
|
+
bendingShrinkHorizontal: this._cloneInterpolatorScalar(config.curves.bendingShrinkHorizontal),
|
|
1042
|
+
bendingStretchHorizontal: this._cloneInterpolatorScalar(config.curves.bendingStretchHorizontal),
|
|
1043
|
+
fakeWavePower: this._cloneInterpolatorScalar(config.curves.fakeWavePower),
|
|
1044
|
+
fakeWaveFreq: this._cloneInterpolatorScalar(config.curves.fakeWaveFreq)
|
|
1045
|
+
};
|
|
1046
|
+
return {
|
|
1047
|
+
gravity: config.gravity.clone(),
|
|
1048
|
+
windForce: config.windForce.clone(),
|
|
1049
|
+
relaxation: config.relaxation,
|
|
1050
|
+
subSteps: config.subSteps,
|
|
1051
|
+
rootSlideLimit: config.rootSlideLimit,
|
|
1052
|
+
rootRotateLimit: config.rootRotateLimit,
|
|
1053
|
+
constraintShrinkLimit: config.constraintShrinkLimit,
|
|
1054
|
+
blendRatio: config.blendRatio,
|
|
1055
|
+
stabilizationFrameRate: config.stabilizationFrameRate,
|
|
1056
|
+
isFakeWave: config.isFakeWave,
|
|
1057
|
+
fakeWaveSpeed: config.fakeWaveSpeed,
|
|
1058
|
+
fakeWavePower: config.fakeWavePower,
|
|
1059
|
+
enableSurfaceCollision: config.enableSurfaceCollision,
|
|
1060
|
+
enableBroadPhase: config.enableBroadPhase,
|
|
1061
|
+
preserveTwist: config.preserveTwist,
|
|
1062
|
+
angleLimitConfig: {
|
|
1063
|
+
angleLimit: config.angleLimitConfig.angleLimit,
|
|
1064
|
+
limitFromRoot: config.angleLimitConfig.limitFromRoot
|
|
1065
|
+
},
|
|
1066
|
+
curves,
|
|
1067
|
+
constraintOptions: {
|
|
1068
|
+
structuralVertical: config.constraintOptions.structuralVertical,
|
|
1069
|
+
structuralHorizontal: config.constraintOptions.structuralHorizontal,
|
|
1070
|
+
shear: config.constraintOptions.shear,
|
|
1071
|
+
bendingVertical: config.constraintOptions.bendingVertical,
|
|
1072
|
+
bendingHorizontal: config.constraintOptions.bendingHorizontal,
|
|
1073
|
+
isLoop: config.constraintOptions.isLoop,
|
|
1074
|
+
collideStructuralVertical: config.constraintOptions.collideStructuralVertical,
|
|
1075
|
+
collideStructuralHorizontal: config.constraintOptions.collideStructuralHorizontal,
|
|
1076
|
+
collideShear: config.constraintOptions.collideShear,
|
|
1077
|
+
enableSurfaceCollision: config.constraintOptions.enableSurfaceCollision
|
|
1078
|
+
}
|
|
1079
|
+
};
|
|
1080
|
+
}
|
|
1081
|
+
_cloneInterpolatorScalar(curve) {
|
|
1082
|
+
return new InterpolatorScalar(curve.mode, new Float32Array(curve.inputs), new Float32Array(curve.outputs));
|
|
1083
|
+
}
|
|
1084
|
+
_sanitizeControllerConfig(config) {
|
|
1085
|
+
config.relaxation = Math.max(0, Math.trunc(config.relaxation));
|
|
1086
|
+
config.subSteps = Math.max(1, Math.trunc(config.subSteps));
|
|
1087
|
+
config.constraintShrinkLimit = Math.max(0, config.constraintShrinkLimit);
|
|
1088
|
+
config.blendRatio = clamp01(config.blendRatio);
|
|
1089
|
+
return config;
|
|
1090
|
+
}
|
|
744
1091
|
}
|
|
745
1092
|
|
|
746
1093
|
export { JointDynamicsSystemController };
|