@woosh/meep-engine 2.164.0 → 2.165.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 (256) hide show
  1. package/build/bundle-worker-terrain.js +1 -1
  2. package/package.json +1 -1
  3. package/src/core/binary/BitImage2.d.ts +91 -0
  4. package/src/core/binary/BitImage2.d.ts.map +1 -0
  5. package/src/core/binary/BitImage2.js +242 -0
  6. package/src/core/geom/2d/oriented-box/min_area_rect_2d.d.ts +22 -0
  7. package/src/core/geom/2d/oriented-box/min_area_rect_2d.d.ts.map +1 -0
  8. package/src/core/geom/2d/oriented-box/min_area_rect_2d.js +69 -0
  9. package/src/core/geom/2d/packing/skyline.d.ts +116 -0
  10. package/src/core/geom/2d/packing/skyline.d.ts.map +1 -0
  11. package/src/core/geom/2d/packing/skyline.js +258 -0
  12. package/src/core/geom/2d/triangle/tri2_rasterize_conservative.d.ts +18 -0
  13. package/src/core/geom/2d/triangle/tri2_rasterize_conservative.d.ts.map +1 -0
  14. package/src/core/geom/2d/triangle/tri2_rasterize_conservative.js +86 -0
  15. package/src/core/geom/3d/atlas/ATLAS_PORT_PLAN.md +486 -0
  16. package/src/core/geom/3d/atlas/BFF_PLAN.md +174 -0
  17. package/src/core/geom/3d/atlas/Chart.d.ts +58 -0
  18. package/src/core/geom/3d/atlas/Chart.d.ts.map +1 -0
  19. package/src/core/geom/3d/atlas/Chart.js +77 -0
  20. package/src/core/geom/3d/atlas/REVIEW_02.md +392 -0
  21. package/src/core/geom/3d/atlas/atlas_bench_lib.d.ts +73 -0
  22. package/src/core/geom/3d/atlas/atlas_bench_lib.d.ts.map +1 -0
  23. package/src/core/geom/3d/atlas/atlas_bench_lib.js +315 -0
  24. package/src/core/geom/3d/atlas/atlas_chart_type.d.ts +17 -0
  25. package/src/core/geom/3d/atlas/atlas_chart_type.d.ts.map +1 -0
  26. package/src/core/geom/3d/atlas/atlas_chart_type.js +16 -0
  27. package/src/core/geom/3d/atlas/atlas_compute_charts.d.ts +25 -0
  28. package/src/core/geom/3d/atlas/atlas_compute_charts.d.ts.map +1 -0
  29. package/src/core/geom/3d/atlas/atlas_compute_charts.js +188 -0
  30. package/src/core/geom/3d/atlas/atlas_extract_chart.d.ts +17 -0
  31. package/src/core/geom/3d/atlas/atlas_extract_chart.d.ts.map +1 -0
  32. package/src/core/geom/3d/atlas/atlas_extract_chart.js +107 -0
  33. package/src/core/geom/3d/atlas/atlas_generate.d.ts +39 -0
  34. package/src/core/geom/3d/atlas/atlas_generate.d.ts.map +1 -0
  35. package/src/core/geom/3d/atlas/atlas_generate.js +43 -0
  36. package/src/core/geom/3d/atlas/atlas_test_fixtures.d.ts +84 -0
  37. package/src/core/geom/3d/atlas/atlas_test_fixtures.d.ts.map +1 -0
  38. package/src/core/geom/3d/atlas/atlas_test_fixtures.js +266 -0
  39. package/src/core/geom/3d/atlas/atlas_write_chart_uvs.d.ts +25 -0
  40. package/src/core/geom/3d/atlas/atlas_write_chart_uvs.d.ts.map +1 -0
  41. package/src/core/geom/3d/atlas/atlas_write_chart_uvs.js +36 -0
  42. package/src/core/geom/3d/atlas/data/atlas_build_edge_dihedrals.d.ts +22 -0
  43. package/src/core/geom/3d/atlas/data/atlas_build_edge_dihedrals.d.ts.map +1 -0
  44. package/src/core/geom/3d/atlas/data/atlas_build_edge_dihedrals.js +62 -0
  45. package/src/core/geom/3d/atlas/data/atlas_build_edge_lengths.d.ts +9 -0
  46. package/src/core/geom/3d/atlas/data/atlas_build_edge_lengths.d.ts.map +1 -0
  47. package/src/core/geom/3d/atlas/data/atlas_build_edge_lengths.js +33 -0
  48. package/src/core/geom/3d/atlas/data/atlas_build_face_areas.d.ts +9 -0
  49. package/src/core/geom/3d/atlas/data/atlas_build_face_areas.d.ts.map +1 -0
  50. package/src/core/geom/3d/atlas/data/atlas_build_face_areas.js +50 -0
  51. package/src/core/geom/3d/atlas/io/atlas_mesh_weld_colocals.d.ts +27 -0
  52. package/src/core/geom/3d/atlas/io/atlas_mesh_weld_colocals.d.ts.map +1 -0
  53. package/src/core/geom/3d/atlas/io/atlas_mesh_weld_colocals.js +39 -0
  54. package/src/core/geom/3d/atlas/io/bt_loop_uv.d.ts +22 -0
  55. package/src/core/geom/3d/atlas/io/bt_loop_uv.d.ts.map +1 -0
  56. package/src/core/geom/3d/atlas/io/bt_loop_uv.js +57 -0
  57. package/src/core/geom/3d/atlas/pack/ChartPlacement.d.ts +36 -0
  58. package/src/core/geom/3d/atlas/pack/ChartPlacement.d.ts.map +1 -0
  59. package/src/core/geom/3d/atlas/pack/ChartPlacement.js +46 -0
  60. package/src/core/geom/3d/atlas/pack/atlas_pack_charts.d.ts +62 -0
  61. package/src/core/geom/3d/atlas/pack/atlas_pack_charts.d.ts.map +1 -0
  62. package/src/core/geom/3d/atlas/pack/atlas_pack_charts.js +551 -0
  63. package/src/core/geom/3d/atlas/param/atlas_chart_param_validity.d.ts +22 -0
  64. package/src/core/geom/3d/atlas/param/atlas_chart_param_validity.d.ts.map +1 -0
  65. package/src/core/geom/3d/atlas/param/atlas_chart_param_validity.js +73 -0
  66. package/src/core/geom/3d/atlas/param/atlas_chart_parameterize_bff.d.ts +37 -0
  67. package/src/core/geom/3d/atlas/param/atlas_chart_parameterize_bff.d.ts.map +1 -0
  68. package/src/core/geom/3d/atlas/param/atlas_chart_parameterize_bff.js +270 -0
  69. package/src/core/geom/3d/atlas/param/atlas_chart_parameterize_lscm.d.ts +23 -0
  70. package/src/core/geom/3d/atlas/param/atlas_chart_parameterize_lscm.d.ts.map +1 -0
  71. package/src/core/geom/3d/atlas/param/atlas_chart_parameterize_lscm.js +224 -0
  72. package/src/core/geom/3d/atlas/param/atlas_chart_parameterize_ortho.d.ts +14 -0
  73. package/src/core/geom/3d/atlas/param/atlas_chart_parameterize_ortho.d.ts.map +1 -0
  74. package/src/core/geom/3d/atlas/param/atlas_chart_parameterize_ortho.js +38 -0
  75. package/src/core/geom/3d/atlas/param/atlas_chart_stretch_metric.d.ts +22 -0
  76. package/src/core/geom/3d/atlas/param/atlas_chart_stretch_metric.d.ts.map +1 -0
  77. package/src/core/geom/3d/atlas/param/atlas_chart_stretch_metric.js +86 -0
  78. package/src/core/geom/3d/atlas/param/atlas_piecewise_resegment.d.ts +20 -0
  79. package/src/core/geom/3d/atlas/param/atlas_piecewise_resegment.d.ts.map +1 -0
  80. package/src/core/geom/3d/atlas/param/atlas_piecewise_resegment.js +183 -0
  81. package/src/core/geom/3d/atlas/param/fit_plane_basis.d.ts +27 -0
  82. package/src/core/geom/3d/atlas/param/fit_plane_basis.d.ts.map +1 -0
  83. package/src/core/geom/3d/atlas/param/fit_plane_basis.js +66 -0
  84. package/src/core/geom/3d/atlas/segment/RegionGraph.d.ts +31 -0
  85. package/src/core/geom/3d/atlas/segment/RegionGraph.d.ts.map +1 -0
  86. package/src/core/geom/3d/atlas/segment/RegionGraph.js +40 -0
  87. package/src/core/geom/3d/atlas/segment/atlas_build_region_graph.d.ts +23 -0
  88. package/src/core/geom/3d/atlas/segment/atlas_build_region_graph.d.ts.map +1 -0
  89. package/src/core/geom/3d/atlas/segment/atlas_build_region_graph.js +136 -0
  90. package/src/core/geom/3d/atlas/segment/atlas_compute_planar_regions.d.ts +24 -0
  91. package/src/core/geom/3d/atlas/segment/atlas_compute_planar_regions.d.ts.map +1 -0
  92. package/src/core/geom/3d/atlas/segment/atlas_compute_planar_regions.js +77 -0
  93. package/src/core/geom/3d/atlas/segment/atlas_merge_charts.d.ts +27 -0
  94. package/src/core/geom/3d/atlas/segment/atlas_merge_charts.d.ts.map +1 -0
  95. package/src/core/geom/3d/atlas/segment/atlas_merge_charts.js +113 -0
  96. package/src/core/geom/3d/atlas/segment/atlas_segment_charts.d.ts +44 -0
  97. package/src/core/geom/3d/atlas/segment/atlas_segment_charts.d.ts.map +1 -0
  98. package/src/core/geom/3d/atlas/segment/atlas_segment_charts.js +275 -0
  99. package/src/core/geom/3d/atlas/segment/atlas_segment_charts_atomic.d.ts +22 -0
  100. package/src/core/geom/3d/atlas/segment/atlas_segment_charts_atomic.d.ts.map +1 -0
  101. package/src/core/geom/3d/atlas/segment/atlas_segment_charts_atomic.js +199 -0
  102. package/src/core/geom/3d/line/line3_compute_point_segment_point_distance_unfolded.d.ts +32 -0
  103. package/src/core/geom/3d/line/line3_compute_point_segment_point_distance_unfolded.d.ts.map +1 -0
  104. package/src/core/geom/3d/line/line3_compute_point_segment_point_distance_unfolded.js +64 -0
  105. package/src/core/geom/3d/mat4/m4_from_rotation_translation_scale.d.ts +20 -0
  106. package/src/core/geom/3d/mat4/m4_from_rotation_translation_scale.d.ts.map +1 -0
  107. package/src/core/geom/3d/mat4/m4_from_rotation_translation_scale.js +66 -0
  108. package/src/core/geom/3d/sphere/harmonics/sh3_dering_optimize_positive.d.ts.map +1 -1
  109. package/src/core/geom/3d/sphere/harmonics/sh3_dering_optimize_positive.js +13 -11
  110. package/src/core/geom/3d/sphere/sphere_compute_bounding_of_2_spheres.d.ts.map +1 -1
  111. package/src/core/geom/3d/sphere/sphere_compute_bounding_of_2_spheres.js +4 -3
  112. package/src/core/geom/3d/topology/simplify/decimate_edge_collapse_snap.d.ts.map +1 -1
  113. package/src/core/geom/3d/topology/simplify/decimate_edge_collapse_snap.js +4 -3
  114. package/src/core/geom/3d/topology/simplify/quadratic/Quadric3.d.ts.map +1 -1
  115. package/src/core/geom/3d/topology/simplify/quadratic/Quadric3.js +4 -3
  116. package/src/core/geom/3d/topology/simplify/quadratic/apply_border_penalty_to_vertex_quadrics.d.ts.map +1 -1
  117. package/src/core/geom/3d/topology/simplify/quadratic/apply_border_penalty_to_vertex_quadrics.js +10 -6
  118. package/src/core/geom/3d/topology/struct/TopoMesh.js +2 -2
  119. package/src/core/geom/3d/topology/struct/TopoTriangle.d.ts +0 -2
  120. package/src/core/geom/3d/topology/struct/TopoTriangle.d.ts.map +1 -1
  121. package/src/core/geom/3d/topology/struct/TopoTriangle.js +2 -2
  122. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_face_find_path_polyanya.d.ts.map +1 -1
  123. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_face_find_path_polyanya.js +8 -27
  124. package/src/core/geom/vec3/v3_cotangent.d.ts +20 -0
  125. package/src/core/geom/vec3/v3_cotangent.d.ts.map +1 -0
  126. package/src/core/geom/vec3/v3_cotangent.js +29 -0
  127. package/src/core/geom/vec3/v3_matrix3_multiply.d.ts +19 -0
  128. package/src/core/geom/vec3/v3_matrix3_multiply.d.ts.map +1 -0
  129. package/src/core/geom/vec3/v3_matrix3_multiply.js +30 -0
  130. package/src/core/geom/vec3/v3_multiply.d.ts +16 -0
  131. package/src/core/geom/vec3/v3_multiply.d.ts.map +1 -0
  132. package/src/core/geom/vec3/v3_multiply.js +19 -0
  133. package/src/core/math/linalg/cg/cg_solve.d.ts +24 -0
  134. package/src/core/math/linalg/cg/cg_solve.d.ts.map +1 -0
  135. package/src/core/math/linalg/cg/cg_solve.js +106 -0
  136. package/src/core/math/linalg/cg/cg_solve_normal_equations.d.ts +21 -0
  137. package/src/core/math/linalg/cg/cg_solve_normal_equations.d.ts.map +1 -0
  138. package/src/core/math/linalg/cg/cg_solve_normal_equations.js +59 -0
  139. package/src/core/math/linalg/eigen/matrix_symmetric_3x3_eigen.d.ts +19 -0
  140. package/src/core/math/linalg/eigen/matrix_symmetric_3x3_eigen.d.ts.map +1 -0
  141. package/src/core/math/linalg/eigen/matrix_symmetric_3x3_eigen.js +117 -0
  142. package/src/core/math/linalg/sparse/SparseMatrixCSR.d.ts +50 -0
  143. package/src/core/math/linalg/sparse/SparseMatrixCSR.d.ts.map +1 -0
  144. package/src/core/math/linalg/sparse/SparseMatrixCSR.js +88 -0
  145. package/src/core/math/linalg/sparse/spm_matvec.d.ts +9 -0
  146. package/src/core/math/linalg/sparse/spm_matvec.d.ts.map +1 -0
  147. package/src/core/math/linalg/sparse/spm_matvec.js +22 -0
  148. package/src/core/math/linalg/sparse/spm_matvec_transpose.d.ts +12 -0
  149. package/src/core/math/linalg/sparse/spm_matvec_transpose.d.ts.map +1 -0
  150. package/src/core/math/linalg/sparse/spm_matvec_transpose.js +29 -0
  151. package/src/core/math/physics/mie/MIE_PARTICLES_STANDARD_PRECOMPUTED.d.ts +39 -0
  152. package/src/core/math/physics/mie/MIE_PARTICLES_STANDARD_PRECOMPUTED.js +22 -1
  153. package/src/core/math/physics/mie/compute_mie_particle_properties_rgb.d.ts.map +1 -1
  154. package/src/core/math/physics/mie/compute_mie_particle_properties_rgb.js +32 -9
  155. package/src/core/math/physics/mie/compute_mie_phase.d.ts +2 -3
  156. package/src/core/math/physics/mie/compute_mie_phase.d.ts.map +1 -1
  157. package/src/core/math/physics/mie/compute_mie_phase.js +1 -3
  158. package/src/core/math/physics/mie/lorenz_mie_coefs.d.ts +0 -1
  159. package/src/core/math/physics/mie/lorenz_mie_coefs.d.ts.map +1 -1
  160. package/src/core/math/physics/mie/lorenz_mie_coefs.js +0 -7
  161. package/src/engine/ecs/attachment/TransformAttachmentBinding.js +3 -3
  162. package/src/engine/ecs/gui/hud/HeadsUpDisplaySystem.js +2 -2
  163. package/src/engine/ecs/terrain/ecs/Terrain.d.ts.map +1 -1
  164. package/src/engine/ecs/terrain/ecs/Terrain.js +4 -3
  165. package/src/engine/ecs/terrain/tiles/TerrainTile.js +2 -2
  166. package/src/engine/ecs/terrain/tiles/TerrainTileManager.d.ts.map +1 -1
  167. package/src/engine/ecs/terrain/tiles/TerrainTileManager.js +9 -8
  168. package/src/engine/graphics/GraphicsEngine.d.ts.map +1 -1
  169. package/src/engine/graphics/GraphicsEngine.js +2 -1
  170. package/src/engine/graphics/ecs/decal/v2/FPDecalSystem.js +2 -2
  171. package/src/engine/graphics/ecs/decal/v2/prototypeDecalSystem.js +2 -2
  172. package/src/engine/graphics/ecs/mesh-v2/ShadedGeometry.js +2 -2
  173. package/src/engine/graphics/ecs/mesh-v2/ShadedGeometrySystem.d.ts.map +1 -1
  174. package/src/engine/graphics/ecs/mesh-v2/ShadedGeometrySystem.js +0 -1
  175. package/src/engine/graphics/ecs/path/tube/build/computeFrenetFrames.d.ts.map +1 -1
  176. package/src/engine/graphics/ecs/path/tube/build/computeFrenetFrames.js +8 -7
  177. package/src/engine/graphics/geometry/MikkT/AvgTSpace.d.ts.map +1 -1
  178. package/src/engine/graphics/geometry/MikkT/AvgTSpace.js +11 -6
  179. package/src/engine/graphics/geometry/MikkT/BuildNeighborsFast.d.ts.map +1 -1
  180. package/src/engine/graphics/geometry/MikkT/BuildNeighborsFast.js +2 -3
  181. package/src/engine/graphics/geometry/MikkT/CalcTexArea.d.ts.map +1 -1
  182. package/src/engine/graphics/geometry/MikkT/CalcTexArea.js +3 -4
  183. package/src/engine/graphics/geometry/MikkT/DegenEpilogue.js +4 -4
  184. package/src/engine/graphics/geometry/MikkT/EvalTspace.d.ts.map +1 -1
  185. package/src/engine/graphics/geometry/MikkT/EvalTspace.js +11 -8
  186. package/src/engine/graphics/geometry/MikkT/GenerateSharedVerticesIndexList.d.ts.map +1 -1
  187. package/src/engine/graphics/geometry/MikkT/GenerateSharedVerticesIndexList.js +7 -8
  188. package/src/engine/graphics/geometry/MikkT/GenerateTSpaces.js +8 -8
  189. package/src/engine/graphics/geometry/MikkT/InitTriInfo.d.ts.map +1 -1
  190. package/src/engine/graphics/geometry/MikkT/InitTriInfo.js +30 -25
  191. package/src/engine/graphics/geometry/MikkT/MikkTSpace.js +7 -7
  192. package/src/engine/graphics/geometry/MikkT/NormalizeSafe.d.ts +0 -1
  193. package/src/engine/graphics/geometry/MikkT/NormalizeSafe.d.ts.map +1 -1
  194. package/src/engine/graphics/geometry/MikkT/NormalizeSafe.js +6 -4
  195. package/src/engine/graphics/geometry/MikkT/STSpace.d.ts +0 -2
  196. package/src/engine/graphics/geometry/MikkT/STSpace.d.ts.map +1 -1
  197. package/src/engine/graphics/geometry/MikkT/STSpace.js +3 -3
  198. package/src/engine/graphics/geometry/MikkT/v3_scale_dot_sub_normalize.d.ts +0 -2
  199. package/src/engine/graphics/geometry/MikkT/v3_scale_dot_sub_normalize.d.ts.map +1 -1
  200. package/src/engine/graphics/geometry/MikkT/v3_scale_dot_sub_normalize.js +0 -1
  201. package/src/engine/graphics/impostors/octahedral/ImpostorBaker.d.ts +0 -2
  202. package/src/engine/graphics/impostors/octahedral/ImpostorBaker.d.ts.map +1 -1
  203. package/src/engine/graphics/impostors/octahedral/ImpostorBaker.js +4 -3
  204. package/src/engine/graphics/impostors/octahedral/grid/HemiOctahedralUvEncoder.js +2 -2
  205. package/src/engine/graphics/impostors/octahedral/grid/UvEncoder.d.ts +17 -7
  206. package/src/engine/graphics/impostors/voxel/VoxelImpostorBaker.js +2 -2
  207. package/src/engine/graphics/particles/particular/engine/utils/volume/ParticleVolume.js +3 -3
  208. package/src/engine/graphics/particles/particular/engine/utils/volume/prototypeParticleVolume.js +4 -3
  209. package/src/engine/graphics/render/forward_plus/LightManager.js +2 -2
  210. package/src/engine/graphics/render/forward_plus/model/Decal.d.ts +0 -2
  211. package/src/engine/graphics/render/forward_plus/model/Decal.d.ts.map +1 -1
  212. package/src/engine/graphics/render/forward_plus/model/Decal.js +3 -3
  213. package/src/engine/graphics/render/forward_plus/prototype/prototypeLightManager.js +4 -3
  214. package/src/engine/graphics/render/visibility/hiz/prototypeHiZ.js +6 -4
  215. package/src/engine/graphics/sh3/lightmap/ARTIFACTS_PLAN.md +146 -0
  216. package/src/engine/graphics/sh3/lightmap/CODE_REVIEW.md +121 -0
  217. package/src/engine/graphics/sh3/lightmap/LIGHTMAPPER_REVIEW.md +183 -0
  218. package/src/engine/graphics/sh3/lightmap/bake_lightmap_for_scene.d.ts +90 -0
  219. package/src/engine/graphics/sh3/lightmap/bake_lightmap_for_scene.d.ts.map +1 -0
  220. package/src/engine/graphics/sh3/lightmap/bake_lightmap_for_scene.js +678 -0
  221. package/src/engine/graphics/sh3/lightmap/lightmap_build_geometry.d.ts +32 -0
  222. package/src/engine/graphics/sh3/lightmap/lightmap_build_geometry.d.ts.map +1 -0
  223. package/src/engine/graphics/sh3/lightmap/lightmap_build_geometry.js +155 -0
  224. package/src/engine/graphics/sh3/lightmap/lightmap_denoise.d.ts +49 -0
  225. package/src/engine/graphics/sh3/lightmap/lightmap_denoise.d.ts.map +1 -0
  226. package/src/engine/graphics/sh3/lightmap/lightmap_denoise.js +136 -0
  227. package/src/engine/graphics/sh3/lightmap/lightmap_dilate.d.ts +19 -0
  228. package/src/engine/graphics/sh3/lightmap/lightmap_dilate.d.ts.map +1 -0
  229. package/src/engine/graphics/sh3/lightmap/lightmap_dilate.js +89 -0
  230. package/src/engine/graphics/sh3/lightmap/lightmap_gather.d.ts +54 -0
  231. package/src/engine/graphics/sh3/lightmap/lightmap_gather.d.ts.map +1 -0
  232. package/src/engine/graphics/sh3/lightmap/lightmap_gather.js +168 -0
  233. package/src/engine/graphics/sh3/lightmap/lightmap_rasterize_triangle.d.ts +30 -0
  234. package/src/engine/graphics/sh3/lightmap/lightmap_rasterize_triangle.d.ts.map +1 -0
  235. package/src/engine/graphics/sh3/lightmap/lightmap_rasterize_triangle.js +145 -0
  236. package/src/engine/graphics/sh3/lightmap/lightmap_seam_fix.d.ts +38 -0
  237. package/src/engine/graphics/sh3/lightmap/lightmap_seam_fix.d.ts.map +1 -0
  238. package/src/engine/graphics/sh3/lightmap/lightmap_seam_fix.js +152 -0
  239. package/src/engine/graphics/sh3/lightmap/prototypeLightmapBaker.d.ts +2 -0
  240. package/src/engine/graphics/sh3/lightmap/prototypeLightmapBaker.d.ts.map +1 -0
  241. package/src/engine/graphics/sh3/lightmap/prototypeLightmapBaker.js +186 -0
  242. package/src/engine/graphics/sh3/path_tracer/PathTracedMesh.d.ts.map +1 -1
  243. package/src/engine/graphics/sh3/path_tracer/PathTracedMesh.js +2 -2
  244. package/src/engine/graphics/sh3/path_tracer/PathTracer.js +2 -2
  245. package/src/engine/graphics/sh3/path_tracer/prepare_scene_gltf.d.ts.map +1 -1
  246. package/src/engine/graphics/sh3/path_tracer/prepare_scene_gltf.js +6 -4
  247. package/src/engine/graphics/sh3/path_tracer/prototypePathTracer.js +3 -3
  248. package/src/engine/graphics/sh3/path_tracer/texture/sample_material.d.ts.map +1 -1
  249. package/src/engine/graphics/sh3/path_tracer/texture/sample_material.js +5 -4
  250. package/src/engine/graphics/sh3/sky/hosek/prototype_hosek.js +2 -2
  251. package/src/engine/input/devices/KeyboardDevice.d.ts +61 -14
  252. package/src/engine/input/devices/KeyboardDevice.d.ts.map +1 -1
  253. package/src/engine/input/devices/KeyboardDevice.js +41 -15
  254. package/src/engine/input/devices/isHTMLElementFocusable.d.ts.map +1 -1
  255. package/src/engine/input/devices/isHTMLElementFocusable.js +2 -9
  256. package/src/engine/sound/simulation/prototypeAcousticSolver.js +261 -143
