reze-engine 0.3.5 → 0.3.6
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 +2 -1
- package/dist/engine.d.ts.map +1 -1
- package/dist/engine.js +44 -100
- package/dist/ik-solver.d.ts +6 -0
- package/dist/ik-solver.d.ts.map +1 -1
- package/dist/ik-solver.js +98 -101
- 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 +0 -5
- package/dist/math.d.ts.map +1 -1
- package/dist/math.js +0 -55
- package/dist/model.d.ts +1 -3
- package/dist/model.d.ts.map +1 -1
- package/dist/model.js +11 -41
- package/dist/player.d.ts +6 -20
- package/dist/player.d.ts.map +1 -1
- package/dist/player.js +88 -191
- 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 +54 -101
- package/src/ik-solver.ts +106 -124
- package/src/math.ts +0 -74
- package/src/model.ts +12 -44
- package/src/player.ts +115 -210
package/dist/player.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"player.d.ts","sourceRoot":"","sources":["../src/player.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,IAAI,EAAqB,MAAM,QAAQ,CAAA;AAGtD,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,
|
|
1
|
+
{"version":3,"file":"player.d.ts","sourceRoot":"","sources":["../src/player.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAE,IAAI,EAAqB,MAAM,QAAQ,CAAA;AAGtD,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,SAAS,CAAY;IAG7B,OAAO,CAAC,SAAS,CAAiB;IAClC,OAAO,CAAC,QAAQ,CAAiB;IACjC,OAAO,CAAC,YAAY,CAAY;IAGhC,OAAO,CAAC,SAAS,CAAY;IAE7B;;OAEG;IACG,OAAO,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAM5C;;OAEG;IACH,OAAO,CAAC,aAAa;IAsDrB;;;OAGG;IACH,IAAI,IAAI,IAAI;IASZ;;OAEG;IACH,KAAK,IAAI,IAAI;IAKb;;OAEG;IACH,IAAI,IAAI,IAAI;IAOZ;;OAEG;IACH,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI;IASxB;;;OAGG;IACH,MAAM,CAAC,eAAe,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI;IAwBrD;;OAEG;IACH,aAAa,CAAC,IAAI,EAAE,MAAM,GAAG,aAAa;IA6F1C;;OAEG;IACH,WAAW,IAAI,iBAAiB;IAQhC,IAAI,WAAW,IAAI,MAAM,CAExB;IAED,IAAI,QAAQ,IAAI,MAAM,CAErB;IAED,IAAI,cAAc,IAAI,OAAO,CAE5B;IAED,IAAI,aAAa,IAAI,OAAO,CAE3B;CACF"}
|
package/dist/player.js
CHANGED
|
@@ -6,15 +6,13 @@ export class Player {
|
|
|
6
6
|
this.frames = [];
|
|
7
7
|
this.boneTracks = new Map();
|
|
8
8
|
this.morphTracks = new Map();
|
|
9
|
-
this.
|
|
9
|
+
this._duration = 0;
|
|
10
10
|
// Playback state
|
|
11
11
|
this.isPlaying = false;
|
|
12
12
|
this.isPaused = false;
|
|
13
|
-
this.
|
|
13
|
+
this._currentTime = 0;
|
|
14
14
|
// Timing
|
|
15
15
|
this.startTime = 0; // Real-time when playback started
|
|
16
|
-
this.pausedTime = 0; // Accumulated paused duration
|
|
17
|
-
this.pauseStartTime = 0;
|
|
18
16
|
}
|
|
19
17
|
/**
|
|
20
18
|
* Load VMD animation file
|
|
@@ -28,68 +26,45 @@ export class Player {
|
|
|
28
26
|
* Process frames into tracks
|
|
29
27
|
*/
|
|
30
28
|
processFrames() {
|
|
31
|
-
//
|
|
32
|
-
const
|
|
33
|
-
|
|
34
|
-
for (const
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
});
|
|
29
|
+
// Helper to group frames by name and sort by time
|
|
30
|
+
const groupFrames = (items) => {
|
|
31
|
+
const tracks = new Map();
|
|
32
|
+
for (const { item, name, time } of items) {
|
|
33
|
+
if (!tracks.has(name))
|
|
34
|
+
tracks.set(name, []);
|
|
35
|
+
tracks.get(name).push({ item, time });
|
|
39
36
|
}
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
for (const { boneFrame, time } of allBoneKeyFrames) {
|
|
43
|
-
if (!boneKeyFramesByBone.has(boneFrame.boneName)) {
|
|
44
|
-
boneKeyFramesByBone.set(boneFrame.boneName, []);
|
|
37
|
+
for (const keyFrames of tracks.values()) {
|
|
38
|
+
keyFrames.sort((a, b) => a.time - b.time);
|
|
45
39
|
}
|
|
46
|
-
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
// Process morph frames
|
|
52
|
-
const allMorphKeyFrames = [];
|
|
40
|
+
return tracks;
|
|
41
|
+
};
|
|
42
|
+
// Collect all bone and morph frames
|
|
43
|
+
const boneItems = [];
|
|
44
|
+
const morphItems = [];
|
|
53
45
|
for (const keyFrame of this.frames) {
|
|
54
|
-
for (const
|
|
55
|
-
|
|
56
|
-
morphFrame,
|
|
57
|
-
time: keyFrame.time,
|
|
58
|
-
});
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
const morphKeyFramesByMorph = new Map();
|
|
62
|
-
for (const { morphFrame, time } of allMorphKeyFrames) {
|
|
63
|
-
if (!morphKeyFramesByMorph.has(morphFrame.morphName)) {
|
|
64
|
-
morphKeyFramesByMorph.set(morphFrame.morphName, []);
|
|
46
|
+
for (const boneFrame of keyFrame.boneFrames) {
|
|
47
|
+
boneItems.push({ item: boneFrame, name: boneFrame.boneName, time: keyFrame.time });
|
|
65
48
|
}
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
for (const keyFrames of morphKeyFramesByMorph.values()) {
|
|
69
|
-
keyFrames.sort((a, b) => a.time - b.time);
|
|
70
|
-
}
|
|
71
|
-
// Store tracks
|
|
72
|
-
this.boneTracks = boneKeyFramesByBone;
|
|
73
|
-
this.morphTracks = morphKeyFramesByMorph;
|
|
74
|
-
// Calculate animation duration from max frame time
|
|
75
|
-
let maxFrameTime = 0;
|
|
76
|
-
for (const keyFrames of this.boneTracks.values()) {
|
|
77
|
-
if (keyFrames.length > 0) {
|
|
78
|
-
const lastTime = keyFrames[keyFrames.length - 1].time;
|
|
79
|
-
if (lastTime > maxFrameTime) {
|
|
80
|
-
maxFrameTime = lastTime;
|
|
81
|
-
}
|
|
49
|
+
for (const morphFrame of keyFrame.morphFrames) {
|
|
50
|
+
morphItems.push({ item: morphFrame, name: morphFrame.morphName, time: keyFrame.time });
|
|
82
51
|
}
|
|
83
52
|
}
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
maxFrameTime = lastTime;
|
|
89
|
-
}
|
|
90
|
-
}
|
|
53
|
+
// Transform to expected format
|
|
54
|
+
this.boneTracks = new Map();
|
|
55
|
+
for (const [name, frames] of groupFrames(boneItems).entries()) {
|
|
56
|
+
this.boneTracks.set(name, frames.map((f) => ({ boneFrame: f.item, time: f.time })));
|
|
91
57
|
}
|
|
92
|
-
this.
|
|
58
|
+
this.morphTracks = new Map();
|
|
59
|
+
for (const [name, frames] of groupFrames(morphItems).entries()) {
|
|
60
|
+
this.morphTracks.set(name, frames.map((f) => ({ morphFrame: f.item, time: f.time })));
|
|
61
|
+
}
|
|
62
|
+
// Calculate duration from all tracks
|
|
63
|
+
const allTracks = [...this.boneTracks.values(), ...this.morphTracks.values()];
|
|
64
|
+
this._duration = allTracks.reduce((max, keyFrames) => {
|
|
65
|
+
const lastTime = keyFrames[keyFrames.length - 1]?.time ?? 0;
|
|
66
|
+
return Math.max(max, lastTime);
|
|
67
|
+
}, 0);
|
|
93
68
|
}
|
|
94
69
|
/**
|
|
95
70
|
* Start or resume playback
|
|
@@ -98,17 +73,8 @@ export class Player {
|
|
|
98
73
|
play() {
|
|
99
74
|
if (this.frames.length === 0)
|
|
100
75
|
return;
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
this.isPaused = false;
|
|
104
|
-
// Adjust start time so current time calculation continues smoothly
|
|
105
|
-
this.startTime = performance.now() - this.currentTime * 1000;
|
|
106
|
-
}
|
|
107
|
-
else {
|
|
108
|
-
// Start from beginning or current seek position
|
|
109
|
-
this.startTime = performance.now() - this.currentTime * 1000;
|
|
110
|
-
this.pausedTime = 0;
|
|
111
|
-
}
|
|
76
|
+
this.isPaused = false;
|
|
77
|
+
this.startTime = performance.now() - this._currentTime * 1000;
|
|
112
78
|
this.isPlaying = true;
|
|
113
79
|
}
|
|
114
80
|
/**
|
|
@@ -118,7 +84,6 @@ export class Player {
|
|
|
118
84
|
if (!this.isPlaying || this.isPaused)
|
|
119
85
|
return;
|
|
120
86
|
this.isPaused = true;
|
|
121
|
-
this.pauseStartTime = performance.now();
|
|
122
87
|
}
|
|
123
88
|
/**
|
|
124
89
|
* Stop playback and reset to beginning
|
|
@@ -126,20 +91,17 @@ export class Player {
|
|
|
126
91
|
stop() {
|
|
127
92
|
this.isPlaying = false;
|
|
128
93
|
this.isPaused = false;
|
|
129
|
-
this.
|
|
94
|
+
this._currentTime = 0;
|
|
130
95
|
this.startTime = 0;
|
|
131
|
-
this.pausedTime = 0;
|
|
132
96
|
}
|
|
133
97
|
/**
|
|
134
98
|
* Seek to specific time
|
|
135
99
|
*/
|
|
136
100
|
seek(time) {
|
|
137
|
-
const clampedTime = Math.max(0, Math.min(time, this.
|
|
138
|
-
this.
|
|
139
|
-
// Adjust start time if playing
|
|
101
|
+
const clampedTime = Math.max(0, Math.min(time, this._duration));
|
|
102
|
+
this._currentTime = clampedTime;
|
|
140
103
|
if (this.isPlaying && !this.isPaused) {
|
|
141
104
|
this.startTime = performance.now() - clampedTime * 1000;
|
|
142
|
-
this.pausedTime = 0;
|
|
143
105
|
}
|
|
144
106
|
}
|
|
145
107
|
/**
|
|
@@ -152,18 +114,18 @@ export class Player {
|
|
|
152
114
|
}
|
|
153
115
|
// If paused, return current pose at paused time (no time update)
|
|
154
116
|
if (this.isPaused) {
|
|
155
|
-
return this.getPoseAtTime(this.
|
|
117
|
+
return this.getPoseAtTime(this._currentTime);
|
|
156
118
|
}
|
|
157
119
|
// Calculate current animation time
|
|
158
120
|
const elapsedSeconds = (currentRealTime - this.startTime) / 1000;
|
|
159
|
-
this.
|
|
121
|
+
this._currentTime = elapsedSeconds;
|
|
160
122
|
// Check if animation ended
|
|
161
|
-
if (this.
|
|
162
|
-
this.
|
|
123
|
+
if (this._currentTime >= this._duration) {
|
|
124
|
+
this._currentTime = this._duration;
|
|
163
125
|
this.pause(); // Auto-pause at end
|
|
164
|
-
return this.getPoseAtTime(this.
|
|
126
|
+
return this.getPoseAtTime(this._currentTime);
|
|
165
127
|
}
|
|
166
|
-
return this.getPoseAtTime(this.
|
|
128
|
+
return this.getPoseAtTime(this._currentTime);
|
|
167
129
|
}
|
|
168
130
|
/**
|
|
169
131
|
* Get pose at specific time (pure function)
|
|
@@ -174,114 +136,61 @@ export class Player {
|
|
|
174
136
|
boneTranslations: new Map(),
|
|
175
137
|
morphWeights: new Map(),
|
|
176
138
|
};
|
|
177
|
-
//
|
|
178
|
-
const
|
|
179
|
-
let left = 0;
|
|
180
|
-
let right = keyFrames.length;
|
|
139
|
+
// Generic binary search for upper bound
|
|
140
|
+
const upperBound = (time, keyFrames) => {
|
|
141
|
+
let left = 0, right = keyFrames.length;
|
|
181
142
|
while (left < right) {
|
|
182
143
|
const mid = Math.floor((left + right) / 2);
|
|
183
|
-
if (keyFrames[mid].time <= time)
|
|
144
|
+
if (keyFrames[mid].time <= time)
|
|
184
145
|
left = mid + 1;
|
|
185
|
-
|
|
186
|
-
else {
|
|
146
|
+
else
|
|
187
147
|
right = mid;
|
|
188
|
-
}
|
|
189
148
|
}
|
|
190
149
|
return left;
|
|
191
150
|
};
|
|
192
|
-
// Process
|
|
151
|
+
// Process bone tracks
|
|
193
152
|
for (const [boneName, keyFrames] of this.boneTracks.entries()) {
|
|
194
153
|
if (keyFrames.length === 0)
|
|
195
154
|
continue;
|
|
196
|
-
|
|
197
|
-
const
|
|
198
|
-
|
|
199
|
-
const clampedFrameTime = Math.max(startTime, Math.min(endTime, time));
|
|
200
|
-
const upperBoundIndex = upperBoundFrameIndex(clampedFrameTime, keyFrames);
|
|
201
|
-
const upperBoundIndexMinusOne = upperBoundIndex - 1;
|
|
202
|
-
if (upperBoundIndexMinusOne < 0)
|
|
155
|
+
const clampedTime = Math.max(keyFrames[0].time, Math.min(keyFrames[keyFrames.length - 1].time, time));
|
|
156
|
+
const idx = upperBound(clampedTime, keyFrames) - 1;
|
|
157
|
+
if (idx < 0)
|
|
203
158
|
continue;
|
|
204
|
-
const
|
|
205
|
-
const
|
|
206
|
-
if (
|
|
207
|
-
|
|
208
|
-
pose.
|
|
209
|
-
pose.boneTranslations.set(boneName, boneFrameA.translation);
|
|
159
|
+
const frameA = keyFrames[idx].boneFrame;
|
|
160
|
+
const frameB = keyFrames[idx + 1]?.boneFrame;
|
|
161
|
+
if (!frameB) {
|
|
162
|
+
pose.boneRotations.set(boneName, frameA.rotation);
|
|
163
|
+
pose.boneTranslations.set(boneName, frameA.translation);
|
|
210
164
|
}
|
|
211
165
|
else {
|
|
212
|
-
|
|
213
|
-
const
|
|
214
|
-
const
|
|
215
|
-
const
|
|
216
|
-
|
|
217
|
-
const
|
|
218
|
-
const
|
|
219
|
-
|
|
220
|
-
interp[2] / 127, // y1
|
|
221
|
-
interp[3] / 127, // y2
|
|
222
|
-
gradient);
|
|
223
|
-
const interpolatedRotation = Quat.slerp(boneFrameA.rotation, boneFrameB.rotation, rotWeight);
|
|
224
|
-
// Interpolate translation using Bezier (separate curves for X, Y, Z)
|
|
225
|
-
const xWeight = bezierInterpolate(interp[0] / 127, // X_x1
|
|
226
|
-
interp[8] / 127, // X_x2
|
|
227
|
-
interp[4] / 127, // X_y1
|
|
228
|
-
interp[12] / 127, // X_y2
|
|
229
|
-
gradient);
|
|
230
|
-
const yWeight = bezierInterpolate(interp[16] / 127, // Y_x1
|
|
231
|
-
interp[24] / 127, // Y_x2
|
|
232
|
-
interp[20] / 127, // Y_y1
|
|
233
|
-
interp[28] / 127, // Y_y2
|
|
234
|
-
gradient);
|
|
235
|
-
const zWeight = bezierInterpolate(interp[32] / 127, // Z_x1
|
|
236
|
-
interp[40] / 127, // Z_x2
|
|
237
|
-
interp[36] / 127, // Z_y1
|
|
238
|
-
interp[44] / 127, // Z_y2
|
|
239
|
-
gradient);
|
|
240
|
-
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);
|
|
241
|
-
pose.boneRotations.set(boneName, interpolatedRotation);
|
|
242
|
-
pose.boneTranslations.set(boneName, interpolatedTranslation);
|
|
166
|
+
const timeA = keyFrames[idx].time;
|
|
167
|
+
const timeB = keyFrames[idx + 1].time;
|
|
168
|
+
const gradient = (clampedTime - timeA) / (timeB - timeA);
|
|
169
|
+
const interp = frameB.interpolation;
|
|
170
|
+
pose.boneRotations.set(boneName, Quat.slerp(frameA.rotation, frameB.rotation, bezierInterpolate(interp[0] / 127, interp[1] / 127, interp[2] / 127, interp[3] / 127, gradient)));
|
|
171
|
+
const lerp = (a, b, w) => a + (b - a) * w;
|
|
172
|
+
const getWeight = (offset) => bezierInterpolate(interp[offset] / 127, interp[offset + 8] / 127, interp[offset + 4] / 127, interp[offset + 12] / 127, gradient);
|
|
173
|
+
pose.boneTranslations.set(boneName, new Vec3(lerp(frameA.translation.x, frameB.translation.x, getWeight(0)), lerp(frameA.translation.y, frameB.translation.y, getWeight(16)), lerp(frameA.translation.z, frameB.translation.z, getWeight(32))));
|
|
243
174
|
}
|
|
244
175
|
}
|
|
245
|
-
//
|
|
246
|
-
const upperBoundMorphIndex = (time, keyFrames) => {
|
|
247
|
-
let left = 0;
|
|
248
|
-
let right = keyFrames.length;
|
|
249
|
-
while (left < right) {
|
|
250
|
-
const mid = Math.floor((left + right) / 2);
|
|
251
|
-
if (keyFrames[mid].time <= time) {
|
|
252
|
-
left = mid + 1;
|
|
253
|
-
}
|
|
254
|
-
else {
|
|
255
|
-
right = mid;
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
return left;
|
|
259
|
-
};
|
|
260
|
-
// Process each morph track
|
|
176
|
+
// Process morph tracks
|
|
261
177
|
for (const [morphName, keyFrames] of this.morphTracks.entries()) {
|
|
262
178
|
if (keyFrames.length === 0)
|
|
263
179
|
continue;
|
|
264
|
-
|
|
265
|
-
const
|
|
266
|
-
|
|
267
|
-
const clampedFrameTime = Math.max(startTime, Math.min(endTime, time));
|
|
268
|
-
const upperBoundIndex = upperBoundMorphIndex(clampedFrameTime, keyFrames);
|
|
269
|
-
const upperBoundIndexMinusOne = upperBoundIndex - 1;
|
|
270
|
-
if (upperBoundIndexMinusOne < 0)
|
|
180
|
+
const clampedTime = Math.max(keyFrames[0].time, Math.min(keyFrames[keyFrames.length - 1].time, time));
|
|
181
|
+
const idx = upperBound(clampedTime, keyFrames) - 1;
|
|
182
|
+
if (idx < 0)
|
|
271
183
|
continue;
|
|
272
|
-
const
|
|
273
|
-
const
|
|
274
|
-
if (
|
|
275
|
-
|
|
276
|
-
pose.morphWeights.set(morphName, morphFrameA.weight);
|
|
184
|
+
const frameA = keyFrames[idx].morphFrame;
|
|
185
|
+
const frameB = keyFrames[idx + 1]?.morphFrame;
|
|
186
|
+
if (!frameB) {
|
|
187
|
+
pose.morphWeights.set(morphName, frameA.weight);
|
|
277
188
|
}
|
|
278
189
|
else {
|
|
279
|
-
|
|
280
|
-
const
|
|
281
|
-
const
|
|
282
|
-
|
|
283
|
-
const interpolatedWeight = morphFrameA.weight + (morphFrameB.weight - morphFrameA.weight) * gradient;
|
|
284
|
-
pose.morphWeights.set(morphName, interpolatedWeight);
|
|
190
|
+
const timeA = keyFrames[idx].time;
|
|
191
|
+
const timeB = keyFrames[idx + 1].time;
|
|
192
|
+
const gradient = (clampedTime - timeA) / (timeB - timeA);
|
|
193
|
+
pose.morphWeights.set(morphName, frameA.weight + (frameB.weight - frameA.weight) * gradient);
|
|
285
194
|
}
|
|
286
195
|
}
|
|
287
196
|
return pose;
|
|
@@ -291,33 +200,21 @@ export class Player {
|
|
|
291
200
|
*/
|
|
292
201
|
getProgress() {
|
|
293
202
|
return {
|
|
294
|
-
current: this.
|
|
295
|
-
duration: this.
|
|
296
|
-
percentage: this.
|
|
203
|
+
current: this._currentTime,
|
|
204
|
+
duration: this._duration,
|
|
205
|
+
percentage: this._duration > 0 ? (this._currentTime / this._duration) * 100 : 0,
|
|
297
206
|
};
|
|
298
207
|
}
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
*/
|
|
302
|
-
getCurrentTime() {
|
|
303
|
-
return this.currentTime;
|
|
208
|
+
get currentTime() {
|
|
209
|
+
return this._currentTime;
|
|
304
210
|
}
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
*/
|
|
308
|
-
getDuration() {
|
|
309
|
-
return this.duration;
|
|
211
|
+
get duration() {
|
|
212
|
+
return this._duration;
|
|
310
213
|
}
|
|
311
|
-
|
|
312
|
-
* Check if playing
|
|
313
|
-
*/
|
|
314
|
-
isPlayingState() {
|
|
214
|
+
get isPlayingState() {
|
|
315
215
|
return this.isPlaying && !this.isPaused;
|
|
316
216
|
}
|
|
317
|
-
|
|
318
|
-
* Check if paused
|
|
319
|
-
*/
|
|
320
|
-
isPausedState() {
|
|
217
|
+
get isPausedState() {
|
|
321
218
|
return this.isPaused;
|
|
322
219
|
}
|
|
323
220
|
}
|
|
@@ -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"}
|