reze-engine 0.1.3 → 0.1.5

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/model.d.ts CHANGED
@@ -1,3 +1,5 @@
1
+ import { Quat } from "./math";
2
+ import { Rigidbody, Joint } from "./physics";
1
3
  export interface Texture {
2
4
  path: string;
3
5
  name: string;
@@ -43,8 +45,6 @@ export interface SkeletonRuntime {
43
45
  worldMatrices: Float32Array;
44
46
  computedBones: boolean[];
45
47
  }
46
- import { Mat4, Vec3, Quat } from "./math";
47
- import { Rigidbody, Joint } from "./physics";
48
48
  export declare class Model {
49
49
  private vertexData;
50
50
  private vertexCount;
@@ -58,44 +58,24 @@ export declare class Model {
58
58
  private runtimeSkeleton;
59
59
  private cachedIdentityMat1;
60
60
  private cachedIdentityMat2;
61
- constructor(vertexData: Float32Array<ArrayBuffer>, indexData: Uint32Array<ArrayBuffer>, textures: Texture[], materials: Material[], skeleton: Skeleton, skinning: Skinning, rigidbodies?: Rigidbody[], joints?: Joint[]);
62
- private buildBoneLookups;
63
61
  private rotTweenState;
62
+ constructor(vertexData: Float32Array<ArrayBuffer>, indexData: Uint32Array<ArrayBuffer>, textures: Texture[], materials: Material[], skeleton: Skeleton, skinning: Skinning, rigidbodies?: Rigidbody[], joints?: Joint[]);
63
+ private initializeRuntimeSkeleton;
64
64
  private initializeRotTweenBuffers;
65
- private static easeInOut;
66
- private static slerp;
67
65
  private updateRotationTweens;
68
66
  getVertices(): Float32Array<ArrayBuffer>;
69
67
  getTextures(): Texture[];
70
68
  getMaterials(): Material[];
71
- getDiffuseTexturePath(materialIndex: number): string | null;
72
69
  getVertexCount(): number;
73
70
  getIndices(): Uint32Array<ArrayBuffer>;
74
71
  getSkeleton(): Skeleton;
75
72
  getSkinning(): Skinning;
76
73
  getRigidbodies(): Rigidbody[];
77
74
  getJoints(): Joint[];
78
- private initializeRuntimePose;
79
- getBoneCount(): number;
80
75
  getBoneNames(): string[];
81
- getBoneIndexByName(name: string): number;
82
- getBoneName(index: number): string | undefined;
83
- getBoneLocal(index: number): {
84
- rotation: Quat;
85
- translation: Vec3;
86
- } | undefined;
87
- rotateBones(indicesOrNames: Array<number | string>, quats: Quat[], durationMs?: number): void;
88
- setBoneRotation(indexOrName: number | string, quat: Quat): void;
89
- setBoneTranslation(indexOrName: number | string, t: Vec3): void;
90
- resetBone(index: number): void;
91
- resetAllBones(): void;
92
- getBoneWorldMatrix(index: number): Float32Array | undefined;
76
+ rotateBones(names: string[], quats: Quat[], durationMs?: number): void;
93
77
  getBoneWorldMatrices(): Float32Array;
94
78
  getBoneInverseBindMatrices(): Float32Array;
95
- getBoneWorldPosition(index: number): Vec3;
96
- getBoneWorldRotation(index: number): Quat;
97
- getBoneInverseBindMatrix(index: number): Mat4 | undefined;
98
- getLocalRotations(): Float32Array;
99
79
  evaluatePose(): void;
100
80
  private computeWorldMatrices;
101
81
  }
@@ -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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"}
package/dist/model.js CHANGED
@@ -1,5 +1,5 @@
1
+ import { Mat4, Quat, easeInOut } from "./math";
1
2
  const VERTEX_STRIDE = 8;
2
- import { Mat4, Vec3, Quat } from "./math";
3
3
  export class Model {
4
4
  constructor(vertexData, indexData, textures, materials, skeleton, skinning, rigidbodies = [], joints = []) {
5
5
  this.textures = [];
@@ -19,39 +19,34 @@ export class Model {
19
19
  this.skinning = skinning;
20
20
  this.rigidbodies = rigidbodies;
21
21
  this.joints = joints;
22
- // Initialize runtime skeleton pose state
23
- const boneCount = skeleton.bones.length;
22
+ if (this.skeleton.bones.length == 0) {
23
+ throw new Error("Model has no bones");
24
+ }
25
+ this.initializeRuntimeSkeleton();
26
+ this.initializeRotTweenBuffers();
27
+ }
28
+ initializeRuntimeSkeleton() {
29
+ const boneCount = this.skeleton.bones.length;
24
30
  this.runtimeSkeleton = {
25
31
  localRotations: new Float32Array(boneCount * 4),
26
32
  localTranslations: new Float32Array(boneCount * 3),
27
33
  worldMatrices: new Float32Array(boneCount * 16),
28
- nameIndex: {}, // Will be populated by buildBoneLookups()
34
+ nameIndex: this.skeleton.bones.reduce((acc, bone, index) => {
35
+ acc[bone.name] = index;
36
+ return acc;
37
+ }, {}),
29
38
  computedBones: new Array(boneCount).fill(false),
30
39
  };
31
- if (this.skeleton.bones.length > 0) {
32
- this.buildBoneLookups();
33
- this.initializeRuntimePose();
34
- this.initializeRotTweenBuffers();
35
- }
36
- }
37
- // Build caches for O(1) bone lookups and populate children arrays
38
- // Called during model initialization
39
- buildBoneLookups() {
40
- const nameToIndex = {};
41
- // Initialize children arrays for all bones and build name index
42
- for (let i = 0; i < this.skeleton.bones.length; i++) {
43
- this.skeleton.bones[i].children = [];
44
- nameToIndex[this.skeleton.bones[i].name] = i;
45
- }
46
- // Build parent->children relationships
40
+ const rotations = this.runtimeSkeleton.localRotations;
47
41
  for (let i = 0; i < this.skeleton.bones.length; i++) {
48
- const bone = this.skeleton.bones[i];
49
- const parentIdx = bone.parentIndex;
50
- if (parentIdx >= 0 && parentIdx < this.skeleton.bones.length) {
51
- this.skeleton.bones[parentIdx].children.push(i);
42
+ const qi = i * 4;
43
+ if (rotations[qi + 3] === 0) {
44
+ rotations[qi] = 0;
45
+ rotations[qi + 1] = 0;
46
+ rotations[qi + 2] = 0;
47
+ rotations[qi + 3] = 1;
52
48
  }
53
49
  }
54
- this.runtimeSkeleton.nameIndex = nameToIndex;
55
50
  }
56
51
  initializeRotTweenBuffers() {
57
52
  const n = this.skeleton.bones.length;
@@ -63,51 +58,26 @@ export class Model {
63
58
  durationMs: new Float32Array(n),
64
59
  };
65
60
  }
66
- static easeInOut(t) {
67
- return t < 0.5 ? 2 * t * t : 1 - Math.pow(-2 * t + 2, 2) / 2;
68
- }
69
- static slerp(aX, aY, aZ, aW, bX, bY, bZ, bW, t) {
70
- let cos = aX * bX + aY * bY + aZ * bZ + aW * bW;
71
- let bx = bX, by = bY, bz = bZ, bw = bW;
72
- if (cos < 0) {
73
- cos = -cos;
74
- bx = -bx;
75
- by = -by;
76
- bz = -bz;
77
- bw = -bw;
78
- }
79
- if (cos > 0.9995) {
80
- const x = aX + t * (bx - aX);
81
- const y = aY + t * (by - aY);
82
- const z = aZ + t * (bz - aZ);
83
- const w = aW + t * (bw - aW);
84
- const invLen = 1 / Math.hypot(x, y, z, w);
85
- return [x * invLen, y * invLen, z * invLen, w * invLen];
86
- }
87
- const theta0 = Math.acos(cos);
88
- const sinTheta0 = Math.sin(theta0);
89
- const theta = theta0 * t;
90
- const s0 = Math.sin(theta0 - theta) / sinTheta0;
91
- const s1 = Math.sin(theta) / sinTheta0;
92
- return [s0 * aX + s1 * bx, s0 * aY + s1 * by, s0 * aZ + s1 * bz, s0 * aW + s1 * bw];
93
- }
94
61
  updateRotationTweens() {
95
62
  const state = this.rotTweenState;
96
63
  const now = performance.now();
97
64
  const rotations = this.runtimeSkeleton.localRotations;
98
- for (let i = 0; i < this.skeleton.bones.length; i++) {
65
+ const boneCount = this.skeleton.bones.length;
66
+ for (let i = 0; i < boneCount; i++) {
99
67
  if (state.active[i] !== 1)
100
68
  continue;
101
69
  const startMs = state.startTimeMs[i];
102
70
  const durMs = Math.max(1, state.durationMs[i]);
103
71
  const t = Math.max(0, Math.min(1, (now - startMs) / durMs));
104
- const e = Model.easeInOut(t);
72
+ const e = easeInOut(t);
105
73
  const qi = i * 4;
106
- const [x, y, z, w] = Model.slerp(state.startQuat[qi], state.startQuat[qi + 1], state.startQuat[qi + 2], state.startQuat[qi + 3], state.targetQuat[qi], state.targetQuat[qi + 1], state.targetQuat[qi + 2], state.targetQuat[qi + 3], e);
107
- rotations[qi] = x;
108
- rotations[qi + 1] = y;
109
- rotations[qi + 2] = z;
110
- rotations[qi + 3] = w;
74
+ const startQuat = new Quat(state.startQuat[qi], state.startQuat[qi + 1], state.startQuat[qi + 2], state.startQuat[qi + 3]);
75
+ const targetQuat = new Quat(state.targetQuat[qi], state.targetQuat[qi + 1], state.targetQuat[qi + 2], state.targetQuat[qi + 3]);
76
+ const result = Quat.slerp(startQuat, targetQuat, e);
77
+ rotations[qi] = result.x;
78
+ rotations[qi + 1] = result.y;
79
+ rotations[qi + 2] = result.z;
80
+ rotations[qi + 3] = result.w;
111
81
  if (t >= 1)
112
82
  state.active[i] = 0;
113
83
  }
@@ -125,15 +95,6 @@ export class Model {
125
95
  getMaterials() {
126
96
  return this.materials;
127
97
  }
128
- // Get diffuse texture path for a material
129
- getDiffuseTexturePath(materialIndex) {
130
- if (materialIndex < 0 || materialIndex >= this.materials.length)
131
- return null;
132
- const material = this.materials[materialIndex];
133
- if (material.diffuseTextureIndex < 0 || material.diffuseTextureIndex >= this.textures.length)
134
- return null;
135
- return this.textures[material.diffuseTextureIndex].path;
136
- }
137
98
  // Get vertex count
138
99
  getVertexCount() {
139
100
  return this.vertexCount;
@@ -156,62 +117,18 @@ export class Model {
156
117
  getJoints() {
157
118
  return this.joints;
158
119
  }
159
- initializeRuntimePose() {
160
- const rotations = this.runtimeSkeleton.localRotations;
161
- for (let i = 0; i < this.skeleton.bones.length; i++) {
162
- const qi = i * 4;
163
- if (rotations[qi + 3] === 0) {
164
- rotations[qi] = 0;
165
- rotations[qi + 1] = 0;
166
- rotations[qi + 2] = 0;
167
- rotations[qi + 3] = 1;
168
- }
169
- }
170
- }
171
120
  // ------- Bone helpers (public API) -------
172
- getBoneCount() {
173
- return this.skeleton.bones.length;
174
- }
175
121
  getBoneNames() {
176
122
  return this.skeleton.bones.map((b) => b.name);
177
123
  }
178
- getBoneIndexByName(name) {
179
- return this.runtimeSkeleton.nameIndex[name] ?? -1;
180
- }
181
- getBoneName(index) {
182
- if (index < 0 || index >= this.skeleton.bones.length)
183
- return undefined;
184
- return this.skeleton.bones[index].name;
185
- }
186
- getBoneLocal(index) {
187
- if (index < 0 || index >= this.skeleton.bones.length)
188
- return undefined;
189
- const qi = index * 4;
190
- const ti = index * 3;
191
- const rot = this.runtimeSkeleton.localRotations;
192
- const trans = this.runtimeSkeleton.localTranslations;
193
- return {
194
- rotation: new Quat(rot[qi], rot[qi + 1], rot[qi + 2], rot[qi + 3]),
195
- translation: new Vec3(trans[ti], trans[ti + 1], trans[ti + 2]),
196
- };
197
- }
198
- rotateBones(indicesOrNames, quats, durationMs) {
124
+ rotateBones(names, quats, durationMs) {
199
125
  const state = this.rotTweenState;
200
126
  const normalized = quats.map((q) => q.normalize());
201
127
  const now = performance.now();
202
128
  const dur = durationMs && durationMs > 0 ? durationMs : 0;
203
- for (let i = 0; i < indicesOrNames.length; i++) {
204
- const input = indicesOrNames[i];
205
- let idx;
206
- if (typeof input === "number") {
207
- idx = input;
208
- }
209
- else {
210
- const resolved = this.getBoneIndexByName(input);
211
- if (resolved < 0)
212
- continue;
213
- idx = resolved;
214
- }
129
+ for (let i = 0; i < names.length; i++) {
130
+ const name = names[i];
131
+ const idx = this.runtimeSkeleton.nameIndex[name] ?? -1;
215
132
  if (idx < 0 || idx >= this.skeleton.bones.length)
216
133
  continue;
217
134
  const qi = idx * 4;
@@ -233,8 +150,14 @@ export class Model {
233
150
  const startMs = state.startTimeMs[idx];
234
151
  const prevDur = Math.max(1, state.durationMs[idx]);
235
152
  const t = Math.max(0, Math.min(1, (now - startMs) / prevDur));
236
- const e = Model.easeInOut(t);
237
- const [cx, cy, cz, cw] = Model.slerp(state.startQuat[qi], state.startQuat[qi + 1], state.startQuat[qi + 2], state.startQuat[qi + 3], state.targetQuat[qi], state.targetQuat[qi + 1], state.targetQuat[qi + 2], state.targetQuat[qi + 3], e);
153
+ const e = easeInOut(t);
154
+ const startQuat = new Quat(state.startQuat[qi], state.startQuat[qi + 1], state.startQuat[qi + 2], state.startQuat[qi + 3]);
155
+ const targetQuat = new Quat(state.targetQuat[qi], state.targetQuat[qi + 1], state.targetQuat[qi + 2], state.targetQuat[qi + 3]);
156
+ const result = Quat.slerp(startQuat, targetQuat, e);
157
+ const cx = result.x;
158
+ const cy = result.y;
159
+ const cz = result.z;
160
+ const cw = result.w;
238
161
  sx = cx;
239
162
  sy = cy;
240
163
  sz = cz;
@@ -253,87 +176,12 @@ export class Model {
253
176
  state.active[idx] = 1;
254
177
  }
255
178
  }
256
- setBoneRotation(indexOrName, quat) {
257
- const index = typeof indexOrName === "number" ? indexOrName : this.getBoneIndexByName(indexOrName);
258
- if (index < 0 || index >= this.skeleton.bones.length)
259
- return;
260
- const qi = index * 4;
261
- const rot = this.runtimeSkeleton.localRotations;
262
- rot[qi] = quat.x;
263
- rot[qi + 1] = quat.y;
264
- rot[qi + 2] = quat.z;
265
- rot[qi + 3] = quat.w;
266
- }
267
- setBoneTranslation(indexOrName, t) {
268
- const index = typeof indexOrName === "number" ? indexOrName : this.getBoneIndexByName(indexOrName);
269
- if (index < 0 || index >= this.skeleton.bones.length)
270
- return;
271
- const ti = index * 3;
272
- const trans = this.runtimeSkeleton.localTranslations;
273
- trans[ti] = t.x;
274
- trans[ti + 1] = t.y;
275
- trans[ti + 2] = t.z;
276
- }
277
- resetBone(index) {
278
- const qi = index * 4;
279
- const ti = index * 3;
280
- const rot = this.runtimeSkeleton.localRotations;
281
- const trans = this.runtimeSkeleton.localTranslations;
282
- rot[qi] = 0;
283
- rot[qi + 1] = 0;
284
- rot[qi + 2] = 0;
285
- rot[qi + 3] = 1;
286
- trans[ti] = 0;
287
- trans[ti + 1] = 0;
288
- trans[ti + 2] = 0;
289
- }
290
- resetAllBones() {
291
- const rot = this.runtimeSkeleton.localRotations;
292
- const trans = this.runtimeSkeleton.localTranslations;
293
- const count = this.getBoneCount();
294
- for (let i = 0; i < count; i++) {
295
- const qi = i * 4;
296
- const ti = i * 3;
297
- rot[qi] = 0;
298
- rot[qi + 1] = 0;
299
- rot[qi + 2] = 0;
300
- rot[qi + 3] = 1;
301
- trans[ti] = 0;
302
- trans[ti + 1] = 0;
303
- trans[ti + 2] = 0;
304
- }
305
- }
306
- getBoneWorldMatrix(index) {
307
- this.evaluatePose();
308
- const start = index * 16;
309
- return this.runtimeSkeleton.worldMatrices.subarray(start, start + 16);
310
- }
311
179
  getBoneWorldMatrices() {
312
180
  return this.runtimeSkeleton.worldMatrices;
313
181
  }
314
182
  getBoneInverseBindMatrices() {
315
183
  return this.skeleton.inverseBindMatrices;
316
184
  }
317
- getBoneWorldPosition(index) {
318
- this.evaluatePose();
319
- const matIdx = index * 16;
320
- const mat = this.runtimeSkeleton.worldMatrices;
321
- return new Vec3(mat[matIdx + 12], mat[matIdx + 13], mat[matIdx + 14]);
322
- }
323
- getBoneWorldRotation(index) {
324
- this.evaluatePose();
325
- const start = index * 16;
326
- return Mat4.toQuatFromArray(this.runtimeSkeleton.worldMatrices, start);
327
- }
328
- getBoneInverseBindMatrix(index) {
329
- if (index < 0 || index >= this.skeleton.bones.length)
330
- return undefined;
331
- const start = index * 16;
332
- return new Mat4(this.skeleton.inverseBindMatrices.subarray(start, start + 16));
333
- }
334
- getLocalRotations() {
335
- return this.runtimeSkeleton.localRotations;
336
- }
337
185
  evaluatePose() {
338
186
  this.updateRotationTweens();
339
187
  this.computeWorldMatrices();
@@ -377,7 +225,13 @@ export class Model {
377
225
  ay = -ay;
378
226
  az = -az;
379
227
  }
380
- const [rx, ry, rz, rw] = Model.slerp(0, 0, 0, 1, ax, ay, az, aw, absRatio);
228
+ const identityQuat = new Quat(0, 0, 0, 1);
229
+ const appendQuat = new Quat(ax, ay, az, aw);
230
+ const result = Quat.slerp(identityQuat, appendQuat, absRatio);
231
+ const rx = result.x;
232
+ const ry = result.y;
233
+ const rz = result.z;
234
+ const rw = result.w;
381
235
  rotateM = Mat4.fromQuat(rx, ry, rz, rw).multiply(rotateM);
382
236
  }
383
237
  if (b.appendMove) {
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "reze-engine",
3
- "version": "0.1.3",
4
- "description": "A WebGPU-based 3D engine with MMD model support and physics",
3
+ "version": "0.1.5",
4
+ "description": "A WebGPU-based MMD model renderer",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
7
7
  "type": "module",