@woosh/meep-engine 2.43.1 → 2.43.4

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 (138) hide show
  1. package/core/binary/BinaryBuffer.js +13 -1
  2. package/core/binary/BitSet.js +2 -2
  3. package/core/bvh2/aabb3/aabb3_array_combine.js +2 -2
  4. package/core/collection/RingBuffer.js +4 -2
  5. package/core/collection/RingBuffer.spec.js +59 -0
  6. package/core/collection/array/ArrayIteratorRandom.js +1 -1
  7. package/core/collection/{ArrayUtils.spec.js → array/arrayPickBestElement.spec.js} +1 -1
  8. package/core/collection/array/arrayPickBestElements.js +51 -0
  9. package/core/collection/array/arrayPickMinElement.js +43 -0
  10. package/core/collection/array/arrayQuickSort.js +1 -1
  11. package/core/collection/array/arraySetSortingDiff.js +1 -1
  12. package/core/collection/array/arraySwapElements.js +12 -0
  13. package/core/collection/array/array_range_equal_strict.js +22 -0
  14. package/core/collection/array/groupArrayBy.js +42 -0
  15. package/core/collection/array/isArrayEqual.js +50 -0
  16. package/core/collection/array/randomMultipleFromArray.js +34 -0
  17. package/core/collection/array/randomizeArrayElementOrder.js +23 -0
  18. package/core/color/sRGB_to_linear.js +9 -4
  19. package/core/geom/2d/convex-hull/convex_hull_monotone_2d.js +1 -1
  20. package/core/geom/3d/aabb/aabb3_build_frustum.js +1 -1
  21. package/core/geom/3d/aabb/compute_aabb_from_points.js +1 -1
  22. package/core/geom/3d/frustum/frustum3_computeNearestPointToPoint.js +3 -1
  23. package/core/geom/3d/morton/v3_morton_encode_transformed.spec.js +20 -0
  24. package/core/geom/3d/plane/orient3d_fast.js +11 -10
  25. package/core/geom/3d/plane/orient3d_robust.js +41 -0
  26. package/core/geom/3d/plane/plane_computeConvex3PlaneIntersection.js +0 -23
  27. package/core/geom/3d/plane/plane_three_compute_convex3_plane_intersection.js +24 -0
  28. package/core/geom/3d/shape/UnionShape3D.js +1 -1
  29. package/core/geom/3d/sphere/harmonics/README.md +15 -0
  30. package/core/geom/3d/sphere/harmonics/sh3_add.js +21 -0
  31. package/core/geom/3d/sphere/harmonics/sh3_dering_optimize_positive.js +618 -0
  32. package/core/geom/3d/sphere/harmonics/sh3_sample_by_direction.js +49 -0
  33. package/core/geom/3d/sphere/harmonics/sh3_sample_irradiance_by_direction.js +53 -0
  34. package/core/geom/3d/tetrahedra/README.md +10 -1
  35. package/core/geom/3d/tetrahedra/TetrahedralMesh.js +650 -0
  36. package/core/geom/3d/tetrahedra/TetrahedralMesh.spec.js +233 -0
  37. package/core/geom/3d/tetrahedra/build_tetrahedral_mesh_buffer_geometry.js +75 -0
  38. package/core/geom/3d/tetrahedra/compute_bounding_simplex_3d.js +2 -2
  39. package/core/geom/3d/tetrahedra/compute_bounding_simplex_3d.spec.js +4 -4
  40. package/core/geom/3d/tetrahedra/delaunay/Cavity.js +49 -7
  41. package/core/geom/3d/tetrahedra/delaunay/compute_delaunay_tetrahedral_mesh.js +51 -17
  42. package/core/geom/3d/tetrahedra/delaunay/debug_validate_mesh.js +19 -0
  43. package/core/geom/3d/tetrahedra/delaunay/fill_in_a_cavity.js +191 -0
  44. package/core/geom/3d/tetrahedra/delaunay/push_boundary_with_validation.js +27 -0
  45. package/core/geom/3d/tetrahedra/delaunay/tetrahedral_mesh_compute_cavity.js +59 -43
  46. package/core/geom/3d/tetrahedra/delaunay/tetrahedral_mesh_compute_sub_determinant.js +77 -0
  47. package/core/geom/3d/tetrahedra/delaunay/tetrahedral_mesh_compute_sub_determinant.spec.js +30 -0
  48. package/core/geom/3d/tetrahedra/delaunay/tetrahedral_mesh_walk_towards_containing_tetrahedron.js +58 -0
  49. package/core/geom/3d/tetrahedra/delaunay/validate_cavity_boundary.js +60 -0
  50. package/core/geom/3d/tetrahedra/{point_in_tetrahedron_circumsphere.js → in_sphere_fast.js} +11 -13
  51. package/core/geom/3d/tetrahedra/in_sphere_robust.js +53 -0
  52. package/core/geom/3d/tetrahedra/prototypeTetrahedraBuilder.js +44 -35
  53. package/core/geom/3d/tetrahedra/tetrahedron_compute_signed_volume.js +83 -0
  54. package/core/geom/3d/tetrahedra/tetrahedron_compute_signed_volume.spec.js +24 -0
  55. package/core/geom/3d/tetrahedra/tetrahedron_contains_point.spec.js +66 -0
  56. package/core/geom/3d/tetrahedra/validate_tetrahedral_mesh.js +166 -0
  57. package/core/geom/3d/util/make_justified_point_grid.js +31 -0
  58. package/core/geom/Bezier.js +0 -27
  59. package/core/geom/Plane.js +0 -4
  60. package/core/geom/packing/miniball/Subspan.js +2 -2
  61. package/core/geom/v3_lerp.js +6 -1
  62. package/core/math/isqrt.js +28 -0
  63. package/core/math/isqrt.spec.js +9 -0
  64. package/core/math/max.spec.js +25 -0
  65. package/core/math/min2.spec.js +25 -0
  66. package/core/model/node-graph/node/NodeInstance.js +3 -3
  67. package/core/primitives/strings/prefixTree/PrefixTreeLeaf.js +1 -1
  68. package/core/process/delay.js +5 -0
  69. package/core/process/task/util/randomCountTask.js +1 -1
  70. package/editor/Editor.js +3 -0
  71. package/editor/ecs/component/editors/ecs/ParameterLookupTableEditor.js +195 -11
  72. package/editor/ecs/component/editors/ecs/ParameterTrackSetEditor.js +16 -0
  73. package/editor/ecs/component/editors/ecs/ParticleEmitterLayerEditor.js +4 -0
  74. package/editor/ecs/component/editors/primitive/ArrayEditor.js +1 -1
  75. package/editor/tools/v2/BlenderCameraOrientationGizmo.js +6 -0
  76. package/editor/view/ecs/components/common/AutoCanvasView.js +13 -25
  77. package/engine/EngineHarness.js +11 -5
  78. package/engine/asset/AssetManager.d.ts +5 -1
  79. package/engine/asset/AssetManager.js +50 -15
  80. package/engine/asset/AssetManager.spec.js +17 -11
  81. package/engine/asset/AssetRequest.js +57 -0
  82. package/engine/asset/loaders/ArrayBufferLoader.js +22 -0
  83. package/engine/asset/loaders/AssetLoader.js +1 -1
  84. package/engine/ecs/System.js +1 -1
  85. package/engine/ecs/dynamic_actions/DynamicActorSystem.js +1 -1
  86. package/engine/ecs/terrain/ecs/TerrainSystem.js +7 -1
  87. package/engine/ecs/transform/copy_three_transform.js +15 -0
  88. package/engine/graphics/FrameRunner.js +5 -9
  89. package/engine/graphics/ecs/animation/animator/AnimationClipDefinition.js +1 -1
  90. package/engine/graphics/ecs/animation/animator/graph/definition/AnimationGraphDefinition.js +1 -1
  91. package/engine/graphics/ecs/camera/Camera.js +1 -10
  92. package/engine/graphics/ecs/camera/CameraSystem.js +8 -8
  93. package/engine/graphics/ecs/camera/ProjectionType.js +9 -0
  94. package/engine/graphics/ecs/camera/build_three_camera_object.js +3 -3
  95. package/engine/graphics/ecs/decal/v2/prototypeDecalSystem.js +59 -4
  96. package/engine/graphics/ecs/light/Light.js +6 -1
  97. package/engine/graphics/ecs/light/LightSystem.d.ts +1 -1
  98. package/engine/graphics/ecs/mesh-v2/three_object_to_entity_composition.js +2 -17
  99. package/engine/graphics/geometry/VertexDataSpec.js +1 -1
  100. package/engine/graphics/geometry/instancing/InstancedMeshGroup.js +2 -2
  101. package/engine/graphics/impostors/octahedral/prototypeBaker.js +3 -3
  102. package/engine/graphics/micron/plugin/GLTFAssetTransformer.js +1 -1
  103. package/engine/graphics/micron/plugin/MicronRenderPlugin.js +3 -1
  104. package/engine/graphics/particles/node-based/codegen/modules/FunctionSignature.js +1 -1
  105. package/engine/graphics/render/forward_plus/LightManager.js +1 -1
  106. package/engine/graphics/render/forward_plus/LightManager.spec.js +4 -0
  107. package/engine/graphics/render/forward_plus/computeFrustumCorners.js +4 -2
  108. package/engine/graphics/render/forward_plus/prototype/prototypeLightManager.js +2 -2
  109. package/engine/graphics/render/layers/RenderLayerUtils.js +2 -2
  110. package/engine/graphics/sh3/LightProbeVolume.js +595 -0
  111. package/engine/graphics/sh3/SH3VisualisationMaterial.js +79 -0
  112. package/engine/graphics/sh3/prototypeSH3Probe.js +427 -0
  113. package/engine/graphics/sh3/visualise_probe.js +40 -0
  114. package/engine/graphics/shaders/DenoiseShader.js +1 -1
  115. package/engine/graphics/texture/atlas/AtlasPatch.js +11 -3
  116. package/engine/graphics/texture/atlas/CachingTextureAtlas.js +2 -2
  117. package/engine/graphics/texture/atlas/TextureAtlas.js +22 -4
  118. package/engine/graphics/texture/atlas/TextureAtlas.spec.js +22 -0
  119. package/engine/graphics/texture/sampler/Sampler2D.js +0 -64
  120. package/engine/graphics/texture/sampler/Sampler2D.spec.js +2 -1
  121. package/engine/graphics/texture/sampler/sampler2d_combine.js +67 -0
  122. package/engine/intelligence/behavior/ecs/BehaviorSystem.spec.js +0 -3
  123. package/engine/intelligence/blackboard/AbstractBlackboard.d.ts +1 -1
  124. package/engine/network/PriorityFetch.js +192 -0
  125. package/engine/simulation/DormandPrince.js +1 -1
  126. package/engine/ui/DraggableAspect.js +0 -1
  127. package/generation/grid/generation/road/GridTaskGenerateRoads.js +1 -1
  128. package/package.json +2 -1
  129. package/samples/terrain/from_image_2.js +127 -82
  130. package/view/elements/CanvasView.js +7 -1
  131. package/view/elements/image/HTMLElementCacheKey.js +1 -1
  132. package/view/util/DomSizeObserver.js +3 -5
  133. package/core/collection/ArrayUtils.js +0 -263
  134. package/core/geom/3d/tetrahedra/delaunay/tetrahedral_mesh_walk_toward_cavity.js +0 -48
  135. package/core/geom/3d/tetrahedra/hxt/a.js +0 -524
  136. package/core/geom/3d/tetrahedra/hxt/hxt.js +0 -140
  137. package/core/geom/3d/tetrahedra/hxt/hxt.wasm +0 -0
  138. package/core/geom/3d/tetrahedra/tetrahedra_collection.js +0 -383
