simulationjsv2 0.7.3 → 0.8.0
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/README.md +1 -3
- package/TODO.md +6 -5
- package/dist/buffers.d.ts +13 -0
- package/dist/buffers.js +44 -0
- package/dist/constants.d.ts +0 -6
- package/dist/constants.js +1 -6
- package/dist/geometry.d.ts +23 -41
- package/dist/geometry.js +85 -204
- package/dist/globals.d.ts +26 -0
- package/dist/globals.js +51 -0
- package/dist/graphics.d.ts +44 -29
- package/dist/graphics.js +252 -229
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/internalUtils.d.ts +14 -31
- package/dist/internalUtils.js +83 -153
- package/dist/materials.d.ts +20 -0
- package/dist/materials.js +51 -0
- package/dist/shaders.d.ts +37 -0
- package/dist/shaders.js +330 -0
- package/dist/simulation.d.ts +7 -24
- package/dist/simulation.js +72 -338
- package/dist/types.d.ts +51 -45
- package/dist/utils.d.ts +8 -3
- package/dist/utils.js +36 -8
- package/package.json +1 -1
package/dist/graphics.js
CHANGED
|
@@ -1,16 +1,23 @@
|
|
|
1
|
-
import { vec3, mat4, vec2
|
|
2
|
-
import {
|
|
1
|
+
import { vec3, mat4, vec2 } from 'wgpu-matrix';
|
|
2
|
+
import { cloneBuf, vector2, vector3, Color, vector2FromVector3, matrix4, vector3FromVector2, distance2d, color, interpolateColors } from './utils.js';
|
|
3
3
|
import { BlankGeometry, CircleGeometry, CubeGeometry, Line2dGeometry, Line3dGeometry, PlaneGeometry, PolygonGeometry, Spline2dGeometry, SquareGeometry, TraceLines2dGeometry as TraceLinesGeometry } from './geometry.js';
|
|
4
|
-
import { SimSceneObjInfo,
|
|
4
|
+
import { SimSceneObjInfo, Float32ArrayCache, internalTransitionValues, posTo2dScreen, vector3ToPixelRatio } from './internalUtils.js';
|
|
5
5
|
import { mat4ByteLength, modelProjMatOffset } from './constants.js';
|
|
6
|
+
import { MemoBuffer } from './buffers.js';
|
|
7
|
+
import { globalInfo, logger, pipelineCache } from './globals.js';
|
|
8
|
+
import { defaultShader, uniformBufferSize, vertexColorShader } from './shaders.js';
|
|
9
|
+
import { BasicMaterial, VertexColorMaterial } from './materials.js';
|
|
6
10
|
export class SimulationElement3d {
|
|
7
11
|
children;
|
|
8
12
|
uniformBuffer;
|
|
13
|
+
prevInfo;
|
|
14
|
+
pipeline;
|
|
15
|
+
shader;
|
|
16
|
+
material;
|
|
17
|
+
cullMode;
|
|
9
18
|
parent;
|
|
10
19
|
centerOffset;
|
|
11
|
-
rotationOffset;
|
|
12
20
|
pos;
|
|
13
|
-
color;
|
|
14
21
|
wireframe;
|
|
15
22
|
vertexCache;
|
|
16
23
|
rotation;
|
|
@@ -25,16 +32,18 @@ export class SimulationElement3d {
|
|
|
25
32
|
constructor(pos, rotation, color = new Color()) {
|
|
26
33
|
this.pos = pos;
|
|
27
34
|
this.centerOffset = vector3();
|
|
28
|
-
|
|
29
|
-
this.rotationOffset = vector3();
|
|
30
|
-
this.color = color;
|
|
31
|
-
this.vertexCache = new VertexCache();
|
|
35
|
+
this.vertexCache = new Float32ArrayCache();
|
|
32
36
|
this.wireframe = false;
|
|
33
37
|
this.rotation = cloneBuf(rotation);
|
|
34
|
-
this.uniformBuffer =
|
|
38
|
+
this.uniformBuffer = new MemoBuffer(GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST, uniformBufferSize);
|
|
35
39
|
this.children = [];
|
|
36
40
|
this.modelMatrix = matrix4();
|
|
37
41
|
this.parent = null;
|
|
42
|
+
this.pipeline = null;
|
|
43
|
+
this.prevInfo = null;
|
|
44
|
+
this.shader = defaultShader;
|
|
45
|
+
this.material = new BasicMaterial(color);
|
|
46
|
+
this.cullMode = 'back';
|
|
38
47
|
}
|
|
39
48
|
add(el, id) {
|
|
40
49
|
el.setParent(this);
|
|
@@ -63,11 +72,20 @@ export class SimulationElement3d {
|
|
|
63
72
|
getParent() {
|
|
64
73
|
return this.parent;
|
|
65
74
|
}
|
|
75
|
+
getCullMode() {
|
|
76
|
+
return this.cullMode;
|
|
77
|
+
}
|
|
78
|
+
setCullMode(mode) {
|
|
79
|
+
this.cullMode = mode;
|
|
80
|
+
}
|
|
66
81
|
setCenterOffset(offset) {
|
|
67
82
|
this.centerOffset = offset;
|
|
68
83
|
}
|
|
69
|
-
|
|
70
|
-
this.
|
|
84
|
+
getShader() {
|
|
85
|
+
return this.shader;
|
|
86
|
+
}
|
|
87
|
+
setShader(shader) {
|
|
88
|
+
this.shader = shader;
|
|
71
89
|
}
|
|
72
90
|
resetCenterOffset() {
|
|
73
91
|
this.centerOffset[0] = 0;
|
|
@@ -78,23 +96,37 @@ export class SimulationElement3d {
|
|
|
78
96
|
this.updateModelMatrix3d();
|
|
79
97
|
return this.modelMatrix;
|
|
80
98
|
}
|
|
81
|
-
|
|
99
|
+
isTransparent() {
|
|
100
|
+
return this.material.isTransparent();
|
|
101
|
+
}
|
|
102
|
+
setMaterial(material) {
|
|
103
|
+
this.material = material;
|
|
104
|
+
}
|
|
105
|
+
getObjectInfo() {
|
|
106
|
+
const topologyString = this.isWireframe() ? 'line-strip' : 'triangle-' + this.getGeometryTopology();
|
|
107
|
+
return `{ "topology": "${topologyString}", "transparent": ${this.isTransparent()}, "cullMode": "${this.cullMode}" }`;
|
|
108
|
+
}
|
|
109
|
+
getUniformBuffer() {
|
|
110
|
+
const mat = this.getModelMatrix();
|
|
111
|
+
const device = globalInfo.errorGetDevice();
|
|
112
|
+
const buffer = this.uniformBuffer.getBuffer();
|
|
113
|
+
device.queue.writeBuffer(buffer, modelProjMatOffset, mat);
|
|
114
|
+
return buffer;
|
|
115
|
+
}
|
|
116
|
+
getPipeline() {
|
|
82
117
|
const device = globalInfo.errorGetDevice();
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
this.
|
|
86
|
-
|
|
87
|
-
usage: GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST
|
|
88
|
-
});
|
|
118
|
+
const objInfo = this.getObjectInfo();
|
|
119
|
+
if (!this.pipeline || !this.prevInfo || this.prevInfo !== objInfo) {
|
|
120
|
+
this.pipeline = pipelineCache.getPipeline(device, objInfo, this.shader);
|
|
121
|
+
this.prevInfo = objInfo;
|
|
89
122
|
}
|
|
90
|
-
|
|
91
|
-
return this.uniformBuffer;
|
|
123
|
+
return this.pipeline;
|
|
92
124
|
}
|
|
93
125
|
mirrorParentTransforms3d(mat) {
|
|
94
126
|
if (!this.parent)
|
|
95
127
|
return;
|
|
96
128
|
this.parent.mirrorParentTransforms3d(mat);
|
|
97
|
-
mat4.translate(mat, this.parent.
|
|
129
|
+
mat4.translate(mat, this.parent.getRelativePos(), mat);
|
|
98
130
|
const parentRot = this.parent.getRotation();
|
|
99
131
|
mat4.rotateZ(mat, parentRot[2], mat);
|
|
100
132
|
mat4.rotateY(mat, parentRot[1], mat);
|
|
@@ -106,12 +138,9 @@ export class SimulationElement3d {
|
|
|
106
138
|
this.mirrorParentTransforms3d(this.modelMatrix);
|
|
107
139
|
}
|
|
108
140
|
mat4.translate(this.modelMatrix, this.pos, this.modelMatrix);
|
|
109
|
-
// vec3.negate(this.rotationOffset, cachedVec1);
|
|
110
|
-
// mat4.translate(this.modelMatrix, cachedVec1, this.modelMatrix);
|
|
111
141
|
mat4.rotateZ(this.modelMatrix, this.rotation[2], this.modelMatrix);
|
|
112
142
|
mat4.rotateY(this.modelMatrix, this.rotation[1], this.modelMatrix);
|
|
113
143
|
mat4.rotateX(this.modelMatrix, this.rotation[0], this.modelMatrix);
|
|
114
|
-
// mat4.translate(this.modelMatrix, this.rotationOffset, this.modelMatrix);
|
|
115
144
|
mat4.translate(this.modelMatrix, this.centerOffset, this.modelMatrix);
|
|
116
145
|
}
|
|
117
146
|
mirrorParentTransforms2d(mat) {
|
|
@@ -135,11 +164,13 @@ export class SimulationElement3d {
|
|
|
135
164
|
else {
|
|
136
165
|
mat4.translate(this.modelMatrix, pos, this.modelMatrix);
|
|
137
166
|
}
|
|
167
|
+
const negated = vec3.negate(this.centerOffset);
|
|
168
|
+
mat4.translate(this.modelMatrix, negated, this.modelMatrix);
|
|
138
169
|
mat4.rotateZ(this.modelMatrix, this.rotation[2], this.modelMatrix);
|
|
139
170
|
mat4.translate(this.modelMatrix, this.centerOffset, this.modelMatrix);
|
|
140
171
|
}
|
|
141
|
-
|
|
142
|
-
return this.geometry.
|
|
172
|
+
getGeometryTopology() {
|
|
173
|
+
return this.geometry.getTopology();
|
|
143
174
|
}
|
|
144
175
|
setWireframe(wireframe) {
|
|
145
176
|
this.wireframe = wireframe;
|
|
@@ -147,13 +178,13 @@ export class SimulationElement3d {
|
|
|
147
178
|
isWireframe() {
|
|
148
179
|
return this.wireframe;
|
|
149
180
|
}
|
|
150
|
-
|
|
151
|
-
return this.
|
|
181
|
+
getMaterial() {
|
|
182
|
+
return this.material;
|
|
152
183
|
}
|
|
153
|
-
|
|
184
|
+
getRelativePos() {
|
|
154
185
|
return this.pos;
|
|
155
186
|
}
|
|
156
|
-
|
|
187
|
+
getPos() {
|
|
157
188
|
const vec = vector3();
|
|
158
189
|
this.updateModelMatrix3d();
|
|
159
190
|
mat4.getTranslation(this.modelMatrix, vec);
|
|
@@ -166,16 +197,17 @@ export class SimulationElement3d {
|
|
|
166
197
|
return this.centerOffset;
|
|
167
198
|
}
|
|
168
199
|
fill(newColor, t = 0, f) {
|
|
169
|
-
const
|
|
200
|
+
const materialColor = this.material.getColor();
|
|
201
|
+
const diff = newColor.diff(materialColor);
|
|
170
202
|
const finalColor = newColor.clone();
|
|
171
203
|
return internalTransitionValues((p) => {
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
204
|
+
materialColor.r += diff.r * p;
|
|
205
|
+
materialColor.g += diff.g * p;
|
|
206
|
+
materialColor.b += diff.b * p;
|
|
207
|
+
materialColor.a += diff.a * p;
|
|
176
208
|
this.vertexCache.updated();
|
|
177
209
|
}, () => {
|
|
178
|
-
this.
|
|
210
|
+
this.material.setColor(finalColor);
|
|
179
211
|
this.vertexCache.updated();
|
|
180
212
|
}, t, f);
|
|
181
213
|
}
|
|
@@ -253,38 +285,41 @@ export class SimulationElement3d {
|
|
|
253
285
|
if (this.vertexCache.shouldUpdate()) {
|
|
254
286
|
this.geometry.recompute();
|
|
255
287
|
}
|
|
256
|
-
let
|
|
288
|
+
let vertexCount = this.geometry.getIndexes(this.isWireframe()).length;
|
|
257
289
|
for (let i = 0; i < this.children.length; i++) {
|
|
258
|
-
|
|
290
|
+
vertexCount += this.children[i].getObj().getVertexCount();
|
|
259
291
|
}
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
292
|
+
return vertexCount;
|
|
293
|
+
}
|
|
294
|
+
getIndexCount() {
|
|
295
|
+
let indexCount = this.geometry.getIndexes(this.isWireframe()).length;
|
|
296
|
+
for (let i = 0; i < this.children.length; i++) {
|
|
297
|
+
indexCount += this.children[i].getObj().getIndexCount();
|
|
266
298
|
}
|
|
267
|
-
return
|
|
299
|
+
return indexCount;
|
|
300
|
+
}
|
|
301
|
+
writeBuffers() {
|
|
302
|
+
this.shader.writeBuffers(this);
|
|
268
303
|
}
|
|
269
|
-
|
|
304
|
+
getVertexBuffer() {
|
|
270
305
|
if (this.vertexCache.shouldUpdate()) {
|
|
271
306
|
this.geometry.recompute();
|
|
272
|
-
|
|
273
|
-
|
|
307
|
+
const vertices = this.geometry.getVertices();
|
|
308
|
+
const stride = this.shader.getBufferLength();
|
|
309
|
+
const vertexBuffer = new Float32Array(vertices.length * stride);
|
|
310
|
+
const shader = this.isWireframe() ? defaultShader : this.shader;
|
|
311
|
+
for (let i = 0; i < vertices.length; i++) {
|
|
312
|
+
shader.setVertexInfo(this, vertexBuffer, vertices[i], i, i * stride);
|
|
274
313
|
}
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
resBuffer = this.geometry.getWireframeBuffer(this.color, vertexParamGenerator);
|
|
278
|
-
}
|
|
279
|
-
else {
|
|
280
|
-
resBuffer = this.geometry.getTriangleBuffer(this.color, vertexParamGenerator);
|
|
281
|
-
}
|
|
282
|
-
bufferGenerator.setInstancing(false);
|
|
283
|
-
this.vertexCache.setCache(resBuffer);
|
|
284
|
-
return resBuffer;
|
|
314
|
+
this.vertexCache.setCache(vertexBuffer);
|
|
315
|
+
return vertexBuffer;
|
|
285
316
|
}
|
|
286
317
|
return this.vertexCache.getCache();
|
|
287
318
|
}
|
|
319
|
+
getIndexBuffer() {
|
|
320
|
+
const order = this.geometry.getIndexes(this.isWireframe());
|
|
321
|
+
return new Uint32Array(order);
|
|
322
|
+
}
|
|
288
323
|
}
|
|
289
324
|
export class EmptyElement extends SimulationElement3d {
|
|
290
325
|
geometry = new BlankGeometry();
|
|
@@ -292,7 +327,7 @@ export class EmptyElement extends SimulationElement3d {
|
|
|
292
327
|
isEmpty = true;
|
|
293
328
|
constructor(label) {
|
|
294
329
|
super(vector3(), vector3());
|
|
295
|
-
this.label = label
|
|
330
|
+
this.label = label ?? null;
|
|
296
331
|
}
|
|
297
332
|
getLabel() {
|
|
298
333
|
return this.label;
|
|
@@ -323,6 +358,7 @@ export class Plane extends SimulationElement3d {
|
|
|
323
358
|
this.rotation = rotation;
|
|
324
359
|
this.points = points;
|
|
325
360
|
this.geometry = new PlaneGeometry(points);
|
|
361
|
+
this.cullMode = 'none';
|
|
326
362
|
}
|
|
327
363
|
setPoints(newPoints) {
|
|
328
364
|
this.points = newPoints;
|
|
@@ -333,70 +369,21 @@ export class Square extends SimulationElement2d {
|
|
|
333
369
|
geometry;
|
|
334
370
|
width;
|
|
335
371
|
height;
|
|
336
|
-
vertexColors;
|
|
337
372
|
/**
|
|
338
373
|
* @param centerOffset{Vector2} - A vector2 of values from 0 to 1
|
|
339
374
|
* @param vertexColors{Record<number, Color>} - 0 is top left vertex, numbers increase clockwise
|
|
340
375
|
*/
|
|
341
|
-
constructor(pos, width, height, color, rotation
|
|
376
|
+
constructor(pos, width, height, color, rotation) {
|
|
342
377
|
super(pos, vector3(0, 0, rotation), color);
|
|
343
|
-
this.width = width
|
|
344
|
-
this.height = height
|
|
345
|
-
this.
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
setOffsetInplace(offset) {
|
|
353
|
-
const diff = vector3FromVector2(offset);
|
|
354
|
-
vec2.sub(diff, this.geometry.getOffset(), diff);
|
|
355
|
-
vec2.mul(diff, vector2(this.width / devicePixelRatio, -this.height / devicePixelRatio), diff);
|
|
356
|
-
this.setOffset(offset);
|
|
357
|
-
this.move(diff);
|
|
358
|
-
}
|
|
359
|
-
cloneColorMap(colorMap) {
|
|
360
|
-
const newColorMap = {};
|
|
361
|
-
Object.entries(colorMap).forEach(([key, value]) => {
|
|
362
|
-
newColorMap[+key] = value.clone();
|
|
363
|
-
});
|
|
364
|
-
return newColorMap;
|
|
365
|
-
}
|
|
366
|
-
setVertexColors(newColorMap, t = 0, f) {
|
|
367
|
-
const colorMap = this.cloneColorMap(newColorMap);
|
|
368
|
-
const diffMap = {};
|
|
369
|
-
Object.entries(colorMap).forEach(([key, value]) => {
|
|
370
|
-
if (!this.vertexColors[+key]) {
|
|
371
|
-
this.vertexColors[+key] = color();
|
|
372
|
-
}
|
|
373
|
-
diffMap[+key] = value.diff(this.vertexColors[+key] || color());
|
|
374
|
-
});
|
|
375
|
-
Object.entries(this.vertexColors).forEach(([key, value]) => {
|
|
376
|
-
if (!diffMap[+key]) {
|
|
377
|
-
const clone = value.clone();
|
|
378
|
-
clone.r *= -1;
|
|
379
|
-
clone.g *= -1;
|
|
380
|
-
clone.b *= -1;
|
|
381
|
-
diffMap[+key] = clone;
|
|
382
|
-
}
|
|
383
|
-
});
|
|
384
|
-
return internalTransitionValues((p) => {
|
|
385
|
-
Object.entries(diffMap).forEach(([key, value]) => {
|
|
386
|
-
const color = this.vertexColors[+key];
|
|
387
|
-
color.r += value.r * p;
|
|
388
|
-
color.g += value.g * p;
|
|
389
|
-
color.b += value.b * p;
|
|
390
|
-
color.a += value.a * p;
|
|
391
|
-
this.vertexColors[+key] = color;
|
|
392
|
-
});
|
|
393
|
-
this.geometry.setVertexColorMap(this.vertexColors);
|
|
394
|
-
this.vertexCache.updated();
|
|
395
|
-
}, () => {
|
|
396
|
-
this.vertexColors = colorMap;
|
|
397
|
-
this.geometry.setVertexColorMap(this.vertexColors);
|
|
398
|
-
this.vertexCache.updated();
|
|
399
|
-
}, t, f);
|
|
378
|
+
this.width = width;
|
|
379
|
+
this.height = height;
|
|
380
|
+
this.geometry = new SquareGeometry(this.width, this.height);
|
|
381
|
+
}
|
|
382
|
+
getWidth() {
|
|
383
|
+
return this.width;
|
|
384
|
+
}
|
|
385
|
+
getHeight() {
|
|
386
|
+
return this.height;
|
|
400
387
|
}
|
|
401
388
|
scaleWidth(amount, t = 0, f) {
|
|
402
389
|
const finalWidth = this.width * amount;
|
|
@@ -509,78 +496,78 @@ export class Circle extends SimulationElement2d {
|
|
|
509
496
|
}
|
|
510
497
|
export class Polygon extends SimulationElement2d {
|
|
511
498
|
geometry;
|
|
512
|
-
vertices
|
|
513
|
-
constructor(pos, points, color, rotation) {
|
|
499
|
+
constructor(pos, vertices, color, rotation) {
|
|
514
500
|
super(pos, vector3(0, 0, rotation), color);
|
|
515
|
-
|
|
516
|
-
this.
|
|
501
|
+
const vectors = vertices.map((vert) => vert.getPos());
|
|
502
|
+
this.shader = vertexColorShader;
|
|
503
|
+
this.geometry = new PolygonGeometry(vectors);
|
|
504
|
+
this.material = new VertexColorMaterial();
|
|
505
|
+
if (color)
|
|
506
|
+
this.material.setColor(color);
|
|
507
|
+
const colors = vertices.map((vert) => vert.getColor() ?? this.material.getColor());
|
|
508
|
+
this.material.setVertexColors(colors);
|
|
517
509
|
}
|
|
518
510
|
getVertices() {
|
|
519
|
-
return this.
|
|
520
|
-
}
|
|
521
|
-
setVertices(
|
|
522
|
-
const
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
511
|
+
return this.geometry.getVertices();
|
|
512
|
+
}
|
|
513
|
+
setVertices(vertices, t = 0, f) {
|
|
514
|
+
const newVertices = vertices.map((vert) => vert.getPos());
|
|
515
|
+
const newColors = vertices.map((vert) => vert.getColor() ?? this.material.getColor());
|
|
516
|
+
const oldColors = this.material.getVertexColors();
|
|
517
|
+
const oldVertices = this.getVertices();
|
|
518
|
+
const lastVert = oldVertices.length > 0 ? oldVertices[oldVertices.length - 1] : vector3();
|
|
519
|
+
const lastColor = oldColors.length > 0 ? oldColors[oldColors.length - 1] : this.material.getColor();
|
|
520
|
+
while (newVertices.length > oldVertices.length) {
|
|
521
|
+
oldVertices.push(cloneBuf(lastVert));
|
|
522
|
+
oldColors.push(lastColor.clone());
|
|
523
|
+
}
|
|
524
|
+
// at this point oldVertices length is assumed to be greater than or equal to newVertices length
|
|
525
|
+
const initialPositions = oldVertices.map((vert) => cloneBuf(vert));
|
|
526
|
+
const posChanges = newVertices.map((vert, i) => {
|
|
527
|
+
const vec = vector3();
|
|
528
|
+
vec3.sub(vert, oldVertices[i], vec);
|
|
529
|
+
return vec;
|
|
526
530
|
});
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
531
|
+
for (let i = newVertices.length; i < oldVertices.length; i++) {
|
|
532
|
+
const vec = cloneBuf(newVertices[newVertices.length - 1]);
|
|
533
|
+
vec3.sub(vec, oldVertices[i], vec);
|
|
534
|
+
posChanges.push(vec);
|
|
535
|
+
}
|
|
536
|
+
const initialColors = oldColors.map((oldColor) => oldColor.clone());
|
|
537
|
+
const colorChanges = newColors.map((currentColor, index) => currentColor.diff(oldColors[index]));
|
|
538
|
+
for (let i = newVertices.length; i < oldVertices.length; i++) {
|
|
539
|
+
colorChanges.push(newColors[newColors.length - 1].diff(oldColors[i]));
|
|
533
540
|
}
|
|
534
|
-
const initialPositions = this.vertices.map((p) => cloneBuf(p.getPos()));
|
|
535
|
-
const posChanges = [
|
|
536
|
-
...vertices.map((vert, i) => {
|
|
537
|
-
const vec = vector3();
|
|
538
|
-
vec3.sub(vert.getPos(), this.vertices[i].getPos(), vec);
|
|
539
|
-
return cloneBuf(vec);
|
|
540
|
-
}),
|
|
541
|
-
...(this.vertices.length > vertices.length
|
|
542
|
-
? this.vertices.slice(vertices.length, this.vertices.length).map((vert) => {
|
|
543
|
-
const vec = cloneBuf(vertices[vertices.length - 1].getPos());
|
|
544
|
-
vec3.sub(vec, vert.getPos(), vec);
|
|
545
|
-
return vec;
|
|
546
|
-
})
|
|
547
|
-
: [])
|
|
548
|
-
];
|
|
549
|
-
const initialColors = this.vertices.map((vert) => (vert.getColor() || this.color).toVec4());
|
|
550
|
-
const colorChanges = [
|
|
551
|
-
...vertices.map((vert, i) => {
|
|
552
|
-
const diff = (vert.getColor() || this.color).diff(this.vertices[i].getColor() || this.color);
|
|
553
|
-
return diff.toVec4();
|
|
554
|
-
}),
|
|
555
|
-
...(this.vertices.length > vertices.length
|
|
556
|
-
? this.vertices.slice(vertices.length, this.vertices.length).map((vert) => {
|
|
557
|
-
const toColor = vertices[vertices.length - 1].getColor();
|
|
558
|
-
return (toColor || this.color).diff(vert.getColor() || this.color).toVec4();
|
|
559
|
-
})
|
|
560
|
-
: [])
|
|
561
|
-
];
|
|
562
541
|
return internalTransitionValues((p) => {
|
|
563
|
-
|
|
542
|
+
for (let i = 0; i < oldVertices.length; i++) {
|
|
543
|
+
const vert = oldVertices[i];
|
|
544
|
+
const currentColor = oldColors[i];
|
|
564
545
|
const posChange = cloneBuf(posChanges[i]);
|
|
565
|
-
const colorChange =
|
|
546
|
+
const colorChange = colorChanges[i].clone();
|
|
566
547
|
vec3.scale(posChange, p, posChange);
|
|
567
|
-
vec3.add(vert
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
}
|
|
548
|
+
vec3.add(vert, posChange, vert);
|
|
549
|
+
currentColor.r += colorChange.r * p;
|
|
550
|
+
currentColor.g += colorChange.g * p;
|
|
551
|
+
currentColor.b += colorChange.b * p;
|
|
552
|
+
currentColor.a += colorChange.a * p;
|
|
553
|
+
}
|
|
573
554
|
this.vertexCache.updated();
|
|
574
555
|
}, () => {
|
|
575
|
-
|
|
556
|
+
for (let i = 0; i < oldVertices.length; i++) {
|
|
557
|
+
const vert = oldVertices[i];
|
|
558
|
+
const currentColor = oldColors[i];
|
|
576
559
|
const initPos = initialPositions[i];
|
|
577
560
|
const initColor = initialColors[i];
|
|
578
561
|
vec3.add(initPos, posChanges[i], initPos);
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
562
|
+
initColor.r += colorChanges[i].r;
|
|
563
|
+
initColor.g += colorChanges[i].g;
|
|
564
|
+
initColor.b += colorChanges[i].b;
|
|
565
|
+
initColor.a += colorChanges[i].a;
|
|
566
|
+
vert.set(initPos);
|
|
567
|
+
currentColor.setValues(initColor);
|
|
568
|
+
}
|
|
569
|
+
oldVertices.splice(newVertices.length, oldVertices.length);
|
|
570
|
+
oldColors.splice(newColors.length, oldColors.length);
|
|
584
571
|
this.vertexCache.updated();
|
|
585
572
|
}, t, f);
|
|
586
573
|
}
|
|
@@ -590,12 +577,12 @@ export class Line3d extends SimulationElement3d {
|
|
|
590
577
|
to;
|
|
591
578
|
thickness;
|
|
592
579
|
constructor(pos, to, thickness) {
|
|
593
|
-
super(pos.getPos(), vector3(), to.getColor()
|
|
580
|
+
super(pos.getPos(), vector3(), to.getColor() ?? undefined);
|
|
594
581
|
this.thickness = thickness;
|
|
595
582
|
this.to = to.getPos();
|
|
596
583
|
vec3.scale(this.to, devicePixelRatio, this.to);
|
|
597
584
|
vec3.sub(this.to, this.pos, this.to);
|
|
598
|
-
this.geometry = new Line3dGeometry(this.pos, this.to, this.thickness
|
|
585
|
+
this.geometry = new Line3dGeometry(this.pos, this.to, this.thickness);
|
|
599
586
|
}
|
|
600
587
|
setStart(pos, t = 0, f) {
|
|
601
588
|
return this.moveTo(pos, t, f);
|
|
@@ -621,11 +608,11 @@ export class Line2d extends SimulationElement2d {
|
|
|
621
608
|
to;
|
|
622
609
|
thickness;
|
|
623
610
|
constructor(from, to, thickness = 1) {
|
|
624
|
-
super(vector2FromVector3(from.getPos()), vector3(), from.getColor()
|
|
611
|
+
super(vector2FromVector3(from.getPos()), vector3(), from.getColor() ?? undefined);
|
|
625
612
|
this.thickness = thickness * devicePixelRatio;
|
|
626
613
|
this.to = to.getPos();
|
|
627
614
|
vec2.sub(this.to, this.pos, this.to);
|
|
628
|
-
this.geometry = new Line2dGeometry(this.pos, this.to, this.thickness
|
|
615
|
+
this.geometry = new Line2dGeometry(this.pos, this.to, this.thickness);
|
|
629
616
|
}
|
|
630
617
|
setStart(pos, t = 0, f) {
|
|
631
618
|
return this.moveTo(pos, t, f);
|
|
@@ -792,7 +779,7 @@ export class CubicBezierCurve2d extends BezierCurve2d {
|
|
|
792
779
|
constructor(points, detail, colors) {
|
|
793
780
|
super(points);
|
|
794
781
|
this.detail = detail;
|
|
795
|
-
this.colors = colors
|
|
782
|
+
this.colors = colors ?? [];
|
|
796
783
|
}
|
|
797
784
|
getDetail() {
|
|
798
785
|
return this.detail;
|
|
@@ -836,7 +823,7 @@ export class SplinePoint2d {
|
|
|
836
823
|
if (prevColor) {
|
|
837
824
|
colors[0] = prevColor;
|
|
838
825
|
}
|
|
839
|
-
else if (this.start
|
|
826
|
+
else if (this.start?.getColor()) {
|
|
840
827
|
colors[0] = this.start.getColor();
|
|
841
828
|
}
|
|
842
829
|
if (this.end.getColor()) {
|
|
@@ -848,7 +835,7 @@ export class SplinePoint2d {
|
|
|
848
835
|
return colors;
|
|
849
836
|
}
|
|
850
837
|
getVectorArray(prevEnd, prevControl) {
|
|
851
|
-
const firstControl = cloneBuf(this.control1
|
|
838
|
+
const firstControl = cloneBuf(this.control1 ?? prevControl ?? vector2());
|
|
852
839
|
if (prevEnd) {
|
|
853
840
|
vec2.add(firstControl, prevEnd, firstControl);
|
|
854
841
|
}
|
|
@@ -875,15 +862,55 @@ export class Spline2d extends SimulationElement2d {
|
|
|
875
862
|
length;
|
|
876
863
|
constructor(pos, points, thickness = devicePixelRatio, detail = 40) {
|
|
877
864
|
const tempPos = vector2FromVector3(pos.getPos());
|
|
878
|
-
super(tempPos, vector3(), pos.getColor()
|
|
865
|
+
super(tempPos, vector3(), pos.getColor() ?? undefined);
|
|
879
866
|
this.thickness = thickness * devicePixelRatio;
|
|
880
867
|
this.detail = detail;
|
|
881
868
|
this.interpolateStart = 0;
|
|
882
869
|
this.interpolateLimit = 1;
|
|
883
870
|
this.length = 0;
|
|
884
|
-
this.geometry = new Spline2dGeometry(points, this.
|
|
871
|
+
this.geometry = new Spline2dGeometry(points, this.thickness, this.detail);
|
|
872
|
+
this.material = new VertexColorMaterial();
|
|
873
|
+
this.material.setColor(pos.getColor() ?? color());
|
|
874
|
+
this.setVertexColors();
|
|
875
|
+
this.shader = vertexColorShader;
|
|
885
876
|
this.estimateLength();
|
|
886
877
|
}
|
|
878
|
+
setVertexColors() {
|
|
879
|
+
const numVertices = this.geometry.getVertices().length;
|
|
880
|
+
const curves = this.geometry.getCurves();
|
|
881
|
+
const curveVertexIndices = this.geometry.getCurveVertexIndices();
|
|
882
|
+
const vertexInterpolations = this.geometry.getVertexInterpolations();
|
|
883
|
+
const colorArray = Array(numVertices);
|
|
884
|
+
let currentCurveIndex = 0;
|
|
885
|
+
for (let i = 0; i < numVertices / 2; i++) {
|
|
886
|
+
if (i >= curveVertexIndices[currentCurveIndex])
|
|
887
|
+
currentCurveIndex++;
|
|
888
|
+
const curveColors = curves[currentCurveIndex]
|
|
889
|
+
.getColors()
|
|
890
|
+
.map((item) => item ?? this.material.getColor());
|
|
891
|
+
const vertexColor = interpolateColors(curveColors, vertexInterpolations[i]);
|
|
892
|
+
colorArray[i] = vertexColor;
|
|
893
|
+
colorArray[numVertices - i - 1] = vertexColor;
|
|
894
|
+
}
|
|
895
|
+
this.material.setVertexColors(colorArray);
|
|
896
|
+
}
|
|
897
|
+
getVertexBuffer() {
|
|
898
|
+
if (this.vertexCache.shouldUpdate()) {
|
|
899
|
+
this.setVertexColors();
|
|
900
|
+
}
|
|
901
|
+
return super.getVertexBuffer();
|
|
902
|
+
}
|
|
903
|
+
isTransparent() {
|
|
904
|
+
const curves = this.geometry.getCurves();
|
|
905
|
+
for (let i = 0; i < curves.length; i++) {
|
|
906
|
+
const colors = curves[i].getColors();
|
|
907
|
+
for (let j = 0; j < colors.length; j++) {
|
|
908
|
+
if (colors[j]?.isTransparent())
|
|
909
|
+
return true;
|
|
910
|
+
}
|
|
911
|
+
}
|
|
912
|
+
return false;
|
|
913
|
+
}
|
|
887
914
|
estimateLength() {
|
|
888
915
|
this.length = 0;
|
|
889
916
|
const curves = this.geometry.getCurves();
|
|
@@ -925,9 +952,9 @@ export class Spline2d extends SimulationElement2d {
|
|
|
925
952
|
}
|
|
926
953
|
updatePointAbsolute(pointIndex, newPoint) {
|
|
927
954
|
const clonePoint = newPoint.clone();
|
|
928
|
-
const start = clonePoint.getStart()?.getPos()
|
|
955
|
+
const start = clonePoint.getStart()?.getPos() ?? vector3();
|
|
929
956
|
const end = clonePoint.getEnd().getPos();
|
|
930
|
-
const pos = this.
|
|
957
|
+
const pos = this.getRelativePos();
|
|
931
958
|
vec3.sub(start, pos, start);
|
|
932
959
|
vec3.sub(end, pos, end);
|
|
933
960
|
this.geometry.updatePoint(pointIndex, clonePoint);
|
|
@@ -985,7 +1012,7 @@ export class Instance extends SimulationElement3d {
|
|
|
985
1012
|
super(vector3(), vector3());
|
|
986
1013
|
// 32 matrices
|
|
987
1014
|
this.maxInstances = 32;
|
|
988
|
-
this.matrixBuffer =
|
|
1015
|
+
this.matrixBuffer = new MemoBuffer(GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST, this.maxInstances * mat4ByteLength);
|
|
989
1016
|
obj.isInstanced = true;
|
|
990
1017
|
this.obj = obj;
|
|
991
1018
|
this.instanceMatrix = [];
|
|
@@ -998,12 +1025,12 @@ export class Instance extends SimulationElement3d {
|
|
|
998
1025
|
this.instanceMatrix.push(clone);
|
|
999
1026
|
}
|
|
1000
1027
|
}
|
|
1001
|
-
setNumInstances(numInstances) {
|
|
1028
|
+
setNumInstances(numInstances, forceResizeBuffer = false) {
|
|
1002
1029
|
if (numInstances < 0)
|
|
1003
1030
|
throw logger.error('Num instances is less than 0');
|
|
1004
|
-
if (numInstances > this.maxInstances) {
|
|
1031
|
+
if (numInstances > this.maxInstances || forceResizeBuffer) {
|
|
1005
1032
|
this.maxInstances = numInstances;
|
|
1006
|
-
this.
|
|
1033
|
+
this.matrixBuffer.setSize(numInstances * mat4ByteLength);
|
|
1007
1034
|
}
|
|
1008
1035
|
const oldLen = this.instanceMatrix.length;
|
|
1009
1036
|
if (numInstances < oldLen) {
|
|
@@ -1029,37 +1056,23 @@ export class Instance extends SimulationElement3d {
|
|
|
1029
1056
|
const device = globalInfo.getDevice();
|
|
1030
1057
|
if (!device)
|
|
1031
1058
|
return;
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
const size = Math.max(minSize, this.instanceMatrix.length);
|
|
1035
|
-
this.allocBuffer(size);
|
|
1036
|
-
}
|
|
1059
|
+
// this.allocBuffer(size);
|
|
1060
|
+
const gpuBuffer = this.matrixBuffer.getBuffer();
|
|
1037
1061
|
const buf = new Float32Array(transformation);
|
|
1038
|
-
device.queue.writeBuffer(
|
|
1039
|
-
|
|
1040
|
-
}
|
|
1041
|
-
allocBuffer(size) {
|
|
1042
|
-
const device = globalInfo.getDevice();
|
|
1043
|
-
if (!device)
|
|
1044
|
-
return;
|
|
1045
|
-
const byteSize = size * mat4ByteLength;
|
|
1046
|
-
this.matrixBuffer = device.createBuffer({
|
|
1047
|
-
size: byteSize,
|
|
1048
|
-
usage: GPUBufferUsage.STORAGE | GPUBufferUsage.COPY_DST
|
|
1049
|
-
});
|
|
1062
|
+
device.queue.writeBuffer(gpuBuffer, instance * mat4ByteLength, buf.buffer, buf.byteOffset, buf.byteLength);
|
|
1063
|
+
gpuBuffer.unmap();
|
|
1050
1064
|
}
|
|
1051
1065
|
mapBuffer() {
|
|
1052
1066
|
const device = globalInfo.getDevice();
|
|
1053
1067
|
if (!device)
|
|
1054
1068
|
return;
|
|
1055
|
-
|
|
1056
|
-
|
|
1057
|
-
|
|
1058
|
-
|
|
1059
|
-
}
|
|
1069
|
+
const minSize = this.maxInstances * mat4ByteLength;
|
|
1070
|
+
const size = Math.max(minSize, this.instanceMatrix.length);
|
|
1071
|
+
this.matrixBuffer.setSize(size);
|
|
1072
|
+
const gpuBuffer = this.matrixBuffer.getBuffer();
|
|
1060
1073
|
const buf = new Float32Array(this.instanceMatrix.map((mat) => [...mat]).flat());
|
|
1061
|
-
device.queue.writeBuffer(
|
|
1062
|
-
|
|
1074
|
+
device.queue.writeBuffer(gpuBuffer, 0, buf.buffer, buf.byteOffset, buf.byteLength);
|
|
1075
|
+
gpuBuffer.unmap();
|
|
1063
1076
|
this.hasMapped = true;
|
|
1064
1077
|
}
|
|
1065
1078
|
getInstances() {
|
|
@@ -1068,20 +1081,26 @@ export class Instance extends SimulationElement3d {
|
|
|
1068
1081
|
getNumInstances() {
|
|
1069
1082
|
return this.instanceMatrix.length;
|
|
1070
1083
|
}
|
|
1071
|
-
|
|
1084
|
+
getInstanceBuffer() {
|
|
1072
1085
|
if (!this.hasMapped) {
|
|
1073
1086
|
this.mapBuffer();
|
|
1074
1087
|
}
|
|
1075
|
-
return this.matrixBuffer;
|
|
1088
|
+
return this.matrixBuffer.getBuffer();
|
|
1076
1089
|
}
|
|
1077
1090
|
getVertexCount() {
|
|
1078
1091
|
return this.obj.getVertexCount();
|
|
1079
1092
|
}
|
|
1080
|
-
|
|
1081
|
-
return this.obj.
|
|
1093
|
+
getIndexCount() {
|
|
1094
|
+
return this.obj.getIndexCount();
|
|
1095
|
+
}
|
|
1096
|
+
getGeometryTopology() {
|
|
1097
|
+
return this.obj.getGeometryTopology();
|
|
1098
|
+
}
|
|
1099
|
+
getVertexBuffer() {
|
|
1100
|
+
return this.obj.getVertexBuffer();
|
|
1082
1101
|
}
|
|
1083
|
-
|
|
1084
|
-
return this.obj.
|
|
1102
|
+
getIndexBuffer() {
|
|
1103
|
+
return this.obj.getIndexBuffer();
|
|
1085
1104
|
}
|
|
1086
1105
|
getModelMatrix() {
|
|
1087
1106
|
return this.obj.getModelMatrix();
|
|
@@ -1093,9 +1112,11 @@ export class TraceLines2d extends SimulationElement2d {
|
|
|
1093
1112
|
super(vector2(), vector3(), color);
|
|
1094
1113
|
this.geometry = new TraceLinesGeometry(maxLen);
|
|
1095
1114
|
}
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1115
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
1116
|
+
addPoint(vert, _color) {
|
|
1117
|
+
const newVert = vert.length < 3 ? vector3(vert[0] ?? 0, vert[1] ?? 0, 0) : vert;
|
|
1118
|
+
// const vert = vertex(point[0], point[1], point?.[2] || 0, color);
|
|
1119
|
+
this.geometry.addVertex(newVert);
|
|
1099
1120
|
this.vertexCache.updated();
|
|
1100
1121
|
}
|
|
1101
1122
|
// always being wireframe means that triangleOrder
|
|
@@ -1111,9 +1132,11 @@ export class TraceLines3d extends SimulationElement3d {
|
|
|
1111
1132
|
super(vector3(), vector3(), color);
|
|
1112
1133
|
this.geometry = new TraceLinesGeometry(maxLen);
|
|
1113
1134
|
}
|
|
1114
|
-
|
|
1115
|
-
|
|
1116
|
-
|
|
1135
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
1136
|
+
addPoint(vert, _color) {
|
|
1137
|
+
// const vert = vertex(point[0], point[1], point?.[2] || 0, color);
|
|
1138
|
+
const newVert = vert.length < 3 ? vector3(vert[0] ?? 0, vert[1] ?? 0, 0) : vert;
|
|
1139
|
+
this.geometry.addVertex(newVert);
|
|
1117
1140
|
this.vertexCache.updated();
|
|
1118
1141
|
}
|
|
1119
1142
|
// always being wireframe means that triangleOrder
|