simulationjsv2 0.6.0 → 0.7.1

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.
@@ -1,9 +1,10 @@
1
1
  import { vec3 } from 'wgpu-matrix';
2
- import { Instance, SimulationElement3d } from './graphics.js';
2
+ import { EmptyElement, SimulationElement3d } from './graphics.js';
3
3
  import { BUF_LEN, worldProjMatOffset } from './constants.js';
4
- import { Color, matrix4, toSceneObjInfoMany, transitionValues, vector2, vector3 } from './utils.js';
4
+ import { Color, matrix4, transitionValues, vector2, vector3 } from './utils.js';
5
5
  import { BlankGeometry } from './geometry.js';
6
- import { addObject, buildDepthTexture, buildMultisampleTexture, updateProjectionMatrix, createPipeline, getTotalVertices, logger, removeObject, removeObjectId, updateOrthoProjectionMatrix, updateWorldProjectionMatrix, wrapVoidPromise } from './internalUtils.js';
6
+ import { SimSceneObjInfo, buildDepthTexture, buildMultisampleTexture, updateProjectionMatrix, createPipeline, getTotalVertices, logger, removeObjectId, updateOrthoProjectionMatrix, updateWorldProjectionMatrix } from './internalUtils.js';
7
+ import { Settings } from './settings.js';
7
8
  const shader = `
8
9
  struct Uniforms {
9
10
  worldProjectionMatrix: mat4x4<f32>,
@@ -31,6 +32,7 @@ fn vertex_main(
31
32
  ) -> VertexOutput {
32
33
  var output: VertexOutput;
33
34
 
35
+
34
36
  if (drawingInstance == 1) {
35
37
  output.Position = uniforms.worldProjectionMatrix * uniforms.modelProjectionMatrix * instanceMatrices[instanceIdx] * vec4(position, 1.0);
36
38
  } else {
@@ -115,7 +117,95 @@ let aspectRatio = 0;
115
117
  const projMat = matrix4();
116
118
  const worldProjMat = matrix4();
117
119
  const orthoMatrix = matrix4();
118
- export class Simulation {
120
+ export class Camera {
121
+ pos;
122
+ rotation;
123
+ aspectRatio = 1;
124
+ updated;
125
+ screenSize = vector2();
126
+ constructor(pos, rotation = vector3()) {
127
+ this.pos = pos;
128
+ this.updated = false;
129
+ this.rotation = rotation;
130
+ }
131
+ setScreenSize(size) {
132
+ this.screenSize = size;
133
+ this.aspectRatio = size[0] / size[1];
134
+ this.updated = true;
135
+ }
136
+ getScreenSize() {
137
+ return this.screenSize;
138
+ }
139
+ hasUpdated() {
140
+ return this.updated;
141
+ }
142
+ updateConsumed() {
143
+ this.updated = false;
144
+ }
145
+ move(amount, t = 0, f) {
146
+ const initial = vector3();
147
+ vec3.clone(this.pos, initial);
148
+ return transitionValues((p) => {
149
+ const x = amount[0] * p;
150
+ const y = amount[1] * p;
151
+ const z = amount[2] * p;
152
+ const diff = vector3(x, y, z);
153
+ vec3.add(this.pos, diff, this.pos);
154
+ }, () => {
155
+ vec3.add(initial, amount, this.pos);
156
+ }, t, f);
157
+ }
158
+ moveTo(pos, t = 0, f) {
159
+ const diff = vector3();
160
+ vec3.sub(pos, this.pos, diff);
161
+ return transitionValues((p) => {
162
+ const x = diff[0] * p;
163
+ const y = diff[1] * p;
164
+ const z = diff[2] * p;
165
+ const amount = vector3(x, y, z);
166
+ vec3.add(this.pos, amount, this.pos);
167
+ }, () => {
168
+ vec3.clone(pos, this.pos);
169
+ }, t, f);
170
+ }
171
+ rotateTo(value, t = 0, f) {
172
+ const diff = vec3.clone(value);
173
+ vec3.sub(diff, diff, this.rotation);
174
+ return transitionValues((p) => {
175
+ const x = diff[0] * p;
176
+ const y = diff[1] * p;
177
+ const z = diff[2] * p;
178
+ vec3.add(this.rotation, this.rotation, vector3(x, y, z));
179
+ this.updated = true;
180
+ }, () => {
181
+ this.rotation = value;
182
+ }, t, f);
183
+ }
184
+ rotate(amount, t = 0, f) {
185
+ const initial = vector3();
186
+ vec3.clone(this.rotation, initial);
187
+ return transitionValues((p) => {
188
+ const x = amount[0] * p;
189
+ const y = amount[1] * p;
190
+ const z = amount[2] * p;
191
+ vec3.add(this.rotation, vector3(x, y, z), this.rotation);
192
+ this.updated = true;
193
+ }, () => {
194
+ vec3.add(initial, amount, this.rotation);
195
+ }, t, f);
196
+ }
197
+ getRotation() {
198
+ return this.rotation;
199
+ }
200
+ getPos() {
201
+ return this.pos;
202
+ }
203
+ getAspectRatio() {
204
+ return this.aspectRatio;
205
+ }
206
+ }
207
+ export let camera = new Camera(vector3());
208
+ export class Simulation extends Settings {
119
209
  canvasRef = null;
120
210
  bgColor = new Color(255, 255, 255);
121
211
  scene = [];
@@ -123,12 +213,12 @@ export class Simulation {
123
213
  running = true;
124
214
  initialized = false;
125
215
  frameRateView;
126
- camera;
127
216
  device = null;
128
217
  pipelines = null;
129
218
  renderInfo = null;
130
219
  resizeEvents;
131
- constructor(idOrCanvasRef, camera = null, showFrameRate = false) {
220
+ constructor(idOrCanvasRef, sceneCamera = null, showFrameRate = false) {
221
+ super();
132
222
  if (typeof idOrCanvasRef === 'string') {
133
223
  const ref = document.getElementById(idOrCanvasRef);
134
224
  if (ref !== null)
@@ -143,10 +233,9 @@ export class Simulation {
143
233
  throw logger.error(`Canvas ref/id provided is invalid`);
144
234
  }
145
235
  const parent = this.canvasRef.parentElement;
146
- if (!camera)
147
- this.camera = new Camera(vector3());
148
- else
149
- this.camera = camera;
236
+ if (sceneCamera) {
237
+ camera = sceneCamera;
238
+ }
150
239
  if (parent === null)
151
240
  throw logger.error('Canvas parent is null');
152
241
  this.resizeEvents = [];
@@ -173,10 +262,24 @@ export class Simulation {
173
262
  return (this.canvasRef?.height || 0) / devicePixelRatio;
174
263
  }
175
264
  add(el, id) {
176
- addObject(this.scene, el, this.device, id);
265
+ if (el instanceof SimulationElement3d) {
266
+ if (this.device !== null) {
267
+ el.propagateDevice(this.device);
268
+ }
269
+ const obj = new SimSceneObjInfo(el, id);
270
+ this.scene.unshift(obj);
271
+ }
272
+ else {
273
+ throw logger.error('Cannot add invalid SimulationElement');
274
+ }
177
275
  }
178
276
  remove(el) {
179
- removeObject(this.scene, el);
277
+ for (let i = 0; i < this.scene.length; i++) {
278
+ if (this.scene[i].getObj() === el) {
279
+ this.scene.splice(i, 1);
280
+ break;
281
+ }
282
+ }
180
283
  }
181
284
  removeId(id) {
182
285
  removeObjectId(this.scene, id);
@@ -228,16 +331,14 @@ export class Simulation {
228
331
  format: 'bgra8unorm'
229
332
  });
230
333
  const screenSize = vector2(this.canvasRef.width, this.canvasRef.height);
231
- this.camera.setScreenSize(screenSize);
334
+ camera.setScreenSize(screenSize);
232
335
  this.render(ctx);
233
336
  })();
234
337
  }
235
338
  propagateDevice(device) {
236
339
  for (let i = 0; i < this.scene.length; i++) {
237
340
  const el = this.scene[i].getObj();
238
- if (el instanceof SceneCollection) {
239
- el.setDevice(device);
240
- }
341
+ el.propagateDevice(device);
241
342
  }
242
343
  }
243
344
  stop() {
@@ -294,8 +395,8 @@ export class Simulation {
294
395
  updateProjectionMatrix(projMat, newAspectRatio);
295
396
  aspectRatio = newAspectRatio;
296
397
  }
297
- updateWorldProjectionMatrix(worldProjMat, projMat, this.camera);
298
- updateOrthoProjectionMatrix(orthoMatrix, this.camera.getScreenSize());
398
+ updateWorldProjectionMatrix(worldProjMat, projMat);
399
+ updateOrthoProjectionMatrix(orthoMatrix, camera.getScreenSize());
299
400
  let multisampleTexture = buildMultisampleTexture(device, ctx, canvas.width, canvas.height);
300
401
  let depthTexture = buildDepthTexture(device, canvas.width, canvas.height);
301
402
  const renderPassDescriptor = {
@@ -328,14 +429,14 @@ export class Simulation {
328
429
  prevFps = fps;
329
430
  canvas.width = canvas.clientWidth * devicePixelRatio;
330
431
  canvas.height = canvas.clientHeight * devicePixelRatio;
331
- const screenSize = this.camera.getScreenSize();
432
+ const screenSize = camera.getScreenSize();
332
433
  if (screenSize[0] !== canvas.width || screenSize[1] !== canvas.height) {
333
- this.camera.setScreenSize(vector2(canvas.width, canvas.height));
434
+ camera.setScreenSize(vector2(canvas.width, canvas.height));
334
435
  screenSize[0] = canvas.width;
335
436
  screenSize[1] = canvas.height;
336
- aspectRatio = this.camera.getAspectRatio();
437
+ aspectRatio = camera.getAspectRatio();
337
438
  updateProjectionMatrix(projMat, aspectRatio);
338
- updateWorldProjectionMatrix(worldProjMat, projMat, this.camera);
439
+ updateWorldProjectionMatrix(worldProjMat, projMat);
339
440
  multisampleTexture = buildMultisampleTexture(device, ctx, screenSize[0], screenSize[1]);
340
441
  depthTexture = buildDepthTexture(device, screenSize[0], screenSize[1]);
341
442
  renderPassDescriptor.depthStencilAttachment.view = depthTexture.createView();
@@ -346,9 +447,9 @@ export class Simulation {
346
447
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
347
448
  // @ts-ignore
348
449
  renderPassDescriptor.colorAttachments[0].resolveTarget = ctx.getCurrentTexture().createView();
349
- if (this.camera.hasUpdated()) {
350
- updateOrthoProjectionMatrix(orthoMatrix, this.camera.getScreenSize());
351
- updateWorldProjectionMatrix(worldProjMat, projMat, this.camera);
450
+ if (camera.hasUpdated()) {
451
+ updateOrthoProjectionMatrix(orthoMatrix, camera.getScreenSize());
452
+ updateWorldProjectionMatrix(worldProjMat, projMat);
352
453
  }
353
454
  const commandEncoder = device.createCommandEncoder();
354
455
  const passEncoder = commandEncoder.beginRenderPass(renderPassDescriptor);
@@ -362,7 +463,7 @@ export class Simulation {
362
463
  });
363
464
  }
364
465
  this.renderScene(device, passEncoder, this.renderInfo.vertexBuffer, this.scene, 0, diff);
365
- this.camera.updateConsumed();
466
+ camera.updateConsumed();
366
467
  passEncoder.end();
367
468
  device.queue.submit([commandEncoder.finish()]);
368
469
  };
@@ -384,7 +485,7 @@ export class Simulation {
384
485
  scene[i].traverseLife(diff);
385
486
  }
386
487
  const obj = scene[i].getObj();
387
- if (obj instanceof SceneCollection) {
488
+ if (obj.hasChildren()) {
388
489
  let shaderInfo = undefined;
389
490
  if (obj instanceof ShaderGroup) {
390
491
  const pipeline = obj.getPipeline();
@@ -394,30 +495,27 @@ export class Simulation {
394
495
  paramGenerator: obj.getVertexParamGenerator(),
395
496
  bufferInfo: obj.hasBindGroup()
396
497
  ? {
397
- buffers: obj.getBindGroupBuffers(),
498
+ buffers: obj.getBindGroupBuffers(device),
398
499
  layout: obj.getBindGroupLayout()
399
500
  }
400
501
  : null
401
502
  };
402
503
  }
403
504
  }
404
- currentOffset += this.renderScene(device, passEncoder, vertexBuffer, obj.getScene(), currentOffset, diff, shaderInfo || undefined);
405
- continue;
505
+ currentOffset += this.renderScene(device, passEncoder, vertexBuffer, obj.getChildrenInfos(), currentOffset, diff, shaderInfo);
406
506
  }
507
+ if (obj.isEmpty)
508
+ continue;
407
509
  const buffer = new Float32Array(obj.getBuffer(shaderInfo?.paramGenerator));
408
510
  const bufLen = shaderInfo?.paramGenerator?.bufferSize || BUF_LEN;
409
511
  const vertexCount = buffer.length / bufLen;
410
- device.queue.writeBuffer(vertexBuffer, currentOffset, buffer);
512
+ device.queue.writeBuffer(vertexBuffer, currentOffset, buffer.buffer, buffer.byteOffset, buffer.byteLength);
411
513
  vertexBuffer.unmap();
412
514
  passEncoder.setVertexBuffer(0, vertexBuffer, currentOffset, buffer.byteLength);
413
- const modelMatrix = obj.getModelMatrix(this.camera);
515
+ const modelMatrix = obj.getModelMatrix();
414
516
  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
- }
517
+ const projBuf = obj.is3d ? worldProjMat : orthoMatrix;
518
+ device.queue.writeBuffer(uniformBuffer, worldProjMatOffset, projBuf.buffer, projBuf.byteOffset, projBuf.byteLength);
421
519
  if (shaderInfo) {
422
520
  passEncoder.setPipeline(shaderInfo.pipeline);
423
521
  }
@@ -436,7 +534,7 @@ export class Simulation {
436
534
  let instances = 1;
437
535
  if (this.renderInfo) {
438
536
  let instanceBuffer;
439
- if (obj instanceof Instance) {
537
+ if (obj.isInstance) {
440
538
  instances = obj.getNumInstances();
441
539
  instanceBuffer = obj.getMatrixBuffer(device);
442
540
  }
@@ -480,7 +578,7 @@ export class Simulation {
480
578
  currentOffset += buffer.byteLength;
481
579
  }
482
580
  for (let i = toRemove.length - 1; i >= 0; i--) {
483
- removeObject(scene, scene[i].getObj());
581
+ this.remove(scene[i].getObj());
484
582
  }
485
583
  return currentOffset - startOffset;
486
584
  }
@@ -496,179 +594,6 @@ export class Simulation {
496
594
  }
497
595
  }
498
596
  }
499
- export class SceneCollection extends SimulationElement3d {
500
- geometry;
501
- name;
502
- scene;
503
- device = null;
504
- constructor(name) {
505
- super(vector3());
506
- this.wireframe = false;
507
- this.name = name || null;
508
- this.scene = [];
509
- this.geometry = new BlankGeometry();
510
- }
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
- }
517
- getName() {
518
- return this.name;
519
- }
520
- getScene() {
521
- return this.scene;
522
- }
523
- setDevice(device) {
524
- this.device = device;
525
- this.propagateDevice(device);
526
- }
527
- propagateDevice(device) {
528
- for (let i = 0; i < this.scene.length; i++) {
529
- const el = this.scene[i].getObj();
530
- if (el instanceof SceneCollection) {
531
- el.setDevice(device);
532
- }
533
- }
534
- }
535
- getVertexCount() {
536
- let total = 0;
537
- for (let i = 0; i < this.scene.length; i++) {
538
- total += this.scene[i].getObj().getVertexCount();
539
- }
540
- return total;
541
- }
542
- getSceneObjects() {
543
- return this.scene.map((item) => item.getObj());
544
- }
545
- setSceneObjects(newScene) {
546
- this.scene = toSceneObjInfoMany(newScene);
547
- }
548
- setScene(newScene) {
549
- this.scene = newScene;
550
- }
551
- add(el, id) {
552
- addObject(this.scene, el, this.device, id);
553
- }
554
- remove(el) {
555
- removeObject(this.scene, el);
556
- }
557
- removeId(id) {
558
- removeObjectId(this.scene, id);
559
- }
560
- /**
561
- * @param lifetime - ms
562
- */
563
- setLifetime(el, lifetime) {
564
- for (let i = 0; i < this.scene.length; i++) {
565
- if (this.scene[i].getObj() === el)
566
- this.scene[i].setLifetime(lifetime);
567
- }
568
- }
569
- empty() {
570
- this.scene = [];
571
- }
572
- getSceneBuffer() {
573
- return this.scene.map((item) => item.getObj().getBuffer()).flat();
574
- }
575
- getWireframe() {
576
- return this.getSceneBuffer();
577
- }
578
- getTriangles() {
579
- return this.getSceneBuffer();
580
- }
581
- updateMatrix(camera) {
582
- this.defaultUpdateMatrix(camera);
583
- }
584
- }
585
- export class Camera {
586
- pos;
587
- rotation;
588
- aspectRatio = 1;
589
- updated;
590
- screenSize = vector2();
591
- constructor(pos, rotation = vector3()) {
592
- this.pos = pos;
593
- this.updated = false;
594
- this.rotation = rotation;
595
- }
596
- setScreenSize(size) {
597
- this.screenSize = size;
598
- this.aspectRatio = size[0] / size[1];
599
- this.updated = true;
600
- }
601
- getScreenSize() {
602
- return this.screenSize;
603
- }
604
- hasUpdated() {
605
- return this.updated;
606
- }
607
- updateConsumed() {
608
- this.updated = false;
609
- }
610
- move(amount, t = 0, f) {
611
- const initial = vector3();
612
- vec3.clone(this.pos, initial);
613
- return transitionValues((p) => {
614
- const x = amount[0] * p;
615
- const y = amount[1] * p;
616
- const z = amount[2] * p;
617
- const diff = vector3(x, y, z);
618
- vec3.add(this.pos, diff, this.pos);
619
- }, () => {
620
- vec3.add(initial, amount, this.pos);
621
- }, t, f);
622
- }
623
- moveTo(pos, t = 0, f) {
624
- const diff = vector3();
625
- vec3.sub(pos, this.pos, diff);
626
- return transitionValues((p) => {
627
- const x = diff[0] * p;
628
- const y = diff[1] * p;
629
- const z = diff[2] * p;
630
- const amount = vector3(x, y, z);
631
- vec3.add(this.pos, amount, this.pos);
632
- }, () => {
633
- vec3.clone(pos, this.pos);
634
- }, t, f);
635
- }
636
- rotateTo(value, t = 0, f) {
637
- const diff = vec3.clone(value);
638
- vec3.sub(diff, diff, this.rotation);
639
- return transitionValues((p) => {
640
- const x = diff[0] * p;
641
- const y = diff[1] * p;
642
- const z = diff[2] * p;
643
- vec3.add(this.rotation, this.rotation, vector3(x, y, z));
644
- this.updated = true;
645
- }, () => {
646
- this.rotation = value;
647
- }, t, f);
648
- }
649
- rotate(amount, t = 0, f) {
650
- const initial = vector3();
651
- vec3.clone(this.rotation, initial);
652
- return transitionValues((p) => {
653
- const x = amount[0] * p;
654
- const y = amount[1] * p;
655
- const z = amount[2] * p;
656
- vec3.add(this.rotation, vector3(x, y, z), this.rotation);
657
- this.updated = true;
658
- }, () => {
659
- vec3.add(initial, amount, this.rotation);
660
- }, t, f);
661
- }
662
- getRotation() {
663
- return this.rotation;
664
- }
665
- getPos() {
666
- return this.pos;
667
- }
668
- getAspectRatio() {
669
- return this.aspectRatio;
670
- }
671
- }
672
597
  const defaultShaderCode = `
