simulationjsv2 0.7.4 → 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 +5 -5
- package/dist/buffers.d.ts +2 -0
- package/dist/buffers.js +9 -1
- 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 +40 -26
- package/dist/graphics.js +217 -199
- package/dist/index.d.ts +2 -0
- package/dist/index.js +2 -0
- package/dist/internalUtils.d.ts +8 -45
- package/dist/internalUtils.js +58 -198
- package/dist/materials.d.ts +17 -0
- package/dist/materials.js +49 -1
- package/dist/shaders.d.ts +31 -5
- package/dist/shaders.js +270 -29
- package/dist/simulation.d.ts +5 -24
- package/dist/simulation.js +49 -231
- package/dist/types.d.ts +48 -43
- package/dist/utils.d.ts +8 -3
- package/dist/utils.js +36 -8
- package/package.json +1 -1
- package/dist/pipelines.d.ts +0 -1
- package/dist/pipelines.js +0 -1
package/dist/graphics.js
CHANGED
|
@@ -1,17 +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
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';
|
|
7
10
|
export class SimulationElement3d {
|
|
8
11
|
children;
|
|
9
12
|
uniformBuffer;
|
|
13
|
+
prevInfo;
|
|
14
|
+
pipeline;
|
|
15
|
+
shader;
|
|
16
|
+
material;
|
|
17
|
+
cullMode;
|
|
10
18
|
parent;
|
|
11
19
|
centerOffset;
|
|
12
|
-
rotationOffset;
|
|
13
20
|
pos;
|
|
14
|
-
color;
|
|
15
21
|
wireframe;
|
|
16
22
|
vertexCache;
|
|
17
23
|
rotation;
|
|
@@ -24,19 +30,20 @@ export class SimulationElement3d {
|
|
|
24
30
|
* @param pos - Expected to be adjusted to devicePixelRatio before reaching constructor
|
|
25
31
|
*/
|
|
26
32
|
constructor(pos, rotation, color = new Color()) {
|
|
27
|
-
const uniformBufferSize = mat4ByteLength * 2 + 4 * 2 + 8; // 4x4 matrix * 2 + vec2<f32> + 8 bc 144 is cool
|
|
28
33
|
this.pos = pos;
|
|
29
34
|
this.centerOffset = vector3();
|
|
30
|
-
|
|
31
|
-
this.rotationOffset = vector3();
|
|
32
|
-
this.color = color;
|
|
33
|
-
this.vertexCache = new VertexCache();
|
|
35
|
+
this.vertexCache = new Float32ArrayCache();
|
|
34
36
|
this.wireframe = false;
|
|
35
37
|
this.rotation = cloneBuf(rotation);
|
|
36
38
|
this.uniformBuffer = new MemoBuffer(GPUBufferUsage.UNIFORM | GPUBufferUsage.COPY_DST, uniformBufferSize);
|
|
37
39
|
this.children = [];
|
|
38
40
|
this.modelMatrix = matrix4();
|
|
39
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';
|
|
40
47
|
}
|
|
41
48
|
add(el, id) {
|
|
42
49
|
el.setParent(this);
|
|
@@ -65,11 +72,20 @@ export class SimulationElement3d {
|
|
|
65
72
|
getParent() {
|
|
66
73
|
return this.parent;
|
|
67
74
|
}
|
|
75
|
+
getCullMode() {
|
|
76
|
+
return this.cullMode;
|
|
77
|
+
}
|
|
78
|
+
setCullMode(mode) {
|
|
79
|
+
this.cullMode = mode;
|
|
80
|
+
}
|
|
68
81
|
setCenterOffset(offset) {
|
|
69
82
|
this.centerOffset = offset;
|
|
70
83
|
}
|
|
71
|
-
|
|
72
|
-
this.
|
|
84
|
+
getShader() {
|
|
85
|
+
return this.shader;
|
|
86
|
+
}
|
|
87
|
+
setShader(shader) {
|
|
88
|
+
this.shader = shader;
|
|
73
89
|
}
|
|
74
90
|
resetCenterOffset() {
|
|
75
91
|
this.centerOffset[0] = 0;
|
|
@@ -81,14 +97,31 @@ export class SimulationElement3d {
|
|
|
81
97
|
return this.modelMatrix;
|
|
82
98
|
}
|
|
83
99
|
isTransparent() {
|
|
84
|
-
return this.
|
|
100
|
+
return this.material.isTransparent();
|
|
85
101
|
}
|
|
86
|
-
|
|
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();
|
|
87
111
|
const device = globalInfo.errorGetDevice();
|
|
88
112
|
const buffer = this.uniformBuffer.getBuffer();
|
|
89
113
|
device.queue.writeBuffer(buffer, modelProjMatOffset, mat);
|
|
90
114
|
return buffer;
|
|
91
115
|
}
|
|
116
|
+
getPipeline() {
|
|
117
|
+
const device = globalInfo.errorGetDevice();
|
|
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;
|
|
122
|
+
}
|
|
123
|
+
return this.pipeline;
|
|
124
|
+
}
|
|
92
125
|
mirrorParentTransforms3d(mat) {
|
|
93
126
|
if (!this.parent)
|
|
94
127
|
return;
|
|
@@ -105,12 +138,9 @@ export class SimulationElement3d {
|
|
|
105
138
|
this.mirrorParentTransforms3d(this.modelMatrix);
|
|
106
139
|
}
|
|
107
140
|
mat4.translate(this.modelMatrix, this.pos, this.modelMatrix);
|
|
108
|
-
// vec3.negate(this.rotationOffset, cachedVec1);
|
|
109
|
-
// mat4.translate(this.modelMatrix, cachedVec1, this.modelMatrix);
|
|
110
141
|
mat4.rotateZ(this.modelMatrix, this.rotation[2], this.modelMatrix);
|
|
111
142
|
mat4.rotateY(this.modelMatrix, this.rotation[1], this.modelMatrix);
|
|
112
143
|
mat4.rotateX(this.modelMatrix, this.rotation[0], this.modelMatrix);
|
|
113
|
-
// mat4.translate(this.modelMatrix, this.rotationOffset, this.modelMatrix);
|
|
114
144
|
mat4.translate(this.modelMatrix, this.centerOffset, this.modelMatrix);
|
|
115
145
|
}
|
|
116
146
|
mirrorParentTransforms2d(mat) {
|
|
@@ -134,11 +164,13 @@ export class SimulationElement3d {
|
|
|
134
164
|
else {
|
|
135
165
|
mat4.translate(this.modelMatrix, pos, this.modelMatrix);
|
|
136
166
|
}
|
|
167
|
+
const negated = vec3.negate(this.centerOffset);
|
|
168
|
+
mat4.translate(this.modelMatrix, negated, this.modelMatrix);
|
|
137
169
|
mat4.rotateZ(this.modelMatrix, this.rotation[2], this.modelMatrix);
|
|
138
170
|
mat4.translate(this.modelMatrix, this.centerOffset, this.modelMatrix);
|
|
139
171
|
}
|
|
140
|
-
|
|
141
|
-
return this.geometry.
|
|
172
|
+
getGeometryTopology() {
|
|
173
|
+
return this.geometry.getTopology();
|
|
142
174
|
}
|
|
143
175
|
setWireframe(wireframe) {
|
|
144
176
|
this.wireframe = wireframe;
|
|
@@ -146,8 +178,8 @@ export class SimulationElement3d {
|
|
|
146
178
|
isWireframe() {
|
|
147
179
|
return this.wireframe;
|
|
148
180
|
}
|
|
149
|
-
|
|
150
|
-
return this.
|
|
181
|
+
getMaterial() {
|
|
182
|
+
return this.material;
|
|
151
183
|
}
|
|
152
184
|
getRelativePos() {
|
|
153
185
|
return this.pos;
|
|
@@ -165,16 +197,17 @@ export class SimulationElement3d {
|
|
|
165
197
|
return this.centerOffset;
|
|
166
198
|
}
|
|
167
199
|
fill(newColor, t = 0, f) {
|
|
168
|
-
const
|
|
200
|
+
const materialColor = this.material.getColor();
|
|
201
|
+
const diff = newColor.diff(materialColor);
|
|
169
202
|
const finalColor = newColor.clone();
|
|
170
203
|
return internalTransitionValues((p) => {
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
204
|
+
materialColor.r += diff.r * p;
|
|
205
|
+
materialColor.g += diff.g * p;
|
|
206
|
+
materialColor.b += diff.b * p;
|
|
207
|
+
materialColor.a += diff.a * p;
|
|
175
208
|
this.vertexCache.updated();
|
|
176
209
|
}, () => {
|
|
177
|
-
this.
|
|
210
|
+
this.material.setColor(finalColor);
|
|
178
211
|
this.vertexCache.updated();
|
|
179
212
|
}, t, f);
|
|
180
213
|
}
|
|
@@ -252,38 +285,41 @@ export class SimulationElement3d {
|
|
|
252
285
|
if (this.vertexCache.shouldUpdate()) {
|
|
253
286
|
this.geometry.recompute();
|
|
254
287
|
}
|
|
255
|
-
let
|
|
288
|
+
let vertexCount = this.geometry.getIndexes(this.isWireframe()).length;
|
|
256
289
|
for (let i = 0; i < this.children.length; i++) {
|
|
257
|
-
|
|
258
|
-
}
|
|
259
|
-
let currentVertices = 0;
|
|
260
|
-
if (this.isWireframe()) {
|
|
261
|
-
currentVertices = this.geometry.getWireframeVertexCount();
|
|
290
|
+
vertexCount += this.children[i].getObj().getVertexCount();
|
|
262
291
|
}
|
|
263
|
-
|
|
264
|
-
|
|
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();
|
|
265
298
|
}
|
|
266
|
-
return
|
|
299
|
+
return indexCount;
|
|
267
300
|
}
|
|
268
|
-
|
|
301
|
+
writeBuffers() {
|
|
302
|
+
this.shader.writeBuffers(this);
|
|
303
|
+
}
|
|
304
|
+
getVertexBuffer() {
|
|
269
305
|
if (this.vertexCache.shouldUpdate()) {
|
|
270
306
|
this.geometry.recompute();
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
}
|
|
278
|
-
else {
|
|
279
|
-
resBuffer = this.geometry.getTriangleBuffer(this.color, vertexParamGenerator);
|
|
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);
|
|
280
313
|
}
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
return resBuffer;
|
|
314
|
+
this.vertexCache.setCache(vertexBuffer);
|
|
315
|
+
return vertexBuffer;
|
|
284
316
|
}
|
|
285
317
|
return this.vertexCache.getCache();
|
|
286
318
|
}
|
|
319
|
+
getIndexBuffer() {
|
|
320
|
+
const order = this.geometry.getIndexes(this.isWireframe());
|
|
321
|
+
return new Uint32Array(order);
|
|
322
|
+
}
|
|
287
323
|
}
|
|
288
324
|
export class EmptyElement extends SimulationElement3d {
|
|
289
325
|
geometry = new BlankGeometry();
|
|
@@ -291,7 +327,7 @@ export class EmptyElement extends SimulationElement3d {
|
|
|
291
327
|
isEmpty = true;
|
|
292
328
|
constructor(label) {
|
|
293
329
|
super(vector3(), vector3());
|
|
294
|
-
this.label = label
|
|
330
|
+
this.label = label ?? null;
|
|
295
331
|
}
|
|
296
332
|
getLabel() {
|
|
297
333
|
return this.label;
|
|
@@ -322,6 +358,7 @@ export class Plane extends SimulationElement3d {
|
|
|
322
358
|
this.rotation = rotation;
|
|
323
359
|
this.points = points;
|
|
324
360
|
this.geometry = new PlaneGeometry(points);
|
|
361
|
+
this.cullMode = 'none';
|
|
325
362
|
}
|
|
326
363
|
setPoints(newPoints) {
|
|
327
364
|
this.points = newPoints;
|
|
@@ -332,70 +369,21 @@ export class Square extends SimulationElement2d {
|
|
|
332
369
|
geometry;
|
|
333
370
|
width;
|
|
334
371
|
height;
|
|
335
|
-
vertexColors;
|
|
336
372
|
/**
|
|
337
373
|
* @param centerOffset{Vector2} - A vector2 of values from 0 to 1
|
|
338
374
|
* @param vertexColors{Record<number, Color>} - 0 is top left vertex, numbers increase clockwise
|
|
339
375
|
*/
|
|
340
|
-
constructor(pos, width, height, color, rotation
|
|
376
|
+
constructor(pos, width, height, color, rotation) {
|
|
341
377
|
super(pos, vector3(0, 0, rotation), color);
|
|
342
|
-
this.width = width
|
|
343
|
-
this.height = height
|
|
344
|
-
this.
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
setOffsetInplace(offset) {
|
|
352
|
-
const diff = vector3FromVector2(offset);
|
|
353
|
-
vec2.sub(diff, this.geometry.getOffset(), diff);
|
|
354
|
-
vec2.mul(diff, vector2(this.width / devicePixelRatio, -this.height / devicePixelRatio), diff);
|
|
355
|
-
this.setOffset(offset);
|
|
356
|
-
this.move(diff);
|
|
357
|
-
}
|
|
358
|
-
cloneColorMap(colorMap) {
|
|
359
|
-
const newColorMap = {};
|
|
360
|
-
Object.entries(colorMap).forEach(([key, value]) => {
|
|
361
|
-
newColorMap[+key] = value.clone();
|
|
362
|
-
});
|
|
363
|
-
return newColorMap;
|
|
364
|
-
}
|
|
365
|
-
setVertexColors(newColorMap, t = 0, f) {
|
|
366
|
-
const colorMap = this.cloneColorMap(newColorMap);
|
|
367
|
-
const diffMap = {};
|
|
368
|
-
Object.entries(colorMap).forEach(([key, value]) => {
|
|
369
|
-
if (!this.vertexColors[+key]) {
|
|
370
|
-
this.vertexColors[+key] = color();
|
|
371
|
-
}
|
|
372
|
-
diffMap[+key] = value.diff(this.vertexColors[+key] || color());
|
|
373
|
-
});
|
|
374
|
-
Object.entries(this.vertexColors).forEach(([key, value]) => {
|
|
375
|
-
if (!diffMap[+key]) {
|
|
376
|
-
const clone = value.clone();
|
|
377
|
-
clone.r *= -1;
|
|
378
|
-
clone.g *= -1;
|
|
379
|
-
clone.b *= -1;
|
|
380
|
-
diffMap[+key] = clone;
|
|
381
|
-
}
|
|
382
|
-
});
|
|
383
|
-
return internalTransitionValues((p) => {
|
|
384
|
-
Object.entries(diffMap).forEach(([key, value]) => {
|
|
385
|
-
const color = this.vertexColors[+key];
|
|
386
|
-
color.r += value.r * p;
|
|
387
|
-
color.g += value.g * p;
|
|
388
|
-
color.b += value.b * p;
|
|
389
|
-
color.a += value.a * p;
|
|
390
|
-
this.vertexColors[+key] = color;
|
|
391
|
-
});
|
|
392
|
-
this.geometry.setVertexColorMap(this.vertexColors);
|
|
393
|
-
this.vertexCache.updated();
|
|
394
|
-
}, () => {
|
|
395
|
-
this.vertexColors = colorMap;
|
|
396
|
-
this.geometry.setVertexColorMap(this.vertexColors);
|
|
397
|
-
this.vertexCache.updated();
|
|
398
|
-
}, 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;
|
|
399
387
|
}
|
|
400
388
|
scaleWidth(amount, t = 0, f) {
|
|
401
389
|
const finalWidth = this.width * amount;
|
|
@@ -508,78 +496,78 @@ export class Circle extends SimulationElement2d {
|
|
|
508
496
|
}
|
|
509
497
|
export class Polygon extends SimulationElement2d {
|
|
510
498
|
geometry;
|
|
511
|
-
vertices
|
|
512
|
-
constructor(pos, points, color, rotation) {
|
|
499
|
+
constructor(pos, vertices, color, rotation) {
|
|
513
500
|
super(pos, vector3(0, 0, rotation), color);
|
|
514
|
-
|
|
515
|
-
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);
|
|
516
509
|
}
|
|
517
510
|
getVertices() {
|
|
518
|
-
return this.
|
|
519
|
-
}
|
|
520
|
-
setVertices(
|
|
521
|
-
const
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
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;
|
|
525
530
|
});
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
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]));
|
|
532
540
|
}
|
|
533
|
-
const initialPositions = this.vertices.map((p) => cloneBuf(p.getPos()));
|
|
534
|
-
const posChanges = [
|
|
535
|
-
...vertices.map((vert, i) => {
|
|
536
|
-
const vec = vector3();
|
|
537
|
-
vec3.sub(vert.getPos(), this.vertices[i].getPos(), vec);
|
|
538
|
-
return cloneBuf(vec);
|
|
539
|
-
}),
|
|
540
|
-
...(this.vertices.length > vertices.length
|
|
541
|
-
? this.vertices.slice(vertices.length, this.vertices.length).map((vert) => {
|
|
542
|
-
const vec = cloneBuf(vertices[vertices.length - 1].getPos());
|
|
543
|
-
vec3.sub(vec, vert.getPos(), vec);
|
|
544
|
-
return vec;
|
|
545
|
-
})
|
|
546
|
-
: [])
|
|
547
|
-
];
|
|
548
|
-
const initialColors = this.vertices.map((vert) => (vert.getColor() || this.color).toVec4());
|
|
549
|
-
const colorChanges = [
|
|
550
|
-
...vertices.map((vert, i) => {
|
|
551
|
-
const diff = (vert.getColor() || this.color).diff(this.vertices[i].getColor() || this.color);
|
|
552
|
-
return diff.toVec4();
|
|
553
|
-
}),
|
|
554
|
-
...(this.vertices.length > vertices.length
|
|
555
|
-
? this.vertices.slice(vertices.length, this.vertices.length).map((vert) => {
|
|
556
|
-
const toColor = vertices[vertices.length - 1].getColor();
|
|
557
|
-
return (toColor || this.color).diff(vert.getColor() || this.color).toVec4();
|
|
558
|
-
})
|
|
559
|
-
: [])
|
|
560
|
-
];
|
|
561
541
|
return internalTransitionValues((p) => {
|
|
562
|
-
|
|
542
|
+
for (let i = 0; i < oldVertices.length; i++) {
|
|
543
|
+
const vert = oldVertices[i];
|
|
544
|
+
const currentColor = oldColors[i];
|
|
563
545
|
const posChange = cloneBuf(posChanges[i]);
|
|
564
|
-
const colorChange =
|
|
546
|
+
const colorChange = colorChanges[i].clone();
|
|
565
547
|
vec3.scale(posChange, p, posChange);
|
|
566
|
-
vec3.add(vert
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
}
|
|
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
|
+
}
|
|
572
554
|
this.vertexCache.updated();
|
|
573
555
|
}, () => {
|
|
574
|
-
|
|
556
|
+
for (let i = 0; i < oldVertices.length; i++) {
|
|
557
|
+
const vert = oldVertices[i];
|
|
558
|
+
const currentColor = oldColors[i];
|
|
575
559
|
const initPos = initialPositions[i];
|
|
576
560
|
const initColor = initialColors[i];
|
|
577
561
|
vec3.add(initPos, posChanges[i], initPos);
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
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);
|
|
583
571
|
this.vertexCache.updated();
|
|
584
572
|
}, t, f);
|
|
585
573
|
}
|
|
@@ -589,12 +577,12 @@ export class Line3d extends SimulationElement3d {
|
|
|
589
577
|
to;
|
|
590
578
|
thickness;
|
|
591
579
|
constructor(pos, to, thickness) {
|
|
592
|
-
super(pos.getPos(), vector3(), to.getColor()
|
|
580
|
+
super(pos.getPos(), vector3(), to.getColor() ?? undefined);
|
|
593
581
|
this.thickness = thickness;
|
|
594
582
|
this.to = to.getPos();
|
|
595
583
|
vec3.scale(this.to, devicePixelRatio, this.to);
|
|
596
584
|
vec3.sub(this.to, this.pos, this.to);
|
|
597
|
-
this.geometry = new Line3dGeometry(this.pos, this.to, this.thickness
|
|
585
|
+
this.geometry = new Line3dGeometry(this.pos, this.to, this.thickness);
|
|
598
586
|
}
|
|
599
587
|
setStart(pos, t = 0, f) {
|
|
600
588
|
return this.moveTo(pos, t, f);
|
|
@@ -620,11 +608,11 @@ export class Line2d extends SimulationElement2d {
|
|
|
620
608
|
to;
|
|
621
609
|
thickness;
|
|
622
610
|
constructor(from, to, thickness = 1) {
|
|
623
|
-
super(vector2FromVector3(from.getPos()), vector3(), from.getColor()
|
|
611
|
+
super(vector2FromVector3(from.getPos()), vector3(), from.getColor() ?? undefined);
|
|
624
612
|
this.thickness = thickness * devicePixelRatio;
|
|
625
613
|
this.to = to.getPos();
|
|
626
614
|
vec2.sub(this.to, this.pos, this.to);
|
|
627
|
-
this.geometry = new Line2dGeometry(this.pos, this.to, this.thickness
|
|
615
|
+
this.geometry = new Line2dGeometry(this.pos, this.to, this.thickness);
|
|
628
616
|
}
|
|
629
617
|
setStart(pos, t = 0, f) {
|
|
630
618
|
return this.moveTo(pos, t, f);
|
|
@@ -791,7 +779,7 @@ export class CubicBezierCurve2d extends BezierCurve2d {
|
|
|
791
779
|
constructor(points, detail, colors) {
|
|
792
780
|
super(points);
|
|
793
781
|
this.detail = detail;
|
|
794
|
-
this.colors = colors
|
|
782
|
+
this.colors = colors ?? [];
|
|
795
783
|
}
|
|
796
784
|
getDetail() {
|
|
797
785
|
return this.detail;
|
|
@@ -835,7 +823,7 @@ export class SplinePoint2d {
|
|
|
835
823
|
if (prevColor) {
|
|
836
824
|
colors[0] = prevColor;
|
|
837
825
|
}
|
|
838
|
-
else if (this.start
|
|
826
|
+
else if (this.start?.getColor()) {
|
|
839
827
|
colors[0] = this.start.getColor();
|
|
840
828
|
}
|
|
841
829
|
if (this.end.getColor()) {
|
|
@@ -847,7 +835,7 @@ export class SplinePoint2d {
|
|
|
847
835
|
return colors;
|
|
848
836
|
}
|
|
849
837
|
getVectorArray(prevEnd, prevControl) {
|
|
850
|
-
const firstControl = cloneBuf(this.control1
|
|
838
|
+
const firstControl = cloneBuf(this.control1 ?? prevControl ?? vector2());
|
|
851
839
|
if (prevEnd) {
|
|
852
840
|
vec2.add(firstControl, prevEnd, firstControl);
|
|
853
841
|
}
|
|
@@ -874,21 +862,50 @@ export class Spline2d extends SimulationElement2d {
|
|
|
874
862
|
length;
|
|
875
863
|
constructor(pos, points, thickness = devicePixelRatio, detail = 40) {
|
|
876
864
|
const tempPos = vector2FromVector3(pos.getPos());
|
|
877
|
-
super(tempPos, vector3(), pos.getColor()
|
|
865
|
+
super(tempPos, vector3(), pos.getColor() ?? undefined);
|
|
878
866
|
this.thickness = thickness * devicePixelRatio;
|
|
879
867
|
this.detail = detail;
|
|
880
868
|
this.interpolateStart = 0;
|
|
881
869
|
this.interpolateLimit = 1;
|
|
882
870
|
this.length = 0;
|
|
883
|
-
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;
|
|
884
876
|
this.estimateLength();
|
|
885
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
|
+
}
|
|
886
903
|
isTransparent() {
|
|
887
904
|
const curves = this.geometry.getCurves();
|
|
888
905
|
for (let i = 0; i < curves.length; i++) {
|
|
889
906
|
const colors = curves[i].getColors();
|
|
890
907
|
for (let j = 0; j < colors.length; j++) {
|
|
891
|
-
if (colors[j]?.
|
|
908
|
+
if (colors[j]?.isTransparent())
|
|
892
909
|
return true;
|
|
893
910
|
}
|
|
894
911
|
}
|
|
@@ -935,7 +952,7 @@ export class Spline2d extends SimulationElement2d {
|
|
|
935
952
|
}
|
|
936
953
|
updatePointAbsolute(pointIndex, newPoint) {
|
|
937
954
|
const clonePoint = newPoint.clone();
|
|
938
|
-
const start = clonePoint.getStart()?.getPos()
|
|
955
|
+
const start = clonePoint.getStart()?.getPos() ?? vector3();
|
|
939
956
|
const end = clonePoint.getEnd().getPos();
|
|
940
957
|
const pos = this.getRelativePos();
|
|
941
958
|
vec3.sub(start, pos, start);
|
|
@@ -1045,15 +1062,6 @@ export class Instance extends SimulationElement3d {
|
|
|
1045
1062
|
device.queue.writeBuffer(gpuBuffer, instance * mat4ByteLength, buf.buffer, buf.byteOffset, buf.byteLength);
|
|
1046
1063
|
gpuBuffer.unmap();
|
|
1047
1064
|
}
|
|
1048
|
-
// private allocBuffer(size: number) {
|
|
1049
|
-
// const device = globalInfo.getDevice();
|
|
1050
|
-
// if (!device) return;
|
|
1051
|
-
// const byteSize = size * mat4ByteLength;
|
|
1052
|
-
// this.matrixBuffer = device.createBuffer({
|
|
1053
|
-
// size: byteSize,
|
|
1054
|
-
// usage:
|
|
1055
|
-
// });
|
|
1056
|
-
// }
|
|
1057
1065
|
mapBuffer() {
|
|
1058
1066
|
const device = globalInfo.getDevice();
|
|
1059
1067
|
if (!device)
|
|
@@ -1073,7 +1081,7 @@ export class Instance extends SimulationElement3d {
|
|
|
1073
1081
|
getNumInstances() {
|
|
1074
1082
|
return this.instanceMatrix.length;
|
|
1075
1083
|
}
|
|
1076
|
-
|
|
1084
|
+
getInstanceBuffer() {
|
|
1077
1085
|
if (!this.hasMapped) {
|
|
1078
1086
|
this.mapBuffer();
|
|
1079
1087
|
}
|
|
@@ -1082,11 +1090,17 @@ export class Instance extends SimulationElement3d {
|
|
|
1082
1090
|
getVertexCount() {
|
|
1083
1091
|
return this.obj.getVertexCount();
|
|
1084
1092
|
}
|
|
1085
|
-
|
|
1086
|
-
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();
|
|
1087
1101
|
}
|
|
1088
|
-
|
|
1089
|
-
return this.obj.
|
|
1102
|
+
getIndexBuffer() {
|
|
1103
|
+
return this.obj.getIndexBuffer();
|
|
1090
1104
|
}
|
|
1091
1105
|
getModelMatrix() {
|
|
1092
1106
|
return this.obj.getModelMatrix();
|
|
@@ -1098,9 +1112,11 @@ export class TraceLines2d extends SimulationElement2d {
|
|
|
1098
1112
|
super(vector2(), vector3(), color);
|
|
1099
1113
|
this.geometry = new TraceLinesGeometry(maxLen);
|
|
1100
1114
|
}
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
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);
|
|
1104
1120
|
this.vertexCache.updated();
|
|
1105
1121
|
}
|
|
1106
1122
|
// always being wireframe means that triangleOrder
|
|
@@ -1116,9 +1132,11 @@ export class TraceLines3d extends SimulationElement3d {
|
|
|
1116
1132
|
super(vector3(), vector3(), color);
|
|
1117
1133
|
this.geometry = new TraceLinesGeometry(maxLen);
|
|
1118
1134
|
}
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
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);
|
|
1122
1140
|
this.vertexCache.updated();
|
|
1123
1141
|
}
|
|
1124
1142
|
// always being wireframe means that triangleOrder
|
package/dist/index.d.ts
CHANGED