@@ -343,7 +343,7 @@ export class BinaryBuffer {
343
343
  *
344
344
  * @param {number} destination_offset starting index in the destination array
345
345
  * @param {number} length number of elements to read
346
- * @param {Uint32Array} destination
346
+ * @param {Uint32Array|number[]|ArrayLike<number>} destination
347
347
  */
348
348
  readUint32Array(destination, destination_offset, length) {
349
349
  for (let i = 0; i < length; i++) {
@@ -707,6 +707,18 @@ export class BinaryBuffer {
707
707
  this.position = end;
708
708
  }
709
709
 
710
+ /**
711
+ *
712
+ * @param {Uint32Array|number[]|ArrayLike<number>} source
713
+ * @param {number} source_offset
714
+ * @param {number} length
715
+ */
716
+ writeUint32Array(source, source_offset, length) {
717
+ for (let i = 0; i < length; i++) {
718
+ this.writeUint32(source[source_offset + i]);
719
+ }
720
+ }
721
+
710
722
  /**
711
723
  *
712
724
  * @param {Uint8Array|Uint8ClampedArray} array
@@ -403,9 +403,9 @@ BitSet.prototype.set = function (bitIndex, value) {
403
403
 
404
404
  if (bitIndex === this.__length - 1) {
405
405
  // trim down set size potentially
406
- const newLastSetBit = this.previousSetBit(bitIndex);
406
+ // const newLastSetBit = this.previousSetBit(bitIndex);
407
407
 
408
- this.__setLength(newLastSetBit + 1);
408
+ this.__setLength(bitIndex );
409
409
  }
410
410
  }
411
411
 
@@ -4,8 +4,8 @@ import { min2 } from "../../math/min2.js";
4
4
  import { max2 } from "../../math/max2.js";
5
5
 
6
6
  /**
7
- *
8
- * @param {ArrayLike<number>|number[]} result
7
+ * Merge bounds of two axis-aligned bounding boxes, the result is a box that tightly bounds inputs
8
+ * @param {ArrayLike<number>|number[]} result where resulting value is written to
9
9
  * @param {ArrayLike<number>|number[]} a
10
10
  * @param {ArrayLike<number>|number[]} b
11
11
  */
@@ -1,4 +1,5 @@
1
1
  import { assert } from "../assert.js";
2
+ import { min2 } from "../math/min2.js";
2
3
 
3
4
  export class RingBuffer {
4
5
  /**
@@ -12,7 +13,7 @@ export class RingBuffer {
12
13
  assert.isNonNegativeInteger(size, 'size');
13
14
 
14
15
  /**
15
- *
16
+ * Capacity of the buffer, number of slots
16
17
  * @type {number}
17
18
  */
18
19
  this.size = size;
@@ -30,7 +31,7 @@ export class RingBuffer {
30
31
  this.tail = 0;
31
32
 
32
33
  /**
33
- *
34
+ * Number of used slots. Starts at 0, goes up to {@link #size}
34
35
  * @type {number}
35
36
  */
36
37
  this.count = 0;
@@ -51,6 +52,7 @@ export class RingBuffer {
51
52
 
52
53
  this.data = array;
53
54
  this.size = new_size;
55
+ this.count = min2(new_size, this.count);
54
56
 
55
57
  this.clear();
56
58
 
@@ -0,0 +1,59 @@
1
+ import { RingBuffer } from "./RingBuffer.js";
2
+
3
+ test("constructor doesn't throw", () => {
4
+ expect(() => new RingBuffer(1)).not.toThrow();
5
+ });
6
+
7
+ test("size set from constructor", () => {
8
+ const sut = new RingBuffer(7);
9
+
10
+ expect(sut.size).toBe(7);
11
+ });
12
+
13
+ test("circular overwriting", () => {
14
+ const sut = new RingBuffer(2);
15
+
16
+ sut.push(3);
17
+ sut.push(7);
18
+ sut.push(11);
19
+
20
+ expect(sut.contains(3)).toBe(false);
21
+ expect(sut.contains(7)).toBe(true);
22
+ expect(sut.contains(11)).toBe(true);
23
+ });
24
+
25
+ test("empty buffer count must be 0", () => {
26
+ const sut = new RingBuffer(1);
27
+
28
+ expect(sut.count).toBe(0);
29
+ });
30
+
31
+ test("buffer count works as expected", () => {
32
+ const sut = new RingBuffer(2);
33
+
34
+ expect(sut.count).toBe(0);
35
+
36
+ sut.push(1);
37
+
38
+ expect(sut.count).toBe(1);
39
+
40
+ sut.push(3);
41
+
42
+ expect(sut.count).toBe(2);
43
+
44
+ sut.push(7);
45
+
46
+ expect(sut.count).toBe(2);
47
+ });
48
+
49
+ test("resizing changes capacity", () => {
50
+ const sut = new RingBuffer(2);
51
+
52
+ sut.resize(1);
53
+
54
+ expect(sut.size).toBe(1);
55
+
56
+ sut.resize(3);
57
+
58
+ expect(sut.size).toBe(3);
59
+ });
@@ -1,6 +1,6 @@
1
1
  import { seededRandom } from "../../math/random/seededRandom.js";
2
- import { randomizeArrayElementOrder } from "../ArrayUtils.js";
3
2
  import { AbstractArrayIterator } from "./AbstractArrayIterator.js";
3
+ import { randomizeArrayElementOrder } from "./randomizeArrayElementOrder.js";
4
4
 
5
5
  export class ArrayIteratorRandom extends AbstractArrayIterator {
6
6
  constructor() {
@@ -1,4 +1,4 @@
1
- import { arrayPickBestElement } from "./array/arrayPickBestElement.js";
1
+ import { arrayPickBestElement } from "./arrayPickBestElement.js";
2
2
 
3
3
  test("arrayPickBestElement largest number", () => {
4
4
  expect(
@@ -0,0 +1,51 @@
1
+ import { assert } from "../../assert.js";
2
+
3
+ /**
4
+ * @template T
5
+ * @param {T[]} array
6
+ * @param {function(T):number} scoreFunction
7
+ * @returns {T[]}
8
+ */
9
+ export function arrayPickBestElements(array, scoreFunction) {
10
+ assert.notEqual(array, undefined, 'array is undefined');
11
+ assert.isArray(array, 'array');
12
+
13
+ assert.typeOf(scoreFunction, 'function', 'scoreFunction');
14
+
15
+ let bestScore;
16
+
17
+ const size = array.length;
18
+
19
+ if (size === 0) {
20
+ return [];
21
+ }
22
+
23
+ const first = array[0];
24
+
25
+ bestScore = scoreFunction(first);
26
+
27
+ assert.isNumber(bestScore, 'bestScore');
28
+
29
+ const result = [first];
30
+
31
+ for (let i = 1; i < size; i++) {
32
+ const el = array[i];
33
+
34
+ // compute score
35
+ const score = scoreFunction(el);
36
+
37
+ assert.isNumber(score, 'score');
38
+
39
+ if (score > bestScore) {
40
+ bestScore = score;
41
+
42
+ result.splice(0, result.length);
43
+
44
+ result.push(el);
45
+ } else if (score === bestScore) {
46
+ result.push(el);
47
+ }
48
+ }
49
+
50
+ return result;
51
+ }
@@ -0,0 +1,43 @@
1
+ import { assert } from "../../assert.js";
2
+
3
+ /**
4
+ * @template T
5
+ * @param {T[]} array
6
+ * @param {function(T):number} scoreFunction
7
+ * @returns {T}
8
+ */
9
+ export function arrayPickMinElement(array, scoreFunction) {
10
+ assert.notEqual(array, undefined, 'array is undefined');
11
+ assert.typeOf(scoreFunction, 'function', 'scoreFunction');
12
+
13
+ let bestElement;
14
+ let bestScore;
15
+
16
+ const size = array.length;
17
+
18
+ if (size === 0) {
19
+ return undefined;
20
+ }
21
+
22
+ bestElement = array[0];
23
+
24
+ bestScore = scoreFunction(bestElement);
25
+
26
+ assert.typeOf(bestScore, 'number', 'bestScore');
27
+
28
+ for (let i = 1; i < size; i++) {
29
+ const el = array[i];
30
+
31
+ // compute score
32
+ const score = scoreFunction(el);
33
+
34
+ assert.typeOf(score, 'number', 'score');
35
+
36
+ if (score < bestScore) {
37
+ bestScore = score;
38
+ bestElement = el;
39
+ }
40
+ }
41
+
42
+ return bestElement;
43
+ }
@@ -1,4 +1,4 @@
1
- import { arraySwapElements } from "../ArrayUtils.js";
1
+ import { arraySwapElements } from "./arraySwapElements.js";
2
2
 
3
3
  const stack = [];
4
4
 
@@ -3,7 +3,7 @@ import { assert } from "../../assert.js";
3
3
  //
4
4
 
5
5
  /**
6
- * Based on 2-way merge algorith from wiki: https://en.wikipedia.org/wiki/K-way_merge_algorithm
6
+ * Based on 2-way merge algorithm from wiki: https://en.wikipedia.org/wiki/K-way_merge_algorithm
7
7
  * @template T
8
8
  * @param {T[]} a
9
9
  * @param {T[]} b
@@ -0,0 +1,12 @@
1
+ /**
2
+ * @template T
3
+ * @param {T[]} array
4
+ * @param {number} index0
5
+ * @param {number} index1
6
+ */
7
+ export function arraySwapElements(array, index0, index1) {
8
+ const t = array[index0];
9
+
10
+ array[index0] = array[index1];
11
+ array[index1] = t;
12
+ }
@@ -0,0 +1,22 @@
1
+ /**
2
+ * Checks that elements in supplied arrays are exactly equal within a certain range defined by a pair of offsets and element count (length)
3
+ * @template T
4
+ * @param {T[]} a
5
+ * @param {number} offset_a
6
+ * @param {T[]} b
7
+ * @param {number} offset_b
8
+ * @param {number} length
9
+ * @returns {boolean}
10
+ */
11
+ export function array_range_equal_strict(a, offset_a, b, offset_b, length) {
12
+
13
+ for (let i = 0; i < length; i++) {
14
+
15
+ if (a[offset_a + i] !== b[offset_b + i]) {
16
+ return false;
17
+ }
18
+
19
+ }
20
+
21
+ return true;
22
+ }
@@ -0,0 +1,42 @@
1
+ import { returnZero } from "../../function/Functions.js";
2
+ import { HashMap } from "../HashMap.js";
3
+
4
+ /**
5
+ * @template T,K
6
+ * @param {T[]} array
7
+ * @param {function(T):K} groupingFunction
8
+ * @param keyHashFunction
9
+ * @returns {Map<K,T[]>}
10
+ */
11
+ export function groupArrayBy(array, groupingFunction, keyHashFunction = returnZero) {
12
+ const result = new HashMap({
13
+ keyHashFunction,
14
+ keyEqualityFunction(a, b) {
15
+ if (a === b) {
16
+ return true;
17
+ }
18
+
19
+ if (typeof a === "object" && a !== null && typeof a.equals === "function") {
20
+ return a.equals(b);
21
+ }
22
+
23
+ return false;
24
+ }
25
+ });
26
+
27
+ for (let i = 0; i < array.length; i++) {
28
+ const element = array[i];
29
+
30
+ const groupKey = groupingFunction(element);
31
+
32
+ const group = result.get(groupKey);
33
+
34
+ if (group === undefined) {
35
+ result.set(groupKey, [element]);
36
+ } else {
37
+ group.push(element);
38
+ }
39
+ }
40
+
41
+ return result;
42
+ }
@@ -0,0 +1,50 @@
1
+ /**
2
+ * @template T,R
3
+ * @param {T[]} first
4
+ * @param {R[]} second
5
+ * @return {boolean}
6
+ */
7
+ export function isArrayEqual(first, second) {
8
+
9
+ const il = first.length;
10
+
11
+ if (il !== second.length) return false;
12
+
13
+ let i = 0;
14
+
15
+ for (; i < il; i++) {
16
+
17
+ const a = first[i];
18
+ const b = second[i];
19
+
20
+ if (a === b) {
21
+ continue;
22
+ }
23
+
24
+
25
+ if (a === undefined) {
26
+ //a is undefined, and B is something else
27
+ return false;
28
+ }
29
+
30
+ if (a === null) {
31
+ //a is null and B is something else
32
+ return false;
33
+ }
34
+
35
+ //try "equals" method
36
+ if (typeof a.equals === "function") {
37
+
38
+ if (!a.equals(b)) {
39
+ return false;
40
+ }
41
+
42
+ } else {
43
+ return false;
44
+ }
45
+
46
+ }
47
+
48
+ return true;
49
+
50
+ }
@@ -0,0 +1,34 @@
1
+ import { randomizeArrayElementOrder } from "./randomizeArrayElementOrder.js";
2
+ import { min2 } from "../../math/min2.js";
3
+
4
+ /**
5
+ * Pick multiple random items from an array
6
+ *
7
+ * @template T
8
+ * @param {function} random
9
+ * @param {T[]} source
10
+ * @param {T[]} target
11
+ * @param {number} count how many items to pick
12
+ * @returns {T}
13
+ */
14
+ export function randomMultipleFromArray(random, source, target, count) {
15
+
16
+ const order = [];
17
+
18
+ const source_length = source.length;
19
+ for (let i = 0; i < source_length; i++) {
20
+ order[i] = i;
21
+ }
22
+
23
+ randomizeArrayElementOrder(random, order);
24
+
25
+ const target_length = min2(source_length, count);
26
+
27
+ for (let i = 0; i < target_length; i++) {
28
+ const index = order[i];
29
+ const element = source[index];
30
+ target.push(element);
31
+ }
32
+
33
+ return target_length;
34
+ }
@@ -0,0 +1,23 @@
1
+ import { randomIntegerBetween } from "../../math/random/randomIntegerBetween.js";
2
+ import { arraySwapElements } from "./arraySwapElements.js";
3
+
4
+ /**
5
+ * @template T
6
+ * @param {function} random
7
+ * @param {T[]} array
8
+ */
9
+ export function randomizeArrayElementOrder(random, array) {
10
+ const n = array.length;
11
+
12
+ const lastValidIndex = n - 1;
13
+
14
+ for (let i = 0; i < n; i++) {
15
+ const t = randomIntegerBetween(random, 0, lastValidIndex);
16
+
17
+ if (t === i) {
18
+ continue;
19
+ }
20
+
21
+ arraySwapElements(array, i, t);
22
+ }
23
+ }
@@ -1,4 +1,9 @@
1
- function convert(c) {
1
+ /**
2
+ *
3
+ * @param {number} c
4
+ * @return {number|number}
5
+ */
6
+ export function convert_channel_sRGB_to_linear(c) {
2
7
  return (c < 0.04045) ? c * 0.0773993808 : Math.pow(c * 0.9478672986 + 0.0521327014, 2.4);
3
8
  }
4
9
 
@@ -10,7 +15,7 @@ function convert(c) {
10
15
  * @param {number} input_offset
11
16
  */
12
17
  export function sRGB_to_linear(output, output_offset, input, input_offset) {
13
- output[output_offset] = convert(input[input_offset]);
14
- output[output_offset + 1] = convert(input[input_offset + 1]);
15
- output[output_offset + 2] = convert(input[input_offset + 2]);
18
+ output[output_offset] = convert_channel_sRGB_to_linear(input[input_offset]);
19
+ output[output_offset + 1] = convert_channel_sRGB_to_linear(input[input_offset + 1]);
20
+ output[output_offset + 2] = convert_channel_sRGB_to_linear(input[input_offset + 2]);
16
21
  }
@@ -57,7 +57,7 @@ export function convex_hull_monotone_2d(points) {
57
57
 
58
58
  //Insert into upper list
59
59
  m = upper.length
60
- while (m > 1 && orient(
60
+ while (m > 1 && orientation3_v2(
61
61
  points[upper[m - 2]],
62
62
  points[upper[m - 1]],
63
63
  p) >= 0) {
@@ -1,5 +1,5 @@
1
1
  /**
2
- *
2
+ * Build orthographic frustum from an axis-aligned bounding box
3
3
  * @param {number[]} result
4
4
  * @param {number} x0
5
5
  * @param {number} y0
@@ -2,7 +2,7 @@ import { min2 } from "../../../math/min2.js";
2
2
  import { max2 } from "../../../math/max2.js";
3
3
 
4
4
  /**
5
- *
5
+ * Multidimensional axis-aligned bounding box calculation
6
6
  * @param {number[]} result
7
7
  * @param {number[]} input
8
8
  * @param {number} input_count
@@ -1,9 +1,11 @@
1
1
  import { computePlanePlaneIntersection } from "../../Plane.js";
2
2
  import Vector3 from "../../Vector3.js";
3
3
  import { plane3_projectPoint } from "../plane/plane3_projectPoint.js";
4
- import { plane_three_computeConvex3PlaneIntersection } from "../plane/plane_computeConvex3PlaneIntersection.js";
5
4
  import { ray_computeNearestPointToPoint } from "../ray/ray_computeNearestPointToPoint.js";
6
5
  import { v3_distance_above_plane } from "../../v3_distance_above_plane.js";
6
+ import {
7
+ plane_three_computeConvex3PlaneIntersection
8
+ } from "../plane/plane_three_compute_convex3_plane_intersection.js";
7
9
 
8
10
  /**
9
11
  *
@@ -0,0 +1,20 @@
1
+ import { v3_morton_encode_transformed } from "./v3_morton_encode_transformed.js";
2
+ import { MATRIX_4_IDENTITY } from "../matrix/MATRIX_4_IDENTITY.js";
3
+
4
+ test("valid number with identity transform", () => {
5
+ const v = v3_morton_encode_transformed(0, 0, 0, MATRIX_4_IDENTITY);
6
+
7
+ expect(typeof v).toBe('number');
8
+ expect(v).not.toBeNaN();
9
+ });
10
+
11
+ test("different coordinates produce different hashes", () => {
12
+ expect(v3_morton_encode_transformed(1, 0, 0, MATRIX_4_IDENTITY))
13
+ .not.toEqual(v3_morton_encode_transformed(0, 0, 0, MATRIX_4_IDENTITY));
14
+
15
+ expect(v3_morton_encode_transformed(0, 1, 0, MATRIX_4_IDENTITY))
16
+ .not.toEqual(v3_morton_encode_transformed(0, 0, 0, MATRIX_4_IDENTITY));
17
+
18
+ expect(v3_morton_encode_transformed(0, 0, 1, MATRIX_4_IDENTITY))
19
+ .not.toEqual(v3_morton_encode_transformed(0, 0, 0, MATRIX_4_IDENTITY));
20
+ });
@@ -1,4 +1,6 @@
1
1
  /**
2
+ * Non-robust
3
+ *
2
4
  * Return a positive value if the point pd lies below the
3
5
  * plane passing through pa, pb, and pc; "below" is defined so
4
6
  * that pa, pb, and pc appear in counterclockwise order when
@@ -24,24 +26,23 @@ export function orient3d_fast(points, a, b, c, d) {
24
26
  const c3 = c * 3;
25
27
 
26
28
  const d_x = points[d3];
27
-
28
- const adx = points[a3] - d_x;
29
- const bdx = points[b3] - d_x;
30
- const cdx = points[c3] - d_x;
31
-
32
29
  const d_y = points[d3 + 1];
30
+ const d_z = points[d3 + 2];
33
31
 
32
+ const adx = points[a3] - d_x;
34
33
  const ady = points[a3 + 1] - d_y;
35
- const bdy = points[b3 + 1] - d_y;
36
- const cdy = points[c3 + 1] - d_y;
34
+ const adz = points[a3 + 2] - d_z;
37
35
 
38
- const d_z = points[d3 + 2];
36
+ const bdx = points[b3] - d_x;
37
+ const bdy = points[b3 + 1] - d_y;
38
+ const cdz = points[c3 + 2] - d_z;
39
39
 
40
- const adz = points[a3 + 2] - d_z;
40
+ const cdx = points[c3] - d_x;
41
+ const cdy = points[c3 + 1] - d_y;
41
42
  const bdz = points[b3 + 2] - d_z;
42
- const cdz = points[c3 + 2] - d_z;
43
43
 
44
44
  return adx * (bdy * cdz - bdz * cdy)
45
45
  + bdx * (cdy * adz - cdz * ady)
46
46
  + cdx * (ady * bdz - adz * bdy);
47
47
  }
48
+
@@ -0,0 +1,41 @@
1
+ import { orient3d } from "robust-predicates";
2
+
3
+ /**
4
+ *
5
+ * @param {number[]} points
6
+ * @param {number} a index of point a
7
+ * @param {number} b index of point b
8
+ * @param {number} c index of point c
9
+ * @param {number} d index of point d
10
+ * @returns {number}
11
+ */
12
+ export function orient3d_robust(
13
+ points,
14
+ a, b, c, d
15
+ ) {
16
+
17
+
18
+ const a3 = a * 3;
19
+ const b3 = b * 3;
20
+ const c3 = c * 3;
21
+ const d3 = d * 3;
22
+
23
+ const ax = points[a3];
24
+ const ay = points[a3 + 1];
25
+ const az = points[a3 + 2];
26
+
27
+ const bx = points[b3];
28
+ const by = points[b3 + 1];
29
+ const bz = points[b3 + 2];
30
+
31
+ const cx = points[c3];
32
+ const cy = points[c3 + 1];
33
+ const cz = points[c3 + 2];
34
+
35
+ const dx = points[d3];
36
+ const dy = points[d3 + 1];
37
+ const dz = points[d3 + 2];
38
+
39
+
40
+ return orient3d(ax, ay, az, bx, by, bz, cx, cy, cz, dx, dy, dz);
41
+ }
@@ -1,28 +1,5 @@
1
1
  import { v3_dot } from "../../v3_dot.js";
2
2
 
3
- /**
4
- *
5
- * @param {number[]} result
6
- * @param {number} result_offset
7
- * @param {Plane} a
8
- * @param {Plane} b
9
- * @param {Plane} c
10
- * @returns {boolean}
11
- */
12
- export function plane_three_computeConvex3PlaneIntersection(result, result_offset, a, b, c) {
13
- const a_normal = a.normal;
14
- const b_normal = b.normal;
15
- const c_normal = c.normal;
16
-
17
- return plane_computeConvex3PlaneIntersection(
18
- result,
19
- result_offset,
20
- a_normal.x, a_normal.y, a_normal.z, a.constant,
21
- b_normal.x, b_normal.y, b_normal.z, b.constant,
22
- c_normal.x, c_normal.y, c_normal.z, c.constant,
23
- );
24
- }
25
-
26
3
  /**
27
4
  * Given 3 planes, compute point of their intersection.
28
5
  * This only works when the planes are "convex", that is - no two planes are parallel.