@woosh/meep-engine 3.27.0 → 3.29.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 (648) hide show
  1. package/build/bundle-worker-terrain.js +1 -1
  2. package/package.json +1 -1
  3. package/src/core/binary/BitSet.d.ts +16 -0
  4. package/src/core/binary/BitSet.d.ts.map +1 -1
  5. package/src/core/binary/BitSet.js +159 -49
  6. package/src/core/binary/allocator/OffsetAllocator.d.ts +48 -0
  7. package/src/core/binary/allocator/OffsetAllocator.d.ts.map +1 -1
  8. package/src/core/binary/allocator/OffsetAllocator.js +208 -9
  9. package/src/core/binary/compression/compress_bytes.d.ts +20 -0
  10. package/src/core/binary/compression/compress_bytes.d.ts.map +1 -0
  11. package/src/core/binary/compression/compress_bytes.js +35 -0
  12. package/src/core/binary/compression/decompress_bytes_into.d.ts +30 -0
  13. package/src/core/binary/compression/decompress_bytes_into.d.ts.map +1 -0
  14. package/src/core/binary/compression/decompress_bytes_into.js +87 -0
  15. package/src/core/binary/compression/deflate_decompress_bound.d.ts +27 -0
  16. package/src/core/binary/compression/deflate_decompress_bound.d.ts.map +1 -0
  17. package/src/core/binary/compression/deflate_decompress_bound.js +32 -0
  18. package/src/core/geom/3d/mat4/m4_linear_determinant.d.ts +15 -0
  19. package/src/core/geom/3d/mat4/m4_linear_determinant.d.ts.map +1 -0
  20. package/src/core/geom/3d/mat4/m4_linear_determinant.js +24 -0
  21. package/src/core/geom/3d/mat4/m4_normal_matrix3.d.ts +4 -2
  22. package/src/core/geom/3d/mat4/m4_normal_matrix3.d.ts.map +1 -1
  23. package/src/core/geom/3d/mat4/m4_normal_matrix3.js +21 -11
  24. package/src/core/geom/3d/quadric/quadric_attribute_add.d.ts +24 -0
  25. package/src/core/geom/3d/quadric/quadric_attribute_add.d.ts.map +1 -0
  26. package/src/core/geom/3d/quadric/quadric_attribute_add.js +31 -0
  27. package/src/core/geom/3d/quadric/quadric_attribute_reduce.d.ts +46 -0
  28. package/src/core/geom/3d/quadric/quadric_attribute_reduce.d.ts.map +1 -0
  29. package/src/core/geom/3d/quadric/quadric_attribute_reduce.js +104 -0
  30. package/src/core/geom/3d/quadric/quadric_attribute_set_from_triangle.d.ts +62 -0
  31. package/src/core/geom/3d/quadric/quadric_attribute_set_from_triangle.d.ts.map +1 -0
  32. package/src/core/geom/3d/quadric/quadric_attribute_set_from_triangle.js +158 -0
  33. package/src/core/geom/3d/quadric/quadric_attribute_size.d.ts +21 -0
  34. package/src/core/geom/3d/quadric/quadric_attribute_size.d.ts.map +1 -0
  35. package/src/core/geom/3d/quadric/quadric_attribute_size.js +24 -0
  36. package/src/core/geom/3d/quadric/quadric_attribute_solve.d.ts +34 -0
  37. package/src/core/geom/3d/quadric/quadric_attribute_solve.d.ts.map +1 -0
  38. package/src/core/geom/3d/quadric/quadric_attribute_solve.js +55 -0
  39. package/src/core/geom/3d/quadric/quadric_attribute_sub.d.ts +28 -0
  40. package/src/core/geom/3d/quadric/quadric_attribute_sub.d.ts.map +1 -0
  41. package/src/core/geom/3d/quadric/quadric_attribute_sub.js +35 -0
  42. package/src/core/geom/3d/topology/struct/binary/BinaryDataBlock.d.ts +15 -0
  43. package/src/core/geom/3d/topology/struct/binary/BinaryDataBlock.d.ts.map +1 -1
  44. package/src/core/geom/3d/topology/struct/binary/BinaryDataBlock.js +35 -0
  45. package/src/core/geom/3d/topology/struct/binary/BtWedgeSet.d.ts +93 -0
  46. package/src/core/geom/3d/topology/struct/binary/BtWedgeSet.d.ts.map +1 -0
  47. package/src/core/geom/3d/topology/struct/binary/BtWedgeSet.js +128 -0
  48. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_compute_wedge_attribute_quadrics.d.ts +38 -0
  49. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_compute_wedge_attribute_quadrics.d.ts.map +1 -0
  50. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_compute_wedge_attribute_quadrics.js +113 -0
  51. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_simplify.d.ts +47 -1
  52. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_simplify.d.ts.map +1 -1
  53. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_simplify.js +677 -8
  54. package/src/core/geom/3d/topology/struct/binary/io/bt_wedges_live_count.d.ts +22 -0
  55. package/src/core/geom/3d/topology/struct/binary/io/bt_wedges_live_count.d.ts.map +1 -0
  56. package/src/core/geom/3d/topology/struct/binary/io/bt_wedges_live_count.js +46 -0
  57. package/src/core/geom/3d/topology/struct/binary/io/bt_wedges_per_vertex.d.ts +19 -0
  58. package/src/core/geom/3d/topology/struct/binary/io/bt_wedges_per_vertex.d.ts.map +1 -0
  59. package/src/core/geom/3d/topology/struct/binary/io/bt_wedges_per_vertex.js +49 -0
  60. package/src/core/graph/layout/layered/BoxLayoutOptions.d.ts +63 -0
  61. package/src/core/graph/layout/layered/BoxLayoutOptions.d.ts.map +1 -0
  62. package/src/core/graph/layout/layered/BoxLayoutOptions.js +80 -0
  63. package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/LayoutBoxGraph.d.ts +35 -0
  64. package/src/core/graph/layout/layered/LayoutBoxGraph.d.ts.map +1 -0
  65. package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/LayoutBoxGraph.js +53 -1
  66. package/src/core/graph/layout/layered/layout_assign_coordinates.d.ts.map +1 -0
  67. package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_assign_coordinates.js +72 -68
  68. package/src/core/graph/layout/layered/layout_assign_layers.d.ts.map +1 -0
  69. package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_assign_layers.js +4 -2
  70. package/src/core/graph/layout/layered/layout_break_cycles.d.ts.map +1 -0
  71. package/src/core/graph/layout/layered/layout_insert_lanes.d.ts.map +1 -0
  72. package/src/core/graph/layout/layered/layout_order_layers.d.ts.map +1 -0
  73. package/src/core/graph/layout/layered/layout_orient_links.d.ts.map +1 -0
  74. package/src/core/model/node-graph/visual/layout/NodeGraphLayoutOptions.d.ts +7 -51
  75. package/src/core/model/node-graph/visual/layout/NodeGraphLayoutOptions.d.ts.map +1 -1
  76. package/src/core/model/node-graph/visual/layout/NodeGraphLayoutOptions.js +8 -69
  77. package/src/core/model/node-graph/visual/layout/layout_build_problem.js +1 -1
  78. package/src/core/model/node-graph/visual/layout/layout_node_graph.js +6 -6
  79. package/src/core/model/node-graph/visual/layout/route_grid_build.js +1 -1
  80. package/src/engine/Engine.d.ts.map +1 -1
  81. package/src/engine/Engine.js +38 -1
  82. package/src/engine/graphics3/DebugDrawSystem.d.ts +7 -5
  83. package/src/engine/graphics3/DebugDrawSystem.d.ts.map +1 -1
  84. package/src/engine/graphics3/DebugDrawSystem.js +206 -203
  85. package/src/engine/graphics3/DecalSystem.d.ts +4 -5
  86. package/src/engine/graphics3/DecalSystem.d.ts.map +1 -1
  87. package/src/engine/graphics3/DecalSystem.js +5 -5
  88. package/src/engine/graphics3/FogOfWarSystem.d.ts +7 -12
  89. package/src/engine/graphics3/FogOfWarSystem.d.ts.map +1 -1
  90. package/src/engine/graphics3/FogOfWarSystem.js +8 -12
  91. package/src/engine/graphics3/GraphicsEngine.d.ts +5 -1
  92. package/src/engine/graphics3/GraphicsEngine.d.ts.map +1 -1
  93. package/src/engine/graphics3/GraphicsEngine.js +834 -830
  94. package/src/engine/graphics3/prefab/prefab_instantiate.js +230 -230
  95. package/src/shade/RENDERER_CONTRACT.md +31 -17
  96. package/src/shade/device/timing/GPU_PROFILER_PROPOSAL_2026_08_28.md +1 -1
  97. package/src/shade/playground/caldera/README.md +529 -0
  98. package/src/shade/playground/caldera/caldera_format.d.ts +151 -0
  99. package/src/shade/playground/caldera/caldera_format.d.ts.map +1 -0
  100. package/src/shade/playground/caldera/caldera_format.js +241 -0
  101. package/src/shade/playground/caldera/index.html +126 -0
  102. package/src/shade/playground/caldera/main.d.ts.map +1 -0
  103. package/src/shade/playground/caldera/main.js +1565 -0
  104. package/src/shade/playground/mesh_row_ceiling/README.md +85 -0
  105. package/src/shade/playground/mesh_row_ceiling/index.html +31 -0
  106. package/src/shade/playground/mesh_row_ceiling/main.d.ts +2 -0
  107. package/src/shade/playground/mesh_row_ceiling/main.d.ts.map +1 -0
  108. package/src/shade/playground/mesh_row_ceiling/main.js +389 -0
  109. package/src/shade/playground/vgeo_runtime/README.md +32 -16
  110. package/src/shade/playground/vgeo_runtime/main.js +21 -7
  111. package/src/shade/playground/{vgeo_viewer → vgeo_runtime}/sample_asset.d.ts +3 -3
  112. package/src/shade/playground/vgeo_runtime/sample_asset.d.ts.map +1 -0
  113. package/src/shade/playground/{vgeo_viewer → vgeo_runtime}/sample_asset.js +12 -11
  114. package/src/shade/playground/vgeo_scene/README.md +487 -0
  115. package/src/shade/playground/vgeo_scene/index.html +144 -0
  116. package/src/shade/playground/vgeo_scene/main.d.ts +2 -0
  117. package/src/shade/playground/vgeo_scene/main.d.ts.map +1 -0
  118. package/src/shade/playground/vgeo_scene/main.js +2217 -0
  119. package/src/shade/renderer/GraphicsContext.d.ts.map +1 -1
  120. package/src/shade/renderer/GraphicsContext.js +6 -0
  121. package/src/shade/renderer/Renderer.d.ts +6 -1
  122. package/src/shade/renderer/Renderer.d.ts.map +1 -1
  123. package/src/shade/renderer/Renderer.js +28 -2
  124. package/src/shade/renderer/animation/skinning/GPUMeshSkinningContext.d.ts.map +1 -1
  125. package/src/shade/renderer/animation/skinning/GPUMeshSkinningContext.js +100 -8
  126. package/src/shade/renderer/extension/RENDER_EXTENSION_DESIGN.md +70 -35
  127. package/src/shade/renderer/extension/RenderExtension.d.ts +15 -18
  128. package/src/shade/renderer/extension/RenderExtension.d.ts.map +1 -1
  129. package/src/shade/renderer/extension/RenderExtension.js +15 -19
  130. package/src/shade/renderer/extension/RenderExtensionRegistry.d.ts +5 -5
  131. package/src/shade/renderer/extension/RenderExtensionRegistry.d.ts.map +1 -1
  132. package/src/shade/renderer/extension/RenderExtensionRegistry.js +29 -166
  133. package/src/shade/renderer/geometry/GPUGeometryManager.d.ts.map +1 -1
  134. package/src/shade/renderer/geometry/GPUGeometryManager.js +73 -16
  135. package/src/shade/renderer/geometry/bvh/GPUGeometryBVHManager.d.ts.map +1 -1
  136. package/src/shade/renderer/geometry/bvh/GPUGeometryBVHManager.js +18 -3
  137. package/src/shade/renderer/geometry/meshlet/COMPACTION_PLAN_2026_09_16.md +663 -0
  138. package/src/shade/renderer/geometry/meshlet/GPUMeshletManager.d.ts +100 -5
  139. package/src/shade/renderer/geometry/meshlet/GPUMeshletManager.d.ts.map +1 -1
  140. package/src/shade/renderer/geometry/meshlet/GPUMeshletManager.js +688 -81
  141. package/src/shade/renderer/geometry/meshlet/MeshletBatch.d.ts.map +1 -1
  142. package/src/shade/renderer/geometry/meshlet/MeshletBatch.js +3 -29
  143. package/src/shade/renderer/geometry/meshlet/encoding/ENCODED_ATTRIBUTE_DEFAULT_VALUES.d.ts +22 -0
  144. package/src/shade/renderer/geometry/meshlet/encoding/ENCODED_ATTRIBUTE_DEFAULT_VALUES.d.ts.map +1 -0
  145. package/src/shade/renderer/geometry/meshlet/encoding/ENCODED_ATTRIBUTE_DEFAULT_VALUES.js +49 -0
  146. package/src/shade/renderer/geometry/virtual/ATTRIBUTE_PLAN_2026_09_18.md +540 -0
  147. package/src/shade/renderer/geometry/virtual/VGEO_FORMAT.md +159 -66
  148. package/src/shade/renderer/geometry/virtual/VIRTUAL_GEOMETRY_DESIGN.md +40 -21
  149. package/src/shade/renderer/geometry/virtual/VIRTUAL_GEOMETRY_PLAN.md +15 -14
  150. package/src/shade/renderer/geometry/virtual/WEDGE_PLAN_2026_09_18.md +358 -0
  151. package/src/shade/renderer/geometry/virtual/build/VGeoBuildOptions.d.ts +58 -8
  152. package/src/shade/renderer/geometry/virtual/build/VGeoBuildOptions.d.ts.map +1 -1
  153. package/src/shade/renderer/geometry/virtual/build/VGeoBuildOptions.js +64 -10
  154. package/src/shade/renderer/geometry/virtual/build/gltf/gltf_open_document.d.ts.map +1 -1
  155. package/src/shade/renderer/geometry/virtual/build/gltf/gltf_open_document.js +5 -9
  156. package/src/shade/renderer/geometry/virtual/build/level/VGeoContribution.d.ts +40 -0
  157. package/src/shade/renderer/geometry/virtual/build/level/VGeoContribution.d.ts.map +1 -0
  158. package/src/shade/renderer/geometry/virtual/build/level/VGeoContribution.js +24 -0
  159. package/src/shade/renderer/geometry/virtual/build/level/VGeoFrontier.d.ts +91 -0
  160. package/src/shade/renderer/geometry/virtual/build/level/VGeoFrontier.d.ts.map +1 -0
  161. package/src/shade/renderer/geometry/virtual/build/level/VGeoFrontier.js +91 -0
  162. package/src/shade/renderer/geometry/virtual/build/level/VGeoGroupRepack.d.ts +24 -0
  163. package/src/shade/renderer/geometry/virtual/build/level/VGeoGroupRepack.d.ts.map +1 -0
  164. package/src/shade/renderer/geometry/virtual/build/level/VGeoGroupRepack.js +25 -0
  165. package/src/shade/renderer/geometry/virtual/build/level/VGeoGroupStep.d.ts +77 -0
  166. package/src/shade/renderer/geometry/virtual/build/level/VGeoGroupStep.d.ts.map +1 -0
  167. package/src/shade/renderer/geometry/virtual/build/level/VGeoGroupStep.js +84 -0
  168. package/src/shade/renderer/geometry/virtual/build/level/VGeoLevel.d.ts.map +1 -0
  169. package/src/shade/renderer/geometry/virtual/build/{VGeoLevelOptions.d.ts → level/VGeoLevelOptions.d.ts} +19 -6
  170. package/src/shade/renderer/geometry/virtual/build/level/VGeoLevelOptions.d.ts.map +1 -0
  171. package/src/shade/renderer/geometry/virtual/build/{VGeoLevelOptions.js → level/VGeoLevelOptions.js} +20 -7
  172. package/src/shade/renderer/geometry/virtual/build/level/VGeoLevelSummary.d.ts.map +1 -0
  173. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_cluster.d.ts +19 -0
  174. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_cluster.d.ts.map +1 -0
  175. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_cluster.js +58 -0
  176. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_cluster_graph.d.ts +18 -0
  177. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_cluster_graph.d.ts.map +1 -0
  178. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_cluster_graph.js +116 -0
  179. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_group_step.d.ts +18 -0
  180. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_group_step.d.ts.map +1 -0
  181. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_group_step.js +545 -0
  182. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_leaf_frontier.d.ts +16 -0
  183. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_leaf_frontier.d.ts.map +1 -0
  184. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_leaf_frontier.js +110 -0
  185. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_levels.d.ts +11 -0
  186. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_levels.d.ts.map +1 -0
  187. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_levels.js +308 -0
  188. package/src/shade/renderer/geometry/virtual/build/{vgeo_build_root_group.d.ts → level/vgeo_build_root_group.d.ts} +1 -1
  189. package/src/shade/renderer/geometry/virtual/build/level/vgeo_build_root_group.d.ts.map +1 -0
  190. package/src/shade/renderer/geometry/virtual/build/{vgeo_build_root_group.js → level/vgeo_build_root_group.js} +1 -1
  191. package/src/shade/renderer/geometry/virtual/build/level/vgeo_compute_group_boundary.d.ts +26 -0
  192. package/src/shade/renderer/geometry/virtual/build/level/vgeo_compute_group_boundary.d.ts.map +1 -0
  193. package/src/shade/renderer/geometry/virtual/build/level/vgeo_compute_group_boundary.js +123 -0
  194. package/src/shade/renderer/geometry/virtual/build/level/vgeo_error_bands.d.ts +26 -0
  195. package/src/shade/renderer/geometry/virtual/build/level/vgeo_error_bands.d.ts.map +1 -0
  196. package/src/shade/renderer/geometry/virtual/build/level/vgeo_error_bands.js +78 -0
  197. package/src/shade/renderer/geometry/virtual/build/level/vgeo_partition_into_groups.d.ts +24 -0
  198. package/src/shade/renderer/geometry/virtual/build/level/vgeo_partition_into_groups.d.ts.map +1 -0
  199. package/src/shade/renderer/geometry/virtual/build/level/vgeo_partition_into_groups.js +337 -0
  200. package/src/shade/renderer/geometry/virtual/build/level/vgeo_run_round.d.ts +29 -0
  201. package/src/shade/renderer/geometry/virtual/build/level/vgeo_run_round.d.ts.map +1 -0
  202. package/src/shade/renderer/geometry/virtual/build/level/vgeo_run_round.js +147 -0
  203. package/src/shade/renderer/geometry/virtual/build/level/vgeo_stitch_frontier.d.ts +37 -0
  204. package/src/shade/renderer/geometry/virtual/build/level/vgeo_stitch_frontier.d.ts.map +1 -0
  205. package/src/shade/renderer/geometry/virtual/build/level/vgeo_stitch_frontier.js +243 -0
  206. package/src/shade/renderer/geometry/virtual/build/level/vgeo_try_repack.d.ts +29 -0
  207. package/src/shade/renderer/geometry/virtual/build/level/vgeo_try_repack.d.ts.map +1 -0
  208. package/src/shade/renderer/geometry/virtual/build/level/vgeo_try_repack.js +117 -0
  209. package/src/shade/renderer/geometry/virtual/build/mesh/VGEO_CREASE_ANGLE.d.ts +46 -0
  210. package/src/shade/renderer/geometry/virtual/build/mesh/VGEO_CREASE_ANGLE.d.ts.map +1 -0
  211. package/src/shade/renderer/geometry/virtual/build/mesh/VGEO_CREASE_ANGLE.js +45 -0
  212. package/src/shade/renderer/geometry/virtual/build/mesh/VGEO_DEFAULT_ATTRIBUTE_WEIGHT_RATIOS.d.ts +64 -0
  213. package/src/shade/renderer/geometry/virtual/build/mesh/VGEO_DEFAULT_ATTRIBUTE_WEIGHT_RATIOS.d.ts.map +1 -0
  214. package/src/shade/renderer/geometry/virtual/build/mesh/VGEO_DEFAULT_ATTRIBUTE_WEIGHT_RATIOS.js +68 -0
  215. package/src/shade/renderer/geometry/virtual/build/{VirtualGeometryMesh.d.ts → mesh/VirtualGeometryMesh.d.ts} +13 -8
  216. package/src/shade/renderer/geometry/virtual/build/mesh/VirtualGeometryMesh.d.ts.map +1 -0
  217. package/src/shade/renderer/geometry/virtual/build/{VirtualGeometryMesh.js → mesh/VirtualGeometryMesh.js} +40 -18
  218. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_attribute_vector_layout.d.ts +58 -0
  219. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_attribute_vector_layout.d.ts.map +1 -0
  220. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_attribute_vector_layout.js +79 -0
  221. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_attribute_vector_read.d.ts +39 -0
  222. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_attribute_vector_read.d.ts.map +1 -0
  223. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_attribute_vector_read.js +68 -0
  224. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_attribute_vector_write.d.ts +53 -0
  225. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_attribute_vector_write.d.ts.map +1 -0
  226. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_attribute_vector_write.js +243 -0
  227. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_compute_vertex_normals.d.ts +45 -0
  228. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_compute_vertex_normals.d.ts.map +1 -0
  229. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_compute_vertex_normals.js +300 -0
  230. package/src/shade/renderer/geometry/virtual/build/{vgeo_compute_vertex_tangents.d.ts → mesh/vgeo_compute_vertex_tangents.d.ts} +12 -8
  231. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_compute_vertex_tangents.d.ts.map +1 -0
  232. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_compute_vertex_tangents.js +151 -0
  233. package/src/shade/renderer/geometry/virtual/build/{vgeo_normalize_source.d.ts → mesh/vgeo_normalize_source.d.ts} +8 -1
  234. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_normalize_source.d.ts.map +1 -0
  235. package/src/shade/renderer/geometry/virtual/build/{vgeo_normalize_source.js → mesh/vgeo_normalize_source.js} +27 -12
  236. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_resolve_attribute_weights.d.ts +38 -0
  237. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_resolve_attribute_weights.d.ts.map +1 -0
  238. package/src/shade/renderer/geometry/virtual/build/mesh/vgeo_resolve_attribute_weights.js +81 -0
  239. package/src/shade/renderer/geometry/virtual/build/{vgeo_assemble_pages.d.ts → page/vgeo_assemble_pages.d.ts} +1 -1
  240. package/src/shade/renderer/geometry/virtual/build/page/vgeo_assemble_pages.d.ts.map +1 -0
  241. package/src/shade/renderer/geometry/virtual/build/{vgeo_assemble_pages.js → page/vgeo_assemble_pages.js} +9 -9
  242. package/src/shade/renderer/geometry/virtual/build/{vgeo_build_page_nodes.d.ts → page/vgeo_build_page_nodes.d.ts} +1 -1
  243. package/src/shade/renderer/geometry/virtual/build/page/vgeo_build_page_nodes.d.ts.map +1 -0
  244. package/src/shade/renderer/geometry/virtual/build/{vgeo_build_page_nodes.js → page/vgeo_build_page_nodes.js} +4 -4
  245. package/src/shade/renderer/geometry/virtual/build/page/vgeo_page_node_count.d.ts.map +1 -0
  246. package/src/shade/renderer/geometry/virtual/build/{vgeo_page_node_count.js → page/vgeo_page_node_count.js} +2 -2
  247. package/src/shade/renderer/geometry/virtual/build/{VGeoFaceGraph.d.ts → partition/VGeoFaceGraph.d.ts} +23 -5
  248. package/src/shade/renderer/geometry/virtual/build/partition/VGeoFaceGraph.d.ts.map +1 -0
  249. package/src/shade/renderer/geometry/virtual/build/{VGeoFaceGraph.js → partition/VGeoFaceGraph.js} +28 -21
  250. package/src/shade/renderer/geometry/virtual/build/partition/vgeo_graph_components.d.ts.map +1 -0
  251. package/src/shade/renderer/geometry/virtual/build/partition/vgeo_partition_graph.d.ts.map +1 -0
  252. package/src/shade/renderer/geometry/virtual/build/{vgeo_partition_graph.js → partition/vgeo_partition_graph.js} +2 -2
  253. package/src/shade/renderer/geometry/virtual/build/partition/vgeo_partition_subgraph.d.ts +41 -0
  254. package/src/shade/renderer/geometry/virtual/build/partition/vgeo_partition_subgraph.d.ts.map +1 -0
  255. package/src/shade/renderer/geometry/virtual/build/partition/vgeo_partition_subgraph.js +92 -0
  256. package/src/shade/renderer/geometry/virtual/build/partition/vgeo_split_face_set.d.ts.map +1 -0
  257. package/src/shade/renderer/geometry/virtual/build/{vgeo_split_face_set.js → partition/vgeo_split_face_set.js} +13 -56
  258. package/src/shade/renderer/geometry/virtual/build/partition/vgeo_split_face_set_packed.d.ts.map +1 -0
  259. package/src/shade/renderer/geometry/virtual/build/partition/vgeo_split_face_set_packed.js +371 -0
  260. package/src/shade/renderer/geometry/virtual/build/sphere/vgeo_bounding_sphere.d.ts.map +1 -0
  261. package/src/shade/renderer/geometry/virtual/build/{vgeo_bounding_sphere.js → sphere/vgeo_bounding_sphere.js} +3 -3
  262. package/src/shade/renderer/geometry/virtual/build/sphere/vgeo_containing_sphere.d.ts.map +1 -0
  263. package/src/shade/renderer/geometry/virtual/build/{vgeo_containing_sphere.js → sphere/vgeo_containing_sphere.js} +3 -3
  264. package/src/shade/renderer/geometry/virtual/build/sphere/vgeo_sphere_inflate_to_contain.d.ts.map +1 -0
  265. package/src/shade/renderer/geometry/virtual/build/{vgeo_sphere_inflate_to_contain.js → sphere/vgeo_sphere_inflate_to_contain.js} +1 -1
  266. package/src/shade/renderer/geometry/virtual/build/submesh/VGeoGatheredFaces.d.ts +39 -0
  267. package/src/shade/renderer/geometry/virtual/build/submesh/VGeoGatheredFaces.d.ts.map +1 -0
  268. package/src/shade/renderer/geometry/virtual/build/submesh/VGeoGatheredFaces.js +42 -0
  269. package/src/shade/renderer/geometry/virtual/build/submesh/VGeoSubmesh.d.ts +37 -0
  270. package/src/shade/renderer/geometry/virtual/build/submesh/VGeoSubmesh.d.ts.map +1 -0
  271. package/src/shade/renderer/geometry/virtual/build/submesh/VGeoSubmesh.js +39 -0
  272. package/src/shade/renderer/geometry/virtual/build/submesh/vgeo_extract_submesh.d.ts +23 -0
  273. package/src/shade/renderer/geometry/virtual/build/submesh/vgeo_extract_submesh.d.ts.map +1 -0
  274. package/src/shade/renderer/geometry/virtual/build/submesh/vgeo_extract_submesh.js +135 -0
  275. package/src/shade/renderer/geometry/virtual/build/submesh/vgeo_gather_faces.d.ts +24 -0
  276. package/src/shade/renderer/geometry/virtual/build/submesh/vgeo_gather_faces.d.ts.map +1 -0
  277. package/src/shade/renderer/geometry/virtual/build/submesh/vgeo_gather_faces.js +95 -0
  278. package/src/shade/renderer/geometry/virtual/build/submesh/vgeo_narrow_indices.d.ts.map +1 -0
  279. package/src/shade/renderer/geometry/virtual/build/{vgeo_narrow_indices.js → submesh/vgeo_narrow_indices.js} +3 -3
  280. package/src/shade/renderer/geometry/virtual/build/vgeo_build.d.ts +6 -2
  281. package/src/shade/renderer/geometry/virtual/build/vgeo_build.d.ts.map +1 -1
  282. package/src/shade/renderer/geometry/virtual/build/vgeo_build.js +37 -16
  283. package/src/shade/renderer/geometry/virtual/build/vgeo_subtree_bounds.d.ts +32 -0
  284. package/src/shade/renderer/geometry/virtual/build/vgeo_subtree_bounds.d.ts.map +1 -0
  285. package/src/shade/renderer/geometry/virtual/build/vgeo_subtree_bounds.js +93 -0
  286. package/src/shade/renderer/geometry/virtual/format/VGeoWriteOptions.d.ts +20 -6
  287. package/src/shade/renderer/geometry/virtual/format/VGeoWriteOptions.d.ts.map +1 -1
  288. package/src/shade/renderer/geometry/virtual/format/VGeoWriteOptions.js +22 -8
  289. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_attributes_read.d.ts +8 -2
  290. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_attributes_read.d.ts.map +1 -1
  291. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_attributes_read.js +8 -2
  292. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_copy_corner.d.ts +16 -0
  293. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_copy_corner.d.ts.map +1 -0
  294. package/src/shade/renderer/geometry/virtual/format/attribute/{vgeo_layers_copy_vertex.js → vgeo_layers_copy_corner.js} +8 -8
  295. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_declare.d.ts +18 -7
  296. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_declare.d.ts.map +1 -1
  297. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_declare.js +19 -8
  298. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_like.d.ts +3 -3
  299. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_like.js +3 -3
  300. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_mesh_wedges.d.ts +27 -0
  301. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_mesh_wedges.d.ts.map +1 -0
  302. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_mesh_wedges.js +97 -0
  303. package/src/shade/renderer/geometry/virtual/format/cluster/VGEO_CLUSTER_OFFSET.d.ts +7 -3
  304. package/src/shade/renderer/geometry/virtual/format/cluster/VGEO_CLUSTER_OFFSET.d.ts.map +1 -1
  305. package/src/shade/renderer/geometry/virtual/format/cluster/VGEO_CLUSTER_OFFSET.js +21 -11
  306. package/src/shade/renderer/geometry/virtual/format/cluster/VGEO_CLUSTER_OFFSET_V4.d.ts +21 -0
  307. package/src/shade/renderer/geometry/virtual/format/cluster/VGEO_CLUSTER_OFFSET_V4.d.ts.map +1 -0
  308. package/src/shade/renderer/geometry/virtual/format/cluster/VGEO_CLUSTER_OFFSET_V4.js +41 -0
  309. package/src/shade/renderer/geometry/virtual/format/dag/VirtualGeometryCluster.d.ts +19 -1
  310. package/src/shade/renderer/geometry/virtual/format/dag/VirtualGeometryCluster.d.ts.map +1 -1
  311. package/src/shade/renderer/geometry/virtual/format/dag/VirtualGeometryCluster.js +20 -1
  312. package/src/shade/renderer/geometry/virtual/format/frame/VGEO_CODEC_DEFLATE.d.ts +25 -0
  313. package/src/shade/renderer/geometry/virtual/format/frame/VGEO_CODEC_DEFLATE.d.ts.map +1 -0
  314. package/src/shade/renderer/geometry/virtual/format/frame/VGEO_CODEC_DEFLATE.js +24 -0
  315. package/src/shade/renderer/geometry/virtual/format/frame/VGEO_CODEC_LZ4.d.ts +5 -0
  316. package/src/shade/renderer/geometry/virtual/format/frame/VGEO_CODEC_LZ4.d.ts.map +1 -1
  317. package/src/shade/renderer/geometry/virtual/format/frame/VGEO_CODEC_LZ4.js +5 -0
  318. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_codec_name.d.ts.map +1 -1
  319. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_codec_name.js +5 -0
  320. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_decode_frame_blob.d.ts +10 -3
  321. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_decode_frame_blob.d.ts.map +1 -1
  322. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_decode_frame_blob.js +37 -3
  323. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_encode_frame_blob.d.ts +21 -13
  324. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_encode_frame_blob.d.ts.map +1 -1
  325. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_encode_frame_blob.js +37 -13
  326. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_frame_decode_bound.d.ts +8 -2
  327. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_frame_decode_bound.d.ts.map +1 -1
  328. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_frame_decode_bound.js +14 -2
  329. package/src/shade/renderer/geometry/virtual/format/header/VGEO_FORMAT_VERSION.d.ts +18 -0
  330. package/src/shade/renderer/geometry/virtual/format/header/VGEO_FORMAT_VERSION.d.ts.map +1 -1
  331. package/src/shade/renderer/geometry/virtual/format/header/VGEO_FORMAT_VERSION.js +19 -1
  332. package/src/shade/renderer/geometry/virtual/format/header/VGEO_HEADER_OFFSET.js +6 -0
  333. package/src/shade/renderer/geometry/virtual/format/header/VGEO_MAX_LEVEL_COUNT.d.ts +21 -0
  334. package/src/shade/renderer/geometry/virtual/format/header/VGEO_MAX_LEVEL_COUNT.d.ts.map +1 -0
  335. package/src/shade/renderer/geometry/virtual/format/header/VGEO_MAX_LEVEL_COUNT.js +20 -0
  336. package/src/shade/renderer/geometry/virtual/format/header/VGEO_MIN_READER_VERSION.d.ts +9 -0
  337. package/src/shade/renderer/geometry/virtual/format/header/VGEO_MIN_READER_VERSION.d.ts.map +1 -1
  338. package/src/shade/renderer/geometry/virtual/format/header/VGEO_MIN_READER_VERSION.js +10 -1
  339. package/src/shade/renderer/geometry/virtual/format/page/VGEO_GROUP_OFFSET.d.ts +15 -0
  340. package/src/shade/renderer/geometry/virtual/format/page/VGEO_GROUP_OFFSET.d.ts.map +1 -0
  341. package/src/shade/renderer/geometry/virtual/format/page/VGEO_GROUP_OFFSET.js +15 -0
  342. package/src/shade/renderer/geometry/virtual/format/page/VGEO_PAGE_OFFSET.d.ts +1 -2
  343. package/src/shade/renderer/geometry/virtual/format/page/VGEO_PAGE_OFFSET.js +10 -3
  344. package/src/shade/renderer/geometry/virtual/format/page/VGEO_PAGE_OFFSET_V5.d.ts +20 -0
  345. package/src/shade/renderer/geometry/virtual/format/page/VGEO_PAGE_OFFSET_V5.d.ts.map +1 -0
  346. package/src/shade/renderer/geometry/virtual/format/page/VGEO_PAGE_OFFSET_V5.js +43 -0
  347. package/src/shade/renderer/geometry/virtual/format/payload/vgeo_encode_cluster_payload.d.ts +32 -2
  348. package/src/shade/renderer/geometry/virtual/format/payload/vgeo_encode_cluster_payload.d.ts.map +1 -1
  349. package/src/shade/renderer/geometry/virtual/format/payload/vgeo_encode_cluster_payload.js +15 -7
  350. package/src/shade/renderer/geometry/virtual/format/read/VGeoContainerReader.d.ts.map +1 -1
  351. package/src/shade/renderer/geometry/virtual/format/read/VGeoContainerReader.js +2 -2
  352. package/src/shade/renderer/geometry/virtual/format/read/VGeoDirectory.d.ts +6 -4
  353. package/src/shade/renderer/geometry/virtual/format/read/VGeoDirectory.d.ts.map +1 -1
  354. package/src/shade/renderer/geometry/virtual/format/read/VGeoDirectory.js +6 -4
  355. package/src/shade/renderer/geometry/virtual/format/read/VGeoPage.d.ts +13 -2
  356. package/src/shade/renderer/geometry/virtual/format/read/VGeoPage.d.ts.map +1 -1
  357. package/src/shade/renderer/geometry/virtual/format/read/VGeoPage.js +13 -2
  358. package/src/shade/renderer/geometry/virtual/format/read/VGeoPageFetcherCore.d.ts +5 -1
  359. package/src/shade/renderer/geometry/virtual/format/read/VGeoPageFetcherCore.d.ts.map +1 -1
  360. package/src/shade/renderer/geometry/virtual/format/read/VGeoPageFetcherCore.js +14 -1
  361. package/src/shade/renderer/geometry/virtual/format/read/vgeo_page_worker_serve.d.ts.map +1 -1
  362. package/src/shade/renderer/geometry/virtual/format/read/vgeo_page_worker_serve.js +1 -0
  363. package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_directory.d.ts +4 -1
  364. package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_directory.d.ts.map +1 -1
  365. package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_directory.js +53 -11
  366. package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_header.d.ts.map +1 -1
  367. package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_header.js +7 -3
  368. package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_page.d.ts +12 -2
  369. package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_page.d.ts.map +1 -1
  370. package/src/shade/renderer/geometry/virtual/format/read/vgeo_read_page.js +120 -37
  371. package/src/shade/renderer/geometry/virtual/format/vgeo_validate_container.d.ts +6 -2
  372. package/src/shade/renderer/geometry/virtual/format/vgeo_validate_container.d.ts.map +1 -1
  373. package/src/shade/renderer/geometry/virtual/format/vgeo_validate_container.js +130 -47
  374. package/src/shade/renderer/geometry/virtual/format/vgeo_write_container.d.ts +2 -2
  375. package/src/shade/renderer/geometry/virtual/format/vgeo_write_container.d.ts.map +1 -1
  376. package/src/shade/renderer/geometry/virtual/format/vgeo_write_container.js +60 -22
  377. package/src/shade/renderer/geometry/virtual/runtime/CULL_PLAN_2026_09_16.md +385 -0
  378. package/src/shade/renderer/geometry/virtual/runtime/CUT_PLAN_2026_09_14.md +21 -2
  379. package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryRuntime.d.ts +52 -2
  380. package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryRuntime.d.ts.map +1 -1
  381. package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryRuntime.js +97 -1
  382. package/src/shade/renderer/geometry/virtual/runtime/RUNTIME_PLAN.md +4 -4
  383. package/src/shade/renderer/geometry/virtual/runtime/VGeoFeedbackLoop.d.ts.map +1 -1
  384. package/src/shade/renderer/geometry/virtual/runtime/VGeoFeedbackLoop.js +10 -0
  385. package/src/shade/renderer/geometry/virtual/runtime/VGeoPageFetcher.d.ts.map +1 -1
  386. package/src/shade/renderer/geometry/virtual/runtime/VGeoPageFetcher.js +9 -0
  387. package/src/shade/renderer/geometry/virtual/runtime/VGeoResidency.d.ts.map +1 -1
  388. package/src/shade/renderer/geometry/virtual/runtime/VGeoResidency.js +59 -34
  389. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_access.d.ts +8 -8
  390. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_access.d.ts.map +1 -1
  391. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_access.js +45 -88
  392. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_arena.d.ts +19 -0
  393. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_arena.d.ts.map +1 -0
  394. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_arena.js +116 -0
  395. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_claim.d.ts +31 -0
  396. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_claim.d.ts.map +1 -0
  397. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_claim.js +99 -0
  398. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_queue.d.ts +17 -0
  399. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_queue.d.ts.map +1 -0
  400. package/src/shade/renderer/geometry/virtual/runtime/cut/chunk_vgeo_cut_queue.js +39 -0
  401. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_reseed.d.ts.map +1 -1
  402. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_reseed.js +7 -63
  403. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_seed.d.ts.map +1 -1
  404. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_seed.js +13 -30
  405. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_traverse.d.ts.map +1 -1
  406. package/src/shade/renderer/geometry/virtual/runtime/cut/shader_vgeo_cut_traverse.js +53 -71
  407. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CLUSTER_ROW_OFFSET.d.ts +1 -0
  408. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CLUSTER_ROW_OFFSET.js +22 -4
  409. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CLUSTER_ROW_WORDS.d.ts +7 -2
  410. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CLUSTER_ROW_WORDS.d.ts.map +1 -1
  411. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CLUSTER_ROW_WORDS.js +8 -3
  412. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CUT_STAT.d.ts +1 -0
  413. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CUT_STAT.js +10 -0
  414. package/src/shade/renderer/geometry/virtual/runtime/layout/VGEO_CUT_STAT_COUNT.js +1 -1
  415. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_page_slot_words.d.ts +13 -11
  416. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_page_slot_words.d.ts.map +1 -1
  417. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_page_slot_words.js +13 -11
  418. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_write_page_block.d.ts.map +1 -1
  419. package/src/shade/renderer/geometry/virtual/runtime/vgeo_runtime_write_page_block.js +4 -0
  420. package/src/shade/renderer/global_illumination/sharc/shader/shader_sharc_evict.d.ts.map +1 -1
  421. package/src/shade/renderer/global_illumination/sharc/shader/shader_sharc_evict.js +3 -4
  422. package/src/shade/renderer/gpu_primitive/indirect/IndirectComputeCommandBuildPass.d.ts +6 -2
  423. package/src/shade/renderer/gpu_primitive/indirect/IndirectComputeCommandBuildPass.d.ts.map +1 -1
  424. package/src/shade/renderer/gpu_primitive/indirect/IndirectComputeCommandBuildPass.js +90 -12
  425. package/src/shade/renderer/gpu_primitive/indirect/WEBGPU_GUARANTEED_MAX_COMPUTE_WORKGROUPS_PER_DIMENSION.d.ts +22 -0
  426. package/src/shade/renderer/gpu_primitive/indirect/WEBGPU_GUARANTEED_MAX_COMPUTE_WORKGROUPS_PER_DIMENSION.d.ts.map +1 -0
  427. package/src/shade/renderer/gpu_primitive/indirect/WEBGPU_GUARANTEED_MAX_COMPUTE_WORKGROUPS_PER_DIMENSION.js +21 -0
  428. package/src/shade/renderer/loader/gltf/load_gltf.d.ts.map +1 -1
  429. package/src/shade/renderer/loader/gltf/load_gltf.js +0 -19
  430. package/src/shade/renderer/material/chunk_material_draw_side.d.ts +14 -0
  431. package/src/shade/renderer/material/chunk_material_draw_side.d.ts.map +1 -0
  432. package/src/shade/renderer/material/chunk_material_draw_side.js +34 -0
  433. package/src/shade/renderer/material/standard/fragment_gbuffer.d.ts.map +1 -1
  434. package/src/shade/renderer/material/standard/fragment_gbuffer.js +8 -1
  435. package/src/shade/renderer/particles/shaders/shader_particle_emit.d.ts.map +1 -1
  436. package/src/shade/renderer/particles/shaders/shader_particle_emit.js +13 -8
  437. package/src/shade/renderer/particles/shaders/shader_particle_simulate.d.ts.map +1 -1
  438. package/src/shade/renderer/particles/shaders/shader_particle_simulate.js +3 -6
  439. package/src/shade/renderer/path_tracer/shader/chunk_sample_material_data.d.ts.map +1 -1
  440. package/src/shade/renderer/path_tracer/shader/chunk_sample_material_data.js +13 -1
  441. package/src/shade/renderer/rasterize/bucket/construct_primitive_state.d.ts +19 -5
  442. package/src/shade/renderer/rasterize/bucket/construct_primitive_state.d.ts.map +1 -1
  443. package/src/shade/renderer/rasterize/bucket/construct_primitive_state.js +23 -5
  444. package/src/shade/renderer/rasterize/bucket/filter_materials_by_bucket.d.ts.map +1 -1
  445. package/src/shade/renderer/rasterize/bucket/filter_materials_by_bucket.js +12 -5
  446. package/src/shade/renderer/rasterize/bucket/prepare_meshlet_draw_commands_by_material.d.ts.map +1 -1
  447. package/src/shade/renderer/rasterize/bucket/prepare_meshlet_draw_commands_by_material.js +4 -12
  448. package/src/shade/renderer/rasterize/bucket/rasterization_opaque_buckets.d.ts +22 -0
  449. package/src/shade/renderer/rasterize/bucket/rasterization_opaque_buckets.d.ts.map +1 -0
  450. package/src/shade/renderer/rasterize/bucket/rasterization_opaque_buckets.js +36 -0
  451. package/src/shade/renderer/rasterize/bucket/shader_read_out_bucket.d.ts +0 -2
  452. package/src/shade/renderer/rasterize/bucket/shader_read_out_bucket.d.ts.map +1 -1
  453. package/src/shade/renderer/rasterize/bucket/shader_read_out_bucket.js +4 -5
  454. package/src/shade/renderer/rasterize/chunk_triangle_winding_is_reversed.d.ts +15 -0
  455. package/src/shade/renderer/rasterize/chunk_triangle_winding_is_reversed.d.ts.map +1 -0
  456. package/src/shade/renderer/rasterize/chunk_triangle_winding_is_reversed.js +35 -0
  457. package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_mesh_filter_2way.d.ts.map +1 -1
  458. package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_mesh_filter_2way.js +5 -3
  459. package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_meshlet_filter_1way.d.ts.map +1 -1
  460. package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_meshlet_filter_1way.js +11 -4
  461. package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_meshlet_filter_1way_full.d.ts.map +1 -1
  462. package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_meshlet_filter_1way_full.js +4 -3
  463. package/src/shade/renderer/rasterize/expand/bucket/RASTERIZATION_BUCKET_LIMIT.d.ts +10 -1
  464. package/src/shade/renderer/rasterize/expand/bucket/RASTERIZATION_BUCKET_LIMIT.d.ts.map +1 -1
  465. package/src/shade/renderer/rasterize/expand/bucket/RASTERIZATION_BUCKET_LIMIT.js +38 -29
  466. package/src/shade/renderer/rasterize/expand/bucket/chunk_rasterization_material_bucket.d.ts +5 -0
  467. package/src/shade/renderer/rasterize/expand/bucket/chunk_rasterization_material_bucket.d.ts.map +1 -1
  468. package/src/shade/renderer/rasterize/expand/bucket/chunk_rasterization_material_bucket.js +63 -55
  469. package/src/shade/renderer/rasterize/expand/bucket/meshlet/graph_sort_meshlets_by_bucket_id.d.ts.map +1 -1
  470. package/src/shade/renderer/rasterize/expand/bucket/meshlet/graph_sort_meshlets_by_bucket_id.js +3 -0
  471. package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_count_by_rasterization_bucket.d.ts.map +1 -1
  472. package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_count_by_rasterization_bucket.js +94 -90
  473. package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_extract_bucket.d.ts.map +1 -1
  474. package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_extract_bucket.js +13 -5
  475. package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_rasterization_bucket_sort.d.ts.map +1 -1
  476. package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_rasterization_bucket_sort.js +96 -89
  477. package/src/shade/renderer/rasterize/expand/graph_meshlets_filter_one_way.d.ts.map +1 -1
  478. package/src/shade/renderer/rasterize/expand/graph_meshlets_filter_one_way.js +3 -1
  479. package/src/shade/renderer/rasterize/expand/graph_meshlets_filter_two_way.d.ts.map +1 -1
  480. package/src/shade/renderer/rasterize/expand/graph_meshlets_filter_two_way.js +4 -1
  481. package/src/shade/renderer/rasterize/expand/graph_meshlets_rasterize.d.ts.map +1 -1
  482. package/src/shade/renderer/rasterize/expand/graph_meshlets_rasterize.js +1 -0
  483. package/src/shade/renderer/rasterize/expand/mesh/shader_mesh_expand_to_meshlets_prefix.d.ts.map +1 -1
  484. package/src/shade/renderer/rasterize/expand/mesh/shader_mesh_expand_to_meshlets_prefix.js +100 -89
  485. package/src/shade/renderer/rasterize/expand/mesh/shader_prefix_sum_to_command.d.ts.map +1 -1
  486. package/src/shade/renderer/rasterize/expand/mesh/shader_prefix_sum_to_command.js +31 -7
  487. package/src/shade/renderer/rasterize/expand/pass0/pass_mesh_cull.d.ts.map +1 -1
  488. package/src/shade/renderer/rasterize/expand/pass0/pass_mesh_cull.js +1 -7
  489. package/src/shade/renderer/rasterize/expand/pass1/filter_meshlets.2-way.compute.d.ts.map +1 -1
  490. package/src/shade/renderer/rasterize/expand/pass1/filter_meshlets.2-way.compute.js +161 -153
  491. package/src/shade/renderer/rasterize/fast/graph_extract_meshes_from_bucket.d.ts.map +1 -1
  492. package/src/shade/renderer/rasterize/fast/graph_extract_meshes_from_bucket.js +2 -7
  493. package/src/shade/renderer/rasterize/fast/graph_rasterize_scene_fast.d.ts.map +1 -1
  494. package/src/shade/renderer/rasterize/fast/graph_rasterize_scene_fast.js +44 -53
  495. package/src/shade/renderer/rasterize/forward/chunk_forward_shade_standard_fragment_brick4.d.ts.map +1 -1
  496. package/src/shade/renderer/rasterize/forward/chunk_forward_shade_standard_fragment_brick4.js +6 -2
  497. package/src/shade/renderer/rasterize/forward/chunk_forward_shade_standard_fragment_ibl.d.ts.map +1 -1
  498. package/src/shade/renderer/rasterize/forward/chunk_forward_shade_standard_fragment_ibl.js +6 -2
  499. package/src/shade/renderer/rasterize/forward/vertex_shader_chunk.d.ts.map +1 -1
  500. package/src/shade/renderer/rasterize/forward/vertex_shader_chunk.js +19 -2
  501. package/src/shade/renderer/rasterize/native/avboit/AVBOIT_PLAN_2026_09_03.md +7 -4
  502. package/src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.d.ts.map +1 -1
  503. package/src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.js +3 -2
  504. package/src/shade/renderer/rasterize/native/chunk_rasterize_triangle.d.ts.map +1 -1
  505. package/src/shade/renderer/rasterize/native/chunk_rasterize_triangle.js +15 -4
  506. package/src/shade/renderer/rasterize/native/depth/shadow_rasterization_alpha_tested_pass_descriptor.d.ts.map +1 -1
  507. package/src/shade/renderer/rasterize/native/depth/shadow_rasterization_alpha_tested_pass_descriptor.js +16 -5
  508. package/src/shade/renderer/rasterize/native/depth/shadow_rasterization_pass_descriptor.d.ts.map +1 -1
  509. package/src/shade/renderer/rasterize/native/depth/shadow_rasterization_pass_descriptor.js +16 -5
  510. package/src/shade/renderer/rasterize/native/oit/graph_rasterize_meshes_transparent_oit.d.ts.map +1 -1
  511. package/src/shade/renderer/rasterize/native/oit/graph_rasterize_meshes_transparent_oit.js +2 -1
  512. package/src/shade/renderer/rasterize/native/rasterization_shader_resources.d.ts.map +1 -1
  513. package/src/shade/renderer/rasterize/native/rasterization_shader_resources.js +4 -0
  514. package/src/shade/renderer/rasterize/native/viz/viz_rasterization_alpha_tested_pass_descriptor.d.ts.map +1 -1
  515. package/src/shade/renderer/rasterize/native/viz/viz_rasterization_alpha_tested_pass_descriptor.js +16 -7
  516. package/src/shade/renderer/rasterize/standard/graph_rasterize_partial_opaque.d.ts.map +1 -1
  517. package/src/shade/renderer/rasterize/standard/graph_rasterize_partial_opaque.js +81 -95
  518. package/src/shade/renderer/rasterize/standard/graph_rasterize_remaining_opaque.d.ts.map +1 -1
  519. package/src/shade/renderer/rasterize/standard/graph_rasterize_remaining_opaque.js +26 -39
  520. package/src/shade/renderer/scene/GPUSceneContext.d.ts.map +1 -1
  521. package/src/shade/renderer/scene/GPUSceneContext.js +2 -0
  522. package/src/shade/renderer/scene/NODE3D_STRUCT.d.ts +19 -0
  523. package/src/shade/renderer/scene/NODE3D_STRUCT.d.ts.map +1 -1
  524. package/src/shade/renderer/scene/NODE3D_STRUCT.js +34 -0
  525. package/src/shade/renderer/scene/chunk_node3d_flags.d.ts +9 -0
  526. package/src/shade/renderer/scene/chunk_node3d_flags.d.ts.map +1 -0
  527. package/src/shade/renderer/scene/chunk_node3d_flags.js +23 -0
  528. package/src/shade/renderer/scene/chunk_scene_database_access.d.ts.map +1 -1
  529. package/src/shade/renderer/scene/chunk_scene_database_access.js +15 -1
  530. package/src/shade/renderer/scene/rows/GPUSceneRows.d.ts.map +1 -1
  531. package/src/shade/renderer/scene/rows/GPUSceneRows.js +9 -1
  532. package/src/shade/renderer/shader/chunk/geometry/mat4/chunk_compute_normal_matrix_from_m4.d.ts +7 -0
  533. package/src/shade/renderer/shader/chunk/geometry/mat4/chunk_compute_normal_matrix_from_m4.d.ts.map +1 -1
  534. package/src/shade/renderer/shader/chunk/geometry/mat4/chunk_compute_normal_matrix_from_m4.js +16 -4
  535. package/src/shade/renderer/shader/chunk/geometry/mat4/chunk_mat4_linear_determinant.d.ts +12 -0
  536. package/src/shade/renderer/shader/chunk/geometry/mat4/chunk_mat4_linear_determinant.d.ts.map +1 -0
  537. package/src/shade/renderer/shader/chunk/geometry/mat4/chunk_mat4_linear_determinant.js +18 -0
  538. package/src/shade/renderer/shader/chunk/geometry/triangle/chunk_triangle_list_reverse_winding.d.ts +24 -0
  539. package/src/shade/renderer/shader/chunk/geometry/triangle/chunk_triangle_list_reverse_winding.d.ts.map +1 -0
  540. package/src/shade/renderer/shader/chunk/geometry/triangle/chunk_triangle_list_reverse_winding.js +33 -0
  541. package/src/shade/renderer/shadow/map/DEFAULT_SHADOWMAP_UPDATE_BUDGET.d.ts +25 -0
  542. package/src/shade/renderer/shadow/map/DEFAULT_SHADOWMAP_UPDATE_BUDGET.d.ts.map +1 -0
  543. package/src/shade/renderer/shadow/map/DEFAULT_SHADOWMAP_UPDATE_BUDGET.js +24 -0
  544. package/src/shade/renderer/shadow/map/GPUSceneShadowmapContext.d.ts +10 -0
  545. package/src/shade/renderer/shadow/map/GPUSceneShadowmapContext.d.ts.map +1 -1
  546. package/src/shade/renderer/shadow/map/GPUSceneShadowmapContext.js +30 -21
  547. package/src/core/model/node-graph/visual/layout/LayoutBoxGraph.d.ts.map +0 -1
  548. package/src/core/model/node-graph/visual/layout/layout_assign_coordinates.d.ts.map +0 -1
  549. package/src/core/model/node-graph/visual/layout/layout_assign_layers.d.ts.map +0 -1
  550. package/src/core/model/node-graph/visual/layout/layout_break_cycles.d.ts.map +0 -1
  551. package/src/core/model/node-graph/visual/layout/layout_insert_lanes.d.ts.map +0 -1
  552. package/src/core/model/node-graph/visual/layout/layout_order_layers.d.ts.map +0 -1
  553. package/src/core/model/node-graph/visual/layout/layout_orient_links.d.ts.map +0 -1
  554. package/src/shade/playground/vgeo_viewer/README.md +0 -150
  555. package/src/shade/playground/vgeo_viewer/cut_geometry.d.ts +0 -61
  556. package/src/shade/playground/vgeo_viewer/cut_geometry.d.ts.map +0 -1
  557. package/src/shade/playground/vgeo_viewer/cut_geometry.js +0 -460
  558. package/src/shade/playground/vgeo_viewer/index.html +0 -77
  559. package/src/shade/playground/vgeo_viewer/main.d.ts.map +0 -1
  560. package/src/shade/playground/vgeo_viewer/main.js +0 -1343
  561. package/src/shade/playground/vgeo_viewer/sample_asset.d.ts.map +0 -1
  562. package/src/shade/playground/vgeo_viewer/select_cut.d.ts +0 -173
  563. package/src/shade/playground/vgeo_viewer/select_cut.d.ts.map +0 -1
  564. package/src/shade/playground/vgeo_viewer/select_cut.js +0 -481
  565. package/src/shade/renderer/geometry/virtual/build/VGeoFaceGraph.d.ts.map +0 -1
  566. package/src/shade/renderer/geometry/virtual/build/VGeoGatheredFaces.d.ts +0 -24
  567. package/src/shade/renderer/geometry/virtual/build/VGeoGatheredFaces.d.ts.map +0 -1
  568. package/src/shade/renderer/geometry/virtual/build/VGeoGatheredFaces.js +0 -25
  569. package/src/shade/renderer/geometry/virtual/build/VGeoLevel.d.ts.map +0 -1
  570. package/src/shade/renderer/geometry/virtual/build/VGeoLevelOptions.d.ts.map +0 -1
  571. package/src/shade/renderer/geometry/virtual/build/VGeoLevelSummary.d.ts.map +0 -1
  572. package/src/shade/renderer/geometry/virtual/build/VGeoSubmesh.d.ts +0 -20
  573. package/src/shade/renderer/geometry/virtual/build/VGeoSubmesh.d.ts.map +0 -1
  574. package/src/shade/renderer/geometry/virtual/build/VGeoSubmesh.js +0 -20
  575. package/src/shade/renderer/geometry/virtual/build/VirtualGeometryMesh.d.ts.map +0 -1
  576. package/src/shade/renderer/geometry/virtual/build/vgeo_assemble_pages.d.ts.map +0 -1
  577. package/src/shade/renderer/geometry/virtual/build/vgeo_bounding_sphere.d.ts.map +0 -1
  578. package/src/shade/renderer/geometry/virtual/build/vgeo_build_levels.d.ts +0 -36
  579. package/src/shade/renderer/geometry/virtual/build/vgeo_build_levels.d.ts.map +0 -1
  580. package/src/shade/renderer/geometry/virtual/build/vgeo_build_levels.js +0 -1786
  581. package/src/shade/renderer/geometry/virtual/build/vgeo_build_page_nodes.d.ts.map +0 -1
  582. package/src/shade/renderer/geometry/virtual/build/vgeo_build_root_group.d.ts.map +0 -1
  583. package/src/shade/renderer/geometry/virtual/build/vgeo_compute_vertex_normals.d.ts +0 -29
  584. package/src/shade/renderer/geometry/virtual/build/vgeo_compute_vertex_normals.d.ts.map +0 -1
  585. package/src/shade/renderer/geometry/virtual/build/vgeo_compute_vertex_normals.js +0 -75
  586. package/src/shade/renderer/geometry/virtual/build/vgeo_compute_vertex_tangents.d.ts.map +0 -1
  587. package/src/shade/renderer/geometry/virtual/build/vgeo_compute_vertex_tangents.js +0 -143
  588. package/src/shade/renderer/geometry/virtual/build/vgeo_containing_sphere.d.ts.map +0 -1
  589. package/src/shade/renderer/geometry/virtual/build/vgeo_extract_submesh.d.ts +0 -14
  590. package/src/shade/renderer/geometry/virtual/build/vgeo_extract_submesh.d.ts.map +0 -1
  591. package/src/shade/renderer/geometry/virtual/build/vgeo_extract_submesh.js +0 -41
  592. package/src/shade/renderer/geometry/virtual/build/vgeo_gather_faces.d.ts +0 -12
  593. package/src/shade/renderer/geometry/virtual/build/vgeo_gather_faces.d.ts.map +0 -1
  594. package/src/shade/renderer/geometry/virtual/build/vgeo_gather_faces.js +0 -71
  595. package/src/shade/renderer/geometry/virtual/build/vgeo_graph_components.d.ts.map +0 -1
  596. package/src/shade/renderer/geometry/virtual/build/vgeo_narrow_indices.d.ts.map +0 -1
  597. package/src/shade/renderer/geometry/virtual/build/vgeo_normalize_source.d.ts.map +0 -1
  598. package/src/shade/renderer/geometry/virtual/build/vgeo_page_node_count.d.ts.map +0 -1
  599. package/src/shade/renderer/geometry/virtual/build/vgeo_partition_graph.d.ts.map +0 -1
  600. package/src/shade/renderer/geometry/virtual/build/vgeo_sphere_inflate_to_contain.d.ts.map +0 -1
  601. package/src/shade/renderer/geometry/virtual/build/vgeo_split_face_set.d.ts.map +0 -1
  602. package/src/shade/renderer/geometry/virtual/build/vgeo_split_face_set_packed.d.ts.map +0 -1
  603. package/src/shade/renderer/geometry/virtual/build/vgeo_split_face_set_packed.js +0 -207
  604. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_copy_vertex.d.ts +0 -16
  605. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_copy_vertex.d.ts.map +0 -1
  606. package/src/shade/renderer/geometry/virtual/residency/VGeoResidencyManager.d.ts +0 -258
  607. package/src/shade/renderer/geometry/virtual/residency/VGeoResidencyManager.d.ts.map +0 -1
  608. package/src/shade/renderer/geometry/virtual/residency/VGeoResidencyOptions.d.ts +0 -49
  609. package/src/shade/renderer/geometry/virtual/residency/VGeoResidencyOptions.d.ts.map +0 -1
  610. package/src/shade/renderer/loader/gltf/fix_up_material_sides.d.ts +0 -10
  611. package/src/shade/renderer/loader/gltf/fix_up_material_sides.d.ts.map +0 -1
  612. package/src/shade/renderer/loader/gltf/fix_up_material_sides.js +0 -109
  613. package/src/shade/renderer/rasterize/expand/graph_triangles_filter_by_material_side.d.ts +0 -17
  614. package/src/shade/renderer/rasterize/expand/graph_triangles_filter_by_material_side.d.ts.map +0 -1
  615. package/src/shade/renderer/rasterize/expand/graph_triangles_filter_by_material_side.js +0 -78
  616. package/src/shade/renderer/rasterize/expand/shader_filter_triangle_by_material_side.d.ts +0 -3
  617. package/src/shade/renderer/rasterize/expand/shader_filter_triangle_by_material_side.d.ts.map +0 -1
  618. package/src/shade/renderer/rasterize/expand/shader_filter_triangle_by_material_side.js +0 -100
  619. package/src/shade/renderer/rasterize/forward/chunk_material_side_should_draw.d.ts +0 -8
  620. package/src/shade/renderer/rasterize/forward/chunk_material_side_should_draw.d.ts.map +0 -1
  621. package/src/shade/renderer/rasterize/forward/chunk_material_side_should_draw.js +0 -26
  622. package/src/shade/renderer/shader/chunk/jobs/chunk_job_system.d.ts +0 -3
  623. package/src/shade/renderer/shader/chunk/jobs/chunk_job_system.d.ts.map +0 -1
  624. /package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_assign_coordinates.d.ts +0 -0
  625. /package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_assign_layers.d.ts +0 -0
  626. /package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_break_cycles.d.ts +0 -0
  627. /package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_break_cycles.js +0 -0
  628. /package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_insert_lanes.d.ts +0 -0
  629. /package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_insert_lanes.js +0 -0
  630. /package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_order_layers.d.ts +0 -0
  631. /package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_order_layers.js +0 -0
  632. /package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_orient_links.d.ts +0 -0
  633. /package/src/core/{model/node-graph/visual/layout → graph/layout/layered}/layout_orient_links.js +0 -0
  634. /package/src/shade/playground/{vgeo_viewer → caldera}/main.d.ts +0 -0
  635. /package/src/shade/renderer/geometry/virtual/build/{VGeoLevel.d.ts → level/VGeoLevel.d.ts} +0 -0
  636. /package/src/shade/renderer/geometry/virtual/build/{VGeoLevel.js → level/VGeoLevel.js} +0 -0
  637. /package/src/shade/renderer/geometry/virtual/build/{VGeoLevelSummary.d.ts → level/VGeoLevelSummary.d.ts} +0 -0
  638. /package/src/shade/renderer/geometry/virtual/build/{VGeoLevelSummary.js → level/VGeoLevelSummary.js} +0 -0
  639. /package/src/shade/renderer/geometry/virtual/build/{vgeo_page_node_count.d.ts → page/vgeo_page_node_count.d.ts} +0 -0
  640. /package/src/shade/renderer/geometry/virtual/build/{vgeo_graph_components.d.ts → partition/vgeo_graph_components.d.ts} +0 -0
  641. /package/src/shade/renderer/geometry/virtual/build/{vgeo_graph_components.js → partition/vgeo_graph_components.js} +0 -0
  642. /package/src/shade/renderer/geometry/virtual/build/{vgeo_partition_graph.d.ts → partition/vgeo_partition_graph.d.ts} +0 -0
  643. /package/src/shade/renderer/geometry/virtual/build/{vgeo_split_face_set.d.ts → partition/vgeo_split_face_set.d.ts} +0 -0
  644. /package/src/shade/renderer/geometry/virtual/build/{vgeo_split_face_set_packed.d.ts → partition/vgeo_split_face_set_packed.d.ts} +0 -0
  645. /package/src/shade/renderer/geometry/virtual/build/{vgeo_bounding_sphere.d.ts → sphere/vgeo_bounding_sphere.d.ts} +0 -0
  646. /package/src/shade/renderer/geometry/virtual/build/{vgeo_containing_sphere.d.ts → sphere/vgeo_containing_sphere.d.ts} +0 -0
  647. /package/src/shade/renderer/geometry/virtual/build/{vgeo_sphere_inflate_to_contain.d.ts → sphere/vgeo_sphere_inflate_to_contain.d.ts} +0 -0
  648. /package/src/shade/renderer/geometry/virtual/build/{vgeo_narrow_indices.d.ts → submesh/vgeo_narrow_indices.d.ts} +0 -0
