@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
@@ -1,8 +1,6 @@
1
1
  import { EngineHarness } from "../../../../engine/EngineHarness.js";
2
2
  import { compute_delaunay_tetrahedral_mesh } from "./delaunay/compute_delaunay_tetrahedral_mesh.js";
3
- import { LineBasicMaterial, Uint32BufferAttribute } from "three";
4
- import { BufferGeometry } from "three/src/core/BufferGeometry.js";
5
- import { Float32BufferAttribute } from "three/src/core/BufferAttribute.js";
3
+ import { LineBasicMaterial } from "three";
6
4
  import { ShadedGeometry } from "../../../../engine/graphics/ecs/mesh-v2/ShadedGeometry.js";
7
5
  import { DrawMode } from "../../../../engine/graphics/ecs/mesh-v2/DrawMode.js";
8
6
  import EntityBuilder from "../../../../engine/ecs/EntityBuilder.js";
@@ -10,7 +8,11 @@ import { Transform } from "../../../../engine/ecs/transform/Transform.js";
10
8
  import { ShadedGeometrySystem } from "../../../../engine/graphics/ecs/mesh-v2/ShadedGeometrySystem.js";
11
9
  import { GizmoRenderingPlugin } from "../../../../engine/graphics/render/gizmo/GizmoRenderingPlugin.js";
12
10
  import { Gizmo } from "../../../../engine/graphics/render/gizmo/Gizmo.js";
13
- import { LAYOUT_TETRA_BYTE_SIZE } from "./tetrahedra_collection.js";
11
+ import { build_tetrahedral_mesh_buffer_geometry } from "./build_tetrahedral_mesh_buffer_geometry.js";
12
+ import { seededRandom } from "../../../math/random/seededRandom.js";
13
+ import { randomFloatBetween } from "../../../math/random/randomFloatBetween.js";
14
+ import { delay } from "../../../process/delay.js";
15
+ import { TetrahedralMesh } from "./TetrahedralMesh.js";
14
16
 
