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.
- package/TODO.md +9 -5
- package/dist/constants.d.ts +2 -0
- package/dist/constants.js +2 -0
- package/dist/geometry.d.ts +11 -1
- package/dist/geometry.js +31 -0
- package/dist/graphics.d.ts +60 -21
- package/dist/graphics.js +266 -109
- package/dist/internalUtils.d.ts +17 -10
- package/dist/internalUtils.js +51 -56
- package/dist/settings.d.ts +7 -0
- package/dist/settings.js +9 -0
- package/dist/simulation.d.ts +31 -72
- package/dist/simulation.js +150 -274
- 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,35 +1,85 @@
|
|
|
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,
|
|
5
|
-
import { modelProjMatOffset } from './constants.js';
|
|
6
|
-
export class
|
|
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, globalInfo, internalTransitionValues, logger, posTo2dScreen, vector3ToPixelRatio } from './internalUtils.js';
|
|
5
|
+
import { mat4ByteLength, modelProjMatOffset } from './constants.js';
|
|
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;
|
|
38
|
+
}
|
|
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;
|
|
27
59
|
}
|
|
28
|
-
|
|
29
|
-
|
|
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
|
+
getModelMatrix() {
|
|
78
|
+
this.updateModelMatrix3d();
|
|
30
79
|
return this.modelMatrix;
|
|
31
80
|
}
|
|
32
|
-
getUniformBuffer(
|
|
81
|
+
getUniformBuffer(mat) {
|
|
82
|
+
const device = globalInfo.errorGetDevice();
|
|
33
83
|
if (!this.uniformBuffer) {
|
|
34
84
|
const uniformBufferSize = 4 * 16 + 4 * 16 + 4 * 2 + 8; // 4x4 matrix + 4x4 matrix + vec2<f32> + 8 bc 144 is cool
|
|
35
85
|
this.uniformBuffer = device.createBuffer({
|
|
@@ -40,12 +90,53 @@ export class SimulationElement {
|
|
|
40
90
|
device.queue.writeBuffer(this.uniformBuffer, modelProjMatOffset, mat);
|
|
41
91
|
return this.uniformBuffer;
|
|
42
92
|
}
|
|
93
|
+
mirrorParentTransforms3d(mat) {
|
|
94
|
+
if (!this.parent)
|
|
95
|
+
return;
|
|
96
|
+
this.parent.mirrorParentTransforms3d(mat);
|
|
97
|
+
mat4.translate(mat, this.parent.getPos(), mat);
|
|
98
|
+
const parentRot = this.parent.getRotation();
|
|
99
|
+
mat4.rotateZ(mat, parentRot[2], mat);
|
|
100
|
+
mat4.rotateY(mat, parentRot[1], mat);
|
|
101
|
+
mat4.rotateX(mat, parentRot[0], mat);
|
|
102
|
+
}
|
|
43
103
|
updateModelMatrix3d() {
|
|
44
104
|
mat4.identity(this.modelMatrix);
|
|
105
|
+
if (this.parent) {
|
|
106
|
+
this.mirrorParentTransforms3d(this.modelMatrix);
|
|
107
|
+
}
|
|
45
108
|
mat4.translate(this.modelMatrix, this.pos, this.modelMatrix);
|
|
109
|
+
// vec3.negate(this.rotationOffset, cachedVec1);
|
|
110
|
+
// mat4.translate(this.modelMatrix, cachedVec1, this.modelMatrix);
|
|
46
111
|
mat4.rotateZ(this.modelMatrix, this.rotation[2], this.modelMatrix);
|
|
47
112
|
mat4.rotateY(this.modelMatrix, this.rotation[1], this.modelMatrix);
|
|
48
113
|
mat4.rotateX(this.modelMatrix, this.rotation[0], this.modelMatrix);
|
|
114
|
+
// mat4.translate(this.modelMatrix, this.rotationOffset, this.modelMatrix);
|
|
115
|
+
mat4.translate(this.modelMatrix, this.centerOffset, this.modelMatrix);
|
|
116
|
+
}
|
|
117
|
+
mirrorParentTransforms2d(mat) {
|
|
118
|
+
if (!this.parent) {
|
|
119
|
+
const parentPos = posTo2dScreen(this.pos);
|
|
120
|
+
mat4.translate(mat, parentPos, mat);
|
|
121
|
+
return;
|
|
122
|
+
}
|
|
123
|
+
this.parent.mirrorParentTransforms2d(mat);
|
|
124
|
+
const parentRot = this.parent.getRotation();
|
|
125
|
+
mat4.rotateZ(mat, parentRot[2], mat);
|
|
126
|
+
mat4.translate(mat, this.pos, mat);
|
|
127
|
+
}
|
|
128
|
+
updateModelMatrix2d() {
|
|
129
|
+
mat4.identity(this.modelMatrix);
|
|
130
|
+
const pos = posTo2dScreen(this.pos);
|
|
131
|
+
vec3.add(pos, this.centerOffset, pos);
|
|
132
|
+
if (this.parent) {
|
|
133
|
+
this.mirrorParentTransforms2d(this.modelMatrix);
|
|
134
|
+
}
|
|
135
|
+
else {
|
|
136
|
+
mat4.translate(this.modelMatrix, pos, this.modelMatrix);
|
|
137
|
+
}
|
|
138
|
+
mat4.rotateZ(this.modelMatrix, this.rotation[2], this.modelMatrix);
|
|
139
|
+
mat4.translate(this.modelMatrix, this.centerOffset, this.modelMatrix);
|
|
49
140
|
}
|
|
50
141
|
getGeometryType() {
|
|
51
142
|
return this.geometry.getType();
|
|
@@ -62,13 +153,22 @@ export class SimulationElement {
|
|
|
62
153
|
getPos() {
|
|
63
154
|
return this.pos;
|
|
64
155
|
}
|
|
156
|
+
getAbsolutePos() {
|
|
157
|
+
const vec = vector3();
|
|
158
|
+
this.updateModelMatrix3d();
|
|
159
|
+
mat4.getTranslation(this.modelMatrix, vec);
|
|
160
|
+
return vec;
|
|
161
|
+
}
|
|
65
162
|
getRotation() {
|
|
66
163
|
return this.rotation;
|
|
67
164
|
}
|
|
165
|
+
getCenterOffset() {
|
|
166
|
+
return this.centerOffset;
|
|
167
|
+
}
|
|
68
168
|
fill(newColor, t = 0, f) {
|
|
69
169
|
const diff = newColor.diff(this.color);
|
|
70
170
|
const finalColor = newColor.clone();
|
|
71
|
-
return
|
|
171
|
+
return internalTransitionValues((p) => {
|
|
72
172
|
this.color.r += diff.r * p;
|
|
73
173
|
this.color.g += diff.g * p;
|
|
74
174
|
this.color.b += diff.b * p;
|
|
@@ -79,76 +179,92 @@ export class SimulationElement {
|
|
|
79
179
|
this.vertexCache.updated();
|
|
80
180
|
}, t, f);
|
|
81
181
|
}
|
|
82
|
-
|
|
182
|
+
moveChildren(amount, t = 0, f) {
|
|
183
|
+
for (let i = 0; i < this.children.length; i++) {
|
|
184
|
+
this.children[i].getObj().move(amount, t, f, true);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
move(amount, t = 0, f, fromDevicePixelRatio = false) {
|
|
83
188
|
const tempAmount = cloneBuf(amount);
|
|
84
|
-
|
|
189
|
+
if (!fromDevicePixelRatio)
|
|
190
|
+
vector3ToPixelRatio(tempAmount);
|
|
85
191
|
const finalPos = cloneBuf(this.pos);
|
|
86
192
|
vec3.add(finalPos, tempAmount, finalPos);
|
|
87
|
-
|
|
193
|
+
this.moveChildren(amount, t, f);
|
|
194
|
+
return internalTransitionValues((p) => {
|
|
88
195
|
this.pos[0] += tempAmount[0] * p;
|
|
89
196
|
this.pos[1] += tempAmount[1] * p;
|
|
90
197
|
this.pos[2] += tempAmount[2] * p;
|
|
91
|
-
this.updateModelMatrix3d();
|
|
92
198
|
}, () => {
|
|
93
199
|
this.pos = finalPos;
|
|
94
|
-
this.updateModelMatrix3d();
|
|
95
200
|
}, t, f);
|
|
96
201
|
}
|
|
97
|
-
moveTo(pos, t = 0, f) {
|
|
202
|
+
moveTo(pos, t = 0, f, fromDevicePixelRatio = false) {
|
|
98
203
|
const tempPos = cloneBuf(pos);
|
|
99
|
-
|
|
204
|
+
if (!fromDevicePixelRatio)
|
|
205
|
+
vector3ToPixelRatio(tempPos);
|
|
100
206
|
const diff = vector3();
|
|
101
207
|
vec3.sub(tempPos, this.pos, diff);
|
|
102
|
-
|
|
208
|
+
this.moveChildren(diff, t, f);
|
|
209
|
+
return internalTransitionValues((p) => {
|
|
103
210
|
this.pos[0] += diff[0] * p;
|
|
104
211
|
this.pos[1] += diff[1] * p;
|
|
105
212
|
this.pos[2] += diff[2] * p;
|
|
106
|
-
this.updateModelMatrix3d();
|
|
107
213
|
}, () => {
|
|
108
214
|
this.pos = tempPos;
|
|
109
|
-
this.updateModelMatrix3d();
|
|
110
215
|
}, t, f);
|
|
111
216
|
}
|
|
217
|
+
rotateChildrenTo(angle) {
|
|
218
|
+
for (let i = 0; i < this.children.length; i++) {
|
|
219
|
+
this.children[i].getObj().rotateTo(angle);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
rotateChildren(angle) {
|
|
223
|
+
for (let i = 0; i < this.children.length; i++) {
|
|
224
|
+
this.children[i].getObj().rotate(angle);
|
|
225
|
+
}
|
|
226
|
+
}
|
|
112
227
|
rotate(amount, t = 0, f) {
|
|
113
|
-
const tempAmount = cloneBuf(amount);
|
|
114
228
|
const finalRotation = cloneBuf(amount);
|
|
115
229
|
vec3.add(finalRotation, this.rotation, finalRotation);
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
this.rotation[
|
|
120
|
-
this.
|
|
230
|
+
const tempDiff = vector3();
|
|
231
|
+
return internalTransitionValues((p) => {
|
|
232
|
+
vec3.scale(amount, p, tempDiff);
|
|
233
|
+
this.rotation[0] += tempDiff[0];
|
|
234
|
+
this.rotation[1] += tempDiff[1];
|
|
235
|
+
this.rotation[2] += tempDiff[2];
|
|
121
236
|
}, () => {
|
|
122
237
|
this.rotation = finalRotation;
|
|
123
|
-
this.updateModelMatrix3d();
|
|
124
238
|
}, t, f);
|
|
125
239
|
}
|
|
126
240
|
rotateTo(rot, t = 0, f) {
|
|
127
241
|
const diff = vec3.sub(rot, this.rotation);
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
this.rotation[
|
|
132
|
-
this.
|
|
242
|
+
const tempDiff = vector3();
|
|
243
|
+
return internalTransitionValues((p) => {
|
|
244
|
+
vec3.scale(diff, p, tempDiff);
|
|
245
|
+
this.rotation[0] += tempDiff[0];
|
|
246
|
+
this.rotation[1] += tempDiff[1];
|
|
247
|
+
this.rotation[2] += tempDiff[2];
|
|
133
248
|
}, () => {
|
|
134
249
|
this.rotation = cloneBuf(rot);
|
|
135
|
-
this.updateModelMatrix3d();
|
|
136
250
|
}, t, f);
|
|
137
251
|
}
|
|
138
252
|
getVertexCount() {
|
|
139
253
|
if (this.vertexCache.shouldUpdate()) {
|
|
140
254
|
this.geometry.recompute();
|
|
141
255
|
}
|
|
256
|
+
let childrenVertices = 0;
|
|
257
|
+
for (let i = 0; i < this.children.length; i++) {
|
|
258
|
+
childrenVertices += this.children[i].getObj().getVertexCount();
|
|
259
|
+
}
|
|
260
|
+
let currentVertices = 0;
|
|
142
261
|
if (this.isWireframe()) {
|
|
143
|
-
|
|
262
|
+
currentVertices = this.geometry.getWireframeVertexCount();
|
|
144
263
|
}
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
const matrix = matrix4();
|
|
150
|
-
mat4.translate(matrix, this.pos, matrix);
|
|
151
|
-
rotateMat4(matrix, this.rotation);
|
|
264
|
+
else {
|
|
265
|
+
currentVertices = this.geometry.getTriangleVertexCount();
|
|
266
|
+
}
|
|
267
|
+
return currentVertices + childrenVertices;
|
|
152
268
|
}
|
|
153
269
|
getBuffer(vertexParamGenerator) {
|
|
154
270
|
if (this.vertexCache.shouldUpdate()) {
|
|
@@ -170,18 +286,20 @@ export class SimulationElement {
|
|
|
170
286
|
return this.vertexCache.getCache();
|
|
171
287
|
}
|
|
172
288
|
}
|
|
173
|
-
export class
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
constructor(
|
|
178
|
-
super(
|
|
179
|
-
this.
|
|
180
|
-
|
|
181
|
-
|
|
289
|
+
export class EmptyElement extends SimulationElement3d {
|
|
290
|
+
geometry = new BlankGeometry();
|
|
291
|
+
label;
|
|
292
|
+
isEmpty = true;
|
|
293
|
+
constructor(label) {
|
|
294
|
+
super(vector3(), vector3());
|
|
295
|
+
this.label = label || null;
|
|
296
|
+
}
|
|
297
|
+
getLabel() {
|
|
298
|
+
return this.label;
|
|
182
299
|
}
|
|
183
300
|
}
|
|
184
|
-
export class SimulationElement2d extends
|
|
301
|
+
export class SimulationElement2d extends SimulationElement3d {
|
|
302
|
+
is3d = false;
|
|
185
303
|
constructor(pos, rotation = vector3(), color) {
|
|
186
304
|
super(vector3FromVector2(pos), rotation, color);
|
|
187
305
|
vector3ToPixelRatio(this.pos);
|
|
@@ -192,15 +310,8 @@ export class SimulationElement2d extends SimulationElement {
|
|
|
192
310
|
rotateTo2d(rot, t = 0, f) {
|
|
193
311
|
return super.rotateTo(vector3(0, 0, rot), t, f);
|
|
194
312
|
}
|
|
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);
|
|
313
|
+
getModelMatrix() {
|
|
314
|
+
super.updateModelMatrix2d();
|
|
204
315
|
return this.modelMatrix;
|
|
205
316
|
}
|
|
206
317
|
}
|
|
@@ -270,7 +381,7 @@ export class Square extends SimulationElement2d {
|
|
|
270
381
|
diffMap[+key] = clone;
|
|
271
382
|
}
|
|
272
383
|
});
|
|
273
|
-
return
|
|
384
|
+
return internalTransitionValues((p) => {
|
|
274
385
|
Object.entries(diffMap).forEach(([key, value]) => {
|
|
275
386
|
const color = this.vertexColors[+key];
|
|
276
387
|
color.r += value.r * p;
|
|
@@ -290,7 +401,7 @@ export class Square extends SimulationElement2d {
|
|
|
290
401
|
scaleWidth(amount, t = 0, f) {
|
|
291
402
|
const finalWidth = this.width * amount;
|
|
292
403
|
const diffWidth = finalWidth - this.width;
|
|
293
|
-
return
|
|
404
|
+
return internalTransitionValues((p) => {
|
|
294
405
|
this.width += diffWidth * p;
|
|
295
406
|
this.geometry.setWidth(this.width);
|
|
296
407
|
this.vertexCache.updated();
|
|
@@ -303,7 +414,7 @@ export class Square extends SimulationElement2d {
|
|
|
303
414
|
scaleHeight(amount, t = 0, f) {
|
|
304
415
|
const finalHeight = this.height * amount;
|
|
305
416
|
const diffHeight = finalHeight - this.height;
|
|
306
|
-
return
|
|
417
|
+
return internalTransitionValues((p) => {
|
|
307
418
|
this.height += diffHeight * p;
|
|
308
419
|
this.geometry.setHeight(this.height);
|
|
309
420
|
this.vertexCache.updated();
|
|
@@ -318,7 +429,7 @@ export class Square extends SimulationElement2d {
|
|
|
318
429
|
const finalHeight = this.height * amount;
|
|
319
430
|
const diffWidth = finalWidth - this.width;
|
|
320
431
|
const diffHeight = finalHeight - this.height;
|
|
321
|
-
return
|
|
432
|
+
return internalTransitionValues((p) => {
|
|
322
433
|
this.width += diffWidth * p;
|
|
323
434
|
this.height += diffHeight * p;
|
|
324
435
|
this.geometry.setWidth(this.width);
|
|
@@ -335,7 +446,7 @@ export class Square extends SimulationElement2d {
|
|
|
335
446
|
setWidth(num, t = 0, f) {
|
|
336
447
|
num *= devicePixelRatio;
|
|
337
448
|
const diffWidth = num - this.width;
|
|
338
|
-
return
|
|
449
|
+
return internalTransitionValues((p) => {
|
|
339
450
|
this.width += diffWidth * p;
|
|
340
451
|
this.geometry.setWidth(this.width);
|
|
341
452
|
this.vertexCache.updated();
|
|
@@ -348,7 +459,7 @@ export class Square extends SimulationElement2d {
|
|
|
348
459
|
setHeight(num, t = 0, f) {
|
|
349
460
|
num *= devicePixelRatio;
|
|
350
461
|
const diffHeight = num - this.height;
|
|
351
|
-
return
|
|
462
|
+
return internalTransitionValues((p) => {
|
|
352
463
|
this.height += diffHeight * p;
|
|
353
464
|
this.geometry.setHeight(this.height);
|
|
354
465
|
this.vertexCache.updated();
|
|
@@ -372,7 +483,7 @@ export class Circle extends SimulationElement2d {
|
|
|
372
483
|
setRadius(num, t = 0, f) {
|
|
373
484
|
num *= devicePixelRatio;
|
|
374
485
|
const diff = num - this.radius;
|
|
375
|
-
return
|
|
486
|
+
return internalTransitionValues((p) => {
|
|
376
487
|
this.radius += diff * p;
|
|
377
488
|
this.geometry.setRadius(this.radius);
|
|
378
489
|
this.vertexCache.updated();
|
|
@@ -385,7 +496,7 @@ export class Circle extends SimulationElement2d {
|
|
|
385
496
|
scale(amount, t = 0, f) {
|
|
386
497
|
const finalRadius = this.radius * amount;
|
|
387
498
|
const diff = finalRadius - this.radius;
|
|
388
|
-
return
|
|
499
|
+
return internalTransitionValues((p) => {
|
|
389
500
|
this.radius += diff * p;
|
|
390
501
|
this.geometry.setRadius(this.radius);
|
|
391
502
|
this.vertexCache.updated();
|
|
@@ -411,14 +522,13 @@ export class Polygon extends SimulationElement2d {
|
|
|
411
522
|
const vertices = newVertices.map((vert) => {
|
|
412
523
|
const newVertex = vert.clone();
|
|
413
524
|
newVertex.setZ(0);
|
|
414
|
-
newVertex.setIs3d(false);
|
|
415
525
|
return newVertex;
|
|
416
526
|
});
|
|
417
|
-
const lastVert = this.vertices.length > 0 ? this.vertices[this.vertices.length - 1] : vertex(0, 0, 0, color()
|
|
527
|
+
const lastVert = this.vertices.length > 0 ? this.vertices[this.vertices.length - 1] : vertex(0, 0, 0, color());
|
|
418
528
|
if (vertices.length > this.vertices.length) {
|
|
419
529
|
while (vertices.length > this.vertices.length) {
|
|
420
530
|
const lastPos = lastVert.getPos();
|
|
421
|
-
this.vertices.push(new Vertex(lastPos[0], lastPos[1], 0, lastVert.getColor() || this.color
|
|
531
|
+
this.vertices.push(new Vertex(lastPos[0], lastPos[1], 0, lastVert.getColor() || this.color));
|
|
422
532
|
}
|
|
423
533
|
}
|
|
424
534
|
const initialPositions = this.vertices.map((p) => cloneBuf(p.getPos()));
|
|
@@ -449,7 +559,7 @@ export class Polygon extends SimulationElement2d {
|
|
|
449
559
|
})
|
|
450
560
|
: [])
|
|
451
561
|
];
|
|
452
|
-
return
|
|
562
|
+
return internalTransitionValues((p) => {
|
|
453
563
|
this.vertices.forEach((vert, i) => {
|
|
454
564
|
const posChange = cloneBuf(posChanges[i]);
|
|
455
565
|
const colorChange = cloneBuf(colorChanges[i]);
|
|
@@ -493,7 +603,7 @@ export class Line3d extends SimulationElement3d {
|
|
|
493
603
|
setEnd(pos, t = 0, f) {
|
|
494
604
|
const diff = vector3();
|
|
495
605
|
vec3.sub(pos, this.to, diff);
|
|
496
|
-
return
|
|
606
|
+
return internalTransitionValues((p) => {
|
|
497
607
|
this.to[0] += diff[0] * p;
|
|
498
608
|
this.to[1] += diff[1] * p;
|
|
499
609
|
this.to[2] += diff[2] * p;
|
|
@@ -526,7 +636,7 @@ export class Line2d extends SimulationElement2d {
|
|
|
526
636
|
// vec2.sub(tempPos, this.getPos(), tempPos);
|
|
527
637
|
const diff = vector3();
|
|
528
638
|
vec2.sub(tempPos, this.to, diff);
|
|
529
|
-
return
|
|
639
|
+
return internalTransitionValues((p) => {
|
|
530
640
|
this.to[0] += diff[0] * p;
|
|
531
641
|
this.to[1] += diff[1] * p;
|
|
532
642
|
this.vertexCache.updated();
|
|
@@ -542,18 +652,18 @@ export class Cube extends SimulationElement3d {
|
|
|
542
652
|
width;
|
|
543
653
|
height;
|
|
544
654
|
depth;
|
|
545
|
-
constructor(pos, width, height, depth, color, rotation) {
|
|
655
|
+
constructor(pos, width, height, depth, color, rotation = vector3()) {
|
|
546
656
|
super(pos, rotation, color);
|
|
547
|
-
this.width = width
|
|
548
|
-
this.height = height
|
|
549
|
-
this.depth = depth
|
|
657
|
+
this.width = width;
|
|
658
|
+
this.height = height;
|
|
659
|
+
this.depth = depth;
|
|
550
660
|
this.rotation = rotation || vector3();
|
|
551
661
|
this.geometry = new CubeGeometry(this.width, this.height, this.depth);
|
|
552
662
|
}
|
|
553
663
|
setWidth(width, t = 0, f) {
|
|
554
664
|
width *= devicePixelRatio;
|
|
555
665
|
const diff = width - this.width;
|
|
556
|
-
return
|
|
666
|
+
return internalTransitionValues((p) => {
|
|
557
667
|
this.width += diff * p;
|
|
558
668
|
this.geometry.setWidth(this.width);
|
|
559
669
|
this.vertexCache.updated();
|
|
@@ -566,7 +676,7 @@ export class Cube extends SimulationElement3d {
|
|
|
566
676
|
setHeight(height, t = 0, f) {
|
|
567
677
|
height *= devicePixelRatio;
|
|
568
678
|
const diff = height - this.width;
|
|
569
|
-
return
|
|
679
|
+
return internalTransitionValues((p) => {
|
|
570
680
|
this.height += diff * p;
|
|
571
681
|
this.geometry.setHeight(this.height);
|
|
572
682
|
this.vertexCache.updated();
|
|
@@ -579,7 +689,7 @@ export class Cube extends SimulationElement3d {
|
|
|
579
689
|
setDepth(depth, t = 0, f) {
|
|
580
690
|
depth *= devicePixelRatio;
|
|
581
691
|
const diff = depth - this.width;
|
|
582
|
-
return
|
|
692
|
+
return internalTransitionValues((p) => {
|
|
583
693
|
this.depth += diff * p;
|
|
584
694
|
this.geometry.setDepth(this.depth);
|
|
585
695
|
this.vertexCache.updated();
|
|
@@ -596,7 +706,7 @@ export class Cube extends SimulationElement3d {
|
|
|
596
706
|
const widthDiff = finalWidth - this.width;
|
|
597
707
|
const heightDiff = finalHeight - this.height;
|
|
598
708
|
const depthDiff = finalDepth - this.depth;
|
|
599
|
-
return
|
|
709
|
+
return internalTransitionValues((p) => {
|
|
600
710
|
this.width += widthDiff * p;
|
|
601
711
|
this.height += heightDiff * p;
|
|
602
712
|
this.depth += depthDiff * p;
|
|
@@ -786,7 +896,7 @@ export class Spline2d extends SimulationElement2d {
|
|
|
786
896
|
}
|
|
787
897
|
setInterpolateStart(start, t = 0, f) {
|
|
788
898
|
const diff = start - this.interpolateStart;
|
|
789
|
-
return
|
|
899
|
+
return internalTransitionValues((p) => {
|
|
790
900
|
this.interpolateStart += diff * p;
|
|
791
901
|
this.geometry.updateInterpolationStart(this.interpolateStart);
|
|
792
902
|
this.vertexCache.updated();
|
|
@@ -798,7 +908,7 @@ export class Spline2d extends SimulationElement2d {
|
|
|
798
908
|
}
|
|
799
909
|
setInterpolateLimit(limit, t = 0, f) {
|
|
800
910
|
const diff = limit - this.interpolateLimit;
|
|
801
|
-
return
|
|
911
|
+
return internalTransitionValues((p) => {
|
|
802
912
|
this.interpolateLimit += diff * p;
|
|
803
913
|
this.geometry.updateInterpolationLimit(this.interpolateLimit);
|
|
804
914
|
this.vertexCache.updated();
|
|
@@ -827,7 +937,7 @@ export class Spline2d extends SimulationElement2d {
|
|
|
827
937
|
setThickness(thickness, t = 0, f) {
|
|
828
938
|
thickness *= devicePixelRatio;
|
|
829
939
|
const diff = thickness - this.thickness;
|
|
830
|
-
return
|
|
940
|
+
return internalTransitionValues((p) => {
|
|
831
941
|
this.thickness += diff * p;
|
|
832
942
|
this.geometry.updateThickness(this.thickness);
|
|
833
943
|
this.vertexCache.updated();
|
|
@@ -867,24 +977,20 @@ export class Instance extends SimulationElement3d {
|
|
|
867
977
|
obj;
|
|
868
978
|
instanceMatrix;
|
|
869
979
|
matrixBuffer;
|
|
870
|
-
device;
|
|
871
980
|
baseMat;
|
|
981
|
+
maxInstances;
|
|
982
|
+
isInstance = true;
|
|
872
983
|
constructor(obj, numInstances) {
|
|
873
|
-
super(vector3());
|
|
874
|
-
|
|
984
|
+
super(vector3(), vector3());
|
|
985
|
+
// 32 matrices
|
|
986
|
+
this.maxInstances = 32;
|
|
875
987
|
this.matrixBuffer = null;
|
|
876
988
|
obj.isInstanced = true;
|
|
877
989
|
this.obj = obj;
|
|
878
990
|
this.instanceMatrix = [];
|
|
879
|
-
this.is3d =
|
|
991
|
+
this.is3d = obj.is3d;
|
|
880
992
|
this.geometry = new BlankGeometry();
|
|
881
993
|
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
|
-
}
|
|
888
994
|
for (let i = 0; i < numInstances; i++) {
|
|
889
995
|
const clone = cloneBuf(this.baseMat);
|
|
890
996
|
this.instanceMatrix.push(clone);
|
|
@@ -893,6 +999,10 @@ export class Instance extends SimulationElement3d {
|
|
|
893
999
|
setNumInstances(numInstances) {
|
|
894
1000
|
if (numInstances < 0)
|
|
895
1001
|
throw logger.error('Num instances is less than 0');
|
|
1002
|
+
if (numInstances > this.maxInstances) {
|
|
1003
|
+
this.maxInstances = numInstances;
|
|
1004
|
+
this.allocBuffer(numInstances);
|
|
1005
|
+
}
|
|
896
1006
|
const oldLen = this.instanceMatrix.length;
|
|
897
1007
|
if (numInstances < oldLen) {
|
|
898
1008
|
const diff = oldLen - numInstances;
|
|
@@ -915,11 +1025,27 @@ export class Instance extends SimulationElement3d {
|
|
|
915
1025
|
return;
|
|
916
1026
|
this.instanceMatrix[instance] = transformation;
|
|
917
1027
|
}
|
|
1028
|
+
allocBuffer(size) {
|
|
1029
|
+
const device = globalInfo.getDevice();
|
|
1030
|
+
if (!device)
|
|
1031
|
+
return;
|
|
1032
|
+
const byteSize = size * mat4ByteLength;
|
|
1033
|
+
this.matrixBuffer = device.createBuffer({
|
|
1034
|
+
size: byteSize,
|
|
1035
|
+
usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST
|
|
1036
|
+
});
|
|
1037
|
+
}
|
|
918
1038
|
mapBuffer() {
|
|
919
|
-
|
|
1039
|
+
const device = globalInfo.getDevice();
|
|
1040
|
+
if (!device)
|
|
920
1041
|
return;
|
|
1042
|
+
if (!this.matrixBuffer) {
|
|
1043
|
+
const minSize = this.maxInstances * mat4ByteLength;
|
|
1044
|
+
const size = Math.max(minSize, this.instanceMatrix.length);
|
|
1045
|
+
this.allocBuffer(size);
|
|
1046
|
+
}
|
|
921
1047
|
const buf = new Float32Array(this.instanceMatrix.map((mat) => [...mat]).flat());
|
|
922
|
-
|
|
1048
|
+
device.queue.writeBuffer(this.matrixBuffer, 0, buf.buffer, buf.byteOffset, buf.byteLength);
|
|
923
1049
|
this.matrixBuffer.unmap();
|
|
924
1050
|
}
|
|
925
1051
|
getInstances() {
|
|
@@ -928,15 +1054,7 @@ export class Instance extends SimulationElement3d {
|
|
|
928
1054
|
getNumInstances() {
|
|
929
1055
|
return this.instanceMatrix.length;
|
|
930
1056
|
}
|
|
931
|
-
getMatrixBuffer(
|
|
932
|
-
if (!this.matrixBuffer) {
|
|
933
|
-
const minSize = 640;
|
|
934
|
-
const size = Math.max(minSize, this.instanceMatrix[0].byteLength * this.instanceMatrix.length);
|
|
935
|
-
this.matrixBuffer = device.createBuffer({
|
|
936
|
-
size,
|
|
937
|
-
usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST
|
|
938
|
-
});
|
|
939
|
-
}
|
|
1057
|
+
getMatrixBuffer() {
|
|
940
1058
|
this.mapBuffer();
|
|
941
1059
|
return this.matrixBuffer;
|
|
942
1060
|
}
|
|
@@ -949,4 +1067,43 @@ export class Instance extends SimulationElement3d {
|
|
|
949
1067
|
getBuffer() {
|
|
950
1068
|
return this.obj.getBuffer();
|
|
951
1069
|
}
|
|
1070
|
+
getModelMatrix() {
|
|
1071
|
+
return this.obj.getModelMatrix();
|
|
1072
|
+
}
|
|
1073
|
+
}
|
|
1074
|
+
export class TraceLines2d extends SimulationElement2d {
|
|
1075
|
+
geometry;
|
|
1076
|
+
constructor(color, maxLen) {
|
|
1077
|
+
super(vector2(), vector3(), color);
|
|
1078
|
+
this.geometry = new TraceLinesGeometry(maxLen);
|
|
1079
|
+
}
|
|
1080
|
+
addPoint(point, color) {
|
|
1081
|
+
const vert = vertex(point[0], point[1], point?.[2] || 0, color);
|
|
1082
|
+
this.geometry.addVertex(vert);
|
|
1083
|
+
this.vertexCache.updated();
|
|
1084
|
+
}
|
|
1085
|
+
// always being wireframe means that triangleOrder
|
|
1086
|
+
// in in the geometry does not need to be a duplicate
|
|
1087
|
+
// of wireframeOrder
|
|
1088
|
+
isWireframe() {
|
|
1089
|
+
return true;
|
|
1090
|
+
}
|
|
1091
|
+
}
|
|
1092
|
+
export class TraceLines3d extends SimulationElement3d {
|
|
1093
|
+
geometry;
|
|
1094
|
+
constructor(color, maxLen) {
|
|
1095
|
+
super(vector3(), vector3(), color);
|
|
1096
|
+
this.geometry = new TraceLinesGeometry(maxLen);
|
|
1097
|
+
}
|
|
1098
|
+
addPoint(point, color) {
|
|
1099
|
+
const vert = vertex(point[0], point[1], point?.[2] || 0, color);
|
|
1100
|
+
this.geometry.addVertex(vert);
|
|
1101
|
+
this.vertexCache.updated();
|
|
1102
|
+
}
|
|
1103
|
+
// always being wireframe means that triangleOrder
|
|
1104
|
+
// in in the geometry does not need to be a duplicate
|
|
1105
|
+
// of wireframeOrder
|
|
1106
|
+
isWireframe() {
|
|
1107
|
+
return true;
|
|
1108
|
+
}
|
|
952
1109
|
}
|