simulationjsv2 0.7.1 → 0.7.3

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 CHANGED
@@ -1,5 +1,7 @@
1
1
  # TODO
2
2
 
3
+ - [ ] Make materials
4
+ - [ ] Move shader group to material
3
5
  - [ ] Fix transparency
4
6
  - [x] Update `updateModelMatrix2d`
5
7
  - [x] Trace line element (wireframe strip for tracing paths)
@@ -6,6 +6,7 @@ export declare const drawingInstancesOffset = 36;
6
6
  export declare const BUF_LEN: number;
7
7
  export declare const worldProjMatOffset = 0;
8
8
  export declare const modelProjMatOffset: number;
9
+ export declare const mat4ByteLength = 64;
9
10
  export declare const xAxis: import("./types.js").Vector3;
10
11
  export declare const yAxis: import("./types.js").Vector3;
11
12
  export declare const zAxis: import("./types.js").Vector3;
package/dist/constants.js CHANGED
@@ -7,6 +7,7 @@ export const drawingInstancesOffset = 36;
7
7
  export const BUF_LEN = vertexSize / 4;
8
8
  export const worldProjMatOffset = 0;
9
9
  export const modelProjMatOffset = 4 * 16;
10
+ export const mat4ByteLength = 64;
10
11
  export const xAxis = vector3(1);
11
12
  export const yAxis = vector3(0, 1);
12
13
  export const zAxis = vector3(0, 0, 1);
