simulationjsv2 0.5.1 → 0.6.0
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/TODO.md +11 -3
- package/dist/constants.d.ts +9 -4
- package/dist/constants.js +10 -4
- package/dist/geometry.d.ts +15 -9
- package/dist/geometry.js +54 -25
- package/dist/graphics.d.ts +30 -42
- package/dist/graphics.js +148 -199
- package/dist/internalUtils.d.ts +9 -6
- package/dist/internalUtils.js +61 -24
- package/dist/simulation.d.ts +15 -6
- package/dist/simulation.js +152 -188
- package/dist/types.d.ts +9 -13
- package/dist/utils.d.ts +1 -0
- package/dist/utils.js +6 -2
- package/package.json +1 -1
package/dist/simulation.js
CHANGED
|
@@ -1,64 +1,40 @@
|
|
|
1
1
|
import { vec3 } from 'wgpu-matrix';
|
|
2
2
|
import { Instance, SimulationElement3d } from './graphics.js';
|
|
3
|
-
import { BUF_LEN } from './constants.js';
|
|
4
|
-
import { Color, toSceneObjInfoMany, transitionValues, vector2, vector3 } from './utils.js';
|
|
3
|
+
import { BUF_LEN, worldProjMatOffset } from './constants.js';
|
|
4
|
+
import { Color, matrix4, toSceneObjInfoMany, transitionValues, vector2, vector3 } from './utils.js';
|
|
5
5
|
import { BlankGeometry } from './geometry.js';
|
|
6
|
-
import { addObject, buildDepthTexture, buildMultisampleTexture,
|
|
6
|
+
import { addObject, buildDepthTexture, buildMultisampleTexture, updateProjectionMatrix, createPipeline, getTotalVertices, logger, removeObject, removeObjectId, updateOrthoProjectionMatrix, updateWorldProjectionMatrix, wrapVoidPromise } from './internalUtils.js';
|
|
7
7
|
const shader = `
|
|
8
8
|
struct Uniforms {
|
|
9
|
-
|
|
10
|
-
|
|
9
|
+
worldProjectionMatrix: mat4x4<f32>,
|
|
10
|
+
modelProjectionMatrix: mat4x4<f32>,
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
@group(0) @binding(0) var<uniform> uniforms
|
|
13
|
+
@group(0) @binding(0) var<uniform> uniforms: Uniforms;
|
|
14
14
|
|
|
15
|
-
@group(0) @binding(1) var<storage> instanceMatrices
|
|
15
|
+
@group(0) @binding(1) var<storage> instanceMatrices: array<mat4x4f>;
|
|
16
16
|
|
|
17
17
|
struct VertexOutput {
|
|
18
|
-
@builtin(position) Position
|
|
19
|
-
@location(0) fragUV
|
|
20
|
-
@location(1) fragColor
|
|
18
|
+
@builtin(position) Position: vec4<f32>,
|
|
19
|
+
@location(0) fragUV: vec2<f32>,
|
|
20
|
+
@location(1) fragColor: vec4<f32>,
|
|
21
21
|
@location(2) fragPosition: vec4<f32>,
|
|
22
22
|
}
|
|
23
23
|
|
|
24
24
|
@vertex
|
|
25
|
-
fn
|
|
26
|
-
@builtin(instance_index) instanceIdx
|
|
27
|
-
@location(0) position
|
|
28
|
-
@location(1) color
|
|
29
|
-
@location(2) uv
|
|
30
|
-
@location(3) drawingInstance: f32
|
|
31
|
-
) -> VertexOutput {
|
|
32
|
-
var output : VertexOutput;
|
|
33
|
-
|
|
34
|
-
if (drawingInstance == 1) {
|
|
35
|
-
let transformedPos = instanceMatrices[instanceIdx] * position;
|
|
36
|
-
output.Position = uniforms.modelViewProjectionMatrix * transformedPos;
|
|
37
|
-
} else {
|
|
38
|
-
output.Position = uniforms.modelViewProjectionMatrix * position;
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
output.fragUV = uv;
|
|
42
|
-
output.fragPosition = output.Position;
|
|
43
|
-
output.fragColor = color;
|
|
44
|
-
return output;
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
@vertex
|
|
48
|
-
fn vertex_main_2d(
|
|
49
|
-
@builtin(instance_index) instanceIdx : u32,
|
|
50
|
-
@location(0) position : vec4<f32>,
|
|
51
|
-
@location(1) color : vec4<f32>,
|
|
52
|
-
@location(2) uv : vec2<f32>,
|
|
25
|
+
fn vertex_main(
|
|
26
|
+
@builtin(instance_index) instanceIdx: u32,
|
|
27
|
+
@location(0) position: vec3<f32>,
|
|
28
|
+
@location(1) color: vec4<f32>,
|
|
29
|
+
@location(2) uv: vec2<f32>,
|
|
53
30
|
@location(3) drawingInstance: f32
|
|
54
31
|
) -> VertexOutput {
|
|
55
32
|
var output: VertexOutput;
|
|
56
33
|
|
|
57
34
|
if (drawingInstance == 1) {
|
|
58
|
-
|
|
59
|
-
output.Position = uniforms.orthoProjectionMatrix * transformedPos;
|
|
35
|
+
output.Position = uniforms.worldProjectionMatrix * uniforms.modelProjectionMatrix * instanceMatrices[instanceIdx] * vec4(position, 1.0);
|
|
60
36
|
} else {
|
|
61
|
-
output.Position = uniforms.
|
|
37
|
+
output.Position = uniforms.worldProjectionMatrix * uniforms.modelProjectionMatrix * vec4(position, 1.0);
|
|
62
38
|
}
|
|
63
39
|
|
|
64
40
|
output.fragUV = uv;
|
|
@@ -117,6 +93,28 @@ class FrameRateView {
|
|
|
117
93
|
}
|
|
118
94
|
}
|
|
119
95
|
}
|
|
96
|
+
const baseBindGroupLayout = {
|
|
97
|
+
entries: [
|
|
98
|
+
{
|
|
99
|
+
binding: 0,
|
|
100
|
+
visibility: GPUShaderStage.VERTEX | GPUShaderStage.FRAGMENT,
|
|
101
|
+
buffer: {
|
|
102
|
+
type: 'uniform'
|
|
103
|
+
}
|
|
104
|
+
},
|
|
105
|
+
{
|
|
106
|
+
binding: 1,
|
|
107
|
+
visibility: GPUShaderStage.VERTEX,
|
|
108
|
+
buffer: {
|
|
109
|
+
type: 'read-only-storage'
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
]
|
|
113
|
+
};
|
|
114
|
+
let aspectRatio = 0;
|
|
115
|
+
const projMat = matrix4();
|
|
116
|
+
const worldProjMat = matrix4();
|
|
117
|
+
const orthoMatrix = matrix4();
|
|
120
118
|
export class Simulation {
|
|
121
119
|
canvasRef = null;
|
|
122
120
|
bgColor = new Color(255, 255, 255);
|
|
@@ -237,7 +235,7 @@ export class Simulation {
|
|
|
237
235
|
propagateDevice(device) {
|
|
238
236
|
for (let i = 0; i < this.scene.length; i++) {
|
|
239
237
|
const el = this.scene[i].getObj();
|
|
240
|
-
if (el instanceof
|
|
238
|
+
if (el instanceof SceneCollection) {
|
|
241
239
|
el.setDevice(device);
|
|
242
240
|
}
|
|
243
241
|
}
|
|
@@ -268,64 +266,21 @@ export class Simulation {
|
|
|
268
266
|
format: presentationFormat,
|
|
269
267
|
alphaMode: 'premultiplied'
|
|
270
268
|
});
|
|
271
|
-
const uniformBufferSize = 4 * 16 + 4 * 16 + 4 * 2 + 8; // 4x4 matrix + 4x4 matrix + vec2<f32> + 8 bc 144 is cool
|
|
272
|
-
const uniformBuffer = device.createBuffer({
|
|
273
|
-
size: uniformBufferSize,
|
|
274
|
-
usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST
|
|
275
|
-
});
|
|
276
269
|
const instanceBuffer = device.createBuffer({
|
|
277
270
|
size: 10 * 4 * 16,
|
|
278
271
|
usage: GPUBufferUsage.STORAGE
|
|
279
272
|
});
|
|
280
|
-
const bindGroupLayout = device.createBindGroupLayout(
|
|
281
|
-
entries: [
|
|
282
|
-
{
|
|
283
|
-
binding: 0,
|
|
284
|
-
visibility: GPUShaderStage.VERTEX,
|
|
285
|
-
buffer: {
|
|
286
|
-
type: 'uniform'
|
|
287
|
-
}
|
|
288
|
-
},
|
|
289
|
-
{
|
|
290
|
-
binding: 1,
|
|
291
|
-
visibility: GPUShaderStage.VERTEX,
|
|
292
|
-
buffer: {
|
|
293
|
-
type: 'read-only-storage'
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
]
|
|
297
|
-
});
|
|
273
|
+
const bindGroupLayout = device.createBindGroupLayout(baseBindGroupLayout);
|
|
298
274
|
this.renderInfo = {
|
|
299
|
-
uniformBuffer,
|
|
300
275
|
bindGroupLayout,
|
|
301
276
|
instanceBuffer,
|
|
302
277
|
vertexBuffer: null
|
|
303
278
|
};
|
|
304
279
|
this.pipelines = {
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
triangleList3d: createPipeline(device, shaderModule, [bindGroupLayout], presentationFormat, 'vertex_main_3d', 'triangle-list'),
|
|
309
|
-
triangleStrip3d: createPipeline(device, shaderModule, [bindGroupLayout], presentationFormat, 'vertex_main_3d', 'triangle-strip'),
|
|
310
|
-
lineStrip3d: createPipeline(device, shaderModule, [bindGroupLayout], presentationFormat, 'vertex_main_3d', 'line-strip')
|
|
280
|
+
triangleList: createPipeline(device, shaderModule, [bindGroupLayout], presentationFormat, 'triangle-list'),
|
|
281
|
+
triangleStrip: createPipeline(device, shaderModule, [bindGroupLayout], presentationFormat, 'triangle-strip'),
|
|
282
|
+
lineStrip: createPipeline(device, shaderModule, [bindGroupLayout], presentationFormat, 'line-strip')
|
|
311
283
|
};
|
|
312
|
-
const uniformBindGroup = device.createBindGroup({
|
|
313
|
-
layout: bindGroupLayout,
|
|
314
|
-
entries: [
|
|
315
|
-
{
|
|
316
|
-
binding: 0,
|
|
317
|
-
resource: {
|
|
318
|
-
buffer: uniformBuffer
|
|
319
|
-
}
|
|
320
|
-
},
|
|
321
|
-
{
|
|
322
|
-
binding: 1,
|
|
323
|
-
resource: {
|
|
324
|
-
buffer: instanceBuffer
|
|
325
|
-
}
|
|
326
|
-
}
|
|
327
|
-
]
|
|
328
|
-
});
|
|
329
284
|
const colorAttachment = {
|
|
330
285
|
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
331
286
|
// @ts-ignore
|
|
@@ -334,18 +289,13 @@ export class Simulation {
|
|
|
334
289
|
loadOp: 'clear',
|
|
335
290
|
storeOp: 'store'
|
|
336
291
|
};
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
updateModelViewProjectionMatrix();
|
|
345
|
-
const updateOrthoMatrix = () => {
|
|
346
|
-
orthoMatrix = getOrthoMatrix(this.camera.getScreenSize());
|
|
347
|
-
};
|
|
348
|
-
updateOrthoMatrix();
|
|
292
|
+
const newAspectRatio = canvas.width / canvas.height;
|
|
293
|
+
if (newAspectRatio !== aspectRatio) {
|
|
294
|
+
updateProjectionMatrix(projMat, newAspectRatio);
|
|
295
|
+
aspectRatio = newAspectRatio;
|
|
296
|
+
}
|
|
297
|
+
updateWorldProjectionMatrix(worldProjMat, projMat, this.camera);
|
|
298
|
+
updateOrthoProjectionMatrix(orthoMatrix, this.camera.getScreenSize());
|
|
349
299
|
let multisampleTexture = buildMultisampleTexture(device, ctx, canvas.width, canvas.height);
|
|
350
300
|
let depthTexture = buildDepthTexture(device, canvas.width, canvas.height);
|
|
351
301
|
const renderPassDescriptor = {
|
|
@@ -383,9 +333,9 @@ export class Simulation {
|
|
|
383
333
|
this.camera.setScreenSize(vector2(canvas.width, canvas.height));
|
|
384
334
|
screenSize[0] = canvas.width;
|
|
385
335
|
screenSize[1] = canvas.height;
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
336
|
+
aspectRatio = this.camera.getAspectRatio();
|
|
337
|
+
updateProjectionMatrix(projMat, aspectRatio);
|
|
338
|
+
updateWorldProjectionMatrix(worldProjMat, projMat, this.camera);
|
|
389
339
|
multisampleTexture = buildMultisampleTexture(device, ctx, screenSize[0], screenSize[1]);
|
|
390
340
|
depthTexture = buildDepthTexture(device, screenSize[0], screenSize[1]);
|
|
391
341
|
renderPassDescriptor.depthStencilAttachment.view = depthTexture.createView();
|
|
@@ -397,16 +347,12 @@ export class Simulation {
|
|
|
397
347
|
// @ts-ignore
|
|
398
348
|
renderPassDescriptor.colorAttachments[0].resolveTarget = ctx.getCurrentTexture().createView();
|
|
399
349
|
if (this.camera.hasUpdated()) {
|
|
400
|
-
|
|
401
|
-
|
|
350
|
+
updateOrthoProjectionMatrix(orthoMatrix, this.camera.getScreenSize());
|
|
351
|
+
updateWorldProjectionMatrix(worldProjMat, projMat, this.camera);
|
|
402
352
|
}
|
|
403
|
-
device.queue.writeBuffer(uniformBuffer, 0, modelViewProjectionMatrix.buffer, modelViewProjectionMatrix.byteOffset, modelViewProjectionMatrix.byteLength);
|
|
404
|
-
device.queue.writeBuffer(uniformBuffer, 4 * 16, // 4x4 matrix
|
|
405
|
-
orthoMatrix.buffer, orthoMatrix.byteOffset, orthoMatrix.byteLength);
|
|
406
353
|
const commandEncoder = device.createCommandEncoder();
|
|
407
354
|
const passEncoder = commandEncoder.beginRenderPass(renderPassDescriptor);
|
|
408
|
-
passEncoder.setPipeline(this.pipelines.
|
|
409
|
-
passEncoder.setBindGroup(0, uniformBindGroup);
|
|
355
|
+
passEncoder.setPipeline(this.pipelines.triangleList);
|
|
410
356
|
const totalVertices = getTotalVertices(this.scene);
|
|
411
357
|
if (this.renderInfo.vertexBuffer === null ||
|
|
412
358
|
this.renderInfo.vertexBuffer.size / (4 * BUF_LEN) < totalVertices) {
|
|
@@ -458,66 +404,63 @@ export class Simulation {
|
|
|
458
404
|
currentOffset += this.renderScene(device, passEncoder, vertexBuffer, obj.getScene(), currentOffset, diff, shaderInfo || undefined);
|
|
459
405
|
continue;
|
|
460
406
|
}
|
|
461
|
-
const buffer = new Float32Array(obj.getBuffer(
|
|
407
|
+
const buffer = new Float32Array(obj.getBuffer(shaderInfo?.paramGenerator));
|
|
462
408
|
const bufLen = shaderInfo?.paramGenerator?.bufferSize || BUF_LEN;
|
|
463
409
|
const vertexCount = buffer.length / bufLen;
|
|
464
410
|
device.queue.writeBuffer(vertexBuffer, currentOffset, buffer);
|
|
465
411
|
vertexBuffer.unmap();
|
|
466
|
-
|
|
412
|
+
passEncoder.setVertexBuffer(0, vertexBuffer, currentOffset, buffer.byteLength);
|
|
413
|
+
const modelMatrix = obj.getModelMatrix(this.camera);
|
|
414
|
+
const uniformBuffer = obj.getUniformBuffer(device, modelMatrix);
|
|
415
|
+
if (obj.is3d) {
|
|
416
|
+
device.queue.writeBuffer(uniformBuffer, worldProjMatOffset, worldProjMat.buffer, worldProjMat.byteOffset, worldProjMat.byteLength);
|
|
417
|
+
}
|
|
418
|
+
else {
|
|
419
|
+
device.queue.writeBuffer(uniformBuffer, worldProjMatOffset, orthoMatrix.buffer, orthoMatrix.byteOffset, orthoMatrix.byteLength);
|
|
420
|
+
}
|
|
467
421
|
if (shaderInfo) {
|
|
468
422
|
passEncoder.setPipeline(shaderInfo.pipeline);
|
|
469
423
|
}
|
|
470
424
|
else if (obj.isWireframe()) {
|
|
471
|
-
|
|
472
|
-
passEncoder.setPipeline(this.pipelines.lineStrip3d);
|
|
473
|
-
}
|
|
474
|
-
else {
|
|
475
|
-
passEncoder.setPipeline(this.pipelines.lineStrip2d);
|
|
476
|
-
}
|
|
425
|
+
passEncoder.setPipeline(this.pipelines.lineStrip);
|
|
477
426
|
}
|
|
478
427
|
else {
|
|
479
428
|
const type = obj.getGeometryType();
|
|
480
429
|
if (type === 'strip') {
|
|
481
|
-
|
|
482
|
-
passEncoder.setPipeline(this.pipelines.triangleStrip3d);
|
|
483
|
-
}
|
|
484
|
-
else {
|
|
485
|
-
passEncoder.setPipeline(this.pipelines.triangleStrip2d);
|
|
486
|
-
}
|
|
430
|
+
passEncoder.setPipeline(this.pipelines.triangleStrip);
|
|
487
431
|
}
|
|
488
432
|
else if (type === 'list') {
|
|
489
|
-
|
|
490
|
-
passEncoder.setPipeline(this.pipelines.triangleList3d);
|
|
491
|
-
}
|
|
492
|
-
else {
|
|
493
|
-
passEncoder.setPipeline(this.pipelines.triangleList2d);
|
|
494
|
-
}
|
|
433
|
+
passEncoder.setPipeline(this.pipelines.triangleList);
|
|
495
434
|
}
|
|
496
435
|
}
|
|
497
436
|
let instances = 1;
|
|
498
|
-
if (
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
binding: 0,
|
|
507
|
-
resource: {
|
|
508
|
-
buffer: this.renderInfo.uniformBuffer
|
|
509
|
-
}
|
|
510
|
-
},
|
|
511
|
-
{
|
|
512
|
-
binding: 1,
|
|
513
|
-
resource: {
|
|
514
|
-
buffer: buf
|
|
515
|
-
}
|
|
516
|
-
}
|
|
517
|
-
]
|
|
518
|
-
});
|
|
519
|
-
passEncoder.setBindGroup(0, uniformBindGroup);
|
|
437
|
+
if (this.renderInfo) {
|
|
438
|
+
let instanceBuffer;
|
|
439
|
+
if (obj instanceof Instance) {
|
|
440
|
+
instances = obj.getNumInstances();
|
|
441
|
+
instanceBuffer = obj.getMatrixBuffer(device);
|
|
442
|
+
}
|
|
443
|
+
else {
|
|
444
|
+
instanceBuffer = this.renderInfo.instanceBuffer;
|
|
520
445
|
}
|
|
446
|
+
const uniformBindGroup = device.createBindGroup({
|
|
447
|
+
layout: this.renderInfo.bindGroupLayout,
|
|
448
|
+
entries: [
|
|
449
|
+
{
|
|
450
|
+
binding: 0,
|
|
451
|
+
resource: {
|
|
452
|
+
buffer: uniformBuffer
|
|
453
|
+
}
|
|
454
|
+
},
|
|
455
|
+
{
|
|
456
|
+
binding: 1,
|
|
457
|
+
resource: {
|
|
458
|
+
buffer: instanceBuffer
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
]
|
|
462
|
+
});
|
|
463
|
+
passEncoder.setBindGroup(0, uniformBindGroup);
|
|
521
464
|
}
|
|
522
465
|
if (shaderInfo && shaderInfo.bufferInfo) {
|
|
523
466
|
const bindGroupEntries = shaderInfo.bufferInfo.buffers.map((buffer, index) => ({
|
|
@@ -532,7 +475,7 @@ export class Simulation {
|
|
|
532
475
|
});
|
|
533
476
|
passEncoder.setBindGroup(1, bindGroup);
|
|
534
477
|
}
|
|
535
|
-
|
|
478
|
+
// TODO maybe switch to drawIndexed
|
|
536
479
|
passEncoder.draw(vertexCount, instances, 0, 0);
|
|
537
480
|
currentOffset += buffer.byteLength;
|
|
538
481
|
}
|
|
@@ -565,8 +508,12 @@ export class SceneCollection extends SimulationElement3d {
|
|
|
565
508
|
this.scene = [];
|
|
566
509
|
this.geometry = new BlankGeometry();
|
|
567
510
|
}
|
|
568
|
-
|
|
569
|
-
|
|
511
|
+
setWireframe(wireframe) {
|
|
512
|
+
this.wireframe = wireframe;
|
|
513
|
+
for (let i = 0; i < this.scene.length; i++) {
|
|
514
|
+
this.scene[i].getObj().setWireframe(wireframe);
|
|
515
|
+
}
|
|
516
|
+
}
|
|
570
517
|
getName() {
|
|
571
518
|
return this.name;
|
|
572
519
|
}
|
|
@@ -580,7 +527,7 @@ export class SceneCollection extends SimulationElement3d {
|
|
|
580
527
|
propagateDevice(device) {
|
|
581
528
|
for (let i = 0; i < this.scene.length; i++) {
|
|
582
529
|
const el = this.scene[i].getObj();
|
|
583
|
-
if (el instanceof
|
|
530
|
+
if (el instanceof SceneCollection) {
|
|
584
531
|
el.setDevice(device);
|
|
585
532
|
}
|
|
586
533
|
}
|
|
@@ -622,16 +569,14 @@ export class SceneCollection extends SimulationElement3d {
|
|
|
622
569
|
empty() {
|
|
623
570
|
this.scene = [];
|
|
624
571
|
}
|
|
625
|
-
getSceneBuffer(
|
|
626
|
-
return this.scene.map((item) => item.getObj().getBuffer(
|
|
572
|
+
getSceneBuffer() {
|
|
573
|
+
return this.scene.map((item) => item.getObj().getBuffer()).flat();
|
|
627
574
|
}
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
return this.getSceneBuffer(camera);
|
|
575
|
+
getWireframe() {
|
|
576
|
+
return this.getSceneBuffer();
|
|
631
577
|
}
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
return this.getSceneBuffer(camera);
|
|
578
|
+
getTriangles() {
|
|
579
|
+
return this.getSceneBuffer();
|
|
635
580
|
}
|
|
636
581
|
updateMatrix(camera) {
|
|
637
582
|
this.defaultUpdateMatrix(camera);
|
|
@@ -726,13 +671,13 @@ export class Camera {
|
|
|
726
671
|
}
|
|
727
672
|
const defaultShaderCode = `
|
|
728
673
|
struct Uniforms {
|
|
729
|
-
|
|
730
|
-
|
|
674
|
+
worldProjectionMatrix: mat4x4<f32>,
|
|
675
|
+
modelProjectionMatrix: mat4x4<f32>,
|
|
731
676
|
}
|
|
732
677
|
|
|
733
|
-
@group(0) @binding(0) var<uniform> uniforms
|
|
678
|
+
@group(0) @binding(0) var<uniform> uniforms: Uniforms;
|
|
734
679
|
|
|
735
|
-
@group(0) @binding(1) var<storage
|
|
680
|
+
@group(0) @binding(1) var<storage> instanceMatrices: array<mat4x4f>;
|
|
736
681
|
`;
|
|
737
682
|
export class ShaderGroup extends SceneCollection {
|
|
738
683
|
geometry;
|
|
@@ -762,24 +707,7 @@ export class ShaderGroup extends SceneCollection {
|
|
|
762
707
|
super.propagateDevice(device);
|
|
763
708
|
this.module = device.createShaderModule({ code: this.code });
|
|
764
709
|
const presentationFormat = navigator.gpu.getPreferredCanvasFormat();
|
|
765
|
-
const bindGroupLayout = device.createBindGroupLayout(
|
|
766
|
-
entries: [
|
|
767
|
-
{
|
|
768
|
-
binding: 0,
|
|
769
|
-
visibility: GPUShaderStage.VERTEX,
|
|
770
|
-
buffer: {
|
|
771
|
-
type: 'uniform'
|
|
772
|
-
}
|
|
773
|
-
},
|
|
774
|
-
{
|
|
775
|
-
binding: 1,
|
|
776
|
-
visibility: GPUShaderStage.VERTEX,
|
|
777
|
-
buffer: {
|
|
778
|
-
type: 'read-only-storage'
|
|
779
|
-
}
|
|
780
|
-
}
|
|
781
|
-
]
|
|
782
|
-
});
|
|
710
|
+
const bindGroupLayout = device.createBindGroupLayout(baseBindGroupLayout);
|
|
783
711
|
const bindGroups = [bindGroupLayout];
|
|
784
712
|
if (this.bindGroup !== null) {
|
|
785
713
|
const entryValues = this.bindGroup.bindings.map((binding, index) => ({
|
|
@@ -792,7 +720,7 @@ export class ShaderGroup extends SceneCollection {
|
|
|
792
720
|
});
|
|
793
721
|
bindGroups.push(this.bindGroupLayout);
|
|
794
722
|
}
|
|
795
|
-
this.pipeline = createPipeline(device, this.module, bindGroups, presentationFormat,
|
|
723
|
+
this.pipeline = createPipeline(device, this.module, bindGroups, presentationFormat, this.topology, this.vertexParams);
|
|
796
724
|
}
|
|
797
725
|
getBindGroupLayout() {
|
|
798
726
|
return this.bindGroupLayout;
|
|
@@ -852,3 +780,39 @@ export class ShaderGroup extends SceneCollection {
|
|
|
852
780
|
return !!this.bindGroup;
|
|
853
781
|
}
|
|
854
782
|
}
|
|
783
|
+
export class Group extends SceneCollection {
|
|
784
|
+
constructor(name) {
|
|
785
|
+
super(name);
|
|
786
|
+
}
|
|
787
|
+
move(amount, t, f) {
|
|
788
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
789
|
+
// @ts-ignore
|
|
790
|
+
return this.loopElements((el) => el.move(amount, t, f));
|
|
791
|
+
}
|
|
792
|
+
moveTo(pos, t, f) {
|
|
793
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
794
|
+
// @ts-ignore
|
|
795
|
+
return this.loopElements((el) => el.moveTo(pos, t, f));
|
|
796
|
+
}
|
|
797
|
+
rotate(amount, t, f) {
|
|
798
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
799
|
+
// @ts-ignore
|
|
800
|
+
return this.loopElements((el) => el.rotate(amount, t, f));
|
|
801
|
+
}
|
|
802
|
+
rotateTo(rotation, t, f) {
|
|
803
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
804
|
+
// @ts-ignore
|
|
805
|
+
return this.loopElements((el) => el.rotateTo(rotation, t, f));
|
|
806
|
+
}
|
|
807
|
+
fill(newColor, t, f) {
|
|
808
|
+
return this.loopElements((el) => el.fill(newColor, t, f));
|
|
809
|
+
}
|
|
810
|
+
loopElements(cb) {
|
|
811
|
+
const scene = this.getScene();
|
|
812
|
+
const promises = Array(scene.length);
|
|
813
|
+
for (let i = 0; i < scene.length; i++) {
|
|
814
|
+
promises[i] = cb(scene[i].getObj());
|
|
815
|
+
}
|
|
816
|
+
return wrapVoidPromise(Promise.all(promises));
|
|
817
|
+
}
|
|
818
|
+
}
|
package/dist/types.d.ts
CHANGED
|
@@ -23,6 +23,7 @@ export type Mat4 = FloatArray & [
|
|
|
23
23
|
number,
|
|
24
24
|
number
|
|
25
25
|
];
|
|
26
|
+
export type Quat = Float32Array & [number, number, number, number];
|
|
26
27
|
export type LerpFunc = (n: number) => number;
|
|
27
28
|
export type VertexColorMap = Record<number, Color>;
|
|
28
29
|
export type ElementRotation<T extends Vector2 | Vector3> = T extends Vector2 ? number : T;
|
|
@@ -54,26 +55,22 @@ export type Spline2dGeometryParams = {
|
|
|
54
55
|
color: Color;
|
|
55
56
|
vertexColors: Color[];
|
|
56
57
|
};
|
|
57
|
-
export type LineGeometryParams
|
|
58
|
-
pos:
|
|
59
|
-
to:
|
|
58
|
+
export type LineGeometryParams = {
|
|
59
|
+
pos: Vector3;
|
|
60
|
+
to: Vector3;
|
|
61
|
+
fromColor: Color | null;
|
|
62
|
+
toColor: Color | null;
|
|
60
63
|
thickness: number;
|
|
61
64
|
};
|
|
62
|
-
export type Line2dGeometryParams = LineGeometryParams<Vector2>;
|
|
63
|
-
export type Line3dGeometryParams = LineGeometryParams<Vector3>;
|
|
64
65
|
export type PolygonGeometryParams = {
|
|
65
66
|
points: Vertex[];
|
|
66
67
|
};
|
|
67
68
|
export type PipelineGroup = {
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
triangleList3d: GPURenderPipeline;
|
|
72
|
-
triangleStrip3d: GPURenderPipeline;
|
|
73
|
-
lineStrip3d: GPURenderPipeline;
|
|
69
|
+
triangleList: GPURenderPipeline;
|
|
70
|
+
triangleStrip: GPURenderPipeline;
|
|
71
|
+
lineStrip: GPURenderPipeline;
|
|
74
72
|
};
|
|
75
73
|
export type RenderInfo = {
|
|
76
|
-
uniformBuffer: GPUBuffer;
|
|
77
74
|
instanceBuffer: GPUBuffer;
|
|
78
75
|
bindGroupLayout: GPUBindGroupLayout;
|
|
79
76
|
vertexBuffer: GPUBuffer | null;
|
|
@@ -81,7 +78,6 @@ export type RenderInfo = {
|
|
|
81
78
|
export type VertexParamGeneratorInfo = {
|
|
82
79
|
bufferSize: number;
|
|
83
80
|
createBuffer: (x: number, y: number, z: number, color: Color) => number[];
|
|
84
|
-
shouldEvaluate?: () => boolean;
|
|
85
81
|
};
|
|
86
82
|
export type ShaderInfo = {
|
|
87
83
|
pipeline: GPURenderPipeline;
|
package/dist/utils.d.ts
CHANGED
|
@@ -45,6 +45,7 @@ export declare class Vertex {
|
|
|
45
45
|
*/
|
|
46
46
|
export declare function transitionValues(callback1: (deltaT: number, t: number) => void, callback2: () => void, transitionLength: number, func?: (n: number) => number): Promise<void>;
|
|
47
47
|
export declare function frameLoop<T extends (dt: number, ...args: any[]) => any>(cb: T): (...params: Parameters<T>) => void;
|
|
48
|
+
export declare function clamp(num: number, min: number, max: number): number;
|
|
48
49
|
export declare function lerp(a: number, b: number, t: number): number;
|
|
49
50
|
export declare function smoothStep(t: number): number;
|
|
50
51
|
export declare function linearStep(t: number): number;
|
package/dist/utils.js
CHANGED
|
@@ -40,7 +40,7 @@ export class Vertex {
|
|
|
40
40
|
uv;
|
|
41
41
|
constructor(x = 0, y = 0, z = 0, color, is3dPoint = true, uv = vector2()) {
|
|
42
42
|
this.pos = vector3(x, y, z);
|
|
43
|
-
this.color = color
|
|
43
|
+
this.color = color || null;
|
|
44
44
|
this.is3d = is3dPoint;
|
|
45
45
|
this.uv = uv;
|
|
46
46
|
}
|
|
@@ -101,7 +101,8 @@ export function transitionValues(callback1, callback2, transitionLength, func) {
|
|
|
101
101
|
let prevTime = Date.now();
|
|
102
102
|
const step = (t, f) => {
|
|
103
103
|
const newT = f(t);
|
|
104
|
-
|
|
104
|
+
const deltaT = newT - prevPercent;
|
|
105
|
+
callback1(deltaT, t);
|
|
105
106
|
prevPercent = newT;
|
|
106
107
|
const now = Date.now();
|
|
107
108
|
let diff = now - prevTime;
|
|
@@ -143,6 +144,9 @@ export function frameLoop(cb) {
|
|
|
143
144
|
start(0, ...p);
|
|
144
145
|
};
|
|
145
146
|
}
|
|
147
|
+
export function clamp(num, min, max) {
|
|
148
|
+
return Math.min(max, Math.max(min, num));
|
|
149
|
+
}
|
|
146
150
|
export function lerp(a, b, t) {
|
|
147
151
|
return a + (b - a) * t;
|
|
148
152
|
}
|