@woosh/meep-engine 3.27.0 → 3.28.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 (255) hide show
  1. package/build/bundle-worker-terrain.js +1 -1
  2. package/package.json +1 -1
  3. package/src/core/geom/3d/mat4/m4_linear_determinant.d.ts +15 -0
  4. package/src/core/geom/3d/mat4/m4_linear_determinant.d.ts.map +1 -0
  5. package/src/core/geom/3d/mat4/m4_linear_determinant.js +24 -0
  6. package/src/core/geom/3d/mat4/m4_normal_matrix3.d.ts +4 -2
  7. package/src/core/geom/3d/mat4/m4_normal_matrix3.d.ts.map +1 -1
  8. package/src/core/geom/3d/mat4/m4_normal_matrix3.js +21 -11
  9. package/src/engine/Engine.d.ts.map +1 -1
  10. package/src/engine/Engine.js +38 -1
  11. package/src/engine/graphics3/GraphicsEngine.d.ts +5 -1
  12. package/src/engine/graphics3/GraphicsEngine.d.ts.map +1 -1
  13. package/src/engine/graphics3/GraphicsEngine.js +834 -830
  14. package/src/shade/RENDERER_CONTRACT.md +19 -10
  15. package/src/shade/device/timing/GPU_PROFILER_PROPOSAL_2026_08_28.md +1 -1
  16. package/src/shade/playground/vgeo_runtime/README.md +27 -13
  17. package/src/shade/playground/vgeo_runtime/main.js +18 -5
  18. package/src/shade/playground/vgeo_runtime/sample_asset.d.ts +18 -0
  19. package/src/shade/playground/vgeo_runtime/sample_asset.d.ts.map +1 -0
  20. package/src/shade/playground/{vgeo_viewer → vgeo_runtime}/sample_asset.js +9 -8
  21. package/src/shade/playground/vgeo_scene/README.md +408 -0
  22. package/src/shade/playground/vgeo_scene/index.html +144 -0
  23. package/src/shade/playground/vgeo_scene/main.d.ts +2 -0
  24. package/src/shade/playground/vgeo_scene/main.d.ts.map +1 -0
  25. package/src/shade/playground/vgeo_scene/main.js +1716 -0
  26. package/src/shade/renderer/Renderer.d.ts +4 -1
  27. package/src/shade/renderer/Renderer.d.ts.map +1 -1
  28. package/src/shade/renderer/Renderer.js +5 -2
  29. package/src/shade/renderer/extension/RENDER_EXTENSION_DESIGN.md +1 -2
  30. package/src/shade/renderer/geometry/meshlet/MeshletBatch.d.ts.map +1 -1
  31. package/src/shade/renderer/geometry/meshlet/MeshletBatch.js +3 -29
  32. package/src/shade/renderer/geometry/meshlet/encoding/ENCODED_ATTRIBUTE_DEFAULT_VALUES.d.ts +22 -0
  33. package/src/shade/renderer/geometry/meshlet/encoding/ENCODED_ATTRIBUTE_DEFAULT_VALUES.d.ts.map +1 -0
  34. package/src/shade/renderer/geometry/meshlet/encoding/ENCODED_ATTRIBUTE_DEFAULT_VALUES.js +49 -0
  35. package/src/shade/renderer/geometry/virtual/VGEO_FORMAT.md +4 -2
  36. package/src/shade/renderer/geometry/virtual/VIRTUAL_GEOMETRY_DESIGN.md +10 -8
  37. package/src/shade/renderer/geometry/virtual/VIRTUAL_GEOMETRY_PLAN.md +12 -11
  38. package/src/shade/renderer/geometry/virtual/build/VGeoBuildOptions.d.ts +1 -1
  39. package/src/shade/renderer/geometry/virtual/build/VGeoBuildOptions.d.ts.map +1 -1
  40. package/src/shade/renderer/geometry/virtual/build/VGeoBuildOptions.js +1 -1
  41. package/src/shade/renderer/geometry/virtual/build/gltf/gltf_open_document.d.ts.map +1 -1
  42. package/src/shade/renderer/geometry/virtual/build/gltf/gltf_open_document.js +5 -9
  43. package/src/shade/renderer/geometry/virtual/build/level/VGeoLevel.d.ts +32 -0
  44. package/src/shade/renderer/geometry/virtual/build/level/VGeoLevel.d.ts.map +1 -0
  45. package/src/shade/renderer/geometry/virtual/build/level/VGeoLevelOptions.d.ts +59 -0
  46. package/src/shade/renderer/geometry/virtual/build/level/VGeoLevelOptions.d.ts.map +1 -0
  47. package/src/shade/renderer/geometry/virtual/build/level/VGeoLevelSummary.d.ts +44 -0
  48. package/src/shade/renderer/geometry/virtual/build/level/VGeoLevelSummary.d.ts.map +1 -0
  49. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_levels.d.ts +36 -0
  50. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_levels.d.ts.map +1 -0
  51. package/src/shade/renderer/geometry/virtual/build/{vgeo_build_levels.js → level/vgeo_build_levels.js} +61 -95
  52. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_root_group.d.ts +19 -0
  53. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_root_group.d.ts.map +1 -0
  54. package/src/shade/renderer/geometry/virtual/build/{vgeo_build_root_group.js → level/vgeo_build_root_group.js} +1 -1
  55. package/src/shade/renderer/geometry/virtual/build/mesh/VirtualGeometryMesh.d.ts +73 -0
  56. package/src/shade/renderer/geometry/virtual/build/mesh/VirtualGeometryMesh.d.ts.map +1 -0
  57. package/src/shade/renderer/geometry/virtual/build/{VirtualGeometryMesh.js → mesh/VirtualGeometryMesh.js} +7 -7
  58. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_compute_vertex_normals.d.ts +29 -0
  59. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_compute_vertex_normals.d.ts.map +1 -0
  60. package/src/shade/renderer/geometry/virtual/build/{vgeo_compute_vertex_normals.js → mesh/vgeo_compute_vertex_normals.js} +3 -3
  61. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_compute_vertex_tangents.d.ts +31 -0
  62. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_compute_vertex_tangents.d.ts.map +1 -0
  63. package/src/shade/renderer/geometry/virtual/build/{vgeo_compute_vertex_tangents.js → mesh/vgeo_compute_vertex_tangents.js} +5 -5
  64. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_normalize_source.d.ts +46 -0
  65. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_normalize_source.d.ts.map +1 -0
  66. package/src/shade/renderer/geometry/virtual/build/{vgeo_normalize_source.js → mesh/vgeo_normalize_source.js} +9 -9
  67. package/src/shade/renderer/geometry/virtual/build/page/vgeo_assemble_pages.d.ts +13 -0
  68. package/src/shade/renderer/geometry/virtual/build/page/vgeo_assemble_pages.d.ts.map +1 -0
  69. package/src/shade/renderer/geometry/virtual/build/{vgeo_assemble_pages.js → page/vgeo_assemble_pages.js} +9 -9
  70. package/src/shade/renderer/geometry/virtual/build/page/vgeo_build_page_nodes.d.ts +13 -0
  71. package/src/shade/renderer/geometry/virtual/build/page/vgeo_build_page_nodes.d.ts.map +1 -0
  72. package/src/shade/renderer/geometry/virtual/build/{vgeo_build_page_nodes.js → page/vgeo_build_page_nodes.js} +4 -4
  73. package/src/shade/renderer/geometry/virtual/build/page/vgeo_page_node_count.d.ts +22 -0
  74. package/src/shade/renderer/geometry/virtual/build/page/vgeo_page_node_count.d.ts.map +1 -0
  75. package/src/shade/renderer/geometry/virtual/build/{vgeo_page_node_count.js → page/vgeo_page_node_count.js} +2 -2
  76. package/src/shade/renderer/geometry/virtual/build/partition/VGeoFaceGraph.d.ts +52 -0
  77. package/src/shade/renderer/geometry/virtual/build/partition/VGeoFaceGraph.d.ts.map +1 -0
  78. package/src/shade/renderer/geometry/virtual/build/{VGeoFaceGraph.js → partition/VGeoFaceGraph.js} +1 -1
  79. package/src/shade/renderer/geometry/virtual/build/partition/vgeo_graph_components.d.ts +14 -0
  80. package/src/shade/renderer/geometry/virtual/build/partition/vgeo_graph_components.d.ts.map +1 -0
  81. package/src/shade/renderer/geometry/virtual/build/partition/vgeo_partition_graph.d.ts +29 -0
  82. package/src/shade/renderer/geometry/virtual/build/partition/vgeo_partition_graph.d.ts.map +1 -0
  83. package/src/shade/renderer/geometry/virtual/build/{vgeo_partition_graph.js → partition/vgeo_partition_graph.js} +2 -2
  84. package/src/shade/renderer/geometry/virtual/build/partition/vgeo_partition_subgraph.d.ts +41 -0
  85. package/src/shade/renderer/geometry/virtual/build/partition/vgeo_partition_subgraph.d.ts.map +1 -0
  86. package/src/shade/renderer/geometry/virtual/build/partition/vgeo_partition_subgraph.js +92 -0
  87. package/src/shade/renderer/geometry/virtual/build/partition/vgeo_split_face_set.d.ts +10 -0
  88. package/src/shade/renderer/geometry/virtual/build/partition/vgeo_split_face_set.d.ts.map +1 -0
  89. package/src/shade/renderer/geometry/virtual/build/{vgeo_split_face_set.js → partition/vgeo_split_face_set.js} +12 -55
  90. package/src/shade/renderer/geometry/virtual/build/partition/vgeo_split_face_set_packed.d.ts +15 -0
  91. package/src/shade/renderer/geometry/virtual/build/partition/vgeo_split_face_set_packed.d.ts.map +1 -0
  92. package/src/shade/renderer/geometry/virtual/build/{vgeo_split_face_set_packed.js → partition/vgeo_split_face_set_packed.js} +3 -3
  93. package/src/shade/renderer/geometry/virtual/build/sphere/vgeo_bounding_sphere.d.ts +12 -0
  94. package/src/shade/renderer/geometry/virtual/build/sphere/vgeo_bounding_sphere.d.ts.map +1 -0
  95. package/src/shade/renderer/geometry/virtual/build/{vgeo_bounding_sphere.js → sphere/vgeo_bounding_sphere.js} +3 -3
  96. package/src/shade/renderer/geometry/virtual/build/sphere/vgeo_containing_sphere.d.ts +18 -0
  97. package/src/shade/renderer/geometry/virtual/build/sphere/vgeo_containing_sphere.d.ts.map +1 -0
  98. package/src/shade/renderer/geometry/virtual/build/{vgeo_containing_sphere.js → sphere/vgeo_containing_sphere.js} +3 -3
  99. package/src/shade/renderer/geometry/virtual/build/sphere/vgeo_sphere_inflate_to_contain.d.ts +9 -0
  100. package/src/shade/renderer/geometry/virtual/build/sphere/vgeo_sphere_inflate_to_contain.d.ts.map +1 -0
  101. package/src/shade/renderer/geometry/virtual/build/{vgeo_sphere_inflate_to_contain.js → sphere/vgeo_sphere_inflate_to_contain.js} +1 -1
  102. package/src/shade/renderer/geometry/virtual/build/submesh/VGeoGatheredFaces.d.ts +24 -0
  103. package/src/shade/renderer/geometry/virtual/build/submesh/VGeoGatheredFaces.d.ts.map +1 -0
  104. package/src/shade/renderer/geometry/virtual/build/submesh/VGeoSubmesh.d.ts +20 -0
  105. package/src/shade/renderer/geometry/virtual/build/submesh/VGeoSubmesh.d.ts.map +1 -0
  106. package/src/shade/renderer/geometry/virtual/build/submesh/vgeo_extract_submesh.d.ts +14 -0
  107. package/src/shade/renderer/geometry/virtual/build/submesh/vgeo_extract_submesh.d.ts.map +1 -0
  108. package/src/shade/renderer/geometry/virtual/build/{vgeo_extract_submesh.js → submesh/vgeo_extract_submesh.js} +5 -5
  109. package/src/shade/renderer/geometry/virtual/build/submesh/vgeo_gather_faces.d.ts +12 -0
  110. package/src/shade/renderer/geometry/virtual/build/submesh/vgeo_gather_faces.d.ts.map +1 -0
  111. package/src/shade/renderer/geometry/virtual/build/{vgeo_gather_faces.js → submesh/vgeo_gather_faces.js} +2 -2
  112. package/src/shade/renderer/geometry/virtual/build/submesh/vgeo_narrow_indices.d.ts +11 -0
  113. package/src/shade/renderer/geometry/virtual/build/submesh/vgeo_narrow_indices.d.ts.map +1 -0
  114. package/src/shade/renderer/geometry/virtual/build/{vgeo_narrow_indices.js → submesh/vgeo_narrow_indices.js} +3 -3
  115. package/src/shade/renderer/geometry/virtual/build/vgeo_build.d.ts.map +1 -1
  116. package/src/shade/renderer/geometry/virtual/build/vgeo_build.js +9 -11
  117. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_attributes_read.d.ts +8 -2
  118. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_attributes_read.d.ts.map +1 -1
  119. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_attributes_read.js +8 -2
  120. package/src/shade/renderer/geometry/virtual/format/page/VGEO_GROUP_OFFSET.d.ts +15 -0
  121. package/src/shade/renderer/geometry/virtual/format/page/VGEO_GROUP_OFFSET.d.ts.map +1 -0
  122. package/src/shade/renderer/geometry/virtual/format/page/VGEO_GROUP_OFFSET.js +15 -0
  123. package/src/shade/renderer/geometry/virtual/format/payload/vgeo_encode_cluster_payload.d.ts +28 -0
  124. package/src/shade/renderer/geometry/virtual/format/payload/vgeo_encode_cluster_payload.d.ts.map +1 -1
  125. package/src/shade/renderer/geometry/virtual/format/payload/vgeo_encode_cluster_payload.js +7 -3
  126. package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_page.d.ts.map +1 -1
  127. package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_page.js +9 -4
  128. package/src/shade/renderer/geometry/virtual/format/vgeo_validate_container.d.ts.map +1 -1
  129. package/src/shade/renderer/geometry/virtual/format/vgeo_validate_container.js +18 -5
  130. package/src/shade/renderer/geometry/virtual/format/vgeo_write_container.d.ts.map +1 -1
  131. package/src/shade/renderer/geometry/virtual/format/vgeo_write_container.js +9 -1
  132. package/src/shade/renderer/geometry/virtual/runtime/CUT_PLAN_2026_09_14.md +21 -2
  133. package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryRuntime.d.ts +52 -2
  134. package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryRuntime.d.ts.map +1 -1
  135. package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryRuntime.js +97 -1
  136. package/src/shade/renderer/geometry/virtual/runtime/RUNTIME_PLAN.md +4 -4
  137. package/src/shade/renderer/geometry/virtual/runtime/VGeoFeedbackLoop.d.ts.map +1 -1
  138. package/src/shade/renderer/geometry/virtual/runtime/VGeoFeedbackLoop.js +10 -0
  139. package/src/shade/renderer/geometry/virtual/runtime/VGeoResidency.d.ts.map +1 -1
  140. package/src/shade/renderer/geometry/virtual/runtime/VGeoResidency.js +59 -34
  141. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_access.d.ts +8 -8
  142. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_access.d.ts.map +1 -1
  143. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_access.js +11 -88
  144. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_arena.d.ts +19 -0
  145. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_arena.d.ts.map +1 -0
  146. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_arena.js +98 -0
  147. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_claim.d.ts +31 -0
  148. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_claim.d.ts.map +1 -0
  149. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_claim.js +99 -0
  150. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_queue.d.ts +17 -0
  151. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_queue.d.ts.map +1 -0
  152. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_queue.js +39 -0
  153. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_reseed.d.ts.map +1 -1
  154. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_reseed.js +7 -63
  155. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_seed.d.ts.map +1 -1
  156. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_seed.js +13 -30
  157. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_traverse.d.ts.map +1 -1
  158. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_traverse.js +6 -52
  159. package/src/shade/renderer/loader/gltf/load_gltf.d.ts.map +1 -1
  160. package/src/shade/renderer/loader/gltf/load_gltf.js +0 -19
  161. package/src/shade/renderer/material/chunk_material_draw_side.d.ts +14 -0
  162. package/src/shade/renderer/material/chunk_material_draw_side.d.ts.map +1 -0
  163. package/src/shade/renderer/material/chunk_material_draw_side.js +34 -0
  164. package/src/shade/renderer/material/standard/fragment_gbuffer.d.ts.map +1 -1
  165. package/src/shade/renderer/material/standard/fragment_gbuffer.js +8 -1
  166. package/src/shade/renderer/path_tracer/shader/chunk_sample_material_data.d.ts.map +1 -1
  167. package/src/shade/renderer/path_tracer/shader/chunk_sample_material_data.js +13 -1
  168. package/src/shade/renderer/rasterize/bucket/construct_primitive_state.d.ts +19 -5
  169. package/src/shade/renderer/rasterize/bucket/construct_primitive_state.d.ts.map +1 -1
  170. package/src/shade/renderer/rasterize/bucket/construct_primitive_state.js +23 -5
  171. package/src/shade/renderer/rasterize/bucket/filter_materials_by_bucket.d.ts.map +1 -1
  172. package/src/shade/renderer/rasterize/bucket/filter_materials_by_bucket.js +12 -5
  173. package/src/shade/renderer/rasterize/bucket/rasterization_opaque_buckets.d.ts +22 -0
  174. package/src/shade/renderer/rasterize/bucket/rasterization_opaque_buckets.d.ts.map +1 -0
  175. package/src/shade/renderer/rasterize/bucket/rasterization_opaque_buckets.js +36 -0
  176. package/src/shade/renderer/rasterize/chunk_triangle_winding_is_reversed.d.ts +15 -0
  177. package/src/shade/renderer/rasterize/chunk_triangle_winding_is_reversed.d.ts.map +1 -0
  178. package/src/shade/renderer/rasterize/chunk_triangle_winding_is_reversed.js +35 -0
  179. package/src/shade/renderer/rasterize/expand/bucket/RASTERIZATION_BUCKET_LIMIT.d.ts +10 -1
  180. package/src/shade/renderer/rasterize/expand/bucket/RASTERIZATION_BUCKET_LIMIT.d.ts.map +1 -1
  181. package/src/shade/renderer/rasterize/expand/bucket/RASTERIZATION_BUCKET_LIMIT.js +38 -29
  182. package/src/shade/renderer/rasterize/expand/bucket/chunk_rasterization_material_bucket.d.ts +5 -0
  183. package/src/shade/renderer/rasterize/expand/bucket/chunk_rasterization_material_bucket.d.ts.map +1 -1
  184. package/src/shade/renderer/rasterize/expand/bucket/chunk_rasterization_material_bucket.js +63 -55
  185. package/src/shade/renderer/rasterize/expand/graph_meshlets_rasterize.d.ts.map +1 -1
  186. package/src/shade/renderer/rasterize/expand/graph_meshlets_rasterize.js +1 -0
  187. package/src/shade/renderer/rasterize/fast/graph_rasterize_scene_fast.d.ts.map +1 -1
  188. package/src/shade/renderer/rasterize/fast/graph_rasterize_scene_fast.js +44 -53
  189. package/src/shade/renderer/rasterize/forward/chunk_forward_shade_standard_fragment_brick4.d.ts.map +1 -1
  190. package/src/shade/renderer/rasterize/forward/chunk_forward_shade_standard_fragment_brick4.js +6 -2
  191. package/src/shade/renderer/rasterize/forward/chunk_forward_shade_standard_fragment_ibl.d.ts.map +1 -1
  192. package/src/shade/renderer/rasterize/forward/chunk_forward_shade_standard_fragment_ibl.js +6 -2
  193. package/src/shade/renderer/rasterize/forward/vertex_shader_chunk.d.ts.map +1 -1
  194. package/src/shade/renderer/rasterize/forward/vertex_shader_chunk.js +19 -2
  195. package/src/shade/renderer/rasterize/native/avboit/AVBOIT_PLAN_2026_09_03.md +7 -4
  196. package/src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.d.ts.map +1 -1
  197. package/src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.js +3 -2
  198. package/src/shade/renderer/rasterize/native/chunk_rasterize_triangle.d.ts.map +1 -1
  199. package/src/shade/renderer/rasterize/native/chunk_rasterize_triangle.js +15 -4
  200. package/src/shade/renderer/rasterize/native/depth/shadow_rasterization_alpha_tested_pass_descriptor.d.ts.map +1 -1
  201. package/src/shade/renderer/rasterize/native/depth/shadow_rasterization_alpha_tested_pass_descriptor.js +16 -5
  202. package/src/shade/renderer/rasterize/native/depth/shadow_rasterization_pass_descriptor.d.ts.map +1 -1
  203. package/src/shade/renderer/rasterize/native/depth/shadow_rasterization_pass_descriptor.js +16 -5
  204. package/src/shade/renderer/rasterize/native/oit/graph_rasterize_meshes_transparent_oit.d.ts.map +1 -1
  205. package/src/shade/renderer/rasterize/native/oit/graph_rasterize_meshes_transparent_oit.js +2 -1
  206. package/src/shade/renderer/rasterize/native/rasterization_shader_resources.d.ts.map +1 -1
  207. package/src/shade/renderer/rasterize/native/rasterization_shader_resources.js +4 -0
  208. package/src/shade/renderer/rasterize/native/viz/viz_rasterization_alpha_tested_pass_descriptor.d.ts.map +1 -1
  209. package/src/shade/renderer/rasterize/native/viz/viz_rasterization_alpha_tested_pass_descriptor.js +16 -7
  210. package/src/shade/renderer/rasterize/standard/graph_rasterize_partial_opaque.d.ts.map +1 -1
  211. package/src/shade/renderer/rasterize/standard/graph_rasterize_partial_opaque.js +78 -88
  212. package/src/shade/renderer/rasterize/standard/graph_rasterize_remaining_opaque.d.ts.map +1 -1
  213. package/src/shade/renderer/rasterize/standard/graph_rasterize_remaining_opaque.js +21 -31
  214. package/src/shade/renderer/scene/GPUSceneContext.d.ts.map +1 -1
  215. package/src/shade/renderer/scene/GPUSceneContext.js +2 -0
  216. package/src/shade/renderer/scene/NODE3D_STRUCT.d.ts +19 -0
  217. package/src/shade/renderer/scene/NODE3D_STRUCT.d.ts.map +1 -1
  218. package/src/shade/renderer/scene/NODE3D_STRUCT.js +34 -0
  219. package/src/shade/renderer/scene/chunk_node3d_flags.d.ts +9 -0
  220. package/src/shade/renderer/scene/chunk_node3d_flags.d.ts.map +1 -0
  221. package/src/shade/renderer/scene/chunk_node3d_flags.js +23 -0
  222. package/src/shade/renderer/scene/chunk_scene_database_access.d.ts.map +1 -1
  223. package/src/shade/renderer/scene/chunk_scene_database_access.js +15 -1
  224. package/src/shade/renderer/scene/rows/GPUSceneRows.d.ts.map +1 -1
  225. package/src/shade/renderer/scene/rows/GPUSceneRows.js +9 -1
  226. package/src/shade/renderer/shader/chunk/geometry/mat4/chunk_compute_normal_matrix_from_m4.d.ts +7 -0
  227. package/src/shade/renderer/shader/chunk/geometry/mat4/chunk_compute_normal_matrix_from_m4.d.ts.map +1 -1
  228. package/src/shade/renderer/shader/chunk/geometry/mat4/chunk_compute_normal_matrix_from_m4.js +16 -4
  229. package/src/shade/renderer/shader/chunk/geometry/mat4/chunk_mat4_linear_determinant.d.ts +12 -0
  230. package/src/shade/renderer/shader/chunk/geometry/mat4/chunk_mat4_linear_determinant.d.ts.map +1 -0
  231. package/src/shade/renderer/shader/chunk/geometry/mat4/chunk_mat4_linear_determinant.js +18 -0
  232. package/src/shade/renderer/shader/chunk/geometry/triangle/chunk_triangle_list_reverse_winding.d.ts +24 -0
  233. package/src/shade/renderer/shader/chunk/geometry/triangle/chunk_triangle_list_reverse_winding.d.ts.map +1 -0
  234. package/src/shade/renderer/shader/chunk/geometry/triangle/chunk_triangle_list_reverse_winding.js +33 -0
  235. package/src/shade/playground/vgeo_viewer/README.md +0 -150
  236. package/src/shade/playground/vgeo_viewer/cut_geometry.js +0 -460
  237. package/src/shade/playground/vgeo_viewer/index.html +0 -77
  238. package/src/shade/playground/vgeo_viewer/main.js +0 -1343
  239. package/src/shade/playground/vgeo_viewer/select_cut.js +0 -481
  240. package/src/shade/renderer/geometry/virtual/residency/VGeoResidencyManager.d.ts +0 -258
  241. package/src/shade/renderer/geometry/virtual/residency/VGeoResidencyManager.d.ts.map +0 -1
  242. package/src/shade/renderer/geometry/virtual/residency/VGeoResidencyOptions.d.ts +0 -49
  243. package/src/shade/renderer/geometry/virtual/residency/VGeoResidencyOptions.d.ts.map +0 -1
  244. package/src/shade/renderer/loader/gltf/fix_up_material_sides.js +0 -109
  245. package/src/shade/renderer/rasterize/expand/graph_triangles_filter_by_material_side.js +0 -78
  246. package/src/shade/renderer/rasterize/expand/shader_filter_triangle_by_material_side.js +0 -100
  247. package/src/shade/renderer/rasterize/forward/chunk_material_side_should_draw.js +0 -26
  248. package/src/shade/renderer/shader/chunk/jobs/chunk_job_system.d.ts +0 -3
  249. package/src/shade/renderer/shader/chunk/jobs/chunk_job_system.d.ts.map +0 -1
  250. /package/src/shade/renderer/geometry/virtual/build/{VGeoLevel.js → level/VGeoLevel.js} +0 -0
  251. /package/src/shade/renderer/geometry/virtual/build/{VGeoLevelOptions.js → level/VGeoLevelOptions.js} +0 -0
  252. /package/src/shade/renderer/geometry/virtual/build/{VGeoLevelSummary.js → level/VGeoLevelSummary.js} +0 -0
  253. /package/src/shade/renderer/geometry/virtual/build/{vgeo_graph_components.js → partition/vgeo_graph_components.js} +0 -0
  254. /package/src/shade/renderer/geometry/virtual/build/{VGeoGatheredFaces.js → submesh/VGeoGatheredFaces.js} +0 -0
  255. /package/src/shade/renderer/geometry/virtual/build/{VGeoSubmesh.js → submesh/VGeoSubmesh.js} +0 -0
