simulationjsv2 0.4.3 → 0.4.5

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.
@@ -184,7 +184,11 @@ export declare class Instance<T extends SimulationElement2d | SimulationElement3
184
184
  private matrixBuffer;
185
185
  private device;
186
186
  readonly isInstance = true;
187
+ private baseMat;
187
188
  constructor(obj: T, numInstances: number);
189
+ setNumInstances(numInstances: number): void;
190
+ setInstance(instance: number, transformation: Mat4): void;
191
+ private mapBuffer;
188
192
  private setMatrixBuffer;
189
193
  getInstances(): Mat4[];
190
194
  getNumInstances(): number;
package/dist/graphics.js CHANGED
@@ -373,6 +373,7 @@ export class Circle extends SimulationElement2d {
373
373
  detail;
374
374
  constructor(pos, radius, color, detail = 50) {
375
375
  super(pos, 0, color);
376
+ vector2ToPixelRatio(this.pos);
376
377
  this.radius = radius;
377
378
  this.detail = detail;
378
379
  this.geometry = new CircleGeometry(this.radius, this.detail);
@@ -894,6 +895,7 @@ export class Instance extends SimulationElement3d {
894
895
  matrixBuffer;
895
896
  device;
896
897
  isInstance = true;
898
+ baseMat;
897
899
  constructor(obj, numInstances) {
898
900
  super(vector3());
899
901
  this.device = null;
@@ -903,18 +905,55 @@ export class Instance extends SimulationElement3d {
903
905
  this.instanceMatrix = [];
904
906
  this.is3d = Boolean(obj.is3d);
905
907
  this.geometry = new BlankGeometry();
906
- const mat = matrix4();
908
+ this.baseMat = matrix4();
907
909
  if (typeof obj.getRotation() === 'number') {
908
- mat4.rotateZ(mat, obj.getRotation(), mat);
910
+ mat4.rotateZ(this.baseMat, obj.getRotation(), this.baseMat);
909
911
  }
910
912
  else {
911
- rotateMat4(mat, obj.getRotation());
913
+ rotateMat4(this.baseMat, obj.getRotation());
912
914
  }
913
915
  for (let i = 0; i < numInstances; i++) {
914
- const clone = cloneBuf(mat);
916
+ const clone = cloneBuf(this.baseMat);
915
917
  this.instanceMatrix.push(clone);
916
918
  }
917
919
  }
920
+ setNumInstances(numInstances) {
921
+ if (numInstances < 0)
922
+ throw logger.error('Num instances is less than 0');
923
+ const oldLen = this.instanceMatrix.length;
924
+ if (numInstances < oldLen) {
925
+ const diff = oldLen - numInstances;
926
+ this.instanceMatrix.splice(oldLen - diff, diff);
927
+ return;
928
+ }
929
+ const oldArr = this.instanceMatrix;
930
+ this.instanceMatrix = Array(numInstances);
931
+ for (let i = 0; i < numInstances; i++) {
932
+ if (i < oldLen) {
933
+ this.instanceMatrix[i] = oldArr[i];
934
+ continue;
935
+ }
936
+ const clone = cloneBuf(this.baseMat);
937
+ this.instanceMatrix[i] = clone;
938
+ }
939
+ if (this.device) {
940
+ this.setMatrixBuffer();
941
+ this.mapBuffer();
942
+ }
943
+ }
944
+ setInstance(instance, transformation) {
945
+ if (instance >= this.instanceMatrix.length)
946
+ return;
947
+ this.instanceMatrix[instance] = transformation;
948
+ this.mapBuffer();
949
+ }
950
+ mapBuffer() {
951
+ if (!this.device || this.matrixBuffer === null)
952
+ return;
953
+ const buf = new Float32Array(this.instanceMatrix.map((mat) => [...mat]).flat());
954
+ this.device.queue.writeBuffer(this.matrixBuffer, 0, buf.buffer, buf.byteOffset, buf.byteLength);
955
+ this.matrixBuffer.unmap();
956
+ }
918
957
  setMatrixBuffer() {
919
958
  if (!this.device || this.instanceMatrix.length === 0)
920
959
  return;
@@ -922,12 +961,9 @@ export class Instance extends SimulationElement3d {
922
961
  const size = Math.max(minSize, this.instanceMatrix[0].byteLength * this.instanceMatrix.length);
923
962
  this.matrixBuffer = this.device.createBuffer({
924
963
  size,
925
- usage: GPUBufferUsage.STORAGE,
926
- mappedAtCreation: true
964
+ usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST
927
965
  });
928
- const buf = this.instanceMatrix.map((mat) => [...mat]).flat();
929
- new Float32Array(this.matrixBuffer.getMappedRange()).set(buf);
930
- this.matrixBuffer.unmap();
966
+ this.mapBuffer();
931
967
  }
932
968
  getInstances() {
933
969
  return this.instanceMatrix;
@@ -283,8 +283,6 @@ export function getTotalVertices(scene) {
283
283
  let total = 0;
284
284
  for (let i = 0; i < scene.length; i++) {
285
285
  const obj = scene[i].getObj();
286
- if (obj.isCollection)
287
- continue;
288
286
  total += obj.getVertexCount();
289
287
  }
290
288
  return total;
@@ -44,6 +44,7 @@ export declare class SceneCollection extends SimulationElement3d {
44
44
  setWireframe(_: boolean): void;
45
45
  getName(): string;
46
46
  getScene(): SimSceneObjInfo[];
47
+ getVertexCount(): number;
47
48
  getSceneObjects(): SimulationElement<Vector3 | Vector2>[];
48
49
  setSceneObjects(newScene: SimulationElement<any>[]): void;
49
50
  setScene(newScene: SimSceneObjInfo[]): void;
@@ -266,7 +266,8 @@ export class Simulation {
266
266
  this.renderInfo = {
267
267
  uniformBuffer,
268
268
  bindGroupLayout,
269
- instanceBuffer
269
+ instanceBuffer,
270
+ vertexBuffer: null
270
271
  };
271
272
  this.pipelines = {
272
273
  triangleList2d: createPipeline(device, shaderModule, bindGroupLayout, presentationFormat, 'vertex_main_2d', 'triangle-list'),
@@ -329,6 +330,8 @@ export class Simulation {
329
330
  const frame = async () => {
330
331
  if (!canvas)
331
332
  return;
333
+ if (!this.renderInfo)
334
+ return;
332
335
  requestAnimationFrame(frame);
333
336
  if (!this.running)
334
337
  return;
@@ -369,22 +372,25 @@ export class Simulation {
369
372
  const passEncoder = commandEncoder.beginRenderPass(renderPassDescriptor);
370
373
  passEncoder.setPipeline(this.pipelines.triangleList3d);
371
374
  passEncoder.setBindGroup(0, uniformBindGroup);
372
- this.renderScene(device, passEncoder, this.scene, diff);
375
+ const totalVertices = getTotalVertices(this.scene);
376
+ if (this.renderInfo.vertexBuffer === null ||
377
+ this.renderInfo.vertexBuffer.size / (4 * BUF_LEN) < totalVertices) {
378
+ this.renderInfo.vertexBuffer = device.createBuffer({
379
+ size: totalVertices * 4 * BUF_LEN,
380
+ usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST
381
+ });
382
+ }
383
+ this.renderScene(device, passEncoder, this.renderInfo.vertexBuffer, this.scene, 0, diff);
373
384
  this.camera.updateConsumed();
374
385
  passEncoder.end();
375
386
  device.queue.submit([commandEncoder.finish()]);
376
387
  };
377
388
  requestAnimationFrame(frame);
378
389
  }
379
- async renderScene(device, passEncoder, scene, diff) {
390
+ renderScene(device, passEncoder, vertexBuffer, scene, startOffset, diff) {
380
391
  if (this.pipelines === null)
381
- return;
382
- let totalVertices = getTotalVertices(scene);
383
- const vertexBuffer = device.createBuffer({
384
- size: totalVertices * 4 * BUF_LEN,
385
- usage: GPUBufferUsage.VERTEX | GPUBufferUsage.COPY_DST
386
- });
387
- let currentOffset = 0;
392
+ return 0;
393
+ let currentOffset = startOffset;
388
394
  let toRemove = [];
389
395
  for (let i = 0; i < scene.length; i++) {
390
396
  const lifetime = scene[i].getLifetime();
@@ -398,7 +404,7 @@ export class Simulation {
398
404
  }
399
405
  const obj = scene[i].getObj();
400
406
  if (obj.isCollection) {
401
- this.renderScene(device, passEncoder, obj.getScene(), diff);
407
+ currentOffset += this.renderScene(device, passEncoder, vertexBuffer, obj.getScene(), currentOffset, diff);
402
408
  continue;
403
409
  }
404
410
  const buffer = new Float32Array(obj.getBuffer(this.camera));
@@ -465,6 +471,7 @@ export class Simulation {
465
471
  for (let i = toRemove.length - 1; i >= 0; i--) {
466
472
  removeObject(scene, scene[i].getObj());
467
473
  }
474
+ return currentOffset - startOffset;
468
475
  }
469
476
  fitElement() {
470
477
  this.assertHasCanvas();
@@ -501,6 +508,13 @@ export class SceneCollection extends SimulationElement3d {
501
508
  getScene() {
502
509
  return this.scene;
503
510
  }
511
+ getVertexCount() {
512
+ let total = 0;
513
+ for (let i = 0; i < this.scene.length; i++) {
514
+ total += this.scene[i].getObj().getVertexCount();
515
+ }
516
+ return total;
517
+ }
504
518
  getSceneObjects() {
505
519
  return this.scene.map((item) => item.getObj());
506
520
  }
package/dist/types.d.ts CHANGED
@@ -75,4 +75,5 @@ export type RenderInfo = {
75
75
  uniformBuffer: GPUBuffer;
76
76
  instanceBuffer: GPUBuffer;
77
77
  bindGroupLayout: GPUBindGroupLayout;
78
+ vertexBuffer: GPUBuffer | null;
78
79
  };
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.4.3",
8
+ "version": "0.4.5",
9
9
  "exports": {
10
10
  ".": {
11
11
  "import": "./dist/index.js",