reze-engine 0.2.19 → 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":"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"}
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[];
@@ -65,6 +102,8 @@ export interface SkeletonRuntime {
65
102
  localTranslations: Float32Array;
66
103
  worldMatrices: Float32Array;
67
104
  computedBones: boolean[];
105
+ ikChainInfo?: IKChainInfo[];
106
+ ikSolvers?: IKSolver[];
68
107
  }
69
108
  export interface MorphRuntime {
70
109
  nameIndex: Record<string, number>;
@@ -87,13 +126,17 @@ export declare class Model {
87
126
  private cachedIdentityMat1;
88
127
  private cachedIdentityMat2;
89
128
  private rotTweenState;
129
+ private transTweenState;
90
130
  private morphTweenState;
91
131
  constructor(vertexData: Float32Array<ArrayBuffer>, indexData: Uint32Array<ArrayBuffer>, textures: Texture[], materials: Material[], skeleton: Skeleton, skinning: Skinning, morphing: Morphing, rigidbodies?: Rigidbody[], joints?: Joint[]);
92
132
  private initializeRuntimeSkeleton;
133
+ private initializeIKRuntime;
93
134
  private initializeRotTweenBuffers;
135
+ private initializeTransTweenBuffers;
94
136
  private initializeMorphTweenBuffers;
95
137
  private initializeRuntimeMorph;
96
138
  private updateRotationTweens;
139
+ private updateTranslationTweens;
97
140
  private updateMorphWeightTweens;
98
141
  getVertices(): Float32Array<ArrayBuffer>;
99
142
  getTextures(): Texture[];
@@ -108,12 +151,14 @@ export declare class Model {
108
151
  getMorphWeights(): Float32Array;
109
152
  getBoneNames(): string[];
110
153
  rotateBones(names: string[], quats: Quat[], durationMs?: number): void;
154
+ moveBones(names: string[], relativeTranslations: Vec3[], durationMs?: number): void;
111
155
  getBoneWorldMatrices(): Float32Array;
112
156
  getBoneInverseBindMatrices(): Float32Array;
113
157
  getMorphNames(): string[];
114
158
  setMorphWeight(name: string, weight: number, durationMs?: number): void;
115
159
  private applyMorphs;
116
160
  evaluatePose(): boolean;
161
+ private solveIKChains;
117
162
  private computeWorldMatrices;
118
163
  }
119
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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"}