@woosh/meep-engine 3.1.0 → 3.2.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 (1822) hide show
  1. package/LICENSE +188 -188
  2. package/README.md +152 -152
  3. package/editor/Editor.js +598 -598
  4. package/editor/EditorCameraNavigation.js +205 -205
  5. package/editor/EditorKeyMap.js +182 -182
  6. package/editor/SelectionVisualizer.js +127 -127
  7. package/editor/actions/concrete/ActionInvalidateSampler.js +27 -27
  8. package/editor/actions/concrete/PatchTerrainHeightAction.js +85 -85
  9. package/editor/camera/camera_framing.js +104 -104
  10. package/editor/clipboard.js +184 -184
  11. package/editor/ecs/component/editors/ObservedIntegerEditor.js +22 -22
  12. package/editor/ecs/component/editors/ObservedStringEditor.js +34 -34
  13. package/editor/ecs/component/editors/common/two_way_sync.js +50 -50
  14. package/editor/ecs/component/editors/ecs/GridObstacleEditor.js +19 -19
  15. package/editor/ecs/component/editors/ecs/ParameterLookupTableEditor.js +35 -35
  16. package/editor/ecs/component/editors/ecs/ParameterTrackEditor.js +17 -17
  17. package/editor/ecs/component/editors/ecs/SGMeshEditor.js +24 -24
  18. package/editor/ecs/component/editors/ecs/ShadedGeometryEditor.js +33 -33
  19. package/editor/ecs/component/editors/ecs/Trail3DEditor.js +45 -45
  20. package/editor/ecs/component/editors/ecs/buildGridObstaclePreview.js +19 -19
  21. package/editor/ecs/component/editors/ecs/terrain/TerrainEditor.js +72 -72
  22. package/editor/ecs/component/editors/shade/MeshletGeometryEditor.js +30 -30
  23. package/editor/ecs/component/editors/shade/ShadeImageEditor.js +70 -70
  24. package/editor/ecs/component/editors/shade/ShadeMaterialEditor.js +34 -34
  25. package/editor/ecs/component/editors/shade/ShadeTextureEditor.js +46 -46
  26. package/editor/ecs/component/editors/shade/StandardShadeMaterialEditor.js +24 -24
  27. package/editor/ecs/component/prototypeObjectEditor.js +265 -265
  28. package/editor/ecs/component/registerBasicTypeEditors.js +100 -100
  29. package/editor/ecs/component/registerEngineComponentEditors.js +95 -95
  30. package/editor/entity_world_bounds.js +27 -27
  31. package/editor/particles/lut_ops.js +148 -148
  32. package/editor/particles/particleEditEvents.js +12 -12
  33. package/editor/particles/rebuildParticleEmitter.js +31 -31
  34. package/editor/persistence/EditorLayoutStore.js +71 -71
  35. package/editor/persistence/SceneMetadata.js +52 -52
  36. package/editor/persistence/SceneSlotManager.js +144 -144
  37. package/editor/persistence/buildNewSceneDataset.js +67 -67
  38. package/editor/persistence/files.js +68 -68
  39. package/editor/persistence/scene_import.js +143 -143
  40. package/editor/persistence/scene_serialization.js +79 -79
  41. package/editor/persistence/string_buffer_codec.js +41 -41
  42. package/editor/process/GridDisplayProcess.js +125 -125
  43. package/editor/process/SymbolicDisplayProcess.js +106 -108
  44. package/editor/process/symbolic/CameraSymbolicDisplay.js +146 -146
  45. package/editor/process/symbolic/LightSymbolicDisplay.js +172 -172
  46. package/editor/process/symbolic/PathSymbolicDisplay.js +118 -118
  47. package/editor/process/symbolic/PositionedMarkerSymbolicDisplay.js +79 -79
  48. package/editor/process/symbolic/SoundEmitterSymbolicDisplay.js +57 -57
  49. package/editor/process/symbolic/SymbolicDisplay.js +62 -62
  50. package/editor/process/symbolic/gizmo_draw_wire_box_oriented.js +85 -85
  51. package/editor/process/symbolic/gizmo_draw_wire_circle.js +53 -53
  52. package/editor/prototypeEditorShell.js +156 -156
  53. package/editor/selection/editor_pick.js +130 -130
  54. package/editor/selection/screen_rect_frustum.js +119 -119
  55. package/editor/style/controls.scss +168 -168
  56. package/editor/style/inspector.scss +223 -223
  57. package/editor/templates/entity_templates.js +167 -167
  58. package/editor/tools/GridPaintTool.js +273 -273
  59. package/editor/tools/SelectionTool.js +307 -307
  60. package/editor/tools/TransformToolV2.js +378 -378
  61. package/editor/tools/engine/ToolEngine.js +188 -188
  62. package/editor/tools/paint/TerrainTexturePaintTool.js +250 -250
  63. package/editor/tools/v2/BlenderCameraOrientationGizmo.js +501 -501
  64. package/editor/tools/v2/TransformControls.js +971 -971
  65. package/editor/tools/v2/handle/gizmo_drag_plane.js +141 -141
  66. package/editor/tools/v2/handle/gizmo_draw.js +399 -399
  67. package/editor/tools/v2/handle/gizmo_handles.js +364 -364
  68. package/editor/tools/v2/handle/gizmo_ray_shapes.js +239 -239
  69. package/editor/view/ecs/HierarchicalEntityListView.js +339 -339
  70. package/editor/view/ecs/components/DatGuiController.js +2 -2
  71. package/editor/view/ecs/components/common/AutoCanvasView.js +100 -100
  72. package/editor/view/ecs/components/common/TextController.js +59 -59
  73. package/editor/view/library/MeshLibraryView.js +175 -175
  74. package/editor/view/library/mesh_library_drag.js +63 -63
  75. package/editor/view/library/model_thumbnail_source.js +86 -86
  76. package/editor/view/makeEntityDecorators.js +125 -125
  77. package/editor/view/node-graph/NodeGraphSelection.js +89 -89
  78. package/editor/view/node-graph/NodeView.js +211 -211
  79. package/editor/view/node-graph/actions/ConnectionDeleteAction.js +36 -36
  80. package/editor/view/node-graph/actions/NodesMoveAction.js +41 -41
  81. package/editor/view/node-graph/connection_wire_geometry.js +107 -107
  82. package/editor/view/particles/ColorLutGradientView.js +291 -291
  83. package/editor/view/particles/ScalarLutCurveView.js +279 -279
  84. package/editor/view/prepareMeshLibrary.js +188 -188
  85. package/editor/view/shell/SceneTreePanelView.js +119 -119
  86. package/editor/view/v2/SplitView.js +2 -2
  87. package/package.json +94 -94
  88. package/samples/generation/generators/interactive/mir_generator_place_buff_objects.js +362 -362
  89. package/src/DUPLICATION_AUDIT_2026_08_07/00_core_reuse_surface.md +738 -738
  90. package/src/DUPLICATION_AUDIT_2026_08_07/A_core_math_geom.md +79 -79
  91. package/src/DUPLICATION_AUDIT_2026_08_07/B_core_data.md +93 -93
  92. package/src/DUPLICATION_AUDIT_2026_08_07/C_gfx_render.md +80 -80
  93. package/src/DUPLICATION_AUDIT_2026_08_07/D_gfx_features.md +164 -164
  94. package/src/DUPLICATION_AUDIT_2026_08_07/E_physics.md +69 -69
  95. package/src/DUPLICATION_AUDIT_2026_08_07/F_sound.md +102 -102
  96. package/src/DUPLICATION_AUDIT_2026_08_07/G_net_save.md +129 -129
  97. package/src/DUPLICATION_AUDIT_2026_08_07/H_engine_misc.md +72 -72
  98. package/src/DUPLICATION_AUDIT_2026_08_07/I_generation_view.md +74 -74
  99. package/src/DUPLICATION_AUDIT_2026_08_07/K_crosscutting.md +169 -169
  100. package/src/DUPLICATION_AUDIT_2026_08_07.md +254 -254
  101. package/src/DUPLICATION_AUDIT_REMEDIATION.md +250 -250
  102. package/src/REVIEW_2026_08_06/adv-core.md +511 -511
  103. package/src/REVIEW_2026_08_06/adv-gfx.md +480 -480
  104. package/src/REVIEW_2026_08_06/adv-view.md +446 -446
  105. package/src/REVIEW_2026_08_06/api-core.md +296 -296
  106. package/src/REVIEW_2026_08_06/api-engine.md +195 -195
  107. package/src/REVIEW_2026_08_06/bvh-phys-sound-net.md +507 -507
  108. package/src/REVIEW_2026_08_06/core-binary.md +348 -348
  109. package/src/REVIEW_2026_08_06/core-collection.md +376 -376
  110. package/src/REVIEW_2026_08_06/core-math.md +221 -221
  111. package/src/REVIEW_2026_08_06/core-process.md +266 -266
  112. package/src/REVIEW_2026_08_06/core-science.md +223 -223
  113. package/src/REVIEW_2026_08_06/engine-ai-nav.md +279 -279
  114. package/src/REVIEW_2026_08_06/engine-animation.md +167 -167
  115. package/src/REVIEW_2026_08_06/engine-asset.md +166 -166
  116. package/src/REVIEW_2026_08_06/engine-ecs.md +920 -920
  117. package/src/REVIEW_2026_08_06/engine-input.md +197 -197
  118. package/src/REVIEW_2026_08_06/engine-misc.md +248 -248
  119. package/src/REVIEW_2026_08_06/engine-terrain.md +52 -52
  120. package/src/REVIEW_2026_08_06/generation.md +176 -176
  121. package/src/REVIEW_2026_08_06/geom-2d.md +434 -434
  122. package/src/REVIEW_2026_08_06/geom-3d.md +117 -117
  123. package/src/REVIEW_2026_08_06/gfx-gi.md +143 -143
  124. package/src/REVIEW_2026_08_06/gfx-render.md +740 -740
  125. package/src/REVIEW_2026_08_06/gfx-texture.md +690 -690
  126. package/src/REVIEW_2026_08_06/prior-criticals.md +49 -49
  127. package/src/REVIEW_2026_08_06/prior-highs.md +138 -138
  128. package/src/REVIEW_2026_08_06/test-gaps.md +364 -364
  129. package/src/REVIEW_2026_08_06/view.md +667 -667
  130. package/src/REVIEW_2026_08_06.md +610 -610
  131. package/src/avif/codec/dec/avif_dec.cpp +233 -233
  132. package/src/avif/codec/dec/avif_dec.js +16 -16
  133. package/src/core/binary/BitImage2.js +246 -246
  134. package/src/core/binary/align_32.js +21 -21
  135. package/src/core/binary/data_view/DataType2DataViewReaders.js +23 -23
  136. package/src/core/binary/data_view/DataType2DataViewWriters.js +25 -25
  137. package/src/core/binary/hash/XXH128Hash.js +55 -55
  138. package/src/core/binary/hash/XXH3_SECRET.js +25 -25
  139. package/src/core/binary/hash/xxh3_128.js +341 -341
  140. package/src/core/binary/hash/xxh3_64.js +241 -241
  141. package/src/core/binary/hash/xxh3_common.js +476 -476
  142. package/src/core/binary/lz4/LZ4_MAX_INPUT_SIZE.js +9 -9
  143. package/src/core/binary/lz4/lz4_compress_block.js +385 -385
  144. package/src/core/binary/lz4/lz4_compress_bound.js +25 -25
  145. package/src/core/binary/lz4/lz4_decompress_block.js +139 -139
  146. package/src/core/binary/lz4/lz4_decompress_bound.js +30 -30
  147. package/src/core/binary/meshopt/MESHOPT_GROUP_SIZE.js +18 -18
  148. package/src/core/binary/meshopt/MeshoptCompressionFilter.js +30 -30
  149. package/src/core/binary/meshopt/MeshoptCompressionMode.js +21 -21
  150. package/src/core/binary/meshopt/__meshopt_test_streams.js +237 -237
  151. package/src/core/binary/meshopt/meshopt_decode.js +73 -73
  152. package/src/core/binary/meshopt/meshopt_decode_byte_group.js +67 -67
  153. package/src/core/binary/meshopt/meshopt_decode_data_block.js +59 -59
  154. package/src/core/binary/meshopt/meshopt_decode_filter_color.js +69 -69
  155. package/src/core/binary/meshopt/meshopt_decode_filter_exponential.js +43 -43
  156. package/src/core/binary/meshopt/meshopt_decode_filter_octahedral.js +60 -60
  157. package/src/core/binary/meshopt/meshopt_decode_filter_quaternion.js +71 -71
  158. package/src/core/binary/meshopt/meshopt_decode_index_buffer.js +294 -294
  159. package/src/core/binary/meshopt/meshopt_decode_index_sequence.js +115 -115
  160. package/src/core/binary/meshopt/meshopt_decode_vertex_buffer.js +381 -381
  161. package/src/core/binary/meshopt/meshopt_read_uint_var.js +59 -59
  162. package/src/core/binary/reinterpret_float32_as_uint32.js +13 -13
  163. package/src/core/binary/reinterpret_uint32_as_float32.js +14 -14
  164. package/src/core/binary/type/DataType2TypedArrayConstructorMapping.js +35 -35
  165. package/src/core/bvh2/bvh3/ebvh_geometry_query_any_triangle_ray.js +149 -149
  166. package/src/core/bvh2/bvh3/ebvh_sort_for_traversal_depth_first.js +96 -96
  167. package/src/core/bvh2/bvh3/query/bvh_query_depth_range_in_frustum.js +101 -101
  168. package/src/core/bvh2/bvh3/query/bvh_query_leaves_generic.js +77 -77
  169. package/src/core/bvh2/bvh3/query/bvh_query_leaves_ray.js +90 -90
  170. package/src/core/bvh2/bvh3/query/bvh_query_leaves_ray_segment.js +94 -94
  171. package/src/core/bvh2/bvh3/query/bvh_query_user_data_generic.js +86 -86
  172. package/src/core/bvh2/bvh3/query/bvh_query_user_data_intersects_capsule.js +101 -101
  173. package/src/core/bvh2/bvh3/query/bvh_query_user_data_intersects_sphere.js +92 -92
  174. package/src/core/bvh2/bvh3/query/bvh_query_user_data_ray.js +96 -96
  175. package/src/core/bvh2/bvh3/query/bvh_query_user_data_ray_segment.js +100 -100
  176. package/src/core/bvh2/visual/BVHGeometry.js +131 -131
  177. package/src/core/bvh8/BVH8.js +436 -436
  178. package/src/core/bvh8/aabb3_round_to_float32.js +22 -22
  179. package/src/core/bvh8/build/BVH8Converter.js +588 -588
  180. package/src/core/bvh8/build/TriangleCluster.js +122 -122
  181. package/src/core/bvh8/build/aabb3_compute_merge_cost.js +28 -28
  182. package/src/core/bvh8/build/aabb3_from_triangle_by_index.js +17 -17
  183. package/src/core/bvh8/build/bvh8_build_for_geometry.js +303 -303
  184. package/src/core/bvh8/build/bvh8_from_proxy.js +256 -256
  185. package/src/core/bvh8/build/byte.js +9 -9
  186. package/src/core/bvh8/build/encode_bounds_e.js +11 -11
  187. package/src/core/bvh8/bvh8_convert_to_dot.js +132 -132
  188. package/src/core/bvh8/bvh8_count_primitives.js +98 -98
  189. package/src/core/bvh8/bvh8_geometry_validate.js +138 -138
  190. package/src/core/bvh8/bvh8_geometry_validate_indirect.js +166 -166
  191. package/src/core/bvh8/bvh8_get_node_bounds.js +34 -34
  192. package/src/core/bvh8/bvh8_get_node_child_bounds.js +52 -52
  193. package/src/core/bvh8/bvh8_node_child_surface_area.js +18 -18
  194. package/src/core/bvh8/bvh8_node_count_triangles.js +27 -27
  195. package/src/core/bvh8/bvh8_quality.js +72 -72
  196. package/src/core/bvh8/bvh8_validate_structure.js +87 -87
  197. package/src/core/clipboard/obtainClipBoard.js +29 -29
  198. package/src/core/clipboard/safeClipboardReadText.js +55 -55
  199. package/src/core/clipboard/safeClipboardWriteText.js +23 -23
  200. package/src/core/collection/array/typed/typed_array_value_denormalize.js +52 -52
  201. package/src/core/collection/array/typed/typed_array_value_normalize.js +51 -51
  202. package/src/core/collection/union-find/union_find.js +79 -79
  203. package/src/core/color/YCoCg/rgb_to_ycocg.js +20 -20
  204. package/src/core/color/YCoCg/ycocg_to_rgb.js +17 -17
  205. package/src/core/color/colormap/MAGMA_LUT.js +26 -26
  206. package/src/core/color/illuminant/D65_TRISTIMULUS_XYZ.js +19 -19
  207. package/src/core/color/lab/lab_apply_hunt_adjustment.js +27 -27
  208. package/src/core/color/lab/lab_distance_hyab.js +23 -23
  209. package/src/core/color/lab/xyz_to_lab.js +62 -62
  210. package/src/core/color/operations/color_darken.js +24 -24
  211. package/src/core/color/operations/color_desaturate.js +24 -24
  212. package/src/core/color/operations/color_lighten.js +24 -24
  213. package/src/core/color/operations/color_saturate.js +24 -24
  214. package/src/core/color/operations/color_scale_okhsv_channel.js +45 -45
  215. package/src/core/color/tonemap/tonemap_aces.js +41 -41
  216. package/src/core/color/ycxcz/xyz_to_ycxcz.js +28 -28
  217. package/src/core/color/ycxcz/ycxcz_to_xyz.js +19 -19
  218. package/src/core/dom/isImageBitmap.js +12 -12
  219. package/src/core/function/frameThrottle.js +23 -23
  220. package/src/core/geom/2d/aabb/aabb2_array_combine.js +7 -7
  221. package/src/core/geom/2d/aabb/aabb2_compute_area.js +7 -7
  222. package/src/core/geom/2d/aabb/aabb2_compute_center_from_multiple.js +7 -7
  223. package/src/core/geom/2d/aabb/aabb2_compute_overlap.js +7 -7
  224. package/src/core/geom/2d/aabb/aabb2_from_v2_array.js +7 -7
  225. package/src/core/geom/2d/aabb/aabb2_intersects_point.js +7 -7
  226. package/src/core/geom/2d/aabb/aabb2_overlap_exists.js +7 -7
  227. package/src/core/geom/2d/circle/circle_compute_circle_intersection.js +7 -7
  228. package/src/core/geom/2d/circle/circle_compute_circle_penetration.js +7 -7
  229. package/src/core/geom/2d/circle/circle_intersects_point.js +7 -7
  230. package/src/core/geom/2d/compute_polygon_area_2d.js +7 -7
  231. package/src/core/geom/2d/convex-hull/fixed_convex_hull_humus.js +7 -7
  232. package/src/core/geom/2d/convex-hull/fixed_convex_hull_relaxation.js +7 -7
  233. package/src/core/geom/2d/convex-hull/orientation3_array.js +7 -7
  234. package/src/core/geom/2d/intersect_ray_2d.js +7 -7
  235. package/src/core/geom/2d/line/line2_distance_to_point_sqr.js +7 -7
  236. package/src/core/geom/2d/line/line2_segment_intersection_fraction_2d.js +44 -44
  237. package/src/core/geom/2d/line/line_segment_compute_line_segment_intersection_2d.js +7 -7
  238. package/src/core/geom/2d/line/line_segment_compute_line_segment_intersection_array_2d.js +7 -7
  239. package/src/core/geom/2d/line/line_segment_compute_line_segment_intersection_vectors_2d.js +7 -7
  240. package/src/core/geom/2d/line/line_segment_compute_line_segment_intersection_vectors_array_2d.js +7 -7
  241. package/src/core/geom/2d/line/line_segment_intersection_fraction_2d.js +7 -7
  242. package/src/core/geom/2d/line/line_segment_line_segment_intersection_exists_2d.js +7 -7
  243. package/src/core/geom/2d/line/segment2_intersects_segment2_2d.js +25 -25
  244. package/src/core/geom/2d/line/segment2_segment_compute_intersection_array_2d.js +46 -46
  245. package/src/core/geom/2d/line/segment2_segment_intersection_fractions.js +52 -52
  246. package/src/core/geom/2d/oriented-box/min_area_rect_2d.js +69 -69
  247. package/src/core/geom/2d/polygon/TRIANGULATION_DESIGN.md +433 -433
  248. package/src/core/geom/2d/polygon/polygon2_clip_axis_halfplane.js +51 -51
  249. package/src/core/geom/2d/polygon/polygon2_clip_halfplane.js +50 -50
  250. package/src/core/geom/2d/polygon/polygon2_is_counter_clockwise.js +84 -84
  251. package/src/core/geom/2d/polygon/polygon2_signed_area.js +52 -52
  252. package/src/core/geom/2d/polygon/polygon2_triangulate.corpus.js +86 -86
  253. package/src/core/geom/2d/polygon/polygon2_triangulate.js +1280 -1280
  254. package/src/core/geom/2d/polygon/polygon2_triangulation_deviation.js +77 -77
  255. package/src/core/geom/2d/quad-tree/qt_collect_by_circle.js +39 -39
  256. package/src/core/geom/2d/quad-tree/qt_match_data_by_circle.js +101 -101
  257. package/src/core/geom/2d/quad-tree/qt_query_data_nearest_to_point.js +7 -7
  258. package/src/core/geom/2d/rectangle_to_aabb.js +7 -7
  259. package/src/core/geom/2d/spline_bezier2_2d.js +7 -7
  260. package/src/core/geom/2d/triangle/tri2_rasterize_conservative.js +99 -99
  261. package/src/core/geom/2d/triangle/tri2_signed_area.js +35 -35
  262. package/src/core/geom/2d/triangle2d_compute_area.js +7 -7
  263. package/src/core/geom/2d/triangle2d_contains_point.js +7 -7
  264. package/src/core/geom/2d/triangle2d_get_barycentric.js +7 -7
  265. package/src/core/geom/2d/v2_morton_encode.js +23 -23
  266. package/src/core/geom/3d/aabb/aabb3_array_intersects_frustum_degree.js +7 -7
  267. package/src/core/geom/3d/aabb/aabb3_box_surface_area_2.js +7 -7
  268. package/src/core/geom/3d/aabb/aabb3_build_frustum.js +5 -5
  269. package/src/core/geom/3d/aabb/aabb3_closest_point_on_surface.js +57 -57
  270. package/src/core/geom/3d/aabb/aabb3_combined_surface_area.js +7 -7
  271. package/src/core/geom/3d/aabb/aabb3_compute_half_surface_area.js +7 -7
  272. package/src/core/geom/3d/aabb/aabb3_compute_projected_area.js +7 -7
  273. package/src/core/geom/3d/aabb/aabb3_compute_surface_area.js +7 -7
  274. package/src/core/geom/3d/aabb/aabb3_detailed_volume_intersection.js +7 -7
  275. package/src/core/geom/3d/aabb/aabb3_estimate_projected_area2.js +7 -7
  276. package/src/core/geom/3d/aabb/aabb3_from_threejs_geometry.js +7 -7
  277. package/src/core/geom/3d/aabb/aabb3_from_triangle_group.js +46 -46
  278. package/src/core/geom/3d/aabb/aabb3_intersects_frustum_degree.js +7 -7
  279. package/src/core/geom/3d/aabb/aabb3_intersects_line_segment.js +7 -7
  280. package/src/core/geom/3d/aabb/aabb3_near_distance_to_intersection_ray_segment.js +7 -7
  281. package/src/core/geom/3d/aabb/aabb3_nearest_point_on_surface.js +7 -7
  282. package/src/core/geom/3d/aabb/aabb3_ray_segment_entry_distance.js +95 -95
  283. package/src/core/geom/3d/aabb/aabb3_raycast.js +7 -7
  284. package/src/core/geom/3d/aabb/aabb3_transform_oriented.js +93 -93
  285. package/src/core/geom/3d/aabb/aabb3_transform_oriented_inverse.js +82 -82
  286. package/src/core/geom/3d/aabb/compute_aabb_from_points.js +7 -7
  287. package/src/core/geom/3d/aabb/compute_triangle_group_aabb3.js +7 -7
  288. package/src/core/geom/3d/atlas/ATLAS_PORT_PLAN.md +486 -486
  289. package/src/core/geom/3d/atlas/BFF_PLAN.md +174 -174
  290. package/src/core/geom/3d/atlas/Chart.js +77 -77
  291. package/src/core/geom/3d/atlas/REVIEW_02.md +392 -392
  292. package/src/core/geom/3d/atlas/atlas_bench_lib.js +315 -315
  293. package/src/core/geom/3d/atlas/atlas_chart_type.js +16 -16
  294. package/src/core/geom/3d/atlas/atlas_compute_charts.js +188 -188
  295. package/src/core/geom/3d/atlas/atlas_extract_chart.js +107 -107
  296. package/src/core/geom/3d/atlas/atlas_generate.js +50 -50
  297. package/src/core/geom/3d/atlas/atlas_test_fixtures.js +266 -266
  298. package/src/core/geom/3d/atlas/atlas_write_chart_uvs.js +36 -36
  299. package/src/core/geom/3d/atlas/data/atlas_build_edge_dihedrals.js +62 -62
  300. package/src/core/geom/3d/atlas/data/atlas_build_edge_lengths.js +33 -33
  301. package/src/core/geom/3d/atlas/data/atlas_build_face_areas.js +50 -50
  302. package/src/core/geom/3d/atlas/io/atlas_mesh_weld_colocals.js +39 -39
  303. package/src/core/geom/3d/atlas/io/bt_loop_uv.js +35 -35
  304. package/src/core/geom/3d/atlas/pack/ChartPlacement.js +46 -46
  305. package/src/core/geom/3d/atlas/param/atlas_chart_parameterize_bff.js +269 -269
  306. package/src/core/geom/3d/atlas/param/atlas_chart_parameterize_lscm.js +209 -209
  307. package/src/core/geom/3d/atlas/param/atlas_chart_parameterize_ortho.js +38 -38
  308. package/src/core/geom/3d/atlas/param/atlas_chart_stretch_metric.js +86 -86
  309. package/src/core/geom/3d/atlas/param/atlas_piecewise_resegment.js +183 -183
  310. package/src/core/geom/3d/atlas/param/fit_plane_basis.js +66 -66
  311. package/src/core/geom/3d/atlas/segment/RegionGraph.js +40 -40
  312. package/src/core/geom/3d/atlas/segment/atlas_build_region_graph.js +136 -136
  313. package/src/core/geom/3d/atlas/segment/atlas_chart_roundness_delta.js +30 -30
  314. package/src/core/geom/3d/atlas/segment/atlas_compute_planar_regions.js +77 -77
  315. package/src/core/geom/3d/atlas/segment/atlas_merge_charts.js +116 -116
  316. package/src/core/geom/3d/atlas/segment/atlas_segment_charts.js +271 -271
  317. package/src/core/geom/3d/atlas/segment/atlas_segment_charts_atomic.js +191 -191
  318. package/src/core/geom/3d/box/box3_projected_half_extent.js +35 -35
  319. package/src/core/geom/3d/capsule/capsule_intersects_aabb3_closed.js +67 -67
  320. package/src/core/geom/3d/capsule/capsule_intersects_aabb3_iterative.js +137 -137
  321. package/src/core/geom/3d/compute_circle_bounding_box.js +7 -7
  322. package/src/core/geom/3d/cone/computeConeBoundingBox.js +7 -7
  323. package/src/core/geom/3d/cone/computeConePlaneSide.js +7 -7
  324. package/src/core/geom/3d/cone/compute_bounding_cone_of_2_cones.js +7 -7
  325. package/src/core/geom/3d/cylinder/cylinder3_raycast.d.ts +38 -0
  326. package/src/core/geom/3d/cylinder/cylinder3_raycast.d.ts.map +1 -0
  327. package/src/core/geom/3d/cylinder/cylinder3_raycast.js +105 -0
  328. package/src/core/geom/3d/equirectangular/equirectangular_direction_to_uv.js +18 -18
  329. package/src/core/geom/3d/equirectangular/equirectangular_uv_to_direction.js +24 -24
  330. package/src/core/geom/3d/frustum/clipping_volume_matrix4_project.js +7 -7
  331. package/src/core/geom/3d/frustum/frustum3_computeNearestPointToPoint.js +7 -7
  332. package/src/core/geom/3d/frustum/frustum3_compute_closest_point.js +117 -117
  333. package/src/core/geom/3d/frustum/frustum_matrix4_project.js +7 -7
  334. package/src/core/geom/3d/frustum/hexahedron_from_aabb.js +7 -7
  335. package/src/core/geom/3d/frustum/read_frustum_corner.js +17 -17
  336. package/src/core/geom/3d/frustum/read_three_planes_to_array.js +7 -7
  337. package/src/core/geom/3d/frustum/slice_frustum_linear_to_points.js +7 -7
  338. package/src/core/geom/3d/gjk/GJK_REVIEW_NOTES.md +146 -146
  339. package/src/core/geom/3d/gjk/gjk.js +430 -430
  340. package/src/core/geom/3d/gjk/gjk_epa_penetration.js +520 -520
  341. package/src/core/geom/3d/gjk/minkowski_support.js +71 -71
  342. package/src/core/geom/3d/gjk/mpr.js +368 -368
  343. package/src/core/geom/3d/line/line3_closest_points_segment_segment.js +7 -7
  344. package/src/core/geom/3d/line/line3_compute_nearest_point_to_point.js +7 -7
  345. package/src/core/geom/3d/line/line3_compute_point_segment_point_distance_unfolded.js +64 -64
  346. package/src/core/geom/3d/line/line3_compute_segment_closest_point_to_aabb3_t.js +153 -153
  347. package/src/core/geom/3d/line/line3_compute_segment_nearest_point_to_aabb3_t.js +7 -7
  348. package/src/core/geom/3d/line/line3_compute_segment_nearest_point_to_point_t.js +7 -7
  349. package/src/core/geom/3d/line/line3_compute_segment_segment_closest_points.js +88 -88
  350. package/src/core/geom/3d/line/line3_segment_segment_closest_point_pair.js +71 -71
  351. package/src/core/geom/3d/line/segment3_point_distance_to_segments.js +25 -25
  352. package/src/core/geom/3d/mat4/allocate_m4.js +7 -7
  353. package/src/core/geom/3d/mat4/apply_mat4_transform_to_direction_v3_array.js +7 -7
  354. package/src/core/geom/3d/mat4/apply_mat4_transform_to_v3_array.js +7 -7
  355. package/src/core/geom/3d/mat4/compose_matrix4_array.js +7 -7
  356. package/src/core/geom/3d/mat4/decompose_matrix_4_array.js +7 -7
  357. package/src/core/geom/3d/mat4/eulerAnglesFromMatrix.js +7 -7
  358. package/src/core/geom/3d/mat4/m4_compose.js +22 -22
  359. package/src/core/geom/3d/mat4/m4_compute_normal_matrix3.js +7 -7
  360. package/src/core/geom/3d/mat4/m4_decompose.js +64 -64
  361. package/src/core/geom/3d/mat4/m4_decompose_array.js +157 -157
  362. package/src/core/geom/3d/mat4/m4_from_rotation_translation_scale.js +32 -32
  363. package/src/core/geom/3d/mat4/m4_from_rotation_translation_scale_scalar.js +67 -67
  364. package/src/core/geom/3d/mat4/m4_linear_matrix3.js +29 -29
  365. package/src/core/geom/3d/mat4/m4_look_at.js +96 -96
  366. package/src/core/geom/3d/mat4/m4_make_rotation_x.js +47 -47
  367. package/src/core/geom/3d/mat4/m4_make_rotation_y.js +47 -47
  368. package/src/core/geom/3d/mat4/m4_make_rotation_z.js +47 -47
  369. package/src/core/geom/3d/mat4/m4_normal_matrix3.js +39 -39
  370. package/src/core/geom/3d/mat4/m4_perspective.js +66 -66
  371. package/src/core/geom/3d/mat4/m4_transpose.js +48 -48
  372. package/src/core/geom/3d/morton/mortonEncode_LUT.js +7 -7
  373. package/src/core/geom/3d/morton/mortonEncode_magicbits.js +7 -7
  374. package/src/core/geom/3d/normal/hemioct/encode_unit3_hemioct.js +5 -5
  375. package/src/core/geom/3d/normal/hemioct/encode_unit_to_hemioct.js +28 -28
  376. package/src/core/geom/3d/normal/lambert_azimuth/decode_azimuth_to_unit.js +30 -30
  377. package/src/core/geom/3d/normal/lambert_azimuth/encode_unit_to_azimuth.js +19 -19
  378. package/src/core/geom/3d/normal/spherical/decode_spheremap_to_unit.js +38 -38
  379. package/src/core/geom/3d/normal/spherical/encode_unit_to_spheremap.js +30 -30
  380. package/src/core/geom/3d/plane/is_point_within_planes.js +7 -7
  381. package/src/core/geom/3d/plane/orient3d_fast_point.js +47 -47
  382. package/src/core/geom/3d/plane/plane3_compute_convex_3_plane_intersection.js +7 -7
  383. package/src/core/geom/3d/plane/plane3_compute_plane_intersection.js +7 -7
  384. package/src/core/geom/3d/plane/plane3_intersect_plane.js +7 -7
  385. package/src/core/geom/3d/plane/plane3_three_compute_convex_3_plane_intersection.js +7 -7
  386. package/src/core/geom/3d/point/point3_raycast.d.ts +33 -0
  387. package/src/core/geom/3d/point/point3_raycast.d.ts.map +1 -0
  388. package/src/core/geom/3d/point/point3_raycast.js +47 -0
  389. package/src/core/geom/3d/polygon/polygon3_compute_normal.js +60 -60
  390. package/src/core/geom/3d/polygon/polygon3_triangulate.js +94 -94
  391. package/src/core/geom/3d/polyhedron/convex_polyhedron3_raycast.d.ts +40 -0
  392. package/src/core/geom/3d/polyhedron/convex_polyhedron3_raycast.d.ts.map +1 -0
  393. package/src/core/geom/3d/polyhedron/convex_polyhedron3_raycast.js +94 -0
  394. package/src/core/geom/3d/quadric/QUADRIC3_SIZE.js +14 -14
  395. package/src/core/geom/3d/quadric/Quadric3.js +282 -282
  396. package/src/core/geom/3d/quadric/quadric3_add.js +33 -33
  397. package/src/core/geom/3d/quadric/quadric3_clear.js +25 -25
  398. package/src/core/geom/3d/quadric/quadric3_copy.js +27 -27
  399. package/src/core/geom/3d/quadric/quadric3_distance.js +36 -36
  400. package/src/core/geom/3d/quadric/quadric3_evaluate.js +25 -25
  401. package/src/core/geom/3d/quadric/quadric3_optimize.js +45 -45
  402. package/src/core/geom/3d/quadric/quadric3_scale.js +32 -32
  403. package/src/core/geom/3d/quadric/quadric3_set_from_plane_through_point.js +30 -30
  404. package/src/core/geom/3d/quadric/quadric3_set_from_vector4.js +35 -35
  405. package/src/core/geom/3d/quadric/quadric3_sub.js +36 -36
  406. package/src/core/geom/3d/quadric/quadric3_to_tensor_m3.js +28 -28
  407. package/src/core/geom/3d/quadric/quadric3_to_tensor_m3_inverse.js +56 -56
  408. package/src/core/geom/3d/quadric/quadric3_to_vector3.js +19 -19
  409. package/src/core/geom/3d/quaternion/quat3_createFromAxisAngle.js +7 -7
  410. package/src/core/geom/3d/quaternion/quat3_integrate.js +62 -62
  411. package/src/core/geom/3d/quaternion/quat3_multiply.js +31 -31
  412. package/src/core/geom/3d/quaternion/quat3_nlerp.js +72 -72
  413. package/src/core/geom/3d/quaternion/quat3_to_matrix3.js +69 -69
  414. package/src/core/geom/3d/quaternion/quat_decode_from_uint32.js +7 -7
  415. package/src/core/geom/3d/quaternion/quat_encode_to_uint32.js +7 -7
  416. package/src/core/geom/3d/ray/ray3_array_compose.js +7 -7
  417. package/src/core/geom/3d/ray/ray3_compute_nearest_point_to_point.js +7 -7
  418. package/src/core/geom/3d/ray/ray3_distance_to_point.js +7 -7
  419. package/src/core/geom/3d/ray/ray3_shift_origin_along_direction.js +7 -7
  420. package/src/core/geom/3d/shape/ConvexHullShape3D.d.ts +17 -0
  421. package/src/core/geom/3d/shape/ConvexHullShape3D.d.ts.map +1 -1
  422. package/src/core/geom/3d/shape/ConvexHullShape3D.js +43 -0
  423. package/src/core/geom/3d/shape/CylinderShape3D.d.ts +1 -0
  424. package/src/core/geom/3d/shape/CylinderShape3D.d.ts.map +1 -1
  425. package/src/core/geom/3d/shape/CylinderShape3D.js +21 -0
  426. package/src/core/geom/3d/shape/PointShape3D.d.ts +7 -0
  427. package/src/core/geom/3d/shape/PointShape3D.d.ts.map +1 -1
  428. package/src/core/geom/3d/shape/PointShape3D.js +88 -63
  429. package/src/core/geom/3d/shape/PosedShape3D.d.ts +6 -0
  430. package/src/core/geom/3d/shape/PosedShape3D.d.ts.map +1 -1
  431. package/src/core/geom/3d/shape/PosedShape3D.js +27 -0
  432. package/src/core/geom/3d/shape/TransformedShape3D.d.ts +10 -0
  433. package/src/core/geom/3d/shape/TransformedShape3D.d.ts.map +1 -1
  434. package/src/core/geom/3d/shape/TransformedShape3D.js +13 -0
  435. package/src/core/geom/3d/shape/Triangle3D.d.ts +1 -0
  436. package/src/core/geom/3d/shape/Triangle3D.d.ts.map +1 -1
  437. package/src/core/geom/3d/shape/Triangle3D.js +26 -0
  438. package/src/core/geom/3d/shape/UnionShape3D.d.ts +6 -0
  439. package/src/core/geom/3d/shape/UnionShape3D.d.ts.map +1 -1
  440. package/src/core/geom/3d/shape/UnionShape3D.js +7 -0
  441. package/src/core/geom/3d/shape/UnitCubeShape3D.js +45 -45
  442. package/src/core/geom/3d/shape/UnitSphereShape3D.js +44 -44
  443. package/src/core/geom/3d/shape/shape3_mesh_from_geometry.js +64 -64
  444. package/src/core/geom/3d/shape/shape_mesh_from_geometry.js +7 -7
  445. package/src/core/geom/3d/shape/util/compute_signed_distance_gradient_by_sampling.js +51 -51
  446. package/src/core/geom/3d/shape/util/shape3d_voxelize_to_grid.js +7 -7
  447. package/src/core/geom/3d/sphere/compute_bounding_sphere_of_2_spheres.js +7 -7
  448. package/src/core/geom/3d/sphere/harmonics/sh3_convolve_with_zh.js +53 -53
  449. package/src/core/geom/3d/sphere/harmonics/sh3_ggx_zh.js +30 -30
  450. package/src/core/geom/3d/sphere/harmonics/sh3_rotate_bl.js +7 -7
  451. package/src/core/geom/3d/sphere/harmonics/sh_compute_K.js +7 -7
  452. package/src/core/geom/3d/sphere/sphere_array_intersects_point.js +7 -7
  453. package/src/core/geom/3d/sphere/sphere_array_intersects_ray.js +7 -7
  454. package/src/core/geom/3d/sphere/sphere_intersects_point.js +7 -7
  455. package/src/core/geom/3d/sphere/sphere_matrix4_transform.js +5 -5
  456. package/src/core/geom/3d/sphere/sphere_projected_sphere_radius_sqr.js +7 -7
  457. package/src/core/geom/3d/sphere/sphere_radius_sqr_from_v3_array_transformed.js +7 -7
  458. package/src/core/geom/3d/sphere/spherical_from_cartesian.js +7 -7
  459. package/src/core/geom/3d/tetrahedra/compute_tetrahedral_mesh_from_surface.js +174 -174
  460. package/src/core/geom/3d/tetrahedra/compute_tetrahedron_quality.js +7 -7
  461. package/src/core/geom/3d/tetrahedra/compute_tetrahedron_volume.js +7 -7
  462. package/src/core/geom/3d/tetrahedra/delaunay/fill_in_a_cavity.js +7 -7
  463. package/src/core/geom/3d/tetrahedra/graphics/build_tetrahedral_mesh_geometry.js +39 -39
  464. package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_build_vertex_to_tets_map.js +48 -48
  465. package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_carve_outside_surface.js +173 -173
  466. package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_compute_tet_quality.js +22 -22
  467. package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_find_tets_around_edge.js +146 -146
  468. package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_flip_23.js +232 -232
  469. package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_flip_32.js +255 -255
  470. package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_improve_quality.js +387 -387
  471. package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_smooth_vertex.js +140 -140
  472. package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_tet_get_neighbours.js +7 -7
  473. package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_vertex_is_boundary.js +97 -97
  474. package/src/core/geom/3d/tetrahedra/tetrahedron_compute_quality.js +66 -66
  475. package/src/core/geom/3d/tetrahedra/triangle/triangle_decode_depth.js +59 -59
  476. package/src/core/geom/3d/tetrahedra/triangle/triangle_rasterized_depth_sample_index.js +54 -54
  477. package/src/core/geom/3d/tetrahedra/validate_neighbour.js +70 -70
  478. package/src/core/geom/3d/topology/struct/binary/BinaryDataBlock.js +314 -314
  479. package/src/core/geom/3d/topology/struct/binary/BinaryDataLayer.js +364 -364
  480. package/src/core/geom/3d/topology/struct/binary/BinaryElementPool.js +567 -567
  481. package/src/core/geom/3d/topology/struct/binary/BinaryTopology.js +1085 -1085
  482. package/src/core/geom/3d/topology/struct/binary/io/bt_boundary_loop.js +73 -73
  483. package/src/core/geom/3d/topology/struct/binary/io/bt_loop_kill.js +35 -35
  484. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_append.js +119 -119
  485. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_close_boundary_holes.js +84 -84
  486. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_compact.js +172 -172
  487. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_compute_face_normals.js +56 -56
  488. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_compute_vertex_quadratics.js +7 -7
  489. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_compute_vertex_quadrics.js +227 -227
  490. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_face_decouple.js +161 -161
  491. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_face_island_erode.js +490 -490
  492. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_fill_small_holes.js +120 -120
  493. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_from_indexed_geometry.js +120 -120
  494. package/src/core/geom/3d/topology/struct/binary/io/edge/bt_edge_collapse.js +52 -52
  495. package/src/core/geom/3d/topology/struct/binary/io/edge/bt_edge_create.js +115 -115
  496. package/src/core/geom/3d/topology/struct/binary/io/edge/bt_edge_flip.js +142 -142
  497. package/src/core/geom/3d/topology/struct/binary/io/edge/bt_edge_get_or_create.js +21 -21
  498. package/src/core/geom/3d/topology/struct/binary/io/edge/bt_edge_kill_parallels.js +92 -92
  499. package/src/core/geom/3d/topology/struct/binary/io/edge/bt_edge_split.js +179 -179
  500. package/src/core/geom/3d/topology/struct/binary/io/edge/bt_edge_swap_vertex_slots.js +28 -28
  501. package/src/core/geom/3d/topology/struct/binary/io/edge/bt_kill_only_edge.js +8 -8
  502. package/src/core/geom/3d/topology/struct/binary/io/edge/bt_mesh_fuse_duplicate_edges.js +83 -83
  503. package/src/core/geom/3d/topology/struct/binary/io/edge/bt_mesh_kill_short_edges.js +89 -89
  504. package/src/core/geom/3d/topology/struct/binary/io/face/bt_face_kill.js +25 -25
  505. package/src/core/geom/3d/topology/struct/binary/io/face/bt_face_poke.js +127 -127
  506. package/src/core/geom/3d/topology/struct/binary/io/face/bt_face_triangulate.js +268 -268
  507. package/src/core/geom/3d/topology/struct/binary/io/face/bt_kill_only_face.js +8 -8
  508. package/src/core/geom/3d/topology/struct/binary/io/face/bt_mesh_kill_degenerate_faces.js +72 -72
  509. package/src/core/geom/3d/topology/struct/binary/io/vertex/bt_kill_only_vert.js +7 -7
  510. package/src/core/geom/3d/topology/struct/binary/io/vertex/bt_merge_verts_by_distance.js +7 -7
  511. package/src/core/geom/3d/topology/struct/binary/io/vertex/bt_mesh_relative_merge_distance.js +48 -48
  512. package/src/core/geom/3d/topology/struct/binary/io/vertex/bt_mesh_split_pinched_vertices.js +256 -256
  513. package/src/core/geom/3d/topology/struct/binary/io/vertex/bt_mesh_vertex_merge_distance.js +77 -77
  514. package/src/core/geom/3d/topology/struct/binary/io/vertex/bt_vert_fuse_duplicate_edges.js +7 -7
  515. package/src/core/geom/3d/topology/struct/binary/io/vertex/bt_vert_kill.js +7 -7
  516. package/src/core/geom/3d/topology/struct/binary/io/vertex/bt_vertex_fuse_duplicate_edges.js +148 -148
  517. package/src/core/geom/3d/topology/struct/binary/io/vertex/bt_vertex_kill_only.js +7 -7
  518. package/src/core/geom/3d/topology/struct/binary/query/bt_collect_boundary_segments.js +29 -29
  519. package/src/core/geom/3d/topology/struct/binary/query/bt_edge_collapse_breaks_link_condition.js +107 -107
  520. package/src/core/geom/3d/topology/struct/binary/query/bt_edge_flip_is_legal.js +41 -41
  521. package/src/core/geom/3d/topology/struct/binary/query/bt_edge_flip_would_fold.js +120 -120
  522. package/src/core/geom/3d/topology/struct/binary/query/bt_edge_get.js +42 -42
  523. package/src/core/geom/3d/topology/struct/binary/query/bt_edge_is_boundary.js +20 -20
  524. package/src/core/geom/3d/topology/struct/binary/query/bt_edge_read_diamond.js +96 -96
  525. package/src/core/geom/3d/topology/struct/binary/query/bt_face_compute_newell_normal.js +72 -72
  526. package/src/core/geom/3d/topology/struct/binary/query/bt_face_get_attached_faces.js +7 -7
  527. package/src/core/geom/3d/topology/struct/binary/query/bt_face_get_edge_adjacent_faces.js +39 -39
  528. package/src/core/geom/3d/topology/struct/binary/query/bt_face_get_edge_adjacent_faces_weighted.js +93 -93
  529. package/src/core/geom/3d/topology/struct/binary/query/bt_face_get_neighbour_faces.js +7 -7
  530. package/src/core/geom/3d/topology/struct/binary/query/bt_face_get_shared_loop.js +48 -48
  531. package/src/core/geom/3d/topology/struct/binary/query/bt_face_island_flood_fill.js +45 -45
  532. package/src/core/geom/3d/topology/struct/binary/query/bt_face_read_triangle.js +66 -66
  533. package/src/core/geom/3d/topology/struct/binary/query/bt_faces_shared_loop.js +7 -7
  534. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_assert_valid.js +44 -44
  535. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_build_boundary_euclidean_distance_field.js +32 -32
  536. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_compute_face_islands.js +53 -53
  537. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_face_find_path.js +703 -703
  538. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_sample_interior_grid_points.js +181 -181
  539. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_segment_penetrates_surface.js +133 -133
  540. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_surface_ray_parity.js +82 -82
  541. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_validate.js +599 -599
  542. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_walk_boundary_loops.js +108 -108
  543. package/src/core/geom/3d/topology/struct/binary/query/bt_query_edge_is_boundary.js +7 -7
  544. package/src/core/geom/3d/triangle/computeTriangleClosestPointToPointBarycentric.js +7 -7
  545. package/src/core/geom/3d/triangle/computeTriangleRayIntersection.js +7 -7
  546. package/src/core/geom/3d/triangle/computeTriangleRayIntersectionBarycentric.js +7 -7
  547. package/src/core/geom/3d/triangle/computeTriangleRayIntersectionBarycentricEdge.js +7 -7
  548. package/src/core/geom/3d/triangle/computeTriangleRayIntersectionBarycentricGeometry.js +7 -7
  549. package/src/core/geom/3d/triangle/compute_triangle_area_3d.js +7 -7
  550. package/src/core/geom/3d/triangle/compute_triangle_normal.js +7 -7
  551. package/src/core/geom/3d/triangle/rayTriangleIntersection.js +7 -7
  552. package/src/core/geom/3d/triangle/tri3_closest_point.js +65 -65
  553. package/src/core/geom/3d/triangle/tri3_closest_point_barycentric.js +171 -171
  554. package/src/core/geom/3d/triangle/tri3_flatten_isometric.js +79 -79
  555. package/src/core/geom/3d/triangle/tri3_ray_intersection.js +160 -160
  556. package/src/core/geom/3d/triangle/tri3_ray_intersection_barycentric.js +96 -96
  557. package/src/core/geom/3d/triangle/tri3_raycast.d.ts +42 -0
  558. package/src/core/geom/3d/triangle/tri3_raycast.d.ts.map +1 -0
  559. package/src/core/geom/3d/triangle/tri3_raycast.js +94 -0
  560. package/src/core/geom/3d/triangle/triangle3_incenter.js +7 -7
  561. package/src/core/geom/3d/triangle/triangle_compute_plane_side.js +7 -7
  562. package/src/core/geom/3d/triangle/triangle_compute_signed_volume.js +7 -7
  563. package/src/core/geom/3d/triangle/triangle_intersects_clipping_volume.js +7 -7
  564. package/src/core/geom/3d/triangle/triangle_mesh_compute_signed_volume.js +7 -7
  565. package/src/core/geom/3d/triangle/v3_compute_triangle_normal.js +7 -7
  566. package/src/core/geom/3d/util/make_justified_point_grid.js +7 -7
  567. package/src/core/geom/GEOMETRY_REVIEW_002_API_ISSUES.md +381 -381
  568. package/src/core/geom/GEOMETRY_REVIEW_002_NAMING.md +684 -684
  569. package/src/core/geom/MANIFOLD_COMPARISON_2026_08_01.md +554 -554
  570. package/src/core/geom/mat3/m3_cm_from_translation.js +7 -7
  571. package/src/core/geom/mat3/m3_cm_invert.js +7 -7
  572. package/src/core/geom/mat3/m3_make_rotation.js +5 -5
  573. package/src/core/geom/mat3/m3_make_rotation_TBN.js +31 -31
  574. package/src/core/geom/mat3/m3_multiply_vec3.js +7 -7
  575. package/src/core/geom/packing/computeBoundingSphereOfSpheres.js +7 -7
  576. package/src/core/geom/packing/max-rect/cost/costByBestShortSide.js +7 -7
  577. package/src/core/geom/packing/max-rect/cost/costByRemainingArea.js +7 -7
  578. package/src/core/geom/packing/max-rect/cutArea.js +7 -7
  579. package/src/core/geom/packing/max-rect/findBestContainer.js +7 -7
  580. package/src/core/geom/packing/max-rect/packMaxRectangles.js +7 -7
  581. package/src/core/geom/packing/max-rect/packOneBox.js +7 -7
  582. package/src/core/geom/packing/max-rect/removeRedundantBoxes.js +7 -7
  583. package/src/core/geom/packing/max-rect/removeRedundantBoxesArray.js +7 -7
  584. package/src/core/geom/random/randomPointInBox.js +7 -7
  585. package/src/core/geom/random/randomPointInCircle.js +7 -7
  586. package/src/core/geom/random/randomPointInPoint.js +7 -7
  587. package/src/core/geom/random/randomPointInSphere.js +7 -7
  588. package/src/core/geom/random/randomPointOnBox.js +7 -7
  589. package/src/core/geom/random/randomPointOnSphere.js +7 -7
  590. package/src/core/geom/random/random_orthonormal_basis.js +31 -31
  591. package/src/core/geom/vec/vector_axpy.js +15 -15
  592. package/src/core/geom/vec/vector_axpy_offset.js +20 -20
  593. package/src/core/geom/vec/vector_copy.js +7 -7
  594. package/src/core/geom/vec/vector_dot_offset.js +25 -25
  595. package/src/core/geom/vec/vector_scale_array.js +7 -7
  596. package/src/core/geom/vec2/v2_rotate.js +21 -21
  597. package/src/core/geom/vec2/v2_rotate_cos_sin.js +21 -21
  598. package/src/core/geom/vec3/v3_angle_atan2_between.js +7 -7
  599. package/src/core/geom/vec3/v3_angle_between.js +7 -7
  600. package/src/core/geom/vec3/v3_angle_cos_between.js +7 -7
  601. package/src/core/geom/vec3/v3_array_add_in_place.js +7 -7
  602. package/src/core/geom/vec3/v3_array_centroid.js +7 -7
  603. package/src/core/geom/vec3/v3_array_copy.js +7 -7
  604. package/src/core/geom/vec3/v3_array_displace_in_direction.js +7 -7
  605. package/src/core/geom/vec3/v3_array_equals.js +7 -7
  606. package/src/core/geom/vec3/v3_array_immediate_add.js +7 -7
  607. package/src/core/geom/vec3/v3_array_matrix4_rotate.js +7 -7
  608. package/src/core/geom/vec3/v3_array_normalize.js +7 -7
  609. package/src/core/geom/vec3/v3_array_scale.js +7 -7
  610. package/src/core/geom/vec3/v3_compute_interior_angle.js +7 -7
  611. package/src/core/geom/vec3/v3_cotangent.js +33 -33
  612. package/src/core/geom/vec3/v3_dot_array_array.js +7 -7
  613. package/src/core/geom/vec3/v3_matrix3_multiply.js +30 -30
  614. package/src/core/geom/vec3/v3_matrix3_rotate.js +49 -49
  615. package/src/core/geom/vec3/v3_matrix4_rotate.js +7 -7
  616. package/src/core/geom/vec3/v3_multiply.js +23 -23
  617. package/src/core/geom/vec3/v3_multiply_scalar.js +7 -7
  618. package/src/core/geom/vec3/v3_orthonormal_matrix_from_normal.js +49 -49
  619. package/src/core/geom/vec3/v3_quat3_apply.js +7 -7
  620. package/src/core/geom/vec3/v3_quat3_apply_inverse.js +7 -7
  621. package/src/core/geom/vec3/v3_quaternion_apply.js +39 -39
  622. package/src/core/geom/vec3/v3_quaternion_apply_inverse.js +41 -41
  623. package/src/core/geom/vec3/v3_reflect.js +24 -24
  624. package/src/core/geom/vec3/v3_scale_array.js +18 -18
  625. package/src/core/geom/vec3/v3_triple_cross.js +45 -45
  626. package/src/core/geom/vec3/v3_triple_cross_product.js +7 -7
  627. package/src/core/geom/vec3/v3_uniform_sample_cone.js +21 -21
  628. package/src/core/geom/vec4/v4_multiply_mat4.js +7 -7
  629. package/src/core/graph/csr/csr_graph_build_distance_field.js +112 -112
  630. package/src/core/graph/csr/csr_graph_find_edge.js +25 -25
  631. package/src/core/graph/csr/csr_graph_find_shortest_path.js +105 -105
  632. package/src/core/graph/csr/csr_graph_from_undirected_edge_list.js +94 -94
  633. package/src/core/graph/graph_k_means_cluster.js +250 -250
  634. package/src/core/graph/layout/CircleLayout.js +1 -1
  635. package/src/core/graph/layout/box/BoxLayouter.js +1 -1
  636. package/src/core/graph/layout/graph_peel_topological_layer.js +45 -45
  637. package/src/core/graph/metis/BinaryTopologyFaceGraph.js +49 -49
  638. package/src/core/graph/metis/bt_mesh_build_face_graph.js +111 -111
  639. package/src/core/graph/metis/cluster_mesh_metis.js +137 -137
  640. package/src/core/graph/metis/native/bisection/bisect_graph.js +100 -100
  641. package/src/core/graph/metis/native/bisection/compute_2way_params.js +86 -86
  642. package/src/core/graph/metis/native/bisection/fm_2way.js +297 -297
  643. package/src/core/graph/metis/native/bisection/grow_bisection.js +137 -137
  644. package/src/core/graph/metis/native/bisection/split_graph_two_way.js +119 -119
  645. package/src/core/graph/metis/native/coarsen/coarsen_graph.js +94 -94
  646. package/src/core/graph/metis/native/coarsen/create_coarse_graph.js +158 -158
  647. package/src/core/graph/metis/native/coarsen/match_shem.js +175 -175
  648. package/src/core/graph/metis/native/initial/initial_kway_bfs.js +122 -122
  649. package/src/core/graph/metis/native/initial/initial_kway_recursive_bisection.js +170 -170
  650. package/src/core/graph/metis/native/metis_partition_kway.js +126 -126
  651. package/src/core/graph/metis/native/refine/RefinementScratch.js +53 -53
  652. package/src/core/graph/metis/native/refine/fm_kway.js +487 -487
  653. package/src/core/graph/metis/native/refine/project_kway.js +43 -43
  654. package/src/core/graph/metis/native/refine/refine_kway.js +43 -43
  655. package/src/core/lang/reactive/pegjs/parser.js +3458 -3458
  656. package/src/core/math/complex/complex_horner_eval.js +31 -31
  657. package/src/core/math/computeWholeDivisorLow.js +33 -33
  658. package/src/core/math/f32_next_down.js +24 -24
  659. package/src/core/math/f32_next_up.js +27 -27
  660. package/src/core/math/hash/hash_mix2.js +22 -22
  661. package/src/core/math/hash/hash_mix3.js +19 -19
  662. package/src/core/math/linalg/cg/cg_solve.js +106 -106
  663. package/src/core/math/linalg/cg/cg_solve_normal_equations.js +59 -59
  664. package/src/core/math/linalg/cubic_residual_times_derivative_accumulate.js +43 -43
  665. package/src/core/math/linalg/eigen/matrix_householder_in_place.js +122 -122
  666. package/src/core/math/linalg/eigen/matrix_qr_in_place.js +190 -190
  667. package/src/core/math/linalg/eigen/matrix_symmetric_3x3_eigen.js +117 -117
  668. package/src/core/math/linalg/givens/givens_apply_rows.js +28 -28
  669. package/src/core/math/linalg/givens/givens_apply_rows_offset.js +30 -30
  670. package/src/core/math/linalg/givens/givens_rotation_coefficients.js +39 -39
  671. package/src/core/math/linalg/lu_factor_linear_system.js +108 -108
  672. package/src/core/math/linalg/lu_solve_linear_system.js +53 -53
  673. package/src/core/math/linalg/polynomial_add_into.js +29 -29
  674. package/src/core/math/linalg/polynomial_complex_roots_aberth_ehrlich.js +159 -159
  675. package/src/core/math/linalg/polynomial_cubic_derivative_eval.js +16 -16
  676. package/src/core/math/linalg/polynomial_cubic_horner_eval.js +19 -19
  677. package/src/core/math/linalg/polynomial_cubic_second_derivative_eval.js +14 -14
  678. package/src/core/math/linalg/polynomial_multiply.js +41 -41
  679. package/src/core/math/linalg/polynomial_real_roots_in_interval.js +211 -211
  680. package/src/core/math/linalg/polynomial_root_bound_cauchy.js +30 -30
  681. package/src/core/math/linalg/polynomial_scale_into.js +17 -17
  682. package/src/core/math/linalg/polynomial_sub_into.js +29 -29
  683. package/src/core/math/linalg/solve_linear_system_GEPP_2x2.js +96 -96
  684. package/src/core/math/linalg/sor_optimal_omega.js +42 -42
  685. package/src/core/math/linalg/sparse/SparseMatrixCSR.js +88 -88
  686. package/src/core/math/linalg/sparse/spm_matvec.js +22 -22
  687. package/src/core/math/linalg/sparse/spm_matvec_transpose.js +29 -29
  688. package/src/core/math/lookup/LUT_HEATMAP.js +30 -30
  689. package/src/core/math/lookup/ParameterLookupTable.js +495 -495
  690. package/src/core/math/lookup/ParameterLookupTableFlags.js +6 -6
  691. package/src/core/math/noise/curl_noise_3d.js +18 -18
  692. package/src/core/math/physics/brdf/cone_cosine_from_roughness.js +28 -28
  693. package/src/core/math/physics/brdf/reflection_sample_weight.js +48 -48
  694. package/src/core/math/physics/kinematics/computeInterceptPoint.js +79 -79
  695. package/src/core/math/random/randomSeed.js +16 -16
  696. package/src/core/math/random/random_pick_weighted_index.js +26 -26
  697. package/src/core/math/round_half_away_from_zero.js +13 -13
  698. package/src/core/math/spline/spline3_hermite_apply_transform.js +107 -107
  699. package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite_1d.js +125 -125
  700. package/src/core/math/spline/spline3_hermite_intersects_spline3_hermite.js +50 -50
  701. package/src/core/math/spline/spline3_hermite_reverse.js +49 -49
  702. package/src/core/math/spline/spline3_hermite_to_monomial.js +37 -37
  703. package/src/core/math/statistics/hammersley_sequence.js +53 -53
  704. package/src/core/model/reactive/model/util/createRandomReactiveExpression.js +185 -185
  705. package/src/core/path/convertPathToURL.js +107 -107
  706. package/src/core/process/delay.js +16 -16
  707. package/src/core/science/units/MEASUREMENT_UNITS_SCIENTIFIC.js +87 -87
  708. package/src/core/science/units/MEASUREMENT_UNITS_SI.js +17 -17
  709. package/src/core/science/units/NamedUnit.js +48 -48
  710. package/src/core/science/units/UNIT_DIMENSION_MAPPING.js +29 -29
  711. package/src/core/science/units/UnitDimension.js +28 -28
  712. package/src/core/science/units/format_quantity.js +74 -74
  713. package/src/core/science/units/magnitude_prefix.js +127 -127
  714. package/src/core/science/units/si/AMPERE.js +13 -13
  715. package/src/core/science/units/si/CANDELA.js +13 -13
  716. package/src/core/science/units/si/DIMENSIONLESS.js +14 -14
  717. package/src/core/science/units/si/KELVIN.js +13 -13
  718. package/src/core/science/units/si/KILOGRAM.js +13 -13
  719. package/src/core/science/units/si/METER.js +13 -13
  720. package/src/core/science/units/si/MOLE.js +13 -13
  721. package/src/core/science/units/si/SECOND.js +13 -13
  722. package/src/core/science/units/si/derived/BECQUEREL.js +16 -16
  723. package/src/core/science/units/si/derived/COULOMB.js +13 -13
  724. package/src/core/science/units/si/derived/FARAD.js +13 -13
  725. package/src/core/science/units/si/derived/GRAY.js +16 -16
  726. package/src/core/science/units/si/derived/HENRY.js +13 -13
  727. package/src/core/science/units/si/derived/HERTZ.js +16 -16
  728. package/src/core/science/units/si/derived/JOULE.js +13 -13
  729. package/src/core/science/units/si/derived/KATAL.js +13 -13
  730. package/src/core/science/units/si/derived/LUMEN.js +14 -14
  731. package/src/core/science/units/si/derived/LUX.js +13 -13
  732. package/src/core/science/units/si/derived/NEWTON.js +13 -13
  733. package/src/core/science/units/si/derived/OHM.js +13 -13
  734. package/src/core/science/units/si/derived/PASCAL.js +13 -13
  735. package/src/core/science/units/si/derived/SIEMENS.js +13 -13
  736. package/src/core/science/units/si/derived/SIEVERT.js +16 -16
  737. package/src/core/science/units/si/derived/TESLA.js +13 -13
  738. package/src/core/science/units/si/derived/VOLT.js +13 -13
  739. package/src/core/science/units/si/derived/WATT.js +13 -13
  740. package/src/core/science/units/si/derived/WEBER.js +13 -13
  741. package/src/core/science/units/unit_matrix_to_string.js +403 -403
  742. package/src/engine/Engine.js +726 -726
  743. package/src/engine/EngineHarness.js +590 -590
  744. package/src/engine/REVIEW_2026_07_03.md +211 -211
  745. package/src/engine/animation/AnimatedActions.js +81 -81
  746. package/src/engine/animation/AnimationUtils.js +252 -252
  747. package/src/engine/animation/async/TimeSeries.js +300 -300
  748. package/src/engine/animation/curve/animation_curve_binary_codec.js +60 -60
  749. package/src/engine/animation/curve/draw/canvas_point_to_curve.js +22 -22
  750. package/src/engine/animation/curve/draw/curve_point_to_canvas.js +38 -38
  751. package/src/engine/animation/curve/draw/position_canvas_to_curve.js +22 -22
  752. package/src/engine/animation/curve/draw/position_curve_to_canvas.js +22 -22
  753. package/src/engine/asset/GameAssetType.d.ts +0 -1
  754. package/src/engine/asset/GameAssetType.js +0 -1
  755. package/src/engine/asset/load_model_scene_bundle.js +27 -27
  756. package/src/engine/asset/loaders/font/FontAsset.js +21 -21
  757. package/src/engine/asset/loaders/font/FontAssetLoader.js +20 -20
  758. package/src/engine/asset/loaders/gltf_test_fixtures.js +358 -358
  759. package/src/engine/asset/loaders/image/ImageBitmapAssetLoader.js +52 -52
  760. package/src/engine/asset/loaders/image/ImageRGBADataLoader.js +94 -94
  761. package/src/engine/asset/loaders/image/png/filter/png_filter_unFilterAverage.js +59 -59
  762. package/src/engine/asset/loaders/image/png/filter/png_filter_unFilterNone.js +55 -55
  763. package/src/engine/asset/loaders/image/png/filter/png_filter_unFilterPaeth.js +74 -74
  764. package/src/engine/asset/loaders/image/png/filter/png_filter_unFilterSub.js +34 -34
  765. package/src/engine/asset/loaders/image/png/filter/png_filter_unFilterUp.js +46 -46
  766. package/src/engine/control/first-person/DESIGN.md +640 -640
  767. package/src/engine/control/first-person/DESIGN_EXTENSIONS.md +563 -563
  768. package/src/engine/control/first-person/FirstPersonMotionPhase.js +134 -134
  769. package/src/engine/control/first-person/FirstPersonPlayerControllerSystem.js +2045 -2045
  770. package/src/engine/control/first-person/mastery/DecisionPoint.js +30 -30
  771. package/src/engine/control/first-person/math/Spring.js +71 -71
  772. package/src/engine/control/first-person/math/computeJumpFromApex.js +23 -23
  773. package/src/engine/control/first-person/math/computeLRCBreathRate.js +41 -41
  774. package/src/engine/control/first-person/math/computeMassRatios.js +44 -44
  775. package/src/engine/control/first-person/math/criticallyDampedSpring.js +34 -34
  776. package/src/engine/control/first-person/math/dampedSpringStep.js +72 -72
  777. package/src/engine/control/first-person/math/jumpDynamics.js +108 -108
  778. package/src/engine/control/first-person/math/stepTowards.js +20 -20
  779. package/src/engine/control/first-person/pose/FirstPersonPose.js +137 -137
  780. package/src/engine/control/first-person/pose/FirstPersonPosture.js +27 -27
  781. package/src/engine/control/first-person/test/buildTestPlayer.js +36 -36
  782. package/src/engine/ecs/ASYNC_SYSTEMS_PROPOSAL.md +531 -531
  783. package/src/engine/ecs/EntityManager.d.ts +7 -3
  784. package/src/engine/ecs/EntityManager.d.ts.map +1 -1
  785. package/src/engine/ecs/EntityManager.js +10 -5
  786. package/src/engine/ecs/HIERARCHY_REVIEW.md +717 -717
  787. package/src/engine/ecs/async/SystemWorkerHost.js +329 -329
  788. package/src/engine/ecs/async/SystemWorkerLoopback.js +143 -143
  789. package/src/engine/ecs/async/WORKER_SYSTEM_PLAN.md +246 -246
  790. package/src/engine/ecs/async/WorkerSystem.js +702 -702
  791. package/src/engine/ecs/async/WorkerSystemProtocol.js +150 -150
  792. package/src/engine/ecs/fow/FogOfWar.js +707 -707
  793. package/src/engine/ecs/fow/FogOfWarEdgeMode.js +40 -40
  794. package/src/engine/ecs/fow/fog_of_war_mask_world_bounds.js +24 -24
  795. package/src/engine/ecs/fow/fog_of_war_uv_transform.js +30 -30
  796. package/src/engine/ecs/gui/hud/testHudEdgeStick.js +132 -134
  797. package/src/engine/ecs/hierarchy/EntityChildIndex.js +140 -140
  798. package/src/engine/ecs/ik/IKProblem.js +42 -42
  799. package/src/engine/ecs/ik/InverseKinematicsSystem.js +193 -193
  800. package/src/engine/ecs/ik/OneBoneSurfaceAlignmentSolver.js +134 -134
  801. package/src/engine/ecs/ik/TwoBoneInverseKinematicsSolver.js +97 -97
  802. package/src/engine/ecs/ik/ik_bone_chain.js +85 -85
  803. package/src/engine/ecs/ik/ik_probe_terrain_contact.js +119 -119
  804. package/src/engine/ecs/parent/EntityNode.d.ts +1 -1
  805. package/src/engine/ecs/parent/EntityNode.js +2 -2
  806. package/src/engine/ecs/parent/ParentEntitySystem.js +255 -255
  807. package/src/engine/ecs/speaker/VoiceSystem.d.ts +2 -2
  808. package/src/engine/ecs/speaker/VoiceSystem.d.ts.map +1 -1
  809. package/src/engine/ecs/speaker/VoiceSystem.js +13 -7
  810. package/src/engine/ecs/storage/binary/SERIALIZATION_COVERAGE.md +269 -269
  811. package/src/engine/ecs/storage/binary/object-v2/BinaryObjectDeSerializer.js +315 -315
  812. package/src/engine/ecs/storage/binary/object-v2/BinaryObjectSerializer.js +331 -331
  813. package/src/engine/ecs/storage/binary/object-v2/DESIGN.md +199 -199
  814. package/src/engine/ecs/storage/binary/object-v2/ObjectBinaryFormat.js +57 -57
  815. package/src/engine/ecs/storage/binary/object-v2/ObjectSerializationAdapter.js +56 -56
  816. package/src/engine/ecs/storage/binary/object-v2/README.md +110 -110
  817. package/src/engine/ecs/storage/binary/object-v2/objectStringCodec.js +48 -48
  818. package/src/engine/ecs/storage/binary/object-v2/serializerTestHarness.js +44 -44
  819. package/src/engine/ecs/storage/populateEngineSerializationRegistry.js +265 -265
  820. package/src/engine/ecs/terrain/TerrainClouds.js +97 -97
  821. package/src/engine/ecs/terrain/ecs/StubTerrainBuildWorker.js +65 -65
  822. package/src/engine/ecs/terrain/ecs/Terrain.d.ts +4 -0
  823. package/src/engine/ecs/terrain/ecs/Terrain.d.ts.map +1 -1
  824. package/src/engine/ecs/terrain/ecs/Terrain.js +790 -790
  825. package/src/engine/ecs/terrain/ecs/TerrainSystem.js +209 -209
  826. package/src/engine/ecs/terrain/ecs/cling/ClingToTerrainSystem.js +316 -316
  827. package/src/engine/ecs/terrain/ecs/layers/TerrainLayers.js +416 -416
  828. package/src/engine/ecs/terrain/ecs/splat/SplatMapping.js +525 -525
  829. package/src/engine/ecs/terrain/overlay/TerrainOverlay.js +302 -302
  830. package/src/engine/ecs/terrain/tiles/TerrainTile.js +561 -561
  831. package/src/engine/ecs/terrain/tiles/TerrainTileManager.js +896 -896
  832. package/src/engine/ecs/terrain/tiles/tile_geometry_to_meshlets.js +36 -36
  833. package/src/engine/ecs/terrain/util/loadVisibleTerrainTiles.js +129 -129
  834. package/src/engine/ecs/transform/Transform64.js +814 -814
  835. package/src/engine/ecs/transform/t64_copy_from_transform.js +35 -35
  836. package/src/engine/ecs/transform/t64_equals_transform.js +55 -55
  837. package/src/engine/ecs/transform/t64_look_rotation.js +36 -36
  838. package/src/engine/ecs/transform/t64_transform_direction.js +25 -25
  839. package/src/engine/ecs/transform/transform_copy_from_t64.js +28 -28
  840. package/src/engine/ecs/transform-attachment/TransformAttachmentSystem.js +345 -345
  841. package/src/engine/ecs/transform-attachment/transform_attachment_find_descendant_by_name.js +65 -65
  842. package/src/engine/ecs/transform-attachment/transform_attachment_parent_of.js +24 -24
  843. package/src/engine/ecs/util/hideEntityGracefully.js +208 -208
  844. package/src/engine/graphics/CONTEXT_LOSS_RECOVERY_PLAN.md +446 -446
  845. package/src/engine/graphics/FULL_SCREEN_QUAD_VERTEX_SHADER.js +14 -14
  846. package/src/engine/graphics/FrameThrottle.js +2 -2
  847. package/src/engine/graphics/ecs/animation/animator/graph/AnimationState.js +207 -207
  848. package/src/engine/graphics/ecs/animation/animator/graph/AnimationTransition.js +151 -151
  849. package/src/engine/graphics/ecs/animation/animator/graph/definition/serialization/AnimationGraphDefinitionAssetLoader.js +22 -22
  850. package/src/engine/graphics/ecs/camera/Camera.js +165 -165
  851. package/src/engine/graphics/ecs/camera/camera_active_frustum.js +25 -25
  852. package/src/engine/graphics/ecs/camera/camera_find_active.js +28 -28
  853. package/src/engine/graphics/ecs/camera/camera_traverse_active.js +18 -18
  854. package/src/engine/graphics/ecs/camera/pp/PerfectPanner.js +170 -170
  855. package/src/engine/graphics/ecs/camera/serialization/CameraSerializationAdapter.js +68 -68
  856. package/src/engine/graphics/ecs/camera/topdown/TopDownCameraController.js +296 -296
  857. package/src/engine/graphics/ecs/decal/v2/Decal.js +220 -220
  858. package/src/engine/graphics/ecs/decal/v2/DecalSerializationAdapter.js +56 -56
  859. package/src/engine/graphics/ecs/decal/v2/DecalSerializationUpgrader_0_1.js +38 -38
  860. package/src/engine/graphics/ecs/light/shadow/compute_view_frustum_aabb_in_space.js +62 -62
  861. package/src/engine/graphics/ecs/light/shadow/extend_shadow_camera_near_for_casters.js +77 -77
  862. package/src/engine/graphics/ecs/make_bvh_depth_range_computer.js +33 -33
  863. package/src/engine/graphics/ecs/mesh-v2/DeferredBoundsQueue.js +88 -88
  864. package/src/engine/graphics/ecs/mesh-v2/ShadedGeometry.js +428 -428
  865. package/src/engine/graphics/ecs/mesh-v2/aggregate/SGMesh.js +303 -303
  866. package/src/engine/graphics/ecs/mesh-v2/aggregate/SGMeshSystem.d.ts +1 -1
  867. package/src/engine/graphics/ecs/mesh-v2/aggregate/serialization/SGMeshSerializationAdapter.js +39 -39
  868. package/src/engine/graphics/ecs/mesh-v2/sg_hierarchy_compute_bounding_box_via_parent_entity.js +36 -36
  869. package/src/engine/graphics/ecs/path/tube/build/GeometryStream.js +94 -94
  870. package/src/engine/graphics/ecs/path/tube/build/build_stream_catmullrom.js +310 -310
  871. package/src/engine/graphics/ecs/path/tube/build/build_stream_linear.js +73 -73
  872. package/src/engine/graphics/ecs/path/tube/build/computeFrenetFrames.js +199 -199
  873. package/src/engine/graphics/ecs/path/tube/build/makeTubeStream.js +217 -217
  874. package/src/engine/graphics/ecs/path/tube/build/make_cap.js +340 -340
  875. package/src/engine/graphics/ecs/path/tube/build/make_ring_faces.js +40 -40
  876. package/src/engine/graphics/ecs/path/tube/build/make_ring_vertices.js +153 -153
  877. package/src/engine/graphics/ecs/render_layers_compute_depth_range.js +64 -64
  878. package/src/engine/graphics/ecs/trail3d/Trail3D.js +483 -483
  879. package/src/engine/graphics/ecs/trail3d/Trail3DFlags.js +26 -26
  880. package/src/engine/graphics/ecs/trail3d/advance_trail.js +42 -42
  881. package/src/engine/graphics/ecs/trail3d/make_gradient_stroke.js +58 -58
  882. package/src/engine/graphics/ecs/trail3d/seed_trail_stroke.js +90 -90
  883. package/src/engine/graphics/ecs/trail3d/seed_trail_tube.js +75 -75
  884. package/src/engine/graphics/ecs/trail3d/trail_head_position.js +19 -19
  885. package/src/engine/graphics/ecs/water/Water.js +104 -104
  886. package/src/engine/graphics/geometry/AttributeData.js +84 -84
  887. package/src/engine/graphics/geometry/buffered/geometry_compute_vertex_normals_indexed.js +49 -49
  888. package/src/engine/graphics/geometry/buffered/query/GeometrySpatialQueryAccelerator.js +288 -288
  889. package/src/engine/graphics/geometry/buffered/query/nearest_point_on_triangle_record.js +87 -87
  890. package/src/engine/graphics/geometry/buffered/read_triangle_vertices.js +102 -102
  891. package/src/engine/graphics/geometry/bvh/buffered/bvh32_from_buffered_geometry.js +52 -52
  892. package/src/engine/graphics/geometry/bvh/buffered/bvh32_from_indexed_geometry.js +20 -20
  893. package/src/engine/graphics/geometry/bvh/buffered/bvh32_from_unindexed_geometry.js +19 -19
  894. package/src/engine/graphics/geometry/optimization/geometry_optimize_uv_tension.js +135 -135
  895. package/src/engine/graphics/impostors/voxel/README.md +149 -149
  896. package/src/engine/graphics/impostors/voxel/VoxelImpostorDescription.js +141 -141
  897. package/src/engine/graphics/particles/node-based/codegen/glsl/getTypeByteSize.js +20 -20
  898. package/src/engine/graphics/particles/node-based/nodes/FloatConstant.d.ts +2 -0
  899. package/src/engine/graphics/particles/node-based/nodes/FloatConstant.d.ts.map +1 -1
  900. package/src/engine/graphics/particles/node-based/nodes/ReadFloatUniform.d.ts +2 -0
  901. package/src/engine/graphics/particles/node-based/nodes/ReadFloatUniform.d.ts.map +1 -1
  902. package/src/engine/graphics/particles/node-based/nodes/ReadVelocity.d.ts +2 -0
  903. package/src/engine/graphics/particles/node-based/nodes/ReadVelocity.d.ts.map +1 -1
  904. package/src/engine/graphics/particles/node-based/nodes/ShaderNode.d.ts +1 -2
  905. package/src/engine/graphics/particles/node-based/nodes/ShaderNode.d.ts.map +1 -1
  906. package/src/engine/graphics/particles/node-based/nodes/Vector3Constant.d.ts +2 -0
  907. package/src/engine/graphics/particles/node-based/nodes/Vector3Constant.d.ts.map +1 -1
  908. package/src/engine/graphics/particles/node-based/nodes/Vector3Merge.d.ts +2 -0
  909. package/src/engine/graphics/particles/node-based/nodes/Vector3Merge.d.ts.map +1 -1
  910. package/src/engine/graphics/particles/node-based/nodes/Vector3Split.d.ts +2 -0
  911. package/src/engine/graphics/particles/node-based/nodes/Vector3Split.d.ts.map +1 -1
  912. package/src/engine/graphics/particles/node-based/nodes/WriteVelocity.d.ts +2 -0
  913. package/src/engine/graphics/particles/node-based/nodes/WriteVelocity.d.ts.map +1 -1
  914. package/src/engine/graphics/particles/node-based/nodes/attribute/ReadVector3Attribute.d.ts +2 -0
  915. package/src/engine/graphics/particles/node-based/nodes/attribute/ReadVector3Attribute.d.ts.map +1 -1
  916. package/src/engine/graphics/particles/node-based/nodes/attribute/WriteVector3Attribute.d.ts +2 -0
  917. package/src/engine/graphics/particles/node-based/nodes/attribute/WriteVector3Attribute.d.ts.map +1 -1
  918. package/src/engine/graphics/particles/node-based/nodes/math/AddFloatNode.d.ts +2 -0
  919. package/src/engine/graphics/particles/node-based/nodes/math/AddFloatNode.d.ts.map +1 -1
  920. package/src/engine/graphics/particles/node-based/nodes/math/Vector3Add.d.ts +2 -0
  921. package/src/engine/graphics/particles/node-based/nodes/math/Vector3Add.d.ts.map +1 -1
  922. package/src/engine/graphics/particles/node-based/nodes/math/Vector3Divide.d.ts +2 -0
  923. package/src/engine/graphics/particles/node-based/nodes/math/Vector3Divide.d.ts.map +1 -1
  924. package/src/engine/graphics/particles/node-based/nodes/math/Vector3Multiply.d.ts +2 -0
  925. package/src/engine/graphics/particles/node-based/nodes/math/Vector3Multiply.d.ts.map +1 -1
  926. package/src/engine/graphics/particles/node-based/nodes/math/Vector3Subtract.d.ts +2 -0
  927. package/src/engine/graphics/particles/node-based/nodes/math/Vector3Subtract.d.ts.map +1 -1
  928. package/src/engine/graphics/particles/node-based/nodes/noise/CurlNoiseNode.d.ts +2 -0
  929. package/src/engine/graphics/particles/node-based/nodes/noise/CurlNoiseNode.d.ts.map +1 -1
  930. package/src/engine/graphics/particles/node-based/nodes/particle_data_type_component_count.js +45 -45
  931. package/src/engine/graphics/particles/particular/engine/ParticularEngine.js +229 -229
  932. package/src/engine/graphics/particles/particular/engine/emitter/ParticleEmitter.d.ts +2 -10
  933. package/src/engine/graphics/particles/particular/engine/emitter/ParticleEmitter.d.ts.map +1 -1
  934. package/src/engine/graphics/particles/particular/engine/emitter/ParticleEmitter.js +1149 -1149
  935. package/src/engine/graphics/particles/particular/engine/emitter/ParticlePool.js +472 -472
  936. package/src/engine/graphics/particles/particular/engine/parameter/ParameterLookupTable.js +2 -2
  937. package/src/engine/graphics/particles/particular/engine/parameter/ParameterLookupTableFlags.js +2 -2
  938. package/src/engine/graphics/particles/particular/engine/parameter/ParameterSet.d.ts.map +1 -1
  939. package/src/engine/graphics/particles/particular/engine/parameter/ParameterSet.js +3 -5
  940. package/src/engine/graphics/particles/particular/engine/shader/ShaderManager.js +135 -135
  941. package/src/engine/graphics/particles/particular/engine/utils/distribute_points_on_indexed_triangles.js +168 -168
  942. package/src/engine/graphics/render/forward_plus/plugin/forwardPlusMaterialMarker.js +18 -18
  943. package/src/engine/graphics/render/forward_plus/read_frustum_corner.js +2 -2
  944. package/src/engine/graphics/render/frame_graph/FRAME_GRAPH_RECOMMENDATIONS.md +219 -219
  945. package/src/engine/graphics/render/frame_graph/FrameGraph.js +900 -900
  946. package/src/engine/graphics/render/frame_graph/FrameGraphScope.js +72 -72
  947. package/src/engine/graphics/render/frame_graph/FrameGraphState.js +39 -39
  948. package/src/engine/graphics/render/frame_graph/ResourceEntry.js +96 -96
  949. package/src/engine/graphics/render/gizmo/GizmoShapeBuffer.js +105 -105
  950. package/src/engine/graphics/render/gizmo/GizmoShapeRenderingInterface.js +162 -162
  951. package/src/engine/graphics/render/layers/RenderLayer.js +95 -95
  952. package/src/engine/graphics/sh3/build_injected_shader.js +56 -56
  953. package/src/engine/graphics/sh3/grid_dilate_average.js +175 -175
  954. package/src/engine/graphics/sh3/path_tracer/BufferedGeometryBVH.js +506 -506
  955. package/src/engine/graphics/sh3/path_tracer/PathTracedMesh.js +161 -161
  956. package/src/engine/graphics/sh3/path_tracer/PathTracedRenderer.js +205 -205
  957. package/src/engine/graphics/sh3/path_tracer/PathTracedScene.js +698 -698
  958. package/src/engine/graphics/sh3/path_tracer/REVIEW_001_ACTION_PLAN.md +490 -490
  959. package/src/engine/graphics/sh3/path_tracer/geometry/compute_triangle_group_aabb3.js +2 -2
  960. package/src/engine/graphics/sh3/path_tracer/make_sky_hosek.js +45 -45
  961. package/src/engine/graphics/sh3/path_tracer/populate_path_traced_scene_from_ecd.js +73 -73
  962. package/src/engine/graphics/sh3/path_tracer/ray_hit_apply_transform.js +32 -32
  963. package/src/engine/graphics/sh3/path_tracer/texture/apply_texture_clamping_to_coordinate.js +28 -28
  964. package/src/engine/graphics/sh3/path_tracer/texture/sample_material.js +142 -142
  965. package/src/engine/graphics/sh3/sky/hosek/render_hosek_sky_to_equirectangular.js +70 -70
  966. package/src/engine/graphics/sh3/sky/hosek/sky_hosek_compute_irradiance_by_direction.js +388 -388
  967. package/src/engine/graphics/shaders/chunks/glsl_octahedral_impostor.js +277 -277
  968. package/src/engine/graphics/shaders/chunks/glsl_voxel_impostor_splat.js +57 -57
  969. package/src/engine/graphics/shadows/vsm.glsl.js +43 -43
  970. package/src/engine/graphics/texture/3d/scs3d_sample_linear3.js +81 -81
  971. package/src/engine/graphics/texture/EnvironmentTextureProjection.js +15 -15
  972. package/src/engine/graphics/texture/channel_count_to_format_prefix.js +26 -26
  973. package/src/engine/graphics/texture/isImageBitmap.js +2 -2
  974. package/src/engine/graphics/texture/reflection/convolve_equirectangular_reflection.js +189 -189
  975. package/src/engine/graphics/texture/reflection/equirectangular_reflection_roughness.js +51 -51
  976. package/src/engine/graphics/texture/sampler/HarmonicDiffusionGrid.js +145 -145
  977. package/src/engine/graphics/texture/sampler/Sampler2DArray.js +172 -172
  978. package/src/engine/graphics/texture/sampler/compare/FLIP_IMPLEMENTATION_PLAN.md +466 -466
  979. package/src/engine/graphics/texture/sampler/compare/flip/FlipParameters.js +18 -18
  980. package/src/engine/graphics/texture/sampler/compare/flip/FlipPooling.js +33 -33
  981. package/src/engine/graphics/texture/sampler/compare/flip/flip_build_feature_kernel.js +147 -147
  982. package/src/engine/graphics/texture/sampler/compare/flip/flip_build_spatial_kernel.js +177 -177
  983. package/src/engine/graphics/texture/sampler/compare/flip/flip_compute_color_difference.js +104 -104
  984. package/src/engine/graphics/texture/sampler/compare/flip/flip_compute_feature_difference.js +76 -76
  985. package/src/engine/graphics/texture/sampler/compare/flip/flip_compute_pixels_per_degree.js +34 -34
  986. package/src/engine/graphics/texture/sampler/compare/flip/flip_constants.js +77 -77
  987. package/src/engine/graphics/texture/sampler/compare/flip/flip_filter_feature.js +48 -48
  988. package/src/engine/graphics/texture/sampler/compare/flip/flip_filter_spatial.js +86 -86
  989. package/src/engine/graphics/texture/sampler/compare/flip/flip_pool.js +71 -71
  990. package/src/engine/graphics/texture/sampler/compare/flip/flip_srgb_to_ycxcz.js +55 -55
  991. package/src/engine/graphics/texture/sampler/compare/flip/sampler2d_flip_ldr.js +80 -80
  992. package/src/engine/graphics/texture/sampler/filter/SeparableKernel.js +82 -82
  993. package/src/engine/graphics/texture/sampler/filter/sampler2d_convolve_separable.js +122 -122
  994. package/src/engine/graphics/texture/sampler/resize/sampler2d_scale_down_lanczos.js +148 -148
  995. package/src/engine/graphics/texture/sampler/sampler2d_channel_apply_lut.js +82 -82
  996. package/src/engine/graphics/texture/sampler/sampler2d_combine.js +67 -67
  997. package/src/engine/graphics/texture/sampler/sampler2d_linear_f16_to_srgb_u8.js +54 -54
  998. package/src/engine/graphics/texture/sampler/sampler2d_sample_equirectangular_direction.js +63 -63
  999. package/src/engine/graphics/texture/sampler/sampler2d_srgb_to_linear.js +33 -33
  1000. package/src/engine/graphics/texture/sampler/sampler2d_srgb_u8_to_linear_f16.js +68 -68
  1001. package/src/engine/graphics/texture/shade_image_preview.js +103 -103
  1002. package/src/engine/graphics/trail/TrailSpawnMode.js +20 -20
  1003. package/src/engine/graphics/trail/tube/TubeX.js +573 -573
  1004. package/src/engine/graphics/trail/tube/TubeXMaterialSpec.js +58 -58
  1005. package/src/engine/graphics/trail/tube/simulator/TubeXFixedPhysicsSimulator.js +34 -34
  1006. package/src/engine/graphics/trail/tube/tube_attributes_spec.js +69 -69
  1007. package/src/engine/graphics/trail/tube/tube_frame.js +83 -83
  1008. package/src/engine/graphics3/AnimationGraphSystem3.js +329 -329
  1009. package/src/engine/graphics3/AnimationSystem3.js +352 -352
  1010. package/src/engine/graphics3/CameraSystem3.js +170 -170
  1011. package/src/engine/graphics3/DecalSystem3.js +441 -441
  1012. package/src/engine/graphics3/FogOfWarSystem3.js +265 -265
  1013. package/src/engine/graphics3/GraphicsEngine3.js +776 -776
  1014. package/src/engine/graphics3/HighlightSystem3.js +241 -241
  1015. package/src/engine/graphics3/LightSystem3.js +211 -211
  1016. package/src/engine/graphics3/MeshSystem3.js +646 -646
  1017. package/src/engine/graphics3/ParticleEmitterSystem3.js +289 -289
  1018. package/src/engine/graphics3/PathDisplaySystem3.js +309 -309
  1019. package/src/engine/graphics3/PickingQuery.js +48 -48
  1020. package/src/engine/graphics3/PickingResult.js +47 -47
  1021. package/src/engine/graphics3/PickingSystem3.js +273 -273
  1022. package/src/engine/graphics3/ShadeCameraAdapter.js +55 -55
  1023. package/src/engine/graphics3/ShadedGeometrySystem3.js +169 -169
  1024. package/src/engine/graphics3/TerrainSystem3.js +566 -566
  1025. package/src/engine/graphics3/TooltipComponentSystem3.js +328 -328
  1026. package/src/engine/graphics3/Trail3DSystem3.js +221 -221
  1027. package/src/engine/graphics3/WaterSystem3.js +293 -293
  1028. package/src/engine/graphics3/animation/ClipPlayback.js +84 -84
  1029. package/src/engine/graphics3/animation/wrap_clip_time.js +23 -23
  1030. package/src/engine/graphics3/animation/write_graph_playback.js +48 -48
  1031. package/src/engine/graphics3/camera_sync_from_transform.js +29 -29
  1032. package/src/engine/graphics3/debug/gizmo_view_from_camera.js +48 -48
  1033. package/src/engine/graphics3/decal/DECAL_CLUSTER.js +61 -61
  1034. package/src/engine/graphics3/decal/DECAL_GPU_RECORD.js +117 -117
  1035. package/src/engine/graphics3/decal/DecalAtlas.js +194 -194
  1036. package/src/engine/graphics3/decal/DecalAtlasFill.js +32 -32
  1037. package/src/engine/graphics3/decal/GPUDecalRenderer.js +360 -360
  1038. package/src/engine/graphics3/decal/chunk_decal_intersects_frustum.js +59 -59
  1039. package/src/engine/graphics3/decal/chunk_decal_sampling_info.js +57 -57
  1040. package/src/engine/graphics3/decal/chunk_decal_surface_frame.js +54 -54
  1041. package/src/engine/graphics3/decal/decal_atlas_border.js +69 -69
  1042. package/src/engine/graphics3/decal/decal_gpu_records.js +120 -120
  1043. package/src/engine/graphics3/decal/decal_material_samplers.js +109 -109
  1044. package/src/engine/graphics3/decal/graph_build_decal_clusters.js +212 -212
  1045. package/src/engine/graphics3/decal/shader_cluster_assign_decals.js +207 -207
  1046. package/src/engine/graphics3/decal/shader_cull_decals_frustum.js +108 -108
  1047. package/src/engine/graphics3/highlight/GPUHighlightRenderer.js +151 -151
  1048. package/src/engine/graphics3/highlight/HIGHLIGHT_OUTLINE.js +23 -23
  1049. package/src/engine/graphics3/highlight/chunk_highlight_lookup.js +53 -53
  1050. package/src/engine/graphics3/highlight/pack_highlight_color.js +44 -44
  1051. package/src/engine/graphics3/highlight/pack_highlight_table.js +74 -74
  1052. package/src/engine/graphics3/highlight/shader_highlight_outline.js +150 -150
  1053. package/src/engine/graphics3/load_cube_environment.js +68 -68
  1054. package/src/engine/graphics3/make_default_environment.js +107 -107
  1055. package/src/engine/graphics3/particles/particle_gpu_records.js +221 -221
  1056. package/src/engine/graphics3/path/build_tube_path_streams.js +98 -98
  1057. package/src/engine/graphics3/path/tube_stream_write_geometry.js +90 -90
  1058. package/src/engine/graphics3/preview/ModelPreviewFraming.js +35 -35
  1059. package/src/engine/graphics3/preview/make_model_preview_scene.js +154 -154
  1060. package/src/engine/graphics3/preview/make_model_thumbnail.js +48 -48
  1061. package/src/engine/graphics3/preview/model_preview_framing.js +70 -70
  1062. package/src/engine/graphics3/shade_bundle_bounds.js +55 -55
  1063. package/src/engine/graphics3/shade_camera_projection_ray.js +77 -77
  1064. package/src/engine/graphics3/shade_node_to_entity_composition.js +84 -84
  1065. package/src/engine/graphics3/terrain/GPUTerrainSplatRenderer.js +481 -481
  1066. package/src/engine/graphics3/terrain/chunk_terrain_grid_overlay.js +61 -61
  1067. package/src/engine/graphics3/terrain/chunk_terrain_splat_mix.js +66 -66
  1068. package/src/engine/graphics3/terrain/pack_terrain_row_table.js +53 -53
  1069. package/src/engine/graphics3/terrain/shader_terrain_splat.js +215 -215
  1070. package/src/engine/graphics3/trail/trail_tube_write_geometry.js +158 -158
  1071. package/src/engine/input/GAMEPAD_API_PROPOSAL.md +717 -717
  1072. package/src/engine/input/analog/apply_radial_dead_zone.js +38 -38
  1073. package/src/engine/input/devices/GamepadDevice.js +466 -466
  1074. package/src/engine/input/devices/ManualInputDevice.js +152 -152
  1075. package/src/engine/input/devices/PointerCoordinates.js +26 -26
  1076. package/src/engine/input/devices/events/GamepadEvents.js +10 -10
  1077. package/src/engine/input/devices/gamepad/GamepadAxes.js +19 -19
  1078. package/src/engine/input/devices/gamepad/GamepadButtons.js +29 -29
  1079. package/src/engine/input/devices/gamepad/GamepadCoordinates.js +17 -17
  1080. package/src/engine/input/devices/gamepad/GamepadDeviceLayout.js +323 -323
  1081. package/src/engine/input/devices/gamepad/GamepadHandle.js +286 -286
  1082. package/src/engine/input/devices/gamepad/GamepadLayout.js +160 -160
  1083. package/src/engine/input/devices/gamepad/GamepadStandardMapping.js +31 -31
  1084. package/src/engine/input/devices/gamepad/GamepadStick.js +169 -169
  1085. package/src/engine/input/devices/gamepad/GamepadStickCalibration.js +119 -119
  1086. package/src/engine/input/devices/gamepad/GamepadStickCalibrator.js +250 -250
  1087. package/src/engine/input/devices/gamepad/gamepad_layout_database.js +144 -144
  1088. package/src/engine/input/devices/gamepad/gamepad_read_hat_axis.js +61 -61
  1089. package/src/engine/input/devices/gamepad/gamepad_write_dpad_vector.js +30 -30
  1090. package/src/engine/input/devices/gamepad/prototypeGamepadTester.js +2124 -2124
  1091. package/src/engine/input/devices/mouse/MouseButtons.js +22 -22
  1092. package/src/engine/input/ecs/components/Input.js +118 -118
  1093. package/src/engine/input/ecs/components/InputController.js +78 -78
  1094. package/src/engine/input/ecs/ism/ISM_DESIGN.md +1523 -1523
  1095. package/src/engine/input/ecs/ism/ISM_IMPLEMENTATION_PLAN.md +627 -627
  1096. package/src/engine/input/ecs/ism/InputActionEvent.js +40 -40
  1097. package/src/engine/input/ecs/ism/InputBinding.js +71 -71
  1098. package/src/engine/input/ecs/ism/InputCoordinateKind.js +25 -25
  1099. package/src/engine/input/ecs/ism/InputCoordinateSource.js +86 -86
  1100. package/src/engine/input/ecs/ism/InputDirection.js +33 -33
  1101. package/src/engine/input/ecs/ism/InputMapProgram.js +236 -236
  1102. package/src/engine/input/ecs/ism/InputMapSystem.js +976 -976
  1103. package/src/engine/input/ecs/ism/InputOcclusion.js +31 -31
  1104. package/src/engine/input/ecs/ism/InputSource.js +67 -67
  1105. package/src/engine/input/ecs/ism/InputSourceTable.js +107 -107
  1106. package/src/engine/input/ecs/ism/coordinate/InputCoordinateChannel.js +93 -93
  1107. package/src/engine/input/ecs/ism/coordinate/InputCoordinateChannelType.js +11 -11
  1108. package/src/engine/input/ecs/ism/coordinate/InputCoordinateDevice.js +153 -153
  1109. package/src/engine/input/ecs/ism/coordinate/InputCoordinateSwitches.js +160 -160
  1110. package/src/engine/input/ecs/ism/device/GAMEPAD_INPUT_DEVICE_ID.js +9 -9
  1111. package/src/engine/input/ecs/ism/device/GamepadInputDeviceAdapter.js +88 -88
  1112. package/src/engine/input/ecs/ism/device/InputDeviceAdapter.js +72 -72
  1113. package/src/engine/input/ecs/ism/device/KEYBOARD_INPUT_DEVICE_ID.js +9 -9
  1114. package/src/engine/input/ecs/ism/device/KeyboardInputDeviceAdapter.js +63 -63
  1115. package/src/engine/input/ecs/ism/device/ManualInputDeviceAdapter.js +55 -55
  1116. package/src/engine/input/ecs/ism/device/POINTER_INPUT_DEVICE_ID.js +9 -9
  1117. package/src/engine/input/ecs/ism/device/PointerInputDeviceAdapter.js +160 -160
  1118. package/src/engine/input/ecs/ism/map/InputBinding.js +88 -88
  1119. package/src/engine/input/ecs/ism/map/InputCoordinateBinding.js +102 -102
  1120. package/src/engine/input/ecs/ism/map/InputLayer.js +220 -220
  1121. package/src/engine/input/ecs/ism/map/InputMap.js +331 -331
  1122. package/src/engine/input/ecs/ism/prototypeInputMap.js +309 -309
  1123. package/src/engine/input/ecs/ism/trigger/InputTrigger.js +148 -148
  1124. package/src/engine/input/ecs/ism/trigger/InputTriggerChord.js +173 -173
  1125. package/src/engine/input/ecs/ism/trigger/InputTriggerGamepadButton.js +37 -37
  1126. package/src/engine/input/ecs/ism/trigger/InputTriggerHold.js +176 -176
  1127. package/src/engine/input/ecs/ism/trigger/InputTriggerKey.js +39 -39
  1128. package/src/engine/input/ecs/ism/trigger/InputTriggerMouseButton.js +38 -38
  1129. package/src/engine/input/ecs/ism/trigger/InputTriggerRelease.js +120 -120
  1130. package/src/engine/input/ecs/ism/trigger/InputTriggerSequence.js +315 -315
  1131. package/src/engine/input/ecs/ism/trigger/InputTriggerSwitch.js +105 -105
  1132. package/src/engine/input/ecs/ism/trigger/InputTriggerType.js +17 -17
  1133. package/src/engine/input/ecs/systems/InputControllerSystem.js +253 -253
  1134. package/src/engine/input/ecs/systems/InputSystem.js +162 -162
  1135. package/src/engine/intelligence/behavior/primitive/FailingBehaviorSerializationAdapter.js +25 -25
  1136. package/src/engine/intelligence/behavior/primitive/SucceedingBehaviorSerializationAdapter.js +26 -26
  1137. package/src/engine/intelligence/behavior/util/AsynchronousDelayAction.js +55 -55
  1138. package/src/engine/interpolation/BinaryInterpolationAdapter.js +56 -56
  1139. package/src/engine/interpolation/Interpoland.js +49 -49
  1140. package/src/engine/interpolation/Interpolated.js +149 -149
  1141. package/src/engine/interpolation/PoseInterpolationAdapter.js +61 -61
  1142. package/src/engine/interpolation/TransformPoseSerializationAdapter.js +57 -57
  1143. package/src/engine/interpolation/pose_interpoland.js +27 -27
  1144. package/src/engine/navigation/ecs/path_following/PathFollower.js +222 -222
  1145. package/src/engine/navigation/mesh/NavigationMesh.js +145 -145
  1146. package/src/engine/navigation/mesh/OVERLAPPING_SURFACES_2026_08_25.md +661 -0
  1147. package/src/engine/navigation/mesh/PATHFINDING_PLAN.md +229 -229
  1148. package/src/engine/navigation/mesh/build/clip_soup_against_overhangs.d.ts.map +1 -1
  1149. package/src/engine/navigation/mesh/build/clip_soup_against_overhangs.js +628 -520
  1150. package/src/engine/network/CONGESTION_CONTROL.md +87 -87
  1151. package/src/engine/network/README.md +52 -52
  1152. package/src/engine/network/adapters/QuaternionInterpolationAdapter.js +43 -43
  1153. package/src/engine/network/adapters/TransformInterpolationAdapter.js +84 -84
  1154. package/src/engine/network/adapters/TransformReplicationAdapter.js +87 -87
  1155. package/src/engine/network/adapters/Vector3InterpolationAdapter.js +46 -46
  1156. package/src/engine/network/convertPathToURL.js +2 -2
  1157. package/src/engine/network/core/MalformedPacketError.js +26 -26
  1158. package/src/engine/network/core/quantize/quantize_float.js +73 -73
  1159. package/src/engine/network/core/quantize/quantize_position.js +65 -65
  1160. package/src/engine/network/core/sequence/ack_bitfield.js +77 -77
  1161. package/src/engine/network/core/sequence/seq16.js +69 -69
  1162. package/src/engine/network/core/sequence/seq32.js +73 -73
  1163. package/src/engine/network/ecs/NetworkSystem.js +84 -84
  1164. package/src/engine/network/ecs/components/NetworkIdentity.js +73 -73
  1165. package/src/engine/network/ecs/owner_authorization.js +55 -55
  1166. package/src/engine/network/ecs/serialization/NetworkIdentitySerializationAdapter.js +64 -64
  1167. package/src/engine/network/replication/ScopeFilter.js +71 -71
  1168. package/src/engine/network/sim/ActionLog.js +152 -152
  1169. package/src/engine/network/sim/SimAction.js +273 -273
  1170. package/src/engine/network/sim/Snapshotter.js +222 -222
  1171. package/src/engine/network/state/FrameBufferRing.js +168 -168
  1172. package/src/engine/network/state/InputRing.js +134 -134
  1173. package/src/engine/network/state/PriorityAccumulator.js +180 -180
  1174. package/src/engine/network/time/TimeDilation.js +62 -62
  1175. package/src/engine/network/transport/Channel.js +336 -336
  1176. package/src/engine/network/transport/Transport.js +203 -203
  1177. package/src/engine/network/transport/adapters/NodeUDPTransport.js +186 -186
  1178. package/src/engine/network/transport/adapters/WebRTCDataChannelTransport.js +105 -105
  1179. package/src/engine/network/transport/fragments/fragment_send.js +147 -147
  1180. package/src/engine/network/transport/fragments/packet_size.js +101 -101
  1181. package/src/engine/network/xhr.js +23 -23
  1182. package/src/engine/physics/BULLET_REVIEW.md +945 -945
  1183. package/src/engine/physics/CANNON_REVIEW.md +1300 -1300
  1184. package/src/engine/physics/CONSTRAINT_SOLVER_BENCH_LOG.md +208 -208
  1185. package/src/engine/physics/CONSTRAINT_SOLVER_IMPROVEMENTS_PLAN.md +364 -364
  1186. package/src/engine/physics/INTEPOLATION_SYSTEM_PLAN.md +287 -287
  1187. package/src/engine/physics/JOLT_REVIEW.md +913 -913
  1188. package/src/engine/physics/PLAN.md +1120 -1094
  1189. package/src/engine/physics/RAPIER_REVIEW.md +934 -934
  1190. package/src/engine/physics/REVIEW_001_ACTION_PLAN.md +642 -642
  1191. package/src/engine/physics/REVIEW_002.md +151 -151
  1192. package/src/engine/physics/REVIEW_003.md +166 -166
  1193. package/src/engine/physics/broadphase/compute_fat_world_aabb.js +97 -97
  1194. package/src/engine/physics/constraint/DofMode.js +35 -35
  1195. package/src/engine/physics/constraint/solve_constraints.js +1 -1
  1196. package/src/engine/physics/contact/combine_material.js +35 -35
  1197. package/src/engine/physics/ecs/BodyKind.js +29 -29
  1198. package/src/engine/physics/ecs/Collider.js +177 -177
  1199. package/src/engine/physics/ecs/ColliderFlags.js +15 -15
  1200. package/src/engine/physics/ecs/ColliderSerializationAdapter.js +37 -37
  1201. package/src/engine/physics/ecs/Joint.js +475 -475
  1202. package/src/engine/physics/ecs/JointSerializationAdapter.js +72 -72
  1203. package/src/engine/physics/ecs/PhysicsSystem.d.ts +3 -0
  1204. package/src/engine/physics/ecs/PhysicsSystem.d.ts.map +1 -1
  1205. package/src/engine/physics/ecs/PhysicsSystem.js +7 -2
  1206. package/src/engine/physics/ecs/RigidBodySerializationUpgrader_0_1.js +37 -37
  1207. package/src/engine/physics/ecs/SleepState.js +12 -12
  1208. package/src/engine/physics/ecs/find_non_finite_physics_state.js +76 -76
  1209. package/src/engine/physics/fluid/FluidField.js +867 -867
  1210. package/src/engine/physics/fluid/FluidSimulator.js +832 -832
  1211. package/src/engine/physics/fluid/REVIEW_02_PLAN.md +243 -243
  1212. package/src/engine/physics/fluid/SliceVisualiser.js +190 -190
  1213. package/src/engine/physics/fluid/ecs/FluidComponent.js +239 -239
  1214. package/src/engine/physics/fluid/ecs/FluidEffectorsComponent.js +89 -89
  1215. package/src/engine/physics/fluid/ecs/FluidObstacle.js +97 -97
  1216. package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
  1217. package/src/engine/physics/fluid/ecs/FluidObstacleSystem.js +348 -348
  1218. package/src/engine/physics/fluid/ecs/FluidSystem.js +142 -142
  1219. package/src/engine/physics/fluid/ecs/FluidWorkerCore.js +123 -123
  1220. package/src/engine/physics/fluid/ecs/WorkerFluidSystem.js +395 -395
  1221. package/src/engine/physics/fluid/ecs/fluid.worker.js +12 -12
  1222. package/src/engine/physics/fluid/ecs/fluid_build_world_to_grid.js +32 -32
  1223. package/src/engine/physics/fluid/ecs/fluid_gather_visible_effectors.js +47 -47
  1224. package/src/engine/physics/fluid/ecs/fluid_reanchor_field.js +85 -85
  1225. package/src/engine/physics/fluid/ecs/fluid_sync_effectors_from_transform.js +16 -16
  1226. package/src/engine/physics/fluid/ecs/fluid_worker_protocol.js +111 -111
  1227. package/src/engine/physics/fluid/ecs/makeFluidWorker.js +18 -18
  1228. package/src/engine/physics/fluid/effector/AbstractFluidEffector.js +81 -81
  1229. package/src/engine/physics/fluid/effector/GlobalFluidEffector.js +202 -202
  1230. package/src/engine/physics/fluid/effector/ImpulseFluidEffector.js +257 -257
  1231. package/src/engine/physics/fluid/effector/WakeFluidEffector.js +405 -405
  1232. package/src/engine/physics/fluid/prototype.js +126 -126
  1233. package/src/engine/physics/fluid/solver/v3_grid_advect_maccormack_scalar.js +143 -143
  1234. package/src/engine/physics/fluid/solver/v3_grid_advect_maccormack_velocity.js +162 -162
  1235. package/src/engine/physics/fluid/solver/v3_grid_advect_sl_velocity.js +107 -107
  1236. package/src/engine/physics/fluid/solver/v3_grid_apply_vorticity_confinement.js +131 -131
  1237. package/src/engine/physics/fluid/solver/v3_grid_compute_solid_neighbour_mask.js +90 -90
  1238. package/src/engine/physics/fluid/solver/v3_grid_limit8_at_indices.js +38 -38
  1239. package/src/engine/physics/fluid/solver/v3_grid_patch_edges_constant.js +77 -77
  1240. package/src/engine/physics/fluid/solver/v3_grid_patch_edges_uniform.js +113 -113
  1241. package/src/engine/physics/fluid/solver/v3_grid_sample_scalar_masked.js +92 -92
  1242. package/src/engine/physics/fluid/solver/v3_grid_shift_in_place.js +107 -107
  1243. package/src/engine/physics/fluid/solver/v3_grid_solve_pressure.js +135 -135
  1244. package/src/engine/physics/fluid/solver/v3_grid_solve_pressure_pcg.js +511 -511
  1245. package/src/engine/physics/fluid/solver/v3_grid_subtract_pressure_gradient.js +108 -108
  1246. package/src/engine/physics/fluid/solver/v3_mac_advect_maccormack_velocity.js +317 -317
  1247. package/src/engine/physics/fluid/solver/v3_mac_advect_scalar.js +236 -236
  1248. package/src/engine/physics/fluid/solver/v3_mac_advect_sl_velocity.js +217 -217
  1249. package/src/engine/physics/fluid/solver/v3_mac_apply_vorticity_confinement.js +174 -174
  1250. package/src/engine/physics/fluid/solver/v3_mac_clip_trace.js +95 -95
  1251. package/src/engine/physics/fluid/solver/v3_mac_compute_divergence.js +77 -77
  1252. package/src/engine/physics/fluid/solver/v3_mac_compute_face_solid.js +131 -131
  1253. package/src/engine/physics/fluid/solver/v3_mac_subtract_pressure_gradient.js +104 -104
  1254. package/src/engine/physics/inertia/world_inverse_inertia.js +160 -160
  1255. package/src/engine/physics/integration/integrate_position.js +97 -97
  1256. package/src/engine/physics/narrowphase/box_box_manifold.js +681 -681
  1257. package/src/engine/physics/narrowphase/box_triangle_contact.js +906 -906
  1258. package/src/engine/physics/narrowphase/capsule_triangle_contact.js +395 -395
  1259. package/src/engine/physics/narrowphase/compute_penetration.js +369 -369
  1260. package/src/engine/physics/narrowphase/decomposition/decompose_to_triangles.js +55 -55
  1261. package/src/engine/physics/narrowphase/decomposition/triangle_buffer_layout.js +37 -37
  1262. package/src/engine/physics/narrowphase/mesh_mesh_tet_manifold.js +117 -117
  1263. package/src/engine/physics/narrowphase/narrowphase_step.js +1738 -1738
  1264. package/src/engine/physics/narrowphase/reduce_manifold_contacts.js +74 -74
  1265. package/src/engine/physics/narrowphase/refine_ray_hit.d.ts +12 -11
  1266. package/src/engine/physics/narrowphase/refine_ray_hit.d.ts.map +1 -1
  1267. package/src/engine/physics/narrowphase/refine_ray_hit.js +228 -36
  1268. package/src/engine/physics/narrowphase/sphere_sphere_contact.js +52 -52
  1269. package/src/engine/physics/narrowphase/sphere_triangle_contact.js +138 -138
  1270. package/src/engine/physics/persistence/solver_caches.js +309 -309
  1271. package/src/engine/physics/queries/overlap_shape.js +187 -187
  1272. package/src/engine/physics/queries/raycast.d.ts +7 -4
  1273. package/src/engine/physics/queries/raycast.d.ts.map +1 -1
  1274. package/src/engine/physics/queries/raycast.js +11 -5
  1275. package/src/engine/physics/queries/shape_cast.js +417 -417
  1276. package/src/engine/physics/solver/apply_impulse_to_body.js +86 -86
  1277. package/src/engine/physics/solver/friction_cone.js +37 -37
  1278. package/src/engine/physics/solver/solve_contacts.js +1 -1
  1279. package/src/engine/platform/WebEnginePlatform.d.ts.map +1 -1
  1280. package/src/engine/platform/WebEnginePlatform.js +1 -2
  1281. package/src/engine/scene/SerializedScene.d.ts +2 -2
  1282. package/src/engine/scene/SerializedScene.d.ts.map +1 -1
  1283. package/src/engine/scene/transitionToScene.js +121 -121
  1284. package/src/engine/simulation/Ticker.d.ts.map +1 -1
  1285. package/src/engine/simulation/Ticker.js +33 -0
  1286. package/src/engine/sound/ecs/audio/LiveEmitterSet.js +345 -345
  1287. package/src/engine/sound/ecs/audio/SpatialAudioIndex.js +140 -140
  1288. package/src/engine/sound/simulation/AcousticSimulator.js +646 -646
  1289. package/src/engine/sound/simulation/IMPLEMENTATION_PLAN.md +432 -432
  1290. package/src/engine/sound/simulation/PROBE_PLACEMENT.md +250 -250
  1291. package/src/engine/sound/simulation/PROBE_TRANSFER_RESEARCH.md +322 -322
  1292. package/src/engine/sound/simulation/README.md +277 -277
  1293. package/src/engine/sound/simulation/REFLECTION_IR_PLAN.md +261 -261
  1294. package/src/engine/sound/simulation/VISIBILITY_GRAPH_PLAN.md +121 -121
  1295. package/src/engine/sound/simulation/configureAcousticSimulation.js +48 -48
  1296. package/src/engine/sound/simulation/core/AcousticMedium.js +113 -113
  1297. package/src/engine/sound/simulation/core/AcousticMediumSerializationAdapter.js +27 -27
  1298. package/src/engine/sound/simulation/core/AcousticOccluderIndex.js +312 -312
  1299. package/src/engine/sound/simulation/core/AcousticRegionIndex.js +159 -159
  1300. package/src/engine/sound/simulation/core/AcousticSolution.js +90 -90
  1301. package/src/engine/sound/simulation/core/AcousticSourceState.js +109 -109
  1302. package/src/engine/sound/simulation/core/AcousticVolumeRegion.js +73 -73
  1303. package/src/engine/sound/simulation/core/OcclusionSolver.js +112 -112
  1304. package/src/engine/sound/simulation/core/RayHit.js +50 -50
  1305. package/src/engine/sound/simulation/core/VolumeField.js +149 -149
  1306. package/src/engine/sound/simulation/definition/AcousticDirectivity.js +114 -114
  1307. package/src/engine/sound/simulation/definition/AcousticDirectivitySerializationAdapter.js +30 -30
  1308. package/src/engine/sound/simulation/definition/AcousticMaterial.js +122 -122
  1309. package/src/engine/sound/simulation/definition/AcousticMaterialSerializationAdapter.js +32 -32
  1310. package/src/engine/sound/simulation/ecs/AcousticBody.js +48 -48
  1311. package/src/engine/sound/simulation/ecs/AcousticBodySerializationAdapter.js +34 -34
  1312. package/src/engine/sound/simulation/ecs/AcousticProbeFieldSystem.js +64 -64
  1313. package/src/engine/sound/simulation/ecs/AcousticSimulationSystem.js +75 -75
  1314. package/src/engine/sound/simulation/ecs/AcousticVolume.js +74 -74
  1315. package/src/engine/sound/simulation/ecs/AcousticVolumeSerializationAdapter.js +37 -37
  1316. package/src/engine/sound/simulation/ecs/AcousticVolumeSystem.js +66 -66
  1317. package/src/engine/sound/simulation/probe/AcousticProbeField.js +578 -578
  1318. package/src/engine/sound/simulation/probe/AcousticProbeFieldSerializationAdapter.js +60 -60
  1319. package/src/engine/sound/simulation/probe/ProbeFieldPathingSolution.js +64 -64
  1320. package/src/engine/sound/simulation/probe/ProbeVisibilityRecheck.js +132 -132
  1321. package/src/engine/sound/simulation/probe/acoustic_probe_transfer.js +103 -103
  1322. package/src/engine/sound/simulation/probe/acoustic_trace_energy.js +136 -136
  1323. package/src/engine/sound/simulation/probe/bakeProbeField.js +169 -169
  1324. package/src/engine/sound/simulation/probe/bakeProbeReflectors.js +110 -110
  1325. package/src/engine/sound/simulation/probe/bakeReverbBands.js +110 -110
  1326. package/src/engine/sound/simulation/probe/bakeVisibility.js +148 -148
  1327. package/src/engine/sound/simulation/probe/echogram_band_rt60.js +83 -83
  1328. package/src/engine/sound/simulation/probe/probe_delaunay_edges.js +215 -215
  1329. package/src/engine/sound/simulation/probe/probe_densify_portals.js +140 -140
  1330. package/src/engine/sound/simulation/probe/probe_detect_portals.js +196 -196
  1331. package/src/engine/sound/simulation/probe/probe_edge_key.js +38 -38
  1332. package/src/engine/sound/simulation/probe/probe_edge_visible.js +41 -41
  1333. package/src/engine/sound/simulation/probe/probe_place_sdf_cover.js +82 -82
  1334. package/src/engine/sound/simulation/probe/probe_refine_connectivity.js +181 -181
  1335. package/src/engine/sound/simulation/probe/probe_sdf_grid.js +171 -171
  1336. package/src/engine/sound/simulation/probe/probe_visibility_augment.js +146 -146
  1337. package/src/engine/sound/simulation/probe/probe_visibility_bridge_components.js +167 -167
  1338. package/src/engine/sound/simulation/render/FoaProbeReverbRenderer.js +354 -354
  1339. package/src/engine/sound/simulation/render/ProbeReverbRenderer.js +231 -231
  1340. package/src/engine/sound/simulation/render/foaReverbImpulseResponse.js +105 -105
  1341. package/src/engine/sound/simulation/render/reverbImpulseResponse.js +66 -66
  1342. package/src/engine/sound/simulation/render/reverb_band_tails.js +93 -93
  1343. package/src/engine/sound/simulation/serialization/populateAcousticSerializationRegistry.js +25 -25
  1344. package/src/engine/sound/sopra/README.md +643 -643
  1345. package/src/engine/sound/sopra/SopraEngine.js +432 -432
  1346. package/src/engine/sound/sopra/asset/AssetManagerBufferProvider.js +71 -71
  1347. package/src/engine/sound/sopra/asset/BufferProvider.js +29 -29
  1348. package/src/engine/sound/sopra/asset/StubBufferProvider.js +58 -58
  1349. package/src/engine/sound/sopra/definition/BusDefinition.js +142 -142
  1350. package/src/engine/sound/sopra/definition/BusDefinitionSerializationAdapter.js +54 -54
  1351. package/src/engine/sound/sopra/definition/DuckingRule.js +106 -106
  1352. package/src/engine/sound/sopra/definition/DuckingRuleSerializationAdapter.js +31 -31
  1353. package/src/engine/sound/sopra/definition/EventDescription.js +262 -262
  1354. package/src/engine/sound/sopra/definition/EventDescriptionSerializationAdapter.js +55 -55
  1355. package/src/engine/sound/sopra/definition/MixerSnapshot.js +83 -83
  1356. package/src/engine/sound/sopra/definition/MixerSnapshotSerializationAdapter.js +39 -39
  1357. package/src/engine/sound/sopra/definition/ParameterDefinition.js +117 -117
  1358. package/src/engine/sound/sopra/definition/ParameterDefinitionSerializationAdapter.js +31 -31
  1359. package/src/engine/sound/sopra/definition/VoiceStealMode.js +18 -18
  1360. package/src/engine/sound/sopra/definition/clip/AbstractAudioClip.js +109 -109
  1361. package/src/engine/sound/sopra/definition/clip/BlendContainerAudioClip.js +185 -185
  1362. package/src/engine/sound/sopra/definition/clip/BlendContainerAudioClipSerializationAdapter.js +59 -59
  1363. package/src/engine/sound/sopra/definition/clip/ContainerAudioClip.js +128 -128
  1364. package/src/engine/sound/sopra/definition/clip/RandomContainerAudioClip.js +226 -226
  1365. package/src/engine/sound/sopra/definition/clip/RandomContainerAudioClipSerializationAdapter.js +54 -54
  1366. package/src/engine/sound/sopra/definition/clip/SampleAudioClip.js +191 -191
  1367. package/src/engine/sound/sopra/definition/clip/SampleAudioClipSerializationAdapter.js +39 -39
  1368. package/src/engine/sound/sopra/definition/clip/SequenceContainerAudioClip.js +79 -79
  1369. package/src/engine/sound/sopra/definition/clip/SequenceContainerAudioClipSerializationAdapter.js +42 -42
  1370. package/src/engine/sound/sopra/definition/clip/SilenceAudioClip.js +77 -77
  1371. package/src/engine/sound/sopra/definition/clip/SilenceAudioClipSerializationAdapter.js +27 -27
  1372. package/src/engine/sound/sopra/definition/clip/SwitchContainerAudioClip.d.ts +5 -0
  1373. package/src/engine/sound/sopra/definition/clip/SwitchContainerAudioClip.d.ts.map +1 -1
  1374. package/src/engine/sound/sopra/definition/clip/SwitchContainerAudioClip.js +125 -125
  1375. package/src/engine/sound/sopra/definition/clip/SwitchContainerAudioClipSerializationAdapter.js +41 -41
  1376. package/src/engine/sound/sopra/definition/effect/AbstractAudioEffect.js +24 -24
  1377. package/src/engine/sound/sopra/definition/effect/CompressorEffect.js +120 -120
  1378. package/src/engine/sound/sopra/definition/effect/CompressorEffectSerializationAdapter.js +31 -31
  1379. package/src/engine/sound/sopra/definition/effect/EqEffect.js +128 -128
  1380. package/src/engine/sound/sopra/definition/effect/EqEffectSerializationAdapter.js +29 -29
  1381. package/src/engine/sound/sopra/definition/effect/ReverbEffect.js +113 -113
  1382. package/src/engine/sound/sopra/definition/effect/ReverbEffectSerializationAdapter.js +25 -25
  1383. package/src/engine/sound/sopra/runtime/BusGraph.js +231 -231
  1384. package/src/engine/sound/sopra/runtime/ParameterStore.js +98 -98
  1385. package/src/engine/sound/sopra/runtime/SopraPlaybackContext.js +68 -68
  1386. package/src/engine/sound/sopra/runtime/Voice.js +145 -145
  1387. package/src/engine/sound/sopra/runtime/VoiceManager.js +136 -136
  1388. package/src/engine/sound/sopra/runtime/VoicePool.js +17 -17
  1389. package/src/engine/sound/sopra/serialization/populateSopraSerializationRegistry.js +42 -42
  1390. package/src/engine/sound/sopra/serialization/sopraJSON.js +99 -99
  1391. package/src/engine/sound/sopra/serialization/sopraSerializationHarness.js +49 -49
  1392. package/src/engine/sound/sopra/util/MockAudioContext.js +224 -224
  1393. package/src/engine/sound/sopra/util/fadeOutAndStop.js +60 -60
  1394. package/src/engine/ui/DraggableAspect.js +115 -115
  1395. package/src/engine/ui/apply_pointer_tilt_3d.js +50 -50
  1396. package/src/generation/COORDINATES.md +54 -54
  1397. package/src/generation/GridGenerationResource.js +24 -24
  1398. package/src/generation/GridTaskGroup.js +214 -214
  1399. package/src/generation/REVIEW_01_ACTION_PLAN.md +628 -628
  1400. package/src/generation/automata/CaveGeneratorCellularAutomata.js +79 -79
  1401. package/src/generation/automata/CellularAutomata.js +22 -22
  1402. package/src/generation/compute_writes_union.js +25 -25
  1403. package/src/generation/filtering/CellFilter.js +117 -117
  1404. package/src/generation/filtering/core/CellFilterBinaryOperation.js +37 -37
  1405. package/src/generation/filtering/core/CellFilterOperationTertiary.js +43 -43
  1406. package/src/generation/filtering/core/CellFilterUnaryOperation.js +29 -29
  1407. package/src/generation/filtering/numeric/process/computeCellFilterSobel.js +36 -36
  1408. package/src/generation/filtering/numeric/process/computeFilterSurfaceNormal.js +42 -42
  1409. package/src/generation/filtering/numeric/util/populateSampler2DFromCellFilter.js +18 -18
  1410. package/src/generation/filtering/numeric/util/write_cell_filter_to_sampler2d.js +47 -47
  1411. package/src/generation/filtering/util/cell_filter_weights_pick.js +54 -54
  1412. package/src/generation/grid/GridData.js +233 -233
  1413. package/src/generation/grid/coords/grid_to_texel.js +10 -10
  1414. package/src/generation/grid/coords/texel_to_grid.js +10 -10
  1415. package/src/generation/grid/generation/GridTaskApplyActionToCells.js +90 -90
  1416. package/src/generation/grid/generation/GridTaskDensityMarkerDistribution.js +388 -388
  1417. package/src/generation/grid/generation/GridTaskExecuteRuleTimes.js +127 -127
  1418. package/src/generation/grid/generation/GridTaskSequence.js +58 -58
  1419. package/src/generation/grid/generation/NoopGridTaskGenerator.js +12 -12
  1420. package/src/generation/grid/generation/discrete/GridTaskActionRuleSet.js +48 -48
  1421. package/src/generation/grid/generation/discrete/GridTaskCellularAutomata.js +146 -146
  1422. package/src/generation/grid/generation/discrete/GridTaskConnectRooms.js +540 -540
  1423. package/src/generation/grid/generation/discrete/layer/GridTaskBuildSourceDistanceMap.js +222 -222
  1424. package/src/generation/grid/generation/grid/GridTaskAddNodesFixed.js +44 -44
  1425. package/src/generation/grid/generation/road/GridTaskGenerateRoads.js +614 -614
  1426. package/src/generation/markers/GridCellActionPlaceMarker.js +244 -244
  1427. package/src/generation/markers/GridCellActionPlaceMarkerGroup.js +86 -86
  1428. package/src/generation/markers/actions/terrain/MarkerNodeActionPaintTerrain.js +266 -266
  1429. package/src/generation/markers/emitter/MarkerNodeEmitterGridCellAction.js +49 -49
  1430. package/src/generation/placement/GridCellActionTransformNearbyMarkers.js +120 -120
  1431. package/src/generation/placement/action/GridCellAction.js +45 -45
  1432. package/src/generation/placement/action/GridCellActionPlaceTags.js +140 -140
  1433. package/src/generation/placement/action/GridCellActionWriteFilterToLayer.js +89 -89
  1434. package/src/generation/placement/action/random/CellActionSelectRandom.js +69 -69
  1435. package/src/generation/placement/action/random/weighted/CellActionSelectWeightedRandom.js +91 -91
  1436. package/src/generation/placement/action/util/GridCellActionSequence.js +61 -61
  1437. package/src/generation/placement/action/util/GridCellDisplacedAction.js +61 -61
  1438. package/src/generation/rules/cell/CellMatcherRemovalPreservesConnectivity.js +183 -183
  1439. package/src/generation/theme/ThemeEngine.js +666 -666
  1440. package/src/shade/RENDERER_CONTRACT.md +568 -568
  1441. package/src/shade/descriptor/texture/format/gpu_texture_format_info.js +267 -267
  1442. package/src/shade/device/ShadeDeviceFailure.js +104 -104
  1443. package/src/shade/device/ShadeDeviceFailureReason.js +41 -41
  1444. package/src/shade/device/mock/IMPLEMENTATION_PLAN.md +255 -255
  1445. package/src/shade/device/mock/REVIEW_2026_08_22.md +527 -527
  1446. package/src/shade/device/mock/SoftwareGPUBindGroup.js +23 -23
  1447. package/src/shade/device/mock/SoftwareGPUBindGroupLayout.js +22 -22
  1448. package/src/shade/device/mock/SoftwareGPUError.js +63 -63
  1449. package/src/shade/device/mock/SoftwareGPUPipeline.js +75 -75
  1450. package/src/shade/device/mock/SoftwareGPUQuerySet.js +113 -113
  1451. package/src/shade/device/mock/SoftwareGPUSampler.js +30 -30
  1452. package/src/shade/device/mock/SoftwareGPUShaderModule.js +32 -32
  1453. package/src/shade/device/mock/SoftwareGPUTextureView.js +22 -22
  1454. package/src/shade/device/mock/SoftwareGPUUncapturedErrorEvent.js +23 -23
  1455. package/src/shade/device/mock/normalize_dynamic_offsets.js +26 -26
  1456. package/src/shade/device/mock/texture_copy.js +287 -287
  1457. package/src/shade/device/timing/GPUTimer.js +285 -285
  1458. package/src/shade/device/timing/GPUTimerArray.js +205 -205
  1459. package/src/shade/playground/add_random_lights.js +49 -49
  1460. package/src/shade/playground/add_random_meshes.js +83 -83
  1461. package/src/shade/playground/animation_prototype.js +508 -508
  1462. package/src/shade/playground/animation_prototype_skinning.js +647 -647
  1463. package/src/shade/playground/animation_prototype_stress.js +765 -765
  1464. package/src/shade/playground/enable_picker.js +59 -59
  1465. package/src/shade/playground/gltf_skinned_prototype.js +560 -560
  1466. package/src/shade/playground/gltf_skinned_stress_prototype.js +387 -387
  1467. package/src/shade/playground/gltf_viewer.js +282 -282
  1468. package/src/shade/playground/load_default_environment.js +19 -19
  1469. package/src/shade/playground/main.js +2727 -2727
  1470. package/src/shade/playground/make_animated_instances.js +117 -117
  1471. package/src/shade/playground/prototype_virtual_texture.js +274 -274
  1472. package/src/shade/playground/prototype_volumetrics_01.js +206 -206
  1473. package/src/shade/playground/sample.js +234 -234
  1474. package/src/shade/playground/sample_load_gltf.js +102 -102
  1475. package/src/shade/playground/spread_node3d_grid.js +19 -19
  1476. package/src/shade/renderer/Renderer.js +2436 -2436
  1477. package/src/shade/renderer/ShadeIndirectLightingMode.js +14 -14
  1478. package/src/shade/renderer/animation/ShadeAnimationChannel.js +414 -414
  1479. package/src/shade/renderer/animation/compute_skinned_mesh_clip_bounding_sphere.js +531 -531
  1480. package/src/shade/renderer/animation/pose/PosePlayback.js +55 -55
  1481. package/src/shade/renderer/animation/pose/pose_evaluate_local.js +179 -179
  1482. package/src/shade/renderer/animation/pose/pose_evaluate_world.js +76 -76
  1483. package/src/shade/renderer/animation/skinning/GPUMeshSkinningContext.js +1024 -1024
  1484. package/src/shade/renderer/animation/skinning/SKINNING_BINDING_STRUCT.js +79 -79
  1485. package/src/shade/renderer/animation/skinning/chunk_skin_blend_mesh_local.js +56 -56
  1486. package/src/shade/renderer/binding/BindGroupManager.js +282 -282
  1487. package/src/shade/renderer/binding/adapt_cache_capacity.js +25 -25
  1488. package/src/shade/renderer/buffer/GPUBufferAllocator.js +116 -116
  1489. package/src/shade/renderer/buffer/buffer_pool_ops.js +123 -123
  1490. package/src/shade/renderer/buffer/table/GPU_DATABASE_PAGE_SIZE.js +9 -9
  1491. package/src/shade/renderer/buffer/table/GPU_DATABASE_UPLOAD_BUFFER_LIMIT.js +8 -8
  1492. package/src/shade/renderer/buffer/table/PageBufferPool.js +71 -71
  1493. package/src/shade/renderer/buffer/table/PageSlotAllocator.js +95 -95
  1494. package/src/shade/renderer/camera/Camera.js +281 -281
  1495. package/src/shade/renderer/camera/GPUCameraContext.js +233 -233
  1496. package/src/shade/renderer/camera/orbital/README.md +84 -84
  1497. package/src/shade/renderer/deferred/shader_composite_volumetrics.js +75 -75
  1498. package/src/shade/renderer/dynamic/DYNAMIC_MESH_VERTEX.js +25 -25
  1499. package/src/shade/renderer/dynamic/GPUDynamicMeshRenderer.js +342 -342
  1500. package/src/shade/renderer/dynamic/GPUDynamicMeshResidency.js +167 -167
  1501. package/src/shade/renderer/dynamic/shader_dynamic_mesh.js +170 -170
  1502. package/src/shade/renderer/extension/FrameContext.js +263 -263
  1503. package/src/shade/renderer/extension/FramePhase.js +104 -104
  1504. package/src/shade/renderer/extension/FrameRecord.js +126 -126
  1505. package/src/shade/renderer/extension/GBufferTextures.js +83 -83
  1506. package/src/shade/renderer/extension/PresentTarget.js +34 -34
  1507. package/src/shade/renderer/extension/RENDER_EXTENSION_DESIGN.md +918 -918
  1508. package/src/shade/renderer/extension/RenderExtension.js +69 -69
  1509. package/src/shade/renderer/extension/RenderExtensionRegistry.js +319 -319
  1510. package/src/shade/renderer/extension/SceneColor.js +40 -40
  1511. package/src/shade/renderer/extension/ViewTextures.js +78 -78
  1512. package/src/shade/renderer/fow/GPUFogOfWarRenderer.js +182 -182
  1513. package/src/shade/renderer/geometry/Geometry.js +608 -608
  1514. package/src/shade/renderer/geometry/geometry_build_from_meshlet_geometry.js +342 -342
  1515. package/src/shade/renderer/geometry/meshlet_geometry_transfer.js +41 -41
  1516. package/src/shade/renderer/geometry/primitives/make_box_geometry.js +153 -153
  1517. package/src/shade/renderer/geometry/primitives/make_cylinder_geometry.js +240 -240
  1518. package/src/shade/renderer/geometry/primitives/make_plane_geometry.js +145 -145
  1519. package/src/shade/renderer/geometry/primitives/make_polyhedron_geometry.js +327 -327
  1520. package/src/shade/renderer/geometry/primitives/make_torus_geometry.js +107 -107
  1521. package/src/shade/renderer/geometry/primitives/make_torus_knot_geometry.js +165 -165
  1522. package/src/shade/renderer/geometry/virtual/VGEO_FORMAT.md +607 -607
  1523. package/src/shade/renderer/geometry/virtual/build/VGeoBuildOptions.js +66 -66
  1524. package/src/shade/renderer/geometry/virtual/build/VGeoBuildResult.js +32 -32
  1525. package/src/shade/renderer/geometry/virtual/build/VGeoFaceGraph.js +103 -103
  1526. package/src/shade/renderer/geometry/virtual/build/VGeoGatheredFaces.js +25 -25
  1527. package/src/shade/renderer/geometry/virtual/build/VGeoLevel.js +33 -33
  1528. package/src/shade/renderer/geometry/virtual/build/VGeoLevelOptions.js +62 -62
  1529. package/src/shade/renderer/geometry/virtual/build/VGeoLevelSummary.js +49 -49
  1530. package/src/shade/renderer/geometry/virtual/build/VGeoSubmesh.js +20 -20
  1531. package/src/shade/renderer/geometry/virtual/build/VirtualGeometryMesh.js +214 -214
  1532. package/src/shade/renderer/geometry/virtual/build/gltf/GltfByteSource.js +122 -122
  1533. package/src/shade/renderer/geometry/virtual/build/gltf/GltfCollectReport.js +29 -29
  1534. package/src/shade/renderer/geometry/virtual/build/gltf/GltfDocument.js +210 -210
  1535. package/src/shade/renderer/geometry/virtual/build/gltf/GltfGeometry.js +48 -48
  1536. package/src/shade/renderer/geometry/virtual/build/gltf/GltfGeometryInstance.js +25 -25
  1537. package/src/shade/renderer/geometry/virtual/build/gltf/GltfGeometrySelection.js +28 -28
  1538. package/src/shade/renderer/geometry/virtual/build/gltf/gltf_collect_geometries.js +296 -296
  1539. package/src/shade/renderer/geometry/virtual/build/gltf/gltf_open_document.js +166 -166
  1540. package/src/shade/renderer/geometry/virtual/build/gltf/gltf_read_geometry.js +199 -199
  1541. package/src/shade/renderer/geometry/virtual/build/vgeo_assemble_pages.js +173 -173
  1542. package/src/shade/renderer/geometry/virtual/build/vgeo_bounding_sphere.js +28 -28
  1543. package/src/shade/renderer/geometry/virtual/build/vgeo_build.js +200 -200
  1544. package/src/shade/renderer/geometry/virtual/build/vgeo_build_levels.js +1786 -1786
  1545. package/src/shade/renderer/geometry/virtual/build/vgeo_build_page_nodes.js +157 -157
  1546. package/src/shade/renderer/geometry/virtual/build/vgeo_build_root_group.js +26 -26
  1547. package/src/shade/renderer/geometry/virtual/build/vgeo_compute_vertex_normals.js +75 -75
  1548. package/src/shade/renderer/geometry/virtual/build/vgeo_compute_vertex_tangents.js +143 -143
  1549. package/src/shade/renderer/geometry/virtual/build/vgeo_containing_sphere.js +44 -44
  1550. package/src/shade/renderer/geometry/virtual/build/vgeo_extract_submesh.js +41 -41
  1551. package/src/shade/renderer/geometry/virtual/build/vgeo_gather_faces.js +71 -71
  1552. package/src/shade/renderer/geometry/virtual/build/vgeo_graph_components.js +123 -123
  1553. package/src/shade/renderer/geometry/virtual/build/vgeo_narrow_indices.js +26 -26
  1554. package/src/shade/renderer/geometry/virtual/build/vgeo_normalize_source.js +112 -112
  1555. package/src/shade/renderer/geometry/virtual/build/vgeo_partition_graph.js +56 -56
  1556. package/src/shade/renderer/geometry/virtual/build/vgeo_sphere_inflate_to_contain.js +70 -70
  1557. package/src/shade/renderer/geometry/virtual/build/vgeo_split_face_set.js +187 -187
  1558. package/src/shade/renderer/geometry/virtual/build/vgeo_split_face_set_packed.js +207 -207
  1559. package/src/shade/renderer/geometry/virtual/format/VGEO_DEFECT.js +18 -18
  1560. package/src/shade/renderer/geometry/virtual/format/VGeoDefect.js +38 -38
  1561. package/src/shade/renderer/geometry/virtual/format/VGeoWriteOptions.js +64 -64
  1562. package/src/shade/renderer/geometry/virtual/format/attribute/VGEO_ATTRIBUTE.js +13 -13
  1563. package/src/shade/renderer/geometry/virtual/format/attribute/VGEO_ATTRIBUTES.js +50 -50
  1564. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_attribute_allocate.js +28 -28
  1565. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_attribute_mask.js +23 -23
  1566. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_attributes_read.js +31 -31
  1567. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_copy_vertex.js +32 -32
  1568. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_declare.js +46 -46
  1569. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_like.js +19 -19
  1570. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_test_fixtures.js +27 -27
  1571. package/src/shade/renderer/geometry/virtual/format/checksum/vgeo_asset_id_preimage.js +62 -62
  1572. package/src/shade/renderer/geometry/virtual/format/checksum/vgeo_compute_asset_id.js +13 -13
  1573. package/src/shade/renderer/geometry/virtual/format/checksum/vgeo_compute_directory_block_checksum.js +41 -41
  1574. package/src/shade/renderer/geometry/virtual/format/checksum/vgeo_compute_frame_checksum.js +41 -41
  1575. package/src/shade/renderer/geometry/virtual/format/checksum/vgeo_compute_header_checksum.js +25 -25
  1576. package/src/shade/renderer/geometry/virtual/format/cluster/VGEO_CLUSTER_OFFSET.js +20 -20
  1577. package/src/shade/renderer/geometry/virtual/format/cluster/VGEO_CLUSTER_RECORD_SIZE.js +5 -5
  1578. package/src/shade/renderer/geometry/virtual/format/cluster/VGEO_MAX_CHILD_REF.js +5 -5
  1579. package/src/shade/renderer/geometry/virtual/format/cluster/VGEO_MAX_CLUSTER_TRIANGLE_COUNT.js +5 -5
  1580. package/src/shade/renderer/geometry/virtual/format/cluster/VGEO_MAX_CLUSTER_VERTEX_COUNT.js +5 -5
  1581. package/src/shade/renderer/geometry/virtual/format/cluster/VGEO_NO_CHILD.js +5 -5
  1582. package/src/shade/renderer/geometry/virtual/format/cluster/VGEO_NO_GROUP.js +5 -5
  1583. package/src/shade/renderer/geometry/virtual/format/cluster/VGEO_SAME_PAGE.js +6 -6
  1584. package/src/shade/renderer/geometry/virtual/format/dag/VirtualGeometryCluster.js +81 -81
  1585. package/src/shade/renderer/geometry/virtual/format/dag/VirtualGeometryGroup.js +37 -37
  1586. package/src/shade/renderer/geometry/virtual/format/dag/VirtualGeometryPageNode.js +55 -55
  1587. package/src/shade/renderer/geometry/virtual/format/directory/VGEO_DIRECTORY_BLOCK_RECORDS.js +5 -5
  1588. package/src/shade/renderer/geometry/virtual/format/directory/VGEO_DIRECTORY_FLAG_ROOT_PAGE.js +5 -5
  1589. package/src/shade/renderer/geometry/virtual/format/directory/VGEO_DIRECTORY_RECORD_SIZE.js +5 -5
  1590. package/src/shade/renderer/geometry/virtual/format/directory/vgeo_directory_block_count.js +12 -12
  1591. package/src/shade/renderer/geometry/virtual/format/frame/VGEO_CHILD_OFFSET.js +11 -11
  1592. package/src/shade/renderer/geometry/virtual/format/frame/VGEO_CHILD_TABLE_ENTRY_SIZE.js +5 -5
  1593. package/src/shade/renderer/geometry/virtual/format/frame/VGEO_CODEC_LZ4.js +11 -11
  1594. package/src/shade/renderer/geometry/virtual/format/frame/VGEO_CODEC_RAW.js +5 -5
  1595. package/src/shade/renderer/geometry/virtual/format/frame/VGEO_FRAME_ALIGNMENT.js +5 -5
  1596. package/src/shade/renderer/geometry/virtual/format/frame/VGEO_FRAME_HEADER_SIZE.js +5 -5
  1597. package/src/shade/renderer/geometry/virtual/format/frame/VGEO_FRAME_OFFSET.js +13 -13
  1598. package/src/shade/renderer/geometry/virtual/format/frame/VGEO_PAGE_MAGIC.js +5 -5
  1599. package/src/shade/renderer/geometry/virtual/format/frame/VGeoFrameBlob.js +21 -21
  1600. package/src/shade/renderer/geometry/virtual/format/frame/VGeoFrameExtent.js +59 -59
  1601. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_codec_name.js +27 -27
  1602. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_decode_frame_blob.js +84 -84
  1603. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_encode_frame_blob.js +56 -56
  1604. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_frame_decode_bound.js +35 -35
  1605. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_scan_frames.js +74 -74
  1606. package/src/shade/renderer/geometry/virtual/format/header/VGEO_FORMAT_VERSION.js +6 -6
  1607. package/src/shade/renderer/geometry/virtual/format/header/VGEO_HASH_ALGO_XXH3.js +5 -5
  1608. package/src/shade/renderer/geometry/virtual/format/header/VGEO_HEADER_OFFSET.js +31 -31
  1609. package/src/shade/renderer/geometry/virtual/format/header/VGEO_HEADER_SIZE.js +5 -5
  1610. package/src/shade/renderer/geometry/virtual/format/header/VGEO_LEVEL_OFFSET.js +20 -20
  1611. package/src/shade/renderer/geometry/virtual/format/header/VGEO_LEVEL_RECORD_SIZE.js +9 -9
  1612. package/src/shade/renderer/geometry/virtual/format/header/VGEO_MAGIC.js +5 -5
  1613. package/src/shade/renderer/geometry/virtual/format/header/VGEO_MIN_READER_VERSION.js +5 -5
  1614. package/src/shade/renderer/geometry/virtual/format/header/VGEO_PAYLOAD_ENCODING_SHADE_MESHLET_V1.js +5 -5
  1615. package/src/shade/renderer/geometry/virtual/format/header/VGeoLevelRecord.js +41 -41
  1616. package/src/shade/renderer/geometry/virtual/format/page/VGEO_GROUP_RECORD_SIZE.js +5 -5
  1617. package/src/shade/renderer/geometry/virtual/format/page/VGEO_MAX_GROUP_CLUSTER_COUNT.js +6 -6
  1618. package/src/shade/renderer/geometry/virtual/format/page/VGEO_METRIC_OFFSET.js +21 -21
  1619. package/src/shade/renderer/geometry/virtual/format/page/VGEO_METRIC_SIZE.js +5 -5
  1620. package/src/shade/renderer/geometry/virtual/format/page/VGEO_NODE_FANOUT.js +9 -9
  1621. package/src/shade/renderer/geometry/virtual/format/page/VGEO_NODE_FLAG_LEAF.js +5 -5
  1622. package/src/shade/renderer/geometry/virtual/format/page/VGEO_NODE_OFFSET.js +10 -10
  1623. package/src/shade/renderer/geometry/virtual/format/page/VGEO_NODE_RECORD_SIZE.js +5 -5
  1624. package/src/shade/renderer/geometry/virtual/format/page/VGEO_PAGE_HEADER_SIZE.js +5 -5
  1625. package/src/shade/renderer/geometry/virtual/format/page/VGEO_PAGE_OFFSET.js +16 -16
  1626. package/src/shade/renderer/geometry/virtual/format/payload/VGEO_ENCODING_FLAGS_MASK.js +6 -6
  1627. package/src/shade/renderer/geometry/virtual/format/payload/VGeoEncodedPayload.js +18 -18
  1628. package/src/shade/renderer/geometry/virtual/format/payload/vgeo_encode_cluster_payload.js +200 -200
  1629. package/src/shade/renderer/geometry/virtual/format/payload/vgeo_payload_attribute_offset.js +39 -39
  1630. package/src/shade/renderer/geometry/virtual/format/payload/vgeo_payload_size.js +20 -20
  1631. package/src/shade/renderer/geometry/virtual/format/prototypeVGEOFormatViewer.js +2063 -2063
  1632. package/src/shade/renderer/geometry/virtual/format/vgeo_validate_container.js +1622 -1622
  1633. package/src/shade/renderer/geometry/virtual/format/vgeo_write_container.js +485 -485
  1634. package/src/shade/renderer/gpu_primitive/sort/ffx/graph_radix_sort.js +115 -115
  1635. package/src/shade/renderer/gpu_primitive/sort/one_sweep/verify_radix_sort_one_sweep.js +110 -110
  1636. package/src/shade/renderer/light/environment/octahedral_resample_kernel.js +50 -50
  1637. package/src/shade/renderer/light/environment/octahedral_uv_to_direction.js +30 -30
  1638. package/src/shade/renderer/light/environment/resample_cube_to_octahedral.js +157 -157
  1639. package/src/shade/renderer/light/make_sunlight.js +35 -35
  1640. package/src/shade/renderer/light/model/io/light_record_point.js +39 -39
  1641. package/src/shade/renderer/loader/gltf/GLTF_PRIMITIVE_MODE.js +23 -23
  1642. package/src/shade/renderer/loader/gltf/MESHOPT_COMPRESSION_PLAN.md +793 -793
  1643. package/src/shade/renderer/loader/gltf/ext/GltfBufferViewExtension.js +54 -54
  1644. package/src/shade/renderer/loader/gltf/ext/GltfBufferViewExtensionSet.js +109 -109
  1645. package/src/shade/renderer/loader/gltf/ext/gltf_apply_buffer_view_extensions.js +69 -69
  1646. package/src/shade/renderer/loader/gltf/ext/gltf_buffer_view_extensions.js +22 -22
  1647. package/src/shade/renderer/loader/gltf/ext/gltf_geometry_extensions.js +39 -39
  1648. package/src/shade/renderer/loader/gltf/ext/meshopt/MeshoptBufferViewExtension.js +301 -301
  1649. package/src/shade/renderer/loader/gltf/gltf_component_type.js +223 -223
  1650. package/src/shade/renderer/loader/gltf/gltf_node_world_matrices.js +137 -137
  1651. package/src/shade/renderer/loader/gltf/gltf_parse_container.js +241 -241
  1652. package/src/shade/renderer/loader/gltf/gltf_read_accessor.js +294 -294
  1653. package/src/shade/renderer/loader/gltf/gltf_used_image_indices.js +49 -49
  1654. package/src/shade/renderer/loader/gltf/load_gltf.js +1253 -1253
  1655. package/src/shade/renderer/loader/gltf/tiny-gltf.js +646 -646
  1656. package/src/shade/renderer/loader/usd/UsdError.js +33 -33
  1657. package/src/shade/renderer/loader/usd/UsdExtensionRegistry.js +69 -69
  1658. package/src/shade/renderer/loader/usd/load_usd.js +226 -226
  1659. package/src/shade/renderer/loader/usd/parse_usda.js +931 -931
  1660. package/src/shade/renderer/loader/usd/unpack_usdz.js +106 -106
  1661. package/src/shade/renderer/loader/usd/usd_build_scene.js +658 -658
  1662. package/src/shade/renderer/loader/usd/usd_compose_transform.js +258 -258
  1663. package/src/shade/renderer/loader/usd/usd_decode_image.js +384 -384
  1664. package/src/shade/renderer/loader/usd/usd_lz4.js +182 -182
  1665. package/src/shade/renderer/loader/usd/usd_triangulate.js +159 -159
  1666. package/src/shade/renderer/material/ShadeMaterial.d.ts +2 -2
  1667. package/src/shade/renderer/material/ShadeMaterial.js +2 -2
  1668. package/src/shade/renderer/material/standard/fragment_gbuffer.js +334 -334
  1669. package/src/shade/renderer/material/standard/fragment_gbuffer_vt.js +169 -169
  1670. package/src/shade/renderer/material/standard/material_gbuffer_vertex.js +45 -45
  1671. package/src/shade/renderer/material/standard_material_to_struct.js +23 -23
  1672. package/src/shade/renderer/particles/prototypeParticleSystem.js +450 -450
  1673. package/src/shade/renderer/particles/runtime/spawn_request_encoding.js +52 -52
  1674. package/src/shade/renderer/pool/TransientResourcePool.js +392 -392
  1675. package/src/shade/renderer/postprocess/bloom/bloom_chain_resolution.js +29 -29
  1676. package/src/shade/renderer/postprocess/bloom/graph_bloom_downsample.js +109 -109
  1677. package/src/shade/renderer/postprocess/bloom/graph_postprocess_bloom.js +155 -155
  1678. package/src/shade/renderer/postprocess/cas/shader_ffx_rcas.js +114 -114
  1679. package/src/shade/renderer/postprocess/dof/DOF_AUTOFOCUS_PARAMS_STRUCT.js +25 -25
  1680. package/src/shade/renderer/postprocess/dof/DOF_FOCUS_STATE_STRUCT.js +23 -23
  1681. package/src/shade/renderer/postprocess/dof/DOF_PRESETS.js +27 -27
  1682. package/src/shade/renderer/postprocess/dof/chunk_dof_coc_band_diameter.js +41 -41
  1683. package/src/shade/renderer/postprocess/dof/chunk_dof_coc_band_radius.js +32 -32
  1684. package/src/shade/renderer/postprocess/dof/chunk_dof_coc_coefficient.js +26 -26
  1685. package/src/shade/renderer/postprocess/dof/compute_dof_autofocus_params.js +64 -64
  1686. package/src/shade/renderer/postprocess/dof/compute_dof_uniform.js +54 -54
  1687. package/src/shade/renderer/postprocess/dof/gather/DOF2_CONFIG.js +91 -91
  1688. package/src/shade/renderer/postprocess/dof/gather/DOF2_PRESETS.js +9 -9
  1689. package/src/shade/renderer/postprocess/dof/gather/DOF2_SETTINGS_STRUCT.js +66 -66
  1690. package/src/shade/renderer/postprocess/dof/gather/DOF2_TEXTURE_FORMAT.js +22 -22
  1691. package/src/shade/renderer/postprocess/dof/gather/DepthOfFieldU.js +292 -292
  1692. package/src/shade/renderer/postprocess/dof/gather/chunk_dof2_coc_to_near_far.js +25 -25
  1693. package/src/shade/renderer/postprocess/dof/gather/chunk_dof2_gather_weight.js +30 -30
  1694. package/src/shade/renderer/postprocess/dof/gather/compute_dof2_uniform.js +54 -54
  1695. package/src/shade/renderer/postprocess/dof/gather/graph_postprocess_dof2.js +194 -194
  1696. package/src/shade/renderer/postprocess/dof/gather/shader_dof2_fill.js +68 -68
  1697. package/src/shade/renderer/postprocess/dof/gather/shader_dof2_gather_far.js +140 -140
  1698. package/src/shade/renderer/postprocess/dof/gather/shader_dof2_gather_near.js +142 -142
  1699. package/src/shade/renderer/postprocess/dof/gather/shader_dof2_recombine.js +99 -99
  1700. package/src/shade/renderer/postprocess/dof/gather/shader_dof2_setup.js +102 -102
  1701. package/src/shade/renderer/postprocess/dof/gather/shader_dof2_tile_dilate.js +75 -75
  1702. package/src/shade/renderer/postprocess/dof/gather/shader_dof2_tile_max.js +73 -73
  1703. package/src/shade/renderer/postprocess/dof/raymarch/DOF_SETTINGS_STRUCT.js +49 -49
  1704. package/src/shade/renderer/postprocess/dof/raymarch/DepthOfField.js +298 -298
  1705. package/src/shade/renderer/postprocess/dof/raymarch/graph_postprocess_dof.js +244 -244
  1706. package/src/shade/renderer/postprocess/dof/raymarch/shader_dof_composite.js +91 -91
  1707. package/src/shade/renderer/postprocess/dof/raymarch/shader_dof_firefly_cleanup.js +61 -61
  1708. package/src/shade/renderer/postprocess/dof/raymarch/shader_dof_prefilter.js +90 -90
  1709. package/src/shade/renderer/postprocess/dof/raymarch/shader_dof_raymarch_compute.js +267 -267
  1710. package/src/shade/renderer/postprocess/dof/raymarch/shader_dof_slice_compute.js +271 -271
  1711. package/src/shade/renderer/postprocess/dof/raymarch/shader_dof_tile_dilate.js +70 -70
  1712. package/src/shade/renderer/postprocess/dof/raymarch/shader_dof_tile_max.js +72 -72
  1713. package/src/shade/renderer/postprocess/dof/shader_dof_autofocus.js +99 -99
  1714. package/src/shade/renderer/postprocess/gtao/generate_magic_square_noise.js +51 -51
  1715. package/src/shade/renderer/postprocess/motion_blur/MotionBlur.js +56 -56
  1716. package/src/shade/renderer/postprocess/upscale-dither/NOTES.md +78 -78
  1717. package/src/shade/renderer/postprocess/upscale-dither/UpscaleDither.js +95 -95
  1718. package/src/shade/renderer/postprocess/upscale-dither/fragment_shader_upscale_dither.js +204 -204
  1719. package/src/shade/renderer/rasterize/bucket/construct_primitive_state.js +58 -58
  1720. package/src/shade/renderer/rasterize/fast/graph_rasterize_scene_fast.js +230 -230
  1721. package/src/shade/renderer/rasterize/native/graph_rasterize_meshes_alpha_tested.js +278 -278
  1722. package/src/shade/renderer/rasterize/native/oit/chunk_material_side_should_draw.js +26 -26
  1723. package/src/shade/renderer/rasterize/native/oit/shader_oit_resolve_moments_ibl.js +178 -178
  1724. package/src/shade/renderer/rasterize/standard/graph_rasterize_partial_opaque.js +235 -235
  1725. package/src/shade/renderer/rasterize/standard/graph_rasterize_remaining_opaque.js +208 -208
  1726. package/src/shade/renderer/rasterize/standard/graph_rasterize_scene.js +206 -206
  1727. package/src/shade/renderer/scene/DynamicMesh.js +70 -70
  1728. package/src/shade/renderer/scene/DynamicMeshBatch.js +90 -90
  1729. package/src/shade/renderer/scene/GPUSceneContext.js +901 -901
  1730. package/src/shade/renderer/scene/SceneNodeBinding.js +56 -56
  1731. package/src/shade/renderer/scene/SkinnedMesh.js +55 -55
  1732. package/src/shade/renderer/scene/TransformAuthority.js +33 -33
  1733. package/src/shade/renderer/scene/optimization/deduplicate_geometries.js +38 -38
  1734. package/src/shade/renderer/scene/optimization/deduplicate_images.js +93 -93
  1735. package/src/shade/renderer/scene/optimization/geometry/internal/match_refit_validate.js +127 -127
  1736. package/src/shade/renderer/scene/optimization/geometry/internal/match_solve_transform.js +492 -492
  1737. package/src/shade/renderer/scene/optimization/optimize_texture_set.js +81 -81
  1738. package/src/shade/renderer/scene/optimization/source_to_sampler2d.js +21 -21
  1739. package/src/shade/renderer/scene/serialization/STANDARD_MATERIAL_SERIALIZED_BYTE_SIZE.js +12 -12
  1740. package/src/shade/renderer/shader/chunk/geometry/quaternion/dual/chunk_dual_quat_transform_point.js +26 -26
  1741. package/src/shade/renderer/shader/chunk/noise/chunk_interleaved_gradient_noise.js +20 -20
  1742. package/src/shade/renderer/shader/chunk/spherical_harmonics/dering/chunk_sh2_dering_optimize_positive.js +61 -61
  1743. package/src/shade/renderer/shader/chunk/texture/chunk_texture_filter_fxaa_lite.js +225 -225
  1744. package/src/shade/renderer/shader/chunk/texture/dither/chunk_dither_color_8bit_gradient_noise.js +25 -25
  1745. package/src/shade/renderer/shadow/map/DirectionalLightShadowmap.js +384 -384
  1746. package/src/shade/renderer/shadow/map/PointLightShadowmap.js +105 -105
  1747. package/src/shade/renderer/shadow/map/SpotLightShadowmap.js +63 -63
  1748. package/src/shade/renderer/shadow/map/TetrahedronPointLightShadowmap.js +89 -89
  1749. package/src/shade/renderer/shadow/map/shadowmap_update_score.js +232 -232
  1750. package/src/shade/renderer/texture/GPUTextureAllocator.js +85 -85
  1751. package/src/shade/renderer/texture/texture_pool_ops.js +171 -171
  1752. package/src/shade/renderer/texture/virtual/PageTableQuadAllocator.js +253 -253
  1753. package/src/shade/renderer/texture/virtual/README.md +276 -276
  1754. package/src/shade/renderer/texture/virtual/VTPageTable.js +330 -330
  1755. package/src/shade/renderer/texture/virtual/VTPhysicalCache.js +349 -349
  1756. package/src/shade/renderer/texture/virtual/VT_CONSTANTS.js +154 -154
  1757. package/src/shade/renderer/texture/virtual/VT_STACK_INFO_STRUCT.js +20 -20
  1758. package/src/shade/renderer/texture/virtual/VirtualTextureManager.js +1276 -1276
  1759. package/src/shade/renderer/texture/virtual/VirtualTextureStack.js +106 -106
  1760. package/src/shade/renderer/texture/virtual/build_chunk_vt_lookup.js +150 -150
  1761. package/src/shade/renderer/texture/virtual/build_shader_vt_feedback.js +232 -232
  1762. package/src/shade/renderer/texture/virtual/chunk_vt_request_key.js +28 -28
  1763. package/src/shade/renderer/texture/virtual/source/VTSourceImage.js +207 -207
  1764. package/src/shade/renderer/texture/virtual/source/VTSourceProcedural.js +135 -135
  1765. package/src/shade/renderer/texture/virtual/source/VTSourceTiled.js +132 -132
  1766. package/src/shade/renderer/water/GPUWaterRenderer.js +167 -167
  1767. package/src/shade/renderer/water/shader_water.js +246 -246
  1768. package/src/shade/renderer/water/water_height_texture_from_sampler.js +56 -56
  1769. package/src/shade/vitest.setup.mjs +89 -89
  1770. package/src/shade/wgsl/validate_wgsl_source.js +316 -316
  1771. package/src/view/controller/controls/NumericIntervalControl.js +90 -90
  1772. package/src/view/controller/controls/Vector2Control.js +83 -83
  1773. package/src/view/controller/controls/Vector3Control.js +90 -90
  1774. package/src/view/elements/Group.js +56 -56
  1775. package/src/view/elements/drawCheckers.js +33 -33
  1776. package/src/view/elements/windrose/WindRoseDiagram.js +369 -369
  1777. package/src/view/graphics/WebGLContextFailureView.js +76 -76
  1778. package/src/view/layout/DockPanel.js +51 -51
  1779. package/src/view/layout/SplitView.js +365 -365
  1780. package/src/view/layout/show_popup_menu.js +81 -81
  1781. package/src/view/minimap/MinimapCanvasView.js +411 -411
  1782. package/src/view/minimap/MinimapImageCache.js +88 -88
  1783. package/src/view/minimap/MinimapMarkerCollection.d.ts +0 -1
  1784. package/src/view/minimap/MinimapMarkerCollection.d.ts.map +1 -1
  1785. package/src/view/minimap/MinimapMarkerCollection.js +180 -180
  1786. package/src/view/minimap/dom/MinimapCameraView.js +206 -206
  1787. package/src/view/minimap/minimap_focus_area.js +97 -97
  1788. package/editor/process/symbolic/SocketsSymbolicDisplay.js +0 -192
  1789. package/src/core/geom/3d/topology/struct/binary/io/moved_tests.txt +0 -37
  1790. package/src/engine/ecs/attachment/Attachment.d.ts +0 -40
  1791. package/src/engine/ecs/attachment/Attachment.d.ts.map +0 -1
  1792. package/src/engine/ecs/attachment/Attachment.js +0 -57
  1793. package/src/engine/ecs/attachment/AttachmentBinding.d.ts +0 -28
  1794. package/src/engine/ecs/attachment/AttachmentBinding.d.ts.map +0 -1
  1795. package/src/engine/ecs/attachment/AttachmentBinding.js +0 -41
  1796. package/src/engine/ecs/attachment/AttachmentSystem.d.ts +0 -61
  1797. package/src/engine/ecs/attachment/AttachmentSystem.d.ts.map +0 -1
  1798. package/src/engine/ecs/attachment/AttachmentSystem.js +0 -307
  1799. package/src/engine/ecs/attachment/BoneAttachmentBinding.d.ts +0 -27
  1800. package/src/engine/ecs/attachment/BoneAttachmentBinding.d.ts.map +0 -1
  1801. package/src/engine/ecs/attachment/BoneAttachmentBinding.js +0 -69
  1802. package/src/engine/ecs/attachment/TransformAttachmentBinding.d.ts +0 -4
  1803. package/src/engine/ecs/attachment/TransformAttachmentBinding.d.ts.map +0 -1
  1804. package/src/engine/ecs/attachment/TransformAttachmentBinding.js +0 -51
  1805. package/src/engine/ecs/sockets/AttachmentSocket.d.ts +0 -32
  1806. package/src/engine/ecs/sockets/AttachmentSocket.d.ts.map +0 -1
  1807. package/src/engine/ecs/sockets/AttachmentSocket.js +0 -60
  1808. package/src/engine/ecs/sockets/AttachmentSocketType.d.ts +0 -6
  1809. package/src/engine/ecs/sockets/AttachmentSocketType.d.ts.map +0 -1
  1810. package/src/engine/ecs/sockets/AttachmentSocketType.js +0 -8
  1811. package/src/engine/ecs/sockets/AttachmentSockets.d.ts +0 -57
  1812. package/src/engine/ecs/sockets/AttachmentSockets.d.ts.map +0 -1
  1813. package/src/engine/ecs/sockets/AttachmentSockets.js +0 -130
  1814. package/src/engine/ecs/sockets/BoneAttachmentSocket.d.ts +0 -29
  1815. package/src/engine/ecs/sockets/BoneAttachmentSocket.d.ts.map +0 -1
  1816. package/src/engine/ecs/sockets/BoneAttachmentSocket.js +0 -56
  1817. package/src/engine/ecs/sockets/serialization/AttachmentSocketsAssetLoader.d.ts +0 -6
  1818. package/src/engine/ecs/sockets/serialization/AttachmentSocketsAssetLoader.d.ts.map +0 -1
  1819. package/src/engine/ecs/sockets/serialization/AttachmentSocketsAssetLoader.js +0 -19
  1820. package/src/shade/renderer/animation/_dump_resolve.d.mts +0 -2
  1821. package/src/shade/renderer/animation/_dump_resolve.d.mts.map +0 -1
  1822. package/src/shade/renderer/animation/_dump_resolve.mjs +0 -5
