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/TODO.md +9 -5
- package/dist/constants.d.ts +1 -0
- package/dist/constants.js +1 -0
- package/dist/geometry.d.ts +11 -1
- package/dist/geometry.js +31 -0
- package/dist/graphics.d.ts +70 -19
- package/dist/graphics.js +274 -101
- package/dist/internalUtils.d.ts +9 -8
- package/dist/internalUtils.js +33 -44
- package/dist/settings.d.ts +7 -0
- package/dist/settings.js +9 -0
- package/dist/simulation.d.ts +30 -69
- package/dist/simulation.js +145 -261
- package/dist/types.d.ts +4 -0
- package/dist/utils.d.ts +8 -8
- package/dist/utils.js +13 -19
- package/package.json +1 -1
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,
|
|
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
|
|
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
|
-
|
|
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.
|
|
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
|
-
|
|
29
|
-
|
|
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
|
|
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
|
-
|
|
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
|
-
|
|
194
|
+
if (!fromDevicePixelRatio)
|
|
195
|
+
vector3ToPixelRatio(tempAmount);
|
|
85
196
|
const finalPos = cloneBuf(this.pos);
|
|
86
197
|
vec3.add(finalPos, tempAmount, finalPos);
|
|
87
|
-
|
|
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
|
-
|
|
209
|
+
if (!fromDevicePixelRatio)
|
|
210
|
+
vector3ToPixelRatio(tempPos);
|
|
100
211
|
const diff = vector3();
|
|
101
212
|
vec3.sub(tempPos, this.pos, diff);
|
|
102
|
-
|
|
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
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
this.rotation[
|
|
120
|
-
this.
|
|
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
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
this.rotation[
|
|
132
|
-
this.
|
|
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
|
-
|
|
267
|
+
currentVertices = this.geometry.getWireframeVertexCount();
|
|
144
268
|
}
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
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
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
constructor(
|
|
178
|
-
super(
|
|
179
|
-
this.
|
|
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
|
|
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
|
-
|
|
196
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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()
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
548
|
-
this.height = height
|
|
549
|
-
this.depth = depth
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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 =
|
|
1011
|
+
this.is3d = obj.is3d;
|
|
880
1012
|
this.geometry = new BlankGeometry();
|
|
881
1013
|
this.baseMat = matrix4();
|
|
882
|
-
|
|
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 (
|
|
1045
|
+
mapBuffer(device) {
|
|
1046
|
+
if (this.matrixBuffer === null)
|
|
920
1047
|
return;
|
|
921
1048
|
const buf = new Float32Array(this.instanceMatrix.map((mat) => [...mat]).flat());
|
|
922
|
-
|
|
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 =
|
|
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
|
}
|