@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,481 +0,0 @@
1
- import { assert } from "../../../core/assert.js";
2
- import { DEG_TO_RAD } from "../../../core/math/DEG_TO_RAD.js";
3
- import {
4
- VGeoPageWant
5
- } from "../../renderer/geometry/virtual/format/read/VGeoPageWant.js";
6
- import { VGEO_NO_CHILD } from "../../renderer/geometry/virtual/format/cluster/VGEO_NO_CHILD.js";
7
- import { VGEO_SAME_PAGE } from "../../renderer/geometry/virtual/format/cluster/VGEO_SAME_PAGE.js";
8
-
9
- /**
10
- * Selecting a cut from a partially resident container.
11
- *
12
- * The traversal itself is the runtime's rule, not a debug approximation of it: descend the page
13
- * graph from the root's parentless groups, refine a cluster whose error projects above τ, take it
14
- * when it does not. What this file adds is the part a whole-file reader never has to think about —
15
- * what to do when the page a refinement wants is not here.
16
- *
17
- * The answer is the format's (`VGEO_FORMAT.md` §10): **draw the coarser cluster and say so**. The
18
- * result is a genuine surface — watertight, correct, merely coarser in that region — and the want it
19
- * records carries the exact byte range that would refine it. That is what makes streaming safe in
20
- * any arrival order, and it is why this file's most interesting number is `clamped`.
21
- *
22
- * "Not here" is `VGeoContainerReader.is_selectable`, not `is_resident`, and the difference is the
23
- * one thing about this traversal that is not obvious: a group is refined into only once every page
24
- * holding one of its *parents* is installed. Residency alone lets a group be entered through the
25
- * parents that arrived while a coarse cluster still covers the one that did not, and then both are
26
- * drawn over the same surface. §10 calls that out by name — "no holes **and no double-draw**, in any
27
- * arrival order" — and the second half is the one that fails silently.
28
- *
29
- * @author Alex Goldring
30
- * @copyright Company Named Limited (c) 2026
31
- */
32
-
33
- /**
34
- * The view a cut is selected for. `VIRTUAL_GEOMETRY_DESIGN.md` §4: a cut is selected at one camera's
35
- * distances and pixel budget, and is the wrong cut for any other.
36
- */
37
- export class VGeoCutView {
38
- /**
39
- * Camera position, object space — the viewer draws at identity, so world and object agree.
40
- * @type {Float32Array}
41
- */
42
- eye = new Float32Array(3);
43
-
44
- /**
45
- * Pixels of permitted error. The one quality dial.
46
- * @type {number}
47
- */
48
- tau = 1;
49
-
50
- /**
51
- * Height of the render target, in pixels — the projection's numerator.
52
- * @type {number}
53
- */
54
- screen_height = 1080;
55
-
56
- /**
57
- * @type {number}
58
- */
59
- fov_y = 60 * DEG_TO_RAD;
60
-
61
- /**
62
- * @type {boolean}
63
- */
64
- cull_enabled = false;
65
-
66
- /**
67
- * Six normalized world-space planes, as {@link Camera.frustum} holds them.
68
- * @type {Float32Array}
69
- */
70
- frustum = new Float32Array(24);
71
- }
72
-
73
- /**
74
- * What one traversal came to, including what it had to look at to get there and what it could not
75
- * reach.
76
- *
77
- * A cut holds the {@link VGeoPage} objects it selected from rather than page indices, so it stays
78
- * drawable across an eviction: the bytes it needs are reachable from the cut itself. Nothing here
79
- * goes stale because residency moved under it.
80
- */
81
- export class VGeoCut {
82
- /**
83
- * The page each selected cluster came from, parallel to {@link clusters}.
84
- * @type {VGeoPage[]}
85
- */
86
- pages = [];
87
-
88
- /**
89
- * Selected clusters, as indices within the page at the same position of {@link pages}. There is
90
- * no global cluster id in the format and none in the reader; a cluster is a page and an index.
91
- * @type {number[]}
92
- */
93
- clusters = [];
94
-
95
- /**
96
- * @type {number}
97
- */
98
- triangle_count = 0;
99
-
100
- /**
101
- * @type {number}
102
- */
103
- vertex_count = 0;
104
-
105
- /**
106
- * @type {number}
107
- */
108
- groups_visited = 0;
109
-
110
- /**
111
- * @type {number}
112
- */
113
- clusters_tested = 0;
114
-
115
- /**
116
- * Clusters whose subtree the frustum threw away, which is a whole region rather than one
117
- * cluster — the reason culling belongs in the traversal and not after it.
118
- * @type {number}
119
- */
120
- culled = 0;
121
-
122
- /**
123
- * Clusters that projected above τ and were drawn anyway, because the page holding their
124
- * refinement is not resident.
125
- *
126
- * **This is the number that says a cut is still arriving.** Zero means the cut on screen is the
127
- * one the container's own metric selects for this view; anything above it means part of the
128
- * surface is standing in for something finer, and {@link wants} says exactly what to fetch to
129
- * fix it.
130
- *
131
- * @type {number}
132
- */
133
- clamped = 0;
134
-
135
- /**
136
- * Of those, the ones whose child group's page is **here** and merely not selectable yet, because
137
- * a page holding one of that group's other parents is not.
138
- *
139
- * They carry no want: there is nothing to fetch from a cluster that already has the bytes it
140
- * points at. What unblocks them is elsewhere in the same cut — the cluster clamped directly
141
- * against the missing page — so this number is not a second streaming frontier, it is how much
142
- * of the coarseness on screen is the ancestor rule holding a group back rather than bandwidth.
143
- *
144
- * @type {number}
145
- */
146
- clamped_on_activation = 0;
147
-
148
- /**
149
- * Which clusters those were, keyed `page · 65536 + cluster`. What the panel counts, a display
150
- * can paint — so the regions still waiting on bytes are visible as regions.
151
- * @type {Set<number>}
152
- */
153
- clamped_keys = new Set();
154
-
155
- /**
156
- * Clusters whose `child_ref` names an entry outside their page's child table.
157
- *
158
- * Impossible in a file the validator accepts, and reachable here precisely because validation is
159
- * off by default — so it is counted and the cluster is drawn as a leaf, rather than read out of
160
- * bounds or thrown out of a traversal that was two thirds of the way to a picture.
161
- *
162
- * @type {number}
163
- */
164
- broken_child_refs = 0;
165
-
166
- /**
167
- * The pages this cut would need to stop being clamped, one entry per page, most wanted first.
168
- * @type {VGeoPageWant[]}
169
- */
170
- wants = [];
171
-
172
- /**
173
- * Distinct pages the traversal read from.
174
- * @type {number}
175
- */
176
- pages_touched = 0;
177
-
178
- /**
179
- * @type {number}
180
- */
181
- duration_ms = 0;
182
- }
183
-
184
- /**
185
- * `VIRTUAL_GEOMETRY_DESIGN.md` §4: `err_px = r_e · screen_height / (2 · tan(fov_y / 2) · d)`, with
186
- * `d` the distance to the *closest point* of the sphere.
187
- *
188
- * A zero error projects to zero unconditionally — otherwise a leaf, whose error is exactly zero,
189
- * would become undrawable the moment the camera entered its sphere.
190
- *
191
- * @param {number} error object-space `r_e`; `+Infinity` for a root's parent
192
- * @param {Float32Array} spheres
193
- * @param {number} base index of the sphere's first component
194
- * @param {Float32Array} eye
195
- * @param {number} k `screen_height / (2 · tan(fov_y / 2))`, hoisted out of the loop
196
- * @returns {number} pixels
197
- */
198
- function project_error(error, spheres, base, eye, k) {
199
- if (error === 0) {
200
- return 0;
201
- }
202
-
203
- const dx = eye[0] - spheres[base];
204
- const dy = eye[1] - spheres[base + 1];
205
- const dz = eye[2] - spheres[base + 2];
206
-
207
- const distance = Math.sqrt(dx * dx + dy * dy + dz * dz) - spheres[base + 3];
208
-
209
- if (distance <= 0) {
210
- // camera inside the sphere; the projection is unbounded and the cluster must refine
211
- return Number.POSITIVE_INFINITY;
212
- }
213
-
214
- return (error * k) / distance;
215
- }
216
-
217
- /**
218
- * Whether a sphere is entirely outside the frustum.
219
- *
220
- * Only the five finite planes are tested. The projection is infinite reverse-Z, so the far plane's
221
- * row is degenerate and normalizing it produces nothing a test can use.
222
- *
223
- * @param {Float32Array} frustum
224
- * @param {Float32Array} spheres
225
- * @param {number} base
226
- * @returns {boolean}
227
- */
228
- function sphere_outside_frustum(frustum, spheres, base) {
229
- const x = spheres[base];
230
- const y = spheres[base + 1];
231
- const z = spheres[base + 2];
232
- const radius = spheres[base + 3];
233
-
234
- for (let plane = 0; plane < 5; plane++) {
235
- const o = plane * 4;
236
-
237
- const distance = frustum[o] * x + frustum[o + 1] * y + frustum[o + 2] * z + frustum[o + 3];
238
-
239
- if (distance < -radius) {
240
- return true;
241
- }
242
- }
243
-
244
- return false;
245
- }
246
-
247
- /**
248
- * Select the cut for a view from whatever the reader currently holds.
249
- *
250
- * A traversal rather than a flat pass over every cluster, per design §4 — and it gets the cut rule's
251
- * first half for free. The rule is `project(parent) > τ AND project(self) ≤ τ`; a group is only ever
252
- * reached by descending *through* the cluster whose step consumed it, and that descent happened
253
- * precisely because the step projected above τ. Every cluster of a group shares that step's sphere
254
- * and error, so the parent test is satisfied by the act of arriving.
255
- *
256
- * The residency clamp is the live one here, and it is the reason a cut can be taken at all before
257
- * the file has finished arriving: a cluster that wants a page nobody has is drawn as it stands.
258
- *
259
- * @param {VGeoContainerReader} reader
260
- * @param {VGeoCutView} view
261
- * @returns {VGeoCut}
262
- */
263
- export function vgeo_select_cut(reader, view) {
264
- assert.defined(reader.root, 'reader.root — the container must be open');
265
-
266
- const started = performance.now();
267
-
268
- const cut = new VGeoCut();
269
-
270
- const k = view.screen_height / (2 * Math.tan(view.fov_y * 0.5));
271
-
272
- /**
273
- * Groups already queued, keyed `page · 65536 + group`. A group is referenced by every sibling
274
- * cluster of the step that consumed it, so without this the traversal would expand it once per
275
- * parent and the cut would carry duplicates.
276
- *
277
- * Multiplied rather than shifted: a page index is a u32, and `<<` would wrap it at the sixteenth
278
- * page of a large asset.
279
- *
280
- * @type {Set<number>}
281
- */
282
- const queued = new Set();
283
-
284
- /**
285
- * @type {Set<number>}
286
- */
287
- const touched = new Set();
288
-
289
- /**
290
- * Wants by page index, so that many clamped clusters wanting one page produce one entry — which
291
- * is also where {@link VGeoPageWant.reference_count} comes from.
292
- * @type {Map<number, VGeoPageWant>}
293
- */
294
- const wants = new Map();
295
-
296
- /**
297
- * Page and group index, interleaved.
298
- * @type {number[]}
299
- */
300
- const stack = [];
301
-
302
- const root = reader.root;
303
-
304
- for (let group = 0; group < root.group_parent_count.length; group++) {
305
- // no cluster anywhere refines into this group, so it is the top of the DAG and selectable
306
- // with nothing above it
307
- if (root.group_parent_count[group] === 0) {
308
- queued.add(group);
309
- stack.push(0, group);
310
- }
311
- }
312
-
313
- while (stack.length > 0) {
314
- const group = stack.pop();
315
- const page_index = stack.pop();
316
-
317
- const page = reader.page(page_index);
318
-
319
- if (page === undefined) {
320
- // Evicted between being queued and being reached. Nothing here fetches, so the subtree
321
- // is simply not selected; the clusters above it were already taken by whoever queued it.
322
- continue;
323
- }
324
-
325
- cut.groups_visited++;
326
- touched.add(page_index);
327
-
328
- const first = page.group_cluster_first[group];
329
- const count = page.group_cluster_count[group];
330
-
331
- for (let i = 0; i < count; i++) {
332
- const id = first + i;
333
-
334
- cut.clusters_tested++;
335
-
336
- /*
337
- Culling on `self_sphere` rather than on the tight `bounds_sphere`, because this decides
338
- the subtree as well as the cluster: monotonicity makes a cluster's self sphere contain
339
- every descendant's geometry, so a self sphere outside the frustum means nothing under
340
- it can be on screen either.
341
- */
342
- if (view.cull_enabled
343
- && sphere_outside_frustum(view.frustum, page.self_sphere, id * 4)) {
344
- cut.culled++;
345
- continue;
346
- }
347
-
348
- const child_ref = page.child_ref[id];
349
-
350
- const self_px = project_error(
351
- page.self_error[id], page.self_sphere, id * 4, view.eye, k
352
- );
353
-
354
- if (self_px <= view.tau || child_ref === VGEO_NO_CHILD) {
355
- select(cut, page, id);
356
- continue;
357
- }
358
-
359
- if (child_ref !== VGEO_SAME_PAGE && child_ref >= page.child_page_index.length) {
360
- cut.broken_child_refs++;
361
-
362
- select(cut, page, id);
363
- continue;
364
- }
365
-
366
- const child_page = child_ref === VGEO_SAME_PAGE
367
- ? page_index
368
- : page.child_page_index[child_ref];
369
-
370
- const child_group = page.child_group[id];
371
-
372
- /*
373
- *Selectable*, not resident — §10, and the difference is the whole of this file's
374
- correctness. A group's parents are made by one simplification step but grouped for the
375
- next one separately, so they can end up in different pages; refining into a group
376
- because its own page arrived, while a page holding one of its other parents has not,
377
- draws it underneath the coarse cluster still standing in for that parent. Both cover the
378
- same surface and the depth buffer picks between them at random. `is_selectable` is the
379
- counter that says the group's entire ancestor cone is here.
380
-
381
- `SAME_PAGE` is asked the same question. Being in this page settles where the bytes are
382
- and nothing about where the group's other parents live.
383
- */
384
- if (reader.is_selectable(child_page, child_group)) {
385
- push(stack, queued, child_page, child_group);
386
- continue;
387
- }
388
-
389
- /*
390
- The clamp. Drawing this cluster is not a fallback for a missing one — it is the correct
391
- coarser surface over exactly the region the missing page would have refined, which is
392
- what makes an arriving cut watertight at every moment rather than only at the end.
393
- */
394
- cut.clamped++;
395
- cut.clamped_keys.add(page_index * 65536 + id);
396
-
397
- select(cut, page, id);
398
-
399
- if (reader.is_resident(child_page)) {
400
- /*
401
- §10: a want naming a page that is already installed is an activation recheck, never
402
- a fetch. There is nothing to ask for *here* — what this group is waiting on is a
403
- page holding one of its other parents, and the format stores parent counts rather
404
- than parent references precisely so that nobody has to name it. Another cluster in
405
- this same traversal is clamped directly against that page and wants it, because
406
- monotonicity puts every ancestor of a cluster projecting above τ above τ as well.
407
- */
408
- cut.clamped_on_activation++;
409
- continue;
410
- }
411
-
412
- want(wants, page, child_ref, child_page, self_px);
413
- }
414
- }
415
-
416
- cut.wants = Array.from(wants.values()).sort((a, b) => b.priority - a.priority);
417
- cut.pages_touched = touched.size;
418
- cut.duration_ms = performance.now() - started;
419
-
420
- return cut;
421
- }
422
-
423
- /**
424
- * @param {VGeoCut} cut
425
- * @param {VGeoPage} page
426
- * @param {number} cluster index within `page`
427
- */
428
- function select(cut, page, cluster) {
429
- cut.pages.push(page);
430
- cut.clusters.push(cluster);
431
-
432
- cut.triangle_count += page.triangle_count[cluster];
433
- cut.vertex_count += page.vertex_count[cluster];
434
- }
435
-
436
- /**
437
- * @param {number[]} stack
438
- * @param {Set<number>} queued
439
- * @param {number} page_index
440
- * @param {number} group
441
- */
442
- function push(stack, queued, page_index, group) {
443
- const key = page_index * 65536 + group;
444
-
445
- if (queued.has(key)) {
446
- return;
447
- }
448
-
449
- queued.add(key);
450
- stack.push(page_index, group);
451
- }
452
-
453
- /**
454
- * Record — or reinforce — a want for the page a clamped cluster could not reach.
455
- *
456
- * Everything the fetch needs comes out of the child table of the page that is already here, which is
457
- * the property (§5) that lets refinement cost one round trip and no metadata request.
458
- *
459
- * @param {Map<number, VGeoPageWant>} wants
460
- * @param {VGeoPage} page the resident page holding the clamped cluster
461
- * @param {number} child_ref index into that page's child table
462
- * @param {number} child_page
463
- * @param {number} projected pixels the clamped cluster's error came to
464
- */
465
- function want(wants, page, child_ref, child_page, projected) {
466
- let record = wants.get(child_page);
467
-
468
- if (record === undefined) {
469
- record = new VGeoPageWant();
470
-
471
- record.page_index = child_page;
472
- record.frame_offset = page.child_frame_offset[child_ref];
473
- record.fetch_size = page.child_fetch_size[child_ref];
474
- record.decoded_size = page.child_decoded_size[child_ref];
475
-
476
- wants.set(child_page, record);
477
- }
478
-
479
- record.reference_count++;
480
- record.priority = Math.max(record.priority, projected);
481
- }