@@ -1,45 +1,45 @@
1
- import { assert } from "../../../../../core/assert.js";
2
- import { aabb3_from_v3_array } from "../../../../../core/geom/3d/aabb/aabb3_from_v3_array.js";
3
- import { v3_morton_encode_bounded } from "../../../../../core/geom/3d/morton/v3_morton_encode_bounded.js";
4
- import { Quadric3 } from "../../../../../core/geom/3d/quadric/Quadric3.js";
1
+ import { assert } from "../../../../../../core/assert.js";
2
+ import { aabb3_from_v3_array } from "../../../../../../core/geom/3d/aabb/aabb3_from_v3_array.js";
3
+ import { v3_morton_encode_bounded } from "../../../../../../core/geom/3d/morton/v3_morton_encode_bounded.js";
4
+ import { Quadric3 } from "../../../../../../core/geom/3d/quadric/Quadric3.js";
5
5
  import {
6
6
  sphere_compute_bounding_of_2_spheres
7
- } from "../../../../../core/geom/3d/sphere/sphere_compute_bounding_of_2_spheres.js";
8
- import { BinaryTopology, NULL_POINTER, } from "../../../../../core/geom/3d/topology/struct/binary/BinaryTopology.js";
7
+ } from "../../../../../../core/geom/3d/sphere/sphere_compute_bounding_of_2_spheres.js";
8
+ import { BinaryTopology, NULL_POINTER, } from "../../../../../../core/geom/3d/topology/struct/binary/BinaryTopology.js";
9
9
  import {
10
10
  bt_mesh_compute_vertex_quadrics
11
- } from "../../../../../core/geom/3d/topology/struct/binary/io/bt_mesh_compute_vertex_quadrics.js";
11
+ } from "../../../../../../core/geom/3d/topology/struct/binary/io/bt_mesh_compute_vertex_quadrics.js";
12
12
  import {
13
13
  bt_mesh_from_indexed_geometry
14
- } from "../../../../../core/geom/3d/topology/struct/binary/io/bt_mesh_from_indexed_geometry.js";
14
+ } from "../../../../../../core/geom/3d/topology/struct/binary/io/bt_mesh_from_indexed_geometry.js";
15
15
  import {
16
16
  bt_mesh_simplify_with_quadrics
17
- } from "../../../../../core/geom/3d/topology/struct/binary/io/bt_mesh_simplify.js";
18
- import { bt_edge_get } from "../../../../../core/geom/3d/topology/struct/binary/query/bt_edge_get.js";
19
- import { bt_mesh_validate } from "../../../../../core/geom/3d/topology/struct/binary/query/bt_mesh_validate.js";
20
- import { bt_mesh_build_face_graph } from "../../../../../core/graph/metis/bt_mesh_build_face_graph.js";
21
- import { vgeo_encode_cluster_payload } from "../format/payload/vgeo_encode_cluster_payload.js";
22
- import { vgeo_layers_copy_vertex } from "../format/attribute/vgeo_layers_copy_vertex.js";
23
- import { vgeo_layers_like } from "../format/attribute/vgeo_layers_like.js";
24
- import { VGEO_MAX_CLUSTER_TRIANGLE_COUNT } from "../format/cluster/VGEO_MAX_CLUSTER_TRIANGLE_COUNT.js";
25
- import { VGEO_MAX_CLUSTER_VERTEX_COUNT } from "../format/cluster/VGEO_MAX_CLUSTER_VERTEX_COUNT.js";
26
- import { VGEO_MAX_GROUP_CLUSTER_COUNT } from "../format/page/VGEO_MAX_GROUP_CLUSTER_COUNT.js";
27
- import { VirtualGeometryCluster } from "../format/dag/VirtualGeometryCluster.js";
28
- import { VirtualGeometryGroup } from "../format/dag/VirtualGeometryGroup.js";
29
- import { vgeo_bounding_sphere } from "./vgeo_bounding_sphere.js";
30
- import { vgeo_compute_vertex_normals } from "./vgeo_compute_vertex_normals.js";
31
- import { vgeo_compute_vertex_tangents } from "./vgeo_compute_vertex_tangents.js";
32
- import { vgeo_containing_sphere } from "./vgeo_containing_sphere.js";
33
- import { vgeo_extract_submesh } from "./vgeo_extract_submesh.js";
34
- import { vgeo_gather_faces } from "./vgeo_gather_faces.js";
35
- import { vgeo_graph_components } from "./vgeo_graph_components.js";
36
- import { vgeo_narrow_indices } from "./vgeo_narrow_indices.js";
37
- import { vgeo_partition_graph } from "./vgeo_partition_graph.js";
38
- import { vgeo_split_face_set } from "./vgeo_split_face_set.js";
39
- import { vgeo_split_face_set_packed } from "./vgeo_split_face_set_packed.js";
40
- import { VGeoFaceGraph } from "./VGeoFaceGraph.js";
17
+ } from "../../../../../../core/geom/3d/topology/struct/binary/io/bt_mesh_simplify.js";
18
+ import { bt_edge_get } from "../../../../../../core/geom/3d/topology/struct/binary/query/bt_edge_get.js";
19
+ import { bt_mesh_validate } from "../../../../../../core/geom/3d/topology/struct/binary/query/bt_mesh_validate.js";
20
+ import { bt_mesh_build_face_graph } from "../../../../../../core/graph/metis/bt_mesh_build_face_graph.js";
21
+ import { vgeo_encode_cluster_payload } from "../../format/payload/vgeo_encode_cluster_payload.js";
22
+ import { vgeo_layers_copy_vertex } from "../../format/attribute/vgeo_layers_copy_vertex.js";
23
+ import { vgeo_layers_like } from "../../format/attribute/vgeo_layers_like.js";
24
+ import { VGEO_MAX_CLUSTER_TRIANGLE_COUNT } from "../../format/cluster/VGEO_MAX_CLUSTER_TRIANGLE_COUNT.js";
25
+ import { VGEO_MAX_CLUSTER_VERTEX_COUNT } from "../../format/cluster/VGEO_MAX_CLUSTER_VERTEX_COUNT.js";
26
+ import { VGEO_MAX_GROUP_CLUSTER_COUNT } from "../../format/page/VGEO_MAX_GROUP_CLUSTER_COUNT.js";
27
+ import { VirtualGeometryCluster } from "../../format/dag/VirtualGeometryCluster.js";
28
+ import { VirtualGeometryGroup } from "../../format/dag/VirtualGeometryGroup.js";
29
+ import { vgeo_bounding_sphere } from "../sphere/vgeo_bounding_sphere.js";
30
+ import { vgeo_compute_vertex_normals } from "../mesh/vgeo_compute_vertex_normals.js";
31
+ import { vgeo_compute_vertex_tangents } from "../mesh/vgeo_compute_vertex_tangents.js";
32
+ import { vgeo_containing_sphere } from "../sphere/vgeo_containing_sphere.js";
33
+ import { vgeo_extract_submesh } from "../submesh/vgeo_extract_submesh.js";
34
+ import { vgeo_gather_faces } from "../submesh/vgeo_gather_faces.js";
35
+ import { vgeo_graph_components } from "../partition/vgeo_graph_components.js";
36
+ import { vgeo_narrow_indices } from "../submesh/vgeo_narrow_indices.js";
37
+ import { vgeo_partition_subgraph } from "../partition/vgeo_partition_subgraph.js";
38
+ import { vgeo_split_face_set } from "../partition/vgeo_split_face_set.js";
39
+ import { vgeo_split_face_set_packed } from "../partition/vgeo_split_face_set_packed.js";
40
+ import { VGeoFaceGraph } from "../partition/VGeoFaceGraph.js";
41
41
  import { VGeoLevel } from "./VGeoLevel.js";