673
598
  struct Uniforms {
674
599
  worldProjectionMatrix: mat4x4<f32>,
@@ -679,8 +604,7 @@ struct Uniforms {
679
604
 
680
605
  @group(0) @binding(1) var<storage> instanceMatrices: array<mat4x4f>;
681
606
  `;
682
- export class ShaderGroup extends SceneCollection {
683
- geometry;
607
+ export class ShaderGroup extends EmptyElement {
684
608
  code;
685
609
  module;
686
610
  pipeline;
@@ -703,8 +627,7 @@ export class ShaderGroup extends SceneCollection {
703
627
  this.vertexParams = vertexParams;
704
628
  this.valueBuffers = null;
705
629
  }
706
- propagateDevice(device) {
707
- super.propagateDevice(device);
630
+ onDeviceChange(device) {
708
631
  this.module = device.createShaderModule({ code: this.code });
709
632
  const presentationFormat = navigator.gpu.getPreferredCanvasFormat();
710
633
  const bindGroupLayout = device.createBindGroupLayout(baseBindGroupLayout);
@@ -728,16 +651,16 @@ export class ShaderGroup extends SceneCollection {
728
651
  getPipeline() {
729
652
  return this.pipeline;
730
653
  }
731
- getBindGroupBuffers() {
654
+ getBindGroupBuffers(device) {
732
655
  if (this.bindGroup === null)
733
656
  return null;
734
- if (this.device === null)
657
+ if (device === null)
735
658
  return null;
736
659
  const values = this.bindGroup.values();
737
660
  if (this.valueBuffers === null) {
738
661
  this.valueBuffers = [];
739
662
  for (let i = 0; i < values.length; i++) {
740
- const buffer = this.createBuffer(this.device, values[i]);
663
+ const buffer = this.createBuffer(device, values[i]);
741
664
  this.valueBuffers.push(buffer);
742
665
  }
743
666
  }
@@ -746,12 +669,12 @@ export class ShaderGroup extends SceneCollection {
746
669
  const arrayConstructor = values[i].array;
747
670
  const array = new arrayConstructor(values[i].value);
748
671
  if (array.byteLength > this.valueBuffers[i].size) {
749
- const newBuffer = this.createBuffer(this.device, values[i]);
672
+ const newBuffer = this.createBuffer(device, values[i]);
750
673
  this.valueBuffers[i].destroy();
751
674
  this.valueBuffers[i] = newBuffer;
752
675
  }
753
676
  else {
754
- this.device.queue.writeBuffer(this.valueBuffers[i], 0, array.buffer, array.byteOffset, array.byteLength);
677
+ device.queue.writeBuffer(this.valueBuffers[i], 0, array.buffer, array.byteOffset, array.byteLength);
755
678
  }
756
679
  }
757
680
  }
@@ -770,9 +693,6 @@ export class ShaderGroup extends SceneCollection {
770
693
  buffer.unmap();
771
694
  return buffer;
772
695
  }
773
- updateMatrix(camera) {
774
- this.defaultUpdateMatrix(camera);
775
- }
776
696
  getVertexParamGenerator() {
777
697
  return this.paramGenerator;
778
698
  }
@@ -780,39 +700,3 @@ export class ShaderGroup extends SceneCollection {
780
700
  return !!this.bindGroup;
781
701
  }
782
702
  }
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
@@ -65,6 +65,10 @@ export type LineGeometryParams = {
65
65
  export type PolygonGeometryParams = {
66
66
  points: Vertex[];
67
67
  };
68
+ export type TraceLinesParams = {
69
+ vertices: Vertex[];
70
+ maxLength: number | null;
71
+ };
68
72
  export type PipelineGroup = {
69
73
  triangleList: GPURenderPipeline;
70
74
  triangleStrip: GPURenderPipeline;
package/dist/utils.d.ts CHANGED
@@ -21,9 +21,8 @@ export declare class Color {
21
21
  export declare class Vertex {
22
22
  private pos;
23
23
  private color;
24
- private is3d;
25
24
  private uv;
26
- constructor(x?: number, y?: number, z?: number, color?: Color, is3dPoint?: boolean, uv?: Vector2);
25
+ constructor(x?: number, y?: number, z?: number, color?: Color, uv?: Vector2);
27
26
  getPos(): Vector3;
28
27
  setPos(pos: Vector3): void;
29
28
  getColor(): Color | null;
@@ -33,18 +32,18 @@ export declare class Vertex {
33
32
  setX(x: number): void;
34
33
  setY(y: number): void;
35
34
  setZ(z: number): void;
36
- setIs3d(is3d: boolean): void;
37
35
  clone(): Vertex;
38
36
  toBuffer(defaultColor: Color): number[];
39
37
  }
40
38
  /**
41
- * @param callback1 - called every frame until the animation is finished
42
- * @param callback2 - called after animation is finished (called immediately when t = 0)
39
+ * @param onFrame - called every frame until the animation is finished
40
+ * @param adjustment - called after animation is finished (called immediately when t = 0) if t > 0 it will only be called if `transformAdjustments` is enabled in settings
43
41
  * @param t - animation time (seconds)
44
42
  * @returns {Promise<void>}
45
43
  */
46
- export declare function transitionValues(callback1: (deltaT: number, t: number) => void, callback2: () => void, transitionLength: number, func?: (n: number) => number): Promise<void>;
47
- export declare function frameLoop<T extends (dt: number, ...args: any[]) => any>(cb: T): (...params: Parameters<T>) => void;
44
+ export declare function transitionValues(onFrame: (deltaT: number, t: number, total: number) => void, adjustment: () => void, transitionLength: number, func?: (n: number) => number): Promise<void>;
45
+ type Shift<T extends any[]> = T extends [] ? [] : T extends [unknown, ...infer R] ? R : never;
46
+ export declare function frameLoop<T extends (dt: number, ...args: any[]) => any>(cb: T): (...params: Shift<Parameters<T>>) => void;
48
47
  export declare function clamp(num: number, min: number, max: number): number;
49
48
  export declare function lerp(a: number, b: number, t: number): number;
50
49
  export declare function smoothStep(t: number): number;
@@ -68,7 +67,7 @@ export declare function vector2FromVector3(vec: Vector3): Vector2;
68
67
  export declare function colorFromVector4(vec: Vector4): Color;
69
68
  export declare function randomInt(range: number, min?: number): number;
70
69
  export declare function randomColor(a?: number): Color;
71
- export declare function vertex(x?: number, y?: number, z?: number, color?: Color, is3dPoint?: boolean, uv?: Vector2): Vertex;
70
+ export declare function vertex(x?: number, y?: number, z?: number, color?: Color, uv?: Vector2): Vertex;
72
71
  export declare function color(r?: number, g?: number, b?: number, a?: number): Color;
73
72
  export declare function colorf(val: number, a?: number): Color;
74
73
  export declare function splinePoint2d(end: Vertex, control1: Vector2, control2: Vector2, detail?: number): SplinePoint2d;
@@ -82,3 +81,4 @@ export declare function distance3d(vector1: Vector3, vector2: Vector3): number;
82
81
  export declare function toSceneObjInfo(el: AnySimulationElement, id?: string): SimSceneObjInfo;
83
82
  export declare function toSceneObjInfoMany(el: AnySimulationElement[], id?: (string | undefined)[]): SimSceneObjInfo[];
84
83
  export declare function interpolateColors(colors: Color[], t: number): Color;
84
+ export {};