@@ -1,6 +1,13 @@
1
1
  import { assert } from "../../../../../../assert.js";
2
2
  import { Uint32Heap } from "../../../../../../collection/heap/Uint32Heap.js";
3
3
  import { Quadric3 } from "../../../../quadric/Quadric3.js";
4
+ import { QUADRIC3_SIZE } from "../../../../quadric/QUADRIC3_SIZE.js";
5
+ import { quadric3_add } from "../../../../quadric/quadric3_add.js";
6
+ import { quadric3_evaluate } from "../../../../quadric/quadric3_evaluate.js";
7
+ import { quadric_attribute_add } from "../../../../quadric/quadric_attribute_add.js";
8
+ import { quadric_attribute_reduce } from "../../../../quadric/quadric_attribute_reduce.js";
9
+ import { quadric_attribute_size } from "../../../../quadric/quadric_attribute_size.js";
10
+ import { quadric_attribute_solve } from "../../../../quadric/quadric_attribute_solve.js";
4
11
  import { NULL_POINTER } from "../BinaryTopology.js";
5
12
  import { bt_edge_collapse_would_fold } from "../query/bt_edge_collapse_would_fold.js";
6
13
  import { bt_loop_kill } from "./bt_loop_kill.js";
@@ -18,6 +25,51 @@ const scratch_coord_b = new Float32Array(3);
18
25
  const scratch_target = new Float32Array(3);
