@woosh/meep-engine 2.79.0 → 2.80.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.
Files changed (45) hide show
  1. package/build/meep.cjs +178 -198
  2. package/build/meep.min.js +1 -1
  3. package/build/meep.module.js +178 -198
  4. package/package.json +1 -1
  5. package/src/core/geom/2d/aabb/AABB2.js +6 -18
  6. package/src/core/geom/3d/SurfacePoint3.spec.js +1 -1
  7. package/src/core/geom/3d/{matrix → mat4}/m4_multiply.spec.js +3 -4
  8. package/src/core/geom/3d/{matrix → mat4}/m4_multiply_alphatensor.spec.js +3 -3
  9. package/src/core/geom/3d/morton/v3_morton_encode_transformed.spec.js +1 -1
  10. package/src/core/geom/3d/sphere/sphere_radius_sqr_from_v3_array_transformed.spec.js +1 -1
  11. package/src/core/geom/Vector3.js +2 -2
  12. package/src/core/geom/Vector3.spec.js +2 -2
  13. package/src/core/geom/packing/max-rect/{MaxRectangles.js → MaxRectanglesPacker.js} +25 -32
  14. package/src/core/geom/packing/max-rect/MaxRectanglesPacker.spec.js +60 -0
  15. package/src/core/geom/packing/max-rect/packMaxRectangles.js +19 -0
  16. package/src/core/graph/cluster_mesh_metis.js +3 -3
  17. package/src/core/graph/metis/metis.js +16 -1
  18. package/src/core/graph/metis/metis_options.js +32 -29
  19. package/src/core/math/interval/overlap1D.js +7 -0
  20. package/src/core/math/noise/create_simplex_noise_2d.js +4 -0
  21. package/src/core/math/spline/computeCatmullRomSplineUniformDistance.js +3 -3
  22. package/src/core/math/spline/v3_computeCatmullRomSplineUniformDistance.js +42 -0
  23. package/src/core/model/node-graph/node/NodeDescription.js +12 -10
  24. package/src/core/model/node-graph/node/NodeDescription.spec.js +14 -1
  25. package/src/core/model/object/objectKeyByValue.js +3 -2
  26. package/src/engine/ecs/renderable/Renderable.js +1 -1
  27. package/src/engine/ecs/terrain/ecs/TerrainSystem.js +1 -1
  28. package/src/engine/ecs/terrain/tiles/TerrainTile.spec.js +2 -2
  29. package/src/engine/ecs/transform/Transform.js +3 -3
  30. package/src/engine/ecs/transform/Transform.spec.js +3 -3
  31. package/src/engine/graphics/ecs/path/entity/testEntityPath.js +16 -10
  32. package/src/engine/graphics/material/optimization/MaterialOptimizationContext.js +1 -1
  33. package/src/engine/graphics/texture/atlas/TextureAtlas.js +1 -1
  34. package/src/engine/graphics/texture/atlas/gpu/WebGLTextureAtlas.js +3 -3
  35. package/src/engine/graphics/three/expand_aabb_by_transformed_three_object.js +1 -1
  36. package/src/engine/graphics/three/expand_aabb_by_transformed_three_object.spec.js +2 -2
  37. package/src/engine/navigation/ecs/components/Path.js +5 -12
  38. package/src/engine/simulation/Ticker.js +40 -61
  39. package/src/core/geom/LineSegment.js +0 -207
  40. /package/src/core/geom/3d/{matrix → mat4}/MATRIX_4_IDENTITY.js +0 -0
  41. /package/src/core/geom/3d/{matrix → mat4}/MATRIX_4_IDENTITY.spec.js +0 -0
  42. /package/src/core/geom/3d/{matrix → mat4}/allocate_transform_m4.js +0 -0
  43. /package/src/core/geom/3d/{matrix → mat4}/m4_make_translation.js +0 -0
  44. /package/src/core/geom/3d/{matrix → mat4}/m4_multiply.js +0 -0
  45. /package/src/core/geom/3d/{matrix → mat4}/m4_multiply_alphatensor.js +0 -0
