simulationjsv2 0.1.10 → 0.2.1

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,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: Vector3, color?: Color);
10
- setPos(pos: Vector3): void;
11
- getPos(): Vector3;
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: Vector3, t?: number, f?: LerpFunc): Promise<void>;
16
- moveTo(pos: Vector3, t?: number, f?: LerpFunc): Promise<void>;
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: Vector3, vertices: Vertex[], color?: Color);
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 width;
138
+ private thickness;
99
139
  private detail;
100
140
  private interpolateLimit;
101
141
  private distance;
102
- constructor(pos: Vertex, points: SplinePoint2d[], width?: number, detail?: number);
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,11 @@ export class SimulationElement {
7
7
  vertexCache;
8
8
  constructor(pos, color = new Color()) {
9
9
  this.pos = pos;
10
- vec3ToPixelRatio(this.pos);
10
+ const temp = vector3(...this.pos);
11
+ vec3ToPixelRatio(temp);
12
+ for (let i = 0; i < this.pos.length; i++) {
13
+ this.pos[i] = temp[i];
14
+ }
11
15
  this.color = color;
12
16
  this.vertexCache = new VertexCache();
13
17
  this.camera = null;
@@ -22,16 +26,13 @@ export class SimulationElement {
22
26
  this.camera = camera;
23
27
  }
24
28
  fill(newColor, t = 0, f) {
25
- const diffR = newColor.r - this.color.r;
26
- const diffG = newColor.g - this.color.g;
27
- const diffB = newColor.b - this.color.b;
28
- const diffA = newColor.a - this.color.a;
29
+ const diff = newColor.diff(this.color);
29
30
  const finalColor = newColor.clone();
30
31
  return transitionValues((p) => {
31
- this.color.r += diffR * p;
32
- this.color.g += diffG * p;
33
- this.color.b += diffB * p;
34
- this.color.a += diffA * p;
32
+ this.color.r += diff.r * p;
33
+ this.color.g += diff.g * p;
34
+ this.color.b += diff.b * p;
35
+ this.color.a += diff.a * p;
35
36
  this.vertexCache.updated();
36
37
  }, () => {
37
38
  this.color = finalColor;
@@ -42,13 +43,12 @@ export class SimulationElement {
42
43
  return this.color;
43
44
  }
44
45
  move(amount, t = 0, f) {
45
- const finalPos = vec3.create();
46
+ const finalPos = amount.length === 3 ? vector3() : vector2();
46
47
  vec3.add(finalPos, this.pos, amount);
47
48
  return transitionValues((p) => {
48
- const x = amount[0] * p;
49
- const y = amount[1] * p;
50
- const z = amount[2] * p;
51
- vec3.add(this.pos, this.pos, vector3(x, y, z));
49
+ for (let i = 0; i < this.pos.length; i++) {
50
+ this.pos[i] += amount[i] * p;
51
+ }
52
52
  this.vertexCache.updated();
53
53
  }, () => {
54
54
  this.pos = finalPos;
@@ -56,16 +56,17 @@ export class SimulationElement {
56
56
  }, t, f);
57
57
  }
58
58
  moveTo(pos, t = 0, f) {
59
- const diff = vec3.create();
59
+ const diff = pos.length === 3 ? vector3() : vector2();
60
60
  vec3.sub(diff, pos, this.pos);
61
61
  return transitionValues((p) => {
62
- const x = diff[0] * p;
63
- const y = diff[1] * p;
64
- const z = diff[2] * p;
65
- vec3.add(this.pos, this.pos, vector3(x, y, z));
62
+ for (let i = 0; i < this.pos.length; i++) {
63
+ this.pos[i] += diff[i] * p;
64
+ }
66
65
  this.vertexCache.updated();
67
66
  }, () => {
68
- this.pos = pos;
67
+ for (let i = 0; i < this.pos.length; i++) {
68
+ this.pos[i] = pos[i];
69
+ }
69
70
  this.vertexCache.updated();
70
71
  }, t, f);
71
72
  }
@@ -139,7 +140,7 @@ export class Square extends SimulationElement {
139
140
  * @param vertexColors{Record<number, Color>} - 0 is top left vertex, numbers increase clockwise
140
141
  */
141
142
  constructor(pos, width, height, color, rotation, vertexColors) {
142
- super(vector3FromVector2(pos), color);
143
+ super(pos, color);
143
144
  this.width = width * devicePixelRatio;
144
145
  this.height = height * devicePixelRatio;
145
146
  this.rotation = rotation || 0;
@@ -261,7 +262,7 @@ export class Circle extends SimulationElement {
261
262
  radius;
262
263
  detail = 100;
263
264
  constructor(pos, radius, color, detail = 50) {
264
- super(vector3FromVector2(pos), color);
265
+ super(pos, color);
265
266
  this.radius = radius * devicePixelRatio;
266
267
  this.detail = detail;
267
268
  }
@@ -431,6 +432,308 @@ export class Polygon extends SimulationElement {
431
432
  return this.vertexCache.getCache();
432
433
  }
433
434
  }
435
+ export class Line3d extends SimulationElement {
436
+ to;
437
+ toColor;
438
+ thickness;
439
+ constructor(pos, to, thickness) {
440
+ super(pos.getPos(), to.getColor() || undefined);
441
+ this.thickness = thickness;
442
+ this.toColor = to.getColor() || this.getColor();
443
+ this.to = to.getPos();
444
+ vec3.scale(this.to, devicePixelRatio, this.to);
445
+ vec3.sub(this.to, this.getPos(), this.to);
446
+ }
447
+ setStart(pos, t = 0, f) {
448
+ return this.moveTo(pos, t, f);
449
+ }
450
+ setEnd(pos, t = 0, f) {
451
+ const diff = vector3();
452
+ vec3.sub(pos, this.to, diff);
453
+ return transitionValues((p) => {
454
+ this.to[0] += diff[0] * p;
455
+ this.to[1] += diff[1] * p;
456
+ this.to[2] += diff[2] * p;
457
+ this.vertexCache.updated();
458
+ }, () => {
459
+ this.to[0] = pos[0];
460
+ this.to[1] = pos[1];
461
+ this.to[2] = pos[2];
462
+ this.vertexCache.updated();
463
+ }, t, f);
464
+ }
465
+ getBuffer(_, force) {
466
+ if (this.vertexCache.shouldUpdate() || force) {
467
+ const normal = vector2(-this.to[1], this.to[0]);
468
+ vec2.normalize(normal, normal);
469
+ vec2.scale(normal, this.thickness / 2, normal);
470
+ const pos = this.getPos();
471
+ const resBuffer = [
472
+ ...vertexBuffer3d(pos[0] + normal[0], pos[1] + normal[1], pos[2], this.getColor()),
473
+ ...vertexBuffer3d(pos[0] - normal[0], pos[1] - normal[1], pos[2], this.getColor()),
474
+ ...vertexBuffer3d(pos[0] + this.to[0] + normal[0], pos[1] + this.to[1] + normal[1], pos[2] + this.to[2], this.toColor || this.getColor()),
475
+ ...vertexBuffer3d(pos[0] - normal[0], pos[1] - normal[1], pos[2], this.getColor()),
476
+ ...vertexBuffer3d(pos[0] + this.to[0] + normal[0], pos[1] + this.to[1] + normal[1], pos[2] + this.to[2], this.toColor || this.getColor()),
477
+ ...vertexBuffer3d(pos[0] + this.to[0] - normal[0], pos[1] + this.to[1] - normal[1], pos[2] + this.to[2], this.toColor || this.getColor())
478
+ ];
479
+ this.vertexCache.setCache(resBuffer);
480
+ return resBuffer;
481
+ }
482
+ return this.vertexCache.getCache();
483
+ }
484
+ }
485
+ export class Line2d extends SimulationElement {
486
+ to;
487
+ toColor;
488
+ thickness;
489
+ constructor(from, to, thickness = 1) {
490
+ super(from.getPos(), from.getColor() || undefined);
491
+ this.thickness = thickness * devicePixelRatio;
492
+ this.toColor = to.getColor();
493
+ this.to = vector2FromVector3(to.getPos());
494
+ vec2.scale(this.to, devicePixelRatio, this.to);
495
+ vec2.sub(this.to, this.getPos(), this.to);
496
+ }
497
+ setEndColor(newColor, t = 0, f) {
498
+ if (!this.toColor)
499
+ this.toColor = this.getColor();
500
+ const diff = newColor.diff(this.toColor);
501
+ const finalColor = newColor.clone();
502
+ return transitionValues((p) => {
503
+ this.toColor.r += diff.r * p;
504
+ this.toColor.g += diff.g * p;
505
+ this.toColor.b += diff.b * p;
506
+ this.toColor.a += diff.a * p;
507
+ this.vertexCache.updated();
508
+ }, () => {
509
+ this.toColor = finalColor;
510
+ this.vertexCache.updated();
511
+ }, t, f);
512
+ }
513
+ setStart(pos, t = 0, f) {
514
+ return this.moveTo(vector3FromVector2(pos), t, f);
515
+ }
516
+ setEnd(pos, t = 0, f) {
517
+ const diff = vector3();
518
+ vec2.sub(pos, this.to, diff);
519
+ return transitionValues((p) => {
520
+ this.to[0] += diff[0] * p;
521
+ this.to[1] += diff[1] * p;
522
+ this.vertexCache.updated();
523
+ }, () => {
524
+ this.to[0] = pos[0];
525
+ this.to[1] = pos[1];
526
+ this.vertexCache.updated();
527
+ }, t, f);
528
+ }
529
+ getBuffer(camera, force) {
530
+ if (this.vertexCache.shouldUpdate() || force) {
531
+ const normal = vector2(-this.to[1], this.to[0]);
532
+ vec2.normalize(normal, normal);
533
+ vec2.scale(normal, this.thickness / 2, normal);
534
+ const screenSize = camera.getScreenSize();
535
+ const pos = this.getPos();
536
+ const resBuffer = [
537
+ ...vertexBuffer2d(pos[0] + normal[0], screenSize[1] - pos[1] + normal[1], this.getColor()),
538
+ ...vertexBuffer2d(pos[0] - normal[0], screenSize[1] - pos[1] - normal[1], this.getColor()),
539
+ ...vertexBuffer2d(pos[0] + this.to[0] + normal[0], screenSize[1] - pos[1] + this.to[1] + normal[1], this.toColor || this.getColor()),
540
+ ...vertexBuffer2d(pos[0] - normal[0], screenSize[1] - pos[1] - normal[1], this.getColor()),
541
+ ...vertexBuffer2d(pos[0] + this.to[0] + normal[0], screenSize[1] - pos[1] + this.to[1] + normal[1], this.toColor || this.getColor()),
542
+ ...vertexBuffer2d(pos[0] + this.to[0] - normal[0], screenSize[1] - pos[1] + this.to[1] - normal[1], this.toColor || this.getColor())
543
+ ];
544
+ this.vertexCache.setCache(resBuffer);
545
+ return resBuffer;
546
+ }
547
+ return this.vertexCache.getCache();
548
+ }
549
+ }
550
+ export class Cube extends SimulationElement {
551
+ vertices;
552
+ rotation;
553
+ width;
554
+ height;
555
+ depth;
556
+ wireframe;
557
+ wireframeLines;
558
+ static wireframeOrder = [
559
+ [0, 1],
560
+ [1, 2],
561
+ [2, 3],
562
+ [3, 0],
563
+ [4, 5],
564
+ [5, 6],
565
+ [6, 7],
566
+ [7, 4],
567
+ [0, 4],
568
+ [3, 7],
569
+ [1, 5],
570
+ [2, 6]
571
+ ];
572
+ constructor(pos, width, height, depth, color, rotation) {
573
+ super(pos, color);
574
+ this.width = width * devicePixelRatio;
575
+ this.height = height * devicePixelRatio;
576
+ this.depth = depth * devicePixelRatio;
577
+ this.rotation = rotation || vector3();
578
+ this.wireframe = false;
579
+ this.wireframeLines = [];
580
+ const numWireframeLines = 12;
581
+ const lineThickness = 0.025;
582
+ for (let i = 0; i < numWireframeLines; i++) {
583
+ this.wireframeLines.push(new Line3d(vertex(), vertex(), lineThickness));
584
+ }
585
+ this.vertices = [];
586
+ this.computeVertices();
587
+ this.shiftWireframeLines();
588
+ }
589
+ computeVertices() {
590
+ console.log(this.width, this.height);
591
+ this.vertices = [
592
+ // front face
593
+ vector3(-this.width / 2, -this.height / 2, this.depth / 2),
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
+ // back face
598
+ vector3(-this.width / 2, -this.height / 2, -this.depth / 2),
599
+ vector3(this.width / 2, -this.height / 2, -this.depth / 2),
600
+ vector3(this.width / 2, this.height / 2, -this.depth / 2),
601
+ vector3(-this.width / 2, this.height / 2, -this.depth / 2)
602
+ ];
603
+ }
604
+ shiftWireframeLines() {
605
+ let rotMatrix = mat4.identity();
606
+ mat4.rotateZ(rotMatrix, this.rotation[2], rotMatrix);
607
+ mat4.rotateY(rotMatrix, this.rotation[1], rotMatrix);
608
+ mat4.rotateX(rotMatrix, this.rotation[0], rotMatrix);
609
+ const pos = this.getPos();
610
+ Cube.wireframeOrder.forEach((lineVertices, index) => {
611
+ const line = this.wireframeLines[index];
612
+ const start = cloneBuf(this.vertices[lineVertices[0]]);
613
+ const endPoint = cloneBuf(this.vertices[lineVertices[1]]);
614
+ vec3.sub(endPoint, start, endPoint);
615
+ vec3.transformMat4(endPoint, rotMatrix, endPoint);
616
+ vec3.transformMat4(start, rotMatrix, start);
617
+ vec3.add(start, pos, start);
618
+ line.setStart(start);
619
+ line.setEnd(endPoint);
620
+ });
621
+ }
622
+ setWireframe(wireframe) {
623
+ this.wireframe = wireframe;
624
+ }
625
+ rotate(amount, t = 0, f) {
626
+ const finalRotation = cloneBuf(this.rotation);
627
+ vec3.add(finalRotation, amount, finalRotation);
628
+ return transitionValues((p) => {
629
+ this.rotation[0] += amount[0] * p;
630
+ this.rotation[1] += amount[1] * p;
631
+ this.rotation[2] += amount[2] * p;
632
+ this.vertexCache.updated();
633
+ }, () => {
634
+ this.rotation = finalRotation;
635
+ this.vertexCache.updated();
636
+ }, t, f);
637
+ }
638
+ setRotation(rot, t = 0, f) {
639
+ const diff = vector3();
640
+ vec3.sub(rot, this.rotation, diff);
641
+ return transitionValues((p) => {
642
+ this.rotation[0] += diff[0] * p;
643
+ this.rotation[1] += diff[1] * p;
644
+ this.rotation[2] += diff[2] * p;
645
+ this.vertexCache.updated();
646
+ }, () => {
647
+ this.rotation = rot;
648
+ this.vertexCache.updated();
649
+ }, t, f);
650
+ }
651
+ setWidth(width, t = 0, f) {
652
+ width *= devicePixelRatio;
653
+ const diff = width - this.width;
654
+ return transitionValues((p) => {
655
+ this.width += diff * p;
656
+ this.vertexCache.updated();
657
+ }, () => {
658
+ this.width = width;
659
+ this.vertexCache.updated();
660
+ }, t, f);
661
+ }
662
+ setHeight(height, t = 0, f) {
663
+ height *= devicePixelRatio;
664
+ const diff = height - this.width;
665
+ return transitionValues((p) => {
666
+ this.height += diff * p;
667
+ this.vertexCache.updated();
668
+ }, () => {
669
+ this.height = height;
670
+ this.vertexCache.updated();
671
+ }, t, f);
672
+ }
673
+ setDepth(depth, t = 0, f) {
674
+ depth *= devicePixelRatio;
675
+ const diff = depth - this.width;
676
+ return transitionValues((p) => {
677
+ this.depth += diff * p;
678
+ this.vertexCache.updated();
679
+ }, () => {
680
+ this.depth = depth;
681
+ this.vertexCache.updated();
682
+ }, t, f);
683
+ }
684
+ scale(amount, t = 0, f) {
685
+ const finalWidth = this.width * amount;
686
+ const finalHeight = this.height * amount;
687
+ const finalDepth = this.depth * amount;
688
+ const widthDiff = finalWidth - this.width;
689
+ const heightDiff = finalHeight - this.height;
690
+ const depthDiff = finalDepth - this.depth;
691
+ return transitionValues((p) => {
692
+ this.width += widthDiff * p;
693
+ this.height += heightDiff * p;
694
+ this.depth += depthDiff * p;
695
+ this.vertexCache.updated();
696
+ }, () => {
697
+ this.width = finalWidth;
698
+ this.height = finalHeight;
699
+ this.depth = finalDepth;
700
+ this.vertexCache.updated();
701
+ }, t, f);
702
+ }
703
+ getBuffer(camera, force) {
704
+ if (this.vertexCache.shouldUpdate() || force) {
705
+ this.computeVertices();
706
+ this.shiftWireframeLines();
707
+ const triangleOrder = [
708
+ 0, 1, 2, 0, 2, 3,
709
+ 4, 5, 6, 4, 6, 7,
710
+ 0, 3, 7, 0, 7, 4,
711
+ 0, 4, 5, 0, 5, 1,
712
+ 1, 2, 6, 1, 5, 6,
713
+ 2, 3, 7, 2, 6, 7
714
+ ];
715
+ let rotMatrix = mat4.identity();
716
+ mat4.rotateZ(rotMatrix, this.rotation[2], rotMatrix);
717
+ mat4.rotateY(rotMatrix, this.rotation[1], rotMatrix);
718
+ mat4.rotateX(rotMatrix, this.rotation[0], rotMatrix);
719
+ const pos = this.getPos();
720
+ let resBuffer = [];
721
+ triangleOrder.forEach((index) => {
722
+ const vertex = cloneBuf(this.vertices[index]);
723
+ vec3.transformMat4(vertex, rotMatrix, vertex);
724
+ resBuffer = resBuffer.concat(vertexBuffer3d(vertex[0] + pos[0], vertex[1] + pos[1], vertex[2] + pos[2], this.getColor()));
725
+ });
726
+ if (this.wireframe) {
727
+ this.wireframeLines.forEach((line) => {
728
+ resBuffer = resBuffer.concat(line.getBuffer(camera, force));
729
+ });
730
+ }
731
+ this.vertexCache.setCache(resBuffer);
732
+ return resBuffer;
733
+ }
734
+ return this.vertexCache.getCache();
735
+ }
736
+ }
434
737
  export class BezierCurve2d {
435
738
  points;
436
739
  constructor(points) {
@@ -557,14 +860,14 @@ export class SplinePoint2d {
557
860
  }
558
861
  export class Spline2d extends SimulationElement {
559
862
  curves;
560
- width;
863
+ thickness;
561
864
  detail;
562
865
  interpolateLimit;
563
866
  distance;
564
- constructor(pos, points, width = 2, detail = 40) {
867
+ constructor(pos, points, thickness = devicePixelRatio, detail = 40) {
565
868
  super(pos.getPos(), pos.getColor() || undefined);
566
869
  this.curves = [];
567
- this.width = width * devicePixelRatio;
870
+ this.thickness = thickness * devicePixelRatio;
568
871
  this.detail = detail;
569
872
  this.interpolateLimit = 1;
570
873
  this.distance = 0;
@@ -623,7 +926,7 @@ export class Spline2d extends SimulationElement {
623
926
  point[1] += screenSize[1] - pos[1];
624
927
  const normal = vector2(-slope[1], slope[0]);
625
928
  vec2.normalize(normal, normal);
626
- vec2.scale(normal, this.width / 2, normal);
929
+ vec2.scale(normal, this.thickness / 2, normal);
627
930
  const colors = this.curves[i].getColors().map((c) => (c ? c : this.getColor()));
628
931
  const vertexColor = interpolateColors(colors, currentInterpolation);
629
932
  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';
@@ -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;
@@ -25,7 +25,7 @@ export declare class SceneCollection extends SimulationElement {
25
25
  private scene;
26
26
  constructor(name: string);
27
27
  getName(): string;
28
- add(el: SimulationElement): void;
28
+ add(el: SimulationElement<any>): void;
29
29
  empty(): void;
30
30
  getBuffer(camera: Camera, force: boolean): number[];
31
31
  }
@@ -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(n: number): number;
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(n) {
241
- return n;
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];
package/package.json CHANGED
@@ -5,18 +5,13 @@
5
5
  "types": "./dist/index.d.ts",
6
6
  "author": "Jackson Otto",
7
7
  "description": "A simple graphics library using WebGPU",
8
- "version": "0.1.10",
8
+ "version": "0.2.1",
9
9
  "exports": {
10
10
  ".": {
11
11
  "import": "./dist/index.js",
12
12
  "types": "./dist/index.d.ts"
13
13
  }
14
14
  },
15
- "scripts": {
16
- "dev": "npx nodemon --watch src -e ts --exec 'npx tsc || exit 1'",
17
- "test": "vite --port 3000",
18
- "build": "npx tsc"
19
- },
20
15
  "devDependencies": {
21
16
  "nodemon": "^3.0.1",
22
17
  "typescript": "^5.1.6",
@@ -25,5 +20,10 @@
25
20
  "dependencies": {
26
21
  "@webgpu/types": "^0.1.34",
27
22
  "wgpu-matrix": "^2.5.1"
23
+ },
24
+ "scripts": {
25
+ "dev": "npx nodemon --watch src -e ts --exec 'npx tsc || exit 1'",
26
+ "test": "vite --port 3000",
27
+ "build": "npx tsc"
28
28
  }
29
- }
29
+ }