42
- import { VirtualGeometryMesh } from "./VirtualGeometryMesh.js";
42
+ import { VirtualGeometryMesh } from "../mesh/VirtualGeometryMesh.js";
43
43
 
44
44
  /**
45
45
  * Build the cluster DAG: leaves out of the source mesh, then merge steps until one cluster is left.
@@ -434,30 +434,32 @@ function bundle_loose_clusters(frontier, loose, group_size) {
434
434
  return [];
435
435
  }
436
436
 
437
- const bounds = new Float32Array([
438
- Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY, Number.POSITIVE_INFINITY,
439
- Number.NEGATIVE_INFINITY, Number.NEGATIVE_INFINITY, Number.NEGATIVE_INFINITY,
440
- ]);
437
+ // Gathered rather than read through the cluster list twice: the bounds and the codes are the
438
+ // same points, and this is the shape `vgeo_split_face_set_packed` already packs in.
439
+ const centres = new Float32Array(loose.length * 3);
441
440
 
442
- for (const cluster of loose) {
443
- const centre = frontier.clusters[cluster].bounds_sphere;
441
+ loose.forEach((cluster, index) => {
442
+ const sphere = frontier.clusters[cluster].bounds_sphere;
444
443
 
445
- for (let axis = 0; axis < 3; axis++) {
446
- bounds[axis] = Math.min(bounds[axis], centre[axis]);
447
- bounds[axis + 3] = Math.max(bounds[axis + 3], centre[axis]);
448
- }
449
- }
444
+ centres[index * 3] = sphere[0];
445
+ centres[index * 3 + 1] = sphere[1];
446
+ centres[index * 3 + 2] = sphere[2];
447
+ });
448
+
449
+ const bounds = new Float32Array(6);
450
+
451
+ aabb3_from_v3_array(bounds, centres, centres.length);
450
452
 
451
453
  /**
452
454
  * @type {Map<number, number>}
453
455
  */
