@woosh/meep-engine 2.139.0 → 2.140.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 (172) hide show
  1. package/package.json +1 -1
  2. package/src/core/bvh2/bvh3/query/bvh_query_user_data_overlaps_aabb.d.ts +3 -3
  3. package/src/core/bvh2/bvh3/query/bvh_query_user_data_overlaps_aabb.d.ts.map +1 -1
  4. package/src/core/bvh2/bvh3/query/bvh_query_user_data_overlaps_aabb.js +4 -4
  5. package/src/{engine/physics/broadphase/aabb_transform_oriented.d.ts → core/geom/3d/aabb/aabb3_transform_oriented.d.ts} +2 -2
  6. package/src/core/geom/3d/aabb/aabb3_transform_oriented.d.ts.map +1 -0
  7. package/src/{engine/physics/broadphase/aabb_transform_oriented.js → core/geom/3d/aabb/aabb3_transform_oriented.js} +1 -1
  8. package/src/core/geom/3d/quaternion/quat3_to_matrix3.d.ts +54 -0
  9. package/src/core/geom/3d/quaternion/quat3_to_matrix3.d.ts.map +1 -0
  10. package/src/core/geom/3d/quaternion/quat3_to_matrix3.js +69 -0
  11. package/src/core/geom/3d/shape/AbstractShape3D.d.ts +24 -2
  12. package/src/core/geom/3d/shape/AbstractShape3D.d.ts.map +1 -1
  13. package/src/core/geom/3d/shape/AbstractShape3D.js +24 -1
  14. package/src/core/geom/3d/shape/HeightMapShape3D.d.ts +148 -0
  15. package/src/core/geom/3d/shape/HeightMapShape3D.d.ts.map +1 -0
  16. package/src/core/geom/3d/shape/HeightMapShape3D.js +451 -0
  17. package/src/core/geom/3d/shape/MeshShape3D.d.ts +210 -0
  18. package/src/core/geom/3d/shape/MeshShape3D.d.ts.map +1 -0
  19. package/src/core/geom/3d/shape/MeshShape3D.js +593 -0
  20. package/src/core/geom/3d/shape/TransformedShape3D.d.ts.map +1 -1
  21. package/src/core/geom/3d/shape/TransformedShape3D.js +46 -2
  22. package/src/core/geom/3d/shape/Triangle3D.d.ts +95 -0
  23. package/src/core/geom/3d/shape/Triangle3D.d.ts.map +1 -0
  24. package/src/core/geom/3d/shape/Triangle3D.js +318 -0
  25. package/src/core/geom/3d/shape/UnionShape3D.js +13 -0
  26. package/src/core/geom/3d/shape/shape_mesh_from_geometry.d.ts +30 -0
  27. package/src/core/geom/3d/shape/shape_mesh_from_geometry.d.ts.map +1 -0
  28. package/src/core/geom/3d/shape/shape_mesh_from_geometry.js +64 -0
  29. package/src/core/geom/3d/tetrahedra/prototype_tetrahedrize_mesh.js +9 -11
  30. package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_build_vertex_to_tets_map.d.ts +28 -0
  31. package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_build_vertex_to_tets_map.d.ts.map +1 -0
  32. package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_build_vertex_to_tets_map.js +48 -0
  33. package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_improve_quality.d.ts.map +1 -1
  34. package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_improve_quality.js +40 -18
  35. package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_smooth_vertex.d.ts +9 -5
  36. package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_smooth_vertex.d.ts.map +1 -1
  37. package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_smooth_vertex.js +38 -10
  38. package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_vertex_is_boundary.d.ts +14 -5
  39. package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_vertex_is_boundary.d.ts.map +1 -1
  40. package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_vertex_is_boundary.js +47 -5
  41. package/src/core/geom/3d/topology/struct/binary/BinaryElementPool.d.ts +19 -0
  42. package/src/core/geom/3d/topology/struct/binary/BinaryElementPool.d.ts.map +1 -1
  43. package/src/core/geom/3d/topology/struct/binary/BinaryElementPool.js +75 -13
  44. package/src/core/geom/3d/triangle/v3_compute_triangle_normal.d.ts +2 -2
  45. package/src/core/geom/3d/triangle/v3_compute_triangle_normal.d.ts.map +1 -1
  46. package/src/core/geom/3d/triangle/v3_compute_triangle_normal.js +1 -1
  47. package/src/core/geom/vec3/v3_dot_array_array.d.ts +3 -3
  48. package/src/core/geom/vec3/v3_dot_array_array.d.ts.map +1 -1
  49. package/src/core/geom/vec3/v3_dot_array_array.js +2 -2
  50. package/src/core/geom/vec3/v3_negate_array.d.ts +3 -3
  51. package/src/core/geom/vec3/v3_negate_array.d.ts.map +1 -1
  52. package/src/core/geom/vec3/v3_negate_array.js +2 -2
  53. package/src/core/geom/vec3/v3_quat3_apply.d.ts +29 -0
  54. package/src/core/geom/vec3/v3_quat3_apply.d.ts.map +1 -0
  55. package/src/core/geom/vec3/v3_quat3_apply.js +39 -0
  56. package/src/core/geom/vec3/v3_quat3_apply_inverse.d.ts +30 -0
  57. package/src/core/geom/vec3/v3_quat3_apply_inverse.d.ts.map +1 -0
  58. package/src/core/geom/vec3/v3_quat3_apply_inverse.js +41 -0
  59. package/src/core/geom/vec3/v3_triple_cross_product.d.ts +32 -0
  60. package/src/core/geom/vec3/v3_triple_cross_product.d.ts.map +1 -0
  61. package/src/core/geom/vec3/v3_triple_cross_product.js +45 -0
  62. package/src/engine/control/first-person/FirstPersonPlayerController.d.ts +16 -3
  63. package/src/engine/control/first-person/FirstPersonPlayerController.d.ts.map +1 -1
  64. package/src/engine/control/first-person/FirstPersonPlayerController.js +211 -211
  65. package/src/engine/control/first-person/FirstPersonPlayerControllerConfig.d.ts +72 -8
  66. package/src/engine/control/first-person/FirstPersonPlayerControllerConfig.d.ts.map +1 -1
  67. package/src/engine/control/first-person/FirstPersonPlayerControllerConfig.js +37 -5
  68. package/src/engine/control/first-person/FirstPersonPlayerControllerSystem.d.ts +101 -3
  69. package/src/engine/control/first-person/FirstPersonPlayerControllerSystem.d.ts.map +1 -1
  70. package/src/engine/control/first-person/FirstPersonPlayerControllerSystem.js +1789 -1416
  71. package/src/engine/control/first-person/TODO.md +173 -127
  72. package/src/engine/control/first-person/abilities/Slide.d.ts.map +1 -1
  73. package/src/engine/control/first-person/abilities/Slide.js +9 -1
  74. package/src/engine/control/first-person/prototype_first_person_controller.js +88 -2
  75. package/src/engine/control/first-person/test/buildTestPlayer.d.ts.map +1 -1
  76. package/src/engine/control/first-person/test/buildTestPlayer.js +9 -1
  77. package/src/engine/graphics/geometry/CapsuleGeometry.d.ts +42 -0
  78. package/src/engine/graphics/geometry/CapsuleGeometry.d.ts.map +1 -0
  79. package/src/engine/graphics/geometry/CapsuleGeometry.js +171 -0
  80. package/src/engine/physics/BULLET_REVIEW.md +945 -0
  81. package/src/engine/physics/CANNON_REVIEW.md +1300 -0
  82. package/src/engine/physics/JOLT_REVIEW.md +913 -0
  83. package/src/engine/physics/PLAN.md +461 -236
  84. package/src/engine/physics/RAPIER_REVIEW.md +934 -0
  85. package/src/engine/physics/REVIEW_001_ACTION_PLAN.md +642 -0
  86. package/src/engine/physics/broadphase/compute_fat_world_aabb.js +2 -2
  87. package/src/engine/physics/contact/ManifoldStore.d.ts +83 -10
  88. package/src/engine/physics/contact/ManifoldStore.d.ts.map +1 -1
  89. package/src/engine/physics/contact/ManifoldStore.js +608 -499
  90. package/src/engine/physics/ecs/ColliderObserverSystem.d.ts +2 -2
  91. package/src/engine/physics/ecs/ColliderObserverSystem.d.ts.map +1 -1
  92. package/src/engine/physics/ecs/PhysicsSystem.d.ts +128 -20
  93. package/src/engine/physics/ecs/PhysicsSystem.d.ts.map +1 -1
  94. package/src/engine/physics/ecs/PhysicsSystem.js +1301 -1159
  95. package/src/engine/physics/fluid/FluidSimulator.d.ts.map +1 -1
  96. package/src/engine/physics/fluid/FluidSimulator.js +2 -1
  97. package/src/engine/physics/fluid/solver/v3_grid_subtract_pressure_gradient.d.ts +28 -6
  98. package/src/engine/physics/fluid/solver/v3_grid_subtract_pressure_gradient.d.ts.map +1 -1
  99. package/src/engine/physics/fluid/solver/v3_grid_subtract_pressure_gradient.js +39 -17
  100. package/src/engine/physics/gjk/expanding_polytope_algorithm.d.ts +6 -6
  101. package/src/engine/physics/gjk/expanding_polytope_algorithm.d.ts.map +1 -1
  102. package/src/engine/physics/gjk/expanding_polytope_algorithm.js +68 -22
  103. package/src/engine/physics/gjk/gjk.d.ts +28 -2
  104. package/src/engine/physics/gjk/gjk.d.ts.map +1 -1
  105. package/src/engine/physics/gjk/gjk.js +421 -378
  106. package/src/engine/physics/gjk/minkowski_support.d.ts +37 -0
  107. package/src/engine/physics/gjk/minkowski_support.d.ts.map +1 -0
  108. package/src/engine/physics/gjk/minkowski_support.js +75 -0
  109. package/src/engine/physics/gjk/mpr.d.ts +56 -0
  110. package/src/engine/physics/gjk/mpr.d.ts.map +1 -0
  111. package/src/engine/physics/gjk/mpr.js +344 -0
  112. package/src/engine/physics/inertia/world_inverse_inertia.d.ts +20 -5
  113. package/src/engine/physics/inertia/world_inverse_inertia.d.ts.map +1 -1
  114. package/src/engine/physics/inertia/world_inverse_inertia.js +36 -38
  115. package/src/engine/physics/integration/integrate_position.d.ts +25 -7
  116. package/src/engine/physics/integration/integrate_position.d.ts.map +1 -1
  117. package/src/engine/physics/integration/integrate_position.js +43 -12
  118. package/src/engine/physics/integration/integrate_velocity.d.ts +30 -0
  119. package/src/engine/physics/integration/integrate_velocity.d.ts.map +1 -1
  120. package/src/engine/physics/integration/integrate_velocity.js +82 -1
  121. package/src/engine/physics/narrowphase/PosedShape.d.ts +0 -8
  122. package/src/engine/physics/narrowphase/PosedShape.d.ts.map +1 -1
  123. package/src/engine/physics/narrowphase/PosedShape.js +28 -30
  124. package/src/engine/physics/narrowphase/box_box_manifold.d.ts.map +1 -1
  125. package/src/engine/physics/narrowphase/box_box_manifold.js +113 -17
  126. package/src/engine/physics/narrowphase/box_triangle_contact.d.ts +30 -0
  127. package/src/engine/physics/narrowphase/box_triangle_contact.d.ts.map +1 -0
  128. package/src/engine/physics/narrowphase/box_triangle_contact.js +811 -0
  129. package/src/engine/physics/narrowphase/capsule_contacts.d.ts.map +1 -1
  130. package/src/engine/physics/narrowphase/capsule_contacts.js +10 -56
  131. package/src/engine/physics/narrowphase/capsule_triangle_contact.d.ts +71 -0
  132. package/src/engine/physics/narrowphase/capsule_triangle_contact.d.ts.map +1 -0
  133. package/src/engine/physics/narrowphase/capsule_triangle_contact.js +375 -0
  134. package/src/engine/physics/narrowphase/compute_penetration.d.ts +91 -0
  135. package/src/engine/physics/narrowphase/compute_penetration.d.ts.map +1 -0
  136. package/src/engine/physics/narrowphase/compute_penetration.js +396 -0
  137. package/src/engine/physics/narrowphase/decomposition/aabb_world_to_local.d.ts +35 -0
  138. package/src/engine/physics/narrowphase/decomposition/aabb_world_to_local.d.ts.map +1 -0
  139. package/src/engine/physics/narrowphase/decomposition/aabb_world_to_local.js +80 -0
  140. package/src/engine/physics/narrowphase/decomposition/decompose_to_triangles.d.ts +31 -0
  141. package/src/engine/physics/narrowphase/decomposition/decompose_to_triangles.d.ts.map +1 -0
  142. package/src/engine/physics/narrowphase/decomposition/decompose_to_triangles.js +55 -0
  143. package/src/engine/physics/narrowphase/decomposition/heightmap_enumerate_triangles.d.ts +42 -0
  144. package/src/engine/physics/narrowphase/decomposition/heightmap_enumerate_triangles.d.ts.map +1 -0
  145. package/src/engine/physics/narrowphase/decomposition/heightmap_enumerate_triangles.js +204 -0
  146. package/src/engine/physics/narrowphase/decomposition/mesh_enumerate_triangles.d.ts +42 -0
  147. package/src/engine/physics/narrowphase/decomposition/mesh_enumerate_triangles.d.ts.map +1 -0
  148. package/src/engine/physics/narrowphase/decomposition/mesh_enumerate_triangles.js +94 -0
  149. package/src/engine/physics/narrowphase/decomposition/triangle_buffer_layout.d.ts +37 -0
  150. package/src/engine/physics/narrowphase/decomposition/triangle_buffer_layout.d.ts.map +1 -0
  151. package/src/engine/physics/narrowphase/decomposition/triangle_buffer_layout.js +37 -0
  152. package/src/engine/physics/narrowphase/narrowphase_step.d.ts +8 -2
  153. package/src/engine/physics/narrowphase/narrowphase_step.d.ts.map +1 -1
  154. package/src/engine/physics/narrowphase/narrowphase_step.js +1422 -382
  155. package/src/engine/physics/narrowphase/sphere_box_contact.d.ts.map +1 -1
  156. package/src/engine/physics/narrowphase/sphere_box_contact.js +16 -23
  157. package/src/engine/physics/narrowphase/sphere_triangle_contact.d.ts +48 -0
  158. package/src/engine/physics/narrowphase/sphere_triangle_contact.d.ts.map +1 -0
  159. package/src/engine/physics/narrowphase/sphere_triangle_contact.js +143 -0
  160. package/src/engine/physics/queries/overlap_shape.d.ts +51 -0
  161. package/src/engine/physics/queries/overlap_shape.d.ts.map +1 -0
  162. package/src/engine/physics/queries/overlap_shape.js +183 -0
  163. package/src/engine/physics/queries/shape_cast.d.ts +56 -0
  164. package/src/engine/physics/queries/shape_cast.d.ts.map +1 -0
  165. package/src/engine/physics/queries/shape_cast.js +387 -0
  166. package/src/engine/physics/solver/solve_contacts.d.ts +116 -30
  167. package/src/engine/physics/solver/solve_contacts.d.ts.map +1 -1
  168. package/src/engine/physics/solver/solve_contacts.js +641 -223
  169. package/src/engine/physics/broadphase/aabb_transform_oriented.d.ts.map +0 -1
  170. package/src/engine/physics/fluid/solver/v3_grid_solve_pressure_unmasked_legacy.d.ts +0 -20
  171. package/src/engine/physics/fluid/solver/v3_grid_solve_pressure_unmasked_legacy.d.ts.map +0 -1
  172. package/src/engine/physics/fluid/solver/v3_grid_solve_pressure_unmasked_legacy.js +0 -83
