reze-engine 0.2.18 → 0.3.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.
@@ -0,0 +1,372 @@
1
+ /**
2
+ * IK Solver implementation
3
+ * Based on reference from babylon-mmd and Saba MMD library
4
+ * https://github.com/benikabocha/saba/blob/master/src/Saba/Model/MMD/MMDIkSolver.cpp
5
+ */
6
+ import { Mat4, Quat, Vec3 } from "./math";
7
+ var InternalEulerRotationOrder;
8
+ (function (InternalEulerRotationOrder) {
9
+ InternalEulerRotationOrder[InternalEulerRotationOrder["YXZ"] = 0] = "YXZ";
10
+ InternalEulerRotationOrder[InternalEulerRotationOrder["ZYX"] = 1] = "ZYX";
11
+ InternalEulerRotationOrder[InternalEulerRotationOrder["XZY"] = 2] = "XZY";
12
+ })(InternalEulerRotationOrder || (InternalEulerRotationOrder = {}));
13
+ var InternalSolveAxis;
14
+ (function (InternalSolveAxis) {
15
+ InternalSolveAxis[InternalSolveAxis["None"] = 0] = "None";
16
+ InternalSolveAxis[InternalSolveAxis["Fixed"] = 1] = "Fixed";
17
+ InternalSolveAxis[InternalSolveAxis["X"] = 2] = "X";
18
+ InternalSolveAxis[InternalSolveAxis["Y"] = 3] = "Y";
19
+ InternalSolveAxis[InternalSolveAxis["Z"] = 4] = "Z";
20
+ })(InternalSolveAxis || (InternalSolveAxis = {}));
21
+ class IKChain {
22
+ constructor(boneIndex, link) {
23
+ this.boneIndex = boneIndex;
24
+ if (link.hasLimit && link.minAngle && link.maxAngle) {
25
+ // Normalize min/max angles
26
+ const minX = Math.min(link.minAngle.x, link.maxAngle.x);
27
+ const minY = Math.min(link.minAngle.y, link.maxAngle.y);
28
+ const minZ = Math.min(link.minAngle.z, link.maxAngle.z);
29
+ const maxX = Math.max(link.minAngle.x, link.maxAngle.x);
30
+ const maxY = Math.max(link.minAngle.y, link.maxAngle.y);
31
+ const maxZ = Math.max(link.minAngle.z, link.maxAngle.z);
32
+ this.minimumAngle = new Vec3(minX, minY, minZ);
33
+ this.maximumAngle = new Vec3(maxX, maxY, maxZ);
34
+ // Determine rotation order based on constraint ranges
35
+ const halfPi = Math.PI * 0.5;
36
+ if (-halfPi < minX && maxX < halfPi) {
37
+ this.rotationOrder = InternalEulerRotationOrder.YXZ;
38
+ }
39
+ else if (-halfPi < minY && maxY < halfPi) {
40
+ this.rotationOrder = InternalEulerRotationOrder.ZYX;
41
+ }
42
+ else {
43
+ this.rotationOrder = InternalEulerRotationOrder.XZY;
44
+ }
45
+ // Determine solve axis optimization
46
+ if (minX === 0 && maxX === 0 && minY === 0 && maxY === 0 && minZ === 0 && maxZ === 0) {
47
+ this.solveAxis = InternalSolveAxis.Fixed;
48
+ }
49
+ else if (minY === 0 && maxY === 0 && minZ === 0 && maxZ === 0) {
50
+ this.solveAxis = InternalSolveAxis.X;
51
+ }
52
+ else if (minX === 0 && maxX === 0 && minZ === 0 && maxZ === 0) {
53
+ this.solveAxis = InternalSolveAxis.Y;
54
+ }
55
+ else if (minX === 0 && maxX === 0 && minY === 0 && maxY === 0) {
56
+ this.solveAxis = InternalSolveAxis.Z;
57
+ }
58
+ else {
59
+ this.solveAxis = InternalSolveAxis.None;
60
+ }
61
+ }
62
+ else {
63
+ this.minimumAngle = null;
64
+ this.maximumAngle = null;
65
+ this.rotationOrder = InternalEulerRotationOrder.XZY; // not used
66
+ this.solveAxis = InternalSolveAxis.None;
67
+ }
68
+ }
69
+ }
70
+ /**
71
+ * Solve IK chains for a model
72
+ */
73
+ export class IKSolverSystem {
74
+ /**
75
+ * Solve all IK chains
76
+ */
77
+ static solve(ikSolvers, bones, localRotations, localTranslations, worldMatrices, ikChainInfo, usePhysics = false) {
78
+ for (const solver of ikSolvers) {
79
+ if (usePhysics && solver.canSkipWhenPhysicsEnabled) {
80
+ continue;
81
+ }
82
+ this.solveIK(solver, bones, localRotations, localTranslations, worldMatrices, ikChainInfo);
83
+ }
84
+ }
85
+ static solveIK(solver, bones, localRotations, localTranslations, worldMatrices, ikChainInfo) {
86
+ if (solver.links.length === 0)
87
+ return;
88
+ const ikBoneIndex = solver.ikBoneIndex;
89
+ const targetBoneIndex = solver.targetBoneIndex;
90
+ // Reset IK rotations
91
+ for (const link of solver.links) {
92
+ const chainInfo = ikChainInfo[link.boneIndex];
93
+ if (chainInfo) {
94
+ chainInfo.ikRotation = new Quat(0, 0, 0, 1);
95
+ }
96
+ }
97
+ // Get IK bone and target positions
98
+ const ikPosition = this.getWorldTranslation(ikBoneIndex, worldMatrices);
99
+ const targetPosition = this.getWorldTranslation(targetBoneIndex, worldMatrices);
100
+ if (ikPosition.subtract(targetPosition).length() < this.EPSILON)
101
+ return;
102
+ // Build IK chains
103
+ const chains = [];
104
+ for (const link of solver.links) {
105
+ chains.push(new IKChain(link.boneIndex, link));
106
+ }
107
+ // Update chain bones and target bone world matrices (initial state, no IK yet)
108
+ for (let i = chains.length - 1; i >= 0; i--) {
109
+ this.updateWorldMatrix(chains[i].boneIndex, bones, localRotations, localTranslations, worldMatrices);
110
+ }
111
+ this.updateWorldMatrix(targetBoneIndex, bones, localRotations, localTranslations, worldMatrices);
112
+ // Re-read positions after initial update
113
+ const updatedIkPosition = this.getWorldTranslation(ikBoneIndex, worldMatrices);
114
+ const updatedTargetPosition = this.getWorldTranslation(targetBoneIndex, worldMatrices);
115
+ if (updatedIkPosition.subtract(updatedTargetPosition).length() < this.EPSILON)
116
+ return;
117
+ // Solve iteratively
118
+ const iteration = Math.min(solver.iterationCount, 256);
119
+ const halfIteration = iteration >> 1;
120
+ for (let i = 0; i < iteration; i++) {
121
+ for (let chainIndex = 0; chainIndex < chains.length; chainIndex++) {
122
+ const chain = chains[chainIndex];
123
+ if (chain.solveAxis !== InternalSolveAxis.Fixed) {
124
+ this.solveChain(chain, chainIndex, solver, ikBoneIndex, targetBoneIndex, bones, localRotations, localTranslations, worldMatrices, ikChainInfo, i < halfIteration);
125
+ }
126
+ }
127
+ // Re-read positions after this iteration
128
+ const currentIkPosition = this.getWorldTranslation(ikBoneIndex, worldMatrices);
129
+ const currentTargetPosition = this.getWorldTranslation(targetBoneIndex, worldMatrices);
130
+ const distance = currentIkPosition.subtract(currentTargetPosition).length();
131
+ if (distance < this.EPSILON)
132
+ break;
133
+ }
134
+ // Apply IK rotations to local rotations
135
+ for (const link of solver.links) {
136
+ const chainInfo = ikChainInfo[link.boneIndex];
137
+ if (chainInfo && chainInfo.ikRotation) {
138
+ const qi = link.boneIndex * 4;
139
+ const localRot = new Quat(localRotations[qi], localRotations[qi + 1], localRotations[qi + 2], localRotations[qi + 3]);
140
+ const finalRot = chainInfo.ikRotation.multiply(localRot).normalize();
141
+ localRotations[qi] = finalRot.x;
142
+ localRotations[qi + 1] = finalRot.y;
143
+ localRotations[qi + 2] = finalRot.z;
144
+ localRotations[qi + 3] = finalRot.w;
145
+ }
146
+ }
147
+ }
148
+ static solveChain(chain, chainIndex, solver, ikBoneIndex, targetBoneIndex, bones, localRotations, localTranslations, worldMatrices, ikChainInfo, useAxis) {
149
+ const chainBoneIndex = chain.boneIndex;
150
+ const chainPosition = this.getWorldTranslation(chainBoneIndex, worldMatrices);
151
+ const ikPosition = this.getWorldTranslation(ikBoneIndex, worldMatrices);
152
+ const targetPosition = this.getWorldTranslation(targetBoneIndex, worldMatrices);
153
+ const chainTargetVector = chainPosition.subtract(targetPosition).normalize();
154
+ const chainIkVector = chainPosition.subtract(ikPosition).normalize();
155
+ const chainRotationAxis = chainTargetVector.cross(chainIkVector);
156
+ if (chainRotationAxis.length() < this.EPSILON)
157
+ return;
158
+ // Get parent's world rotation matrix (translation removed)
159
+ const parentWorldRotMatrix = this.getParentWorldRotationMatrix(chainBoneIndex, bones, worldMatrices);
160
+ let finalRotationAxis;
161
+ if (chain.minimumAngle !== null && useAxis) {
162
+ switch (chain.solveAxis) {
163
+ case InternalSolveAxis.None: {
164
+ const invParentRot = parentWorldRotMatrix.inverse();
165
+ finalRotationAxis = this.transformNormal(chainRotationAxis, invParentRot).normalize();
166
+ break;
167
+ }
168
+ case InternalSolveAxis.X: {
169
+ const m = parentWorldRotMatrix.values;
170
+ const axisX = new Vec3(m[0], m[1], m[2]);
171
+ const dot = chainRotationAxis.dot(axisX);
172
+ finalRotationAxis = new Vec3(dot >= 0 ? 1 : -1, 0, 0);
173
+ break;
174
+ }
175
+ case InternalSolveAxis.Y: {
176
+ const m = parentWorldRotMatrix.values;
177
+ const axisY = new Vec3(m[4], m[5], m[6]);
178
+ const dot = chainRotationAxis.dot(axisY);
179
+ finalRotationAxis = new Vec3(0, dot >= 0 ? 1 : -1, 0);
180
+ break;
181
+ }
182
+ case InternalSolveAxis.Z: {
183
+ const m = parentWorldRotMatrix.values;
184
+ const axisZ = new Vec3(m[8], m[9], m[10]);
185
+ const dot = chainRotationAxis.dot(axisZ);
186
+ finalRotationAxis = new Vec3(0, 0, dot >= 0 ? 1 : -1);
187
+ break;
188
+ }
189
+ default:
190
+ finalRotationAxis = chainRotationAxis;
191
+ }
192
+ }
193
+ else {
194
+ const invParentRot = parentWorldRotMatrix.inverse();
195
+ finalRotationAxis = this.transformNormal(chainRotationAxis, invParentRot).normalize();
196
+ }
197
+ let dot = chainTargetVector.dot(chainIkVector);
198
+ dot = Math.max(-1.0, Math.min(1.0, dot));
199
+ const angle = Math.min(solver.limitAngle * (chainIndex + 1), Math.acos(dot));
200
+ const ikRotation = Quat.fromAxisAngle(finalRotationAxis, angle);
201
+ const chainInfo = ikChainInfo[chainBoneIndex];
202
+ if (chainInfo) {
203
+ chainInfo.ikRotation = ikRotation.multiply(chainInfo.ikRotation);
204
+ // Apply angle constraints if present
205
+ if (chain.minimumAngle !== null && chain.maximumAngle !== null) {
206
+ const qi = chainBoneIndex * 4;
207
+ const localRot = new Quat(localRotations[qi], localRotations[qi + 1], localRotations[qi + 2], localRotations[qi + 3]);
208
+ chainInfo.localRotation = localRot.clone();
209
+ const combinedRot = chainInfo.ikRotation.multiply(localRot);
210
+ const rotMatrix = Mat4.fromQuat(combinedRot.x, combinedRot.y, combinedRot.z, combinedRot.w);
211
+ const m = rotMatrix.values;
212
+ let rX, rY, rZ;
213
+ switch (chain.rotationOrder) {
214
+ case InternalEulerRotationOrder.YXZ: {
215
+ rX = Math.asin(-m[9]); // m32
216
+ if (Math.abs(rX) > this.THRESHOLD) {
217
+ rX = rX < 0 ? -this.THRESHOLD : this.THRESHOLD;
218
+ }
219
+ let cosX = Math.cos(rX);
220
+ if (cosX !== 0)
221
+ cosX = 1 / cosX;
222
+ rY = Math.atan2(m[8] * cosX, m[10] * cosX); // m31, m33
223
+ rZ = Math.atan2(m[1] * cosX, m[5] * cosX); // m12, m22
224
+ rX = this.limitAngle(rX, chain.minimumAngle.x, chain.maximumAngle.x, useAxis);
225
+ rY = this.limitAngle(rY, chain.minimumAngle.y, chain.maximumAngle.y, useAxis);
226
+ rZ = this.limitAngle(rZ, chain.minimumAngle.z, chain.maximumAngle.z, useAxis);
227
+ chainInfo.ikRotation = Quat.fromAxisAngle(new Vec3(0, 1, 0), rY);
228
+ chainInfo.ikRotation = chainInfo.ikRotation.multiply(Quat.fromAxisAngle(new Vec3(1, 0, 0), rX));
229
+ chainInfo.ikRotation = chainInfo.ikRotation.multiply(Quat.fromAxisAngle(new Vec3(0, 0, 1), rZ));
230
+ break;
231
+ }
232
+ case InternalEulerRotationOrder.ZYX: {
233
+ rY = Math.asin(-m[2]); // m13
234
+ if (Math.abs(rY) > this.THRESHOLD) {
235
+ rY = rY < 0 ? -this.THRESHOLD : this.THRESHOLD;
236
+ }
237
+ let cosY = Math.cos(rY);
238
+ if (cosY !== 0)
239
+ cosY = 1 / cosY;
240
+ rX = Math.atan2(m[6] * cosY, m[10] * cosY); // m23, m33
241
+ rZ = Math.atan2(m[1] * cosY, m[0] * cosY); // m12, m11
242
+ rX = this.limitAngle(rX, chain.minimumAngle.x, chain.maximumAngle.x, useAxis);
243
+ rY = this.limitAngle(rY, chain.minimumAngle.y, chain.maximumAngle.y, useAxis);
244
+ rZ = this.limitAngle(rZ, chain.minimumAngle.z, chain.maximumAngle.z, useAxis);
245
+ chainInfo.ikRotation = Quat.fromAxisAngle(new Vec3(0, 0, 1), rZ);
246
+ chainInfo.ikRotation = chainInfo.ikRotation.multiply(Quat.fromAxisAngle(new Vec3(0, 1, 0), rY));
247
+ chainInfo.ikRotation = chainInfo.ikRotation.multiply(Quat.fromAxisAngle(new Vec3(1, 0, 0), rX));
248
+ break;
249
+ }
250
+ case InternalEulerRotationOrder.XZY: {
251
+ rZ = Math.asin(-m[4]); // m21
252
+ if (Math.abs(rZ) > this.THRESHOLD) {
253
+ rZ = rZ < 0 ? -this.THRESHOLD : this.THRESHOLD;
254
+ }
255
+ let cosZ = Math.cos(rZ);
256
+ if (cosZ !== 0)
257
+ cosZ = 1 / cosZ;
258
+ rX = Math.atan2(m[6] * cosZ, m[5] * cosZ); // m23, m22
259
+ rY = Math.atan2(m[8] * cosZ, m[0] * cosZ); // m31, m11
260
+ rX = this.limitAngle(rX, chain.minimumAngle.x, chain.maximumAngle.x, useAxis);
261
+ rY = this.limitAngle(rY, chain.minimumAngle.y, chain.maximumAngle.y, useAxis);
262
+ rZ = this.limitAngle(rZ, chain.minimumAngle.z, chain.maximumAngle.z, useAxis);
263
+ chainInfo.ikRotation = Quat.fromAxisAngle(new Vec3(1, 0, 0), rX);
264
+ chainInfo.ikRotation = chainInfo.ikRotation.multiply(Quat.fromAxisAngle(new Vec3(0, 0, 1), rZ));
265
+ chainInfo.ikRotation = chainInfo.ikRotation.multiply(Quat.fromAxisAngle(new Vec3(0, 1, 0), rY));
266
+ break;
267
+ }
268
+ }
269
+ const invertedLocalRotation = localRot.conjugate().normalize();
270
+ chainInfo.ikRotation = chainInfo.ikRotation.multiply(invertedLocalRotation);
271
+ }
272
+ }
273
+ // Update world matrices for affected bones (using IK-modified rotations)
274
+ for (let i = chainIndex; i >= 0; i--) {
275
+ const link = solver.links[i];
276
+ this.updateWorldMatrixWithIK(link.boneIndex, bones, localRotations, localTranslations, worldMatrices, ikChainInfo);
277
+ }
278
+ this.updateWorldMatrix(targetBoneIndex, bones, localRotations, localTranslations, worldMatrices);
279
+ }
280
+ static limitAngle(angle, min, max, useAxis) {
281
+ if (angle < min) {
282
+ const diff = 2 * min - angle;
283
+ return diff <= max && useAxis ? diff : min;
284
+ }
285
+ else if (angle > max) {
286
+ const diff = 2 * max - angle;
287
+ return diff >= min && useAxis ? diff : max;
288
+ }
289
+ else {
290
+ return angle;
291
+ }
292
+ }
293
+ static getWorldTranslation(boneIndex, worldMatrices) {
294
+ const offset = boneIndex * 16;
295
+ return new Vec3(worldMatrices[offset + 12], worldMatrices[offset + 13], worldMatrices[offset + 14]);
296
+ }
297
+ static getParentWorldRotationMatrix(boneIndex, bones, worldMatrices) {
298
+ const bone = bones[boneIndex];
299
+ if (bone.parentIndex >= 0) {
300
+ const parentOffset = bone.parentIndex * 16;
301
+ const parentMat = new Mat4(worldMatrices.subarray(parentOffset, parentOffset + 16));
302
+ // Remove translation
303
+ const rotMat = Mat4.identity();
304
+ const m = parentMat.values;
305
+ rotMat.values.set([m[0], m[1], m[2], 0, m[4], m[5], m[6], 0, m[8], m[9], m[10], 0, 0, 0, 0, 1]);
306
+ return rotMat;
307
+ }
308
+ else {
309
+ return Mat4.identity();
310
+ }
311
+ }
312
+ static transformNormal(normal, matrix) {
313
+ const m = matrix.values;
314
+ return new Vec3(m[0] * normal.x + m[4] * normal.y + m[8] * normal.z, m[1] * normal.x + m[5] * normal.y + m[9] * normal.z, m[2] * normal.x + m[6] * normal.y + m[10] * normal.z);
315
+ }
316
+ static updateWorldMatrixWithIK(boneIndex, bones, localRotations, localTranslations, worldMatrices, ikChainInfo) {
317
+ const bone = bones[boneIndex];
318
+ const qi = boneIndex * 4;
319
+ const ti = boneIndex * 3;
320
+ // Use IK-modified rotation if available
321
+ const localRot = new Quat(localRotations[qi], localRotations[qi + 1], localRotations[qi + 2], localRotations[qi + 3]);
322
+ const chainInfo = ikChainInfo[boneIndex];
323
+ let finalRot = localRot;
324
+ if (chainInfo && chainInfo.ikRotation) {
325
+ finalRot = chainInfo.ikRotation.multiply(localRot).normalize();
326
+ }
327
+ const rotateM = Mat4.fromQuat(finalRot.x, finalRot.y, finalRot.z, finalRot.w);
328
+ const localTx = localTranslations[ti];
329
+ const localTy = localTranslations[ti + 1];
330
+ const localTz = localTranslations[ti + 2];
331
+ const localM = Mat4.identity()
332
+ .translateInPlace(bone.bindTranslation[0], bone.bindTranslation[1], bone.bindTranslation[2])
333
+ .multiply(rotateM)
334
+ .translateInPlace(localTx, localTy, localTz);
335
+ const worldOffset = boneIndex * 16;
336
+ if (bone.parentIndex >= 0) {
337
+ const parentOffset = bone.parentIndex * 16;
338
+ const parentMat = new Mat4(worldMatrices.subarray(parentOffset, parentOffset + 16));
339
+ const worldMat = parentMat.multiply(localM);
340
+ worldMatrices.subarray(worldOffset, worldOffset + 16).set(worldMat.values);
341
+ }
342
+ else {
343
+ worldMatrices.subarray(worldOffset, worldOffset + 16).set(localM.values);
344
+ }
345
+ }
346
+ static updateWorldMatrix(boneIndex, bones, localRotations, localTranslations, worldMatrices) {
347
+ const bone = bones[boneIndex];
348
+ const qi = boneIndex * 4;
349
+ const ti = boneIndex * 3;
350
+ const localRot = new Quat(localRotations[qi], localRotations[qi + 1], localRotations[qi + 2], localRotations[qi + 3]);
351
+ const rotateM = Mat4.fromQuat(localRot.x, localRot.y, localRot.z, localRot.w);
352
+ const localTx = localTranslations[ti];
353
+ const localTy = localTranslations[ti + 1];
354
+ const localTz = localTranslations[ti + 2];
355
+ const localM = Mat4.identity()
356
+ .translateInPlace(bone.bindTranslation[0], bone.bindTranslation[1], bone.bindTranslation[2])
357
+ .multiply(rotateM)
358
+ .translateInPlace(localTx, localTy, localTz);
359
+ const worldOffset = boneIndex * 16;
360
+ if (bone.parentIndex >= 0) {
361
+ const parentOffset = bone.parentIndex * 16;
362
+ const parentMat = new Mat4(worldMatrices.subarray(parentOffset, parentOffset + 16));
363
+ const worldMat = parentMat.multiply(localM);
364
+ worldMatrices.subarray(worldOffset, worldOffset + 16).set(worldMat.values);
365
+ }
366
+ else {
367
+ worldMatrices.subarray(worldOffset, worldOffset + 16).set(localM.values);
368
+ }
369
+ }
370
+ }
371
+ IKSolverSystem.EPSILON = 1.0e-8;
372
+ IKSolverSystem.THRESHOLD = (88 * Math.PI) / 180;
package/dist/math.d.ts CHANGED
@@ -28,6 +28,7 @@ export declare class Quat {
28
28
  rotateVec(v: Vec3): Vec3;
29
29
  rotate(v: Vec3): Vec3;
30
30
  static fromTo(from: Vec3, to: Vec3): Quat;
31
+ static fromAxisAngle(axis: Vec3, angle: number): Quat;
31
32
  toArray(): [number, number, number, number];
32
33
  static slerp(a: Quat, b: Quat, t: number): Quat;
33
34
  static fromEuler(rotX: number, rotY: number, rotZ: number): Quat;
@@ -1 +1 @@
1
- {"version":3,"file":"math.d.ts","sourceRoot":"","sources":["../src/math.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"math.d.ts","sourceRoot":"","sources":["../src/math.ts"],"names":[],"mappings":"AACA,wBAAgB,SAAS,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAE3C;AAED,qBAAa,IAAI;IACf,CAAC,EAAE,MAAM,CAAA;IACT,CAAC,EAAE,MAAM,CAAA;IACT,CAAC,EAAE,MAAM,CAAA;gBAEG,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM;IAM3C,GAAG,CAAC,KAAK,EAAE,IAAI,GAAG,IAAI;IAItB,QAAQ,CAAC,KAAK,EAAE,IAAI,GAAG,IAAI;IAI3B,MAAM,IAAI,MAAM;IAIhB,SAAS,IAAI,IAAI;IAMjB,KAAK,CAAC,KAAK,EAAE,IAAI,GAAG,IAAI;IAQxB,GAAG,CAAC,KAAK,EAAE,IAAI,GAAG,MAAM;IAIxB,KAAK,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAI3B,KAAK,IAAI,IAAI;CAGd;AAED,qBAAa,IAAI;IACf,CAAC,EAAE,MAAM,CAAA;IACT,CAAC,EAAE,MAAM,CAAA;IACT,CAAC,EAAE,MAAM,CAAA;IACT,CAAC,EAAE,MAAM,CAAA;gBAEG,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM;IAOtD,GAAG,CAAC,KAAK,EAAE,IAAI,GAAG,IAAI;IAItB,KAAK,IAAI,IAAI;IAIb,QAAQ,CAAC,KAAK,EAAE,IAAI,GAAG,IAAI;IAU3B,SAAS,IAAI,IAAI;IAKjB,MAAM,IAAI,MAAM;IAIhB,SAAS,IAAI,IAAI;IAOjB,SAAS,CAAC,CAAC,EAAE,IAAI,GAAG,IAAI;IAwBxB,MAAM,CAAC,CAAC,EAAE,IAAI,GAAG,IAAI;IAQrB,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,GAAG,IAAI;IAiBzC,MAAM,CAAC,aAAa,CAAC,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI;IAQrD,OAAO,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;IAK3C,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI;IAoC/C,MAAM,CAAC,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI;IAiBhE,OAAO,IAAI,IAAI;CAuBhB;AAED,qBAAa,IAAI;IACf,MAAM,EAAE,YAAY,CAAA;gBAER,MAAM,EAAE,YAAY;IAIhC,MAAM,CAAC,QAAQ,IAAI,IAAI;IAMvB,MAAM,CAAC,WAAW,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI;IA4BhF,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,GAAG,IAAI;IA4BtD,QAAQ,CAAC,KAAK,EAAE,IAAI,GAAG,IAAI;IAqB3B,MAAM,CAAC,cAAc,CACnB,CAAC,EAAE,YAAY,EACf,OAAO,EAAE,MAAM,EACf,CAAC,EAAE,YAAY,EACf,OAAO,EAAE,MAAM,EACf,GAAG,EAAE,YAAY,EACjB,SAAS,EAAE,MAAM,GAChB,IAAI;IAiBP,KAAK,IAAI,IAAI;IAIb,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,EAAE,CAAC,EAAE,MAAM,GAAG,IAAI;IAmCjE,MAAM,CAAC,oBAAoB,CAAC,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,GAAG,IAAI;IASjE,WAAW,IAAI,IAAI;IAKnB,MAAM,IAAI,IAAI;IAKd,MAAM,CAAC,eAAe,CAAC,CAAC,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI;IA6C7D,WAAW,IAAI,IAAI;IAqBnB,gBAAgB,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,IAAI;IAY1D,OAAO,IAAI,IAAI;CA8DhB"}
package/dist/math.js CHANGED
@@ -102,6 +102,14 @@ export class Quat {
102
102
  const invW = 1 / w;
103
103
  return new Quat(axis.x * invW, axis.y * invW, axis.z * invW, w * 0.5).normalize();
104
104
  }
105
+ // Static method: create quaternion from rotation axis and angle
106
+ static fromAxisAngle(axis, angle) {
107
+ const normalizedAxis = axis.normalize();
108
+ const halfAngle = angle * 0.5;
109
+ const sinHalf = Math.sin(halfAngle);
110
+ const cosHalf = Math.cos(halfAngle);
111
+ return new Quat(normalizedAxis.x * sinHalf, normalizedAxis.y * sinHalf, normalizedAxis.z * sinHalf, cosHalf);
112
+ }
105
113
  toArray() {
106
114
  return [this.x, this.y, this.z, this.w];
107
115
  }
package/dist/model.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { Quat } from "./math";
1
+ import { Quat, Vec3 } from "./math";
2
2
  import { Rigidbody, Joint } from "./physics";
3
3
  export interface Texture {
4
4
  path: string;
@@ -32,6 +32,43 @@ export interface Bone {
32
32
  appendRatio?: number;
33
33
  appendRotate?: boolean;
34
34
  appendMove?: boolean;
35
+ ikTargetIndex?: number;
36
+ ikIteration?: number;
37
+ ikLimitAngle?: number;
38
+ ikLinks?: IKLink[];
39
+ }
40
+ export interface IKLink {
41
+ boneIndex: number;
42
+ hasLimit: boolean;
43
+ minAngle?: Vec3;
44
+ maxAngle?: Vec3;
45
+ rotationOrder?: EulerRotationOrder;
46
+ solveAxis?: SolveAxis;
47
+ }
48
+ export declare enum EulerRotationOrder {
49
+ YXZ = 0,
50
+ ZYX = 1,
51
+ XZY = 2
52
+ }
53
+ export declare enum SolveAxis {
54
+ None = 0,
55
+ Fixed = 1,
56
+ X = 2,
57
+ Y = 3,
58
+ Z = 4
59
+ }
60
+ export interface IKSolver {
61
+ index: number;
62
+ ikBoneIndex: number;
63
+ targetBoneIndex: number;
64
+ iterationCount: number;
65
+ limitAngle: number;
66
+ links: IKLink[];
67
+ canSkipWhenPhysicsEnabled: boolean;
68
+ }
69
+ export interface IKChainInfo {
70
+ ikRotation: Quat;
71
+ localRotation: Quat;
35
72
  }
36
73
  export interface Skeleton {
37
74
  bones: Bone[];
@@ -41,31 +78,66 @@ export interface Skinning {
41
78
  joints: Uint16Array;
42
79
  weights: Uint8Array;
43
80
  }
81
+ export interface VertexMorphOffset {
82
+ vertexIndex: number;
83
+ positionOffset: [number, number, number];
84
+ }
85
+ export interface GroupMorphReference {
86
+ morphIndex: number;
87
+ ratio: number;
88
+ }
89
+ export interface Morph {
90
+ name: string;
91
+ type: number;
92
+ vertexOffsets: VertexMorphOffset[];
93
+ groupReferences?: GroupMorphReference[];
94
+ }
95
+ export interface Morphing {
96
+ morphs: Morph[];
97
+ offsetsBuffer: Float32Array;
98
+ }
44
99
  export interface SkeletonRuntime {
45
100
  nameIndex: Record<string, number>;
46
101
  localRotations: Float32Array;
47
102
  localTranslations: Float32Array;
48
103
  worldMatrices: Float32Array;
49
104
  computedBones: boolean[];
105
+ ikChainInfo?: IKChainInfo[];
106
+ ikSolvers?: IKSolver[];
107
+ }
108
+ export interface MorphRuntime {
109
+ nameIndex: Record<string, number>;
110
+ weights: Float32Array;
50
111
  }
51
112
  export declare class Model {
52
113
  private vertexData;
114
+ private baseVertexData;
53
115
  private vertexCount;
54
116
  private indexData;
55
117
  private textures;
56
118
  private materials;
57
119
  private skeleton;
58
120
  private skinning;
121
+ private morphing;
59
122
  private rigidbodies;
60
123
  private joints;
61
124
  private runtimeSkeleton;
125
+ private runtimeMorph;
62
126
  private cachedIdentityMat1;
63
127
  private cachedIdentityMat2;
64
128
  private rotTweenState;
65
- constructor(vertexData: Float32Array<ArrayBuffer>, indexData: Uint32Array<ArrayBuffer>, textures: Texture[], materials: Material[], skeleton: Skeleton, skinning: Skinning, rigidbodies?: Rigidbody[], joints?: Joint[]);
129
+ private transTweenState;
130
+ private morphTweenState;
131
+ constructor(vertexData: Float32Array<ArrayBuffer>, indexData: Uint32Array<ArrayBuffer>, textures: Texture[], materials: Material[], skeleton: Skeleton, skinning: Skinning, morphing: Morphing, rigidbodies?: Rigidbody[], joints?: Joint[]);
66
132
  private initializeRuntimeSkeleton;
133
+ private initializeIKRuntime;
67
134
  private initializeRotTweenBuffers;
135
+ private initializeTransTweenBuffers;
136
+ private initializeMorphTweenBuffers;
137
+ private initializeRuntimeMorph;
68
138
  private updateRotationTweens;
139
+ private updateTranslationTweens;
140
+ private updateMorphWeightTweens;
69
141
  getVertices(): Float32Array<ArrayBuffer>;
70
142
  getTextures(): Texture[];
71
143
  getMaterials(): Material[];
@@ -75,11 +147,18 @@ export declare class Model {
75
147
  getSkinning(): Skinning;
76
148
  getRigidbodies(): Rigidbody[];
77
149
  getJoints(): Joint[];
150
+ getMorphing(): Morphing;
151
+ getMorphWeights(): Float32Array;
78
152
  getBoneNames(): string[];
79
153
  rotateBones(names: string[], quats: Quat[], durationMs?: number): void;
154
+ moveBones(names: string[], relativeTranslations: Vec3[], durationMs?: number): void;
80
155
  getBoneWorldMatrices(): Float32Array;
81
156
  getBoneInverseBindMatrices(): Float32Array;
82
- evaluatePose(): void;
157
+ getMorphNames(): string[];
158
+ setMorphWeight(name: string, weight: number, durationMs?: number): void;
159
+ private applyMorphs;
160
+ evaluatePose(): boolean;
161
+ private solveIKChains;
83
162
  private computeWorldMatrices;
84
163
  }
85
164
  //# sourceMappingURL=model.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../src/model.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"model.d.ts","sourceRoot":"","sources":["../src/model.ts"],"names":[],"mappings":"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"}