454
456
  const codes = new Map();
455
457
 
456
- for (const cluster of loose) {
457
- const centre = frontier.clusters[cluster].bounds_sphere;
458
-
459
- codes.set(cluster, v3_morton_encode_bounded(centre[0], centre[1], centre[2], bounds));
460
- }
458
+ loose.forEach((cluster, index) => {
459
+ codes.set(cluster, v3_morton_encode_bounded(
460
+ centres[index * 3], centres[index * 3 + 1], centres[index * 3 + 2], bounds
461
+ ));
462
+ });
461
463
 
462
464
  const order = loose.slice();
463
465
 
@@ -621,6 +623,14 @@ function absorb_singleton_pieces(pieces, cluster_graph) {
621
623
  function partition_into_groups(frontier, band, cluster_graph, group_size) {
622
624
  const membership = new Int32Array(frontier.clusters.length).fill(-1);
623
625
 
626
+ /**
627
+ * Dense rather than a `Map`, and hoisted out of the component loop so it is one allocation per
628
+ * level. See {@link vgeo_partition_subgraph} for why the density is load-bearing rather than a
629
+ * micro-optimisation.
630
+ * @type {Uint32Array}
631
+ */
632
+ const local_index = new Uint32Array(frontier.clusters.length);
633
+
624
634
  for (const cluster of band) {
625
635
  membership[cluster] = 0;
626
636
  }
@@ -692,55 +702,11 @@ function partition_into_groups(frontier, band, cluster_graph, group_size) {
692
702
  membership[cluster] = token;
693
703
  }
694
704
 
695
- const local_index = new Map();
696
-
697
- component.forEach((cluster, index) => local_index.set(cluster, index));
698
-
699
- const local_addresses = new Uint32Array(component.length + 1);
700
- const local_adjacency = [];
701
- const local_weights = [];
702
-
703
- component.forEach((cluster, index) => {
704
- local_addresses[index] = local_adjacency.length;
705
-
706
- for (let i = cluster_graph.edge_addresses[cluster]; i < cluster_graph.edge_addresses[cluster + 1]; i++) {
707
- const other = cluster_graph.adjacency[i];
708
-
709
- if (membership[other] !== token) {
710
- continue;
711
- }
712
-
713
- local_adjacency.push(local_index.get(other));
714
- local_weights.push(cluster_graph.edge_weights[i]);
715
- }
716
- });
717
-
718
- local_addresses[component.length] = local_adjacency.length;
719
-
720
- const assignment = vgeo_partition_graph(
721
- component.length,
722
- part_count,
723
- local_addresses,
724
- Uint32Array.from(local_adjacency),
725
- Float32Array.from(local_weights),
726
- GROUP_SEED
705
+ const parts = vgeo_partition_subgraph(
706
+ cluster_graph, component, membership, token, part_count, GROUP_SEED, local_index
727
707
  );
728
708
 
729
- const parts = [];
730
-
731
- for (let i = 0; i < part_count; i++) {
732
- parts.push([]);
733
- }
734
-
735
- component.forEach((cluster, index) => {
736
- parts[assignment[index]].push(cluster);
737
- });
738
-
739
709
  for (const part of parts) {
740
- if (part.length === 0) {
741
- continue;
742
- }
743
-
744
710
  token++;
745
711
 
746
712
  for (const cluster of part) {
@@ -0,0 +1,19 @@
1
+ /**
2
+ * The root cluster has no simplification step above it, so nothing grouped it, and the format still
3
+ * wants every cluster in exactly one group. It gets a group of its own: the always-selectable entry
4
+ * point the runtime starts its cut from.
5
+ *
6
+ * There is exactly one of these because the DAG has exactly one root — a build that ends with
7
+ * several parentless clusters has not finished, and bundling them into a synthetic group would only
8
+ * hide that (see `vgeo_build_levels`).
9
+ *
10
+ * @param {VirtualGeometryCluster} cluster the root
11
+ * @param {number} level
12
+ * @returns {VirtualGeometryGroup}
13
+ *
14
+ * @author Alex Goldring
15
+ * @copyright Company Named Limited (c) 2026
16
+ */
17
+ export function vgeo_build_root_group(cluster: VirtualGeometryCluster, level: number): VirtualGeometryGroup;
18
+ import { VirtualGeometryGroup } from "../../format/dag/VirtualGeometryGroup.js";
19
+ //# sourceMappingURL=vgeo_build_root_group.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vgeo_build_root_group.d.ts","sourceRoot":"","sources":["../../../../../../../../src/shade/renderer/geometry/virtual/build/level/vgeo_build_root_group.js"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;GAeG;AACH,8EANW,MAAM,GACJ,oBAAoB,CAYhC;qCAzBoC,0CAA0C"}
@@ -1,4 +1,4 @@
1
- import { VirtualGeometryGroup } from "../format/dag/VirtualGeometryGroup.js";
1
+ import { VirtualGeometryGroup } from "../../format/dag/VirtualGeometryGroup.js";
2
2
 
3
3
  /**
4
4
  * The root cluster has no simplification step above it, so nothing grouped it, and the format still
@@ -0,0 +1,73 @@
1
+ /**
2
+ * A level of geometry as the builder handles it: a `BinaryTopology` carrying the positions, the
3
+ * connectivity, and the per-vertex attributes all together.
4
+ *
5
+ * Everything per-vertex lives in the topology. It has to: an edge collapse moves and removes
6
+ * vertices, and the topology is the only thing that knows which. A vertex data layer is addressed
7
+ * by vertex id and sized by the vertex pool, so a channel cannot fall out of step with the mesh it
8
+ * describes — there is no second array to resize, no invariant to assert, and no way for the
9
+ * simplifier to leave a live vertex without a slot.
10
+ *
11
+ * The channels are named by their index into {@link VGEO_ATTRIBUTES}, which is the format's frozen
12
+ * table — {@link layers} has one slot per entry, holding a layer or null.
13
+ *
14
+ * @author Alex Goldring
15
+ * @copyright Company Named Limited (c) 2026
16
+ */
17
+ export class VirtualGeometryMesh {
18
+ /**
19
+ * Take a geometry apart into the form the builder simplifies: its positions and index become a
20
+ * topology, its other attributes become vertex data layers on that same topology.
21
+ *
22
+ * The attribute values are copied in, not adopted. The builder re-derives the shading frame as
23
+ * it coarsens, and the caller's geometry is no longer where that lands.
24
+ *
25
+ * The normal and tangent channels are declared whether or not the geometry carries them: they
26
+ * are what the shading model reads, so the builder owes an asset both. What it does not have,
27
+ * {@link synthesized} records, and {@link vgeo_normalize_source} fills.
28
+ *
29
+ * @param {Geometry} geometry triangles, with a position attribute; the index is synthesized when
30
+ * the geometry does not carry one
31
+ * @returns {VirtualGeometryMesh}
32
+ */
33
+ static from_geometry(geometry: Geometry): VirtualGeometryMesh;
34
+ /**
35
+ * @param {BinaryTopology} topology
36
+ * @param {(BinaryDataLayer|null)[]} layers declared on `topology`
37
+ */
38
+ constructor(topology: BinaryTopology, layers: (BinaryDataLayer | null)[]);
39
+ /**
40
+ * Positions, connectivity, and the vertex data block the {@link layers} address.
41
+ * @type {BinaryTopology}
42
+ */
43
+ topology: BinaryTopology;
44
+ /**
45
+ * One slot per {@link VGEO_ATTRIBUTES} entry, holding the vertex data layer that carries that
46
+ * channel or null where this geometry does not carry it.
47
+ * {@link VGEO_ATTRIBUTE.POSITION}'s slot is always null — position is the topology's own.
48
+ * @type {(BinaryDataLayer|null)[]}
49
+ */
50
+ layers: (BinaryDataLayer | null)[];
51
+ /**
52
+ * One flag per {@link VGEO_ATTRIBUTES} entry, true where the channel exists because the builder
53
+ * added it rather than because the source geometry carried it.
54
+ *
55
+ * Read once, by {@link vgeo_normalize_source}, and for one reason: a synthesized channel has to
56
+ * be derived from the *welded* mesh, which does not exist yet when the channel is declared.
57
+ * Normalization fuses coincident vertices, and a normal derived before that fuse is the average
58
+ * of one side of a seam — the very defect deriving it is supposed to avoid.
59
+ *
60
+ * An authored channel is never among these. A hand-tuned normal is data, and the builder is not
61
+ * entitled to replace it.
62
+ *
63
+ * @type {boolean[]}
64
+ */
65
+ synthesized: boolean[];
66
+ /**
67
+ * Ids of every allocated face, ascending.
68
+ * @returns {number[]}
69
+ */
70
+ face_ids(): number[];
71
+ }
72
+ import { BinaryTopology } from "../../../../../../core/geom/3d/topology/struct/binary/BinaryTopology.js";
73
+ //# sourceMappingURL=VirtualGeometryMesh.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"VirtualGeometryMesh.d.ts","sourceRoot":"","sources":["../../../../../../../../src/shade/renderer/geometry/virtual/build/mesh/VirtualGeometryMesh.js"],"names":[],"mappings":"AAUA;;;;;;;;;;;;;;;GAeG;AACH;IA6CI;;;;;;;;;;;;;;OAcG;IACH,0CAFa,mBAAmB,CA8G/B;IAzID;;;OAGG;IACH,sBAHW,cAAc,UACd,CAAC,kBAAgB,IAAI,CAAC,EAAE,EAUlC;IA1CD;;;OAGG;IACH,UAFU,cAAc,CAER;IAEhB;;;;;OAKG;IACH,QAFU,CAAC,kBAAgB,IAAI,CAAC,EAAE,CAEtB;IAEZ;;;;;;;;;;;;;OAaG;IACH,aAFU,OAAO,EAAE,CAEyC;IA6I5D;;;OAGG;IACH,YAFa,MAAM,EAAE,CAcpB;CACJ;+BApN8B,yEAAyE"}
@@ -1,12 +1,12 @@
1
- import { assert } from "../../../../../core/assert.js";
2
- import { BinaryTopology } from "../../../../../core/geom/3d/topology/struct/binary/BinaryTopology.js";
1
+ import { assert } from "../../../../../../core/assert.js";
2
+ import { BinaryTopology } from "../../../../../../core/geom/3d/topology/struct/binary/BinaryTopology.js";
3
3
  import {
4
4
  bt_mesh_from_indexed_geometry
5
- } from "../../../../../core/geom/3d/topology/struct/binary/io/bt_mesh_from_indexed_geometry.js";
6
- import { StandardAttributes } from "../../StandardAttributes.js";
7
- import { vgeo_layers_declare } from "../format/attribute/vgeo_layers_declare.js";
8
- import { VGEO_ATTRIBUTE } from "../format/attribute/VGEO_ATTRIBUTE.js";
9
- import { VGEO_ATTRIBUTES } from "../format/attribute/VGEO_ATTRIBUTES.js";
5
+ } from "../../../../../../core/geom/3d/topology/struct/binary/io/bt_mesh_from_indexed_geometry.js";
6
+ import { StandardAttributes } from "../../../StandardAttributes.js";
7
+ import { vgeo_layers_declare } from "../../format/attribute/vgeo_layers_declare.js";
8
+ import { VGEO_ATTRIBUTE } from "../../format/attribute/VGEO_ATTRIBUTE.js";
9
+ import { VGEO_ATTRIBUTES } from "../../format/attribute/VGEO_ATTRIBUTES.js";
10
10
 
11
11
  /**
12
12
  * A level of geometry as the builder handles it: a `BinaryTopology` carrying the positions, the
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Area-weighted vertex normals of a mesh, written into its normal channel.
3
+ *
4
+ * The geometry a mesh actually has is the answer for that mesh: carrying a surviving vertex's
5
+ * original normal through a dozen collapses shades a coarse level by whichever vertices happened to
6
+ * win, which is visibly wrong.
7
+ *
8
+ * **Except where the vertex was pinned.** A pinned vertex is one the step was forbidden to move, and
9
+ * every group that touches it carries it — which is exactly what lets a cut place two levels of
10
+ * detail side by side without a crack. That guarantee has to cover what the vertex *carries*, not
11
+ * only where it is: recomputed here, a pinned vertex would get the average of the faces on this
12
+ * side of the seam only, the group across the seam would get the average of its own, and the two
13
+ * would disagree by however much the surface turns. So a pinned vertex keeps what it had, exactly
14
+ * as it keeps where it was, and the frame stays continuous across every cut the DAG admits.
15
+ *
16
+ * The pass itself is {@link bt_mesh_compute_vertex_normals}; all this adds is the pin rule and
17
+ * lifting its result out of the topology's own normal slots and into the format's normal attribute,
18
+ * which is where the encoder reads from.
19
+ *
20
+ * @param {VirtualGeometryMesh} mesh whose normal layer is sized by the vertex pool and so carries a
21
+ * slot for every live vertex by construction
22
+ * @param {Set<number>} pinned vertex ids to leave exactly as they are; empty for a mesh nothing has
23
+ * locked yet
24
+ *
25
+ * @author Alex Goldring
26
+ * @copyright Company Named Limited (c) 2026
27
+ */
28
+ export function vgeo_compute_vertex_normals(mesh: VirtualGeometryMesh, pinned: Set<number>): void;
29
+ //# sourceMappingURL=vgeo_compute_vertex_normals.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vgeo_compute_vertex_normals.d.ts","sourceRoot":"","sources":["../../../../../../../../src/shade/renderer/geometry/virtual/build/mesh/vgeo_compute_vertex_normals.js"],"names":[],"mappings":"AAYA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,+EANW,IAAI,MAAM,CAAC,QAyCrB"}
@@ -1,8 +1,8 @@
1
- import { assert } from "../../../../../core/assert.js";
1
+ import { assert } from "../../../../../../core/assert.js";
2
2
  import {
3
3
  bt_mesh_compute_vertex_normals
4
- } from "../../../../../core/geom/3d/topology/struct/binary/io/bt_mesh_compute_vertex_normals.js";
5
- import { VGEO_ATTRIBUTE } from "../format/attribute/VGEO_ATTRIBUTE.js";
4
+ } from "../../../../../../core/geom/3d/topology/struct/binary/io/bt_mesh_compute_vertex_normals.js";
5
+ import { VGEO_ATTRIBUTE } from "../../format/attribute/VGEO_ATTRIBUTE.js";
6
6
 
7
7
  /**
8
8
  * One vertex's normal, on its way out of the topology's slot and into the format's channel.
@@ -0,0 +1,31 @@
1
+ /**
2
+ * Vertex tangents of a mesh, written into its tangent channel.
3
+ *
4
+ * A tangent is a direction *in the texture parameterization*, so where the mesh carries a `UV0` this
5
+ * is Lengyel's per-triangle solve accumulated per vertex and orthogonalized against the normal —
6
+ * {@link geometry_build_tangents}, the same pass {@link Geometry#computeTangents} runs, so an asset
7
+ * that goes through the virtual-geometry builder gets the frame it would have got anywhere else.
8
+ * Where the mesh carries no UVs there is no parameterization to be tangent to, and the frame becomes
9
+ * an arbitrary but well-conditioned basis around the normal — Frisvad's, via
10
+ * {@link build_tangent_from_normal}. That is not a fallback for a broken input: a shading model that
11
+ * reads a tangent frame reads one whether or not the surface is textured, and the alternative is
12
+ * the format's flat default, which is parallel to the normal over a whole band of any closed
13
+ * surface and degenerates the frame there.
14
+ *
15
+ * `pinned` carries the same meaning and the same reason as it does for
16
+ * {@link vgeo_compute_vertex_normals}: a vertex two groups share must carry byte-identical values in
17
+ * both, or the seam a cut is allowed to put between them shades as a crease.
18
+ *
19
+ * The flat arrays this builds are indexed by *vertex id*, holes and all, so a pool with released
20
+ * slots needs no compaction and no remap — a released slot is simply a triangle corner nothing
21
+ * names.
22
+ *
23
+ * @param {VirtualGeometryMesh} mesh whose tangent and normal layers are sized by the vertex pool
24
+ * @param {Set<number>} pinned vertex ids to leave exactly as they are; empty for a mesh nothing has
25
+ * locked yet
26
+ *
27
+ * @author Alex Goldring
28
+ * @copyright Company Named Limited (c) 2026
29
+ */
30
+ export function vgeo_compute_vertex_tangents(mesh: VirtualGeometryMesh, pinned: Set<number>): void;
31
+ //# sourceMappingURL=vgeo_compute_vertex_tangents.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vgeo_compute_vertex_tangents.d.ts","sourceRoot":"","sources":["../../../../../../../../src/shade/renderer/geometry/virtual/build/mesh/vgeo_compute_vertex_tangents.js"],"names":[],"mappings":"AAoBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,gFANW,IAAI,MAAM,CAAC,QAmGrB"}
@@ -1,10 +1,10 @@
1
- import { assert } from "../../../../../core/assert.js";
1
+ import { assert } from "../../../../../../core/assert.js";
2
2
  import {
3
3
  bt_face_read_triangle_vertices
4
- } from "../../../../../core/geom/3d/topology/struct/binary/query/bt_face_read_triangle.js";
5
- import { build_tangent_from_normal } from "../../normals/build_tangent_from_normal.js";
6
- import { geometry_build_tangents } from "../../normals/geometry_build_tangents.js";
7
- import { VGEO_ATTRIBUTE } from "../format/attribute/VGEO_ATTRIBUTE.js";
4
+ } from "../../../../../../core/geom/3d/topology/struct/binary/query/bt_face_read_triangle.js";
5
+ import { build_tangent_from_normal } from "../../../normals/build_tangent_from_normal.js";
6
+ import { geometry_build_tangents } from "../../../normals/geometry_build_tangents.js";
7
+ import { VGEO_ATTRIBUTE } from "../../format/attribute/VGEO_ATTRIBUTE.js";
8
8
 
9
9
  /**
10
10
  * One vertex's tangent, on its way into the format's channel.
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Bring a source mesh to the state the level loop assumes: no edge shorter than the weld tolerance,
3
+ * coincident vertices fused, nothing dangling, and consistent topology.
4
+ *
5
+ * The short-edge pass is not optional — the merge's own contract requires it, because merging two
6
+ * vertices that share a face leaves a loop cycle visiting one vertex twice, and no boundary walk can
7
+ * get through the non-manifold edge that produces.
8
+ *
9
+ * It **collapses** those edges rather than killing them, and the difference is the whole surface.
10
+ * `bt_mesh_kill_short_edges` deletes both faces of every edge it names, which is right for a soup
11
+ * and wrong here: the weld behind it closes most of the resulting holes and leaves the rest, and a
12
+ * hole left in the source is a hole in every level of the DAG built on it. Measured on the Stanford
13
+ * dragon, closed to begin with: killing opened 18,438 boundary edges and left 281 of them standing;
14
+ * collapsing leaves none.
15
+ *
16
+ * Neither is the fuse that follows it. The merge re-points vertex references but leaves the two
17
+ * edges that now connect the same pair as two distinct edges, and face adjacency is read off radial
18
+ * cycles — so without the fuse, two triangles welded along a seam still look unrelated to every
19
+ * query downstream, and the clusterer shreds the mesh along every UV seam it has.
20
+ *
21
+ * Nor is the degenerate-face kill. The short-edge pass clears the pairs an *edge* is short enough to
22
+ * name, but the merge is a hash grid: two corners of one face up to twice the tolerance apart can
23
+ * still land on a common master and become one vertex, leaving a face that visits it twice.
24
+ *
25
+ * The tolerance is a fraction of the mesh's own size rather than a distance, and it is resolved here
26
+ * — once, off the source's bounds, before any pass has removed anything — so every pass below welds
27
+ * the same amount of the same surface. A conversion is many geometries at many sizes, and there is
28
+ * no one distance that is right for all of them.
29
+ *
30
+ * The shading frame is regularized too, and last. A geometry that arrived without normals or without
31
+ * tangents is given them here rather than at the door, because *here* is the first point at which
32
+ * the mesh is the one the rest of the build will see: derived before the weld, a normal at a seam
33
+ * vertex would be the average of whichever side of the seam the exporter happened to split it into,
34
+ * and the fuse would then pick one of those halves to keep. Derived after it, the vertex has its
35
+ * whole ring. Channels the source did carry are left exactly as they came.
36
+ *
37
+ * @param {VirtualGeometryMesh} mesh mutated in place
38
+ * @param {number} weld_ratio fraction of the bounding-box diagonal; see
39
+ * {@link VGeoBuildOptions#weld_ratio}
40
+ * @returns {number} the object-space distance the ratio came to for this mesh
41
+ *
42
+ * @author Alex Goldring
43
+ * @copyright Company Named Limited (c) 2026
44
+ */
45
+ export function vgeo_normalize_source(mesh: VirtualGeometryMesh, weld_ratio: number): number;
46
+ //# sourceMappingURL=vgeo_normalize_source.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vgeo_normalize_source.d.ts","sourceRoot":"","sources":["../../../../../../../../src/shade/renderer/geometry/virtual/build/mesh/vgeo_normalize_source.js"],"names":[],"mappings":"AA+BA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2CG;AACH,6EAPW,MAAM,GAEJ,MAAM,CAyClB"}
@@ -1,24 +1,24 @@
1
- import { assert } from "../../../../../core/assert.js";
1
+ import { assert } from "../../../../../../core/assert.js";
2
2
  import {
3
3
  bt_mesh_cleanup_faceless_references
4
- } from "../../../../../core/geom/3d/topology/struct/binary/io/bt_mesh_cleanup_faceless_references.js";
4
+ } from "../../../../../../core/geom/3d/topology/struct/binary/io/bt_mesh_cleanup_faceless_references.js";
5
5
  import {
6
6
  bt_mesh_collapse_short_edges
7
- } from "../../../../../core/geom/3d/topology/struct/binary/io/edge/bt_mesh_collapse_short_edges.js";
7
+ } from "../../../../../../core/geom/3d/topology/struct/binary/io/edge/bt_mesh_collapse_short_edges.js";
8
8
  import {
9
9
  bt_mesh_fuse_duplicate_edges
10
- } from "../../../../../core/geom/3d/topology/struct/binary/io/edge/bt_mesh_fuse_duplicate_edges.js";
10
+ } from "../../../../../../core/geom/3d/topology/struct/binary/io/edge/bt_mesh_fuse_duplicate_edges.js";
11
11
  import {
12
12
  bt_mesh_kill_degenerate_faces
13
- } from "../../../../../core/geom/3d/topology/struct/binary/io/face/bt_mesh_kill_degenerate_faces.js";
13
+ } from "../../../../../../core/geom/3d/topology/struct/binary/io/face/bt_mesh_kill_degenerate_faces.js";
14
14
  import {
15
15
  bt_merge_vertices_by_distance
16
- } from "../../../../../core/geom/3d/topology/struct/binary/io/vertex/bt_merge_vertices_by_distance.js";
16
+ } from "../../../../../../core/geom/3d/topology/struct/binary/io/vertex/bt_merge_vertices_by_distance.js";
17
17
  import {
18
18
  bt_mesh_relative_merge_distance
19
- } from "../../../../../core/geom/3d/topology/struct/binary/io/vertex/bt_mesh_relative_merge_distance.js";
20
- import { bt_mesh_validate } from "../../../../../core/geom/3d/topology/struct/binary/query/bt_mesh_validate.js";
21
- import { VGEO_ATTRIBUTE } from "../format/attribute/VGEO_ATTRIBUTE.js";
19
+ } from "../../../../../../core/geom/3d/topology/struct/binary/io/vertex/bt_mesh_relative_merge_distance.js";
20
+ import { bt_mesh_validate } from "../../../../../../core/geom/3d/topology/struct/binary/query/bt_mesh_validate.js";
21
+ import { VGEO_ATTRIBUTE } from "../../format/attribute/VGEO_ATTRIBUTE.js";
22
22
  import { vgeo_compute_vertex_normals } from "./vgeo_compute_vertex_normals.js";
