simulationjsv2 0.2.4 → 0.2.6

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.
@@ -1 +1,4 @@
1
1
  export declare const BUF_LEN = 10;
2
+ export declare const vertexSize = 40;
3
+ export declare const colorOffset = 16;
4
+ export declare const uvOffset = 32;
package/dist/constants.js CHANGED
@@ -1 +1,4 @@
1
1
  export const BUF_LEN = 10;
2
+ export const vertexSize = 40; // 4 * 10
3
+ export const colorOffset = 16; // 4 * 4
4
+ export const uvOffset = 32; // 4 * 8
@@ -0,0 +1,103 @@
1
+ import { CircleGeometryParams, CubeGeometryParams, Line2dGeometryParams, Line3dGeometryParams, Mat4, PolygonGeometryParams, SplineGeometryParams, SquareGeometryParams, Vector2, Vector3, VertexColorMap } from './types.js';
2
+ import { Color, Vertex } from './utils.js';
3
+ import { SplinePoint2d } from './graphics.js';
4
+ export declare abstract class Geometry {
5
+ protected abstract wireframeOrder: number[];
6
+ protected abstract triangleOrder: number[];
7
+ protected abstract params: Record<string, any>;
8
+ protected vertices: Vector3[];
9
+ protected matrix: Mat4;
10
+ protected geometryType: 'list' | 'strip';
11
+ constructor(vertices?: Vector3[], geometryType?: 'list' | 'strip');
12
+ updateMatrix(matrix: Mat4): void;
13
+ getType(): "list" | "strip";
14
+ abstract recompute(): void;
15
+ protected bufferFromOrder(order: number[], color: Color): number[];
16
+ getWireframeBuffer(color: Color): number[];
17
+ getTriangleBuffer(color: Color): number[];
18
+ }
19
+ export declare class PlaneGeometry extends Geometry {
20
+ protected params: {};
21
+ protected wireframeOrder: number[];
22
+ protected triangleOrder: number[];
23
+ private rawVertices;
24
+ constructor(vertices: Vertex[]);
25
+ private updateWireframeOrder;
26
+ recompute(): void;
27
+ updateVertices(vertices: Vertex[]): void;
28
+ getTriangleBuffer(color: Color): number[];
29
+ }
30
+ export declare class CubeGeometry extends Geometry {
31
+ protected params: CubeGeometryParams;
32
+ protected wireframeOrder: number[];
33
+ protected triangleOrder: number[];
34
+ constructor(width: number, height: number, depth: number);
35
+ setWidth(width: number): void;
36
+ setHeight(height: number): void;
37
+ setDepth(depth: number): void;
38
+ recompute(): void;
39
+ updateSize(width: number, height: number, depth: number): void;
40
+ }
41
+ export declare class SquareGeometry extends Geometry {
42
+ protected wireframeOrder: number[];
43
+ protected triangleOrder: number[];
44
+ protected params: SquareGeometryParams;
45
+ constructor(width: number, height: number);
46
+ setVertexColorMap(colorMap: VertexColorMap): void;
47
+ setWidth(width: number): void;
48
+ setHeight(height: number): void;
49
+ recompute(): void;
50
+ getTriangleBuffer(color: Color): number[];
51
+ }
52
+ export declare class BlankGeometry extends Geometry {
53
+ protected wireframeOrder: never[];
54
+ protected triangleOrder: never[];
55
+ protected params: {};
56
+ constructor();
57
+ recompute(): void;
58
+ }
59
+ export declare class CircleGeometry extends Geometry {
60
+ protected wireframeOrder: number[];
61
+ protected triangleOrder: number[];
62
+ protected params: CircleGeometryParams;
63
+ constructor(radius: number, detail: number);
64
+ setRadius(radius: number): void;
65
+ private updateWireframeOrder;
66
+ private updateTriangleOrder;
67
+ recompute(): void;
68
+ }
69
+ export declare class SplineGeometry extends Geometry {
70
+ protected wireframeOrder: number[];
71
+ protected triangleOrder: number[];
72
+ protected params: SplineGeometryParams;
73
+ constructor(points: SplinePoint2d[], color: Color, thickness: number, detail: number);
74
+ updateInterpolationStart(start: number): void;
75
+ updateInterpolationLimit(limit: number): void;
76
+ private computeCurves;
77
+ private updateWireframeOrder;
78
+ recompute(): void;
79
+ getWireframeBuffer(color: Color): number[];
80
+ getTriangleBuffer(_: Color): number[];
81
+ }
82
+ export declare class Line2dGeometry extends Geometry {
83
+ protected wireframeOrder: number[];
84
+ protected triangleOrder: number[];
85
+ protected params: Line2dGeometryParams;
86
+ constructor(pos: Vector2, to: Vector2, thickness: number);
87
+ recompute(): void;
88
+ }
89
+ export declare class Line3dGeometry extends Geometry {
90
+ protected wireframeOrder: number[];
91
+ protected triangleOrder: number[];
92
+ protected params: Line3dGeometryParams;
93
+ constructor(pos: Vector3, to: Vector3, thickness: number);
94
+ recompute(): void;
95
+ }
96
+ export declare class PolygonGeometry extends Geometry {
97
+ protected wireframeOrder: number[];
98
+ protected triangleOrder: number[];
99
+ protected params: PolygonGeometryParams;
100
+ constructor(points: Vertex[]);
101
+ recompute(): void;
102
+ getTriangleBuffer(color: Color): number[];
103
+ }
@@ -0,0 +1,407 @@
1
+ import { mat4, vec2, vec3 } from 'wgpu-matrix';
2
+ import { cloneBuf, interpolateColors, lossyTriangulate, matrix4, triangulateWireFrameOrder, vector2, vector2FromVector3, vector3, vector3FromVector2, vertex, vertexBuffer } from './utils.js';
3
+ import { CubicBezierCurve2d } from './graphics.js';
4
+ export class Geometry {
5
+ vertices;
6
+ matrix;
7
+ geometryType;
8
+ constructor(vertices = [], geometryType = 'list') {
9
+ this.vertices = vertices;
10
+ this.matrix = matrix4();
11
+ this.geometryType = geometryType;
12
+ }
13
+ updateMatrix(matrix) {
14
+ this.matrix = matrix;
15
+ }
16
+ getType() {
17
+ return this.geometryType;
18
+ }
19
+ bufferFromOrder(order, color) {
20
+ return order
21
+ .map((vertexIndex) => {
22
+ const pos = cloneBuf(this.vertices[vertexIndex]);
23
+ vec3.transformMat4(pos, this.matrix, pos);
24
+ return vertexBuffer(pos[0], pos[1], pos[2], color);
25
+ })
26
+ .flat();
27
+ }
28
+ getWireframeBuffer(color) {
29
+ return this.bufferFromOrder(this.wireframeOrder, color);
30
+ }
31
+ getTriangleBuffer(color) {
32
+ return this.bufferFromOrder(this.triangleOrder, color);
33
+ }
34
+ }
35
+ export class PlaneGeometry extends Geometry {
36
+ params = {};
37
+ wireframeOrder;
38
+ triangleOrder;
39
+ rawVertices;
40
+ constructor(vertices) {
41
+ super();
42
+ this.wireframeOrder = [];
43
+ this.triangleOrder = [];
44
+ this.rawVertices = vertices;
45
+ this.updateVertices(vertices);
46
+ }
47
+ updateWireframeOrder() {
48
+ this.wireframeOrder = triangulateWireFrameOrder(this.vertices.length);
49
+ }
50
+ recompute() { }
51
+ updateVertices(vertices) {
52
+ this.rawVertices = vertices;
53
+ this.vertices = vertices.map((vertex) => vertex.getPos());
54
+ this.updateWireframeOrder();
55
+ }
56
+ getTriangleBuffer(color) {
57
+ return lossyTriangulate(this.rawVertices)
58
+ .flat()
59
+ .map((vertex) => {
60
+ const pos = cloneBuf(vertex.getPos());
61
+ vec3.transformMat4(pos, this.matrix, pos);
62
+ return vertexBuffer(pos[0], pos[1], pos[2], vertex.getColor() || color);
63
+ })
64
+ .flat();
65
+ }
66
+ }
67
+ export class CubeGeometry extends Geometry {
68
+ params;
69
+ wireframeOrder = [0, 1, 2, 3, 0, 2, 6, 5, 1, 6, 7, 4, 5, 7, 3, 4, 0, 5, 6, 3];
70
+ // prettier-ignore
71
+ triangleOrder = [
72
+ 0, 1, 2, 0, 2, 3,
73
+ 4, 5, 6, 4, 6, 7,
74
+ 0, 3, 7, 0, 7, 4,
75
+ 0, 4, 5, 0, 5, 1,
76
+ 1, 2, 6, 1, 5, 6,
77
+ 2, 3, 7, 2, 6, 7
78
+ ];
79
+ constructor(width, height, depth) {
80
+ super();
81
+ this.params = {
82
+ width,
83
+ height,
84
+ depth
85
+ };
86
+ this.recompute();
87
+ }
88
+ setWidth(width) {
89
+ this.params.width = width;
90
+ }
91
+ setHeight(height) {
92
+ this.params.height = height;
93
+ }
94
+ setDepth(depth) {
95
+ this.params.depth = depth;
96
+ }
97
+ recompute() {
98
+ const { width, height, depth } = this.params;
99
+ this.vertices = [
100
+ // front face
101
+ vector3(-width / 2, -height / 2, depth / 2),
102
+ vector3(width / 2, -height / 2, depth / 2),
103
+ vector3(width / 2, height / 2, depth / 2),
104
+ vector3(-width / 2, height / 2, depth / 2),
105
+ // back face
106
+ vector3(-width / 2, -height / 2, -depth / 2),
107
+ vector3(width / 2, -height / 2, -depth / 2),
108
+ vector3(width / 2, height / 2, -depth / 2),
109
+ vector3(-width / 2, height / 2, -depth / 2)
110
+ ];
111
+ }
112
+ updateSize(width, height, depth) {
113
+ this.params.width = width;
114
+ this.params.height = height;
115
+ this.params.depth = depth;
116
+ }
117
+ }
118
+ export class SquareGeometry extends Geometry {
119
+ wireframeOrder = [0, 1, 2, 3, 0, 2];
120
+ triangleOrder = [0, 1, 3, 2];
121
+ params;
122
+ constructor(width, height) {
123
+ super([], 'strip');
124
+ this.params = {
125
+ width,
126
+ height,
127
+ colorMap: {}
128
+ };
129
+ this.recompute();
130
+ }
131
+ setVertexColorMap(colorMap) {
132
+ this.params.colorMap = colorMap;
133
+ }
134
+ setWidth(width) {
135
+ this.params.width = width;
136
+ }
137
+ setHeight(height) {
138
+ this.params.height = height;
139
+ }
140
+ recompute() {
141
+ this.vertices = [
142
+ vector3(-this.params.width / 2, this.params.height / 2, 0),
143
+ vector3(this.params.width / 2, this.params.height / 2, 0),
144
+ vector3(this.params.width / 2, -this.params.height / 2, 0),
145
+ vector3(-this.params.width / 2, -this.params.height / 2, 0)
146
+ ];
147
+ }
148
+ getTriangleBuffer(color) {
149
+ return this.triangleOrder
150
+ .map((vertexIndex) => {
151
+ const pos = cloneBuf(this.vertices[vertexIndex]);
152
+ vec3.transformMat4(pos, this.matrix, pos);
153
+ return vertexBuffer(pos[0], pos[1], pos[2], this.params.colorMap[vertexIndex] || color);
154
+ })
155
+ .flat();
156
+ }
157
+ }
158
+ export class BlankGeometry extends Geometry {
159
+ wireframeOrder = [];
160
+ triangleOrder = [];
161
+ params = {};
162
+ constructor() {
163
+ super();
164
+ }
165
+ recompute() { }
166
+ }
167
+ export class CircleGeometry extends Geometry {
168
+ wireframeOrder;
169
+ triangleOrder;
170
+ params;
171
+ constructor(radius, detail) {
172
+ super([], 'strip');
173
+ this.wireframeOrder = [];
174
+ this.triangleOrder = [];
175
+ this.params = { radius, detail };
176
+ this.recompute();
177
+ }
178
+ setRadius(radius) {
179
+ this.params.radius = radius;
180
+ }
181
+ updateWireframeOrder() {
182
+ this.wireframeOrder = triangulateWireFrameOrder(this.vertices.length);
183
+ }
184
+ updateTriangleOrder() {
185
+ this.triangleOrder = lossyTriangulate(Array(this.vertices.length)
186
+ .fill(0)
187
+ .map((_, index) => index)).flat();
188
+ }
189
+ recompute() {
190
+ const vertices = [];
191
+ const rotationInc = (Math.PI * 2) / this.params.detail;
192
+ for (let i = 0; i < this.params.detail; i++) {
193
+ const mat = matrix4();
194
+ mat4.rotateZ(mat, rotationInc * i, mat);
195
+ const vec = vector3(this.params.radius);
196
+ vec3.transformMat4(vec, mat, vec);
197
+ vertices.push(vector3(vec[0], vec[1], vec[2]));
198
+ }
199
+ this.vertices = vertices;
200
+ this.updateTriangleOrder();
201
+ this.updateWireframeOrder();
202
+ }
203
+ }
204
+ export class SplineGeometry extends Geometry {
205
+ wireframeOrder;
206
+ triangleOrder;
207
+ params;
208
+ constructor(points, color, thickness, detail) {
209
+ super([], 'list');
210
+ this.wireframeOrder = [];
211
+ this.triangleOrder = [];
212
+ this.params = {
213
+ points: points,
214
+ curves: [],
215
+ distance: 0,
216
+ detail: detail,
217
+ interpolateStart: 0,
218
+ interpolateLimit: 1,
219
+ thickness: thickness,
220
+ color: color,
221
+ vertexColors: []
222
+ };
223
+ this.computeCurves();
224
+ this.recompute();
225
+ }
226
+ updateInterpolationStart(start) {
227
+ this.params.interpolateStart = Math.min(1, Math.max(0, start));
228
+ }
229
+ updateInterpolationLimit(limit) {
230
+ this.params.interpolateLimit = Math.min(1, Math.max(0, limit));
231
+ }
232
+ computeCurves() {
233
+ for (let i = 0; i < this.params.points.length; i++) {
234
+ let prevControl = null;
235
+ let prevColor = null;
236
+ if (i > 0) {
237
+ prevControl = cloneBuf(this.params.points[i - 1].getRawControls()[1]);
238
+ vec2.negate(prevControl, prevControl);
239
+ const prevColors = this.params.points[i - 1].getColors();
240
+ if (prevColors.at(-1)) {
241
+ prevColor = prevColors.at(-1) || null;
242
+ }
243
+ }
244
+ const bezierPoints = this.params.points[i].getVectorArray(i > 0 ? vector2FromVector3(this.params.points[i - 1].getEnd().getPos()) : null, prevControl);
245
+ const curve = new CubicBezierCurve2d(bezierPoints, this.params.points[i].getDetail(), this.params.points[i].getColors(prevColor));
246
+ this.params.distance += curve.getLength();
247
+ this.params.curves.push(curve);
248
+ }
249
+ }
250
+ updateWireframeOrder() {
251
+ this.wireframeOrder = triangulateWireFrameOrder(this.vertices.length);
252
+ }
253
+ recompute() {
254
+ this.params.vertexColors = [];
255
+ this.vertices = [];
256
+ let verticesTop = [];
257
+ const verticesBottom = [];
258
+ let currentDistance = 0;
259
+ let interpolationStarted = false;
260
+ outer: for (let i = 0; i < this.params.curves.length; i++) {
261
+ const detail = this.params.curves[i].getDetail() || this.params.detail;
262
+ const step = 1 / detail;
263
+ const distanceRatio = currentDistance / this.params.distance;
264
+ if (distanceRatio > this.params.interpolateLimit)
265
+ break;
266
+ const curveLength = this.params.curves[i].getLength();
267
+ currentDistance += curveLength;
268
+ const sectionRatio = curveLength / this.params.distance;
269
+ for (let j = 0; j < detail + 1; j++) {
270
+ let currentInterpolation = step * j;
271
+ let atLimit = false;
272
+ if (step * j * sectionRatio + distanceRatio > this.params.interpolateLimit) {
273
+ atLimit = true;
274
+ currentInterpolation = (this.params.interpolateLimit - distanceRatio) / sectionRatio;
275
+ }
276
+ if (currentInterpolation * sectionRatio + distanceRatio < this.params.interpolateStart) {
277
+ continue;
278
+ }
279
+ if (!interpolationStarted) {
280
+ interpolationStarted = true;
281
+ currentInterpolation = (this.params.interpolateStart - distanceRatio) / sectionRatio;
282
+ j--;
283
+ }
284
+ const [point2d, slope] = this.params.curves[i].interpolateSlope(currentInterpolation);
285
+ const point = vector3FromVector2(point2d);
286
+ const normal = vector2(-slope[1], slope[0]);
287
+ vec2.normalize(normal, normal);
288
+ vec2.scale(normal, this.params.thickness / 2, normal);
289
+ const colors = this.params.curves[i].getColors().map((c) => (c ? c : this.params.color));
290
+ const vertexColor = interpolateColors(colors, currentInterpolation);
291
+ this.params.vertexColors.push(vertexColor);
292
+ const vertTop = vertex(point[0] + normal[0], point[1] + normal[1], 0, vertexColor);
293
+ verticesTop.push(vertTop);
294
+ const vertBottom = vertex(point[0] - normal[0], point[1] - normal[1], 0, vertexColor);
295
+ verticesBottom.unshift(vertBottom);
296
+ if (atLimit) {
297
+ break outer;
298
+ }
299
+ }
300
+ }
301
+ verticesTop = verticesTop.concat(verticesBottom);
302
+ const tempColors = [...this.params.vertexColors];
303
+ tempColors.reverse();
304
+ this.params.vertexColors = this.params.vertexColors.concat(tempColors);
305
+ this.vertices = verticesTop.map((vertex) => vertex.getPos());
306
+ this.triangleOrder = lossyTriangulate(Array(verticesTop.length)
307
+ .fill(0)
308
+ .map((_, index) => index)).flat();
309
+ this.updateWireframeOrder();
310
+ }
311
+ getWireframeBuffer(color) {
312
+ return this.wireframeOrder
313
+ .map((vertexIndex) => {
314
+ const vertex = cloneBuf(this.vertices[vertexIndex]);
315
+ vec3.transformMat4(vertex, this.matrix, vertex);
316
+ return vertexBuffer(vertex[0], vertex[1], vertex[2], color);
317
+ })
318
+ .flat();
319
+ }
320
+ getTriangleBuffer(_) {
321
+ return this.triangleOrder
322
+ .map((vertexIndex) => {
323
+ const vertex = cloneBuf(this.vertices[vertexIndex]);
324
+ vec3.transformMat4(vertex, this.matrix, vertex);
325
+ return vertexBuffer(vertex[0], vertex[1], vertex[2], this.params.vertexColors[vertexIndex]);
326
+ })
327
+ .flat();
328
+ }
329
+ }
330
+ export class Line2dGeometry extends Geometry {
331
+ wireframeOrder = [0, 1, 2, 3, 0, 2];
332
+ triangleOrder = [0, 1, 3, 2];
333
+ params;
334
+ constructor(pos, to, thickness) {
335
+ super([], 'strip');
336
+ this.params = {
337
+ pos,
338
+ to,
339
+ thickness
340
+ };
341
+ }
342
+ recompute() {
343
+ const normal = vector2(-this.params.to[1], this.params.to[0]);
344
+ vec2.normalize(normal, normal);
345
+ vec2.scale(normal, this.params.thickness / 2, normal);
346
+ this.vertices = [
347
+ vector3(-normal[0], -normal[1]),
348
+ vector3(normal[0], normal[1]),
349
+ vector3(this.params.to[0] + normal[0], this.params.to[1] + normal[1]),
350
+ vector3(this.params.to[0] - normal[0], this.params.to[1] - normal[1])
351
+ ];
352
+ }
353
+ }
354
+ export class Line3dGeometry extends Geometry {
355
+ wireframeOrder = [0, 1, 2, 3, 0, 2];
356
+ triangleOrder = [0, 1, 2, 3, 0];
357
+ params;
358
+ constructor(pos, to, thickness) {
359
+ super([], 'strip');
360
+ this.params = {
361
+ pos,
362
+ to,
363
+ thickness
364
+ };
365
+ }
366
+ recompute() {
367
+ const normal = vector2(-this.params.to[1], this.params.to[0]);
368
+ vec2.normalize(normal, normal);
369
+ vec2.scale(normal, this.params.thickness / 2, normal);
370
+ this.vertices = [
371
+ vector3(-normal[0], -normal[1]),
372
+ vector3(normal[0], normal[1]),
373
+ vector3(this.params.to[0] + normal[0], this.params.to[1] + normal[1], this.params.to[2]),
374
+ vector3(this.params.to[0] - normal[0], this.params.to[1] - normal[1], this.params.to[2])
375
+ ];
376
+ }
377
+ }
378
+ export class PolygonGeometry extends Geometry {
379
+ wireframeOrder;
380
+ triangleOrder;
381
+ params;
382
+ constructor(points) {
383
+ super();
384
+ this.wireframeOrder = [];
385
+ this.triangleOrder = [];
386
+ this.params = {
387
+ points
388
+ };
389
+ this.recompute();
390
+ }
391
+ recompute() {
392
+ this.vertices = this.params.points.map((point) => point.getPos());
393
+ this.triangleOrder = lossyTriangulate(Array(this.vertices.length)
394
+ .fill(0)
395
+ .map((_, index) => index)).flat();
396
+ this.wireframeOrder = triangulateWireFrameOrder(this.vertices.length);
397
+ }
398
+ getTriangleBuffer(color) {
399
+ return this.triangleOrder
400
+ .map((vertexIndex) => {
401
+ const vertex = cloneBuf(this.vertices[vertexIndex]);
402
+ vec3.transformMat4(vertex, this.matrix, vertex);
403
+ return vertexBuffer(vertex[0], vertex[1], 0, this.params.points[vertexIndex].getColor() || color);
404
+ })
405
+ .flat();
406
+ }
407
+ }