19
26
  const scratch_combined_q = new Quadric3();
20
27
 
28
+ /**
29
+ * The pair's summed attribute quadric, and its reduction. Grown to whatever channel count the
30
+ * current call carries and reused across every candidate it scores — `evaluate_edge_collapse` runs
31
+ * once per heap insert and again for every neighbour of every collapse, and an allocation there is
32
+ * an allocation per edge per round.
33
+ * @type {Float64Array}
34
+ */
35
+ let scratch_attribute_sum = new Float64Array(0);
36
+
37
+ /**
38
+ * @type {Float64Array}
39
+ */
40
+ const scratch_attribute_reduced = new Float64Array(QUADRIC3_SIZE);
41
+
42
+ /**
43
+ * One wedge group's reduction, on its way into the sum over groups.
44
+ * @type {Float64Array}
45
+ */
46
+ const scratch_group_reduced = new Float64Array(QUADRIC3_SIZE);
47
+
48
+ /**
49
+ * The wedges of a candidate's two endpoints, the survivor's first, and the local union-find that
50
+ * groups them. Only the multi-wedge path touches these, which on smooth geometry is never.
51
+ * @type {Uint32Array}
52
+ */
53
+ let scratch_wedge_ids = new Uint32Array(0);
54
+
55
+ /**
56
+ * @type {Uint32Array}
57
+ */
58
+ let scratch_wedge_group = new Uint32Array(0);
59
+
60
+ /**
61
+ * The corners of the faces a collapse would destroy, as `(at a, at b)` pairs. Two on a manifold
62
+ * edge, which is why it starts small and grows.
63
+ * @type {Uint32Array}
64
+ */
65
+ let scratch_dying_loops = new Uint32Array(8);
66
+
67
+ /**
68
+ * The fitted attribute record, on its way onto the survivor.
69
+ * @type {Float64Array}
70
+ */
71
+ let scratch_attribute_values = new Float64Array(0);
72
+
21
73
  /**
22
74
  * Count the number of still-live faces attached to an edge via its radial loop cycle.
23
75
  * Orphan loops (whose face was already killed by a prior collapse) are skipped so
@@ -60,10 +112,15 @@ function count_edge_faces(mesh, edge_id) {
60
112
  * @param {number} edge_id
61
113
  * @param {Quadric3[]} quadratics
62
114
  * @param {Set<number>} restricted_vertices
115
+ * @param {{values: Float64Array, components: number, quadrics: Float64Array, weights: Float64Array}|null}
116
+ * attributes the channels the collapse carries, or `null` to carry none
117
+ * @param {BtWedgeSet|null} wedges which corners of each vertex shade as one
63
118
  * @param {Float32Array|number[]} out_target Target position is written here.
64
119
  * @returns {number}
65
120
  */