23
23
  import { vgeo_compute_vertex_tangents } from "./vgeo_compute_vertex_tangents.js";
24
24
 
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Assign groups to pages.
3
+ *
4
+ * @param {VirtualGeometryGroup[][]} groups_by_level indexed by level; every group of every level,
5
+ * including the root level's
6
+ * @param {Float32Array} object_bounds `[min xyz, max xyz]` of the whole geometry, for the Morton grid
7
+ * @param {number} nominal_page_size decoded bytes per page, as a hard cap: no returned page decodes
8
+ * to more, and a group that cannot fit one on its own throws
9
+ * @returns {VirtualGeometryPage[]} in file order, root page first
10
+ */
11
+ export function vgeo_assemble_pages(groups_by_level: VirtualGeometryGroup[][], object_bounds: Float32Array, nominal_page_size: number): VirtualGeometryPage[];
12
+ import { VirtualGeometryPage } from "../../format/dag/VirtualGeometryPage.js";
13
+ //# sourceMappingURL=vgeo_assemble_pages.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vgeo_assemble_pages.d.ts","sourceRoot":"","sources":["../../../../../../../../src/shade/renderer/geometry/virtual/build/page/vgeo_assemble_pages.js"],"names":[],"mappings":"AAwMA;;;;;;;;;GASG;AACH,qDAPW,sBAAsB,EAAE,iBAExB,YAAY,qBACZ,MAAM,GAEJ,mBAAmB,EAAE,CAiIjC;oCAzUmC,yCAAyC"}
@@ -1,12 +1,12 @@
1
- import { assert } from "../../../../../core/assert.js";
2
- import { v3_morton_encode_bounded } from "../../../../../core/geom/3d/morton/v3_morton_encode_bounded.js";
3
- import { VGEO_CLUSTER_RECORD_SIZE } from "../format/cluster/VGEO_CLUSTER_RECORD_SIZE.js";
4
- import { VGEO_GROUP_RECORD_SIZE } from "../format/page/VGEO_GROUP_RECORD_SIZE.js";
5
- import { VGEO_NODE_RECORD_SIZE } from "../format/page/VGEO_NODE_RECORD_SIZE.js";
6
- import { VGEO_PAGE_HEADER_SIZE } from "../format/page/VGEO_PAGE_HEADER_SIZE.js";
7
- import { VGEO_PARENT_ENTRY_SIZE } from "../format/page/VGEO_PARENT_ENTRY_SIZE.js";
8
- import { VGEO_PARENT_PAGE_ENTRY_SIZE } from "../format/page/VGEO_PARENT_PAGE_ENTRY_SIZE.js";
9
- import { VirtualGeometryPage } from "../format/dag/VirtualGeometryPage.js";
1
+ import { assert } from "../../../../../../core/assert.js";
2
+ import { v3_morton_encode_bounded } from "../../../../../../core/geom/3d/morton/v3_morton_encode_bounded.js";
3
+ import { VGEO_CLUSTER_RECORD_SIZE } from "../../format/cluster/VGEO_CLUSTER_RECORD_SIZE.js";
4
+ import { VGEO_GROUP_RECORD_SIZE } from "../../format/page/VGEO_GROUP_RECORD_SIZE.js";
5
+ import { VGEO_NODE_RECORD_SIZE } from "../../format/page/VGEO_NODE_RECORD_SIZE.js";
6
+ import { VGEO_PAGE_HEADER_SIZE } from "../../format/page/VGEO_PAGE_HEADER_SIZE.js";
7
+ import { VGEO_PARENT_ENTRY_SIZE } from "../../format/page/VGEO_PARENT_ENTRY_SIZE.js";
8
+ import { VGEO_PARENT_PAGE_ENTRY_SIZE } from "../../format/page/VGEO_PARENT_PAGE_ENTRY_SIZE.js";
9
+ import { VirtualGeometryPage } from "../../format/dag/VirtualGeometryPage.js";
10
10
  import { vgeo_build_page_nodes } from "./vgeo_build_page_nodes.js";