@@ -0,0 +1,95 @@
1
+ /**
2
+ * Buffer-backed flyweight triangle shape.
3
+ *
4
+ * Vertex data is NOT stored on the instance — instead the triangle binds
5
+ * to a region of an external Float64 buffer via {@link bind}, reading
6
+ * 9 consecutive floats (vA.xyz, vB.xyz, vC.xyz) at the bound offset.
7
+ *
8
+ * Pattern: the narrowphase keeps one persistent `Triangle3D` per side of
9
+ * a contact pair and rebinds its offset while iterating decomposed
10
+ * triangles from a non-convex shape's enumerator. Zero allocations per
11
+ * iteration step — the cost of "another triangle" is a single integer
12
+ * offset change.
13
+ *
14
+ * The shape is convex (a triangle is the canonical 2-simplex in 3D, and
15
+ * GJK handles 2-simplices natively). It's degenerate in the sense that
16
+ * `volume = 0` and `contains_point` is always false — a triangle is a
17
+ * 2D surface in 3D space, no interior.
18
+ *
19
+ * @author Alex Goldring
20
+ * @copyright Company Named Limited (c) 2026
21
+ */
22
+ export class Triangle3D extends AbstractShape3D {
23
+ /**
24
+ * Convenience constructor for tests and one-off triangles.
25
+ * Allocates a private 9-float buffer; for hot paths use {@link bind}
26
+ * against a shared buffer instead.
27
+ *
28
+ * @param {number} ax
29
+ * @param {number} ay
30
+ * @param {number} az
31
+ * @param {number} bx
32
+ * @param {number} by
33
+ * @param {number} bz
34
+ * @param {number} cx
35
+ * @param {number} cy
36
+ * @param {number} cz
37
+ * @returns {Triangle3D}
38
+ */
39
+ static from(ax: number, ay: number, az: number, bx: number, by: number, bz: number, cx: number, cy: number, cz: number): Triangle3D;
40
+ /**
41
+ * External buffer holding vertex data.
42
+ * @type {Float64Array | null}
43
+ */
44
+ buffer: Float64Array | null;
45
+ /**
46
+ * Float-index of vA.x in {@link buffer}. The other 8 floats
47
+ * (vA.yz, vB.xyz, vC.xyz) follow consecutively.
48
+ * @type {number}
49
+ */
50
+ offset: number;
51
+ /**
52
+ * Bind this triangle to a region of an external buffer. Reads 9
53
+ * consecutive floats starting at `offset`.
54
+ *
55
+ * @param {Float64Array} buffer
56
+ * @param {number} offset float-index of vA.x in the buffer
57
+ * @returns {Triangle3D} this (for chaining)
58
+ */
59
+ bind(buffer: Float64Array, offset: number): Triangle3D;
60
+ support(result: any, result_offset: any, direction_x: any, direction_y: any, direction_z: any): void;
61
+ compute_bounding_box(result: any): void;
62
+ /**
63
+ * A triangle has zero interior volume.
64
+ */
65
+ contains_point(_point: any): boolean;
66
+ /**
67
+ * Signed distance has a well-defined sign relative to the triangle's
68
+ * face plane: positive on the side that the face normal points to
69
+ * (normal = (B-A) × (C-A), CCW convention), negative on the other.
70
+ *
71
+ * Magnitude is the true point-to-triangle distance (handles vertex,
72
+ * edge, and face Voronoi regions correctly via
73
+ * {@link computeTriangleClosestPointToPointBarycentric}).
74
+ */
75
+ signed_distance_at_point(point: any): number;
76
+ nearest_point_on_surface(result: any, reference: any): void;
77
+ /**
78
+ * Uniform random barycentric sample within the triangle.
79
+ * Triangles have no interior, so the sample lies on the surface.
80
+ */
81
+ sample_random_point_in_volume(result: any, result_offset: any, random: any): void;
82
+ /**
83
+ * @param {Triangle3D} other
84
+ * @returns {boolean}
85
+ */
86
+ equals(other: Triangle3D): boolean;
87
+ /**
88
+ * Fast type-check marker.
89
+ * @readonly
90
+ * @type {boolean}
91
+ */
92
+ readonly isTriangle3D: boolean;
93
+ }
94
+ import { AbstractShape3D } from "./AbstractShape3D.js";
95
+ //# sourceMappingURL=Triangle3D.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Triangle3D.d.ts","sourceRoot":"","sources":["../../../../../../src/core/geom/3d/shape/Triangle3D.js"],"names":[],"mappings":"AAMA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH;IAmCI;;;;;;;;;;;;;;;OAeG;IACH,gBAXW,MAAM,MACN,MAAM,MACN,MAAM,MACN,MAAM,MACN,MAAM,MACN,MAAM,MACN,MAAM,MACN,MAAM,MACN,MAAM,GACJ,UAAU,CAWtB;IAxDG;;;OAGG;IACH,QAFU,YAAY,GAAG,IAAI,CAEX;IAElB;;;;OAIG;IACH,QAFU,MAAM,CAED;IAGnB;;;;;;;OAOG;IACH,aAJW,YAAY,UACZ,MAAM,GACJ,UAAU,CAStB;IA6BD,qGAyBC;IAED,wCAeC;IAED;;OAEG;IACH,qCAEC;IAED;;;;;;;;OAQG;IACH,6CA4CC;IAED,4DAwBC;IAED;;;OAGG;IACH,kFAsBC;IAwBD;;;OAGG;IACH,cAHW,UAAU,GACR,OAAO,CAenB;IAgBL;;;;OAIG;IACH,uBAFU,OAAO,CAEgB;CAPhC;gCA1S+B,sBAAsB"}
@@ -0,0 +1,318 @@
1
+ import { assert } from "../../../assert.js";
2
+ import { computeHashFloat } from "../../../primitives/numbers/computeHashFloat.js";
3
+ import { v3_length } from "../../vec3/v3_length.js";
4
+ import { computeTriangleClosestPointToPointBarycentric } from "../triangle/computeTriangleClosestPointToPointBarycentric.js";
5
+ import { AbstractShape3D } from "./AbstractShape3D.js";
6
+
7
+ /**
8
+ * Buffer-backed flyweight triangle shape.
9
+ *
10
+ * Vertex data is NOT stored on the instance — instead the triangle binds
11
+ * to a region of an external Float64 buffer via {@link bind}, reading
12
+ * 9 consecutive floats (vA.xyz, vB.xyz, vC.xyz) at the bound offset.
13
+ *
14
+ * Pattern: the narrowphase keeps one persistent `Triangle3D` per side of
15
+ * a contact pair and rebinds its offset while iterating decomposed
16
+ * triangles from a non-convex shape's enumerator. Zero allocations per
17
+ * iteration step — the cost of "another triangle" is a single integer
18
+ * offset change.
19
+ *
20
+ * The shape is convex (a triangle is the canonical 2-simplex in 3D, and
21
+ * GJK handles 2-simplices natively). It's degenerate in the sense that
22
+ * `volume = 0` and `contains_point` is always false — a triangle is a
23
+ * 2D surface in 3D space, no interior.
24
+ *
25
+ * @author Alex Goldring
26
+ * @copyright Company Named Limited (c) 2026
27
+ */
28
+ export class Triangle3D extends AbstractShape3D {
29
+ constructor() {
30
+ super();
31
+
32
+ /**
33
+ * External buffer holding vertex data.
34
+ * @type {Float64Array | null}
35
+ */
36
+ this.buffer = null;
37
+
38
+ /**
39
+ * Float-index of vA.x in {@link buffer}. The other 8 floats
40
+ * (vA.yz, vB.xyz, vC.xyz) follow consecutively.
41
+ * @type {number}
42
+ */
43
+ this.offset = 0;
44
+ }
45
+
46
+ /**
47
+ * Bind this triangle to a region of an external buffer. Reads 9
48
+ * consecutive floats starting at `offset`.
49
+ *
50
+ * @param {Float64Array} buffer
51
+ * @param {number} offset float-index of vA.x in the buffer
52
+ * @returns {Triangle3D} this (for chaining)
53
+ */
54
+ bind(buffer, offset) {
55
+ assert.isNonNegativeInteger(offset, "offset");
56
+
57
+ this.buffer = buffer;
58
+ this.offset = offset;
59
+
60
+ return this;
61
+ }
62
+
63
+ /**
64
+ * Convenience constructor for tests and one-off triangles.
65
+ * Allocates a private 9-float buffer; for hot paths use {@link bind}
66
+ * against a shared buffer instead.
67
+ *
68
+ * @param {number} ax
69
+ * @param {number} ay
70
+ * @param {number} az
71
+ * @param {number} bx
72
+ * @param {number} by
73
+ * @param {number} bz
74
+ * @param {number} cx
75
+ * @param {number} cy
76
+ * @param {number} cz
77
+ * @returns {Triangle3D}
78
+ */
79
+ static from(ax, ay, az, bx, by, bz, cx, cy, cz) {
80
+ const buf = new Float64Array(9);
81
+ buf[0] = ax; buf[1] = ay; buf[2] = az;
82
+ buf[3] = bx; buf[4] = by; buf[5] = bz;
83
+ buf[6] = cx; buf[7] = cy; buf[8] = cz;
84
+
85
+ const t = new Triangle3D();
86
+ t.bind(buf, 0);
87
+ return t;
88
+ }
89
+
90
+ support(result, result_offset, direction_x, direction_y, direction_z) {
91
+ const b = this.buffer;
92
+ const o = this.offset;
93
+
94
+ const ax = b[o ]; const ay = b[o + 1]; const az = b[o + 2];
95
+ const bx = b[o + 3]; const by = b[o + 4]; const bz = b[o + 5];
96
+ const cx = b[o + 6]; const cy = b[o + 7]; const cz = b[o + 8];
97
+
98
+ const da = ax * direction_x + ay * direction_y + az * direction_z;
99
+ const db = bx * direction_x + by * direction_y + bz * direction_z;
100
+ const dc = cx * direction_x + cy * direction_y + cz * direction_z;
101
+
102
+ if (da >= db && da >= dc) {
103
+ result[result_offset ] = ax;
104
+ result[result_offset + 1] = ay;
105
+ result[result_offset + 2] = az;
106
+ } else if (db >= dc) {
107
+ result[result_offset ] = bx;
108
+ result[result_offset + 1] = by;
109
+ result[result_offset + 2] = bz;
110
+ } else {
111
+ result[result_offset ] = cx;
112
+ result[result_offset + 1] = cy;
113
+ result[result_offset + 2] = cz;
114
+ }
115
+ }
116
+
117
+ compute_bounding_box(result) {
118
+ const b = this.buffer;
119
+ const o = this.offset;
120
+
121
+ const ax = b[o ]; const ay = b[o + 1]; const az = b[o + 2];
122
+ const bx = b[o + 3]; const by = b[o + 4]; const bz = b[o + 5];
123
+ const cx = b[o + 6]; const cy = b[o + 7]; const cz = b[o + 8];
124
+
125
+ result[0] = ax < bx ? (ax < cx ? ax : cx) : (bx < cx ? bx : cx);
126
+ result[1] = ay < by ? (ay < cy ? ay : cy) : (by < cy ? by : cy);
127
+ result[2] = az < bz ? (az < cz ? az : cz) : (bz < cz ? bz : cz);
128
+
129
+ result[3] = ax > bx ? (ax > cx ? ax : cx) : (bx > cx ? bx : cx);
130
+ result[4] = ay > by ? (ay > cy ? ay : cy) : (by > cy ? by : cy);
131
+ result[5] = az > bz ? (az > cz ? az : cz) : (bz > cz ? bz : cz);
132
+ }
133
+
134
+ /**
135
+ * A triangle has zero interior volume.
136
+ */
137
+ contains_point(_point) {
138
+ return false;
139
+ }
140
+
141
+ /**
142
+ * Signed distance has a well-defined sign relative to the triangle's
143
+ * face plane: positive on the side that the face normal points to
144
+ * (normal = (B-A) × (C-A), CCW convention), negative on the other.
145
+ *
146
+ * Magnitude is the true point-to-triangle distance (handles vertex,
147
+ * edge, and face Voronoi regions correctly via
148
+ * {@link computeTriangleClosestPointToPointBarycentric}).
149
+ */
150
+ signed_distance_at_point(point) {
151
+ const b = this.buffer;
152
+ const o = this.offset;
153
+
154
+ const ax = b[o ]; const ay = b[o + 1]; const az = b[o + 2];
155
+ const bx = b[o + 3]; const by = b[o + 4]; const bz = b[o + 5];
156
+ const cx = b[o + 6]; const cy = b[o + 7]; const cz = b[o + 8];
157
+
158
+ const px = point[0]; const py = point[1]; const pz = point[2];
159
+
160
+ computeTriangleClosestPointToPointBarycentric(
161
+ scratch_bary, 0,
162
+ px, py, pz,
163
+ ax, ay, az,
164
+ bx, by, bz,
165
+ cx, cy, cz
166
+ );
167
+
168
+ // result format: [alpha_A, alpha_B]; alpha_C = 1 - alpha_A - alpha_B
169
+ const alpha_a = scratch_bary[0];
170
+ const alpha_b = scratch_bary[1];
171
+ const alpha_c = 1 - alpha_a - alpha_b;
172
+
173
+ const closest_x = alpha_a * ax + alpha_b * bx + alpha_c * cx;
174
+ const closest_y = alpha_a * ay + alpha_b * by + alpha_c * cy;
175
+ const closest_z = alpha_a * az + alpha_b * bz + alpha_c * cz;
176
+
177
+ const dx = px - closest_x;
178
+ const dy = py - closest_y;
179
+ const dz = pz - closest_z;
180
+
181
+ const distance = v3_length(dx, dy, dz);
182
+
183
+ // face normal = (B - A) × (C - A) — CCW convention
184
+ const e1x = bx - ax; const e1y = by - ay; const e1z = bz - az;
185
+ const e2x = cx - ax; const e2y = cy - ay; const e2z = cz - az;
186
+
187
+ const nx = e1y * e2z - e1z * e2y;
188
+ const ny = e1z * e2x - e1x * e2z;
189
+ const nz = e1x * e2y - e1y * e2x;
190
+
191
+ const side = (px - ax) * nx + (py - ay) * ny + (pz - az) * nz;
192
+
193
+ return side >= 0 ? distance : -distance;
194
+ }
195
+
196
+ nearest_point_on_surface(result, reference) {
197
+ const b = this.buffer;
198
+ const o = this.offset;
199
+
200
+ const ax = b[o ]; const ay = b[o + 1]; const az = b[o + 2];
201
+ const bx = b[o + 3]; const by = b[o + 4]; const bz = b[o + 5];
202
+ const cx = b[o + 6]; const cy = b[o + 7]; const cz = b[o + 8];
203
+
204
+ computeTriangleClosestPointToPointBarycentric(
205
+ scratch_bary, 0,
206
+ reference[0], reference[1], reference[2],
207
+ ax, ay, az,
208
+ bx, by, bz,
209
+ cx, cy, cz
210
+ );
211
+
212
+ // result format: [alpha_A, alpha_B]; alpha_C = 1 - alpha_A - alpha_B
213
+ const alpha_a = scratch_bary[0];
214
+ const alpha_b = scratch_bary[1];
215
+ const alpha_c = 1 - alpha_a - alpha_b;
216
+
217
+ result[0] = alpha_a * ax + alpha_b * bx + alpha_c * cx;
218
+ result[1] = alpha_a * ay + alpha_b * by + alpha_c * cy;
219
+ result[2] = alpha_a * az + alpha_b * bz + alpha_c * cz;
220
+ }
221
+
222
+ /**
223
+ * Uniform random barycentric sample within the triangle.
224
+ * Triangles have no interior, so the sample lies on the surface.
225
+ */
226
+ sample_random_point_in_volume(result, result_offset, random) {
227
+ let r1 = random();
228
+ let r2 = random();
229
+
230
+ // unit-square reflection trick for uniform-barycentric sampling
231
+ if (r1 + r2 > 1) {
232
+ r1 = 1 - r1;
233
+ r2 = 1 - r2;
234
+ }
235
+
236
+ const r0 = 1 - r1 - r2;
237
+
238
+ const b = this.buffer;
239
+ const o = this.offset;
240
+
241
+ const ax = b[o ]; const ay = b[o + 1]; const az = b[o + 2];
242
+ const bx = b[o + 3]; const by = b[o + 4]; const bz = b[o + 5];
243
+ const cx = b[o + 6]; const cy = b[o + 7]; const cz = b[o + 8];
244
+
245
+ result[result_offset ] = r0 * ax + r1 * bx + r2 * cx;
246
+ result[result_offset + 1] = r0 * ay + r1 * by + r2 * cy;
247
+ result[result_offset + 2] = r0 * az + r1 * bz + r2 * cz;
248
+ }
249
+
250
+ get volume() {
251
+ return 0;
252
+ }
253
+
254
+ get surface_area() {
255
+ const b = this.buffer;
256
+ const o = this.offset;
257
+
258
+ const ax = b[o ]; const ay = b[o + 1]; const az = b[o + 2];
259
+ const bx = b[o + 3]; const by = b[o + 4]; const bz = b[o + 5];
260
+ const cx = b[o + 6]; const cy = b[o + 7]; const cz = b[o + 8];
261
+
262
+ const e1x = bx - ax; const e1y = by - ay; const e1z = bz - az;
263
+ const e2x = cx - ax; const e2y = cy - ay; const e2z = cz - az;
264
+
265
+ const nx = e1y * e2z - e1z * e2y;
266
+ const ny = e1z * e2x - e1x * e2z;
267
+ const nz = e1x * e2y - e1y * e2x;
268
+
269
+ return 0.5 * v3_length(nx, ny, nz);
270
+ }
271
+
272
+ /**
273
+ * @param {Triangle3D} other
274
+ * @returns {boolean}
275
+ */
276
+ equals(other) {
277
+ if (!super.equals(other)) return false;
278
+
279
+ const a = this.buffer;
280
+ const ao = this.offset;
281
+ const b = other.buffer;
282
+ const bo = other.offset;
283
+
284
+ for (let i = 0; i < 9; i++) {
285
+ if (a[ao + i] !== b[bo + i]) return false;
286
+ }
287
+
288
+ return true;
289
+ }
290
+
291
+ hash() {
292
+ const b = this.buffer;
293
+ const o = this.offset;
294
+
295
+ let h = 0;
296
+
297
+ for (let i = 0; i < 9; i++) {
298
+ h = ((h << 5) - h + computeHashFloat(b[o + i])) | 0;
299
+ }
300
+
301
+ return h;
302
+ }
303
+ }
304
+
305
+ /**
306
+ * Fast type-check marker.
307
+ * @readonly
308
+ * @type {boolean}
309
+ */
310
+ Triangle3D.prototype.isTriangle3D = true;
311
+
312
+ /**
313
+ * Scratch for barycentric output from {@link computeTriangleClosestPointToPointBarycentric}.
314
+ * Module-scoped because every triangle method that needs barycentric
315
+ * coords does it strictly inline — no nested calls that could re-enter.
316
+ * @type {Float64Array}
317
+ */
318
+ const scratch_bary = new Float64Array(2);
@@ -352,3 +352,16 @@ export class UnionShape3D extends AbstractShape3D {
352
352
  return hash;
353
353
  }
