reze-engine 0.2.9 → 0.2.11
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 +7 -1
- package/dist/engine.d.ts.map +1 -1
- package/dist/engine.js +18 -2
- package/package.json +1 -1
- package/src/engine.ts +22 -3
- package/src/physics.ts +752 -752
package/dist/engine.d.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
|
-
import { Quat } from "./math";
|
|
1
|
+
import { Quat, Vec3 } from "./math";
|
|
2
2
|
export type EngineOptions = {
|
|
3
3
|
ambient?: number;
|
|
4
4
|
bloomIntensity?: number;
|
|
5
5
|
rimLightIntensity?: number;
|
|
6
|
+
cameraDistance?: number;
|
|
7
|
+
cameraTarget?: Vec3;
|
|
6
8
|
};
|
|
7
9
|
export interface EngineStats {
|
|
8
10
|
fps: number;
|
|
@@ -17,6 +19,8 @@ export declare class Engine {
|
|
|
17
19
|
private camera;
|
|
18
20
|
private cameraUniformBuffer;
|
|
19
21
|
private cameraMatrixData;
|
|
22
|
+
private cameraDistance;
|
|
23
|
+
private cameraTarget;
|
|
20
24
|
private lightUniformBuffer;
|
|
21
25
|
private lightData;
|
|
22
26
|
private lightCount;
|
|
@@ -94,6 +98,8 @@ export declare class Engine {
|
|
|
94
98
|
private animationFrames;
|
|
95
99
|
private animationTimeouts;
|
|
96
100
|
private gpuMemoryMB;
|
|
101
|
+
private hasAnimation;
|
|
102
|
+
private playingAnimation;
|
|
97
103
|
constructor(canvas: HTMLCanvasElement, options?: EngineOptions);
|
|
98
104
|
init(): Promise<void>;
|
|
99
105
|
private createPipelines;
|
package/dist/engine.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,IAAI,
|
|
1
|
+
{"version":3,"file":"engine.d.ts","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"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"}
|
package/dist/engine.js
CHANGED
|
@@ -6,6 +6,8 @@ import { VMDLoader } from "./vmd-loader";
|
|
|
6
6
|
export class Engine {
|
|
7
7
|
constructor(canvas, options) {
|
|
8
8
|
this.cameraMatrixData = new Float32Array(36);
|
|
9
|
+
this.cameraDistance = 26.6;
|
|
10
|
+
this.cameraTarget = new Vec3(0, 12.5, 0);
|
|
9
11
|
this.lightData = new Float32Array(64);
|
|
10
12
|
this.lightCount = 0;
|
|
11
13
|
this.resizeObserver = null;
|
|
@@ -51,11 +53,15 @@ export class Engine {
|
|
|
51
53
|
this.animationFrames = [];
|
|
52
54
|
this.animationTimeouts = [];
|
|
53
55
|
this.gpuMemoryMB = 0;
|
|
56
|
+
this.hasAnimation = false; // Set to true when loadAnimation is called
|
|
57
|
+
this.playingAnimation = false; // Set to true when playAnimation is called
|
|
54
58
|
this.canvas = canvas;
|
|
55
59
|
if (options) {
|
|
56
60
|
this.ambient = options.ambient ?? 1.0;
|
|
57
61
|
this.bloomIntensity = options.bloomIntensity ?? 0.12;
|
|
58
62
|
this.rimLightIntensity = options.rimLightIntensity ?? 0.45;
|
|
63
|
+
this.cameraDistance = options.cameraDistance ?? 26.6;
|
|
64
|
+
this.cameraTarget = options.cameraTarget ?? new Vec3(0, 12.5, 0);
|
|
59
65
|
}
|
|
60
66
|
}
|
|
61
67
|
// Step 1: Get WebGPU device and context
|
|
@@ -1219,7 +1225,7 @@ export class Engine {
|
|
|
1219
1225
|
size: 40 * 4,
|
|
1220
1226
|
usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
|
|
1221
1227
|
});
|
|
1222
|
-
this.camera = new Camera(Math.PI, Math.PI / 2.5,
|
|
1228
|
+
this.camera = new Camera(Math.PI, Math.PI / 2.5, this.cameraDistance, this.cameraTarget);
|
|
1223
1229
|
this.camera.aspect = this.canvas.width / this.canvas.height;
|
|
1224
1230
|
this.camera.attachControl(this.canvas);
|
|
1225
1231
|
}
|
|
@@ -1260,11 +1266,13 @@ export class Engine {
|
|
|
1260
1266
|
async loadAnimation(url) {
|
|
1261
1267
|
const frames = await VMDLoader.load(url);
|
|
1262
1268
|
this.animationFrames = frames;
|
|
1269
|
+
this.hasAnimation = true;
|
|
1263
1270
|
}
|
|
1264
1271
|
playAnimation() {
|
|
1265
1272
|
if (this.animationFrames.length === 0)
|
|
1266
1273
|
return;
|
|
1267
1274
|
this.stopAnimation();
|
|
1275
|
+
this.playingAnimation = true;
|
|
1268
1276
|
const allBoneKeyFrames = [];
|
|
1269
1277
|
for (const keyFrame of this.animationFrames) {
|
|
1270
1278
|
for (const boneFrame of keyFrame.boneFrames) {
|
|
@@ -1314,9 +1322,9 @@ export class Engine {
|
|
|
1314
1322
|
const identityQuats = new Array(bonesToReset.length).fill(identityQuat);
|
|
1315
1323
|
this.rotateBones(bonesToReset, identityQuats, 0);
|
|
1316
1324
|
}
|
|
1317
|
-
this.currentModel.evaluatePose();
|
|
1318
1325
|
// Reset physics immediately and upload matrices to prevent A-pose flash
|
|
1319
1326
|
if (this.physics) {
|
|
1327
|
+
this.currentModel.evaluatePose();
|
|
1320
1328
|
const worldMats = this.currentModel.getBoneWorldMatrices();
|
|
1321
1329
|
this.physics.reset(worldMats, this.currentModel.getBoneInverseBindMatrices());
|
|
1322
1330
|
// Upload matrices immediately so next frame shows correct pose
|
|
@@ -1358,6 +1366,7 @@ export class Engine {
|
|
|
1358
1366
|
clearTimeout(timeoutId);
|
|
1359
1367
|
}
|
|
1360
1368
|
this.animationTimeouts = [];
|
|
1369
|
+
this.playingAnimation = false;
|
|
1361
1370
|
}
|
|
1362
1371
|
getStats() {
|
|
1363
1372
|
return { ...this.stats };
|
|
@@ -1762,6 +1771,13 @@ export class Engine {
|
|
|
1762
1771
|
// Use single encoder for both compute and render (reduces sync points)
|
|
1763
1772
|
const encoder = this.device.createCommandEncoder();
|
|
1764
1773
|
this.updateModelPose(deltaTime, encoder);
|
|
1774
|
+
// Hide model if animation is loaded but not playing yet (prevents A-pose flash)
|
|
1775
|
+
// Still update physics and poses, just don't render visually
|
|
1776
|
+
if (this.hasAnimation && !this.playingAnimation) {
|
|
1777
|
+
// Submit encoder to ensure matrices are uploaded and physics initializes
|
|
1778
|
+
this.device.queue.submit([encoder.finish()]);
|
|
1779
|
+
return;
|
|
1780
|
+
}
|
|
1765
1781
|
const pass = encoder.beginRenderPass(this.renderPassDescriptor);
|
|
1766
1782
|
pass.setVertexBuffer(0, this.vertexBuffer);
|
|
1767
1783
|
pass.setVertexBuffer(1, this.jointsBuffer);
|
package/package.json
CHANGED
package/src/engine.ts
CHANGED
|
@@ -9,6 +9,8 @@ export type EngineOptions = {
|
|
|
9
9
|
ambient?: number
|
|
10
10
|
bloomIntensity?: number
|
|
11
11
|
rimLightIntensity?: number
|
|
12
|
+
cameraDistance?: number
|
|
13
|
+
cameraTarget?: Vec3
|
|
12
14
|
}
|
|
13
15
|
|
|
14
16
|
export interface EngineStats {
|
|
@@ -38,6 +40,8 @@ export class Engine {
|
|
|
38
40
|
private camera!: Camera
|
|
39
41
|
private cameraUniformBuffer!: GPUBuffer
|
|
40
42
|
private cameraMatrixData = new Float32Array(36)
|
|
43
|
+
private cameraDistance: number = 26.6
|
|
44
|
+
private cameraTarget: Vec3 = new Vec3(0, 12.5, 0)
|
|
41
45
|
private lightUniformBuffer!: GPUBuffer
|
|
42
46
|
private lightData = new Float32Array(64)
|
|
43
47
|
private lightCount = 0
|
|
@@ -133,6 +137,8 @@ export class Engine {
|
|
|
133
137
|
private animationFrames: VMDKeyFrame[] = []
|
|
134
138
|
private animationTimeouts: number[] = []
|
|
135
139
|
private gpuMemoryMB: number = 0
|
|
140
|
+
private hasAnimation = false // Set to true when loadAnimation is called
|
|
141
|
+
private playingAnimation = false // Set to true when playAnimation is called
|
|
136
142
|
|
|
137
143
|
constructor(canvas: HTMLCanvasElement, options?: EngineOptions) {
|
|
138
144
|
this.canvas = canvas
|
|
@@ -140,6 +146,8 @@ export class Engine {
|
|
|
140
146
|
this.ambient = options.ambient ?? 1.0
|
|
141
147
|
this.bloomIntensity = options.bloomIntensity ?? 0.12
|
|
142
148
|
this.rimLightIntensity = options.rimLightIntensity ?? 0.45
|
|
149
|
+
this.cameraDistance = options.cameraDistance ?? 26.6
|
|
150
|
+
this.cameraTarget = options.cameraTarget ?? new Vec3(0, 12.5, 0)
|
|
143
151
|
}
|
|
144
152
|
}
|
|
145
153
|
|
|
@@ -1360,7 +1368,7 @@ export class Engine {
|
|
|
1360
1368
|
usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
|
|
1361
1369
|
})
|
|
1362
1370
|
|
|
1363
|
-
this.camera = new Camera(Math.PI, Math.PI / 2.5,
|
|
1371
|
+
this.camera = new Camera(Math.PI, Math.PI / 2.5, this.cameraDistance, this.cameraTarget)
|
|
1364
1372
|
|
|
1365
1373
|
this.camera.aspect = this.canvas.width / this.canvas.height
|
|
1366
1374
|
this.camera.attachControl(this.canvas)
|
|
@@ -1409,12 +1417,14 @@ export class Engine {
|
|
|
1409
1417
|
public async loadAnimation(url: string) {
|
|
1410
1418
|
const frames = await VMDLoader.load(url)
|
|
1411
1419
|
this.animationFrames = frames
|
|
1420
|
+
this.hasAnimation = true
|
|
1412
1421
|
}
|
|
1413
1422
|
|
|
1414
1423
|
public playAnimation() {
|
|
1415
1424
|
if (this.animationFrames.length === 0) return
|
|
1416
1425
|
|
|
1417
1426
|
this.stopAnimation()
|
|
1427
|
+
this.playingAnimation = true
|
|
1418
1428
|
|
|
1419
1429
|
const allBoneKeyFrames: BoneKeyFrame[] = []
|
|
1420
1430
|
for (const keyFrame of this.animationFrames) {
|
|
@@ -1472,10 +1482,10 @@ export class Engine {
|
|
|
1472
1482
|
this.rotateBones(bonesToReset, identityQuats, 0)
|
|
1473
1483
|
}
|
|
1474
1484
|
|
|
1475
|
-
this.currentModel.evaluatePose()
|
|
1476
|
-
|
|
1477
1485
|
// Reset physics immediately and upload matrices to prevent A-pose flash
|
|
1478
1486
|
if (this.physics) {
|
|
1487
|
+
this.currentModel.evaluatePose()
|
|
1488
|
+
|
|
1479
1489
|
const worldMats = this.currentModel.getBoneWorldMatrices()
|
|
1480
1490
|
this.physics.reset(worldMats, this.currentModel.getBoneInverseBindMatrices())
|
|
1481
1491
|
|
|
@@ -1526,6 +1536,7 @@ export class Engine {
|
|
|
1526
1536
|
clearTimeout(timeoutId)
|
|
1527
1537
|
}
|
|
1528
1538
|
this.animationTimeouts = []
|
|
1539
|
+
this.playingAnimation = false
|
|
1529
1540
|
}
|
|
1530
1541
|
|
|
1531
1542
|
public getStats(): EngineStats {
|
|
@@ -2001,6 +2012,14 @@ export class Engine {
|
|
|
2001
2012
|
|
|
2002
2013
|
this.updateModelPose(deltaTime, encoder)
|
|
2003
2014
|
|
|
2015
|
+
// Hide model if animation is loaded but not playing yet (prevents A-pose flash)
|
|
2016
|
+
// Still update physics and poses, just don't render visually
|
|
2017
|
+
if (this.hasAnimation && !this.playingAnimation) {
|
|
2018
|
+
// Submit encoder to ensure matrices are uploaded and physics initializes
|
|
2019
|
+
this.device.queue.submit([encoder.finish()])
|
|
2020
|
+
return
|
|
2021
|
+
}
|
|
2022
|
+
|
|
2004
2023
|
const pass = encoder.beginRenderPass(this.renderPassDescriptor)
|
|
2005
2024
|
|
|
2006
2025
|
pass.setVertexBuffer(0, this.vertexBuffer)
|