reze-engine 0.15.0 → 0.16.0
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/README.md +3 -3
- package/dist/camera.d.ts +2 -0
- package/dist/camera.d.ts.map +1 -1
- package/dist/camera.js +8 -3
- package/dist/engine.d.ts +19 -4
- package/dist/engine.d.ts.map +1 -1
- package/dist/engine.js +294 -27
- package/dist/gpu-profile.d.ts +19 -0
- package/dist/gpu-profile.d.ts.map +1 -0
- package/dist/gpu-profile.js +120 -0
- package/dist/ik-solver.d.ts.map +1 -1
- package/dist/ik-solver.js +13 -7
- package/dist/math.d.ts +2 -0
- package/dist/math.d.ts.map +1 -1
- package/dist/math.js +65 -46
- package/dist/model.d.ts +28 -1
- package/dist/model.d.ts.map +1 -1
- package/dist/model.js +259 -75
- package/dist/physics/body.d.ts +2 -0
- package/dist/physics/body.d.ts.map +1 -1
- package/dist/physics/body.js +30 -0
- package/dist/physics/constraint.d.ts +13 -0
- package/dist/physics/constraint.d.ts.map +1 -1
- package/dist/physics/constraint.js +13 -0
- package/dist/physics/contact.d.ts +28 -0
- package/dist/physics/contact.d.ts.map +1 -1
- package/dist/physics/contact.js +27 -32
- package/dist/physics/physics.d.ts +3 -0
- package/dist/physics/physics.d.ts.map +1 -1
- package/dist/physics/physics.js +57 -8
- package/dist/physics/profile.d.ts +18 -0
- package/dist/physics/profile.d.ts.map +1 -0
- package/dist/physics/profile.js +44 -0
- package/dist/physics/solver.d.ts.map +1 -1
- package/dist/physics/solver.js +436 -293
- package/dist/pmx-loader.d.ts.map +1 -1
- package/dist/pmx-loader.js +2 -30
- package/dist/shaders/materials/body.d.ts +1 -1
- package/dist/shaders/materials/body.d.ts.map +1 -1
- package/dist/shaders/materials/body.js +3 -1
- package/dist/shaders/materials/cloth_rough.d.ts +1 -1
- package/dist/shaders/materials/cloth_rough.d.ts.map +1 -1
- package/dist/shaders/materials/cloth_rough.js +3 -1
- package/dist/shaders/materials/cloth_smooth.d.ts +1 -1
- package/dist/shaders/materials/cloth_smooth.d.ts.map +1 -1
- package/dist/shaders/materials/common.d.ts +2 -2
- package/dist/shaders/materials/common.d.ts.map +1 -1
- package/dist/shaders/materials/common.js +8 -0
- package/dist/shaders/materials/default.d.ts +1 -1
- package/dist/shaders/materials/default.d.ts.map +1 -1
- package/dist/shaders/materials/eye.d.ts +1 -1
- package/dist/shaders/materials/eye.d.ts.map +1 -1
- package/dist/shaders/materials/face.d.ts +1 -1
- package/dist/shaders/materials/face.d.ts.map +1 -1
- package/dist/shaders/materials/face.js +4 -1
- package/dist/shaders/materials/hair.d.ts +1 -1
- package/dist/shaders/materials/hair.d.ts.map +1 -1
- package/dist/shaders/materials/metal.d.ts +1 -1
- package/dist/shaders/materials/metal.d.ts.map +1 -1
- package/dist/shaders/materials/stockings.d.ts +1 -1
- package/dist/shaders/materials/stockings.d.ts.map +1 -1
- package/dist/shaders/materials/stockings.js +13 -9
- package/dist/shaders/passes/composite.d.ts +1 -1
- package/dist/shaders/passes/composite.d.ts.map +1 -1
- package/dist/shaders/passes/composite.js +18 -12
- package/dist/shaders/passes/morph.d.ts +2 -0
- package/dist/shaders/passes/morph.d.ts.map +1 -0
- package/dist/shaders/passes/morph.js +49 -0
- package/package.json +1 -1
- package/src/camera.ts +9 -3
- package/src/engine.ts +336 -29
- package/src/ik-solver.ts +14 -7
- package/src/math.ts +41 -51
- package/src/model.ts +288 -91
- package/src/physics/body.ts +29 -0
- package/src/physics/constraint.ts +30 -0
- package/src/physics/contact.ts +43 -30
- package/src/physics/physics.ts +58 -17
- package/src/physics/solver.ts +431 -284
- package/src/pmx-loader.ts +2 -35
- package/src/shaders/materials/body.ts +3 -1
- package/src/shaders/materials/cloth_rough.ts +3 -1
- package/src/shaders/materials/common.ts +8 -0
- package/src/shaders/materials/face.ts +4 -1
- package/src/shaders/materials/stockings.ts +13 -9
- package/src/shaders/passes/composite.ts +18 -12
- package/src/shaders/passes/morph.ts +50 -0
- package/dist/physics-debug.d.ts +0 -30
- package/dist/physics-debug.d.ts.map +0 -1
- package/dist/physics-debug.js +0 -526
- package/dist/shaders/passes/physics-debug.d.ts +0 -2
- package/dist/shaders/passes/physics-debug.d.ts.map +0 -1
- package/dist/shaders/passes/physics-debug.js +0 -69
package/dist/model.js
CHANGED
|
@@ -6,6 +6,13 @@ import { VMDLoader } from "./vmd-loader";
|
|
|
6
6
|
import { VMDWriter } from "./vmd-writer";
|
|
7
7
|
import { AnimationState, interpolateControlPoints, rawInterpolationToBoneInterpolation, } from "./animation";
|
|
8
8
|
const VERTEX_STRIDE = 8;
|
|
9
|
+
// Animation-sampling scratch (applyPoseFromClip → convertVMDTranslationToLocal). These
|
|
10
|
+
// run sequentially and are not reentrant with the world-matrix scratch in math.ts, so
|
|
11
|
+
// plain module singletons are safe and let the per-bone sample path allocate nothing.
|
|
12
|
+
const _animSlerp = new Quat(0, 0, 0, 1);
|
|
13
|
+
const _animInterpT = new Vec3(0, 0, 0);
|
|
14
|
+
const _convOut = new Vec3(0, 0, 0);
|
|
15
|
+
const _convMat = new Float32Array(16);
|
|
9
16
|
export class Model {
|
|
10
17
|
get name() {
|
|
11
18
|
return this._name;
|
|
@@ -37,6 +44,15 @@ export class Model {
|
|
|
37
44
|
}
|
|
38
45
|
constructor(vertexData, indexData, textures, materials, skeleton, skinning, morphing, rigidbodies = [], joints = []) {
|
|
39
46
|
this._name = "";
|
|
47
|
+
this.morphPrevMinVert = -1; // vertices touched by last applyMorphs (reset to base this pass)
|
|
48
|
+
this.morphPrevMaxVert = -1;
|
|
49
|
+
this.morphPendingMinVert = -1; // accumulated range awaiting a GPU upload
|
|
50
|
+
this.morphPendingMaxVert = -1;
|
|
51
|
+
this.morphUploadFull = true; // first upload after load pushes the whole buffer once
|
|
52
|
+
// GPU morph path: when enabled (engine set up the compute buffers), applyMorphs only
|
|
53
|
+
// resolves effective weights and flags them dirty — the compute pass does the vertex work.
|
|
54
|
+
this.gpuMorphEnabled = false;
|
|
55
|
+
this.morphWeightsDirty = false;
|
|
40
56
|
this.textures = [];
|
|
41
57
|
this.materials = [];
|
|
42
58
|
// Physics data from PMX
|
|
@@ -141,6 +157,58 @@ export class Model {
|
|
|
141
157
|
}
|
|
142
158
|
this.runtimeSkeleton.ikChainInfo = ikChainInfo;
|
|
143
159
|
this.runtimeSkeleton.ikSolvers = ikSolvers;
|
|
160
|
+
this.buildDeformOrder();
|
|
161
|
+
}
|
|
162
|
+
// Precompute the bone order that computeWorldMatrices iterates every frame: every
|
|
163
|
+
// bone appears after its parent. This is the exact finishing order the previous
|
|
164
|
+
// recursive computeWorld() produced (walk up the not-yet-emitted ancestor chain,
|
|
165
|
+
// then emit it top-down; ties broken by ascending index) — so behavior is identical,
|
|
166
|
+
// minus the per-frame closure + visited-array allocation and the recursion overhead.
|
|
167
|
+
buildDeformOrder() {
|
|
168
|
+
const bones = this.skeleton.bones;
|
|
169
|
+
const n = bones.length;
|
|
170
|
+
const order = new Int32Array(n);
|
|
171
|
+
const done = new Uint8Array(n);
|
|
172
|
+
const stack = [];
|
|
173
|
+
let k = 0;
|
|
174
|
+
for (let i = 0; i < n; i++) {
|
|
175
|
+
if (done[i])
|
|
176
|
+
continue;
|
|
177
|
+
stack.length = 0;
|
|
178
|
+
let cur = i;
|
|
179
|
+
// Collect the chain of not-yet-emitted ancestors up to the root (or a done one).
|
|
180
|
+
while (cur >= 0 && cur < n && !done[cur]) {
|
|
181
|
+
stack.push(cur);
|
|
182
|
+
cur = bones[cur].parentIndex;
|
|
183
|
+
}
|
|
184
|
+
// Emit from the topmost ancestor down so parents precede children.
|
|
185
|
+
for (let s = stack.length - 1; s >= 0; s--) {
|
|
186
|
+
const b = stack[s];
|
|
187
|
+
done[b] = 1;
|
|
188
|
+
order[k++] = b;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
this.deformOrder = order;
|
|
192
|
+
// Accumulate bind-pose world positions in the same parent-before-child order and
|
|
193
|
+
// with the same add order as the old recursive computeBindPoseWorldPosition, so the
|
|
194
|
+
// downstream arithmetic stays bit-identical.
|
|
195
|
+
const bindWorld = new Float32Array(n * 3);
|
|
196
|
+
for (let idx = 0; idx < n; idx++) {
|
|
197
|
+
const i = order[idx];
|
|
198
|
+
const bt = bones[i].bindTranslation;
|
|
199
|
+
const p = bones[i].parentIndex;
|
|
200
|
+
if (p >= 0 && p < n) {
|
|
201
|
+
bindWorld[i * 3 + 0] = bindWorld[p * 3 + 0] + bt[0];
|
|
202
|
+
bindWorld[i * 3 + 1] = bindWorld[p * 3 + 1] + bt[1];
|
|
203
|
+
bindWorld[i * 3 + 2] = bindWorld[p * 3 + 2] + bt[2];
|
|
204
|
+
}
|
|
205
|
+
else {
|
|
206
|
+
bindWorld[i * 3 + 0] = bt[0];
|
|
207
|
+
bindWorld[i * 3 + 1] = bt[1];
|
|
208
|
+
bindWorld[i * 3 + 2] = bt[2];
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
this.bindWorldPos = bindWorld;
|
|
144
212
|
}
|
|
145
213
|
initializeTweenBuffers() {
|
|
146
214
|
const boneCount = this.skeleton.bones.length;
|
|
@@ -411,51 +479,50 @@ export class Model {
|
|
|
411
479
|
}
|
|
412
480
|
}
|
|
413
481
|
// VMD translation (world delta from bind pose) → bone local space; optional rotation for animation vs IK
|
|
482
|
+
// Returns a REUSED scratch Vec3 (_convOut) — callers must copy immediately (they do:
|
|
483
|
+
// .set() / destructure). Zero allocation; result is bit-identical to the previous
|
|
484
|
+
// recursive implementation (verified numerically).
|
|
414
485
|
convertVMDTranslationToLocal(boneIdx, vmdRelativeTranslation, rotation) {
|
|
415
|
-
const
|
|
416
|
-
const
|
|
417
|
-
const
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
const
|
|
431
|
-
|
|
432
|
-
//
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
let
|
|
438
|
-
if (
|
|
439
|
-
|
|
486
|
+
const bone = this.skeleton.bones[boneIdx];
|
|
487
|
+
const bindWorld = this.bindWorldPos;
|
|
488
|
+
const bt = bone.bindTranslation;
|
|
489
|
+
const p = bone.parentIndex;
|
|
490
|
+
// afterBindTranslation = (bindWorld[bone] + vmd − bindWorld[parent]) − bindTranslation.
|
|
491
|
+
// (Algebraically this reduces to vmd, since bindWorld[bone] = bindWorld[parent] +
|
|
492
|
+
// bindTranslation, but the explicit form keeps the result bit-identical to before.)
|
|
493
|
+
const bi3 = boneIdx * 3;
|
|
494
|
+
const targetX = bindWorld[bi3 + 0] + vmdRelativeTranslation.x;
|
|
495
|
+
const targetY = bindWorld[bi3 + 1] + vmdRelativeTranslation.y;
|
|
496
|
+
const targetZ = bindWorld[bi3 + 2] + vmdRelativeTranslation.z;
|
|
497
|
+
const px = p >= 0 ? bindWorld[p * 3 + 0] : 0;
|
|
498
|
+
const py = p >= 0 ? bindWorld[p * 3 + 1] : 0;
|
|
499
|
+
const pz = p >= 0 ? bindWorld[p * 3 + 2] : 0;
|
|
500
|
+
const abx = targetX - px - bt[0];
|
|
501
|
+
const aby = targetY - py - bt[1];
|
|
502
|
+
const abz = targetZ - pz - bt[2];
|
|
503
|
+
// Inverse rotation = conjugate + normalize (matches localRotation.clone().conjugate()
|
|
504
|
+
// .normalize()), applied via a rotation matrix (matches Mat4.fromQuat). Uses animation
|
|
505
|
+
// rotation when provided so IK-modified localRot doesn't perturb the conversion.
|
|
506
|
+
const q = rotation ?? this.runtimeSkeleton.localRotations[boneIdx];
|
|
507
|
+
const qlen = Math.sqrt(q.x * q.x + q.y * q.y + q.z * q.z + q.w * q.w);
|
|
508
|
+
let ix, iy, iz, iw;
|
|
509
|
+
if (qlen === 0) {
|
|
510
|
+
ix = 0;
|
|
511
|
+
iy = 0;
|
|
512
|
+
iz = 0;
|
|
513
|
+
iw = 1;
|
|
440
514
|
}
|
|
441
515
|
else {
|
|
442
|
-
|
|
516
|
+
const inv = 1 / qlen;
|
|
517
|
+
ix = -q.x * inv;
|
|
518
|
+
iy = -q.y * inv;
|
|
519
|
+
iz = -q.z * inv;
|
|
520
|
+
iw = q.w * inv;
|
|
443
521
|
}
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
const afterBindTranslation = parentSpacePos.subtract(new Vec3(bone.bindTranslation[0], bone.bindTranslation[1], bone.bindTranslation[2]));
|
|
449
|
-
// Apply inverse rotation to get local translation
|
|
450
|
-
// Use provided rotation (animation rotation) or fall back to current localRotation
|
|
451
|
-
// Using animation rotation prevents conflicts when IK modifies the rotation
|
|
452
|
-
const localRotation = rotation ?? localRot[boneIdx];
|
|
453
|
-
// Clone to avoid mutating, then conjugate and normalize
|
|
454
|
-
const invRotation = localRotation.clone().conjugate().normalize();
|
|
455
|
-
const rotationMat = Mat4.fromQuat(invRotation.x, invRotation.y, invRotation.z, invRotation.w);
|
|
456
|
-
const rm = rotationMat.values;
|
|
457
|
-
const localTranslation = new Vec3(rm[0] * afterBindTranslation.x + rm[4] * afterBindTranslation.y + rm[8] * afterBindTranslation.z, rm[1] * afterBindTranslation.x + rm[5] * afterBindTranslation.y + rm[9] * afterBindTranslation.z, rm[2] * afterBindTranslation.x + rm[6] * afterBindTranslation.y + rm[10] * afterBindTranslation.z);
|
|
458
|
-
return localTranslation;
|
|
522
|
+
Mat4.fromQuatInto(ix, iy, iz, iw, _convMat, 0);
|
|
523
|
+
const rm = _convMat;
|
|
524
|
+
_convOut.setXYZ(rm[0] * abx + rm[4] * aby + rm[8] * abz, rm[1] * abx + rm[5] * aby + rm[9] * abz, rm[2] * abx + rm[6] * aby + rm[10] * abz);
|
|
525
|
+
return _convOut;
|
|
459
526
|
}
|
|
460
527
|
getWorldMatrices() {
|
|
461
528
|
return this.runtimeSkeleton.worldMatrices;
|
|
@@ -552,13 +619,15 @@ export class Model {
|
|
|
552
619
|
this.applyMorphs();
|
|
553
620
|
}
|
|
554
621
|
applyMorphs() {
|
|
555
|
-
// Reset vertex data to base positions
|
|
556
|
-
this.vertexData.set(this.baseVertexData);
|
|
557
622
|
const vertexCount = this.vertexCount;
|
|
558
623
|
const morphCount = this.morphing.morphs.length;
|
|
559
624
|
const weights = this.runtimeMorph.weights;
|
|
560
|
-
//
|
|
561
|
-
|
|
625
|
+
// Effective weights (group-morph resolution + clamp). Both paths need these: the GPU
|
|
626
|
+
// path uploads them for the compute pass; the CPU path applies them below. Reused buffer.
|
|
627
|
+
if (!this.morphEffectiveWeights || this.morphEffectiveWeights.length !== morphCount) {
|
|
628
|
+
this.morphEffectiveWeights = new Float32Array(morphCount);
|
|
629
|
+
}
|
|
630
|
+
const effectiveWeights = this.morphEffectiveWeights;
|
|
562
631
|
effectiveWeights.set(weights); // Start with direct weights
|
|
563
632
|
// Apply group morphs: group morph weight * ratio affects referenced morphs
|
|
564
633
|
for (let morphIdx = 0; morphIdx < morphCount; morphIdx++) {
|
|
@@ -568,18 +637,30 @@ export class Model {
|
|
|
568
637
|
if (groupWeight > 0.0001) {
|
|
569
638
|
for (const ref of morph.groupReferences) {
|
|
570
639
|
if (ref.morphIndex >= 0 && ref.morphIndex < morphCount) {
|
|
571
|
-
// Add group morph's contribution to the referenced morph
|
|
572
640
|
effectiveWeights[ref.morphIndex] += groupWeight * ref.ratio;
|
|
573
641
|
}
|
|
574
642
|
}
|
|
575
643
|
}
|
|
576
644
|
}
|
|
577
645
|
}
|
|
578
|
-
// Clamp effective weights to [0, 1]
|
|
579
646
|
for (let i = 0; i < morphCount; i++) {
|
|
580
647
|
effectiveWeights[i] = Math.max(0, Math.min(1, effectiveWeights[i]));
|
|
581
648
|
}
|
|
582
|
-
//
|
|
649
|
+
// GPU path: the compute pass applies the vertex offsets from these weights.
|
|
650
|
+
if (this.gpuMorphEnabled) {
|
|
651
|
+
this.morphWeightsDirty = true;
|
|
652
|
+
return;
|
|
653
|
+
}
|
|
654
|
+
// ── CPU path ── Reset only the vertices morphed by the previous pass back to base
|
|
655
|
+
// (targeted reset; vertexData never diverges from base outside that range).
|
|
656
|
+
if (this.morphPrevMaxVert >= 0) {
|
|
657
|
+
const s = this.morphPrevMinVert * VERTEX_STRIDE;
|
|
658
|
+
const e = (this.morphPrevMaxVert + 1) * VERTEX_STRIDE;
|
|
659
|
+
this.vertexData.set(this.baseVertexData.subarray(s, e), s);
|
|
660
|
+
}
|
|
661
|
+
// Apply vertex morphs, tracking the touched vertex-index range for partial upload.
|
|
662
|
+
let curMinVert = -1;
|
|
663
|
+
let curMaxVert = -1;
|
|
583
664
|
for (let morphIdx = 0; morphIdx < morphCount; morphIdx++) {
|
|
584
665
|
const effectiveWeight = effectiveWeights[morphIdx];
|
|
585
666
|
if (effectiveWeight === 0 || effectiveWeight < 0.0001)
|
|
@@ -587,26 +668,136 @@ export class Model {
|
|
|
587
668
|
const morph = this.morphing.morphs[morphIdx];
|
|
588
669
|
if (morph.type !== 1)
|
|
589
670
|
continue; // Only process vertex morphs
|
|
590
|
-
// For vertex morphs, iterate through vertices that have offsets
|
|
591
671
|
for (const vertexOffset of morph.vertexOffsets) {
|
|
592
672
|
const vIdx = vertexOffset.vertexIndex;
|
|
593
673
|
if (vIdx < 0 || vIdx >= vertexCount)
|
|
594
674
|
continue;
|
|
595
|
-
// Get morph offset for this vertex
|
|
596
675
|
const offsetX = vertexOffset.positionOffset[0];
|
|
597
676
|
const offsetY = vertexOffset.positionOffset[1];
|
|
598
677
|
const offsetZ = vertexOffset.positionOffset[2];
|
|
599
|
-
// Skip if offset is zero
|
|
600
678
|
if (Math.abs(offsetX) < 0.0001 && Math.abs(offsetY) < 0.0001 && Math.abs(offsetZ) < 0.0001) {
|
|
601
679
|
continue;
|
|
602
680
|
}
|
|
603
|
-
// Apply weighted offset to vertex position (positions are at stride 0, 8, 16, ...)
|
|
604
681
|
const vertexIdx = vIdx * VERTEX_STRIDE;
|
|
605
682
|
this.vertexData[vertexIdx] += offsetX * effectiveWeight;
|
|
606
683
|
this.vertexData[vertexIdx + 1] += offsetY * effectiveWeight;
|
|
607
684
|
this.vertexData[vertexIdx + 2] += offsetZ * effectiveWeight;
|
|
685
|
+
if (curMinVert < 0 || vIdx < curMinVert)
|
|
686
|
+
curMinVert = vIdx;
|
|
687
|
+
if (vIdx > curMaxVert)
|
|
688
|
+
curMaxVert = vIdx;
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
let dirtyMin = curMinVert;
|
|
692
|
+
let dirtyMax = curMaxVert;
|
|
693
|
+
if (this.morphPrevMaxVert >= 0) {
|
|
694
|
+
if (dirtyMin < 0 || this.morphPrevMinVert < dirtyMin)
|
|
695
|
+
dirtyMin = this.morphPrevMinVert;
|
|
696
|
+
if (this.morphPrevMaxVert > dirtyMax)
|
|
697
|
+
dirtyMax = this.morphPrevMaxVert;
|
|
698
|
+
}
|
|
699
|
+
if (dirtyMin >= 0 && dirtyMax >= 0) {
|
|
700
|
+
this.morphPendingMinVert =
|
|
701
|
+
this.morphPendingMinVert < 0 ? dirtyMin : Math.min(this.morphPendingMinVert, dirtyMin);
|
|
702
|
+
this.morphPendingMaxVert =
|
|
703
|
+
this.morphPendingMaxVert < 0 ? dirtyMax : Math.max(this.morphPendingMaxVert, dirtyMax);
|
|
704
|
+
}
|
|
705
|
+
this.morphPrevMinVert = curMinVert;
|
|
706
|
+
this.morphPrevMaxVert = curMaxVert;
|
|
707
|
+
}
|
|
708
|
+
// ── GPU morph path support ──
|
|
709
|
+
// Called by the engine once it has created the compute buffers for this model; switches
|
|
710
|
+
// applyMorphs to the weights-only branch.
|
|
711
|
+
enableGpuMorphs() {
|
|
712
|
+
this.gpuMorphEnabled = true;
|
|
713
|
+
}
|
|
714
|
+
// True (once) when morph weights changed since the last check — the engine then uploads
|
|
715
|
+
// getEffectiveMorphWeights() and dispatches the compute pass.
|
|
716
|
+
consumeMorphWeightsDirty() {
|
|
717
|
+
const d = this.morphWeightsDirty;
|
|
718
|
+
this.morphWeightsDirty = false;
|
|
719
|
+
return d;
|
|
720
|
+
}
|
|
721
|
+
// Effective (group-resolved, clamped) morph weights for GPU upload. Ensures they're
|
|
722
|
+
// computed at least once even before the first weight change.
|
|
723
|
+
getEffectiveMorphWeights() {
|
|
724
|
+
if (!this.morphEffectiveWeights)
|
|
725
|
+
this.applyMorphs();
|
|
726
|
+
return this.morphEffectiveWeights ?? new Float32Array(0);
|
|
727
|
+
}
|
|
728
|
+
// Build the CSR inversion of vertex-morph offsets for the GPU compute pass. Returns null
|
|
729
|
+
// when the model has no vertex-morph offsets (no GPU path needed). Entries for each vertex
|
|
730
|
+
// are emitted in ascending morph-index order, matching the CPU accumulation order.
|
|
731
|
+
buildMorphComputeData() {
|
|
732
|
+
const V = this.vertexCount;
|
|
733
|
+
const M = this.morphing.morphs.length;
|
|
734
|
+
const morphs = this.morphing.morphs;
|
|
735
|
+
const EPS = 0.0001;
|
|
736
|
+
const isLive = (o) => o.vertexIndex >= 0 &&
|
|
737
|
+
o.vertexIndex < V &&
|
|
738
|
+
(Math.abs(o.positionOffset[0]) >= EPS ||
|
|
739
|
+
Math.abs(o.positionOffset[1]) >= EPS ||
|
|
740
|
+
Math.abs(o.positionOffset[2]) >= EPS);
|
|
741
|
+
const counts = new Uint32Array(V);
|
|
742
|
+
for (let m = 0; m < M; m++) {
|
|
743
|
+
const morph = morphs[m];
|
|
744
|
+
if (morph.type !== 1)
|
|
745
|
+
continue;
|
|
746
|
+
for (const o of morph.vertexOffsets)
|
|
747
|
+
if (isLive(o))
|
|
748
|
+
counts[o.vertexIndex]++;
|
|
749
|
+
}
|
|
750
|
+
const rowStart = new Uint32Array(V + 1);
|
|
751
|
+
let acc = 0;
|
|
752
|
+
for (let v = 0; v < V; v++) {
|
|
753
|
+
rowStart[v] = acc;
|
|
754
|
+
acc += counts[v];
|
|
755
|
+
}
|
|
756
|
+
rowStart[V] = acc;
|
|
757
|
+
const E = acc;
|
|
758
|
+
if (E === 0)
|
|
759
|
+
return null;
|
|
760
|
+
const colMorph = new Uint32Array(E);
|
|
761
|
+
const colOffset = new Float32Array(E * 3);
|
|
762
|
+
const fill = new Uint32Array(V);
|
|
763
|
+
for (let m = 0; m < M; m++) {
|
|
764
|
+
const morph = morphs[m];
|
|
765
|
+
if (morph.type !== 1)
|
|
766
|
+
continue;
|
|
767
|
+
for (const o of morph.vertexOffsets) {
|
|
768
|
+
if (!isLive(o))
|
|
769
|
+
continue;
|
|
770
|
+
const v = o.vertexIndex;
|
|
771
|
+
const p = rowStart[v] + fill[v]++;
|
|
772
|
+
colMorph[p] = m;
|
|
773
|
+
colOffset[p * 3] = o.positionOffset[0];
|
|
774
|
+
colOffset[p * 3 + 1] = o.positionOffset[1];
|
|
775
|
+
colOffset[p * 3 + 2] = o.positionOffset[2];
|
|
608
776
|
}
|
|
609
777
|
}
|
|
778
|
+
const basePositions = new Float32Array(V * 3);
|
|
779
|
+
for (let v = 0; v < V; v++) {
|
|
780
|
+
const vi = v * VERTEX_STRIDE;
|
|
781
|
+
basePositions[v * 3] = this.baseVertexData[vi];
|
|
782
|
+
basePositions[v * 3 + 1] = this.baseVertexData[vi + 1];
|
|
783
|
+
basePositions[v * 3 + 2] = this.baseVertexData[vi + 2];
|
|
784
|
+
}
|
|
785
|
+
return { basePositions, rowStart, colMorph, colOffset, morphCount: M, vertexCount: V, entryCount: E };
|
|
786
|
+
}
|
|
787
|
+
// Consume the pending morph vertex-upload range for the engine. Returns null when a
|
|
788
|
+
// full upload is needed (first time after load, or nothing tracked), else the inclusive
|
|
789
|
+
// [minVert, maxVert] slice that changed. Resets pending state.
|
|
790
|
+
consumeVertexUploadRange() {
|
|
791
|
+
if (this.morphUploadFull || this.morphPendingMaxVert < 0) {
|
|
792
|
+
this.morphUploadFull = false;
|
|
793
|
+
this.morphPendingMinVert = -1;
|
|
794
|
+
this.morphPendingMaxVert = -1;
|
|
795
|
+
return null;
|
|
796
|
+
}
|
|
797
|
+
const range = { minVert: this.morphPendingMinVert, maxVert: this.morphPendingMaxVert };
|
|
798
|
+
this.morphPendingMinVert = -1;
|
|
799
|
+
this.morphPendingMaxVert = -1;
|
|
800
|
+
return range;
|
|
610
801
|
}
|
|
611
802
|
buildClipFromVmdKeyFrames(vmdKeyFrames) {
|
|
612
803
|
const boneTracksByBone = {};
|
|
@@ -835,11 +1026,11 @@ export class Model {
|
|
|
835
1026
|
const gradient = frameDelta > 0 ? (clampedFrame - frameA.frame) / frameDelta : 0;
|
|
836
1027
|
const interp = frameB.interpolation;
|
|
837
1028
|
const rotT = interpolateControlPoints(interp.rotation, gradient);
|
|
838
|
-
const rotation = Quat.
|
|
1029
|
+
const rotation = Quat.slerpInto(frameA.rotation, frameB.rotation, rotT, _animSlerp);
|
|
839
1030
|
const txWeight = interpolateControlPoints(interp.translationX, gradient);
|
|
840
1031
|
const tyWeight = interpolateControlPoints(interp.translationY, gradient);
|
|
841
1032
|
const tzWeight = interpolateControlPoints(interp.translationZ, gradient);
|
|
842
|
-
const interpolatedVMDTranslation =
|
|
1033
|
+
const interpolatedVMDTranslation = _animInterpT.setXYZ(frameA.translation.x + (frameB.translation.x - frameA.translation.x) * txWeight, frameA.translation.y + (frameB.translation.y - frameA.translation.y) * tyWeight, frameA.translation.z + (frameB.translation.z - frameA.translation.z) * tzWeight);
|
|
843
1034
|
const localTranslation = this.convertVMDTranslationToLocal(boneIdx, interpolatedVMDTranslation, rotation);
|
|
844
1035
|
localRot.set(rotation);
|
|
845
1036
|
localTrans.set(localTranslation);
|
|
@@ -906,10 +1097,14 @@ export class Model {
|
|
|
906
1097
|
if (!ikChainInfo)
|
|
907
1098
|
return;
|
|
908
1099
|
// Solve each IK solver sequentially, ensuring consistent state between solvers
|
|
1100
|
+
let firstSolver = true;
|
|
909
1101
|
for (const solver of ikSolvers) {
|
|
910
|
-
//
|
|
911
|
-
//
|
|
912
|
-
|
|
1102
|
+
// Each solver must see the effects of previous solvers on localRotations, so
|
|
1103
|
+
// recompute world matrices between solvers. The first solver is skipped: the
|
|
1104
|
+
// caller (update) already computed them and nothing has changed localRotations yet.
|
|
1105
|
+
if (!firstSolver)
|
|
1106
|
+
this.computeWorldMatrices();
|
|
1107
|
+
firstSolver = false;
|
|
913
1108
|
// Clear computed set for this solver's pass
|
|
914
1109
|
this.ikComputedSet.clear();
|
|
915
1110
|
// Solve this IK chain
|
|
@@ -1033,20 +1228,13 @@ export class Model {
|
|
|
1033
1228
|
const boneCount = bones.length;
|
|
1034
1229
|
if (boneCount === 0)
|
|
1035
1230
|
return;
|
|
1036
|
-
//
|
|
1037
|
-
|
|
1038
|
-
|
|
1039
|
-
|
|
1040
|
-
|
|
1231
|
+
// Flat traversal in precomputed order: every bone's parent is already done, so no
|
|
1232
|
+
// per-bone visited check, no recursion, and no per-call allocation. Same per-bone
|
|
1233
|
+
// math as before. Scratch slots are safe to reuse since there's no reentrancy now.
|
|
1234
|
+
const order = this.deformOrder;
|
|
1235
|
+
for (let k = 0; k < boneCount; k++) {
|
|
1236
|
+
const i = order[k];
|
|
1041
1237
|
const b = bones[i];
|
|
1042
|
-
if (b.parentIndex >= boneCount) {
|
|
1043
|
-
console.warn(`[RZM] bone ${i} parent out of range: ${b.parentIndex}`);
|
|
1044
|
-
}
|
|
1045
|
-
// Ensure parent is computed FIRST, before we touch any scratch buffers.
|
|
1046
|
-
// Recursion may itself use scratchMat4Values[0] / scratchQuat; doing it up
|
|
1047
|
-
// front keeps the current frame's scratch slots untouched when we use them below.
|
|
1048
|
-
if (b.parentIndex >= 0 && !computed[b.parentIndex])
|
|
1049
|
-
computeWorld(b.parentIndex);
|
|
1050
1238
|
const boneRot = localRot[i];
|
|
1051
1239
|
let fx = boneRot.x, fy = boneRot.y, fz = boneRot.z, fw = boneRot.w;
|
|
1052
1240
|
let addLocalTx = 0, addLocalTy = 0, addLocalTz = 0;
|
|
@@ -1103,10 +1291,6 @@ export class Model {
|
|
|
1103
1291
|
else {
|
|
1104
1292
|
worldMat.values.set(localMVals);
|
|
1105
1293
|
}
|
|
1106
|
-
|
|
1107
|
-
};
|
|
1108
|
-
// Process all bones (recursion handles dependencies automatically)
|
|
1109
|
-
for (let i = 0; i < boneCount; i++)
|
|
1110
|
-
computeWorld(i);
|
|
1294
|
+
}
|
|
1111
1295
|
}
|
|
1112
1296
|
}
|
package/dist/physics/body.d.ts
CHANGED
|
@@ -22,9 +22,11 @@ export declare class RigidBodyStore {
|
|
|
22
22
|
readonly bodyOffsetMatrix: Float32Array;
|
|
23
23
|
readonly bodyOffsetInverse: Float32Array;
|
|
24
24
|
private boneOffsetsReady;
|
|
25
|
+
private collisionPairs;
|
|
25
26
|
constructor(rigidbodies: Rigidbody[]);
|
|
26
27
|
updateAabbs(margin?: number): void;
|
|
27
28
|
computeBoneOffsets(boneInverseBindMatrices: Float32Array): void;
|
|
28
29
|
isBoneOffsetsReady(): boolean;
|
|
30
|
+
getCollisionPairs(): Uint16Array;
|
|
29
31
|
}
|
|
30
32
|
//# sourceMappingURL=body.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"body.d.ts","sourceRoot":"","sources":["../../src/physics/body.ts"],"names":[],"mappings":"AACA,OAAO,EAAiC,KAAK,SAAS,EAAE,MAAM,SAAS,CAAA;AAIvE,qBAAa,cAAc;IACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IAEtB,QAAQ,CAAC,SAAS,EAAE,YAAY,CAAA;IAChC,QAAQ,CAAC,YAAY,EAAE,YAAY,CAAA;IACnC,QAAQ,CAAC,gBAAgB,EAAE,YAAY,CAAA;IACvC,QAAQ,CAAC,iBAAiB,EAAE,YAAY,CAAA;IAExC,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAA;IAI9B,QAAQ,CAAC,UAAU,EAAE,YAAY,CAAA;IACjC,QAAQ,CAAC,aAAa,EAAE,YAAY,CAAA;IACpC,QAAQ,CAAC,cAAc,EAAE,YAAY,CAAA;IACrC,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAA;IACzB,QAAQ,CAAC,SAAS,EAAE,UAAU,CAAA;IAC9B,QAAQ,CAAC,QAAQ,EAAE,YAAY,CAAA;IAC/B,QAAQ,CAAC,WAAW,EAAE,YAAY,CAAA;IAIlC,QAAQ,CAAC,cAAc,EAAE,WAAW,CAAA;IACpC,QAAQ,CAAC,eAAe,EAAE,WAAW,CAAA;IAErC,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAA;IAC1B,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAA;IAE3B,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAA;IAC9B,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAA;IAI9B,QAAQ,CAAC,gBAAgB,EAAE,YAAY,CAAA;IACvC,QAAQ,CAAC,iBAAiB,EAAE,YAAY,CAAA;IACxC,OAAO,CAAC,gBAAgB,CAAQ;
|
|
1
|
+
{"version":3,"file":"body.d.ts","sourceRoot":"","sources":["../../src/physics/body.ts"],"names":[],"mappings":"AACA,OAAO,EAAiC,KAAK,SAAS,EAAE,MAAM,SAAS,CAAA;AAIvE,qBAAa,cAAc;IACzB,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;IAEtB,QAAQ,CAAC,SAAS,EAAE,YAAY,CAAA;IAChC,QAAQ,CAAC,YAAY,EAAE,YAAY,CAAA;IACnC,QAAQ,CAAC,gBAAgB,EAAE,YAAY,CAAA;IACvC,QAAQ,CAAC,iBAAiB,EAAE,YAAY,CAAA;IAExC,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAA;IAI9B,QAAQ,CAAC,UAAU,EAAE,YAAY,CAAA;IACjC,QAAQ,CAAC,aAAa,EAAE,YAAY,CAAA;IACpC,QAAQ,CAAC,cAAc,EAAE,YAAY,CAAA;IACrC,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAA;IACzB,QAAQ,CAAC,SAAS,EAAE,UAAU,CAAA;IAC9B,QAAQ,CAAC,QAAQ,EAAE,YAAY,CAAA;IAC/B,QAAQ,CAAC,WAAW,EAAE,YAAY,CAAA;IAIlC,QAAQ,CAAC,cAAc,EAAE,WAAW,CAAA;IACpC,QAAQ,CAAC,eAAe,EAAE,WAAW,CAAA;IAErC,QAAQ,CAAC,KAAK,EAAE,UAAU,CAAA;IAC1B,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAA;IAE3B,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAA;IAC9B,QAAQ,CAAC,OAAO,EAAE,YAAY,CAAA;IAI9B,QAAQ,CAAC,gBAAgB,EAAE,YAAY,CAAA;IACvC,QAAQ,CAAC,iBAAiB,EAAE,YAAY,CAAA;IACxC,OAAO,CAAC,gBAAgB,CAAQ;IAMhC,OAAO,CAAC,cAAc,CAA2B;gBAErC,WAAW,EAAE,SAAS,EAAE;IA4DpC,WAAW,CAAC,MAAM,SAAM,GAAG,IAAI;IA2F/B,kBAAkB,CAAC,uBAAuB,EAAE,YAAY,GAAG,IAAI;IAqD/D,kBAAkB,IAAI,OAAO;IAM7B,iBAAiB,IAAI,WAAW;CAoBjC"}
|
package/dist/physics/body.js
CHANGED
|
@@ -5,6 +5,11 @@ import { RigidbodyType, RigidbodyShape } from "./types";
|
|
|
5
5
|
export class RigidBodyStore {
|
|
6
6
|
constructor(rigidbodies) {
|
|
7
7
|
this.boneOffsetsReady = false;
|
|
8
|
+
// Flat list of (i, j) pairs that survive the static-static + group/mask
|
|
9
|
+
// filter. None of those inputs change after construction, so building this
|
|
10
|
+
// once collapses 60k pair tests/step (349 bodies) down to a few thousand.
|
|
11
|
+
// Built lazily on first access.
|
|
12
|
+
this.collisionPairs = null;
|
|
8
13
|
const N = rigidbodies.length;
|
|
9
14
|
this.count = N;
|
|
10
15
|
this.positions = new Float32Array(N * 3);
|
|
@@ -159,6 +164,31 @@ export class RigidBodyStore {
|
|
|
159
164
|
isBoneOffsetsReady() {
|
|
160
165
|
return this.boneOffsetsReady;
|
|
161
166
|
}
|
|
167
|
+
// Pair-filter inputs (invMass, group, mask) are immutable post-construction,
|
|
168
|
+
// so build the candidate-pair list once and reuse every step.
|
|
169
|
+
getCollisionPairs() {
|
|
170
|
+
if (this.collisionPairs !== null)
|
|
171
|
+
return this.collisionPairs;
|
|
172
|
+
const N = this.count;
|
|
173
|
+
const invMass = this.invMass;
|
|
174
|
+
const group = this.collisionGroup;
|
|
175
|
+
const mask = this.willCollideMask;
|
|
176
|
+
const buf = [];
|
|
177
|
+
for (let i = 0; i < N; i++) {
|
|
178
|
+
const gi = group[i];
|
|
179
|
+
const mi = mask[i];
|
|
180
|
+
const dynA = invMass[i] > 0;
|
|
181
|
+
for (let j = i + 1; j < N; j++) {
|
|
182
|
+
if (!dynA && invMass[j] === 0)
|
|
183
|
+
continue;
|
|
184
|
+
if ((mi & group[j]) === 0 || (mask[j] & gi) === 0)
|
|
185
|
+
continue;
|
|
186
|
+
buf.push(i, j);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
this.collisionPairs = new Uint16Array(buf);
|
|
190
|
+
return this.collisionPairs;
|
|
191
|
+
}
|
|
162
192
|
}
|
|
163
193
|
const _scratchA = new Float32Array(16);
|
|
164
194
|
const _scratchB = new Float32Array(16);
|
|
@@ -11,6 +11,19 @@ export interface SixDofSpringConstraint {
|
|
|
11
11
|
springEnabled: Uint8Array;
|
|
12
12
|
springStiffness: Float32Array;
|
|
13
13
|
equilibriumPoint: Float32Array;
|
|
14
|
+
cacheSkip: boolean;
|
|
15
|
+
cacheLeverA: Float32Array;
|
|
16
|
+
cacheLeverB: Float32Array;
|
|
17
|
+
cacheLinAxes: Float32Array;
|
|
18
|
+
cacheLinCrossA: Float32Array;
|
|
19
|
+
cacheLinCrossB: Float32Array;
|
|
20
|
+
cacheLinJacInv: Float32Array;
|
|
21
|
+
cacheLinTargetVel: Float32Array;
|
|
22
|
+
cacheLinActive: Uint8Array;
|
|
23
|
+
cacheAngAxes: Float32Array;
|
|
24
|
+
cacheAngTargetVel: Float32Array;
|
|
25
|
+
cacheAngActive: Uint8Array;
|
|
26
|
+
cacheAngJacInv: number;
|
|
14
27
|
}
|
|
15
28
|
export declare const STOP_ERP = 0.475;
|
|
16
29
|
export declare function buildConstraints(rigidbodies: Rigidbody[], joints: Joint[]): SixDofSpringConstraint[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constraint.d.ts","sourceRoot":"","sources":["../../src/physics/constraint.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AAW/C,MAAM,WAAW,sBAAsB;IACrC,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;IAEb,MAAM,EAAE,YAAY,CAAA;IACpB,MAAM,EAAE,YAAY,CAAA;IAGpB,SAAS,EAAE,YAAY,CAAA;IACvB,SAAS,EAAE,YAAY,CAAA;IACvB,UAAU,EAAE,YAAY,CAAA;IACxB,UAAU,EAAE,YAAY,CAAA;IAExB,aAAa,EAAE,UAAU,CAAA;IACzB,eAAe,EAAE,YAAY,CAAA;IAC7B,gBAAgB,EAAE,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"constraint.d.ts","sourceRoot":"","sources":["../../src/physics/constraint.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,SAAS,CAAA;AAW/C,MAAM,WAAW,sBAAsB;IACrC,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;IAEb,MAAM,EAAE,YAAY,CAAA;IACpB,MAAM,EAAE,YAAY,CAAA;IAGpB,SAAS,EAAE,YAAY,CAAA;IACvB,SAAS,EAAE,YAAY,CAAA;IACvB,UAAU,EAAE,YAAY,CAAA;IACxB,UAAU,EAAE,YAAY,CAAA;IAExB,aAAa,EAAE,UAAU,CAAA;IACzB,eAAe,EAAE,YAAY,CAAA;IAC7B,gBAAgB,EAAE,YAAY,CAAA;IAK9B,SAAS,EAAE,OAAO,CAAA;IAClB,WAAW,EAAE,YAAY,CAAA;IACzB,WAAW,EAAE,YAAY,CAAA;IACzB,YAAY,EAAE,YAAY,CAAA;IAC1B,cAAc,EAAE,YAAY,CAAA;IAC5B,cAAc,EAAE,YAAY,CAAA;IAC5B,cAAc,EAAE,YAAY,CAAA;IAC5B,iBAAiB,EAAE,YAAY,CAAA;IAC/B,cAAc,EAAE,UAAU,CAAA;IAC1B,YAAY,EAAE,YAAY,CAAA;IAC1B,iBAAiB,EAAE,YAAY,CAAA;IAC/B,cAAc,EAAE,UAAU,CAAA;IAC1B,cAAc,EAAE,MAAM,CAAA;CACvB;AAED,eAAO,MAAM,QAAQ,QAAQ,CAAA;AAM7B,wBAAgB,gBAAgB,CAC9B,WAAW,EAAE,SAAS,EAAE,EACxB,MAAM,EAAE,KAAK,EAAE,GACd,sBAAsB,EAAE,CAkF1B"}
|
|
@@ -64,6 +64,19 @@ export function buildConstraints(rigidbodies, joints) {
|
|
|
64
64
|
springEnabled,
|
|
65
65
|
springStiffness,
|
|
66
66
|
equilibriumPoint: new Float32Array(6),
|
|
67
|
+
cacheSkip: false,
|
|
68
|
+
cacheLeverA: new Float32Array(3),
|
|
69
|
+
cacheLeverB: new Float32Array(3),
|
|
70
|
+
cacheLinAxes: new Float32Array(9),
|
|
71
|
+
cacheLinCrossA: new Float32Array(9),
|
|
72
|
+
cacheLinCrossB: new Float32Array(9),
|
|
73
|
+
cacheLinJacInv: new Float32Array(3),
|
|
74
|
+
cacheLinTargetVel: new Float32Array(3),
|
|
75
|
+
cacheLinActive: new Uint8Array(3),
|
|
76
|
+
cacheAngAxes: new Float32Array(9),
|
|
77
|
+
cacheAngTargetVel: new Float32Array(3),
|
|
78
|
+
cacheAngActive: new Uint8Array(3),
|
|
79
|
+
cacheAngJacInv: 0,
|
|
67
80
|
});
|
|
68
81
|
}
|
|
69
82
|
return out;
|
|
@@ -18,6 +18,34 @@ export interface Contact {
|
|
|
18
18
|
appliedNormalImpulse: number;
|
|
19
19
|
appliedFrictionImpulse1: number;
|
|
20
20
|
appliedFrictionImpulse2: number;
|
|
21
|
+
cAxN: number;
|
|
22
|
+
cAyN: number;
|
|
23
|
+
cAzN: number;
|
|
24
|
+
cBxN: number;
|
|
25
|
+
cByN: number;
|
|
26
|
+
cBzN: number;
|
|
27
|
+
jacInvN: number;
|
|
28
|
+
bounceVel: number;
|
|
29
|
+
t1x: number;
|
|
30
|
+
t1y: number;
|
|
31
|
+
t1z: number;
|
|
32
|
+
cAxT1: number;
|
|
33
|
+
cAyT1: number;
|
|
34
|
+
cAzT1: number;
|
|
35
|
+
cBxT1: number;
|
|
36
|
+
cByT1: number;
|
|
37
|
+
cBzT1: number;
|
|
38
|
+
jacInvT1: number;
|
|
39
|
+
t2x: number;
|
|
40
|
+
t2y: number;
|
|
41
|
+
t2z: number;
|
|
42
|
+
cAxT2: number;
|
|
43
|
+
cAyT2: number;
|
|
44
|
+
cAzT2: number;
|
|
45
|
+
cBxT2: number;
|
|
46
|
+
cByT2: number;
|
|
47
|
+
cBzT2: number;
|
|
48
|
+
jacInvT2: number;
|
|
21
49
|
}
|
|
22
50
|
export declare class ContactPool {
|
|
23
51
|
private pool;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"contact.d.ts","sourceRoot":"","sources":["../../src/physics/contact.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAA;AAO5C,eAAO,MAAM,cAAc,OAAO,CAAA;AAElC,MAAM,WAAW,OAAO;IACtB,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;IAEb,GAAG,EAAE,MAAM,CAAA;IACX,GAAG,EAAE,MAAM,CAAA;IACX,GAAG,EAAE,MAAM,CAAA;IACX,GAAG,EAAE,MAAM,CAAA;IACX,GAAG,EAAE,MAAM,CAAA;IACX,GAAG,EAAE,MAAM,CAAA;IAEX,EAAE,EAAE,MAAM,CAAA;IACV,EAAE,EAAE,MAAM,CAAA;IACV,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,MAAM,CAAA;IAChB,WAAW,EAAE,MAAM,CAAA;IAEnB,oBAAoB,EAAE,MAAM,CAAA;IAC5B,uBAAuB,EAAE,MAAM,CAAA;IAC/B,uBAAuB,EAAE,MAAM,CAAA;
|
|
1
|
+
{"version":3,"file":"contact.d.ts","sourceRoot":"","sources":["../../src/physics/contact.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,QAAQ,CAAA;AAO5C,eAAO,MAAM,cAAc,OAAO,CAAA;AAElC,MAAM,WAAW,OAAO;IACtB,KAAK,EAAE,MAAM,CAAA;IACb,KAAK,EAAE,MAAM,CAAA;IAEb,GAAG,EAAE,MAAM,CAAA;IACX,GAAG,EAAE,MAAM,CAAA;IACX,GAAG,EAAE,MAAM,CAAA;IACX,GAAG,EAAE,MAAM,CAAA;IACX,GAAG,EAAE,MAAM,CAAA;IACX,GAAG,EAAE,MAAM,CAAA;IAEX,EAAE,EAAE,MAAM,CAAA;IACV,EAAE,EAAE,MAAM,CAAA;IACV,EAAE,EAAE,MAAM,CAAA;IACV,KAAK,EAAE,MAAM,CAAA;IACb,QAAQ,EAAE,MAAM,CAAA;IAChB,WAAW,EAAE,MAAM,CAAA;IAEnB,oBAAoB,EAAE,MAAM,CAAA;IAC5B,uBAAuB,EAAE,MAAM,CAAA;IAC/B,uBAAuB,EAAE,MAAM,CAAA;IAI/B,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;IACxC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;IACxC,OAAO,EAAE,MAAM,CAAA;IACf,SAAS,EAAE,MAAM,CAAA;IAEjB,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;IACrC,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;IAC3C,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;IAC3C,QAAQ,EAAE,MAAM,CAAA;IAEhB,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;IACrC,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;IAC3C,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;IAC3C,QAAQ,EAAE,MAAM,CAAA;CACjB;AA8BD,qBAAa,WAAW;IACtB,OAAO,CAAC,IAAI,CAAgB;IAC5B,KAAK,SAAI;IAET,OAAO,IAAI,OAAO;IAelB,KAAK,IAAI,IAAI;IAGb,GAAG,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO;CAGxB;AASD,wBAAgB,WAAW,CAAC,KAAK,EAAE,cAAc,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,OAAO,CAahF;AAkxBD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,cAAc,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,IAAI,EAAE,WAAW,GAAG,IAAI,CAuCrG;AA4BD,wBAAgB,YAAY,CAAC,KAAK,EAAE,cAAc,EAAE,IAAI,EAAE,WAAW,GAAG,IAAI,CAS3E"}
|