354
354
  }
355
+
356
+ /**
357
+ * The set-union of convex shapes is convex only in the trivial cases (one
358
+ * child, or fully overlapping children). The general case is non-convex,
359
+ * so the narrowphase must decompose the union into its children and run
360
+ * per-child GJK against the other body, then merge the resulting contact
361
+ * manifolds. Treating the union as a single convex blob via GJK on a
362
+ * combined support would conflate distinct children into a fake hull.
363
+ *
364
+ * @readonly
365
+ * @type {boolean}
366
+ */
367
+ UnionShape3D.prototype.is_convex = false;
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Build a {@link MeshShape3D} from a Three-style indexed triangle buffer.
3
+ *
4
+ * Pipeline:
5
+ * 1. {@link bt_mesh_from_indexed_geometry} reconstructs a
6
+ * {@link BinaryTopology} (vertex / edge / loop / face cycles).
7
+ * 2. {@link compute_tetrahedral_mesh_from_surface} tetrahedralises the
8
+ * volume enclosed by the surface, carving away exterior tets.
9
+ * 3. The tet mesh is **compacted** — the carving pass leaves the free
10
+ * list populated with low-index slots, and downstream consumers
11
+ * (`tetrahedral_mesh_to_bvh` iterates by index, the shape's
12
+ * `recompute_cached` does the same) expect a hole-free range.
13
+ * Compaction relocates live tets so indices `[0, count)` are dense.
14
+ * 4. The flat positions + indices are kept verbatim on the shape for
15
+ * fast support-function and triangle-distance queries.
16
+ * 5. A {@link BVH} is built over the tet AABBs, used by
17
+ * {@link MeshShape3D#contains_point} for O(log N) point-in-mesh
18
+ * queries that correctly handle disconnected meshes (which the
19
+ * previous tet-walker did not).
20
+ *
21
+ * The caller's buffers are NOT cloned — they're attached to the shape
22
+ * directly. Don't mutate them after handing them in.
23
+ *
24
+ * @param {Float32Array} positions flat `(x, y, z)` per vertex
25
+ * @param {Uint32Array} indices three uint32 per triangle (CCW winding)
26
+ * @returns {MeshShape3D}
27
+ */
28
+ export function shape_mesh_from_geometry(positions: Float32Array, indices: Uint32Array): MeshShape3D;
29
+ import { MeshShape3D } from "./MeshShape3D.js";
30
+ //# sourceMappingURL=shape_mesh_from_geometry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shape_mesh_from_geometry.d.ts","sourceRoot":"","sources":["../../../../../../src/core/geom/3d/shape/shape_mesh_from_geometry.js"],"names":[],"mappings":"AAMA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,oDAJW,YAAY,WACZ,WAAW,GACT,WAAW,CAgCvB;4BA3D2B,kBAAkB"}
@@ -0,0 +1,64 @@
1
+ import { tetrahedral_mesh_to_bvh } from "../tetrahedra/bvh/tetrahedral_mesh_to_bvh.js";
2
+ import { compute_tetrahedral_mesh_from_surface } from "../tetrahedra/compute_tetrahedral_mesh_from_surface.js";
3
+ import { BinaryTopology } from "../topology/struct/binary/BinaryTopology.js";
4
+ import { bt_mesh_from_indexed_geometry } from "../topology/struct/binary/io/bt_mesh_from_indexed_geometry.js";
5
+ import { MeshShape3D } from "./MeshShape3D.js";
6
+
7
+ /**
8
+ * Build a {@link MeshShape3D} from a Three-style indexed triangle buffer.
9
+ *
10
+ * Pipeline:
11
+ * 1. {@link bt_mesh_from_indexed_geometry} reconstructs a
12
+ * {@link BinaryTopology} (vertex / edge / loop / face cycles).
13
+ * 2. {@link compute_tetrahedral_mesh_from_surface} tetrahedralises the
14
+ * volume enclosed by the surface, carving away exterior tets.
15
+ * 3. The tet mesh is **compacted** — the carving pass leaves the free
16
+ * list populated with low-index slots, and downstream consumers
17
+ * (`tetrahedral_mesh_to_bvh` iterates by index, the shape's
18
+ * `recompute_cached` does the same) expect a hole-free range.
19
+ * Compaction relocates live tets so indices `[0, count)` are dense.
20
+ * 4. The flat positions + indices are kept verbatim on the shape for
21
+ * fast support-function and triangle-distance queries.
22
+ * 5. A {@link BVH} is built over the tet AABBs, used by
23
+ * {@link MeshShape3D#contains_point} for O(log N) point-in-mesh
24
+ * queries that correctly handle disconnected meshes (which the
25
+ * previous tet-walker did not).
26
+ *
27
+ * The caller's buffers are NOT cloned — they're attached to the shape
28
+ * directly. Don't mutate them after handing them in.
29
+ *
30
+ * @param {Float32Array} positions flat `(x, y, z)` per vertex
31
+ * @param {Uint32Array} indices three uint32 per triangle (CCW winding)
32
+ * @returns {MeshShape3D}
33
+ */
34
+ export function shape_mesh_from_geometry(positions, indices) {
35
+ const shape = new MeshShape3D();
36
+ shape.positions = positions;
37
+ shape.indices = indices;
38
+
39
+ // 1. BinaryTopology from the indexed buffer.
40
+ const topology = new BinaryTopology();
41
+ bt_mesh_from_indexed_geometry(topology, indices, positions);
42
+
43
+ // 2. Tetrahedralise. interior_steiner_cells_per_dim = 0 — for
44
+ // collision queries the inside/outside oracle only needs
45
+ // surface-vertex tets; interior Steiner points add cost without
46
+ // changing the contains_point result.
47
+ shape.tet_positions = compute_tetrahedral_mesh_from_surface(shape.tet_mesh, topology, 0);
48
+
49
+ // 3. Compact. The carve pass freed slots in the tet mesh's
50
+ // allocator; compaction repacks live tets into a dense
51
+ // [0, count) range. Without this, `tetrahedral_mesh_to_bvh`
52
+ // iterates "tet index 0..count" and treats freed indices as if
53
+ // they were live tets — produces phantom BVH leaves with stale
54
+ // vertex data.
55
+ shape.tet_mesh.compact();
56
+
57
+ // 4. BVH over tet AABBs for the point-in-mesh query path.
58
+ tetrahedral_mesh_to_bvh(shape.tet_bvh, shape.tet_mesh, shape.tet_positions);
59
+
60
+ // 5. Refresh cached bbox / volume / surface area.
61
+ shape.recompute_cached();
62
+
63
+ return shape;
64
+ }
@@ -50,18 +50,16 @@ import { TetrahedralMesh } from "./TetrahedralMesh.js";
50
50
  // radius-ratio metric.
51
51
  const SLIVER_QUALITY_THRESHOLD = 0.05;
52
52
 
53
- // Sliver-removal driver config. Currently OFF by default because the
54
- // driver isn't optimised for interactive use yet: on a 6,500-tet Suzanne
55
- // (and similar) it takes ~50 seconds per pass, which would freeze the UI
56
- // on every drop. The main hotspot is `tetrahedral_mesh_vertex_is_boundary`
57
- // inside the smoothing pass it scans every tet in the mesh per vertex.
58
- // Builds a vertex→tet adjacency cache once per pass to replace it.
53
+ // Sliver-removal driver config. The driver now builds a vertex→tet
54
+ // adjacency cache once per pass and shares it with the boundary check,
55
+ // the local quality eval, and the smoothing primitive bringing per-pass
56
+ // cost from O(N²) down to O(N·deg). On a 3,242-tet densified cube the
57
+ // driver dropped from ~23 s to ~3 s; on closed-surface meshes (Suzanne,
58
+ // Teapot) where every vertex is boundary, smoothing is a near no-op and
59
+ // the pass should finish in well under a second.
59
60
  //
60
- // When enabled, the driver halves the sliver count on Suzanne and
61
- // commits ~200 3-2 flips; smoothing is a no-op on closed-surface meshes
62
- // because every vertex is on the boundary. Toggle this to true if you
63
- // want the BEFORE → AFTER numbers logged in the per-mesh console line.
64
- const ENABLE_IMPROVE_QUALITY = false;
61
+ // BEFORE AFTER numbers are logged in the per-mesh console line.
62
+ const ENABLE_IMPROVE_QUALITY = true;
65
63
  const IMPROVE_TARGET_QUALITY = 0.05; // sliver cutoff only — keep the workload small
66
64
  const IMPROVE_MAX_PASSES = 1;
67
65
 
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Build a `Map<vertex_id, tet_id[]>` enumerating every live tet that
3
+ * contains each vertex. One full pass over the mesh; the result lets
4
+ * subsequent per-vertex queries run in O(deg) instead of O(N).
5
+ *
6
+ * Useful when the caller is about to perform many per-vertex queries —
7
+ * e.g. boundary-status checks or 1-ring quality evaluations across a whole
8
+ * mesh during a quality-improvement pass. Without the cache, each query
9
+ * has to scan every live tet (see
10
+ * {@link tetrahedral_mesh_find_tets_attached_to_vertex} and
11
+ * {@link tetrahedral_mesh_vertex_is_boundary}), which compounds to O(N²)
12
+ * over a full pass.
13
+ *
14
+ * The map is a SNAPSHOT: it reflects mesh state at build time. Any flips,
15
+ * deletions or appends that happen afterwards will leave it stale. Callers
16
+ * must either rebuild after each mutation or accept the staleness (for
17
+ * boundary checks the cache is flip-invariant, so a once-per-pass rebuild
18
+ * is safe; for queries that need the exact current 1-ring, the caller
19
+ * should filter through `mesh.exists` and rebuild after mutations they
20
+ * care about).
21
+ *
22
+ * Cost: O(N) where N is `mesh.count`.
23
+ *
24
+ * @param {TetrahedralMesh} mesh
25
+ * @returns {Map<number, number[]>}
26
+ */
27
+ export function tetrahedral_mesh_build_vertex_to_tets_map(mesh: TetrahedralMesh): Map<number, number[]>;
28
+ //# sourceMappingURL=tetrahedral_mesh_build_vertex_to_tets_map.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tetrahedral_mesh_build_vertex_to_tets_map.d.ts","sourceRoot":"","sources":["../../../../../../src/core/geom/3d/tetrahedra/tetrahedral_mesh_build_vertex_to_tets_map.js"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,kFAFa,IAAI,MAAM,EAAE,MAAM,EAAE,CAAC,CAqBjC"}
@@ -0,0 +1,48 @@
1
+ import { assert } from "../../../assert.js";
2
+
3
+ /**
4
+ * Build a `Map<vertex_id, tet_id[]>` enumerating every live tet that
5
+ * contains each vertex. One full pass over the mesh; the result lets
6
+ * subsequent per-vertex queries run in O(deg) instead of O(N).
7
+ *
8
+ * Useful when the caller is about to perform many per-vertex queries —
9
+ * e.g. boundary-status checks or 1-ring quality evaluations across a whole
10
+ * mesh during a quality-improvement pass. Without the cache, each query
11
+ * has to scan every live tet (see
12
+ * {@link tetrahedral_mesh_find_tets_attached_to_vertex} and
13
+ * {@link tetrahedral_mesh_vertex_is_boundary}), which compounds to O(N²)
14
+ * over a full pass.
15
+ *
16
+ * The map is a SNAPSHOT: it reflects mesh state at build time. Any flips,
17
+ * deletions or appends that happen afterwards will leave it stale. Callers
18
+ * must either rebuild after each mutation or accept the staleness (for
19
+ * boundary checks the cache is flip-invariant, so a once-per-pass rebuild
20
+ * is safe; for queries that need the exact current 1-ring, the caller
21
+ * should filter through `mesh.exists` and rebuild after mutations they
22
+ * care about).
23
+ *
24
+ * Cost: O(N) where N is `mesh.count`.
25
+ *
26
+ * @param {TetrahedralMesh} mesh
27
+ * @returns {Map<number, number[]>}
28
+ */
29
+ export function tetrahedral_mesh_build_vertex_to_tets_map(mesh) {
30
+ assert.defined(mesh, 'mesh');
31
+
32
+ /** @type {Map<number, number[]>} */
33
+ const map = new Map();
34
+
35
+ mesh.forEach((tet, m) => {
36
+ for (let i = 0; i < 4; i++) {
37
+ const v = m.getVertexIndex(tet, i);
38
+ let bucket = map.get(v);
39
+ if (bucket === undefined) {
40
+ bucket = [];
41
+ map.set(v, bucket);
42
+ }
43
+ bucket.push(tet);
44
+ }
45
+ });
46
+
47
+ return map;
48
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"tetrahedral_mesh_improve_quality.d.ts","sourceRoot":"","sources":["../../../../../../src/core/geom/3d/tetrahedra/tetrahedral_mesh_improve_quality.js"],"names":[],"mappings":"AA6CA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiDG;AACH,gFApBW,YAAY,GAAC,MAAM,EAAE;qBAEV,MAAM;iBACV,MAAM;uBACA,MAAM;mBACV,OAAO;uBACH,OAAO;IAElB;IACZ,UAAc,EAAE,MAAM,CAAC;IACvB,oBAAwB,EAAE,MAAM,CAAC;IACjC,mBAAuB,EAAE,MAAM,CAAC;IAChC,kBAAsB,EAAE,MAAM,CAAC;IAC/B,iBAAqB,EAAE,MAAM,CAAC;IAC9B,kBAAsB,EAAE,MAAM,CAAC;IAC/B,iBAAqB,EAAE,MAAM,CAAC;IAC9B,mBAAuB,EAAE,MAAM,CAAC;IAChC,iBAAqB,EAAE,MAAM,CAAC;CAC3B,CAuOH"}
1
+ {"version":3,"file":"tetrahedral_mesh_improve_quality.d.ts","sourceRoot":"","sources":["../../../../../../src/core/geom/3d/tetrahedra/tetrahedral_mesh_improve_quality.js"],"names":[],"mappings":"AA2CA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiDG;AACH,gFApBW,YAAY,GAAC,MAAM,EAAE;qBAEV,MAAM;iBACV,MAAM;uBACA,MAAM;mBACV,OAAO;uBACH,OAAO;IAElB;IACZ,UAAc,EAAE,MAAM,CAAC;IACvB,oBAAwB,EAAE,MAAM,CAAC;IACjC,mBAAuB,EAAE,MAAM,CAAC;IAChC,kBAAsB,EAAE,MAAM,CAAC;IAC/B,iBAAqB,EAAE,MAAM,CAAC;IAC9B,kBAAsB,EAAE,MAAM,CAAC;IAC/B,iBAAqB,EAAE,MAAM,CAAC;IAC9B,mBAAuB,EAAE,MAAM,CAAC;IAChC,iBAAqB,EAAE,MAAM,CAAC;CAC3B,CA8OH"}