simulationjsv2 0.6.0 → 0.7.2

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, globalInfo } from './internalUtils.js';
7
+ import { Settings } from './settings.js';
7
8
  const shader = `
8
9
  struct Uniforms {
9
10
  worldProjectionMatrix: mat4x4<f32>,
@@ -115,20 +116,107 @@ let aspectRatio = 0;
115
116
  const projMat = matrix4();
116
117
  const worldProjMat = matrix4();
117
118
  const orthoMatrix = matrix4();
118
- export class Simulation {
119
+ export class Camera {
120
+ pos;
121
+ rotation;
122
+ aspectRatio = 1;
123
+ updated;
124
+ screenSize = vector2();
125
+ constructor(pos, rotation = vector3()) {
126
+ this.pos = pos;
127
+ this.updated = false;
128
+ this.rotation = rotation;
129
+ }
130
+ setScreenSize(size) {
131
+ this.screenSize = size;
132
+ this.aspectRatio = size[0] / size[1];
133
+ this.updated = true;
134
+ }
135
+ getScreenSize() {
136
+ return this.screenSize;
137
+ }
138
+ hasUpdated() {
139
+ return this.updated;
140
+ }
141
+ updateConsumed() {
142
+ this.updated = false;
143
+ }
144
+ move(amount, t = 0, f) {
145
+ const initial = vector3();
146
+ vec3.clone(this.pos, initial);
147
+ return transitionValues((p) => {
148
+ const x = amount[0] * p;
149
+ const y = amount[1] * p;
150
+ const z = amount[2] * p;
151
+ const diff = vector3(x, y, z);
152
+ vec3.add(this.pos, diff, this.pos);
153
+ }, () => {
154
+ vec3.add(initial, amount, this.pos);
155
+ }, t, f);
156
+ }
157
+ moveTo(pos, t = 0, f) {
158
+ const diff = vector3();
159
+ vec3.sub(pos, this.pos, diff);
160
+ return transitionValues((p) => {
161
+ const x = diff[0] * p;
162
+ const y = diff[1] * p;
163
+ const z = diff[2] * p;
164
+ const amount = vector3(x, y, z);
165
+ vec3.add(this.pos, amount, this.pos);
166
+ }, () => {
167
+ vec3.clone(pos, this.pos);
168
+ }, t, f);
169
+ }
170
+ rotateTo(value, t = 0, f) {
171
+ const diff = vec3.clone(value);
172
+ vec3.sub(diff, diff, this.rotation);
173
+ return transitionValues((p) => {
174
+ const x = diff[0] * p;
175
+ const y = diff[1] * p;
176
+ const z = diff[2] * p;
177
+ vec3.add(this.rotation, this.rotation, vector3(x, y, z));
178
+ this.updated = true;
179
+ }, () => {
180
+ this.rotation = value;
181
+ }, t, f);
182
+ }
183
+ rotate(amount, t = 0, f) {
184
+ const initial = vector3();
185
+ vec3.clone(this.rotation, initial);
186
+ return transitionValues((p) => {
187
+ const x = amount[0] * p;
188
+ const y = amount[1] * p;
189
+ const z = amount[2] * p;
190
+ vec3.add(this.rotation, vector3(x, y, z), this.rotation);
191
+ this.updated = true;
192
+ }, () => {
193
+ vec3.add(initial, amount, this.rotation);
194
+ }, t, f);
195
+ }
196
+ getRotation() {
197
+ return this.rotation;
198
+ }
199
+ getPos() {
200
+ return this.pos;
201
+ }
202
+ getAspectRatio() {
203
+ return this.aspectRatio;
204
+ }
205
+ }
206
+ export let camera = new Camera(vector3());
207
+ export class Simulation extends Settings {
119
208
  canvasRef = null;
120
209
  bgColor = new Color(255, 255, 255);
121
210
  scene = [];
122
211
  fittingElement = false;
123
212
  running = true;
124
213
  initialized = false;
125
- frameRateView;
126
- camera;
127
- device = null;
128
214
  pipelines = null;
129
215
  renderInfo = null;
130
216
  resizeEvents;
131
- constructor(idOrCanvasRef, camera = null, showFrameRate = false) {
217
+ frameRateView;
218
+ constructor(idOrCanvasRef, sceneCamera = null, showFrameRate = false) {
219
+ super();
132
220
  if (typeof idOrCanvasRef === 'string') {
133
221
  const ref = document.getElementById(idOrCanvasRef);
134
222
  if (ref !== null)
@@ -143,10 +231,9 @@ export class Simulation {
143
231
  throw logger.error(`Canvas ref/id provided is invalid`);
144
232
  }
145
233
  const parent = this.canvasRef.parentElement;
146
- if (!camera)
147
- this.camera = new Camera(vector3());
148
- else
149
- this.camera = camera;
234
+ if (sceneCamera) {
235
+ camera = sceneCamera;
236
+ }
150
237
  if (parent === null)
151
238
  throw logger.error('Canvas parent is null');
152
239
  this.resizeEvents = [];
@@ -173,10 +260,21 @@ export class Simulation {
173
260
  return (this.canvasRef?.height || 0) / devicePixelRatio;
174
261
  }
175
262
  add(el, id) {
176
- addObject(this.scene, el, this.device, id);
263
+ if (el instanceof SimulationElement3d) {
264
+ const obj = new SimSceneObjInfo(el, id);
265
+ this.scene.unshift(obj);
266
+ }
267
+ else {
268
+ throw logger.error('Cannot add invalid SimulationElement');
269
+ }
177
270
  }
178
271
  remove(el) {
179
- removeObject(this.scene, el);
272
+ for (let i = 0; i < this.scene.length; i++) {
273
+ if (this.scene[i].getObj() === el) {
274
+ this.scene.splice(i, 1);
275
+ break;
276
+ }
277
+ }
180
278
  }
181
279
  removeId(id) {
182
280
  removeObjectId(this.scene, id);
@@ -221,25 +319,16 @@ export class Simulation {
221
319
  if (!ctx)
222
320
  throw logger.error('Context is null');
223
321
  const device = await adapter.requestDevice();
224
- this.device = device;
225
- this.propagateDevice(device);
322
+ globalInfo.setDevice(device);
226
323
  ctx.configure({
227
324
  device,
228
325
  format: 'bgra8unorm'
229
326
  });
230
327
  const screenSize = vector2(this.canvasRef.width, this.canvasRef.height);
231
- this.camera.setScreenSize(screenSize);
328
+ camera.setScreenSize(screenSize);
232
329
  this.render(ctx);
233
330
  })();
234
331
  }
235
- propagateDevice(device) {
236
- for (let i = 0; i < this.scene.length; i++) {
237
- const el = this.scene[i].getObj();
238
- if (el instanceof SceneCollection) {
239
- el.setDevice(device);
240
- }
241
- }
242
- }
243
332
  stop() {
244
333
  this.running = false;
245
334
  }
@@ -253,10 +342,10 @@ export class Simulation {
253
342
  return this.scene.map((item) => item.getObj());
254
343
  }
255
344
  render(ctx) {
256
- if (this.canvasRef === null || this.device === null)
345
+ const device = globalInfo.getDevice();
346
+ if (this.canvasRef === null || device === null)
257
347
  return;
258
348
  const canvas = this.canvasRef;
259
- const device = this.device;
260
349
  canvas.width = canvas.clientWidth * devicePixelRatio;
261
350
  canvas.height = canvas.clientHeight * devicePixelRatio;
262
351
  const presentationFormat = navigator.gpu.getPreferredCanvasFormat();
@@ -294,8 +383,8 @@ export class Simulation {
294
383
  updateProjectionMatrix(projMat, newAspectRatio);
295
384
  aspectRatio = newAspectRatio;
296
385
  }
297
- updateWorldProjectionMatrix(worldProjMat, projMat, this.camera);
298
- updateOrthoProjectionMatrix(orthoMatrix, this.camera.getScreenSize());
386
+ updateWorldProjectionMatrix(worldProjMat, projMat);
387
+ updateOrthoProjectionMatrix(orthoMatrix, camera.getScreenSize());
299
388
  let multisampleTexture = buildMultisampleTexture(device, ctx, canvas.width, canvas.height);
300
389
  let depthTexture = buildDepthTexture(device, canvas.width, canvas.height);
301
390
  const renderPassDescriptor = {
@@ -328,14 +417,14 @@ export class Simulation {
328
417
  prevFps = fps;
329
418
  canvas.width = canvas.clientWidth * devicePixelRatio;
330
419
  canvas.height = canvas.clientHeight * devicePixelRatio;
331
- const screenSize = this.camera.getScreenSize();
420
+ const screenSize = camera.getScreenSize();
332
421
  if (screenSize[0] !== canvas.width || screenSize[1] !== canvas.height) {
333
- this.camera.setScreenSize(vector2(canvas.width, canvas.height));
422
+ camera.setScreenSize(vector2(canvas.width, canvas.height));
334
423
  screenSize[0] = canvas.width;
335
424
  screenSize[1] = canvas.height;
336
- aspectRatio = this.camera.getAspectRatio();
425
+ aspectRatio = camera.getAspectRatio();
337
426
  updateProjectionMatrix(projMat, aspectRatio);
338
- updateWorldProjectionMatrix(worldProjMat, projMat, this.camera);
427
+ updateWorldProjectionMatrix(worldProjMat, projMat);
339
428
  multisampleTexture = buildMultisampleTexture(device, ctx, screenSize[0], screenSize[1]);
340
429
  depthTexture = buildDepthTexture(device, screenSize[0], screenSize[1]);
341
430
  renderPassDescriptor.depthStencilAttachment.view = depthTexture.createView();
@@ -346,9 +435,9 @@ export class Simulation {
346
435
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
347
436
  // @ts-ignore
348
437
  renderPassDescriptor.colorAttachments[0].resolveTarget = ctx.getCurrentTexture().createView();
349
- if (this.camera.hasUpdated()) {
350
- updateOrthoProjectionMatrix(orthoMatrix, this.camera.getScreenSize());
351
- updateWorldProjectionMatrix(worldProjMat, projMat, this.camera);
438
+ if (camera.hasUpdated()) {
439
+ updateOrthoProjectionMatrix(orthoMatrix, camera.getScreenSize());
440
+ updateWorldProjectionMatrix(worldProjMat, projMat);
352
441
  }
353
442
  const commandEncoder = device.createCommandEncoder();
354
443
  const passEncoder = commandEncoder.beginRenderPass(renderPassDescriptor);
@@ -362,7 +451,7 @@ export class Simulation {
362
451
  });
363
452
  }
364
453
  this.renderScene(device, passEncoder, this.renderInfo.vertexBuffer, this.scene, 0, diff);
365
- this.camera.updateConsumed();
454
+ camera.updateConsumed();
366
455
  passEncoder.end();
367
456
  device.queue.submit([commandEncoder.finish()]);
368
457
  };
@@ -384,7 +473,7 @@ export class Simulation {
384
473
  scene[i].traverseLife(diff);
385
474
  }
386
475
  const obj = scene[i].getObj();
387
- if (obj instanceof SceneCollection) {
476
+ if (obj.hasChildren()) {
388
477
  let shaderInfo = undefined;
389
478
  if (obj instanceof ShaderGroup) {
390
479
  const pipeline = obj.getPipeline();
@@ -394,30 +483,27 @@ export class Simulation {
394
483
  paramGenerator: obj.getVertexParamGenerator(),
395
484
  bufferInfo: obj.hasBindGroup()
396
485
  ? {
397
- buffers: obj.getBindGroupBuffers(),
486
+ buffers: obj.getBindGroupBuffers(device),
398
487
  layout: obj.getBindGroupLayout()
399
488
  }
400
489
  : null
401
490
  };
402
491
  }
403
492
  }
404
- currentOffset += this.renderScene(device, passEncoder, vertexBuffer, obj.getScene(), currentOffset, diff, shaderInfo || undefined);
405
- continue;
493
+ currentOffset += this.renderScene(device, passEncoder, vertexBuffer, obj.getChildrenInfos(), currentOffset, diff, shaderInfo);
406
494
  }
495
+ if (obj.isEmpty)
496
+ continue;
407
497
  const buffer = new Float32Array(obj.getBuffer(shaderInfo?.paramGenerator));
408
498
  const bufLen = shaderInfo?.paramGenerator?.bufferSize || BUF_LEN;
409
499
  const vertexCount = buffer.length / bufLen;
410
- device.queue.writeBuffer(vertexBuffer, currentOffset, buffer);
500
+ device.queue.writeBuffer(vertexBuffer, currentOffset, buffer.buffer, buffer.byteOffset, buffer.byteLength);
411
501
  vertexBuffer.unmap();
412
502
  passEncoder.setVertexBuffer(0, vertexBuffer, currentOffset, buffer.byteLength);
413
- const modelMatrix = obj.getModelMatrix(this.camera);
414
- const uniformBuffer = obj.getUniformBuffer(device, modelMatrix);
415
- if (obj.is3d) {
416
- device.queue.writeBuffer(uniformBuffer, worldProjMatOffset, worldProjMat.buffer, worldProjMat.byteOffset, worldProjMat.byteLength);
417
- }
418
- else {
419
- device.queue.writeBuffer(uniformBuffer, worldProjMatOffset, orthoMatrix.buffer, orthoMatrix.byteOffset, orthoMatrix.byteLength);
420
- }
503
+ const modelMatrix = obj.getModelMatrix();
504
+ const uniformBuffer = obj.getUniformBuffer(modelMatrix);
505
+ const projBuf = obj.is3d ? worldProjMat : orthoMatrix;
506
+ device.queue.writeBuffer(uniformBuffer, worldProjMatOffset, projBuf.buffer, projBuf.byteOffset, projBuf.byteLength);
421
507
  if (shaderInfo) {
422
508
  passEncoder.setPipeline(shaderInfo.pipeline);
423
509
  }
@@ -436,9 +522,10 @@ export class Simulation {
436
522
  let instances = 1;
437
523
  if (this.renderInfo) {
438
524
  let instanceBuffer;
439
- if (obj instanceof Instance) {
525
+ if (obj.isInstance) {
440
526
  instances = obj.getNumInstances();
441
- instanceBuffer = obj.getMatrixBuffer(device);
527
+ instanceBuffer =
528
+ obj.getMatrixBuffer() ?? this.renderInfo.instanceBuffer;
442
529
  }
443
530
  else {
444
531
  instanceBuffer = this.renderInfo.instanceBuffer;
@@ -480,7 +567,7 @@ export class Simulation {
480
567
  currentOffset += buffer.byteLength;
481
568
  }
482
569
  for (let i = toRemove.length - 1; i >= 0; i--) {
483
- removeObject(scene, scene[i].getObj());
570
+ this.remove(scene[i].getObj());
484
571
  }
485
572
  return currentOffset - startOffset;
486
573
  }
@@ -496,179 +583,6 @@ export class Simulation {
496
583
  }
497
584
  }
498
585
  }
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
586
  const defaultShaderCode = `