@@ -2220,7 +2220,7 @@ let Vector3$1 = class Vector3 {
2220
2220
 
2221
2221
  /**
2222
2222
  *
2223
- * @param {number[]} array
2223
+ * @param {number[]|Float32Array} array
2224
2224
  * @param {number} offset
2225
2225
  */
2226
2226
  readFromArray(array, offset = 0) {
@@ -2233,7 +2233,7 @@ let Vector3$1 = class Vector3 {
2233
2233
 
2234
2234
  /**
2235
2235
  *
2236
- * @param {number[]} array
2236
+ * @param {number[]|Float32Array} array
2237
2237
  * @param {number} offset
2238
2238
  */
2239
2239
  writeToArray(array, offset = 0) {
@@ -77619,10 +77619,11 @@ class ShadedGeometrySystem extends System {
77619
77619
  }
77620
77620
 
77621
77621
  /**
77622
- *
77622
+ * Given an object and a value, find the first property with matching value and returns name of that property
77623
+ * Useful for working with ENUM-like objects
77623
77624
  * @param {Object<T>} object
77624
77625
  * @param {T} value
77625
- * @returns {string|undefined}
77626
+ * @returns {string|undefined} name of the property, or undefined if property not found
77626
77627
  */
77627
77628
  function objectKeyByValue(object, value) {
77628
77629
  for (let i in object) {
@@ -79230,46 +79231,6 @@ Stats.Panel = function ( name, fg, bg ) {
79230
79231
 
79231
79232
  };
79232
79233
 
79233
- /**
79234
- *
79235
- * @param {number} ax0
79236
- * @param {number} ay0
79237
- * @param {number} ax1
79238
- * @param {number} ay1
79239
- * @param {number} bx0
79240
- * @param {number} by0
79241
- * @param {number} bx1
79242
- * @param {number} by1
79243
- * @param {AABB2} result
79244
- * @returns {boolean} true if overlap exists, false if no overlap
79245
- */
79246
- function aabb2_compute_overlap(
79247
- ax0, ay0, ax1, ay1,
79248
- bx0, by0, bx1, by1,
79249
- result
79250
- ) {
79251
-
79252
- const x0 = max2(ax0, bx0);
79253
- const x1 = min2(ax1, bx1);
79254
-
79255
- if (x0 >= x1) {
79256
- //no overlap
79257
- return false;
79258
- }
79259
-
79260
- const y0 = max2(ay0, by0);
79261
- const y1 = min2(ay1, by1);
79262
-
79263
- if (y0 >= y1) {
79264
- //no overlap
79265
- return false;
79266
- }
79267
-
79268
- result.set(x0, y0, x1, y1);
79269
-
79270
- return true;
79271
- }
79272
-
79273
79234
  /**
79274
79235
  *
79275
79236
  * Find intersection point between two line segments if they intersect at all
@@ -79354,6 +79315,46 @@ function line_segment_compute_line_segment_intersection_2d(
79354
79315
  return collision;
79355
79316
  }
79356
79317
 
79318
+ /**
79319
+ *
79320
+ * @param {number} ax0
79321
+ * @param {number} ay0
79322
+ * @param {number} ax1
79323
+ * @param {number} ay1
79324
+ * @param {number} bx0
79325
+ * @param {number} by0
79326
+ * @param {number} bx1
79327
+ * @param {number} by1
79328
+ * @param {AABB2} result
79329
+ * @returns {boolean} true if overlap exists, false if no overlap
79330
+ */
79331
+ function aabb2_compute_overlap(
79332
+ ax0, ay0, ax1, ay1,
79333
+ bx0, by0, bx1, by1,
79334
+ result
79335
+ ) {
79336
+
79337
+ const x0 = max2(ax0, bx0);
79338
+ const x1 = min2(ax1, bx1);
79339
+
79340
+ if (x0 >= x1) {
79341
+ //no overlap
79342
+ return false;
79343
+ }
79344
+
79345
+ const y0 = max2(ay0, by0);
79346
+ const y1 = min2(ay1, by1);
79347
+
79348
+ if (y0 >= y1) {
79349
+ //no overlap
79350
+ return false;
79351
+ }
79352
+
79353
+ result.set(x0, y0, x1, y1);
79354
+
79355
+ return true;
79356
+ }
79357
+
79357
79358
  /**
79358
79359
  * Created by Alex on 08/08/2016.
79359
79360
  * @copyright Alex Goldring 2016
@@ -79482,7 +79483,7 @@ class AABB2 {
79482
79483
  /**
79483
79484
  *
79484
79485
  * @param {AABB2} other
79485
- * @returns {number}
79486
+ * @returns {boolean}
79486
79487
  */
79487
79488
  overlapExists(other) {
79488
79489
  const ax0 = this.x0;
@@ -79509,6 +79510,7 @@ class AABB2 {
79509
79510
  _expandToFit(x0, y0, x1, y1) {
79510
79511
  this.x0 = min2(this.x0, x0);
79511
79512
  this.y0 = min2(this.y0, y0);
79513
+
79512
79514
  this.x1 = max2(this.x1, x1);
79513
79515
  this.y1 = max2(this.y1, y1);
79514
79516
  }
@@ -79519,21 +79521,8 @@ class AABB2 {
79519
79521
  * @param {number} y
79520
79522
  */
79521
79523
  _expandToFitPoint(x, y) {
79522
- if (x < this.x0) {
79523
- this.x0 = x;
79524
- }
79525
-
79526
- if (x > this.x1) {
79527
- this.x1 = x;
79528
- }
79529
-
79530
- if (y < this.y0) {
79531
- this.y0 = y;
79532
- }
79533
-
79534
- if (y > this.y1) {
79535
- this.y1 = y;
79536
- }
79524
+ // shortcut, use a 0-size box
79525
+ this._expandToFit(x, y, x, y);
79537
79526
  }
79538
79527
 
79539
79528
  /**
@@ -95343,23 +95332,38 @@ class Clock {
95343
95332
  * Created by Alex on 06/05/2015.
95344
95333
  */
95345
95334
 
95335
+ /**
95336
+ * Simulation tick generator
95337
+ * Dispatches "tick" every animation frame or "maxDelay" time, whichever happens to be soonest
95338
+ * This is essentially the timing bus that all the simulation systems subscribe to for their step advancement
95339
+ */
95346
95340
  class Ticker {
95347
95341
  /**
95348
95342
  * @readonly
95349
95343
  * @type {Clock}
95350
95344
  */
95351
95345
  clock = new Clock();
95346
+
95352
95347
  /**
95353
95348
  * @private
95354
95349
  * @type {boolean}
95355
95350
  */
95356
- isRunning = false;
95351
+ #isRunning = false;
95352
+
95357
95353
 
95358
95354
  /**
95359
- *
95360
- * @type {SignalHandler[]}
95355
+ * Dispatches time delta in seconds since last tick
95356
+ * @readonly
95357
+ * @type {Signal<number>}
95361
95358
  */
95362
- callbacks = [];
95359
+ onTick = new Signal();
95360
+
95361
+ /**
95362
+ * @deprecated
95363
+ */
95364
+ get callbacks() {
95365
+ throw new Error('deprecated, use onTick signal instead');
95366
+ }
95363
95367
 
95364
95368
  /**
95365
95369
  *
@@ -95370,78 +95374,43 @@ class Ticker {
95370
95374
  }
95371
95375
 
95372
95376
  /**
95373
- *
95377
+ * @deprecated use onTick signal directly instead
95374
95378
  * @param {function} callback
95375
95379
  * @param {*} [thisArg]
95376
95380
  */
95377
95381
  subscribe(callback, thisArg) {
95378
- const handler = new SignalHandler(callback, thisArg);
95379
-
95380
- this.callbacks.push(handler);
95382
+ this.onTick.add(callback, thisArg);
95381
95383
  }
95382
95384
 
95383
95385
  /**
95384
- *
95386
+ * @deprecated use onTick signal directly instead
95385
95387
  * @param {function} callback
95386
95388
  * @param {*} [thisArg]
95387
95389
  */
95388
95390
  unsubscribe(callback, thisArg) {
95389
-
95390
- const callbacks = this.callbacks;
95391
- const n = callbacks.length;
95392
- for (let i = 0; i < n; i++) {
95393
- const cb = callbacks[i];
95394
-
95395
- if (cb.handle === callback) {
95396
- if (thisArg !== undefined) {
95397
- if (thisArg === cb.context) {
95398
- callbacks.splice(i, 1);
95399
- return;
95400
- }
95401
- } else {
95402
- callbacks.splice(i, 1);
95403
- return;
95404
- }
95405
- }
95406
- }
95407
-
95391
+ this.onTick.remove(callback, thisArg);
95408
95392
  }
95409
95393
 
95410
95394
  /**
95411
95395
  *
95412
- * @param {number} maxTimeout
95396
+ * @param {number} [maxTimeout]
95413
95397
  */
95414
95398
  start({ maxTimeout = 100 } = {}) {
95415
95399
 
95416
-
95417
- const self = this;
95418
95400
  let timeout = null;
95419
95401
  let animationFrame = null;
95420
95402
 
95421
- this.isRunning = true;
95422
-
95423
- function update() {
95424
- if (self.isRunning) {
95425
-
95426
- const delta = self.clock.getDelta();
95427
-
95428
- const callbacks = self.callbacks;
95403
+ this.#isRunning = true;
95429
95404
 
95430
- for (let i = 0; i < callbacks.length; i++) {
95431
- const callback = callbacks[i];
95432
-
95433
- try {
95434
- callback.handle.call(callback.context, delta);
95435
- } catch (e) {
95436
- }
95437
-
95438
- }
95405
+ const update = () => {
95406
+ if (!this.#isRunning) {
95407
+ return;
95439
95408
  }
95440
- }
95441
95409
 
95442
- function cycle() {
95443
- update();
95444
- }
95410
+ const delta = this.clock.getDelta();
95411
+
95412
+ this.onTick.send1(delta);
95413
+ };
95445
95414
 
95446
95415
  function timeoutCallback() {
95447
95416
  cancelAnimationFrame(animationFrame);
@@ -95457,22 +95426,22 @@ class Ticker {
95457
95426
 
95458
95427
  function animate() {
95459
95428
  animationFrame = requestAnimationFrame(animationFrameCallback);
95460
- cycle();
95429
+ update();
95461
95430
  timeout = setTimeout(timeoutCallback, maxTimeout);
95462
95431
  }
95463
95432
 
95464
- self.clock.getDelta(); //purge delta
95465
- self.clock.start();
95433
+ this.clock.getDelta(); //purge delta
95434
+ this.clock.start();
95466
95435
 
95467
95436
  requestAnimationFrame(animationFrameCallback);
95468
95437
  }
95469
95438
 
95470
95439
  pause() {
95471
- this.isRunning = false;
95440
+ this.#isRunning = false;
95472
95441
  }
95473
95442
 
95474
95443
  resume() {
95475
- this.isRunning = true;
95444
+ this.#isRunning = true;
95476
95445
  }
95477
95446
  }
95478
95447
 
@@ -106097,76 +106066,6 @@ class QuadTreeNode extends AABB2 {
106097
106066
 
106098
106067
  }
106099
106068
 
106100
- /**
106101
- * Remove all rectangles that are fully contained within others
106102
- * @param {QuadTreeNode} boxes
106103
- */
106104
- function removeRedundantBoxes(boxes) {
106105
- const removals = [];
106106
-
106107
-
106108
- let datum;
106109
-
106110
- /**
106111
- *
106112
- * @param {QuadTreeDatum} intersection
106113
- */
106114
- function visitDatumIntersection(intersection) {
106115
- if (datum === intersection) {
106116
- //skip self
106117
- return;
106118
- }
106119
-
106120
- const ax0 = intersection.x0;
106121
- const ay0 = intersection.y0;
106122
- const ax1 = intersection.x1;
106123
- const ay1 = intersection.y1;
106124
-
106125
- const bx0 = datum.x0;
106126
- const by0 = datum.y0;
106127
- const bx1 = datum.x1;
106128
- const by1 = datum.y1;
106129
-
106130
- //question is now whether it is containment
106131
- if (ax0 >= bx0 && ax1 <= bx1 && ay0 >= by0 && ay1 <= by1) {
106132
- //b contains a
106133
- removals.push(intersection);
106134
- } else if (bx0 >= ax0 && bx1 <= ax1 && by0 >= ay0 && by1 <= ay1) {
106135
- //a contains b
106136
- removals.push(datum);
106137
-
106138
- //scheduled removal of the datum, prevent further traversal
106139
- return false;
106140
- }
106141
- }
106142
-
106143
- /**
106144
- *
106145
- * @param {QuadTreeNode} node
106146
- */
106147
- function visitTreeNode(node) {
106148
- const data = node.data;
106149
- const dataCount = data.length;
106150
-
106151
- for (let i = 0; i < dataCount; i++) {
106152
- /**
106153
- *
106154
- * @type {QuadTreeDatum}
106155
- */
106156
- datum = data[i];
106157
-
106158
- node.traverseRectangleIntersections(datum.x0, datum.y0, datum.x1, datum.y1, visitDatumIntersection);
106159
- }
106160
- }
106161
-
106162
- boxes.traversePreOrder(visitTreeNode);
106163
-
106164
- for (let i = 0; i < removals.length; i++) {
106165
- const removal = removals[i];
106166
- removal.disconnect();
106167
- }
106168
- }
106169
-
106170
106069
  /**
106171
106070
  *
106172
106071
  * @param {number} containerWidth
@@ -106402,6 +106301,81 @@ function packOneBox(box, free) {
106402
106301
  return true;
106403
106302
  }
106404
106303
 
106304
+ /**
106305
+ * Remove all rectangles that are fully contained within others
106306
+ * @param {QuadTreeNode} boxes
106307
+ */
106308
+ function removeRedundantBoxes(boxes) {
106309
+ const removals = [];
106310
+
106311
+
106312
+ let datum;
106313
+
106314
+ /**
106315
+ *
106316
+ * @param {QuadTreeDatum} intersection
106317
+ */
106318
+ function visitDatumIntersection(intersection) {
106319
+ if (datum === intersection) {
106320
+ //skip self
106321
+ return;
106322
+ }
106323
+
106324
+ const ax0 = intersection.x0;
106325
+ const ay0 = intersection.y0;
106326
+ const ax1 = intersection.x1;
106327
+ const ay1 = intersection.y1;
106328
+
106329
+ const bx0 = datum.x0;
106330
+ const by0 = datum.y0;
106331
+ const bx1 = datum.x1;
106332
+ const by1 = datum.y1;
106333
+
106334
+ //question is now whether it is containment
106335
+ if (ax0 >= bx0 && ax1 <= bx1 && ay0 >= by0 && ay1 <= by1) {
106336
+ //b contains a
106337
+ removals.push(intersection);
106338
+ } else if (bx0 >= ax0 && bx1 <= ax1 && by0 >= ay0 && by1 <= ay1) {
106339
+ //a contains b
106340
+ removals.push(datum);
106341
+
106342
+ //scheduled removal of the datum, prevent further traversal
106343
+ return false;
106344
+ }
106345
+ }
106346
+
106347
+ /**
106348
+ *
106349
+ * @param {QuadTreeNode} node
106350
+ */
106351
+ function visitTreeNode(node) {
106352
+ const data = node.data;
106353
+ const dataCount = data.length;
106354
+
106355
+ for (let i = 0; i < dataCount; i++) {
106356
+ /**
106357
+ *
106358
+ * @type {QuadTreeDatum}
106359
+ */
106360
+ datum = data[i];
106361
+
106362
+ node.traverseRectangleIntersections(datum.x0, datum.y0, datum.x1, datum.y1, visitDatumIntersection);
106363
+ }
106364
+ }
106365
+
106366
+ boxes.traversePreOrder(visitTreeNode);
106367
+
106368
+ for (let i = 0; i < removals.length; i++) {
106369
+ const removal = removals[i];
106370
+ removal.disconnect();
106371
+ }
106372
+ }
106373
+
106374
+ /**
106375
+ * Packs rectangles into a finite area, packer is incremental and supports both insertions and removals of rectangles
106376
+ * Implementation of "max rectangles" packing algorithm.
106377
+ * Useful for packing texture atlases
106378
+ */
106405
106379
  class MaxRectanglesPacker {
106406
106380
  /**
106407
106381
  *
@@ -106416,6 +106390,8 @@ class MaxRectanglesPacker {
106416
106390
  * @type {QuadTreeNode}
106417
106391
  */
106418
106392
  this.free = new QuadTreeNode(0, 0, width, height);
106393
+
106394
+ // initialize a with a free space occupying the entire area
106419
106395
  this.free.add(null, 0, 0, width, height);
106420
106396
 
106421
106397
  /**
@@ -106490,7 +106466,8 @@ class MaxRectanglesPacker {
106490
106466
  }
106491
106467
 
106492
106468
  /**
106493
- *
106469
+ * Tests whether a rectangle of given dimensions can be packed into remaining space
106470
+ * Essentially, if this method succeeds - insertion will succeed as well, and if it fails - insertion will fail too
106494
106471
  * @param {number} w
106495
106472
  * @param {number} h
106496
106473
  * @return {boolean}
@@ -106574,9 +106551,10 @@ class MaxRectanglesPacker {
106574
106551
  }
106575
106552
 
106576
106553
  /**
106577
- * Resize the packer canvas
106554
+ * Resize the packer canvas, may trigger repacking if new dimensions are smaller than the existing ones
106578
106555
  * @param {number} width
106579
106556
  * @param {number} height
106557
+ * @returns {boolean} false if packing fails after resize, true otherwise
106580
106558
  */
106581
106559
  resize(width, height) {
106582
106560
 
@@ -106589,18 +106567,20 @@ class MaxRectanglesPacker {
106589
106567
 
106590
106568
  if (oldWidth > width || oldHeight > height) {
106591
106569
  //canvas was made smaller in at least one dimension, re-pack is required
106592
- this.repack();
106593
- } else {
106594
- //canvas was enlarged, we can simply add new free areas
106595
- if (width > oldWidth) {
106596
- this.free.insertDatum(new QuadTreeDatum(oldWidth, 0, width, height));
106597
- }
106598
- if (height > oldHeight) {
106599
- this.free.insertDatum(new QuadTreeDatum(0, oldHeight, width, height));
106600
- }
106570
+ return this.repack();
106571
+ }
106572
+
106573
+ //canvas was enlarged, we can simply add new free areas
106574
+ if (width > oldWidth) {
106575
+ this.free.insertDatum(new QuadTreeDatum(oldWidth, 0, width, height));
106576
+ }
106577
+ if (height > oldHeight) {
106578
+ this.free.insertDatum(new QuadTreeDatum(0, oldHeight, width, height));
106601
106579
  }
106602
106580
 
106603
106581
  // assert.ok(this.validate());
106582
+
106583
+ return true;
106604
106584
  }
106605
106585
 
106606
106586
  validate() {
package/package.json CHANGED
@@ -5,7 +5,7 @@
5
5
  "description": "Fully featured ECS game engine written in JavaScript",
6
6
  "type": "module",
7
7
  "author": "Alexander Goldring",
8
- "version": "2.79.0",
8
+ "version": "2.80.0",
9
9
  "main": "build/meep.module.js",
10
10
  "module": "build/meep.module.js",
11
11
  "exports": {
@@ -9,11 +9,11 @@ import { clamp } from "../../../math/clamp.js";
9
9
  import { max2 } from "../../../math/max2.js";
10
10
  import { min2 } from "../../../math/min2.js";
11
11
  import Vector2 from "../../Vector2.js";
12
- import { aabb2_compute_overlap } from "./aabb2_compute_overlap.js";
13
- import { aabb2_overlap_exists } from "./aabb2_overlap_exists.js";
14
12
  import {
15
13
  line_segment_compute_line_segment_intersection_2d
16
14
  } from "../line/line_segment_compute_line_segment_intersection_2d.js";
15
+ import { aabb2_compute_overlap } from "./aabb2_compute_overlap.js";
16
+ import { aabb2_overlap_exists } from "./aabb2_overlap_exists.js";
17
17
 
18
18
  /**
19
19
  *
@@ -146,7 +146,7 @@ class AABB2 {
146
146
  /**
147
147
  *
148
148
  * @param {AABB2} other
149
- * @returns {number}
149
+ * @returns {boolean}
150
150
  */
151
151
  overlapExists(other) {
152
152
  const ax0 = this.x0;
@@ -173,6 +173,7 @@ class AABB2 {
173
173
  _expandToFit(x0, y0, x1, y1) {
174
174
  this.x0 = min2(this.x0, x0);
175
175
  this.y0 = min2(this.y0, y0);
176
+
176
177
  this.x1 = max2(this.x1, x1);
177
178
  this.y1 = max2(this.y1, y1);
178
179
  }
@@ -183,21 +184,8 @@ class AABB2 {
183
184
  * @param {number} y
184
185
  */
185
186
  _expandToFitPoint(x, y) {
186
- if (x < this.x0) {
187
- this.x0 = x;
188
- }
189
-
190
- if (x > this.x1) {
191
- this.x1 = x;
192
- }
193
-
194
- if (y < this.y0) {
195
- this.y0 = y;
196
- }
197
-
198
- if (y > this.y1) {
199
- this.y1 = y;
200
- }
187
+ // shortcut, use a 0-size box
188
+ this._expandToFit(x, y, x, y);
201
189
  }
202
190
 
203
191
  /**
@@ -1,5 +1,5 @@
1
+ import { MATRIX_4_IDENTITY } from "./mat4/MATRIX_4_IDENTITY.js";
1
2
  import { SurfacePoint3 } from "./SurfacePoint3.js";
2
- import { MATRIX_4_IDENTITY } from "./matrix/MATRIX_4_IDENTITY.js";
3
3
 
4
4
 
5
5
  test("equals", () => {
@@ -1,7 +1,6 @@
1
- import {MATRIX_4_IDENTITY} from "./MATRIX_4_IDENTITY.js";
2
- import {m4_multiply} from "./m4_multiply.js";
3
- import {m4_multiply_alphatensor} from "./m4_multiply_alphatensor.js";
4
- import {number_pretty_print} from "../../../primitives/numbers/number_pretty_print.js";
1
+ import { number_pretty_print } from "../../../primitives/numbers/number_pretty_print.js";
2
+ import { m4_multiply } from "./m4_multiply.js";
3
+ import { MATRIX_4_IDENTITY } from "./MATRIX_4_IDENTITY.js";
5
4
 
6
5
  test("identity multiplication", () => {
7
6
 
@@ -1,6 +1,6 @@
1
- import {m4_multiply_alphatensor} from "./m4_multiply_alphatensor.js";
2
- import {MATRIX_4_IDENTITY} from "./MATRIX_4_IDENTITY.js";
3
- import {number_pretty_print} from "../../../primitives/numbers/number_pretty_print.js";
1
+ import { number_pretty_print } from "../../../primitives/numbers/number_pretty_print.js";
2
+ import { m4_multiply_alphatensor } from "./m4_multiply_alphatensor.js";
3
+ import { MATRIX_4_IDENTITY } from "./MATRIX_4_IDENTITY.js";
4
4
 
5
5
  test("identity multiplication", () => {
6
6
 
@@ -1,5 +1,5 @@
1
+ import { MATRIX_4_IDENTITY } from "../mat4/MATRIX_4_IDENTITY.js";
1
2
  import { v3_morton_encode_transformed } from "./v3_morton_encode_transformed.js";
2
- import { MATRIX_4_IDENTITY } from "../matrix/MATRIX_4_IDENTITY.js";
3
3
 
4
4
  test("valid number with identity transform", () => {
5
5
  const v = v3_morton_encode_transformed(0, 0, 0, MATRIX_4_IDENTITY);
@@ -1,5 +1,5 @@
1
+ import { MATRIX_4_IDENTITY } from "../mat4/MATRIX_4_IDENTITY.js";
1
2
  import { sphere_radius_sqr_from_v3_array_transformed } from "./sphere_radius_sqr_from_v3_array_transformed.js";
2
- import { MATRIX_4_IDENTITY } from "../matrix/MATRIX_4_IDENTITY.js";
3
3
 
4
4
  test("base case", () => {
5
5
  expect(sphere_radius_sqr_from_v3_array_transformed([0, 0, 0], 3, MATRIX_4_IDENTITY)).toBe(0);
@@ -37,7 +37,7 @@ class Vector3 {
37
37
 
38
38
  /**
39
39
  *
40
- * @param {number[]} array
40
+ * @param {number[]|Float32Array} array
41
41
  * @param {number} offset
42
42
  */
43
43
  readFromArray(array, offset = 0) {
@@ -50,7 +50,7 @@ class Vector3 {
50
50
 
51
51
  /**
52
52
  *
53
- * @param {number[]} array
53
+ * @param {number[]|Float32Array} array
54
54
  * @param {number} offset
55
55
  */
56
56
  writeToArray(array, offset = 0) {
@@ -1,5 +1,5 @@
1
- import {MATRIX_4_IDENTITY} from "./3d/matrix/MATRIX_4_IDENTITY.js";
2
- import {v3_slerp} from "./vec3/v3_slerp.js";
1
+ import { MATRIX_4_IDENTITY } from "./3d/mat4/MATRIX_4_IDENTITY.js";
2
+ import { v3_slerp } from "./vec3/v3_slerp.js";
3
3
  import Vector3 from "./Vector3.js";
4
4
 
5
5
  test('slerp', () => {