reze-engine 0.6.5 → 0.6.7

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/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
- for (let i = chains.length - 1; i >= 0; i--) {
130
- this.updateWorldMatrix(chains[i].boneIndex, bones, localRotations, localTranslations, worldMatrices, undefined)
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 IK-modified rotations)
258
- for (let i = chainIndex; i >= 0; i--) {
259
- const link = solver.links[i]
260
- this.updateWorldMatrix(link.boneIndex, bones, localRotations, localTranslations, worldMatrices, ikChainInfo)
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
@@ -581,8 +581,12 @@ export class Model {
581
581
  /**
582
582
  * Convert VMD-style relative translation (relative to bind pose world position) to local translation
583
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.
584
588
  */
585
- private convertVMDTranslationToLocal(boneIdx: number, vmdRelativeTranslation: Vec3): Vec3 {
589
+ private convertVMDTranslationToLocal(boneIdx: number, vmdRelativeTranslation: Vec3, rotation?: Quat): Vec3 {
586
590
  const skeleton = this.skeleton
587
591
  const bones = skeleton.bones
588
592
  const localRot = this.runtimeSkeleton.localRotations
@@ -625,7 +629,9 @@ export class Model {
625
629
  )
626
630
 
627
631
  // Apply inverse rotation to get local translation
628
- const localRotation = localRot[boneIdx]
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]
629
635
  // Clone to avoid mutating, then conjugate and normalize
630
636
  const invRotation = localRotation.clone().conjugate().normalize()
631
637
  const rotationMat = Mat4.fromQuat(invRotation.x, invRotation.y, invRotation.z, invRotation.w)
@@ -717,6 +723,57 @@ export class Model {
717
723
  this.applyMorphs()
718
724
  }
719
725
 
726
+ /**
727
+ * Atomic pose setter for external animation editors.
728
+ * Sets bone rotations, translations, and morph weights in a single pass,
729
+ * identical to how getPoseAtTime applies VMD poses during playback.
730
+ * Cancels any active tweens on affected bones/morphs.
731
+ */
732
+ setPose(
733
+ rotations?: Record<string, Quat>,
734
+ translations?: Record<string, Vec3>,
735
+ morphs?: Record<string, number>
736
+ ): void {
737
+ const state = this.tweenState
738
+
739
+ if (rotations) {
740
+ for (const [name, quat] of Object.entries(rotations)) {
741
+ const idx = this.runtimeSkeleton.nameIndex[name] ?? -1
742
+ if (idx < 0 || idx >= this.skeleton.bones.length) continue
743
+
744
+ this.runtimeSkeleton.localRotations[idx].set(quat.clone().normalize())
745
+ state.rotActive[idx] = 0
746
+ }
747
+ }
748
+
749
+ if (translations) {
750
+ for (const [name, vec] of Object.entries(translations)) {
751
+ const idx = this.runtimeSkeleton.nameIndex[name] ?? -1
752
+ if (idx < 0 || idx >= this.skeleton.bones.length) continue
753
+
754
+ const rotation = rotations?.[name]?.clone().normalize()
755
+ const localTranslation = this.convertVMDTranslationToLocal(idx, vec, rotation)
756
+ this.runtimeSkeleton.localTranslations[idx].set(localTranslation)
757
+ state.transActive[idx] = 0
758
+ }
759
+ }
760
+
761
+ if (morphs) {
762
+ let morphChanged = false
763
+ for (const [name, weight] of Object.entries(morphs)) {
764
+ const idx = this.runtimeMorph.nameIndex[name] ?? -1
765
+ if (idx < 0 || idx >= this.runtimeMorph.weights.length) continue
766
+
767
+ this.runtimeMorph.weights[idx] = Math.max(0, Math.min(1, weight))
768
+ state.morphActive[idx] = 0
769
+ morphChanged = true
770
+ }
771
+ if (morphChanged) {
772
+ this.applyMorphs()
773
+ }
774
+ }
775
+ }
776
+
720
777
  private applyMorphs(): void {
721
778
  // Reset vertex data to base positions
722
779
  this.vertexData.set(this.baseVertexData)
@@ -1016,9 +1073,12 @@ export class Model {
1016
1073
 
1017
1074
  if (!frameB) {
1018
1075
  // No interpolation needed - direct assignment
1019
- localRot.set(frameA.rotation)
1020
- // Convert VMD relative translation to local translation
1021
- const localTranslation = this.convertVMDTranslationToLocal(boneIdx, frameA.translation)
1076
+ // Use animation frame's rotation for translation conversion to ensure consistency
1077
+ // This prevents conflicts when IK later modifies the rotation
1078
+ const frameRotation = frameA.rotation
1079
+ localRot.set(frameRotation)
1080
+ // Convert VMD relative translation to local translation using animation rotation
1081
+ const localTranslation = this.convertVMDTranslationToLocal(boneIdx, frameA.translation, frameRotation)
1022
1082
  localTrans.set(localTranslation)
1023
1083
  } else {
1024
1084
  const timeA = keyFrames[idx].time
@@ -1061,8 +1121,10 @@ export class Model {
1061
1121
  frameA.translation.z + (frameB.translation.z - frameA.translation.z) * tzWeight
1062
1122
  )
1063
1123
 
1064
- // Convert interpolated VMD translation to local translation
1065
- const localTranslation = this.convertVMDTranslationToLocal(boneIdx, interpolatedVMDTranslation)
1124
+ // Convert interpolated VMD translation to local translation using animation rotation
1125
+ // This ensures translation is computed for the animation rotation, not the runtime rotation
1126
+ // that will be modified by IK, preventing conflicts
1127
+ const localTranslation = this.convertVMDTranslationToLocal(boneIdx, interpolatedVMDTranslation, rotation)
1066
1128
 
1067
1129
  // Direct property writes to avoid object allocation
1068
1130
  localRot.set(rotation)
@@ -1161,14 +1223,136 @@ export class Model {
1161
1223
  const ikChainInfo = this.runtimeSkeleton.ikChainInfo
1162
1224
  if (!ikChainInfo) return
1163
1225
 
1164
- IKSolverSystem.solve(
1165
- ikSolvers,
1166
- this.skeleton.bones,
1167
- this.runtimeSkeleton.localRotations,
1168
- this.runtimeSkeleton.localTranslations,
1169
- this.runtimeSkeleton.worldMatrices,
1170
- ikChainInfo
1171
- )
1226
+ // Solve each IK solver sequentially, ensuring consistent state between solvers
1227
+ for (const solver of ikSolvers) {
1228
+ // Recompute ALL world matrices before each solver starts
1229
+ // This ensures each solver sees the effects of previous solvers on localRotations
1230
+ this.computeWorldMatrices()
1231
+
1232
+ // Clear computed set for this solver's pass
1233
+ this.ikComputedSet.clear()
1234
+
1235
+ // Solve this IK chain
1236
+ // Pass callback that uses model's world matrix computation (handles append correctly)
1237
+ IKSolverSystem.solve(
1238
+ [solver], // Solve one at a time
1239
+ this.skeleton.bones,
1240
+ this.runtimeSkeleton.localRotations,
1241
+ this.runtimeSkeleton.localTranslations,
1242
+ this.runtimeSkeleton.worldMatrices,
1243
+ ikChainInfo,
1244
+ (boneIndex, applyIK) => {
1245
+ // Clear computed set for each bone update to allow recomputation in same iteration
1246
+ this.ikComputedSet.delete(boneIndex)
1247
+ this.computeSingleBoneWorldMatrix(boneIndex, applyIK)
1248
+ }
1249
+ )
1250
+ }
1251
+ }
1252
+
1253
+ // Cached set to track which bones are being computed in current IK pass (to avoid infinite recursion)
1254
+ private ikComputedSet: Set<number> = new Set()
1255
+
1256
+ // Add this new method to compute a single bone's world matrix
1257
+ // Recursively ensures parents are computed first to avoid using stale parent matrices
1258
+ private computeSingleBoneWorldMatrix(boneIndex: number, applyIK: boolean): void {
1259
+ const bones = this.skeleton.bones
1260
+ const localRot = this.runtimeSkeleton.localRotations
1261
+ const localTrans = this.runtimeSkeleton.localTranslations
1262
+ const worldMats = this.runtimeSkeleton.worldMatrices
1263
+ const ikChainInfo = this.runtimeSkeleton.ikChainInfo
1264
+
1265
+ const b = bones[boneIndex]
1266
+
1267
+ // Prevent infinite recursion: if this bone is already being computed in this call chain, skip
1268
+ if (this.ikComputedSet.has(boneIndex)) {
1269
+ return
1270
+ }
1271
+
1272
+ // Mark this bone as being computed to prevent infinite recursion
1273
+ this.ikComputedSet.add(boneIndex)
1274
+
1275
+ // Recursively compute parent first if it exists (ensures parent matrix is up-to-date)
1276
+ if (b.parentIndex >= 0) {
1277
+ this.computeSingleBoneWorldMatrix(b.parentIndex, applyIK)
1278
+ }
1279
+
1280
+ // Get base rotation
1281
+ let boneRot = localRot[boneIndex]
1282
+
1283
+ // Apply IK rotation if requested
1284
+ if (applyIK && ikChainInfo) {
1285
+ const chainInfo = ikChainInfo[boneIndex]
1286
+ if (chainInfo?.ikRotation) {
1287
+ boneRot = chainInfo.ikRotation.multiply(boneRot).normalize()
1288
+ }
1289
+ }
1290
+
1291
+ let rotateM = Mat4.fromQuat(boneRot.x, boneRot.y, boneRot.z, boneRot.w)
1292
+ let addLocalTx = 0, addLocalTy = 0, addLocalTz = 0
1293
+
1294
+ // Handle append transformations (same logic as computeWorldMatrices)
1295
+ const appendParentIdx = b.appendParentIndex
1296
+ const hasAppend = b.appendRotate &&
1297
+ appendParentIdx !== undefined &&
1298
+ appendParentIdx >= 0 &&
1299
+ appendParentIdx < bones.length
1300
+
1301
+ if (hasAppend) {
1302
+ const ratio = b.appendRatio === undefined ? 1 : Math.max(-1, Math.min(1, b.appendRatio))
1303
+ const hasRatio = Math.abs(ratio) > 1e-6
1304
+
1305
+ if (hasRatio) {
1306
+ if (b.appendRotate) {
1307
+ // Get append parent's rotation
1308
+ // During IK solving, use only base local rotation (not IK rotations) to avoid
1309
+ // conflicts with IK rotations that are still being computed incrementally
1310
+ // IK rotations will be applied to localRotations after IK solving completes
1311
+ if (appendParentIdx >= 0) {
1312
+ // Compute append parent's world matrix for dependency order, but use base rotation for append
1313
+ this.computeSingleBoneWorldMatrix(appendParentIdx, applyIK)
1314
+ }
1315
+
1316
+ // Use append parent's base local rotation only (IK rotations are applied after solving)
1317
+ let appendRot = localRot[appendParentIdx]
1318
+
1319
+ let ax = appendRot.x, ay = appendRot.y, az = appendRot.z
1320
+ const aw = appendRot.w
1321
+ const absRatio = ratio < 0 ? -ratio : ratio
1322
+ if (ratio < 0) { ax = -ax; ay = -ay; az = -az }
1323
+
1324
+ const appendQuat = new Quat(ax, ay, az, aw)
1325
+ const result = Quat.slerp(Quat.identity(), appendQuat, absRatio)
1326
+ rotateM = Mat4.fromQuat(result.x, result.y, result.z, result.w).multiply(rotateM)
1327
+ }
1328
+
1329
+ if (b.appendMove) {
1330
+ const appendTrans = localTrans[appendParentIdx]
1331
+ addLocalTx = appendTrans.x * ratio
1332
+ addLocalTy = appendTrans.y * ratio
1333
+ addLocalTz = appendTrans.z * ratio
1334
+ }
1335
+ }
1336
+ }
1337
+
1338
+ const boneTrans = localTrans[boneIndex]
1339
+ const localTx = boneTrans.x + addLocalTx
1340
+ const localTy = boneTrans.y + addLocalTy
1341
+ const localTz = boneTrans.z + addLocalTz
1342
+
1343
+ this.cachedIdentityMat1
1344
+ .setIdentity()
1345
+ .translateInPlace(b.bindTranslation[0], b.bindTranslation[1], b.bindTranslation[2])
1346
+ this.cachedIdentityMat2.setIdentity().translateInPlace(localTx, localTy, localTz)
1347
+ const localM = this.cachedIdentityMat1.multiply(rotateM).multiply(this.cachedIdentityMat2)
1348
+
1349
+ const worldMat = worldMats[boneIndex]
1350
+ if (b.parentIndex >= 0) {
1351
+ const parentMat = worldMats[b.parentIndex]
1352
+ Mat4.multiplyArrays(parentMat.values, 0, localM.values, 0, worldMat.values, 0)
1353
+ } else {
1354
+ worldMat.values.set(localM.values)
1355
+ }
1172
1356
  }
1173
1357
 
1174
1358
  private computeWorldMatrices(): void {
@@ -1261,4 +1445,4 @@ export class Model {
1261
1445
  // Process all bones (recursion handles dependencies automatically)
1262
1446
  for (let i = 0; i < boneCount; i++) computeWorld(i)
1263
1447
  }
1264
- }
1448
+ }
@@ -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
- }
@@ -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
@@ -1 +0,0 @@
1
- {"version":3,"file":"engine_ts.d.ts","sourceRoot":"","sources":["../src/engine_ts.ts"],"names":[],"mappings":"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"}