673
587
  struct Uniforms {
674
588
  worldProjectionMatrix: mat4x4<f32>,
@@ -679,8 +593,7 @@ struct Uniforms {
679
593
 
680
594
  @group(0) @binding(1) var<storage> instanceMatrices: array<mat4x4f>;
681
595
  `;
682
- export class ShaderGroup extends SceneCollection {
683
- geometry;
596
+ export class ShaderGroup extends EmptyElement {
684
597
  code;
685
598
  module;
686
599
  pipeline;
@@ -703,8 +616,8 @@ export class ShaderGroup extends SceneCollection {
703
616
  this.vertexParams = vertexParams;
704
617
  this.valueBuffers = null;
705
618
  }
706
- propagateDevice(device) {
707
- super.propagateDevice(device);
619
+ initPipeline() {
620
+ const device = globalInfo.errorGetDevice();
708
621
  this.module = device.createShaderModule({ code: this.code });
709
622
  const presentationFormat = navigator.gpu.getPreferredCanvasFormat();
710
623
  const bindGroupLayout = device.createBindGroupLayout(baseBindGroupLayout);
@@ -726,18 +639,20 @@ export class ShaderGroup extends SceneCollection {
726
639
  return this.bindGroupLayout;
727
640
  }
728
641
  getPipeline() {
642
+ if (!this.pipeline)
643
+ this.initPipeline();
729
644
  return this.pipeline;
730
645
  }
731
- getBindGroupBuffers() {
646
+ getBindGroupBuffers(device) {
732
647
  if (this.bindGroup === null)
733
648
  return null;
734
- if (this.device === null)
649
+ if (device === null)
735
650
  return null;
736
651
  const values = this.bindGroup.values();
737
652
  if (this.valueBuffers === null) {
738
653
  this.valueBuffers = [];
739
654
  for (let i = 0; i < values.length; i++) {
740
- const buffer = this.createBuffer(this.device, values[i]);
655
+ const buffer = this.createBuffer(device, values[i]);
741
656
  this.valueBuffers.push(buffer);
742
657
  }
743
658
  }
@@ -746,12 +661,12 @@ export class ShaderGroup extends SceneCollection {
746
661
  const arrayConstructor = values[i].array;
747
662
  const array = new arrayConstructor(values[i].value);
748
663
  if (array.byteLength > this.valueBuffers[i].size) {
749
- const newBuffer = this.createBuffer(this.device, values[i]);
664
+ const newBuffer = this.createBuffer(device, values[i]);
750
665
  this.valueBuffers[i].destroy();
751
666
  this.valueBuffers[i] = newBuffer;
752
667
  }
753
668
  else {
754
- this.device.queue.writeBuffer(this.valueBuffers[i], 0, array.buffer, array.byteOffset, array.byteLength);
669
+ device.queue.writeBuffer(this.valueBuffers[i], 0, array.buffer, array.byteOffset, array.byteLength);
755
670
  }
756
671
  }
757
672
  }
@@ -770,9 +685,6 @@ export class ShaderGroup extends SceneCollection {
770
685
  buffer.unmap();
771
686
  return buffer;
772
687
  }
773
- updateMatrix(camera) {
774
- this.defaultUpdateMatrix(camera);
775
- }
776
688
  getVertexParamGenerator() {
777
689
  return this.paramGenerator;
778
690
  }
@@ -780,39 +692,3 @@ export class ShaderGroup extends SceneCollection {
780
692
  return !!this.bindGroup;
781
693
  }
782
694
  }
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 {};