@@ -1,607 +1,607 @@
1
- # `.vgeo` — Virtual Geometry Container Format
2
-
3
- Status: **writer and validator implemented; no reader yet.** Companion to
4
- [VIRTUAL_GEOMETRY_DESIGN.md](./VIRTUAL_GEOMETRY_DESIGN.md); every requirement pinned in
5
- its §5/§6 is realized here as a concrete field or invariant. Pinned structure below;
6
- open details are listed at the end. One `.vgeo` file = one unique geometry's complete
7
- cluster DAG; instances share the file.
8
-
9
- The implementation lives beside this document: `format/` is the container — what a file is,
10
- how one is written, and `vgeo_validate_container.js`, which audits every §11 invariant in
11
- one — and `build/` is the pipeline that produces it from a `Geometry`, glTF front end
12
- included. The node command line over both is at `tools/geometry/virtual/`. One glTF yields **one file per
13
- primitive**, in object space, with the scene's placements written to a sidecar manifest
14
- rather than baked in. The runtime side (pager, residency, cut pass) is still design only.
15
-
16
- ## 1. Design constraints (inherited, binding)
17
-
18
- - **Geometry only.** `.vgeo` carries geometry and its vertex attributes — nothing else.
19
- Materials are orthogonal, engine-side concerns; a multi-material source splits into
20
- one geometry per material before it reaches the DAG builder — for glTF that split is
21
- free, since a primitive already carries exactly one material, and the converter's
22
- front-end emits one file per primitive. The format has no material fields.
23
- - Billions of source triangles per asset: 64-bit file offsets, 32-bit page indices.
24
- - Immutable, content-addressed; perfect HTTP/CDN caching; fetched by single-range
25
- requests.
26
- - Fetch unit = size-bounded **page**, independently decodable; a group never spans pages.
27
- - No separate global hierarchy: cluster metadata travels **in** pages, so the hierarchy
28
- streams with the geometry it describes.
29
- - **Traversal-first**: a page carries everything needed to fetch the pages it refines
30
- into. Standard runtime operation is header → root page → page-to-page traversal; the
31
- directory is auxiliary (tooling, validation, arbitrary-page access), never a hot-path
32
- dependency.
33
- - Time-to-first-pixel = header + root page, O(1) in asset size.
34
- - Prefix-readable: a plain byte-prefix of the file is a complete coarse asset.
35
- - Per-page compression inside the container only; transparent HTTP compression is
36
- assumed absent (it does not compose with range requests).
37
- - The page DAG is acyclic by construction: child references point strictly forward in
38
- the file.
39
-
40
- ## 2. Conventions
41
-
42
- - Little-endian throughout. Types: `u8 u16 u32 u64 f32`; `[T; N]` = N-element array.
43
- - All file offsets are absolute byte offsets from file start. All in-page offsets are
44
- byte offsets from the start of the **decoded** page.
45
- - **Frames** (stored pages) start at 16-byte-aligned file offsets; `directory_offset`
46
- is 16-aligned; alignment padding is real bytes in the file. Inside a decoded page,
47
- all tables and payload sections are 4-byte aligned (Shade's pools are u32-word
48
- addressed).
49
- - Levels are numbered `0 = leaves`, increasing toward the root. "Coarser" = higher
50
- level. A page's **band** is a contiguous level range `min_level..max_level`.
51
- A level is a **group** ordinal, not a per-cluster depth: it says which band a group
52
- sits in, and a group's clusters may sit at several different depths in the DAG,
53
- because a cluster the builder had no use for is carried forward untouched rather than
54
- coarsened for the sake of symmetry. Cluster records carry no level, and nothing needs
55
- one. What the ordinal guarantees is the property file order depends on: **every group
56
- is in a strictly lower band than the group holding its parents**, so pages laid out by
57
- descending band make every child reference point forward.
58
- - Sentinels for cluster `child_ref`: `NO_CHILD = 0xFFFF` (leaves),
59
- `SAME_PAGE = 0xFFFE` (child group lives in this page — legal only in multi-level
60
- pages, the root page included); valid child-table indices are `≤ 0xFFFD`. Cluster
61
- `child_group`: `NO_GROUP = 0xFFFF`, exactly for leaves. All `f32` fields are NaN-free.
62
- Error values are finite `≥ 0`, except the root's parent error which is `+∞` (f32
63
- infinity).
64
- - Reserved fields: writers MUST write 0; readers MUST ignore their contents.
65
- - Hashing is xxHash3; a `hash_algo` id is reserved for future change. **Integrity
66
- model**: identity-seeded per-frame checksums are the *operative client-side*
67
- mechanism — and because all DAG edges (child tables, cluster records) live inside
68
- frames, the traversal path is covered by them end to end; the header and the
69
- directory carry their own checksums; `asset_id` is whole-file and
70
- *publisher/pipeline/cache-side* — a range-fetching client never reads the whole file
71
- and can never verify it. None of these are a security boundary — they defend against
72
- truncation, corruption, version skew, and cache mixups, not attackers.
73
-
74
- ## 3. Top-level layout
75
-
76
- ```
77
- [ Header (256 B) ]
78
- [ Level table ] ← level_count × 32 B, §4.1
79
- [ Root page frame ] ← always-resident set = header + table + this
80
- [ Page frames, coarse-first band order ] ← prefix of the file = coarse asset
81
- [ Page directory ] ← flat 32 B records, range-fetchable
82
- [ Directory block checksums ] ← u64 per 128 records (4 KB block)
83
- ```
84
-
85
- The frame region is **exactly** `[root_page_offset, directory_offset)` — that is the
86
- normative end-of-frames rule (see §5). Its start is a header field rather than a constant
87
- because the level table (§4.1) precedes it and its size depends on the build. The directory is **derived data**: every field in it is
88
- reconstructible by scanning frames and decoding page headers. It exists for special
89
- tasks — tooling, validation, RAM budgeting before fetch, resuming from a disk cache,
90
- jumping to an arbitrary page without walking the DAG — and standard runtime traversal
91
- never touches it. Random-access readers fetch directory slices on demand: record `i`
92
- lives at exactly `directory_offset + 32·i`.
93
-
94
- ## 4. Header (256 bytes, fixed)
95
-
96
- All u64/u128 fields are naturally 8-byte aligned.
97
-
98
- | offset | type | field | notes |
99
- |-------:|-----------|--------------------------|-------|
100
- | 0 | u32 | magic | `'VGEO'` = 0x4F454756 |
101
- | 4 | u16 | format_version | breaking layout changes only |
102
- | 6 | u16 | min_reader_version | reader MUST reject if its version is lower |
103
- | 8 | u16 | header_size | = 256 |
104
- | 10 | u8 | hash_algo | 0 = xxHash3; readers MUST reject unknown values |
105
- | 11 | u8 | reserved | |
106
- | 12 | u32 | feature_flags_required | readers MUST reject any unknown set bit |
107
- | 16 | u32 | feature_flags_ignorable | readers MUST ignore unknown set bits |
108
- | 20 | u32 | payload_encoding | 1 = `SHADE_MESHLET_V1` (§8); readers MUST reject unknown values |
109
- | 24 | [u8; 16] | asset_id | xxh3-128 of the whole file with every **derived checksum field** zeroed (see below); stored low64 LE at bytes 0–7, high64 LE at bytes 8–15 |
110
- | 40 | u32 | vertex_attribute_mask | advisory attribute presence (§8 bit table) |
111
- | 44 | u32 | total_pages | = directory record count |
112
- | 48 | u64 | total_clusters | ≥ 1 |
113
- | 56 | u64 | total_groups | ≥ 1 |
114
- | 64 | u64 | root_page_offset | = `align16(256 + 32 · level_count)` — the level table (§4.1) sits between |
115
- | 72 | u32 | root_page_fetch_size | same definition as child-table/directory `fetch_size`, for page 0 |
116
- | 76 | u32 | root_page_decoded_size | RAM admission for the always-resident set, known from the header alone |
117
- | 80 | u64 | directory_offset | also the exact end of the frame region |
118
- | 88 | u64 | dir_block_checksums_offset | `ceil(total_pages / 128)` × u64 |
119
- | 96 | u32 | nominal_page_size | build parameter, bytes; informational — readers MUST NOT assume (§11.5 exception) |
120
- | 100 | u16 | reserved | |
121
- | 102 | u8 | level_count | levels `0..level_count-1` |
122
- | 103 | u8 | reserved | |
123
- | 104 | u64 | source_vertex_count | vertices of the normalized source mesh (post-weld) the leaves represent |
124
- | 112 | u64 | source_face_count | triangles of the normalized source mesh |
125
- | 120 | [f32; 4] | object_sphere | object-space minimal bounding sphere (center xyz, radius) of the whole geometry |
126
- | 136 | [f32; 6] | object_bounds | object-space AABB (min xyz, max xyz); instances transform at runtime |
127
- | 160 | [u8; 88] | reserved | |
128
- | 248 | u64 | header_checksum | xxh3-64 of bytes 0–255 with this field zeroed (`asset_id` already final) |
129
-
130
- ### 4.1 Level table (`level_count` × 32 B, immediately after the header)
131
-
132
- Statistics per level, at `256 + 32·i`, ending where the root page frame begins. Small —
133
- a hundred levels is 3.2 KB — so a single fetch of the file's head brings the header, the
134
- whole table, and the always-resident root page together, and the table is available before
135
- any page has been decoded.
136
-
137
- | offset | type | field | notes |
138
- |-------:|------|-------------------|-------|
139
- | 0 | f32 | min_error | smallest object-space `r_e` any cluster of this level carries |
140
- | 4 | f32 | max_error | largest |
141
- | 8 | f32 | max_sphere_radius | largest LOD-metric sphere radius at this level |
142
- | 12 | u32 | cluster_count | ≥ 1 |
143
- | 16 | u32 | group_count | groups sitting in this band; ≥ 1 |
144
- | 20 | u32 | triangle_count | |
145
- | 24 | u64 | reserved | |
146
-
147
- What it is for: an instance's level range can be **bracketed** from the errors and radii
148
- alone — the coarsest level that still passes the threshold at the instance's near point,
149
- the finest that could be wanted at its far one — without reading a cluster record or
150
- fetching a page. That is what lets a scene of ten thousand identical parts resolve to a
151
- handful of distinct cuts instead of ten thousand of them, and what lets a prefetch name
152
- exactly the bands a bracket spans.
153
-
154
- These are facts about the build, not a policy. In particular **`max_error` is not monotonic
155
- in the level**: a round merges an error band, and a later round can produce a cluster finer
156
- than an earlier one did, by finally reaching geometry that had been waiting for a partner.
157
- A reader that wants a monotonic bound takes a running maximum from the coarsest end; that
158
- is the reader's choice and not the file's.
159
-
160
- `cluster_count` and `group_count` sum to the header's `total_clusters` and `total_groups`,
161
- which is the cross-check that keeps the table from drifting from the pages.
162
-
163
- **What `asset_id` covers.** The whole file, with these fields treated as zero: `asset_id` itself,
164
- `header_checksum`, every frame's `checksum` (§5), and the entire `dir_block_checksums` region (§9).
165
- Excluding the last two is what breaks the circle — the frame checksums are seeded from
166
- `asset_id_low64` and the directory block checksums from `asset_id_high64`, so covering them would
167
- make the identity a function of itself. Nothing is lost by the exclusion: every one of those fields
168
- is a function of content the hash still covers, so any change to the asset still moves `asset_id`.
169
-
170
- Build order, and the order a verifier repeats: zero those fields → hash → write `asset_id` →
171
- compute and write the frame and directory-block checksums it seeds → compute and write
172
- `header_checksum` over bytes 0–255 with only that field zeroed.
173
-
174
- The asset filename MUST be derived from `asset_id` in streamed deployments (content
175
- addressing is what makes same-URL version skew impossible; every client-side integrity
176
- property leans on it). The field is authoritative, the name is the enforcement.
177
-
178
- A new `payload_encoding` (e.g. quantized positions) is a **per-asset capability gate,
179
- not a format break**: old readers cleanly reject the asset instead of misreading it;
180
- `format_version` moves only when the container layout itself changes.
181
-
182
- ## 5. Page frame (stored page)
183
-
184
- Every page — root included — is stored as a self-delimiting frame:
185
-
186
- ```
187
- [ FrameHeader (24 B) ] [ Child table (plaintext) ] [ blob (codec-encoded) ]
188
- ```
189
-
190
- | offset | type | field | notes |
191
- |-------:|------|------------------|-------|
192
- | 0 | u32 | magic | `'VGPG'` = 0x47504756 |
193
- | 4 | u8 | codec | 0 = raw, 1 = one LZ4 block; applies to the blob only; readers MUST reject unknown values |
194
- | 5 | u8 | flags | 0 |
195
- | 6 | u16 | child_page_count | entries in the child table; 0 for all-leaf pages |
196
- | 8 | u32 | stored_size | bytes of blob (after the child table) |
197
- | 12 | u32 | decoded_size | decoded-page bytes (== stored_size when raw); MUST equal the referencing child-table entry's (and the directory record's), else reject |
198
- | 16 | u64 | checksum | xxh3-64, **seed = asset_id_low64 XOR page_index**, over frame bytes `[0, 16)` followed by `[24, 24 + 48·child_page_count + stored_size)` — everything but this field |
199
-
200
- **Child table** — `child_page_count` × 48 B, plaintext (never compressed), deduplicated:
201
- one entry per distinct child page this page's clusters refine into. This is what makes
202
- traversal self-sufficient — an installed page needs nothing but itself to fetch every
203
- page one level down — and it is plaintext for two load-bearing reasons: fetch ranges
204
- are readable before (or without) blob decode, and stored sizes stay independent of
205
- offset values, which keeps the build's layout computation non-circular (§10).
206
-
207
- | offset | type | field | notes |
208
- |-------:|------|---------------|-------|
209
- | 0 | u64 | frame_offset | absolute; strictly greater than this page's own frame offset (§11.3) |
210
- | 8 | u32 | page_index | the child page's global index (frame ordinal) — checksum seed, want dedup |
211
- | 12 | u32 | fetch_size | `24 + 48·child.child_page_count + child.stored_size`, rounded up to 16 — the exact range to fetch |
212
- | 16 | u32 | decoded_size | RAM budgeting before fetch; MUST equal the child frame's |
213
- | 20 | u32 | reserved | |
214
- | 24 | metric | metric | the child page's own metric (§6.2), copied — this is what makes a page testable *before* it is fetched; MUST equal that page's header metric (§11.11) |
215
-
216
- The identity-seeded checksum binds the frame to *this page of this asset* and covers
217
- the frame header fields, the child table, and the blob — a well-formed frame of the
218
- wrong page, wrong asset, or wrong version fails verification instead of installing
219
- silently. It also guards the traversal path itself: a corrupt child-table entry fetches
220
- a range whose frame cannot checksum as the expected page index.
221
-
222
- The next frame starts at `round_up(frame_offset + 24 + 48·child_page_count +
223
- stored_size, 16)`. **Prefix scanning**: page indices are frame ordinals (file order ==
224
- index order); scan sequentially and stop when the next aligned offset + 24 exceeds
225
- `min(bytes_available, directory_offset)` — never rely on magic mismatch as a
226
- terminator.
227
-
228
- **Codecs.** `codec` is a property of one frame, not of the file: a writer picks per page
229
- and an asset may carry a mixture, so a reader that handles the defined codecs handles
230
- any file without asking what it was written with. That is what makes "compress unless it
231
- would not shrink" expressible — the LZ4 worst case is about one byte in 255 plus a
232
- token, and paying it to store bytes verbatim is a straight loss, so a page that does not
233
- compress is written raw and says so.
234
-
235
- A new codec id is a **per-asset capability gate, not a format break**, exactly as a new
236
- `payload_encoding` is: an older reader meets a codec it has no decoder for and refuses
237
- the asset instead of misreading it. `format_version` moves only when the container
238
- layout itself changes, and adding a codec does not change it.
239
-
240
- `1` is a **bare LZ4 block**, not an LZ4 frame: LZ4's own framing carries a magic, a
241
- checksum and a content size that this frame already carries better, and `decoded_size`
242
- is what the block is decoded against. Blocks are independent — no match reaches outside
243
- the page — so a page decodes from its own bytes with no other page involved, which is
244
- the same property residency already needs.
245
-
246
- `decoded_size` is untrusted input, and readers allocate against it before anything can
247
- contradict it. It MUST therefore be checked against what `stored_size` bytes could
248
- physically produce under `codec` — exactly `stored_size` for raw, at most
249
- `255·stored_size + 19` for LZ4 — *before* the allocation. A block that then decodes to
250
- anything other than `decoded_size` MUST be rejected: a page truncated to a plausible
251
- prefix is the one corruption that reads as a valid page with geometry missing.
252
-
253
- **What it is worth, measured.** LZ4 over the pages of the Stanford models comes to
254
- **1.12x on the bunny, 1.18x on the dragon and 1.14x on the 27M-triangle lucy** — pages
255
- are >99% of a file, so that is very nearly the file ratio. That is modest, and the reason
256
- is worth writing down because it says where the next win is rather than here:
257
-
258
- | section | share of page bytes | lz4 |
259
- |---|---:|---:|
260
- | page header, group, node and cluster tables | 7% | 1.6x |
261
- | payload | 93% | 1.09–1.15x |
262
-
263
- The tables compress, and there are not enough of them to matter. The payload does not,
264
- because under `SHADE_MESHLET_V1` it is float32 positions and packed attribute words —
265
- high-entropy at the byte level, with no repetition for an LZ matcher to find. For
266
- reference, on the same bytes `gzip -9` reaches 1.22x and `xz -9` 1.63x, so this is the
267
- data resisting rather than the codec failing; an entropy coder buys a little more for a
268
- lot more time. **The lever is `payload_encoding`, not `codec`** — quantized positions
269
- (§12) shrink those bytes directly and leave the residue far more compressible.
270
-
271
- What the reader pays is one block decode per page installed, into the buffer the page was
272
- going to be copied into anyway: ~350–500 MB/s of decoded output from the JS decoder, so
273
- about 0.6 ms for a 256 KB page.
274
-
275
- ## 6. Decoded page
276
-
277
- ```
278
- [ PageHeader (56 B) ] [ Group table ] [ Node table ] [ Cluster records ] [ Payload ]
279
- ```
280
-
281
- PageHeader:
282
-
283
- | offset | type | field | notes |
284
- |-------:|------|-----------------------|-------|
285
- | 0 | u16 | group_count | ≥ 1; group table immediately follows the header |
286
- | 2 | u16 | cluster_count | ≥ 1 |
287
- | 4 | u8 | min_level | page band; non-root pages span one contiguous band |
288
- | 5 | u8 | max_level | |
289
- | 6 | u16 | node_count | ≥ 1; ≤ 2·`group_count` (§6.1) |
290
- | 8 | u32 | cluster_table_offset | |
291
- | 12 | u32 | payload_offset | |
292
- | 16 | u32 | payload_size | |
293
- | 20 | u32 | node_table_offset | = `56 + 8·group_count`; the node table follows the group table |
294
- | 24 | [u8; 8] | reserved | |
295
- | 32 | metric | metric | this page's own traversal metric (§6.2) — the root node's, repeated here so an installed page can be tested from itself |
296
-
297
- Group table — `group_count` × 8 B. Groups are the atomic LOD/residency unit; because a
298
- group never spans pages, installing/evicting a page carries whole groups by
299
- construction — no global group index exists or is needed:
300
-
301
- | offset | type | field | notes |
302
- |-------:|------|----------------------|-------|
303
- | 0 | u16 | cluster_first | index into this page's cluster records |
304
- | 2 | u16 | cluster_count | ≥ 1; ≤ 4096 (format cap, §11.5) |
305
- | 4 | u16 | parent_cluster_count | number of parent clusters referencing this group, `SAME_PAGE` references included; 0 exactly for the root page's topmost-level groups — drives activation (§10) |
306
- | 6 | u16 | reserved | |
307
-
308
- ### 6.1 Node table (`node_count` × 32 B)
309
-
310
- A tree over **this page's groups**, and nothing else. It is the part of the hierarchy below page
311
- granularity, and it has no paging question of its own: it arrives with the page it describes,
312
- leaves with it, and can never name anything that is not there.
313
-
314
- | offset | type | field | notes |
315
- |-------:|--------|-------------|-------|
316
- | 0 | metric | metric | bounds everything under this node (§6.2) |
317
- | 24 | u16 | child_first | first child — a node index when interior, a group index when a leaf |
318
- | 26 | u16 | child_count | 1..4 |
319
- | 28 | u16 | flags | bit 0: leaf (children are groups) |
320
- | 30 | u16 | reserved | |
321
-
322
- Node 0 is the root, always. Children occupy a **contiguous run**, and the tree is laid out
323
- breadth-first, so an interior node's `child_first` is strictly greater than its own index — which
324
- bounds any walk without a reader having to track one. Leaves **partition** the group table: every
325
- group is reached through exactly one leaf, no group twice and none not at all. A page with a single
326
- group still has a tree: one leaf node covering it, so a reader always starts at node 0 and never
327
- special-cases.
328
-
329
- Cost, measured across sphere assets from 3k to 98k triangles at page sizes from 8 KB to 256 KB: the
330
- node table plus every metric copy runs **0.3%–1.6% of asset size**, and trees come out one to three
331
- deep.
332
-
333
- ### 6.2 Traversal metric (24 B)
334
-
335
- The same three fields wherever they appear — a child-table entry (§5), a page header (§6), a node
336
- (§6.1):
337
-
338
- | offset | type | field | notes |
339
- |-------:|----------|------------------|-------|
340
- | 0 | [f32; 4] | sphere | contains every bound anything covered carries |
341
- | 16 | f32 | min_self_error | finest error covered |
342
- | 20 | f32 | max_parent_error | coarsest parent error covered; `+∞` where the root is covered |
343
-
344
- One sphere serves both the spatial test and the projection. It is the union of the covered clusters'
345
- `parent_sphere`s, and monotonicity does the rest: `parent_sphere` contains `self_sphere`, which
346
- contains the cluster's own vertices, so nothing under the node escapes it.
347
-
348
- `max_parent_error` is the load-bearing number. A cluster is drawn only while `project(parent) > τ`,
349
- so if the *largest* parent error under a node still projects to no more than τ, nothing under it can
350
- be drawn and the entire subtree is skippable. `min_self_error` answers the other question — whether
351
- anything here is drawable at all, or whether this is only a waypoint on the way to something finer —
352
- which is what a prefetch ranks its wants by.
353
-
354
- A group is the natural unit for all of this and needs no new geometry: every cluster of a group is
355
- consumed by one step and therefore shares that step's `parent_sphere` and `parent_error`, which is
356
- the same fact that makes the group the atomic LOD decision.
357
-
358
- **The copy in a child-table entry is the point of the whole thing.** It is what a traversal reads
359
- *before* fetching a page, and without it the only way to learn a page was not wanted is to fetch and
360
- decode it. Being a copy, it can drift; §11.11 requires it to match the page's own.
361
-
362
- ## 7. Cluster record (112 bytes)
363
-
364
- Everything the runtime cut rule, culling, wants, and upload need — denormalized per
365
- cluster so selection reads one record. Two kinds of spheres, deliberately distinct: the
366
- **LOD-metric pair** (`self_sphere`/`parent_sphere` — shared per group step so all
367
- siblings project identical values, monotonically inflated, never a tight fit) and the
368
- **culling bounds** (`bounds_sphere`/`aabb` — this cluster's own tight fits, never used
369
- in the cut test):
370
-
371
- | offset | type | field | notes |
372
- |-------:|----------|-----------------|-------|
373
- | 0 | [f32; 4] | self_sphere | LOD-metric sphere (center xyz + radius) of the group step that created this cluster; leaves: equals `bounds_sphere` |
374
- | 16 | f32 | self_error | object-space `r_e`; leaves: 0 |
375
- | 20 | f32 | parent_error | error of the step that consumed it; roots: +∞ |
376
- | 24 | [f32; 4] | parent_sphere | LOD-metric sphere of the consuming step; roots: duplicate of self_sphere |
377
- | 40 | [f32; 4] | bounds_sphere | this cluster's own minimal bounding sphere (miniball), object-space — culling |
378
- | 56 | [f32; 6] | aabb | this cluster's object-space AABB — culling, GPU metadata `bounds_box`, and the (future) dequantization grid |
379
- | 80 | u16 | child_ref | index into this frame's child table; `SAME_PAGE` when the child group is in this page; `NO_CHILD` for leaves |
380
- | 82 | u16 | child_group | group index within the child page (or this page, for `SAME_PAGE`); `NO_GROUP` for leaves |
381
- | 84 | u32 | cone_reserved | reserved for backface-cone culling — **write 0**. No cull pass consumes a cone today and the producer needs a `BinaryTopology` port; the sub-encoding is pinned together with that pass, not before |
382
- | 88 | u32 | encoding_flags | frozen bit table in §8 |
383
- | 92 | u32 | payload_offset | into this page's payload section; ≡ 0 (mod 4) |
384
- | 96 | u32 | payload_size | bytes; ≡ 0 (mod 4) |
385
- | 100 | u8 | vertex_count | 3 ≤ n ≤ 128 |
386
- | 101 | u8 | triangle_count | 1 ≤ n ≤ 128 |
387
- | 102 | u16 | reserved | |
388
- | 104 | u64 | reserved | |
389
-
390
- Monotonicity (`parent_error ≥ self_error`, `parent_sphere ⊇ self_sphere`) is a build
391
- invariant, not a reader concern. A single-cluster asset is valid: one root page, one
392
- group with `parent_cluster_count = 0`, one cluster with `parent_error = +∞`,
393
- `child_ref = NO_CHILD`, `child_page_count = 0`.
394
-
395
- ## 8. Payload encoding
396
-
397
- `payload_encoding = 1` (`SHADE_MESHLET_V1`). **Byte-compat scope**: the payload block is
398
- byte-compatible with `GPUMeshletManager`'s **data pool** — uploading it is a copy. The
399
- 40-byte GPU metadata rows (`MESHLET_METADATA_STRUCT`: bounds_box, address,
400
- primitive_count, vertex_count, flags) are **synthesized at install** from the cluster
401
- record (aabb → bounds_box, counts widened to u32, `address = slot_base_word +
402
- payload_offset/4`, flags = encoding_flags) — a small pack step that is part of the
403
- design's "VRAM paging mechanism is new work", not an existing patch path.
404
-
405
- Payload block layout:
406
-
407
- 1. Index section: `triangle_count × 3` local u8 indices, zero-padded to a 4-byte word
408
- boundary.
409
- 2. Attribute sections, in the frozen order below, each `words × vertex_count` u32
410
- words — unless its `encoding_flags` bit marks it constant-compressed, in which case
411
- exactly `words` u32s are stored once.
412
-
413
- Frozen tables (byte-identical to Shade's `ENCODED_ORDERED_ATTRIBUTES`,
414
- `ENCODED_ATTRIBUTE_SIZES`, `MESHLET_METADATA_FLAGS` as of this writing — the spec, not
415
- the source, is now the authority for `.vgeo` files):
416
-
417
- | # | attribute | words/vertex | encoding | flags bit (constant-compressed) | mask bit |
418
- |---|-----------|-------------:|----------------------------|-------------------------------:|---------:|
419
- | 0 | position | 3 | raw f32×3 | — (never compressed) | 0 |
420
- | 1 | normal | 1 | octahedral u32 | 1 (0x01) | 1 |
421
- | 2 | tangent | 1 | packed u32 | 2 (0x02) | 2 |
422
- | 3 | color | 1 | RGBA8 u32 | 4 (0x04) | 3 |
423
- | 4 | uv0 | 2 | raw f32×2 | 8 (0x08) | 4 |
424
- | 5 | uv1 | 1 | 2×unorm16 u32 | 16 (0x10) | 5 |
425
-
426
- - `encoding_flags` bits 5 (0x20, skinning joints) and 6 (0x40, skinning weights) MUST
427
- be clear, and **no skinning sections are stored** — `SHADE_MESHLET_V1` payloads end
428
- at uv1. (Load-bearing note: skinning attributes are last in Shade's attribute order
429
- and the static decode path never addresses them, which is exactly what makes their
430
- omission safe. VG is static-only, design §9.)
431
- - All other `encoding_flags` bits are reserved, MUST be 0.
432
- - An attribute the source lacks still ships its section, constant-compressed to the
433
- engine default — **sections are never omitted**; `vertex_attribute_mask` is advisory
434
- (which attributes carry real data). True section omission would shift every following
435
- offset and is only expressible as a new `payload_encoding` id.
436
-
437
- Quantized positions land as a **new `payload_encoding` id** (plus a page codec if
438
- entropy coding pays). The cluster record already carries the dequantization grid
439
- (`aabb`).
440
-
441
- ## 9. Page directory (auxiliary)
442
-
443
- Flat array of `total_pages` 32 B records at `directory_offset`; record `i` describes
444
- page index `i` (page index order == file order == coarse-first). Auxiliary and fully
445
- derivable from the frames (§3) — standard runtime traversal never reads it.
446
-
447
- | offset | type | field | notes |
448
- |-------:|------|----------------|-------|
449
- | 0 | u64 | frame_offset | absolute; frame per §5 |
450
- | 8 | u32 | fetch_size | as in the child table: the exact byte range to fetch is `[frame_offset, frame_offset + fetch_size)` |
451
- | 12 | u32 | decoded_size | MUST equal the frame's |
452
- | 16 | u8 | min_level | |
453
- | 17 | u8 | max_level | |
454
- | 18 | u16 | flags | bit 0: root page |
455
- | 20 | u16 | group_count | |
456
- | 22 | u16 | cluster_count | |
457
- | 24 | u64 | reserved | |
458
-
459
- **Directory integrity**: `dir_block_checksums` holds one xxh3-64 per 128 directory
460
- records (one 4 KB block), seed = `asset_id_high64 XOR block_index`. Readers that use
461
- the directory fetch it at block granularity and MUST verify.
462
-
463
- ## 10. Reader requirements
464
-
465
- Standard runtime operation is **pure traversal** — the directory is not involved:
466
-
467
- - Cold start: fetch `[0, 256)`, verify `header_checksum`, magic, versions (§4 reject
468
- rules), then fetch `[root_page_offset, root_page_offset + root_page_fetch_size)` — the
469
- level table (§4.1) sits between the two, so a head prefix covering both brings the whole
470
- always-resident set in one request. The root frame's `decoded_size` MUST equal
471
- `root_page_decoded_size` and its frame extent MUST match `root_page_fetch_size`, else
472
- reject. Or speculatively fetch one larger head prefix — coarse-first layout makes every
473
- prefix byte useful.
474
- - **Refinement**: a want is a `child_ref` in an installed page; its child-table entry
475
- carries the exact byte range — one round-trip per cold page, no metadata fetch ever.
476
- Wants dedup on `page_index` across clusters, groups, and instances. A want whose
477
- target page is **already installed** resolves as an activation recheck of the
478
- referenced group (below), never a fetch.
479
- - **Activation (closure without dependency lists)** — the selectable invariant:
480
-
481
- *A group `g` is selectable iff every one of its `parent_cluster_count` references is
482
- live — the referencing cluster's page is installed and that cluster's own group is
483
- selectable. Groups with `parent_cluster_count = 0` (exactly the root page's topmost
484
- level) are selectable at install.*
485
-
486
- By induction, a selectable cluster's entire ancestor cone is installed and
487
- selectable — the closure the cut rule needs, restored by a per-group counter instead
488
- of dependency lists. Runtime bookkeeping: each resident group keeps a live-reference
489
- counter; when a group becomes selectable, its clusters' references (child-table and
490
- `SAME_PAGE` alike) increment the referenced groups' counters — cascading
491
- transitively; installing a page counts the existing live references into it (the
492
- runtime maintains a reverse-reference index for pending pages — the same structure
493
- that carries wants). Counters only grow while the pages involved stay resident (the
494
- eviction rule below guarantees referencing parents outlive children). Activation
495
- flips whole groups; the cut rule's clamp reads *selectable*, not merely resident
496
- (design §4/§6): resident-but-inactive groups draw nothing, their coarser selectable
497
- ancestors keep covering that surface — **no holes and no double-draw, in any arrival
498
- order**, because a group never draws before all pages holding its parents are
499
- installed and selectable.
500
- - **In-flight protection**: a fetch discovered through parent page P pins P until the
501
- child installs — known at queue time, purely local. Arrivals verify the
502
- identity-seeded frame checksum; activation makes any arrival order safe beyond that.
503
- - **Eviction**: within each residency tier, a page is evictable only while it has no
504
- resident child pages in that tier — checked against its own child table (`SAME_PAGE`
505
- references never pin). Leaves-first order emerges from the rule; the root page is
506
- pinned.
507
- - Verify every ranged response is `206` with the requested `Content-Range`; a `200`
508
- means the server ignored the range — abort the transfer immediately (design §6).
509
- - Verify frame checksums (identity-seeded, §5) before decode, and `decoded_size`
510
- against the child-table entry used to fetch and against the codec's decode bound
511
- (§5) before allocating for it. On mismatch: bounded retries with
512
- backoff, then **quarantine** the page — the clamped cut keeps a coarse stand-in
513
- correct indefinitely — and surface telemetry. Never retry-loop: corruption at a
514
- content-addressed URL is deterministic.
515
- - After install, stamp each cluster's selection row with its own page index and its
516
- child page index/group (touch and want emission, design §6/§7).
517
- - Fetch batching: coalesce adjacent wanted pages into contiguous single ranges; ranges
518
- never cross a band boundary by construction (coarse-first ordering), so coalescing
519
- lives within bands — the within-band spatial curve (§12) is what carries fetch
520
- locality and must be chosen with that as a criterion. Fetching through small unwanted
521
- gaps is permitted under an implementation waste threshold.
522
- - Never assume `nominal_page_size`; per-page sizes come from child tables (traversal),
523
- frames (prefix scan), or the directory (special tasks).
524
-
525
- Build consequence (accepted): child tables hold downstream offsets — the format is
526
- optimized for reading, and the builder pays for it. Preferred strategy: emit frames
527
- with placeholder child tables, then **backpatch** them once all offsets are known, and
528
- finalize frame checksums last (the checksum covers the child table). Computing the full
529
- layout up front (compress all blobs → prefix-sum offsets → one forward emit) is equally
530
- valid. Both are cheap and non-circular **because child tables are plaintext in the
531
- frame**: a frame's extent (`24 + 48·children + stored_size`, with `stored_size` the
532
- blob's compressed size) never depends on the offset values, and patching plaintext
533
- bytes needs no re-compression. Build times are non-interactive by expectation —
534
- clustering and simplification dominate regardless.
535
-
536
- ## 11. Build invariants (validated at build, assumed by readers)
537
-
538
- 1. A group's clusters are contiguous in one page (`cluster_first/cluster_count`); a
539
- group never spans pages. Non-root pages span a single contiguous level band.
540
- 2. Child tables are exact: deduplicated, one entry per distinct **other** page
541
- referenced by this page's clusters (`SAME_PAGE` references appear in no child
542
- table); every `child_ref`/`child_group` resolves to a valid entry and group;
543
- `frame_offset`/`fetch_size`/`decoded_size` agree with the referenced frame and the
544
- directory (all referencing pages agree by construction).
545
- 3. Acyclicity and reachability: every child-table `frame_offset` is strictly greater
546
- than the owning page's frame offset (file order is topological), and every page is
547
- reachable from the root page through child tables.
548
- 4. File order (== page index order) is coarse-first: the root page first, bands by
549
- descending level, spatial locality within a band. The root page contains the
550
- complete topmost level(s) — at minimum a complete drawable cut of the DAG. A
551
- cluster's child group is always in a page whose band tops out strictly below its own
552
- page's, unless the reference is `SAME_PAGE`.
553
- 5. Group size: `1 ≤ cluster_count ≤ 4096` (format cap; builders target far less —
554
- design §3 grouping is adaptive from ~4). `parent_cluster_count` equals the exact
555
- number of clusters (across all pages, `SAME_PAGE` included) whose
556
- `child_ref/child_group` name this group; it is 0 exactly for the root page's
557
- topmost-level groups. A page holding one indivisible oversized group MAY exceed
558
- `nominal_page_size`; the hard bound is the frame's u32 `stored_size`.
559
- 6. `1 ≤ triangle_count ≤ 128`, `3 ≤ vertex_count ≤ 128` (Shade meshlet limits);
560
- `total_clusters ≥ 1`; `source_vertex_count ≥ 3`, `source_face_count ≥ 1`.
561
- 7. Error/sphere monotonicity per design §4; `self_error = 0` and `child_ref = NO_CHILD`
562
- exactly for leaves; `parent_error = +∞` exactly for **the** root — there is exactly
563
- one, and it is in page 0. Several parentless clusters would be several entry points,
564
- and the cut only ever enters at one; it is also what an unconverged build leaves
565
- behind, which is the likelier cause. All floats NaN-free.
566
- `bounds_sphere` and `aabb` contain the cluster's decoded vertices; the header's
567
- `object_sphere` and `object_bounds` contain the normalized source mesh.
568
- 8. Payload offsets and sizes are 4-byte multiples; every payload decodes/uploads
569
- against `payload_encoding` with no external state beyond its own cluster record.
570
- A leaf's `self_error` of 0 is only as honest as the simplifier's metric — see design
571
- §2, boundary constraint quadrics — and no reader-side check can distinguish an
572
- exact coarse cluster from one whose error went unrecorded.
573
- 9. `asset_id` and `header_checksum` verify per §4 — including its zeroing rule, which excludes
574
- every derived checksum field; every frame verifies per §5; the directory verifies per §9 and
575
- byte-for-byte matches what a frame scan reconstructs. `header_checksum` covers bytes 0–255
576
- only, so the level table's integrity rests on `asset_id`, which covers the whole file.
577
- 10. Every page's node table is a tree over exactly that page's groups: node 0 is the root, an
578
- interior node's children are a contiguous run at a strictly greater index, `1 ≤ child_count ≤ 4`,
579
- and the leaves partition the group table — each group reached through exactly one leaf. Each
580
- node's metric bounds its whole subtree: its sphere contains every child's, its `min_self_error`
581
- is no greater than any child's, its `max_parent_error` no less. The page header's metric equals
582
- the root node's.
583
- 11. Every child-table entry's metric equals the header metric of the page it names. It is a copy
584
- read before that page is fetched, so nothing else can catch it having drifted — and a traversal
585
- that trusts a stale one skips a page it needed and leaves a hole.
586
- 12. Every frame names a defined `codec` (§5); a raw frame's `stored_size` equals its
587
- `decoded_size`; and no frame's `decoded_size` exceeds what its codec could produce from
588
- `stored_size` bytes. Every blob decodes to exactly `decoded_size` — a short decode is a
589
- truncated page, and a page truncated to a plausible prefix is the one corruption that reads
590
- as valid geometry with pieces missing.
591
- 13. `root_page_offset = align16(256 + 32 · level_count)`; the level table's `cluster_count` and
592
- `group_count` columns sum to `total_clusters` and `total_groups`; every level holds at least
593
- one cluster and one group; `min_error ≤ max_error`, both finite and ≥ 0.
594
-
595
- ## 12. Open
596
-
597
- - Page codec ids beyond raw and LZ4 (§5). LZ4 is the default and is where the cheap
598
- ratio is; a slower, denser codec (meshopt-style over the payload, deflate-family over
599
- the tables) is a per-frame `codec` id away and costs no reader that already handles a
600
- mixture. The quantized-position `payload_encoding` is the other half of the same
601
- question, and would take most of what LZ4 currently finds.
602
- - Default `nominal_page_size` (design §5: order hundreds of KB, measured).
603
- - Spatial ordering curve within a level band (Morton over group centroids is the
604
- default candidate; chosen with fetch-coalescing locality as an explicit criterion,
605
- §10).
606
- - Backface-cone cull pass and, with it, the `cone_reserved` sub-encoding.
607
- - Multi-geometry containers (v1: one geometry per file; scenes reference many files).
1
+ # `.vgeo` — Virtual Geometry Container Format
2
+
3
+ Status: **writer and validator implemented; no reader yet.** Companion to
4
+ [VIRTUAL_GEOMETRY_DESIGN.md](./VIRTUAL_GEOMETRY_DESIGN.md); every requirement pinned in
5
+ its §5/§6 is realized here as a concrete field or invariant. Pinned structure below;
6
+ open details are listed at the end. One `.vgeo` file = one unique geometry's complete
7
+ cluster DAG; instances share the file.
8
+
9
+ The implementation lives beside this document: `format/` is the container — what a file is,
10
+ how one is written, and `vgeo_validate_container.js`, which audits every §11 invariant in
11
+ one — and `build/` is the pipeline that produces it from a `Geometry`, glTF front end
12
+ included. The node command line over both is at `tools/geometry/virtual/`. One glTF yields **one file per
13
+ primitive**, in object space, with the scene's placements written to a sidecar manifest
14
+ rather than baked in. The runtime side (pager, residency, cut pass) is still design only.
15
+
16
+ ## 1. Design constraints (inherited, binding)
17
+
18
+ - **Geometry only.** `.vgeo` carries geometry and its vertex attributes — nothing else.
19
+ Materials are orthogonal, engine-side concerns; a multi-material source splits into
20
+ one geometry per material before it reaches the DAG builder — for glTF that split is
21
+ free, since a primitive already carries exactly one material, and the converter's
22
+ front-end emits one file per primitive. The format has no material fields.
23
+ - Billions of source triangles per asset: 64-bit file offsets, 32-bit page indices.
24
+ - Immutable, content-addressed; perfect HTTP/CDN caching; fetched by single-range
25
+ requests.
26
+ - Fetch unit = size-bounded **page**, independently decodable; a group never spans pages.
27
+ - No separate global hierarchy: cluster metadata travels **in** pages, so the hierarchy
28
+ streams with the geometry it describes.
29
+ - **Traversal-first**: a page carries everything needed to fetch the pages it refines
30
+ into. Standard runtime operation is header → root page → page-to-page traversal; the
31
+ directory is auxiliary (tooling, validation, arbitrary-page access), never a hot-path
32
+ dependency.
33
+ - Time-to-first-pixel = header + root page, O(1) in asset size.
34
+ - Prefix-readable: a plain byte-prefix of the file is a complete coarse asset.
35
+ - Per-page compression inside the container only; transparent HTTP compression is
36
+ assumed absent (it does not compose with range requests).
37
+ - The page DAG is acyclic by construction: child references point strictly forward in
38
+ the file.
39
+
40
+ ## 2. Conventions
41
+
42
+ - Little-endian throughout. Types: `u8 u16 u32 u64 f32`; `[T; N]` = N-element array.
43
+ - All file offsets are absolute byte offsets from file start. All in-page offsets are
44
+ byte offsets from the start of the **decoded** page.
45
+ - **Frames** (stored pages) start at 16-byte-aligned file offsets; `directory_offset`
46
+ is 16-aligned; alignment padding is real bytes in the file. Inside a decoded page,
47
+ all tables and payload sections are 4-byte aligned (Shade's pools are u32-word
48
+ addressed).
49
+ - Levels are numbered `0 = leaves`, increasing toward the root. "Coarser" = higher
50
+ level. A page's **band** is a contiguous level range `min_level..max_level`.
51
+ A level is a **group** ordinal, not a per-cluster depth: it says which band a group
52
+ sits in, and a group's clusters may sit at several different depths in the DAG,
53
+ because a cluster the builder had no use for is carried forward untouched rather than
54
+ coarsened for the sake of symmetry. Cluster records carry no level, and nothing needs
55
+ one. What the ordinal guarantees is the property file order depends on: **every group
56
+ is in a strictly lower band than the group holding its parents**, so pages laid out by
57
+ descending band make every child reference point forward.
58
+ - Sentinels for cluster `child_ref`: `NO_CHILD = 0xFFFF` (leaves),
59
+ `SAME_PAGE = 0xFFFE` (child group lives in this page — legal only in multi-level
60
+ pages, the root page included); valid child-table indices are `≤ 0xFFFD`. Cluster
61
+ `child_group`: `NO_GROUP = 0xFFFF`, exactly for leaves. All `f32` fields are NaN-free.
62
+ Error values are finite `≥ 0`, except the root's parent error which is `+∞` (f32
63
+ infinity).
64
+ - Reserved fields: writers MUST write 0; readers MUST ignore their contents.
65
+ - Hashing is xxHash3; a `hash_algo` id is reserved for future change. **Integrity
66
+ model**: identity-seeded per-frame checksums are the *operative client-side*
67
+ mechanism — and because all DAG edges (child tables, cluster records) live inside
68
+ frames, the traversal path is covered by them end to end; the header and the
69
+ directory carry their own checksums; `asset_id` is whole-file and
70
+ *publisher/pipeline/cache-side* — a range-fetching client never reads the whole file
71
+ and can never verify it. None of these are a security boundary — they defend against
72
+ truncation, corruption, version skew, and cache mixups, not attackers.
73
+
74
+ ## 3. Top-level layout
75
+
76
+ ```
77
+ [ Header (256 B) ]
78
+ [ Level table ] ← level_count × 32 B, §4.1
79
+ [ Root page frame ] ← always-resident set = header + table + this
80
+ [ Page frames, coarse-first band order ] ← prefix of the file = coarse asset
81
+ [ Page directory ] ← flat 32 B records, range-fetchable
82
+ [ Directory block checksums ] ← u64 per 128 records (4 KB block)
83
+ ```
84
+
85
+ The frame region is **exactly** `[root_page_offset, directory_offset)` — that is the
86
+ normative end-of-frames rule (see §5). Its start is a header field rather than a constant
87
+ because the level table (§4.1) precedes it and its size depends on the build. The directory is **derived data**: every field in it is
88
+ reconstructible by scanning frames and decoding page headers. It exists for special
89
+ tasks — tooling, validation, RAM budgeting before fetch, resuming from a disk cache,
90
+ jumping to an arbitrary page without walking the DAG — and standard runtime traversal
91
+ never touches it. Random-access readers fetch directory slices on demand: record `i`
92
+ lives at exactly `directory_offset + 32·i`.
93
+
94
+ ## 4. Header (256 bytes, fixed)
95
+
96
+ All u64/u128 fields are naturally 8-byte aligned.
97
+
98
+ | offset | type | field | notes |
99
+ |-------:|-----------|--------------------------|-------|
100
+ | 0 | u32 | magic | `'VGEO'` = 0x4F454756 |
101
+ | 4 | u16 | format_version | breaking layout changes only |
102
+ | 6 | u16 | min_reader_version | reader MUST reject if its version is lower |
103
+ | 8 | u16 | header_size | = 256 |
104
+ | 10 | u8 | hash_algo | 0 = xxHash3; readers MUST reject unknown values |
105
+ | 11 | u8 | reserved | |
106
+ | 12 | u32 | feature_flags_required | readers MUST reject any unknown set bit |
107
+ | 16 | u32 | feature_flags_ignorable | readers MUST ignore unknown set bits |
108
+ | 20 | u32 | payload_encoding | 1 = `SHADE_MESHLET_V1` (§8); readers MUST reject unknown values |
109
+ | 24 | [u8; 16] | asset_id | xxh3-128 of the whole file with every **derived checksum field** zeroed (see below); stored low64 LE at bytes 0–7, high64 LE at bytes 8–15 |
110
+ | 40 | u32 | vertex_attribute_mask | advisory attribute presence (§8 bit table) |
111
+ | 44 | u32 | total_pages | = directory record count |
112
+ | 48 | u64 | total_clusters | ≥ 1 |
113
+ | 56 | u64 | total_groups | ≥ 1 |
114
+ | 64 | u64 | root_page_offset | = `align16(256 + 32 · level_count)` — the level table (§4.1) sits between |
115
+ | 72 | u32 | root_page_fetch_size | same definition as child-table/directory `fetch_size`, for page 0 |
116
+ | 76 | u32 | root_page_decoded_size | RAM admission for the always-resident set, known from the header alone |
117
+ | 80 | u64 | directory_offset | also the exact end of the frame region |
118
+ | 88 | u64 | dir_block_checksums_offset | `ceil(total_pages / 128)` × u64 |
119
+ | 96 | u32 | nominal_page_size | build parameter, bytes; informational — readers MUST NOT assume (§11.5 exception) |
120
+ | 100 | u16 | reserved | |
121
+ | 102 | u8 | level_count | levels `0..level_count-1` |
122
+ | 103 | u8 | reserved | |
123
+ | 104 | u64 | source_vertex_count | vertices of the normalized source mesh (post-weld) the leaves represent |
124
+ | 112 | u64 | source_face_count | triangles of the normalized source mesh |
125
+ | 120 | [f32; 4] | object_sphere | object-space minimal bounding sphere (center xyz, radius) of the whole geometry |
126
+ | 136 | [f32; 6] | object_bounds | object-space AABB (min xyz, max xyz); instances transform at runtime |
127
+ | 160 | [u8; 88] | reserved | |
128
+ | 248 | u64 | header_checksum | xxh3-64 of bytes 0–255 with this field zeroed (`asset_id` already final) |
129
+
130
+ ### 4.1 Level table (`level_count` × 32 B, immediately after the header)
131
+
132
+ Statistics per level, at `256 + 32·i`, ending where the root page frame begins. Small —
133
+ a hundred levels is 3.2 KB — so a single fetch of the file's head brings the header, the
134
+ whole table, and the always-resident root page together, and the table is available before
135
+ any page has been decoded.
136
+
137
+ | offset | type | field | notes |
138
+ |-------:|------|-------------------|-------|
139
+ | 0 | f32 | min_error | smallest object-space `r_e` any cluster of this level carries |
140
+ | 4 | f32 | max_error | largest |
141
+ | 8 | f32 | max_sphere_radius | largest LOD-metric sphere radius at this level |
142
+ | 12 | u32 | cluster_count | ≥ 1 |
143
+ | 16 | u32 | group_count | groups sitting in this band; ≥ 1 |
144
+ | 20 | u32 | triangle_count | |
145
+ | 24 | u64 | reserved | |
146
+
147
+ What it is for: an instance's level range can be **bracketed** from the errors and radii
148
+ alone — the coarsest level that still passes the threshold at the instance's near point,
149
+ the finest that could be wanted at its far one — without reading a cluster record or
150
+ fetching a page. That is what lets a scene of ten thousand identical parts resolve to a
151
+ handful of distinct cuts instead of ten thousand of them, and what lets a prefetch name
152
+ exactly the bands a bracket spans.
153
+
154
+ These are facts about the build, not a policy. In particular **`max_error` is not monotonic
155
+ in the level**: a round merges an error band, and a later round can produce a cluster finer
156
+ than an earlier one did, by finally reaching geometry that had been waiting for a partner.
157
+ A reader that wants a monotonic bound takes a running maximum from the coarsest end; that
158
+ is the reader's choice and not the file's.
159
+
160
+ `cluster_count` and `group_count` sum to the header's `total_clusters` and `total_groups`,
161
+ which is the cross-check that keeps the table from drifting from the pages.
162
+
163
+ **What `asset_id` covers.** The whole file, with these fields treated as zero: `asset_id` itself,
164
+ `header_checksum`, every frame's `checksum` (§5), and the entire `dir_block_checksums` region (§9).
165
+ Excluding the last two is what breaks the circle — the frame checksums are seeded from
166
+ `asset_id_low64` and the directory block checksums from `asset_id_high64`, so covering them would
167
+ make the identity a function of itself. Nothing is lost by the exclusion: every one of those fields
168
+ is a function of content the hash still covers, so any change to the asset still moves `asset_id`.
169
+
170
+ Build order, and the order a verifier repeats: zero those fields → hash → write `asset_id` →
171
+ compute and write the frame and directory-block checksums it seeds → compute and write
172
+ `header_checksum` over bytes 0–255 with only that field zeroed.
173
+
174
+ The asset filename MUST be derived from `asset_id` in streamed deployments (content
175
+ addressing is what makes same-URL version skew impossible; every client-side integrity
176
+ property leans on it). The field is authoritative, the name is the enforcement.
177
+
178
+ A new `payload_encoding` (e.g. quantized positions) is a **per-asset capability gate,
179
+ not a format break**: old readers cleanly reject the asset instead of misreading it;
180
+ `format_version` moves only when the container layout itself changes.
181
+
182
+ ## 5. Page frame (stored page)
183
+
184
+ Every page — root included — is stored as a self-delimiting frame:
185
+
186
+ ```
187
+ [ FrameHeader (24 B) ] [ Child table (plaintext) ] [ blob (codec-encoded) ]
188
+ ```
189
+
190
+ | offset | type | field | notes |
191
+ |-------:|------|------------------|-------|
192
+ | 0 | u32 | magic | `'VGPG'` = 0x47504756 |
193
+ | 4 | u8 | codec | 0 = raw, 1 = one LZ4 block; applies to the blob only; readers MUST reject unknown values |
194
+ | 5 | u8 | flags | 0 |
195
+ | 6 | u16 | child_page_count | entries in the child table; 0 for all-leaf pages |
196
+ | 8 | u32 | stored_size | bytes of blob (after the child table) |
197
+ | 12 | u32 | decoded_size | decoded-page bytes (== stored_size when raw); MUST equal the referencing child-table entry's (and the directory record's), else reject |
198
+ | 16 | u64 | checksum | xxh3-64, **seed = asset_id_low64 XOR page_index**, over frame bytes `[0, 16)` followed by `[24, 24 + 48·child_page_count + stored_size)` — everything but this field |
199
+
200
+ **Child table** — `child_page_count` × 48 B, plaintext (never compressed), deduplicated:
201
+ one entry per distinct child page this page's clusters refine into. This is what makes
202
+ traversal self-sufficient — an installed page needs nothing but itself to fetch every
203
+ page one level down — and it is plaintext for two load-bearing reasons: fetch ranges
204
+ are readable before (or without) blob decode, and stored sizes stay independent of
205
+ offset values, which keeps the build's layout computation non-circular (§10).
206
+
207
+ | offset | type | field | notes |
208
+ |-------:|------|---------------|-------|
209
+ | 0 | u64 | frame_offset | absolute; strictly greater than this page's own frame offset (§11.3) |
210
+ | 8 | u32 | page_index | the child page's global index (frame ordinal) — checksum seed, want dedup |
211
+ | 12 | u32 | fetch_size | `24 + 48·child.child_page_count + child.stored_size`, rounded up to 16 — the exact range to fetch |
212
+ | 16 | u32 | decoded_size | RAM budgeting before fetch; MUST equal the child frame's |
213
+ | 20 | u32 | reserved | |
214
+ | 24 | metric | metric | the child page's own metric (§6.2), copied — this is what makes a page testable *before* it is fetched; MUST equal that page's header metric (§11.11) |
215
+
216
+ The identity-seeded checksum binds the frame to *this page of this asset* and covers
217
+ the frame header fields, the child table, and the blob — a well-formed frame of the
218
+ wrong page, wrong asset, or wrong version fails verification instead of installing
219
+ silently. It also guards the traversal path itself: a corrupt child-table entry fetches
220
+ a range whose frame cannot checksum as the expected page index.
221
+
222
+ The next frame starts at `round_up(frame_offset + 24 + 48·child_page_count +
223
+ stored_size, 16)`. **Prefix scanning**: page indices are frame ordinals (file order ==
224
+ index order); scan sequentially and stop when the next aligned offset + 24 exceeds
225
+ `min(bytes_available, directory_offset)` — never rely on magic mismatch as a
226
+ terminator.
227
+
228
+ **Codecs.** `codec` is a property of one frame, not of the file: a writer picks per page
229
+ and an asset may carry a mixture, so a reader that handles the defined codecs handles
230
+ any file without asking what it was written with. That is what makes "compress unless it
231
+ would not shrink" expressible — the LZ4 worst case is about one byte in 255 plus a
232
+ token, and paying it to store bytes verbatim is a straight loss, so a page that does not
233
+ compress is written raw and says so.
234
+
235
+ A new codec id is a **per-asset capability gate, not a format break**, exactly as a new
236
+ `payload_encoding` is: an older reader meets a codec it has no decoder for and refuses
237
+ the asset instead of misreading it. `format_version` moves only when the container
238
+ layout itself changes, and adding a codec does not change it.
239
+
240
+ `1` is a **bare LZ4 block**, not an LZ4 frame: LZ4's own framing carries a magic, a
241
+ checksum and a content size that this frame already carries better, and `decoded_size`
242
+ is what the block is decoded against. Blocks are independent — no match reaches outside
243
+ the page — so a page decodes from its own bytes with no other page involved, which is
244
+ the same property residency already needs.
245
+
246
+ `decoded_size` is untrusted input, and readers allocate against it before anything can
247
+ contradict it. It MUST therefore be checked against what `stored_size` bytes could
248
+ physically produce under `codec` — exactly `stored_size` for raw, at most
249
+ `255·stored_size + 19` for LZ4 — *before* the allocation. A block that then decodes to
250
+ anything other than `decoded_size` MUST be rejected: a page truncated to a plausible
251
+ prefix is the one corruption that reads as a valid page with geometry missing.
252
+
253
+ **What it is worth, measured.** LZ4 over the pages of the Stanford models comes to
254
+ **1.12x on the bunny, 1.18x on the dragon and 1.14x on the 27M-triangle lucy** — pages
255
+ are >99% of a file, so that is very nearly the file ratio. That is modest, and the reason
256
+ is worth writing down because it says where the next win is rather than here:
257
+
258
+ | section | share of page bytes | lz4 |
259
+ |---|---:|---:|
260
+ | page header, group, node and cluster tables | 7% | 1.6x |
261
+ | payload | 93% | 1.09–1.15x |
262
+
263
+ The tables compress, and there are not enough of them to matter. The payload does not,
264
+ because under `SHADE_MESHLET_V1` it is float32 positions and packed attribute words —
265
+ high-entropy at the byte level, with no repetition for an LZ matcher to find. For
266
+ reference, on the same bytes `gzip -9` reaches 1.22x and `xz -9` 1.63x, so this is the
267
+ data resisting rather than the codec failing; an entropy coder buys a little more for a
268
+ lot more time. **The lever is `payload_encoding`, not `codec`** — quantized positions
269
+ (§12) shrink those bytes directly and leave the residue far more compressible.
270
+
271
+ What the reader pays is one block decode per page installed, into the buffer the page was
272
+ going to be copied into anyway: ~350–500 MB/s of decoded output from the JS decoder, so
273
+ about 0.6 ms for a 256 KB page.
274
+
275
+ ## 6. Decoded page
276
+
277
+ ```
278
+ [ PageHeader (56 B) ] [ Group table ] [ Node table ] [ Cluster records ] [ Payload ]
279
+ ```
280
+
281
+ PageHeader:
282
+
283
+ | offset | type | field | notes |
284
+ |-------:|------|-----------------------|-------|
285
+ | 0 | u16 | group_count | ≥ 1; group table immediately follows the header |
286
+ | 2 | u16 | cluster_count | ≥ 1 |
287
+ | 4 | u8 | min_level | page band; non-root pages span one contiguous band |
288
+ | 5 | u8 | max_level | |
289
+ | 6 | u16 | node_count | ≥ 1; ≤ 2·`group_count` (§6.1) |
290
+ | 8 | u32 | cluster_table_offset | |
291
+ | 12 | u32 | payload_offset | |
292
+ | 16 | u32 | payload_size | |
293
+ | 20 | u32 | node_table_offset | = `56 + 8·group_count`; the node table follows the group table |
294
+ | 24 | [u8; 8] | reserved | |
295
+ | 32 | metric | metric | this page's own traversal metric (§6.2) — the root node's, repeated here so an installed page can be tested from itself |
296
+
297
+ Group table — `group_count` × 8 B. Groups are the atomic LOD/residency unit; because a
298
+ group never spans pages, installing/evicting a page carries whole groups by
299
+ construction — no global group index exists or is needed:
300
+
301
+ | offset | type | field | notes |
302
+ |-------:|------|----------------------|-------|
303
+ | 0 | u16 | cluster_first | index into this page's cluster records |
304
+ | 2 | u16 | cluster_count | ≥ 1; ≤ 4096 (format cap, §11.5) |
305
+ | 4 | u16 | parent_cluster_count | number of parent clusters referencing this group, `SAME_PAGE` references included; 0 exactly for the root page's topmost-level groups — drives activation (§10) |
306
+ | 6 | u16 | reserved | |
307
+
308
+ ### 6.1 Node table (`node_count` × 32 B)
309
+
310
+ A tree over **this page's groups**, and nothing else. It is the part of the hierarchy below page
311
+ granularity, and it has no paging question of its own: it arrives with the page it describes,
312
+ leaves with it, and can never name anything that is not there.
313
+
314
+ | offset | type | field | notes |
315
+ |-------:|--------|-------------|-------|
316
+ | 0 | metric | metric | bounds everything under this node (§6.2) |
317
+ | 24 | u16 | child_first | first child — a node index when interior, a group index when a leaf |
318
+ | 26 | u16 | child_count | 1..4 |
319
+ | 28 | u16 | flags | bit 0: leaf (children are groups) |
320
+ | 30 | u16 | reserved | |
321
+
322
+ Node 0 is the root, always. Children occupy a **contiguous run**, and the tree is laid out
323
+ breadth-first, so an interior node's `child_first` is strictly greater than its own index — which
324
+ bounds any walk without a reader having to track one. Leaves **partition** the group table: every
325
+ group is reached through exactly one leaf, no group twice and none not at all. A page with a single
326
+ group still has a tree: one leaf node covering it, so a reader always starts at node 0 and never
327
+ special-cases.
328
+
329
+ Cost, measured across sphere assets from 3k to 98k triangles at page sizes from 8 KB to 256 KB: the
330
+ node table plus every metric copy runs **0.3%–1.6% of asset size**, and trees come out one to three
331
+ deep.
332
+
333
+ ### 6.2 Traversal metric (24 B)
334
+
335
+ The same three fields wherever they appear — a child-table entry (§5), a page header (§6), a node
336
+ (§6.1):
337
+
338
+ | offset | type | field | notes |
339
+ |-------:|----------|------------------|-------|
340
+ | 0 | [f32; 4] | sphere | contains every bound anything covered carries |
341
+ | 16 | f32 | min_self_error | finest error covered |
342
+ | 20 | f32 | max_parent_error | coarsest parent error covered; `+∞` where the root is covered |
343
+
344
+ One sphere serves both the spatial test and the projection. It is the union of the covered clusters'
345
+ `parent_sphere`s, and monotonicity does the rest: `parent_sphere` contains `self_sphere`, which
346
+ contains the cluster's own vertices, so nothing under the node escapes it.
347
+
348
+ `max_parent_error` is the load-bearing number. A cluster is drawn only while `project(parent) > τ`,
349
+ so if the *largest* parent error under a node still projects to no more than τ, nothing under it can
350
+ be drawn and the entire subtree is skippable. `min_self_error` answers the other question — whether
351
+ anything here is drawable at all, or whether this is only a waypoint on the way to something finer —
352
+ which is what a prefetch ranks its wants by.
353
+
354
+ A group is the natural unit for all of this and needs no new geometry: every cluster of a group is
355
+ consumed by one step and therefore shares that step's `parent_sphere` and `parent_error`, which is
356
+ the same fact that makes the group the atomic LOD decision.
357
+
358
+ **The copy in a child-table entry is the point of the whole thing.** It is what a traversal reads
359
+ *before* fetching a page, and without it the only way to learn a page was not wanted is to fetch and
360
+ decode it. Being a copy, it can drift; §11.11 requires it to match the page's own.
361
+
362
+ ## 7. Cluster record (112 bytes)
363
+
364
+ Everything the runtime cut rule, culling, wants, and upload need — denormalized per
365
+ cluster so selection reads one record. Two kinds of spheres, deliberately distinct: the
366
+ **LOD-metric pair** (`self_sphere`/`parent_sphere` — shared per group step so all
367
+ siblings project identical values, monotonically inflated, never a tight fit) and the
368
+ **culling bounds** (`bounds_sphere`/`aabb` — this cluster's own tight fits, never used
369
+ in the cut test):
370
+
371
+ | offset | type | field | notes |
372
+ |-------:|----------|-----------------|-------|
373
+ | 0 | [f32; 4] | self_sphere | LOD-metric sphere (center xyz + radius) of the group step that created this cluster; leaves: equals `bounds_sphere` |
374
+ | 16 | f32 | self_error | object-space `r_e`; leaves: 0 |
375
+ | 20 | f32 | parent_error | error of the step that consumed it; roots: +∞ |
376
+ | 24 | [f32; 4] | parent_sphere | LOD-metric sphere of the consuming step; roots: duplicate of self_sphere |
377
+ | 40 | [f32; 4] | bounds_sphere | this cluster's own minimal bounding sphere (miniball), object-space — culling |
378
+ | 56 | [f32; 6] | aabb | this cluster's object-space AABB — culling, GPU metadata `bounds_box`, and the (future) dequantization grid |
379
+ | 80 | u16 | child_ref | index into this frame's child table; `SAME_PAGE` when the child group is in this page; `NO_CHILD` for leaves |
380
+ | 82 | u16 | child_group | group index within the child page (or this page, for `SAME_PAGE`); `NO_GROUP` for leaves |
381
+ | 84 | u32 | cone_reserved | reserved for backface-cone culling — **write 0**. No cull pass consumes a cone today and the producer needs a `BinaryTopology` port; the sub-encoding is pinned together with that pass, not before |
382
+ | 88 | u32 | encoding_flags | frozen bit table in §8 |
383
+ | 92 | u32 | payload_offset | into this page's payload section; ≡ 0 (mod 4) |
384
+ | 96 | u32 | payload_size | bytes; ≡ 0 (mod 4) |
385
+ | 100 | u8 | vertex_count | 3 ≤ n ≤ 128 |
386
+ | 101 | u8 | triangle_count | 1 ≤ n ≤ 128 |
387
+ | 102 | u16 | reserved | |
388
+ | 104 | u64 | reserved | |
389
+
390
+ Monotonicity (`parent_error ≥ self_error`, `parent_sphere ⊇ self_sphere`) is a build
391
+ invariant, not a reader concern. A single-cluster asset is valid: one root page, one
392
+ group with `parent_cluster_count = 0`, one cluster with `parent_error = +∞`,
393
+ `child_ref = NO_CHILD`, `child_page_count = 0`.
394
+
395
+ ## 8. Payload encoding
396
+
397
+ `payload_encoding = 1` (`SHADE_MESHLET_V1`). **Byte-compat scope**: the payload block is
398
+ byte-compatible with `GPUMeshletManager`'s **data pool** — uploading it is a copy. The
399
+ 40-byte GPU metadata rows (`MESHLET_METADATA_STRUCT`: bounds_box, address,
400
+ primitive_count, vertex_count, flags) are **synthesized at install** from the cluster
401
+ record (aabb → bounds_box, counts widened to u32, `address = slot_base_word +
402
+ payload_offset/4`, flags = encoding_flags) — a small pack step that is part of the
403
+ design's "VRAM paging mechanism is new work", not an existing patch path.
404
+
405
+ Payload block layout:
406
+
407
+ 1. Index section: `triangle_count × 3` local u8 indices, zero-padded to a 4-byte word
408
+ boundary.
409
+ 2. Attribute sections, in the frozen order below, each `words × vertex_count` u32
410
+ words — unless its `encoding_flags` bit marks it constant-compressed, in which case
411
+ exactly `words` u32s are stored once.
412
+
413
+ Frozen tables (byte-identical to Shade's `ENCODED_ORDERED_ATTRIBUTES`,
414
+ `ENCODED_ATTRIBUTE_SIZES`, `MESHLET_METADATA_FLAGS` as of this writing — the spec, not
415
+ the source, is now the authority for `.vgeo` files):
416
+
417
+ | # | attribute | words/vertex | encoding | flags bit (constant-compressed) | mask bit |
418
+ |---|-----------|-------------:|----------------------------|-------------------------------:|---------:|
419
+ | 0 | position | 3 | raw f32×3 | — (never compressed) | 0 |
420
+ | 1 | normal | 1 | octahedral u32 | 1 (0x01) | 1 |
421
+ | 2 | tangent | 1 | packed u32 | 2 (0x02) | 2 |
422
+ | 3 | color | 1 | RGBA8 u32 | 4 (0x04) | 3 |
423
+ | 4 | uv0 | 2 | raw f32×2 | 8 (0x08) | 4 |
424
+ | 5 | uv1 | 1 | 2×unorm16 u32 | 16 (0x10) | 5 |
425
+
426
+ - `encoding_flags` bits 5 (0x20, skinning joints) and 6 (0x40, skinning weights) MUST
427
+ be clear, and **no skinning sections are stored** — `SHADE_MESHLET_V1` payloads end
428
+ at uv1. (Load-bearing note: skinning attributes are last in Shade's attribute order
429
+ and the static decode path never addresses them, which is exactly what makes their
430
+ omission safe. VG is static-only, design §9.)
431
+ - All other `encoding_flags` bits are reserved, MUST be 0.
432
+ - An attribute the source lacks still ships its section, constant-compressed to the
433
+ engine default — **sections are never omitted**; `vertex_attribute_mask` is advisory
434
+ (which attributes carry real data). True section omission would shift every following
435
+ offset and is only expressible as a new `payload_encoding` id.
436
+
437
+ Quantized positions land as a **new `payload_encoding` id** (plus a page codec if
438
+ entropy coding pays). The cluster record already carries the dequantization grid
439
+ (`aabb`).
440
+
441
+ ## 9. Page directory (auxiliary)
442
+
443
+ Flat array of `total_pages` 32 B records at `directory_offset`; record `i` describes
444
+ page index `i` (page index order == file order == coarse-first). Auxiliary and fully
445
+ derivable from the frames (§3) — standard runtime traversal never reads it.
446
+
447
+ | offset | type | field | notes |
448
+ |-------:|------|----------------|-------|
449
+ | 0 | u64 | frame_offset | absolute; frame per §5 |
450
+ | 8 | u32 | fetch_size | as in the child table: the exact byte range to fetch is `[frame_offset, frame_offset + fetch_size)` |
451
+ | 12 | u32 | decoded_size | MUST equal the frame's |
452
+ | 16 | u8 | min_level | |
453
+ | 17 | u8 | max_level | |
454
+ | 18 | u16 | flags | bit 0: root page |
455
+ | 20 | u16 | group_count | |
456
+ | 22 | u16 | cluster_count | |
457
+ | 24 | u64 | reserved | |
458
+
459
+ **Directory integrity**: `dir_block_checksums` holds one xxh3-64 per 128 directory
460
+ records (one 4 KB block), seed = `asset_id_high64 XOR block_index`. Readers that use
461
+ the directory fetch it at block granularity and MUST verify.
462
+
463
+ ## 10. Reader requirements
464
+
465
+ Standard runtime operation is **pure traversal** — the directory is not involved:
466
+
467
+ - Cold start: fetch `[0, 256)`, verify `header_checksum`, magic, versions (§4 reject
468
+ rules), then fetch `[root_page_offset, root_page_offset + root_page_fetch_size)` — the
469
+ level table (§4.1) sits between the two, so a head prefix covering both brings the whole
470
+ always-resident set in one request. The root frame's `decoded_size` MUST equal
471
+ `root_page_decoded_size` and its frame extent MUST match `root_page_fetch_size`, else
472
+ reject. Or speculatively fetch one larger head prefix — coarse-first layout makes every
473
+ prefix byte useful.
474
+ - **Refinement**: a want is a `child_ref` in an installed page; its child-table entry
475
+ carries the exact byte range — one round-trip per cold page, no metadata fetch ever.
476
+ Wants dedup on `page_index` across clusters, groups, and instances. A want whose
477
+ target page is **already installed** resolves as an activation recheck of the
478
+ referenced group (below), never a fetch.
479
+ - **Activation (closure without dependency lists)** — the selectable invariant:
480
+
481
+ *A group `g` is selectable iff every one of its `parent_cluster_count` references is
482
+ live — the referencing cluster's page is installed and that cluster's own group is
483
+ selectable. Groups with `parent_cluster_count = 0` (exactly the root page's topmost
484
+ level) are selectable at install.*
485
+
486
+ By induction, a selectable cluster's entire ancestor cone is installed and
487
+ selectable — the closure the cut rule needs, restored by a per-group counter instead
488
+ of dependency lists. Runtime bookkeeping: each resident group keeps a live-reference
489
+ counter; when a group becomes selectable, its clusters' references (child-table and
490
+ `SAME_PAGE` alike) increment the referenced groups' counters — cascading
491
+ transitively; installing a page counts the existing live references into it (the
492
+ runtime maintains a reverse-reference index for pending pages — the same structure
493
+ that carries wants). Counters only grow while the pages involved stay resident (the
494
+ eviction rule below guarantees referencing parents outlive children). Activation
495
+ flips whole groups; the cut rule's clamp reads *selectable*, not merely resident
496
+ (design §4/§6): resident-but-inactive groups draw nothing, their coarser selectable
497
+ ancestors keep covering that surface — **no holes and no double-draw, in any arrival
498
+ order**, because a group never draws before all pages holding its parents are
499
+ installed and selectable.
500
+ - **In-flight protection**: a fetch discovered through parent page P pins P until the
501
+ child installs — known at queue time, purely local. Arrivals verify the
502
+ identity-seeded frame checksum; activation makes any arrival order safe beyond that.
503
+ - **Eviction**: within each residency tier, a page is evictable only while it has no
504
+ resident child pages in that tier — checked against its own child table (`SAME_PAGE`
505
+ references never pin). Leaves-first order emerges from the rule; the root page is
506
+ pinned.
507
+ - Verify every ranged response is `206` with the requested `Content-Range`; a `200`
508
+ means the server ignored the range — abort the transfer immediately (design §6).
509
+ - Verify frame checksums (identity-seeded, §5) before decode, and `decoded_size`
510
+ against the child-table entry used to fetch and against the codec's decode bound
511
+ (§5) before allocating for it. On mismatch: bounded retries with
512
+ backoff, then **quarantine** the page — the clamped cut keeps a coarse stand-in
513
+ correct indefinitely — and surface telemetry. Never retry-loop: corruption at a
514
+ content-addressed URL is deterministic.
515
+ - After install, stamp each cluster's selection row with its own page index and its
516
+ child page index/group (touch and want emission, design §6/§7).
517
+ - Fetch batching: coalesce adjacent wanted pages into contiguous single ranges; ranges
518
+ never cross a band boundary by construction (coarse-first ordering), so coalescing
519
+ lives within bands — the within-band spatial curve (§12) is what carries fetch
520
+ locality and must be chosen with that as a criterion. Fetching through small unwanted
521
+ gaps is permitted under an implementation waste threshold.
522
+ - Never assume `nominal_page_size`; per-page sizes come from child tables (traversal),
523
+ frames (prefix scan), or the directory (special tasks).
524
+
525
+ Build consequence (accepted): child tables hold downstream offsets — the format is
526
+ optimized for reading, and the builder pays for it. Preferred strategy: emit frames
527
+ with placeholder child tables, then **backpatch** them once all offsets are known, and
528
+ finalize frame checksums last (the checksum covers the child table). Computing the full
529
+ layout up front (compress all blobs → prefix-sum offsets → one forward emit) is equally
530
+ valid. Both are cheap and non-circular **because child tables are plaintext in the
531
+ frame**: a frame's extent (`24 + 48·children + stored_size`, with `stored_size` the
532
+ blob's compressed size) never depends on the offset values, and patching plaintext
533
+ bytes needs no re-compression. Build times are non-interactive by expectation —
534
+ clustering and simplification dominate regardless.
535
+
536
+ ## 11. Build invariants (validated at build, assumed by readers)
537
+
538
+ 1. A group's clusters are contiguous in one page (`cluster_first/cluster_count`); a
539
+ group never spans pages. Non-root pages span a single contiguous level band.
540
+ 2. Child tables are exact: deduplicated, one entry per distinct **other** page
541
+ referenced by this page's clusters (`SAME_PAGE` references appear in no child
542
+ table); every `child_ref`/`child_group` resolves to a valid entry and group;
543
+ `frame_offset`/`fetch_size`/`decoded_size` agree with the referenced frame and the
544
+ directory (all referencing pages agree by construction).
545
+ 3. Acyclicity and reachability: every child-table `frame_offset` is strictly greater
546
+ than the owning page's frame offset (file order is topological), and every page is
547
+ reachable from the root page through child tables.
548
+ 4. File order (== page index order) is coarse-first: the root page first, bands by
549
+ descending level, spatial locality within a band. The root page contains the
550
+ complete topmost level(s) — at minimum a complete drawable cut of the DAG. A
551
+ cluster's child group is always in a page whose band tops out strictly below its own
552
+ page's, unless the reference is `SAME_PAGE`.
553
+ 5. Group size: `1 ≤ cluster_count ≤ 4096` (format cap; builders target far less —
554
+ design §3 grouping is adaptive from ~4). `parent_cluster_count` equals the exact
555
+ number of clusters (across all pages, `SAME_PAGE` included) whose
556
+ `child_ref/child_group` name this group; it is 0 exactly for the root page's
557
+ topmost-level groups. A page holding one indivisible oversized group MAY exceed
558
+ `nominal_page_size`; the hard bound is the frame's u32 `stored_size`.
559
+ 6. `1 ≤ triangle_count ≤ 128`, `3 ≤ vertex_count ≤ 128` (Shade meshlet limits);
560
+ `total_clusters ≥ 1`; `source_vertex_count ≥ 3`, `source_face_count ≥ 1`.
561
+ 7. Error/sphere monotonicity per design §4; `self_error = 0` and `child_ref = NO_CHILD`
562
+ exactly for leaves; `parent_error = +∞` exactly for **the** root — there is exactly
563
+ one, and it is in page 0. Several parentless clusters would be several entry points,
564
+ and the cut only ever enters at one; it is also what an unconverged build leaves
565
+ behind, which is the likelier cause. All floats NaN-free.
566
+ `bounds_sphere` and `aabb` contain the cluster's decoded vertices; the header's
567
+ `object_sphere` and `object_bounds` contain the normalized source mesh.
568
+ 8. Payload offsets and sizes are 4-byte multiples; every payload decodes/uploads
569
+ against `payload_encoding` with no external state beyond its own cluster record.
570
+ A leaf's `self_error` of 0 is only as honest as the simplifier's metric — see design
571
+ §2, boundary constraint quadrics — and no reader-side check can distinguish an
572
+ exact coarse cluster from one whose error went unrecorded.
573
+ 9. `asset_id` and `header_checksum` verify per §4 — including its zeroing rule, which excludes
574
+ every derived checksum field; every frame verifies per §5; the directory verifies per §9 and
575
+ byte-for-byte matches what a frame scan reconstructs. `header_checksum` covers bytes 0–255
576
+ only, so the level table's integrity rests on `asset_id`, which covers the whole file.
577
+ 10. Every page's node table is a tree over exactly that page's groups: node 0 is the root, an
578
+ interior node's children are a contiguous run at a strictly greater index, `1 ≤ child_count ≤ 4`,
579
+ and the leaves partition the group table — each group reached through exactly one leaf. Each
580
+ node's metric bounds its whole subtree: its sphere contains every child's, its `min_self_error`
581
+ is no greater than any child's, its `max_parent_error` no less. The page header's metric equals
582
+ the root node's.
583
+ 11. Every child-table entry's metric equals the header metric of the page it names. It is a copy
584
+ read before that page is fetched, so nothing else can catch it having drifted — and a traversal
585
+ that trusts a stale one skips a page it needed and leaves a hole.
586
+ 12. Every frame names a defined `codec` (§5); a raw frame's `stored_size` equals its
587
+ `decoded_size`; and no frame's `decoded_size` exceeds what its codec could produce from
588
+ `stored_size` bytes. Every blob decodes to exactly `decoded_size` — a short decode is a
589
+ truncated page, and a page truncated to a plausible prefix is the one corruption that reads
590
+ as valid geometry with pieces missing.
591
+ 13. `root_page_offset = align16(256 + 32 · level_count)`; the level table's `cluster_count` and
592
+ `group_count` columns sum to `total_clusters` and `total_groups`; every level holds at least
593
+ one cluster and one group; `min_error ≤ max_error`, both finite and ≥ 0.
594
+
595
+ ## 12. Open
596
+
597
+ - Page codec ids beyond raw and LZ4 (§5). LZ4 is the default and is where the cheap
598
+ ratio is; a slower, denser codec (meshopt-style over the payload, deflate-family over
599
+ the tables) is a per-frame `codec` id away and costs no reader that already handles a
600
+ mixture. The quantized-position `payload_encoding` is the other half of the same
601
+ question, and would take most of what LZ4 currently finds.
602
+ - Default `nominal_page_size` (design §5: order hundreds of KB, measured).
603
+ - Spatial ordering curve within a level band (Morton over group centroids is the
604
+ default candidate; chosen with fetch-coalescing locality as an explicit criterion,
605
+ §10).
606
+ - Backface-cone cull pass and, with it, the `cone_reserved` sub-encoding.
607
+ - Multi-geometry containers (v1: one geometry per file; scenes reference many files).