@woosh/meep-engine 3.0.2 → 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 (1823) hide show
  1. package/LICENSE +188 -188
  2. package/README.md +152 -145
  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/grid/grid2transform/GridPosition2TransformSystem.d.ts +2 -2
  1072. package/src/engine/grid/grid2transform/GridPosition2TransformSystem.d.ts.map +1 -1
  1073. package/src/engine/input/GAMEPAD_API_PROPOSAL.md +717 -717
  1074. package/src/engine/input/analog/apply_radial_dead_zone.js +38 -38
  1075. package/src/engine/input/devices/GamepadDevice.js +466 -466
  1076. package/src/engine/input/devices/ManualInputDevice.js +152 -152
  1077. package/src/engine/input/devices/PointerCoordinates.js +26 -26
  1078. package/src/engine/input/devices/events/GamepadEvents.js +10 -10
  1079. package/src/engine/input/devices/gamepad/GamepadAxes.js +19 -19
  1080. package/src/engine/input/devices/gamepad/GamepadButtons.js +29 -29
  1081. package/src/engine/input/devices/gamepad/GamepadCoordinates.js +17 -17
  1082. package/src/engine/input/devices/gamepad/GamepadDeviceLayout.js +323 -323
  1083. package/src/engine/input/devices/gamepad/GamepadHandle.js +286 -286
  1084. package/src/engine/input/devices/gamepad/GamepadLayout.js +160 -160
  1085. package/src/engine/input/devices/gamepad/GamepadStandardMapping.js +31 -31
  1086. package/src/engine/input/devices/gamepad/GamepadStick.js +169 -169
  1087. package/src/engine/input/devices/gamepad/GamepadStickCalibration.js +119 -119
  1088. package/src/engine/input/devices/gamepad/GamepadStickCalibrator.js +250 -250
  1089. package/src/engine/input/devices/gamepad/gamepad_layout_database.js +144 -144
  1090. package/src/engine/input/devices/gamepad/gamepad_read_hat_axis.js +61 -61
  1091. package/src/engine/input/devices/gamepad/gamepad_write_dpad_vector.js +30 -30
  1092. package/src/engine/input/devices/gamepad/prototypeGamepadTester.js +2124 -2124
  1093. package/src/engine/input/devices/mouse/MouseButtons.js +22 -22
  1094. package/src/engine/input/ecs/components/Input.js +118 -118
  1095. package/src/engine/input/ecs/components/InputController.js +78 -78
  1096. package/src/engine/input/ecs/ism/ISM_DESIGN.md +1523 -1523
  1097. package/src/engine/input/ecs/ism/ISM_IMPLEMENTATION_PLAN.md +627 -627
  1098. package/src/engine/input/ecs/ism/InputActionEvent.js +40 -40
  1099. package/src/engine/input/ecs/ism/InputBinding.js +71 -71
  1100. package/src/engine/input/ecs/ism/InputCoordinateKind.js +25 -25
  1101. package/src/engine/input/ecs/ism/InputCoordinateSource.js +86 -86
  1102. package/src/engine/input/ecs/ism/InputDirection.js +33 -33
  1103. package/src/engine/input/ecs/ism/InputMapProgram.js +236 -236
  1104. package/src/engine/input/ecs/ism/InputMapSystem.js +976 -976
  1105. package/src/engine/input/ecs/ism/InputOcclusion.js +31 -31
  1106. package/src/engine/input/ecs/ism/InputSource.js +67 -67
  1107. package/src/engine/input/ecs/ism/InputSourceTable.js +107 -107
  1108. package/src/engine/input/ecs/ism/coordinate/InputCoordinateChannel.js +93 -93
  1109. package/src/engine/input/ecs/ism/coordinate/InputCoordinateChannelType.js +11 -11
  1110. package/src/engine/input/ecs/ism/coordinate/InputCoordinateDevice.js +153 -153
  1111. package/src/engine/input/ecs/ism/coordinate/InputCoordinateSwitches.js +160 -160
  1112. package/src/engine/input/ecs/ism/device/GAMEPAD_INPUT_DEVICE_ID.js +9 -9
  1113. package/src/engine/input/ecs/ism/device/GamepadInputDeviceAdapter.js +88 -88
  1114. package/src/engine/input/ecs/ism/device/InputDeviceAdapter.js +72 -72
  1115. package/src/engine/input/ecs/ism/device/KEYBOARD_INPUT_DEVICE_ID.js +9 -9
  1116. package/src/engine/input/ecs/ism/device/KeyboardInputDeviceAdapter.js +63 -63
  1117. package/src/engine/input/ecs/ism/device/ManualInputDeviceAdapter.js +55 -55
  1118. package/src/engine/input/ecs/ism/device/POINTER_INPUT_DEVICE_ID.js +9 -9
  1119. package/src/engine/input/ecs/ism/device/PointerInputDeviceAdapter.js +160 -160
  1120. package/src/engine/input/ecs/ism/map/InputBinding.js +88 -88
  1121. package/src/engine/input/ecs/ism/map/InputCoordinateBinding.js +102 -102
  1122. package/src/engine/input/ecs/ism/map/InputLayer.js +220 -220
  1123. package/src/engine/input/ecs/ism/map/InputMap.js +331 -331
  1124. package/src/engine/input/ecs/ism/prototypeInputMap.js +309 -309
  1125. package/src/engine/input/ecs/ism/trigger/InputTrigger.js +148 -148
  1126. package/src/engine/input/ecs/ism/trigger/InputTriggerChord.js +173 -173
  1127. package/src/engine/input/ecs/ism/trigger/InputTriggerGamepadButton.js +37 -37
  1128. package/src/engine/input/ecs/ism/trigger/InputTriggerHold.js +176 -176
  1129. package/src/engine/input/ecs/ism/trigger/InputTriggerKey.js +39 -39
  1130. package/src/engine/input/ecs/ism/trigger/InputTriggerMouseButton.js +38 -38
  1131. package/src/engine/input/ecs/ism/trigger/InputTriggerRelease.js +120 -120
  1132. package/src/engine/input/ecs/ism/trigger/InputTriggerSequence.js +315 -315
  1133. package/src/engine/input/ecs/ism/trigger/InputTriggerSwitch.js +105 -105
  1134. package/src/engine/input/ecs/ism/trigger/InputTriggerType.js +17 -17
  1135. package/src/engine/input/ecs/systems/InputControllerSystem.js +253 -253
  1136. package/src/engine/input/ecs/systems/InputSystem.js +162 -162
  1137. package/src/engine/intelligence/behavior/primitive/FailingBehaviorSerializationAdapter.js +25 -25
  1138. package/src/engine/intelligence/behavior/primitive/SucceedingBehaviorSerializationAdapter.js +26 -26
  1139. package/src/engine/intelligence/behavior/util/AsynchronousDelayAction.js +55 -55
  1140. package/src/engine/interpolation/BinaryInterpolationAdapter.js +56 -56
  1141. package/src/engine/interpolation/Interpoland.js +49 -49
  1142. package/src/engine/interpolation/Interpolated.js +149 -149
  1143. package/src/engine/interpolation/PoseInterpolationAdapter.js +61 -61
  1144. package/src/engine/interpolation/TransformPoseSerializationAdapter.js +57 -57
  1145. package/src/engine/interpolation/pose_interpoland.js +27 -27
  1146. package/src/engine/navigation/ecs/path_following/PathFollower.js +222 -222
  1147. package/src/engine/navigation/mesh/NavigationMesh.js +145 -145
  1148. package/src/engine/navigation/mesh/OVERLAPPING_SURFACES_2026_08_25.md +661 -0
  1149. package/src/engine/navigation/mesh/PATHFINDING_PLAN.md +229 -229
  1150. package/src/engine/navigation/mesh/build/clip_soup_against_overhangs.d.ts.map +1 -1
  1151. package/src/engine/navigation/mesh/build/clip_soup_against_overhangs.js +628 -520
  1152. package/src/engine/network/CONGESTION_CONTROL.md +87 -87
  1153. package/src/engine/network/README.md +52 -52
  1154. package/src/engine/network/adapters/QuaternionInterpolationAdapter.js +43 -43
  1155. package/src/engine/network/adapters/TransformInterpolationAdapter.js +84 -84
  1156. package/src/engine/network/adapters/TransformReplicationAdapter.js +87 -87
  1157. package/src/engine/network/adapters/Vector3InterpolationAdapter.js +46 -46
  1158. package/src/engine/network/convertPathToURL.js +2 -2
  1159. package/src/engine/network/core/MalformedPacketError.js +26 -26
  1160. package/src/engine/network/core/quantize/quantize_float.js +73 -73
  1161. package/src/engine/network/core/quantize/quantize_position.js +65 -65
  1162. package/src/engine/network/core/sequence/ack_bitfield.js +77 -77
  1163. package/src/engine/network/core/sequence/seq16.js +69 -69
  1164. package/src/engine/network/core/sequence/seq32.js +73 -73
  1165. package/src/engine/network/ecs/NetworkSystem.js +84 -84
  1166. package/src/engine/network/ecs/components/NetworkIdentity.js +73 -73
  1167. package/src/engine/network/ecs/owner_authorization.js +55 -55
  1168. package/src/engine/network/ecs/serialization/NetworkIdentitySerializationAdapter.js +64 -64
  1169. package/src/engine/network/replication/ScopeFilter.js +71 -71
  1170. package/src/engine/network/sim/ActionLog.js +152 -152
  1171. package/src/engine/network/sim/SimAction.js +273 -273
  1172. package/src/engine/network/sim/Snapshotter.js +222 -222
  1173. package/src/engine/network/state/FrameBufferRing.js +168 -168
  1174. package/src/engine/network/state/InputRing.js +134 -134
  1175. package/src/engine/network/state/PriorityAccumulator.js +180 -180
  1176. package/src/engine/network/time/TimeDilation.js +62 -62
  1177. package/src/engine/network/transport/Channel.js +336 -336
  1178. package/src/engine/network/transport/Transport.js +203 -203
  1179. package/src/engine/network/transport/adapters/NodeUDPTransport.js +186 -186
  1180. package/src/engine/network/transport/adapters/WebRTCDataChannelTransport.js +105 -105
  1181. package/src/engine/network/transport/fragments/fragment_send.js +147 -147
  1182. package/src/engine/network/transport/fragments/packet_size.js +101 -101
  1183. package/src/engine/network/xhr.js +23 -23
  1184. package/src/engine/physics/BULLET_REVIEW.md +945 -945
  1185. package/src/engine/physics/CANNON_REVIEW.md +1300 -1300
  1186. package/src/engine/physics/CONSTRAINT_SOLVER_BENCH_LOG.md +208 -208
  1187. package/src/engine/physics/CONSTRAINT_SOLVER_IMPROVEMENTS_PLAN.md +364 -364
  1188. package/src/engine/physics/INTEPOLATION_SYSTEM_PLAN.md +287 -287
  1189. package/src/engine/physics/JOLT_REVIEW.md +913 -913
  1190. package/src/engine/physics/PLAN.md +1120 -1094
  1191. package/src/engine/physics/RAPIER_REVIEW.md +934 -934
  1192. package/src/engine/physics/REVIEW_001_ACTION_PLAN.md +642 -642
  1193. package/src/engine/physics/REVIEW_002.md +151 -151
  1194. package/src/engine/physics/REVIEW_003.md +166 -166
  1195. package/src/engine/physics/broadphase/compute_fat_world_aabb.js +97 -97
  1196. package/src/engine/physics/constraint/DofMode.js +35 -35
  1197. package/src/engine/physics/constraint/solve_constraints.js +1 -1
  1198. package/src/engine/physics/contact/combine_material.js +35 -35
  1199. package/src/engine/physics/ecs/BodyKind.js +29 -29
  1200. package/src/engine/physics/ecs/Collider.js +177 -177
  1201. package/src/engine/physics/ecs/ColliderFlags.js +15 -15
  1202. package/src/engine/physics/ecs/ColliderSerializationAdapter.js +37 -37
  1203. package/src/engine/physics/ecs/Joint.js +475 -475
  1204. package/src/engine/physics/ecs/JointSerializationAdapter.js +72 -72
  1205. package/src/engine/physics/ecs/PhysicsSystem.d.ts +3 -0
  1206. package/src/engine/physics/ecs/PhysicsSystem.d.ts.map +1 -1
  1207. package/src/engine/physics/ecs/PhysicsSystem.js +7 -2
  1208. package/src/engine/physics/ecs/RigidBodySerializationUpgrader_0_1.js +37 -37
  1209. package/src/engine/physics/ecs/SleepState.js +12 -12
  1210. package/src/engine/physics/ecs/find_non_finite_physics_state.js +76 -76
  1211. package/src/engine/physics/fluid/FluidField.js +867 -867
  1212. package/src/engine/physics/fluid/FluidSimulator.js +832 -832
  1213. package/src/engine/physics/fluid/REVIEW_02_PLAN.md +243 -243
  1214. package/src/engine/physics/fluid/SliceVisualiser.js +190 -190
  1215. package/src/engine/physics/fluid/ecs/FluidComponent.js +239 -239
  1216. package/src/engine/physics/fluid/ecs/FluidEffectorsComponent.js +89 -89
  1217. package/src/engine/physics/fluid/ecs/FluidObstacle.js +97 -97
  1218. package/src/engine/physics/fluid/ecs/FluidObstacleSystem.js +348 -348
  1219. package/src/engine/physics/fluid/ecs/FluidSystem.js +142 -142
  1220. package/src/engine/physics/fluid/ecs/FluidWorkerCore.js +123 -123
  1221. package/src/engine/physics/fluid/ecs/WorkerFluidSystem.js +395 -395
  1222. package/src/engine/physics/fluid/ecs/fluid.worker.js +12 -12
  1223. package/src/engine/physics/fluid/ecs/fluid_build_world_to_grid.js +32 -32
  1224. package/src/engine/physics/fluid/ecs/fluid_gather_visible_effectors.js +47 -47
  1225. package/src/engine/physics/fluid/ecs/fluid_reanchor_field.js +85 -85
  1226. package/src/engine/physics/fluid/ecs/fluid_sync_effectors_from_transform.js +16 -16
  1227. package/src/engine/physics/fluid/ecs/fluid_worker_protocol.js +111 -111
  1228. package/src/engine/physics/fluid/ecs/makeFluidWorker.js +18 -18
  1229. package/src/engine/physics/fluid/effector/AbstractFluidEffector.js +81 -81
  1230. package/src/engine/physics/fluid/effector/GlobalFluidEffector.js +202 -202
  1231. package/src/engine/physics/fluid/effector/ImpulseFluidEffector.js +257 -257
  1232. package/src/engine/physics/fluid/effector/WakeFluidEffector.js +405 -405
  1233. package/src/engine/physics/fluid/prototype.js +126 -126
  1234. package/src/engine/physics/fluid/solver/v3_grid_advect_maccormack_scalar.js +143 -143
  1235. package/src/engine/physics/fluid/solver/v3_grid_advect_maccormack_velocity.js +162 -162
  1236. package/src/engine/physics/fluid/solver/v3_grid_advect_sl_velocity.js +107 -107
  1237. package/src/engine/physics/fluid/solver/v3_grid_apply_vorticity_confinement.js +131 -131
  1238. package/src/engine/physics/fluid/solver/v3_grid_compute_solid_neighbour_mask.js +90 -90
  1239. package/src/engine/physics/fluid/solver/v3_grid_limit8_at_indices.js +38 -38
  1240. package/src/engine/physics/fluid/solver/v3_grid_patch_edges_constant.js +77 -77
  1241. package/src/engine/physics/fluid/solver/v3_grid_patch_edges_uniform.js +113 -113
  1242. package/src/engine/physics/fluid/solver/v3_grid_sample_scalar_masked.js +92 -92
  1243. package/src/engine/physics/fluid/solver/v3_grid_shift_in_place.js +107 -107
  1244. package/src/engine/physics/fluid/solver/v3_grid_solve_pressure.js +135 -135
  1245. package/src/engine/physics/fluid/solver/v3_grid_solve_pressure_pcg.js +511 -511
  1246. package/src/engine/physics/fluid/solver/v3_grid_subtract_pressure_gradient.js +108 -108
  1247. package/src/engine/physics/fluid/solver/v3_mac_advect_maccormack_velocity.js +317 -317
  1248. package/src/engine/physics/fluid/solver/v3_mac_advect_scalar.js +236 -236
  1249. package/src/engine/physics/fluid/solver/v3_mac_advect_sl_velocity.js +217 -217
  1250. package/src/engine/physics/fluid/solver/v3_mac_apply_vorticity_confinement.js +174 -174
  1251. package/src/engine/physics/fluid/solver/v3_mac_clip_trace.js +95 -95
  1252. package/src/engine/physics/fluid/solver/v3_mac_compute_divergence.js +77 -77
  1253. package/src/engine/physics/fluid/solver/v3_mac_compute_face_solid.js +131 -131
  1254. package/src/engine/physics/fluid/solver/v3_mac_subtract_pressure_gradient.js +104 -104
  1255. package/src/engine/physics/inertia/world_inverse_inertia.js +160 -160
  1256. package/src/engine/physics/integration/integrate_position.js +97 -97
  1257. package/src/engine/physics/narrowphase/box_box_manifold.js +681 -681
  1258. package/src/engine/physics/narrowphase/box_triangle_contact.js +906 -906
  1259. package/src/engine/physics/narrowphase/capsule_triangle_contact.js +395 -395
  1260. package/src/engine/physics/narrowphase/compute_penetration.js +369 -369
  1261. package/src/engine/physics/narrowphase/decomposition/decompose_to_triangles.js +55 -55
  1262. package/src/engine/physics/narrowphase/decomposition/triangle_buffer_layout.js +37 -37
  1263. package/src/engine/physics/narrowphase/mesh_mesh_tet_manifold.js +117 -117
  1264. package/src/engine/physics/narrowphase/narrowphase_step.js +1738 -1738
  1265. package/src/engine/physics/narrowphase/reduce_manifold_contacts.js +74 -74
  1266. package/src/engine/physics/narrowphase/refine_ray_hit.d.ts +12 -11
  1267. package/src/engine/physics/narrowphase/refine_ray_hit.d.ts.map +1 -1
  1268. package/src/engine/physics/narrowphase/refine_ray_hit.js +228 -36
  1269. package/src/engine/physics/narrowphase/sphere_sphere_contact.js +52 -52
  1270. package/src/engine/physics/narrowphase/sphere_triangle_contact.js +138 -138
  1271. package/src/engine/physics/persistence/solver_caches.js +309 -309
  1272. package/src/engine/physics/queries/overlap_shape.js +187 -187
  1273. package/src/engine/physics/queries/raycast.d.ts +7 -4
  1274. package/src/engine/physics/queries/raycast.d.ts.map +1 -1
  1275. package/src/engine/physics/queries/raycast.js +11 -5
  1276. package/src/engine/physics/queries/shape_cast.js +417 -417
  1277. package/src/engine/physics/solver/apply_impulse_to_body.js +86 -86
  1278. package/src/engine/physics/solver/friction_cone.js +37 -37
  1279. package/src/engine/physics/solver/solve_contacts.js +1 -1
  1280. package/src/engine/platform/WebEnginePlatform.d.ts.map +1 -1
  1281. package/src/engine/platform/WebEnginePlatform.js +1 -2
  1282. package/src/engine/scene/SerializedScene.d.ts +2 -2
  1283. package/src/engine/scene/SerializedScene.d.ts.map +1 -1
  1284. package/src/engine/scene/transitionToScene.js +121 -121
  1285. package/src/engine/simulation/Ticker.d.ts.map +1 -1
  1286. package/src/engine/simulation/Ticker.js +33 -0
  1287. package/src/engine/sound/ecs/audio/LiveEmitterSet.js +345 -345
  1288. package/src/engine/sound/ecs/audio/SpatialAudioIndex.js +140 -140
  1289. package/src/engine/sound/simulation/AcousticSimulator.js +646 -646
  1290. package/src/engine/sound/simulation/IMPLEMENTATION_PLAN.md +432 -432
  1291. package/src/engine/sound/simulation/PROBE_PLACEMENT.md +250 -250
  1292. package/src/engine/sound/simulation/PROBE_TRANSFER_RESEARCH.md +322 -322
  1293. package/src/engine/sound/simulation/README.md +277 -277
  1294. package/src/engine/sound/simulation/REFLECTION_IR_PLAN.md +261 -261
  1295. package/src/engine/sound/simulation/VISIBILITY_GRAPH_PLAN.md +121 -121
  1296. package/src/engine/sound/simulation/configureAcousticSimulation.js +48 -48
  1297. package/src/engine/sound/simulation/core/AcousticMedium.js +113 -113
  1298. package/src/engine/sound/simulation/core/AcousticMediumSerializationAdapter.js +27 -27
  1299. package/src/engine/sound/simulation/core/AcousticOccluderIndex.js +312 -312
  1300. package/src/engine/sound/simulation/core/AcousticRegionIndex.js +159 -159
  1301. package/src/engine/sound/simulation/core/AcousticSolution.js +90 -90
  1302. package/src/engine/sound/simulation/core/AcousticSourceState.js +109 -109
  1303. package/src/engine/sound/simulation/core/AcousticVolumeRegion.js +73 -73
  1304. package/src/engine/sound/simulation/core/OcclusionSolver.js +112 -112
  1305. package/src/engine/sound/simulation/core/RayHit.js +50 -50
  1306. package/src/engine/sound/simulation/core/VolumeField.js +149 -149
  1307. package/src/engine/sound/simulation/definition/AcousticDirectivity.js +114 -114
  1308. package/src/engine/sound/simulation/definition/AcousticDirectivitySerializationAdapter.js +30 -30
  1309. package/src/engine/sound/simulation/definition/AcousticMaterial.js +122 -122
  1310. package/src/engine/sound/simulation/definition/AcousticMaterialSerializationAdapter.js +32 -32
  1311. package/src/engine/sound/simulation/ecs/AcousticBody.js +48 -48
  1312. package/src/engine/sound/simulation/ecs/AcousticBodySerializationAdapter.js +34 -34
  1313. package/src/engine/sound/simulation/ecs/AcousticProbeFieldSystem.js +64 -64
  1314. package/src/engine/sound/simulation/ecs/AcousticSimulationSystem.js +75 -75
  1315. package/src/engine/sound/simulation/ecs/AcousticVolume.js +74 -74
  1316. package/src/engine/sound/simulation/ecs/AcousticVolumeSerializationAdapter.js +37 -37
  1317. package/src/engine/sound/simulation/ecs/AcousticVolumeSystem.js +66 -66
  1318. package/src/engine/sound/simulation/probe/AcousticProbeField.js +578 -578
  1319. package/src/engine/sound/simulation/probe/AcousticProbeFieldSerializationAdapter.js +60 -60
  1320. package/src/engine/sound/simulation/probe/ProbeFieldPathingSolution.js +64 -64
  1321. package/src/engine/sound/simulation/probe/ProbeVisibilityRecheck.js +132 -132
  1322. package/src/engine/sound/simulation/probe/acoustic_probe_transfer.js +103 -103
  1323. package/src/engine/sound/simulation/probe/acoustic_trace_energy.js +136 -136
  1324. package/src/engine/sound/simulation/probe/bakeProbeField.js +169 -169
  1325. package/src/engine/sound/simulation/probe/bakeProbeReflectors.js +110 -110
  1326. package/src/engine/sound/simulation/probe/bakeReverbBands.js +110 -110
  1327. package/src/engine/sound/simulation/probe/bakeVisibility.js +148 -148
  1328. package/src/engine/sound/simulation/probe/echogram_band_rt60.js +83 -83
  1329. package/src/engine/sound/simulation/probe/probe_delaunay_edges.js +215 -215
  1330. package/src/engine/sound/simulation/probe/probe_densify_portals.js +140 -140
  1331. package/src/engine/sound/simulation/probe/probe_detect_portals.js +196 -196
  1332. package/src/engine/sound/simulation/probe/probe_edge_key.js +38 -38
  1333. package/src/engine/sound/simulation/probe/probe_edge_visible.js +41 -41
  1334. package/src/engine/sound/simulation/probe/probe_place_sdf_cover.js +82 -82
  1335. package/src/engine/sound/simulation/probe/probe_refine_connectivity.js +181 -181
  1336. package/src/engine/sound/simulation/probe/probe_sdf_grid.js +171 -171
  1337. package/src/engine/sound/simulation/probe/probe_visibility_augment.js +146 -146
  1338. package/src/engine/sound/simulation/probe/probe_visibility_bridge_components.js +167 -167
  1339. package/src/engine/sound/simulation/render/FoaProbeReverbRenderer.js +354 -354
  1340. package/src/engine/sound/simulation/render/ProbeReverbRenderer.js +231 -231
  1341. package/src/engine/sound/simulation/render/foaReverbImpulseResponse.js +105 -105
  1342. package/src/engine/sound/simulation/render/reverbImpulseResponse.js +66 -66
  1343. package/src/engine/sound/simulation/render/reverb_band_tails.js +93 -93
  1344. package/src/engine/sound/simulation/serialization/populateAcousticSerializationRegistry.js +25 -25
  1345. package/src/engine/sound/sopra/README.md +643 -643
  1346. package/src/engine/sound/sopra/SopraEngine.js +432 -432
  1347. package/src/engine/sound/sopra/asset/AssetManagerBufferProvider.js +71 -71
  1348. package/src/engine/sound/sopra/asset/BufferProvider.js +29 -29
  1349. package/src/engine/sound/sopra/asset/StubBufferProvider.js +58 -58
  1350. package/src/engine/sound/sopra/definition/BusDefinition.js +142 -142
  1351. package/src/engine/sound/sopra/definition/BusDefinitionSerializationAdapter.js +54 -54
  1352. package/src/engine/sound/sopra/definition/DuckingRule.js +106 -106
  1353. package/src/engine/sound/sopra/definition/DuckingRuleSerializationAdapter.js +31 -31
  1354. package/src/engine/sound/sopra/definition/EventDescription.js +262 -262
  1355. package/src/engine/sound/sopra/definition/EventDescriptionSerializationAdapter.js +55 -55
  1356. package/src/engine/sound/sopra/definition/MixerSnapshot.js +83 -83
  1357. package/src/engine/sound/sopra/definition/MixerSnapshotSerializationAdapter.js +39 -39
  1358. package/src/engine/sound/sopra/definition/ParameterDefinition.js +117 -117
  1359. package/src/engine/sound/sopra/definition/ParameterDefinitionSerializationAdapter.js +31 -31
  1360. package/src/engine/sound/sopra/definition/VoiceStealMode.js +18 -18
  1361. package/src/engine/sound/sopra/definition/clip/AbstractAudioClip.js +109 -109
  1362. package/src/engine/sound/sopra/definition/clip/BlendContainerAudioClip.js +185 -185
  1363. package/src/engine/sound/sopra/definition/clip/BlendContainerAudioClipSerializationAdapter.js +59 -59
  1364. package/src/engine/sound/sopra/definition/clip/ContainerAudioClip.js +128 -128
  1365. package/src/engine/sound/sopra/definition/clip/RandomContainerAudioClip.js +226 -226
  1366. package/src/engine/sound/sopra/definition/clip/RandomContainerAudioClipSerializationAdapter.js +54 -54
  1367. package/src/engine/sound/sopra/definition/clip/SampleAudioClip.js +191 -191
  1368. package/src/engine/sound/sopra/definition/clip/SampleAudioClipSerializationAdapter.js +39 -39
  1369. package/src/engine/sound/sopra/definition/clip/SequenceContainerAudioClip.js +79 -79
  1370. package/src/engine/sound/sopra/definition/clip/SequenceContainerAudioClipSerializationAdapter.js +42 -42
  1371. package/src/engine/sound/sopra/definition/clip/SilenceAudioClip.js +77 -77
  1372. package/src/engine/sound/sopra/definition/clip/SilenceAudioClipSerializationAdapter.js +27 -27
  1373. package/src/engine/sound/sopra/definition/clip/SwitchContainerAudioClip.d.ts +5 -0
  1374. package/src/engine/sound/sopra/definition/clip/SwitchContainerAudioClip.d.ts.map +1 -1
  1375. package/src/engine/sound/sopra/definition/clip/SwitchContainerAudioClip.js +125 -125
  1376. package/src/engine/sound/sopra/definition/clip/SwitchContainerAudioClipSerializationAdapter.js +41 -41
  1377. package/src/engine/sound/sopra/definition/effect/AbstractAudioEffect.js +24 -24
  1378. package/src/engine/sound/sopra/definition/effect/CompressorEffect.js +120 -120
  1379. package/src/engine/sound/sopra/definition/effect/CompressorEffectSerializationAdapter.js +31 -31
  1380. package/src/engine/sound/sopra/definition/effect/EqEffect.js +128 -128
  1381. package/src/engine/sound/sopra/definition/effect/EqEffectSerializationAdapter.js +29 -29
  1382. package/src/engine/sound/sopra/definition/effect/ReverbEffect.js +113 -113
  1383. package/src/engine/sound/sopra/definition/effect/ReverbEffectSerializationAdapter.js +25 -25
  1384. package/src/engine/sound/sopra/runtime/BusGraph.js +231 -231
  1385. package/src/engine/sound/sopra/runtime/ParameterStore.js +98 -98
  1386. package/src/engine/sound/sopra/runtime/SopraPlaybackContext.js +68 -68
  1387. package/src/engine/sound/sopra/runtime/Voice.js +145 -145
  1388. package/src/engine/sound/sopra/runtime/VoiceManager.js +136 -136
  1389. package/src/engine/sound/sopra/runtime/VoicePool.js +17 -17
  1390. package/src/engine/sound/sopra/serialization/populateSopraSerializationRegistry.js +42 -42
  1391. package/src/engine/sound/sopra/serialization/sopraJSON.js +99 -99
  1392. package/src/engine/sound/sopra/serialization/sopraSerializationHarness.js +49 -49
  1393. package/src/engine/sound/sopra/util/MockAudioContext.js +224 -224
  1394. package/src/engine/sound/sopra/util/fadeOutAndStop.js +60 -60
  1395. package/src/engine/ui/DraggableAspect.js +115 -115
  1396. package/src/engine/ui/apply_pointer_tilt_3d.js +50 -50
  1397. package/src/generation/COORDINATES.md +54 -54
  1398. package/src/generation/GridGenerationResource.js +24 -24
  1399. package/src/generation/GridTaskGroup.js +214 -214
  1400. package/src/generation/REVIEW_01_ACTION_PLAN.md +628 -628
  1401. package/src/generation/automata/CaveGeneratorCellularAutomata.js +79 -79
  1402. package/src/generation/automata/CellularAutomata.js +22 -22
  1403. package/src/generation/compute_writes_union.js +25 -25
  1404. package/src/generation/filtering/CellFilter.js +117 -117
  1405. package/src/generation/filtering/core/CellFilterBinaryOperation.js +37 -37
  1406. package/src/generation/filtering/core/CellFilterOperationTertiary.js +43 -43
  1407. package/src/generation/filtering/core/CellFilterUnaryOperation.js +29 -29
  1408. package/src/generation/filtering/numeric/process/computeCellFilterSobel.js +36 -36
  1409. package/src/generation/filtering/numeric/process/computeFilterSurfaceNormal.js +42 -42
  1410. package/src/generation/filtering/numeric/util/populateSampler2DFromCellFilter.js +18 -18
  1411. package/src/generation/filtering/numeric/util/write_cell_filter_to_sampler2d.js +47 -47
  1412. package/src/generation/filtering/util/cell_filter_weights_pick.js +54 -54
  1413. package/src/generation/grid/GridData.js +233 -233
  1414. package/src/generation/grid/coords/grid_to_texel.js +10 -10
  1415. package/src/generation/grid/coords/texel_to_grid.js +10 -10
  1416. package/src/generation/grid/generation/GridTaskApplyActionToCells.js +90 -90
  1417. package/src/generation/grid/generation/GridTaskDensityMarkerDistribution.js +388 -388
  1418. package/src/generation/grid/generation/GridTaskExecuteRuleTimes.js +127 -127
  1419. package/src/generation/grid/generation/GridTaskSequence.js +58 -58
  1420. package/src/generation/grid/generation/NoopGridTaskGenerator.js +12 -12
  1421. package/src/generation/grid/generation/discrete/GridTaskActionRuleSet.js +48 -48
  1422. package/src/generation/grid/generation/discrete/GridTaskCellularAutomata.js +146 -146
  1423. package/src/generation/grid/generation/discrete/GridTaskConnectRooms.js +540 -540
  1424. package/src/generation/grid/generation/discrete/layer/GridTaskBuildSourceDistanceMap.js +222 -222
  1425. package/src/generation/grid/generation/grid/GridTaskAddNodesFixed.js +44 -44
  1426. package/src/generation/grid/generation/road/GridTaskGenerateRoads.js +614 -614
  1427. package/src/generation/markers/GridCellActionPlaceMarker.js +244 -244
  1428. package/src/generation/markers/GridCellActionPlaceMarkerGroup.js +86 -86
  1429. package/src/generation/markers/actions/terrain/MarkerNodeActionPaintTerrain.js +266 -266
  1430. package/src/generation/markers/emitter/MarkerNodeEmitterGridCellAction.js +49 -49
  1431. package/src/generation/placement/GridCellActionTransformNearbyMarkers.js +120 -120
  1432. package/src/generation/placement/action/GridCellAction.js +45 -45
  1433. package/src/generation/placement/action/GridCellActionPlaceTags.js +140 -140
  1434. package/src/generation/placement/action/GridCellActionWriteFilterToLayer.js +89 -89
  1435. package/src/generation/placement/action/random/CellActionSelectRandom.js +69 -69
  1436. package/src/generation/placement/action/random/weighted/CellActionSelectWeightedRandom.js +91 -91
  1437. package/src/generation/placement/action/util/GridCellActionSequence.js +61 -61
  1438. package/src/generation/placement/action/util/GridCellDisplacedAction.js +61 -61
  1439. package/src/generation/rules/cell/CellMatcherRemovalPreservesConnectivity.js +183 -183
  1440. package/src/generation/theme/ThemeEngine.js +666 -666
  1441. package/src/shade/RENDERER_CONTRACT.md +568 -0
  1442. package/src/shade/descriptor/texture/format/gpu_texture_format_info.js +267 -267
  1443. package/src/shade/device/ShadeDeviceFailure.js +104 -104
  1444. package/src/shade/device/ShadeDeviceFailureReason.js +41 -41
  1445. package/src/shade/device/mock/IMPLEMENTATION_PLAN.md +255 -255
  1446. package/src/shade/device/mock/REVIEW_2026_08_22.md +527 -527
  1447. package/src/shade/device/mock/SoftwareGPUBindGroup.js +23 -23
  1448. package/src/shade/device/mock/SoftwareGPUBindGroupLayout.js +22 -22
  1449. package/src/shade/device/mock/SoftwareGPUError.js +63 -63
  1450. package/src/shade/device/mock/SoftwareGPUPipeline.js +75 -75
  1451. package/src/shade/device/mock/SoftwareGPUQuerySet.js +113 -113
  1452. package/src/shade/device/mock/SoftwareGPUSampler.js +30 -30
  1453. package/src/shade/device/mock/SoftwareGPUShaderModule.js +32 -32
  1454. package/src/shade/device/mock/SoftwareGPUTextureView.js +22 -22
  1455. package/src/shade/device/mock/SoftwareGPUUncapturedErrorEvent.js +23 -23
  1456. package/src/shade/device/mock/normalize_dynamic_offsets.js +26 -26
  1457. package/src/shade/device/mock/texture_copy.js +287 -287
  1458. package/src/shade/device/timing/GPUTimer.js +285 -285
  1459. package/src/shade/device/timing/GPUTimerArray.js +205 -205
  1460. package/src/shade/playground/add_random_lights.js +49 -49
  1461. package/src/shade/playground/add_random_meshes.js +83 -83
  1462. package/src/shade/playground/animation_prototype.js +508 -508
  1463. package/src/shade/playground/animation_prototype_skinning.js +647 -647
  1464. package/src/shade/playground/animation_prototype_stress.js +765 -765
  1465. package/src/shade/playground/enable_picker.js +59 -59
  1466. package/src/shade/playground/gltf_skinned_prototype.js +560 -560
  1467. package/src/shade/playground/gltf_skinned_stress_prototype.js +387 -387
  1468. package/src/shade/playground/gltf_viewer.js +282 -282
  1469. package/src/shade/playground/load_default_environment.js +19 -19
  1470. package/src/shade/playground/main.js +2727 -2727
  1471. package/src/shade/playground/make_animated_instances.js +117 -117
  1472. package/src/shade/playground/prototype_virtual_texture.js +274 -274
  1473. package/src/shade/playground/prototype_volumetrics_01.js +206 -206
  1474. package/src/shade/playground/sample.js +234 -234
  1475. package/src/shade/playground/sample_load_gltf.js +102 -102
  1476. package/src/shade/playground/spread_node3d_grid.js +19 -19
  1477. package/src/shade/renderer/Renderer.js +2436 -2436
  1478. package/src/shade/renderer/ShadeIndirectLightingMode.js +14 -14
  1479. package/src/shade/renderer/animation/ShadeAnimationChannel.js +414 -414
  1480. package/src/shade/renderer/animation/compute_skinned_mesh_clip_bounding_sphere.js +531 -531
  1481. package/src/shade/renderer/animation/pose/PosePlayback.js +55 -55
  1482. package/src/shade/renderer/animation/pose/pose_evaluate_local.js +179 -179
  1483. package/src/shade/renderer/animation/pose/pose_evaluate_world.js +76 -76
  1484. package/src/shade/renderer/animation/skinning/GPUMeshSkinningContext.js +1024 -1024
  1485. package/src/shade/renderer/animation/skinning/SKINNING_BINDING_STRUCT.js +79 -79
  1486. package/src/shade/renderer/animation/skinning/chunk_skin_blend_mesh_local.js +56 -56
  1487. package/src/shade/renderer/binding/BindGroupManager.js +282 -282
  1488. package/src/shade/renderer/binding/adapt_cache_capacity.js +25 -25
  1489. package/src/shade/renderer/buffer/GPUBufferAllocator.js +116 -116
  1490. package/src/shade/renderer/buffer/buffer_pool_ops.js +123 -123
  1491. package/src/shade/renderer/buffer/table/GPU_DATABASE_PAGE_SIZE.js +9 -9
  1492. package/src/shade/renderer/buffer/table/GPU_DATABASE_UPLOAD_BUFFER_LIMIT.js +8 -8
  1493. package/src/shade/renderer/buffer/table/PageBufferPool.js +71 -71
  1494. package/src/shade/renderer/buffer/table/PageSlotAllocator.js +95 -95
  1495. package/src/shade/renderer/camera/Camera.js +281 -281
  1496. package/src/shade/renderer/camera/GPUCameraContext.js +233 -233
  1497. package/src/shade/renderer/camera/orbital/README.md +84 -84
  1498. package/src/shade/renderer/deferred/shader_composite_volumetrics.js +75 -75
  1499. package/src/shade/renderer/dynamic/DYNAMIC_MESH_VERTEX.js +25 -25
  1500. package/src/shade/renderer/dynamic/GPUDynamicMeshRenderer.js +342 -342
  1501. package/src/shade/renderer/dynamic/GPUDynamicMeshResidency.js +167 -167
  1502. package/src/shade/renderer/dynamic/shader_dynamic_mesh.js +170 -170
  1503. package/src/shade/renderer/extension/FrameContext.js +263 -263
  1504. package/src/shade/renderer/extension/FramePhase.js +104 -104
  1505. package/src/shade/renderer/extension/FrameRecord.js +126 -126
  1506. package/src/shade/renderer/extension/GBufferTextures.js +83 -83
  1507. package/src/shade/renderer/extension/PresentTarget.js +34 -34
  1508. package/src/shade/renderer/extension/RENDER_EXTENSION_DESIGN.md +918 -918
  1509. package/src/shade/renderer/extension/RenderExtension.js +69 -69
  1510. package/src/shade/renderer/extension/RenderExtensionRegistry.js +319 -319
  1511. package/src/shade/renderer/extension/SceneColor.js +40 -40
  1512. package/src/shade/renderer/extension/ViewTextures.js +78 -78
  1513. package/src/shade/renderer/fow/GPUFogOfWarRenderer.js +182 -182
  1514. package/src/shade/renderer/geometry/Geometry.js +608 -608
  1515. package/src/shade/renderer/geometry/geometry_build_from_meshlet_geometry.js +342 -342
  1516. package/src/shade/renderer/geometry/meshlet_geometry_transfer.js +41 -41
  1517. package/src/shade/renderer/geometry/primitives/make_box_geometry.js +153 -153
  1518. package/src/shade/renderer/geometry/primitives/make_cylinder_geometry.js +240 -240
  1519. package/src/shade/renderer/geometry/primitives/make_plane_geometry.js +145 -145
  1520. package/src/shade/renderer/geometry/primitives/make_polyhedron_geometry.js +327 -327
  1521. package/src/shade/renderer/geometry/primitives/make_torus_geometry.js +107 -107
  1522. package/src/shade/renderer/geometry/primitives/make_torus_knot_geometry.js +165 -165
  1523. package/src/shade/renderer/geometry/virtual/VGEO_FORMAT.md +607 -607
  1524. package/src/shade/renderer/geometry/virtual/build/VGeoBuildOptions.js +66 -66
  1525. package/src/shade/renderer/geometry/virtual/build/VGeoBuildResult.js +32 -32
  1526. package/src/shade/renderer/geometry/virtual/build/VGeoFaceGraph.js +103 -103
  1527. package/src/shade/renderer/geometry/virtual/build/VGeoGatheredFaces.js +25 -25
  1528. package/src/shade/renderer/geometry/virtual/build/VGeoLevel.js +33 -33
  1529. package/src/shade/renderer/geometry/virtual/build/VGeoLevelOptions.js +62 -62
  1530. package/src/shade/renderer/geometry/virtual/build/VGeoLevelSummary.js +49 -49
  1531. package/src/shade/renderer/geometry/virtual/build/VGeoSubmesh.js +20 -20
  1532. package/src/shade/renderer/geometry/virtual/build/VirtualGeometryMesh.js +214 -214
  1533. package/src/shade/renderer/geometry/virtual/build/gltf/GltfByteSource.js +122 -122
  1534. package/src/shade/renderer/geometry/virtual/build/gltf/GltfCollectReport.js +29 -29
  1535. package/src/shade/renderer/geometry/virtual/build/gltf/GltfDocument.js +210 -210
  1536. package/src/shade/renderer/geometry/virtual/build/gltf/GltfGeometry.js +48 -48
  1537. package/src/shade/renderer/geometry/virtual/build/gltf/GltfGeometryInstance.js +25 -25
  1538. package/src/shade/renderer/geometry/virtual/build/gltf/GltfGeometrySelection.js +28 -28
  1539. package/src/shade/renderer/geometry/virtual/build/gltf/gltf_collect_geometries.js +296 -296
  1540. package/src/shade/renderer/geometry/virtual/build/gltf/gltf_open_document.js +166 -166
  1541. package/src/shade/renderer/geometry/virtual/build/gltf/gltf_read_geometry.js +199 -199
  1542. package/src/shade/renderer/geometry/virtual/build/vgeo_assemble_pages.js +173 -173
  1543. package/src/shade/renderer/geometry/virtual/build/vgeo_bounding_sphere.js +28 -28
  1544. package/src/shade/renderer/geometry/virtual/build/vgeo_build.js +200 -200
  1545. package/src/shade/renderer/geometry/virtual/build/vgeo_build_levels.js +1786 -1786
  1546. package/src/shade/renderer/geometry/virtual/build/vgeo_build_page_nodes.js +157 -157
  1547. package/src/shade/renderer/geometry/virtual/build/vgeo_build_root_group.js +26 -26
  1548. package/src/shade/renderer/geometry/virtual/build/vgeo_compute_vertex_normals.js +75 -75
  1549. package/src/shade/renderer/geometry/virtual/build/vgeo_compute_vertex_tangents.js +143 -143
  1550. package/src/shade/renderer/geometry/virtual/build/vgeo_containing_sphere.js +44 -44
  1551. package/src/shade/renderer/geometry/virtual/build/vgeo_extract_submesh.js +41 -41
  1552. package/src/shade/renderer/geometry/virtual/build/vgeo_gather_faces.js +71 -71
  1553. package/src/shade/renderer/geometry/virtual/build/vgeo_graph_components.js +123 -123
  1554. package/src/shade/renderer/geometry/virtual/build/vgeo_narrow_indices.js +26 -26
  1555. package/src/shade/renderer/geometry/virtual/build/vgeo_normalize_source.js +112 -112
  1556. package/src/shade/renderer/geometry/virtual/build/vgeo_partition_graph.js +56 -56
  1557. package/src/shade/renderer/geometry/virtual/build/vgeo_sphere_inflate_to_contain.js +70 -70
  1558. package/src/shade/renderer/geometry/virtual/build/vgeo_split_face_set.js +187 -187
  1559. package/src/shade/renderer/geometry/virtual/build/vgeo_split_face_set_packed.js +207 -207
  1560. package/src/shade/renderer/geometry/virtual/format/VGEO_DEFECT.js +18 -18
  1561. package/src/shade/renderer/geometry/virtual/format/VGeoDefect.js +38 -38
  1562. package/src/shade/renderer/geometry/virtual/format/VGeoWriteOptions.js +64 -64
  1563. package/src/shade/renderer/geometry/virtual/format/attribute/VGEO_ATTRIBUTE.js +13 -13
  1564. package/src/shade/renderer/geometry/virtual/format/attribute/VGEO_ATTRIBUTES.js +50 -50
  1565. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_attribute_allocate.js +28 -28
  1566. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_attribute_mask.js +23 -23
  1567. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_attributes_read.js +31 -31
  1568. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_copy_vertex.js +32 -32
  1569. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_declare.js +46 -46
  1570. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_like.js +19 -19
  1571. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_test_fixtures.js +27 -27
  1572. package/src/shade/renderer/geometry/virtual/format/checksum/vgeo_asset_id_preimage.js +62 -62
  1573. package/src/shade/renderer/geometry/virtual/format/checksum/vgeo_compute_asset_id.js +13 -13
  1574. package/src/shade/renderer/geometry/virtual/format/checksum/vgeo_compute_directory_block_checksum.js +41 -41
  1575. package/src/shade/renderer/geometry/virtual/format/checksum/vgeo_compute_frame_checksum.js +41 -41
  1576. package/src/shade/renderer/geometry/virtual/format/checksum/vgeo_compute_header_checksum.js +25 -25
  1577. package/src/shade/renderer/geometry/virtual/format/cluster/VGEO_CLUSTER_OFFSET.js +20 -20
  1578. package/src/shade/renderer/geometry/virtual/format/cluster/VGEO_CLUSTER_RECORD_SIZE.js +5 -5
  1579. package/src/shade/renderer/geometry/virtual/format/cluster/VGEO_MAX_CHILD_REF.js +5 -5
  1580. package/src/shade/renderer/geometry/virtual/format/cluster/VGEO_MAX_CLUSTER_TRIANGLE_COUNT.js +5 -5
  1581. package/src/shade/renderer/geometry/virtual/format/cluster/VGEO_MAX_CLUSTER_VERTEX_COUNT.js +5 -5
  1582. package/src/shade/renderer/geometry/virtual/format/cluster/VGEO_NO_CHILD.js +5 -5
  1583. package/src/shade/renderer/geometry/virtual/format/cluster/VGEO_NO_GROUP.js +5 -5
  1584. package/src/shade/renderer/geometry/virtual/format/cluster/VGEO_SAME_PAGE.js +6 -6
  1585. package/src/shade/renderer/geometry/virtual/format/dag/VirtualGeometryCluster.js +81 -81
  1586. package/src/shade/renderer/geometry/virtual/format/dag/VirtualGeometryGroup.js +37 -37
  1587. package/src/shade/renderer/geometry/virtual/format/dag/VirtualGeometryPageNode.js +55 -55
  1588. package/src/shade/renderer/geometry/virtual/format/directory/VGEO_DIRECTORY_BLOCK_RECORDS.js +5 -5
  1589. package/src/shade/renderer/geometry/virtual/format/directory/VGEO_DIRECTORY_FLAG_ROOT_PAGE.js +5 -5
  1590. package/src/shade/renderer/geometry/virtual/format/directory/VGEO_DIRECTORY_RECORD_SIZE.js +5 -5
  1591. package/src/shade/renderer/geometry/virtual/format/directory/vgeo_directory_block_count.js +12 -12
  1592. package/src/shade/renderer/geometry/virtual/format/frame/VGEO_CHILD_OFFSET.js +11 -11
  1593. package/src/shade/renderer/geometry/virtual/format/frame/VGEO_CHILD_TABLE_ENTRY_SIZE.js +5 -5
  1594. package/src/shade/renderer/geometry/virtual/format/frame/VGEO_CODEC_LZ4.js +11 -11
  1595. package/src/shade/renderer/geometry/virtual/format/frame/VGEO_CODEC_RAW.js +5 -5
  1596. package/src/shade/renderer/geometry/virtual/format/frame/VGEO_FRAME_ALIGNMENT.js +5 -5
  1597. package/src/shade/renderer/geometry/virtual/format/frame/VGEO_FRAME_HEADER_SIZE.js +5 -5
  1598. package/src/shade/renderer/geometry/virtual/format/frame/VGEO_FRAME_OFFSET.js +13 -13
  1599. package/src/shade/renderer/geometry/virtual/format/frame/VGEO_PAGE_MAGIC.js +5 -5
  1600. package/src/shade/renderer/geometry/virtual/format/frame/VGeoFrameBlob.js +21 -21
  1601. package/src/shade/renderer/geometry/virtual/format/frame/VGeoFrameExtent.js +59 -59
  1602. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_codec_name.js +27 -27
  1603. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_decode_frame_blob.js +84 -84
  1604. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_encode_frame_blob.js +56 -56
  1605. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_frame_decode_bound.js +35 -35
  1606. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_scan_frames.js +74 -74
  1607. package/src/shade/renderer/geometry/virtual/format/header/VGEO_FORMAT_VERSION.js +6 -6
  1608. package/src/shade/renderer/geometry/virtual/format/header/VGEO_HASH_ALGO_XXH3.js +5 -5
  1609. package/src/shade/renderer/geometry/virtual/format/header/VGEO_HEADER_OFFSET.js +31 -31
  1610. package/src/shade/renderer/geometry/virtual/format/header/VGEO_HEADER_SIZE.js +5 -5
  1611. package/src/shade/renderer/geometry/virtual/format/header/VGEO_LEVEL_OFFSET.js +20 -20
  1612. package/src/shade/renderer/geometry/virtual/format/header/VGEO_LEVEL_RECORD_SIZE.js +9 -9
  1613. package/src/shade/renderer/geometry/virtual/format/header/VGEO_MAGIC.js +5 -5
  1614. package/src/shade/renderer/geometry/virtual/format/header/VGEO_MIN_READER_VERSION.js +5 -5
  1615. package/src/shade/renderer/geometry/virtual/format/header/VGEO_PAYLOAD_ENCODING_SHADE_MESHLET_V1.js +5 -5
  1616. package/src/shade/renderer/geometry/virtual/format/header/VGeoLevelRecord.js +41 -41
  1617. package/src/shade/renderer/geometry/virtual/format/page/VGEO_GROUP_RECORD_SIZE.js +5 -5
  1618. package/src/shade/renderer/geometry/virtual/format/page/VGEO_MAX_GROUP_CLUSTER_COUNT.js +6 -6
  1619. package/src/shade/renderer/geometry/virtual/format/page/VGEO_METRIC_OFFSET.js +21 -21
  1620. package/src/shade/renderer/geometry/virtual/format/page/VGEO_METRIC_SIZE.js +5 -5
  1621. package/src/shade/renderer/geometry/virtual/format/page/VGEO_NODE_FANOUT.js +9 -9
  1622. package/src/shade/renderer/geometry/virtual/format/page/VGEO_NODE_FLAG_LEAF.js +5 -5
  1623. package/src/shade/renderer/geometry/virtual/format/page/VGEO_NODE_OFFSET.js +10 -10
  1624. package/src/shade/renderer/geometry/virtual/format/page/VGEO_NODE_RECORD_SIZE.js +5 -5
  1625. package/src/shade/renderer/geometry/virtual/format/page/VGEO_PAGE_HEADER_SIZE.js +5 -5
  1626. package/src/shade/renderer/geometry/virtual/format/page/VGEO_PAGE_OFFSET.js +16 -16
  1627. package/src/shade/renderer/geometry/virtual/format/payload/VGEO_ENCODING_FLAGS_MASK.js +6 -6
  1628. package/src/shade/renderer/geometry/virtual/format/payload/VGeoEncodedPayload.js +18 -18
  1629. package/src/shade/renderer/geometry/virtual/format/payload/vgeo_encode_cluster_payload.js +200 -200
  1630. package/src/shade/renderer/geometry/virtual/format/payload/vgeo_payload_attribute_offset.js +39 -39
  1631. package/src/shade/renderer/geometry/virtual/format/payload/vgeo_payload_size.js +20 -20
  1632. package/src/shade/renderer/geometry/virtual/format/prototypeVGEOFormatViewer.js +2063 -2063
  1633. package/src/shade/renderer/geometry/virtual/format/vgeo_validate_container.js +1622 -1622
  1634. package/src/shade/renderer/geometry/virtual/format/vgeo_write_container.js +485 -485
  1635. package/src/shade/renderer/gpu_primitive/sort/ffx/graph_radix_sort.js +115 -115
  1636. package/src/shade/renderer/gpu_primitive/sort/one_sweep/verify_radix_sort_one_sweep.js +110 -110
  1637. package/src/shade/renderer/light/environment/octahedral_resample_kernel.js +50 -50
  1638. package/src/shade/renderer/light/environment/octahedral_uv_to_direction.js +30 -30
  1639. package/src/shade/renderer/light/environment/resample_cube_to_octahedral.js +157 -157
  1640. package/src/shade/renderer/light/make_sunlight.js +35 -35
  1641. package/src/shade/renderer/light/model/io/light_record_point.js +39 -39
  1642. package/src/shade/renderer/loader/gltf/GLTF_PRIMITIVE_MODE.js +23 -23
  1643. package/src/shade/renderer/loader/gltf/MESHOPT_COMPRESSION_PLAN.md +793 -793
  1644. package/src/shade/renderer/loader/gltf/ext/GltfBufferViewExtension.js +54 -54
  1645. package/src/shade/renderer/loader/gltf/ext/GltfBufferViewExtensionSet.js +109 -109
  1646. package/src/shade/renderer/loader/gltf/ext/gltf_apply_buffer_view_extensions.js +69 -69
  1647. package/src/shade/renderer/loader/gltf/ext/gltf_buffer_view_extensions.js +22 -22
  1648. package/src/shade/renderer/loader/gltf/ext/gltf_geometry_extensions.js +39 -39
  1649. package/src/shade/renderer/loader/gltf/ext/meshopt/MeshoptBufferViewExtension.js +301 -301
  1650. package/src/shade/renderer/loader/gltf/gltf_component_type.js +223 -223
  1651. package/src/shade/renderer/loader/gltf/gltf_node_world_matrices.js +137 -137
  1652. package/src/shade/renderer/loader/gltf/gltf_parse_container.js +241 -241
  1653. package/src/shade/renderer/loader/gltf/gltf_read_accessor.js +294 -294
  1654. package/src/shade/renderer/loader/gltf/gltf_used_image_indices.js +49 -49
  1655. package/src/shade/renderer/loader/gltf/load_gltf.js +1253 -1253
  1656. package/src/shade/renderer/loader/gltf/tiny-gltf.js +646 -646
  1657. package/src/shade/renderer/loader/usd/UsdError.js +33 -33
  1658. package/src/shade/renderer/loader/usd/UsdExtensionRegistry.js +69 -69
  1659. package/src/shade/renderer/loader/usd/load_usd.js +226 -226
  1660. package/src/shade/renderer/loader/usd/parse_usda.js +931 -931
  1661. package/src/shade/renderer/loader/usd/unpack_usdz.js +106 -106
  1662. package/src/shade/renderer/loader/usd/usd_build_scene.js +658 -658
  1663. package/src/shade/renderer/loader/usd/usd_compose_transform.js +258 -258
  1664. package/src/shade/renderer/loader/usd/usd_decode_image.js +384 -384
  1665. package/src/shade/renderer/loader/usd/usd_lz4.js +182 -182
  1666. package/src/shade/renderer/loader/usd/usd_triangulate.js +159 -159
  1667. package/src/shade/renderer/material/ShadeMaterial.d.ts +2 -2
  1668. package/src/shade/renderer/material/ShadeMaterial.js +2 -2
  1669. package/src/shade/renderer/material/standard/fragment_gbuffer.js +334 -334
  1670. package/src/shade/renderer/material/standard/fragment_gbuffer_vt.js +169 -169
  1671. package/src/shade/renderer/material/standard/material_gbuffer_vertex.js +45 -45
  1672. package/src/shade/renderer/material/standard_material_to_struct.js +23 -23
  1673. package/src/shade/renderer/particles/prototypeParticleSystem.js +450 -450
  1674. package/src/shade/renderer/particles/runtime/spawn_request_encoding.js +52 -52
  1675. package/src/shade/renderer/pool/TransientResourcePool.js +392 -392
  1676. package/src/shade/renderer/postprocess/bloom/bloom_chain_resolution.js +29 -29
  1677. package/src/shade/renderer/postprocess/bloom/graph_bloom_downsample.js +109 -109
  1678. package/src/shade/renderer/postprocess/bloom/graph_postprocess_bloom.js +155 -155
  1679. package/src/shade/renderer/postprocess/cas/shader_ffx_rcas.js +114 -114
  1680. package/src/shade/renderer/postprocess/dof/DOF_AUTOFOCUS_PARAMS_STRUCT.js +25 -25
  1681. package/src/shade/renderer/postprocess/dof/DOF_FOCUS_STATE_STRUCT.js +23 -23
  1682. package/src/shade/renderer/postprocess/dof/DOF_PRESETS.js +27 -27
  1683. package/src/shade/renderer/postprocess/dof/chunk_dof_coc_band_diameter.js +41 -41
  1684. package/src/shade/renderer/postprocess/dof/chunk_dof_coc_band_radius.js +32 -32
  1685. package/src/shade/renderer/postprocess/dof/chunk_dof_coc_coefficient.js +26 -26
  1686. package/src/shade/renderer/postprocess/dof/compute_dof_autofocus_params.js +64 -64
  1687. package/src/shade/renderer/postprocess/dof/compute_dof_uniform.js +54 -54
  1688. package/src/shade/renderer/postprocess/dof/gather/DOF2_CONFIG.js +91 -91
  1689. package/src/shade/renderer/postprocess/dof/gather/DOF2_PRESETS.js +9 -9
  1690. package/src/shade/renderer/postprocess/dof/gather/DOF2_SETTINGS_STRUCT.js +66 -66
  1691. package/src/shade/renderer/postprocess/dof/gather/DOF2_TEXTURE_FORMAT.js +22 -22
  1692. package/src/shade/renderer/postprocess/dof/gather/DepthOfFieldU.js +292 -292
  1693. package/src/shade/renderer/postprocess/dof/gather/chunk_dof2_coc_to_near_far.js +25 -25
  1694. package/src/shade/renderer/postprocess/dof/gather/chunk_dof2_gather_weight.js +30 -30
  1695. package/src/shade/renderer/postprocess/dof/gather/compute_dof2_uniform.js +54 -54
  1696. package/src/shade/renderer/postprocess/dof/gather/graph_postprocess_dof2.js +194 -194
  1697. package/src/shade/renderer/postprocess/dof/gather/shader_dof2_fill.js +68 -68
  1698. package/src/shade/renderer/postprocess/dof/gather/shader_dof2_gather_far.js +140 -140
  1699. package/src/shade/renderer/postprocess/dof/gather/shader_dof2_gather_near.js +142 -142
  1700. package/src/shade/renderer/postprocess/dof/gather/shader_dof2_recombine.js +99 -99
  1701. package/src/shade/renderer/postprocess/dof/gather/shader_dof2_setup.js +102 -102
  1702. package/src/shade/renderer/postprocess/dof/gather/shader_dof2_tile_dilate.js +75 -75
  1703. package/src/shade/renderer/postprocess/dof/gather/shader_dof2_tile_max.js +73 -73
  1704. package/src/shade/renderer/postprocess/dof/raymarch/DOF_SETTINGS_STRUCT.js +49 -49
  1705. package/src/shade/renderer/postprocess/dof/raymarch/DepthOfField.js +298 -298
  1706. package/src/shade/renderer/postprocess/dof/raymarch/graph_postprocess_dof.js +244 -244
  1707. package/src/shade/renderer/postprocess/dof/raymarch/shader_dof_composite.js +91 -91
  1708. package/src/shade/renderer/postprocess/dof/raymarch/shader_dof_firefly_cleanup.js +61 -61
  1709. package/src/shade/renderer/postprocess/dof/raymarch/shader_dof_prefilter.js +90 -90
  1710. package/src/shade/renderer/postprocess/dof/raymarch/shader_dof_raymarch_compute.js +267 -267
  1711. package/src/shade/renderer/postprocess/dof/raymarch/shader_dof_slice_compute.js +271 -271
  1712. package/src/shade/renderer/postprocess/dof/raymarch/shader_dof_tile_dilate.js +70 -70
  1713. package/src/shade/renderer/postprocess/dof/raymarch/shader_dof_tile_max.js +72 -72
  1714. package/src/shade/renderer/postprocess/dof/shader_dof_autofocus.js +99 -99
  1715. package/src/shade/renderer/postprocess/gtao/generate_magic_square_noise.js +51 -51
  1716. package/src/shade/renderer/postprocess/motion_blur/MotionBlur.js +56 -56
  1717. package/src/shade/renderer/postprocess/upscale-dither/NOTES.md +78 -78
  1718. package/src/shade/renderer/postprocess/upscale-dither/UpscaleDither.js +95 -95
  1719. package/src/shade/renderer/postprocess/upscale-dither/fragment_shader_upscale_dither.js +204 -204
  1720. package/src/shade/renderer/rasterize/bucket/construct_primitive_state.js +58 -58
  1721. package/src/shade/renderer/rasterize/fast/graph_rasterize_scene_fast.js +230 -230
  1722. package/src/shade/renderer/rasterize/native/graph_rasterize_meshes_alpha_tested.js +278 -278
  1723. package/src/shade/renderer/rasterize/native/oit/chunk_material_side_should_draw.js +26 -26
  1724. package/src/shade/renderer/rasterize/native/oit/shader_oit_resolve_moments_ibl.js +178 -178
  1725. package/src/shade/renderer/rasterize/standard/graph_rasterize_partial_opaque.js +235 -235
  1726. package/src/shade/renderer/rasterize/standard/graph_rasterize_remaining_opaque.js +208 -208
  1727. package/src/shade/renderer/rasterize/standard/graph_rasterize_scene.js +206 -206
  1728. package/src/shade/renderer/scene/DynamicMesh.js +70 -70
  1729. package/src/shade/renderer/scene/DynamicMeshBatch.js +90 -90
  1730. package/src/shade/renderer/scene/GPUSceneContext.js +901 -901
  1731. package/src/shade/renderer/scene/SceneNodeBinding.js +56 -56
  1732. package/src/shade/renderer/scene/SkinnedMesh.js +55 -55
  1733. package/src/shade/renderer/scene/TransformAuthority.js +33 -33
  1734. package/src/shade/renderer/scene/optimization/deduplicate_geometries.js +38 -38
  1735. package/src/shade/renderer/scene/optimization/deduplicate_images.js +93 -93
  1736. package/src/shade/renderer/scene/optimization/geometry/internal/match_refit_validate.js +127 -127
  1737. package/src/shade/renderer/scene/optimization/geometry/internal/match_solve_transform.js +492 -492
  1738. package/src/shade/renderer/scene/optimization/optimize_texture_set.js +81 -81
  1739. package/src/shade/renderer/scene/optimization/source_to_sampler2d.js +21 -21
  1740. package/src/shade/renderer/scene/serialization/STANDARD_MATERIAL_SERIALIZED_BYTE_SIZE.js +12 -12
  1741. package/src/shade/renderer/shader/chunk/geometry/quaternion/dual/chunk_dual_quat_transform_point.js +26 -26
  1742. package/src/shade/renderer/shader/chunk/noise/chunk_interleaved_gradient_noise.js +20 -20
  1743. package/src/shade/renderer/shader/chunk/spherical_harmonics/dering/chunk_sh2_dering_optimize_positive.js +61 -61
  1744. package/src/shade/renderer/shader/chunk/texture/chunk_texture_filter_fxaa_lite.js +225 -225
  1745. package/src/shade/renderer/shader/chunk/texture/dither/chunk_dither_color_8bit_gradient_noise.js +25 -25
  1746. package/src/shade/renderer/shadow/map/DirectionalLightShadowmap.js +384 -384
  1747. package/src/shade/renderer/shadow/map/PointLightShadowmap.js +105 -105
  1748. package/src/shade/renderer/shadow/map/SpotLightShadowmap.js +63 -63
  1749. package/src/shade/renderer/shadow/map/TetrahedronPointLightShadowmap.js +89 -89
  1750. package/src/shade/renderer/shadow/map/shadowmap_update_score.js +232 -232
  1751. package/src/shade/renderer/texture/GPUTextureAllocator.js +85 -85
  1752. package/src/shade/renderer/texture/texture_pool_ops.js +171 -171
  1753. package/src/shade/renderer/texture/virtual/PageTableQuadAllocator.js +253 -253
  1754. package/src/shade/renderer/texture/virtual/README.md +276 -276
  1755. package/src/shade/renderer/texture/virtual/VTPageTable.js +330 -330
  1756. package/src/shade/renderer/texture/virtual/VTPhysicalCache.js +349 -349
  1757. package/src/shade/renderer/texture/virtual/VT_CONSTANTS.js +154 -154
  1758. package/src/shade/renderer/texture/virtual/VT_STACK_INFO_STRUCT.js +20 -20
  1759. package/src/shade/renderer/texture/virtual/VirtualTextureManager.js +1276 -1276
  1760. package/src/shade/renderer/texture/virtual/VirtualTextureStack.js +106 -106
  1761. package/src/shade/renderer/texture/virtual/build_chunk_vt_lookup.js +150 -150
  1762. package/src/shade/renderer/texture/virtual/build_shader_vt_feedback.js +232 -232
  1763. package/src/shade/renderer/texture/virtual/chunk_vt_request_key.js +28 -28
  1764. package/src/shade/renderer/texture/virtual/source/VTSourceImage.js +207 -207
  1765. package/src/shade/renderer/texture/virtual/source/VTSourceProcedural.js +135 -135
  1766. package/src/shade/renderer/texture/virtual/source/VTSourceTiled.js +132 -132
  1767. package/src/shade/renderer/water/GPUWaterRenderer.js +167 -167
  1768. package/src/shade/renderer/water/shader_water.js +246 -246
  1769. package/src/shade/renderer/water/water_height_texture_from_sampler.js +56 -56
  1770. package/src/shade/vitest.setup.mjs +89 -89
  1771. package/src/shade/wgsl/validate_wgsl_source.js +316 -316
  1772. package/src/view/controller/controls/NumericIntervalControl.js +90 -90
  1773. package/src/view/controller/controls/Vector2Control.js +83 -83
  1774. package/src/view/controller/controls/Vector3Control.js +90 -90
  1775. package/src/view/elements/Group.js +56 -56
  1776. package/src/view/elements/drawCheckers.js +33 -33
  1777. package/src/view/elements/windrose/WindRoseDiagram.js +369 -369
  1778. package/src/view/graphics/WebGLContextFailureView.js +76 -76
  1779. package/src/view/layout/DockPanel.js +51 -51
  1780. package/src/view/layout/SplitView.js +365 -365
  1781. package/src/view/layout/show_popup_menu.js +81 -81
  1782. package/src/view/minimap/MinimapCanvasView.js +411 -411
  1783. package/src/view/minimap/MinimapImageCache.js +88 -88
  1784. package/src/view/minimap/MinimapMarkerCollection.d.ts +0 -1
  1785. package/src/view/minimap/MinimapMarkerCollection.d.ts.map +1 -1
  1786. package/src/view/minimap/MinimapMarkerCollection.js +180 -180
  1787. package/src/view/minimap/dom/MinimapCameraView.js +206 -206
  1788. package/src/view/minimap/minimap_focus_area.js +97 -97
  1789. package/editor/process/symbolic/SocketsSymbolicDisplay.js +0 -192
  1790. package/src/core/geom/3d/topology/struct/binary/io/moved_tests.txt +0 -37
  1791. package/src/engine/ecs/attachment/Attachment.d.ts +0 -40
  1792. package/src/engine/ecs/attachment/Attachment.d.ts.map +0 -1
  1793. package/src/engine/ecs/attachment/Attachment.js +0 -57
  1794. package/src/engine/ecs/attachment/AttachmentBinding.d.ts +0 -28
  1795. package/src/engine/ecs/attachment/AttachmentBinding.d.ts.map +0 -1
  1796. package/src/engine/ecs/attachment/AttachmentBinding.js +0 -41
  1797. package/src/engine/ecs/attachment/AttachmentSystem.d.ts +0 -61
  1798. package/src/engine/ecs/attachment/AttachmentSystem.d.ts.map +0 -1
  1799. package/src/engine/ecs/attachment/AttachmentSystem.js +0 -307
  1800. package/src/engine/ecs/attachment/BoneAttachmentBinding.d.ts +0 -27
  1801. package/src/engine/ecs/attachment/BoneAttachmentBinding.d.ts.map +0 -1
  1802. package/src/engine/ecs/attachment/BoneAttachmentBinding.js +0 -69
  1803. package/src/engine/ecs/attachment/TransformAttachmentBinding.d.ts +0 -4
  1804. package/src/engine/ecs/attachment/TransformAttachmentBinding.d.ts.map +0 -1
  1805. package/src/engine/ecs/attachment/TransformAttachmentBinding.js +0 -51
  1806. package/src/engine/ecs/sockets/AttachmentSocket.d.ts +0 -32
  1807. package/src/engine/ecs/sockets/AttachmentSocket.d.ts.map +0 -1
  1808. package/src/engine/ecs/sockets/AttachmentSocket.js +0 -60
  1809. package/src/engine/ecs/sockets/AttachmentSocketType.d.ts +0 -6
  1810. package/src/engine/ecs/sockets/AttachmentSocketType.d.ts.map +0 -1
  1811. package/src/engine/ecs/sockets/AttachmentSocketType.js +0 -8
  1812. package/src/engine/ecs/sockets/AttachmentSockets.d.ts +0 -57
  1813. package/src/engine/ecs/sockets/AttachmentSockets.d.ts.map +0 -1
  1814. package/src/engine/ecs/sockets/AttachmentSockets.js +0 -130
  1815. package/src/engine/ecs/sockets/BoneAttachmentSocket.d.ts +0 -29
  1816. package/src/engine/ecs/sockets/BoneAttachmentSocket.d.ts.map +0 -1
  1817. package/src/engine/ecs/sockets/BoneAttachmentSocket.js +0 -56
  1818. package/src/engine/ecs/sockets/serialization/AttachmentSocketsAssetLoader.d.ts +0 -6
  1819. package/src/engine/ecs/sockets/serialization/AttachmentSocketsAssetLoader.d.ts.map +0 -1
  1820. package/src/engine/ecs/sockets/serialization/AttachmentSocketsAssetLoader.js +0 -19
  1821. package/src/shade/renderer/animation/_dump_resolve.d.mts +0 -2
  1822. package/src/shade/renderer/animation/_dump_resolve.d.mts.map +0 -1
  1823. 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).