@@ -34,9 +34,8 @@ export declare abstract class SimulationElement3d {
34
34
  setCenterOffset(offset: Vector3): void;
35
35
  setRotationOffset(offset: Vector3): void;
36
36
  resetCenterOffset(): void;
37
- propagateDevice(device: GPUDevice): void;
38
37
  getModelMatrix(): Mat4;
39
- getUniformBuffer(device: GPUDevice, mat: Mat4): GPUBuffer;
38
+ getUniformBuffer(mat: Mat4): GPUBuffer;
40
39
  protected mirrorParentTransforms3d(mat: Mat4): void;
41
40
  protected updateModelMatrix3d(): void;
42
41
  protected mirrorParentTransforms2d(mat: Mat4): void;
@@ -59,7 +58,6 @@ export declare abstract class SimulationElement3d {
59
58
  rotateTo(rot: Vector3, t?: number, f?: LerpFunc): Promise<void>;
60
59
  getVertexCount(): number;
61
60
  getBuffer(vertexParamGenerator?: VertexParamGeneratorInfo): Float32Array | number[];
62
- protected abstract onDeviceChange(device: GPUDevice): void;
63
61
  }
64
62
  export declare class EmptyElement extends SimulationElement3d {
65
63
  protected geometry: BlankGeometry;
@@ -67,7 +65,6 @@ export declare class EmptyElement extends SimulationElement3d {
67
65
  isEmpty: boolean;
68
66
  constructor(label?: string);
69
67
  getLabel(): string | null;
70
- protected onDeviceChange(_device: GPUDevice): void;
71
68
  }
72
69
  export declare abstract class SimulationElement2d extends SimulationElement3d {
73
70
  is3d: boolean;
@@ -81,7 +78,6 @@ export declare class Plane extends SimulationElement3d {
81
78
  points: Vertex[];
82
79
  constructor(pos: Vector3, points: Vertex[], color?: Color, rotation?: Vector3);
83
80
  setPoints(newPoints: Vertex[]): void;
84
- protected onDeviceChange(_device: GPUDevice): void;
85
81
  }
86
82
  export declare class Square extends SimulationElement2d {
87
83
  protected geometry: SquareGeometry;
@@ -102,7 +98,6 @@ export declare class Square extends SimulationElement2d {
102
98
  scale(amount: number, t?: number, f?: LerpFunc): Promise<void>;
103
99
  setWidth(num: number, t?: number, f?: LerpFunc): Promise<void>;
104
100
  setHeight(num: number, t?: number, f?: LerpFunc): Promise<void>;
105
- protected onDeviceChange(_device: GPUDevice): void;
106
101
  }
107
102
  export declare class Circle extends SimulationElement2d {
108
103
  protected geometry: CircleGeometry;
@@ -111,7 +106,6 @@ export declare class Circle extends SimulationElement2d {
111
106
  constructor(pos: Vector2, radius: number, color?: Color, detail?: number);
112
107
  setRadius(num: number, t?: number, f?: LerpFunc): Promise<void>;
113
108
  scale(amount: number, t?: number, f?: LerpFunc): Promise<void>;
114
- protected onDeviceChange(_device: GPUDevice): void;
115
109
  }
116
110
  export declare class Polygon extends SimulationElement2d {
117
111
  protected geometry: PolygonGeometry;
@@ -119,7 +113,6 @@ export declare class Polygon extends SimulationElement2d {
119
113
  constructor(pos: Vector2, points: Vertex[], color?: Color, rotation?: number);
120
114
  getVertices(): Vertex[];
121
115
  setVertices(newVertices: Vertex[], t?: number, f?: LerpFunc): Promise<void>;
122
- protected onDeviceChange(_device: GPUDevice): void;
123
116
  }
124
117
  export declare class Line3d extends SimulationElement3d {
125
118
  protected geometry: Line3dGeometry;
@@ -128,7 +121,6 @@ export declare class Line3d extends SimulationElement3d {
128
121
  constructor(pos: Vertex, to: Vertex, thickness: number);
129
122
  setStart(pos: Vector3, t?: number, f?: LerpFunc): Promise<void>;
130
123
  setEnd(pos: Vector3, t?: number, f?: LerpFunc): Promise<void>;
131
- protected onDeviceChange(_device: GPUDevice): void;
132
124
  }
133
125
  export declare class Line2d extends SimulationElement2d {
134
126
  protected geometry: Line2dGeometry;
@@ -137,7 +129,6 @@ export declare class Line2d extends SimulationElement2d {
137
129
  constructor(from: Vertex, to: Vertex, thickness?: number);
138
130
  setStart(pos: Vector3, t?: number, f?: LerpFunc): Promise<void>;
139
131
  setEnd(pos: Vector3, t?: number, f?: LerpFunc): Promise<void>;
140
- protected onDeviceChange(_device: GPUDevice): void;
141
132
  }
142
133
  export declare class Cube extends SimulationElement3d {
143
134
  protected geometry: CubeGeometry;
@@ -149,7 +140,6 @@ export declare class Cube extends SimulationElement3d {
149
140
  setHeight(height: number, t?: number, f?: LerpFunc): Promise<void>;
150
141
  setDepth(depth: number, t?: number, f?: LerpFunc): Promise<void>;
151
142
  scale(amount: number, t?: number, f?: LerpFunc): Promise<void>;
152
- protected onDeviceChange(_device: GPUDevice): void;
153
143
  }
154
144
  export declare class BezierCurve2d {
155
145
  private points;
@@ -202,7 +192,6 @@ export declare class Spline2d extends SimulationElement2d {
202
192
  setThickness(thickness: number, t?: number, f?: LerpFunc): Promise<void>;
203
193
  interpolateSlope(t: number): Vector2[] | readonly [Vector2, Vector2];
204
194
  interpolate(t: number): Vector2;
205
- protected onDeviceChange(_device: GPUDevice): void;
206
195
  }
207
196
  export declare class Instance<T extends AnySimulationElement> extends SimulationElement3d {
208
197
  protected geometry: BlankGeometry;
@@ -210,18 +199,20 @@ export declare class Instance<T extends AnySimulationElement> extends Simulation
210
199
  private instanceMatrix;
211
200
  private matrixBuffer;
212
201
  private baseMat;
202
+ private maxInstances;
203
+ private hasMapped;
213
204
  isInstance: boolean;
214
205
  constructor(obj: T, numInstances: number);
215
206
  setNumInstances(numInstances: number): void;
216
207
  setInstance(instance: number, transformation: Mat4): void;
208
+ private allocBuffer;
217
209
  private mapBuffer;
218
210
  getInstances(): Mat4[];
219
211
  getNumInstances(): number;
220
- getMatrixBuffer(device: GPUDevice): GPUBuffer;
212
+ getMatrixBuffer(): GPUBuffer;
221
213
  getVertexCount(): number;
222
214
  getGeometryType(): "list" | "strip";
223
215
  getBuffer(): Float32Array | number[];
224
- protected onDeviceChange(device: GPUDevice): void;
225
216
  getModelMatrix(): Mat4;
226
217
  }
227
218
  export declare class TraceLines2d extends SimulationElement2d {
@@ -229,12 +220,10 @@ export declare class TraceLines2d extends SimulationElement2d {
229
220
  constructor(color?: Color, maxLen?: number);
230
221
  addPoint(point: Vector2 | Vector3, color?: Color): void;
231
222
  isWireframe(): boolean;
232
- protected onDeviceChange(_: GPUDevice): void;
233
223
  }
234
224
  export declare class TraceLines3d extends SimulationElement3d {
235
225
  protected geometry: TraceLinesGeometry;
236
226
  constructor(color?: Color, maxLen?: number);
237
227
  addPoint(point: Vector2 | Vector3, color?: Color): void;
238
228
  isWireframe(): boolean;
239
- protected onDeviceChange(_: GPUDevice): void;
240
229
  }
package/dist/graphics.js CHANGED
@@ -1,8 +1,8 @@
1
1
  import { vec3, mat4, vec2, vec4 } from 'wgpu-matrix';
2
2
  import { Vertex, cloneBuf, color, colorFromVector4, vector2, vector3, vertex, Color, vector2FromVector3, matrix4, vector3FromVector2, distance2d } from './utils.js';
3
3
  import { BlankGeometry, CircleGeometry, CubeGeometry, Line2dGeometry, Line3dGeometry, PlaneGeometry, PolygonGeometry, Spline2dGeometry, SquareGeometry, TraceLines2dGeometry as TraceLinesGeometry } from './geometry.js';
4
- import { SimSceneObjInfo, VertexCache, bufferGenerator, internalTransitionValues, logger, posTo2dScreen, rotateMat4, vector3ToPixelRatio } from './internalUtils.js';
5
- import { modelProjMatOffset } from './constants.js';
4
+ import { SimSceneObjInfo, VertexCache, bufferGenerator, globalInfo, internalTransitionValues, logger, posTo2dScreen, vector3ToPixelRatio } from './internalUtils.js';
5
+ import { mat4ByteLength, modelProjMatOffset } from './constants.js';
6
6
  export class SimulationElement3d {
7
7
  children;
8
8
  uniformBuffer;
@@ -74,17 +74,12 @@ export class SimulationElement3d {
74
74
  this.centerOffset[1] = 0;
75
75
  this.centerOffset[2] = 0;
76
76
  }
77
- propagateDevice(device) {
78
- this.onDeviceChange(device);
79
- for (let i = 0; i < this.children.length; i++) {
80
- this.children[i].getObj().propagateDevice(device);
81
- }
82
- }
83
77
  getModelMatrix() {
84
78
  this.updateModelMatrix3d();
85
79
  return this.modelMatrix;
86
80
  }
87
- getUniformBuffer(device, mat) {
81
+ getUniformBuffer(mat) {
82
+ const device = globalInfo.errorGetDevice();
88
83
  if (!this.uniformBuffer) {
89
84
  const uniformBufferSize = 4 * 16 + 4 * 16 + 4 * 2 + 8; // 4x4 matrix + 4x4 matrix + vec2<f32> + 8 bc 144 is cool
90
85
  this.uniformBuffer = device.createBuffer({
@@ -302,8 +297,6 @@ export class EmptyElement extends SimulationElement3d {
302
297
  getLabel() {
303
298
  return this.label;
304
299
  }
305
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
306
- onDeviceChange(_device) { }
307
300
  }
308
301
  export class SimulationElement2d extends SimulationElement3d {
309
302
  is3d = false;
@@ -335,8 +328,6 @@ export class Plane extends SimulationElement3d {
335
328
  this.points = newPoints;
336
329
  this.vertexCache.updated();
337
330
  }
338
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
339
- onDeviceChange(_device) { }
340
331
  }
341
332
  export class Square extends SimulationElement2d {
342
333
  geometry;
@@ -478,8 +469,6 @@ export class Square extends SimulationElement2d {
478
469
  this.vertexCache.updated();
479
470
  }, t, f);
480
471
  }
481
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
482
- onDeviceChange(_device) { }
483
472
  }
484
473
  export class Circle extends SimulationElement2d {
485
474
  geometry;
@@ -517,8 +506,6 @@ export class Circle extends SimulationElement2d {
517
506
  this.vertexCache.updated();
518
507
  }, t, f);
519
508
  }
520
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
521
- onDeviceChange(_device) { }
522
509
  }
523
510
  export class Polygon extends SimulationElement2d {
524
511
  geometry;
@@ -597,8 +584,6 @@ export class Polygon extends SimulationElement2d {
597
584
  this.vertexCache.updated();
598
585
  }, t, f);
599
586
  }
600
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
601
- onDeviceChange(_device) { }
602
587
  }
603
588
  export class Line3d extends SimulationElement3d {
604
589
  geometry;
@@ -630,8 +615,6 @@ export class Line3d extends SimulationElement3d {
630
615
  this.vertexCache.updated();
631
616
  }, t, f);
632
617
  }
633
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
634
- onDeviceChange(_device) { }
635
618
  }
636
619
  export class Line2d extends SimulationElement2d {
637
620
  geometry;
@@ -663,8 +646,6 @@ export class Line2d extends SimulationElement2d {
663
646
  this.vertexCache.updated();
664
647
  }, t, f);
665
648
  }
666
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
667
- onDeviceChange(_device) { }
668
649
  }
669
650
  export class Cube extends SimulationElement3d {
670
651
  geometry;
@@ -743,8 +724,6 @@ export class Cube extends SimulationElement3d {
743
724
  this.vertexCache.updated();
744
725
  }, t, f);
745
726
  }
746
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
747
- onDeviceChange(_device) { }
748
727
  }
749
728
  export class BezierCurve2d {
750
729
  points;
@@ -992,8 +971,6 @@ export class Spline2d extends SimulationElement2d {
992
971
  const [vec] = this.interpolateSlope(t);
993
972
  return vec;
994
973
  }
995
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
996
- onDeviceChange(_device) { }
997
974
  }
998
975
  export class Instance extends SimulationElement3d {
999
976
  geometry;
@@ -1001,17 +978,21 @@ export class Instance extends SimulationElement3d {
1001
978
  instanceMatrix;
1002
979
  matrixBuffer;
1003
980
  baseMat;
981
+ maxInstances;
982
+ hasMapped;
1004
983
  isInstance = true;
1005
984
  constructor(obj, numInstances) {
1006
985
  super(vector3(), vector3());
986
+ // 32 matrices
987
+ this.maxInstances = 32;
1007
988
  this.matrixBuffer = null;
1008
989
  obj.isInstanced = true;
1009
990
  this.obj = obj;
1010
991
  this.instanceMatrix = [];
1011
992
  this.is3d = obj.is3d;
1012
993
  this.geometry = new BlankGeometry();
994
+ this.hasMapped = false;
1013
995
  this.baseMat = matrix4();
1014
- rotateMat4(this.baseMat, obj.getRotation());
1015
996
  for (let i = 0; i < numInstances; i++) {
1016
997
  const clone = cloneBuf(this.baseMat);
1017
998
  this.instanceMatrix.push(clone);
@@ -1020,6 +1001,10 @@ export class Instance extends SimulationElement3d {
1020
1001
  setNumInstances(numInstances) {
1021
1002
  if (numInstances < 0)
1022
1003
  throw logger.error('Num instances is less than 0');
1004
+ if (numInstances > this.maxInstances) {
1005
+ this.maxInstances = numInstances;
1006
+ this.allocBuffer(numInstances);
1007
+ }
1023
1008
  const oldLen = this.instanceMatrix.length;
1024
1009
  if (numInstances < oldLen) {
1025
1010
  const diff = oldLen - numInstances;
@@ -1041,13 +1026,41 @@ export class Instance extends SimulationElement3d {
1041
1026
  if (instance >= this.instanceMatrix.length || instance < 0)
1042
1027
  return;
1043
1028
  this.instanceMatrix[instance] = transformation;
1029
+ const device = globalInfo.getDevice();
1030
+ if (!device)
1031
+ return;
1032
+ if (!this.matrixBuffer) {
1033
+ const minSize = this.maxInstances * mat4ByteLength;
1034
+ const size = Math.max(minSize, this.instanceMatrix.length);
1035
+ this.allocBuffer(size);
1036
+ }
1037
+ const buf = new Float32Array(transformation);
1038
+ device.queue.writeBuffer(this.matrixBuffer, instance * mat4ByteLength, buf.buffer, buf.byteOffset, buf.byteLength);
1039
+ this.matrixBuffer.unmap();
1044
1040
  }
1045
- mapBuffer(device) {
1046
- if (this.matrixBuffer === null)
1041
+ allocBuffer(size) {
1042
+ const device = globalInfo.getDevice();
1043
+ if (!device)
1047
1044
  return;
1045
+ const byteSize = size * mat4ByteLength;
1046
+ this.matrixBuffer = device.createBuffer({
1047
+ size: byteSize,
1048
+ usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST
1049
+ });
1050
+ }
1051
+ mapBuffer() {
1052
+ const device = globalInfo.getDevice();
1053
+ if (!device)
1054
+ return;
1055
+ if (!this.matrixBuffer) {
1056
+ const minSize = this.maxInstances * mat4ByteLength;
1057
+ const size = Math.max(minSize, this.instanceMatrix.length);
1058
+ this.allocBuffer(size);
1059
+ }
1048
1060
  const buf = new Float32Array(this.instanceMatrix.map((mat) => [...mat]).flat());
1049
1061
  device.queue.writeBuffer(this.matrixBuffer, 0, buf.buffer, buf.byteOffset, buf.byteLength);
1050
1062
  this.matrixBuffer.unmap();
1063
+ this.hasMapped = true;
1051
1064
  }
1052
1065
  getInstances() {
1053
1066
  return this.instanceMatrix;
@@ -1055,16 +1068,10 @@ export class Instance extends SimulationElement3d {
1055
1068
  getNumInstances() {
1056
1069
  return this.instanceMatrix.length;
1057
1070
  }
1058
- getMatrixBuffer(device) {
1059
- if (!this.matrixBuffer) {
1060
- const minSize = 512;
1061
- const size = Math.max(minSize, this.instanceMatrix[0].byteLength * this.instanceMatrix.length);
1062
- this.matrixBuffer = device.createBuffer({
1063
- size,
1064
- usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST
1065
- });
1071
+ getMatrixBuffer() {
1072
+ if (!this.hasMapped) {
1073
+ this.mapBuffer();
1066
1074
  }
1067
- this.mapBuffer(device);
1068
1075
  return this.matrixBuffer;
1069
1076
  }
1070
1077
  getVertexCount() {
@@ -1076,9 +1083,6 @@ export class Instance extends SimulationElement3d {
1076
1083
  getBuffer() {
1077
1084
  return this.obj.getBuffer();
1078
1085
  }
1079
- onDeviceChange(device) {
1080
- this.obj.propagateDevice(device);
1081
- }
1082
1086
  getModelMatrix() {
1083
1087
  return this.obj.getModelMatrix();
1084
1088
  }
@@ -1100,8 +1104,6 @@ export class TraceLines2d extends SimulationElement2d {
1100
1104
  isWireframe() {
1101
1105
  return true;
1102
1106
  }
1103
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
1104
- onDeviceChange(_) { }
1105
1107
  }
1106
1108
  export class TraceLines3d extends SimulationElement3d {
1107
1109
  geometry;
@@ -1120,6 +1122,4 @@ export class TraceLines3d extends SimulationElement3d {
1120
1122
  isWireframe() {
1121
1123
  return true;
1122
1124
  }
1123
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
1124
- onDeviceChange(_) { }
1125
1125
  }
@@ -12,6 +12,14 @@ export declare class VertexCache {
12
12
  shouldUpdate(): boolean;
13
13
  getVertexCount(): number;
14
14
  }
15
+ export declare class GlobalInfo {
16
+ private device;
17
+ constructor();
18
+ setDevice(device: GPUDevice): void;
19
+ errorGetDevice(): GPUDevice;
20
+ getDevice(): GPUDevice | null;
21
+ }
22
+ export declare const globalInfo: GlobalInfo;
15
23
  export declare const updateProjectionMatrix: (mat: Mat4, aspectRatio: number, zNear?: number, zFar?: number) => any;
16
24
  export declare const updateWorldProjectionMatrix: (worldProjMat: Mat4, projMat: Mat4) => void;
17
25
  export declare const updateOrthoProjectionMatrix: (mat: Mat4, screenSize: [number, number]) => Float32Array;
@@ -57,8 +65,6 @@ declare class BufferGenerator {
57
65
  export declare const bufferGenerator: BufferGenerator;
58
66
  export declare function vector3ToPixelRatio(vec: Vector3): void;
59
67
  export declare function vector2ToPixelRatio(vec: Vector2): void;
60
- export declare function matrixFromRotation(rotation: Vector3): Mat4;
61
- export declare function rotateMat4(mat: Mat4, rotation: Vector3): void;
62
68
  export declare function createPipeline(device: GPUDevice, module: GPUShaderModule, bindGroupLayouts: GPUBindGroupLayout[], presentationFormat: GPUTextureFormat, topology: GPUPrimitiveTopology, vertexParams?: VertexParamInfo[]): GPURenderPipeline;
63
69
  export declare function triangulateWireFrameOrder(len: number): number[];
64
70
  export declare function getTotalVertices(scene: SimSceneObjInfo[]): number;
@@ -26,6 +26,24 @@ export class VertexCache {
26
26
  return this.vertices.length / BUF_LEN;
27
27
  }
28
28
  }
29
+ export class GlobalInfo {
30
+ device;
31
+ constructor() {
32
+ this.device = null;
33
+ }
34
+ setDevice(device) {
35
+ this.device = device;
36
+ }
37
+ errorGetDevice() {
38
+ if (!this.device)
39
+ throw logger.error('GPUDevice is null');
40
+ return this.device;
41
+ }
42
+ getDevice() {
43
+ return this.device;
44
+ }
45
+ }
46
+ export const globalInfo = new GlobalInfo();
29
47
  export const updateProjectionMatrix = (mat, aspectRatio, zNear = 1, zFar = 500) => {
30
48
  const fov = Math.PI / 4;
31
49
  return mat4.perspective(fov, aspectRatio, zNear, zFar, mat);
@@ -201,18 +219,6 @@ export function vector2ToPixelRatio(vec) {
201
219
  vec[0] *= devicePixelRatio;
202
220
  vec[1] *= devicePixelRatio;
203
221
  }
204
- export function matrixFromRotation(rotation) {
205
- const rotMatrix = mat4.identity();
206
- mat4.rotateZ(rotMatrix, rotation[2], rotMatrix);
207
- mat4.rotateY(rotMatrix, rotation[1], rotMatrix);
208
- mat4.rotateX(rotMatrix, rotation[0], rotMatrix);
209
- return rotMatrix;
210
- }
211
- export function rotateMat4(mat, rotation) {
212
- mat4.rotateZ(mat, rotation[2], mat);
213
- mat4.rotateY(mat, rotation[1], mat);
214
- mat4.rotateX(mat, rotation[0], mat);
215
- }
216
222
  export function createPipeline(device, module, bindGroupLayouts, presentationFormat, topology, vertexParams) {
217
223
  let params = [
218
224
  {
@@ -31,11 +31,10 @@ export declare class Simulation extends Settings {
31
31
  private fittingElement;
32
32
  private running;
33
33
  private initialized;
34
- private frameRateView;
35
- private device;
36
34
  private pipelines;
37
35
  private renderInfo;
38
36
  private resizeEvents;
37
+ private frameRateView;
39
38
  constructor(idOrCanvasRef: string | HTMLCanvasElement, sceneCamera?: Camera | null, showFrameRate?: boolean);
40
39
  private handleCanvasResize;
41
40
  onResize(cb: (width: number, height: number) => void): void;
@@ -51,7 +50,6 @@ export declare class Simulation extends Settings {
51
50
  private applyCanvasSize;
52
51
  setCanvasSize(width: number, height: number): void;
53
52
  start(): void;
54
- private propagateDevice;
55
53
  stop(): void;
56
54
  setBackground(color: Color): void;
57
55
  getScene(): SimSceneObjInfo[];
@@ -71,7 +69,7 @@ export declare class ShaderGroup extends EmptyElement {
71
69
  private bindGroup;
72
70
  private valueBuffers;
73
71
  constructor(shaderCode: string, topology: GPUPrimitiveTopology | undefined, vertexParams: VertexParamInfo[], paramGenerator: VertexParamGeneratorInfo, bindGroup?: BindGroupInfo);
74
- protected onDeviceChange(device: GPUDevice): void;
72
+ private initPipeline;
75
73
  getBindGroupLayout(): GPUBindGroupLayout | null;
76
74
  getPipeline(): GPURenderPipeline | null;
77
75
  getBindGroupBuffers(device: GPUDevice): GPUBuffer[] | null;
@@ -3,7 +3,7 @@ import { EmptyElement, SimulationElement3d } from './graphics.js';
3
3
  import { BUF_LEN, worldProjMatOffset } from './constants.js';
4
4
  import { Color, matrix4, transitionValues, vector2, vector3 } from './utils.js';
5
5
  import { BlankGeometry } from './geometry.js';
6
- import { SimSceneObjInfo, buildDepthTexture, buildMultisampleTexture, updateProjectionMatrix, createPipeline, getTotalVertices, logger, removeObjectId, updateOrthoProjectionMatrix, updateWorldProjectionMatrix } from './internalUtils.js';
6
+ import { SimSceneObjInfo, buildDepthTexture, buildMultisampleTexture, updateProjectionMatrix, createPipeline, getTotalVertices, logger, removeObjectId, updateOrthoProjectionMatrix, updateWorldProjectionMatrix, globalInfo } from './internalUtils.js';
7
7
  import { Settings } from './settings.js';
8
8
  const shader = `
9
9
  struct Uniforms {
@@ -32,7 +32,6 @@ fn vertex_main(
32
32
  ) -> VertexOutput {
33
33
  var output: VertexOutput;
34
34
 
35
-
36
35
  if (drawingInstance == 1) {
37
36
  output.Position = uniforms.worldProjectionMatrix * uniforms.modelProjectionMatrix * instanceMatrices[instanceIdx] * vec4(position, 1.0);
38
37
  } else {
@@ -70,16 +69,21 @@ class FrameRateView {
70
69
  fpsBuffer = [];
71
70
  maxFpsBufferLength = 8;
72
71
  prevAvg = 0;
72
+ showing;
73
73
  constructor(show) {
74
74
  this.el = document.createElement('div');
75
75
  this.el.classList.add('simjs-frame-rate');
76
+ this.showing = show;
76
77
  const style = document.createElement('style');
77
78
  style.innerHTML = simjsFrameRateCss;
78
- if (show) {
79
+ if (this.showing) {
79
80
  document.head.appendChild(style);
80
81
  document.body.appendChild(this.el);
81
82
  }
82
83
  }
84
+ isActive() {
85
+ return this.showing;
86
+ }
83
87
  updateFrameRate(num) {
84
88
  if (this.fpsBuffer.length < this.maxFpsBufferLength) {
85
89
  this.fpsBuffer.push(num);
@@ -212,11 +216,10 @@ export class Simulation extends Settings {
212
216
  fittingElement = false;
213
217
  running = true;
214
218
  initialized = false;
215
- frameRateView;
216
- device = null;
217
219
  pipelines = null;
218
220
  renderInfo = null;
219
221
  resizeEvents;
222
+ frameRateView;
220
223
  constructor(idOrCanvasRef, sceneCamera = null, showFrameRate = false) {
221
224
  super();
222
225
  if (typeof idOrCanvasRef === 'string') {
@@ -263,9 +266,6 @@ export class Simulation extends Settings {
263
266
  }
264
267
  add(el, id) {
265
268
  if (el instanceof SimulationElement3d) {
266
- if (this.device !== null) {
267
- el.propagateDevice(this.device);
268
- }
269
269
  const obj = new SimSceneObjInfo(el, id);
270
270
  this.scene.unshift(obj);
271
271
  }
@@ -324,8 +324,7 @@ export class Simulation extends Settings {
324
324
  if (!ctx)
325
325
  throw logger.error('Context is null');
326
326
  const device = await adapter.requestDevice();
327
- this.device = device;
328
- this.propagateDevice(device);
327
+ globalInfo.setDevice(device);
329
328
  ctx.configure({
330
329
  device,
331
330
  format: 'bgra8unorm'
@@ -335,12 +334,6 @@ export class Simulation extends Settings {
335
334
  this.render(ctx);
336
335
  })();
337
336
  }
338
- propagateDevice(device) {
339
- for (let i = 0; i < this.scene.length; i++) {
340
- const el = this.scene[i].getObj();
341
- el.propagateDevice(device);
342
- }
343
- }
344
337
  stop() {
345
338
  this.running = false;
346
339
  }
@@ -354,10 +347,10 @@ export class Simulation extends Settings {
354
347
  return this.scene.map((item) => item.getObj());
355
348
  }
356
349
  render(ctx) {
357
- if (this.canvasRef === null || this.device === null)
350
+ const device = globalInfo.getDevice();
351
+ if (this.canvasRef === null || device === null)
358
352
  return;
359
353
  const canvas = this.canvasRef;
360
- const device = this.device;
361
354
  canvas.width = canvas.clientWidth * devicePixelRatio;
362
355
  canvas.height = canvas.clientHeight * devicePixelRatio;
363
356
  const presentationFormat = navigator.gpu.getPreferredCanvasFormat();
@@ -412,9 +405,7 @@ export class Simulation extends Settings {
412
405
  let prev = Date.now() - 10;
413
406
  let prevFps = 0;
414
407
  const frame = async () => {
415
- if (!canvas)
416
- return;
417
- if (!this.renderInfo)
408
+ if (!canvas || !this.renderInfo)
418
409
  return;
419
410
  requestAnimationFrame(frame);
420
411
  if (!this.running)
@@ -423,7 +414,7 @@ export class Simulation extends Settings {
423
414
  const diff = Math.max(now - prev, 1);
424
415
  prev = now;
425
416
  const fps = 1000 / diff;
426
- if (fps === prevFps) {
417
+ if (fps === prevFps && this.frameRateView.isActive()) {
427
418
  this.frameRateView.updateFrameRate(fps);
428
419
  }
429
420
  prevFps = fps;
@@ -513,7 +504,7 @@ export class Simulation extends Settings {
513
504
  vertexBuffer.unmap();
514
505
  passEncoder.setVertexBuffer(0, vertexBuffer, currentOffset, buffer.byteLength);
515
506
  const modelMatrix = obj.getModelMatrix();
516
- const uniformBuffer = obj.getUniformBuffer(device, modelMatrix);
507
+ const uniformBuffer = obj.getUniformBuffer(modelMatrix);
517
508
  const projBuf = obj.is3d ? worldProjMat : orthoMatrix;
518
509
  device.queue.writeBuffer(uniformBuffer, worldProjMatOffset, projBuf.buffer, projBuf.byteOffset, projBuf.byteLength);
519
510
  if (shaderInfo) {
@@ -536,7 +527,8 @@ export class Simulation extends Settings {
536
527
  let instanceBuffer;
537
528
  if (obj.isInstance) {
538
529
  instances = obj.getNumInstances();
539
- instanceBuffer = obj.getMatrixBuffer(device);
530
+ instanceBuffer =
531
+ obj.getMatrixBuffer() ?? this.renderInfo.instanceBuffer;
540
532
  }
541
533
  else {
542
534
  instanceBuffer = this.renderInfo.instanceBuffer;
@@ -627,7 +619,8 @@ export class ShaderGroup extends EmptyElement {
627
619
  this.vertexParams = vertexParams;
628
620
  this.valueBuffers = null;
629
621
  }
630
- onDeviceChange(device) {
622
+ initPipeline() {
623
+ const device = globalInfo.errorGetDevice();
631
624
  this.module = device.createShaderModule({ code: this.code });
632
625
  const presentationFormat = navigator.gpu.getPreferredCanvasFormat();
633
626
  const bindGroupLayout = device.createBindGroupLayout(baseBindGroupLayout);
@@ -649,6 +642,8 @@ export class ShaderGroup extends EmptyElement {
649
642
  return this.bindGroupLayout;
650
643
  }
651
644
  getPipeline() {
645
+ if (!this.pipeline)
646
+ this.initPipeline();
652
647
  return this.pipeline;
653
648
  }
654
649
  getBindGroupBuffers(device) {
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "types": "./dist/index.d.ts",
6
6
  "author": "Jackson Otto",
7
7
  "description": "A simple graphics library using WebGPU",
8
- "version": "0.7.1",
8
+ "version": "0.7.3",
9
9
  "exports": {
10
10
  ".": {
11
11
  "import": "./dist/index.js",