reze-engine 0.6.4 → 0.6.6
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/ik-solver.d.ts +2 -1
- package/dist/ik-solver.d.ts.map +1 -1
- package/dist/ik-solver.js +31 -14
- package/dist/model.d.ts +11 -0
- package/dist/model.d.ts.map +1 -1
- package/dist/model.js +178 -47
- package/dist/runtime-bone.d.ts +49 -0
- package/dist/runtime-bone.d.ts.map +1 -0
- package/dist/runtime-bone.js +121 -0
- package/package.json +1 -1
- package/src/ik-solver.ts +37 -14
- package/src/model.ts +221 -65
- package/dist/bezier-interpolate.d.ts +0 -15
- package/dist/bezier-interpolate.d.ts.map +0 -1
- package/dist/bezier-interpolate.js +0 -40
- package/dist/engine_ts.d.ts +0 -143
- package/dist/engine_ts.d.ts.map +0 -1
- package/dist/engine_ts.js +0 -1575
- package/dist/ik.d.ts +0 -32
- package/dist/ik.d.ts.map +0 -1
- package/dist/ik.js +0 -337
- package/dist/player.d.ts +0 -64
- package/dist/player.d.ts.map +0 -1
- package/dist/player.js +0 -220
- package/dist/pool-scene.d.ts +0 -52
- package/dist/pool-scene.d.ts.map +0 -1
- package/dist/pool-scene.js +0 -1122
- package/dist/pool.d.ts +0 -38
- package/dist/pool.d.ts.map +0 -1
- package/dist/pool.js +0 -422
- package/dist/rzm-converter.d.ts +0 -12
- package/dist/rzm-converter.d.ts.map +0 -1
- package/dist/rzm-converter.js +0 -40
- package/dist/rzm-loader.d.ts +0 -24
- package/dist/rzm-loader.d.ts.map +0 -1
- package/dist/rzm-loader.js +0 -488
- package/dist/rzm-writer.d.ts +0 -27
- package/dist/rzm-writer.d.ts.map +0 -1
- package/dist/rzm-writer.js +0 -701
package/src/ik-solver.ts
CHANGED
|
@@ -7,6 +7,9 @@
|
|
|
7
7
|
import { Mat4, Quat, Vec3 } from "./math"
|
|
8
8
|
import { Bone, IKLink, IKSolver, IKChainInfo } from "./model"
|
|
9
9
|
|
|
10
|
+
// Callback type for updating world matrix (provided by model to handle append transformations)
|
|
11
|
+
export type UpdateWorldMatrixFn = (boneIndex: number, applyIK: boolean) => void
|
|
12
|
+
|
|
10
13
|
const enum InternalEulerRotationOrder {
|
|
11
14
|
YXZ = 0,
|
|
12
15
|
ZYX = 1,
|
|
@@ -89,10 +92,11 @@ export class IKSolverSystem {
|
|
|
89
92
|
localRotations: Quat[],
|
|
90
93
|
localTranslations: Vec3[],
|
|
91
94
|
worldMatrices: Mat4[],
|
|
92
|
-
ikChainInfo: IKChainInfo[]
|
|
95
|
+
ikChainInfo: IKChainInfo[],
|
|
96
|
+
updateWorldMatrix?: UpdateWorldMatrixFn
|
|
93
97
|
): void {
|
|
94
98
|
for (const solver of ikSolvers) {
|
|
95
|
-
this.solveIK(solver, bones, localRotations, localTranslations, worldMatrices, ikChainInfo)
|
|
99
|
+
this.solveIK(solver, bones, localRotations, localTranslations, worldMatrices, ikChainInfo, updateWorldMatrix)
|
|
96
100
|
}
|
|
97
101
|
}
|
|
98
102
|
|
|
@@ -102,7 +106,8 @@ export class IKSolverSystem {
|
|
|
102
106
|
localRotations: Quat[],
|
|
103
107
|
localTranslations: Vec3[],
|
|
104
108
|
worldMatrices: Mat4[],
|
|
105
|
-
ikChainInfo: IKChainInfo[]
|
|
109
|
+
ikChainInfo: IKChainInfo[],
|
|
110
|
+
updateWorldMatrix?: UpdateWorldMatrixFn
|
|
106
111
|
): void {
|
|
107
112
|
if (solver.links.length === 0) return
|
|
108
113
|
|
|
@@ -126,10 +131,17 @@ export class IKSolverSystem {
|
|
|
126
131
|
}
|
|
127
132
|
|
|
128
133
|
// Update chain bones and target bone world matrices (initial state, no IK yet)
|
|
129
|
-
|
|
130
|
-
|
|
134
|
+
if (updateWorldMatrix) {
|
|
135
|
+
for (let i = chains.length - 1; i >= 0; i--) {
|
|
136
|
+
updateWorldMatrix(chains[i].boneIndex, false)
|
|
137
|
+
}
|
|
138
|
+
updateWorldMatrix(targetBoneIndex, false)
|
|
139
|
+
} else {
|
|
140
|
+
for (let i = chains.length - 1; i >= 0; i--) {
|
|
141
|
+
this.updateWorldMatrix(chains[i].boneIndex, bones, localRotations, localTranslations, worldMatrices, undefined)
|
|
142
|
+
}
|
|
143
|
+
this.updateWorldMatrix(targetBoneIndex, bones, localRotations, localTranslations, worldMatrices, undefined)
|
|
131
144
|
}
|
|
132
|
-
this.updateWorldMatrix(targetBoneIndex, bones, localRotations, localTranslations, worldMatrices, undefined)
|
|
133
145
|
|
|
134
146
|
if (this.getDistance(ikBoneIndex, targetBoneIndex, worldMatrices) < this.EPSILON) return
|
|
135
147
|
|
|
@@ -152,7 +164,8 @@ export class IKSolverSystem {
|
|
|
152
164
|
localTranslations,
|
|
153
165
|
worldMatrices,
|
|
154
166
|
ikChainInfo,
|
|
155
|
-
i < halfIteration
|
|
167
|
+
i < halfIteration,
|
|
168
|
+
updateWorldMatrix
|
|
156
169
|
)
|
|
157
170
|
}
|
|
158
171
|
}
|
|
@@ -182,7 +195,8 @@ export class IKSolverSystem {
|
|
|
182
195
|
localTranslations: Vec3[],
|
|
183
196
|
worldMatrices: Mat4[],
|
|
184
197
|
ikChainInfo: IKChainInfo[],
|
|
185
|
-
useAxis: boolean
|
|
198
|
+
useAxis: boolean,
|
|
199
|
+
updateWorldMatrix?: UpdateWorldMatrixFn
|
|
186
200
|
): void {
|
|
187
201
|
const chainBoneIndex = chain.boneIndex
|
|
188
202
|
const chainPosition = this.getWorldTranslation(chainBoneIndex, worldMatrices)
|
|
@@ -254,13 +268,21 @@ export class IKSolverSystem {
|
|
|
254
268
|
}
|
|
255
269
|
}
|
|
256
270
|
|
|
257
|
-
// Update world matrices for affected bones (using
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
271
|
+
// Update world matrices for affected bones (using callback - handles append correctly)
|
|
272
|
+
if (updateWorldMatrix) {
|
|
273
|
+
for (let i = chainIndex; i >= 0; i--) {
|
|
274
|
+
const link = solver.links[i]
|
|
275
|
+
updateWorldMatrix(link.boneIndex, true) // applyIK = true
|
|
276
|
+
}
|
|
277
|
+
updateWorldMatrix(targetBoneIndex, false)
|
|
278
|
+
} else {
|
|
279
|
+
for (let i = chainIndex; i >= 0; i--) {
|
|
280
|
+
const link = solver.links[i]
|
|
281
|
+
this.updateWorldMatrix(link.boneIndex, bones, localRotations, localTranslations, worldMatrices, ikChainInfo)
|
|
282
|
+
}
|
|
283
|
+
this.updateWorldMatrix(ikBoneIndex, bones, localRotations, localTranslations, worldMatrices, undefined)
|
|
284
|
+
this.updateWorldMatrix(targetBoneIndex, bones, localRotations, localTranslations, worldMatrices, undefined)
|
|
261
285
|
}
|
|
262
|
-
this.updateWorldMatrix(ikBoneIndex, bones, localRotations, localTranslations, worldMatrices, undefined)
|
|
263
|
-
this.updateWorldMatrix(targetBoneIndex, bones, localRotations, localTranslations, worldMatrices, undefined)
|
|
264
286
|
}
|
|
265
287
|
|
|
266
288
|
private static limitAngle(angle: number, min: number, max: number, useAxis: boolean): number {
|
|
@@ -410,3 +432,4 @@ export class IKSolverSystem {
|
|
|
410
432
|
}
|
|
411
433
|
}
|
|
412
434
|
}
|
|
435
|
+
|
package/src/model.ts
CHANGED
|
@@ -531,62 +531,14 @@ export class Model {
|
|
|
531
531
|
const now = this.tweenTimeMs
|
|
532
532
|
const dur = durationMs && durationMs > 0 ? durationMs : 0
|
|
533
533
|
|
|
534
|
-
// Compute bind pose world positions for all bones
|
|
535
|
-
const skeleton = this.skeleton
|
|
536
|
-
const computeBindPoseWorldPosition = (idx: number): Vec3 => {
|
|
537
|
-
const bone = skeleton.bones[idx]
|
|
538
|
-
const bindPos = new Vec3(bone.bindTranslation[0], bone.bindTranslation[1], bone.bindTranslation[2])
|
|
539
|
-
if (bone.parentIndex >= 0 && bone.parentIndex < skeleton.bones.length) {
|
|
540
|
-
const parentWorldPos = computeBindPoseWorldPosition(bone.parentIndex)
|
|
541
|
-
return parentWorldPos.add(bindPos)
|
|
542
|
-
} else {
|
|
543
|
-
return bindPos
|
|
544
|
-
}
|
|
545
|
-
}
|
|
546
|
-
|
|
547
534
|
for (const [name, vmdRelativeTranslation] of Object.entries(boneTranslations)) {
|
|
548
535
|
const idx = this.runtimeSkeleton.nameIndex[name] ?? -1
|
|
549
536
|
if (idx < 0 || idx >= this.skeleton.bones.length) continue
|
|
550
537
|
|
|
551
|
-
const bone = this.skeleton.bones[idx]
|
|
552
538
|
const translations = this.runtimeSkeleton.localTranslations
|
|
553
|
-
const localRot = this.runtimeSkeleton.localRotations
|
|
554
|
-
|
|
555
|
-
// VMD translation is relative to bind pose world position
|
|
556
|
-
// targetWorldPos = bindPoseWorldPos + vmdRelativeTranslation
|
|
557
|
-
const bindPoseWorldPos = computeBindPoseWorldPosition(idx)
|
|
558
|
-
const targetWorldPos = bindPoseWorldPos.add(vmdRelativeTranslation)
|
|
559
|
-
|
|
560
|
-
// Convert target world position to local translation
|
|
561
|
-
// We need parent's bind pose world position to transform to parent space
|
|
562
|
-
let parentBindPoseWorldPos: Vec3
|
|
563
|
-
if (bone.parentIndex >= 0) {
|
|
564
|
-
parentBindPoseWorldPos = computeBindPoseWorldPosition(bone.parentIndex)
|
|
565
|
-
} else {
|
|
566
|
-
parentBindPoseWorldPos = Vec3.zeros()
|
|
567
|
-
}
|
|
568
|
-
|
|
569
|
-
// Transform target world position to parent's local space
|
|
570
|
-
// In bind pose, parent's world matrix is just a translation
|
|
571
|
-
const parentSpacePos = targetWorldPos.subtract(parentBindPoseWorldPos)
|
|
572
|
-
|
|
573
|
-
// Subtract bindTranslation to get position after bind translation
|
|
574
|
-
const afterBindTranslation = parentSpacePos.subtract(
|
|
575
|
-
new Vec3(bone.bindTranslation[0], bone.bindTranslation[1], bone.bindTranslation[2])
|
|
576
|
-
)
|
|
577
|
-
|
|
578
|
-
// Apply inverse rotation to get local translation
|
|
579
|
-
const localRotation = localRot[idx]
|
|
580
|
-
// Clone to avoid mutating, then conjugate and normalize
|
|
581
|
-
const invRotation = localRotation.clone().conjugate().normalize()
|
|
582
|
-
const rotationMat = Mat4.fromQuat(invRotation.x, invRotation.y, invRotation.z, invRotation.w)
|
|
583
|
-
const rm = rotationMat.values
|
|
584
|
-
const localTranslation = new Vec3(
|
|
585
|
-
rm[0] * afterBindTranslation.x + rm[4] * afterBindTranslation.y + rm[8] * afterBindTranslation.z,
|
|
586
|
-
rm[1] * afterBindTranslation.x + rm[5] * afterBindTranslation.y + rm[9] * afterBindTranslation.z,
|
|
587
|
-
rm[2] * afterBindTranslation.x + rm[6] * afterBindTranslation.y + rm[10] * afterBindTranslation.z
|
|
588
|
-
)
|
|
589
539
|
|
|
540
|
+
// Convert VMD relative translation to local translation
|
|
541
|
+
const localTranslation = this.convertVMDTranslationToLocal(idx, vmdRelativeTranslation)
|
|
590
542
|
const [tx, ty, tz] = [localTranslation.x, localTranslation.y, localTranslation.z]
|
|
591
543
|
|
|
592
544
|
if (dur === 0) {
|
|
@@ -626,6 +578,73 @@ export class Model {
|
|
|
626
578
|
}
|
|
627
579
|
}
|
|
628
580
|
|
|
581
|
+
/**
|
|
582
|
+
* Convert VMD-style relative translation (relative to bind pose world position) to local translation
|
|
583
|
+
* This helper is used by both moveBones and getPoseAtTime to ensure consistent translation handling
|
|
584
|
+
* @param boneIdx - Bone index
|
|
585
|
+
* @param vmdRelativeTranslation - VMD relative translation
|
|
586
|
+
* @param rotation - Optional rotation to use for conversion. If not provided, uses current localRotation.
|
|
587
|
+
* Use animation rotation (from frame) to avoid conflicts when IK modifies rotation.
|
|
588
|
+
*/
|
|
589
|
+
private convertVMDTranslationToLocal(boneIdx: number, vmdRelativeTranslation: Vec3, rotation?: Quat): Vec3 {
|
|
590
|
+
const skeleton = this.skeleton
|
|
591
|
+
const bones = skeleton.bones
|
|
592
|
+
const localRot = this.runtimeSkeleton.localRotations
|
|
593
|
+
|
|
594
|
+
// Compute bind pose world positions for all bones
|
|
595
|
+
const computeBindPoseWorldPosition = (idx: number): Vec3 => {
|
|
596
|
+
const bone = bones[idx]
|
|
597
|
+
const bindPos = new Vec3(bone.bindTranslation[0], bone.bindTranslation[1], bone.bindTranslation[2])
|
|
598
|
+
if (bone.parentIndex >= 0 && bone.parentIndex < bones.length) {
|
|
599
|
+
const parentWorldPos = computeBindPoseWorldPosition(bone.parentIndex)
|
|
600
|
+
return parentWorldPos.add(bindPos)
|
|
601
|
+
} else {
|
|
602
|
+
return bindPos
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
const bone = bones[boneIdx]
|
|
607
|
+
|
|
608
|
+
// VMD translation is relative to bind pose world position
|
|
609
|
+
// targetWorldPos = bindPoseWorldPos + vmdRelativeTranslation
|
|
610
|
+
const bindPoseWorldPos = computeBindPoseWorldPosition(boneIdx)
|
|
611
|
+
const targetWorldPos = bindPoseWorldPos.add(vmdRelativeTranslation)
|
|
612
|
+
|
|
613
|
+
// Convert target world position to local translation
|
|
614
|
+
// We need parent's bind pose world position to transform to parent space
|
|
615
|
+
let parentBindPoseWorldPos: Vec3
|
|
616
|
+
if (bone.parentIndex >= 0) {
|
|
617
|
+
parentBindPoseWorldPos = computeBindPoseWorldPosition(bone.parentIndex)
|
|
618
|
+
} else {
|
|
619
|
+
parentBindPoseWorldPos = Vec3.zeros()
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
// Transform target world position to parent's local space
|
|
623
|
+
// In bind pose, parent's world matrix is just a translation
|
|
624
|
+
const parentSpacePos = targetWorldPos.subtract(parentBindPoseWorldPos)
|
|
625
|
+
|
|
626
|
+
// Subtract bindTranslation to get position after bind translation
|
|
627
|
+
const afterBindTranslation = parentSpacePos.subtract(
|
|
628
|
+
new Vec3(bone.bindTranslation[0], bone.bindTranslation[1], bone.bindTranslation[2])
|
|
629
|
+
)
|
|
630
|
+
|
|
631
|
+
// Apply inverse rotation to get local translation
|
|
632
|
+
// Use provided rotation (animation rotation) or fall back to current localRotation
|
|
633
|
+
// Using animation rotation prevents conflicts when IK modifies the rotation
|
|
634
|
+
const localRotation = rotation ?? localRot[boneIdx]
|
|
635
|
+
// Clone to avoid mutating, then conjugate and normalize
|
|
636
|
+
const invRotation = localRotation.clone().conjugate().normalize()
|
|
637
|
+
const rotationMat = Mat4.fromQuat(invRotation.x, invRotation.y, invRotation.z, invRotation.w)
|
|
638
|
+
const rm = rotationMat.values
|
|
639
|
+
const localTranslation = new Vec3(
|
|
640
|
+
rm[0] * afterBindTranslation.x + rm[4] * afterBindTranslation.y + rm[8] * afterBindTranslation.z,
|
|
641
|
+
rm[1] * afterBindTranslation.x + rm[5] * afterBindTranslation.y + rm[9] * afterBindTranslation.z,
|
|
642
|
+
rm[2] * afterBindTranslation.x + rm[6] * afterBindTranslation.y + rm[10] * afterBindTranslation.z
|
|
643
|
+
)
|
|
644
|
+
|
|
645
|
+
return localTranslation
|
|
646
|
+
}
|
|
647
|
+
|
|
629
648
|
getBoneWorldMatrices(): Float32Array {
|
|
630
649
|
// Convert Mat4[] to Float32Array for WebGPU compatibility
|
|
631
650
|
const boneCount = this.skeleton.bones.length
|
|
@@ -1003,8 +1022,13 @@ export class Model {
|
|
|
1003
1022
|
|
|
1004
1023
|
if (!frameB) {
|
|
1005
1024
|
// No interpolation needed - direct assignment
|
|
1006
|
-
|
|
1007
|
-
|
|
1025
|
+
// Use animation frame's rotation for translation conversion to ensure consistency
|
|
1026
|
+
// This prevents conflicts when IK later modifies the rotation
|
|
1027
|
+
const frameRotation = frameA.rotation
|
|
1028
|
+
localRot.set(frameRotation)
|
|
1029
|
+
// Convert VMD relative translation to local translation using animation rotation
|
|
1030
|
+
const localTranslation = this.convertVMDTranslationToLocal(boneIdx, frameA.translation, frameRotation)
|
|
1031
|
+
localTrans.set(localTranslation)
|
|
1008
1032
|
} else {
|
|
1009
1033
|
const timeA = keyFrames[idx].time
|
|
1010
1034
|
const timeB = keyFrames[idx + 1].time
|
|
@@ -1024,7 +1048,7 @@ export class Model {
|
|
|
1024
1048
|
// Use Quat.slerp to interpolate rotation
|
|
1025
1049
|
const rotation = Quat.slerp(frameA.rotation, frameB.rotation, rotT)
|
|
1026
1050
|
|
|
1027
|
-
// Interpolate translation using bezier for each component
|
|
1051
|
+
// Interpolate VMD translation using bezier for each component
|
|
1028
1052
|
// Inline getWeight to avoid function call overhead
|
|
1029
1053
|
const getWeight = (offset: number) =>
|
|
1030
1054
|
bezierInterpolate(
|
|
@@ -1039,11 +1063,21 @@ export class Model {
|
|
|
1039
1063
|
const tyWeight = getWeight(16)
|
|
1040
1064
|
const tzWeight = getWeight(32)
|
|
1041
1065
|
|
|
1066
|
+
// Interpolate VMD relative translations (relative to bind pose world position)
|
|
1067
|
+
const interpolatedVMDTranslation = new Vec3(
|
|
1068
|
+
frameA.translation.x + (frameB.translation.x - frameA.translation.x) * txWeight,
|
|
1069
|
+
frameA.translation.y + (frameB.translation.y - frameA.translation.y) * tyWeight,
|
|
1070
|
+
frameA.translation.z + (frameB.translation.z - frameA.translation.z) * tzWeight
|
|
1071
|
+
)
|
|
1072
|
+
|
|
1073
|
+
// Convert interpolated VMD translation to local translation using animation rotation
|
|
1074
|
+
// This ensures translation is computed for the animation rotation, not the runtime rotation
|
|
1075
|
+
// that will be modified by IK, preventing conflicts
|
|
1076
|
+
const localTranslation = this.convertVMDTranslationToLocal(boneIdx, interpolatedVMDTranslation, rotation)
|
|
1077
|
+
|
|
1042
1078
|
// Direct property writes to avoid object allocation
|
|
1043
1079
|
localRot.set(rotation)
|
|
1044
|
-
localTrans.
|
|
1045
|
-
localTrans.y = frameA.translation.y + (frameB.translation.y - frameA.translation.y) * tyWeight
|
|
1046
|
-
localTrans.z = frameA.translation.z + (frameB.translation.z - frameA.translation.z) * tzWeight
|
|
1080
|
+
localTrans.set(localTranslation)
|
|
1047
1081
|
}
|
|
1048
1082
|
}
|
|
1049
1083
|
|
|
@@ -1138,14 +1172,136 @@ export class Model {
|
|
|
1138
1172
|
const ikChainInfo = this.runtimeSkeleton.ikChainInfo
|
|
1139
1173
|
if (!ikChainInfo) return
|
|
1140
1174
|
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
this.
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1175
|
+
// Solve each IK solver sequentially, ensuring consistent state between solvers
|
|
1176
|
+
for (const solver of ikSolvers) {
|
|
1177
|
+
// Recompute ALL world matrices before each solver starts
|
|
1178
|
+
// This ensures each solver sees the effects of previous solvers on localRotations
|
|
1179
|
+
this.computeWorldMatrices()
|
|
1180
|
+
|
|
1181
|
+
// Clear computed set for this solver's pass
|
|
1182
|
+
this.ikComputedSet.clear()
|
|
1183
|
+
|
|
1184
|
+
// Solve this IK chain
|
|
1185
|
+
// Pass callback that uses model's world matrix computation (handles append correctly)
|
|
1186
|
+
IKSolverSystem.solve(
|
|
1187
|
+
[solver], // Solve one at a time
|
|
1188
|
+
this.skeleton.bones,
|
|
1189
|
+
this.runtimeSkeleton.localRotations,
|
|
1190
|
+
this.runtimeSkeleton.localTranslations,
|
|
1191
|
+
this.runtimeSkeleton.worldMatrices,
|
|
1192
|
+
ikChainInfo,
|
|
1193
|
+
(boneIndex, applyIK) => {
|
|
1194
|
+
// Clear computed set for each bone update to allow recomputation in same iteration
|
|
1195
|
+
this.ikComputedSet.delete(boneIndex)
|
|
1196
|
+
this.computeSingleBoneWorldMatrix(boneIndex, applyIK)
|
|
1197
|
+
}
|
|
1198
|
+
)
|
|
1199
|
+
}
|
|
1200
|
+
}
|
|
1201
|
+
|
|
1202
|
+
// Cached set to track which bones are being computed in current IK pass (to avoid infinite recursion)
|
|
1203
|
+
private ikComputedSet: Set<number> = new Set()
|
|
1204
|
+
|
|
1205
|
+
// Add this new method to compute a single bone's world matrix
|
|
1206
|
+
// Recursively ensures parents are computed first to avoid using stale parent matrices
|
|
1207
|
+
private computeSingleBoneWorldMatrix(boneIndex: number, applyIK: boolean): void {
|
|
1208
|
+
const bones = this.skeleton.bones
|
|
1209
|
+
const localRot = this.runtimeSkeleton.localRotations
|
|
1210
|
+
const localTrans = this.runtimeSkeleton.localTranslations
|
|
1211
|
+
const worldMats = this.runtimeSkeleton.worldMatrices
|
|
1212
|
+
const ikChainInfo = this.runtimeSkeleton.ikChainInfo
|
|
1213
|
+
|
|
1214
|
+
const b = bones[boneIndex]
|
|
1215
|
+
|
|
1216
|
+
// Prevent infinite recursion: if this bone is already being computed in this call chain, skip
|
|
1217
|
+
if (this.ikComputedSet.has(boneIndex)) {
|
|
1218
|
+
return
|
|
1219
|
+
}
|
|
1220
|
+
|
|
1221
|
+
// Mark this bone as being computed to prevent infinite recursion
|
|
1222
|
+
this.ikComputedSet.add(boneIndex)
|
|
1223
|
+
|
|
1224
|
+
// Recursively compute parent first if it exists (ensures parent matrix is up-to-date)
|
|
1225
|
+
if (b.parentIndex >= 0) {
|
|
1226
|
+
this.computeSingleBoneWorldMatrix(b.parentIndex, applyIK)
|
|
1227
|
+
}
|
|
1228
|
+
|
|
1229
|
+
// Get base rotation
|
|
1230
|
+
let boneRot = localRot[boneIndex]
|
|
1231
|
+
|
|
1232
|
+
// Apply IK rotation if requested
|
|
1233
|
+
if (applyIK && ikChainInfo) {
|
|
1234
|
+
const chainInfo = ikChainInfo[boneIndex]
|
|
1235
|
+
if (chainInfo?.ikRotation) {
|
|
1236
|
+
boneRot = chainInfo.ikRotation.multiply(boneRot).normalize()
|
|
1237
|
+
}
|
|
1238
|
+
}
|
|
1239
|
+
|
|
1240
|
+
let rotateM = Mat4.fromQuat(boneRot.x, boneRot.y, boneRot.z, boneRot.w)
|
|
1241
|
+
let addLocalTx = 0, addLocalTy = 0, addLocalTz = 0
|
|
1242
|
+
|
|
1243
|
+
// Handle append transformations (same logic as computeWorldMatrices)
|
|
1244
|
+
const appendParentIdx = b.appendParentIndex
|
|
1245
|
+
const hasAppend = b.appendRotate &&
|
|
1246
|
+
appendParentIdx !== undefined &&
|
|
1247
|
+
appendParentIdx >= 0 &&
|
|
1248
|
+
appendParentIdx < bones.length
|
|
1249
|
+
|
|
1250
|
+
if (hasAppend) {
|
|
1251
|
+
const ratio = b.appendRatio === undefined ? 1 : Math.max(-1, Math.min(1, b.appendRatio))
|
|
1252
|
+
const hasRatio = Math.abs(ratio) > 1e-6
|
|
1253
|
+
|
|
1254
|
+
if (hasRatio) {
|
|
1255
|
+
if (b.appendRotate) {
|
|
1256
|
+
// Get append parent's rotation
|
|
1257
|
+
// During IK solving, use only base local rotation (not IK rotations) to avoid
|
|
1258
|
+
// conflicts with IK rotations that are still being computed incrementally
|
|
1259
|
+
// IK rotations will be applied to localRotations after IK solving completes
|
|
1260
|
+
if (appendParentIdx >= 0) {
|
|
1261
|
+
// Compute append parent's world matrix for dependency order, but use base rotation for append
|
|
1262
|
+
this.computeSingleBoneWorldMatrix(appendParentIdx, applyIK)
|
|
1263
|
+
}
|
|
1264
|
+
|
|
1265
|
+
// Use append parent's base local rotation only (IK rotations are applied after solving)
|
|
1266
|
+
let appendRot = localRot[appendParentIdx]
|
|
1267
|
+
|
|
1268
|
+
let ax = appendRot.x, ay = appendRot.y, az = appendRot.z
|
|
1269
|
+
const aw = appendRot.w
|
|
1270
|
+
const absRatio = ratio < 0 ? -ratio : ratio
|
|
1271
|
+
if (ratio < 0) { ax = -ax; ay = -ay; az = -az }
|
|
1272
|
+
|
|
1273
|
+
const appendQuat = new Quat(ax, ay, az, aw)
|
|
1274
|
+
const result = Quat.slerp(Quat.identity(), appendQuat, absRatio)
|
|
1275
|
+
rotateM = Mat4.fromQuat(result.x, result.y, result.z, result.w).multiply(rotateM)
|
|
1276
|
+
}
|
|
1277
|
+
|
|
1278
|
+
if (b.appendMove) {
|
|
1279
|
+
const appendTrans = localTrans[appendParentIdx]
|
|
1280
|
+
addLocalTx = appendTrans.x * ratio
|
|
1281
|
+
addLocalTy = appendTrans.y * ratio
|
|
1282
|
+
addLocalTz = appendTrans.z * ratio
|
|
1283
|
+
}
|
|
1284
|
+
}
|
|
1285
|
+
}
|
|
1286
|
+
|
|
1287
|
+
const boneTrans = localTrans[boneIndex]
|
|
1288
|
+
const localTx = boneTrans.x + addLocalTx
|
|
1289
|
+
const localTy = boneTrans.y + addLocalTy
|
|
1290
|
+
const localTz = boneTrans.z + addLocalTz
|
|
1291
|
+
|
|
1292
|
+
this.cachedIdentityMat1
|
|
1293
|
+
.setIdentity()
|
|
1294
|
+
.translateInPlace(b.bindTranslation[0], b.bindTranslation[1], b.bindTranslation[2])
|
|
1295
|
+
this.cachedIdentityMat2.setIdentity().translateInPlace(localTx, localTy, localTz)
|
|
1296
|
+
const localM = this.cachedIdentityMat1.multiply(rotateM).multiply(this.cachedIdentityMat2)
|
|
1297
|
+
|
|
1298
|
+
const worldMat = worldMats[boneIndex]
|
|
1299
|
+
if (b.parentIndex >= 0) {
|
|
1300
|
+
const parentMat = worldMats[b.parentIndex]
|
|
1301
|
+
Mat4.multiplyArrays(parentMat.values, 0, localM.values, 0, worldMat.values, 0)
|
|
1302
|
+
} else {
|
|
1303
|
+
worldMat.values.set(localM.values)
|
|
1304
|
+
}
|
|
1149
1305
|
}
|
|
1150
1306
|
|
|
1151
1307
|
private computeWorldMatrices(): void {
|
|
@@ -1238,4 +1394,4 @@ export class Model {
|
|
|
1238
1394
|
// Process all bones (recursion handles dependencies automatically)
|
|
1239
1395
|
for (let i = 0; i < boneCount; i++) computeWorld(i)
|
|
1240
1396
|
}
|
|
1241
|
-
}
|
|
1397
|
+
}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Bezier interpolation for VMD animations
|
|
3
|
-
* Based on the reference implementation from babylon-mmd
|
|
4
|
-
*/
|
|
5
|
-
/**
|
|
6
|
-
* Bezier interpolation function
|
|
7
|
-
* @param x1 First control point X (0-127, normalized to 0-1)
|
|
8
|
-
* @param x2 Second control point X (0-127, normalized to 0-1)
|
|
9
|
-
* @param y1 First control point Y (0-127, normalized to 0-1)
|
|
10
|
-
* @param y2 Second control point Y (0-127, normalized to 0-1)
|
|
11
|
-
* @param t Interpolation parameter (0-1)
|
|
12
|
-
* @returns Interpolated value (0-1)
|
|
13
|
-
*/
|
|
14
|
-
export declare function bezierInterpolate(x1: number, x2: number, y1: number, y2: number, t: number): number;
|
|
15
|
-
//# sourceMappingURL=bezier-interpolate.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"bezier-interpolate.d.ts","sourceRoot":"","sources":["../src/bezier-interpolate.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,MAAM,CAgCnG"}
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Bezier interpolation for VMD animations
|
|
3
|
-
* Based on the reference implementation from babylon-mmd
|
|
4
|
-
*/
|
|
5
|
-
/**
|
|
6
|
-
* Bezier interpolation function
|
|
7
|
-
* @param x1 First control point X (0-127, normalized to 0-1)
|
|
8
|
-
* @param x2 Second control point X (0-127, normalized to 0-1)
|
|
9
|
-
* @param y1 First control point Y (0-127, normalized to 0-1)
|
|
10
|
-
* @param y2 Second control point Y (0-127, normalized to 0-1)
|
|
11
|
-
* @param t Interpolation parameter (0-1)
|
|
12
|
-
* @returns Interpolated value (0-1)
|
|
13
|
-
*/
|
|
14
|
-
export function bezierInterpolate(x1, x2, y1, y2, t) {
|
|
15
|
-
// Clamp t to [0, 1]
|
|
16
|
-
t = Math.max(0, Math.min(1, t));
|
|
17
|
-
// Binary search for the t value that gives us the desired x
|
|
18
|
-
// We're solving for t in the Bezier curve: x(t) = 3*(1-t)^2*t*x1 + 3*(1-t)*t^2*x2 + t^3
|
|
19
|
-
let start = 0;
|
|
20
|
-
let end = 1;
|
|
21
|
-
let mid = 0.5;
|
|
22
|
-
// Iterate until we find the t value that gives us the desired x
|
|
23
|
-
for (let i = 0; i < 15; i++) {
|
|
24
|
-
// Evaluate Bezier curve at mid point
|
|
25
|
-
const x = 3 * (1 - mid) * (1 - mid) * mid * x1 + 3 * (1 - mid) * mid * mid * x2 + mid * mid * mid;
|
|
26
|
-
if (Math.abs(x - t) < 0.0001) {
|
|
27
|
-
break;
|
|
28
|
-
}
|
|
29
|
-
if (x < t) {
|
|
30
|
-
start = mid;
|
|
31
|
-
}
|
|
32
|
-
else {
|
|
33
|
-
end = mid;
|
|
34
|
-
}
|
|
35
|
-
mid = (start + end) / 2;
|
|
36
|
-
}
|
|
37
|
-
// Now evaluate the y value at this t
|
|
38
|
-
const y = 3 * (1 - mid) * (1 - mid) * mid * y1 + 3 * (1 - mid) * mid * mid * y2 + mid * mid * mid;
|
|
39
|
-
return y;
|
|
40
|
-
}
|
package/dist/engine_ts.d.ts
DELETED
|
@@ -1,143 +0,0 @@
|
|
|
1
|
-
import { Quat, Vec3 } from "reze-mmd";
|
|
2
|
-
export type EngineOptions = {
|
|
3
|
-
ambientColor?: Vec3;
|
|
4
|
-
bloomIntensity?: number;
|
|
5
|
-
rimLightIntensity?: number;
|
|
6
|
-
cameraDistance?: number;
|
|
7
|
-
cameraTarget?: Vec3;
|
|
8
|
-
};
|
|
9
|
-
export interface EngineStats {
|
|
10
|
-
fps: number;
|
|
11
|
-
frameTime: number;
|
|
12
|
-
}
|
|
13
|
-
export declare class Engine {
|
|
14
|
-
private canvas;
|
|
15
|
-
private device;
|
|
16
|
-
private context;
|
|
17
|
-
private presentationFormat;
|
|
18
|
-
private camera;
|
|
19
|
-
private cameraUniformBuffer;
|
|
20
|
-
private cameraMatrixData;
|
|
21
|
-
private cameraDistance;
|
|
22
|
-
private cameraTarget;
|
|
23
|
-
private lightUniformBuffer;
|
|
24
|
-
private lightData;
|
|
25
|
-
private vertexBuffer;
|
|
26
|
-
private indexBuffer?;
|
|
27
|
-
private resizeObserver;
|
|
28
|
-
private depthTexture;
|
|
29
|
-
private modelPipeline;
|
|
30
|
-
private eyePipeline;
|
|
31
|
-
private hairPipelineOverEyes;
|
|
32
|
-
private hairPipelineOverNonEyes;
|
|
33
|
-
private hairDepthPipeline;
|
|
34
|
-
private outlinePipeline;
|
|
35
|
-
private hairOutlinePipeline;
|
|
36
|
-
private mainBindGroupLayout;
|
|
37
|
-
private outlineBindGroupLayout;
|
|
38
|
-
private jointsBuffer;
|
|
39
|
-
private weightsBuffer;
|
|
40
|
-
private skinMatrixBuffer?;
|
|
41
|
-
private multisampleTexture;
|
|
42
|
-
private readonly sampleCount;
|
|
43
|
-
private renderPassDescriptor;
|
|
44
|
-
private readonly STENCIL_EYE_VALUE;
|
|
45
|
-
private readonly BLOOM_DOWNSCALE_FACTOR;
|
|
46
|
-
private static readonly DEFAULT_BLOOM_THRESHOLD;
|
|
47
|
-
private static readonly DEFAULT_BLOOM_INTENSITY;
|
|
48
|
-
private static readonly DEFAULT_RIM_LIGHT_INTENSITY;
|
|
49
|
-
private static readonly DEFAULT_CAMERA_DISTANCE;
|
|
50
|
-
private static readonly DEFAULT_CAMERA_TARGET;
|
|
51
|
-
private static readonly TRANSPARENCY_EPSILON;
|
|
52
|
-
private static readonly STATS_FPS_UPDATE_INTERVAL_MS;
|
|
53
|
-
private static readonly STATS_FRAME_TIME_ROUNDING;
|
|
54
|
-
private ambientColor;
|
|
55
|
-
private sceneRenderTexture;
|
|
56
|
-
private sceneRenderTextureView;
|
|
57
|
-
private bloomExtractTexture;
|
|
58
|
-
private bloomBlurTexture1;
|
|
59
|
-
private bloomBlurTexture2;
|
|
60
|
-
private bloomExtractPipeline;
|
|
61
|
-
private bloomBlurPipeline;
|
|
62
|
-
private bloomComposePipeline;
|
|
63
|
-
private blurDirectionBuffer;
|
|
64
|
-
private bloomIntensityBuffer;
|
|
65
|
-
private bloomThresholdBuffer;
|
|
66
|
-
private linearSampler;
|
|
67
|
-
private bloomExtractBindGroup?;
|
|
68
|
-
private bloomBlurHBindGroup?;
|
|
69
|
-
private bloomBlurVBindGroup?;
|
|
70
|
-
private bloomComposeBindGroup?;
|
|
71
|
-
private bloomThreshold;
|
|
72
|
-
private bloomIntensity;
|
|
73
|
-
private rimLightIntensity;
|
|
74
|
-
private currentModel;
|
|
75
|
-
private modelDir;
|
|
76
|
-
private physics;
|
|
77
|
-
private materialSampler;
|
|
78
|
-
private textureCache;
|
|
79
|
-
private vertexBufferNeedsUpdate;
|
|
80
|
-
private drawCalls;
|
|
81
|
-
private lastFpsUpdate;
|
|
82
|
-
private framesSinceLastUpdate;
|
|
83
|
-
private lastFrameTime;
|
|
84
|
-
private frameTimeSum;
|
|
85
|
-
private frameTimeCount;
|
|
86
|
-
private stats;
|
|
87
|
-
private animationFrameId;
|
|
88
|
-
private renderLoopCallback;
|
|
89
|
-
private player;
|
|
90
|
-
private hasAnimation;
|
|
91
|
-
constructor(canvas: HTMLCanvasElement, options?: EngineOptions);
|
|
92
|
-
init(): Promise<void>;
|
|
93
|
-
private createRenderPipeline;
|
|
94
|
-
private createPipelines;
|
|
95
|
-
private createBloomPipelines;
|
|
96
|
-
private setupBloom;
|
|
97
|
-
private setupResize;
|
|
98
|
-
private handleResize;
|
|
99
|
-
private setupCamera;
|
|
100
|
-
private setupLighting;
|
|
101
|
-
private setAmbientColor;
|
|
102
|
-
loadAnimation(url: string): Promise<void>;
|
|
103
|
-
playAnimation(): void;
|
|
104
|
-
stopAnimation(): void;
|
|
105
|
-
pauseAnimation(): void;
|
|
106
|
-
seekAnimation(time: number): void;
|
|
107
|
-
getAnimationProgress(): import("./player").AnimationProgress;
|
|
108
|
-
/**
|
|
109
|
-
* Apply animation pose to model
|
|
110
|
-
*/
|
|
111
|
-
private applyPose;
|
|
112
|
-
/**
|
|
113
|
-
* Reset bones and physics to match a given pose
|
|
114
|
-
* @param pose The pose to apply
|
|
115
|
-
* @param resetBonesWithoutKeyframes If true, reset bones that don't have keyframes in the pose to identity
|
|
116
|
-
*/
|
|
117
|
-
private resetBonesAndPhysics;
|
|
118
|
-
getStats(): EngineStats;
|
|
119
|
-
runRenderLoop(callback?: () => void): void;
|
|
120
|
-
stopRenderLoop(): void;
|
|
121
|
-
dispose(): void;
|
|
122
|
-
loadModel(path: string): Promise<void>;
|
|
123
|
-
rotateBones(bones: string[], rotations: Quat[], durationMs?: number): void;
|
|
124
|
-
moveBones(bones: string[], relativeTranslations: Vec3[], durationMs?: number): void;
|
|
125
|
-
setMorphWeight(name: string, weight: number, durationMs?: number): void;
|
|
126
|
-
private updateVertexBuffer;
|
|
127
|
-
private setupModelBuffers;
|
|
128
|
-
private setupMaterials;
|
|
129
|
-
private createMaterialUniformBuffer;
|
|
130
|
-
private createUniformBuffer;
|
|
131
|
-
private createTextureFromPath;
|
|
132
|
-
private renderEyes;
|
|
133
|
-
private renderHair;
|
|
134
|
-
render(): void;
|
|
135
|
-
private applyBloom;
|
|
136
|
-
private updateCameraUniforms;
|
|
137
|
-
private updateRenderTarget;
|
|
138
|
-
private updateModelPose;
|
|
139
|
-
private computeSkinMatrices;
|
|
140
|
-
private drawOutlines;
|
|
141
|
-
private updateStats;
|
|
142
|
-
}
|
|
143
|
-
//# sourceMappingURL=engine_ts.d.ts.map
|
package/dist/engine_ts.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"engine_ts.d.ts","sourceRoot":"","sources":["../src/engine_ts.ts"],"names":[],"mappings":"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"}
|