15
17
  /**
16
18
  *
@@ -26,45 +28,52 @@ async function main(engine) {
26
28
  const offset = [7.5, 1, 7.5];
27
29
  const scale = [.5, .5, .5];
28
30
 
29
- const points = [
30
- 0, 0, 0,
31
- 10, 0, 0,
32
- 10, 0, 10,
33
- 0, 0, 10,
34
-
35
- 0, 10, 0,
36
- 10, 10, 0,
37
- 10, 10, 10,
38
- 0, 10, 10,
39
- ];
40
-
41
- const tetrahedra = compute_delaunay_tetrahedral_mesh(points, points.length / 3);
42
-
43
- const lines = [];
31
+ const points = [];
32
+
33
+ // points.push(
34
+ // 0, 0, 0,
35
+ // 10, 0, 0,
36
+ // 10, 0, 10,
37
+ // 0, 0, 10,
38
+ //
39
+ // 0, 10, 0,
40
+ // 10, 10, 0,
41
+ // 10, 10, 10,
42
+ // 0, 10, 10,
43
+ // );
44
+
45
+ const random = seededRandom();
46
+
47
+ for (let i = 0; i < 600; i++) {
48
+ points.push(
49
+ randomFloatBetween(random, -100, 100),
50
+ randomFloatBetween(random, 0, 150),
51
+ randomFloatBetween(random, -100, 100),
52
+ );
53
+ }
44
54
 
45
- for (let i = tetrahedra.__occupancy.nextSetBit(0); i !== -1; i = tetrahedra.__occupancy.nextSetBit(i + 1)) {
55
+ // make_justified_point_grid(new AABB3(-100, 0, -100, 100, 150, 100), 40, (x, y, z) => {
56
+ // points.push(x, y, z);
57
+ // });
46
58
 
47
- const tet_address = i * LAYOUT_TETRA_BYTE_SIZE;
59
+ await delay(1000);
48
60
 
49
- const a = tetrahedra.__view.getUint32(tet_address);
50
- const b = tetrahedra.__view.getUint32(tet_address + 4);
51
- const c = tetrahedra.__view.getUint32(tet_address + 8);
52
- const d = tetrahedra.__view.getUint32(tet_address + 12);
61
+ const tetrahedra = new TetrahedralMesh();
62
+ // console.time('mesh build');
63
+ console.profile('mesh build');
64
+ compute_delaunay_tetrahedral_mesh(tetrahedra, points, points.length / 3);
65
+ console.profileEnd('mesh build');
66
+ // console.timeEnd('mesh build');
53
67
 
54
- lines.push(a, b);
55
- lines.push(a, c);
56
- lines.push(a, d);
68
+ console.log(tetrahedra);
57
69
 
58
- lines.push(b, c);
59
- lines.push(c, d);
60
- lines.push(b, d);
70
+ await delay(500);
61
71
 
62
- }
72
+ const relocated_elements = tetrahedra.compact();
73
+ console.log(`Compaction relocated ${relocated_elements} elements`);
63
74
 
64
- const geometry = new BufferGeometry();
75
+ const geometry = build_tetrahedral_mesh_buffer_geometry(tetrahedra, points);
65
76
 
66
- geometry.setIndex(new Uint32BufferAttribute(lines, 1, false));
67
- geometry.setAttribute('position', new Float32BufferAttribute(points, 3, false));
68
77
 
69
78
 
70
79
  new EntityBuilder()
@@ -0,0 +1,83 @@
1
+ /**
2
+ * Compute signed volume of a tetrahedron with the last point at the origin
3
+ * @see "EFFICIENT FEATURE EXTRACTION FOR 2D/3D OBJECTS IN MESH REPRESENTATION" by Cha Zhang and Tsuhan Chen
4
+ * @param {number} ax
5
+ * @param {number} ay
6
+ * @param {number} az
7
+ * @param {number} bx
8
+ * @param {number} by
9
+ * @param {number} bz
10
+ * @param {number} cx
11
+ * @param {number} cy
12
+ * @param {number} cz
13
+ * @return {number}
14
+ */
15
+ function triangle_compute_signed_volume(
16
+ ax, ay, az,
17
+ bx, by, bz,
18
+ cx, cy, cz
19
+ ) {
20
+
21
+ const v321 = cx * by * az;
22
+ const v231 = bx * cy * az;
23
+ const v312 = cx * ay * bz;
24
+ const v132 = ax * cy * bz;
25
+ const v213 = bx * ay * cz;
26
+ const v123 = ax * by * cz;
27
+
28
+ return (1.0 / 6.0) * (-v321 + v231 + v312 - v132 - v213 + v123);
29
+
30
+ }
31
+
32
+
33
+ /**
34
+ * @see https://en.wikipedia.org/wiki/Tetrahedron
35
+ *
36
+ * @param {ArrayLike<number>|number[]|Float32Array} points
37
+ * @param {number} a
38
+ * @param {number} b
39
+ * @param {number} c
40
+ * @param {number} d
41
+ * @returns {number}
42
+ */
43
+ export function tetrahedron_compute_signed_volume(points, a, b, c, d) {
44
+
45
+ const a3 = a * 3;
46
+ const b3 = b * 3;
47
+ const c3 = c * 3;
48
+ const d3 = d * 3;
49
+
50
+ const ax = points[a3];
51
+ const ay = points[a3 + 1];
52
+ const az = points[a3 + 2];
53
+
54
+ const bx = points[b3];
55
+ const by = points[b3 + 1];
56
+ const bz = points[b3 + 2];
57
+
58
+ const cx = points[c3];
59
+ const cy = points[c3 + 1];
60
+ const cz = points[c3 + 2];
61
+
62
+ const dx = points[d3];
63
+ const dy = points[d3 + 1];
64
+ const dz = points[d3 + 2];
65
+
66
+ const adx = ax - dx;
67
+ const ady = ay - dy;
68
+ const adz = az - dz;
69
+
70
+ const bdx = bx - dx;
71
+ const bdy = by - dy;
72
+ const bdz = bz - dz;
73
+
74
+ const cdx = cx - dx;
75
+ const cdy = cy - dy;
76
+ const cdz = cz - dz;
77
+
78
+ return triangle_compute_signed_volume(
79
+ adx, ady, adz,
80
+ bdx, bdy, bdz,
81
+ cdx, cdy, cdz
82
+ );
83
+ }
@@ -0,0 +1,24 @@
1
+ import { tetrahedron_compute_signed_volume } from "./tetrahedron_compute_signed_volume.js";
2
+
3
+ test("0 volume", () => {
4
+ expect(tetrahedron_compute_signed_volume([
5
+ 0, 0, 0
6
+ ], 0, 0, 0, 0)).toBe(0);
7
+ });
8
+
9
+ test("positive volume", () => {
10
+
11
+ expect(tetrahedron_compute_signed_volume([
12
+ 1, 0, 1,
13
+ 1, 0, 0,
14
+ 0, 0, 0,
15
+ 1, 1, 1
16
+ ], 1, 2, 3, 0)).toBeGreaterThan(0);
17
+
18
+ expect(tetrahedron_compute_signed_volume([
19
+ 0, 0, 0,
20
+ 2, 0, 0,
21
+ 0, 2, 0,
22
+ 0, 0, 2
23
+ ], 1, 2, 3, 0)).toBeGreaterThan(0);
24
+ })
@@ -0,0 +1,66 @@
1
+ import { tetrahedron_contains_point } from "./tetrahedron_contains_point.js";
2
+
3
+ test("basic containment", () => {
4
+ const tetrahedron = [
5
+ 1, 0, 1,
6
+ 1, 0, 0,
7
+ 0, 0, 0,
8
+ 1, 1, 1
9
+ ];
10
+
11
+ expect(
12
+ tetrahedron_contains_point([
13
+ ...tetrahedron,
14
+ //
15
+ 0.5, 0.1, 0.5
16
+ ], 0, 1, 2, 3, 4)
17
+ ).toBe(true);
18
+
19
+ expect(
20
+ tetrahedron_contains_point([
21
+ ...tetrahedron,
22
+ //
23
+ -1, 0, 0
24
+ ], 0, 1, 2, 3, 4)
25
+ ).toBe(false);
26
+
27
+ expect(
28
+ tetrahedron_contains_point([
29
+ ...tetrahedron,
30
+ //
31
+ 2, 0, 0
32
+ ], 0, 1, 2, 3, 4)
33
+ ).toBe(false);
34
+
35
+ expect(
36
+ tetrahedron_contains_point([
37
+ ...tetrahedron,
38
+ //
39
+ 0, -1, 0
40
+ ], 0, 1, 2, 3, 4)
41
+ ).toBe(false);
42
+
43
+ expect(
44
+ tetrahedron_contains_point([
45
+ ...tetrahedron,
46
+ //
47
+ 0, 2, 0
48
+ ], 0, 1, 2, 3, 4)
49
+ ).toBe(false);
50
+
51
+ expect(
52
+ tetrahedron_contains_point([
53
+ ...tetrahedron,
54
+ //
55
+ 0, 0, -1
56
+ ], 0, 1, 2, 3, 4)
57
+ ).toBe(false);
58
+
59
+ expect(
60
+ tetrahedron_contains_point([
61
+ ...tetrahedron,
62
+ //
63
+ 0, 0, 2
64
+ ], 0, 1, 2, 3, 4)
65
+ ).toBe(false);
66
+ });
@@ -0,0 +1,166 @@
1
+ import { tetrahedron_compute_signed_volume } from "./tetrahedron_compute_signed_volume.js";
2
+ import { noop } from "../../../function/Functions.js";
3
+ import { INVALID_NEIGHBOUR } from "./TetrahedralMesh.js";
4
+
5
+ /**
6
+ *
7
+ * @param {TetrahedralMesh} mesh
8
+ * @param {ArrayLike<number>|number[]} points
9
+ * @param {number} tet
10
+ * @return {number}
11
+ */
12
+ export function get_tetrahedron_volume(mesh, points, tet) {
13
+
14
+ const a = mesh.getVertexIndex(tet, 0);
15
+ const b = mesh.getVertexIndex(tet, 1);
16
+ const c = mesh.getVertexIndex(tet, 2);
17
+ const d = mesh.getVertexIndex(tet, 3);
18
+
19
+ return tetrahedron_compute_signed_volume(points, a, b, c, d);
20
+ }
21
+
22
+ /**
23
+ *
24
+ * @param {TetrahedralMesh} mesh
25
+ * @param {number} tet
26
+ * @param {number} neighbour_id
27
+ * @param {function(string):*} consumer
28
+ * @return {boolean}
29
+ */
30
+ export function validate_neighbour(mesh, tet, neighbour_id, consumer) {
31
+ let valid = true;
32
+
33
+ const neighbour = mesh.getNeighbour(tet, neighbour_id);
34
+
35
+ if (neighbour === INVALID_NEIGHBOUR) {
36
+ return true;
37
+ }
38
+
39
+ // decode neighbour
40
+ const neighbour_tet = neighbour >> 2;
41
+ const neighbour_vertex_id = neighbour & 3;
42
+
43
+ if (!mesh.exists(neighbour_tet)) {
44
+
45
+
46
+ consumer(`Tetrahedron ${tet} Neighbour[${neighbour_id}] ${neighbour_tet} does not exist in the mesh`);
47
+
48
+ return false;
49
+ }
50
+
51
+ const back_link = mesh.getNeighbour(neighbour_tet, neighbour_vertex_id);
52
+
53
+ if (back_link === INVALID_NEIGHBOUR) {
54
+
55
+ consumer(`Tetrahedron ${tet} Neighbour[${neighbour_id}] ${neighbour_tet} links back to invalid neighbour (no neighbour), expected ${tet} instead`);
56
+ return false;
57
+ }
58
+
59
+ const back_link_tet = back_link >> 2;
60
+ const back_link_vertex_index = back_link & 3;
61
+
62
+ if (back_link_tet !== tet) {
63
+ valid = false;
64
+
65
+ consumer(`Tetrahedron ${tet} Neighbour[${neighbour_id}] ${neighbour_tet} links back to a different tet, expected ${tet}, got ${back_link_tet}`)
66
+ } else if (back_link_vertex_index !== neighbour_id) {
67
+ valid = false;
68
+
69
+ consumer(`Tetrahedron ${tet} Neighbour[${neighbour_id}] ${neighbour_tet} links back to a different vertex, expected ${neighbour_id}, got ${back_link_vertex_index}`);
70
+
71
+ }
72
+
73
+ for (let j = 0; j < 4; j++) {
74
+ const v = mesh.getVertexIndex(tet, j);
75
+
76
+ if (j === neighbour_id) {
77
+ continue;
78
+ }
79
+
80
+ if (!mesh.tetContainsVertex(neighbour_tet, v)) {
81
+ valid = false;
82
+
83
+ consumer(`Tetrahedron ${tet} Neighbour[${neighbour_id}] ${neighbour_tet} does not share vertex ${v} with the tet`);
84
+
85
+ }
86
+ }
87
+
88
+ return valid;
89
+ }
90
+
91
+
92
+ /**
93
+ *
94
+ * @param {TetrahedralMesh} mesh
95
+ * @param {number} tet
96
+ * @param {function(problem:string):*} consumer
97
+ */
98
+ export function validate_tetrahedron_neighbourhood(mesh, tet, consumer = noop) {
99
+ let valid = true;
100
+
101
+ for (let i = 0; i < 4; i++) {
102
+
103
+ if (!validate_neighbour(mesh, tet, i, consumer)) {
104
+ valid = false;
105
+ }
106
+
107
+ }
108
+
109
+ return valid;
110
+ }
111
+
112
+ /**
113
+ *
114
+ * @param {TetrahedralMesh} mesh
115
+ * @param {number} tet
116
+ * @returns {boolean}
117
+ */
118
+ function is_tetrahedron_degenerate(mesh, tet) {
119
+
120
+ for (let i0 = 0; i0 < 4; i0++) {
121
+ const v0 = mesh.getVertexIndex(tet, i0);
122
+ for (let i1 = i0 + 1; i1 < 4; i1++) {
123
+ if (v0 === mesh.getVertexIndex(tet, i1)) {
124
+ // identical vertices
125
+ return true;
126
+ }
127
+ }
128
+ }
129
+
130
+ return false;
131
+ }
132
+
133
+ /**
134
+ *
135
+ * @param {TetrahedralMesh} mesh
136
+ * @param {ArrayLike<number>} points
137
+ * @param {(problem:string)=>*} [consumer]
138
+ * @returns {boolean}
139
+ */
140
+ export function validate_tetrahedral_mesh(mesh, points, consumer = noop) {
141
+ let is_valid = true;
142
+
143
+ mesh.forEach((tet, mesh) => {
144
+
145
+ const volume = get_tetrahedron_volume(mesh, points, tet);
146
+ if (volume < 0) {
147
+ is_valid = false;
148
+
149
+ consumer(`Tetrahedron ${tet} has negative volume ${volume}`);
150
+ }
151
+
152
+ // check for degeneracy
153
+ if (is_tetrahedron_degenerate(mesh, tet)) {
154
+ is_valid = false;
155
+ consumer(`Tetrahedron ${tet} is degenerate (multiple vertices have the same index)`);
156
+ }
157
+
158
+ if (!validate_tetrahedron_neighbourhood(mesh, tet, consumer)) {
159
+ is_valid = false;
160
+ }
161
+
162
+ });
163
+
164
+
165
+ return is_valid;
166
+ }
@@ -0,0 +1,31 @@
1
+ import { max2 } from "../../../math/max2.js";
2
+
3
+ /**
4
+ * Created a grid of points to fill given bounds, spacing is used as upper-bound,
5
+ * actual spacing will be justified to provide even distanced along each dimension separately
6
+ * @param {AABB3} aabb3
7
+ * @param {number} spacing
8
+ * @param {function(x:number,y:number,z:number)} callback
9
+ */
10
+ export function make_justified_point_grid(aabb3, spacing, callback) {
11
+
12
+ const steps_x = Math.ceil(aabb3.getExtentsX() / spacing);
13
+ const steps_y = Math.ceil(aabb3.getExtentsY() / spacing);
14
+ const steps_z = Math.ceil(aabb3.getExtentsZ() / spacing);
15
+
16
+ const spacing_x = aabb3.getExtentsX() / max2(1, steps_x - 1);
17
+ const spacing_y = aabb3.getExtentsY() / max2(1, steps_y - 1);
18
+ const spacing_z = aabb3.getExtentsZ() / max2(1, steps_z - 1);
19
+
20
+ for (let i = 0; i < steps_x; i++) {
21
+ for (let j = 0; j < steps_y; j++) {
22
+ for (let k = 0; k < steps_z; k++) {
23
+ const x = i * spacing_x + aabb3.x0;
24
+ const y = j * spacing_y + aabb3.y0;
25
+ const z = k * spacing_z + aabb3.z0;
26
+
27
+ callback(x, y, z);
28
+ }
29
+ }
30
+ }
31
+ }
@@ -1,30 +1,3 @@
1
- import Vector3 from "./Vector3.js";
2
-
3
- export function Bezier() {
4
-
5
- }
6
-
7
- Bezier.computeQuadratic = (function () {
8
- const a = new Vector3();
9
-
10
- function computeQuadratic(p0, p1, p2, t, result) {
11
- const minus = 1 - t;
12
- const minus2 = minus * minus;
13
-
14
- result.copy(p0).multiplyScalar(minus2);
15
-
16
- a.copy(p1).multiplyScalar(minus * 2 * t);
17
- result.add(a);
18
-
19
- a.copy(p2).multiplyScalar(t * t);
20
- result.add(a);
21
-
22
- }
23
-
24
- return computeQuadratic;
25
- })();
26
-
27
-
28
1
  /**
29
2
  *
30
3
  * @param {Vector2} result
@@ -5,10 +5,6 @@
5
5
 
6
6
  import { v3_dot } from "./v3_dot.js";
7
7
 
8
- function Plane() {
9
-
10
- }
11
-
12
8
  /**
13
9
 
14
10
  Algorithm taken from http://geomalgorithms.com/a05-_intersect-1.html. See the
@@ -40,13 +40,13 @@ export class Subspan {
40
40
 
41
41
  /**
42
42
  * DxD square matrix, where D is number of dimensions
43
- * @type {[]}
43
+ * @type {number[][]}
44
44
  */
