reze-engine 0.3.3 → 0.3.4
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 +1 -1
- package/dist/engine.d.ts.map +1 -1
- package/dist/engine.js +2 -2
- package/dist/ik.d.ts +32 -0
- package/dist/ik.d.ts.map +1 -0
- package/dist/ik.js +337 -0
- package/dist/math.d.ts +1 -0
- package/dist/math.d.ts.map +1 -1
- package/dist/math.js +3 -0
- package/dist/player.d.ts +3 -25
- package/dist/player.d.ts.map +1 -1
- package/dist/player.js +3 -115
- package/dist/pool-scene.d.ts +52 -0
- package/dist/pool-scene.d.ts.map +1 -0
- package/dist/pool-scene.js +1122 -0
- package/dist/pool.d.ts +38 -0
- package/dist/pool.d.ts.map +1 -0
- package/dist/pool.js +422 -0
- package/package.json +1 -1
- package/src/engine.ts +2 -2
- package/src/ik.ts +449 -0
- package/src/math.ts +4 -0
- package/src/player.ts +3 -139
package/dist/player.js
CHANGED
|
@@ -16,60 +16,14 @@ export class Player {
|
|
|
16
16
|
this.startTime = 0; // Real-time when playback started
|
|
17
17
|
this.pausedTime = 0; // Accumulated paused duration
|
|
18
18
|
this.pauseStartTime = 0;
|
|
19
|
-
this.audioLoaded = false;
|
|
20
19
|
}
|
|
21
20
|
/**
|
|
22
|
-
* Load VMD animation file
|
|
21
|
+
* Load VMD animation file
|
|
23
22
|
*/
|
|
24
|
-
async loadVmd(vmdUrl
|
|
23
|
+
async loadVmd(vmdUrl) {
|
|
25
24
|
// Load animation
|
|
26
25
|
this.frames = await VMDLoader.load(vmdUrl);
|
|
27
26
|
this.processFrames();
|
|
28
|
-
// Load audio if provided
|
|
29
|
-
if (audioUrl) {
|
|
30
|
-
await this.loadAudio(audioUrl);
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
/**
|
|
34
|
-
* Load audio file
|
|
35
|
-
*/
|
|
36
|
-
async loadAudio(url) {
|
|
37
|
-
this.audioUrl = url;
|
|
38
|
-
this.audioLoaded = false;
|
|
39
|
-
return new Promise((resolve, reject) => {
|
|
40
|
-
const audio = new Audio(url);
|
|
41
|
-
audio.preload = "auto";
|
|
42
|
-
// iOS Safari requires playsinline attribute for inline playback
|
|
43
|
-
// This must be set before loading
|
|
44
|
-
audio.setAttribute("playsinline", "true");
|
|
45
|
-
audio.setAttribute("webkit-playsinline", "true");
|
|
46
|
-
// Set volume to ensure audio is ready
|
|
47
|
-
audio.volume = 1.0;
|
|
48
|
-
// iOS sometimes requires audio element to be in DOM
|
|
49
|
-
// Add it hidden to the document body
|
|
50
|
-
audio.style.display = "none";
|
|
51
|
-
audio.style.position = "absolute";
|
|
52
|
-
audio.style.visibility = "hidden";
|
|
53
|
-
audio.style.width = "0";
|
|
54
|
-
audio.style.height = "0";
|
|
55
|
-
document.body.appendChild(audio);
|
|
56
|
-
audio.addEventListener("loadeddata", () => {
|
|
57
|
-
this.audioElement = audio;
|
|
58
|
-
this.audioLoaded = true;
|
|
59
|
-
resolve();
|
|
60
|
-
});
|
|
61
|
-
audio.addEventListener("error", (e) => {
|
|
62
|
-
console.warn("Failed to load audio:", url, e);
|
|
63
|
-
this.audioLoaded = false;
|
|
64
|
-
// Remove from DOM on error
|
|
65
|
-
if (audio.parentNode) {
|
|
66
|
-
audio.parentNode.removeChild(audio);
|
|
67
|
-
}
|
|
68
|
-
// Don't reject - animation should still work without audio
|
|
69
|
-
resolve();
|
|
70
|
-
});
|
|
71
|
-
audio.load();
|
|
72
|
-
});
|
|
73
27
|
}
|
|
74
28
|
/**
|
|
75
29
|
* Process frames into tracks
|
|
@@ -140,6 +94,7 @@ export class Player {
|
|
|
140
94
|
}
|
|
141
95
|
/**
|
|
142
96
|
* Start or resume playback
|
|
97
|
+
* Note: For iOS, this should be called synchronously from a user interaction event
|
|
143
98
|
*/
|
|
144
99
|
play() {
|
|
145
100
|
if (this.frames.length === 0)
|
|
@@ -156,22 +111,6 @@ export class Player {
|
|
|
156
111
|
this.pausedTime = 0;
|
|
157
112
|
}
|
|
158
113
|
this.isPlaying = true;
|
|
159
|
-
// Play audio if available
|
|
160
|
-
if (this.audioElement && this.audioLoaded) {
|
|
161
|
-
// Ensure audio is ready for iOS
|
|
162
|
-
this.audioElement.currentTime = this.currentTime;
|
|
163
|
-
this.audioElement.muted = false;
|
|
164
|
-
this.audioElement.volume = 1.0;
|
|
165
|
-
// iOS requires play() to be called synchronously during user interaction
|
|
166
|
-
// This must happen directly from the user's click/touch event
|
|
167
|
-
const playPromise = this.audioElement.play();
|
|
168
|
-
if (playPromise !== undefined) {
|
|
169
|
-
playPromise.catch((error) => {
|
|
170
|
-
// Log error but don't block animation playback
|
|
171
|
-
console.warn("Audio play failed:", error, error.name);
|
|
172
|
-
});
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
114
|
}
|
|
176
115
|
/**
|
|
177
116
|
* Pause playback
|
|
@@ -181,10 +120,6 @@ export class Player {
|
|
|
181
120
|
return;
|
|
182
121
|
this.isPaused = true;
|
|
183
122
|
this.pauseStartTime = performance.now();
|
|
184
|
-
// Pause audio if available
|
|
185
|
-
if (this.audioElement) {
|
|
186
|
-
this.audioElement.pause();
|
|
187
|
-
}
|
|
188
123
|
}
|
|
189
124
|
/**
|
|
190
125
|
* Stop playback and reset to beginning
|
|
@@ -195,11 +130,6 @@ export class Player {
|
|
|
195
130
|
this.currentTime = 0;
|
|
196
131
|
this.startTime = 0;
|
|
197
132
|
this.pausedTime = 0;
|
|
198
|
-
// Stop audio if available
|
|
199
|
-
if (this.audioElement) {
|
|
200
|
-
this.audioElement.pause();
|
|
201
|
-
this.audioElement.currentTime = 0;
|
|
202
|
-
}
|
|
203
133
|
}
|
|
204
134
|
/**
|
|
205
135
|
* Seek to specific time
|
|
@@ -212,10 +142,6 @@ export class Player {
|
|
|
212
142
|
this.startTime = performance.now() - clampedTime * 1000;
|
|
213
143
|
this.pausedTime = 0;
|
|
214
144
|
}
|
|
215
|
-
// Seek audio if available
|
|
216
|
-
if (this.audioElement && this.audioLoaded) {
|
|
217
|
-
this.audioElement.currentTime = clampedTime;
|
|
218
|
-
}
|
|
219
145
|
}
|
|
220
146
|
/**
|
|
221
147
|
* Update playback and return current pose
|
|
@@ -238,14 +164,6 @@ export class Player {
|
|
|
238
164
|
this.pause(); // Auto-pause at end
|
|
239
165
|
return this.getPoseAtTime(this.currentTime);
|
|
240
166
|
}
|
|
241
|
-
// Sync audio if present (with tolerance)
|
|
242
|
-
if (this.audioElement && this.audioLoaded) {
|
|
243
|
-
const audioTime = this.audioElement.currentTime;
|
|
244
|
-
const syncTolerance = 0.1; // 100ms tolerance
|
|
245
|
-
if (Math.abs(audioTime - this.currentTime) > syncTolerance) {
|
|
246
|
-
this.audioElement.currentTime = this.currentTime;
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
167
|
return this.getPoseAtTime(this.currentTime);
|
|
250
168
|
}
|
|
251
169
|
/**
|
|
@@ -403,34 +321,4 @@ export class Player {
|
|
|
403
321
|
isPausedState() {
|
|
404
322
|
return this.isPaused;
|
|
405
323
|
}
|
|
406
|
-
/**
|
|
407
|
-
* Check if has audio
|
|
408
|
-
*/
|
|
409
|
-
hasAudio() {
|
|
410
|
-
return this.audioElement !== undefined && this.audioLoaded;
|
|
411
|
-
}
|
|
412
|
-
/**
|
|
413
|
-
* Set audio volume (0.0 to 1.0)
|
|
414
|
-
*/
|
|
415
|
-
setVolume(volume) {
|
|
416
|
-
if (this.audioElement) {
|
|
417
|
-
this.audioElement.volume = Math.max(0, Math.min(1, volume));
|
|
418
|
-
}
|
|
419
|
-
}
|
|
420
|
-
/**
|
|
421
|
-
* Mute audio
|
|
422
|
-
*/
|
|
423
|
-
mute() {
|
|
424
|
-
if (this.audioElement) {
|
|
425
|
-
this.audioElement.muted = true;
|
|
426
|
-
}
|
|
427
|
-
}
|
|
428
|
-
/**
|
|
429
|
-
* Unmute audio
|
|
430
|
-
*/
|
|
431
|
-
unmute() {
|
|
432
|
-
if (this.audioElement) {
|
|
433
|
-
this.audioElement.muted = false;
|
|
434
|
-
}
|
|
435
|
-
}
|
|
436
324
|
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
export interface PoolSceneConfig {
|
|
2
|
+
cloudSharpness?: number;
|
|
3
|
+
windSpeed?: [number, number];
|
|
4
|
+
bumpFactor?: number;
|
|
5
|
+
bumpDistance?: number;
|
|
6
|
+
skyColor?: [number, number, number];
|
|
7
|
+
moonlightColor?: [number, number, number];
|
|
8
|
+
skyByMoonlightColor?: [number, number, number];
|
|
9
|
+
waterColor?: [number, number, number];
|
|
10
|
+
exposure?: number;
|
|
11
|
+
epsilon?: number;
|
|
12
|
+
marchSteps?: number;
|
|
13
|
+
moonPosition?: [number, number, number];
|
|
14
|
+
}
|
|
15
|
+
export declare class PoolScene {
|
|
16
|
+
private device;
|
|
17
|
+
private pipeline;
|
|
18
|
+
private computePipeline;
|
|
19
|
+
private uniformBuffer;
|
|
20
|
+
private computeUniformBuffer;
|
|
21
|
+
private bindGroup;
|
|
22
|
+
private computeBindGroup;
|
|
23
|
+
private startTime;
|
|
24
|
+
private config;
|
|
25
|
+
private format;
|
|
26
|
+
private sampleCount;
|
|
27
|
+
private cameraUniformBuffer;
|
|
28
|
+
private waterHeightTexture;
|
|
29
|
+
private waterHeightTextureView;
|
|
30
|
+
private waterHeightSampler;
|
|
31
|
+
private waterHeightTextureSize;
|
|
32
|
+
private waterPlanePipeline;
|
|
33
|
+
private waterPlaneVertexBuffer;
|
|
34
|
+
private waterPlaneIndexBuffer;
|
|
35
|
+
private waterPlaneBindGroup;
|
|
36
|
+
private waterPlaneSize;
|
|
37
|
+
private waterPlaneSubdivisions;
|
|
38
|
+
private moonPosition;
|
|
39
|
+
private moonRadius;
|
|
40
|
+
constructor(device: GPUDevice, format: GPUTextureFormat, sampleCount: number, cameraUniformBuffer: GPUBuffer, config?: PoolSceneConfig);
|
|
41
|
+
private createWaterHeightTexture;
|
|
42
|
+
private createComputePipeline;
|
|
43
|
+
private createPipeline;
|
|
44
|
+
private createUniformBuffer;
|
|
45
|
+
dispatchCompute(encoder: GPUCommandEncoder, width: number, height: number, modelPos?: [number, number, number]): void;
|
|
46
|
+
private createWaterPlane;
|
|
47
|
+
private createWaterPlanePipeline;
|
|
48
|
+
renderWaterPlane(pass: GPURenderPassEncoder, width: number, height: number, modelPos?: [number, number, number]): void;
|
|
49
|
+
render(pass: GPURenderPassEncoder, width: number, height: number, modelPos?: [number, number, number]): void;
|
|
50
|
+
getSkyColor(): [number, number, number];
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=pool-scene.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pool-scene.d.ts","sourceRoot":"","sources":["../src/pool-scene.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,eAAe;IAC9B,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,SAAS,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC5B,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;IACnC,cAAc,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;IACzC,mBAAmB,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;IAC9C,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;IACrC,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAA;CACxC;AAED,qBAAa,SAAS;IACpB,OAAO,CAAC,MAAM,CAAW;IACzB,OAAO,CAAC,QAAQ,CAAoB;IACpC,OAAO,CAAC,eAAe,CAAqB;IAC5C,OAAO,CAAC,aAAa,CAAY;IACjC,OAAO,CAAC,oBAAoB,CAAY;IACxC,OAAO,CAAC,SAAS,CAAe;IAChC,OAAO,CAAC,gBAAgB,CAAe;IACvC,OAAO,CAAC,SAAS,CAA4B;IAC7C,OAAO,CAAC,MAAM,CAA2B;IACzC,OAAO,CAAC,MAAM,CAAkB;IAChC,OAAO,CAAC,WAAW,CAAQ;IAC3B,OAAO,CAAC,mBAAmB,CAAY;IACvC,OAAO,CAAC,kBAAkB,CAAa;IACvC,OAAO,CAAC,sBAAsB,CAAiB;IAC/C,OAAO,CAAC,kBAAkB,CAAa;IACvC,OAAO,CAAC,sBAAsB,CAAc;IAC5C,OAAO,CAAC,kBAAkB,CAAoB;IAC9C,OAAO,CAAC,sBAAsB,CAAY;IAC1C,OAAO,CAAC,qBAAqB,CAAY;IACzC,OAAO,CAAC,mBAAmB,CAAe;IAC1C,OAAO,CAAC,cAAc,CAAgB;IACtC,OAAO,CAAC,sBAAsB,CAAc;IAC5C,OAAO,CAAC,YAAY,CAA0B;IAC9C,OAAO,CAAC,UAAU,CAAe;gBAG/B,MAAM,EAAE,SAAS,EACjB,MAAM,EAAE,gBAAgB,EACxB,WAAW,EAAE,MAAM,EACnB,mBAAmB,EAAE,SAAS,EAC9B,MAAM,GAAE,eAAoB;IA6B9B,OAAO,CAAC,wBAAwB;IAmBhC,OAAO,CAAC,qBAAqB;IA8G7B,OAAO,CAAC,cAAc;IAqatB,OAAO,CAAC,mBAAmB;IAgCpB,eAAe,CACpB,OAAO,EAAE,iBAAiB,EAC1B,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,QAAQ,GAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAa;IA2ChD,OAAO,CAAC,gBAAgB;IA4DxB,OAAO,CAAC,wBAAwB;IAmazB,gBAAgB,CACrB,IAAI,EAAE,oBAAoB,EAC1B,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,QAAQ,GAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAa;IAiBzC,MAAM,CACX,IAAI,EAAE,oBAAoB,EAC1B,KAAK,EAAE,MAAM,EACb,MAAM,EAAE,MAAM,EACd,QAAQ,GAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAa;IAezC,WAAW,IAAI,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;CAG/C"}
|