@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,168 @@
1
+ import { rgb_to_luminance } from "../../../../core/color/rgb_to_luminance.js";
2
+ import { Ray3 } from "../../../../core/geom/3d/ray/Ray3.js";
3
+ import { ray3_compose_array } from "../../../../core/geom/3d/ray/ray3_compose_array.js";
4
+ import { v3_dot } from "../../../../core/geom/vec3/v3_dot.js";
5
+ import { v3_matrix3_rotate } from "../../../../core/geom/vec3/v3_matrix3_rotate.js";
6
+ import { v3_orthonormal_matrix_from_normal } from "../../../../core/geom/vec3/v3_orthonormal_matrix_from_normal.js";
7
+ import { getBiasedNormalSample } from "../path_tracer/sampling/getBiasedNormalSample.js";
8
+
9
+ const _ray = new Ray3();
10
+ const _normal = new Float32Array(3);
11
+ const _dir = new Float32Array(3);
12
+ const _radiance = new Float32Array(3);
13
+ const _hit = new Float32Array(16);
14
+ const _basis = new Float32Array(9);
15
+ const _tangent = new Float32Array(3);
16
+ const _bitangent = new Float32Array(3);
17
+
18
+ /**
19
+ * Estimate the lightmap value at a single surface point in **mixed mode**: the
20
+ * cosine-weighted average incoming radiance — indirect bounces + sky only (direct
21
+ * light is supplied at render time by the realtime lights, not baked).
22
+ *
23
+ * Reuses {@link PathTracer#path_trace} along cosine-weighted hemisphere directions
24
+ * ({@link getBiasedNormalSample}, power 1) — bounced light, emissive surfaces, and
25
+ * the environment. Each texel draws its own independent random directions (no fixed
26
+ * sample set is shared between texels, which would otherwise show as structured
27
+ * bias on flat surfaces).
28
+ *
29
+ * **Supersampling:** each sample's ray ORIGIN is jittered within the texel's world
30
+ * footprint (in the surface tangent plane, magnitude `cfg.supersample × texel`), so
31
+ * a texel straddling a shadow boundary or silhouette averages lit/occluded
32
+ * sub-positions into a soft gradient instead of a hard one-texel line.
33
+ *
34
+ * Also produces two auxiliary signals used by the baker:
35
+ * - the **variance of the mean** (luminance), written to `out[3]`, which drives
36
+ * the variance-guided denoiser;
37
+ * - a **confidence** in [0,1] (the return value): `1 - (fraction of short probes
38
+ * that hit a BACK face)`. Flags only buried/wrong-side points; an enclosed-room
39
+ * floor (front faces all around) stays confident. `cfg.confidence_probes === 0`
40
+ * disables it (confidence 1).
41
+ *
42
+ * The stored radiance is `E / π` (cosine-weighted mean); three.js's lightmap path
43
+ * multiplies it back by `π · albedo / π = albedo`, preserving surface colour.
44
+ *
45
+ * @param {Float32Array|number[]} out 4 channels written: linear r, g, b, luminance variance-of-mean
46
+ * @param {number} px world-space point x (already nudged off the surface)
47
+ * @param {number} py world-space point y
48
+ * @param {number} pz world-space point z
49
+ * @param {number} nx world-space surface normal x (unit)
50
+ * @param {number} ny world-space surface normal y
51
+ * @param {number} nz world-space surface normal z
52
+ * @param {number} texel_world_size world-space size of one lightmap texel at this point
53
+ * @param {PathTracedScene} scene
54
+ * @param {PathTracer} path_tracer
55
+ * @param {{samples:number, max_samples:number, variance_target:number, min_bounce:number, max_bounce:number, confidence_probes:number, inside_probe_texels:number, supersample:number}} cfg
56
+ * `samples` is the minimum count; sampling continues up to `max_samples` while the
57
+ * relative variance-of-mean exceeds `variance_target` (0 = fixed `samples`).
58
+ * @param {function():number} random
59
+ * @returns {number} confidence in [0,1]
60
+ */
61
+ export function lightmap_gather(
62
+ out,
63
+ px, py, pz,
64
+ nx, ny, nz,
65
+ texel_world_size,
66
+ scene,
67
+ path_tracer,
68
+ cfg,
69
+ random
70
+ ) {
71
+ _normal[0] = nx;
72
+ _normal[1] = ny;
73
+ _normal[2] = nz;
74
+
75
+ const min_samples = cfg.samples;
76
+ const max_samples = Math.max(min_samples, cfg.max_samples ?? min_samples);
77
+ const variance_target = cfg.variance_target ?? 0; // relative var-of-mean target; 0 = fixed count
78
+ const min_bounce = cfg.min_bounce;
79
+ const max_bounce = cfg.max_bounce;
80
+
81
+ // surface tangent frame for sub-texel origin jitter (supersampling)
82
+ const jitter = (cfg.supersample ?? 0) * texel_world_size;
83
+ if (jitter > 0) {
84
+ v3_orthonormal_matrix_from_normal(_basis, 0, nx, ny, nz);
85
+ v3_matrix3_rotate(_tangent, 0, 1, 0, 0, _basis);
86
+ v3_matrix3_rotate(_bitangent, 0, 0, 1, 0, _basis);
87
+ }
88
+
89
+ let r = 0;
90
+ let g = 0;
91
+ let b = 0;
92
+ let lum_sum = 0;
93
+ let lum_sum_sq = 0;
94
+
95
+ // Variance-adaptive sampling: take at least `min_samples`, then keep going
96
+ // while the relative noise of the mean is still above target, up to
97
+ // `max_samples`. Noisy regions (contacts, occlusion edges, high-frequency
98
+ // bounce) naturally draw more samples; smooth sky-lit areas stop early.
99
+ let n = 0;
100
+ let variance_of_mean = 0;
101
+ while (n < max_samples) {
102
+ let ox = px;
103
+ let oy = py;
104
+ let oz = pz;
105
+
106
+ if (jitter > 0) {
107
+ const ju = (random() - 0.5) * jitter;
108
+ const jv = (random() - 0.5) * jitter;
109
+ ox += _tangent[0] * ju + _bitangent[0] * jv;
110
+ oy += _tangent[1] * ju + _bitangent[1] * jv;
111
+ oz += _tangent[2] * ju + _bitangent[2] * jv;
112
+ }
113
+
114
+ // cosine-weighted hemisphere direction around the surface normal
115
+ getBiasedNormalSample(_dir, 0, _normal, 0, 1, random);
116
+
117
+ ray3_compose_array(_ray, ox, oy, oz, _dir[0], _dir[1], _dir[2]);
118
+ _ray.tMax = Infinity;
119
+
120
+ path_tracer.path_trace(_radiance, _ray, min_bounce, max_bounce, random, scene);
121
+
122
+ r += _radiance[0];
123
+ g += _radiance[1];
124
+ b += _radiance[2];
125
+
126
+ const lum = rgb_to_luminance(_radiance[0], _radiance[1], _radiance[2]);
127
+ lum_sum += lum;
128
+ lum_sum_sq += lum * lum;
129
+ n++;
130
+
131
+ if (n >= min_samples) {
132
+ const mean = lum_sum / n;
133
+ // unbiased variance-of-the-mean: (sample variance)/n = popVar/(n-1).
134
+ // (n > 1 always holds here: min_samples >= 4 in every config.)
135
+ const pop_var = Math.max(0, lum_sum_sq / n - mean * mean);
136
+ variance_of_mean = n > 1 ? pop_var / (n - 1) : 0;
137
+ if (variance_target > 0 && variance_of_mean <= variance_target * (mean * mean + 1e-8)) {
138
+ break; // relative noise low enough
139
+ }
140
+ }
141
+ }
142
+
143
+ const inv = 1 / n;
144
+ out[0] = r * inv;
145
+ out[1] = g * inv;
146
+ out[2] = b * inv;
147
+ out[3] = variance_of_mean;
148
+
149
+ // geometric confidence: is the sample point buried (on the wrong side of
150
+ // nearby geometry)? Count short probes whose first hit is a BACK face.
151
+ const probes = cfg.confidence_probes;
152
+ if (probes <= 0) {
153
+ return 1;
154
+ }
155
+
156
+ const inside_distance = cfg.inside_probe_texels * texel_world_size;
157
+ let backface = 0;
158
+ for (let p = 0; p < probes; p++) {
159
+ getBiasedNormalSample(_dir, 0, _normal, 0, 1, random);
160
+ ray3_compose_array(_ray, px, py, pz, _dir[0], _dir[1], _dir[2]);
161
+ _ray.tMax = inside_distance;
162
+ if (scene.trace(_hit, _ray) >= 0 && v3_dot(_hit[3], _hit[4], _hit[5], _dir[0], _dir[1], _dir[2]) > 0) {
163
+ backface++;
164
+ }
165
+ }
166
+
167
+ return 1 - backface / probes;
168
+ }
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Rasterize a 2D triangle in integer pixel space, invoking `callback` once per
3
+ * covered texel with the barycentric weights of the three vertices (A, B, C) at
4
+ * the sampled point. The weights are an exact partition of unity (`wA+wB+wC===1`,
5
+ * all `>=0`), so a caller can interpolate any per-vertex attribute directly.
6
+ *
7
+ * Default (center) mode: a texel is covered iff its CENTER lies inside the
8
+ * triangle, sampled at that center.
9
+ *
10
+ * Conservative mode (`conservative === true`): a texel is also covered if its
11
+ * cell overlaps the triangle even though its center is outside (thin features,
12
+ * chart borders). For those, the sample is **clamped to the closest point on the
13
+ * triangle** so the interpolated position/normal stays on the surface — avoiding
14
+ * the dropped-edge-texel black gutters of center-only coverage.
15
+ *
16
+ * Degenerate (zero-area) triangles produce no callbacks.
17
+ *
18
+ * @param {number} ax vertex A x, in pixels
19
+ * @param {number} ay vertex A y, in pixels
20
+ * @param {number} bx vertex B x, in pixels
21
+ * @param {number} by vertex B y, in pixels
22
+ * @param {number} cx vertex C x, in pixels
23
+ * @param {number} cy vertex C y, in pixels
24
+ * @param {number} width raster width (texel centers tested in [0, width))
25
+ * @param {number} height raster height (texel centers tested in [0, height))
26
+ * @param {function(px:number, py:number, wA:number, wB:number, wC:number):void} callback
27
+ * @param {boolean} [conservative] include edge-overlapping texels with a clamped sample (default false)
28
+ */
29
+ export function lightmap_rasterize_triangle(ax: number, ay: number, bx: number, by: number, cx: number, cy: number, width: number, height: number, callback: any, conservative?: boolean): void;
30
+ //# sourceMappingURL=lightmap_rasterize_triangle.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lightmap_rasterize_triangle.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/graphics/sh3/lightmap/lightmap_rasterize_triangle.js"],"names":[],"mappings":"AAsDA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,gDAXW,MAAM,MACN,MAAM,MACN,MAAM,MACN,MAAM,MACN,MAAM,MACN,MAAM,SACN,MAAM,UACN,MAAM,gCAEN,OAAO,QAgEjB"}
@@ -0,0 +1,145 @@
1
+ /** Half the diagonal of a unit texel — the conservative overlap reach from a center. */
2
+ const HALF_TEXEL_DIAGONAL = Math.SQRT2 * 0.5;
3
+
4
+ /**
5
+ * Closest point to (px,py) on segment (ax,ay)->(bx,by), written to out[0..1].
6
+ *
7
+ * @param {Float32Array|number[]} out
8
+ * @param {number} px
9
+ * @param {number} py
10
+ * @param {number} ax
11
+ * @param {number} ay
12
+ * @param {number} bx
13
+ * @param {number} by
14
+ */
15
+ function closest_on_segment(out, px, py, ax, ay, bx, by) {
16
+ const ex = bx - ax;
17
+ const ey = by - ay;
18
+ const len2 = ex * ex + ey * ey;
19
+ let t = len2 > 0 ? ((px - ax) * ex + (py - ay) * ey) / len2 : 0;
20
+ if (t < 0) t = 0; else if (t > 1) t = 1;
21
+ out[0] = ax + t * ex;
22
+ out[1] = ay + t * ey;
23
+ }
24
+
25
+ const _q = new Float32Array(2);
26
+ const _e = new Float32Array(2);
27
+
28
+ /**
29
+ * Closest point to (px,py) on the (filled) triangle, written to out[0..1].
30
+ * Assumes the point is outside the triangle (callers test inside first).
31
+ *
32
+ * @param {Float32Array|number[]} out
33
+ */
34
+ function closest_on_triangle(out, px, py, ax, ay, bx, by, cx, cy) {
35
+ let best_d2 = Infinity;
36
+
37
+ closest_on_segment(_e, px, py, ax, ay, bx, by);
38
+ let dx = px - _e[0], dy = py - _e[1];
39
+ let d2 = dx * dx + dy * dy;
40
+ if (d2 < best_d2) { best_d2 = d2; out[0] = _e[0]; out[1] = _e[1]; }
41
+
42
+ closest_on_segment(_e, px, py, bx, by, cx, cy);
43
+ dx = px - _e[0]; dy = py - _e[1];
44
+ d2 = dx * dx + dy * dy;
45
+ if (d2 < best_d2) { best_d2 = d2; out[0] = _e[0]; out[1] = _e[1]; }
46
+
47
+ closest_on_segment(_e, px, py, cx, cy, ax, ay);
48
+ dx = px - _e[0]; dy = py - _e[1];
49
+ d2 = dx * dx + dy * dy;
50
+ if (d2 < best_d2) { best_d2 = d2; out[0] = _e[0]; out[1] = _e[1]; }
51
+
52
+ return Math.sqrt(best_d2);
53
+ }
54
+
55
+ /**
56
+ * Rasterize a 2D triangle in integer pixel space, invoking `callback` once per
57
+ * covered texel with the barycentric weights of the three vertices (A, B, C) at
58
+ * the sampled point. The weights are an exact partition of unity (`wA+wB+wC===1`,
59
+ * all `>=0`), so a caller can interpolate any per-vertex attribute directly.
60
+ *
61
+ * Default (center) mode: a texel is covered iff its CENTER lies inside the
62
+ * triangle, sampled at that center.
63
+ *
64
+ * Conservative mode (`conservative === true`): a texel is also covered if its
65
+ * cell overlaps the triangle even though its center is outside (thin features,
66
+ * chart borders). For those, the sample is **clamped to the closest point on the
67
+ * triangle** so the interpolated position/normal stays on the surface — avoiding
68
+ * the dropped-edge-texel black gutters of center-only coverage.
69
+ *
70
+ * Degenerate (zero-area) triangles produce no callbacks.
71
+ *
72
+ * @param {number} ax vertex A x, in pixels
73
+ * @param {number} ay vertex A y, in pixels
74
+ * @param {number} bx vertex B x, in pixels
75
+ * @param {number} by vertex B y, in pixels
76
+ * @param {number} cx vertex C x, in pixels
77
+ * @param {number} cy vertex C y, in pixels
78
+ * @param {number} width raster width (texel centers tested in [0, width))
79
+ * @param {number} height raster height (texel centers tested in [0, height))
80
+ * @param {function(px:number, py:number, wA:number, wB:number, wC:number):void} callback
81
+ * @param {boolean} [conservative] include edge-overlapping texels with a clamped sample (default false)
82
+ */
83
+ export function lightmap_rasterize_triangle(ax, ay, bx, by, cx, cy, width, height, callback, conservative = false) {
84
+ // conservative mode reaches one extra texel of overlap, so widen the scan box
85
+ const margin = conservative ? 1 : 0;
86
+
87
+ const min_x = Math.max(0, Math.floor(Math.min(ax, bx, cx)) - margin);
88
+ const max_x = Math.min(width - 1, Math.floor(Math.max(ax, bx, cx)) + margin);
89
+ const min_y = Math.max(0, Math.floor(Math.min(ay, by, cy)) - margin);
90
+ const max_y = Math.min(height - 1, Math.floor(Math.max(ay, by, cy)) + margin);
91
+
92
+ const d = (by - cy) * (ax - cx) + (cx - bx) * (ay - cy);
93
+
94
+ if (d === 0) {
95
+ // degenerate triangle, no area to cover
96
+ return;
97
+ }
98
+
99
+ const inv_d = 1 / d;
100
+
101
+ for (let py = min_y; py <= max_y; py++) {
102
+ const sy = py + 0.5;
103
+
104
+ for (let px = min_x; px <= max_x; px++) {
105
+ const sx = px + 0.5;
106
+
107
+ const wA = ((by - cy) * (sx - cx) + (cx - bx) * (sy - cy)) * inv_d;
108
+ const wB = ((cy - ay) * (sx - cx) + (ax - cx) * (sy - cy)) * inv_d;
109
+ const wC = 1 - wA - wB;
110
+
111
+ if (wA >= 0 && wB >= 0 && wC >= 0) {
112
+ callback(px, py, wA, wB, wC);
113
+ continue;
114
+ }
115
+
116
+ if (!conservative) {
117
+ continue;
118
+ }
119
+
120
+ // center is outside: keep the texel only if its cell overlaps the
121
+ // triangle, sampling the clamped (on-triangle) closest point
122
+ const dist = closest_on_triangle(_q, sx, sy, ax, ay, bx, by, cx, cy);
123
+ if (dist > HALF_TEXEL_DIAGONAL) {
124
+ continue;
125
+ }
126
+
127
+ const qx = _q[0];
128
+ const qy = _q[1];
129
+ let cwA = ((by - cy) * (qx - cx) + (cx - bx) * (qy - cy)) * inv_d;
130
+ let cwB = ((cy - ay) * (qx - cx) + (ax - cx) * (qy - cy)) * inv_d;
131
+ // clamp tiny negative fp drift so the weights stay a valid convex combo
132
+ if (cwA < 0) cwA = 0;
133
+ if (cwB < 0) cwB = 0;
134
+ let cwC = 1 - cwA - cwB;
135
+ if (cwC < 0) {
136
+ cwC = 0;
137
+ const s = cwA + cwB;
138
+ cwA /= s;
139
+ cwB /= s;
140
+ }
141
+
142
+ callback(px, py, cwA, cwB, cwC);
143
+ }
144
+ }
145
+ }
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Reduce lighting discontinuities across UV seams by blending the two atlas-space
3
+ * sides of each shared 3D edge toward each other (a CPU take on the Bakery
4
+ * line-blend seam fix — far simpler than least-squares stitching).
5
+ *
6
+ * A seam is a 3D edge that two charts both keep on their boundary: two
7
+ * {@link Chart#boundary_edges} with the same pair of SOURCE vertices but different
8
+ * UVs. For each such pair we walk both edges in lockstep (parameter t in [0,1],
9
+ * aligned by source-vertex order) at ~half-texel steps and average the covered
10
+ * texels on both sides, repeated a few times so the match propagates.
11
+ *
12
+ * **Only smooth seams are blended.** A shared chart-boundary edge can also be a
13
+ * hard feature crease (a cube's top face meets its side face at 90°), where the
14
+ * two sides have genuinely different lighting and MUST NOT be merged — blending
15
+ * there leaks the dark side into the bright one. So a pair of texels is averaged
16
+ * only when their world normals agree (`dot >= normal_threshold`); creases, whose
17
+ * normals are perpendicular, are left alone. This is the normal-continuity test
18
+ * the Bakery seam fix uses.
19
+ *
20
+ * Seams only ever occur within a single mesh's unwrap (different meshes don't share
21
+ * edges), so `chart_groups` is one chart list per mesh.
22
+ *
23
+ * @param {Float32Array} data atlas pixels, row-major, stride `channels`
24
+ * @param {Float32Array} normals per-texel world normal (3 per texel), length width*height*3
25
+ * @param {Uint8Array} coverage per-texel coverage (1 = valid), length width*height
26
+ * @param {number} width
27
+ * @param {number} height
28
+ * @param {number} channels values per texel
29
+ * @param {Chart[][]} chart_groups one packed-chart list per mesh
30
+ * @param {object} [options]
31
+ * @param {number} [options.iterations] blend passes (default 4)
32
+ * @param {number} [options.normal_threshold] min normal dot to treat an edge as a smooth seam (default 0.9)
33
+ */
34
+ export function lightmap_seam_fix(data: Float32Array, normals: Float32Array, coverage: Uint8Array, width: number, height: number, channels: number, chart_groups: Chart[][], options?: {
35
+ iterations?: number;
36
+ normal_threshold?: number;
37
+ }): void;
38
+ //# sourceMappingURL=lightmap_seam_fix.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lightmap_seam_fix.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/graphics/sh3/lightmap/lightmap_seam_fix.js"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,wCAXW,YAAY,WACZ,YAAY,YACZ,UAAU,SACV,MAAM,UACN,MAAM,YACN,MAAM,gBACN,OAAO,EAAE;IAEQ,UAAU,GAA3B,MAAM;IACW,gBAAgB,GAAjC,MAAM;SAgBhB"}
@@ -0,0 +1,152 @@
1
+ /**
2
+ * Reduce lighting discontinuities across UV seams by blending the two atlas-space
3
+ * sides of each shared 3D edge toward each other (a CPU take on the Bakery
4
+ * line-blend seam fix — far simpler than least-squares stitching).
5
+ *
6
+ * A seam is a 3D edge that two charts both keep on their boundary: two
7
+ * {@link Chart#boundary_edges} with the same pair of SOURCE vertices but different
8
+ * UVs. For each such pair we walk both edges in lockstep (parameter t in [0,1],
9
+ * aligned by source-vertex order) at ~half-texel steps and average the covered
10
+ * texels on both sides, repeated a few times so the match propagates.
11
+ *
12
+ * **Only smooth seams are blended.** A shared chart-boundary edge can also be a
13
+ * hard feature crease (a cube's top face meets its side face at 90°), where the
14
+ * two sides have genuinely different lighting and MUST NOT be merged — blending
15
+ * there leaks the dark side into the bright one. So a pair of texels is averaged
16
+ * only when their world normals agree (`dot >= normal_threshold`); creases, whose
17
+ * normals are perpendicular, are left alone. This is the normal-continuity test
18
+ * the Bakery seam fix uses.
19
+ *
20
+ * Seams only ever occur within a single mesh's unwrap (different meshes don't share
21
+ * edges), so `chart_groups` is one chart list per mesh.
22
+ *
23
+ * @param {Float32Array} data atlas pixels, row-major, stride `channels`
24
+ * @param {Float32Array} normals per-texel world normal (3 per texel), length width*height*3
25
+ * @param {Uint8Array} coverage per-texel coverage (1 = valid), length width*height
26
+ * @param {number} width
27
+ * @param {number} height
28
+ * @param {number} channels values per texel
29
+ * @param {Chart[][]} chart_groups one packed-chart list per mesh
30
+ * @param {object} [options]
31
+ * @param {number} [options.iterations] blend passes (default 4)
32
+ * @param {number} [options.normal_threshold] min normal dot to treat an edge as a smooth seam (default 0.9)
33
+ */
34
+ export function lightmap_seam_fix(data, normals, coverage, width, height, channels, chart_groups, options = {}) {
35
+ const iterations = options.iterations ?? 4;
36
+ const normal_threshold = options.normal_threshold ?? 0.9;
37
+
38
+ const seams = collect_seams(chart_groups);
39
+ if (seams.length === 0) {
40
+ return;
41
+ }
42
+
43
+ for (let iter = 0; iter < iterations; iter++) {
44
+ for (let s = 0; s < seams.length; s++) {
45
+ blend_seam(data, normals, coverage, width, height, channels, seams[s], normal_threshold);
46
+ }
47
+ }
48
+ }
49
+
50
+ /**
51
+ * @param {Chart[][]} chart_groups
52
+ * @returns {Array<{au0:number,av0:number,au1:number,av1:number,bu0:number,bv0:number,bu1:number,bv1:number}>}
53
+ */
54
+ function collect_seams(chart_groups) {
55
+ const seams = [];
56
+
57
+ for (let g = 0; g < chart_groups.length; g++) {
58
+ const charts = chart_groups[g];
59
+ const by_edge = new Map();
60
+
61
+ for (let ci = 0; ci < charts.length; ci++) {
62
+ const chart = charts[ci];
63
+ const be = chart.boundary_edges;
64
+ const vol = chart.vertex_of_local;
65
+ const uv = chart.uv;
66
+
67
+ for (let i = 0; i < be.length; i += 2) {
68
+ const lv0 = be[i];
69
+ const lv1 = be[i + 1];
70
+ let o0 = vol[lv0];
71
+ let o1 = vol[lv1];
72
+ let u0 = uv[lv0 * 2], v0 = uv[lv0 * 2 + 1];
73
+ let u1 = uv[lv1 * 2], v1 = uv[lv1 * 2 + 1];
74
+
75
+ // orient endpoints by source-vertex id so both sides align in t
76
+ if (o0 > o1) {
77
+ const to = o0; o0 = o1; o1 = to;
78
+ const tu = u0; u0 = u1; u1 = tu;
79
+ const tv = v0; v0 = v1; v1 = tv;
80
+ }
81
+
82
+ const key = o0 + "_" + o1;
83
+ const existing = by_edge.get(key);
84
+ const edge = { u0, v0, u1, v1 };
85
+ if (existing === undefined) {
86
+ by_edge.set(key, edge);
87
+ } else {
88
+ // a second occurrence of this edge -> a seam between two charts
89
+ seams.push({
90
+ au0: existing.u0, av0: existing.v0, au1: existing.u1, av1: existing.v1,
91
+ bu0: edge.u0, bv0: edge.v0, bu1: edge.u1, bv1: edge.v1,
92
+ });
93
+ }
94
+ }
95
+ }
96
+ }
97
+
98
+ return seams;
99
+ }
100
+
101
+ /**
102
+ * Average the covered texels along both sides of one seam edge — but only where
103
+ * the two sides are the same continuous surface (normals agree); hard creases are
104
+ * skipped.
105
+ */
106
+ function blend_seam(data, normals, coverage, width, height, channels, seam, normal_threshold) {
107
+ const a_len = Math.hypot((seam.au1 - seam.au0) * width, (seam.av1 - seam.av0) * height);
108
+ const b_len = Math.hypot((seam.bu1 - seam.bu0) * width, (seam.bv1 - seam.bv0) * height);
109
+ const steps = Math.max(2, Math.ceil(Math.max(a_len, b_len) * 2)); // ~half-texel steps
110
+
111
+ for (let i = 0; i <= steps; i++) {
112
+ const t = i / steps;
113
+
114
+ const ax = clamp_index((seam.au0 + (seam.au1 - seam.au0) * t) * width, width);
115
+ const ay = clamp_index((seam.av0 + (seam.av1 - seam.av0) * t) * height, height);
116
+ const bx = clamp_index((seam.bu0 + (seam.bu1 - seam.bu0) * t) * width, width);
117
+ const by = clamp_index((seam.bv0 + (seam.bv1 - seam.bv0) * t) * height, height);
118
+
119
+ const pa = ay * width + ax;
120
+ const pb = by * width + bx;
121
+ if (coverage[pa] === 0 || coverage[pb] === 0) {
122
+ continue;
123
+ }
124
+
125
+ // only blend a continuous surface, never a hard feature crease
126
+ const na = pa * 3;
127
+ const nb = pb * 3;
128
+ const dot = normals[na] * normals[nb] + normals[na + 1] * normals[nb + 1] + normals[na + 2] * normals[nb + 2];
129
+ if (dot < normal_threshold) {
130
+ continue;
131
+ }
132
+
133
+ const base_a = pa * channels;
134
+ const base_b = pb * channels;
135
+ for (let c = 0; c < channels; c++) {
136
+ const avg = (data[base_a + c] + data[base_b + c]) * 0.5;
137
+ data[base_a + c] = avg;
138
+ data[base_b + c] = avg;
139
+ }
140
+ }
141
+ }
142
+
143
+ /**
144
+ * @param {number} coord pixel coordinate (may be fractional / out of range)
145
+ * @param {number} size
146
+ * @returns {number} integer texel index in [0, size)
147
+ */
148
+ function clamp_index(coord, size) {
149
+ let v = Math.floor(coord);
150
+ if (v < 0) v = 0; else if (v >= size) v = size - 1;
151
+ return v;
152
+ }
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=prototypeLightmapBaker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prototypeLightmapBaker.d.ts","sourceRoot":"","sources":["../../../../../../src/engine/graphics/sh3/lightmap/prototypeLightmapBaker.js"],"names":[],"mappings":""}