11
11
  import { vgeo_page_node_count } from "./vgeo_page_node_count.js";
12
12
 
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Build the tree over a page's groups.
3
+ *
4
+ * Breadth-first, so that a node's children occupy a contiguous run of indices and every parent sits
5
+ * at a lower index than its children — which is what lets the metric be filled in by one backwards
6
+ * sweep, and what lets a reader walk the tree without a stack of anything but indices.
7
+ *
8
+ * @param {VirtualGeometryPage} page whose `groups` are already in the order they will be written
9
+ * @returns {VirtualGeometryPageNode[]} the tree, root first; never empty
10
+ */
11
+ export function vgeo_build_page_nodes(page: VirtualGeometryPage): VirtualGeometryPageNode[];
12
+ import { VirtualGeometryPageNode } from "../../format/dag/VirtualGeometryPageNode.js";
13
+ //# sourceMappingURL=vgeo_build_page_nodes.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vgeo_build_page_nodes.d.ts","sourceRoot":"","sources":["../../../../../../../../src/shade/renderer/geometry/virtual/build/page/vgeo_build_page_nodes.js"],"names":[],"mappings":"AAsDA;;;;;;;;;GASG;AACH,kEAFa,uBAAuB,EAAE,CA8FrC;wCAvJuC,6CAA6C"}
@@ -1,9 +1,9 @@
1
- import { assert } from "../../../../../core/assert.js";
1
+ import { assert } from "../../../../../../core/assert.js";
2
2
  import {
3
3
  sphere_compute_bounding_of_2_spheres
4
- } from "../../../../../core/geom/3d/sphere/sphere_compute_bounding_of_2_spheres.js";
5
- import { VGEO_NODE_FANOUT } from "../format/page/VGEO_NODE_FANOUT.js";
6
- import { VirtualGeometryPageNode } from "../format/dag/VirtualGeometryPageNode.js";
4
+ } from "../../../../../../core/geom/3d/sphere/sphere_compute_bounding_of_2_spheres.js";
5
+ import { VGEO_NODE_FANOUT } from "../../format/page/VGEO_NODE_FANOUT.js";
6
+ import { VirtualGeometryPageNode } from "../../format/dag/VirtualGeometryPageNode.js";
7
7
 
8
8
  /**
9
9
  * Build a page's group tree, and the page's own metric with it.