matrix-engine-wgpu 1.3.13 → 1.3.17
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/package.json +2 -2
- package/readme.md +23 -0
- package/src/engine/ball.js +0 -482
- package/src/engine/cube.js +0 -496
- package/src/engine/engine.js +0 -476
- package/src/engine/final/adaptJSON1.js +0 -53
- package/src/engine/final/utils2.js +0 -63
- package/src/engine/lights.js +0 -126
- package/src/engine/loader-obj.js +0 -473
- package/src/engine/materials.js +0 -307
- package/src/engine/matrix-class.js +0 -252
- package/src/engine/mesh-obj.js +0 -553
- package/src/engine/mesh.js +0 -475
- package/src/engine/raycast.js +0 -219
- package/src/engine/utils.js +0 -881
- package/src/libs/mat.js +0 -0
- package/src/multilang/lang.js +0 -35
- package/src/physics/matrix-ammo.js +0 -361
- package/src/shaders/fragment.video.wgsl.js +0 -83
- package/src/shaders/fragment.wgsl.js +0 -75
- package/src/shaders/shaders.js +0 -51
- package/src/shaders/standard-matrix-engine-shaders/standard-matrix-engine-fs.glsl +0 -56
- package/src/shaders/standard-matrix-engine-shaders/standard-matrix-engine-vs.glsl +0 -75
- package/src/shaders/vertex.wgsl.js +0 -49
- package/src/shaders/vertexShadow.wgsl.js +0 -20
- package/src/sounds/sounds.js +0 -69
- package/src/world.js +0 -427
package/src/engine/engine.js
DELETED
|
@@ -1,476 +0,0 @@
|
|
|
1
|
-
// Note: The code in this file does not use the 'dst' output parameter of functions in the
|
|
2
|
-
// 'wgpu-matrix' library, so produces many temporary vectors and matrices.
|
|
3
|
-
// This is intentional, as this sample prefers readability over performance.
|
|
4
|
-
import { mat4, vec3 } from 'wgpu-matrix';
|
|
5
|
-
import {LOG_INFO} from './utils';
|
|
6
|
-
// import Input from './input';
|
|
7
|
-
|
|
8
|
-
// // Common interface for camera implementations
|
|
9
|
-
// export default interface Camera {
|
|
10
|
-
// // update updates the camera using the user-input and returns the view matrix.
|
|
11
|
-
// update(delta_time: number, input: Input): Mat4;
|
|
12
|
-
|
|
13
|
-
// // The camera matrix.
|
|
14
|
-
// // This is the inverse of the view matrix.
|
|
15
|
-
// matrix: Mat4;
|
|
16
|
-
// // Alias to column vector 0 of the camera matrix.
|
|
17
|
-
// right: Vec4;
|
|
18
|
-
// // Alias to column vector 1 of the camera matrix.
|
|
19
|
-
// up: Vec4;
|
|
20
|
-
// // Alias to column vector 2 of the camera matrix.
|
|
21
|
-
// back: Vec4;
|
|
22
|
-
// // Alias to column vector 3 of the camera matrix.
|
|
23
|
-
// position: Vec4;
|
|
24
|
-
// }
|
|
25
|
-
|
|
26
|
-
// The common functionality between camera implementations
|
|
27
|
-
class CameraBase {
|
|
28
|
-
// The camera matrix
|
|
29
|
-
matrix_ = new Float32Array([
|
|
30
|
-
1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1,
|
|
31
|
-
]);
|
|
32
|
-
|
|
33
|
-
// The calculated view matrix readonly
|
|
34
|
-
view_ = mat4.create();
|
|
35
|
-
|
|
36
|
-
// Aliases to column vectors of the matrix
|
|
37
|
-
right_ = new Float32Array(this.matrix_.buffer, 4 * 0, 4);
|
|
38
|
-
up_ = new Float32Array(this.matrix_.buffer, 4 * 4, 4);
|
|
39
|
-
back_ = new Float32Array(this.matrix_.buffer, 4 * 8, 4);
|
|
40
|
-
position_ = new Float32Array(this.matrix_.buffer, 4 * 12, 4);
|
|
41
|
-
|
|
42
|
-
// Returns the camera matrix
|
|
43
|
-
get matrix() {
|
|
44
|
-
return this.matrix_;
|
|
45
|
-
}
|
|
46
|
-
// Assigns `mat` to the camera matrix
|
|
47
|
-
set matrix(mat) {
|
|
48
|
-
mat4.copy(mat, this.matrix_);
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
setProjection(fov = (2 * Math.PI) / 5, aspect = 1, near = 1, far = 1000) {
|
|
52
|
-
this.projectionMatrix = mat4.perspective(fov, aspect, near, far);
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
// Returns the camera view matrix
|
|
56
|
-
get view() {
|
|
57
|
-
return this.view_;
|
|
58
|
-
}
|
|
59
|
-
// Assigns `mat` to the camera view
|
|
60
|
-
set view(mat) {
|
|
61
|
-
mat4.copy(mat, this.view_);
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
// Returns column vector 0 of the camera matrix
|
|
65
|
-
get right() {
|
|
66
|
-
return this.right_;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
// Assigns `vec` to the first 3 elements of column vector 0 of the camera matrix
|
|
70
|
-
set right(vec) {
|
|
71
|
-
vec3.copy(vec, this.right_);
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
// Returns column vector 1 of the camera matrix
|
|
75
|
-
get up() {
|
|
76
|
-
return this.up_;
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
// Assigns `vec` to the first 3 elements of column vector 1 of the camera matrix \ Vec3
|
|
80
|
-
set up(vec) {
|
|
81
|
-
vec3.copy(vec, this.up_);
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
// Returns column vector 2 of the camera matrix
|
|
85
|
-
get back() {
|
|
86
|
-
return this.back_;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
// Assigns `vec` to the first 3 elements of column vector 2 of the camera matrix
|
|
90
|
-
set back(vec) {
|
|
91
|
-
vec3.copy(vec, this.back_);
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
// Returns column vector 3 of the camera matrix
|
|
95
|
-
get position() {
|
|
96
|
-
return this.position_;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
// Assigns `vec` to the first 3 elements of column vector 3 of the camera matrix
|
|
100
|
-
set position(vec) {
|
|
101
|
-
vec3.copy(vec, this.position_);
|
|
102
|
-
}
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
// WASDCamera is a camera implementation that behaves similar to first-person-shooter PC games.
|
|
106
|
-
export class WASDCamera extends CameraBase {
|
|
107
|
-
// The camera absolute pitch angle
|
|
108
|
-
pitch = 0;
|
|
109
|
-
// The camera absolute yaw angle
|
|
110
|
-
yaw = 0;
|
|
111
|
-
|
|
112
|
-
// The movement veloicty readonly
|
|
113
|
-
velocity_ = vec3.create();
|
|
114
|
-
|
|
115
|
-
// Speed multiplier for camera movement
|
|
116
|
-
movementSpeed = 10;
|
|
117
|
-
|
|
118
|
-
// Speed multiplier for camera rotation
|
|
119
|
-
rotationSpeed = 1;
|
|
120
|
-
|
|
121
|
-
// Movement velocity drag coeffient [0 .. 1]
|
|
122
|
-
// 0: Continues forever
|
|
123
|
-
// 1: Instantly stops moving
|
|
124
|
-
frictionCoefficient = 0.99;
|
|
125
|
-
|
|
126
|
-
// Returns velocity vector
|
|
127
|
-
get velocity() {
|
|
128
|
-
return this.velocity_;
|
|
129
|
-
}
|
|
130
|
-
// Assigns `vec` to the velocity vector
|
|
131
|
-
set velocity(vec) {
|
|
132
|
-
vec3.copy(vec, this.velocity_);
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
constructor(options) {
|
|
136
|
-
super();
|
|
137
|
-
if (options && (options.position || options.target)) {
|
|
138
|
-
const position = options.position ?? vec3.create(0, 0, 0);
|
|
139
|
-
const target = options.target ?? vec3.create(0, 0, 0);
|
|
140
|
-
const forward = vec3.normalize(vec3.sub(target, position));
|
|
141
|
-
this.recalculateAngles(forward);
|
|
142
|
-
this.position = position;
|
|
143
|
-
|
|
144
|
-
this.setProjection()
|
|
145
|
-
console.log(`%cCamera constructor : ${position}`, LOG_INFO);
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
// Returns the camera matrix
|
|
150
|
-
get matrix() {
|
|
151
|
-
return super.matrix;
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
// Assigns `mat` to the camera matrix, and recalcuates the camera angles
|
|
155
|
-
set matrix(mat) {
|
|
156
|
-
super.matrix = mat;
|
|
157
|
-
this.recalculateAngles(this.back);
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
update(deltaTime, input) {
|
|
161
|
-
const sign = (positive, negative) =>
|
|
162
|
-
(positive ? 1 : 0) - (negative ? 1 : 0);
|
|
163
|
-
|
|
164
|
-
// Apply the delta rotation to the pitch and yaw angles
|
|
165
|
-
this.yaw -= input.analog.x * deltaTime * this.rotationSpeed;
|
|
166
|
-
this.pitch -= input.analog.y * deltaTime * this.rotationSpeed;
|
|
167
|
-
|
|
168
|
-
// Wrap yaw between [0° .. 360°], just to prevent large accumulation.
|
|
169
|
-
this.yaw = mod(this.yaw, Math.PI * 2);
|
|
170
|
-
// Clamp pitch between [-90° .. +90°] to prevent somersaults.
|
|
171
|
-
this.pitch = clamp(this.pitch, -Math.PI / 2, Math.PI / 2);
|
|
172
|
-
|
|
173
|
-
// Save the current position, as we're about to rebuild the camera matrix.
|
|
174
|
-
const position = vec3.copy(this.position);
|
|
175
|
-
|
|
176
|
-
// Reconstruct the camera's rotation, and store into the camera matrix.
|
|
177
|
-
super.matrix = mat4.rotateX(mat4.rotationY(this.yaw), this.pitch);
|
|
178
|
-
// super.matrix = mat4.rotateX(mat4.rotationY(this.yaw), -this.pitch);
|
|
179
|
-
// super.matrix = mat4.rotateY(mat4.rotateX(this.pitch), this.yaw);
|
|
180
|
-
|
|
181
|
-
// Calculate the new target velocity
|
|
182
|
-
const digital = input.digital;
|
|
183
|
-
const deltaRight = sign(digital.right, digital.left);
|
|
184
|
-
const deltaUp = sign(digital.up, digital.down);
|
|
185
|
-
const targetVelocity = vec3.create();
|
|
186
|
-
const deltaBack = sign(digital.backward, digital.forward);
|
|
187
|
-
vec3.addScaled(targetVelocity, this.right, deltaRight, targetVelocity);
|
|
188
|
-
vec3.addScaled(targetVelocity, this.up, deltaUp, targetVelocity);
|
|
189
|
-
vec3.addScaled(targetVelocity, this.back, deltaBack, targetVelocity);
|
|
190
|
-
vec3.normalize(targetVelocity, targetVelocity);
|
|
191
|
-
vec3.mulScalar(targetVelocity, this.movementSpeed, targetVelocity);
|
|
192
|
-
|
|
193
|
-
// Mix new target velocity
|
|
194
|
-
this.velocity = lerp(
|
|
195
|
-
targetVelocity,
|
|
196
|
-
this.velocity,
|
|
197
|
-
Math.pow(1 - this.frictionCoefficient, deltaTime)
|
|
198
|
-
);
|
|
199
|
-
|
|
200
|
-
// Integrate velocity to calculate new position
|
|
201
|
-
this.position = vec3.addScaled(position, this.velocity, deltaTime);
|
|
202
|
-
|
|
203
|
-
// Invert the camera matrix to build the view matrix
|
|
204
|
-
this.view = mat4.invert(this.matrix);
|
|
205
|
-
return this.view;
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
// Recalculates the yaw and pitch values from a directional vector
|
|
209
|
-
recalculateAngles(dir) {
|
|
210
|
-
this.yaw = Math.atan2(dir[0], dir[2]);
|
|
211
|
-
this.pitch = -Math.asin(dir[1]);
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
|
|
215
|
-
// ArcballCamera implements a basic orbiting camera around the world origin
|
|
216
|
-
export class ArcballCamera extends CameraBase {
|
|
217
|
-
// The camera distance from the target
|
|
218
|
-
distance = 0;
|
|
219
|
-
|
|
220
|
-
// The current angular velocity
|
|
221
|
-
angularVelocity = 0;
|
|
222
|
-
|
|
223
|
-
// The current rotation axis
|
|
224
|
-
axis_ = vec3.create();
|
|
225
|
-
|
|
226
|
-
// Returns the rotation axis
|
|
227
|
-
get axis() {
|
|
228
|
-
return this.axis_;
|
|
229
|
-
}
|
|
230
|
-
// Assigns `vec` to the rotation axis
|
|
231
|
-
set axis(vec) {
|
|
232
|
-
vec3.copy(vec, this.axis_);
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
// Speed multiplier for camera rotation
|
|
236
|
-
rotationSpeed = 1;
|
|
237
|
-
|
|
238
|
-
// Speed multiplier for camera zoom
|
|
239
|
-
zoomSpeed = 0.1;
|
|
240
|
-
|
|
241
|
-
// Rotation velocity drag coeffient [0 .. 1]
|
|
242
|
-
// 0: Spins forever
|
|
243
|
-
// 1: Instantly stops spinning
|
|
244
|
-
frictionCoefficient = 0.999;
|
|
245
|
-
|
|
246
|
-
// Construtor
|
|
247
|
-
constructor(options) {
|
|
248
|
-
super();
|
|
249
|
-
if (options && options.position) {
|
|
250
|
-
this.position = options.position;
|
|
251
|
-
this.distance = vec3.len(this.position);
|
|
252
|
-
this.back = vec3.normalize(this.position);
|
|
253
|
-
this.recalcuateRight();
|
|
254
|
-
this.recalcuateUp();
|
|
255
|
-
}
|
|
256
|
-
}
|
|
257
|
-
|
|
258
|
-
// Returns the camera matrix
|
|
259
|
-
get matrix() {
|
|
260
|
-
return super.matrix;
|
|
261
|
-
}
|
|
262
|
-
|
|
263
|
-
// Assigns `mat` to the camera matrix, and recalcuates the distance
|
|
264
|
-
set matrix(mat) {
|
|
265
|
-
super.matrix = mat;
|
|
266
|
-
this.distance = vec3.len(this.position);
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
update(deltaTime, input) {
|
|
270
|
-
const epsilon = 0.0000001;
|
|
271
|
-
|
|
272
|
-
if (input.analog.touching) {
|
|
273
|
-
// Currently being dragged.
|
|
274
|
-
this.angularVelocity = 0;
|
|
275
|
-
} else {
|
|
276
|
-
// Dampen any existing angular velocity
|
|
277
|
-
this.angularVelocity *= Math.pow(1 - this.frictionCoefficient, deltaTime);
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
// Calculate the movement vector
|
|
281
|
-
const movement = vec3.create();
|
|
282
|
-
vec3.addScaled(movement, this.right, input.analog.x, movement);
|
|
283
|
-
vec3.addScaled(movement, this.up, -input.analog.y, movement);
|
|
284
|
-
|
|
285
|
-
// Cross the movement vector with the view direction to calculate the rotation axis x magnitude
|
|
286
|
-
const crossProduct = vec3.cross(movement, this.back);
|
|
287
|
-
|
|
288
|
-
// Calculate the magnitude of the drag
|
|
289
|
-
const magnitude = vec3.len(crossProduct);
|
|
290
|
-
|
|
291
|
-
if (magnitude > epsilon) {
|
|
292
|
-
// Normalize the crossProduct to get the rotation axis
|
|
293
|
-
this.axis = vec3.scale(crossProduct, 1 / magnitude);
|
|
294
|
-
|
|
295
|
-
// Remember the current angular velocity. This is used when the touch is released for a fling.
|
|
296
|
-
this.angularVelocity = magnitude * this.rotationSpeed;
|
|
297
|
-
}
|
|
298
|
-
|
|
299
|
-
// The rotation around this.axis to apply to the camera matrix this update
|
|
300
|
-
const rotationAngle = this.angularVelocity * deltaTime;
|
|
301
|
-
if (rotationAngle > epsilon) {
|
|
302
|
-
// Rotate the matrix around axis
|
|
303
|
-
// Note: The rotation is not done as a matrix-matrix multiply as the repeated multiplications
|
|
304
|
-
// will quickly introduce substantial error into the matrix.
|
|
305
|
-
this.back = vec3.normalize(rotate(this.back, this.axis, rotationAngle));
|
|
306
|
-
this.recalcuateRight();
|
|
307
|
-
this.recalcuateUp();
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
// recalculate `this.position` from `this.back` considering zoom
|
|
311
|
-
if (input.analog.zoom !== 0) {
|
|
312
|
-
this.distance *= 1 + input.analog.zoom * this.zoomSpeed;
|
|
313
|
-
}
|
|
314
|
-
this.position = vec3.scale(this.back, this.distance);
|
|
315
|
-
|
|
316
|
-
// Invert the camera matrix to build the view matrix
|
|
317
|
-
this.view = mat4.invert(this.matrix);
|
|
318
|
-
return this.view;
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
// Assigns `this.right` with the cross product of `this.up` and `this.back`
|
|
322
|
-
recalcuateRight() {
|
|
323
|
-
this.right = vec3.normalize(vec3.cross(this.up, this.back));
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
// Assigns `this.up` with the cross product of `this.back` and `this.right`
|
|
327
|
-
recalcuateUp() {
|
|
328
|
-
this.up = vec3.normalize(vec3.cross(this.back, this.right));
|
|
329
|
-
}
|
|
330
|
-
}
|
|
331
|
-
|
|
332
|
-
// Returns `x` clamped between [`min` .. `max`]
|
|
333
|
-
function clamp(x, min, max) {
|
|
334
|
-
return Math.min(Math.max(x, min), max);
|
|
335
|
-
}
|
|
336
|
-
|
|
337
|
-
// Returns `x` float-modulo `div`
|
|
338
|
-
function mod(x, div) {
|
|
339
|
-
return x - Math.floor(Math.abs(x) / div) * div * Math.sign(x);
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
// Returns `vec` rotated `angle` radians around `axis`
|
|
343
|
-
function rotate(vec, axis, angle) {
|
|
344
|
-
return vec3.transformMat4Upper3x3(vec, mat4.rotation(axis, angle));
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
// Returns the linear interpolation between 'a' and 'b' using 's'
|
|
348
|
-
function lerp(a, b, s) {
|
|
349
|
-
return vec3.addScaled(a, vec3.sub(b, a), s);
|
|
350
|
-
}
|
|
351
|
-
|
|
352
|
-
// Input holds as snapshot of input state
|
|
353
|
-
// export default interface Input {
|
|
354
|
-
// // Digital input (e.g keyboard state)
|
|
355
|
-
// readonly digital: {
|
|
356
|
-
// readonly forward: boolean;
|
|
357
|
-
// readonly backward: boolean;
|
|
358
|
-
// readonly left: boolean;
|
|
359
|
-
// readonly right: boolean;
|
|
360
|
-
// readonly up: boolean;
|
|
361
|
-
// readonly down: boolean;
|
|
362
|
-
// };
|
|
363
|
-
// // Analog input (e.g mouse, touchscreen)
|
|
364
|
-
// readonly analog: {
|
|
365
|
-
// readonly x: number;
|
|
366
|
-
// readonly y: number;
|
|
367
|
-
// readonly zoom: number;
|
|
368
|
-
// readonly touching: boolean;
|
|
369
|
-
// };
|
|
370
|
-
// }
|
|
371
|
-
// InputHandler is a function that when called, returns the current Input state.
|
|
372
|
-
// export type InputHandler = () => Input;
|
|
373
|
-
// createInputHandler returns an InputHandler by attaching event handlers to the window and canvas.
|
|
374
|
-
export function createInputHandler(window, canvas) {
|
|
375
|
-
let digital = {
|
|
376
|
-
forward: false,
|
|
377
|
-
backward: false,
|
|
378
|
-
left: false,
|
|
379
|
-
right: false,
|
|
380
|
-
up: false,
|
|
381
|
-
down: false,
|
|
382
|
-
};
|
|
383
|
-
let analog = {
|
|
384
|
-
x: 0,
|
|
385
|
-
y: 0,
|
|
386
|
-
zoom: 0,
|
|
387
|
-
};
|
|
388
|
-
let mouseDown = false;
|
|
389
|
-
|
|
390
|
-
const setDigital = (e, value) => {
|
|
391
|
-
switch (e.code) {
|
|
392
|
-
case 'KeyW':
|
|
393
|
-
digital.forward = value;
|
|
394
|
-
e.preventDefault();
|
|
395
|
-
e.stopPropagation();
|
|
396
|
-
break;
|
|
397
|
-
case 'KeyS':
|
|
398
|
-
digital.backward = value;
|
|
399
|
-
e.preventDefault();
|
|
400
|
-
e.stopPropagation();
|
|
401
|
-
break;
|
|
402
|
-
case 'KeyA':
|
|
403
|
-
digital.left = value;
|
|
404
|
-
e.preventDefault();
|
|
405
|
-
e.stopPropagation();
|
|
406
|
-
break;
|
|
407
|
-
case 'KeyD':
|
|
408
|
-
digital.right = value;
|
|
409
|
-
e.preventDefault();
|
|
410
|
-
e.stopPropagation();
|
|
411
|
-
break;
|
|
412
|
-
case 'Space':
|
|
413
|
-
digital.up = value;
|
|
414
|
-
e.preventDefault();
|
|
415
|
-
e.stopPropagation();
|
|
416
|
-
break;
|
|
417
|
-
case 'ShiftLeft':
|
|
418
|
-
case 'ControlLeft':
|
|
419
|
-
case 'KeyC':
|
|
420
|
-
digital.down = value;
|
|
421
|
-
e.preventDefault();
|
|
422
|
-
e.stopPropagation();
|
|
423
|
-
break;
|
|
424
|
-
}
|
|
425
|
-
};
|
|
426
|
-
|
|
427
|
-
window.addEventListener('keydown', (e) => setDigital(e, true));
|
|
428
|
-
window.addEventListener('keyup', (e) => setDigital(e, false));
|
|
429
|
-
|
|
430
|
-
canvas.style.touchAction = 'pinch-zoom';
|
|
431
|
-
canvas.addEventListener('pointerdown', () => {
|
|
432
|
-
mouseDown = true;
|
|
433
|
-
});
|
|
434
|
-
canvas.addEventListener('pointerup', () => {
|
|
435
|
-
mouseDown = false;
|
|
436
|
-
});
|
|
437
|
-
canvas.addEventListener('pointermove', (e) => {
|
|
438
|
-
mouseDown = e.pointerType == 'mouse' ? (e.buttons & 1) !== 0 : true;
|
|
439
|
-
if (mouseDown) {
|
|
440
|
-
// console.log('TEST ', analog)
|
|
441
|
-
analog.x += e.movementX / 10;
|
|
442
|
-
analog.y += e.movementY / 10;
|
|
443
|
-
}
|
|
444
|
-
});
|
|
445
|
-
canvas.addEventListener(
|
|
446
|
-
'wheel',
|
|
447
|
-
(e) => {
|
|
448
|
-
mouseDown = (e.buttons & 1) !== 0;
|
|
449
|
-
if (mouseDown) {
|
|
450
|
-
// The scroll value varies substantially between user agents / browsers.
|
|
451
|
-
// Just use the sign.
|
|
452
|
-
analog.zoom += Math.sign(e.deltaY);
|
|
453
|
-
e.preventDefault();
|
|
454
|
-
e.stopPropagation();
|
|
455
|
-
}
|
|
456
|
-
},
|
|
457
|
-
{ passive: false }
|
|
458
|
-
);
|
|
459
|
-
|
|
460
|
-
return () => {
|
|
461
|
-
const out = {
|
|
462
|
-
digital,
|
|
463
|
-
analog: {
|
|
464
|
-
x: analog.x,
|
|
465
|
-
y: analog.y,
|
|
466
|
-
zoom: analog.zoom,
|
|
467
|
-
touching: mouseDown,
|
|
468
|
-
},
|
|
469
|
-
};
|
|
470
|
-
// Clear the analog values, as these accumulate.
|
|
471
|
-
analog.x = 0;
|
|
472
|
-
analog.y = 0;
|
|
473
|
-
analog.zoom = 0;
|
|
474
|
-
return out;
|
|
475
|
-
};
|
|
476
|
-
}
|
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
import {computeSurfaceNormals, computeProjectedPlaneUVs} from './utils2.js';
|
|
2
|
-
|
|
3
|
-
export function adaptJSON1(dragonRawData) {
|
|
4
|
-
|
|
5
|
-
let mesh = {
|
|
6
|
-
positions: dragonRawData.positions,
|
|
7
|
-
triangles: dragonRawData.cells,
|
|
8
|
-
normals: [],
|
|
9
|
-
uvs: []
|
|
10
|
-
};
|
|
11
|
-
|
|
12
|
-
// Compute surface normals
|
|
13
|
-
mesh.normals = computeSurfaceNormals(mesh.positions, mesh.triangles);
|
|
14
|
-
|
|
15
|
-
// Compute some easy uvs for testing
|
|
16
|
-
mesh.uvs = computeProjectedPlaneUVs(mesh.positions, 'xy');
|
|
17
|
-
|
|
18
|
-
return mesh;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
export function addVerticesNormalUvs(mesh) {
|
|
22
|
-
|
|
23
|
-
var meshAdapted = {
|
|
24
|
-
positions: [],
|
|
25
|
-
cells: [],
|
|
26
|
-
uvs: mesh.textures,
|
|
27
|
-
vertices: mesh.vertices
|
|
28
|
-
// normals: mesh.vertexNormals
|
|
29
|
-
};
|
|
30
|
-
// force syntese
|
|
31
|
-
for (var x = 0; x < mesh.vertices.length; x=x+3) {
|
|
32
|
-
var sub = [];
|
|
33
|
-
sub.push(mesh.vertices[x])
|
|
34
|
-
sub.push(mesh.vertices[x+1])
|
|
35
|
-
sub.push(mesh.vertices[x+2])
|
|
36
|
-
meshAdapted.positions.push(sub)
|
|
37
|
-
sub = [];
|
|
38
|
-
sub.push(mesh.indices[x])
|
|
39
|
-
sub.push(mesh.indices[x+1])
|
|
40
|
-
sub.push(mesh.indices[x+2])
|
|
41
|
-
meshAdapted.cells.push(sub)
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
// Compute surface normals
|
|
45
|
-
meshAdapted.normals = computeSurfaceNormals(meshAdapted.positions, meshAdapted.cells);
|
|
46
|
-
// Compute some easy uvs for testing
|
|
47
|
-
meshAdapted.uvs = computeProjectedPlaneUVs(meshAdapted.positions, 'xy');
|
|
48
|
-
|
|
49
|
-
meshAdapted.triangles = meshAdapted.cells
|
|
50
|
-
return meshAdapted;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
import { vec3 } from 'wgpu-matrix';
|
|
2
|
-
|
|
3
|
-
export function computeSurfaceNormals(positions,triangles){
|
|
4
|
-
const normals = positions.map(() => {
|
|
5
|
-
// Initialize to zero.
|
|
6
|
-
return [0, 0, 0];
|
|
7
|
-
});
|
|
8
|
-
triangles.forEach(([i0, i1, i2]) => {
|
|
9
|
-
const p0 = positions[i0];
|
|
10
|
-
const p1 = positions[i1];
|
|
11
|
-
const p2 = positions[i2];
|
|
12
|
-
|
|
13
|
-
const v0 = vec3.subtract(p1, p0);
|
|
14
|
-
const v1 = vec3.subtract(p2, p0);
|
|
15
|
-
|
|
16
|
-
vec3.normalize(v0, v0);
|
|
17
|
-
vec3.normalize(v1, v1);
|
|
18
|
-
const norm = vec3.cross(v0, v1);
|
|
19
|
-
|
|
20
|
-
// Accumulate the normals.
|
|
21
|
-
vec3.add(normals[i0], norm, normals[i0]);
|
|
22
|
-
vec3.add(normals[i1], norm, normals[i1]);
|
|
23
|
-
vec3.add(normals[i2], norm, normals[i2]);
|
|
24
|
-
});
|
|
25
|
-
normals.forEach((n) => {
|
|
26
|
-
// Normalize accumulated normals.
|
|
27
|
-
vec3.normalize(n, n);
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
return normals;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
// type ProjectedPlane = 'xy' | 'xz' | 'yz';
|
|
34
|
-
const projectedPlane2Ids = {
|
|
35
|
-
xy: [0, 1],
|
|
36
|
-
xz: [0, 2],
|
|
37
|
-
yz: [1, 2],
|
|
38
|
-
};
|
|
39
|
-
|
|
40
|
-
export function computeProjectedPlaneUVs(positions, projectedPlane) {
|
|
41
|
-
const idxs = projectedPlane2Ids[projectedPlane];
|
|
42
|
-
const uvs = positions.map(() => {
|
|
43
|
-
// Initialize to zero.
|
|
44
|
-
return [0, 0];
|
|
45
|
-
});
|
|
46
|
-
const extentMin = [Infinity, Infinity];
|
|
47
|
-
const extentMax = [-Infinity, -Infinity];
|
|
48
|
-
positions.forEach((pos, i) => {
|
|
49
|
-
// Simply project to the selected plane
|
|
50
|
-
uvs[i][0] = pos[idxs[0]];
|
|
51
|
-
uvs[i][1] = pos[idxs[1]];
|
|
52
|
-
|
|
53
|
-
extentMin[0] = Math.min(pos[idxs[0]], extentMin[0]);
|
|
54
|
-
extentMin[1] = Math.min(pos[idxs[1]], extentMin[1]);
|
|
55
|
-
extentMax[0] = Math.max(pos[idxs[0]], extentMax[0]);
|
|
56
|
-
extentMax[1] = Math.max(pos[idxs[1]], extentMax[1]);
|
|
57
|
-
});
|
|
58
|
-
uvs.forEach((uv) => {
|
|
59
|
-
uv[0] = (uv[0] - extentMin[0]) / (extentMax[0] - extentMin[0]);
|
|
60
|
-
uv[1] = (uv[1] - extentMin[1]) / (extentMax[1] - extentMin[1]);
|
|
61
|
-
});
|
|
62
|
-
return uvs;
|
|
63
|
-
}
|
package/src/engine/lights.js
DELETED
|
@@ -1,126 +0,0 @@
|
|
|
1
|
-
import {mat4, vec3} from 'wgpu-matrix';
|
|
2
|
-
|
|
3
|
-
export class SpotLight {
|
|
4
|
-
position;
|
|
5
|
-
target;
|
|
6
|
-
up;
|
|
7
|
-
direction;
|
|
8
|
-
|
|
9
|
-
viewMatrix;
|
|
10
|
-
projectionMatrix;
|
|
11
|
-
viewProjMatrix;
|
|
12
|
-
|
|
13
|
-
fov;
|
|
14
|
-
aspect;
|
|
15
|
-
near;
|
|
16
|
-
far;
|
|
17
|
-
|
|
18
|
-
innerCutoff;
|
|
19
|
-
outerCutoff;
|
|
20
|
-
|
|
21
|
-
spotlightUniformBuffer;
|
|
22
|
-
|
|
23
|
-
constructor(
|
|
24
|
-
position = vec3.create(0, 5, 10),
|
|
25
|
-
target = vec3.create(0, 0, 0),
|
|
26
|
-
fov = 45,
|
|
27
|
-
aspect = 1.0,
|
|
28
|
-
near = 0.1,
|
|
29
|
-
far = 100
|
|
30
|
-
) {
|
|
31
|
-
this.position = position;
|
|
32
|
-
this.target = target;
|
|
33
|
-
this.up = vec3.create(0, 1, 0);
|
|
34
|
-
this.direction = vec3.normalize(vec3.subtract(target, position));
|
|
35
|
-
|
|
36
|
-
this.viewMatrix = mat4.lookAt(position, target, this.up);
|
|
37
|
-
this.projectionMatrix = mat4.perspective(
|
|
38
|
-
(fov * Math.PI) / 180,
|
|
39
|
-
aspect,
|
|
40
|
-
near,
|
|
41
|
-
far
|
|
42
|
-
);
|
|
43
|
-
this.viewProjMatrix = mat4.multiply(this.projectionMatrix, this.viewMatrix);
|
|
44
|
-
|
|
45
|
-
this.fov = fov;
|
|
46
|
-
this.aspect = aspect;
|
|
47
|
-
this.near = near;
|
|
48
|
-
this.far = far;
|
|
49
|
-
|
|
50
|
-
this.innerCutoff = Math.cos((Math.PI / 180) * 12.5);
|
|
51
|
-
this.outerCutoff = Math.cos((Math.PI / 180) * 17.5);
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
update() {
|
|
55
|
-
this.direction = vec3.normalize(vec3.subtract(this.target, this.position));
|
|
56
|
-
this.viewMatrix = mat4.lookAt(this.position, this.target, this.up);
|
|
57
|
-
this.viewProjMatrix = mat4.multiply(this.projectionMatrix, this.viewMatrix);
|
|
58
|
-
console.log('test light update this.position : ', this.position)
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
updateSceneUniforms = (sceneUniformBuffer, camera, inputHandler) => {
|
|
62
|
-
|
|
63
|
-
console.log('test camera.view ', camera.view)
|
|
64
|
-
// Update spotlight matrices
|
|
65
|
-
this.update();
|
|
66
|
-
|
|
67
|
-
const now = Date.now();
|
|
68
|
-
|
|
69
|
-
// Get camera matrices
|
|
70
|
-
camera.update(now, inputHandler()); // Your camera class should also update view/projection
|
|
71
|
-
const camVP = mat4.multiply(camera.projectionMatrix, camera.view);
|
|
72
|
-
|
|
73
|
-
// Prepare float data
|
|
74
|
-
const sceneData = new Float32Array(16 + 16 + 4); // 2 matrices + vec3
|
|
75
|
-
|
|
76
|
-
// Light view-proj matrix
|
|
77
|
-
sceneData.set(this.viewProjMatrix, 0);
|
|
78
|
-
|
|
79
|
-
// Camera view-proj matrix
|
|
80
|
-
sceneData.set(camVP, 16);
|
|
81
|
-
|
|
82
|
-
// Light position (vec3f + padding)
|
|
83
|
-
sceneData.set(this.position, 32);
|
|
84
|
-
|
|
85
|
-
// Write to GPU
|
|
86
|
-
this.device.queue.writeBuffer(
|
|
87
|
-
sceneUniformBuffer,
|
|
88
|
-
0,
|
|
89
|
-
sceneData.buffer,
|
|
90
|
-
sceneData.byteOffset,
|
|
91
|
-
sceneData.byteLength
|
|
92
|
-
);
|
|
93
|
-
|
|
94
|
-
console.log('light.viewProj[0..3]', this.viewProjMatrix.slice(0, 4));
|
|
95
|
-
console.log('camera.vp[0..3]', camVP.slice(0, 4));
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
prepareBuffer(device) {
|
|
99
|
-
this.device = device;
|
|
100
|
-
this.spotlightUniformBuffer = device.createBuffer({
|
|
101
|
-
size: 16 * 4, // 64 bytes
|
|
102
|
-
usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST,
|
|
103
|
-
});
|
|
104
|
-
|
|
105
|
-
const spotlightData = this.getLightDataBuffer();
|
|
106
|
-
|
|
107
|
-
device.queue.writeBuffer(
|
|
108
|
-
this.spotlightUniformBuffer,
|
|
109
|
-
0,
|
|
110
|
-
spotlightData.buffer,
|
|
111
|
-
spotlightData.byteOffset,
|
|
112
|
-
spotlightData.byteLength
|
|
113
|
-
);
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
getLightDataBuffer() {
|
|
117
|
-
return new Float32Array([
|
|
118
|
-
...this.position, 0.0,
|
|
119
|
-
...this.direction, 0.0,
|
|
120
|
-
this.innerCutoff,
|
|
121
|
-
this.outerCutoff,
|
|
122
|
-
0.0,
|
|
123
|
-
0.0,
|
|
124
|
-
]);
|
|
125
|
-
}
|
|
126
|
-
}
|