66
- function evaluate_edge_collapse(mesh, edge_id, quadratics, restricted_vertices, out_target) {
121
+ function evaluate_edge_collapse(
122
+ mesh, edge_id, quadratics, restricted_vertices, attributes, wedges, out_target
123
+ ) {
67
124
  const v1 = mesh.edge_read_vertex1(edge_id);
68
125
  const v2 = mesh.edge_read_vertex2(edge_id);
69
126
 
@@ -89,6 +146,12 @@ function evaluate_edge_collapse(mesh, edge_id, quadratics, restricted_vertices,
89
146
  return Number.POSITIVE_INFINITY;
90
147
  }
91
148
 
149
+ let attribute_cost = 0;
150
+
151
+ if (attributes !== null) {
152
+ reduce_pair_attributes(mesh, v1, v2, attributes, wedges, scratch_attribute_reduced);
153
+ }
154
+
92
155
  if (v1_restricted) {
93
156
  mesh.vertex_read_coordinate(out_target, 0, v1);
94
157
  } else if (v2_restricted) {
@@ -97,6 +160,22 @@ function evaluate_edge_collapse(mesh, edge_id, quadratics, restricted_vertices,
97
160
  scratch_combined_q.copy(q1);
98
161
  scratch_combined_q.add(q2);
99
162
 
163
+ if (attributes !== null) {
164
+ /*
165
+ The channels decide where the vertex goes, and this is where they do it. `A` and `b` of
166
+ the reduced attribute quadric are what is left of them after the exact solve for their
167
+ own values, so a collapse across a crease or a texture seam is pulled away from the
168
+ placement that would smear it.
169
+
170
+ Only `optimize` reads this sum. Its weight slot is now a plane count plus a triangle
171
+ count, which is not a quantity, and nothing downstream takes a distance from it -- the
172
+ cost below is the two pure geometric quadrics, evaluated separately.
173
+ */
174
+ quadric3_add(
175
+ scratch_combined_q, 0, scratch_combined_q, 0, scratch_attribute_reduced, 0
176
+ );
177
+ }
178
+
100
179
  if (!scratch_combined_q.optimize(out_target)) {
101
180
  // Singular combined tensor: fall back to the midpoint
102
181
  mesh.vertex_read_coordinate(scratch_coord_a, 0, v1);
@@ -112,8 +191,14 @@ function evaluate_edge_collapse(mesh, edge_id, quadratics, restricted_vertices,
112
191
  const ty = out_target[1];
113
192
  const tz = out_target[2];
114
193
 
194
+ if (attributes !== null) {
195
+ // What the channels still cost once each has been given its best value at this position --
196
+ // in units of length, because the weights put them there.
197
+ attribute_cost = Math.abs(quadric3_evaluate(scratch_attribute_reduced, 0, tx, ty, tz));
198
+ }
199
+
115
200
  // Cost can drift slightly negative for near-zero values due to fp noise.
116
- return Math.abs(q1.evaluate(tx, ty, tz) + q2.evaluate(tx, ty, tz));
201
+ return Math.abs(q1.evaluate(tx, ty, tz) + q2.evaluate(tx, ty, tz)) + attribute_cost;
117
202
  }
118
203
 
119
204
  /**
@@ -124,9 +209,13 @@ function evaluate_edge_collapse(mesh, edge_id, quadratics, restricted_vertices,
124
209
  * @param {number} survivor
125
210
  * @param {Quadric3[]} quadratics
126
211
  * @param {Set<number>} restricted_vertices
212
+ * @param {{values: Float64Array, components: number, quadrics: Float64Array, weights: Float64Array}|null} attributes
213
+ * @param {BtWedgeSet|null} wedges
127
214
  * @param {Uint32Heap} heap
128
215
  */
129
- function update_neighbor_costs(mesh, survivor, quadratics, restricted_vertices, heap) {
216
+ function update_neighbor_costs(
217
+ mesh, survivor, quadratics, restricted_vertices, attributes, wedges, heap
218
+ ) {
130
219
  let curr_e = mesh.vertex_read_edge(survivor);
131
220
 
132
221
  if (curr_e === NULL_POINTER) {
@@ -148,7 +237,10 @@ function update_neighbor_costs(mesh, survivor, quadratics, restricted_vertices,
148
237
  const idx = heap.find_index_by_id(curr_e);
149
238
 
150
239
  if (idx !== -1) {
151
- const cost = evaluate_edge_collapse(mesh, curr_e, quadratics, restricted_vertices, scratch_target);
240
+ const cost = evaluate_edge_collapse(
241
+ mesh, curr_e, quadratics, restricted_vertices, attributes, wedges, scratch_target
242
+ );
243
+
152
244
  heap.__update_score_by_index(idx, cost);
153
245
  }
154
246
 
@@ -156,6 +248,504 @@ function update_neighbor_costs(mesh, survivor, quadratics, restricted_vertices,
156
248
  } while (curr_e !== start_e && curr_e !== NULL_POINTER);
157
249
  }
158
250
 
251
+ /**
252
+ * The corners of every face a collapse of `(a, b)` would destroy, as pairs — the corner at `a`
253
+ * followed by the corner at `b` — written into {@link scratch_dying_loops}.
254
+ *
255
+ * **The faces a collapse destroys are not only the ones on the edge it names.** They are the ones
256
+ * holding *both* endpoints: the edge's own, the ones on any parallel edge {@link bt_edge_kill_parallels}
257
+ * clears first, and the ones {@link bt_vertex_fuse_duplicate_edges} finds degenerate afterwards. That
258
+ * is {@link collapse_kills_protected_face}'s contract, written down there and true here for the same
259
+ * reason — and a triangle holding both endpoints has an edge between them, so walking the disk cycle
260
+ * for edges to `b` finds all of them.
261
+ *
262
+ * Walking one radial cycle instead would miss the parallel edges, and a wedge whose only dying face
263
+ * is on one of those would be adopted by the survivor rather than merged into it: two corner groups
264
+ * that are one piece of surface, left as two, which is a crease where the mesh has none.
265
+ *
266
+ * @param {BinaryTopology} mesh
267
+ * @param {number} a
268
+ * @param {number} b
269
+ * @returns {number} how many pairs were written
270
+ */
271
+ function collect_dying_faces(mesh, a, b) {
272
+ let count = 0;
273
+
274
+ let edge = mesh.vertex_read_edge(a);
275
+
276
+ if (edge === NULL_POINTER) {
277
+ return 0;
278
+ }
279
+
280
+ const start_edge = edge;
281
+ const face_pool = mesh.faces;
282
+
283
+ do {
284
+ const at_v1 = mesh.edge_read_vertex1(edge) === a;
285
+
286
+ const other = at_v1 ? mesh.edge_read_vertex2(edge) : mesh.edge_read_vertex1(edge);
287
+
288
+ if (other === b) {
289
+ const first_loop = mesh.edge_read_loop(edge);
290
+
291
+ let loop = first_loop;
292
+
293
+ while (loop !== NULL_POINTER) {
294
+ const face = mesh.loop_read_face(loop);
295
+
296
+ if (face !== NULL_POINTER && face_pool.is_allocated(face)) {
297
+ const next_loop = mesh.loop_read_next(loop);
298
+
299
+ const at_a = mesh.loop_read_vertex(loop) === a ? loop : next_loop;
300
+
301
+ if (scratch_dying_loops.length < (count + 1) * 2) {
302
+ const grown = new Uint32Array(Math.max(8, (count + 1) * 4));
303
+
304
+ grown.set(scratch_dying_loops);
305
+
306
+ scratch_dying_loops = grown;
307
+ }
308
+
309
+ scratch_dying_loops[count * 2] = at_a;
310
+ scratch_dying_loops[count * 2 + 1] = at_a === loop ? next_loop : loop;
311
+
312
+ count++;
313
+ }
314
+
315
+ loop = mesh.loop_read_radial_next(loop);
316
+
317
+ if (loop === first_loop) {
318
+ break;
319
+ }
320
+ }
321
+ }
322
+
323
+ edge = at_v1 ? mesh.edge_read_v1_disk_next(edge) : mesh.edge_read_v2_disk_next(edge);
324
+ } while (edge !== start_edge && edge !== NULL_POINTER);
325
+
326
+ return count;
327
+ }
328
+
329
+ /**
330
+ * Which wedges of a collapse's two endpoints would become one, and the reduced attribute quadric
331
+ * that follows from it.
332
+ *
333
+ * **A live face is what says two corners shade as one.** Each face on the edge holds one corner at
334
+ * each endpoint, and that face is about to die into the survivor — so whatever those two corners
335
+ * were, they are one corner's worth of surface afterwards. Everything else the two vertices carry
336
+ * stays apart. That rule needs no tolerance and no comparison of values, which matters: two
337
+ * neighbours on a smoothly curved surface have genuinely different normals, so a rule that merged
338
+ * only equal values would invent a crease at every collapse a sphere has.
339
+ *
340
+ * Each resulting group is reduced separately and the reductions summed, because each group solves
341
+ * for its own value ({@link quadric_attribute_reduce} is the substitution of that solve). Summing
342
+ * the quadrics first and reducing once would be the claim that all of them share one value, which
343
+ * is the thing a seam denies.
344
+ *
345
+ * **A collapse with no face to destroy is a fuse of two points, not a simplification of a surface**,
346
+ * and it is treated as one group. Nothing survives to hold the corners apart, and the alternative
347
+ * leaves the victim's accumulated history on a wedge that may have no corners left to carry it. Rare,
348
+ * and measured rather than assumed: 6 of 6,195 collapses over a 12,288-triangle sphere's whole DAG.
349
+ *
350
+ * @param {BinaryTopology} mesh
351
+ * @param {number} v1
352
+ * @param {number} v2
353
+ * @param {{values: Float64Array, components: number, quadrics: Float64Array, weights: Float64Array}} attributes
354
+ * @param {BtWedgeSet} wedges
355
+ * @param {Float64Array} out `QUADRIC3_SIZE` elements, overwritten
356
+ */
357
+ function reduce_pair_attributes(mesh, v1, v2, attributes, wedges, out) {
358
+ const components = attributes.components;
359
+ const size = quadric_attribute_size(components);
360
+
361
+ const quadrics = attributes.quadrics;
362
+
363
+ const first_1 = wedges.first_of_vertex[v1];
364
+ const first_2 = wedges.first_of_vertex[v2];
365
+
366
+ /*
367
+ One wedge each, which is every vertex of a mesh with no seams and the overwhelming majority of
368
+ one that has them. They can only end up in the same group, so the answer is the sum of the two
369
+ reduced once -- exactly the arithmetic this had before wedges existed, kept on the path that
370
+ runs once per edge per round.
371
+ */
372
+ if (
373
+ first_1 !== NULL_POINTER && wedges.next_of_wedge[first_1] === NULL_POINTER
374
+ && first_2 !== NULL_POINTER && wedges.next_of_wedge[first_2] === NULL_POINTER
375
+ ) {
376
+ quadric_attribute_add(
377
+ scratch_attribute_sum, 0,
378
+ quadrics, first_1 * size, quadrics, first_2 * size,
379
+ components
380
+ );
381
+
382
+ quadric_attribute_reduce(out, 0, scratch_attribute_sum, 0, components);
383
+
384
+ return;
385
+ }
386
+
387
+ let count = 0;
388
+
389
+ for (let w = first_1; w !== NULL_POINTER; w = wedges.next_of_wedge[w]) {
390
+ count++;
391
+ }
392
+
393
+ for (let w = first_2; w !== NULL_POINTER; w = wedges.next_of_wedge[w]) {
394
+ count++;
395
+ }
396
+
397
+ if (scratch_wedge_ids.length < count) {
398
+ scratch_wedge_ids = new Uint32Array(count);
399
+ scratch_wedge_group = new Uint32Array(count);
400
+ }
401
+
402
+ let n = 0;
403
+
404
+ for (let w = first_1; w !== NULL_POINTER; w = wedges.next_of_wedge[w]) {
405
+ scratch_wedge_ids[n] = w;
406
+ scratch_wedge_group[n] = n;
407
+ n++;
408
+ }
409
+
410
+ const first_count = n;
411
+
412
+ for (let w = first_2; w !== NULL_POINTER; w = wedges.next_of_wedge[w]) {
413
+ scratch_wedge_ids[n] = w;
414
+ scratch_wedge_group[n] = n;
415
+ n++;
416
+ }
417
+
418
+ const dying = collect_dying_faces(mesh, v1, v2);
419
+
420
+ for (let pair = 0; pair < dying; pair++) {
421
+ local_union(
422
+ local_index(wedges.find(wedges.of_loop[scratch_dying_loops[pair * 2]]), n),
423
+ local_index(wedges.find(wedges.of_loop[scratch_dying_loops[pair * 2 + 1]]), n)
424
+ );
425
+ }
426
+
427
+ if (dying === 0 && first_count > 0) {
428
+ /*
429
+ Whatever the second vertex holds joins the first's first wedge, and the first's *other*
430
+ wedges are left alone -- which is exactly what {@link carry_wedges} does when the edge has no
431
+ face, and the two have to agree or the price of a collapse is not the price of the collapse
432
+ that happens. (Which of the pair survives is decided after this runs, so a swapped pair
433
+ scores the mirror of what it will do; the shape of the partition is the same either way and
434
+ this is a heuristic over 0.1% of collapses.)
435
+ */
436
+ for (let i = first_count; i < n; i++) {
437
+ local_union(0, i);
438
+ }
439
+ }
440
+
441
+ out.fill(0, 0, QUADRIC3_SIZE);
442
+
443
+ for (let group = 0; group < n; group++) {
444
+ if (local_find(group) !== group) {
445
+ continue;
446
+ }
447
+
448
+ let members = 0;
449
+
450
+ for (let i = 0; i < n; i++) {
451
+ if (local_find(i) !== group) {
452
+ continue;
453
+ }
454
+
455
+ const from = scratch_wedge_ids[i] * size;
456
+
457
+ if (members === 0) {
458
+ for (let element = 0; element < size; element++) {
459
+ scratch_attribute_sum[element] = quadrics[from + element];
460
+ }
461
+ } else {
462
+ quadric_attribute_add(
463
+ scratch_attribute_sum, 0, scratch_attribute_sum, 0, quadrics, from, components
464
+ );
465
+ }
466
+
467
+ members++;
468
+ }
469
+
470
+ quadric_attribute_reduce(scratch_group_reduced, 0, scratch_attribute_sum, 0, components);
471
+
472
+ quadric3_add(out, 0, out, 0, scratch_group_reduced, 0);
473
+ }
474
+ }
475
+
476
+ /**
477
+ * Where a wedge id sits in {@link scratch_wedge_ids}, or `-1`.
478
+ *
479
+ * A scan rather than a map: it is over the wedges of two vertices, which is two on a crease and one
480
+ * on everything else.
481
+ *
482
+ * @param {number} wedge
483
+ * @param {number} count
484
+ * @returns {number}
485
+ */
486
+ function local_index(wedge, count) {
487
+ for (let i = 0; i < count; i++) {
488
+ if (scratch_wedge_ids[i] === wedge) {
489
+ return i;
490
+ }
491
+ }
492
+
493
+ return -1;
494
+ }
495
+
496
+ /**
497
+ * @param {number} index
498
+ * @returns {number}
499
+ */
500
+ function local_find(index) {
501
+ let root = index;
502
+
503
+ while (scratch_wedge_group[root] !== root) {
504
+ root = scratch_wedge_group[root];
505
+ }
506
+
507
+ return root;
508
+ }
509
+
510
+ /**
511
+ * @param {number} a index into {@link scratch_wedge_ids}, or `-1` for a wedge not among them
512
+ * @param {number} b
513
+ */
514
+ function local_union(a, b) {
515
+ if (a < 0 || b < 0) {
516
+ return;
517
+ }
518
+
519
+ const root_a = local_find(a);
520
+ const root_b = local_find(b);
521
+
522
+ if (root_a !== root_b) {
523
+ scratch_wedge_group[root_b] = root_a;
524
+ }
525
+ }
526
+
527
+ /**
528
+ * Move the survivor's attribute record onto the value the pair between them stands for, when there
529
+ * is no field to fit one from.
530
+ *
531
+ * The fallback, not the rule. A vertex whose every incident triangle was a sliver -- or which has
532
+ * none left at all -- has an attribute quadric of no weight, and a quadric of no weight has no field
533
+ * to evaluate. Blending is what is left, and it is a reasonable answer rather than a good one: it is
534
+ * confined to the values that went in, where a fit is not, and it says nothing about where the
535
+ * vertex ended up.
536
+ *
537
+ * Blended by accumulated quadric weight, which is how much source surface each endpoint speaks for:
538
+ * a vertex that a dozen collapses have folded into already represents a dozen vertices' worth of the
539
+ * original, and taking half its word against a vertex that represents one would let whichever side
540
+ * of a merge happened to be shorter of history pull the value across.
541
+ *
542
+ * Two endpoints that have accumulated nothing have no claim over one another, and split it.
543
+ *
544
+ * @param {Float64Array} values indexed by wedge id, `components` elements each
545
+ * @param {number} components
546
+ * @param {number} survivor wedge
547
+ * @param {number} victim wedge
548
+ * @param {number} survivor_weight
549
+ * @param {number} victim_weight
550
+ */
551
+ function blend_attributes(values, components, survivor, victim, survivor_weight, victim_weight) {
552
+ const total = survivor_weight + victim_weight;
553
+
554
+ const survivor_share = total > 0 ? survivor_weight / total : 0.5;
555
+ const victim_share = 1 - survivor_share;
556
+
557
+ const survivor_base = survivor * components;
558
+ const victim_base = victim * components;
559
+
560
+ for (let component = 0; component < components; component++) {
561
+ values[survivor_base + component] =
562
+ values[survivor_base + component] * survivor_share
563
+ + values[victim_base + component] * victim_share;
564
+ }
565
+ }
566
+
567
+ /**
568
+ * Merge the pair's wedges, and — where there are values riding along — decide what the survivor
569
+ * carries and give it the victim's accumulated fields.
570
+ *
571
+ * **The merge happens whether or not anything is being carried.** A wedge set is a statement about
572
+ * which corners of the result belong together, and a set that stops tracking collapses is a set
573
+ * whose ids go stale: the victim's loops arrive at the survivor still naming the victim's wedge, and
574
+ * every consumer downstream reads a seam where there is none. Measured, because it got past a
575
+ * byte-identity gate and was caught by an unrelated assertion instead: a round over a mesh with no
576
+ * channels at all cut clusters of 132 vertices against a ceiling of 128.
577
+ *
578
+ * Once per **wedge**, because a vertex has one position and not one appearance. The survivor comes
579
+ * out of this holding its own wedges, whichever of the victim's merged into them, and whichever of
580
+ * the victim's did not — those simply move, still carrying what they always did.
581
+ * {@link reduce_pair_attributes} is the rule for which is which, and it is the same walk.
582
+ *
583
+ * Every wedge that ends up on the survivor is fitted afresh, not only the merged ones: the vertex
584
+ * moved, and a field is evaluated *at a position*.
585
+ *
586
+ * A merged wedge's quadric absorbs its partner's first, so the fit it is then asked for is over
587
+ * *everything* the pair has ever stood for — which is what makes the answer a deviation from the
588
+ * source rather than from the step before it, exactly as the geometric quadric's is.
589
+ *
590
+ * Then the value: the position it is being moved to, plugged into the field those accumulated
591
+ * triangles describe. Where there is no field — a wedge every one of whose triangles was a sliver,
592
+ * or which has no triangles left — {@link blend_attributes} is the fallback, applied at the merge so
593
+ * that a wedge with nothing to fit from still ends up between the two values rather than on one of
594
+ * them. A successful fit overwrites it. (Two victim wedges merging into one survivor wedge, which
595
+ * takes a non-manifold edge, blend the second against the first's result; it is a fallback inside a
596
+ * fallback and it is confined to the values that went in either way.)
597
+ *
598
+ * **A restricted survivor is given the victim's fields and none of its values.** Its position does
599
+ * not move, but the fit at that unchanged position would still come out different, because `W`, `G`
600
+ * and `D` under it have grown. That would break the one thing pinning is for: a vertex two groups
601
+ * share must carry byte-identical values in both. It keeps the quadric so that a *later* step, one
602
+ * that is free to move it, fits from the whole history rather than from the fragment it started
603
+ * with. A wedge it *adopts* is a wedge the other group never had, carrying corners that are this
604
+ * group's alone, so it is no exception to that.
605
+ *
606
+ * @param {BinaryTopology} mesh
607
+ * @param {BtWedgeSet} wedges
608
+ * @param {{values: Float64Array, components: number, quadrics: Float64Array, weights: Float64Array}|null} attributes
609
+ * @param {number} survivor
610
+ * @param {number} victim
611
+ * @param {boolean} survivor_restricted
612
+ * @param {number} survivor_weight geometric quadric weight, for the fallback
613
+ * @param {number} victim_weight
614
+ * @param {Float32Array|number[]} target where the survivor is being moved to
615
+ */
616
+ function carry_wedges(
617
+ mesh, wedges, attributes, survivor, victim, survivor_restricted,
618
+ survivor_weight, victim_weight, target
619
+ ) {
620
+ const dying = collect_dying_faces(mesh, survivor, victim);
621
+
622
+ for (let pair = 0; pair < dying; pair++) {
623
+ absorb_wedge(
624
+ wedges, attributes,
625
+ wedges.find(wedges.of_loop[scratch_dying_loops[pair * 2]]),
626
+ wedges.find(wedges.of_loop[scratch_dying_loops[pair * 2 + 1]]),
627
+ survivor_restricted, survivor_weight, victim_weight
628
+ );
629
+ }
630
+
631
+ if (dying === 0 && wedges.first_of_vertex[survivor] !== NULL_POINTER) {
632
+ // A fuse of two points rather than a simplification of a surface; see
633
+ // {@link reduce_pair_attributes}, whose cost model this has to agree with.
634
+ const into = wedges.find(wedges.first_of_vertex[survivor]);
635
+
636
+ for (
637
+ let wedge = wedges.first_of_vertex[victim];
638
+ wedge !== NULL_POINTER;
639
+ wedge = wedges.next_of_wedge[wedge]
640
+ ) {
641
+ absorb_wedge(
642
+ wedges, attributes, into, wedges.find(wedge),
643
+ survivor_restricted, survivor_weight, victim_weight
644
+ );
645
+ }
646
+ }
647
+
648
+ // The survivor's own list, less whatever merged into something else, then the victim's on top of
649
+ // it. The loops themselves are not touched: a corner's wedge id goes stale and `find` resolves
650
+ // it, which is the whole reason nothing has to go looking for a corner in order to move it.
651
+ relist_wedges(wedges, survivor, survivor);
652
+ relist_wedges(wedges, victim, survivor);
653
+
654
+ if (survivor_restricted || attributes === null) {
655
+ return;
656
+ }
657
+
658
+ const components = attributes.components;
659
+
660
+ for (
661
+ let wedge = wedges.first_of_vertex[survivor];
662
+ wedge !== NULL_POINTER;
663
+ wedge = wedges.next_of_wedge[wedge]
664
+ ) {
665
+ const fitted = quadric_attribute_solve(
666
+ scratch_attribute_values, 0,
667
+ attributes.quadrics, wedge * quadric_attribute_size(components), components,
668
+ attributes.weights,
669
+ target[0], target[1], target[2]
670
+ );
671
+
672
+ if (fitted) {
673
+ attributes.values.set(
674
+ scratch_attribute_values.subarray(0, components), wedge * components
675
+ );
676
+ }
677
+ }
678
+ }
679
+
680
+ /**
681
+ * Make `other` part of `wedge`: its accumulated field, and — for the case where there turns out to
682
+ * be no field to fit from — its value.
683
+ *
684
+ * @param {BtWedgeSet} wedges
685
+ * @param {{values: Float64Array, components: number, quadrics: Float64Array, weights: Float64Array}|null} attributes
686
+ * @param {number} wedge root that survives, the survivor's
687
+ * @param {number} other root that does not, the victim's
688
+ * @param {boolean} survivor_restricted
689
+ * @param {number} survivor_weight
690
+ * @param {number} victim_weight
691
+ */
692
+ function absorb_wedge(
693
+ wedges, attributes, wedge, other, survivor_restricted, survivor_weight, victim_weight
694
+ ) {
695
+ if (!wedges.merge(wedge, other)) {
696
+ // Already one wedge. A manifold edge's two faces name the same pair twice, which is the
697
+ // common case rather than an oddity, so this is the guard that keeps a quadric from being
698
+ // counted into itself.
699
+ return;
700
+ }
701
+
702
+ if (attributes === null) {
703
+ return;
704
+ }
705
+
706
+ const components = attributes.components;
707
+ const size = quadric_attribute_size(components);
708
+
709
+ quadric_attribute_add(
710
+ attributes.quadrics, wedge * size,
711
+ attributes.quadrics, wedge * size,
712
+ attributes.quadrics, other * size,
713
+ components
714
+ );
715
+
716
+ if (!survivor_restricted) {
717
+ blend_attributes(
718
+ attributes.values, components, wedge, other, survivor_weight, victim_weight
719
+ );
720
+ }
721
+ }
722
+
723
+ /**
724
+ * Move every wedge of `from` onto `to`, dropping the ones that are no longer their own root.
725
+ *
726
+ * `from === to` is a compaction in place, which is what the survivor needs: its own wedges can have
727
+ * merged into each other, through a victim wedge that touched both.
728
+ *
729
+ * @param {BtWedgeSet} wedges
730
+ * @param {number} from vertex
731
+ * @param {number} to vertex
732
+ */
733
+ function relist_wedges(wedges, from, to) {
734
+ let wedge = wedges.first_of_vertex[from];
735
+
736
+ wedges.detach_all(from);
737
+
738
+ while (wedge !== NULL_POINTER) {
739
+ const next = wedges.next_of_wedge[wedge];
740
+
741
+ if (wedges.find(wedge) === wedge) {
742
+ wedges.attach(wedge, to);
743
+ }
744
+
745
+ wedge = next;
746
+ }
747
+ }
748
+
159
749
  /**
160
750
  * Would collapsing this edge destroy a face the caller asked to keep?
161
751
  *
@@ -316,7 +906,48 @@ export function bt_mesh_simplify(
316
906
  * @param {number} target_face_count Desired face count after simplification.
317
907
  * @param {Set<number>} restricted_vertices Vertices that must not move or be removed.
318
908
  * @param {Set<number>} protected_faces Faces that must not be removed.
909
+ * `attributes` is per-vertex data that travels *through* the collapse rather than being re-derived
910
+ * from the result. Whatever a merged vertex is to carry has to be decided here, from the values
911
+ * being merged: the mesh a collapse leaves behind is a different surface, and a value read off it
912
+ * afterwards describes that one rather than the one the caller started with.
913
+ *
914
+ * It is carried per **wedge** — a set of corners at one vertex that shade as one — so a hard edge
915
+ * or a texture seam survives a collapse instead of being averaged away. Which of the pair's wedges
916
+ * become one is decided by the faces the collapse destroys, in {@link reduce_pair_attributes}; a
917
+ * mesh with no seams has one wedge per vertex, every collapse merges the pair, and all of this is
918
+ * the arithmetic it always was.
919
+ *
920
+ * It is **fitted**, not inherited and not averaged. Each channel varies affinely over a triangle, so
921
+ * every triangle a wedge has ever absorbed says what that channel should be at any position; the
922
+ * survivor takes the value that best explains all of them at once, at the position it is being moved
923
+ * to ({@link quadric_attribute_solve}). Those same accumulated fields also reach the *placement* and
924
+ * the cost, through {@link quadric_attribute_reduce} -- so a collapse that would smear a crease or a
925
+ * texture seam is both moved away from it and priced for it. A vertex with no field to fit from
926
+ * falls back to a weighted blend, and a **restricted** survivor is left exactly as it is, for the
927
+ * same reason its position is.
928
+ *
929
+ * The values themselves mean nothing here. A caller whose record holds a direction or a flag rather
930
+ * than a quantity has to say so afterwards, over the array this leaves behind.
931
+ *
932
+ * What the call **returns** is still the pure geometric quadric's answer, evaluated at wherever the
933
+ * higher-dimensional metric put each vertex. Solving in one metric and reporting in the other is
934
+ * what keeps the number an object-space length (`VIRTUAL_GEOMETRY_DESIGN.md` §3).
935
+ *
319
936
  * @param {Quadric3[]} quadratics indexed by vertex id, one per allocated vertex; mutated in place
937
+ * @param {{values: Float64Array, components: number, quadrics: Float64Array, weights: Float64Array}|null} [attributes]
938
+ * per-wedge records to carry through the collapses, with the attribute quadrics that fit them
939
+ * ({@link bt_mesh_compute_wedge_attribute_quadrics}) and the per-channel weights those were
940
+ * built with. `values` and `quadrics` are indexed by **wedge id**;
941
+ * {@link bt_wedges_per_vertex} is the set where that is the vertex id. `null` to carry nothing,
942
+ * which is what every caller but the virtual-geometry builder does. {@link bt_mesh_simplify_by_error}
943
+ * is not among them at all — it is a separate implementation with its own cost function, and so
944
+ * is untouched by any of this, which matters because it simplifies to a *tolerance* that an
945
+ * attribute term would quietly move.
946
+ * @param {BtWedgeSet|null} [wedges] which corners of each vertex shade as one, **mutated in place**
947
+ * as the collapses merge them. Required when `attributes` is given, and useful without it: a
948
+ * caller that carries no values may still care which corners of the result belong together, and
949
+ * a set that is not maintained is a set whose ids go stale — corners of one vertex would resolve
950
+ * to different wedges and every consumer downstream would see a seam that is not there.
320
951
  * @returns {number} object-space distance the surface moved, `0` when no collapse was performed
321
952
  */
322
953
  export function bt_mesh_simplify_with_quadrics(
@@ -324,7 +955,9 @@ export function bt_mesh_simplify_with_quadrics(
324
955
  target_face_count,
325
956
  restricted_vertices,
326
957
  protected_faces,
327
- quadratics
958
+ quadratics,
959
+ attributes = null,
960
+ wedges = null
328
961
  ) {
329
962
  assert.defined(mesh, 'mesh');
330
963
  assert.notNull(mesh, 'mesh');
@@ -345,6 +978,22 @@ export function bt_mesh_simplify_with_quadrics(
345
978
  return 0;
346
979
  }
347
980
 
981
+ if (attributes !== null) {
982
+ assert.notNull(wedges, 'wedges, which carrying attributes requires');
983
+
984
+ const size = quadric_attribute_size(attributes.components);
985
+
986
+ // Grown, never shrunk: a build is thousands of calls over the same handful of channel
987
+ // counts, and every one of them would otherwise allocate.
988
+ if (scratch_attribute_sum.length < size) {
989
+ scratch_attribute_sum = new Float64Array(size);
990
+ }
991
+
992
+ if (scratch_attribute_values.length < attributes.components) {
993
+ scratch_attribute_values = new Float64Array(attributes.components);
994
+ }
995
+ }
996
+
348
997
  const edge_pool = mesh.edges;
349
998
  const heap = new Uint32Heap(edge_pool.size);
350
999
 
@@ -357,7 +1006,9 @@ export function bt_mesh_simplify_with_quadrics(
357
1006
  continue;
358
1007
  }
359
1008
 
360
- const cost = evaluate_edge_collapse(mesh, e, quadratics, restricted_vertices, scratch_target);
1009
+ const cost = evaluate_edge_collapse(
1010
+ mesh, e, quadratics, restricted_vertices, attributes, wedges, scratch_target
1011
+ );
361
1012
 
362
1013
  if (cost === Number.POSITIVE_INFINITY) {
363
1014
  continue;
@@ -407,7 +1058,9 @@ export function bt_mesh_simplify_with_quadrics(
407
1058
  continue;
408
1059
  }
409
1060
 
410
- const cost = evaluate_edge_collapse(mesh, edge_id, quadratics, restricted_vertices, scratch_target);
1061
+ const cost = evaluate_edge_collapse(
1062
+ mesh, edge_id, quadratics, restricted_vertices, attributes, wedges, scratch_target
1063
+ );
411
1064
 
412
1065
  if (cost === Number.POSITIVE_INFINITY) {
413
1066
  continue;
@@ -433,6 +1086,20 @@ export function bt_mesh_simplify_with_quadrics(
433
1086
  const pre_survivor = mesh.edge_read_vertex1(edge_id);
434
1087
  const pre_victim = mesh.edge_read_vertex2(edge_id);
435
1088
 
1089
+ // Before the accumulation below, which is what makes the blend fallback weigh the two
1090
+ // endpoints' own histories rather than the survivor's already carrying the victim's. And
1091
+ // before the topology mutates, which is what lets the faces about to die say which corners
1092
+ // shade as one.
1093
+ if (wedges !== null) {
1094
+ carry_wedges(
1095
+ mesh, wedges, attributes, pre_survivor, pre_victim,
1096
+ restricted_vertices.has(pre_survivor),
1097
+ quadratics[pre_survivor].weight,
1098
+ quadratics[pre_victim].weight,
1099
+ scratch_target
1100
+ );
1101
+ }
1102
+
436
1103
  // Accumulate victim's quadric onto the survivor before the topology mutates.
437
1104
  quadratics[pre_survivor].add(quadratics[pre_victim]);
438
1105
  quadratics[pre_victim] = null;
@@ -453,7 +1120,9 @@ export function bt_mesh_simplify_with_quadrics(
453
1120
  // are still intact.
454
1121
  current_face_count -= bt_vertex_fuse_duplicate_edges(mesh, survivor);
455
1122
 
456
- update_neighbor_costs(mesh, survivor, quadratics, restricted_vertices, heap);
1123
+ update_neighbor_costs(
1124
+ mesh, survivor, quadratics, restricted_vertices, attributes, wedges, heap
1125
+ );
457
1126
  }
458
1127
 
459
1128
  // Measured here, before the cleanup below, because a vertex left behind by a patch that was