simulationjsv2 0.4.10 → 0.5.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 +3 -2
- package/dist/geometry.d.ts +8 -8
- package/dist/geometry.js +14 -14
- package/dist/graphics.d.ts +3 -3
- package/dist/graphics.js +12 -8
- package/dist/internalUtils.d.ts +3 -3
- package/dist/internalUtils.js +7 -7
- package/dist/simulation.d.ts +17 -4
- package/dist/simulation.js +142 -33
- package/dist/types.d.ts +22 -8
- package/package.json +1 -1
package/TODO.md
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
# TODO
|
|
2
2
|
|
|
3
|
-
- [
|
|
4
|
-
|
|
3
|
+
- [ ] Make input position vec3 not vec4
|
|
4
|
+
- [ ] Change position/rotation to be matrix transform on gpu
|
|
5
|
+
- [ ] Make getBuffer return cached Float32Array
|
package/dist/geometry.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { VertexParamGeneratorInfo, CircleGeometryParams, CubeGeometryParams, EmptyParams, Line2dGeometryParams, Line3dGeometryParams, Mat4, PolygonGeometryParams, Spline2dGeometryParams, SquareGeometryParams, Vector2, Vector3, VertexColorMap } from './types.js';
|
|
2
2
|
import { Color, Vertex } from './utils.js';
|
|
3
3
|
import { CubicBezierCurve2d, SplinePoint2d } from './graphics.js';
|
|
4
4
|
export declare abstract class Geometry<T extends EmptyParams> {
|
|
@@ -14,9 +14,9 @@ export declare abstract class Geometry<T extends EmptyParams> {
|
|
|
14
14
|
abstract recompute(): void;
|
|
15
15
|
getTriangleVertexCount(): number;
|
|
16
16
|
getWireframeVertexCount(): number;
|
|
17
|
-
protected bufferFromOrder(order: number[], color: Color,
|
|
18
|
-
getWireframeBuffer(color: Color,
|
|
19
|
-
getTriangleBuffer(color: Color,
|
|
17
|
+
protected bufferFromOrder(order: number[], color: Color, vertexParamGenerator?: VertexParamGeneratorInfo): number[];
|
|
18
|
+
getWireframeBuffer(color: Color, vertexParamGenerator?: VertexParamGeneratorInfo): number[];
|
|
19
|
+
getTriangleBuffer(color: Color, vertexParamGenerator?: VertexParamGeneratorInfo): number[];
|
|
20
20
|
}
|
|
21
21
|
export declare class PlaneGeometry extends Geometry<EmptyParams> {
|
|
22
22
|
protected params: {};
|
|
@@ -26,7 +26,7 @@ export declare class PlaneGeometry extends Geometry<EmptyParams> {
|
|
|
26
26
|
constructor(vertices: Vertex[]);
|
|
27
27
|
recompute(): void;
|
|
28
28
|
updateVertices(vertices: Vertex[]): void;
|
|
29
|
-
getTriangleBuffer(color: Color,
|
|
29
|
+
getTriangleBuffer(color: Color, vertexParamGenerator?: VertexParamGeneratorInfo): number[];
|
|
30
30
|
}
|
|
31
31
|
export declare class CubeGeometry extends Geometry<CubeGeometryParams> {
|
|
32
32
|
protected params: CubeGeometryParams;
|
|
@@ -48,7 +48,7 @@ export declare class SquareGeometry extends Geometry<SquareGeometryParams> {
|
|
|
48
48
|
setWidth(width: number): void;
|
|
49
49
|
setHeight(height: number): void;
|
|
50
50
|
recompute(): void;
|
|
51
|
-
getTriangleBuffer(color: Color,
|
|
51
|
+
getTriangleBuffer(color: Color, vertexParamGenerator?: VertexParamGeneratorInfo): number[];
|
|
52
52
|
}
|
|
53
53
|
export declare class BlankGeometry extends Geometry<EmptyParams> {
|
|
54
54
|
protected wireframeOrder: never[];
|
|
@@ -83,8 +83,8 @@ export declare class Spline2dGeometry extends Geometry<Spline2dGeometryParams> {
|
|
|
83
83
|
private computeCurves;
|
|
84
84
|
private updateWireframeOrder;
|
|
85
85
|
recompute(): void;
|
|
86
|
-
getWireframeBuffer(color: Color,
|
|
87
|
-
getTriangleBuffer(_: Color,
|
|
86
|
+
getWireframeBuffer(color: Color, vertexParamGenerator?: VertexParamGeneratorInfo): number[];
|
|
87
|
+
getTriangleBuffer(_: Color, vertexParamGenerator?: VertexParamGeneratorInfo): number[];
|
|
88
88
|
}
|
|
89
89
|
export declare class Line2dGeometry extends Geometry<Line2dGeometryParams> {
|
|
90
90
|
protected wireframeOrder: number[];
|
package/dist/geometry.js
CHANGED
|
@@ -24,20 +24,20 @@ export class Geometry {
|
|
|
24
24
|
getWireframeVertexCount() {
|
|
25
25
|
return this.wireframeOrder.length;
|
|
26
26
|
}
|
|
27
|
-
bufferFromOrder(order, color,
|
|
27
|
+
bufferFromOrder(order, color, vertexParamGenerator) {
|
|
28
28
|
return order
|
|
29
29
|
.map((vertexIndex) => {
|
|
30
30
|
const pos = cloneBuf(this.vertices[vertexIndex]);
|
|
31
31
|
vec3.transformMat4(pos, this.matrix, pos);
|
|
32
|
-
return bufferGenerator.generate(pos[0], pos[1], pos[2], color, vector2(),
|
|
32
|
+
return bufferGenerator.generate(pos[0], pos[1], pos[2], color, vector2(), vertexParamGenerator);
|
|
33
33
|
})
|
|
34
34
|
.flat();
|
|
35
35
|
}
|
|
36
|
-
getWireframeBuffer(color,
|
|
37
|
-
return this.bufferFromOrder(this.wireframeOrder, color,
|
|
36
|
+
getWireframeBuffer(color, vertexParamGenerator) {
|
|
37
|
+
return this.bufferFromOrder(this.wireframeOrder, color, vertexParamGenerator);
|
|
38
38
|
}
|
|
39
|
-
getTriangleBuffer(color,
|
|
40
|
-
return this.bufferFromOrder(this.triangleOrder, color,
|
|
39
|
+
getTriangleBuffer(color, vertexParamGenerator) {
|
|
40
|
+
return this.bufferFromOrder(this.triangleOrder, color, vertexParamGenerator);
|
|
41
41
|
}
|
|
42
42
|
}
|
|
43
43
|
export class PlaneGeometry extends Geometry {
|
|
@@ -61,13 +61,13 @@ export class PlaneGeometry extends Geometry {
|
|
|
61
61
|
.fill(0)
|
|
62
62
|
.map((_, index) => index)).flat();
|
|
63
63
|
}
|
|
64
|
-
getTriangleBuffer(color,
|
|
64
|
+
getTriangleBuffer(color, vertexParamGenerator) {
|
|
65
65
|
return this.triangleOrder
|
|
66
66
|
.map((index) => {
|
|
67
67
|
const vertex = this.rawVertices[index];
|
|
68
68
|
const pos = cloneBuf(vertex.getPos());
|
|
69
69
|
vec3.transformMat4(pos, this.matrix, pos);
|
|
70
|
-
return bufferGenerator.generate(pos[0], pos[1], pos[2], vertex.getColor() || color, vector2(),
|
|
70
|
+
return bufferGenerator.generate(pos[0], pos[1], pos[2], vertex.getColor() || color, vector2(), vertexParamGenerator);
|
|
71
71
|
})
|
|
72
72
|
.flat();
|
|
73
73
|
}
|
|
@@ -155,12 +155,12 @@ export class SquareGeometry extends Geometry {
|
|
|
155
155
|
vector3(-this.params.width * centerOffset[0], -this.params.height * (1 - centerOffset[1]))
|
|
156
156
|
];
|
|
157
157
|
}
|
|
158
|
-
getTriangleBuffer(color,
|
|
158
|
+
getTriangleBuffer(color, vertexParamGenerator) {
|
|
159
159
|
return this.triangleOrder
|
|
160
160
|
.map((vertexIndex) => {
|
|
161
161
|
const pos = cloneBuf(this.vertices[vertexIndex]);
|
|
162
162
|
vec3.transformMat4(pos, this.matrix, pos);
|
|
163
|
-
return bufferGenerator.generate(pos[0], pos[1], pos[2], this.params.colorMap[vertexIndex] || color, vector2(),
|
|
163
|
+
return bufferGenerator.generate(pos[0], pos[1], pos[2], this.params.colorMap[vertexIndex] || color, vector2(), vertexParamGenerator);
|
|
164
164
|
})
|
|
165
165
|
.flat();
|
|
166
166
|
}
|
|
@@ -349,21 +349,21 @@ export class Spline2dGeometry extends Geometry {
|
|
|
349
349
|
.map((_, index) => index)).flat();
|
|
350
350
|
this.updateWireframeOrder();
|
|
351
351
|
}
|
|
352
|
-
getWireframeBuffer(color,
|
|
352
|
+
getWireframeBuffer(color, vertexParamGenerator) {
|
|
353
353
|
return this.wireframeOrder
|
|
354
354
|
.map((vertexIndex) => {
|
|
355
355
|
const vertex = cloneBuf(this.vertices[vertexIndex]);
|
|
356
356
|
vec3.transformMat4(vertex, this.matrix, vertex);
|
|
357
|
-
return bufferGenerator.generate(vertex[0], vertex[1], vertex[2], color, vector2(),
|
|
357
|
+
return bufferGenerator.generate(vertex[0], vertex[1], vertex[2], color, vector2(), vertexParamGenerator);
|
|
358
358
|
})
|
|
359
359
|
.flat();
|
|
360
360
|
}
|
|
361
|
-
getTriangleBuffer(_,
|
|
361
|
+
getTriangleBuffer(_, vertexParamGenerator) {
|
|
362
362
|
return this.triangleOrder
|
|
363
363
|
.map((vertexIndex) => {
|
|
364
364
|
const vertex = cloneBuf(this.vertices[vertexIndex]);
|
|
365
365
|
vec3.transformMat4(vertex, this.matrix, vertex);
|
|
366
|
-
return bufferGenerator.generate(vertex[0], vertex[1], vertex[2], this.params.vertexColors[vertexIndex], vector2(),
|
|
366
|
+
return bufferGenerator.generate(vertex[0], vertex[1], vertex[2], this.params.vertexColors[vertexIndex], vector2(), vertexParamGenerator);
|
|
367
367
|
})
|
|
368
368
|
.flat();
|
|
369
369
|
}
|
package/dist/graphics.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/// <reference types="@webgpu/types" />
|
|
2
2
|
import { Camera } from './simulation.js';
|
|
3
|
-
import type { Vector2, Vector3, LerpFunc, VertexColorMap, ElementRotation, Mat4, AnySimulationElement,
|
|
3
|
+
import type { Vector2, Vector3, LerpFunc, VertexColorMap, ElementRotation, Mat4, AnySimulationElement, VertexParamGeneratorInfo } from './types.js';
|
|
4
4
|
import { Vertex, Color } from './utils.js';
|
|
5
5
|
import { BlankGeometry, CircleGeometry, CubeGeometry, Geometry, Line2dGeometry, Line3dGeometry, PlaneGeometry, PolygonGeometry, Spline2dGeometry, SquareGeometry } from './geometry.js';
|
|
6
6
|
import { VertexCache } from './internalUtils.js';
|
|
@@ -30,7 +30,7 @@ export declare abstract class SimulationElement<T extends Vector2 | Vector3 = Ve
|
|
|
30
30
|
protected abstract updateMatrix(camera: Camera): void;
|
|
31
31
|
getVertexCount(): number;
|
|
32
32
|
protected defaultUpdateMatrix(camera: Camera): void;
|
|
33
|
-
getBuffer(camera: Camera,
|
|
33
|
+
getBuffer(camera: Camera, vertexParamGenerator?: VertexParamGeneratorInfo): number[];
|
|
34
34
|
}
|
|
35
35
|
export declare abstract class SimulationElement3d extends SimulationElement {
|
|
36
36
|
protected pos: Vector3;
|
|
@@ -49,7 +49,7 @@ export declare abstract class SimulationElement2d extends SimulationElement<Vect
|
|
|
49
49
|
rotate(rotation: number, t?: number, f?: LerpFunc): Promise<void>;
|
|
50
50
|
rotateTo(newRotation: number, t?: number, f?: LerpFunc): Promise<void>;
|
|
51
51
|
move(amount: Vector2, t?: number, f?: LerpFunc): Promise<void>;
|
|
52
|
-
moveTo(
|
|
52
|
+
moveTo(newPos: Vector2, t?: number, f?: LerpFunc): Promise<void>;
|
|
53
53
|
}
|
|
54
54
|
export declare class Plane extends SimulationElement3d {
|
|
55
55
|
protected geometry: PlaneGeometry;
|
package/dist/graphics.js
CHANGED
|
@@ -73,8 +73,8 @@ export class SimulationElement {
|
|
|
73
73
|
}
|
|
74
74
|
this.geometry.updateMatrix(matrix);
|
|
75
75
|
}
|
|
76
|
-
getBuffer(camera,
|
|
77
|
-
const shouldEvalExtender =
|
|
76
|
+
getBuffer(camera, vertexParamGenerator) {
|
|
77
|
+
const shouldEvalExtender = vertexParamGenerator?.shouldEvaluate?.();
|
|
78
78
|
const reEvalExtender = shouldEvalExtender === undefined ? true : shouldEvalExtender;
|
|
79
79
|
if (this.vertexCache.shouldUpdate() || camera.hasUpdated() || reEvalExtender) {
|
|
80
80
|
this.updateMatrix(camera);
|
|
@@ -84,10 +84,10 @@ export class SimulationElement {
|
|
|
84
84
|
}
|
|
85
85
|
let resBuffer;
|
|
86
86
|
if (this.isWireframe()) {
|
|
87
|
-
resBuffer = this.geometry.getWireframeBuffer(this.color,
|
|
87
|
+
resBuffer = this.geometry.getWireframeBuffer(this.color, vertexParamGenerator);
|
|
88
88
|
}
|
|
89
89
|
else {
|
|
90
|
-
resBuffer = this.geometry.getTriangleBuffer(this.color,
|
|
90
|
+
resBuffer = this.geometry.getTriangleBuffer(this.color, vertexParamGenerator);
|
|
91
91
|
}
|
|
92
92
|
bufferGenerator.setInstancing(false);
|
|
93
93
|
this.vertexCache.setCache(resBuffer);
|
|
@@ -188,18 +188,22 @@ export class SimulationElement2d extends SimulationElement {
|
|
|
188
188
|
}, t, f);
|
|
189
189
|
}
|
|
190
190
|
move(amount, t = 0, f) {
|
|
191
|
+
const tempAmount = cloneBuf(amount);
|
|
192
|
+
vector2ToPixelRatio(tempAmount);
|
|
191
193
|
const finalPos = vector2();
|
|
192
|
-
vec3.add(
|
|
194
|
+
vec3.add(tempAmount, this.pos, finalPos);
|
|
193
195
|
return transitionValues((p) => {
|
|
194
|
-
this.pos[0] +=
|
|
195
|
-
this.pos[1] +=
|
|
196
|
+
this.pos[0] += tempAmount[0] * p;
|
|
197
|
+
this.pos[1] += tempAmount[1] * p;
|
|
196
198
|
this.vertexCache.updated();
|
|
197
199
|
}, () => {
|
|
198
200
|
this.pos = finalPos;
|
|
199
201
|
this.vertexCache.updated();
|
|
200
202
|
}, t, f);
|
|
201
203
|
}
|
|
202
|
-
moveTo(
|
|
204
|
+
moveTo(newPos, t = 0, f) {
|
|
205
|
+
const pos = cloneBuf(newPos);
|
|
206
|
+
vector2ToPixelRatio(pos);
|
|
203
207
|
const diff = vector2();
|
|
204
208
|
vec2.sub(pos, this.pos, diff);
|
|
205
209
|
return transitionValues((p) => {
|
package/dist/internalUtils.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/// <reference types="@webgpu/types" />
|
|
2
|
-
import { AnySimulationElement,
|
|
2
|
+
import { AnySimulationElement, VertexParamGeneratorInfo, Mat4, Vector2, Vector3, VertexParamInfo } from './types.js';
|
|
3
3
|
import { Color } from './utils.js';
|
|
4
4
|
export declare class VertexCache {
|
|
5
5
|
private vertices;
|
|
@@ -52,14 +52,14 @@ declare class BufferGenerator {
|
|
|
52
52
|
private instancing;
|
|
53
53
|
constructor();
|
|
54
54
|
setInstancing(state: boolean): void;
|
|
55
|
-
generate(x: number, y: number, z: number, color: Color, uv?: Vector2,
|
|
55
|
+
generate(x: number, y: number, z: number, color: Color, uv?: Vector2, vertexParamGenerator?: VertexParamGeneratorInfo): number[];
|
|
56
56
|
}
|
|
57
57
|
export declare const bufferGenerator: BufferGenerator;
|
|
58
58
|
export declare function vector3ToPixelRatio(vec: Vector3): void;
|
|
59
59
|
export declare function vector2ToPixelRatio(vec: Vector2): void;
|
|
60
60
|
export declare function matrixFromRotation(rotation: Vector3): Mat4;
|
|
61
61
|
export declare function rotateMat4(mat: Mat4, rotation: Vector3): void;
|
|
62
|
-
export declare function createPipeline(device: GPUDevice, module: GPUShaderModule,
|
|
62
|
+
export declare function createPipeline(device: GPUDevice, module: GPUShaderModule, bindGroupLayouts: GPUBindGroupLayout[], presentationFormat: GPUTextureFormat, entryPoint: string, topology: GPUPrimitiveTopology, vertexParams?: VertexParamInfo[]): GPURenderPipeline;
|
|
63
63
|
export declare function triangulateWireFrameOrder(len: number): number[];
|
|
64
64
|
export declare function getTotalVertices(scene: SimSceneObjInfo[]): number;
|
|
65
65
|
export {};
|
package/dist/internalUtils.js
CHANGED
|
@@ -182,11 +182,11 @@ class BufferGenerator {
|
|
|
182
182
|
setInstancing(state) {
|
|
183
183
|
this.instancing = state;
|
|
184
184
|
}
|
|
185
|
-
generate(x, y, z, color, uv = vector2(),
|
|
186
|
-
if (
|
|
187
|
-
const buf =
|
|
188
|
-
if (buf.length !==
|
|
189
|
-
logger.log_error(`Vertex size for shader group does not match buffer extension size (${buf.length} to expected ${
|
|
185
|
+
generate(x, y, z, color, uv = vector2(), vertexParamGenerator) {
|
|
186
|
+
if (vertexParamGenerator) {
|
|
187
|
+
const buf = vertexParamGenerator.createBuffer(x, y, z, color);
|
|
188
|
+
if (buf.length !== vertexParamGenerator.bufferSize) {
|
|
189
|
+
logger.log_error(`Vertex size for shader group does not match buffer extension size (${buf.length} to expected ${vertexParamGenerator.bufferSize})`);
|
|
190
190
|
return [];
|
|
191
191
|
}
|
|
192
192
|
return buf;
|
|
@@ -216,7 +216,7 @@ export function rotateMat4(mat, rotation) {
|
|
|
216
216
|
mat4.rotateY(mat, rotation[1], mat);
|
|
217
217
|
mat4.rotateX(mat, rotation[0], mat);
|
|
218
218
|
}
|
|
219
|
-
export function createPipeline(device, module,
|
|
219
|
+
export function createPipeline(device, module, bindGroupLayouts, presentationFormat, entryPoint, topology, vertexParams) {
|
|
220
220
|
let params = [
|
|
221
221
|
{
|
|
222
222
|
// position
|
|
@@ -259,7 +259,7 @@ export function createPipeline(device, module, bindGroupLayout, presentationForm
|
|
|
259
259
|
}
|
|
260
260
|
return device.createRenderPipeline({
|
|
261
261
|
layout: device.createPipelineLayout({
|
|
262
|
-
bindGroupLayouts:
|
|
262
|
+
bindGroupLayouts: bindGroupLayouts
|
|
263
263
|
}),
|
|
264
264
|
vertex: {
|
|
265
265
|
module,
|
package/dist/simulation.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/// <reference types="@webgpu/types" />
|
|
2
2
|
import { SimulationElement3d } from './graphics.js';
|
|
3
|
-
import type { Vector2, Vector3, LerpFunc, AnySimulationElement,
|
|
3
|
+
import type { Vector2, Vector3, LerpFunc, AnySimulationElement, VertexParamGeneratorInfo, VertexParamInfo, BindGroupInfo } from './types.js';
|
|
4
4
|
import { Color } from './utils.js';
|
|
5
5
|
import { BlankGeometry } from './geometry.js';
|
|
6
6
|
import { SimSceneObjInfo } from './internalUtils.js';
|
|
@@ -16,7 +16,12 @@ export declare class Simulation {
|
|
|
16
16
|
private device;
|
|
17
17
|
private pipelines;
|
|
18
18
|
private renderInfo;
|
|
19
|
+
private resizeEvents;
|
|
19
20
|
constructor(idOrCanvasRef: string | HTMLCanvasElement, camera?: Camera | null, showFrameRate?: boolean);
|
|
21
|
+
private handleCanvasResize;
|
|
22
|
+
onResize(cb: (width: number, height: number) => void): void;
|
|
23
|
+
getWidth(): number;
|
|
24
|
+
getHeight(): number;
|
|
20
25
|
add(el: AnySimulationElement, id?: string): void;
|
|
21
26
|
remove(el: AnySimulationElement): void;
|
|
22
27
|
removeId(id: string): void;
|
|
@@ -24,6 +29,7 @@ export declare class Simulation {
|
|
|
24
29
|
* @param lifetime - ms
|
|
25
30
|
*/
|
|
26
31
|
setLifetime(el: AnySimulationElement, lifetime: number): void;
|
|
32
|
+
private applyCanvasSize;
|
|
27
33
|
setCanvasSize(width: number, height: number): void;
|
|
28
34
|
start(): void;
|
|
29
35
|
private propagateDevice;
|
|
@@ -87,12 +93,19 @@ export declare class ShaderGroup extends SceneCollection {
|
|
|
87
93
|
private code;
|
|
88
94
|
private module;
|
|
89
95
|
private pipeline;
|
|
96
|
+
private bindGroupLayout;
|
|
90
97
|
private topology;
|
|
91
|
-
private
|
|
98
|
+
private paramGenerator;
|
|
92
99
|
private vertexParams;
|
|
93
|
-
|
|
100
|
+
private bindGroup;
|
|
101
|
+
private valueBuffers;
|
|
102
|
+
constructor(shaderCode: string, topology: GPUPrimitiveTopology | undefined, vertexParams: VertexParamInfo[], paramGenerator: VertexParamGeneratorInfo, bindGroup?: BindGroupInfo);
|
|
94
103
|
protected propagateDevice(device: GPUDevice): void;
|
|
104
|
+
getBindGroupLayout(): GPUBindGroupLayout | null;
|
|
95
105
|
getPipeline(): GPURenderPipeline | null;
|
|
106
|
+
getBindGroupBuffers(): GPUBuffer[] | null;
|
|
107
|
+
private createBuffer;
|
|
96
108
|
protected updateMatrix(camera: Camera): void;
|
|
97
|
-
|
|
109
|
+
getVertexParamGenerator(): VertexParamGeneratorInfo;
|
|
110
|
+
hasBindGroup(): boolean;
|
|
98
111
|
}
|
package/dist/simulation.js
CHANGED
|
@@ -12,7 +12,7 @@ struct Uniforms {
|
|
|
12
12
|
|
|
13
13
|
@group(0) @binding(0) var<uniform> uniforms : Uniforms;
|
|
14
14
|
|
|
15
|
-
@group(0) @binding(1) var<storage
|
|
15
|
+
@group(0) @binding(1) var<storage> instanceMatrices : array<mat4x4f>;
|
|
16
16
|
|
|
17
17
|
struct VertexOutput {
|
|
18
18
|
@builtin(position) Position : vec4<f32>,
|
|
@@ -129,6 +129,7 @@ export class Simulation {
|
|
|
129
129
|
device = null;
|
|
130
130
|
pipelines = null;
|
|
131
131
|
renderInfo = null;
|
|
132
|
+
resizeEvents;
|
|
132
133
|
constructor(idOrCanvasRef, camera = null, showFrameRate = false) {
|
|
133
134
|
if (typeof idOrCanvasRef === 'string') {
|
|
134
135
|
const ref = document.getElementById(idOrCanvasRef);
|
|
@@ -150,16 +151,29 @@ export class Simulation {
|
|
|
150
151
|
this.camera = camera;
|
|
151
152
|
if (parent === null)
|
|
152
153
|
throw logger.error('Canvas parent is null');
|
|
154
|
+
this.resizeEvents = [];
|
|
153
155
|
addEventListener('resize', () => {
|
|
154
|
-
|
|
155
|
-
const width = parent.clientWidth;
|
|
156
|
-
const height = parent.clientHeight;
|
|
157
|
-
this.setCanvasSize(width, height);
|
|
158
|
-
}
|
|
156
|
+
this.handleCanvasResize(parent);
|
|
159
157
|
});
|
|
160
158
|
this.frameRateView = new FrameRateView(showFrameRate);
|
|
161
159
|
this.frameRateView.updateFrameRate(1);
|
|
162
160
|
}
|
|
161
|
+
handleCanvasResize(parent) {
|
|
162
|
+
if (this.fittingElement) {
|
|
163
|
+
const width = parent.clientWidth;
|
|
164
|
+
const height = parent.clientHeight;
|
|
165
|
+
this.setCanvasSize(width, height);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
onResize(cb) {
|
|
169
|
+
this.resizeEvents.push(cb);
|
|
170
|
+
}
|
|
171
|
+
getWidth() {
|
|
172
|
+
return (this.canvasRef?.width || 0) / devicePixelRatio;
|
|
173
|
+
}
|
|
174
|
+
getHeight() {
|
|
175
|
+
return (this.canvasRef?.height || 0) / devicePixelRatio;
|
|
176
|
+
}
|
|
163
177
|
add(el, id) {
|
|
164
178
|
addObject(this.scene, el, this.device, id);
|
|
165
179
|
}
|
|
@@ -178,7 +192,7 @@ export class Simulation {
|
|
|
178
192
|
this.scene[i].setLifetime(lifetime);
|
|
179
193
|
}
|
|
180
194
|
}
|
|
181
|
-
|
|
195
|
+
applyCanvasSize(width, height) {
|
|
182
196
|
if (this.canvasRef === null)
|
|
183
197
|
return;
|
|
184
198
|
this.canvasRef.width = width * devicePixelRatio;
|
|
@@ -186,6 +200,12 @@ export class Simulation {
|
|
|
186
200
|
this.canvasRef.style.width = width + 'px';
|
|
187
201
|
this.canvasRef.style.height = height + 'px';
|
|
188
202
|
}
|
|
203
|
+
setCanvasSize(width, height) {
|
|
204
|
+
this.applyCanvasSize(width, height);
|
|
205
|
+
for (let i = 0; i < this.resizeEvents.length; i++) {
|
|
206
|
+
this.resizeEvents[i](width, height);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
189
209
|
start() {
|
|
190
210
|
if (this.initialized) {
|
|
191
211
|
this.running = true;
|
|
@@ -282,12 +302,12 @@ export class Simulation {
|
|
|
282
302
|
vertexBuffer: null
|
|
283
303
|
};
|
|
284
304
|
this.pipelines = {
|
|
285
|
-
triangleList2d: createPipeline(device, shaderModule, bindGroupLayout, presentationFormat, 'vertex_main_2d', 'triangle-list'),
|
|
286
|
-
triangleStrip2d: createPipeline(device, shaderModule, bindGroupLayout, presentationFormat, 'vertex_main_2d', 'triangle-strip'),
|
|
287
|
-
lineStrip2d: createPipeline(device, shaderModule, bindGroupLayout, presentationFormat, 'vertex_main_2d', 'line-strip'),
|
|
288
|
-
triangleList3d: createPipeline(device, shaderModule, bindGroupLayout, presentationFormat, 'vertex_main_3d', 'triangle-list'),
|
|
289
|
-
triangleStrip3d: createPipeline(device, shaderModule, bindGroupLayout, presentationFormat, 'vertex_main_3d', 'triangle-strip'),
|
|
290
|
-
lineStrip3d: createPipeline(device, shaderModule, bindGroupLayout, presentationFormat, 'vertex_main_3d', 'line-strip')
|
|
305
|
+
triangleList2d: createPipeline(device, shaderModule, [bindGroupLayout], presentationFormat, 'vertex_main_2d', 'triangle-list'),
|
|
306
|
+
triangleStrip2d: createPipeline(device, shaderModule, [bindGroupLayout], presentationFormat, 'vertex_main_2d', 'triangle-strip'),
|
|
307
|
+
lineStrip2d: createPipeline(device, shaderModule, [bindGroupLayout], presentationFormat, 'vertex_main_2d', 'line-strip'),
|
|
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')
|
|
291
311
|
};
|
|
292
312
|
const uniformBindGroup = device.createBindGroup({
|
|
293
313
|
layout: bindGroupLayout,
|
|
@@ -423,14 +443,23 @@ export class Simulation {
|
|
|
423
443
|
if (obj instanceof ShaderGroup) {
|
|
424
444
|
const pipeline = obj.getPipeline();
|
|
425
445
|
if (pipeline !== null) {
|
|
426
|
-
shaderInfo = {
|
|
446
|
+
shaderInfo = {
|
|
447
|
+
pipeline,
|
|
448
|
+
paramGenerator: obj.getVertexParamGenerator(),
|
|
449
|
+
bufferInfo: obj.hasBindGroup()
|
|
450
|
+
? {
|
|
451
|
+
buffers: obj.getBindGroupBuffers(),
|
|
452
|
+
layout: obj.getBindGroupLayout()
|
|
453
|
+
}
|
|
454
|
+
: null
|
|
455
|
+
};
|
|
427
456
|
}
|
|
428
457
|
}
|
|
429
458
|
currentOffset += this.renderScene(device, passEncoder, vertexBuffer, obj.getScene(), currentOffset, diff, shaderInfo || undefined);
|
|
430
459
|
continue;
|
|
431
460
|
}
|
|
432
|
-
const buffer = new Float32Array(obj.getBuffer(this.camera, shaderInfo?.
|
|
433
|
-
const bufLen = shaderInfo?.
|
|
461
|
+
const buffer = new Float32Array(obj.getBuffer(this.camera, shaderInfo?.paramGenerator));
|
|
462
|
+
const bufLen = shaderInfo?.paramGenerator?.bufferSize || BUF_LEN;
|
|
434
463
|
const vertexCount = buffer.length / bufLen;
|
|
435
464
|
device.queue.writeBuffer(vertexBuffer, currentOffset, buffer);
|
|
436
465
|
vertexBuffer.unmap();
|
|
@@ -490,6 +519,19 @@ export class Simulation {
|
|
|
490
519
|
passEncoder.setBindGroup(0, uniformBindGroup);
|
|
491
520
|
}
|
|
492
521
|
}
|
|
522
|
+
if (shaderInfo && shaderInfo.bufferInfo) {
|
|
523
|
+
const bindGroupEntries = shaderInfo.bufferInfo.buffers.map((buffer, index) => ({
|
|
524
|
+
binding: index,
|
|
525
|
+
resource: {
|
|
526
|
+
buffer
|
|
527
|
+
}
|
|
528
|
+
}));
|
|
529
|
+
const bindGroup = device.createBindGroup({
|
|
530
|
+
layout: shaderInfo.bufferInfo.layout,
|
|
531
|
+
entries: bindGroupEntries
|
|
532
|
+
});
|
|
533
|
+
passEncoder.setBindGroup(1, bindGroup);
|
|
534
|
+
}
|
|
493
535
|
passEncoder.setVertexBuffer(0, vertexBuffer, currentOffset, buffer.byteLength);
|
|
494
536
|
passEncoder.draw(vertexCount, instances, 0, 0);
|
|
495
537
|
currentOffset += buffer.byteLength;
|
|
@@ -682,17 +724,7 @@ export class Camera {
|
|
|
682
724
|
return this.aspectRatio;
|
|
683
725
|
}
|
|
684
726
|
}
|
|
685
|
-
|
|
686
|
-
geometry;
|
|
687
|
-
code;
|
|
688
|
-
module;
|
|
689
|
-
pipeline;
|
|
690
|
-
topology;
|
|
691
|
-
bufferExtender;
|
|
692
|
-
vertexParams;
|
|
693
|
-
constructor(shaderCode, topology = 'triangle-list', vertexParams, bufferExtender) {
|
|
694
|
-
super();
|
|
695
|
-
const defaultCode = `
|
|
727
|
+
const defaultShaderCode = `
|
|
696
728
|
struct Uniforms {
|
|
697
729
|
modelViewProjectionMatrix : mat4x4<f32>,
|
|
698
730
|
orthoProjectionMatrix : mat4x4<f32>
|
|
@@ -702,17 +734,34 @@ struct Uniforms {
|
|
|
702
734
|
|
|
703
735
|
@group(0) @binding(1) var<storage, read> instanceMatrices : array<mat4x4f>;
|
|
704
736
|
`;
|
|
737
|
+
export class ShaderGroup extends SceneCollection {
|
|
738
|
+
geometry;
|
|
739
|
+
code;
|
|
740
|
+
module;
|
|
741
|
+
pipeline;
|
|
742
|
+
bindGroupLayout;
|
|
743
|
+
topology;
|
|
744
|
+
paramGenerator;
|
|
745
|
+
vertexParams;
|
|
746
|
+
bindGroup;
|
|
747
|
+
valueBuffers;
|
|
748
|
+
constructor(shaderCode, topology = 'triangle-list', vertexParams, paramGenerator, bindGroup) {
|
|
749
|
+
super();
|
|
705
750
|
this.geometry = new BlankGeometry();
|
|
706
|
-
this.code =
|
|
751
|
+
this.code = defaultShaderCode + shaderCode;
|
|
707
752
|
this.module = null;
|
|
708
753
|
this.pipeline = null;
|
|
754
|
+
this.bindGroupLayout = null;
|
|
755
|
+
this.bindGroup = bindGroup || null;
|
|
709
756
|
this.topology = topology;
|
|
710
|
-
this.
|
|
757
|
+
this.paramGenerator = paramGenerator;
|
|
711
758
|
this.vertexParams = vertexParams;
|
|
759
|
+
this.valueBuffers = null;
|
|
712
760
|
}
|
|
713
761
|
propagateDevice(device) {
|
|
714
762
|
super.propagateDevice(device);
|
|
715
763
|
this.module = device.createShaderModule({ code: this.code });
|
|
764
|
+
const presentationFormat = navigator.gpu.getPreferredCanvasFormat();
|
|
716
765
|
const bindGroupLayout = device.createBindGroupLayout({
|
|
717
766
|
entries: [
|
|
718
767
|
{
|
|
@@ -731,16 +780,76 @@ struct Uniforms {
|
|
|
731
780
|
}
|
|
732
781
|
]
|
|
733
782
|
});
|
|
734
|
-
const
|
|
735
|
-
|
|
783
|
+
const bindGroups = [bindGroupLayout];
|
|
784
|
+
if (this.bindGroup !== null) {
|
|
785
|
+
const entryValues = this.bindGroup.bindings.map((binding, index) => ({
|
|
786
|
+
binding: index,
|
|
787
|
+
visibility: binding.visibility,
|
|
788
|
+
buffer: binding.buffer
|
|
789
|
+
}));
|
|
790
|
+
this.bindGroupLayout = device.createBindGroupLayout({
|
|
791
|
+
entries: entryValues
|
|
792
|
+
});
|
|
793
|
+
bindGroups.push(this.bindGroupLayout);
|
|
794
|
+
}
|
|
795
|
+
this.pipeline = createPipeline(device, this.module, bindGroups, presentationFormat, 'vertex_main_2d', this.topology, this.vertexParams);
|
|
796
|
+
}
|
|
797
|
+
getBindGroupLayout() {
|
|
798
|
+
return this.bindGroupLayout;
|
|
736
799
|
}
|
|
737
800
|
getPipeline() {
|
|
738
801
|
return this.pipeline;
|
|
739
802
|
}
|
|
803
|
+
getBindGroupBuffers() {
|
|
804
|
+
if (this.bindGroup === null)
|
|
805
|
+
return null;
|
|
806
|
+
if (this.device === null)
|
|
807
|
+
return null;
|
|
808
|
+
const values = this.bindGroup.values();
|
|
809
|
+
if (this.valueBuffers === null) {
|
|
810
|
+
const buffers = [];
|
|
811
|
+
for (let i = 0; i < values.length; i++) {
|
|
812
|
+
const buffer = this.createBuffer(this.device, values[i]);
|
|
813
|
+
buffers.push(buffer);
|
|
814
|
+
}
|
|
815
|
+
this.valueBuffers = buffers;
|
|
816
|
+
}
|
|
817
|
+
else {
|
|
818
|
+
for (let i = 0; i < values.length; i++) {
|
|
819
|
+
const arrayConstructor = values[i].array;
|
|
820
|
+
const array = new arrayConstructor(values[i].value);
|
|
821
|
+
if (array.byteLength > this.valueBuffers[i].size) {
|
|
822
|
+
this.valueBuffers[i].destroy();
|
|
823
|
+
const newBuffer = this.createBuffer(this.device, values[i]);
|
|
824
|
+
this.valueBuffers[i] = newBuffer;
|
|
825
|
+
}
|
|
826
|
+
else {
|
|
827
|
+
this.device.queue.writeBuffer(this.valueBuffers[i], 0, array.buffer, array.byteOffset, array.byteLength);
|
|
828
|
+
}
|
|
829
|
+
}
|
|
830
|
+
}
|
|
831
|
+
return this.valueBuffers;
|
|
832
|
+
}
|
|
833
|
+
createBuffer(device, value) {
|
|
834
|
+
const arrayConstructor = value.array;
|
|
835
|
+
const array = new arrayConstructor(value.value);
|
|
836
|
+
const buffer = device.createBuffer({
|
|
837
|
+
mappedAtCreation: true,
|
|
838
|
+
size: array.byteLength,
|
|
839
|
+
usage: value.usage
|
|
840
|
+
});
|
|
841
|
+
const bufferArr = new arrayConstructor(buffer.getMappedRange());
|
|
842
|
+
bufferArr.set(array);
|
|
843
|
+
buffer.unmap();
|
|
844
|
+
return buffer;
|
|
845
|
+
}
|
|
740
846
|
updateMatrix(camera) {
|
|
741
847
|
this.defaultUpdateMatrix(camera);
|
|
742
848
|
}
|
|
743
|
-
|
|
744
|
-
return this.
|
|
849
|
+
getVertexParamGenerator() {
|
|
850
|
+
return this.paramGenerator;
|
|
851
|
+
}
|
|
852
|
+
hasBindGroup() {
|
|
853
|
+
return !!this.bindGroup;
|
|
745
854
|
}
|
|
746
855
|
}
|
package/dist/types.d.ts
CHANGED
|
@@ -78,20 +78,34 @@ export type RenderInfo = {
|
|
|
78
78
|
bindGroupLayout: GPUBindGroupLayout;
|
|
79
79
|
vertexBuffer: GPUBuffer | null;
|
|
80
80
|
};
|
|
81
|
-
export type
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
};
|
|
85
|
-
export type BufferExtenderInfo = {
|
|
86
|
-
size: number;
|
|
87
|
-
extender: (x: number, y: number, z: number, color: Color) => number[];
|
|
81
|
+
export type VertexParamGeneratorInfo = {
|
|
82
|
+
bufferSize: number;
|
|
83
|
+
createBuffer: (x: number, y: number, z: number, color: Color) => number[];
|
|
88
84
|
shouldEvaluate?: () => boolean;
|
|
89
85
|
};
|
|
90
86
|
export type ShaderInfo = {
|
|
91
87
|
pipeline: GPURenderPipeline;
|
|
92
|
-
|
|
88
|
+
paramGenerator: VertexParamGeneratorInfo;
|
|
89
|
+
bufferInfo: {
|
|
90
|
+
buffers: GPUBuffer[];
|
|
91
|
+
layout: GPUBindGroupLayout;
|
|
92
|
+
} | null;
|
|
93
93
|
};
|
|
94
94
|
export type VertexParamInfo = {
|
|
95
95
|
format: GPUVertexFormat;
|
|
96
96
|
size: number;
|
|
97
97
|
};
|
|
98
|
+
export type BindGroupEntry = {
|
|
99
|
+
visibility: GPUBindGroupLayoutEntry['visibility'];
|
|
100
|
+
buffer: GPUBindGroupLayoutEntry['buffer'];
|
|
101
|
+
};
|
|
102
|
+
export type ArrayConstructors = Float32ArrayConstructor | Float64ArrayConstructor | Int8ArrayConstructor | Int16ArrayConstructor | Int32ArrayConstructor;
|
|
103
|
+
export type BindGroupValue = {
|
|
104
|
+
value: number[];
|
|
105
|
+
usage: GPUBufferDescriptor['usage'];
|
|
106
|
+
array: ArrayConstructors;
|
|
107
|
+
};
|
|
108
|
+
export type BindGroupInfo = {
|
|
109
|
+
bindings: BindGroupEntry[];
|
|
110
|
+
values: () => BindGroupValue[];
|
|
111
|
+
};
|