45
45
  this.Q = null;
46
46
 
47
47
  /**
48
48
  * DxD square matrix, where D is number of dimensions
49
- * @type {[]}
49
+ * @type {number[][]}
50
50
  */
51
51
  this.R = null;
52
52
 
@@ -11,7 +11,12 @@ import { lerp } from "../math/lerp.js";
11
11
  * @param {number} b_z
12
12
  * @param {number} fraction
13
13
  */
14
- export function v3_lerp(result, a_x, a_y, a_z, b_x, b_y, b_z, fraction) {
14
+ export function v3_lerp(
15
+ result,
16
+ a_x, a_y, a_z,
17
+ b_x, b_y, b_z,
18
+ fraction
19
+ ) {
15
20
 
16
21
  const x = lerp(a_x, b_x, fraction);
17
22
  const y = lerp(a_y, b_y, fraction);
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Integer square root
3
+ *
4
+ * @author Jim Ulery (attributed on hextreme)
5
+ * @see https://en.wikipedia.org/wiki/Integer_square_root
6
+ * @see https://git.immc.ucl.ac.be/hextreme/hxt_seqdel/-/blob/master/src/hxt_tetrahedra.c#L54
7
+ *
8
+ * @param {number} input
9
+ * @returns {number}
10
+ */
11
+ export function isqrt(input) {
12
+ let temp;
13
+
14
+ let g = 0;
15
+ let b = 0x8000;
16
+ let bshft = 15;
17
+
18
+ let val = input;
19
+
20
+ do {
21
+ if (val >= (temp = (((g << 1) + b) << bshft--))) {
22
+ g += b;
23
+ val -= temp;
24
+ }
25
+ } while (b >>= 1);
26
+
27
+ return g;
28
+ }
@@ -0,0 +1,9 @@
1
+ import { isqrt } from "./isqrt.js";
2
+
3
+ test('1', () => {
4
+ expect(isqrt(1)).toBe(1);
5
+ });
6
+
7
+ test('4', () => {
8
+ expect(isqrt(4)).toBe(2);
9
+ });
@@ -0,0 +1,25 @@
1
+ import { max2 } from "./max2.js";
2
+
3
+ test("0,0", () => {
4
+ expect(max2(0, 0)).toBe(0);
5
+ });
6
+
7
+ test("0,1", () => {
8
+ expect(max2(0, 1)).toBe(1);
9
+ });
10
+
11
+ test("1,0", () => {
12
+ expect(max2(1, 0)).toBe(1);
13
+ });
14
+
15
+ test("-1,0", () => {
16
+ expect(max2(-1, 0)).toBe(0);
17
+ });
18
+
19
+ test("0,-1", () => {
20
+ expect(max2(0, -1)).toBe(0);
21
+ });
22
+
23
+ test("Infinity,-Infinity", () => {
24
+ expect(max2(Infinity, -Infinity)).toBe(Infinity);
25
+ });
@@ -0,0 +1,25 @@
1
+ import { min2 } from "./min2.js";
2
+
3
+ test("0,0", () => {
4
+ expect(min2(0, 0)).toBe(0);
5
+ });
6
+
7
+ test("0,1", () => {
8
+ expect(min2(0, 1)).toBe(0);
9
+ });
10
+
11
+ test("1,0", () => {
12
+ expect(min2(1, 0)).toBe(0);
13
+ });
14
+
15
+ test("-1,0", () => {
16
+ expect(min2(-1, 0)).toBe(-1);
17
+ });
18
+
19
+ test("0,-1", () => {
20
+ expect(min2(0, -1)).toBe(-1);
21
+ });
22
+
23
+ test("Infinity,-Infinity", () => {
24
+ expect(min2(Infinity, -Infinity)).toBe(-Infinity);
25
+ });
@@ -1,8 +1,8 @@
1
1
  import { assert } from "../../../assert.js";
2
- import { isArrayEqual } from "../../../collection/ArrayUtils.js";
3
2
  import List from "../../../collection/list/List.js";
4
3
  import { NodeInstancePortReference } from "./NodeInstancePortReference.js";
5
4
  import { PortDirection } from "./PortDirection.js";
5
+ import { isArrayEqual } from "../../../collection/array/isArrayEqual.js";
6
6
 
7
7
  export class NodeInstance {
8
8
  constructor() {
@@ -27,14 +27,14 @@ export class NodeInstance {
27
27
 
28
28
  /**
29
29
  * Internal instance data
30
- * @type {[]}
30
+ * @type {Array}
31
31
  */
32
32
  this.parameters = [];
33
33
 
34
34
 
35
35
  /**
36
36
  * @transient
37
- * @type {[]}
37
+ * @type {Array}
38
38
  */
39
39
  this.outputsValues = [];
40
40
 
@@ -6,7 +6,7 @@ export class PrefixTreeLeaf extends PrefixTreeNode {
6
6
 
7
7
  /**
8
8
  * Values associated with the word
9
- * @type {[]}
9
+ * @type {Array}
10
10
  */
11
11
  this.values = [];
12
12
 
@@ -0,0 +1,5 @@
1
+ export function delay(timeout_ms) {
2
+ return new Promise((resolve, reject) => {
3
+ setTimeout(resolve, timeout_ms);
4
+ });
5
+ }