@@ -0,0 +1,315 @@
1
+ import { BinaryTopology, NULL_POINTER } from "../topology/struct/binary/BinaryTopology.js";
2
+ import { bt_mesh_from_unindexed_geometry } from "../topology/struct/binary/io/bt_mesh_from_unindexed_geometry.js";
3
+ import { bt_mesh_simplify_by_error } from "../topology/struct/binary/io/bt_mesh_simplify_by_error.js";
4
+ import { CHART_TYPE } from "./atlas_chart_type.js";
5
+ import { atlas_compute_charts } from "./atlas_compute_charts.js";
6
+ import { atlas_pack_charts } from "./pack/atlas_pack_charts.js";
7
+ import { atlas_chart_stretch_metric } from "./param/atlas_chart_stretch_metric.js";
8
+
9
+ /**
10
+ * Test/bench-only shared library for the atlas metrics benches. NOT imported by
11
+ * production code. Provides deterministic geometry generators (triangle soups),
12
+ * a rich per-run metric panel (chart count, stretch distribution incl. the
13
+ * high-distortion tail, chart-type histogram, seam length, packing utilization),
14
+ * and an A/B runner so a candidate option can be measured against the baseline
15
+ * with a directional gate.
16
+ *
17
+ * The metrics here are the standing instrument for validating the REVIEW_02.md
18
+ * "top opportunities": LSCM stretch tail (-> ARAP/cone-fit), chart count + seam
19
+ * length (-> mergeCharts), and packing utilization (-> best-fit placement).
20
+ */
21
+
22
+ // ─── Geometry generators (deterministic triangle soups) ──────────────────────
23
+ function pushTri(soup, ax, ay, az, bx, by, bz, cx, cy, cz) {
24
+ soup.push(ax, ay, az, bx, by, bz, cx, cy, cz);
25
+ }
26
+
27
+ /** Quad as two triangles; skips degenerate (coincident-vertex) triangles. */
28
+ function pushQuad(soup, a, b, c, d) {
29
+ if (!(same(a, b) || same(b, c) || same(a, c))) pushTri(soup, a[0], a[1], a[2], b[0], b[1], b[2], c[0], c[1], c[2]);
30
+ if (!(same(a, c) || same(c, d) || same(a, d))) pushTri(soup, a[0], a[1], a[2], c[0], c[1], c[2], d[0], d[1], d[2]);
31
+ }
32
+
33
+ function same(a, b) {
34
+ return a[0] === b[0] && a[1] === b[1] && a[2] === b[2];
35
+ }
36
+
37
+ /** Flat n×n plane in z=0. Single planar region => one chart, zero stretch. */
38
+ export function soup_plane(n) {
39
+ const soup = [];
40
+ const v = (i, j) => [i / n, j / n, 0];
41
+ for (let j = 0; j < n; j++) for (let i = 0; i < n; i++) pushQuad(soup, v(i, j), v(i + 1, j), v(i + 1, j + 1), v(i, j + 1));
42
+ return soup;
43
+ }
44
+
45
+ /** Deterministic gently-bumpy terrain (curved, smooth, no RNG). */
46
+ export function soup_terrain(n, amplitude) {
47
+ const h = (i, j) => amplitude * (Math.sin(i * 0.35) * Math.cos(j * 0.4) + 0.5 * Math.sin(i * 0.8 + j * 0.25));
48
+ const v = (i, j) => [i / n, j / n, h(i, j)];
49
+ const soup = [];
50
+ for (let j = 0; j < n; j++) for (let i = 0; i < n; i++) pushQuad(soup, v(i, j), v(i + 1, j), v(i + 1, j + 1), v(i, j + 1));
51
+ return soup;
52
+ }
53
+
54
+ /** Dense bumpy terrain decimated by the production simplifier -> irregular, over-segmenting asset. */
55
+ export function soup_decimated_terrain(n, amplitude, error) {
56
+ const mesh = build_mesh(soup_terrain(n, amplitude));
57
+ bt_mesh_simplify_by_error(mesh, error);
58
+ return topology_to_soup(mesh);
59
+ }
60
+
61
+ /** UV sphere (fanned poles, no degenerate tris). Smooth closed surface. */
62
+ export function soup_uv_sphere(rings, sectors) {
63
+ const soup = [];
64
+ const north = [0, 1, 0], south = [0, -1, 0];
65
+ const pos = (i, s) => {
66
+ const phi = (i / rings) * Math.PI, th = (s / sectors) * 2 * Math.PI;
67
+ return [Math.sin(phi) * Math.cos(th), Math.cos(phi), Math.sin(phi) * Math.sin(th)];
68
+ };
69
+ const vtx = (i, s) => (i === 0 ? north : i === rings ? south : pos(i, s));
70
+ for (let i = 0; i < rings; i++) for (let s = 0; s < sectors; s++) {
71
+ pushQuad(soup, vtx(i, s), vtx(i + 1, s), vtx(i + 1, s + 1), vtx(i, s + 1));
72
+ }
73
+ return soup;
74
+ }
75
+
76
+ /** Upper hemisphere cap (intrinsic positive curvature -> MUST distort under any flattening). */
77
+ export function soup_hemisphere(rings, sectors) {
78
+ const soup = [];
79
+ const north = [0, 1, 0];
80
+ const pos = (i, s) => {
81
+ const phi = (i / rings) * (Math.PI / 2), th = (s / sectors) * 2 * Math.PI;
82
+ return [Math.sin(phi) * Math.cos(th), Math.cos(phi), Math.sin(phi) * Math.sin(th)];
83
+ };
84
+ const vtx = (i, s) => (i === 0 ? north : pos(i, s));
85
+ for (let i = 0; i < rings; i++) for (let s = 0; s < sectors; s++) {
86
+ pushQuad(soup, vtx(i, s), vtx(i + 1, s), vtx(i + 1, s + 1), vtx(i, s + 1));
87
+ }
88
+ return soup;
89
+ }
90
+
91
+ /** Open cylinder side (no caps): a DEVELOPABLE surface — should flatten to a flat strip with ~zero stretch. */
92
+ export function soup_cylinder_open(radial, rings, height, radius) {
93
+ const soup = [];
94
+ const v = (i, s) => {
95
+ const y = -height / 2 + (i / rings) * height, th = (s / radial) * 2 * Math.PI;
96
+ return [radius * Math.cos(th), y, radius * Math.sin(th)];
97
+ };
98
+ for (let i = 0; i < rings; i++) for (let s = 0; s < radial; s++) pushQuad(soup, v(i, s), v(i + 1, s), v(i + 1, s + 1), v(i, s + 1));
99
+ return soup;
100
+ }
101
+
102
+ /** Open cone side (no base): DEVELOPABLE — flattens to a circular sector with ~zero stretch. */
103
+ export function soup_cone_open(radial, rings, height, radius) {
104
+ const soup = [];
105
+ const apex = [0, height, 0];
106
+ const v = (i, s) => {
107
+ const t = i / rings, th = (s / radial) * 2 * Math.PI;
108
+ return [t * radius * Math.cos(th), (1 - t) * height, t * radius * Math.sin(th)];
109
+ };
110
+ const vtx = (i, s) => (i === 0 ? apex : v(i, s));
111
+ for (let i = 0; i < rings; i++) for (let s = 0; s < radial; s++) pushQuad(soup, vtx(i, s), vtx(i + 1, s), vtx(i + 1, s + 1), vtx(i, s + 1));
112
+ return soup;
113
+ }
114
+
115
+ /** Torus: irregular, curved charts (a packing stress fixture). */
116
+ export function soup_torus(rings, sides, R, rr) {
117
+ const soup = [];
118
+ const v = (i, j) => {
119
+ const u = (i / rings) * 2 * Math.PI, w = (j / sides) * 2 * Math.PI;
120
+ const cx = R + rr * Math.cos(w);
121
+ return [cx * Math.cos(u), rr * Math.sin(w), cx * Math.sin(u)];
122
+ };
123
+ for (let i = 0; i < rings; i++) for (let j = 0; j < sides; j++) pushQuad(soup, v(i, j), v(i + 1, j), v(i + 1, j + 1), v(i, j + 1));
124
+ return soup;
125
+ }
126
+
127
+ /** Grid of unit cubes (each cube => 6 charts at 90°; a chart-count fixture). */
128
+ export function soup_cube_field(count) {
129
+ const soup = [];
130
+ const corners = [[0, 0, 0], [1, 0, 0], [1, 1, 0], [0, 1, 0], [0, 0, 1], [1, 0, 1], [1, 1, 1], [0, 1, 1]];
131
+ const quads = [[0, 1, 5, 4], [1, 2, 6, 5], [2, 3, 7, 6], [3, 0, 4, 7], [3, 2, 1, 0], [4, 5, 6, 7]];
132
+ const side = Math.ceil(Math.cbrt(count));
133
+ for (let n = 0; n < count; n++) {
134
+ const ox = (n % side) * 2, oy = (Math.floor(n / side) % side) * 2, oz = Math.floor(n / (side * side)) * 2;
135
+ const c = corners.map((p) => [ox + p[0], oy + p[1], oz + p[2]]);
136
+ for (const q of quads) pushQuad(soup, c[q[0]], c[q[1]], c[q[2]], c[q[3]]);
137
+ }
138
+ return soup;
139
+ }
140
+
141
+ export function build_mesh(soup) {
142
+ const mesh = new BinaryTopology();
143
+ bt_mesh_from_unindexed_geometry(mesh, soup);
144
+ return mesh;
145
+ }
146
+
147
+ function topology_to_soup(mesh) {
148
+ const soup = [];
149
+ const a = [0, 0, 0];
150
+ const faces = mesh.faces;
151
+ for (let f = 0; f < faces.size; f++) {
152
+ if (!faces.is_allocated(f)) continue;
153
+ let l = mesh.face_read_loop(f);
154
+ const start = l;
155
+ const verts = [];
156
+ do {
157
+ mesh.vertex_read_coordinate(a, 0, mesh.loop_read_vertex(l));
158
+ verts.push(a[0], a[1], a[2]);
159
+ l = mesh.loop_read_next(l);
160
+ } while (l !== start);
161
+ if (verts.length === 9) soup.push(...verts);
162
+ }
163
+ return soup;
164
+ }
165
+
166
+ // ─── Metrics ─────────────────────────────────────────────────────────────────
167
+ /** Charts whose worst (L∞) per-triangle stretch exceeds this count as the "high-distortion tail". */
168
+ export const TAIL_STRETCH = 2.0;
169
+
170
+ function percentile(sorted, p) {
171
+ if (sorted.length === 0) return 0;
172
+ return sorted[Math.min(sorted.length - 1, Math.floor(p * sorted.length))];
173
+ }
174
+
175
+ /**
176
+ * Per-run chart-quality metrics. `charts` are finalized charts (each with
177
+ * `surface_area`, `parametric_area`, `type`, and solved `uv`).
178
+ *
179
+ * @param {Chart[]} charts
180
+ * @returns {object} chart_count, ortho/lscm/piecewise counts, area-weighted
181
+ * mean_stretch, max_stretch, p50/p90/p99 of per-chart worst stretch,
182
+ * tail_count + tail_area_frac (charts above TAIL_STRETCH), degenerate count.
183
+ */
184
+ export function chart_metrics(charts) {
185
+ let total_area = 0, weighted_mean_sum = 0, max_stretch = 0, degenerate = 0;
186
+ let tail_count = 0, tail_area = 0;
187
+ const per_chart_max = [];
188
+ const types = { ortho: 0, lscm: 0, piecewise: 0, bff: 0 };
189
+
190
+ for (const c of charts) {
191
+ if (c.type === CHART_TYPE.ORTHO) types.ortho++;
192
+ else if (c.type === CHART_TYPE.LSCM) types.lscm++;
193
+ else if (c.type === CHART_TYPE.PIECEWISE) types.piecewise++;
194
+ else if (c.type === CHART_TYPE.BFF) types.bff++;
195
+
196
+ const m = atlas_chart_stretch_metric(c);
197
+ if (!Number.isFinite(m.mean_stretch) || !Number.isFinite(m.max_stretch)) {
198
+ degenerate++;
199
+ continue;
200
+ }
201
+ const area = c.surface_area;
202
+ total_area += area;
203
+ weighted_mean_sum += m.mean_stretch * area;
204
+ per_chart_max.push(m.max_stretch);
205
+ if (m.max_stretch > max_stretch) max_stretch = m.max_stretch;
206
+ if (m.max_stretch > TAIL_STRETCH) { tail_count++; tail_area += area; }
207
+ }
208
+
209
+ per_chart_max.sort((a, b) => a - b);
210
+ return {
211
+ chart_count: charts.length,
212
+ types,
213
+ mean_stretch: total_area > 0 ? weighted_mean_sum / total_area : 0,
214
+ max_stretch,
215
+ p50_stretch: percentile(per_chart_max, 0.5),
216
+ p90_stretch: percentile(per_chart_max, 0.9),
217
+ p99_stretch: percentile(per_chart_max, 0.99),
218
+ tail_count,
219
+ tail_area_frac: total_area > 0 ? tail_area / total_area : 0,
220
+ degenerate,
221
+ };
222
+ }
223
+
224
+ /** Total 3D length of edges cut between different charts (texture seams) + fraction of interior length. */
225
+ export function seam_metrics(mesh, charts) {
226
+ const face_chart = new Int32Array(mesh.faces.size).fill(-1);
227
+ for (let ci = 0; ci < charts.length; ci++) {
228
+ const c = charts[ci];
229
+ for (let t = 0; t < c.triangle_count; t++) face_chart[c.tri_face[t]] = ci;
230
+ }
231
+ const v1 = [0, 0, 0], v2 = [0, 0, 0];
232
+ let seam_len = 0, interior_len = 0;
233
+ const edges = mesh.edges;
234
+ for (let e = 0; e < edges.size; e++) {
235
+ if (!edges.is_allocated(e)) continue;
236
+ const l1 = mesh.edge_read_loop(e);
237
+ if (l1 === NULL_POINTER) continue;
238
+ const l2 = mesh.loop_read_radial_next(l1);
239
+ if (l2 === l1) continue; // boundary edge, not a cut
240
+ mesh.vertex_read_coordinate(v1, 0, mesh.edge_read_vertex1(e));
241
+ mesh.vertex_read_coordinate(v2, 0, mesh.edge_read_vertex2(e));
242
+ const len = Math.hypot(v1[0] - v2[0], v1[1] - v2[1], v1[2] - v2[2]);
243
+ interior_len += len;
244
+ if (face_chart[mesh.loop_read_face(l1)] !== face_chart[mesh.loop_read_face(l2)]) seam_len += len;
245
+ }
246
+ return { seam_len, seam_pct: interior_len > 0 ? (seam_len / interior_len) * 100 : 0, interior_len };
247
+ }
248
+
249
+ // ─── Pipeline + A/B runner ───────────────────────────────────────────────────
250
+ /**
251
+ * Run the full pipeline once and return the metric panel. Always rebuilds the
252
+ * mesh from the soup so packing-only A/Bs are independent (pack mutates uv).
253
+ *
254
+ * @param {number[]} soup triangle soup
255
+ * @param {object} [computeOpts] atlas_compute_charts options
256
+ * @param {object} [packOpts] atlas_pack_charts options
257
+ * @returns {object} flattened metric panel
258
+ */
259
+ export function measure(soup, computeOpts = {}, packOpts = {}) {
260
+ const mesh = build_mesh(soup);
261
+ const computed = atlas_compute_charts(mesh, computeOpts);
262
+ const packed = atlas_pack_charts(computed.charts, packOpts);
263
+ const cm = chart_metrics(computed.charts);
264
+ const sm = seam_metrics(mesh, computed.charts);
265
+ return {
266
+ ...cm,
267
+ seam_len: sm.seam_len,
268
+ seam_pct: sm.seam_pct,
269
+ utilization: packed.utilization,
270
+ pages: packed.page_count,
271
+ atlas: `${packed.atlas_width}x${packed.atlas_height}`,
272
+ };
273
+ }
274
+
275
+ /** Median wall-clock of `fn` over a time budget, with warmup. */
276
+ export function time_median(fn, budget_ms = 2000, warmup = 2) {
277
+ for (let i = 0; i < warmup; i++) fn();
278
+ const samples = [];
279
+ const start = performance.now();
280
+ while (performance.now() - start < budget_ms) {
281
+ const t0 = performance.now();
282
+ fn();
283
+ samples.push(performance.now() - t0);
284
+ }
285
+ samples.sort((a, b) => a - b);
286
+ return percentile(samples, 0.5);
287
+ }
288
+
289
+ /**
290
+ * A/B: measure baseline vs candidate on the same fixture and return both panels
291
+ * plus per-key deltas. The caller asserts the expected direction (the gate).
292
+ *
293
+ * @param {number[]} soup
294
+ * @param {{compute?:object, pack?:object}} a baseline options
295
+ * @param {{compute?:object, pack?:object}} b candidate options
296
+ * @returns {{base:object, cand:object, delta:object}}
297
+ */
298
+ export function ab(soup, a, b) {
299
+ const base = measure(soup, a.compute, a.pack);
300
+ const cand = measure(soup, b.compute, b.pack);
301
+ const delta = {};
302
+ for (const k of ["chart_count", "mean_stretch", "max_stretch", "p90_stretch", "p99_stretch", "tail_count", "tail_area_frac", "seam_len", "seam_pct", "utilization"]) {
303
+ delta[k] = cand[k] - base[k];
304
+ }
305
+ return { base, cand, delta };
306
+ }
307
+
308
+ /** Compact one-line metric panel for console output. */
309
+ export function fmt(m) {
310
+ return `charts ${m.chart_count} (O${m.types.ortho}/L${m.types.lscm}/P${m.types.piecewise}/B${m.types.bff})` +
311
+ ` stretch mean ${m.mean_stretch.toFixed(3)} max ${m.max_stretch.toFixed(1)} p90 ${m.p90_stretch.toFixed(2)} p99 ${m.p99_stretch.toFixed(2)}` +
312
+ ` tail ${m.tail_count} (${(m.tail_area_frac * 100).toFixed(1)}% area)` +
313
+ ` seam ${m.seam_len.toFixed(2)} (${m.seam_pct.toFixed(1)}%)` +
314
+ ` util ${(m.utilization * 100).toFixed(1)}% ${m.atlas} x${m.pages}`;
315
+ }
@@ -0,0 +1,17 @@
1
+ /**
2
+ * How a chart's UVs were produced. Typed constant (no stringly-typed states),
3
+ * mirroring xatlas `ChartType`.
4
+ * @readonly
5
+ */
6
+ export const CHART_TYPE: Readonly<{
7
+ /** Orthographic projection accepted (planar or near-planar). */
8
+ ORTHO: 0;
9
+ /** Least-squares conformal map. */
10
+ LSCM: 1;
11
+ /** Single-triangle fallback after ortho and LSCM both failed validity. */
12
+ PIECEWISE: 2;
13
+ /** Boundary-first flattening: intrinsic low-distortion boundary + conformal
14
+ * interior, the rescue for a chart whose LSCM free boundary self-intersects. */
15
+ BFF: 3;
16
+ }>;
17
+ //# sourceMappingURL=atlas_chart_type.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"atlas_chart_type.d.ts","sourceRoot":"","sources":["../../../../../../src/core/geom/3d/atlas/atlas_chart_type.js"],"names":[],"mappings":"AAAA;;;;GAIG;AACH;IACI,gEAAgE;;IAEhE,mCAAmC;;IAEnC,0EAA0E;;IAE1E;qFACiF;;GAElF"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * How a chart's UVs were produced. Typed constant (no stringly-typed states),
3
+ * mirroring xatlas `ChartType`.
4
+ * @readonly
5
+ */
6
+ export const CHART_TYPE = Object.freeze({
7
+ /** Orthographic projection accepted (planar or near-planar). */
8
+ ORTHO: 0,
9
+ /** Least-squares conformal map. */
10
+ LSCM: 1,
11
+ /** Single-triangle fallback after ortho and LSCM both failed validity. */
12
+ PIECEWISE: 2,
13
+ /** Boundary-first flattening: intrinsic low-distortion boundary + conformal
14
+ * interior, the rescue for a chart whose LSCM free boundary self-intersects. */
15
+ BFF: 3,
16
+ });
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Compute UV charts for a mesh (xatlas `ComputeCharts`): condition the mesh,
3
+ * segment it, and parameterize each chart. The returned charts carry their own
4
+ * vertex/triangle tables and per-chart UVs (local, unpacked) in `chart.uv`, ready
5
+ * for {@link atlas_pack_charts}. UVs are NOT written onto the mesh here — that is
6
+ * the explicit {@link atlas_write_chart_uvs} step (kept separate so charts from
7
+ * several meshes can be packed together before being actualized).
8
+ *
9
+ * @param {BinaryTopology} mesh mutated in place (welding, normals) but not its loop UVs
10
+ * @param {object} [options]
11
+ * @param {boolean} [options.weld] colocal-weld the input first (default true)
12
+ * @param {object} [options.segment] overrides for atlas_segment_charts
13
+ * @param {object} [options.lscm] overrides for atlas_chart_parameterize_lscm
14
+ * @returns {{charts: Chart[], face_chart: Int32Array, chart_count: number}}
15
+ */
16
+ export function atlas_compute_charts(mesh: BinaryTopology, options?: {
17
+ weld?: boolean;
18
+ segment?: object;
19
+ lscm?: object;
20
+ }): {
21
+ charts: Chart[];
22
+ face_chart: Int32Array;
23
+ chart_count: number;
24
+ };
25
+ //# sourceMappingURL=atlas_compute_charts.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"atlas_compute_charts.d.ts","sourceRoot":"","sources":["../../../../../../src/core/geom/3d/atlas/atlas_compute_charts.js"],"names":[],"mappings":"AAiHA;;;;;;;;;;;;;;GAcG;AACH;IAL6B,IAAI,GAAtB,OAAO;IACU,OAAO,GAAxB,MAAM;IACW,IAAI,GAArB,MAAM;;YACK,OAAO;gBAAc,UAAU;iBAAe,MAAM;EA6DzE"}
@@ -0,0 +1,188 @@
1
+ import { bt_mesh_compute_face_normals } from "../topology/struct/binary/io/bt_mesh_compute_face_normals.js";
2
+ import { CHART_TYPE } from "./atlas_chart_type.js";
3
+ import { atlas_extract_chart } from "./atlas_extract_chart.js";
4
+ import { atlas_build_edge_dihedrals } from "./data/atlas_build_edge_dihedrals.js";
5
+ import { atlas_build_edge_lengths } from "./data/atlas_build_edge_lengths.js";
6
+ import { atlas_build_face_areas } from "./data/atlas_build_face_areas.js";
7
+ import { atlas_mesh_weld_colocals } from "./io/atlas_mesh_weld_colocals.js";
8
+ import { atlas_chart_param_validity } from "./param/atlas_chart_param_validity.js";
9
+ import { atlas_chart_parameterize_bff } from "./param/atlas_chart_parameterize_bff.js";
10
+ import { atlas_chart_parameterize_lscm } from "./param/atlas_chart_parameterize_lscm.js";
11
+ import { atlas_chart_parameterize_ortho } from "./param/atlas_chart_parameterize_ortho.js";
12
+ import { atlas_chart_stretch_metric } from "./param/atlas_chart_stretch_metric.js";
13
+ import { atlas_piecewise_resegment } from "./param/atlas_piecewise_resegment.js";
14
+ import { atlas_build_region_graph } from "./segment/atlas_build_region_graph.js";
15
+ import { atlas_compute_planar_regions } from "./segment/atlas_compute_planar_regions.js";
16
+ import { atlas_merge_charts } from "./segment/atlas_merge_charts.js";
17
+ import { atlas_segment_charts } from "./segment/atlas_segment_charts.js";
18
+ import { atlas_segment_charts_atomic } from "./segment/atlas_segment_charts_atomic.js";
19
+
20
+ /** Ortho is accepted only below these stretch bounds (xatlas thresholds). */
21
+ const ORTHO_MEAN_STRETCH_MAX = 1.1;
22
+ const ORTHO_MAX_STRETCH_MAX = 1.25;
23
+
24
+ /** The BFF rescue keeps a chart whole instead of exploding it into piecewise pieces,
25
+ * accepted only when its whole-chart map is near-isometric in the mean — bounded
26
+ * just above the ortho mean gate (measured rescues are ~1.0). This bounds AVERAGE
27
+ * distortion, not the worst triangle or shape compactness, so it is a chart-COUNT
28
+ * win at comparable mean stretch, not a strict per-metric improvement; charts above
29
+ * the bound fall through to piecewise's compact, individually ortho-valid pieces.
30
+ * Measured net effect is Pareto-positive (decimated terrain: −6 charts, mean and
31
+ * p99 stretch both down). */
32
+ const BFF_MAX_MEAN_STRETCH = 1.25;
33
+
34
+ /**
35
+ * Whether a parameterization validity report describes a bijective (no-overlap,
36
+ * consistent-winding) UV map: no flipped triangles, no self-intersection, no
37
+ * degenerate (zero-area) UV triangles.
38
+ *
39
+ * @param {{mixed_winding: boolean, self_intersects: boolean, zero_area_count: number}} validity from atlas_chart_param_validity
40
+ * @returns {boolean}
41
+ */
42
+ function is_bijective(validity) {
43
+ return !validity.mixed_winding && !validity.self_intersects && validity.zero_area_count === 0;
44
+ }
45
+
46
+ /**
47
+ * Finalize a chart: record its type and 3D/UV areas, then append.
48
+ *
49
+ * @param {Chart} chart the chart from {@link atlas_extract_chart}, with solved UVs
50
+ * @param {number} type one of {@link CHART_TYPE}
51
+ * @param {Chart[]} out finished charts accumulator, appended to
52
+ */
53
+ function finalize(chart, type, out) {
54
+ const s = atlas_chart_stretch_metric(chart);
55
+ chart.type = type;
56
+ chart.surface_area = s.geom_area;
57
+ chart.parametric_area = s.param_area;
58
+ out.push(chart);
59
+ }
60
+
61
+ /**
62
+ * Parameterize one segmentation chart, appending one or more finished charts to
63
+ * `out`: orthographic if it passes the stretch gate, otherwise LSCM if the
64
+ * chart has a boundary, otherwise region-grow piecewise re-segmentation into
65
+ * connected, ortho-valid sub-charts.
66
+ *
67
+ * @param {Chart} chart the chart from {@link atlas_extract_chart}; its `uv` is solved in place
68
+ * @param {object} [lscm_options] overrides for {@link atlas_chart_parameterize_lscm}
69
+ * @param {Chart[]} out finished charts accumulator, appended to
70
+ */
71
+ function parameterize_chart(chart, lscm_options, out) {
72
+ atlas_chart_parameterize_ortho(chart);
73
+ const ortho_validity = atlas_chart_param_validity(chart);
74
+ const ortho_stretch = atlas_chart_stretch_metric(chart);
75
+
76
+ if (
77
+ is_bijective(ortho_validity) &&
78
+ ortho_stretch.mean_stretch <= ORTHO_MEAN_STRETCH_MAX &&
79
+ ortho_stretch.max_stretch <= ORTHO_MAX_STRETCH_MAX
80
+ ) {
81
+ finalize(chart, CHART_TYPE.ORTHO, out);
82
+ return;
83
+ }
84
+
85
+ if (atlas_chart_parameterize_lscm(chart, lscm_options)) {
86
+ if (is_bijective(atlas_chart_param_validity(chart))) {
87
+ finalize(chart, CHART_TYPE.LSCM, out);
88
+ return;
89
+ }
90
+ }
91
+
92
+ // Rescue a disk chart whose LSCM free boundary self-intersected by flattening
93
+ // it whole with boundary-first flattening (BFF), instead of exploding it into
94
+ // piecewise sub-charts — but only when the result is bijective AND near
95
+ // isometric (else piecewise's compact pieces are the better outcome). BFF runs
96
+ // only on charts that already failed ortho and LSCM, so it is free on clean
97
+ // meshes (no chart reaches here) and ~0 cost where LSCM was already failing.
98
+ if (atlas_chart_parameterize_bff(chart, lscm_options)) {
99
+ if (
100
+ is_bijective(atlas_chart_param_validity(chart)) &&
101
+ atlas_chart_stretch_metric(chart).mean_stretch <= BFF_MAX_MEAN_STRETCH
102
+ ) {
103
+ finalize(chart, CHART_TYPE.BFF, out);
104
+ return;
105
+ }
106
+ }
107
+
108
+ // Fallback: region-grow into connected, ortho-valid sub-charts.
109
+ for (const piece of atlas_piecewise_resegment(chart)) {
110
+ finalize(piece, CHART_TYPE.PIECEWISE, out);
111
+ }
112
+ }
113
+
114
+ /**
115
+ * Compute UV charts for a mesh (xatlas `ComputeCharts`): condition the mesh,
116
+ * segment it, and parameterize each chart. The returned charts carry their own
117
+ * vertex/triangle tables and per-chart UVs (local, unpacked) in `chart.uv`, ready
118
+ * for {@link atlas_pack_charts}. UVs are NOT written onto the mesh here — that is
119
+ * the explicit {@link atlas_write_chart_uvs} step (kept separate so charts from
120
+ * several meshes can be packed together before being actualized).
121
+ *
122
+ * @param {BinaryTopology} mesh mutated in place (welding, normals) but not its loop UVs
123
+ * @param {object} [options]
124
+ * @param {boolean} [options.weld] colocal-weld the input first (default true)
125
+ * @param {object} [options.segment] overrides for atlas_segment_charts
126
+ * @param {object} [options.lscm] overrides for atlas_chart_parameterize_lscm
127
+ * @returns {{charts: Chart[], face_chart: Int32Array, chart_count: number}}
128
+ */
129
+ export function atlas_compute_charts(mesh, options = {}) {
130
+ const weld = options.weld ?? true;
131
+
132
+ if (weld) {
133
+ atlas_mesh_weld_colocals(mesh);
134
+ }
135
+
136
+ bt_mesh_compute_face_normals(mesh);
137
+
138
+ const face_areas = atlas_build_face_areas(mesh);
139
+ const edge_lengths = atlas_build_edge_lengths(mesh);
140
+ const edge_dihedrals = atlas_build_edge_dihedrals(mesh);
141
+
142
+ // Region-atomic segmentation (default) grows whole coplanar regions as
143
+ // units; set options.segment.atomic = false for the face-granular twin.
144
+ const atomic = options.segment?.atomic ?? true;
145
+ let segmentation;
146
+ if (atomic) {
147
+ const regions = atlas_compute_planar_regions(mesh, edge_dihedrals);
148
+ const region_graph = atlas_build_region_graph(
149
+ mesh, regions.region_of_face, regions.region_count, face_areas, edge_lengths, edge_dihedrals
150
+ );
151
+ segmentation = atlas_segment_charts_atomic(region_graph, regions.region_of_face, options.segment);
152
+ } else {
153
+ segmentation = atlas_segment_charts(mesh, face_areas, edge_lengths, edge_dihedrals, options.segment);
154
+ }
155
+
156
+ let face_chart = segmentation.face_chart;
157
+ let chart_count = segmentation.chart_count;
158
+
159
+ // Optional: merge adjacent near-coplanar charts (xatlas mergeCharts) to undo
160
+ // over-segmentation from the greedy growth. Off by default; the merged charts
161
+ // are re-extracted + re-parameterized below.
162
+ if (options.segment?.merge) {
163
+ const merged = atlas_merge_charts(mesh, face_chart, chart_count, face_areas, options.segment);
164
+ face_chart = merged.face_chart;
165
+ chart_count = merged.chart_count;
166
+ }
167
+
168
+ // Bucket faces by chart in one pass so each extraction touches only its own
169
+ // faces, instead of re-scanning every face once per chart (O(charts × faces)).
170
+ const chart_faces = [];
171
+ for (let c = 0; c < chart_count; c++) {
172
+ chart_faces.push([]);
173
+ }
174
+ const faces = mesh.faces;
175
+ for (let f = 0; f < faces.size; f++) {
176
+ if (!faces.is_allocated(f)) continue;
177
+ const c = face_chart[f];
178
+ if (c >= 0) chart_faces[c].push(f);
179
+ }
180
+
181
+ const charts = [];
182
+ for (let c = 0; c < chart_count; c++) {
183
+ const chart = atlas_extract_chart(mesh, face_chart, c, chart_faces[c]);
184
+ parameterize_chart(chart, options.lscm, charts);
185
+ }
186
+
187
+ return { charts, face_chart, chart_count };
188
+ }
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Extract a single chart from a segmented mesh into a {@link Chart} for
3
+ * parameterization and packing (xatlas chart construction). `boundary_edges` is
4
+ * flat pairs of chart-local vertex indices forming the chart outline; `uv` is
5
+ * zero-filled for the solver.
6
+ *
7
+ * @param {BinaryTopology} mesh
8
+ * @param {Int32Array} face_chart from atlas_segment_charts (face -> chart id, -1 if none)
9
+ * @param {number} chart_id
10
+ * @param {number[]} [face_list] the chart's face ids; when omitted they are found
11
+ * by scanning the whole mesh. The multi-chart driver precomputes one bucket per
12
+ * chart so it does not re-scan all faces once per chart (O(charts × faces)).
13
+ * @returns {Chart}
14
+ */
15
+ export function atlas_extract_chart(mesh: BinaryTopology, face_chart: Int32Array, chart_id: number, face_list?: number[]): Chart;
16
+ import { Chart } from "./Chart.js";
17
+ //# sourceMappingURL=atlas_extract_chart.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"atlas_extract_chart.d.ts","sourceRoot":"","sources":["../../../../../../src/core/geom/3d/atlas/atlas_extract_chart.js"],"names":[],"mappings":"AAWA;;;;;;;;;;;;;GAaG;AACH,sEAPW,UAAU,YACV,MAAM,cACN,MAAM,EAAE,GAGN,KAAK,CAmFjB;sBA1GqB,YAAY"}