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.
package/dist/graphics.js CHANGED
@@ -1,32 +1,87 @@
1
1
  import { vec3, mat4, vec2, vec4 } from 'wgpu-matrix';
2
- import { Vertex, cloneBuf, color, colorFromVector4, vector2, vector3, vertex, Color, transitionValues, vector2FromVector3, matrix4, vector3FromVector2, distance2d } from './utils.js';
3
- import { BlankGeometry, CircleGeometry, CubeGeometry, Line2dGeometry, Line3dGeometry, PlaneGeometry, PolygonGeometry, Spline2dGeometry, SquareGeometry } from './geometry.js';
4
- import { VertexCache, bufferGenerator, logger, rotateMat4, vector3ToPixelRatio } from './internalUtils.js';
2
+ import { Vertex, cloneBuf, color, colorFromVector4, vector2, vector3, vertex, Color, vector2FromVector3, matrix4, vector3FromVector2, distance2d } from './utils.js';
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
5
  import { modelProjMatOffset } from './constants.js';
6
- export class SimulationElement {
6
+ export class SimulationElement3d {
7
+ children;
8
+ uniformBuffer;
9
+ parent;
10
+ centerOffset;
11
+ rotationOffset;
7
12
  pos;
8
13
  color;
9
14
  wireframe;
10
15
  vertexCache;
11
16
  rotation;
12
17
  modelMatrix;
13
- uniformBuffer;
14
- isInstanced;
18
+ isInstance = false;
19
+ isInstanced = false;
20
+ is3d = true;
21
+ isEmpty = false;
15
22
  /**
16
23
  * @param pos - Expected to be adjusted to devicePixelRatio before reaching constructor
17
24
  */
18
25
  constructor(pos, rotation, color = new Color()) {
19
26
  this.pos = pos;
27
+ this.centerOffset = vector3();
28
+ // TODO test this
29
+ this.rotationOffset = vector3();
20
30
  this.color = color;
21
31
  this.vertexCache = new VertexCache();
22
32
  this.wireframe = false;
23
- this.isInstanced = false;
24
- this.rotation = rotation;
33
+ this.rotation = cloneBuf(rotation);
25
34
  this.uniformBuffer = null;
35
+ this.children = [];
26
36
  this.modelMatrix = matrix4();
37
+ this.parent = null;
27
38
  }
28
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
29
- getModelMatrix(_) {
39
+ add(el, id) {
40
+ el.setParent(this);
41
+ const info = new SimSceneObjInfo(el, id);
42
+ this.children.push(info);
43
+ }
44
+ remove(el) {
45
+ for (let i = 0; i < this.children.length; i++) {
46
+ if (this.children[i].getObj() === el) {
47
+ this.children.splice(i, 1);
48
+ }
49
+ }
50
+ }
51
+ getChildren() {
52
+ return this.children.map((child) => child.getObj());
53
+ }
54
+ getChildrenInfos() {
55
+ return this.children;
56
+ }
57
+ hasChildren() {
58
+ return this.children.length > 0;
59
+ }
60
+ setParent(parent) {
61
+ this.parent = parent;
62
+ }
63
+ getParent() {
64
+ return this.parent;
65
+ }
66
+ setCenterOffset(offset) {
67
+ this.centerOffset = offset;
68
+ }
69
+ setRotationOffset(offset) {
70
+ this.rotationOffset = offset;
71
+ }
72
+ resetCenterOffset() {
73
+ this.centerOffset[0] = 0;
74
+ this.centerOffset[1] = 0;
75
+ this.centerOffset[2] = 0;
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
+ getModelMatrix() {
84
+ this.updateModelMatrix3d();
30
85
  return this.modelMatrix;
31
86
  }
32
87
  getUniformBuffer(device, mat) {
@@ -40,12 +95,53 @@ export class SimulationElement {
40
95
  device.queue.writeBuffer(this.uniformBuffer, modelProjMatOffset, mat);
41
96
  return this.uniformBuffer;
42
97
  }
98
+ mirrorParentTransforms3d(mat) {
99
+ if (!this.parent)
100
+ return;
101
+ this.parent.mirrorParentTransforms3d(mat);
102
+ mat4.translate(mat, this.parent.getPos(), mat);
103
+ const parentRot = this.parent.getRotation();
104
+ mat4.rotateZ(mat, parentRot[2], mat);
105
+ mat4.rotateY(mat, parentRot[1], mat);
106
+ mat4.rotateX(mat, parentRot[0], mat);
107
+ }
43
108
  updateModelMatrix3d() {
44
109
  mat4.identity(this.modelMatrix);
110
+ if (this.parent) {
111
+ this.mirrorParentTransforms3d(this.modelMatrix);
112
+ }
45
113
  mat4.translate(this.modelMatrix, this.pos, this.modelMatrix);
114
+ // vec3.negate(this.rotationOffset, cachedVec1);
115
+ // mat4.translate(this.modelMatrix, cachedVec1, this.modelMatrix);
46
116
  mat4.rotateZ(this.modelMatrix, this.rotation[2], this.modelMatrix);
47
117
  mat4.rotateY(this.modelMatrix, this.rotation[1], this.modelMatrix);
48
118
  mat4.rotateX(this.modelMatrix, this.rotation[0], this.modelMatrix);
119
+ // mat4.translate(this.modelMatrix, this.rotationOffset, this.modelMatrix);
120
+ mat4.translate(this.modelMatrix, this.centerOffset, this.modelMatrix);
121
+ }
122
+ mirrorParentTransforms2d(mat) {
123
+ if (!this.parent) {
124
+ const parentPos = posTo2dScreen(this.pos);
125
+ mat4.translate(mat, parentPos, mat);
126
+ return;
127
+ }
128
+ this.parent.mirrorParentTransforms2d(mat);
129
+ const parentRot = this.parent.getRotation();
130
+ mat4.rotateZ(mat, parentRot[2], mat);
131
+ mat4.translate(mat, this.pos, mat);
132
+ }
133
+ updateModelMatrix2d() {
134
+ mat4.identity(this.modelMatrix);
135
+ const pos = posTo2dScreen(this.pos);
136
+ vec3.add(pos, this.centerOffset, pos);
137
+ if (this.parent) {
138
+ this.mirrorParentTransforms2d(this.modelMatrix);
139
+ }
140
+ else {
141
+ mat4.translate(this.modelMatrix, pos, this.modelMatrix);
142
+ }
143
+ mat4.rotateZ(this.modelMatrix, this.rotation[2], this.modelMatrix);
144
+ mat4.translate(this.modelMatrix, this.centerOffset, this.modelMatrix);
49
145
  }
50
146
  getGeometryType() {
51
147
  return this.geometry.getType();
@@ -62,13 +158,22 @@ export class SimulationElement {
62
158
  getPos() {
63
159
  return this.pos;
64
160
  }
161
+ getAbsolutePos() {
162
+ const vec = vector3();
163
+ this.updateModelMatrix3d();
164
+ mat4.getTranslation(this.modelMatrix, vec);
165
+ return vec;
166
+ }
65
167
  getRotation() {
66
168
  return this.rotation;
67
169
  }
170
+ getCenterOffset() {
171
+ return this.centerOffset;
172
+ }
68
173
  fill(newColor, t = 0, f) {
69
174
  const diff = newColor.diff(this.color);
70
175
  const finalColor = newColor.clone();
71
- return transitionValues((p) => {
176
+ return internalTransitionValues((p) => {
72
177
  this.color.r += diff.r * p;
73
178
  this.color.g += diff.g * p;
74
179
  this.color.b += diff.b * p;
@@ -79,76 +184,92 @@ export class SimulationElement {
79
184
  this.vertexCache.updated();
80
185
  }, t, f);
81
186
  }
82
- move(amount, t = 0, f) {
187
+ moveChildren(amount, t = 0, f) {
188
+ for (let i = 0; i < this.children.length; i++) {
189
+ this.children[i].getObj().move(amount, t, f, true);
190
+ }
191
+ }
192
+ move(amount, t = 0, f, fromDevicePixelRatio = false) {
83
193
  const tempAmount = cloneBuf(amount);
84
- vector3ToPixelRatio(tempAmount);
194
+ if (!fromDevicePixelRatio)
195
+ vector3ToPixelRatio(tempAmount);
85
196
  const finalPos = cloneBuf(this.pos);
86
197
  vec3.add(finalPos, tempAmount, finalPos);
87
- return transitionValues((p) => {
198
+ this.moveChildren(amount, t, f);
199
+ return internalTransitionValues((p) => {
88
200
  this.pos[0] += tempAmount[0] * p;
89
201
  this.pos[1] += tempAmount[1] * p;
90
202
  this.pos[2] += tempAmount[2] * p;
91
- this.updateModelMatrix3d();
92
203
  }, () => {
93
204
  this.pos = finalPos;
94
- this.updateModelMatrix3d();
95
205
  }, t, f);
96
206
  }
97
- moveTo(pos, t = 0, f) {
207
+ moveTo(pos, t = 0, f, fromDevicePixelRatio = false) {
98
208
  const tempPos = cloneBuf(pos);
99
- vector3ToPixelRatio(tempPos);
209
+ if (!fromDevicePixelRatio)
210
+ vector3ToPixelRatio(tempPos);
100
211
  const diff = vector3();
101
212
  vec3.sub(tempPos, this.pos, diff);
102
- return transitionValues((p) => {
213
+ this.moveChildren(diff, t, f);
214
+ return internalTransitionValues((p) => {
103
215
  this.pos[0] += diff[0] * p;
104
216
  this.pos[1] += diff[1] * p;
105
217
  this.pos[2] += diff[2] * p;
106
- this.updateModelMatrix3d();
107
218
  }, () => {
108
219
  this.pos = tempPos;
109
- this.updateModelMatrix3d();
110
220
  }, t, f);
111
221
  }
222
+ rotateChildrenTo(angle) {
223
+ for (let i = 0; i < this.children.length; i++) {
224
+ this.children[i].getObj().rotateTo(angle);
225
+ }
226
+ }
227
+ rotateChildren(angle) {
228
+ for (let i = 0; i < this.children.length; i++) {
229
+ this.children[i].getObj().rotate(angle);
230
+ }
231
+ }
112
232
  rotate(amount, t = 0, f) {
113
- const tempAmount = cloneBuf(amount);
114
233
  const finalRotation = cloneBuf(amount);
115
234
  vec3.add(finalRotation, this.rotation, finalRotation);
116
- return transitionValues((p) => {
117
- this.rotation[0] += tempAmount[0] * p;
118
- this.rotation[1] += tempAmount[1] * p;
119
- this.rotation[2] += tempAmount[2] * p;
120
- this.updateModelMatrix3d();
235
+ const tempDiff = vector3();
236
+ return internalTransitionValues((p) => {
237
+ vec3.scale(amount, p, tempDiff);
238
+ this.rotation[0] += tempDiff[0];
239
+ this.rotation[1] += tempDiff[1];
240
+ this.rotation[2] += tempDiff[2];
121
241
  }, () => {
122
242
  this.rotation = finalRotation;
123
- this.updateModelMatrix3d();
124
243
  }, t, f);
125
244
  }
126
245
  rotateTo(rot, t = 0, f) {
127
246
  const diff = vec3.sub(rot, this.rotation);
128
- return transitionValues((p) => {
129
- this.rotation[0] += diff[0] * p;
130
- this.rotation[1] += diff[1] * p;
131
- this.rotation[2] += diff[2] * p;
132
- this.updateModelMatrix3d();
247
+ const tempDiff = vector3();
248
+ return internalTransitionValues((p) => {
249
+ vec3.scale(diff, p, tempDiff);
250
+ this.rotation[0] += tempDiff[0];
251
+ this.rotation[1] += tempDiff[1];
252
+ this.rotation[2] += tempDiff[2];
133
253
  }, () => {
134
254
  this.rotation = cloneBuf(rot);
135
- this.updateModelMatrix3d();
136
255
  }, t, f);
137
256
  }
138
257
  getVertexCount() {
139
258
  if (this.vertexCache.shouldUpdate()) {
140
259
  this.geometry.recompute();
141
260
  }
261
+ let childrenVertices = 0;
262
+ for (let i = 0; i < this.children.length; i++) {
263
+ childrenVertices += this.children[i].getObj().getVertexCount();
264
+ }
265
+ let currentVertices = 0;
142
266
  if (this.isWireframe()) {
143
- return this.geometry.getWireframeVertexCount();
267
+ currentVertices = this.geometry.getWireframeVertexCount();
144
268
  }
145
- return this.geometry.getTriangleVertexCount();
146
- }
147
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
148
- defaultUpdateMatrix(_) {
149
- const matrix = matrix4();
150
- mat4.translate(matrix, this.pos, matrix);
151
- rotateMat4(matrix, this.rotation);
269
+ else {
270
+ currentVertices = this.geometry.getTriangleVertexCount();
271
+ }
272
+ return currentVertices + childrenVertices;
152
273
  }
153
274
  getBuffer(vertexParamGenerator) {
154
275
  if (this.vertexCache.shouldUpdate()) {
@@ -170,18 +291,22 @@ export class SimulationElement {
170
291
  return this.vertexCache.getCache();
171
292
  }
172
293
  }
173
- export class SimulationElement3d extends SimulationElement {
174
- pos;
175
- rotation;
176
- is3d = true;
177
- constructor(pos, rotation = vector3(), color) {
178
- super(pos, rotation, color);
179
- this.pos = pos;
180
- vector3ToPixelRatio(this.pos);
181
- this.rotation = rotation;
294
+ export class EmptyElement extends SimulationElement3d {
295
+ geometry = new BlankGeometry();
296
+ label;
297
+ isEmpty = true;
298
+ constructor(label) {
299
+ super(vector3(), vector3());
300
+ this.label = label || null;
182
301
  }
302
+ getLabel() {
303
+ return this.label;
304
+ }
305
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
306
+ onDeviceChange(_device) { }
183
307
  }
184
- export class SimulationElement2d extends SimulationElement {
308
+ export class SimulationElement2d extends SimulationElement3d {
309
+ is3d = false;
185
310
  constructor(pos, rotation = vector3(), color) {
186
311
  super(vector3FromVector2(pos), rotation, color);
187
312
  vector3ToPixelRatio(this.pos);
@@ -192,15 +317,8 @@ export class SimulationElement2d extends SimulationElement {
192
317
  rotateTo2d(rot, t = 0, f) {
193
318
  return super.rotateTo(vector3(0, 0, rot), t, f);
194
319
  }
195
- updateModelMatrix2d(camera) {
196
- mat4.identity(this.modelMatrix);
197
- const pos = cloneBuf(this.pos);
198
- pos[1] = camera.getScreenSize()[1] + pos[1];
199
- mat4.translate(this.modelMatrix, pos, this.modelMatrix);
200
- mat4.rotateZ(this.modelMatrix, this.rotation[2], this.modelMatrix);
201
- }
202
- getModelMatrix(camera) {
203
- this.updateModelMatrix2d(camera);
320
+ getModelMatrix() {
321
+ super.updateModelMatrix2d();
204
322
  return this.modelMatrix;
205
323
  }
206
324
  }
@@ -217,6 +335,8 @@ export class Plane extends SimulationElement3d {
217
335
  this.points = newPoints;
218
336
  this.vertexCache.updated();
219
337
  }
338
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
339
+ onDeviceChange(_device) { }
220
340
  }
221
341
  export class Square extends SimulationElement2d {
222
342
  geometry;
@@ -270,7 +390,7 @@ export class Square extends SimulationElement2d {
270
390
  diffMap[+key] = clone;
271
391
  }
272
392
  });
273
- return transitionValues((p) => {
393
+ return internalTransitionValues((p) => {
274
394
  Object.entries(diffMap).forEach(([key, value]) => {
275
395
  const color = this.vertexColors[+key];
276
396
  color.r += value.r * p;
@@ -290,7 +410,7 @@ export class Square extends SimulationElement2d {
290
410
  scaleWidth(amount, t = 0, f) {
291
411
  const finalWidth = this.width * amount;
292
412
  const diffWidth = finalWidth - this.width;
293
- return transitionValues((p) => {
413
+ return internalTransitionValues((p) => {
294
414
  this.width += diffWidth * p;
295
415
  this.geometry.setWidth(this.width);
296
416
  this.vertexCache.updated();
@@ -303,7 +423,7 @@ export class Square extends SimulationElement2d {
303
423
  scaleHeight(amount, t = 0, f) {
304
424
  const finalHeight = this.height * amount;
305
425
  const diffHeight = finalHeight - this.height;
306
- return transitionValues((p) => {
426
+ return internalTransitionValues((p) => {
307
427
  this.height += diffHeight * p;
308
428
  this.geometry.setHeight(this.height);
309
429
  this.vertexCache.updated();
@@ -318,7 +438,7 @@ export class Square extends SimulationElement2d {
318
438
  const finalHeight = this.height * amount;
319
439
  const diffWidth = finalWidth - this.width;
320
440
  const diffHeight = finalHeight - this.height;
321
- return transitionValues((p) => {
441
+ return internalTransitionValues((p) => {
322
442
  this.width += diffWidth * p;
323
443
  this.height += diffHeight * p;
324
444
  this.geometry.setWidth(this.width);
@@ -335,7 +455,7 @@ export class Square extends SimulationElement2d {
335
455
  setWidth(num, t = 0, f) {
336
456
  num *= devicePixelRatio;
337
457
  const diffWidth = num - this.width;
338
- return transitionValues((p) => {
458
+ return internalTransitionValues((p) => {
339
459
  this.width += diffWidth * p;
340
460
  this.geometry.setWidth(this.width);
341
461
  this.vertexCache.updated();
@@ -348,7 +468,7 @@ export class Square extends SimulationElement2d {
348
468
  setHeight(num, t = 0, f) {
349
469
  num *= devicePixelRatio;
350
470
  const diffHeight = num - this.height;
351
- return transitionValues((p) => {
471
+ return internalTransitionValues((p) => {
352
472
  this.height += diffHeight * p;
353
473
  this.geometry.setHeight(this.height);
354
474
  this.vertexCache.updated();
@@ -358,6 +478,8 @@ export class Square extends SimulationElement2d {
358
478
  this.vertexCache.updated();
359
479
  }, t, f);
360
480
  }
481
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
482
+ onDeviceChange(_device) { }
361
483
  }
362
484
  export class Circle extends SimulationElement2d {
363
485
  geometry;
@@ -372,7 +494,7 @@ export class Circle extends SimulationElement2d {
372
494
  setRadius(num, t = 0, f) {
373
495
  num *= devicePixelRatio;
374
496
  const diff = num - this.radius;
375
- return transitionValues((p) => {
497
+ return internalTransitionValues((p) => {
376
498
  this.radius += diff * p;
377
499
  this.geometry.setRadius(this.radius);
378
500
  this.vertexCache.updated();
@@ -385,7 +507,7 @@ export class Circle extends SimulationElement2d {
385
507
  scale(amount, t = 0, f) {
386
508
  const finalRadius = this.radius * amount;
387
509
  const diff = finalRadius - this.radius;
388
- return transitionValues((p) => {
510
+ return internalTransitionValues((p) => {
389
511
  this.radius += diff * p;
390
512
  this.geometry.setRadius(this.radius);
391
513
  this.vertexCache.updated();
@@ -395,6 +517,8 @@ export class Circle extends SimulationElement2d {
395
517
  this.vertexCache.updated();
396
518
  }, t, f);
397
519
  }
520
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
521
+ onDeviceChange(_device) { }
398
522
  }
399
523
  export class Polygon extends SimulationElement2d {
400
524
  geometry;
@@ -411,14 +535,13 @@ export class Polygon extends SimulationElement2d {
411
535
  const vertices = newVertices.map((vert) => {
412
536
  const newVertex = vert.clone();
413
537
  newVertex.setZ(0);
414
- newVertex.setIs3d(false);
415
538
  return newVertex;
416
539
  });
417
- const lastVert = this.vertices.length > 0 ? this.vertices[this.vertices.length - 1] : vertex(0, 0, 0, color(), false);
540
+ const lastVert = this.vertices.length > 0 ? this.vertices[this.vertices.length - 1] : vertex(0, 0, 0, color());
418
541
  if (vertices.length > this.vertices.length) {
419
542
  while (vertices.length > this.vertices.length) {
420
543
  const lastPos = lastVert.getPos();
421
- this.vertices.push(new Vertex(lastPos[0], lastPos[1], 0, lastVert.getColor() || this.color, false));
544
+ this.vertices.push(new Vertex(lastPos[0], lastPos[1], 0, lastVert.getColor() || this.color));
422
545
  }
423
546
  }
424
547
  const initialPositions = this.vertices.map((p) => cloneBuf(p.getPos()));
@@ -449,7 +572,7 @@ export class Polygon extends SimulationElement2d {
449
572
  })
450
573
  : [])
451
574
  ];
452
- return transitionValues((p) => {
575
+ return internalTransitionValues((p) => {
453
576
  this.vertices.forEach((vert, i) => {
454
577
  const posChange = cloneBuf(posChanges[i]);
455
578
  const colorChange = cloneBuf(colorChanges[i]);
@@ -474,6 +597,8 @@ export class Polygon extends SimulationElement2d {
474
597
  this.vertexCache.updated();
475
598
  }, t, f);
476
599
  }
600
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
601
+ onDeviceChange(_device) { }
477
602
  }
478
603
  export class Line3d extends SimulationElement3d {
479
604
  geometry;
@@ -493,7 +618,7 @@ export class Line3d extends SimulationElement3d {
493
618
  setEnd(pos, t = 0, f) {
494
619
  const diff = vector3();
495
620
  vec3.sub(pos, this.to, diff);
496
- return transitionValues((p) => {
621
+ return internalTransitionValues((p) => {
497
622
  this.to[0] += diff[0] * p;
498
623
  this.to[1] += diff[1] * p;
499
624
  this.to[2] += diff[2] * p;
@@ -505,6 +630,8 @@ export class Line3d extends SimulationElement3d {
505
630
  this.vertexCache.updated();
506
631
  }, t, f);
507
632
  }
633
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
634
+ onDeviceChange(_device) { }
508
635
  }
509
636
  export class Line2d extends SimulationElement2d {
510
637
  geometry;
@@ -526,7 +653,7 @@ export class Line2d extends SimulationElement2d {
526
653
  // vec2.sub(tempPos, this.getPos(), tempPos);
527
654
  const diff = vector3();
528
655
  vec2.sub(tempPos, this.to, diff);
529
- return transitionValues((p) => {
656
+ return internalTransitionValues((p) => {
530
657
  this.to[0] += diff[0] * p;
531
658
  this.to[1] += diff[1] * p;
532
659
  this.vertexCache.updated();
@@ -536,24 +663,26 @@ export class Line2d extends SimulationElement2d {
536
663
  this.vertexCache.updated();
537
664
  }, t, f);
538
665
  }
666
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
667
+ onDeviceChange(_device) { }
539
668
  }
540
669
  export class Cube extends SimulationElement3d {
541
670
  geometry;
542
671
  width;
543
672
  height;
544
673
  depth;
545
- constructor(pos, width, height, depth, color, rotation) {
674
+ constructor(pos, width, height, depth, color, rotation = vector3()) {
546
675
  super(pos, rotation, color);
547
- this.width = width * devicePixelRatio;
548
- this.height = height * devicePixelRatio;
549
- this.depth = depth * devicePixelRatio;
676
+ this.width = width;
677
+ this.height = height;
678
+ this.depth = depth;
550
679
  this.rotation = rotation || vector3();
551
680
  this.geometry = new CubeGeometry(this.width, this.height, this.depth);
552
681
  }
553
682
  setWidth(width, t = 0, f) {
554
683
  width *= devicePixelRatio;
555
684
  const diff = width - this.width;
556
- return transitionValues((p) => {
685
+ return internalTransitionValues((p) => {
557
686
  this.width += diff * p;
558
687
  this.geometry.setWidth(this.width);
559
688
  this.vertexCache.updated();
@@ -566,7 +695,7 @@ export class Cube extends SimulationElement3d {
566
695
  setHeight(height, t = 0, f) {
567
696
  height *= devicePixelRatio;
568
697
  const diff = height - this.width;
569
- return transitionValues((p) => {
698
+ return internalTransitionValues((p) => {
570
699
  this.height += diff * p;
571
700
  this.geometry.setHeight(this.height);
572
701
  this.vertexCache.updated();
@@ -579,7 +708,7 @@ export class Cube extends SimulationElement3d {
579
708
  setDepth(depth, t = 0, f) {
580
709
  depth *= devicePixelRatio;
581
710
  const diff = depth - this.width;
582
- return transitionValues((p) => {
711
+ return internalTransitionValues((p) => {
583
712
  this.depth += diff * p;
584
713
  this.geometry.setDepth(this.depth);
585
714
  this.vertexCache.updated();
@@ -596,7 +725,7 @@ export class Cube extends SimulationElement3d {
596
725
  const widthDiff = finalWidth - this.width;
597
726
  const heightDiff = finalHeight - this.height;
598
727
  const depthDiff = finalDepth - this.depth;
599
- return transitionValues((p) => {
728
+ return internalTransitionValues((p) => {
600
729
  this.width += widthDiff * p;
601
730
  this.height += heightDiff * p;
602
731
  this.depth += depthDiff * p;
@@ -614,6 +743,8 @@ export class Cube extends SimulationElement3d {
614
743
  this.vertexCache.updated();
615
744
  }, t, f);
616
745
  }
746
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
747
+ onDeviceChange(_device) { }
617
748
  }
618
749
  export class BezierCurve2d {
619
750
  points;
@@ -786,7 +917,7 @@ export class Spline2d extends SimulationElement2d {
786
917
  }
787
918
  setInterpolateStart(start, t = 0, f) {
788
919
  const diff = start - this.interpolateStart;
789
- return transitionValues((p) => {
920
+ return internalTransitionValues((p) => {
790
921
  this.interpolateStart += diff * p;
791
922
  this.geometry.updateInterpolationStart(this.interpolateStart);
792
923
  this.vertexCache.updated();
@@ -798,7 +929,7 @@ export class Spline2d extends SimulationElement2d {
798
929
  }
799
930
  setInterpolateLimit(limit, t = 0, f) {
800
931
  const diff = limit - this.interpolateLimit;
801
- return transitionValues((p) => {
932
+ return internalTransitionValues((p) => {
802
933
  this.interpolateLimit += diff * p;
803
934
  this.geometry.updateInterpolationLimit(this.interpolateLimit);
804
935
  this.vertexCache.updated();
@@ -827,7 +958,7 @@ export class Spline2d extends SimulationElement2d {
827
958
  setThickness(thickness, t = 0, f) {
828
959
  thickness *= devicePixelRatio;
829
960
  const diff = thickness - this.thickness;
830
- return transitionValues((p) => {
961
+ return internalTransitionValues((p) => {
831
962
  this.thickness += diff * p;
832
963
  this.geometry.updateThickness(this.thickness);
833
964
  this.vertexCache.updated();
@@ -861,30 +992,26 @@ export class Spline2d extends SimulationElement2d {
861
992
  const [vec] = this.interpolateSlope(t);
862
993
  return vec;
863
994
  }
995
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
996
+ onDeviceChange(_device) { }
864
997
  }
865
998
  export class Instance extends SimulationElement3d {
866
999
  geometry;
867
1000
  obj;
868
1001
  instanceMatrix;
869
1002
  matrixBuffer;
870
- device;
871
1003
  baseMat;
1004
+ isInstance = true;
872
1005
  constructor(obj, numInstances) {
873
- super(vector3());
874
- this.device = null;
1006
+ super(vector3(), vector3());
875
1007
  this.matrixBuffer = null;
876
1008
  obj.isInstanced = true;
877
1009
  this.obj = obj;
878
1010
  this.instanceMatrix = [];
879
- this.is3d = Boolean(obj.is3d);
1011
+ this.is3d = obj.is3d;
880
1012
  this.geometry = new BlankGeometry();
881
1013
  this.baseMat = matrix4();
882
- if (typeof obj.getRotation() === 'number') {
883
- mat4.rotateZ(this.baseMat, obj.getRotation(), this.baseMat);
884
- }
885
- else {
886
- rotateMat4(this.baseMat, obj.getRotation());
887
- }
1014
+ rotateMat4(this.baseMat, obj.getRotation());
888
1015
  for (let i = 0; i < numInstances; i++) {
889
1016
  const clone = cloneBuf(this.baseMat);
890
1017
  this.instanceMatrix.push(clone);
@@ -915,11 +1042,11 @@ export class Instance extends SimulationElement3d {
915
1042
  return;
916
1043
  this.instanceMatrix[instance] = transformation;
917
1044
  }
918
- mapBuffer() {
919
- if (!this.device || this.matrixBuffer === null)
1045
+ mapBuffer(device) {
1046
+ if (this.matrixBuffer === null)
920
1047
  return;
921
1048
  const buf = new Float32Array(this.instanceMatrix.map((mat) => [...mat]).flat());
922
- this.device.queue.writeBuffer(this.matrixBuffer, 0, buf.buffer, buf.byteOffset, buf.byteLength);
1049
+ device.queue.writeBuffer(this.matrixBuffer, 0, buf.buffer, buf.byteOffset, buf.byteLength);
923
1050
  this.matrixBuffer.unmap();
924
1051
  }
925
1052
  getInstances() {
@@ -930,14 +1057,14 @@ export class Instance extends SimulationElement3d {
930
1057
  }
931
1058
  getMatrixBuffer(device) {
932
1059
  if (!this.matrixBuffer) {
933
- const minSize = 640;
1060
+ const minSize = 512;
934
1061
  const size = Math.max(minSize, this.instanceMatrix[0].byteLength * this.instanceMatrix.length);
935
1062
  this.matrixBuffer = device.createBuffer({
936
1063
  size,
937
1064
  usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST
938
1065
  });
939
1066
  }
940
- this.mapBuffer();
1067
+ this.mapBuffer(device);
941
1068
  return this.matrixBuffer;
942
1069
  }
943
1070
  getVertexCount() {
@@ -949,4 +1076,50 @@ export class Instance extends SimulationElement3d {
949
1076
  getBuffer() {
950
1077
  return this.obj.getBuffer();
951
1078
  }
1079
+ onDeviceChange(device) {
1080
+ this.obj.propagateDevice(device);
1081
+ }
1082
+ getModelMatrix() {
1083
+ return this.obj.getModelMatrix();
1084
+ }
1085
+ }
1086
+ export class TraceLines2d extends SimulationElement2d {
1087
+ geometry;
1088
+ constructor(color, maxLen) {
1089
+ super(vector2(), vector3(), color);
1090
+ this.geometry = new TraceLinesGeometry(maxLen);
1091
+ }
1092
+ addPoint(point, color) {
1093
+ const vert = vertex(point[0], point[1], point?.[2] || 0, color);
1094
+ this.geometry.addVertex(vert);
1095
+ this.vertexCache.updated();
1096
+ }
1097
+ // always being wireframe means that triangleOrder
1098
+ // in in the geometry does not need to be a duplicate
1099
+ // of wireframeOrder
1100
+ isWireframe() {
1101
+ return true;
1102
+ }
1103
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
1104
+ onDeviceChange(_) { }
1105
+ }
1106
+ export class TraceLines3d extends SimulationElement3d {
1107
+ geometry;
1108
+ constructor(color, maxLen) {
1109
+ super(vector3(), vector3(), color);
1110
+ this.geometry = new TraceLinesGeometry(maxLen);
1111
+ }
1112
+ addPoint(point, color) {
1113
+ const vert = vertex(point[0], point[1], point?.[2] || 0, color);
1114
+ this.geometry.addVertex(vert);
1115
+ this.vertexCache.updated();
1116
+ }
1117
+ // always being wireframe means that triangleOrder
1118
+ // in in the geometry does not need to be a duplicate
1119
+ // of wireframeOrder
1120
+ isWireframe() {
1121
+ return true;
1122
+ }
1123
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
1124
+ onDeviceChange(_) { }
952
1125
  }