simulationjsv2 0.1.10 → 0.2.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/dist/graphics.d.ts +52 -12
- package/dist/graphics.js +325 -26
- package/dist/index.d.ts +1 -1
- package/dist/index.js +1 -1
- package/dist/simulation.d.ts +1 -1
- package/dist/simulation.js +16 -2
- package/dist/utils.d.ts +3 -1
- package/dist/utils.js +19 -2
- package/package.json +1 -1
package/dist/graphics.d.ts
CHANGED
|
@@ -1,19 +1,19 @@
|
|
|
1
1
|
import { Camera } from './simulation.js';
|
|
2
2
|
import type { Vector2, Vector3, LerpFunc, VertexColorMap } from './types.js';
|
|
3
3
|
import { Vertex, VertexCache, Color } from './utils.js';
|
|
4
|
-
export declare abstract class SimulationElement {
|
|
4
|
+
export declare abstract class SimulationElement<T extends Vector2 | Vector3 = Vector3> {
|
|
5
5
|
private pos;
|
|
6
6
|
private color;
|
|
7
7
|
camera: Camera | null;
|
|
8
8
|
vertexCache: VertexCache;
|
|
9
|
-
constructor(pos:
|
|
10
|
-
setPos(pos:
|
|
11
|
-
getPos():
|
|
9
|
+
constructor(pos: T, color?: Color);
|
|
10
|
+
setPos(pos: T): void;
|
|
11
|
+
getPos(): T;
|
|
12
12
|
setCamera(camera: Camera): void;
|
|
13
13
|
fill(newColor: Color, t?: number, f?: LerpFunc): Promise<void>;
|
|
14
14
|
getColor(): Color;
|
|
15
|
-
move(amount:
|
|
16
|
-
moveTo(pos:
|
|
15
|
+
move(amount: T, t?: number, f?: LerpFunc): Promise<void>;
|
|
16
|
+
moveTo(pos: T, t?: number, f?: LerpFunc): Promise<void>;
|
|
17
17
|
abstract getBuffer(camera: Camera, force: boolean): number[];
|
|
18
18
|
}
|
|
19
19
|
export declare class Plane extends SimulationElement {
|
|
@@ -25,7 +25,7 @@ export declare class Plane extends SimulationElement {
|
|
|
25
25
|
rotateTo(angle: Vector3, t?: number, f?: LerpFunc): Promise<void>;
|
|
26
26
|
getBuffer(_: Camera, force: boolean): number[];
|
|
27
27
|
}
|
|
28
|
-
export declare class Square extends SimulationElement {
|
|
28
|
+
export declare class Square extends SimulationElement<Vector2> {
|
|
29
29
|
private width;
|
|
30
30
|
private height;
|
|
31
31
|
private rotation;
|
|
@@ -44,7 +44,7 @@ export declare class Square extends SimulationElement {
|
|
|
44
44
|
setRotation(newRotation: number, t?: number, f?: LerpFunc): Promise<void>;
|
|
45
45
|
getBuffer(camera: Camera, force: boolean): number[];
|
|
46
46
|
}
|
|
47
|
-
export declare class Circle extends SimulationElement {
|
|
47
|
+
export declare class Circle extends SimulationElement<Vector2> {
|
|
48
48
|
private radius;
|
|
49
49
|
private detail;
|
|
50
50
|
constructor(pos: Vector2, radius: number, color?: Color, detail?: number);
|
|
@@ -52,16 +52,56 @@ export declare class Circle extends SimulationElement {
|
|
|
52
52
|
scale(amount: number, t?: number, f?: LerpFunc): Promise<void>;
|
|
53
53
|
getBuffer(camera: Camera, force: boolean): number[];
|
|
54
54
|
}
|
|
55
|
-
export declare class Polygon extends SimulationElement {
|
|
55
|
+
export declare class Polygon extends SimulationElement<Vector2> {
|
|
56
56
|
private vertices;
|
|
57
57
|
private rotation;
|
|
58
|
-
constructor(pos:
|
|
58
|
+
constructor(pos: Vector2, vertices: Vertex[], color?: Color);
|
|
59
59
|
rotate(amount: number, t?: number, f?: LerpFunc): Promise<void>;
|
|
60
60
|
rotateTo(num: number, t?: number, f?: LerpFunc): Promise<void>;
|
|
61
61
|
getVertices(): Vertex[];
|
|
62
62
|
setVertices(newVertices: Vertex[], t?: number, f?: LerpFunc): Promise<void>;
|
|
63
63
|
getBuffer(camera: Camera, force: boolean): number[];
|
|
64
64
|
}
|
|
65
|
+
export declare class Line3d extends SimulationElement {
|
|
66
|
+
private to;
|
|
67
|
+
private toColor;
|
|
68
|
+
private thickness;
|
|
69
|
+
constructor(pos: Vertex, to: Vertex, thickness: number);
|
|
70
|
+
setStart(pos: Vector3, t?: number, f?: LerpFunc): Promise<void>;
|
|
71
|
+
setEnd(pos: Vector3, t?: number, f?: LerpFunc): Promise<void>;
|
|
72
|
+
getBuffer(_: Camera, force: boolean): number[];
|
|
73
|
+
}
|
|
74
|
+
export declare class Line2d extends SimulationElement {
|
|
75
|
+
private to;
|
|
76
|
+
private toColor;
|
|
77
|
+
private thickness;
|
|
78
|
+
constructor(from: Vertex, to: Vertex, thickness?: number);
|
|
79
|
+
setEndColor(newColor: Color, t?: number, f?: LerpFunc): Promise<void>;
|
|
80
|
+
setStart(pos: Vector2, t?: number, f?: LerpFunc): Promise<void>;
|
|
81
|
+
setEnd(pos: Vector2, t?: number, f?: LerpFunc): Promise<void>;
|
|
82
|
+
getBuffer(camera: Camera, force: boolean): number[];
|
|
83
|
+
}
|
|
84
|
+
export declare class Cube extends SimulationElement {
|
|
85
|
+
private vertices;
|
|
86
|
+
private rotation;
|
|
87
|
+
private width;
|
|
88
|
+
private height;
|
|
89
|
+
private depth;
|
|
90
|
+
private wireframe;
|
|
91
|
+
private wireframeLines;
|
|
92
|
+
private static readonly wireframeOrder;
|
|
93
|
+
constructor(pos: Vector3, width: number, height: number, depth: number, color?: Color, rotation?: Vector3);
|
|
94
|
+
private computeVertices;
|
|
95
|
+
private shiftWireframeLines;
|
|
96
|
+
setWireframe(wireframe: boolean): void;
|
|
97
|
+
rotate(amount: Vector3, t?: number, f?: LerpFunc): Promise<void>;
|
|
98
|
+
setRotation(rot: Vector3, t?: number, f?: LerpFunc): Promise<void>;
|
|
99
|
+
setWidth(width: number, t?: number, f?: LerpFunc): Promise<void>;
|
|
100
|
+
setHeight(height: number, t?: number, f?: LerpFunc): Promise<void>;
|
|
101
|
+
setDepth(depth: number, t?: number, f?: LerpFunc): Promise<void>;
|
|
102
|
+
scale(amount: number, t?: number, f?: LerpFunc): Promise<void>;
|
|
103
|
+
getBuffer(camera: Camera, force: boolean): number[];
|
|
104
|
+
}
|
|
65
105
|
export declare class BezierCurve2d {
|
|
66
106
|
private points;
|
|
67
107
|
constructor(points: Vector2[]);
|
|
@@ -95,11 +135,11 @@ export declare class SplinePoint2d {
|
|
|
95
135
|
}
|
|
96
136
|
export declare class Spline2d extends SimulationElement {
|
|
97
137
|
private curves;
|
|
98
|
-
private
|
|
138
|
+
private thickness;
|
|
99
139
|
private detail;
|
|
100
140
|
private interpolateLimit;
|
|
101
141
|
private distance;
|
|
102
|
-
constructor(pos: Vertex, points: SplinePoint2d[],
|
|
142
|
+
constructor(pos: Vertex, points: SplinePoint2d[], thickness?: number, detail?: number);
|
|
103
143
|
setInterpolateLimit(limit: number, t?: number, f?: LerpFunc): Promise<void>;
|
|
104
144
|
getBuffer(camera: Camera, force: boolean): number[];
|
|
105
145
|
}
|
package/dist/graphics.js
CHANGED
|
@@ -7,7 +7,7 @@ export class SimulationElement {
|
|
|
7
7
|
vertexCache;
|
|
8
8
|
constructor(pos, color = new Color()) {
|
|
9
9
|
this.pos = pos;
|
|
10
|
-
vec3ToPixelRatio(this.pos);
|
|
10
|
+
vec3ToPixelRatio(vector3(...this.pos));
|
|
11
11
|
this.color = color;
|
|
12
12
|
this.vertexCache = new VertexCache();
|
|
13
13
|
this.camera = null;
|
|
@@ -22,16 +22,13 @@ export class SimulationElement {
|
|
|
22
22
|
this.camera = camera;
|
|
23
23
|
}
|
|
24
24
|
fill(newColor, t = 0, f) {
|
|
25
|
-
const
|
|
26
|
-
const diffG = newColor.g - this.color.g;
|
|
27
|
-
const diffB = newColor.b - this.color.b;
|
|
28
|
-
const diffA = newColor.a - this.color.a;
|
|
25
|
+
const diff = newColor.diff(this.color);
|
|
29
26
|
const finalColor = newColor.clone();
|
|
30
27
|
return transitionValues((p) => {
|
|
31
|
-
this.color.r +=
|
|
32
|
-
this.color.g +=
|
|
33
|
-
this.color.b +=
|
|
34
|
-
this.color.a +=
|
|
28
|
+
this.color.r += diff.r * p;
|
|
29
|
+
this.color.g += diff.g * p;
|
|
30
|
+
this.color.b += diff.b * p;
|
|
31
|
+
this.color.a += diff.a * p;
|
|
35
32
|
this.vertexCache.updated();
|
|
36
33
|
}, () => {
|
|
37
34
|
this.color = finalColor;
|
|
@@ -42,13 +39,12 @@ export class SimulationElement {
|
|
|
42
39
|
return this.color;
|
|
43
40
|
}
|
|
44
41
|
move(amount, t = 0, f) {
|
|
45
|
-
const finalPos =
|
|
42
|
+
const finalPos = amount.length === 3 ? vector3() : vector2();
|
|
46
43
|
vec3.add(finalPos, this.pos, amount);
|
|
47
44
|
return transitionValues((p) => {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
vec3.add(this.pos, this.pos, vector3(x, y, z));
|
|
45
|
+
for (let i = 0; i < this.pos.length; i++) {
|
|
46
|
+
this.pos[i] += amount[i] * p;
|
|
47
|
+
}
|
|
52
48
|
this.vertexCache.updated();
|
|
53
49
|
}, () => {
|
|
54
50
|
this.pos = finalPos;
|
|
@@ -56,16 +52,17 @@ export class SimulationElement {
|
|
|
56
52
|
}, t, f);
|
|
57
53
|
}
|
|
58
54
|
moveTo(pos, t = 0, f) {
|
|
59
|
-
const diff =
|
|
55
|
+
const diff = pos.length === 3 ? vector3() : vector2();
|
|
60
56
|
vec3.sub(diff, pos, this.pos);
|
|
61
57
|
return transitionValues((p) => {
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
vec3.add(this.pos, this.pos, vector3(x, y, z));
|
|
58
|
+
for (let i = 0; i < this.pos.length; i++) {
|
|
59
|
+
this.pos[i] += diff[i] * p;
|
|
60
|
+
}
|
|
66
61
|
this.vertexCache.updated();
|
|
67
62
|
}, () => {
|
|
68
|
-
this.pos
|
|
63
|
+
for (let i = 0; i < this.pos.length; i++) {
|
|
64
|
+
this.pos[i] = pos[i];
|
|
65
|
+
}
|
|
69
66
|
this.vertexCache.updated();
|
|
70
67
|
}, t, f);
|
|
71
68
|
}
|
|
@@ -139,7 +136,7 @@ export class Square extends SimulationElement {
|
|
|
139
136
|
* @param vertexColors{Record<number, Color>} - 0 is top left vertex, numbers increase clockwise
|
|
140
137
|
*/
|
|
141
138
|
constructor(pos, width, height, color, rotation, vertexColors) {
|
|
142
|
-
super(
|
|
139
|
+
super(pos, color);
|
|
143
140
|
this.width = width * devicePixelRatio;
|
|
144
141
|
this.height = height * devicePixelRatio;
|
|
145
142
|
this.rotation = rotation || 0;
|
|
@@ -261,7 +258,7 @@ export class Circle extends SimulationElement {
|
|
|
261
258
|
radius;
|
|
262
259
|
detail = 100;
|
|
263
260
|
constructor(pos, radius, color, detail = 50) {
|
|
264
|
-
super(
|
|
261
|
+
super(pos, color);
|
|
265
262
|
this.radius = radius * devicePixelRatio;
|
|
266
263
|
this.detail = detail;
|
|
267
264
|
}
|
|
@@ -431,6 +428,308 @@ export class Polygon extends SimulationElement {
|
|
|
431
428
|
return this.vertexCache.getCache();
|
|
432
429
|
}
|
|
433
430
|
}
|
|
431
|
+
export class Line3d extends SimulationElement {
|
|
432
|
+
to;
|
|
433
|
+
toColor;
|
|
434
|
+
thickness;
|
|
435
|
+
constructor(pos, to, thickness) {
|
|
436
|
+
super(pos.getPos(), to.getColor() || undefined);
|
|
437
|
+
this.thickness = thickness;
|
|
438
|
+
this.toColor = to.getColor() || this.getColor();
|
|
439
|
+
this.to = to.getPos();
|
|
440
|
+
vec3.scale(this.to, devicePixelRatio, this.to);
|
|
441
|
+
vec3.sub(this.to, this.getPos(), this.to);
|
|
442
|
+
}
|
|
443
|
+
setStart(pos, t = 0, f) {
|
|
444
|
+
return this.moveTo(pos, t, f);
|
|
445
|
+
}
|
|
446
|
+
setEnd(pos, t = 0, f) {
|
|
447
|
+
const diff = vector3();
|
|
448
|
+
vec3.sub(pos, this.to, diff);
|
|
449
|
+
return transitionValues((p) => {
|
|
450
|
+
this.to[0] += diff[0] * p;
|
|
451
|
+
this.to[1] += diff[1] * p;
|
|
452
|
+
this.to[2] += diff[2] * p;
|
|
453
|
+
this.vertexCache.updated();
|
|
454
|
+
}, () => {
|
|
455
|
+
this.to[0] = pos[0];
|
|
456
|
+
this.to[1] = pos[1];
|
|
457
|
+
this.to[2] = pos[2];
|
|
458
|
+
this.vertexCache.updated();
|
|
459
|
+
}, t, f);
|
|
460
|
+
}
|
|
461
|
+
getBuffer(_, force) {
|
|
462
|
+
if (this.vertexCache.shouldUpdate() || force) {
|
|
463
|
+
const normal = vector2(-this.to[1], this.to[0]);
|
|
464
|
+
vec2.normalize(normal, normal);
|
|
465
|
+
vec2.scale(normal, this.thickness / 2, normal);
|
|
466
|
+
const pos = this.getPos();
|
|
467
|
+
const resBuffer = [
|
|
468
|
+
...vertexBuffer3d(pos[0] + normal[0], pos[1] + normal[1], pos[2], this.getColor()),
|
|
469
|
+
...vertexBuffer3d(pos[0] - normal[0], pos[1] - normal[1], pos[2], this.getColor()),
|
|
470
|
+
...vertexBuffer3d(pos[0] + this.to[0] + normal[0], pos[1] + this.to[1] + normal[1], pos[2] + this.to[2], this.toColor || this.getColor()),
|
|
471
|
+
...vertexBuffer3d(pos[0] - normal[0], pos[1] - normal[1], pos[2], this.getColor()),
|
|
472
|
+
...vertexBuffer3d(pos[0] + this.to[0] + normal[0], pos[1] + this.to[1] + normal[1], pos[2] + this.to[2], this.toColor || this.getColor()),
|
|
473
|
+
...vertexBuffer3d(pos[0] + this.to[0] - normal[0], pos[1] + this.to[1] - normal[1], pos[2] + this.to[2], this.toColor || this.getColor())
|
|
474
|
+
];
|
|
475
|
+
this.vertexCache.setCache(resBuffer);
|
|
476
|
+
return resBuffer;
|
|
477
|
+
}
|
|
478
|
+
return this.vertexCache.getCache();
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
export class Line2d extends SimulationElement {
|
|
482
|
+
to;
|
|
483
|
+
toColor;
|
|
484
|
+
thickness;
|
|
485
|
+
constructor(from, to, thickness = 1) {
|
|
486
|
+
super(from.getPos(), from.getColor() || undefined);
|
|
487
|
+
this.thickness = thickness * devicePixelRatio;
|
|
488
|
+
this.toColor = to.getColor();
|
|
489
|
+
this.to = vector2FromVector3(to.getPos());
|
|
490
|
+
vec2.scale(this.to, devicePixelRatio, this.to);
|
|
491
|
+
vec2.sub(this.to, this.getPos(), this.to);
|
|
492
|
+
}
|
|
493
|
+
setEndColor(newColor, t = 0, f) {
|
|
494
|
+
if (!this.toColor)
|
|
495
|
+
this.toColor = this.getColor();
|
|
496
|
+
const diff = newColor.diff(this.toColor);
|
|
497
|
+
const finalColor = newColor.clone();
|
|
498
|
+
return transitionValues((p) => {
|
|
499
|
+
this.toColor.r += diff.r * p;
|
|
500
|
+
this.toColor.g += diff.g * p;
|
|
501
|
+
this.toColor.b += diff.b * p;
|
|
502
|
+
this.toColor.a += diff.a * p;
|
|
503
|
+
this.vertexCache.updated();
|
|
504
|
+
}, () => {
|
|
505
|
+
this.toColor = finalColor;
|
|
506
|
+
this.vertexCache.updated();
|
|
507
|
+
}, t, f);
|
|
508
|
+
}
|
|
509
|
+
setStart(pos, t = 0, f) {
|
|
510
|
+
return this.moveTo(vector3FromVector2(pos), t, f);
|
|
511
|
+
}
|
|
512
|
+
setEnd(pos, t = 0, f) {
|
|
513
|
+
const diff = vector3();
|
|
514
|
+
vec2.sub(pos, this.to, diff);
|
|
515
|
+
return transitionValues((p) => {
|
|
516
|
+
this.to[0] += diff[0] * p;
|
|
517
|
+
this.to[1] += diff[1] * p;
|
|
518
|
+
this.vertexCache.updated();
|
|
519
|
+
}, () => {
|
|
520
|
+
this.to[0] = pos[0];
|
|
521
|
+
this.to[1] = pos[1];
|
|
522
|
+
this.vertexCache.updated();
|
|
523
|
+
}, t, f);
|
|
524
|
+
}
|
|
525
|
+
getBuffer(camera, force) {
|
|
526
|
+
if (this.vertexCache.shouldUpdate() || force) {
|
|
527
|
+
const normal = vector2(-this.to[1], this.to[0]);
|
|
528
|
+
vec2.normalize(normal, normal);
|
|
529
|
+
vec2.scale(normal, this.thickness / 2, normal);
|
|
530
|
+
const screenSize = camera.getScreenSize();
|
|
531
|
+
const pos = this.getPos();
|
|
532
|
+
const resBuffer = [
|
|
533
|
+
...vertexBuffer2d(pos[0] + normal[0], screenSize[1] - pos[1] + normal[1], this.getColor()),
|
|
534
|
+
...vertexBuffer2d(pos[0] - normal[0], screenSize[1] - pos[1] - normal[1], this.getColor()),
|
|
535
|
+
...vertexBuffer2d(pos[0] + this.to[0] + normal[0], screenSize[1] - pos[1] + this.to[1] + normal[1], this.toColor || this.getColor()),
|
|
536
|
+
...vertexBuffer2d(pos[0] - normal[0], screenSize[1] - pos[1] - normal[1], this.getColor()),
|
|
537
|
+
...vertexBuffer2d(pos[0] + this.to[0] + normal[0], screenSize[1] - pos[1] + this.to[1] + normal[1], this.toColor || this.getColor()),
|
|
538
|
+
...vertexBuffer2d(pos[0] + this.to[0] - normal[0], screenSize[1] - pos[1] + this.to[1] - normal[1], this.toColor || this.getColor())
|
|
539
|
+
];
|
|
540
|
+
this.vertexCache.setCache(resBuffer);
|
|
541
|
+
return resBuffer;
|
|
542
|
+
}
|
|
543
|
+
return this.vertexCache.getCache();
|
|
544
|
+
}
|
|
545
|
+
}
|
|
546
|
+
export class Cube extends SimulationElement {
|
|
547
|
+
vertices;
|
|
548
|
+
rotation;
|
|
549
|
+
width;
|
|
550
|
+
height;
|
|
551
|
+
depth;
|
|
552
|
+
wireframe;
|
|
553
|
+
wireframeLines;
|
|
554
|
+
static wireframeOrder = [
|
|
555
|
+
[0, 1],
|
|
556
|
+
[1, 2],
|
|
557
|
+
[2, 3],
|
|
558
|
+
[3, 0],
|
|
559
|
+
[4, 5],
|
|
560
|
+
[5, 6],
|
|
561
|
+
[6, 7],
|
|
562
|
+
[7, 4],
|
|
563
|
+
[0, 4],
|
|
564
|
+
[3, 7],
|
|
565
|
+
[1, 5],
|
|
566
|
+
[2, 6]
|
|
567
|
+
];
|
|
568
|
+
constructor(pos, width, height, depth, color, rotation) {
|
|
569
|
+
super(pos, color);
|
|
570
|
+
this.width = width * devicePixelRatio;
|
|
571
|
+
this.height = height * devicePixelRatio;
|
|
572
|
+
this.depth = depth * devicePixelRatio;
|
|
573
|
+
this.rotation = rotation || vector3();
|
|
574
|
+
this.wireframe = false;
|
|
575
|
+
this.wireframeLines = [];
|
|
576
|
+
const numWireframeLines = 12;
|
|
577
|
+
const lineThickness = 0.025;
|
|
578
|
+
for (let i = 0; i < numWireframeLines; i++) {
|
|
579
|
+
this.wireframeLines.push(new Line3d(vertex(), vertex(), lineThickness));
|
|
580
|
+
}
|
|
581
|
+
this.vertices = [];
|
|
582
|
+
this.computeVertices();
|
|
583
|
+
this.shiftWireframeLines();
|
|
584
|
+
}
|
|
585
|
+
computeVertices() {
|
|
586
|
+
console.log(this.width, this.height);
|
|
587
|
+
this.vertices = [
|
|
588
|
+
// front face
|
|
589
|
+
vector3(-this.width / 2, -this.height / 2, this.depth / 2),
|
|
590
|
+
vector3(this.width / 2, -this.height / 2, this.depth / 2),
|
|
591
|
+
vector3(this.width / 2, this.height / 2, this.depth / 2),
|
|
592
|
+
vector3(-this.width / 2, this.height / 2, this.depth / 2),
|
|
593
|
+
// back face
|
|
594
|
+
vector3(-this.width / 2, -this.height / 2, -this.depth / 2),
|
|
595
|
+
vector3(this.width / 2, -this.height / 2, -this.depth / 2),
|
|
596
|
+
vector3(this.width / 2, this.height / 2, -this.depth / 2),
|
|
597
|
+
vector3(-this.width / 2, this.height / 2, -this.depth / 2)
|
|
598
|
+
];
|
|
599
|
+
}
|
|
600
|
+
shiftWireframeLines() {
|
|
601
|
+
let rotMatrix = mat4.identity();
|
|
602
|
+
mat4.rotateZ(rotMatrix, this.rotation[2], rotMatrix);
|
|
603
|
+
mat4.rotateY(rotMatrix, this.rotation[1], rotMatrix);
|
|
604
|
+
mat4.rotateX(rotMatrix, this.rotation[0], rotMatrix);
|
|
605
|
+
const pos = this.getPos();
|
|
606
|
+
Cube.wireframeOrder.forEach((lineVertices, index) => {
|
|
607
|
+
const line = this.wireframeLines[index];
|
|
608
|
+
const start = cloneBuf(this.vertices[lineVertices[0]]);
|
|
609
|
+
const endPoint = cloneBuf(this.vertices[lineVertices[1]]);
|
|
610
|
+
vec3.sub(endPoint, start, endPoint);
|
|
611
|
+
vec3.transformMat4(endPoint, rotMatrix, endPoint);
|
|
612
|
+
vec3.transformMat4(start, rotMatrix, start);
|
|
613
|
+
vec3.add(start, pos, start);
|
|
614
|
+
line.setStart(start);
|
|
615
|
+
line.setEnd(endPoint);
|
|
616
|
+
});
|
|
617
|
+
}
|
|
618
|
+
setWireframe(wireframe) {
|
|
619
|
+
this.wireframe = wireframe;
|
|
620
|
+
}
|
|
621
|
+
rotate(amount, t = 0, f) {
|
|
622
|
+
const finalRotation = cloneBuf(this.rotation);
|
|
623
|
+
vec3.add(finalRotation, amount, finalRotation);
|
|
624
|
+
return transitionValues((p) => {
|
|
625
|
+
this.rotation[0] += amount[0] * p;
|
|
626
|
+
this.rotation[1] += amount[1] * p;
|
|
627
|
+
this.rotation[2] += amount[2] * p;
|
|
628
|
+
this.vertexCache.updated();
|
|
629
|
+
}, () => {
|
|
630
|
+
this.rotation = finalRotation;
|
|
631
|
+
this.vertexCache.updated();
|
|
632
|
+
}, t, f);
|
|
633
|
+
}
|
|
634
|
+
setRotation(rot, t = 0, f) {
|
|
635
|
+
const diff = vector3();
|
|
636
|
+
vec3.sub(rot, this.rotation, diff);
|
|
637
|
+
return transitionValues((p) => {
|
|
638
|
+
this.rotation[0] += diff[0] * p;
|
|
639
|
+
this.rotation[1] += diff[1] * p;
|
|
640
|
+
this.rotation[2] += diff[2] * p;
|
|
641
|
+
this.vertexCache.updated();
|
|
642
|
+
}, () => {
|
|
643
|
+
this.rotation = rot;
|
|
644
|
+
this.vertexCache.updated();
|
|
645
|
+
}, t, f);
|
|
646
|
+
}
|
|
647
|
+
setWidth(width, t = 0, f) {
|
|
648
|
+
width *= devicePixelRatio;
|
|
649
|
+
const diff = width - this.width;
|
|
650
|
+
return transitionValues((p) => {
|
|
651
|
+
this.width += diff * p;
|
|
652
|
+
this.vertexCache.updated();
|
|
653
|
+
}, () => {
|
|
654
|
+
this.width = width;
|
|
655
|
+
this.vertexCache.updated();
|
|
656
|
+
}, t, f);
|
|
657
|
+
}
|
|
658
|
+
setHeight(height, t = 0, f) {
|
|
659
|
+
height *= devicePixelRatio;
|
|
660
|
+
const diff = height - this.width;
|
|
661
|
+
return transitionValues((p) => {
|
|
662
|
+
this.height += diff * p;
|
|
663
|
+
this.vertexCache.updated();
|
|
664
|
+
}, () => {
|
|
665
|
+
this.height = height;
|
|
666
|
+
this.vertexCache.updated();
|
|
667
|
+
}, t, f);
|
|
668
|
+
}
|
|
669
|
+
setDepth(depth, t = 0, f) {
|
|
670
|
+
depth *= devicePixelRatio;
|
|
671
|
+
const diff = depth - this.width;
|
|
672
|
+
return transitionValues((p) => {
|
|
673
|
+
this.depth += diff * p;
|
|
674
|
+
this.vertexCache.updated();
|
|
675
|
+
}, () => {
|
|
676
|
+
this.depth = depth;
|
|
677
|
+
this.vertexCache.updated();
|
|
678
|
+
}, t, f);
|
|
679
|
+
}
|
|
680
|
+
scale(amount, t = 0, f) {
|
|
681
|
+
const finalWidth = this.width * amount;
|
|
682
|
+
const finalHeight = this.height * amount;
|
|
683
|
+
const finalDepth = this.depth * amount;
|
|
684
|
+
const widthDiff = finalWidth - this.width;
|
|
685
|
+
const heightDiff = finalHeight - this.height;
|
|
686
|
+
const depthDiff = finalDepth - this.depth;
|
|
687
|
+
return transitionValues((p) => {
|
|
688
|
+
this.width += widthDiff * p;
|
|
689
|
+
this.height += heightDiff * p;
|
|
690
|
+
this.depth += depthDiff * p;
|
|
691
|
+
this.vertexCache.updated();
|
|
692
|
+
}, () => {
|
|
693
|
+
this.width = finalWidth;
|
|
694
|
+
this.height = finalHeight;
|
|
695
|
+
this.depth = finalDepth;
|
|
696
|
+
this.vertexCache.updated();
|
|
697
|
+
}, t, f);
|
|
698
|
+
}
|
|
699
|
+
getBuffer(camera, force) {
|
|
700
|
+
if (this.vertexCache.shouldUpdate() || force) {
|
|
701
|
+
this.computeVertices();
|
|
702
|
+
this.shiftWireframeLines();
|
|
703
|
+
const triangleOrder = [
|
|
704
|
+
0, 1, 2, 0, 2, 3,
|
|
705
|
+
4, 5, 6, 4, 6, 7,
|
|
706
|
+
0, 3, 7, 0, 7, 4,
|
|
707
|
+
0, 4, 5, 0, 5, 1,
|
|
708
|
+
1, 2, 6, 1, 5, 6,
|
|
709
|
+
2, 3, 7, 2, 6, 7
|
|
710
|
+
];
|
|
711
|
+
let rotMatrix = mat4.identity();
|
|
712
|
+
mat4.rotateZ(rotMatrix, this.rotation[2], rotMatrix);
|
|
713
|
+
mat4.rotateY(rotMatrix, this.rotation[1], rotMatrix);
|
|
714
|
+
mat4.rotateX(rotMatrix, this.rotation[0], rotMatrix);
|
|
715
|
+
const pos = this.getPos();
|
|
716
|
+
let resBuffer = [];
|
|
717
|
+
triangleOrder.forEach((index) => {
|
|
718
|
+
const vertex = cloneBuf(this.vertices[index]);
|
|
719
|
+
vec3.transformMat4(vertex, rotMatrix, vertex);
|
|
720
|
+
resBuffer = resBuffer.concat(vertexBuffer3d(vertex[0] + pos[0], vertex[1] + pos[1], vertex[2] + pos[2], this.getColor()));
|
|
721
|
+
});
|
|
722
|
+
if (this.wireframe) {
|
|
723
|
+
this.wireframeLines.forEach((line) => {
|
|
724
|
+
resBuffer = resBuffer.concat(line.getBuffer(camera, force));
|
|
725
|
+
});
|
|
726
|
+
}
|
|
727
|
+
this.vertexCache.setCache(resBuffer);
|
|
728
|
+
return resBuffer;
|
|
729
|
+
}
|
|
730
|
+
return this.vertexCache.getCache();
|
|
731
|
+
}
|
|
732
|
+
}
|
|
434
733
|
export class BezierCurve2d {
|
|
435
734
|
points;
|
|
436
735
|
constructor(points) {
|
|
@@ -557,14 +856,14 @@ export class SplinePoint2d {
|
|
|
557
856
|
}
|
|
558
857
|
export class Spline2d extends SimulationElement {
|
|
559
858
|
curves;
|
|
560
|
-
|
|
859
|
+
thickness;
|
|
561
860
|
detail;
|
|
562
861
|
interpolateLimit;
|
|
563
862
|
distance;
|
|
564
|
-
constructor(pos, points,
|
|
863
|
+
constructor(pos, points, thickness = devicePixelRatio, detail = 40) {
|
|
565
864
|
super(pos.getPos(), pos.getColor() || undefined);
|
|
566
865
|
this.curves = [];
|
|
567
|
-
this.
|
|
866
|
+
this.thickness = thickness * devicePixelRatio;
|
|
568
867
|
this.detail = detail;
|
|
569
868
|
this.interpolateLimit = 1;
|
|
570
869
|
this.distance = 0;
|
|
@@ -623,7 +922,7 @@ export class Spline2d extends SimulationElement {
|
|
|
623
922
|
point[1] += screenSize[1] - pos[1];
|
|
624
923
|
const normal = vector2(-slope[1], slope[0]);
|
|
625
924
|
vec2.normalize(normal, normal);
|
|
626
|
-
vec2.scale(normal, this.
|
|
925
|
+
vec2.scale(normal, this.thickness / 2, normal);
|
|
627
926
|
const colors = this.curves[i].getColors().map((c) => (c ? c : this.getColor()));
|
|
628
927
|
const vertexColor = interpolateColors(colors, currentInterpolation);
|
|
629
928
|
const vertTop = vertex(point[0] + normal[0], point[1] + normal[1], 0, vertexColor);
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export * from './simulation.js';
|
|
2
2
|
export * from './graphics.js';
|
|
3
3
|
export * from './types.js';
|
|
4
|
-
export { Vertex, Color, cloneBuf, vector4, vector3, vector2, vector3FromVector2, colorFromVector4, randomInt, randomColor, vertex, color, colorf, transitionValues, lerp, smoothStep, linearStep, splinePoint2d, continuousSplinePoint2d } from './utils.js';
|
|
4
|
+
export { Vertex, Color, cloneBuf, vector4, vector3, vector2, vector3FromVector2, colorFromVector4, randomInt, randomColor, vertex, color, colorf, transitionValues, lerp, smoothStep, linearStep, exponentialStep, splinePoint2d, continuousSplinePoint2d } from './utils.js';
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export * from './simulation.js';
|
|
2
2
|
export * from './graphics.js';
|
|
3
3
|
export * from './types.js';
|
|
4
|
-
export { Vertex, Color, cloneBuf, vector4, vector3, vector2, vector3FromVector2, colorFromVector4, randomInt, randomColor, vertex, color, colorf, transitionValues, lerp, smoothStep, linearStep, splinePoint2d, continuousSplinePoint2d } from './utils.js';
|
|
4
|
+
export { Vertex, Color, cloneBuf, vector4, vector3, vector2, vector3FromVector2, colorFromVector4, randomInt, randomColor, vertex, color, colorf, transitionValues, lerp, smoothStep, linearStep, exponentialStep, splinePoint2d, continuousSplinePoint2d } from './utils.js';
|
package/dist/simulation.d.ts
CHANGED
|
@@ -11,7 +11,7 @@ export declare class Simulation {
|
|
|
11
11
|
private frameRateView;
|
|
12
12
|
private camera;
|
|
13
13
|
constructor(idOrCanvasRef: string | HTMLCanvasElement, camera?: Camera | null, showFrameRate?: boolean);
|
|
14
|
-
add(el: SimulationElement): void;
|
|
14
|
+
add(el: SimulationElement<any>): void;
|
|
15
15
|
setCanvasSize(width: number, height: number): void;
|
|
16
16
|
start(): void;
|
|
17
17
|
stop(): void;
|
package/dist/simulation.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { vec3 } from 'wgpu-matrix';
|
|
2
2
|
import { SimulationElement } from './graphics.js';
|
|
3
3
|
import { BUF_LEN } from './constants.js';
|
|
4
|
-
import { Color, applyElementToScene, buildMultisampleTexture, buildProjectionMatrix, getOrthoMatrix, getTransformationMatrix, logger, transitionValues, vector2, vector3 } from './utils.js';
|
|
4
|
+
import { Color, applyElementToScene, buildDepthTexture, buildMultisampleTexture, buildProjectionMatrix, getOrthoMatrix, getTransformationMatrix, logger, transitionValues, vector2, vector3 } from './utils.js';
|
|
5
5
|
const vertexSize = 44; // 4 * 10 + 1
|
|
6
6
|
const colorOffset = 16; // 4 * 4
|
|
7
7
|
const uvOffset = 32; // 4 * 8
|
|
@@ -229,6 +229,11 @@ export class Simulation {
|
|
|
229
229
|
},
|
|
230
230
|
multisample: {
|
|
231
231
|
count: 4
|
|
232
|
+
},
|
|
233
|
+
depthStencil: {
|
|
234
|
+
depthWriteEnabled: true,
|
|
235
|
+
depthCompare: 'less',
|
|
236
|
+
format: 'depth24plus'
|
|
232
237
|
}
|
|
233
238
|
});
|
|
234
239
|
const uniformBufferSize = 4 * 16 + 4 * 16 + 4 * 2 + 8; // 4x4 matrix + 4x4 matrix + vec2<f32> + 8 bc 144 is cool
|
|
@@ -267,8 +272,15 @@ export class Simulation {
|
|
|
267
272
|
};
|
|
268
273
|
updateOrthoMatrix();
|
|
269
274
|
let multisampleTexture = buildMultisampleTexture(device, ctx, canvas.width, canvas.height);
|
|
275
|
+
let depthTexture = buildDepthTexture(device, canvas.width, canvas.height);
|
|
270
276
|
const renderPassDescriptor = {
|
|
271
|
-
colorAttachments: [colorAttachment]
|
|
277
|
+
colorAttachments: [colorAttachment],
|
|
278
|
+
depthStencilAttachment: {
|
|
279
|
+
view: depthTexture.createView(),
|
|
280
|
+
depthClearValue: 1.0,
|
|
281
|
+
depthLoadOp: 'clear',
|
|
282
|
+
depthStoreOp: 'store'
|
|
283
|
+
}
|
|
272
284
|
};
|
|
273
285
|
// sub 10 to start with a reasonable gap between starting time and next frame time
|
|
274
286
|
let prev = Date.now() - 10;
|
|
@@ -296,6 +308,8 @@ export class Simulation {
|
|
|
296
308
|
projectionMatrix = buildProjectionMatrix(aspect);
|
|
297
309
|
updateModelViewProjectionMatrix();
|
|
298
310
|
multisampleTexture = buildMultisampleTexture(device, ctx, screenSize[0], screenSize[1]);
|
|
311
|
+
depthTexture = buildDepthTexture(device, screenSize[0], screenSize[1]);
|
|
312
|
+
renderPassDescriptor.depthStencilAttachment.view = depthTexture.createView();
|
|
299
313
|
}
|
|
300
314
|
// @ts-ignore
|
|
301
315
|
renderPassDescriptor.colorAttachments[0].view = multisampleTexture.createView();
|
package/dist/utils.d.ts
CHANGED
|
@@ -51,6 +51,7 @@ export declare class Vertex {
|
|
|
51
51
|
export declare const buildProjectionMatrix: (aspectRatio: number, zNear?: number, zFar?: number) => any;
|
|
52
52
|
export declare const getTransformationMatrix: (pos: Vector3, rotation: Vector3, projectionMatrix: mat4) => Float32Array;
|
|
53
53
|
export declare const getOrthoMatrix: (screenSize: [number, number]) => Float32Array;
|
|
54
|
+
export declare const buildDepthTexture: (device: GPUDevice, width: number, height: number) => GPUTexture;
|
|
54
55
|
export declare const buildMultisampleTexture: (device: GPUDevice, ctx: GPUCanvasContext, width: number, height: number) => GPUTexture;
|
|
55
56
|
export declare const applyElementToScene: (scene: SimulationElement[], camera: Camera | null, el: SimulationElement) => void;
|
|
56
57
|
declare class Logger {
|
|
@@ -72,7 +73,8 @@ export declare function lossyTriangulate(vertices: Vertex[]): (readonly [Vertex,
|
|
|
72
73
|
export declare function transitionValues(callback1: (deltaT: number, t: number) => void, callback2: () => void, transitionLength: number, func?: (n: number) => number): Promise<void>;
|
|
73
74
|
export declare function lerp(a: number, b: number, t: number): number;
|
|
74
75
|
export declare function smoothStep(t: number): number;
|
|
75
|
-
export declare function linearStep(
|
|
76
|
+
export declare function linearStep(t: number): number;
|
|
77
|
+
export declare function exponentialStep(t: number): number;
|
|
76
78
|
export declare function vertexBuffer3d(x: number, y: number, z: number, color: Color, uv?: Vector2): number[];
|
|
77
79
|
export declare function vertexBuffer2d(x: number, y: number, color: Color, uv?: Vector2): number[];
|
|
78
80
|
export declare function vec3ToPixelRatio(vec: Vector3): void;
|
package/dist/utils.js
CHANGED
|
@@ -125,6 +125,14 @@ export const getTransformationMatrix = (pos, rotation, projectionMatrix) => {
|
|
|
125
125
|
export const getOrthoMatrix = (screenSize) => {
|
|
126
126
|
return mat4.ortho(0, screenSize[0], 0, screenSize[1], 0, 100);
|
|
127
127
|
};
|
|
128
|
+
export const buildDepthTexture = (device, width, height) => {
|
|
129
|
+
return device.createTexture({
|
|
130
|
+
size: [width, height],
|
|
131
|
+
format: 'depth24plus',
|
|
132
|
+
usage: GPUTextureUsage.RENDER_ATTACHMENT,
|
|
133
|
+
sampleCount: 4
|
|
134
|
+
});
|
|
135
|
+
};
|
|
128
136
|
export const buildMultisampleTexture = (device, ctx, width, height) => {
|
|
129
137
|
return device.createTexture({
|
|
130
138
|
size: [width, height],
|
|
@@ -237,8 +245,17 @@ export function smoothStep(t) {
|
|
|
237
245
|
const v2 = 1 - (1 - t) * (1 - t);
|
|
238
246
|
return lerp(v1, v2, t);
|
|
239
247
|
}
|
|
240
|
-
export function linearStep(
|
|
241
|
-
return
|
|
248
|
+
export function linearStep(t) {
|
|
249
|
+
return t;
|
|
250
|
+
}
|
|
251
|
+
export function exponentialStep(t) {
|
|
252
|
+
return t === 0
|
|
253
|
+
? 0
|
|
254
|
+
: t === 1
|
|
255
|
+
? 1
|
|
256
|
+
: t < 0.5
|
|
257
|
+
? Math.pow(2, 20 * t - 10) / 2
|
|
258
|
+
: (2 - Math.pow(2, -20 * t + 10)) / 2;
|
|
242
259
|
}
|
|
243
260
|
export function vertexBuffer3d(x, y, z, color, uv = vector2()) {
|
|
244
261
|
return [x, y, z, 1, ...color.toBuffer(), ...uv, 1];
|