simulationjsv2 0.1.3 → 0.1.5

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,5 +1,5 @@
1
1
  import { Camera, Color } from './simulation.js';
2
- import type { Vector2, Vector3, LerpFunc, VertexColorMap } from './types.js';
2
+ import type { Vector2, Vector3, LerpFunc, VertexColorMap, Vector4 } from './types.js';
3
3
  declare class VertexCache {
4
4
  private vertices;
5
5
  private hasUpdated;
@@ -10,14 +10,22 @@ declare class VertexCache {
10
10
  shouldUpdate(): boolean;
11
11
  getVertexCount(): number;
12
12
  }
13
- declare class Vertex {
14
- private readonly pos;
15
- private readonly color;
16
- private readonly is3d;
13
+ export declare class Vertex {
14
+ private pos;
15
+ private color;
16
+ private is3d;
17
17
  private readonly uv;
18
18
  constructor(x?: number, y?: number, z?: number, color?: Color, is3dPoint?: boolean, uv?: Vector2);
19
19
  getPos(): Vector3;
20
20
  getColor(): Color | null;
21
+ getUv(): Vector2;
22
+ setColor(color: Color): void;
23
+ setPos(pos: Vector3): void;
24
+ setX(x: number): void;
25
+ setY(y: number): void;
26
+ setZ(z: number): void;
27
+ setIs3d(is3d: boolean): void;
28
+ clone(): Vertex;
21
29
  toBuffer(defaultColor: Color): number[];
22
30
  }
23
31
  export declare abstract class SimulationElement {
@@ -38,7 +46,7 @@ export declare abstract class SimulationElement {
38
46
  export declare class Plane extends SimulationElement {
39
47
  private points;
40
48
  private rotation;
41
- constructor(pos: Vector3, points: Vertex[], rotation?: Vector3, color?: Color);
49
+ constructor(pos: Vector3, points: Vertex[], color?: Color, rotation?: Vector3);
42
50
  setPoints(newPoints: Vertex[]): void;
43
51
  rotate(amount: Vector3, t?: number, f?: LerpFunc): Promise<void>;
44
52
  rotateTo(angle: Vector3, t?: number, f?: LerpFunc): Promise<void>;
@@ -49,6 +57,7 @@ export declare class Square extends SimulationElement {
49
57
  private height;
50
58
  private rotation;
51
59
  private vertexColors;
60
+ private points;
52
61
  /**
53
62
  * @param vertexColors{Record<number, Color>} - 0 is top left vertex, numbers increase clockwise
54
63
  */
@@ -71,20 +80,22 @@ export declare class Circle extends SimulationElement {
71
80
  getBuffer(camera: Camera, force: boolean): number[];
72
81
  }
73
82
  export declare class Polygon extends SimulationElement {
74
- private points;
83
+ private vertices;
75
84
  private rotation;
76
- constructor(pos: Vector3, points: Vector2[], color?: Color);
85
+ constructor(pos: Vector3, vertices: Vertex[], color?: Color);
77
86
  rotate(amount: number, t?: number, f?: LerpFunc): Promise<void>;
78
87
  rotateTo(num: number, t?: number, f?: LerpFunc): Promise<void>;
79
- setPoints(newPoints: Vector3[], t?: number, f?: LerpFunc): Promise<void>;
80
- getBuffer(): never[];
88
+ setPoints(newVertices: Vertex[], t?: number, f?: LerpFunc): Promise<void>;
89
+ getBuffer(camera: Camera, force: boolean): number[];
81
90
  }
91
+ export declare function vector4(x?: number, y?: number, z?: number, w?: number): Vector4;
82
92
  export declare function vector3(x?: number, y?: number, z?: number): Vector3;
83
93
  export declare function vector2(x?: number, y?: number): Vector2;
84
94
  export declare function vec3fromVec2(vec: Vector2): Vector3;
95
+ export declare function colorFromVec4(vec: Vector4): Color;
85
96
  export declare function randomInt(range: number, min?: number): number;
86
97
  export declare function randomColor(a?: number): Color;
87
- export declare function vertex(x?: number, y?: number, z?: number, color?: Color): Vertex;
98
+ export declare function vertex(x?: number, y?: number, z?: number, color?: Color, is3dPoint?: boolean, uv?: Vector2): Vertex;
88
99
  export declare function color(r?: number, g?: number, b?: number, a?: number): Color;
89
100
  export declare function colorf(val: number, a?: number): Color;
90
101
  export {};
package/dist/graphics.js CHANGED
@@ -1,4 +1,4 @@
1
- import { vec3, quat, mat4, vec2 } from 'wgpu-matrix';
1
+ import { vec3, quat, mat4, vec2, vec4 } from 'wgpu-matrix';
2
2
  import { Color, transitionValues } from './simulation.js';
3
3
  import { BUF_LEN } from './constants.js';
4
4
  class VertexCache {
@@ -22,7 +22,7 @@ class VertexCache {
22
22
  return this.vertices.length / BUF_LEN;
23
23
  }
24
24
  }
25
- class Vertex {
25
+ export class Vertex {
26
26
  pos;
27
27
  color;
28
28
  is3d;
@@ -39,11 +39,35 @@ class Vertex {
39
39
  getColor() {
40
40
  return this.color;
41
41
  }
42
+ getUv() {
43
+ return this.uv;
44
+ }
45
+ setColor(color) {
46
+ this.color = color;
47
+ }
48
+ setPos(pos) {
49
+ this.pos = pos;
50
+ }
51
+ setX(x) {
52
+ this.pos[0] = x;
53
+ }
54
+ setY(y) {
55
+ this.pos[1] = y;
56
+ }
57
+ setZ(z) {
58
+ this.pos[2] = z;
59
+ }
60
+ setIs3d(is3d) {
61
+ this.is3d = is3d;
62
+ }
63
+ clone() {
64
+ return new Vertex(this.pos[0], this.pos[1], this.pos[2], this.color?.clone(), this.is3d, cloneBuf(this.uv));
65
+ }
42
66
  toBuffer(defaultColor) {
43
67
  if (this.is3d)
44
- return vertexBuffer3d(this.pos, this.color || defaultColor, this.uv);
68
+ return vertexBuffer3d(this.pos[0], this.pos[1], this.pos[2], this.color || defaultColor, this.uv);
45
69
  else
46
- return vertexBuffer2d(this.pos, this.color || defaultColor, this.uv);
70
+ return vertexBuffer2d(this.pos[0], this.pos[1], this.color || defaultColor, this.uv);
47
71
  }
48
72
  }
49
73
  export class SimulationElement {
@@ -119,7 +143,7 @@ export class SimulationElement {
119
143
  export class Plane extends SimulationElement {
120
144
  points;
121
145
  rotation;
122
- constructor(pos, points, rotation = vector3(), color) {
146
+ constructor(pos, points, color, rotation = vector3()) {
123
147
  super(pos, color);
124
148
  this.points = points;
125
149
  this.rotation = rotation;
@@ -155,8 +179,8 @@ export class Plane extends SimulationElement {
155
179
  }
156
180
  getBuffer(_, force) {
157
181
  if (this.vertexCache.shouldUpdate() || force) {
158
- const resBuffer = [];
159
- const triangles = generateTriangles(this.points).flat();
182
+ let resBuffer = [];
183
+ const triangles = lossyTriangulate(this.points).flat();
160
184
  triangles.forEach((verticy) => {
161
185
  const rot = quat.create();
162
186
  quat.fromEuler(...this.rotation, 'xyz', rot);
@@ -167,7 +191,7 @@ export class Plane extends SimulationElement {
167
191
  vec3.add(out, this.getPos(), out);
168
192
  let vertexColor = verticy.getColor();
169
193
  vertexColor = vertexColor ? vertexColor : this.getColor();
170
- resBuffer.push(...vertexBuffer3d(out, vertexColor));
194
+ resBuffer = resBuffer.concat(vertexBuffer3d(out[0], out[1], out[2], vertexColor));
171
195
  });
172
196
  this.vertexCache.setCache(resBuffer);
173
197
  return resBuffer;
@@ -180,6 +204,7 @@ export class Square extends SimulationElement {
180
204
  height;
181
205
  rotation;
182
206
  vertexColors;
207
+ points;
183
208
  /**
184
209
  * @param vertexColors{Record<number, Color>} - 0 is top left vertex, numbers increase clockwise
185
210
  */
@@ -189,6 +214,12 @@ export class Square extends SimulationElement {
189
214
  this.height = height * devicePixelRatio;
190
215
  this.rotation = rotation || 0;
191
216
  this.vertexColors = vertexColors || {};
217
+ this.points = [
218
+ vector2(this.width / 2, this.height / 2),
219
+ vector2(-this.width / 2, this.height / 2),
220
+ vector2(-this.width / 2, -this.height / 2),
221
+ vector2(this.width / 2, -this.height / 2)
222
+ ];
192
223
  }
193
224
  scaleWidth(amount, t = 0, f) {
194
225
  const finalWidth = this.width * amount;
@@ -270,29 +301,25 @@ export class Square extends SimulationElement {
270
301
  }, t, f);
271
302
  }
272
303
  getBuffer(camera, force) {
273
- const resBuffer = [];
274
304
  if (this.vertexCache.shouldUpdate() || force) {
275
- const points = [
276
- vector2(this.width / 2, this.height / 2),
277
- vector2(-this.width / 2, this.height / 2),
278
- vector2(-this.width / 2, -this.height / 2),
279
- vector2(this.width / 2, -this.height / 2)
280
- ].map((vec) => {
281
- const mat = mat4.identity();
282
- mat4.rotateZ(mat, this.rotation, mat);
283
- vec2.transformMat4(vec, mat, vec);
305
+ let resBuffer = [];
306
+ const vertexOrder = [0, 1, 2, 0, 2, 3];
307
+ const rotationMat = mat4.identity();
308
+ mat4.rotateZ(rotationMat, this.rotation, rotationMat);
309
+ const points = this.points.map((vec) => {
284
310
  const pos = vector2();
285
- vec2.clone(this.getPos(), pos);
311
+ vec2.add(vec, pos, pos);
312
+ vec2.transformMat4(vec, rotationMat, pos);
313
+ vec2.add(vec, this.getPos(), pos);
286
314
  pos[1] = camera.getScreenSize()[1] - pos[1];
287
- vec2.add(pos, vector2(this.width / 2, -this.height / 2), pos);
288
- vec2.add(vec, pos, vec);
289
- return vec;
315
+ pos[0] += this.width / 2;
316
+ pos[1] -= this.height / 2;
317
+ return pos;
290
318
  });
291
- const vertexOrder = [0, 1, 2, 0, 2, 3];
292
319
  vertexOrder.forEach((vertex) => {
293
320
  let vertexColor = this.vertexColors[vertex];
294
321
  vertexColor = vertexColor ? vertexColor : this.getColor();
295
- resBuffer.push(...vertexBuffer2d(vec3fromVec2(points[vertex]), vertexColor));
322
+ resBuffer = resBuffer.concat(vertexBuffer2d(points[vertex][0], points[vertex][1], vertexColor));
296
323
  });
297
324
  this.vertexCache.setCache(resBuffer);
298
325
  return resBuffer;
@@ -343,7 +370,7 @@ export class Circle extends SimulationElement {
343
370
  const screenSize = camera.getScreenSize();
344
371
  points.push(new Vertex(vec[0], screenSize[1] - vec[1], vec[2], this.getColor(), false));
345
372
  }
346
- const vertices = generateTriangles(points).reduce((acc, curr) => {
373
+ const vertices = lossyTriangulate(points).reduce((acc, curr) => {
347
374
  curr.forEach((vertex) => acc.push(...vertex.toBuffer(this.getColor())));
348
375
  return acc;
349
376
  }, []);
@@ -354,15 +381,15 @@ export class Circle extends SimulationElement {
354
381
  }
355
382
  }
356
383
  export class Polygon extends SimulationElement {
357
- points;
384
+ vertices;
358
385
  rotation = 0;
359
- /*
360
- * points adjusted for device pixel ratio
361
- */
362
- constructor(pos, points, color) {
386
+ constructor(pos, vertices, color) {
363
387
  super(pos, color);
364
- this.points = points.map((point) => {
365
- return new Vertex(point[0], point[1], 0, this.getColor(), false);
388
+ this.vertices = vertices.map((vertex) => {
389
+ const newVertex = vertex.clone();
390
+ newVertex.setZ(0);
391
+ newVertex.setIs3d(false);
392
+ return vertex;
366
393
  });
367
394
  }
368
395
  rotate(amount, t = 0, f) {
@@ -383,66 +410,96 @@ export class Polygon extends SimulationElement {
383
410
  this.rotation = num;
384
411
  }, t, f);
385
412
  }
386
- setPoints(newPoints, t = 0, f) {
387
- const points = newPoints.map((point) => {
388
- const vec = vector3(...point);
389
- return vec;
413
+ setPoints(newVertices, t = 0, f) {
414
+ const vertices = newVertices.map((vert) => {
415
+ const newVertex = vert.clone();
416
+ newVertex.setZ(0);
417
+ newVertex.setIs3d(false);
418
+ return newVertex;
390
419
  });
391
- const lastPoint = this.points.length > 0 ? this.points[this.points.length - 1] : vec3.create();
392
- if (points.length > this.points.length) {
393
- while (points.length > this.points.length) {
394
- this.points.push(new Vertex(lastPoint[0], lastPoint[1], 0, this.getColor(), false));
420
+ const lastVert = this.vertices.length > 0 ? this.vertices[this.vertices.length - 1] : vertex(0, 0, 0, color(), false);
421
+ if (vertices.length > this.vertices.length) {
422
+ while (vertices.length > this.vertices.length) {
423
+ const lastPos = lastVert.getPos();
424
+ this.vertices.push(new Vertex(lastPos[0], lastPos[1], 0, lastVert.getColor() || this.getColor(), false));
395
425
  }
396
426
  }
397
- const initial = this.points.map((p) => vector3(...p.getPos()));
398
- const changes = [
399
- ...points.map((p, i) => {
400
- const vec = vec3.create();
401
- vec3.sub(vec, p, this.points[i]);
402
- return vec;
427
+ const initialPositions = this.vertices.map((p) => cloneBuf(p.getPos()));
428
+ const posChanges = [
429
+ ...vertices.map((vert, i) => {
430
+ const vec = vector3();
431
+ vec3.sub(vert.getPos(), this.vertices[i].getPos(), vec);
432
+ return cloneBuf(vec);
403
433
  }),
404
- ...this.points.slice(points.length, this.points.length).map((point) => {
405
- const vec = vector3(...points[points.length - 1]) || vec3.create();
406
- vec3.sub(vec, vec, point);
407
- return vec;
408
- })
434
+ ...(this.vertices.length > vertices.length
435
+ ? this.vertices.slice(vertices.length, this.vertices.length).map((vert) => {
436
+ const vec = cloneBuf(vertices[vertices.length - 1].getPos());
437
+ vec3.sub(vec, vert.getPos(), vec);
438
+ return vec;
439
+ })
440
+ : [])
441
+ ];
442
+ const initialColors = this.vertices.map((vert) => (vert.getColor() || this.getColor()).toVec4());
443
+ const colorChanges = [
444
+ ...vertices.map((vert, i) => {
445
+ const diff = (vert.getColor() || this.getColor()).diff(this.vertices[i].getColor() || this.getColor());
446
+ return diff.toVec4();
447
+ }),
448
+ ...(this.vertices.length > vertices.length
449
+ ? this.vertices.slice(vertices.length, this.vertices.length).map((vert) => {
450
+ const toColor = vertices[vertices.length - 1].getColor();
451
+ return (toColor || this.getColor()).diff(vert.getColor() || this.getColor()).toVec4();
452
+ })
453
+ : [])
409
454
  ];
410
455
  return transitionValues((p) => {
411
- this.points = this.points.map((point, i) => {
412
- const change = vector3(...changes[i]);
413
- vec3.scale(change, change, p);
414
- vec3.add(point, point, change);
415
- return point;
456
+ this.vertices.forEach((vert, i) => {
457
+ const posChange = cloneBuf(posChanges[i]);
458
+ const colorChange = cloneBuf(colorChanges[i]);
459
+ vec3.scale(posChange, p, posChange);
460
+ vec3.add(vert.getPos(), posChange, posChange);
461
+ vec4.scale(colorChange, p, colorChange);
462
+ vec4.add((vert.getColor() || this.getColor()).toVec4(), colorChange, colorChange);
463
+ vert.setPos(posChange);
464
+ vert.setColor(colorFromVec4(colorChange));
416
465
  });
417
466
  this.vertexCache.updated();
418
467
  }, () => {
419
- this.points = initial.map((p, i) => {
420
- const vec = vec3.create();
421
- vec3.add(vec, p, changes[i]);
422
- return vec;
468
+ this.vertices.forEach((vert, i) => {
469
+ const initPos = initialPositions[i];
470
+ const initColor = initialColors[i];
471
+ vec3.add(initPos, posChanges[i], initPos);
472
+ vec4.add(initColor, colorChanges[i], initColor);
473
+ vert.setPos(initPos);
474
+ vert.setColor(colorFromVec4(initColor));
423
475
  });
424
- this.points.splice(points.length, this.points.length);
476
+ this.vertices.splice(vertices.length, this.vertices.length);
425
477
  this.vertexCache.updated();
426
478
  }, t, f);
427
479
  }
428
- getBuffer() {
429
- // let triangles: Triangles = [];
430
- // if (this.triangleCache.shouldUpdate()) {
431
- // let newPoints: vec3[] = this.points.map((vec) => {
432
- // const newPoint = vec3.create();
433
- // vec3.add(newPoint, vec, this.getPos());
434
- // return newPoint;
435
- // });
436
- // triangles = generateTriangles(newPoints);
437
- // this.triangleCache.setCache(triangles);
438
- // } else {
439
- // triangles = this.triangleCache.getCache();
440
- // }
441
- // return trianglesAndColorToBuffer(triangles, this.getColor());
442
- return [];
480
+ getBuffer(camera, force) {
481
+ if (this.vertexCache.shouldUpdate() || force) {
482
+ let resBuffer = [];
483
+ const rotationMat = mat4.identity();
484
+ mat4.rotateZ(rotationMat, this.rotation, rotationMat);
485
+ lossyTriangulate(this.vertices)
486
+ .flat()
487
+ .forEach((vert) => {
488
+ const pos = vector3();
489
+ vec3.add(vert.getPos(), pos, pos);
490
+ vec3.transformMat4(pos, rotationMat, pos);
491
+ vec3.add(this.getPos(), pos, pos);
492
+ pos[1] = camera.getScreenSize()[1] - pos[1];
493
+ resBuffer = resBuffer.concat(vertexBuffer2d(pos[0], pos[1], vert.getColor() || this.getColor()));
494
+ });
495
+ this.vertexCache.setCache(resBuffer);
496
+ return resBuffer;
497
+ }
498
+ return this.vertexCache.getCache();
443
499
  }
444
500
  }
445
- function generateTriangles(vertices) {
501
+ // optomized for speed, depending on orientation of vertices as input, shape may not be preserved
502
+ function lossyTriangulate(vertices) {
446
503
  const res = [];
447
504
  let facingRight = true;
448
505
  let rightOffset = 0;
@@ -470,11 +527,20 @@ function generateTriangles(vertices) {
470
527
  }
471
528
  return res;
472
529
  }
473
- function vertexBuffer3d(point, color, uv = vector2()) {
474
- return [...point, 1, ...color.toBuffer(), ...uv, 1];
530
+ function vertexBuffer3d(x, y, z, color, uv = vector2()) {
531
+ return [x, y, z, 1, ...color.toBuffer(), ...uv, 1];
475
532
  }
476
- function vertexBuffer2d(point, color, uv = vector2()) {
477
- return [...point, 1, ...color.toBuffer(), ...uv, 0];
533
+ function vertexBuffer2d(x, y, color, uv = vector2()) {
534
+ return [x, y, 0, 1, ...color.toBuffer(), ...uv, 0];
535
+ }
536
+ function vec3ToPixelRatio(vec) {
537
+ vec3.mul(vec, vector3(devicePixelRatio, devicePixelRatio, devicePixelRatio), vec);
538
+ }
539
+ function cloneBuf(buf) {
540
+ return new Float32Array(buf);
541
+ }
542
+ export function vector4(x = 0, y = 0, z = 0, w = 0) {
543
+ return vec4.fromValues(x, y, z, w);
478
544
  }
479
545
  export function vector3(x = 0, y = 0, z = 0) {
480
546
  return vec3.fromValues(x, y, z);
@@ -482,20 +548,20 @@ export function vector3(x = 0, y = 0, z = 0) {
482
548
  export function vector2(x = 0, y = 0) {
483
549
  return vec2.fromValues(x, y, 0);
484
550
  }
485
- function vec3ToPixelRatio(vec) {
486
- vec3.mul(vec, vector3(devicePixelRatio, devicePixelRatio, devicePixelRatio), vec);
487
- }
488
551
  export function vec3fromVec2(vec) {
489
552
  return vector3(vec[0], vec[1]);
490
553
  }
554
+ export function colorFromVec4(vec) {
555
+ return new Color(vec[0], vec[1], vec[2], vec[3]);
556
+ }
491
557
  export function randomInt(range, min = 0) {
492
558
  return Math.floor(Math.random() * (range - min)) + min;
493
559
  }
494
560
  export function randomColor(a = 1) {
495
561
  return new Color(randomInt(255), randomInt(255), randomInt(255), a);
496
562
  }
497
- export function vertex(x, y, z, color) {
498
- return new Vertex(x, y, z, color);
563
+ export function vertex(x, y, z, color, is3dPoint, uv) {
564
+ return new Vertex(x, y, z, color, is3dPoint, uv);
499
565
  }
500
566
  export function color(r, g, b, a) {
501
567
  return new Color(r, g, b, a);
@@ -55,12 +55,14 @@ export declare class Color {
55
55
  constructor(r?: number, g?: number, b?: number, a?: number);
56
56
  clone(): Color;
57
57
  toBuffer(): readonly [number, number, number, number];
58
+ toVec4(): import("./types.js").Vector4;
58
59
  toObject(): {
59
60
  r: number;
60
61
  g: number;
61
62
  b: number;
62
63
  a: number;
63
64
  };
65
+ diff(color: Color): Color;
64
66
  }
65
67
  /**
66
68
  * @param callback1 - called every frame until the animation is finished
@@ -1,5 +1,5 @@
1
1
  import { vec3 } from 'wgpu-matrix';
2
- import { SimulationElement, vector2, vector3 } from './graphics.js';
2
+ import { SimulationElement, vector2, vector3, vector4 } from './graphics.js';
3
3
  import { BUF_LEN } from './constants.js';
4
4
  import { applyElementToScene, buildDepthTexture, buildProjectionMatrix, getOrthoMatrix, getTransformationMatrix, logger } from './utils.js';
5
5
  const vertexSize = 44; // 4 * 10 + 1
@@ -281,7 +281,7 @@ export class Simulation {
281
281
  // sub 10 to start with a reasonable gap between starting time and next frame time
282
282
  let prev = Date.now() - 10;
283
283
  let prevFps = 0;
284
- const frame = () => {
284
+ const frame = async () => {
285
285
  if (!this.running || !canvas)
286
286
  return;
287
287
  requestAnimationFrame(frame);
@@ -317,11 +317,11 @@ export class Simulation {
317
317
  orthoMatrix.buffer, orthoMatrix.byteOffset, orthoMatrix.byteLength);
318
318
  device.queue.writeBuffer(uniformBuffer, 4 * 16 + 4 * 16, // 4x4 matrix + 4x4 matrix
319
319
  screenSize.buffer, screenSize.byteOffset, screenSize.byteLength);
320
- const vertexArray = [];
321
- this.scene.forEach((obj) => {
322
- const buffer = obj.getBuffer(this.camera, this.camera.hasUpdated());
323
- buffer.forEach((vertex) => vertexArray.push(vertex));
324
- });
320
+ let vertexArray = [];
321
+ for (let i = 0; i < this.scene.length; i++) {
322
+ const buffer = this.scene[i].getBuffer(this.camera, this.camera.hasUpdated());
323
+ vertexArray = vertexArray.concat(buffer);
324
+ }
325
325
  this.camera.updateConsumed();
326
326
  const vertexF32Array = new Float32Array(vertexArray);
327
327
  const vertexBuffer = device.createBuffer({
@@ -486,6 +486,9 @@ export class Color {
486
486
  toBuffer() {
487
487
  return [this.r / 255, this.g / 255, this.b / 255, this.a];
488
488
  }
489
+ toVec4() {
490
+ return vector4(this.r, this.g, this.b, this.a);
491
+ }
489
492
  toObject() {
490
493
  return {
491
494
  r: this.r / 255,
@@ -494,6 +497,9 @@ export class Color {
494
497
  a: this.a
495
498
  };
496
499
  }
500
+ diff(color) {
501
+ return new Color(this.r - color.r, this.g - color.g, this.b - color.b, this.a - color.a);
502
+ }
497
503
  }
498
504
  /**
499
505
  * @param callback1 - called every frame until the animation is finished
package/dist/types.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import { Color } from './simulation.js';
2
+ export type Vector4 = Float32Array & [number, number, number, number];
2
3
  export type Vector3 = Float32Array & [number, number, number];
3
4
  export type Vector2 = Float32Array & [number, number];
4
5
  export type LerpFunc = (n: number) => number;
package/package.json CHANGED
@@ -5,7 +5,7 @@
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.3",
8
+ "version": "0.1.5",
9
9
  "exports": {
10
10
  ".": {
11
11
  "import": "./dist/index.js",