reze-engine 0.3.0 → 0.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/engine.d.ts CHANGED
@@ -100,14 +100,9 @@ export declare class Engine {
100
100
  private stats;
101
101
  private animationFrameId;
102
102
  private renderLoopCallback;
103
- private animationFrames;
104
- private animationTimeouts;
103
+ private player;
105
104
  private hasAnimation;
106
- private playingAnimation;
107
105
  private animationStartTime;
108
- private animationDuration;
109
- private boneTracks;
110
- private morphTracks;
111
106
  constructor(canvas: HTMLCanvasElement, options?: EngineOptions);
112
107
  init(): Promise<void>;
113
108
  private createPipelines;
@@ -119,10 +114,16 @@ export declare class Engine {
119
114
  private setupCamera;
120
115
  private setupLighting;
121
116
  private setAmbientColor;
122
- loadAnimation(url: string): Promise<void>;
117
+ loadAnimation(url: string, audioUrl?: string): Promise<void>;
123
118
  playAnimation(): void;
124
119
  stopAnimation(): void;
125
- private animate;
120
+ pauseAnimation(): void;
121
+ seekAnimation(time: number): void;
122
+ getAnimationProgress(): import("./player").AnimationProgress;
123
+ /**
124
+ * Apply animation pose to model
125
+ */
126
+ private applyPose;
126
127
  getStats(): EngineStats;
127
128
  runRenderLoop(callback?: () => void): void;
128
129
  stopRenderLoop(): void;
@@ -1 +1 @@
1
- {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"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"}
package/dist/engine.js CHANGED
@@ -1,9 +1,8 @@
1
- import { bezierInterpolate } from "./bezier-interpolate";
2
1
  import { Camera } from "./camera";
3
2
  import { Quat, Vec3 } from "./math";
4
3
  import { PmxLoader } from "./pmx-loader";
5
4
  import { Physics } from "./physics";
6
- import { VMDLoader } from "./vmd-loader";
5
+ import { Player } from "./player";
7
6
  export class Engine {
8
7
  constructor(canvas, options) {
9
8
  this.cameraMatrixData = new Float32Array(36);
@@ -49,14 +48,9 @@ export class Engine {
49
48
  };
50
49
  this.animationFrameId = null;
51
50
  this.renderLoopCallback = null;
52
- this.animationFrames = [];
53
- this.animationTimeouts = [];
51
+ this.player = new Player();
54
52
  this.hasAnimation = false; // Set to true when loadAnimation is called
55
- this.playingAnimation = false; // Set to true when playAnimation is called
56
- this.animationStartTime = 0; // When animation started playing
57
- this.animationDuration = 0; // Total animation duration in seconds
58
- this.boneTracks = new Map();
59
- this.morphTracks = new Map();
53
+ this.animationStartTime = 0; // Track when animation first started (for A-pose prevention)
60
54
  this.canvas = canvas;
61
55
  if (options) {
62
56
  this.ambientColor = options.ambientColor ?? new Vec3(1.0, 1.0, 1.0);
@@ -1125,96 +1119,56 @@ export class Engine {
1125
1119
  this.lightData[2] = color.z;
1126
1120
  this.lightData[3] = 0.0; // Padding for vec3f alignment
1127
1121
  }
1128
- async loadAnimation(url) {
1129
- const frames = await VMDLoader.load(url);
1130
- this.animationFrames = frames;
1122
+ async loadAnimation(url, audioUrl) {
1123
+ await this.player.loadVmd(url, audioUrl);
1131
1124
  this.hasAnimation = true;
1132
- }
1133
- playAnimation() {
1134
- if (this.animationFrames.length === 0)
1135
- return;
1136
- this.stopAnimation();
1137
- this.playingAnimation = true;
1138
- // Process bone frames
1139
- const allBoneKeyFrames = [];
1140
- for (const keyFrame of this.animationFrames) {
1141
- for (const boneFrame of keyFrame.boneFrames) {
1142
- allBoneKeyFrames.push({
1143
- boneFrame,
1144
- time: keyFrame.time,
1145
- });
1146
- }
1147
- }
1148
- const boneKeyFramesByBone = new Map();
1149
- for (const { boneFrame, time } of allBoneKeyFrames) {
1150
- if (!boneKeyFramesByBone.has(boneFrame.boneName)) {
1151
- boneKeyFramesByBone.set(boneFrame.boneName, []);
1152
- }
1153
- boneKeyFramesByBone.get(boneFrame.boneName).push({ boneFrame, time });
1154
- }
1155
- for (const keyFrames of boneKeyFramesByBone.values()) {
1156
- keyFrames.sort((a, b) => a.time - b.time);
1157
- }
1158
- // Process morph frames
1159
- const allMorphKeyFrames = [];
1160
- for (const keyFrame of this.animationFrames) {
1161
- for (const morphFrame of keyFrame.morphFrames) {
1162
- allMorphKeyFrames.push({
1163
- morphFrame,
1164
- time: keyFrame.time,
1165
- });
1166
- }
1167
- }
1168
- const morphKeyFramesByMorph = new Map();
1169
- for (const { morphFrame, time } of allMorphKeyFrames) {
1170
- if (!morphKeyFramesByMorph.has(morphFrame.morphName)) {
1171
- morphKeyFramesByMorph.set(morphFrame.morphName, []);
1172
- }
1173
- morphKeyFramesByMorph.get(morphFrame.morphName).push({ morphFrame, time });
1174
- }
1175
- for (const keyFrames of morphKeyFramesByMorph.values()) {
1176
- keyFrames.sort((a, b) => a.time - b.time);
1177
- }
1178
- // Store tracks for frame-based animation
1179
- this.boneTracks = boneKeyFramesByBone;
1180
- this.morphTracks = morphKeyFramesByMorph;
1181
- // Calculate animation duration from max frame time (already in seconds)
1182
- let maxFrameTime = 0;
1183
- for (const keyFrames of this.boneTracks.values()) {
1184
- if (keyFrames.length > 0) {
1185
- const lastTime = keyFrames[keyFrames.length - 1].time;
1186
- if (lastTime > maxFrameTime) {
1187
- maxFrameTime = lastTime;
1188
- }
1189
- }
1190
- }
1191
- for (const keyFrames of this.morphTracks.values()) {
1192
- if (keyFrames.length > 0) {
1193
- const lastTime = keyFrames[keyFrames.length - 1].time;
1194
- if (lastTime > maxFrameTime) {
1195
- maxFrameTime = lastTime;
1196
- }
1197
- }
1198
- }
1199
- this.animationDuration = maxFrameTime > 0 ? maxFrameTime : 0;
1200
- this.animationStartTime = performance.now();
1201
- // Initialize bones and morphs to time 0 pose
1125
+ // Show first frame (time 0) immediately
1202
1126
  if (this.currentModel) {
1127
+ const initialPose = this.player.getPoseAtTime(0);
1128
+ this.applyPose(initialPose);
1129
+ // Reset bones without time 0 keyframes
1203
1130
  const skeleton = this.currentModel.getSkeleton();
1204
- const bonesWithTime0 = new Set();
1205
- // Apply time 0 bone keyframes
1206
- for (const [boneName, keyFrames] of this.boneTracks.entries()) {
1207
- if (keyFrames.length > 0 && keyFrames[0].time === 0) {
1208
- const boneFrame = keyFrames[0].boneFrame;
1209
- this.rotateBones([boneName], [boneFrame.rotation], 0);
1210
- this.moveBones([boneName], [boneFrame.translation], 0);
1211
- bonesWithTime0.add(boneName);
1131
+ const bonesWithPose = new Set(initialPose.boneRotations.keys());
1132
+ const bonesToReset = [];
1133
+ for (const bone of skeleton.bones) {
1134
+ if (!bonesWithPose.has(bone.name)) {
1135
+ bonesToReset.push(bone.name);
1212
1136
  }
1213
1137
  }
1138
+ if (bonesToReset.length > 0) {
1139
+ const identityQuat = new Quat(0, 0, 0, 1);
1140
+ const identityQuats = new Array(bonesToReset.length).fill(identityQuat);
1141
+ this.rotateBones(bonesToReset, identityQuats, 0);
1142
+ }
1143
+ // Update model pose and physics
1144
+ this.currentModel.evaluatePose();
1145
+ if (this.physics) {
1146
+ const worldMats = this.currentModel.getBoneWorldMatrices();
1147
+ this.physics.reset(worldMats, this.currentModel.getBoneInverseBindMatrices());
1148
+ // Upload matrices immediately
1149
+ this.device.queue.writeBuffer(this.worldMatrixBuffer, 0, worldMats.buffer, worldMats.byteOffset, worldMats.byteLength);
1150
+ const encoder = this.device.createCommandEncoder();
1151
+ this.computeSkinMatrices(encoder);
1152
+ this.device.queue.submit([encoder.finish()]);
1153
+ }
1154
+ }
1155
+ }
1156
+ playAnimation() {
1157
+ if (!this.hasAnimation || !this.currentModel)
1158
+ return;
1159
+ const wasPaused = this.player.isPausedState();
1160
+ const wasPlaying = this.player.isPlayingState();
1161
+ // Only reset pose and physics if starting from beginning (not resuming)
1162
+ if (!wasPlaying && !wasPaused) {
1163
+ // Get initial pose at time 0
1164
+ const initialPose = this.player.getPoseAtTime(0);
1165
+ this.applyPose(initialPose);
1214
1166
  // Reset bones without time 0 keyframes
1167
+ const skeleton = this.currentModel.getSkeleton();
1168
+ const bonesWithPose = new Set(initialPose.boneRotations.keys());
1215
1169
  const bonesToReset = [];
1216
1170
  for (const bone of skeleton.bones) {
1217
- if (!bonesWithTime0.has(bone.name)) {
1171
+ if (!bonesWithPose.has(bone.name)) {
1218
1172
  bonesToReset.push(bone.name);
1219
1173
  }
1220
1174
  }
@@ -1223,13 +1177,6 @@ export class Engine {
1223
1177
  const identityQuats = new Array(bonesToReset.length).fill(identityQuat);
1224
1178
  this.rotateBones(bonesToReset, identityQuats, 0);
1225
1179
  }
1226
- // Apply time 0 morph keyframes
1227
- for (const [morphName, keyFrames] of this.morphTracks.entries()) {
1228
- if (keyFrames.length > 0 && keyFrames[0].time === 0) {
1229
- const morphFrame = keyFrames[0].morphFrame;
1230
- this.setMorphWeight(morphName, morphFrame.weight, 0);
1231
- }
1232
- }
1233
1180
  // Reset physics immediately and upload matrices to prevent A-pose flash
1234
1181
  if (this.physics) {
1235
1182
  this.currentModel.evaluatePose();
@@ -1242,176 +1189,61 @@ export class Engine {
1242
1189
  this.device.queue.submit([encoder.finish()]);
1243
1190
  }
1244
1191
  }
1192
+ // Start playback (or resume if paused)
1193
+ this.player.play();
1194
+ if (this.animationStartTime === 0) {
1195
+ this.animationStartTime = performance.now();
1196
+ }
1245
1197
  }
1246
1198
  stopAnimation() {
1247
- for (const timeoutId of this.animationTimeouts) {
1248
- clearTimeout(timeoutId);
1199
+ this.player.stop();
1200
+ }
1201
+ pauseAnimation() {
1202
+ this.player.pause();
1203
+ }
1204
+ seekAnimation(time) {
1205
+ if (!this.currentModel || !this.hasAnimation)
1206
+ return;
1207
+ this.player.seek(time);
1208
+ // Immediately apply pose at seeked time
1209
+ const pose = this.player.getPoseAtTime(time);
1210
+ this.applyPose(pose);
1211
+ // Update model pose and physics
1212
+ this.currentModel.evaluatePose();
1213
+ if (this.physics) {
1214
+ const worldMats = this.currentModel.getBoneWorldMatrices();
1215
+ this.physics.reset(worldMats, this.currentModel.getBoneInverseBindMatrices());
1216
+ // Upload matrices immediately
1217
+ this.device.queue.writeBuffer(this.worldMatrixBuffer, 0, worldMats.buffer, worldMats.byteOffset, worldMats.byteLength);
1218
+ const encoder = this.device.createCommandEncoder();
1219
+ this.computeSkinMatrices(encoder);
1220
+ this.device.queue.submit([encoder.finish()]);
1249
1221
  }
1250
- this.animationTimeouts = [];
1251
- this.playingAnimation = false;
1252
- this.boneTracks.clear();
1253
- this.morphTracks.clear();
1254
1222
  }
1255
- // Frame-based animation update (called every frame)
1256
- // Similar to reference: MmdRuntimeModelAnimation.animate(frameTime)
1257
- // frameTime is in seconds (already converted from VMD frame numbers in loader)
1258
- animate(frameTime) {
1223
+ getAnimationProgress() {
1224
+ return this.player.getProgress();
1225
+ }
1226
+ /**
1227
+ * Apply animation pose to model
1228
+ */
1229
+ applyPose(pose) {
1259
1230
  if (!this.currentModel)
1260
1231
  return;
1261
- // Helper to find upper bound index (binary search)
1262
- const upperBoundFrameIndex = (time, keyFrames) => {
1263
- let left = 0;
1264
- let right = keyFrames.length;
1265
- while (left < right) {
1266
- const mid = Math.floor((left + right) / 2);
1267
- if (keyFrames[mid].time <= time) {
1268
- left = mid + 1;
1269
- }
1270
- else {
1271
- right = mid;
1272
- }
1273
- }
1274
- return left;
1275
- };
1276
- const boneNamesToRotate = [];
1277
- const rotationsToApply = [];
1278
- const boneNamesToMove = [];
1279
- const translationsToApply = [];
1280
- const morphNamesToSet = [];
1281
- const morphWeightsToSet = [];
1282
- // Process each bone track
1283
- for (const [boneName, keyFrames] of this.boneTracks.entries()) {
1284
- if (keyFrames.length === 0)
1285
- continue;
1286
- // Clamp frame time to track range (all times are in seconds)
1287
- const startTime = keyFrames[0].time;
1288
- const endTime = keyFrames[keyFrames.length - 1].time;
1289
- const clampedFrameTime = Math.max(startTime, Math.min(endTime, frameTime));
1290
- const upperBoundIndex = upperBoundFrameIndex(clampedFrameTime, keyFrames);
1291
- const upperBoundIndexMinusOne = upperBoundIndex - 1;
1292
- if (upperBoundIndexMinusOne < 0)
1293
- continue;
1294
- const timeB = keyFrames[upperBoundIndex]?.time;
1295
- const boneFrameA = keyFrames[upperBoundIndexMinusOne].boneFrame;
1296
- if (timeB === undefined) {
1297
- // Last keyframe or beyond - use the last keyframe value
1298
- boneNamesToRotate.push(boneName);
1299
- rotationsToApply.push(boneFrameA.rotation);
1300
- boneNamesToMove.push(boneName);
1301
- translationsToApply.push(boneFrameA.translation);
1302
- }
1303
- else {
1304
- // Interpolate between two keyframes
1305
- const timeA = keyFrames[upperBoundIndexMinusOne].time;
1306
- const boneFrameB = keyFrames[upperBoundIndex].boneFrame;
1307
- const gradient = (clampedFrameTime - timeA) / (timeB - timeA);
1308
- // Interpolate rotation using Bezier
1309
- const interp = boneFrameB.interpolation;
1310
- const rotWeight = bezierInterpolate(interp[0] / 127, // x1
1311
- interp[1] / 127, // x2
1312
- interp[2] / 127, // y1
1313
- interp[3] / 127, // y2
1314
- gradient);
1315
- const interpolatedRotation = Quat.slerp(boneFrameA.rotation, boneFrameB.rotation, rotWeight);
1316
- // Interpolate translation using Bezier (separate curves for X, Y, Z)
1317
- // VMD interpolation layout (from reference, 4x4 grid, row-major):
1318
- // Row 0: X_x1, Y_x1, phy1, phy2,
1319
- // Row 1: X_y1, Y_y1, Z_y1, R_y1,
1320
- // Row 2: X_x2, Y_x2, Z_x2, R_x2,
1321
- // Row 3: X_y2, Y_y2, Z_y2, R_y2,
1322
- // Row 4: Y_x1, Z_x1, R_x1, X_y1,
1323
- // Row 5: Y_y1, Z_y1, R_y1, X_x2,
1324
- // Row 6: Y_x2, Z_x2, R_x2, X_y2,
1325
- // Row 7: Y_y2, Z_y2, R_y2, 00,
1326
- // Row 8: Z_x1, R_x1, X_y1, Y_y1,
1327
- // Row 9: Z_y1, R_y1, X_x2, Y_x2,
1328
- // Row 10: Z_x2, R_x2, X_y2, Y_y2,
1329
- // Row 11: Z_y2, R_y2, 00, 00,
1330
- // Row 12: R_x1, X_y1, Y_y1, Z_y1,
1331
- // Row 13: R_y1, X_x2, Y_x2, Z_x2,
1332
- // Row 14: R_x2, X_y2, Y_y2, Z_y2,
1333
- // Row 15: R_y2, 00, 00, 00
1334
- // For rotation: R_x1=16, R_y1=20, R_x2=24, R_y2=28
1335
- // For position X: X_x1=0, X_y1=4, X_x2=8, X_y2=12
1336
- // For position Y: Y_x1=16, Y_y1=20, Y_x2=24, Y_y2=28
1337
- // For position Z: Z_x1=32, Z_y1=36, Z_x2=40, Z_y2=44
1338
- const xWeight = bezierInterpolate(interp[0] / 127, // X_x1
1339
- interp[8] / 127, // X_x2
1340
- interp[4] / 127, // X_y1
1341
- interp[12] / 127, // X_y2
1342
- gradient);
1343
- const yWeight = bezierInterpolate(interp[16] / 127, // Y_x1
1344
- interp[24] / 127, // Y_x2
1345
- interp[20] / 127, // Y_y1
1346
- interp[28] / 127, // Y_y2
1347
- gradient);
1348
- const zWeight = bezierInterpolate(interp[32] / 127, // Z_x1
1349
- interp[40] / 127, // Z_x2
1350
- interp[36] / 127, // Z_y1
1351
- interp[44] / 127, // Z_y2
1352
- gradient);
1353
- const interpolatedTranslation = new Vec3(boneFrameA.translation.x + (boneFrameB.translation.x - boneFrameA.translation.x) * xWeight, boneFrameA.translation.y + (boneFrameB.translation.y - boneFrameA.translation.y) * yWeight, boneFrameA.translation.z + (boneFrameB.translation.z - boneFrameA.translation.z) * zWeight);
1354
- boneNamesToRotate.push(boneName);
1355
- rotationsToApply.push(interpolatedRotation);
1356
- boneNamesToMove.push(boneName);
1357
- translationsToApply.push(interpolatedTranslation);
1358
- }
1232
+ // Apply bone rotations
1233
+ if (pose.boneRotations.size > 0) {
1234
+ const boneNames = Array.from(pose.boneRotations.keys());
1235
+ const rotations = Array.from(pose.boneRotations.values());
1236
+ this.rotateBones(boneNames, rotations, 0);
1359
1237
  }
1360
- // Helper to find upper bound index for morph frames
1361
- const upperBoundMorphIndex = (time, keyFrames) => {
1362
- let left = 0;
1363
- let right = keyFrames.length;
1364
- while (left < right) {
1365
- const mid = Math.floor((left + right) / 2);
1366
- if (keyFrames[mid].time <= time) {
1367
- left = mid + 1;
1368
- }
1369
- else {
1370
- right = mid;
1371
- }
1372
- }
1373
- return left;
1374
- };
1375
- // Process each morph track
1376
- for (const [morphName, keyFrames] of this.morphTracks.entries()) {
1377
- if (keyFrames.length === 0)
1378
- continue;
1379
- // Clamp frame time to track range
1380
- const startTime = keyFrames[0].time;
1381
- const endTime = keyFrames[keyFrames.length - 1].time;
1382
- const clampedFrameTime = Math.max(startTime, Math.min(endTime, frameTime));
1383
- const upperBoundIndex = upperBoundMorphIndex(clampedFrameTime, keyFrames);
1384
- const upperBoundIndexMinusOne = upperBoundIndex - 1;
1385
- if (upperBoundIndexMinusOne < 0)
1386
- continue;
1387
- const timeB = keyFrames[upperBoundIndex]?.time;
1388
- const morphFrameA = keyFrames[upperBoundIndexMinusOne].morphFrame;
1389
- if (timeB === undefined) {
1390
- // Last keyframe or beyond - use the last keyframe value
1391
- morphNamesToSet.push(morphName);
1392
- morphWeightsToSet.push(morphFrameA.weight);
1393
- }
1394
- else {
1395
- // Linear interpolation between two keyframes
1396
- const timeA = keyFrames[upperBoundIndexMinusOne].time;
1397
- const morphFrameB = keyFrames[upperBoundIndex].morphFrame;
1398
- const gradient = (clampedFrameTime - timeA) / (timeB - timeA);
1399
- const interpolatedWeight = morphFrameA.weight + (morphFrameB.weight - morphFrameA.weight) * gradient;
1400
- morphNamesToSet.push(morphName);
1401
- morphWeightsToSet.push(interpolatedWeight);
1402
- }
1403
- }
1404
- // Apply all rotations, translations, and morphs at once (no tweening - direct application)
1405
- if (boneNamesToRotate.length > 0) {
1406
- this.rotateBones(boneNamesToRotate, rotationsToApply, 0);
1238
+ // Apply bone translations
1239
+ if (pose.boneTranslations.size > 0) {
1240
+ const boneNames = Array.from(pose.boneTranslations.keys());
1241
+ const translations = Array.from(pose.boneTranslations.values());
1242
+ this.moveBones(boneNames, translations, 0);
1407
1243
  }
1408
- if (boneNamesToMove.length > 0) {
1409
- this.moveBones(boneNamesToMove, translationsToApply, 0);
1410
- }
1411
- if (morphNamesToSet.length > 0) {
1412
- for (let i = 0; i < morphNamesToSet.length; i++) {
1413
- this.setMorphWeight(morphNamesToSet[i], morphWeightsToSet[i], 0);
1414
- }
1244
+ // Apply morph weights
1245
+ for (const [morphName, weight] of pose.morphWeights.entries()) {
1246
+ this.setMorphWeight(morphName, weight, 0);
1415
1247
  }
1416
1248
  }
1417
1249
  getStats() {
@@ -1839,20 +1671,11 @@ export class Engine {
1839
1671
  this.updateCameraUniforms();
1840
1672
  this.updateRenderTarget();
1841
1673
  // Animate VMD animation if playing
1842
- if (this.playingAnimation && this.currentModel && this.animationDuration > 0) {
1843
- const elapsedSeconds = (currentTime - this.animationStartTime) / 1000;
1844
- if (elapsedSeconds >= this.animationDuration) {
1845
- // Animation has ended, stop it
1846
- this.stopAnimation();
1674
+ if (this.hasAnimation && this.currentModel) {
1675
+ const pose = this.player.update(currentTime);
1676
+ if (pose) {
1677
+ this.applyPose(pose);
1847
1678
  }
1848
- else {
1849
- const frameTime = elapsedSeconds;
1850
- this.animate(frameTime);
1851
- }
1852
- }
1853
- else if (this.playingAnimation && this.animationDuration <= 0) {
1854
- // Animation has no duration or invalid, stop it immediately
1855
- this.stopAnimation();
1856
1679
  }
1857
1680
  // Update model pose first (this may update morph weights via tweens)
1858
1681
  // We need to do this before creating the encoder to ensure vertex buffer is ready
@@ -1870,14 +1693,6 @@ export class Engine {
1870
1693
  // Use single encoder for both compute and render (reduces sync points)
1871
1694
  const encoder = this.device.createCommandEncoder();
1872
1695
  this.updateModelPose(deltaTime, encoder);
1873
- // Hide model if animation is loaded but hasn't started playing yet (prevents A-pose flash)
1874
- // Once animation has played (even if it stopped), continue rendering normally
1875
- // Still update physics and poses, just don't render visually before first play
1876
- if (this.hasAnimation && !this.playingAnimation && this.animationStartTime === 0) {
1877
- // Submit encoder to ensure matrices are uploaded and physics initializes
1878
- this.device.queue.submit([encoder.finish()]);
1879
- return;
1880
- }
1881
1696
  const pass = encoder.beginRenderPass(this.renderPassDescriptor);
1882
1697
  if (this.currentModel) {
1883
1698
  pass.setVertexBuffer(0, this.vertexBuffer);
@@ -0,0 +1,100 @@
1
+ import { Quat, Vec3 } from "./math";
2
+ export interface AnimationPose {
3
+ boneRotations: Map<string, Quat>;
4
+ boneTranslations: Map<string, Vec3>;
5
+ morphWeights: Map<string, number>;
6
+ }
7
+ export interface AnimationProgress {
8
+ current: number;
9
+ duration: number;
10
+ percentage: number;
11
+ }
12
+ export declare class Player {
13
+ private frames;
14
+ private boneTracks;
15
+ private morphTracks;
16
+ private duration;
17
+ private isPlaying;
18
+ private isPaused;
19
+ private currentTime;
20
+ private startTime;
21
+ private pausedTime;
22
+ private pauseStartTime;
23
+ private audioElement?;
24
+ private audioUrl?;
25
+ private audioLoaded;
26
+ /**
27
+ * Load VMD animation file and optionally audio
28
+ */
29
+ loadVmd(vmdUrl: string, audioUrl?: string): Promise<void>;
30
+ /**
31
+ * Load audio file
32
+ */
33
+ loadAudio(url: string): Promise<void>;
34
+ /**
35
+ * Process frames into tracks
36
+ */
37
+ private processFrames;
38
+ /**
39
+ * Start or resume playback
40
+ */
41
+ play(): void;
42
+ /**
43
+ * Pause playback
44
+ */
45
+ pause(): void;
46
+ /**
47
+ * Stop playback and reset to beginning
48
+ */
49
+ stop(): void;
50
+ /**
51
+ * Seek to specific time
52
+ */
53
+ seek(time: number): void;
54
+ /**
55
+ * Update playback and return current pose
56
+ * Returns null if not playing, but returns current pose if paused
57
+ */
58
+ update(currentRealTime: number): AnimationPose | null;
59
+ /**
60
+ * Get pose at specific time (pure function)
61
+ */
62
+ getPoseAtTime(time: number): AnimationPose;
63
+ /**
64
+ * Get current playback progress
65
+ */
66
+ getProgress(): AnimationProgress;
67
+ /**
68
+ * Get current time
69
+ */
70
+ getCurrentTime(): number;
71
+ /**
72
+ * Get animation duration
73
+ */
74
+ getDuration(): number;
75
+ /**
76
+ * Check if playing
77
+ */
78
+ isPlayingState(): boolean;
79
+ /**
80
+ * Check if paused
81
+ */
82
+ isPausedState(): boolean;
83
+ /**
84
+ * Check if has audio
85
+ */
86
+ hasAudio(): boolean;
87
+ /**
88
+ * Set audio volume (0.0 to 1.0)
89
+ */
90
+ setVolume(volume: number): void;
91
+ /**
92
+ * Mute audio
93
+ */
94
+ mute(): void;
95
+ /**
96
+ * Unmute audio
97
+ */
98
+ unmute(): void;
99
+ }
100
+ //# sourceMappingURL=player.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"player.d.ts","sourceRoot":"","sources":["../src/player.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,QAAQ,CAAA;AAGnC,MAAM,WAAW,aAAa;IAC5B,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;IAChC,gBAAgB,EAAE,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;IACnC,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAClC;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,MAAM,CAAA;IACf,QAAQ,EAAE,MAAM,CAAA;IAChB,UAAU,EAAE,MAAM,CAAA;CACnB;AAED,qBAAa,MAAM;IAEjB,OAAO,CAAC,MAAM,CAAoB;IAClC,OAAO,CAAC,UAAU,CAAwE;IAC1F,OAAO,CAAC,WAAW,CAA0E;IAC7F,OAAO,CAAC,QAAQ,CAAY;IAG5B,OAAO,CAAC,SAAS,CAAiB;IAClC,OAAO,CAAC,QAAQ,CAAiB;IACjC,OAAO,CAAC,WAAW,CAAY;IAG/B,OAAO,CAAC,SAAS,CAAY;IAC7B,OAAO,CAAC,UAAU,CAAY;IAC9B,OAAO,CAAC,cAAc,CAAY;IAGlC,OAAO,CAAC,YAAY,CAAC,CAAkB;IACvC,OAAO,CAAC,QAAQ,CAAC,CAAQ;IACzB,OAAO,CAAC,WAAW,CAAiB;IAEpC;;OAEG;IACG,OAAO,CAAC,MAAM,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAW/D;;OAEG;IACG,SAAS,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAyB3C;;OAEG;IACH,OAAO,CAAC,aAAa;IAwErB;;OAEG;IACH,IAAI,IAAI,IAAI;IAyBZ;;OAEG;IACH,KAAK,IAAI,IAAI;IAYb;;OAEG;IACH,IAAI,IAAI,IAAI;IAcZ;;OAEG;IACH,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IAgBxB;;;OAGG;IACH,MAAM,CAAC,eAAe,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI;IAiCrD;;OAEG;IACH,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa;IA+I1C;;OAEG;IACH,WAAW,IAAI,iBAAiB;IAQhC;;OAEG;IACH,cAAc,IAAI,MAAM;IAIxB;;OAEG;IACH,WAAW,IAAI,MAAM;IAIrB;;OAEG;IACH,cAAc,IAAI,OAAO;IAIzB;;OAEG;IACH,aAAa,IAAI,OAAO;IAIxB;;OAEG;IACH,QAAQ,IAAI,OAAO;IAInB;;OAEG;IACH,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,IAAI;IAM/B;;OAEG;IACH,IAAI,IAAI,IAAI;IAMZ;;OAEG;IACH,MAAM,IAAI,IAAI;CAKf"}