@woosh/meep-engine 2.131.47 → 2.132.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 (235) hide show
  1. package/README.md +1 -1
  2. package/package.json +1 -1
  3. package/src/core/bvh2/bvh3/ebvh_optimize_treelet.d.ts.map +1 -1
  4. package/src/core/bvh2/bvh3/ebvh_optimize_treelet.js +4 -3
  5. package/src/core/codegen/LineBuilder.js +3 -3
  6. package/src/core/collection/heap/Uint32Heap.d.ts +14 -0
  7. package/src/core/collection/heap/Uint32Heap.d.ts.map +1 -1
  8. package/src/core/collection/heap/Uint32Heap.js +18 -0
  9. package/src/core/collection/map/HashMap.d.ts.map +1 -1
  10. package/src/core/collection/map/HashMap.js +4 -22
  11. package/src/core/collection/map/generate_next_linear_congruential_index.d.ts +15 -0
  12. package/src/core/collection/map/generate_next_linear_congruential_index.d.ts.map +1 -0
  13. package/src/core/collection/map/generate_next_linear_congruential_index.js +18 -0
  14. package/src/core/geom/3d/line/line3_compute_nearest_point_to_point.d.ts.map +1 -1
  15. package/src/core/geom/3d/line/line3_compute_nearest_point_to_point.js +10 -26
  16. package/src/core/geom/3d/line/line3_compute_segment_nearest_point_to_point_t.d.ts +19 -0
  17. package/src/core/geom/3d/line/line3_compute_segment_nearest_point_to_point_t.d.ts.map +1 -0
  18. package/src/core/geom/3d/line/line3_compute_segment_nearest_point_to_point_t.js +48 -0
  19. package/src/core/geom/3d/line/line3_compute_segment_point_distance.d.ts +15 -0
  20. package/src/core/geom/3d/line/line3_compute_segment_point_distance.d.ts.map +1 -0
  21. package/src/core/geom/3d/line/line3_compute_segment_point_distance.js +24 -0
  22. package/src/core/geom/3d/line/line3_compute_segment_point_distance_eikonal.d.ts +17 -0
  23. package/src/core/geom/3d/line/line3_compute_segment_point_distance_eikonal.d.ts.map +1 -0
  24. package/src/core/geom/3d/line/line3_compute_segment_point_distance_eikonal.js +95 -0
  25. package/src/core/geom/3d/line/line3_compute_segment_point_distance_sqr.d.ts +16 -0
  26. package/src/core/geom/3d/line/line3_compute_segment_point_distance_sqr.d.ts.map +1 -0
  27. package/src/core/geom/3d/line/{line3_computeSegmentPointDistance_sqr.js → line3_compute_segment_point_distance_sqr.js} +16 -3
  28. package/src/core/geom/3d/plane/plane3_matrix4_project.d.ts.map +1 -1
  29. package/src/core/geom/3d/plane/plane3_matrix4_project.js +0 -1
  30. package/src/core/geom/3d/topology/struct/TopoMesh.d.ts +4 -0
  31. package/src/core/geom/3d/topology/struct/TopoMesh.d.ts.map +1 -1
  32. package/src/core/geom/3d/topology/struct/TopoMesh.js +4 -0
  33. package/src/core/geom/3d/topology/struct/binary/BinaryElementPool.d.ts +18 -1
  34. package/src/core/geom/3d/topology/struct/binary/BinaryElementPool.d.ts.map +1 -1
  35. package/src/core/geom/3d/topology/struct/binary/BinaryElementPool.js +56 -0
  36. package/src/core/geom/3d/topology/struct/binary/BinaryTopology.d.ts +46 -16
  37. package/src/core/geom/3d/topology/struct/binary/BinaryTopology.d.ts.map +1 -1
  38. package/src/core/geom/3d/topology/struct/binary/BinaryTopology.js +85 -15
  39. package/src/core/geom/3d/topology/struct/binary/io/bt_disk_edge_add.d.ts +9 -0
  40. package/src/core/geom/3d/topology/struct/binary/io/bt_disk_edge_add.d.ts.map +1 -0
  41. package/src/core/geom/3d/topology/struct/binary/io/bt_disk_edge_add.js +43 -0
  42. package/src/core/geom/3d/topology/struct/binary/io/bt_disk_edge_remove.d.ts +4 -3
  43. package/src/core/geom/3d/topology/struct/binary/io/bt_disk_edge_remove.d.ts.map +1 -1
  44. package/src/core/geom/3d/topology/struct/binary/io/bt_disk_edge_remove.js +38 -4
  45. package/src/core/geom/3d/topology/struct/binary/io/bt_loop_kill.d.ts +8 -0
  46. package/src/core/geom/3d/topology/struct/binary/io/bt_loop_kill.d.ts.map +1 -0
  47. package/src/core/geom/3d/topology/struct/binary/io/bt_loop_kill.js +36 -0
  48. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_cleanup_faceless_references.d.ts +10 -0
  49. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_cleanup_faceless_references.d.ts.map +1 -0
  50. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_cleanup_faceless_references.js +62 -0
  51. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_face_decouple.d.ts +13 -0
  52. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_face_decouple.d.ts.map +1 -0
  53. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_face_decouple.js +145 -0
  54. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_face_decouple_islands.d.ts +12 -0
  55. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_face_decouple_islands.d.ts.map +1 -0
  56. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_face_decouple_islands.js +111 -0
  57. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_face_island_erode.d.ts +15 -0
  58. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_face_island_erode.d.ts.map +1 -0
  59. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_face_island_erode.js +290 -0
  60. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_from_indexed_geometry.d.ts +11 -0
  61. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_from_indexed_geometry.d.ts.map +1 -0
  62. package/src/core/geom/3d/topology/struct/binary/io/{bt_index_geometry_to_topology.js → bt_mesh_from_indexed_geometry.js} +6 -7
  63. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_from_unindexed_geometry.d.ts +8 -0
  64. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_from_unindexed_geometry.d.ts.map +1 -0
  65. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_from_unindexed_geometry.js +31 -0
  66. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_triangulate.d.ts +7 -0
  67. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_triangulate.d.ts.map +1 -0
  68. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_triangulate.js +22 -0
  69. package/src/core/geom/3d/topology/struct/binary/io/bt_radial_loop_add.d.ts +8 -0
  70. package/src/core/geom/3d/topology/struct/binary/io/bt_radial_loop_add.d.ts.map +1 -0
  71. package/src/core/geom/3d/topology/struct/binary/io/bt_radial_loop_add.js +32 -0
  72. package/src/core/geom/3d/topology/struct/binary/io/bt_radial_loop_remove.d.ts +8 -0
  73. package/src/core/geom/3d/topology/struct/binary/io/bt_radial_loop_remove.d.ts.map +1 -0
  74. package/src/core/geom/3d/topology/struct/binary/io/bt_radial_loop_remove.js +26 -0
  75. package/src/core/geom/3d/topology/struct/binary/io/edge/OrderedEdge.d.ts.map +1 -0
  76. package/src/core/geom/3d/topology/struct/binary/io/{OrderedEdge.js → edge/OrderedEdge.js} +1 -1
  77. package/src/core/geom/3d/topology/struct/binary/io/edge/bt_edge_create.d.ts.map +1 -0
  78. package/src/core/geom/3d/topology/struct/binary/io/{bt_edge_create.js → edge/bt_edge_create.js} +1 -1
  79. package/src/core/geom/3d/topology/struct/binary/io/edge/bt_edge_get_or_create.d.ts.map +1 -0
  80. package/src/core/geom/3d/topology/struct/binary/io/{bt_edge_get_or_create.js → edge/bt_edge_get_or_create.js} +1 -1
  81. package/src/core/geom/3d/topology/struct/binary/io/edge/bt_edge_kill.d.ts.map +1 -0
  82. package/src/core/geom/3d/topology/struct/binary/io/{bt_edge_kill.js → edge/bt_edge_kill.js} +6 -3
  83. package/src/core/geom/3d/topology/struct/binary/io/edge/bt_edge_split.d.ts +13 -0
  84. package/src/core/geom/3d/topology/struct/binary/io/edge/bt_edge_split.d.ts.map +1 -0
  85. package/src/core/geom/3d/topology/struct/binary/io/edge/bt_edge_split.js +180 -0
  86. package/src/core/geom/3d/topology/struct/binary/io/edge/bt_kill_only_edge.d.ts.map +1 -0
  87. package/src/core/geom/3d/topology/struct/binary/io/edge/bt_mesh_calc_edges.d.ts.map +1 -0
  88. package/src/core/geom/3d/topology/struct/binary/io/{bt_mesh_calc_edges.js → edge/bt_mesh_calc_edges.js} +10 -7
  89. package/src/core/geom/3d/topology/struct/binary/io/edge/get_or_create_edge_map.d.ts.map +1 -0
  90. package/src/core/geom/3d/topology/struct/binary/io/face/bt_face_kill.d.ts +8 -0
  91. package/src/core/geom/3d/topology/struct/binary/io/face/bt_face_kill.d.ts.map +1 -0
  92. package/src/core/geom/3d/topology/struct/binary/io/face/bt_face_kill.js +26 -0
  93. package/src/core/geom/3d/topology/struct/binary/io/face/bt_face_poke.d.ts +15 -0
  94. package/src/core/geom/3d/topology/struct/binary/io/face/bt_face_poke.d.ts.map +1 -0
  95. package/src/core/geom/3d/topology/struct/binary/io/face/bt_face_poke.js +152 -0
  96. package/src/core/geom/3d/topology/struct/binary/io/face/bt_face_triangulate.d.ts +13 -0
  97. package/src/core/geom/3d/topology/struct/binary/io/face/bt_face_triangulate.d.ts.map +1 -0
  98. package/src/core/geom/3d/topology/struct/binary/io/face/bt_face_triangulate.js +124 -0
  99. package/src/core/geom/3d/topology/struct/binary/io/face/bt_kill_only_face.d.ts.map +1 -0
  100. package/src/core/geom/3d/topology/struct/binary/io/vertex/bt_kill_only_vert.d.ts.map +1 -0
  101. package/src/core/geom/3d/topology/struct/binary/io/vertex/bt_merge_verts_by_distance.d.ts +10 -0
  102. package/src/core/geom/3d/topology/struct/binary/io/vertex/bt_merge_verts_by_distance.d.ts.map +1 -0
  103. package/src/core/geom/3d/topology/struct/binary/io/vertex/bt_merge_verts_by_distance.js +165 -0
  104. package/src/core/geom/3d/topology/struct/binary/io/vertex/bt_vert_kill.d.ts.map +1 -0
  105. package/src/core/geom/3d/topology/struct/binary/io/{bt_vert_kill.js → vertex/bt_vert_kill.js} +5 -2
  106. package/src/core/geom/3d/topology/struct/binary/io/vertex/bt_vertex_replace.d.ts +13 -0
  107. package/src/core/geom/3d/topology/struct/binary/io/vertex/bt_vertex_replace.d.ts.map +1 -0
  108. package/src/core/geom/3d/topology/struct/binary/io/vertex/bt_vertex_replace.js +125 -0
  109. package/src/core/geom/3d/topology/struct/binary/query/bt_edge_has_vertex.d.ts +9 -0
  110. package/src/core/geom/3d/topology/struct/binary/query/bt_edge_has_vertex.d.ts.map +1 -0
  111. package/src/core/geom/3d/topology/struct/binary/query/{bt_mesh_edge_has_vertex.js → bt_edge_has_vertex.js} +1 -1
  112. package/src/core/geom/3d/topology/struct/binary/query/{bt_mesh_edge_other_vertex.d.ts → bt_edge_other_vertex.d.ts} +2 -2
  113. package/src/core/geom/3d/topology/struct/binary/query/bt_edge_other_vertex.d.ts.map +1 -0
  114. package/src/core/geom/3d/topology/struct/binary/query/{bt_mesh_edge_other_vertex.js → bt_edge_other_vertex.js} +1 -1
  115. package/src/core/geom/3d/topology/struct/binary/query/bt_face_get_attached_faces.d.ts +12 -0
  116. package/src/core/geom/3d/topology/struct/binary/query/bt_face_get_attached_faces.d.ts.map +1 -0
  117. package/src/core/geom/3d/topology/struct/binary/query/bt_face_get_attached_faces.js +96 -0
  118. package/src/core/geom/3d/topology/struct/binary/query/bt_face_get_centroid.d.ts +10 -0
  119. package/src/core/geom/3d/topology/struct/binary/query/bt_face_get_centroid.d.ts.map +1 -0
  120. package/src/core/geom/3d/topology/struct/binary/query/bt_face_get_centroid.js +75 -0
  121. package/src/core/geom/3d/topology/struct/binary/query/bt_face_get_incenter.d.ts +10 -0
  122. package/src/core/geom/3d/topology/struct/binary/query/bt_face_get_incenter.d.ts.map +1 -0
  123. package/src/core/geom/3d/topology/struct/binary/query/bt_face_get_incenter.js +85 -0
  124. package/src/core/geom/3d/topology/struct/binary/query/bt_face_get_neighbour_faces.d.ts +12 -0
  125. package/src/core/geom/3d/topology/struct/binary/query/bt_face_get_neighbour_faces.d.ts.map +1 -0
  126. package/src/core/geom/3d/topology/struct/binary/query/bt_face_get_neighbour_faces.js +74 -0
  127. package/src/core/geom/3d/topology/struct/binary/query/bt_face_is_degenerate.d.ts +9 -0
  128. package/src/core/geom/3d/topology/struct/binary/query/bt_face_is_degenerate.d.ts.map +1 -0
  129. package/src/core/geom/3d/topology/struct/binary/query/bt_face_is_degenerate.js +78 -0
  130. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_build_boundary_distance_field.d.ts +15 -0
  131. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_build_boundary_distance_field.d.ts.map +1 -0
  132. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_build_boundary_distance_field.js +151 -0
  133. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_compute_edge_distance_eikonal.d.ts +13 -0
  134. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_compute_edge_distance_eikonal.d.ts.map +1 -0
  135. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_compute_edge_distance_eikonal.js +46 -0
  136. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_compute_face_islands.d.ts +9 -0
  137. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_compute_face_islands.d.ts.map +1 -0
  138. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_compute_face_islands.js +78 -0
  139. package/src/core/geom/3d/topology/struct/binary/query/bt_vertex_distance_to_edge.d.ts +10 -0
  140. package/src/core/geom/3d/topology/struct/binary/query/bt_vertex_distance_to_edge.d.ts.map +1 -0
  141. package/src/core/geom/3d/topology/struct/binary/query/bt_vertex_distance_to_edge.js +48 -0
  142. package/src/core/geom/3d/topology/struct/binary/query/bt_vertex_distance_to_vertex.d.ts +9 -0
  143. package/src/core/geom/3d/topology/struct/binary/query/bt_vertex_distance_to_vertex.d.ts.map +1 -0
  144. package/src/core/geom/3d/topology/struct/binary/query/bt_vertex_distance_to_vertex.js +31 -0
  145. package/src/core/geom/3d/topology/struct/prototypeBinaryTopology.js +2 -2
  146. package/src/core/geom/3d/triangle/triangle3_incenter.d.ts +19 -0
  147. package/src/core/geom/3d/triangle/triangle3_incenter.d.ts.map +1 -0
  148. package/src/core/geom/3d/triangle/triangle3_incenter.js +60 -0
  149. package/src/core/geom/3d/triangle/triangle_compute_plane_side.d.ts +24 -0
  150. package/src/core/geom/3d/triangle/triangle_compute_plane_side.d.ts.map +1 -0
  151. package/src/core/geom/3d/triangle/{computeTrianglePlaneSide.js → triangle_compute_plane_side.js} +9 -5
  152. package/src/core/geom/3d/triangle/triangle_intersects_clipping_volume.js +2 -2
  153. package/src/core/math/hash/lowbias32.d.ts +9 -0
  154. package/src/core/math/hash/lowbias32.d.ts.map +1 -0
  155. package/src/core/math/hash/lowbias32.js +20 -0
  156. package/src/core/process/task/util/iteratorTask.d.ts +2 -2
  157. package/src/core/process/task/util/iteratorTask.d.ts.map +1 -1
  158. package/src/core/process/task/util/iteratorTask.js +3 -3
  159. package/src/engine/graphics/particles/particular/engine/utils/distrubuteParticlesOnMesh.d.ts.map +1 -1
  160. package/src/engine/graphics/particles/particular/engine/utils/distrubuteParticlesOnMesh.js +4 -4
  161. package/src/engine/graphics/render/forward_plus/query/detailed_sphere_frustum_intersection_test.js +4 -4
  162. package/src/engine/navigation/ecs/components/Path.js +3 -3
  163. package/src/engine/navigation/grid/find_path_on_grid_astar.d.ts +4 -4
  164. package/src/engine/navigation/grid/find_path_on_grid_astar.d.ts.map +1 -1
  165. package/src/engine/navigation/grid/find_path_on_grid_astar.js +5 -4
  166. package/src/engine/navigation/mesh/NavigationMesh.d.ts +32 -0
  167. package/src/engine/navigation/mesh/NavigationMesh.d.ts.map +1 -0
  168. package/src/engine/navigation/mesh/NavigationMesh.js +190 -0
  169. package/src/engine/navigation/mesh/NavigationMeshAgent.d.ts +9 -0
  170. package/src/engine/navigation/mesh/NavigationMeshAgent.d.ts.map +1 -0
  171. package/src/engine/navigation/mesh/NavigationMeshAgent.js +11 -0
  172. package/src/engine/navigation/mesh/README.md +3 -0
  173. package/src/engine/navigation/mesh/bt_mesh_face_find_path.d.ts +14 -0
  174. package/src/engine/navigation/mesh/bt_mesh_face_find_path.d.ts.map +1 -0
  175. package/src/engine/navigation/mesh/bt_mesh_face_find_path.js +203 -0
  176. package/src/engine/navigation/mesh/build/bvh_build_from_unindexed_triangles.d.ts +8 -0
  177. package/src/engine/navigation/mesh/build/bvh_build_from_unindexed_triangles.d.ts.map +1 -0
  178. package/src/engine/navigation/mesh/build/bvh_build_from_unindexed_triangles.js +46 -0
  179. package/src/engine/navigation/mesh/build/enforce_agent_height_clearance.d.ts +12 -0
  180. package/src/engine/navigation/mesh/build/enforce_agent_height_clearance.d.ts.map +1 -0
  181. package/src/engine/navigation/mesh/build/enforce_agent_height_clearance.js +204 -0
  182. package/src/engine/navigation/mesh/build/navmesh_build_topology.d.ts +14 -0
  183. package/src/engine/navigation/mesh/build/navmesh_build_topology.d.ts.map +1 -0
  184. package/src/engine/navigation/mesh/build/navmesh_build_topology.js +183 -0
  185. package/src/engine/navigation/mesh/bvh_build_from_bt_mesh.d.ts +7 -0
  186. package/src/engine/navigation/mesh/bvh_build_from_bt_mesh.d.ts.map +1 -0
  187. package/src/engine/navigation/mesh/bvh_build_from_bt_mesh.js +64 -0
  188. package/src/engine/navigation/mesh/funnel_string_pull.d.ts +15 -0
  189. package/src/engine/navigation/mesh/funnel_string_pull.d.ts.map +1 -0
  190. package/src/engine/navigation/mesh/funnel_string_pull.js +225 -0
  191. package/src/core/geom/3d/line/line3_computeSegmentPointDistance_sqr.d.ts +0 -14
  192. package/src/core/geom/3d/line/line3_computeSegmentPointDistance_sqr.d.ts.map +0 -1
  193. package/src/core/geom/3d/topology/struct/binary/io/OrderedEdge.d.ts.map +0 -1
  194. package/src/core/geom/3d/topology/struct/binary/io/bt_edge_create.d.ts.map +0 -1
  195. package/src/core/geom/3d/topology/struct/binary/io/bt_edge_get_or_create.d.ts.map +0 -1
  196. package/src/core/geom/3d/topology/struct/binary/io/bt_edge_kill.d.ts.map +0 -1
  197. package/src/core/geom/3d/topology/struct/binary/io/bt_face_kill.d.ts +0 -7
  198. package/src/core/geom/3d/topology/struct/binary/io/bt_face_kill.d.ts.map +0 -1
  199. package/src/core/geom/3d/topology/struct/binary/io/bt_face_kill.js +0 -8
  200. package/src/core/geom/3d/topology/struct/binary/io/bt_index_geometry_to_topology.d.ts +0 -11
  201. package/src/core/geom/3d/topology/struct/binary/io/bt_index_geometry_to_topology.d.ts.map +0 -1
  202. package/src/core/geom/3d/topology/struct/binary/io/bt_kill_only_edge.d.ts.map +0 -1
  203. package/src/core/geom/3d/topology/struct/binary/io/bt_kill_only_face.d.ts.map +0 -1
  204. package/src/core/geom/3d/topology/struct/binary/io/bt_kill_only_vert.d.ts.map +0 -1
  205. package/src/core/geom/3d/topology/struct/binary/io/bt_merge_verts_by_distance.d.ts +0 -18
  206. package/src/core/geom/3d/topology/struct/binary/io/bt_merge_verts_by_distance.d.ts.map +0 -1
  207. package/src/core/geom/3d/topology/struct/binary/io/bt_merge_verts_by_distance.js +0 -83
  208. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_calc_edges.d.ts.map +0 -1
  209. package/src/core/geom/3d/topology/struct/binary/io/bt_vert_kill.d.ts.map +0 -1
  210. package/src/core/geom/3d/topology/struct/binary/io/get_or_create_edge_map.d.ts.map +0 -1
  211. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_edge_has_vertex.d.ts +0 -9
  212. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_edge_has_vertex.d.ts.map +0 -1
  213. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_edge_other_vertex.d.ts.map +0 -1
  214. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_face_get_neighbour_faces.d.ts +0 -10
  215. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_face_get_neighbour_faces.d.ts.map +0 -1
  216. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_face_get_neighbour_faces.js +0 -44
  217. package/src/core/geom/3d/triangle/computeTrianglePlaneSide.d.ts +0 -20
  218. package/src/core/geom/3d/triangle/computeTrianglePlaneSide.d.ts.map +0 -1
  219. package/src/engine/navigation/__module.d.ts +0 -2
  220. package/src/engine/navigation/__module.d.ts.map +0 -1
  221. package/src/engine/navigation/__module.js +0 -1
  222. /package/src/core/geom/3d/topology/struct/binary/io/{OrderedEdge.d.ts → edge/OrderedEdge.d.ts} +0 -0
  223. /package/src/core/geom/3d/topology/struct/binary/io/{bt_edge_create.d.ts → edge/bt_edge_create.d.ts} +0 -0
  224. /package/src/core/geom/3d/topology/struct/binary/io/{bt_edge_get_or_create.d.ts → edge/bt_edge_get_or_create.d.ts} +0 -0
  225. /package/src/core/geom/3d/topology/struct/binary/io/{bt_edge_kill.d.ts → edge/bt_edge_kill.d.ts} +0 -0
  226. /package/src/core/geom/3d/topology/struct/binary/io/{bt_kill_only_edge.d.ts → edge/bt_kill_only_edge.d.ts} +0 -0
  227. /package/src/core/geom/3d/topology/struct/binary/io/{bt_kill_only_edge.js → edge/bt_kill_only_edge.js} +0 -0
  228. /package/src/core/geom/3d/topology/struct/binary/io/{bt_mesh_calc_edges.d.ts → edge/bt_mesh_calc_edges.d.ts} +0 -0
  229. /package/src/core/geom/3d/topology/struct/binary/io/{get_or_create_edge_map.d.ts → edge/get_or_create_edge_map.d.ts} +0 -0
  230. /package/src/core/geom/3d/topology/struct/binary/io/{get_or_create_edge_map.js → edge/get_or_create_edge_map.js} +0 -0
  231. /package/src/core/geom/3d/topology/struct/binary/io/{bt_kill_only_face.d.ts → face/bt_kill_only_face.d.ts} +0 -0
  232. /package/src/core/geom/3d/topology/struct/binary/io/{bt_kill_only_face.js → face/bt_kill_only_face.js} +0 -0
  233. /package/src/core/geom/3d/topology/struct/binary/io/{bt_kill_only_vert.d.ts → vertex/bt_kill_only_vert.d.ts} +0 -0
  234. /package/src/core/geom/3d/topology/struct/binary/io/{bt_kill_only_vert.js → vertex/bt_kill_only_vert.js} +0 -0
  235. /package/src/core/geom/3d/topology/struct/binary/io/{bt_vert_kill.d.ts → vertex/bt_vert_kill.d.ts} +0 -0
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Remove vertices/edges/loops/disks etc. that are not referenced by any faces.
3
+ * Useful when running topology modifying algorithms such as erosion or simplification.
4
+ * Performs in-place modification of the mesh.
5
+ *
6
+ * If a valid mesh is passed in, after calling this - the mesh is guaranteed to be in a valid state.
7
+ * @param {BinaryTopology} mesh
8
+ */
9
+ export function bt_mesh_cleanup_faceless_references(mesh: BinaryTopology): void;
10
+ //# sourceMappingURL=bt_mesh_cleanup_faceless_references.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bt_mesh_cleanup_faceless_references.d.ts","sourceRoot":"","sources":["../../../../../../../../../src/core/geom/3d/topology/struct/binary/io/bt_mesh_cleanup_faceless_references.js"],"names":[],"mappings":"AAKA;;;;;;;GAOG;AACH,gFAgDC"}
@@ -0,0 +1,62 @@
1
+ import { NULL_POINTER } from "../BinaryTopology.js";
2
+ import { bt_loop_kill } from "./bt_loop_kill.js";
3
+ import { bt_edge_kill } from "./edge/bt_edge_kill.js";
4
+ import { bt_vert_kill } from "./vertex/bt_vert_kill.js";
5
+
6
+ /**
7
+ * Remove vertices/edges/loops/disks etc. that are not referenced by any faces.
8
+ * Useful when running topology modifying algorithms such as erosion or simplification.
9
+ * Performs in-place modification of the mesh.
10
+ *
11
+ * If a valid mesh is passed in, after calling this - the mesh is guaranteed to be in a valid state.
12
+ * @param {BinaryTopology} mesh
13
+ */
14
+ export function bt_mesh_cleanup_faceless_references(mesh) {
15
+ const loop_pool = mesh.loops;
16
+
17
+ // Cull orphaned loops
18
+ // Loops without a face pointer are not part of any face polygon.
19
+ // bt_loop_kill should untangle the loop from its edge's radial cycle and vertex.
20
+ const loop_count = loop_pool.size;
21
+ for (let l = 0; l < loop_count; l++) {
22
+ if (!loop_pool.is_allocated(l)) {
23
+ continue;
24
+ }
25
+
26
+ if (mesh.loop_read_face(l) === NULL_POINTER) {
27
+ bt_loop_kill(mesh, l);
28
+ }
29
+ }
30
+
31
+ const edge_pool = mesh.edges;
32
+
33
+ // Cull disconnected edges
34
+ // Edges without a loop are not part of any face
35
+ const edge_count = edge_pool.size;
36
+ for (let e = 0; e < edge_count; e++) {
37
+ if (!edge_pool.is_allocated(e)) {
38
+ continue;
39
+ }
40
+
41
+ if (mesh.edge_read_loop(e) === NULL_POINTER) {
42
+ bt_edge_kill(mesh, e);
43
+ }
44
+ }
45
+
46
+ const vertex_pool = mesh.vertices;
47
+
48
+ // Cull disconnected vertices
49
+ // Vertices without an edge pointer are completely isolated.
50
+ // Note: bt_edge_kill above handles untangling killed edges from vertex disk cycles,
51
+ // so any vertices left entirely stranded will now safely read as NULL_POINTER.
52
+ const vertex_count = vertex_pool.size;
53
+ for (let v = 0; v < vertex_count; v++) {
54
+ if (!vertex_pool.is_allocated(v)) {
55
+ continue;
56
+ }
57
+
58
+ if (mesh.vertex_read_edge(v) === NULL_POINTER) {
59
+ bt_vert_kill(mesh, v);
60
+ }
61
+ }
62
+ }
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Breaks up shared edges and vertices between two faces.
3
+ * As a result duplicate vertices and edges may be created.
4
+ *
5
+ * Primary isolate faces so they can be edited independently.
6
+ *
7
+ * @param {BinaryTopology} mesh
8
+ * @param {number} face0_id
9
+ * @param {number} face1_id
10
+ * @see bt_merge_verts_by_distance
11
+ */
12
+ export function bt_mesh_face_decouple(mesh: BinaryTopology, face0_id: number, face1_id: number): void;
13
+ //# sourceMappingURL=bt_mesh_face_decouple.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bt_mesh_face_decouple.d.ts","sourceRoot":"","sources":["../../../../../../../../../src/core/geom/3d/topology/struct/binary/io/bt_mesh_face_decouple.js"],"names":[],"mappings":"AAQA;;;;;;;;;;GAUG;AACH,sEAJW,MAAM,YACN,MAAM,QAgIhB"}
@@ -0,0 +1,145 @@
1
+ import { assert } from "../../../../../../assert.js";
2
+ import { NULL_POINTER } from "../BinaryTopology.js";
3
+ import { bt_disk_edge_add } from "./bt_disk_edge_add.js";
4
+ import { bt_disk_edge_remove } from "./bt_disk_edge_remove.js";
5
+ import { bt_radial_loop_add } from "./bt_radial_loop_add.js";
6
+ import { bt_radial_loop_remove } from "./bt_radial_loop_remove.js";
7
+ import { bt_edge_create } from "./edge/bt_edge_create.js";
8
+
9
+ /**
10
+ * Breaks up shared edges and vertices between two faces.
11
+ * As a result duplicate vertices and edges may be created.
12
+ *
13
+ * Primary isolate faces so they can be edited independently.
14
+ *
15
+ * @param {BinaryTopology} mesh
16
+ * @param {number} face0_id
17
+ * @param {number} face1_id
18
+ * @see bt_merge_verts_by_distance
19
+ */
20
+ export function bt_mesh_face_decouple(
21
+ mesh,
22
+ face0_id,
23
+ face1_id,
24
+ ) {
25
+ assert.isNonNegativeInteger(face0_id, 'face0_id');
26
+ assert.isNonNegativeInteger(face1_id, 'face1_id');
27
+ assert.defined(mesh, 'mesh');
28
+ assert.notNull(mesh, 'mesh');
29
+
30
+ assert.equal(mesh.isBinaryTopology, true, 'mesh.isBinaryTopology !== true');
31
+
32
+ let l0 = mesh.face_read_loop(face0_id);
33
+ let l1 = mesh.face_read_loop(face1_id);
34
+
35
+ if (l0 === NULL_POINTER || l1 === NULL_POINTER) {
36
+ return;
37
+ }
38
+
39
+ // 1. Gather components of face0
40
+ const v0_set = new Set();
41
+ const e0_set = new Set();
42
+ let start0 = l0;
43
+ do {
44
+ v0_set.add(mesh.loop_read_vertex(l0));
45
+ e0_set.add(mesh.loop_read_edge(l0));
46
+ l0 = mesh.loop_read_next(l0);
47
+ } while (l0 !== start0);
48
+
49
+ // 2. Map intersection components from face1
50
+ const v1_loops = [];
51
+ const shared_v = new Set();
52
+ const shared_e = new Set();
53
+ const unshared_e_set = new Set();
54
+
55
+ let start1 = l1;
56
+ do {
57
+ v1_loops.push(l1);
58
+ const v = mesh.loop_read_vertex(l1);
59
+ const e = mesh.loop_read_edge(l1);
60
+
61
+ if (v0_set.has(v)) {
62
+ shared_v.add(v);
63
+ }
64
+ if (e0_set.has(e)) {
65
+ shared_e.add(e);
66
+ } else {
67
+ unshared_e_set.add(e);
68
+ }
69
+
70
+ l1 = mesh.loop_read_next(l1);
71
+ } while (l1 !== start1);
72
+
73
+ // If nothing is shared, they are already decoupled.
74
+ if (shared_v.size === 0 && shared_e.size === 0){
75
+ return;
76
+ }
77
+
78
+ // Pre-allocate arrays for fast coordinate/normal copying
79
+ const temp_coords = new Float32Array(3);
80
+ const temp_normal = new Float32Array(3);
81
+
82
+ // 3. Duplicate shared vertices
83
+ const v_map = new Map();
84
+ for (const v of shared_v) {
85
+ const v_new = mesh.vertices.allocate();
86
+
87
+ mesh.vertex_read_coordinate(temp_coords, 0, v);
88
+ mesh.vertex_write_coordinate(v_new, temp_coords, 0);
89
+
90
+ mesh.vertex_read_normal(temp_normal, 0, v);
91
+ mesh.vertex_write_normal(v_new, temp_normal, 0);
92
+
93
+ mesh.vertex_write_edge(v_new, NULL_POINTER);
94
+ v_map.set(v, v_new);
95
+ }
96
+
97
+ // 4. Duplicate shared edges
98
+ const e_map = new Map();
99
+ for (const e of shared_e) {
100
+ const v1 = mesh.edge_read_vertex1(e);
101
+ const v2 = mesh.edge_read_vertex2(e);
102
+
103
+ const v1_new = v_map.has(v1) ? v_map.get(v1) : v1;
104
+ const v2_new = v_map.has(v2) ? v_map.get(v2) : v2;
105
+
106
+ const e_new = bt_edge_create(mesh, v1_new, v2_new);
107
+ e_map.set(e, e_new);
108
+ }
109
+
110
+ // 5. Shift unshared edges that are attached to duplicated vertices
111
+ for (const e of unshared_e_set) {
112
+ const v1 = mesh.edge_read_vertex1(e);
113
+ const v2 = mesh.edge_read_vertex2(e);
114
+
115
+ if (v_map.has(v1)) {
116
+ bt_disk_edge_remove(mesh, e, v1);
117
+ const v1_new = v_map.get(v1);
118
+ mesh.edge_write_vertex1(e, v1_new);
119
+ bt_disk_edge_add(mesh, e, v1_new);
120
+ }
121
+ if (v_map.has(v2)) {
122
+ bt_disk_edge_remove(mesh, e, v2);
123
+ const v2_new = v_map.get(v2);
124
+ mesh.edge_write_vertex2(e, v2_new);
125
+ bt_disk_edge_add(mesh, e, v2_new);
126
+ }
127
+ }
128
+
129
+ // 6. Redirect loops on face1 to the new duplicated edges and vertices
130
+ for (const loop of v1_loops) {
131
+ const v = mesh.loop_read_vertex(loop);
132
+ const e = mesh.loop_read_edge(loop);
133
+
134
+ if (v_map.has(v)) {
135
+ mesh.loop_write_vertex(loop, v_map.get(v));
136
+ }
137
+
138
+ if (e_map.has(e)) {
139
+ const e_new = e_map.get(e);
140
+
141
+ bt_radial_loop_remove(mesh, loop, e);
142
+ bt_radial_loop_add(mesh, loop, e_new);
143
+ }
144
+ }
145
+ }
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Breaks up any shared edges and vertices between faces across given islands.
3
+ * As a result each island shares no vertices or edges with other islands.
4
+ *
5
+ * Note: Islands do not have to be connected, but must be disjoint.
6
+ * Note: Islands do not have to include all faces of the mesh.
7
+ *
8
+ * @param {BinaryTopology} mesh
9
+ * @param {number[][]} islands 2D array of face IDs
10
+ */
11
+ export function bt_mesh_face_decouple_islands(mesh: BinaryTopology, islands: number[][]): void;
12
+ //# sourceMappingURL=bt_mesh_face_decouple_islands.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bt_mesh_face_decouple_islands.d.ts","sourceRoot":"","sources":["../../../../../../../../../src/core/geom/3d/topology/struct/binary/io/bt_mesh_face_decouple_islands.js"],"names":[],"mappings":"AAGA;;;;;;;;;GASG;AACH,6EAFW,MAAM,EAAE,EAAE,QAmGpB"}
@@ -0,0 +1,111 @@
1
+ import { bt_face_get_attached_faces } from "../query/bt_face_get_attached_faces.js";
2
+ import { bt_mesh_face_decouple } from "./bt_mesh_face_decouple.js";
3
+
4
+ /**
5
+ * Breaks up any shared edges and vertices between faces across given islands.
6
+ * As a result each island shares no vertices or edges with other islands.
7
+ *
8
+ * Note: Islands do not have to be connected, but must be disjoint.
9
+ * Note: Islands do not have to include all faces of the mesh.
10
+ *
11
+ * @param {BinaryTopology} mesh
12
+ * @param {number[][]} islands 2D array of face IDs
13
+ */
14
+ export function bt_mesh_face_decouple_islands(mesh, islands) {
15
+
16
+ if (islands.length <= 1) {
17
+ // no need to decouple
18
+ return;
19
+ }
20
+
21
+ /**
22
+ *
23
+ * @type {number[]}
24
+ */
25
+ const all_island_faces = [];
26
+ /**
27
+ *
28
+ * @type {Map<number, number>}
29
+ */
30
+ const face_to_islands = new Map();
31
+
32
+ // build face -> island map
33
+ for (let island_id = 0; island_id < islands.length; island_id++) {
34
+ const island = islands[island_id];
35
+
36
+ const island_size = island.length;
37
+
38
+ for (let j = 0; j < island_size; j++) {
39
+ const face = island[j];
40
+
41
+ face_to_islands.set(face, island_id);
42
+ all_island_faces.push(face);
43
+
44
+ }
45
+ }
46
+
47
+ // crawl faces
48
+ const relevant_face_count = all_island_faces.length;
49
+
50
+ /**
51
+ *
52
+ * @type {number[]}
53
+ */
54
+ const other_faces = [];
55
+
56
+ /**
57
+ *
58
+ * @type {Map<number, Set<number>>}
59
+ */
60
+ const processed_pairs = new Map();
61
+
62
+ /**
63
+ *
64
+ * @param {number} face
65
+ * @returns {Set<number>}
66
+ */
67
+ function get_processed_pair(face) {
68
+ const existing = processed_pairs.get(face);
69
+
70
+ if (existing !== undefined) {
71
+ return existing;
72
+ }
73
+
74
+ const v = new Set();
75
+
76
+ processed_pairs.set(face, v);
77
+
78
+ return v;
79
+ }
80
+
81
+ for (let i = 0; i < relevant_face_count; i++) {
82
+ const face = all_island_faces[i];
83
+
84
+ const island_id = face_to_islands.get(face);
85
+
86
+ const attached_count = bt_face_get_attached_faces(other_faces, 0, mesh, face);
87
+
88
+ for (let j = 0; j < attached_count; j++) {
89
+ const attached_face = other_faces[j];
90
+
91
+ const neighbour_island_id = face_to_islands.get(attached_face);
92
+
93
+ if (neighbour_island_id === island_id || neighbour_island_id === undefined) {
94
+ continue;
95
+ }
96
+
97
+ const this_pairs = get_processed_pair(face);
98
+
99
+ if (this_pairs.has(attached_face)) {
100
+ // already processed
101
+ continue;
102
+ }
103
+
104
+ bt_mesh_face_decouple(mesh, face, attached_face);
105
+
106
+ // record processed pair
107
+ this_pairs.add(attached_face);
108
+ get_processed_pair(attached_face).add(face);
109
+ }
110
+ }
111
+ }
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Shrinks an island of faces by a given distance.
3
+ * Conceptually, this moves the outline of the island inwards.
4
+ * Assumes the input mesh is triangulated, see {@link bt_mesh_triangulate}.
5
+ *
6
+ * It is assumed that the island does not share any edges/vertices with any other part of the mesh. If this assumption is violated - expect undefined behavior.
7
+ * An island is not restricted to all faces being co-planar, it may curve.
8
+ * The erosion distance may be smaller than the smallest triangle height in the island, or it may be significantly larger - there is no restriction.
9
+ *
10
+ * @param {BinaryTopology} mesh
11
+ * @param {number[]} faces
12
+ * @param {number} erode_distance
13
+ */
14
+ export function bt_mesh_face_island_erode(mesh: BinaryTopology, faces: number[], erode_distance: number): void;
15
+ //# sourceMappingURL=bt_mesh_face_island_erode.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bt_mesh_face_island_erode.d.ts","sourceRoot":"","sources":["../../../../../../../../../src/core/geom/3d/topology/struct/binary/io/bt_mesh_face_island_erode.js"],"names":[],"mappings":"AAcA;;;;;;;;;;;;GAYG;AACH,uEAHW,MAAM,EAAE,kBACR,MAAM,QAwQhB"}
@@ -0,0 +1,290 @@
1
+ import { assert } from "../../../../../../assert.js";
2
+ import { clamp01 } from "../../../../../../math/clamp01.js";
3
+ import { inverseLerp } from "../../../../../../math/inverseLerp.js";
4
+ import {
5
+ line3_compute_segment_point_distance_eikonal
6
+ } from "../../../../line/line3_compute_segment_point_distance_eikonal.js";
7
+ import { NULL_POINTER } from "../BinaryTopology.js";
8
+ import { bt_face_get_incenter } from "../query/bt_face_get_incenter.js";
9
+ import { bt_mesh_build_boundary_distance_field } from "../query/bt_mesh_build_boundary_distance_field.js";
10
+ import { bt_mesh_cleanup_faceless_references } from "./bt_mesh_cleanup_faceless_references.js";
11
+ import { bt_edge_split } from "./edge/bt_edge_split.js";
12
+ import { bt_face_kill } from "./face/bt_face_kill.js";
13
+ import { bt_mesh_face_poke } from "./face/bt_face_poke.js";
14
+
15
+ /**
16
+ * Shrinks an island of faces by a given distance.
17
+ * Conceptually, this moves the outline of the island inwards.
18
+ * Assumes the input mesh is triangulated, see {@link bt_mesh_triangulate}.
19
+ *
20
+ * It is assumed that the island does not share any edges/vertices with any other part of the mesh. If this assumption is violated - expect undefined behavior.
21
+ * An island is not restricted to all faces being co-planar, it may curve.
22
+ * The erosion distance may be smaller than the smallest triangle height in the island, or it may be significantly larger - there is no restriction.
23
+ *
24
+ * @param {BinaryTopology} mesh
25
+ * @param {number[]} faces
26
+ * @param {number} erode_distance
27
+ */
28
+ export function bt_mesh_face_island_erode(
29
+ mesh,
30
+ faces,
31
+ erode_distance
32
+ ) {
33
+
34
+ if (faces.length === 0 || erode_distance <= 0) {
35
+ // no work to do
36
+ return;
37
+ }
38
+
39
+ /**
40
+ *
41
+ * @type {Set<number>}
42
+ */
43
+ const island_vertices = new Set();
44
+
45
+ /**
46
+ *
47
+ * @type {Set<number>}
48
+ */
49
+ const island_edges = new Set();
50
+
51
+ // 1. Map all vertices and edges of the island
52
+ for (let i = 0; i < faces.length; i++) {
53
+ const f = faces[i];
54
+ const l_first = mesh.face_read_loop(f);
55
+ if (l_first === NULL_POINTER) continue;
56
+
57
+ let l_curr = l_first;
58
+ do {
59
+ island_vertices.add(mesh.loop_read_vertex(l_curr));
60
+ island_edges.add(mesh.loop_read_edge(l_curr));
61
+ l_curr = mesh.loop_read_next(l_curr);
62
+ } while (l_curr !== l_first);
63
+ }
64
+
65
+ // 2. Identify boundary vertices (edges with only one loop)
66
+ const boundary_vertices = new Set();
67
+ const boundary_edges_set = new Set();
68
+
69
+ for (const e of island_edges) {
70
+ const l = mesh.edge_read_loop(e);
71
+ if (mesh.loop_read_radial_next(l) === l) {
72
+ boundary_vertices.add(mesh.edge_read_vertex1(e));
73
+ boundary_vertices.add(mesh.edge_read_vertex2(e));
74
+
75
+ boundary_edges_set.add(e);
76
+ }
77
+ }
78
+
79
+ if (boundary_vertices.size === 0) {
80
+ // no boundary vertices found
81
+ // should never happen if the mesh is valid
82
+ return;
83
+ }
84
+
85
+ // 3. Compute Geodesic Distance Field
86
+ /**
87
+ * Vertex -> Distance from boundary
88
+ * @type {Map<number, number>}
89
+ */
90
+ const vertex_boundary_distances = new Map();
91
+ bt_mesh_build_boundary_distance_field(vertex_boundary_distances, mesh, island_vertices, boundary_vertices);
92
+ // ---------------------------------------------------------
93
+ // 3.5. PEAK RESCUE PASS (The Fix)
94
+ // Handle cases where a face is "submerged" by vertex values
95
+ // but geometrically contains a safe zone (e.g. single triangle).
96
+ // ---------------------------------------------------------
97
+
98
+ // We snapshot the faces list because we might modify topology (poke)
99
+ const faces_to_check = [...faces];
100
+ const centroid = [];
101
+ const scratch_v1 = [];
102
+ const scratch_v2 = [];
103
+
104
+ for (const f of faces_to_check) {
105
+ // Collect face vertices and check if they are all "dead"
106
+ let l_curr = mesh.face_read_loop(f);
107
+ const l_end = l_curr;
108
+ let all_dead = true;
109
+
110
+ do {
111
+ const v = mesh.loop_read_vertex(l_curr);
112
+ if ((vertex_boundary_distances.get(v) || 0) >= erode_distance) {
113
+ all_dead = false;
114
+ }
115
+ l_curr = mesh.loop_read_next(l_curr);
116
+ } while (l_curr !== l_end);
117
+
118
+ if (all_dead) {
119
+ // This face is slated for total deletion.
120
+ // Check if we should rescue it by adding a peak vertex.
121
+
122
+ // 1. Calculate Centroid (incenter only for triangle, falls back to centroid for other N-gons)
123
+ bt_face_get_incenter(centroid, 0, mesh, f);
124
+
125
+ // 2. Calculate Centroid Distance to Boundary
126
+ // (For a single island face, min dist to its own boundary edges)
127
+ let min_dist = Infinity;
128
+ // Iterate edges of this face
129
+ l_curr = mesh.face_read_loop(f);
130
+ do {
131
+ const e = mesh.loop_read_edge(l_curr);
132
+
133
+ const v1 = mesh.edge_read_vertex1(e);
134
+ const v2 = mesh.edge_read_vertex2(e);
135
+
136
+ if (island_vertices.has(v1) && island_vertices.has(v2)) {
137
+
138
+ mesh.vertex_read_coordinate(scratch_v1, 0, v1);
139
+ mesh.vertex_read_coordinate(scratch_v2, 0, v2);
140
+
141
+ const d1 = vertex_boundary_distances.get(v1);
142
+ const d2 = vertex_boundary_distances.get(v2);
143
+
144
+ if (d1 < erode_distance || d2 < erode_distance) {
145
+ // only consider edges that could cross the erosion threshold
146
+
147
+ const d = line3_compute_segment_point_distance_eikonal(
148
+ d1, d2,
149
+ scratch_v1[0], scratch_v1[1], scratch_v1[2],
150
+ scratch_v2[0], scratch_v2[1], scratch_v2[2],
151
+ centroid[0], centroid[1], centroid[2]
152
+ );
153
+
154
+ if (d < min_dist) {
155
+ min_dist = d;
156
+ }
157
+
158
+ }
159
+
160
+ }
161
+
162
+ l_curr = mesh.loop_read_next(l_curr);
163
+ } while (l_curr !== l_end);
164
+
165
+ // If min_dist is Infinity, it means this face has NO boundary edges
166
+ // (it's internal). It should have inherited values from neighbors.
167
+ // We ignore it, or assume linear interpolation was correct.
168
+ // We only rescue faces touching the boundary that collapsed.
169
+
170
+ if (min_dist !== Infinity && min_dist > erode_distance) {
171
+ // RESCUE: The center is safe!
172
+ // Poke the face to create a vertex at the centroid.
173
+ const new_vert = bt_mesh_face_poke(mesh, f, centroid[0], centroid[1], centroid[2]);
174
+
175
+ // Update Data
176
+ island_vertices.add(new_vert);
177
+ vertex_boundary_distances.set(new_vert, min_dist);
178
+
179
+ // Read the new edges connected to the center and add to processing set
180
+ let e_first = mesh.vertex_read_edge(new_vert);
181
+
182
+ let e_scan = e_first;
183
+ do {
184
+ island_edges.add(e_scan);
185
+
186
+ const v1 = mesh.edge_read_vertex1(e_scan);
187
+ const is_v1 = v1 === new_vert;
188
+
189
+ // DEBUG checks
190
+ const v2 = mesh.edge_read_vertex2(e_scan);
191
+ if (is_v1) {
192
+ assert.equal(v1, new_vert, 'edge vertex does not match new vertex');
193
+ assert.notEqual(v2, new_vert, 'edge vertex does not match new vertex');
194
+ } else {
195
+ assert.equal(v2, new_vert, 'edge vertex does not match new vertex');
196
+ assert.notEqual(v1, new_vert, 'edge vertex does not match new vertex');
197
+ }
198
+
199
+ e_scan = is_v1 ? mesh.edge_read_v1_disk_next(e_scan) : mesh.edge_read_v2_disk_next(e_scan);
200
+ } while (e_scan !== e_first);
201
+ }
202
+ }
203
+ }
204
+ // ---------------------------------------------------------
205
+
206
+ // 4. Trace the Contour & Split Edges
207
+
208
+ /**
209
+ *
210
+ * @type {{e: number, t: number}[]}
211
+ */
212
+ const edges_to_split = [];
213
+
214
+ for (const e of island_edges) {
215
+
216
+ assert.equal(mesh.edges.is_allocated(e), true, 'edge is not allocated');
217
+
218
+ const v1 = mesh.edge_read_vertex1(e);
219
+ const v2 = mesh.edge_read_vertex2(e);
220
+
221
+ const d1 = vertex_boundary_distances.get(v1);
222
+ const d2 = vertex_boundary_distances.get(v2);
223
+
224
+ // If the edge strictly crosses the erosion threshold
225
+ const crosses_erosion_boundary = (d1 < erode_distance && d2 > erode_distance) || (d2 < erode_distance && d1 > erode_distance);
226
+
227
+ if (crosses_erosion_boundary) {
228
+ // Calculate exact interpolation parameter
229
+ const t = clamp01(inverseLerp(d1, d2, erode_distance));
230
+ edges_to_split.push({ e, t });
231
+ }
232
+ }
233
+
234
+ // Execute splits
235
+ for (const { e, t } of edges_to_split) {
236
+ // splits the edge as well as adjacent faces.
237
+ bt_edge_split(mesh, e, t);
238
+ }
239
+
240
+ // Cull Dead Geometry
241
+ // Any vertex that had a distance < erode_distance is dead.
242
+ // Any face connected to a dead vertex must be destroyed.
243
+ /**
244
+ *
245
+ * @type {Set<number>}
246
+ */
247
+ const faces_to_kill = new Set();
248
+
249
+ for (const [vertex, distance] of vertex_boundary_distances.entries()) {
250
+ const EPSILON = 1e-17;
251
+
252
+ if (distance >= erode_distance - EPSILON) {
253
+ // too far, survives
254
+ continue;
255
+ }
256
+
257
+ const e_first = mesh.vertex_read_edge(vertex);
258
+
259
+ if (e_first === NULL_POINTER) {
260
+ continue;
261
+ }
262
+
263
+ let e_curr = e_first;
264
+ do {
265
+ // Traverse radial loops to get all connected faces
266
+ const l_first = mesh.edge_read_loop(e_curr);
267
+ if (l_first !== NULL_POINTER) {
268
+ let l_curr = l_first;
269
+ do {
270
+ faces_to_kill.add(mesh.loop_read_face(l_curr));
271
+ l_curr = mesh.loop_read_radial_next(l_curr);
272
+ } while (l_curr !== l_first);
273
+ }
274
+
275
+ // Move around disk cycle
276
+ const v1 = mesh.edge_read_vertex1(e_curr);
277
+ e_curr = (v1 === vertex) ? mesh.edge_read_v1_disk_next(e_curr) : mesh.edge_read_v2_disk_next(e_curr);
278
+ } while (e_curr !== e_first && e_curr !== NULL_POINTER);
279
+ }
280
+
281
+ // Eradicate the dead faces
282
+ for (const f of faces_to_kill) {
283
+ bt_face_kill(mesh, f);
284
+ }
285
+
286
+ // 6. Cleanup floating vertices and edges
287
+ if (faces_to_kill.size > 0) {
288
+ bt_mesh_cleanup_faceless_references(mesh);
289
+ }
290
+ }