reze-engine 0.13.0 → 0.13.2
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 +32 -29
- package/dist/ik-solver.d.ts +5 -6
- package/dist/ik-solver.d.ts.map +1 -1
- package/dist/ik-solver.js +163 -98
- package/dist/math.d.ts +20 -0
- package/dist/math.d.ts.map +1 -1
- package/dist/math.js +300 -0
- package/dist/model.d.ts +9 -2
- package/dist/model.d.ts.map +1 -1
- package/dist/model.js +113 -52
- package/dist/physics.d.ts.map +1 -1
- package/dist/physics.js +27 -19
- package/package.json +1 -1
- package/src/ik-solver.ts +164 -111
- package/src/math.ts +291 -0
- package/src/model.ts +124 -60
- package/src/physics.ts +31 -23
package/src/physics.ts
CHANGED
|
@@ -1,4 +1,11 @@
|
|
|
1
1
|
import { Quat, Vec3, Mat4 } from "./math"
|
|
2
|
+
|
|
3
|
+
// Physics-local scratch pool for per-frame sync (syncFromBones, applyAmmoRigidbodiesToBones).
|
|
4
|
+
// Each method uses only these slots and completes synchronously before the next is called.
|
|
5
|
+
const _physMat: Float32Array[] = [
|
|
6
|
+
new Float32Array(16), new Float32Array(16), new Float32Array(16),
|
|
7
|
+
]
|
|
8
|
+
const _physQuat = new Quat(0, 0, 0, 1)
|
|
2
9
|
import { loadAmmo } from "./ammo-loader"
|
|
3
10
|
import type { AmmoInstance } from "@fred3d/ammo"
|
|
4
11
|
|
|
@@ -500,11 +507,11 @@ export class Physics {
|
|
|
500
507
|
}
|
|
501
508
|
|
|
502
509
|
// Step order: 1) Sync Static/Kinematic from bones, 2) Step physics, 3) Apply dynamic to bones
|
|
503
|
-
this.syncFromBones(boneWorldMatrices,
|
|
510
|
+
this.syncFromBones(boneWorldMatrices, boneCount)
|
|
504
511
|
|
|
505
512
|
this.stepAmmoPhysics(dt)
|
|
506
513
|
|
|
507
|
-
this.applyAmmoRigidbodiesToBones(boneWorldMatrices,
|
|
514
|
+
this.applyAmmoRigidbodiesToBones(boneWorldMatrices, boneCount)
|
|
508
515
|
}
|
|
509
516
|
|
|
510
517
|
// Compute bodyOffsetMatrixInverse for all rigidbodies (called once during initialization)
|
|
@@ -583,7 +590,7 @@ export class Physics {
|
|
|
583
590
|
}
|
|
584
591
|
|
|
585
592
|
// Sync Static (FollowBone) and Kinematic rigidbodies to follow bone transforms
|
|
586
|
-
private syncFromBones(boneWorldMatrices: Mat4[],
|
|
593
|
+
private syncFromBones(boneWorldMatrices: Mat4[], boneCount: number): void {
|
|
587
594
|
if (!this.ammo || !this.dynamicsWorld) return
|
|
588
595
|
|
|
589
596
|
const Ammo = this.ammo
|
|
@@ -602,16 +609,18 @@ export class Physics {
|
|
|
602
609
|
const boneIdx = rb.boneIndex
|
|
603
610
|
const boneWorldMat = boneWorldMatrices[boneIdx]
|
|
604
611
|
|
|
605
|
-
//
|
|
606
|
-
|
|
607
|
-
const nodeWorldMatrix = boneWorldMat.multiply(bodyOffsetMatrix)
|
|
612
|
+
// Lazy-cache bodyOffsetMatrix on first hit (cold path).
|
|
613
|
+
if (!rb.bodyOffsetMatrix) rb.bodyOffsetMatrix = rb.bodyOffsetMatrixInverse.inverse()
|
|
608
614
|
|
|
609
|
-
|
|
610
|
-
|
|
615
|
+
// nodeWorld = boneWorld × bodyOffsetMatrix → _physMat[0]
|
|
616
|
+
Mat4.multiplyArrays(boneWorldMat.values, 0, rb.bodyOffsetMatrix.values, 0, _physMat[0], 0)
|
|
617
|
+
const nodeVals = _physMat[0]
|
|
618
|
+
const wx = nodeVals[12], wy = nodeVals[13], wz = nodeVals[14]
|
|
619
|
+
Mat4.toQuatFromArrayInto(nodeVals, 0, _physQuat)
|
|
611
620
|
|
|
612
621
|
const transform = new Ammo.btTransform()
|
|
613
|
-
const pos = new Ammo.btVector3(
|
|
614
|
-
const quat = new Ammo.btQuaternion(
|
|
622
|
+
const pos = new Ammo.btVector3(wx, wy, wz)
|
|
623
|
+
const quat = new Ammo.btQuaternion(_physQuat.x, _physQuat.y, _physQuat.z, _physQuat.w)
|
|
615
624
|
|
|
616
625
|
transform.setOrigin(pos)
|
|
617
626
|
transform.setRotation(quat)
|
|
@@ -643,11 +652,7 @@ export class Physics {
|
|
|
643
652
|
}
|
|
644
653
|
|
|
645
654
|
// Apply dynamic rigidbody world transforms to bone world matrices in-place
|
|
646
|
-
private applyAmmoRigidbodiesToBones(
|
|
647
|
-
boneWorldMatrices: Mat4[],
|
|
648
|
-
boneInverseBindMatrices: Float32Array,
|
|
649
|
-
boneCount: number
|
|
650
|
-
): void {
|
|
655
|
+
private applyAmmoRigidbodiesToBones(boneWorldMatrices: Mat4[], boneCount: number): void {
|
|
651
656
|
if (!this.ammo || !this.dynamicsWorld) return
|
|
652
657
|
|
|
653
658
|
for (let i = 0; i < this.rigidbodies.length; i++) {
|
|
@@ -663,16 +668,19 @@ export class Physics {
|
|
|
663
668
|
const origin = transform.getOrigin()
|
|
664
669
|
const rotation = transform.getRotation()
|
|
665
670
|
|
|
666
|
-
|
|
667
|
-
|
|
668
|
-
|
|
671
|
+
// nodeWorldMatrix → _physMat[0] (from ammo position/rotation directly)
|
|
672
|
+
Mat4.fromPositionRotationInto(
|
|
673
|
+
origin.x(), origin.y(), origin.z(),
|
|
674
|
+
rotation.x(), rotation.y(), rotation.z(), rotation.w(),
|
|
675
|
+
_physMat[0]
|
|
676
|
+
)
|
|
669
677
|
|
|
670
|
-
// boneWorld = nodeWorld × bodyOffsetMatrixInverse
|
|
671
|
-
const
|
|
678
|
+
// boneWorld = nodeWorld × bodyOffsetMatrixInverse → _physMat[1]
|
|
679
|
+
const boneVals = _physMat[1]
|
|
680
|
+
Mat4.multiplyArrays(_physMat[0], 0, rb.bodyOffsetMatrixInverse.values, 0, boneVals, 0)
|
|
672
681
|
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
boneWorldMatrices[boneIdx].values.set(values)
|
|
682
|
+
if (!isNaN(boneVals[0]) && !isNaN(boneVals[15]) && Math.abs(boneVals[0]) < 1e6 && Math.abs(boneVals[15]) < 1e6) {
|
|
683
|
+
boneWorldMatrices[boneIdx].values.set(boneVals)
|
|
676
684
|
} else {
|
|
677
685
|
console.warn(`[Physics] Invalid bone world matrix for rigidbody ${i} (${rb.name}), skipping update`)
|
|
678
686
|
}
|