@woosh/meep-engine 3.1.0 → 3.3.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 (1869) hide show
  1. package/LICENSE +188 -188
  2. package/README.md +152 -152
  3. package/editor/Editor.js +598 -598
  4. package/editor/EditorCameraNavigation.js +205 -205
  5. package/editor/EditorKeyMap.js +182 -182
  6. package/editor/SelectionVisualizer.js +127 -127
  7. package/editor/actions/concrete/ActionInvalidateSampler.js +27 -27
  8. package/editor/actions/concrete/PatchTerrainHeightAction.js +85 -85
  9. package/editor/camera/camera_framing.js +104 -104
  10. package/editor/clipboard.js +184 -184
  11. package/editor/ecs/component/editors/ObservedIntegerEditor.js +22 -22
  12. package/editor/ecs/component/editors/ObservedStringEditor.js +34 -34
  13. package/editor/ecs/component/editors/common/two_way_sync.js +50 -50
  14. package/editor/ecs/component/editors/ecs/GridObstacleEditor.js +19 -19
  15. package/editor/ecs/component/editors/ecs/ParameterLookupTableEditor.js +35 -35
  16. package/editor/ecs/component/editors/ecs/ParameterTrackEditor.js +17 -17
  17. package/editor/ecs/component/editors/ecs/SGMeshEditor.js +24 -24
  18. package/editor/ecs/component/editors/ecs/ShadedGeometryEditor.js +33 -33
  19. package/editor/ecs/component/editors/ecs/Trail3DEditor.js +45 -45
  20. package/editor/ecs/component/editors/ecs/buildGridObstaclePreview.js +19 -19
  21. package/editor/ecs/component/editors/ecs/terrain/TerrainEditor.js +72 -72
  22. package/editor/ecs/component/editors/shade/MeshletGeometryEditor.js +30 -30
  23. package/editor/ecs/component/editors/shade/ShadeImageEditor.js +70 -70
  24. package/editor/ecs/component/editors/shade/ShadeMaterialEditor.js +34 -34
  25. package/editor/ecs/component/editors/shade/ShadeTextureEditor.js +46 -46
  26. package/editor/ecs/component/editors/shade/StandardShadeMaterialEditor.js +24 -24
  27. package/editor/ecs/component/prototypeObjectEditor.js +265 -265
  28. package/editor/ecs/component/registerBasicTypeEditors.js +100 -100
  29. package/editor/ecs/component/registerEngineComponentEditors.js +95 -95
  30. package/editor/entity_world_bounds.js +27 -27
  31. package/editor/particles/lut_ops.js +148 -148
  32. package/editor/particles/particleEditEvents.js +12 -12
  33. package/editor/particles/rebuildParticleEmitter.js +31 -31
  34. package/editor/persistence/EditorLayoutStore.js +71 -71
  35. package/editor/persistence/SceneMetadata.js +52 -52
  36. package/editor/persistence/SceneSlotManager.js +144 -144
  37. package/editor/persistence/buildNewSceneDataset.js +67 -67
  38. package/editor/persistence/files.js +68 -68
  39. package/editor/persistence/scene_import.js +143 -143
  40. package/editor/persistence/scene_serialization.js +79 -79
  41. package/editor/persistence/string_buffer_codec.js +41 -41
  42. package/editor/process/GridDisplayProcess.js +125 -125
  43. package/editor/process/SymbolicDisplayProcess.js +106 -108
  44. package/editor/process/symbolic/CameraSymbolicDisplay.js +146 -146
  45. package/editor/process/symbolic/LightSymbolicDisplay.js +172 -172
  46. package/editor/process/symbolic/PathSymbolicDisplay.js +118 -118
  47. package/editor/process/symbolic/PositionedMarkerSymbolicDisplay.js +79 -79
  48. package/editor/process/symbolic/SoundEmitterSymbolicDisplay.js +57 -57
  49. package/editor/process/symbolic/SymbolicDisplay.js +62 -62
  50. package/editor/process/symbolic/gizmo_draw_wire_box_oriented.js +85 -85
  51. package/editor/process/symbolic/gizmo_draw_wire_circle.js +53 -53
  52. package/editor/prototypeEditorShell.js +156 -156
  53. package/editor/selection/editor_pick.js +130 -130
  54. package/editor/selection/screen_rect_frustum.js +119 -119
  55. package/editor/style/controls.scss +168 -168
  56. package/editor/style/inspector.scss +223 -223
  57. package/editor/templates/entity_templates.js +167 -167
  58. package/editor/tools/GridPaintTool.js +273 -273
  59. package/editor/tools/SelectionTool.js +307 -307
  60. package/editor/tools/TransformToolV2.js +378 -378
  61. package/editor/tools/engine/ToolEngine.js +188 -188
  62. package/editor/tools/paint/TerrainTexturePaintTool.js +250 -250
  63. package/editor/tools/v2/BlenderCameraOrientationGizmo.js +501 -501
  64. package/editor/tools/v2/TransformControls.js +971 -971
  65. package/editor/tools/v2/handle/gizmo_drag_plane.js +141 -141
  66. package/editor/tools/v2/handle/gizmo_draw.js +399 -399
  67. package/editor/tools/v2/handle/gizmo_handles.js +364 -364
  68. package/editor/tools/v2/handle/gizmo_ray_shapes.js +239 -239
  69. package/editor/view/ecs/HierarchicalEntityListView.js +339 -339
  70. package/editor/view/ecs/components/DatGuiController.js +2 -2
  71. package/editor/view/ecs/components/common/AutoCanvasView.js +100 -100
  72. package/editor/view/ecs/components/common/TextController.js +59 -59
  73. package/editor/view/library/MeshLibraryView.js +175 -175
  74. package/editor/view/library/mesh_library_drag.js +63 -63
  75. package/editor/view/library/model_thumbnail_source.js +86 -86
  76. package/editor/view/makeEntityDecorators.js +125 -125
  77. package/editor/view/node-graph/NodeGraphSelection.js +89 -89
  78. package/editor/view/node-graph/NodeView.js +211 -211
  79. package/editor/view/node-graph/actions/ConnectionDeleteAction.js +36 -36
  80. package/editor/view/node-graph/actions/NodesMoveAction.js +41 -41
  81. package/editor/view/node-graph/connection_wire_geometry.js +107 -107
  82. package/editor/view/particles/ColorLutGradientView.js +291 -291
  83. package/editor/view/particles/ScalarLutCurveView.js +279 -279
  84. package/editor/view/prepareMeshLibrary.js +188 -188
  85. package/editor/view/shell/SceneTreePanelView.js +119 -119
  86. package/editor/view/v2/SplitView.js +2 -2
  87. package/package.json +94 -94
  88. package/samples/generation/generators/interactive/mir_generator_place_buff_objects.js +362 -362
  89. package/src/DUPLICATION_AUDIT_2026_08_07/00_core_reuse_surface.md +738 -738
  90. package/src/DUPLICATION_AUDIT_2026_08_07/A_core_math_geom.md +79 -79
  91. package/src/DUPLICATION_AUDIT_2026_08_07/B_core_data.md +93 -93
  92. package/src/DUPLICATION_AUDIT_2026_08_07/C_gfx_render.md +80 -80
  93. package/src/DUPLICATION_AUDIT_2026_08_07/D_gfx_features.md +164 -164
  94. package/src/DUPLICATION_AUDIT_2026_08_07/E_physics.md +69 -69
  95. package/src/DUPLICATION_AUDIT_2026_08_07/F_sound.md +102 -102
  96. package/src/DUPLICATION_AUDIT_2026_08_07/G_net_save.md +129 -129
  97. package/src/DUPLICATION_AUDIT_2026_08_07/H_engine_misc.md +72 -72
  98. package/src/DUPLICATION_AUDIT_2026_08_07/I_generation_view.md +74 -74
  99. package/src/DUPLICATION_AUDIT_2026_08_07/K_crosscutting.md +169 -169
  100. package/src/DUPLICATION_AUDIT_2026_08_07.md +254 -254
  101. package/src/DUPLICATION_AUDIT_REMEDIATION.md +250 -250
  102. package/src/REVIEW_2026_08_06/adv-core.md +511 -511
  103. package/src/REVIEW_2026_08_06/adv-gfx.md +480 -480
  104. package/src/REVIEW_2026_08_06/adv-view.md +446 -446
  105. package/src/REVIEW_2026_08_06/api-core.md +296 -296
  106. package/src/REVIEW_2026_08_06/api-engine.md +195 -195
  107. package/src/REVIEW_2026_08_06/bvh-phys-sound-net.md +507 -507
  108. package/src/REVIEW_2026_08_06/core-binary.md +348 -348
  109. package/src/REVIEW_2026_08_06/core-collection.md +376 -376
  110. package/src/REVIEW_2026_08_06/core-math.md +221 -221
  111. package/src/REVIEW_2026_08_06/core-process.md +266 -266
  112. package/src/REVIEW_2026_08_06/core-science.md +223 -223
  113. package/src/REVIEW_2026_08_06/engine-ai-nav.md +279 -279
  114. package/src/REVIEW_2026_08_06/engine-animation.md +167 -167
  115. package/src/REVIEW_2026_08_06/engine-asset.md +166 -166
  116. package/src/REVIEW_2026_08_06/engine-ecs.md +920 -920
  117. package/src/REVIEW_2026_08_06/engine-input.md +197 -197
  118. package/src/REVIEW_2026_08_06/engine-misc.md +248 -248
  119. package/src/REVIEW_2026_08_06/engine-terrain.md +52 -52
  120. package/src/REVIEW_2026_08_06/generation.md +176 -176
  121. package/src/REVIEW_2026_08_06/geom-2d.md +434 -434
  122. package/src/REVIEW_2026_08_06/geom-3d.md +117 -117
  123. package/src/REVIEW_2026_08_06/gfx-gi.md +143 -143
  124. package/src/REVIEW_2026_08_06/gfx-render.md +740 -740
  125. package/src/REVIEW_2026_08_06/gfx-texture.md +690 -690
  126. package/src/REVIEW_2026_08_06/prior-criticals.md +49 -49
  127. package/src/REVIEW_2026_08_06/prior-highs.md +138 -138
  128. package/src/REVIEW_2026_08_06/test-gaps.md +364 -364
  129. package/src/REVIEW_2026_08_06/view.md +667 -667
  130. package/src/REVIEW_2026_08_06.md +610 -610
  131. package/src/avif/codec/dec/avif_dec.cpp +233 -233
  132. package/src/avif/codec/dec/avif_dec.js +16 -16
  133. package/src/avif/encoder_worker.js +5 -18
  134. package/src/core/binary/BitImage2.js +246 -246
  135. package/src/core/binary/align_32.js +21 -21
  136. package/src/core/binary/data_view/DataType2DataViewReaders.js +23 -23
  137. package/src/core/binary/data_view/DataType2DataViewWriters.js +25 -25
  138. package/src/core/binary/hash/XXH128Hash.js +55 -55
  139. package/src/core/binary/hash/XXH3_SECRET.js +25 -25
  140. package/src/core/binary/hash/xxh3_128.js +341 -341
  141. package/src/core/binary/hash/xxh3_64.js +241 -241
  142. package/src/core/binary/hash/xxh3_common.js +476 -476
  143. package/src/core/binary/lz4/LZ4_MAX_INPUT_SIZE.js +9 -9
  144. package/src/core/binary/lz4/lz4_compress_block.js +385 -385
  145. package/src/core/binary/lz4/lz4_compress_bound.js +25 -25
  146. package/src/core/binary/lz4/lz4_decompress_block.js +139 -139
  147. package/src/core/binary/lz4/lz4_decompress_bound.js +30 -30
  148. package/src/core/binary/meshopt/MESHOPT_GROUP_SIZE.js +18 -18
  149. package/src/core/binary/meshopt/MeshoptCompressionFilter.js +30 -30
  150. package/src/core/binary/meshopt/MeshoptCompressionMode.js +21 -21
  151. package/src/core/binary/meshopt/__meshopt_test_streams.js +237 -237
  152. package/src/core/binary/meshopt/meshopt_decode.js +73 -73
  153. package/src/core/binary/meshopt/meshopt_decode_byte_group.js +67 -67
  154. package/src/core/binary/meshopt/meshopt_decode_data_block.js +59 -59
  155. package/src/core/binary/meshopt/meshopt_decode_filter_color.js +69 -69
  156. package/src/core/binary/meshopt/meshopt_decode_filter_exponential.js +43 -43
  157. package/src/core/binary/meshopt/meshopt_decode_filter_octahedral.js +60 -60
  158. package/src/core/binary/meshopt/meshopt_decode_filter_quaternion.js +71 -71
  159. package/src/core/binary/meshopt/meshopt_decode_index_buffer.js +294 -294
  160. package/src/core/binary/meshopt/meshopt_decode_index_sequence.js +115 -115
  161. package/src/core/binary/meshopt/meshopt_decode_vertex_buffer.js +381 -381
  162. package/src/core/binary/meshopt/meshopt_read_uint_var.js +59 -59
  163. package/src/core/binary/reinterpret_float32_as_uint32.js +13 -13
  164. package/src/core/binary/reinterpret_uint32_as_float32.js +14 -14
  165. package/src/core/binary/type/DataType2TypedArrayConstructorMapping.js +35 -35
  166. package/src/core/bvh2/bvh3/ebvh_geometry_query_any_triangle_ray.js +149 -149
  167. package/src/core/bvh2/bvh3/ebvh_sort_for_traversal_depth_first.js +96 -96
  168. package/src/core/bvh2/bvh3/query/bvh_query_depth_range_in_frustum.js +101 -101
  169. package/src/core/bvh2/bvh3/query/bvh_query_leaves_generic.js +77 -77
  170. package/src/core/bvh2/bvh3/query/bvh_query_leaves_ray.js +90 -90
  171. package/src/core/bvh2/bvh3/query/bvh_query_leaves_ray_segment.js +94 -94
  172. package/src/core/bvh2/bvh3/query/bvh_query_user_data_generic.js +86 -86
  173. package/src/core/bvh2/bvh3/query/bvh_query_user_data_intersects_capsule.js +101 -101
  174. package/src/core/bvh2/bvh3/query/bvh_query_user_data_intersects_sphere.js +92 -92
  175. package/src/core/bvh2/bvh3/query/bvh_query_user_data_ray.js +96 -96
  176. package/src/core/bvh2/bvh3/query/bvh_query_user_data_ray_segment.js +100 -100
  177. package/src/core/bvh2/visual/BVHGeometry.js +131 -131
  178. package/src/core/bvh8/BVH8.js +436 -436
  179. package/src/core/bvh8/aabb3_round_to_float32.js +22 -22
  180. package/src/core/bvh8/build/BVH8Converter.js +588 -588
  181. package/src/core/bvh8/build/TriangleCluster.js +122 -122
  182. package/src/core/bvh8/build/aabb3_compute_merge_cost.js +28 -28
  183. package/src/core/bvh8/build/aabb3_from_triangle_by_index.js +17 -17
  184. package/src/core/bvh8/build/bvh8_build_for_geometry.js +303 -303
  185. package/src/core/bvh8/build/bvh8_from_proxy.js +256 -256
  186. package/src/core/bvh8/build/byte.js +9 -9
  187. package/src/core/bvh8/build/encode_bounds_e.js +11 -11
  188. package/src/core/bvh8/bvh8_convert_to_dot.js +132 -132
  189. package/src/core/bvh8/bvh8_count_primitives.js +98 -98
  190. package/src/core/bvh8/bvh8_geometry_validate.js +138 -138
  191. package/src/core/bvh8/bvh8_geometry_validate_indirect.js +166 -166
  192. package/src/core/bvh8/bvh8_get_node_bounds.js +34 -34
  193. package/src/core/bvh8/bvh8_get_node_child_bounds.js +52 -52
  194. package/src/core/bvh8/bvh8_node_child_surface_area.js +18 -18
  195. package/src/core/bvh8/bvh8_node_count_triangles.js +27 -27
  196. package/src/core/bvh8/bvh8_quality.js +72 -72
  197. package/src/core/bvh8/bvh8_validate_structure.js +87 -87
  198. package/src/core/clipboard/obtainClipBoard.js +29 -29
  199. package/src/core/clipboard/safeClipboardReadText.js +55 -55
  200. package/src/core/clipboard/safeClipboardWriteText.js +23 -23
  201. package/src/core/collection/array/typed/typed_array_value_denormalize.js +52 -52
  202. package/src/core/collection/array/typed/typed_array_value_normalize.js +51 -51
  203. package/src/core/collection/union-find/union_find.js +79 -79
  204. package/src/core/color/PQ/PQ_constants.d.ts +43 -0
  205. package/src/core/color/PQ/PQ_constants.d.ts.map +1 -0
  206. package/src/core/color/PQ/PQ_constants.js +50 -0
  207. package/src/core/color/PQ/PQ_to_linear.d.ts +24 -0
  208. package/src/core/color/PQ/PQ_to_linear.d.ts.map +1 -0
  209. package/src/core/color/PQ/PQ_to_linear.js +35 -0
  210. package/src/core/color/PQ/linear_to_PQ.d.ts +27 -0
  211. package/src/core/color/PQ/linear_to_PQ.d.ts.map +1 -0
  212. package/src/core/color/PQ/linear_to_PQ.js +32 -0
  213. package/src/core/color/YCoCg/rgb_to_ycocg.js +20 -20
  214. package/src/core/color/YCoCg/ycocg_to_rgb.js +17 -17
  215. package/src/core/color/colormap/MAGMA_LUT.js +26 -26
  216. package/src/core/color/illuminant/D65_TRISTIMULUS_XYZ.js +19 -19
  217. package/src/core/color/lab/lab_apply_hunt_adjustment.js +27 -27
  218. package/src/core/color/lab/lab_distance_hyab.js +23 -23
  219. package/src/core/color/lab/xyz_to_lab.js +62 -62
  220. package/src/core/color/operations/color_darken.js +24 -24
  221. package/src/core/color/operations/color_desaturate.js +24 -24
  222. package/src/core/color/operations/color_lighten.js +24 -24
  223. package/src/core/color/operations/color_saturate.js +24 -24
  224. package/src/core/color/operations/color_scale_okhsv_channel.js +45 -45
  225. package/src/core/color/tonemap/tonemap_aces.js +41 -41
  226. package/src/core/color/ycxcz/xyz_to_ycxcz.js +28 -28
  227. package/src/core/color/ycxcz/ycxcz_to_xyz.js +19 -19
  228. package/src/core/dom/isImageBitmap.js +12 -12
  229. package/src/core/function/frameThrottle.js +23 -23
  230. package/src/core/geom/2d/aabb/aabb2_array_combine.js +7 -7
  231. package/src/core/geom/2d/aabb/aabb2_compute_area.js +7 -7
  232. package/src/core/geom/2d/aabb/aabb2_compute_center_from_multiple.js +7 -7
  233. package/src/core/geom/2d/aabb/aabb2_compute_overlap.js +7 -7
  234. package/src/core/geom/2d/aabb/aabb2_from_v2_array.js +7 -7
  235. package/src/core/geom/2d/aabb/aabb2_intersects_point.js +7 -7
  236. package/src/core/geom/2d/aabb/aabb2_overlap_exists.js +7 -7
  237. package/src/core/geom/2d/circle/circle_compute_circle_intersection.js +7 -7
  238. package/src/core/geom/2d/circle/circle_compute_circle_penetration.js +7 -7
  239. package/src/core/geom/2d/circle/circle_intersects_point.js +7 -7
  240. package/src/core/geom/2d/compute_polygon_area_2d.js +7 -7
  241. package/src/core/geom/2d/convex-hull/fixed_convex_hull_humus.js +7 -7
  242. package/src/core/geom/2d/convex-hull/fixed_convex_hull_relaxation.js +7 -7
  243. package/src/core/geom/2d/convex-hull/orientation3_array.js +7 -7
  244. package/src/core/geom/2d/intersect_ray_2d.js +7 -7
  245. package/src/core/geom/2d/line/line2_distance_to_point_sqr.js +7 -7
  246. package/src/core/geom/2d/line/line2_segment_intersection_fraction_2d.js +44 -44
  247. package/src/core/geom/2d/line/line_segment_compute_line_segment_intersection_2d.js +7 -7
  248. package/src/core/geom/2d/line/line_segment_compute_line_segment_intersection_array_2d.js +7 -7
  249. package/src/core/geom/2d/line/line_segment_compute_line_segment_intersection_vectors_2d.js +7 -7
  250. package/src/core/geom/2d/line/line_segment_compute_line_segment_intersection_vectors_array_2d.js +7 -7
  251. package/src/core/geom/2d/line/line_segment_intersection_fraction_2d.js +7 -7
  252. package/src/core/geom/2d/line/line_segment_line_segment_intersection_exists_2d.js +7 -7
  253. package/src/core/geom/2d/line/segment2_intersects_segment2_2d.js +25 -25
  254. package/src/core/geom/2d/line/segment2_segment_compute_intersection_array_2d.js +46 -46
  255. package/src/core/geom/2d/line/segment2_segment_intersection_fractions.js +52 -52
  256. package/src/core/geom/2d/oriented-box/min_area_rect_2d.js +69 -69
  257. package/src/core/geom/2d/polygon/TRIANGULATION_DESIGN.md +433 -433
  258. package/src/core/geom/2d/polygon/polygon2_clip_axis_halfplane.js +51 -51
  259. package/src/core/geom/2d/polygon/polygon2_clip_halfplane.js +50 -50
  260. package/src/core/geom/2d/polygon/polygon2_is_counter_clockwise.js +84 -84
  261. package/src/core/geom/2d/polygon/polygon2_signed_area.js +52 -52
  262. package/src/core/geom/2d/polygon/polygon2_triangulate.corpus.js +86 -86
  263. package/src/core/geom/2d/polygon/polygon2_triangulate.js +1280 -1280
  264. package/src/core/geom/2d/polygon/polygon2_triangulation_deviation.js +77 -77
  265. package/src/core/geom/2d/quad-tree/qt_collect_by_circle.js +39 -39
  266. package/src/core/geom/2d/quad-tree/qt_match_data_by_circle.js +101 -101
  267. package/src/core/geom/2d/quad-tree/qt_query_data_nearest_to_point.js +7 -7
  268. package/src/core/geom/2d/rectangle_to_aabb.js +7 -7
  269. package/src/core/geom/2d/spline_bezier2_2d.js +7 -7
  270. package/src/core/geom/2d/triangle/tri2_rasterize_conservative.js +99 -99
  271. package/src/core/geom/2d/triangle/tri2_signed_area.js +35 -35
  272. package/src/core/geom/2d/triangle2d_compute_area.js +7 -7
  273. package/src/core/geom/2d/triangle2d_contains_point.js +7 -7
  274. package/src/core/geom/2d/triangle2d_get_barycentric.js +7 -7
  275. package/src/core/geom/2d/v2_morton_encode.js +23 -23
  276. package/src/core/geom/3d/aabb/aabb3_array_intersects_frustum_degree.js +7 -7
  277. package/src/core/geom/3d/aabb/aabb3_box_surface_area_2.js +7 -7
  278. package/src/core/geom/3d/aabb/aabb3_build_frustum.js +5 -5
  279. package/src/core/geom/3d/aabb/aabb3_closest_point_on_surface.js +57 -57
  280. package/src/core/geom/3d/aabb/aabb3_combined_surface_area.js +7 -7
  281. package/src/core/geom/3d/aabb/aabb3_compute_half_surface_area.js +7 -7
  282. package/src/core/geom/3d/aabb/aabb3_compute_projected_area.js +7 -7
  283. package/src/core/geom/3d/aabb/aabb3_compute_surface_area.js +7 -7
  284. package/src/core/geom/3d/aabb/aabb3_detailed_volume_intersection.js +7 -7
  285. package/src/core/geom/3d/aabb/aabb3_estimate_projected_area2.js +7 -7
  286. package/src/core/geom/3d/aabb/aabb3_from_threejs_geometry.js +7 -7
  287. package/src/core/geom/3d/aabb/aabb3_from_triangle_group.js +46 -46
  288. package/src/core/geom/3d/aabb/aabb3_intersects_frustum_degree.js +7 -7
  289. package/src/core/geom/3d/aabb/aabb3_intersects_line_segment.js +7 -7
  290. package/src/core/geom/3d/aabb/aabb3_near_distance_to_intersection_ray_segment.js +7 -7
  291. package/src/core/geom/3d/aabb/aabb3_nearest_point_on_surface.js +7 -7
  292. package/src/core/geom/3d/aabb/aabb3_ray_segment_entry_distance.js +95 -95
  293. package/src/core/geom/3d/aabb/aabb3_raycast.js +7 -7
  294. package/src/core/geom/3d/aabb/aabb3_transform_oriented.js +93 -93
  295. package/src/core/geom/3d/aabb/aabb3_transform_oriented_inverse.js +82 -82
  296. package/src/core/geom/3d/aabb/compute_aabb_from_points.js +7 -7
  297. package/src/core/geom/3d/aabb/compute_triangle_group_aabb3.js +7 -7
  298. package/src/core/geom/3d/atlas/ATLAS_PORT_PLAN.md +486 -486
  299. package/src/core/geom/3d/atlas/BFF_PLAN.md +174 -174
  300. package/src/core/geom/3d/atlas/Chart.js +77 -77
  301. package/src/core/geom/3d/atlas/REVIEW_02.md +392 -392
  302. package/src/core/geom/3d/atlas/atlas_bench_lib.js +315 -315
  303. package/src/core/geom/3d/atlas/atlas_chart_type.js +16 -16
  304. package/src/core/geom/3d/atlas/atlas_compute_charts.js +188 -188
  305. package/src/core/geom/3d/atlas/atlas_extract_chart.js +107 -107
  306. package/src/core/geom/3d/atlas/atlas_generate.js +50 -50
  307. package/src/core/geom/3d/atlas/atlas_test_fixtures.js +266 -266
  308. package/src/core/geom/3d/atlas/atlas_write_chart_uvs.js +36 -36
  309. package/src/core/geom/3d/atlas/data/atlas_build_edge_dihedrals.js +62 -62
  310. package/src/core/geom/3d/atlas/data/atlas_build_edge_lengths.js +33 -33
  311. package/src/core/geom/3d/atlas/data/atlas_build_face_areas.js +50 -50
  312. package/src/core/geom/3d/atlas/io/atlas_mesh_weld_colocals.js +39 -39
  313. package/src/core/geom/3d/atlas/io/bt_loop_uv.js +35 -35
  314. package/src/core/geom/3d/atlas/pack/ChartPlacement.js +46 -46
  315. package/src/core/geom/3d/atlas/param/atlas_chart_parameterize_bff.js +269 -269
  316. package/src/core/geom/3d/atlas/param/atlas_chart_parameterize_lscm.js +209 -209
  317. package/src/core/geom/3d/atlas/param/atlas_chart_parameterize_ortho.js +38 -38
  318. package/src/core/geom/3d/atlas/param/atlas_chart_stretch_metric.js +86 -86
  319. package/src/core/geom/3d/atlas/param/atlas_piecewise_resegment.js +183 -183
  320. package/src/core/geom/3d/atlas/param/fit_plane_basis.js +66 -66
  321. package/src/core/geom/3d/atlas/segment/RegionGraph.js +40 -40
  322. package/src/core/geom/3d/atlas/segment/atlas_build_region_graph.js +136 -136
  323. package/src/core/geom/3d/atlas/segment/atlas_chart_roundness_delta.js +30 -30
  324. package/src/core/geom/3d/atlas/segment/atlas_compute_planar_regions.js +77 -77
  325. package/src/core/geom/3d/atlas/segment/atlas_merge_charts.js +116 -116
  326. package/src/core/geom/3d/atlas/segment/atlas_segment_charts.js +271 -271
  327. package/src/core/geom/3d/atlas/segment/atlas_segment_charts_atomic.js +191 -191
  328. package/src/core/geom/3d/box/box3_projected_half_extent.js +35 -35
  329. package/src/core/geom/3d/capsule/capsule_intersects_aabb3_closed.js +67 -67
  330. package/src/core/geom/3d/capsule/capsule_intersects_aabb3_iterative.js +137 -137
  331. package/src/core/geom/3d/compute_circle_bounding_box.js +7 -7
  332. package/src/core/geom/3d/cone/computeConeBoundingBox.js +7 -7
  333. package/src/core/geom/3d/cone/computeConePlaneSide.js +7 -7
  334. package/src/core/geom/3d/cone/compute_bounding_cone_of_2_cones.js +7 -7
  335. package/src/core/geom/3d/cylinder/cylinder3_raycast.d.ts +38 -0
  336. package/src/core/geom/3d/cylinder/cylinder3_raycast.d.ts.map +1 -0
  337. package/src/core/geom/3d/cylinder/cylinder3_raycast.js +105 -0
  338. package/src/core/geom/3d/equirectangular/equirectangular_direction_to_uv.js +18 -18
  339. package/src/core/geom/3d/equirectangular/equirectangular_uv_to_direction.js +24 -24
  340. package/src/core/geom/3d/frustum/clipping_volume_matrix4_project.js +7 -7
  341. package/src/core/geom/3d/frustum/frustum3_computeNearestPointToPoint.js +7 -7
  342. package/src/core/geom/3d/frustum/frustum3_compute_closest_point.js +117 -117
  343. package/src/core/geom/3d/frustum/frustum_matrix4_project.js +7 -7
  344. package/src/core/geom/3d/frustum/hexahedron_from_aabb.js +7 -7
  345. package/src/core/geom/3d/frustum/read_frustum_corner.js +17 -17
  346. package/src/core/geom/3d/frustum/read_three_planes_to_array.js +7 -7
  347. package/src/core/geom/3d/frustum/slice_frustum_linear_to_points.js +7 -7
  348. package/src/core/geom/3d/gjk/GJK_REVIEW_NOTES.md +146 -146
  349. package/src/core/geom/3d/gjk/gjk.js +430 -430
  350. package/src/core/geom/3d/gjk/gjk_epa_penetration.js +520 -520
  351. package/src/core/geom/3d/gjk/minkowski_support.js +71 -71
  352. package/src/core/geom/3d/gjk/mpr.js +368 -368
  353. package/src/core/geom/3d/line/line3_closest_points_segment_segment.js +7 -7
  354. package/src/core/geom/3d/line/line3_compute_nearest_point_to_point.js +7 -7
  355. package/src/core/geom/3d/line/line3_compute_point_segment_point_distance_unfolded.js +64 -64
  356. package/src/core/geom/3d/line/line3_compute_segment_closest_point_to_aabb3_t.js +153 -153
  357. package/src/core/geom/3d/line/line3_compute_segment_nearest_point_to_aabb3_t.js +7 -7
  358. package/src/core/geom/3d/line/line3_compute_segment_nearest_point_to_point_t.js +7 -7
  359. package/src/core/geom/3d/line/line3_compute_segment_segment_closest_points.js +88 -88
  360. package/src/core/geom/3d/line/line3_segment_segment_closest_point_pair.js +71 -71
  361. package/src/core/geom/3d/line/segment3_point_distance_to_segments.js +25 -25
  362. package/src/core/geom/3d/mat4/allocate_m4.js +7 -7
  363. package/src/core/geom/3d/mat4/apply_mat4_transform_to_direction_v3_array.js +7 -7
  364. package/src/core/geom/3d/mat4/apply_mat4_transform_to_v3_array.js +7 -7
  365. package/src/core/geom/3d/mat4/compose_matrix4_array.js +7 -7
  366. package/src/core/geom/3d/mat4/decompose_matrix_4_array.js +7 -7
  367. package/src/core/geom/3d/mat4/eulerAnglesFromMatrix.js +7 -7
  368. package/src/core/geom/3d/mat4/m4_compose.js +22 -22
  369. package/src/core/geom/3d/mat4/m4_compute_normal_matrix3.js +7 -7
  370. package/src/core/geom/3d/mat4/m4_decompose.js +64 -64
  371. package/src/core/geom/3d/mat4/m4_decompose_array.js +157 -157
  372. package/src/core/geom/3d/mat4/m4_from_rotation_translation_scale.js +32 -32
  373. package/src/core/geom/3d/mat4/m4_from_rotation_translation_scale_scalar.js +67 -67
  374. package/src/core/geom/3d/mat4/m4_linear_matrix3.js +29 -29
  375. package/src/core/geom/3d/mat4/m4_look_at.js +96 -96
  376. package/src/core/geom/3d/mat4/m4_make_rotation_x.js +47 -47
  377. package/src/core/geom/3d/mat4/m4_make_rotation_y.js +47 -47
  378. package/src/core/geom/3d/mat4/m4_make_rotation_z.js +47 -47
  379. package/src/core/geom/3d/mat4/m4_normal_matrix3.js +39 -39
  380. package/src/core/geom/3d/mat4/m4_perspective.js +66 -66
  381. package/src/core/geom/3d/mat4/m4_transpose.js +48 -48
  382. package/src/core/geom/3d/morton/mortonEncode_LUT.js +7 -7
  383. package/src/core/geom/3d/morton/mortonEncode_magicbits.js +7 -7
  384. package/src/core/geom/3d/normal/hemioct/encode_unit3_hemioct.js +5 -5
  385. package/src/core/geom/3d/normal/hemioct/encode_unit_to_hemioct.js +28 -28
  386. package/src/core/geom/3d/normal/lambert_azimuth/decode_azimuth_to_unit.js +30 -30
  387. package/src/core/geom/3d/normal/lambert_azimuth/encode_unit_to_azimuth.js +19 -19
  388. package/src/core/geom/3d/normal/spherical/decode_spheremap_to_unit.js +38 -38
  389. package/src/core/geom/3d/normal/spherical/encode_unit_to_spheremap.js +30 -30
  390. package/src/core/geom/3d/plane/is_point_within_planes.js +7 -7
  391. package/src/core/geom/3d/plane/orient3d_fast_point.js +47 -47
  392. package/src/core/geom/3d/plane/plane3_compute_convex_3_plane_intersection.js +7 -7
  393. package/src/core/geom/3d/plane/plane3_compute_plane_intersection.js +7 -7
  394. package/src/core/geom/3d/plane/plane3_intersect_plane.js +7 -7
  395. package/src/core/geom/3d/plane/plane3_three_compute_convex_3_plane_intersection.js +7 -7
  396. package/src/core/geom/3d/point/point3_raycast.d.ts +33 -0
  397. package/src/core/geom/3d/point/point3_raycast.d.ts.map +1 -0
  398. package/src/core/geom/3d/point/point3_raycast.js +47 -0
  399. package/src/core/geom/3d/polygon/polygon3_compute_normal.js +60 -60
  400. package/src/core/geom/3d/polygon/polygon3_triangulate.js +94 -94
  401. package/src/core/geom/3d/polyhedron/convex_polyhedron3_raycast.d.ts +40 -0
  402. package/src/core/geom/3d/polyhedron/convex_polyhedron3_raycast.d.ts.map +1 -0
  403. package/src/core/geom/3d/polyhedron/convex_polyhedron3_raycast.js +94 -0
  404. package/src/core/geom/3d/quadric/QUADRIC3_SIZE.js +14 -14
  405. package/src/core/geom/3d/quadric/Quadric3.js +282 -282
  406. package/src/core/geom/3d/quadric/quadric3_add.js +33 -33
  407. package/src/core/geom/3d/quadric/quadric3_clear.js +25 -25
  408. package/src/core/geom/3d/quadric/quadric3_copy.js +27 -27
  409. package/src/core/geom/3d/quadric/quadric3_distance.js +36 -36
  410. package/src/core/geom/3d/quadric/quadric3_evaluate.js +25 -25
  411. package/src/core/geom/3d/quadric/quadric3_optimize.js +45 -45
  412. package/src/core/geom/3d/quadric/quadric3_scale.js +32 -32
  413. package/src/core/geom/3d/quadric/quadric3_set_from_plane_through_point.js +30 -30
  414. package/src/core/geom/3d/quadric/quadric3_set_from_vector4.js +35 -35
  415. package/src/core/geom/3d/quadric/quadric3_sub.js +36 -36
  416. package/src/core/geom/3d/quadric/quadric3_to_tensor_m3.js +28 -28
  417. package/src/core/geom/3d/quadric/quadric3_to_tensor_m3_inverse.js +56 -56
  418. package/src/core/geom/3d/quadric/quadric3_to_vector3.js +19 -19
  419. package/src/core/geom/3d/quaternion/quat3_createFromAxisAngle.js +7 -7
  420. package/src/core/geom/3d/quaternion/quat3_integrate.js +62 -62
  421. package/src/core/geom/3d/quaternion/quat3_multiply.js +31 -31
  422. package/src/core/geom/3d/quaternion/quat3_nlerp.js +72 -72
  423. package/src/core/geom/3d/quaternion/quat3_to_matrix3.js +69 -69
  424. package/src/core/geom/3d/quaternion/quat_decode_from_uint32.js +7 -7
  425. package/src/core/geom/3d/quaternion/quat_encode_to_uint32.js +7 -7
  426. package/src/core/geom/3d/ray/ray3_array_compose.js +7 -7
  427. package/src/core/geom/3d/ray/ray3_compute_nearest_point_to_point.js +7 -7
  428. package/src/core/geom/3d/ray/ray3_distance_to_point.js +7 -7
  429. package/src/core/geom/3d/ray/ray3_shift_origin_along_direction.js +7 -7
  430. package/src/core/geom/3d/shape/ConvexHullShape3D.d.ts +17 -0
  431. package/src/core/geom/3d/shape/ConvexHullShape3D.d.ts.map +1 -1
  432. package/src/core/geom/3d/shape/ConvexHullShape3D.js +43 -0
  433. package/src/core/geom/3d/shape/CylinderShape3D.d.ts +1 -0
  434. package/src/core/geom/3d/shape/CylinderShape3D.d.ts.map +1 -1
  435. package/src/core/geom/3d/shape/CylinderShape3D.js +21 -0
  436. package/src/core/geom/3d/shape/PointShape3D.d.ts +7 -0
  437. package/src/core/geom/3d/shape/PointShape3D.d.ts.map +1 -1
  438. package/src/core/geom/3d/shape/PointShape3D.js +88 -63
  439. package/src/core/geom/3d/shape/PosedShape3D.d.ts +6 -0
  440. package/src/core/geom/3d/shape/PosedShape3D.d.ts.map +1 -1
  441. package/src/core/geom/3d/shape/PosedShape3D.js +27 -0
  442. package/src/core/geom/3d/shape/TransformedShape3D.d.ts +10 -0
  443. package/src/core/geom/3d/shape/TransformedShape3D.d.ts.map +1 -1
  444. package/src/core/geom/3d/shape/TransformedShape3D.js +13 -0
  445. package/src/core/geom/3d/shape/Triangle3D.d.ts +1 -0
  446. package/src/core/geom/3d/shape/Triangle3D.d.ts.map +1 -1
  447. package/src/core/geom/3d/shape/Triangle3D.js +26 -0
  448. package/src/core/geom/3d/shape/UnionShape3D.d.ts +6 -0
  449. package/src/core/geom/3d/shape/UnionShape3D.d.ts.map +1 -1
  450. package/src/core/geom/3d/shape/UnionShape3D.js +7 -0
  451. package/src/core/geom/3d/shape/UnitCubeShape3D.js +45 -45
  452. package/src/core/geom/3d/shape/UnitSphereShape3D.js +44 -44
  453. package/src/core/geom/3d/shape/shape3_mesh_from_geometry.js +64 -64
  454. package/src/core/geom/3d/shape/shape_mesh_from_geometry.js +7 -7
  455. package/src/core/geom/3d/shape/util/compute_signed_distance_gradient_by_sampling.js +51 -51
  456. package/src/core/geom/3d/shape/util/shape3d_voxelize_to_grid.js +7 -7
  457. package/src/core/geom/3d/sphere/compute_bounding_sphere_of_2_spheres.js +7 -7
  458. package/src/core/geom/3d/sphere/harmonics/sh3_convolve_with_zh.js +53 -53
  459. package/src/core/geom/3d/sphere/harmonics/sh3_ggx_zh.js +30 -30
  460. package/src/core/geom/3d/sphere/harmonics/sh3_rotate_bl.js +7 -7
  461. package/src/core/geom/3d/sphere/harmonics/sh_compute_K.js +7 -7
  462. package/src/core/geom/3d/sphere/sphere_array_intersects_point.js +7 -7
  463. package/src/core/geom/3d/sphere/sphere_array_intersects_ray.js +7 -7
  464. package/src/core/geom/3d/sphere/sphere_intersects_point.js +7 -7
  465. package/src/core/geom/3d/sphere/sphere_matrix4_transform.js +5 -5
  466. package/src/core/geom/3d/sphere/sphere_projected_sphere_radius_sqr.js +7 -7
  467. package/src/core/geom/3d/sphere/sphere_radius_sqr_from_v3_array_transformed.js +7 -7
  468. package/src/core/geom/3d/sphere/spherical_from_cartesian.js +7 -7
  469. package/src/core/geom/3d/tetrahedra/compute_tetrahedral_mesh_from_surface.js +174 -174
  470. package/src/core/geom/3d/tetrahedra/compute_tetrahedron_quality.js +7 -7
  471. package/src/core/geom/3d/tetrahedra/compute_tetrahedron_volume.js +7 -7
  472. package/src/core/geom/3d/tetrahedra/delaunay/fill_in_a_cavity.js +7 -7
  473. package/src/core/geom/3d/tetrahedra/graphics/build_tetrahedral_mesh_geometry.js +39 -39
  474. package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_build_vertex_to_tets_map.js +48 -48
  475. package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_carve_outside_surface.js +173 -173
  476. package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_compute_tet_quality.js +22 -22
  477. package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_find_tets_around_edge.js +146 -146
  478. package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_flip_23.js +232 -232
  479. package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_flip_32.js +255 -255
  480. package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_improve_quality.js +387 -387
  481. package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_smooth_vertex.js +140 -140
  482. package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_tet_get_neighbours.js +7 -7
  483. package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_vertex_is_boundary.js +97 -97
  484. package/src/core/geom/3d/tetrahedra/tetrahedron_compute_quality.js +66 -66
  485. package/src/core/geom/3d/tetrahedra/triangle/triangle_decode_depth.js +59 -59
  486. package/src/core/geom/3d/tetrahedra/triangle/triangle_rasterized_depth_sample_index.js +54 -54
  487. package/src/core/geom/3d/tetrahedra/validate_neighbour.js +70 -70
  488. package/src/core/geom/3d/topology/struct/binary/BinaryDataBlock.js +314 -314
  489. package/src/core/geom/3d/topology/struct/binary/BinaryDataLayer.js +364 -364
  490. package/src/core/geom/3d/topology/struct/binary/BinaryElementPool.js +567 -567
  491. package/src/core/geom/3d/topology/struct/binary/BinaryTopology.js +1085 -1085
  492. package/src/core/geom/3d/topology/struct/binary/io/bt_boundary_loop.js +73 -73
  493. package/src/core/geom/3d/topology/struct/binary/io/bt_loop_kill.js +35 -35
  494. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_append.js +119 -119
  495. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_close_boundary_holes.js +84 -84
  496. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_compact.js +172 -172
  497. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_compute_face_normals.js +56 -56
  498. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_compute_vertex_quadratics.js +7 -7
  499. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_compute_vertex_quadrics.js +227 -227
  500. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_face_decouple.js +161 -161
  501. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_face_island_erode.js +490 -490
  502. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_fill_small_holes.js +120 -120
  503. package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_from_indexed_geometry.js +120 -120
  504. package/src/core/geom/3d/topology/struct/binary/io/edge/bt_edge_collapse.js +52 -52
  505. package/src/core/geom/3d/topology/struct/binary/io/edge/bt_edge_create.js +115 -115
  506. package/src/core/geom/3d/topology/struct/binary/io/edge/bt_edge_flip.js +142 -142
  507. package/src/core/geom/3d/topology/struct/binary/io/edge/bt_edge_get_or_create.js +21 -21
  508. package/src/core/geom/3d/topology/struct/binary/io/edge/bt_edge_kill_parallels.js +92 -92
  509. package/src/core/geom/3d/topology/struct/binary/io/edge/bt_edge_split.js +179 -179
  510. package/src/core/geom/3d/topology/struct/binary/io/edge/bt_edge_swap_vertex_slots.js +28 -28
  511. package/src/core/geom/3d/topology/struct/binary/io/edge/bt_kill_only_edge.js +8 -8
  512. package/src/core/geom/3d/topology/struct/binary/io/edge/bt_mesh_fuse_duplicate_edges.js +83 -83
  513. package/src/core/geom/3d/topology/struct/binary/io/edge/bt_mesh_kill_short_edges.js +89 -89
  514. package/src/core/geom/3d/topology/struct/binary/io/face/bt_face_kill.js +25 -25
  515. package/src/core/geom/3d/topology/struct/binary/io/face/bt_face_poke.js +127 -127
  516. package/src/core/geom/3d/topology/struct/binary/io/face/bt_face_triangulate.js +268 -268
  517. package/src/core/geom/3d/topology/struct/binary/io/face/bt_kill_only_face.js +8 -8
  518. package/src/core/geom/3d/topology/struct/binary/io/face/bt_mesh_kill_degenerate_faces.js +72 -72
  519. package/src/core/geom/3d/topology/struct/binary/io/vertex/bt_kill_only_vert.js +7 -7
  520. package/src/core/geom/3d/topology/struct/binary/io/vertex/bt_merge_verts_by_distance.js +7 -7
  521. package/src/core/geom/3d/topology/struct/binary/io/vertex/bt_mesh_relative_merge_distance.js +48 -48
  522. package/src/core/geom/3d/topology/struct/binary/io/vertex/bt_mesh_split_pinched_vertices.js +256 -256
  523. package/src/core/geom/3d/topology/struct/binary/io/vertex/bt_mesh_vertex_merge_distance.js +77 -77
  524. package/src/core/geom/3d/topology/struct/binary/io/vertex/bt_vert_fuse_duplicate_edges.js +7 -7
  525. package/src/core/geom/3d/topology/struct/binary/io/vertex/bt_vert_kill.js +7 -7
  526. package/src/core/geom/3d/topology/struct/binary/io/vertex/bt_vertex_fuse_duplicate_edges.js +148 -148
  527. package/src/core/geom/3d/topology/struct/binary/io/vertex/bt_vertex_kill_only.js +7 -7
  528. package/src/core/geom/3d/topology/struct/binary/query/bt_collect_boundary_segments.js +29 -29
  529. package/src/core/geom/3d/topology/struct/binary/query/bt_edge_collapse_breaks_link_condition.js +107 -107
  530. package/src/core/geom/3d/topology/struct/binary/query/bt_edge_flip_is_legal.js +41 -41
  531. package/src/core/geom/3d/topology/struct/binary/query/bt_edge_flip_would_fold.js +120 -120
  532. package/src/core/geom/3d/topology/struct/binary/query/bt_edge_get.js +42 -42
  533. package/src/core/geom/3d/topology/struct/binary/query/bt_edge_is_boundary.js +20 -20
  534. package/src/core/geom/3d/topology/struct/binary/query/bt_edge_other_face.d.ts +32 -0
  535. package/src/core/geom/3d/topology/struct/binary/query/bt_edge_other_face.d.ts.map +1 -0
  536. package/src/core/geom/3d/topology/struct/binary/query/bt_edge_other_face.js +59 -0
  537. package/src/core/geom/3d/topology/struct/binary/query/bt_edge_read_diamond.js +96 -96
  538. package/src/core/geom/3d/topology/struct/binary/query/bt_face_compute_newell_normal.js +72 -72
  539. package/src/core/geom/3d/topology/struct/binary/query/bt_face_get_attached_faces.js +7 -7
  540. package/src/core/geom/3d/topology/struct/binary/query/bt_face_get_edge_adjacent_faces.js +39 -39
  541. package/src/core/geom/3d/topology/struct/binary/query/bt_face_get_edge_adjacent_faces_weighted.js +93 -93
  542. package/src/core/geom/3d/topology/struct/binary/query/bt_face_get_neighbour_faces.js +7 -7
  543. package/src/core/geom/3d/topology/struct/binary/query/bt_face_get_shared_loop.js +48 -48
  544. package/src/core/geom/3d/topology/struct/binary/query/bt_face_island_flood_fill.js +45 -45
  545. package/src/core/geom/3d/topology/struct/binary/query/bt_face_read_triangle.js +66 -66
  546. package/src/core/geom/3d/topology/struct/binary/query/bt_face_third_vertex.d.ts +26 -0
  547. package/src/core/geom/3d/topology/struct/binary/query/bt_face_third_vertex.d.ts.map +1 -0
  548. package/src/core/geom/3d/topology/struct/binary/query/bt_face_third_vertex.js +55 -0
  549. package/src/core/geom/3d/topology/struct/binary/query/bt_faces_shared_loop.js +7 -7
  550. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_assert_valid.js +44 -44
  551. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_build_boundary_euclidean_distance_field.js +32 -32
  552. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_compute_face_islands.js +53 -53
  553. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_face_find_path.js +703 -703
  554. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_sample_interior_grid_points.js +181 -181
  555. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_segment_penetrates_surface.js +133 -133
  556. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_surface_ray_parity.js +82 -82
  557. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_validate.js +599 -599
  558. package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_walk_boundary_loops.js +108 -108
  559. package/src/core/geom/3d/topology/struct/binary/query/bt_query_edge_is_boundary.js +7 -7
  560. package/src/core/geom/3d/triangle/computeTriangleClosestPointToPointBarycentric.js +7 -7
  561. package/src/core/geom/3d/triangle/computeTriangleRayIntersection.js +7 -7
  562. package/src/core/geom/3d/triangle/computeTriangleRayIntersectionBarycentric.js +7 -7
  563. package/src/core/geom/3d/triangle/computeTriangleRayIntersectionBarycentricEdge.js +7 -7
  564. package/src/core/geom/3d/triangle/computeTriangleRayIntersectionBarycentricGeometry.js +7 -7
  565. package/src/core/geom/3d/triangle/compute_triangle_area_3d.js +7 -7
  566. package/src/core/geom/3d/triangle/compute_triangle_normal.js +7 -7
  567. package/src/core/geom/3d/triangle/rayTriangleIntersection.js +7 -7
  568. package/src/core/geom/3d/triangle/tri3_closest_point.js +65 -65
  569. package/src/core/geom/3d/triangle/tri3_closest_point_barycentric.js +171 -171
  570. package/src/core/geom/3d/triangle/tri3_flatten_isometric.js +79 -79
  571. package/src/core/geom/3d/triangle/tri3_ray_intersection.js +160 -160
  572. package/src/core/geom/3d/triangle/tri3_ray_intersection_barycentric.js +96 -96
  573. package/src/core/geom/3d/triangle/tri3_raycast.d.ts +42 -0
  574. package/src/core/geom/3d/triangle/tri3_raycast.d.ts.map +1 -0
  575. package/src/core/geom/3d/triangle/tri3_raycast.js +94 -0
  576. package/src/core/geom/3d/triangle/triangle3_incenter.js +7 -7
  577. package/src/core/geom/3d/triangle/triangle_compute_plane_side.js +7 -7
  578. package/src/core/geom/3d/triangle/triangle_compute_signed_volume.js +7 -7
  579. package/src/core/geom/3d/triangle/triangle_intersects_clipping_volume.js +7 -7
  580. package/src/core/geom/3d/triangle/triangle_mesh_compute_signed_volume.js +7 -7
  581. package/src/core/geom/3d/triangle/v3_compute_triangle_normal.js +7 -7
  582. package/src/core/geom/3d/util/make_justified_point_grid.js +7 -7
  583. package/src/core/geom/GEOMETRY_REVIEW_002_API_ISSUES.md +381 -381
  584. package/src/core/geom/GEOMETRY_REVIEW_002_NAMING.md +684 -684
  585. package/src/core/geom/MANIFOLD_COMPARISON_2026_08_01.md +554 -554
  586. package/src/core/geom/mat3/m3_cm_from_translation.js +7 -7
  587. package/src/core/geom/mat3/m3_cm_invert.js +7 -7
  588. package/src/core/geom/mat3/m3_make_rotation.js +5 -5
  589. package/src/core/geom/mat3/m3_make_rotation_TBN.js +31 -31
  590. package/src/core/geom/mat3/m3_multiply_vec3.js +7 -7
  591. package/src/core/geom/packing/computeBoundingSphereOfSpheres.js +7 -7
  592. package/src/core/geom/packing/max-rect/cost/costByBestShortSide.js +7 -7
  593. package/src/core/geom/packing/max-rect/cost/costByRemainingArea.js +7 -7
  594. package/src/core/geom/packing/max-rect/cutArea.js +7 -7
  595. package/src/core/geom/packing/max-rect/findBestContainer.js +7 -7
  596. package/src/core/geom/packing/max-rect/packMaxRectangles.js +7 -7
  597. package/src/core/geom/packing/max-rect/packOneBox.js +7 -7
  598. package/src/core/geom/packing/max-rect/removeRedundantBoxes.js +7 -7
  599. package/src/core/geom/packing/max-rect/removeRedundantBoxesArray.js +7 -7
  600. package/src/core/geom/random/randomPointInBox.js +7 -7
  601. package/src/core/geom/random/randomPointInCircle.js +7 -7
  602. package/src/core/geom/random/randomPointInPoint.js +7 -7
  603. package/src/core/geom/random/randomPointInSphere.js +7 -7
  604. package/src/core/geom/random/randomPointOnBox.js +7 -7
  605. package/src/core/geom/random/randomPointOnSphere.js +7 -7
  606. package/src/core/geom/random/random_orthonormal_basis.js +31 -31
  607. package/src/core/geom/vec/vector_axpy.js +15 -15
  608. package/src/core/geom/vec/vector_axpy_offset.js +20 -20
  609. package/src/core/geom/vec/vector_copy.js +7 -7
  610. package/src/core/geom/vec/vector_dot_offset.js +25 -25
  611. package/src/core/geom/vec/vector_scale_array.js +7 -7
  612. package/src/core/geom/vec2/v2_rotate.js +21 -21
  613. package/src/core/geom/vec2/v2_rotate_cos_sin.js +21 -21
  614. package/src/core/geom/vec3/v3_angle_atan2_between.js +7 -7
  615. package/src/core/geom/vec3/v3_angle_between.js +7 -7
  616. package/src/core/geom/vec3/v3_angle_cos_between.js +7 -7
  617. package/src/core/geom/vec3/v3_array_add_in_place.js +7 -7
  618. package/src/core/geom/vec3/v3_array_centroid.js +7 -7
  619. package/src/core/geom/vec3/v3_array_copy.js +7 -7
  620. package/src/core/geom/vec3/v3_array_displace_in_direction.js +7 -7
  621. package/src/core/geom/vec3/v3_array_equals.js +7 -7
  622. package/src/core/geom/vec3/v3_array_immediate_add.js +7 -7
  623. package/src/core/geom/vec3/v3_array_matrix4_rotate.js +7 -7
  624. package/src/core/geom/vec3/v3_array_normalize.js +7 -7
  625. package/src/core/geom/vec3/v3_array_scale.js +7 -7
  626. package/src/core/geom/vec3/v3_compute_interior_angle.js +7 -7
  627. package/src/core/geom/vec3/v3_cotangent.js +33 -33
  628. package/src/core/geom/vec3/v3_dot_array_array.js +7 -7
  629. package/src/core/geom/vec3/v3_matrix3_multiply.js +30 -30
  630. package/src/core/geom/vec3/v3_matrix3_rotate.js +49 -49
  631. package/src/core/geom/vec3/v3_matrix4_rotate.js +7 -7
  632. package/src/core/geom/vec3/v3_multiply.js +23 -23
  633. package/src/core/geom/vec3/v3_multiply_scalar.js +7 -7
  634. package/src/core/geom/vec3/v3_orthonormal_matrix_from_normal.js +49 -49
  635. package/src/core/geom/vec3/v3_quat3_apply.js +7 -7
  636. package/src/core/geom/vec3/v3_quat3_apply_inverse.js +7 -7
  637. package/src/core/geom/vec3/v3_quaternion_apply.js +39 -39
  638. package/src/core/geom/vec3/v3_quaternion_apply_inverse.js +41 -41
  639. package/src/core/geom/vec3/v3_reflect.js +24 -24
  640. package/src/core/geom/vec3/v3_scale_array.js +18 -18
  641. package/src/core/geom/vec3/v3_triple_cross.js +45 -45
  642. package/src/core/geom/vec3/v3_triple_cross_product.js +7 -7
  643. package/src/core/geom/vec3/v3_uniform_sample_cone.js +21 -21
  644. package/src/core/geom/vec4/v4_multiply_mat4.js +7 -7
  645. package/src/core/graph/csr/csr_graph_build_distance_field.js +112 -112
  646. package/src/core/graph/csr/csr_graph_find_edge.js +25 -25
  647. package/src/core/graph/csr/csr_graph_find_shortest_path.js +105 -105
  648. package/src/core/graph/csr/csr_graph_from_undirected_edge_list.js +94 -94
  649. package/src/core/graph/graph_k_means_cluster.js +250 -250
  650. package/src/core/graph/layout/CircleLayout.js +1 -1
  651. package/src/core/graph/layout/box/BoxLayouter.js +1 -1
  652. package/src/core/graph/layout/graph_peel_topological_layer.js +45 -45
  653. package/src/core/graph/metis/BinaryTopologyFaceGraph.js +49 -49
  654. package/src/core/graph/metis/bt_mesh_build_face_graph.js +111 -111
  655. package/src/core/graph/metis/cluster_mesh_metis.js +137 -137
  656. package/src/core/graph/metis/native/bisection/bisect_graph.js +100 -100
  657. package/src/core/graph/metis/native/bisection/compute_2way_params.js +86 -86
  658. package/src/core/graph/metis/native/bisection/fm_2way.js +297 -297
  659. package/src/core/graph/metis/native/bisection/grow_bisection.js +137 -137
  660. package/src/core/graph/metis/native/bisection/split_graph_two_way.js +119 -119
  661. package/src/core/graph/metis/native/coarsen/coarsen_graph.js +94 -94
  662. package/src/core/graph/metis/native/coarsen/create_coarse_graph.js +158 -158
  663. package/src/core/graph/metis/native/coarsen/match_shem.js +175 -175
  664. package/src/core/graph/metis/native/initial/initial_kway_bfs.js +122 -122
  665. package/src/core/graph/metis/native/initial/initial_kway_recursive_bisection.js +170 -170
  666. package/src/core/graph/metis/native/metis_partition_kway.js +126 -126
  667. package/src/core/graph/metis/native/refine/RefinementScratch.js +53 -53
  668. package/src/core/graph/metis/native/refine/fm_kway.js +487 -487
  669. package/src/core/graph/metis/native/refine/project_kway.js +43 -43
  670. package/src/core/graph/metis/native/refine/refine_kway.js +43 -43
  671. package/src/core/lang/reactive/pegjs/parser.js +3458 -3458
  672. package/src/core/math/complex/complex_horner_eval.js +31 -31
  673. package/src/core/math/computeWholeDivisorLow.js +33 -33
  674. package/src/core/math/f32_next_down.js +24 -24
  675. package/src/core/math/f32_next_up.js +27 -27
  676. package/src/core/math/hash/hash_mix2.js +22 -22
  677. package/src/core/math/hash/hash_mix3.js +19 -19
  678. package/src/core/math/linalg/cg/cg_solve.js +106 -106
  679. package/src/core/math/linalg/cg/cg_solve_normal_equations.js +59 -59
  680. package/src/core/math/linalg/cubic_residual_times_derivative_accumulate.js +43 -43
  681. package/src/core/math/linalg/eigen/matrix_householder_in_place.js +122 -122
  682. package/src/core/math/linalg/eigen/matrix_qr_in_place.js +190 -190
  683. package/src/core/math/linalg/eigen/matrix_symmetric_3x3_eigen.js +117 -117
  684. package/src/core/math/linalg/givens/givens_apply_rows.js +28 -28
  685. package/src/core/math/linalg/givens/givens_apply_rows_offset.js +30 -30
  686. package/src/core/math/linalg/givens/givens_rotation_coefficients.js +39 -39
  687. package/src/core/math/linalg/lu_factor_linear_system.js +108 -108
  688. package/src/core/math/linalg/lu_solve_linear_system.js +53 -53
  689. package/src/core/math/linalg/polynomial_add_into.js +29 -29
  690. package/src/core/math/linalg/polynomial_complex_roots_aberth_ehrlich.js +159 -159
  691. package/src/core/math/linalg/polynomial_cubic_derivative_eval.js +16 -16
  692. package/src/core/math/linalg/polynomial_cubic_horner_eval.js +19 -19
  693. package/src/core/math/linalg/polynomial_cubic_second_derivative_eval.js +14 -14
  694. package/src/core/math/linalg/polynomial_multiply.js +41 -41
  695. package/src/core/math/linalg/polynomial_real_roots_in_interval.js +211 -211
  696. package/src/core/math/linalg/polynomial_root_bound_cauchy.js +30 -30
  697. package/src/core/math/linalg/polynomial_scale_into.js +17 -17
  698. package/src/core/math/linalg/polynomial_sub_into.js +29 -29
  699. package/src/core/math/linalg/solve_linear_system_GEPP_2x2.js +96 -96
  700. package/src/core/math/linalg/sor_optimal_omega.js +42 -42
  701. package/src/core/math/linalg/sparse/SparseMatrixCSR.js +88 -88
  702. package/src/core/math/linalg/sparse/spm_matvec.js +22 -22
  703. package/src/core/math/linalg/sparse/spm_matvec_transpose.js +29 -29
  704. package/src/core/math/lookup/LUT_HEATMAP.js +30 -30
  705. package/src/core/math/lookup/ParameterLookupTable.js +495 -495
  706. package/src/core/math/lookup/ParameterLookupTableFlags.js +6 -6
  707. package/src/core/math/noise/curl_noise_3d.js +18 -18
  708. package/src/core/math/physics/brdf/cone_cosine_from_roughness.js +28 -28
  709. package/src/core/math/physics/brdf/reflection_sample_weight.js +48 -48
  710. package/src/core/math/physics/kinematics/computeInterceptPoint.js +79 -79
  711. package/src/core/math/random/randomSeed.js +16 -16
  712. package/src/core/math/random/random_pick_weighted_index.js +26 -26
  713. package/src/core/math/round_half_away_from_zero.js +13 -13
  714. package/src/core/math/spline/spline3_hermite_apply_transform.js +107 -107
  715. package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite_1d.js +125 -125
  716. package/src/core/math/spline/spline3_hermite_intersects_spline3_hermite.js +50 -50
  717. package/src/core/math/spline/spline3_hermite_reverse.js +49 -49
  718. package/src/core/math/spline/spline3_hermite_to_monomial.js +37 -37
  719. package/src/core/math/statistics/hammersley_sequence.js +53 -53
  720. package/src/core/model/reactive/model/util/createRandomReactiveExpression.js +185 -185
  721. package/src/core/path/convertPathToURL.js +107 -107
  722. package/src/core/process/delay.js +16 -16
  723. package/src/core/science/units/MEASUREMENT_UNITS_SCIENTIFIC.js +87 -87
  724. package/src/core/science/units/MEASUREMENT_UNITS_SI.js +17 -17
  725. package/src/core/science/units/NamedUnit.js +48 -48
  726. package/src/core/science/units/UNIT_DIMENSION_MAPPING.js +29 -29
  727. package/src/core/science/units/UnitDimension.js +28 -28
  728. package/src/core/science/units/format_quantity.js +74 -74
  729. package/src/core/science/units/magnitude_prefix.js +127 -127
  730. package/src/core/science/units/si/AMPERE.js +13 -13
  731. package/src/core/science/units/si/CANDELA.js +13 -13
  732. package/src/core/science/units/si/DIMENSIONLESS.js +14 -14
  733. package/src/core/science/units/si/KELVIN.js +13 -13
  734. package/src/core/science/units/si/KILOGRAM.js +13 -13
  735. package/src/core/science/units/si/METER.js +13 -13
  736. package/src/core/science/units/si/MOLE.js +13 -13
  737. package/src/core/science/units/si/SECOND.js +13 -13
  738. package/src/core/science/units/si/derived/BECQUEREL.js +16 -16
  739. package/src/core/science/units/si/derived/COULOMB.js +13 -13
  740. package/src/core/science/units/si/derived/FARAD.js +13 -13
  741. package/src/core/science/units/si/derived/GRAY.js +16 -16
  742. package/src/core/science/units/si/derived/HENRY.js +13 -13
  743. package/src/core/science/units/si/derived/HERTZ.js +16 -16
  744. package/src/core/science/units/si/derived/JOULE.js +13 -13
  745. package/src/core/science/units/si/derived/KATAL.js +13 -13
  746. package/src/core/science/units/si/derived/LUMEN.js +14 -14
  747. package/src/core/science/units/si/derived/LUX.js +13 -13
  748. package/src/core/science/units/si/derived/NEWTON.js +13 -13
  749. package/src/core/science/units/si/derived/OHM.js +13 -13
  750. package/src/core/science/units/si/derived/PASCAL.js +13 -13
  751. package/src/core/science/units/si/derived/SIEMENS.js +13 -13
  752. package/src/core/science/units/si/derived/SIEVERT.js +16 -16
  753. package/src/core/science/units/si/derived/TESLA.js +13 -13
  754. package/src/core/science/units/si/derived/VOLT.js +13 -13
  755. package/src/core/science/units/si/derived/WATT.js +13 -13
  756. package/src/core/science/units/si/derived/WEBER.js +13 -13
  757. package/src/core/science/units/unit_matrix_to_string.js +403 -403
  758. package/src/engine/Engine.js +726 -726
  759. package/src/engine/EngineHarness.js +590 -590
  760. package/src/engine/REVIEW_2026_07_03.md +211 -211
  761. package/src/engine/animation/AnimatedActions.js +81 -81
  762. package/src/engine/animation/AnimationUtils.js +252 -252
  763. package/src/engine/animation/async/TimeSeries.js +300 -300
  764. package/src/engine/animation/curve/animation_curve_binary_codec.js +60 -60
  765. package/src/engine/animation/curve/draw/canvas_point_to_curve.js +22 -22
  766. package/src/engine/animation/curve/draw/curve_point_to_canvas.js +38 -38
  767. package/src/engine/animation/curve/draw/position_canvas_to_curve.js +22 -22
  768. package/src/engine/animation/curve/draw/position_curve_to_canvas.js +22 -22
  769. package/src/engine/asset/GameAssetType.d.ts +0 -1
  770. package/src/engine/asset/GameAssetType.js +0 -1
  771. package/src/engine/asset/load_model_scene_bundle.js +27 -27
  772. package/src/engine/asset/loaders/font/FontAsset.js +21 -21
  773. package/src/engine/asset/loaders/font/FontAssetLoader.js +20 -20
  774. package/src/engine/asset/loaders/gltf_test_fixtures.js +358 -358
  775. package/src/engine/asset/loaders/image/ImageBitmapAssetLoader.js +52 -52
  776. package/src/engine/asset/loaders/image/ImageRGBADataLoader.js +94 -94
  777. package/src/engine/asset/loaders/image/png/filter/png_filter_unFilterAverage.js +59 -59
  778. package/src/engine/asset/loaders/image/png/filter/png_filter_unFilterNone.js +55 -55
  779. package/src/engine/asset/loaders/image/png/filter/png_filter_unFilterPaeth.js +74 -74
  780. package/src/engine/asset/loaders/image/png/filter/png_filter_unFilterSub.js +34 -34
  781. package/src/engine/asset/loaders/image/png/filter/png_filter_unFilterUp.js +46 -46
  782. package/src/engine/control/first-person/DESIGN.md +640 -640
  783. package/src/engine/control/first-person/DESIGN_EXTENSIONS.md +563 -563
  784. package/src/engine/control/first-person/FirstPersonMotionPhase.js +134 -134
  785. package/src/engine/control/first-person/FirstPersonPlayerControllerSystem.js +2045 -2045
  786. package/src/engine/control/first-person/mastery/DecisionPoint.js +30 -30
  787. package/src/engine/control/first-person/math/Spring.js +71 -71
  788. package/src/engine/control/first-person/math/computeJumpFromApex.js +23 -23
  789. package/src/engine/control/first-person/math/computeLRCBreathRate.js +41 -41
  790. package/src/engine/control/first-person/math/computeMassRatios.js +44 -44
  791. package/src/engine/control/first-person/math/criticallyDampedSpring.js +34 -34
  792. package/src/engine/control/first-person/math/dampedSpringStep.js +72 -72
  793. package/src/engine/control/first-person/math/jumpDynamics.js +108 -108
  794. package/src/engine/control/first-person/math/stepTowards.js +20 -20
  795. package/src/engine/control/first-person/pose/FirstPersonPose.js +137 -137
  796. package/src/engine/control/first-person/pose/FirstPersonPosture.js +27 -27
  797. package/src/engine/control/first-person/test/buildTestPlayer.js +36 -36
  798. package/src/engine/ecs/ASYNC_SYSTEMS_PROPOSAL.md +531 -531
  799. package/src/engine/ecs/EntityManager.d.ts +7 -3
  800. package/src/engine/ecs/EntityManager.d.ts.map +1 -1
  801. package/src/engine/ecs/EntityManager.js +10 -5
  802. package/src/engine/ecs/HIERARCHY_REVIEW.md +717 -717
  803. package/src/engine/ecs/async/SystemWorkerHost.js +329 -329
  804. package/src/engine/ecs/async/SystemWorkerLoopback.js +143 -143
  805. package/src/engine/ecs/async/WORKER_SYSTEM_PLAN.md +246 -246
  806. package/src/engine/ecs/async/WorkerSystem.js +702 -702
  807. package/src/engine/ecs/async/WorkerSystemProtocol.js +150 -150
  808. package/src/engine/ecs/fow/FogOfWar.js +707 -707
  809. package/src/engine/ecs/fow/FogOfWarEdgeMode.js +40 -40
  810. package/src/engine/ecs/fow/fog_of_war_mask_world_bounds.js +24 -24
  811. package/src/engine/ecs/fow/fog_of_war_uv_transform.js +30 -30
  812. package/src/engine/ecs/gui/hud/testHudEdgeStick.js +132 -134
  813. package/src/engine/ecs/hierarchy/EntityChildIndex.js +140 -140
  814. package/src/engine/ecs/ik/IKProblem.js +42 -42
  815. package/src/engine/ecs/ik/InverseKinematicsSystem.js +193 -193
  816. package/src/engine/ecs/ik/OneBoneSurfaceAlignmentSolver.js +134 -134
  817. package/src/engine/ecs/ik/TwoBoneInverseKinematicsSolver.js +97 -97
  818. package/src/engine/ecs/ik/ik_bone_chain.js +85 -85
  819. package/src/engine/ecs/ik/ik_probe_terrain_contact.js +119 -119
  820. package/src/engine/ecs/parent/EntityNode.d.ts +1 -1
  821. package/src/engine/ecs/parent/EntityNode.js +2 -2
  822. package/src/engine/ecs/parent/ParentEntitySystem.js +255 -255
  823. package/src/engine/ecs/speaker/VoiceSystem.d.ts +2 -2
  824. package/src/engine/ecs/speaker/VoiceSystem.d.ts.map +1 -1
  825. package/src/engine/ecs/speaker/VoiceSystem.js +13 -7
  826. package/src/engine/ecs/storage/binary/SERIALIZATION_COVERAGE.md +269 -269
  827. package/src/engine/ecs/storage/binary/object-v2/BinaryObjectDeSerializer.js +315 -315
  828. package/src/engine/ecs/storage/binary/object-v2/BinaryObjectSerializer.js +331 -331
  829. package/src/engine/ecs/storage/binary/object-v2/DESIGN.md +199 -199
  830. package/src/engine/ecs/storage/binary/object-v2/ObjectBinaryFormat.js +57 -57
  831. package/src/engine/ecs/storage/binary/object-v2/ObjectSerializationAdapter.js +56 -56
  832. package/src/engine/ecs/storage/binary/object-v2/README.md +110 -110
  833. package/src/engine/ecs/storage/binary/object-v2/objectStringCodec.js +48 -48
  834. package/src/engine/ecs/storage/binary/object-v2/serializerTestHarness.js +44 -44
  835. package/src/engine/ecs/storage/populateEngineSerializationRegistry.d.ts.map +1 -1
  836. package/src/engine/ecs/storage/populateEngineSerializationRegistry.js +5 -1
  837. package/src/engine/ecs/terrain/TerrainClouds.js +97 -97
  838. package/src/engine/ecs/terrain/ecs/StubTerrainBuildWorker.js +65 -65
  839. package/src/engine/ecs/terrain/ecs/Terrain.d.ts +4 -0
  840. package/src/engine/ecs/terrain/ecs/Terrain.d.ts.map +1 -1
  841. package/src/engine/ecs/terrain/ecs/Terrain.js +790 -790
  842. package/src/engine/ecs/terrain/ecs/TerrainSystem.js +209 -209
  843. package/src/engine/ecs/terrain/ecs/cling/ClingToTerrainSystem.js +316 -316
  844. package/src/engine/ecs/terrain/ecs/layers/TerrainLayers.js +416 -416
  845. package/src/engine/ecs/terrain/ecs/splat/SplatMapping.js +525 -525
  846. package/src/engine/ecs/terrain/overlay/TerrainOverlay.js +302 -302
  847. package/src/engine/ecs/terrain/tiles/TerrainTile.js +561 -561
  848. package/src/engine/ecs/terrain/tiles/TerrainTileManager.js +896 -896
  849. package/src/engine/ecs/terrain/tiles/tile_geometry_to_meshlets.js +36 -36
  850. package/src/engine/ecs/terrain/util/loadVisibleTerrainTiles.js +129 -129
  851. package/src/engine/ecs/transform/Transform64.js +814 -814
  852. package/src/engine/ecs/transform/t64_copy_from_transform.js +35 -35
  853. package/src/engine/ecs/transform/t64_equals_transform.js +55 -55
  854. package/src/engine/ecs/transform/t64_look_rotation.js +36 -36
  855. package/src/engine/ecs/transform/t64_transform_direction.js +25 -25
  856. package/src/engine/ecs/transform/transform_copy_from_t64.js +28 -28
  857. package/src/engine/ecs/transform-attachment/TransformAttachmentSystem.js +345 -345
  858. package/src/engine/ecs/transform-attachment/transform_attachment_find_descendant_by_name.js +65 -65
  859. package/src/engine/ecs/transform-attachment/transform_attachment_parent_of.js +24 -24
  860. package/src/engine/ecs/util/hideEntityGracefully.js +208 -208
  861. package/src/engine/graphics/CONTEXT_LOSS_RECOVERY_PLAN.md +446 -446
  862. package/src/engine/graphics/FULL_SCREEN_QUAD_VERTEX_SHADER.js +14 -14
  863. package/src/engine/graphics/FrameThrottle.js +2 -2
  864. package/src/engine/graphics/ecs/animation/animator/graph/AnimationState.js +207 -207
  865. package/src/engine/graphics/ecs/animation/animator/graph/AnimationTransition.js +151 -151
  866. package/src/engine/graphics/ecs/animation/animator/graph/definition/serialization/AnimationGraphDefinitionAssetLoader.js +22 -22
  867. package/src/engine/graphics/ecs/camera/Camera.js +165 -165
  868. package/src/engine/graphics/ecs/camera/camera_active_frustum.js +25 -25
  869. package/src/engine/graphics/ecs/camera/camera_find_active.js +28 -28
  870. package/src/engine/graphics/ecs/camera/camera_traverse_active.js +18 -18
  871. package/src/engine/graphics/ecs/camera/pp/PerfectPanner.js +170 -170
  872. package/src/engine/graphics/ecs/camera/serialization/CameraSerializationAdapter.js +68 -68
  873. package/src/engine/graphics/ecs/camera/topdown/TopDownCameraController.js +296 -296
  874. package/src/engine/graphics/ecs/decal/v2/Decal.js +220 -220
  875. package/src/engine/graphics/ecs/decal/v2/DecalSerializationAdapter.js +56 -56
  876. package/src/engine/graphics/ecs/decal/v2/DecalSerializationUpgrader_0_1.js +38 -38
  877. package/src/engine/graphics/ecs/light/shadow/compute_view_frustum_aabb_in_space.js +62 -62
  878. package/src/engine/graphics/ecs/light/shadow/extend_shadow_camera_near_for_casters.js +77 -77
  879. package/src/engine/graphics/ecs/make_bvh_depth_range_computer.js +33 -33
  880. package/src/engine/graphics/ecs/mesh-v2/DeferredBoundsQueue.js +88 -88
  881. package/src/engine/graphics/ecs/mesh-v2/ShadedGeometry.js +428 -428
  882. package/src/engine/graphics/ecs/mesh-v2/aggregate/SGMesh.js +303 -303
  883. package/src/engine/graphics/ecs/mesh-v2/aggregate/SGMeshSystem.d.ts +1 -1
  884. package/src/engine/graphics/ecs/mesh-v2/aggregate/serialization/SGMeshSerializationAdapter.js +39 -39
  885. package/src/engine/graphics/ecs/mesh-v2/sg_hierarchy_compute_bounding_box_via_parent_entity.js +36 -36
  886. package/src/engine/graphics/ecs/path/tube/build/GeometryStream.js +94 -94
  887. package/src/engine/graphics/ecs/path/tube/build/build_stream_catmullrom.js +310 -310
  888. package/src/engine/graphics/ecs/path/tube/build/build_stream_linear.js +73 -73
  889. package/src/engine/graphics/ecs/path/tube/build/computeFrenetFrames.js +199 -199
  890. package/src/engine/graphics/ecs/path/tube/build/makeTubeStream.js +217 -217
  891. package/src/engine/graphics/ecs/path/tube/build/make_cap.js +340 -340
  892. package/src/engine/graphics/ecs/path/tube/build/make_ring_faces.js +40 -40
  893. package/src/engine/graphics/ecs/path/tube/build/make_ring_vertices.js +153 -153
  894. package/src/engine/graphics/ecs/render_layers_compute_depth_range.js +64 -64
  895. package/src/engine/graphics/ecs/trail3d/Trail3D.js +483 -483
  896. package/src/engine/graphics/ecs/trail3d/Trail3DFlags.js +26 -26
  897. package/src/engine/graphics/ecs/trail3d/advance_trail.js +42 -42
  898. package/src/engine/graphics/ecs/trail3d/make_gradient_stroke.js +58 -58
  899. package/src/engine/graphics/ecs/trail3d/seed_trail_stroke.js +90 -90
  900. package/src/engine/graphics/ecs/trail3d/seed_trail_tube.js +75 -75
  901. package/src/engine/graphics/ecs/trail3d/trail_head_position.js +19 -19
  902. package/src/engine/graphics/ecs/water/Water.js +104 -104
  903. package/src/engine/graphics/geometry/AttributeData.js +84 -84
  904. package/src/engine/graphics/geometry/buffered/geometry_compute_vertex_normals_indexed.js +49 -49
  905. package/src/engine/graphics/geometry/buffered/query/GeometrySpatialQueryAccelerator.js +288 -288
  906. package/src/engine/graphics/geometry/buffered/query/nearest_point_on_triangle_record.js +87 -87
  907. package/src/engine/graphics/geometry/buffered/read_triangle_vertices.js +102 -102
  908. package/src/engine/graphics/geometry/bvh/buffered/bvh32_from_buffered_geometry.js +52 -52
  909. package/src/engine/graphics/geometry/bvh/buffered/bvh32_from_indexed_geometry.js +20 -20
  910. package/src/engine/graphics/geometry/bvh/buffered/bvh32_from_unindexed_geometry.js +19 -19
  911. package/src/engine/graphics/geometry/optimization/geometry_optimize_uv_tension.js +135 -135
  912. package/src/engine/graphics/impostors/voxel/README.md +149 -149
  913. package/src/engine/graphics/impostors/voxel/VoxelImpostorDescription.js +141 -141
  914. package/src/engine/graphics/particles/node-based/codegen/glsl/getTypeByteSize.js +20 -20
  915. package/src/engine/graphics/particles/node-based/nodes/FloatConstant.d.ts +2 -0
  916. package/src/engine/graphics/particles/node-based/nodes/FloatConstant.d.ts.map +1 -1
  917. package/src/engine/graphics/particles/node-based/nodes/ReadFloatUniform.d.ts +2 -0
  918. package/src/engine/graphics/particles/node-based/nodes/ReadFloatUniform.d.ts.map +1 -1
  919. package/src/engine/graphics/particles/node-based/nodes/ReadVelocity.d.ts +2 -0
  920. package/src/engine/graphics/particles/node-based/nodes/ReadVelocity.d.ts.map +1 -1
  921. package/src/engine/graphics/particles/node-based/nodes/ShaderNode.d.ts +1 -2
  922. package/src/engine/graphics/particles/node-based/nodes/ShaderNode.d.ts.map +1 -1
  923. package/src/engine/graphics/particles/node-based/nodes/Vector3Constant.d.ts +2 -0
  924. package/src/engine/graphics/particles/node-based/nodes/Vector3Constant.d.ts.map +1 -1
  925. package/src/engine/graphics/particles/node-based/nodes/Vector3Merge.d.ts +2 -0
  926. package/src/engine/graphics/particles/node-based/nodes/Vector3Merge.d.ts.map +1 -1
  927. package/src/engine/graphics/particles/node-based/nodes/Vector3Split.d.ts +2 -0
  928. package/src/engine/graphics/particles/node-based/nodes/Vector3Split.d.ts.map +1 -1
  929. package/src/engine/graphics/particles/node-based/nodes/WriteVelocity.d.ts +2 -0
  930. package/src/engine/graphics/particles/node-based/nodes/WriteVelocity.d.ts.map +1 -1
  931. package/src/engine/graphics/particles/node-based/nodes/attribute/ReadVector3Attribute.d.ts +2 -0
  932. package/src/engine/graphics/particles/node-based/nodes/attribute/ReadVector3Attribute.d.ts.map +1 -1
  933. package/src/engine/graphics/particles/node-based/nodes/attribute/WriteVector3Attribute.d.ts +2 -0
  934. package/src/engine/graphics/particles/node-based/nodes/attribute/WriteVector3Attribute.d.ts.map +1 -1
  935. package/src/engine/graphics/particles/node-based/nodes/math/AddFloatNode.d.ts +2 -0
  936. package/src/engine/graphics/particles/node-based/nodes/math/AddFloatNode.d.ts.map +1 -1
  937. package/src/engine/graphics/particles/node-based/nodes/math/Vector3Add.d.ts +2 -0
  938. package/src/engine/graphics/particles/node-based/nodes/math/Vector3Add.d.ts.map +1 -1
  939. package/src/engine/graphics/particles/node-based/nodes/math/Vector3Divide.d.ts +2 -0
  940. package/src/engine/graphics/particles/node-based/nodes/math/Vector3Divide.d.ts.map +1 -1
  941. package/src/engine/graphics/particles/node-based/nodes/math/Vector3Multiply.d.ts +2 -0
  942. package/src/engine/graphics/particles/node-based/nodes/math/Vector3Multiply.d.ts.map +1 -1
  943. package/src/engine/graphics/particles/node-based/nodes/math/Vector3Subtract.d.ts +2 -0
  944. package/src/engine/graphics/particles/node-based/nodes/math/Vector3Subtract.d.ts.map +1 -1
  945. package/src/engine/graphics/particles/node-based/nodes/noise/CurlNoiseNode.d.ts +2 -0
  946. package/src/engine/graphics/particles/node-based/nodes/noise/CurlNoiseNode.d.ts.map +1 -1
  947. package/src/engine/graphics/particles/node-based/nodes/particle_data_type_component_count.js +45 -45
  948. package/src/engine/graphics/particles/particular/engine/ParticularEngine.js +229 -229
  949. package/src/engine/graphics/particles/particular/engine/emitter/ParticleEmitter.d.ts +2 -10
  950. package/src/engine/graphics/particles/particular/engine/emitter/ParticleEmitter.d.ts.map +1 -1
  951. package/src/engine/graphics/particles/particular/engine/emitter/ParticleEmitter.js +1149 -1149
  952. package/src/engine/graphics/particles/particular/engine/emitter/ParticlePool.js +472 -472
  953. package/src/engine/graphics/particles/particular/engine/parameter/ParameterLookupTable.js +2 -2
  954. package/src/engine/graphics/particles/particular/engine/parameter/ParameterLookupTableFlags.js +2 -2
  955. package/src/engine/graphics/particles/particular/engine/parameter/ParameterSet.d.ts.map +1 -1
  956. package/src/engine/graphics/particles/particular/engine/parameter/ParameterSet.js +3 -5
  957. package/src/engine/graphics/particles/particular/engine/shader/ShaderManager.js +135 -135
  958. package/src/engine/graphics/particles/particular/engine/utils/distribute_points_on_indexed_triangles.js +168 -168
  959. package/src/engine/graphics/render/forward_plus/plugin/forwardPlusMaterialMarker.js +18 -18
  960. package/src/engine/graphics/render/forward_plus/read_frustum_corner.js +2 -2
  961. package/src/engine/graphics/render/frame_graph/FRAME_GRAPH_RECOMMENDATIONS.md +219 -219
  962. package/src/engine/graphics/render/frame_graph/FrameGraph.js +900 -900
  963. package/src/engine/graphics/render/frame_graph/FrameGraphScope.js +72 -72
  964. package/src/engine/graphics/render/frame_graph/FrameGraphState.js +39 -39
  965. package/src/engine/graphics/render/frame_graph/ResourceEntry.js +96 -96
  966. package/src/engine/graphics/render/gizmo/GizmoShapeBuffer.js +105 -105
  967. package/src/engine/graphics/render/gizmo/GizmoShapeRenderingInterface.js +162 -162
  968. package/src/engine/graphics/render/layers/RenderLayer.js +95 -95
  969. package/src/engine/graphics/sh3/build_injected_shader.js +56 -56
  970. package/src/engine/graphics/sh3/grid_dilate_average.js +175 -175
  971. package/src/engine/graphics/sh3/path_tracer/BufferedGeometryBVH.js +506 -506
  972. package/src/engine/graphics/sh3/path_tracer/PathTracedMesh.js +161 -161
  973. package/src/engine/graphics/sh3/path_tracer/PathTracedRenderer.js +205 -205
  974. package/src/engine/graphics/sh3/path_tracer/PathTracedScene.js +698 -698
  975. package/src/engine/graphics/sh3/path_tracer/REVIEW_001_ACTION_PLAN.md +490 -490
  976. package/src/engine/graphics/sh3/path_tracer/geometry/compute_triangle_group_aabb3.js +2 -2
  977. package/src/engine/graphics/sh3/path_tracer/make_sky_hosek.js +45 -45
  978. package/src/engine/graphics/sh3/path_tracer/populate_path_traced_scene_from_ecd.js +73 -73
  979. package/src/engine/graphics/sh3/path_tracer/ray_hit_apply_transform.js +32 -32
  980. package/src/engine/graphics/sh3/path_tracer/texture/apply_texture_clamping_to_coordinate.js +28 -28
  981. package/src/engine/graphics/sh3/path_tracer/texture/sample_material.js +142 -142
  982. package/src/engine/graphics/sh3/sky/hosek/render_hosek_sky_to_equirectangular.js +70 -70
  983. package/src/engine/graphics/sh3/sky/hosek/sky_hosek_compute_irradiance_by_direction.js +388 -388
  984. package/src/engine/graphics/shaders/chunks/glsl_octahedral_impostor.js +277 -277
  985. package/src/engine/graphics/shaders/chunks/glsl_voxel_impostor_splat.js +57 -57
  986. package/src/engine/graphics/shadows/vsm.glsl.js +43 -43
  987. package/src/engine/graphics/texture/3d/scs3d_sample_linear3.js +81 -81
  988. package/src/engine/graphics/texture/EnvironmentTextureProjection.js +15 -15
  989. package/src/engine/graphics/texture/channel_count_to_format_prefix.js +26 -26
  990. package/src/engine/graphics/texture/isImageBitmap.js +2 -2
  991. package/src/engine/graphics/texture/reflection/convolve_equirectangular_reflection.js +189 -189
  992. package/src/engine/graphics/texture/reflection/equirectangular_reflection_roughness.js +51 -51
  993. package/src/engine/graphics/texture/sampler/HarmonicDiffusionGrid.js +145 -145
  994. package/src/engine/graphics/texture/sampler/Sampler2DArray.js +172 -172
  995. package/src/engine/graphics/texture/sampler/compare/FLIP_IMPLEMENTATION_PLAN.md +466 -466
  996. package/src/engine/graphics/texture/sampler/compare/flip/FlipParameters.js +18 -18
  997. package/src/engine/graphics/texture/sampler/compare/flip/FlipPooling.js +33 -33
  998. package/src/engine/graphics/texture/sampler/compare/flip/flip_build_feature_kernel.js +147 -147
  999. package/src/engine/graphics/texture/sampler/compare/flip/flip_build_spatial_kernel.js +177 -177
  1000. package/src/engine/graphics/texture/sampler/compare/flip/flip_compute_color_difference.js +104 -104
  1001. package/src/engine/graphics/texture/sampler/compare/flip/flip_compute_feature_difference.js +76 -76
  1002. package/src/engine/graphics/texture/sampler/compare/flip/flip_compute_pixels_per_degree.js +34 -34
  1003. package/src/engine/graphics/texture/sampler/compare/flip/flip_constants.js +77 -77
  1004. package/src/engine/graphics/texture/sampler/compare/flip/flip_filter_feature.js +48 -48
  1005. package/src/engine/graphics/texture/sampler/compare/flip/flip_filter_spatial.js +86 -86
  1006. package/src/engine/graphics/texture/sampler/compare/flip/flip_pool.js +71 -71
  1007. package/src/engine/graphics/texture/sampler/compare/flip/flip_srgb_to_ycxcz.js +55 -55
  1008. package/src/engine/graphics/texture/sampler/compare/flip/sampler2d_flip_ldr.js +80 -80
  1009. package/src/engine/graphics/texture/sampler/filter/SeparableKernel.js +82 -82
  1010. package/src/engine/graphics/texture/sampler/filter/sampler2d_convolve_separable.js +122 -122
  1011. package/src/engine/graphics/texture/sampler/resize/sampler2d_scale_down_lanczos.js +148 -148
  1012. package/src/engine/graphics/texture/sampler/sampler2d_channel_apply_lut.js +82 -82
  1013. package/src/engine/graphics/texture/sampler/sampler2d_combine.js +67 -67
  1014. package/src/engine/graphics/texture/sampler/sampler2d_linear_f16_to_srgb_u8.js +54 -54
  1015. package/src/engine/graphics/texture/sampler/sampler2d_sample_equirectangular_direction.js +63 -63
  1016. package/src/engine/graphics/texture/sampler/sampler2d_srgb_to_linear.js +33 -33
  1017. package/src/engine/graphics/texture/sampler/sampler2d_srgb_u8_to_linear_f16.js +68 -68
  1018. package/src/engine/graphics/texture/shade_image_preview.js +103 -103
  1019. package/src/engine/graphics/trail/TrailSpawnMode.js +20 -20
  1020. package/src/engine/graphics/trail/tube/TubeX.js +573 -573
  1021. package/src/engine/graphics/trail/tube/TubeXMaterialSpec.js +58 -58
  1022. package/src/engine/graphics/trail/tube/simulator/TubeXFixedPhysicsSimulator.js +34 -34
  1023. package/src/engine/graphics/trail/tube/tube_attributes_spec.js +69 -69
  1024. package/src/engine/graphics/trail/tube/tube_frame.js +83 -83
  1025. package/src/engine/graphics3/AnimationGraphSystem3.js +329 -329
  1026. package/src/engine/graphics3/AnimationSystem3.js +352 -352
  1027. package/src/engine/graphics3/CameraSystem3.js +170 -170
  1028. package/src/engine/graphics3/DecalSystem3.js +441 -441
  1029. package/src/engine/graphics3/FogOfWarSystem3.js +265 -265
  1030. package/src/engine/graphics3/GraphicsEngine3.js +776 -776
  1031. package/src/engine/graphics3/HighlightSystem3.js +241 -241
  1032. package/src/engine/graphics3/LightSystem3.js +211 -211
  1033. package/src/engine/graphics3/MeshSystem3.js +646 -646
  1034. package/src/engine/graphics3/ParticleEmitterSystem3.js +289 -289
  1035. package/src/engine/graphics3/PathDisplaySystem3.js +309 -309
  1036. package/src/engine/graphics3/PickingQuery.js +48 -48
  1037. package/src/engine/graphics3/PickingResult.js +47 -47
  1038. package/src/engine/graphics3/PickingSystem3.js +273 -273
  1039. package/src/engine/graphics3/ShadeCameraAdapter.js +55 -55
  1040. package/src/engine/graphics3/ShadedGeometrySystem3.js +169 -169
  1041. package/src/engine/graphics3/TerrainSystem3.js +566 -566
  1042. package/src/engine/graphics3/TooltipComponentSystem3.js +328 -328
  1043. package/src/engine/graphics3/Trail3DSystem3.js +221 -221
  1044. package/src/engine/graphics3/VolumetricLightMap.d.ts +90 -0
  1045. package/src/engine/graphics3/VolumetricLightMap.d.ts.map +1 -0
  1046. package/src/engine/graphics3/VolumetricLightMap.js +160 -0
  1047. package/src/engine/graphics3/VolumetricLightMapSerializationAdapter.d.ts +32 -0
  1048. package/src/engine/graphics3/VolumetricLightMapSerializationAdapter.d.ts.map +1 -0
  1049. package/src/engine/graphics3/VolumetricLightMapSerializationAdapter.js +67 -0
  1050. package/src/engine/graphics3/VolumetricLightMapSystem3.d.ts +98 -0
  1051. package/src/engine/graphics3/VolumetricLightMapSystem3.d.ts.map +1 -0
  1052. package/src/engine/graphics3/VolumetricLightMapSystem3.js +261 -0
  1053. package/src/engine/graphics3/WaterSystem3.js +293 -293
  1054. package/src/engine/graphics3/animation/ClipPlayback.js +84 -84
  1055. package/src/engine/graphics3/animation/wrap_clip_time.js +23 -23
  1056. package/src/engine/graphics3/animation/write_graph_playback.js +48 -48
  1057. package/src/engine/graphics3/camera_sync_from_transform.js +29 -29
  1058. package/src/engine/graphics3/debug/gizmo_view_from_camera.js +48 -48
  1059. package/src/engine/graphics3/decal/DECAL_CLUSTER.js +61 -61
  1060. package/src/engine/graphics3/decal/DECAL_GPU_RECORD.js +117 -117
  1061. package/src/engine/graphics3/decal/DecalAtlas.js +194 -194
  1062. package/src/engine/graphics3/decal/DecalAtlasFill.js +32 -32
  1063. package/src/engine/graphics3/decal/GPUDecalRenderer.js +360 -360
  1064. package/src/engine/graphics3/decal/chunk_decal_intersects_frustum.js +59 -59
  1065. package/src/engine/graphics3/decal/chunk_decal_sampling_info.js +57 -57
  1066. package/src/engine/graphics3/decal/chunk_decal_surface_frame.js +54 -54
  1067. package/src/engine/graphics3/decal/decal_atlas_border.js +69 -69
  1068. package/src/engine/graphics3/decal/decal_gpu_records.js +120 -120
  1069. package/src/engine/graphics3/decal/decal_material_samplers.js +109 -109
  1070. package/src/engine/graphics3/decal/graph_build_decal_clusters.js +212 -212
  1071. package/src/engine/graphics3/decal/shader_cluster_assign_decals.js +207 -207
  1072. package/src/engine/graphics3/decal/shader_cull_decals_frustum.js +108 -108
  1073. package/src/engine/graphics3/highlight/GPUHighlightRenderer.js +151 -151
  1074. package/src/engine/graphics3/highlight/HIGHLIGHT_OUTLINE.js +23 -23
  1075. package/src/engine/graphics3/highlight/chunk_highlight_lookup.js +53 -53
  1076. package/src/engine/graphics3/highlight/pack_highlight_color.js +44 -44
  1077. package/src/engine/graphics3/highlight/pack_highlight_table.js +74 -74
  1078. package/src/engine/graphics3/highlight/shader_highlight_outline.js +150 -150
  1079. package/src/engine/graphics3/load_cube_environment.js +68 -68
  1080. package/src/engine/graphics3/make_default_environment.js +107 -107
  1081. package/src/engine/graphics3/particles/particle_gpu_records.js +221 -221
  1082. package/src/engine/graphics3/path/build_tube_path_streams.js +98 -98
  1083. package/src/engine/graphics3/path/tube_stream_write_geometry.js +90 -90
  1084. package/src/engine/graphics3/preview/ModelPreviewFraming.js +35 -35
  1085. package/src/engine/graphics3/preview/make_model_preview_scene.js +154 -154
  1086. package/src/engine/graphics3/preview/make_model_thumbnail.js +48 -48
  1087. package/src/engine/graphics3/preview/model_preview_framing.js +70 -70
  1088. package/src/engine/graphics3/shade_bundle_bounds.js +55 -55
  1089. package/src/engine/graphics3/shade_camera_projection_ray.js +77 -77
  1090. package/src/engine/graphics3/shade_node_to_entity_composition.js +84 -84
  1091. package/src/engine/graphics3/terrain/GPUTerrainSplatRenderer.js +481 -481
  1092. package/src/engine/graphics3/terrain/chunk_terrain_grid_overlay.js +61 -61
  1093. package/src/engine/graphics3/terrain/chunk_terrain_splat_mix.js +66 -66
  1094. package/src/engine/graphics3/terrain/pack_terrain_row_table.js +53 -53
  1095. package/src/engine/graphics3/terrain/shader_terrain_splat.js +215 -215
  1096. package/src/engine/graphics3/trail/trail_tube_write_geometry.js +158 -158
  1097. package/src/engine/input/GAMEPAD_API_PROPOSAL.md +717 -717
  1098. package/src/engine/input/analog/apply_radial_dead_zone.js +38 -38
  1099. package/src/engine/input/devices/GamepadDevice.js +466 -466
  1100. package/src/engine/input/devices/ManualInputDevice.js +152 -152
  1101. package/src/engine/input/devices/PointerCoordinates.js +26 -26
  1102. package/src/engine/input/devices/events/GamepadEvents.js +10 -10
  1103. package/src/engine/input/devices/gamepad/GamepadAxes.js +19 -19
  1104. package/src/engine/input/devices/gamepad/GamepadButtons.js +29 -29
  1105. package/src/engine/input/devices/gamepad/GamepadCoordinates.js +17 -17
  1106. package/src/engine/input/devices/gamepad/GamepadDeviceLayout.js +323 -323
  1107. package/src/engine/input/devices/gamepad/GamepadHandle.js +286 -286
  1108. package/src/engine/input/devices/gamepad/GamepadLayout.js +160 -160
  1109. package/src/engine/input/devices/gamepad/GamepadStandardMapping.js +31 -31
  1110. package/src/engine/input/devices/gamepad/GamepadStick.js +169 -169
  1111. package/src/engine/input/devices/gamepad/GamepadStickCalibration.js +119 -119
  1112. package/src/engine/input/devices/gamepad/GamepadStickCalibrator.js +250 -250
  1113. package/src/engine/input/devices/gamepad/gamepad_layout_database.js +144 -144
  1114. package/src/engine/input/devices/gamepad/gamepad_read_hat_axis.js +61 -61
  1115. package/src/engine/input/devices/gamepad/gamepad_write_dpad_vector.js +30 -30
  1116. package/src/engine/input/devices/gamepad/prototypeGamepadTester.js +2124 -2124
  1117. package/src/engine/input/devices/mouse/MouseButtons.js +22 -22
  1118. package/src/engine/input/ecs/components/Input.js +118 -118
  1119. package/src/engine/input/ecs/components/InputController.js +78 -78
  1120. package/src/engine/input/ecs/ism/ISM_DESIGN.md +1523 -1523
  1121. package/src/engine/input/ecs/ism/ISM_IMPLEMENTATION_PLAN.md +627 -627
  1122. package/src/engine/input/ecs/ism/InputActionEvent.js +40 -40
  1123. package/src/engine/input/ecs/ism/InputBinding.js +71 -71
  1124. package/src/engine/input/ecs/ism/InputCoordinateKind.js +25 -25
  1125. package/src/engine/input/ecs/ism/InputCoordinateSource.js +86 -86
  1126. package/src/engine/input/ecs/ism/InputDirection.js +33 -33
  1127. package/src/engine/input/ecs/ism/InputMapProgram.js +236 -236
  1128. package/src/engine/input/ecs/ism/InputMapSystem.js +976 -976
  1129. package/src/engine/input/ecs/ism/InputOcclusion.js +31 -31
  1130. package/src/engine/input/ecs/ism/InputSource.js +67 -67
  1131. package/src/engine/input/ecs/ism/InputSourceTable.js +107 -107
  1132. package/src/engine/input/ecs/ism/coordinate/InputCoordinateChannel.js +93 -93
  1133. package/src/engine/input/ecs/ism/coordinate/InputCoordinateChannelType.js +11 -11
  1134. package/src/engine/input/ecs/ism/coordinate/InputCoordinateDevice.js +153 -153
  1135. package/src/engine/input/ecs/ism/coordinate/InputCoordinateSwitches.js +160 -160
  1136. package/src/engine/input/ecs/ism/device/GAMEPAD_INPUT_DEVICE_ID.js +9 -9
  1137. package/src/engine/input/ecs/ism/device/GamepadInputDeviceAdapter.js +88 -88
  1138. package/src/engine/input/ecs/ism/device/InputDeviceAdapter.js +72 -72
  1139. package/src/engine/input/ecs/ism/device/KEYBOARD_INPUT_DEVICE_ID.js +9 -9
  1140. package/src/engine/input/ecs/ism/device/KeyboardInputDeviceAdapter.js +63 -63
  1141. package/src/engine/input/ecs/ism/device/ManualInputDeviceAdapter.js +55 -55
  1142. package/src/engine/input/ecs/ism/device/POINTER_INPUT_DEVICE_ID.js +9 -9
  1143. package/src/engine/input/ecs/ism/device/PointerInputDeviceAdapter.js +160 -160
  1144. package/src/engine/input/ecs/ism/map/InputBinding.js +88 -88
  1145. package/src/engine/input/ecs/ism/map/InputCoordinateBinding.js +102 -102
  1146. package/src/engine/input/ecs/ism/map/InputLayer.js +220 -220
  1147. package/src/engine/input/ecs/ism/map/InputMap.js +331 -331
  1148. package/src/engine/input/ecs/ism/prototypeInputMap.js +309 -309
  1149. package/src/engine/input/ecs/ism/trigger/InputTrigger.js +148 -148
  1150. package/src/engine/input/ecs/ism/trigger/InputTriggerChord.js +173 -173
  1151. package/src/engine/input/ecs/ism/trigger/InputTriggerGamepadButton.js +37 -37
  1152. package/src/engine/input/ecs/ism/trigger/InputTriggerHold.js +176 -176
  1153. package/src/engine/input/ecs/ism/trigger/InputTriggerKey.js +39 -39
  1154. package/src/engine/input/ecs/ism/trigger/InputTriggerMouseButton.js +38 -38
  1155. package/src/engine/input/ecs/ism/trigger/InputTriggerRelease.js +120 -120
  1156. package/src/engine/input/ecs/ism/trigger/InputTriggerSequence.js +315 -315
  1157. package/src/engine/input/ecs/ism/trigger/InputTriggerSwitch.js +105 -105
  1158. package/src/engine/input/ecs/ism/trigger/InputTriggerType.js +17 -17
  1159. package/src/engine/input/ecs/systems/InputControllerSystem.js +253 -253
  1160. package/src/engine/input/ecs/systems/InputSystem.js +162 -162
  1161. package/src/engine/intelligence/behavior/primitive/FailingBehaviorSerializationAdapter.js +25 -25
  1162. package/src/engine/intelligence/behavior/primitive/SucceedingBehaviorSerializationAdapter.js +26 -26
  1163. package/src/engine/intelligence/behavior/util/AsynchronousDelayAction.js +55 -55
  1164. package/src/engine/interpolation/BinaryInterpolationAdapter.js +56 -56
  1165. package/src/engine/interpolation/Interpoland.js +49 -49
  1166. package/src/engine/interpolation/Interpolated.js +149 -149
  1167. package/src/engine/interpolation/PoseInterpolationAdapter.js +61 -61
  1168. package/src/engine/interpolation/TransformPoseSerializationAdapter.js +57 -57
  1169. package/src/engine/interpolation/pose_interpoland.js +27 -27
  1170. package/src/engine/navigation/ecs/path_following/PathFollower.js +222 -222
  1171. package/src/engine/navigation/mesh/NavigationMesh.js +145 -145
  1172. package/src/engine/navigation/mesh/OVERLAPPING_SURFACES_2026_08_25.md +661 -0
  1173. package/src/engine/navigation/mesh/PATHFINDING_PLAN.md +229 -229
  1174. package/src/engine/navigation/mesh/build/clip_soup_against_overhangs.d.ts.map +1 -1
  1175. package/src/engine/navigation/mesh/build/clip_soup_against_overhangs.js +628 -520
  1176. package/src/engine/network/CONGESTION_CONTROL.md +87 -87
  1177. package/src/engine/network/README.md +52 -52
  1178. package/src/engine/network/adapters/QuaternionInterpolationAdapter.js +43 -43
  1179. package/src/engine/network/adapters/TransformInterpolationAdapter.js +84 -84
  1180. package/src/engine/network/adapters/TransformReplicationAdapter.js +87 -87
  1181. package/src/engine/network/adapters/Vector3InterpolationAdapter.js +46 -46
  1182. package/src/engine/network/convertPathToURL.js +2 -2
  1183. package/src/engine/network/core/MalformedPacketError.js +26 -26
  1184. package/src/engine/network/core/quantize/quantize_float.js +73 -73
  1185. package/src/engine/network/core/quantize/quantize_position.js +65 -65
  1186. package/src/engine/network/core/sequence/ack_bitfield.js +77 -77
  1187. package/src/engine/network/core/sequence/seq16.js +69 -69
  1188. package/src/engine/network/core/sequence/seq32.js +73 -73
  1189. package/src/engine/network/ecs/NetworkSystem.js +84 -84
  1190. package/src/engine/network/ecs/components/NetworkIdentity.js +73 -73
  1191. package/src/engine/network/ecs/owner_authorization.js +55 -55
  1192. package/src/engine/network/ecs/serialization/NetworkIdentitySerializationAdapter.js +64 -64
  1193. package/src/engine/network/replication/ScopeFilter.js +71 -71
  1194. package/src/engine/network/sim/ActionLog.js +152 -152
  1195. package/src/engine/network/sim/SimAction.js +273 -273
  1196. package/src/engine/network/sim/Snapshotter.js +222 -222
  1197. package/src/engine/network/state/FrameBufferRing.js +168 -168
  1198. package/src/engine/network/state/InputRing.js +134 -134
  1199. package/src/engine/network/state/PriorityAccumulator.js +180 -180
  1200. package/src/engine/network/time/TimeDilation.js +62 -62
  1201. package/src/engine/network/transport/Channel.js +336 -336
  1202. package/src/engine/network/transport/Transport.js +203 -203
  1203. package/src/engine/network/transport/adapters/NodeUDPTransport.js +186 -186
  1204. package/src/engine/network/transport/adapters/WebRTCDataChannelTransport.js +105 -105
  1205. package/src/engine/network/transport/fragments/fragment_send.js +147 -147
  1206. package/src/engine/network/transport/fragments/packet_size.js +101 -101
  1207. package/src/engine/network/xhr.js +23 -23
  1208. package/src/engine/physics/BULLET_REVIEW.md +945 -945
  1209. package/src/engine/physics/CANNON_REVIEW.md +1300 -1300
  1210. package/src/engine/physics/CONSTRAINT_SOLVER_BENCH_LOG.md +208 -208
  1211. package/src/engine/physics/CONSTRAINT_SOLVER_IMPROVEMENTS_PLAN.md +364 -364
  1212. package/src/engine/physics/INTEPOLATION_SYSTEM_PLAN.md +287 -287
  1213. package/src/engine/physics/JOLT_REVIEW.md +913 -913
  1214. package/src/engine/physics/PLAN.md +1120 -1094
  1215. package/src/engine/physics/RAPIER_REVIEW.md +934 -934
  1216. package/src/engine/physics/REVIEW_001_ACTION_PLAN.md +642 -642
  1217. package/src/engine/physics/REVIEW_002.md +151 -151
  1218. package/src/engine/physics/REVIEW_003.md +166 -166
  1219. package/src/engine/physics/broadphase/compute_fat_world_aabb.js +97 -97
  1220. package/src/engine/physics/constraint/DofMode.js +35 -35
  1221. package/src/engine/physics/constraint/solve_constraints.js +1 -1
  1222. package/src/engine/physics/contact/combine_material.js +35 -35
  1223. package/src/engine/physics/ecs/BodyKind.js +29 -29
  1224. package/src/engine/physics/ecs/Collider.js +177 -177
  1225. package/src/engine/physics/ecs/ColliderFlags.js +15 -15
  1226. package/src/engine/physics/ecs/ColliderSerializationAdapter.js +37 -37
  1227. package/src/engine/physics/ecs/Joint.js +475 -475
  1228. package/src/engine/physics/ecs/JointSerializationAdapter.js +72 -72
  1229. package/src/engine/physics/ecs/PhysicsSystem.d.ts +3 -0
  1230. package/src/engine/physics/ecs/PhysicsSystem.d.ts.map +1 -1
  1231. package/src/engine/physics/ecs/PhysicsSystem.js +7 -2
  1232. package/src/engine/physics/ecs/RigidBodySerializationUpgrader_0_1.js +37 -37
  1233. package/src/engine/physics/ecs/SleepState.js +12 -12
  1234. package/src/engine/physics/ecs/find_non_finite_physics_state.js +76 -76
  1235. package/src/engine/physics/fluid/FluidField.js +867 -867
  1236. package/src/engine/physics/fluid/FluidSimulator.js +832 -832
  1237. package/src/engine/physics/fluid/REVIEW_02_PLAN.md +243 -243
  1238. package/src/engine/physics/fluid/SliceVisualiser.js +190 -190
  1239. package/src/engine/physics/fluid/ecs/FluidComponent.js +239 -239
  1240. package/src/engine/physics/fluid/ecs/FluidEffectorsComponent.js +89 -89
  1241. package/src/engine/physics/fluid/ecs/FluidObstacle.js +97 -97
  1242. package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
  1243. package/src/engine/physics/fluid/ecs/FluidObstacleSystem.js +348 -348
  1244. package/src/engine/physics/fluid/ecs/FluidSystem.js +142 -142
  1245. package/src/engine/physics/fluid/ecs/FluidWorkerCore.js +123 -123
  1246. package/src/engine/physics/fluid/ecs/WorkerFluidSystem.js +395 -395
  1247. package/src/engine/physics/fluid/ecs/fluid.worker.js +12 -12
  1248. package/src/engine/physics/fluid/ecs/fluid_build_world_to_grid.js +32 -32
  1249. package/src/engine/physics/fluid/ecs/fluid_gather_visible_effectors.js +47 -47
  1250. package/src/engine/physics/fluid/ecs/fluid_reanchor_field.js +85 -85
  1251. package/src/engine/physics/fluid/ecs/fluid_sync_effectors_from_transform.js +16 -16
  1252. package/src/engine/physics/fluid/ecs/fluid_worker_protocol.js +111 -111
  1253. package/src/engine/physics/fluid/ecs/makeFluidWorker.js +18 -18
  1254. package/src/engine/physics/fluid/effector/AbstractFluidEffector.js +81 -81
  1255. package/src/engine/physics/fluid/effector/GlobalFluidEffector.js +202 -202
  1256. package/src/engine/physics/fluid/effector/ImpulseFluidEffector.js +257 -257
  1257. package/src/engine/physics/fluid/effector/WakeFluidEffector.js +405 -405
  1258. package/src/engine/physics/fluid/prototype.js +126 -126
  1259. package/src/engine/physics/fluid/solver/v3_grid_advect_maccormack_scalar.js +143 -143
  1260. package/src/engine/physics/fluid/solver/v3_grid_advect_maccormack_velocity.js +162 -162
  1261. package/src/engine/physics/fluid/solver/v3_grid_advect_sl_velocity.js +107 -107
  1262. package/src/engine/physics/fluid/solver/v3_grid_apply_vorticity_confinement.js +131 -131
  1263. package/src/engine/physics/fluid/solver/v3_grid_compute_solid_neighbour_mask.js +90 -90
  1264. package/src/engine/physics/fluid/solver/v3_grid_limit8_at_indices.js +38 -38
  1265. package/src/engine/physics/fluid/solver/v3_grid_patch_edges_constant.js +77 -77
  1266. package/src/engine/physics/fluid/solver/v3_grid_patch_edges_uniform.js +113 -113
  1267. package/src/engine/physics/fluid/solver/v3_grid_sample_scalar_masked.js +92 -92
  1268. package/src/engine/physics/fluid/solver/v3_grid_shift_in_place.js +107 -107
  1269. package/src/engine/physics/fluid/solver/v3_grid_solve_pressure.js +135 -135
  1270. package/src/engine/physics/fluid/solver/v3_grid_solve_pressure_pcg.js +511 -511
  1271. package/src/engine/physics/fluid/solver/v3_grid_subtract_pressure_gradient.js +108 -108
  1272. package/src/engine/physics/fluid/solver/v3_mac_advect_maccormack_velocity.js +317 -317
  1273. package/src/engine/physics/fluid/solver/v3_mac_advect_scalar.js +236 -236
  1274. package/src/engine/physics/fluid/solver/v3_mac_advect_sl_velocity.js +217 -217
  1275. package/src/engine/physics/fluid/solver/v3_mac_apply_vorticity_confinement.js +174 -174
  1276. package/src/engine/physics/fluid/solver/v3_mac_clip_trace.js +95 -95
  1277. package/src/engine/physics/fluid/solver/v3_mac_compute_divergence.js +77 -77
  1278. package/src/engine/physics/fluid/solver/v3_mac_compute_face_solid.js +131 -131
  1279. package/src/engine/physics/fluid/solver/v3_mac_subtract_pressure_gradient.js +104 -104
  1280. package/src/engine/physics/inertia/world_inverse_inertia.js +160 -160
  1281. package/src/engine/physics/integration/integrate_position.js +97 -97
  1282. package/src/engine/physics/narrowphase/box_box_manifold.js +681 -681
  1283. package/src/engine/physics/narrowphase/box_triangle_contact.js +906 -906
  1284. package/src/engine/physics/narrowphase/capsule_triangle_contact.js +395 -395
  1285. package/src/engine/physics/narrowphase/compute_penetration.js +369 -369
  1286. package/src/engine/physics/narrowphase/decomposition/decompose_to_triangles.js +55 -55
  1287. package/src/engine/physics/narrowphase/decomposition/triangle_buffer_layout.js +37 -37
  1288. package/src/engine/physics/narrowphase/mesh_mesh_tet_manifold.js +117 -117
  1289. package/src/engine/physics/narrowphase/narrowphase_step.js +1738 -1738
  1290. package/src/engine/physics/narrowphase/reduce_manifold_contacts.js +74 -74
  1291. package/src/engine/physics/narrowphase/refine_ray_hit.d.ts +12 -11
  1292. package/src/engine/physics/narrowphase/refine_ray_hit.d.ts.map +1 -1
  1293. package/src/engine/physics/narrowphase/refine_ray_hit.js +228 -36
  1294. package/src/engine/physics/narrowphase/sphere_sphere_contact.js +52 -52
  1295. package/src/engine/physics/narrowphase/sphere_triangle_contact.js +138 -138
  1296. package/src/engine/physics/persistence/solver_caches.js +309 -309
  1297. package/src/engine/physics/queries/overlap_shape.js +187 -187
  1298. package/src/engine/physics/queries/raycast.d.ts +7 -4
  1299. package/src/engine/physics/queries/raycast.d.ts.map +1 -1
  1300. package/src/engine/physics/queries/raycast.js +11 -5
  1301. package/src/engine/physics/queries/shape_cast.js +417 -417
  1302. package/src/engine/physics/solver/apply_impulse_to_body.js +86 -86
  1303. package/src/engine/physics/solver/friction_cone.js +37 -37
  1304. package/src/engine/physics/solver/solve_contacts.js +1 -1
  1305. package/src/engine/platform/WebEnginePlatform.d.ts.map +1 -1
  1306. package/src/engine/platform/WebEnginePlatform.js +1 -2
  1307. package/src/engine/scene/SerializedScene.d.ts +2 -2
  1308. package/src/engine/scene/SerializedScene.d.ts.map +1 -1
  1309. package/src/engine/scene/transitionToScene.js +121 -121
  1310. package/src/engine/simulation/Ticker.d.ts.map +1 -1
  1311. package/src/engine/simulation/Ticker.js +33 -0
  1312. package/src/engine/sound/ecs/audio/LiveEmitterSet.js +345 -345
  1313. package/src/engine/sound/ecs/audio/SpatialAudioIndex.js +140 -140
  1314. package/src/engine/sound/simulation/AcousticSimulator.js +646 -646
  1315. package/src/engine/sound/simulation/IMPLEMENTATION_PLAN.md +432 -432
  1316. package/src/engine/sound/simulation/PROBE_PLACEMENT.md +250 -250
  1317. package/src/engine/sound/simulation/PROBE_TRANSFER_RESEARCH.md +322 -322
  1318. package/src/engine/sound/simulation/README.md +277 -277
  1319. package/src/engine/sound/simulation/REFLECTION_IR_PLAN.md +261 -261
  1320. package/src/engine/sound/simulation/VISIBILITY_GRAPH_PLAN.md +121 -121
  1321. package/src/engine/sound/simulation/configureAcousticSimulation.js +48 -48
  1322. package/src/engine/sound/simulation/core/AcousticMedium.js +113 -113
  1323. package/src/engine/sound/simulation/core/AcousticMediumSerializationAdapter.js +27 -27
  1324. package/src/engine/sound/simulation/core/AcousticOccluderIndex.js +312 -312
  1325. package/src/engine/sound/simulation/core/AcousticRegionIndex.js +159 -159
  1326. package/src/engine/sound/simulation/core/AcousticSolution.js +90 -90
  1327. package/src/engine/sound/simulation/core/AcousticSourceState.js +109 -109
  1328. package/src/engine/sound/simulation/core/AcousticVolumeRegion.js +73 -73
  1329. package/src/engine/sound/simulation/core/OcclusionSolver.js +112 -112
  1330. package/src/engine/sound/simulation/core/RayHit.js +50 -50
  1331. package/src/engine/sound/simulation/core/VolumeField.js +149 -149
  1332. package/src/engine/sound/simulation/definition/AcousticDirectivity.js +114 -114
  1333. package/src/engine/sound/simulation/definition/AcousticDirectivitySerializationAdapter.js +30 -30
  1334. package/src/engine/sound/simulation/definition/AcousticMaterial.js +122 -122
  1335. package/src/engine/sound/simulation/definition/AcousticMaterialSerializationAdapter.js +32 -32
  1336. package/src/engine/sound/simulation/ecs/AcousticBody.js +48 -48
  1337. package/src/engine/sound/simulation/ecs/AcousticBodySerializationAdapter.js +34 -34
  1338. package/src/engine/sound/simulation/ecs/AcousticProbeFieldSystem.js +64 -64
  1339. package/src/engine/sound/simulation/ecs/AcousticSimulationSystem.js +75 -75
  1340. package/src/engine/sound/simulation/ecs/AcousticVolume.js +74 -74
  1341. package/src/engine/sound/simulation/ecs/AcousticVolumeSerializationAdapter.js +37 -37
  1342. package/src/engine/sound/simulation/ecs/AcousticVolumeSystem.js +66 -66
  1343. package/src/engine/sound/simulation/probe/AcousticProbeField.js +578 -578
  1344. package/src/engine/sound/simulation/probe/AcousticProbeFieldSerializationAdapter.js +60 -60
  1345. package/src/engine/sound/simulation/probe/ProbeFieldPathingSolution.js +64 -64
  1346. package/src/engine/sound/simulation/probe/ProbeVisibilityRecheck.js +132 -132
  1347. package/src/engine/sound/simulation/probe/acoustic_probe_transfer.js +103 -103
  1348. package/src/engine/sound/simulation/probe/acoustic_trace_energy.js +136 -136
  1349. package/src/engine/sound/simulation/probe/bakeProbeField.js +169 -169
  1350. package/src/engine/sound/simulation/probe/bakeProbeReflectors.js +110 -110
  1351. package/src/engine/sound/simulation/probe/bakeReverbBands.js +110 -110
  1352. package/src/engine/sound/simulation/probe/bakeVisibility.js +148 -148
  1353. package/src/engine/sound/simulation/probe/echogram_band_rt60.js +83 -83
  1354. package/src/engine/sound/simulation/probe/probe_delaunay_edges.js +215 -215
  1355. package/src/engine/sound/simulation/probe/probe_densify_portals.js +140 -140
  1356. package/src/engine/sound/simulation/probe/probe_detect_portals.js +196 -196
  1357. package/src/engine/sound/simulation/probe/probe_edge_key.js +38 -38
  1358. package/src/engine/sound/simulation/probe/probe_edge_visible.js +41 -41
  1359. package/src/engine/sound/simulation/probe/probe_place_sdf_cover.js +82 -82
  1360. package/src/engine/sound/simulation/probe/probe_refine_connectivity.js +181 -181
  1361. package/src/engine/sound/simulation/probe/probe_sdf_grid.js +171 -171
  1362. package/src/engine/sound/simulation/probe/probe_visibility_augment.js +146 -146
  1363. package/src/engine/sound/simulation/probe/probe_visibility_bridge_components.js +167 -167
  1364. package/src/engine/sound/simulation/render/FoaProbeReverbRenderer.js +354 -354
  1365. package/src/engine/sound/simulation/render/ProbeReverbRenderer.js +231 -231
  1366. package/src/engine/sound/simulation/render/foaReverbImpulseResponse.js +105 -105
  1367. package/src/engine/sound/simulation/render/reverbImpulseResponse.js +66 -66
  1368. package/src/engine/sound/simulation/render/reverb_band_tails.js +93 -93
  1369. package/src/engine/sound/simulation/serialization/populateAcousticSerializationRegistry.js +25 -25
  1370. package/src/engine/sound/sopra/README.md +643 -643
  1371. package/src/engine/sound/sopra/SopraEngine.js +432 -432
  1372. package/src/engine/sound/sopra/asset/AssetManagerBufferProvider.js +71 -71
  1373. package/src/engine/sound/sopra/asset/BufferProvider.js +29 -29
  1374. package/src/engine/sound/sopra/asset/StubBufferProvider.js +58 -58
  1375. package/src/engine/sound/sopra/definition/BusDefinition.js +142 -142
  1376. package/src/engine/sound/sopra/definition/BusDefinitionSerializationAdapter.js +54 -54
  1377. package/src/engine/sound/sopra/definition/DuckingRule.js +106 -106
  1378. package/src/engine/sound/sopra/definition/DuckingRuleSerializationAdapter.js +31 -31
  1379. package/src/engine/sound/sopra/definition/EventDescription.js +262 -262
  1380. package/src/engine/sound/sopra/definition/EventDescriptionSerializationAdapter.js +55 -55
  1381. package/src/engine/sound/sopra/definition/MixerSnapshot.js +83 -83
  1382. package/src/engine/sound/sopra/definition/MixerSnapshotSerializationAdapter.js +39 -39
  1383. package/src/engine/sound/sopra/definition/ParameterDefinition.js +117 -117
  1384. package/src/engine/sound/sopra/definition/ParameterDefinitionSerializationAdapter.js +31 -31
  1385. package/src/engine/sound/sopra/definition/VoiceStealMode.js +18 -18
  1386. package/src/engine/sound/sopra/definition/clip/AbstractAudioClip.js +109 -109
  1387. package/src/engine/sound/sopra/definition/clip/BlendContainerAudioClip.js +185 -185
  1388. package/src/engine/sound/sopra/definition/clip/BlendContainerAudioClipSerializationAdapter.js +59 -59
  1389. package/src/engine/sound/sopra/definition/clip/ContainerAudioClip.js +128 -128
  1390. package/src/engine/sound/sopra/definition/clip/RandomContainerAudioClip.js +226 -226
  1391. package/src/engine/sound/sopra/definition/clip/RandomContainerAudioClipSerializationAdapter.js +54 -54
  1392. package/src/engine/sound/sopra/definition/clip/SampleAudioClip.js +191 -191
  1393. package/src/engine/sound/sopra/definition/clip/SampleAudioClipSerializationAdapter.js +39 -39
  1394. package/src/engine/sound/sopra/definition/clip/SequenceContainerAudioClip.js +79 -79
  1395. package/src/engine/sound/sopra/definition/clip/SequenceContainerAudioClipSerializationAdapter.js +42 -42
  1396. package/src/engine/sound/sopra/definition/clip/SilenceAudioClip.js +77 -77
  1397. package/src/engine/sound/sopra/definition/clip/SilenceAudioClipSerializationAdapter.js +27 -27
  1398. package/src/engine/sound/sopra/definition/clip/SwitchContainerAudioClip.d.ts +5 -0
  1399. package/src/engine/sound/sopra/definition/clip/SwitchContainerAudioClip.d.ts.map +1 -1
  1400. package/src/engine/sound/sopra/definition/clip/SwitchContainerAudioClip.js +125 -125
  1401. package/src/engine/sound/sopra/definition/clip/SwitchContainerAudioClipSerializationAdapter.js +41 -41
  1402. package/src/engine/sound/sopra/definition/effect/AbstractAudioEffect.js +24 -24
  1403. package/src/engine/sound/sopra/definition/effect/CompressorEffect.js +120 -120
  1404. package/src/engine/sound/sopra/definition/effect/CompressorEffectSerializationAdapter.js +31 -31
  1405. package/src/engine/sound/sopra/definition/effect/EqEffect.js +128 -128
  1406. package/src/engine/sound/sopra/definition/effect/EqEffectSerializationAdapter.js +29 -29
  1407. package/src/engine/sound/sopra/definition/effect/ReverbEffect.js +113 -113
  1408. package/src/engine/sound/sopra/definition/effect/ReverbEffectSerializationAdapter.js +25 -25
  1409. package/src/engine/sound/sopra/runtime/BusGraph.js +231 -231
  1410. package/src/engine/sound/sopra/runtime/ParameterStore.js +98 -98
  1411. package/src/engine/sound/sopra/runtime/SopraPlaybackContext.js +68 -68
  1412. package/src/engine/sound/sopra/runtime/Voice.js +145 -145
  1413. package/src/engine/sound/sopra/runtime/VoiceManager.js +136 -136
  1414. package/src/engine/sound/sopra/runtime/VoicePool.js +17 -17
  1415. package/src/engine/sound/sopra/serialization/populateSopraSerializationRegistry.js +42 -42
  1416. package/src/engine/sound/sopra/serialization/sopraJSON.js +99 -99
  1417. package/src/engine/sound/sopra/serialization/sopraSerializationHarness.js +49 -49
  1418. package/src/engine/sound/sopra/util/MockAudioContext.js +224 -224
  1419. package/src/engine/sound/sopra/util/fadeOutAndStop.js +60 -60
  1420. package/src/engine/ui/DraggableAspect.js +115 -115
  1421. package/src/engine/ui/apply_pointer_tilt_3d.js +50 -50
  1422. package/src/generation/COORDINATES.md +54 -54
  1423. package/src/generation/GridGenerationResource.js +24 -24
  1424. package/src/generation/GridTaskGroup.js +214 -214
  1425. package/src/generation/REVIEW_01_ACTION_PLAN.md +628 -628
  1426. package/src/generation/automata/CaveGeneratorCellularAutomata.js +79 -79
  1427. package/src/generation/automata/CellularAutomata.js +22 -22
  1428. package/src/generation/compute_writes_union.js +25 -25
  1429. package/src/generation/filtering/CellFilter.js +117 -117
  1430. package/src/generation/filtering/core/CellFilterBinaryOperation.js +37 -37
  1431. package/src/generation/filtering/core/CellFilterOperationTertiary.js +43 -43
  1432. package/src/generation/filtering/core/CellFilterUnaryOperation.js +29 -29
  1433. package/src/generation/filtering/numeric/process/computeCellFilterSobel.js +36 -36
  1434. package/src/generation/filtering/numeric/process/computeFilterSurfaceNormal.js +42 -42
  1435. package/src/generation/filtering/numeric/util/populateSampler2DFromCellFilter.js +18 -18
  1436. package/src/generation/filtering/numeric/util/write_cell_filter_to_sampler2d.js +47 -47
  1437. package/src/generation/filtering/util/cell_filter_weights_pick.js +54 -54
  1438. package/src/generation/grid/GridData.js +233 -233
  1439. package/src/generation/grid/coords/grid_to_texel.js +10 -10
  1440. package/src/generation/grid/coords/texel_to_grid.js +10 -10
  1441. package/src/generation/grid/generation/GridTaskApplyActionToCells.js +90 -90
  1442. package/src/generation/grid/generation/GridTaskDensityMarkerDistribution.js +388 -388
  1443. package/src/generation/grid/generation/GridTaskExecuteRuleTimes.js +127 -127
  1444. package/src/generation/grid/generation/GridTaskSequence.js +58 -58
  1445. package/src/generation/grid/generation/NoopGridTaskGenerator.js +12 -12
  1446. package/src/generation/grid/generation/discrete/GridTaskActionRuleSet.js +48 -48
  1447. package/src/generation/grid/generation/discrete/GridTaskCellularAutomata.js +146 -146
  1448. package/src/generation/grid/generation/discrete/GridTaskConnectRooms.js +540 -540
  1449. package/src/generation/grid/generation/discrete/layer/GridTaskBuildSourceDistanceMap.js +222 -222
  1450. package/src/generation/grid/generation/grid/GridTaskAddNodesFixed.js +44 -44
  1451. package/src/generation/grid/generation/road/GridTaskGenerateRoads.js +614 -614
  1452. package/src/generation/markers/GridCellActionPlaceMarker.js +244 -244
  1453. package/src/generation/markers/GridCellActionPlaceMarkerGroup.js +86 -86
  1454. package/src/generation/markers/actions/terrain/MarkerNodeActionPaintTerrain.js +266 -266
  1455. package/src/generation/markers/emitter/MarkerNodeEmitterGridCellAction.js +49 -49
  1456. package/src/generation/placement/GridCellActionTransformNearbyMarkers.js +120 -120
  1457. package/src/generation/placement/action/GridCellAction.js +45 -45
  1458. package/src/generation/placement/action/GridCellActionPlaceTags.js +140 -140
  1459. package/src/generation/placement/action/GridCellActionWriteFilterToLayer.js +89 -89
  1460. package/src/generation/placement/action/random/CellActionSelectRandom.js +69 -69
  1461. package/src/generation/placement/action/random/weighted/CellActionSelectWeightedRandom.js +91 -91
  1462. package/src/generation/placement/action/util/GridCellActionSequence.js +61 -61
  1463. package/src/generation/placement/action/util/GridCellDisplacedAction.js +61 -61
  1464. package/src/generation/rules/cell/CellMatcherRemovalPreservesConnectivity.js +183 -183
  1465. package/src/generation/theme/ThemeEngine.js +666 -666
  1466. package/src/shade/RENDERER_CONTRACT.md +568 -568
  1467. package/src/shade/descriptor/texture/format/gpu_texture_format_info.js +267 -267
  1468. package/src/shade/device/ShadeDeviceFailure.js +104 -104
  1469. package/src/shade/device/ShadeDeviceFailureReason.js +41 -41
  1470. package/src/shade/device/mock/IMPLEMENTATION_PLAN.md +255 -255
  1471. package/src/shade/device/mock/REVIEW_2026_08_22.md +527 -527
  1472. package/src/shade/device/mock/SoftwareGPUBindGroup.js +23 -23
  1473. package/src/shade/device/mock/SoftwareGPUBindGroupLayout.js +22 -22
  1474. package/src/shade/device/mock/SoftwareGPUError.js +63 -63
  1475. package/src/shade/device/mock/SoftwareGPUPipeline.js +75 -75
  1476. package/src/shade/device/mock/SoftwareGPUQuerySet.js +113 -113
  1477. package/src/shade/device/mock/SoftwareGPUSampler.js +30 -30
  1478. package/src/shade/device/mock/SoftwareGPUShaderModule.js +32 -32
  1479. package/src/shade/device/mock/SoftwareGPUTextureView.js +22 -22
  1480. package/src/shade/device/mock/SoftwareGPUUncapturedErrorEvent.js +23 -23
  1481. package/src/shade/device/mock/normalize_dynamic_offsets.js +26 -26
  1482. package/src/shade/device/mock/texture_copy.js +287 -287
  1483. package/src/shade/device/timing/GPUTimer.js +285 -285
  1484. package/src/shade/device/timing/GPUTimerArray.js +205 -205
  1485. package/src/shade/playground/add_random_lights.js +49 -49
  1486. package/src/shade/playground/add_random_meshes.js +83 -83
  1487. package/src/shade/playground/animation_prototype.js +508 -508
  1488. package/src/shade/playground/animation_prototype_skinning.js +647 -647
  1489. package/src/shade/playground/animation_prototype_stress.js +765 -765
  1490. package/src/shade/playground/enable_picker.js +59 -59
  1491. package/src/shade/playground/gltf_skinned_prototype.js +560 -560
  1492. package/src/shade/playground/gltf_skinned_stress_prototype.js +387 -387
  1493. package/src/shade/playground/gltf_viewer.js +282 -282
  1494. package/src/shade/playground/load_default_environment.js +19 -19
  1495. package/src/shade/playground/main.js +2727 -2727
  1496. package/src/shade/playground/make_animated_instances.js +117 -117
  1497. package/src/shade/playground/prototype_virtual_texture.js +274 -274
  1498. package/src/shade/playground/prototype_volumetrics_01.js +206 -206
  1499. package/src/shade/playground/sample.js +234 -234
  1500. package/src/shade/playground/sample_load_gltf.js +102 -102
  1501. package/src/shade/playground/spread_node3d_grid.js +19 -19
  1502. package/src/shade/renderer/Renderer.js +2436 -2436
  1503. package/src/shade/renderer/ShadeIndirectLightingMode.js +14 -14
  1504. package/src/shade/renderer/animation/ShadeAnimationChannel.js +414 -414
  1505. package/src/shade/renderer/animation/compute_skinned_mesh_clip_bounding_sphere.js +531 -531
  1506. package/src/shade/renderer/animation/pose/PosePlayback.js +55 -55
  1507. package/src/shade/renderer/animation/pose/pose_evaluate_local.js +179 -179
  1508. package/src/shade/renderer/animation/pose/pose_evaluate_world.js +76 -76
  1509. package/src/shade/renderer/animation/skinning/GPUMeshSkinningContext.js +1024 -1024
  1510. package/src/shade/renderer/animation/skinning/SKINNING_BINDING_STRUCT.js +79 -79
  1511. package/src/shade/renderer/animation/skinning/chunk_skin_blend_mesh_local.js +56 -56
  1512. package/src/shade/renderer/binding/BindGroupManager.js +282 -282
  1513. package/src/shade/renderer/binding/adapt_cache_capacity.js +25 -25
  1514. package/src/shade/renderer/buffer/GPUBufferAllocator.js +116 -116
  1515. package/src/shade/renderer/buffer/buffer_pool_ops.js +123 -123
  1516. package/src/shade/renderer/buffer/table/GPU_DATABASE_PAGE_SIZE.js +9 -9
  1517. package/src/shade/renderer/buffer/table/GPU_DATABASE_UPLOAD_BUFFER_LIMIT.js +8 -8
  1518. package/src/shade/renderer/buffer/table/PageBufferPool.js +71 -71
  1519. package/src/shade/renderer/buffer/table/PageSlotAllocator.js +95 -95
  1520. package/src/shade/renderer/camera/Camera.js +281 -281
  1521. package/src/shade/renderer/camera/GPUCameraContext.js +233 -233
  1522. package/src/shade/renderer/camera/orbital/README.md +84 -84
  1523. package/src/shade/renderer/deferred/shader_composite_volumetrics.js +75 -75
  1524. package/src/shade/renderer/dynamic/DYNAMIC_MESH_VERTEX.js +25 -25
  1525. package/src/shade/renderer/dynamic/GPUDynamicMeshRenderer.js +342 -342
  1526. package/src/shade/renderer/dynamic/GPUDynamicMeshResidency.js +167 -167
  1527. package/src/shade/renderer/dynamic/shader_dynamic_mesh.js +170 -170
  1528. package/src/shade/renderer/extension/FrameContext.js +263 -263
  1529. package/src/shade/renderer/extension/FramePhase.js +104 -104
  1530. package/src/shade/renderer/extension/FrameRecord.js +126 -126
  1531. package/src/shade/renderer/extension/GBufferTextures.js +83 -83
  1532. package/src/shade/renderer/extension/PresentTarget.js +34 -34
  1533. package/src/shade/renderer/extension/RENDER_EXTENSION_DESIGN.md +918 -918
  1534. package/src/shade/renderer/extension/RenderExtension.js +69 -69
  1535. package/src/shade/renderer/extension/RenderExtensionRegistry.js +319 -319
  1536. package/src/shade/renderer/extension/SceneColor.js +40 -40
  1537. package/src/shade/renderer/extension/ViewTextures.js +78 -78
  1538. package/src/shade/renderer/fow/GPUFogOfWarRenderer.js +182 -182
  1539. package/src/shade/renderer/geometry/Geometry.js +608 -608
  1540. package/src/shade/renderer/geometry/geometry_build_from_meshlet_geometry.js +342 -342
  1541. package/src/shade/renderer/geometry/meshlet_geometry_transfer.js +41 -41
  1542. package/src/shade/renderer/geometry/primitives/make_box_geometry.js +153 -153
  1543. package/src/shade/renderer/geometry/primitives/make_cylinder_geometry.js +240 -240
  1544. package/src/shade/renderer/geometry/primitives/make_plane_geometry.js +145 -145
  1545. package/src/shade/renderer/geometry/primitives/make_polyhedron_geometry.js +327 -327
  1546. package/src/shade/renderer/geometry/primitives/make_torus_geometry.js +107 -107
  1547. package/src/shade/renderer/geometry/primitives/make_torus_knot_geometry.js +165 -165
  1548. package/src/shade/renderer/geometry/virtual/VGEO_FORMAT.md +607 -607
  1549. package/src/shade/renderer/geometry/virtual/build/VGeoBuildOptions.js +66 -66
  1550. package/src/shade/renderer/geometry/virtual/build/VGeoBuildResult.js +32 -32
  1551. package/src/shade/renderer/geometry/virtual/build/VGeoFaceGraph.js +103 -103
  1552. package/src/shade/renderer/geometry/virtual/build/VGeoGatheredFaces.js +25 -25
  1553. package/src/shade/renderer/geometry/virtual/build/VGeoLevel.js +33 -33
  1554. package/src/shade/renderer/geometry/virtual/build/VGeoLevelOptions.js +62 -62
  1555. package/src/shade/renderer/geometry/virtual/build/VGeoLevelSummary.js +49 -49
  1556. package/src/shade/renderer/geometry/virtual/build/VGeoSubmesh.js +20 -20
  1557. package/src/shade/renderer/geometry/virtual/build/VirtualGeometryMesh.js +214 -214
  1558. package/src/shade/renderer/geometry/virtual/build/gltf/GltfByteSource.js +122 -122
  1559. package/src/shade/renderer/geometry/virtual/build/gltf/GltfCollectReport.js +29 -29
  1560. package/src/shade/renderer/geometry/virtual/build/gltf/GltfDocument.js +210 -210
  1561. package/src/shade/renderer/geometry/virtual/build/gltf/GltfGeometry.js +48 -48
  1562. package/src/shade/renderer/geometry/virtual/build/gltf/GltfGeometryInstance.js +25 -25
  1563. package/src/shade/renderer/geometry/virtual/build/gltf/GltfGeometrySelection.js +28 -28
  1564. package/src/shade/renderer/geometry/virtual/build/gltf/gltf_collect_geometries.js +296 -296
  1565. package/src/shade/renderer/geometry/virtual/build/gltf/gltf_open_document.js +166 -166
  1566. package/src/shade/renderer/geometry/virtual/build/gltf/gltf_read_geometry.js +199 -199
  1567. package/src/shade/renderer/geometry/virtual/build/vgeo_assemble_pages.js +173 -173
  1568. package/src/shade/renderer/geometry/virtual/build/vgeo_bounding_sphere.js +28 -28
  1569. package/src/shade/renderer/geometry/virtual/build/vgeo_build.js +200 -200
  1570. package/src/shade/renderer/geometry/virtual/build/vgeo_build_levels.js +1786 -1786
  1571. package/src/shade/renderer/geometry/virtual/build/vgeo_build_page_nodes.js +157 -157
  1572. package/src/shade/renderer/geometry/virtual/build/vgeo_build_root_group.js +26 -26
  1573. package/src/shade/renderer/geometry/virtual/build/vgeo_compute_vertex_normals.js +75 -75
  1574. package/src/shade/renderer/geometry/virtual/build/vgeo_compute_vertex_tangents.js +143 -143
  1575. package/src/shade/renderer/geometry/virtual/build/vgeo_containing_sphere.js +44 -44
  1576. package/src/shade/renderer/geometry/virtual/build/vgeo_extract_submesh.js +41 -41
  1577. package/src/shade/renderer/geometry/virtual/build/vgeo_gather_faces.js +71 -71
  1578. package/src/shade/renderer/geometry/virtual/build/vgeo_graph_components.js +123 -123
  1579. package/src/shade/renderer/geometry/virtual/build/vgeo_narrow_indices.js +26 -26
  1580. package/src/shade/renderer/geometry/virtual/build/vgeo_normalize_source.js +112 -112
  1581. package/src/shade/renderer/geometry/virtual/build/vgeo_partition_graph.js +56 -56
  1582. package/src/shade/renderer/geometry/virtual/build/vgeo_sphere_inflate_to_contain.js +70 -70
  1583. package/src/shade/renderer/geometry/virtual/build/vgeo_split_face_set.js +187 -187
  1584. package/src/shade/renderer/geometry/virtual/build/vgeo_split_face_set_packed.js +207 -207
  1585. package/src/shade/renderer/geometry/virtual/format/VGEO_DEFECT.js +18 -18
  1586. package/src/shade/renderer/geometry/virtual/format/VGeoDefect.js +38 -38
  1587. package/src/shade/renderer/geometry/virtual/format/VGeoWriteOptions.js +64 -64
  1588. package/src/shade/renderer/geometry/virtual/format/attribute/VGEO_ATTRIBUTE.js +13 -13
  1589. package/src/shade/renderer/geometry/virtual/format/attribute/VGEO_ATTRIBUTES.js +50 -50
  1590. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_attribute_allocate.js +28 -28
  1591. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_attribute_mask.js +23 -23
  1592. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_attributes_read.js +31 -31
  1593. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_copy_vertex.js +32 -32
  1594. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_declare.js +46 -46
  1595. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_like.js +19 -19
  1596. package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_test_fixtures.js +27 -27
  1597. package/src/shade/renderer/geometry/virtual/format/checksum/vgeo_asset_id_preimage.js +62 -62
  1598. package/src/shade/renderer/geometry/virtual/format/checksum/vgeo_compute_asset_id.js +13 -13
  1599. package/src/shade/renderer/geometry/virtual/format/checksum/vgeo_compute_directory_block_checksum.js +41 -41
  1600. package/src/shade/renderer/geometry/virtual/format/checksum/vgeo_compute_frame_checksum.js +41 -41
  1601. package/src/shade/renderer/geometry/virtual/format/checksum/vgeo_compute_header_checksum.js +25 -25
  1602. package/src/shade/renderer/geometry/virtual/format/cluster/VGEO_CLUSTER_OFFSET.js +20 -20
  1603. package/src/shade/renderer/geometry/virtual/format/cluster/VGEO_CLUSTER_RECORD_SIZE.js +5 -5
  1604. package/src/shade/renderer/geometry/virtual/format/cluster/VGEO_MAX_CHILD_REF.js +5 -5
  1605. package/src/shade/renderer/geometry/virtual/format/cluster/VGEO_MAX_CLUSTER_TRIANGLE_COUNT.js +5 -5
  1606. package/src/shade/renderer/geometry/virtual/format/cluster/VGEO_MAX_CLUSTER_VERTEX_COUNT.js +5 -5
  1607. package/src/shade/renderer/geometry/virtual/format/cluster/VGEO_NO_CHILD.js +5 -5
  1608. package/src/shade/renderer/geometry/virtual/format/cluster/VGEO_NO_GROUP.js +5 -5
  1609. package/src/shade/renderer/geometry/virtual/format/cluster/VGEO_SAME_PAGE.js +6 -6
  1610. package/src/shade/renderer/geometry/virtual/format/dag/VirtualGeometryCluster.js +81 -81
  1611. package/src/shade/renderer/geometry/virtual/format/dag/VirtualGeometryGroup.js +37 -37
  1612. package/src/shade/renderer/geometry/virtual/format/dag/VirtualGeometryPageNode.js +55 -55
  1613. package/src/shade/renderer/geometry/virtual/format/directory/VGEO_DIRECTORY_BLOCK_RECORDS.js +5 -5
  1614. package/src/shade/renderer/geometry/virtual/format/directory/VGEO_DIRECTORY_FLAG_ROOT_PAGE.js +5 -5
  1615. package/src/shade/renderer/geometry/virtual/format/directory/VGEO_DIRECTORY_RECORD_SIZE.js +5 -5
  1616. package/src/shade/renderer/geometry/virtual/format/directory/vgeo_directory_block_count.js +12 -12
  1617. package/src/shade/renderer/geometry/virtual/format/frame/VGEO_CHILD_OFFSET.js +11 -11
  1618. package/src/shade/renderer/geometry/virtual/format/frame/VGEO_CHILD_TABLE_ENTRY_SIZE.js +5 -5
  1619. package/src/shade/renderer/geometry/virtual/format/frame/VGEO_CODEC_LZ4.js +11 -11
  1620. package/src/shade/renderer/geometry/virtual/format/frame/VGEO_CODEC_RAW.js +5 -5
  1621. package/src/shade/renderer/geometry/virtual/format/frame/VGEO_FRAME_ALIGNMENT.js +5 -5
  1622. package/src/shade/renderer/geometry/virtual/format/frame/VGEO_FRAME_HEADER_SIZE.js +5 -5
  1623. package/src/shade/renderer/geometry/virtual/format/frame/VGEO_FRAME_OFFSET.js +13 -13
  1624. package/src/shade/renderer/geometry/virtual/format/frame/VGEO_PAGE_MAGIC.js +5 -5
  1625. package/src/shade/renderer/geometry/virtual/format/frame/VGeoFrameBlob.js +21 -21
  1626. package/src/shade/renderer/geometry/virtual/format/frame/VGeoFrameExtent.js +59 -59
  1627. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_codec_name.js +27 -27
  1628. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_decode_frame_blob.js +84 -84
  1629. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_encode_frame_blob.js +56 -56
  1630. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_frame_decode_bound.js +35 -35
  1631. package/src/shade/renderer/geometry/virtual/format/frame/vgeo_scan_frames.js +74 -74
  1632. package/src/shade/renderer/geometry/virtual/format/header/VGEO_FORMAT_VERSION.js +6 -6
  1633. package/src/shade/renderer/geometry/virtual/format/header/VGEO_HASH_ALGO_XXH3.js +5 -5
  1634. package/src/shade/renderer/geometry/virtual/format/header/VGEO_HEADER_OFFSET.js +31 -31
  1635. package/src/shade/renderer/geometry/virtual/format/header/VGEO_HEADER_SIZE.js +5 -5
  1636. package/src/shade/renderer/geometry/virtual/format/header/VGEO_LEVEL_OFFSET.js +20 -20
  1637. package/src/shade/renderer/geometry/virtual/format/header/VGEO_LEVEL_RECORD_SIZE.js +9 -9
  1638. package/src/shade/renderer/geometry/virtual/format/header/VGEO_MAGIC.js +5 -5
  1639. package/src/shade/renderer/geometry/virtual/format/header/VGEO_MIN_READER_VERSION.js +5 -5
  1640. package/src/shade/renderer/geometry/virtual/format/header/VGEO_PAYLOAD_ENCODING_SHADE_MESHLET_V1.js +5 -5
  1641. package/src/shade/renderer/geometry/virtual/format/header/VGeoLevelRecord.js +41 -41
  1642. package/src/shade/renderer/geometry/virtual/format/page/VGEO_GROUP_RECORD_SIZE.js +5 -5
  1643. package/src/shade/renderer/geometry/virtual/format/page/VGEO_MAX_GROUP_CLUSTER_COUNT.js +6 -6
  1644. package/src/shade/renderer/geometry/virtual/format/page/VGEO_METRIC_OFFSET.js +21 -21
  1645. package/src/shade/renderer/geometry/virtual/format/page/VGEO_METRIC_SIZE.js +5 -5
  1646. package/src/shade/renderer/geometry/virtual/format/page/VGEO_NODE_FANOUT.js +9 -9
  1647. package/src/shade/renderer/geometry/virtual/format/page/VGEO_NODE_FLAG_LEAF.js +5 -5
  1648. package/src/shade/renderer/geometry/virtual/format/page/VGEO_NODE_OFFSET.js +10 -10
  1649. package/src/shade/renderer/geometry/virtual/format/page/VGEO_NODE_RECORD_SIZE.js +5 -5
  1650. package/src/shade/renderer/geometry/virtual/format/page/VGEO_PAGE_HEADER_SIZE.js +5 -5
  1651. package/src/shade/renderer/geometry/virtual/format/page/VGEO_PAGE_OFFSET.js +16 -16
  1652. package/src/shade/renderer/geometry/virtual/format/payload/VGEO_ENCODING_FLAGS_MASK.js +6 -6
  1653. package/src/shade/renderer/geometry/virtual/format/payload/VGeoEncodedPayload.js +18 -18
  1654. package/src/shade/renderer/geometry/virtual/format/payload/vgeo_encode_cluster_payload.js +200 -200
  1655. package/src/shade/renderer/geometry/virtual/format/payload/vgeo_payload_attribute_offset.js +39 -39
  1656. package/src/shade/renderer/geometry/virtual/format/payload/vgeo_payload_size.js +20 -20
  1657. package/src/shade/renderer/geometry/virtual/format/prototypeVGEOFormatViewer.js +2063 -2063
  1658. package/src/shade/renderer/geometry/virtual/format/vgeo_validate_container.js +1622 -1622
  1659. package/src/shade/renderer/geometry/virtual/format/vgeo_write_container.js +485 -485
  1660. package/src/shade/renderer/global_illumination/brick4/cpu/brick4_empty_gpu_structure.d.ts +23 -0
  1661. package/src/shade/renderer/global_illumination/brick4/cpu/brick4_empty_gpu_structure.d.ts.map +1 -0
  1662. package/src/shade/renderer/global_illumination/brick4/cpu/brick4_empty_gpu_structure.js +34 -0
  1663. package/src/shade/renderer/gpu_primitive/sort/ffx/graph_radix_sort.js +115 -115
  1664. package/src/shade/renderer/gpu_primitive/sort/one_sweep/verify_radix_sort_one_sweep.js +110 -110
  1665. package/src/shade/renderer/light/environment/octahedral_resample_kernel.js +50 -50
  1666. package/src/shade/renderer/light/environment/octahedral_uv_to_direction.js +30 -30
  1667. package/src/shade/renderer/light/environment/resample_cube_to_octahedral.js +157 -157
  1668. package/src/shade/renderer/light/make_sunlight.js +35 -35
  1669. package/src/shade/renderer/light/model/io/light_record_point.js +39 -39
  1670. package/src/shade/renderer/loader/gltf/GLTF_PRIMITIVE_MODE.js +23 -23
  1671. package/src/shade/renderer/loader/gltf/MESHOPT_COMPRESSION_PLAN.md +793 -793
  1672. package/src/shade/renderer/loader/gltf/ext/GltfBufferViewExtension.js +54 -54
  1673. package/src/shade/renderer/loader/gltf/ext/GltfBufferViewExtensionSet.js +109 -109
  1674. package/src/shade/renderer/loader/gltf/ext/gltf_apply_buffer_view_extensions.js +69 -69
  1675. package/src/shade/renderer/loader/gltf/ext/gltf_buffer_view_extensions.js +22 -22
  1676. package/src/shade/renderer/loader/gltf/ext/gltf_geometry_extensions.js +39 -39
  1677. package/src/shade/renderer/loader/gltf/ext/meshopt/MeshoptBufferViewExtension.js +301 -301
  1678. package/src/shade/renderer/loader/gltf/gltf_component_type.js +223 -223
  1679. package/src/shade/renderer/loader/gltf/gltf_node_world_matrices.js +137 -137
  1680. package/src/shade/renderer/loader/gltf/gltf_parse_container.js +241 -241
  1681. package/src/shade/renderer/loader/gltf/gltf_read_accessor.js +294 -294
  1682. package/src/shade/renderer/loader/gltf/gltf_used_image_indices.js +49 -49
  1683. package/src/shade/renderer/loader/gltf/load_gltf.js +1253 -1253
  1684. package/src/shade/renderer/loader/gltf/tiny-gltf.js +646 -646
  1685. package/src/shade/renderer/loader/usd/UsdError.js +33 -33
  1686. package/src/shade/renderer/loader/usd/UsdExtensionRegistry.js +69 -69
  1687. package/src/shade/renderer/loader/usd/load_usd.js +226 -226
  1688. package/src/shade/renderer/loader/usd/parse_usda.js +931 -931
  1689. package/src/shade/renderer/loader/usd/unpack_usdz.js +106 -106
  1690. package/src/shade/renderer/loader/usd/usd_build_scene.js +658 -658
  1691. package/src/shade/renderer/loader/usd/usd_compose_transform.js +258 -258
  1692. package/src/shade/renderer/loader/usd/usd_decode_image.js +384 -384
  1693. package/src/shade/renderer/loader/usd/usd_lz4.js +182 -182
  1694. package/src/shade/renderer/loader/usd/usd_triangulate.js +159 -159
  1695. package/src/shade/renderer/material/ShadeMaterial.d.ts +2 -2
  1696. package/src/shade/renderer/material/ShadeMaterial.js +2 -2
  1697. package/src/shade/renderer/material/standard/fragment_gbuffer.js +334 -334
  1698. package/src/shade/renderer/material/standard/fragment_gbuffer_vt.js +169 -169
  1699. package/src/shade/renderer/material/standard/material_gbuffer_vertex.js +45 -45
  1700. package/src/shade/renderer/material/standard_material_to_struct.js +23 -23
  1701. package/src/shade/renderer/particles/prototypeParticleSystem.js +450 -450
  1702. package/src/shade/renderer/particles/runtime/spawn_request_encoding.js +52 -52
  1703. package/src/shade/renderer/pool/TransientResourcePool.js +392 -392
  1704. package/src/shade/renderer/postprocess/bloom/bloom_chain_resolution.js +29 -29
  1705. package/src/shade/renderer/postprocess/bloom/graph_bloom_downsample.js +109 -109
  1706. package/src/shade/renderer/postprocess/bloom/graph_postprocess_bloom.js +155 -155
  1707. package/src/shade/renderer/postprocess/cas/shader_ffx_rcas.js +114 -114
  1708. package/src/shade/renderer/postprocess/dof/DOF_AUTOFOCUS_PARAMS_STRUCT.js +25 -25
  1709. package/src/shade/renderer/postprocess/dof/DOF_FOCUS_STATE_STRUCT.js +23 -23
  1710. package/src/shade/renderer/postprocess/dof/DOF_PRESETS.js +27 -27
  1711. package/src/shade/renderer/postprocess/dof/chunk_dof_coc_band_diameter.js +41 -41
  1712. package/src/shade/renderer/postprocess/dof/chunk_dof_coc_band_radius.js +32 -32
  1713. package/src/shade/renderer/postprocess/dof/chunk_dof_coc_coefficient.js +26 -26
  1714. package/src/shade/renderer/postprocess/dof/compute_dof_autofocus_params.js +64 -64
  1715. package/src/shade/renderer/postprocess/dof/compute_dof_uniform.js +54 -54
  1716. package/src/shade/renderer/postprocess/dof/gather/DOF2_CONFIG.js +91 -91
  1717. package/src/shade/renderer/postprocess/dof/gather/DOF2_PRESETS.js +9 -9
  1718. package/src/shade/renderer/postprocess/dof/gather/DOF2_SETTINGS_STRUCT.js +66 -66
  1719. package/src/shade/renderer/postprocess/dof/gather/DOF2_TEXTURE_FORMAT.js +22 -22
  1720. package/src/shade/renderer/postprocess/dof/gather/DepthOfFieldU.js +292 -292
  1721. package/src/shade/renderer/postprocess/dof/gather/chunk_dof2_coc_to_near_far.js +25 -25
  1722. package/src/shade/renderer/postprocess/dof/gather/chunk_dof2_gather_weight.js +30 -30
  1723. package/src/shade/renderer/postprocess/dof/gather/compute_dof2_uniform.js +54 -54
  1724. package/src/shade/renderer/postprocess/dof/gather/graph_postprocess_dof2.js +194 -194
  1725. package/src/shade/renderer/postprocess/dof/gather/shader_dof2_fill.js +68 -68
  1726. package/src/shade/renderer/postprocess/dof/gather/shader_dof2_gather_far.js +140 -140
  1727. package/src/shade/renderer/postprocess/dof/gather/shader_dof2_gather_near.js +142 -142
  1728. package/src/shade/renderer/postprocess/dof/gather/shader_dof2_recombine.js +99 -99
  1729. package/src/shade/renderer/postprocess/dof/gather/shader_dof2_setup.js +102 -102
  1730. package/src/shade/renderer/postprocess/dof/gather/shader_dof2_tile_dilate.js +75 -75
  1731. package/src/shade/renderer/postprocess/dof/gather/shader_dof2_tile_max.js +73 -73
  1732. package/src/shade/renderer/postprocess/dof/raymarch/DOF_SETTINGS_STRUCT.js +49 -49
  1733. package/src/shade/renderer/postprocess/dof/raymarch/DepthOfField.js +298 -298
  1734. package/src/shade/renderer/postprocess/dof/raymarch/graph_postprocess_dof.js +244 -244
  1735. package/src/shade/renderer/postprocess/dof/raymarch/shader_dof_composite.js +91 -91
  1736. package/src/shade/renderer/postprocess/dof/raymarch/shader_dof_firefly_cleanup.js +61 -61
  1737. package/src/shade/renderer/postprocess/dof/raymarch/shader_dof_prefilter.js +90 -90
  1738. package/src/shade/renderer/postprocess/dof/raymarch/shader_dof_raymarch_compute.js +267 -267
  1739. package/src/shade/renderer/postprocess/dof/raymarch/shader_dof_slice_compute.js +271 -271
  1740. package/src/shade/renderer/postprocess/dof/raymarch/shader_dof_tile_dilate.js +70 -70
  1741. package/src/shade/renderer/postprocess/dof/raymarch/shader_dof_tile_max.js +72 -72
  1742. package/src/shade/renderer/postprocess/dof/shader_dof_autofocus.js +99 -99
  1743. package/src/shade/renderer/postprocess/gtao/generate_magic_square_noise.js +51 -51
  1744. package/src/shade/renderer/postprocess/motion_blur/MotionBlur.js +56 -56
  1745. package/src/shade/renderer/postprocess/upscale-dither/NOTES.md +78 -78
  1746. package/src/shade/renderer/postprocess/upscale-dither/UpscaleDither.js +95 -95
  1747. package/src/shade/renderer/postprocess/upscale-dither/fragment_shader_upscale_dither.js +204 -204
  1748. package/src/shade/renderer/rasterize/bucket/construct_primitive_state.js +58 -58
  1749. package/src/shade/renderer/rasterize/fast/graph_rasterize_scene_fast.js +230 -230
  1750. package/src/shade/renderer/rasterize/native/graph_rasterize_meshes_alpha_tested.js +278 -278
  1751. package/src/shade/renderer/rasterize/native/oit/chunk_material_side_should_draw.js +26 -26
  1752. package/src/shade/renderer/rasterize/native/oit/shader_oit_resolve_moments_ibl.js +178 -178
  1753. package/src/shade/renderer/rasterize/standard/graph_rasterize_partial_opaque.js +235 -235
  1754. package/src/shade/renderer/rasterize/standard/graph_rasterize_remaining_opaque.js +208 -208
  1755. package/src/shade/renderer/rasterize/standard/graph_rasterize_scene.js +206 -206
  1756. package/src/shade/renderer/scene/DynamicMesh.js +70 -70
  1757. package/src/shade/renderer/scene/DynamicMeshBatch.js +90 -90
  1758. package/src/shade/renderer/scene/GPUSceneContext.js +901 -901
  1759. package/src/shade/renderer/scene/SceneNodeBinding.js +56 -56
  1760. package/src/shade/renderer/scene/SkinnedMesh.js +55 -55
  1761. package/src/shade/renderer/scene/TransformAuthority.js +33 -33
  1762. package/src/shade/renderer/scene/optimization/deduplicate_geometries.js +38 -38
  1763. package/src/shade/renderer/scene/optimization/deduplicate_images.js +93 -93
  1764. package/src/shade/renderer/scene/optimization/geometry/internal/anchor_grow_topological.d.ts.map +1 -1
  1765. package/src/shade/renderer/scene/optimization/geometry/internal/anchor_grow_topological.js +12 -3
  1766. package/src/shade/renderer/scene/optimization/geometry/internal/match_refit_validate.js +127 -127
  1767. package/src/shade/renderer/scene/optimization/geometry/internal/match_solve_transform.js +492 -492
  1768. package/src/shade/renderer/scene/optimization/geometry/internal/match_validate_topology.js +3 -3
  1769. package/src/shade/renderer/scene/optimization/geometry/internal/seed_correspondence_from_window.js +3 -3
  1770. package/src/shade/renderer/scene/optimization/optimize_texture_set.js +81 -81
  1771. package/src/shade/renderer/scene/optimization/source_to_sampler2d.js +21 -21
  1772. package/src/shade/renderer/scene/serialization/STANDARD_MATERIAL_SERIALIZED_BYTE_SIZE.js +12 -12
  1773. package/src/shade/renderer/scene/serialization/deserialize_scene.d.ts.map +1 -1
  1774. package/src/shade/renderer/scene/serialization/deserialize_scene.js +0 -2
  1775. package/src/shade/renderer/shader/chunk/geometry/quaternion/dual/chunk_dual_quat_transform_point.js +26 -26
  1776. package/src/shade/renderer/shader/chunk/noise/chunk_interleaved_gradient_noise.js +20 -20
  1777. package/src/shade/renderer/shader/chunk/spherical_harmonics/dering/chunk_sh2_dering_optimize_positive.js +61 -61
  1778. package/src/shade/renderer/shader/chunk/texture/chunk_texture_filter_fxaa_lite.js +225 -225
  1779. package/src/shade/renderer/shader/chunk/texture/dither/chunk_dither_color_8bit_gradient_noise.js +25 -25
  1780. package/src/shade/renderer/shadow/map/DirectionalLightShadowmap.js +384 -384
  1781. package/src/shade/renderer/shadow/map/PointLightShadowmap.js +105 -105
  1782. package/src/shade/renderer/shadow/map/SpotLightShadowmap.js +63 -63
  1783. package/src/shade/renderer/shadow/map/TetrahedronPointLightShadowmap.js +89 -89
  1784. package/src/shade/renderer/shadow/map/shadowmap_update_score.js +232 -232
  1785. package/src/shade/renderer/texture/GPUTextureAllocator.js +85 -85
  1786. package/src/shade/renderer/texture/texture_pool_ops.js +171 -171
  1787. package/src/shade/renderer/texture/virtual/PageTableQuadAllocator.js +253 -253
  1788. package/src/shade/renderer/texture/virtual/README.md +276 -276
  1789. package/src/shade/renderer/texture/virtual/VTPageTable.js +330 -330
  1790. package/src/shade/renderer/texture/virtual/VTPhysicalCache.js +349 -349
  1791. package/src/shade/renderer/texture/virtual/VT_CONSTANTS.js +154 -154
  1792. package/src/shade/renderer/texture/virtual/VT_STACK_INFO_STRUCT.js +20 -20
  1793. package/src/shade/renderer/texture/virtual/VirtualTextureManager.js +1276 -1276
  1794. package/src/shade/renderer/texture/virtual/VirtualTextureStack.js +106 -106
  1795. package/src/shade/renderer/texture/virtual/build_chunk_vt_lookup.js +150 -150
  1796. package/src/shade/renderer/texture/virtual/build_shader_vt_feedback.js +232 -232
  1797. package/src/shade/renderer/texture/virtual/chunk_vt_request_key.js +28 -28
  1798. package/src/shade/renderer/texture/virtual/source/VTSourceImage.js +207 -207
  1799. package/src/shade/renderer/texture/virtual/source/VTSourceProcedural.js +135 -135
  1800. package/src/shade/renderer/texture/virtual/source/VTSourceTiled.js +132 -132
  1801. package/src/shade/renderer/water/GPUWaterRenderer.js +167 -167
  1802. package/src/shade/renderer/water/shader_water.js +246 -246
  1803. package/src/shade/renderer/water/water_height_texture_from_sampler.js +56 -56
  1804. package/src/shade/vitest.setup.mjs +89 -89
  1805. package/src/shade/wgsl/validate_wgsl_source.js +316 -316
  1806. package/src/view/controller/controls/NumericIntervalControl.js +90 -90
  1807. package/src/view/controller/controls/Vector2Control.js +83 -83
  1808. package/src/view/controller/controls/Vector3Control.js +90 -90
  1809. package/src/view/elements/Group.js +56 -56
  1810. package/src/view/elements/drawCheckers.js +33 -33
  1811. package/src/view/elements/windrose/WindRoseDiagram.js +369 -369
  1812. package/src/view/graphics/WebGLContextFailureView.js +76 -76
  1813. package/src/view/layout/DockPanel.js +51 -51
  1814. package/src/view/layout/SplitView.js +365 -365
  1815. package/src/view/layout/show_popup_menu.js +81 -81
  1816. package/src/view/minimap/MinimapCanvasView.js +411 -411
  1817. package/src/view/minimap/MinimapImageCache.js +88 -88
  1818. package/src/view/minimap/MinimapMarkerCollection.d.ts +0 -1
  1819. package/src/view/minimap/MinimapMarkerCollection.d.ts.map +1 -1
  1820. package/src/view/minimap/MinimapMarkerCollection.js +180 -180
  1821. package/src/view/minimap/dom/MinimapCameraView.js +206 -206
  1822. package/src/view/minimap/minimap_focus_area.js +97 -97
  1823. package/editor/process/symbolic/SocketsSymbolicDisplay.js +0 -192
  1824. package/src/core/geom/3d/topology/struct/binary/io/moved_tests.txt +0 -37
  1825. package/src/engine/ecs/attachment/Attachment.d.ts +0 -40
  1826. package/src/engine/ecs/attachment/Attachment.d.ts.map +0 -1
  1827. package/src/engine/ecs/attachment/Attachment.js +0 -57
  1828. package/src/engine/ecs/attachment/AttachmentBinding.d.ts +0 -28
  1829. package/src/engine/ecs/attachment/AttachmentBinding.d.ts.map +0 -1
  1830. package/src/engine/ecs/attachment/AttachmentBinding.js +0 -41
  1831. package/src/engine/ecs/attachment/AttachmentSystem.d.ts +0 -61
  1832. package/src/engine/ecs/attachment/AttachmentSystem.d.ts.map +0 -1
  1833. package/src/engine/ecs/attachment/AttachmentSystem.js +0 -307
  1834. package/src/engine/ecs/attachment/BoneAttachmentBinding.d.ts +0 -27
  1835. package/src/engine/ecs/attachment/BoneAttachmentBinding.d.ts.map +0 -1
  1836. package/src/engine/ecs/attachment/BoneAttachmentBinding.js +0 -69
  1837. package/src/engine/ecs/attachment/TransformAttachmentBinding.d.ts +0 -4
  1838. package/src/engine/ecs/attachment/TransformAttachmentBinding.d.ts.map +0 -1
  1839. package/src/engine/ecs/attachment/TransformAttachmentBinding.js +0 -51
  1840. package/src/engine/ecs/sockets/AttachmentSocket.d.ts +0 -32
  1841. package/src/engine/ecs/sockets/AttachmentSocket.d.ts.map +0 -1
  1842. package/src/engine/ecs/sockets/AttachmentSocket.js +0 -60
  1843. package/src/engine/ecs/sockets/AttachmentSocketType.d.ts +0 -6
  1844. package/src/engine/ecs/sockets/AttachmentSocketType.d.ts.map +0 -1
  1845. package/src/engine/ecs/sockets/AttachmentSocketType.js +0 -8
  1846. package/src/engine/ecs/sockets/AttachmentSockets.d.ts +0 -57
  1847. package/src/engine/ecs/sockets/AttachmentSockets.d.ts.map +0 -1
  1848. package/src/engine/ecs/sockets/AttachmentSockets.js +0 -130
  1849. package/src/engine/ecs/sockets/BoneAttachmentSocket.d.ts +0 -29
  1850. package/src/engine/ecs/sockets/BoneAttachmentSocket.d.ts.map +0 -1
  1851. package/src/engine/ecs/sockets/BoneAttachmentSocket.js +0 -56
  1852. package/src/engine/ecs/sockets/serialization/AttachmentSocketsAssetLoader.d.ts +0 -6
  1853. package/src/engine/ecs/sockets/serialization/AttachmentSocketsAssetLoader.d.ts.map +0 -1
  1854. package/src/engine/ecs/sockets/serialization/AttachmentSocketsAssetLoader.js +0 -19
  1855. package/src/shade/renderer/animation/_dump_resolve.d.mts +0 -2
  1856. package/src/shade/renderer/animation/_dump_resolve.d.mts.map +0 -1
  1857. package/src/shade/renderer/animation/_dump_resolve.mjs +0 -5
  1858. package/src/shade/renderer/scene/optimization/geometry/internal/bt_face_loop_helpers.d.ts +0 -32
  1859. package/src/shade/renderer/scene/optimization/geometry/internal/bt_face_loop_helpers.d.ts.map +0 -1
  1860. package/src/shade/renderer/scene/optimization/geometry/internal/bt_face_loop_helpers.js +0 -77
  1861. package/src/shade/renderer/scene/optimization/geometry/internal/bt_find_edge_between.d.ts +0 -12
  1862. package/src/shade/renderer/scene/optimization/geometry/internal/bt_find_edge_between.d.ts.map +0 -1
  1863. package/src/shade/renderer/scene/optimization/geometry/internal/bt_find_edge_between.js +0 -35
  1864. package/src/shade/renderer/scene/serialization/linear_to_pq.d.ts +0 -2
  1865. package/src/shade/renderer/scene/serialization/linear_to_pq.d.ts.map +0 -1
  1866. package/src/shade/renderer/scene/serialization/linear_to_pq.js +0 -14
  1867. package/src/shade/renderer/scene/serialization/pq_to_linear.d.ts +0 -9
  1868. package/src/shade/renderer/scene/serialization/pq_to_linear.d.ts.map +0 -1
  1869. package/src/shade/renderer/scene/serialization/pq_to_linear.js +0 -30
@@ -1,793 +1,793 @@
1
- # `EXT_meshopt_compression` / `KHR_meshopt_compression` — implementation plan
2
-
3
- Status: plan. Written 2026-08-20.
4
-
5
- Scope: decode side of both extensions.
6
-
7
- - `EXT_meshopt_compression` — ratified, Vendor.
8
- <https://github.com/KhronosGroup/glTF/tree/main/extensions/2.0/Vendor/EXT_meshopt_compression>
9
- - `KHR_meshopt_compression` — ratified, Khronos, merged 2026-01-23 (PR #2517).
10
- <https://github.com/KhronosGroup/glTF/tree/main/extensions/2.0/Khronos/KHR_meshopt_compression>
11
-
12
- Reference encoder/decoder: <https://github.com/zeux/meshoptimizer>. Consulted for questions the
13
- specification text leaves ambiguous; **not vendored and not transcribed** — no new dependency, and
14
- the bitstream below is implemented from the two specifications.
15
-
16
- ## 1. What these extensions are, and why that shapes the split
17
-
18
- Neither is a geometry extension. Both are *bufferView* extensions: a bufferView declares that its
19
- bytes are produced by running a decoder over a byte range of some other buffer. Nothing about the
20
- decode depends on what the bufferView is later read as — vertex attributes, index data, morph
21
- deltas, animation keyframes and `EXT_mesh_gpu_instancing` transforms all go through the same three
22
- modes and (now) five filters.
23
-
24
- That is the seam. Everything except roughly two dozen lines is a **byte-array in, byte-array out**
25
- codec with no knowledge of glTF at all:
26
-
27
- ```
28
- src/core/binary/meshopt/ pure codec — bytes in, bytes out.
29
- ^ No glTF, no geometry, no engine.
30
- | called by
31
- src/.../gltf/ext/meshopt/ one bufferView's worth of meshopt: read the
32
- ^ extension object, check it, return the bytes.
33
- | called through GltfBufferViewExtension by
34
- src/.../gltf/ext/ the generic bufferView-extension layer — which
35
- ^ extension claims a view, and what becomes of what
36
- | it produced. Names no codec.
37
- | called by
38
- src/shade/renderer/loader/gltf/tiny-gltf.js one call, after buffers resolve. Names no
39
- extension at all.
40
- ```
41
-
42
- `core/binary` is the codec's right home: it is where meep already keeps byte-level codecs
43
- (`base64/`, `base58/`, `half_to_float_uint16`, `BinaryBuffer`'s LEB128 `readUintVar`). The codec
44
- imports nothing outside `core/`, so it is usable from a worker, a tool, or the USD loader without
45
- dragging Shade in.
46
-
47
- ### 1.1 KHR is EXT plus three things
48
-
49
- The two extensions share a JSON shape, a `bufferView`/`buffer` model, fallback buffers, and modes
50
- 1 and 2 byte for byte. KHR adds:
51
-
52
- 1. **Attribute codec version 1** (header `0xa1`). A genuinely different bitstream for mode 0: a
53
- per-block control header, four control modes, an extra 1-bit sentinel encoding, and three
54
- *channel* modes that widen the delta from 8-bit to 16-bit or to a rotated 32-bit XOR.
55
- Version 0 (`0xa0`) remains legal under KHR and is bit-identical to EXT.
56
- 2. **Filter 4, `COLOR`** — YCoCg, `byteStride` 4 or 8.
57
- 3. One extra validity rule (`ATTRIBUTES` requires `byteStride >= 4`) and the constraint that a
58
- bufferView must not carry both extensions.
59
-
60
- So there is one codec that decodes everything, and a glTF layer that enforces the per-name subset:
61
- a `0xa1` stream or a `COLOR` filter under the `EXT_` name is an invalid file and is rejected.
62
-
63
- ## 2. Modules
64
-
65
- ### 2.1 `src/core/binary/meshopt/` — the codec
66
-
67
- | File | Export |
68
- |:--|:--|
69
- | `MeshoptCompressionMode.js` | `@enum` — `Attributes: 0`, `Triangles: 1`, `Indices: 2` |
70
- | `MeshoptCompressionFilter.js` | `@enum` — `None: 0`, `Octahedral: 1`, `Quaternion: 2`, `Exponential: 3`, `Color: 4` |
71
- | `MESHOPT_GROUP_SIZE.js` | the group size, and the 24-byte bound a group read stays inside |
72
- | `meshopt_decode_byte_group.js` | one group of 16 byte-deltas at a given sentinel width |
73
- | `meshopt_decode_data_block.js` | one "data block": header bits + its groups, for one byte position |
74
- | `meshopt_decode_vertex_buffer.js` | mode 0, versions 0 and 1 |
75
- | `meshopt_decode_index_buffer.js` | mode 1 |
76
- | `meshopt_decode_index_sequence.js` | mode 2 |
77
- | `meshopt_decode_filter_octahedral.js` | filter 1, in place |
78
- | `meshopt_decode_filter_quaternion.js` | filter 2, in place |
79
- | `meshopt_decode_filter_exponential.js` | filter 3, in place |
80
- | `meshopt_decode_filter_color.js` | filter 4, in place |
81
- | `meshopt_decode.js` | dispatch: mode, then filter |
82
- | `meshopt_read_uint_var.js` | bounded LEB128 over a `Uint8Array` |
83
- | `__meshopt_test_streams.js` | test-only encoders, shared by the codec specs and the glTF fixtures |
84
-
85
- Signatures:
86
-
87
- ```js
88
- meshopt_decode_vertex_buffer(destination, count, byte_stride, source)
89
- meshopt_decode_index_buffer(destination, index_count, index_size, source)
90
- meshopt_decode_index_sequence(destination, index_count, index_size, source)
91
- meshopt_decode_filter_*(destination, count, byte_stride)
92
- meshopt_decode(destination, count, byte_stride, mode, filter, source)
93
- ```
94
-
95
- `destination` and `source` are `Uint8Array` throughout — the codec never assumes an aligned
96
- `ArrayBuffer` offset, because a compressed source range in a glTF is only byte-aligned. Index modes
97
- and filters build their typed views internally from `index_size` / `byte_stride`.
98
-
99
- Two additions outside the package, both genuinely generic and both matching meep's existing naming:
100
-
101
- - `src/core/math/round_half_away_from_zero.js` — `Math.round` breaks ties toward `+Infinity`
102
- (`Math.round(-2.5) === -2`). Four of the five filters specify `round()` on a signed symmetric
103
- quantity and round half away from zero. Sits beside the existing `round_up.js`.
104
- - nothing else: `msb_32` (`core/binary`) is already `findMSB` including its `-1` for zero, `exp2`
105
- and `copysign` (`core/math`) already exist, and `decode_octahedron_to_unit`
106
- (`core/geom/3d/normal/octahedron`) is reused by filter 1 — see §4.1.
107
-
108
- ### 2.2 `src/shade/renderer/loader/gltf/ext/` — bufferView extensions, generically
109
-
110
- A bufferView extension says "these bytes are not in the buffer I point at; run this to get them".
111
- Meshopt is two of them; a future codec would be a third. The parser should know that shape and
112
- nothing else, so the layer is split in two — see §9 for why this is not how it was first written.
113
-
114
- | File | What it is |
115
- |:--|:--|
116
- | `GltfBufferViewExtension.js` | the contract one extension implements: a `name`, `decode()`, and whether it declares placeholder buffers |
117
- | `GltfBufferViewExtensionSet.js` | which extensions a parser honours, and `claim(view)` — the *only* thing that decides whether anything happens |
118
- | `gltf_apply_buffer_view_extensions.js` | the walk: claim, delegate, append the buffer, replace the descriptor. Identical for every extension |
119
- | `gltf_buffer_view_extensions.js` | `GLTF_BUFFER_VIEW_EXTENSIONS`, the set the parser uses by default |
120
- | `meshopt/MeshoptBufferViewExtension.js` | one class, two instances: `EXT_MESHOPT_COMPRESSION`, `KHR_MESHOPT_COMPRESSION` |
121
-
122
- The walker:
123
-
124
- 1. returns a **new** `bufferViews` array — claimed entries are replaced by fresh descriptors,
125
- unclaimed entries pass through **by reference**,
126
- 2. **appends** each decoded buffer to `buffers`, pointing the new descriptor at it with
127
- `byteOffset: 0`,
128
- 3. keeps `byteStride`, `target` and everything else from the parent, so accessor reads are unchanged,
129
- 4. refuses a decoder that answered with the wrong number of bytes, whichever decoder it was.
130
-
131
- Returning a new array rather than mutating the old descriptors is load-bearing, not taste — §6.3.
132
-
133
- The difference between the two meshopt instances is two fields and no branches: which filter names
134
- the extension defines, and the newest codec version each *mode* may carry. Per mode because both
135
- index codecs' version 1 is legal under either extension; it is only the attribute codec that the
136
- vendor extension pins at 0.
137
-
138
- ### 2.3 `tiny-gltf.js` — the call site
139
-
140
- Three edits, all in `loadFromJson`:
141
-
142
- - **`~L422-448`, buffer resolution.** Today a buffer with no `uri` outside the GLB fast path is fed
143
- to `resolveUri(undefined, baseUrl)` and fetched as `<baseUrl>undefined`. That is exactly the shape
144
- of a meshopt *fallback* buffer (`{ "byteLength": N }`, no URI), so today a `gltfpack`-produced
145
- `.gltf` cannot load at all. A buffer that is marked `fallback` or has no `uri` resolves to a
146
- zero-length `ArrayBuffer` instead of a request (§6.8). Also: the GLB branch currently loads *only*
147
- the binary chunk and ignores `buffers[1..n]`, which is where both extensions put the placeholder —
148
- the branch becomes "buffer 0 is the chunk, the rest resolve normally".
149
- - **`~L524-534`, an image sourced from a bufferView.** Throw if that bufferView is compressed. The
150
- combination is legal in the abstract and pointless in practice (the payload is already a PNG or a
151
- JPEG); the alternative to throwing is handing `createImageBitmap` the fallback buffer's bytes,
152
- which is a silent wrong answer.
153
- - **`~L557`, after `await Promise.all(pendingBuffers)`.** One call to
154
- `gltf_apply_buffer_view_extensions` before `json.buffers` and `json.bufferViews` are published.
155
-
156
- The parser names no extension: it asks `this.bufferViewExtensions` — a public field, defaulted to the
157
- standard set and replaceable — and the set is the one place that knows what is implemented.
158
-
159
- **Nothing in `load_gltf.js` changes.** It reads `gltf.bufferViews` / `gltf.buffers` inside
160
- `process()`, which runs after `loadFromJson` has returned, so it sees decoded views and never learns
161
- either extension exists. That is the point of doing this at the bufferView layer.
162
-
163
- ## 3. The bitstream, as implemented
164
-
165
- Written from the two specifications' Appendix A/B. Notes marked ⚠ are places where a plausible
166
- reading is wrong.
167
-
168
- ### 3.1 Mode 0 — attributes
169
-
170
- ```
171
- header 1 byte: 0xa0 (version 0) or 0xa1 (version 1, KHR only)
172
- blocks one or more attribute blocks
173
- tail padding zero bytes
174
- tail block baseline element (byte_stride bytes)
175
- channel modes (byte_stride / 4 bytes, version 1 only)
176
- ```
177
-
178
- ⚠ **The padding comes BEFORE the tail block; the tail block is flush against the end of the
179
- stream.** So the baseline element starts at `byteLength - tail_size`, where
180
-
181
- ```
182
- tail_size = byte_stride + (version === 1 ? byte_stride / 4 : 0)
183
- tail_size_pad = max(tail_size, version === 1 ? 24 : 32)
184
- ```
185
-
186
- and the decoder must have consumed exactly `byteLength - tail_size_pad` bytes when the blocks are
187
- done. EXT's wording — "a baseline element stored verbatim, padded to 32 bytes" — reads equally well
188
- as element-then-padding, which for any stride below 32 puts the baseline in the wrong place and
189
- decodes garbage. KHR's rewording ("Tail padding, which pads the size of the *subsequent* tail
190
- block…") settles it, and the reference decoder agrees: it takes the baseline from
191
- `data_end - tail_size`, with `tail_size` **unpadded**, while validating the remainder against
192
- `tail_size_pad`. Two different quantities that coincide only when `byte_stride >= 32`.
193
-
194
- Block loop, identical in both versions:
195
-
196
- ```
197
- max_block_elements = min(floor(8192 / byte_stride) & ~15, 256)
198
- block_elements = min(remaining, max_block_elements)
199
- group_count = ceil(block_elements / 16)
200
- ```
201
-
202
- ⚠ `8192 / byte_stride` is integer division — `floor` before the mask. With `byte_stride <= 256` the
203
- result is never below 32, so the loop always advances.
204
-
205
- A block is, in order:
206
-
207
- - a **control header** of `byte_stride / 4` bytes — **version 1 only**,
208
- - `byte_stride` **data blocks**, one per byte position `k` of the element.
209
-
210
- The control header packs a 2-bit *control mode* per byte position, low bits first:
211
- `(c0 << 0) | (c1 << 2) | (c2 << 4) | (c3 << 6)`, one byte per aligned group of four byte positions.
212
- The control mode selects what the data block for that byte position looks like:
213
-
214
- | control mode | data block |
215
- |:--|:--|
216
- | 0 | header bits, group encodings `{zero, 1-bit, 2-bit, 4-bit}` |
217
- | 1 | header bits, group encodings `{1-bit, 2-bit, 4-bit, raw}` |
218
- | 2 | nothing at all — every delta byte is 0, no header bits, no bytes consumed |
219
- | 3 | literal: `group_count * 16` delta bytes, no header bits |
220
-
221
- Version 0 has no control header and behaves as a fixed table
222
- `{zero, 2-bit, 4-bit, raw}` for every byte position.
223
-
224
- Where header bits are present they are `ceil(group_count / 4)` bytes, 2 bits per group, packed
225
- **low bits first**: `(g0 << 0) | (g1 << 2) | (g2 << 4) | (g3 << 6)`. Group encodings:
226
-
227
- | encoding | packed bytes | sentinel | total |
228
- |:--|:--|:--|:--|
229
- | zero | 0 | — | 0 |
230
- | 1-bit | 2 | `1` | 2..18 |
231
- | 2-bit | 4 | `3` | 4..20 |
232
- | 4-bit | 8 | `15` | 8..24 |
233
- | raw | 16 | — | 16 |
234
-
235
- ⚠ Bit order inside a packed byte is **not uniform**. 2-bit and 4-bit run high bits first —
236
- `(d3 << 0) | (d2 << 2) | (d1 << 4) | (d0 << 6)` and `(d1 << 0) | (d0 << 4)` — while **1-bit runs low
237
- bits first**, `(d0 << 0) | (d1 << 1) | … | (d7 << 7)`. The spec says so explicitly (it is there to
238
- let SIMD implementations reuse a lookup table); it is not a transcription slip.
239
-
240
- A delta equal to the sentinel means the real value is outside the bit range and is taken as a whole
241
- byte from the run that follows the packed bytes, in order of appearance.
242
-
243
- The delta bytes so recovered are then turned into values by the **channel mode**. Channels are
244
- aligned groups of four byte positions; version 1 stores one mode byte per channel in the tail, and
245
- version 0 behaves as though every channel were mode 0.
246
-
247
- | channel mode | reconstruction |
248
- |:--|:--|
249
- | 0 | per byte: `v = (unzigzag8(d) + prev) & 0xff` |
250
- | 1 | per aligned 2 bytes, little-endian: `v = (unzigzag16(d) + prev) & 0xffff` |
251
- | 2 | per aligned 4 bytes, little-endian: `v = rotl32(d, r) ^ prev` |
252
-
253
- `r` is the **high** 4 bits of the channel mode byte and applies only to mode 2. ⚠ The decoder
254
- rotates **left by `r`** — the spec's `rotate(v, r) = (v << r) | (v >> ((32 - r) & 31))` is the
255
- decode direction, despite the surrounding sentence describing how the encoder produced the delta.
256
- A mode byte whose low nibble is 3 or above, or whose high nibble is non-zero for mode 0 or 1, makes
257
- the stream invalid.
258
-
259
- Groups always decode sixteen elements; anything past `block_elements` is discarded and does not
260
- advance the delta chain. Each block ends by taking its **last decoded element** as the next block's
261
- baseline.
262
-
263
- The specification's own worked example is the acceptance test for the group decoder (§5.1).
264
-
265
- ### 3.2 Mode 1 — triangles
266
-
267
- ```
268
- header 1 byte, (h & 0xf0) == 0xe0; version = h & 0x0f, 0 or 1 (both specs pin 0xe1)
269
- codes index_count / 3 bytes, one per triangle
270
- data variable, immediately after the codes
271
- codeaux the last 16 bytes
272
- ```
273
-
274
- State: `next` (high-watermark, 0), `last` (0), a 16-entry edge FIFO and a 16-entry vertex FIFO, both
275
- filled with `0xFFFFFFFF`. `data` must end exactly at the start of `codeaux` — that equality is the
276
- stream's own checksum.
277
-
278
- `fec_max` is 13 for version 1 and 15 for version 0; it is what makes codes `0xXd`/`0xXe` mean
279
- `last - 1` / `last + 1` rather than two more FIFO slots. Reading it from the header rather than
280
- hard-coding 13 is why both versions decode correctly.
281
-
282
- ⚠ The two branches index the vertex FIFO differently: the `code < 0xf0` path reads
283
- `(offset - 1 - fec) & 15`, the `0xf0..0xff` paths read `(offset - feb) & 15`. This follows from the
284
- spec's own wording ("index Y" versus "index Z-1") and is not a slip.
285
-
286
- ⚠ A conditional push writes the value at `offset` and then does not advance `offset`. Skipping the
287
- write as well is *not* equivalent: every later FIFO read at distance `d` would see what belongs at
288
- `d - 1`. Two tests reach back past a vertex that was not pushed, because until something does the
289
- difference is invisible.
290
-
291
- ⚠ The explicit indices in the `0xfe`/`0xff` branch are read in the order a, b, c, and `last` chains
292
- through them, so that order is load-bearing. Their position relative to the `next++` allocations is
293
- *not*: an index is either fresh or explicit, never both, so the two passes do not interfere. (The
294
- plan asserted otherwise; see §8.)
295
-
296
- ### 3.3 Mode 2 — indices
297
-
298
- ```
299
- header 1 byte, (h & 0xf0) == 0xd0 (both specs pin 0xd1)
300
- deltas one LEB128 varint per index
301
- tail 4 reserved bytes
302
- ```
303
-
304
- `v & 1` selects one of two running baselines; `v >> 1` is a zigzag delta applied to it. Two
305
- baselines rather than one is what lets an encoder splice two monotonic runs (strips, line lists)
306
- cheaply. Again `data` must land exactly on the 4-byte tail.
307
-
308
- ### 3.4 Filters
309
-
310
- All five are in place over the already-decoded bufferView, `count` elements of `byte_stride` bytes.
311
-
312
- - **Octahedral** — `byte_stride` 4 → `Int8Array`, 8 → `Int16Array`. Components 0 and 1 are the
313
- octahedral pair, component 2 encodes 1.0 at the element's own precision `K`, component 3 passes
314
- through untouched. Output scaled by `max` = 127 or 32767. Reuses meep's own
315
- `decode_octahedron_to_unit` — see §4.1.
316
- - **Quaternion** — `byte_stride` 8, `Int16Array`. `one = input[3] | 3`,
317
- `max_component = input[3] & 3`; outputs land at `(max_component + 1..3) & 3` for x/y/z and
318
- `(max_component + 0) & 3` for w.
319
- ⚠ `input[3]` is read for *both* purposes before any output is written — one of the four writes
320
- lands on it.
321
- ⚠ The radicand `1 - x² - y² - z²` is clamped at 0. meep already learned this in
322
- `quat3_decode_from_uint32`; a NaN quaternion out of a loader poisons every transform downstream.
323
- - **Exponential** — `byte_stride` divisible by 4. Each 32-bit word is `e = word >> 24` (signed),
324
- `m = (word << 8) >> 8` (signed); the result `2^e · m` is written back as a float32. `e` is
325
- spec-bounded to [-100, 100] and `|m| < 2^23`, so the product is exact in float32 and computing it
326
- in JS doubles and storing through a `Float32Array` is bit-identical to the reference's
327
- build-the-exponent-and-multiply.
328
- - **Color** (KHR only) — `byte_stride` 4 → `Uint8Array`, 8 → `Uint16Array`. YCoCg:
329
-
330
- ```
331
- as = (1 << (msb_32(input[3]) + 1)) - 1
332
- r = input[0] + int(input[1]) - int(input[2])
333
- g = input[0] + int(input[2])
334
- b = input[0] - int(input[1]) - int(input[2])
335
- a = input[3] & (as >> 1); a = (a << 1) | (a & 1)
336
- output = round(component * (UINTN_MAX / as))
337
- ```
338
-
339
- ⚠ Components 0 and 3 are **unsigned**, components 1 and 2 are **signed**, in the same element.
340
- `msb_32` already returns `-1` for zero, so a malformed `input[3] === 0` yields `as = 0`, an
341
- infinite scale, and finite garbage bytes once stored through a `Uint8Array` — defined, ugly, and
342
- not worth a guard (§6.9).
343
-
344
- ## 4. What is reused, and what deliberately is not
345
-
346
- ### 4.1 Reused
347
-
348
- - **`decode_octahedron_to_unit`** (`core/geom/3d/normal/octahedron`) implements filter 1's core.
349
- meep's fold is the same arithmetic as the spec's `copysign` form (`x + t·sign(x)` either way) and
350
- it renormalises, but it is written **Y-up**: meep's `(x, y, z)` is the spec's `(x, z, y)`. The
351
- swizzle is the whole of the adaptation, and a spec checks the composition against the
352
- specification's formula directly rather than against meep's.
353
- - **`msb_32`** (`core/binary`) is `findMSB` for filter 4, `-1`-on-zero included.
354
- - **`exp2`** and **`copysign`** (`core/math`).
355
- - **`gltf_test_fixtures.js`** (`engine/asset/loaders`) already builds a one-triangle glTF and GLB by
356
- hand; the end-to-end fixture extends it rather than introducing a second fixture vocabulary.
357
-
358
- ### 4.2 Deliberately not
359
-
360
- - **`BinaryBuffer.readUintVar`** is the same LEB128 scheme and reusing it would honour "use meep's
361
- existing code". It is still wrong here: it reads through a `DataView` bound to a whole
362
- `ArrayBuffer` where the compressed range is a slice, it is unbounded on malformed input where the
363
- reference stops at five bytes, and `value |= (b & 0x7f) << shift` turns negative once `shift`
364
- reaches 28 — which is inside the range mode 1 and mode 2 indices legitimately use. The deviation
365
- and its three reasons are documented where `meshopt_read_uint_var` is defined, so the next reader
366
- does not "fix" the duplication.
367
- - **`quat3_decode_from_uint32`** is a different packing — 10-bit, fixed range, dropped component
368
- inserted *at* index `max` — where filter 2 is 16-bit, variable precision and *cyclic*. Documented
369
- as deliberately not reused rather than left to look overlooked.
370
- - **`Vector3` / `Quaternion` / `vec3` helpers.** The filters run over hundreds of thousands of
371
- elements through typed-array views; routing each through an object allocation would be the one
372
- place in this feature where reuse costs more than it is worth. Scalars, module-static scratch.
373
-
374
- ## 5. Tests
375
-
376
- Every module gets a `.spec.js` beside it. House rules apply: black-box, no mocks, and no rejection
377
- tests against `assert.*` (stripped in production) — everything that must reject bad *file* input
378
- does so with a real `throw`, and those are tested.
379
-
380
- ### 5.1 The independent oracle
381
-
382
- The single most valuable test is free: **Appendix A of both specifications contains a worked
383
- example** of the 4-bit sentinel encoding —
384
-
385
- ```
386
- 0x17 0x5f 0xf0 0xbc 0x77 0xa9 0x21 0x00 0x34 0xb5
387
- -> -1 -4 -3 26 -91 0 -6 6 -4 -4 5 -5 1 -1 0 0
388
- ```
389
-
390
- — which pins the packed-nibble order, the sentinel value, the sentinel run's position and its
391
- ordering, and the zigzag, all at once, from a document that is not this implementation. It is the
392
- first test written, and the group decoder is developed against it. (Checked by hand while writing
393
- this plan: the nibbles are `1 7 5 S S 0 11 12 7 7 10 9 2 1 0 0`, the two sentinels take `0x34` and
394
- `0xb5`, and de-zigzagging reproduces the stated line exactly.)
395
-
396
- ### 5.2 Hand-derived vectors
397
-
398
- The remaining streams are small enough to author by hand from the spec, with the derivation in the
399
- test as a comment. Worked out in advance so this plan can be checked before any code exists:
400
-
401
- - **mode 0 v0, all-zero groups.** `byte_stride` 4, `count` 3 → one block, one group, four data
402
- blocks each a single `0x00` header byte: `[0xa0, 0x00, 0x00, 0x00, 0x00]` then 28 zero bytes then
403
- the 4 baseline bytes. All three elements equal the baseline. This is the test that fails if the
404
- tail is read from the wrong end (§3.1 ⚠) — under the element-then-padding reading the baseline
405
- comes out `0,0,0,0`.
406
- - **mode 0 v1, control modes.** The same shape with header `0xa1`, one control byte, and one tail
407
- channel-mode byte: control mode 2 (nothing stored) on every byte position; then control mode 3
408
- (literal) with hand-written delta bytes; then control mode 0 with a 1-bit sentinel group, which
409
- is the only place the low-bits-first packing is exercised.
410
- - **mode 0 v1, channel modes 1 and 2.** `byte_stride` 4, one channel: a 16-bit delta pair that
411
- wraps modulo 65536, and a rotated XOR whose `r` is non-zero — the two places where a
412
- left-versus-right rotation or a byte-order slip is invisible at `r = 0`.
413
- - **mode 1, one triangle.** `[0xe1, 0xf0]` + 16 `codeaux` bytes with `codeaux[0] = 0x00` →
414
- `feb = fec = 0` → `a, b, c = next++, next++, next++` → `[0, 1, 2]`. 18 bytes, `1 + 6/3 + 16`;
415
- `data` lands exactly on `codeaux`.
416
- - **mode 1, two triangles sharing an edge.** Append code `0x00`: after triangle one the edge FIFO
417
- holds `(1,0), (2,1), (0,2)` at offset 3, so `fe = 0` reads `(0, 2)` and `fec = 0` takes
418
- `c = next = 3` → `[0, 1, 2, 0, 2, 3]`. This is the test that fails if the edge-FIFO push order is
419
- wrong.
420
- - **mode 1, the `0xXf` and `0xfe`/`0xff` paths** — explicit indices through `decodeIndex`, and the
421
- `codeaux == 0` restart that resets `next`.
422
- - **mode 2.** `[0xd1, 0x14, 0x08, 0, 0, 0, 0]` → `0x14 = 20`: baseline 0, zigzag 10, delta +5 → `5`;
423
- `0x08 = 8`: baseline 0, zigzag 4, delta +2 → `7`. Output `[5, 7]`. Plus a vector that alternates
424
- the baseline bit, which is the whole reason mode 2 exists.
425
- - **filters.** Values computed from each spec's own pseudo-code in the test, not from the
426
- implementation: unit ±X/±Y/±Z normals through octahedral at both strides, identity and
427
- each-of-four-`max_component` quaternions, exponential words with negative exponents, negative
428
- mantissas and `m = 0`, and for colour a grey, a saturated primary and a partial alpha at both
429
- strides and at a `K` below the component width.
430
- - **rejection.** Truncated streams, wrong header bytes, a `0xa1` stream offered under the `EXT_`
431
- name, a `COLOR` filter under the `EXT_` name, an invalid channel mode byte, and a mode 1 stream
432
- whose `data` does not land on `codeaux`.
433
-
434
- ### 5.3 Round trip
435
-
436
- A **test-only** mode 0 encoder in the spec file (raw-byte groups only, the simplest legal encoding)
437
- gives a randomised round trip over strides 4/8/12/16/64 and counts that straddle the 16-element
438
- group and 256-element block boundaries. It is deliberately *secondary*: it shares the layout
439
- assumptions of the decoder, so a shared misreading passes. Its job is exercising the block and group
440
- loop bounds, not proving the format. §5.1 and §5.2 prove the format.
441
-
442
- ### 5.4 End to end
443
-
444
- `gltf_test_fixtures.js` gains `build_meshopt_triangle_gltf_json(extension_name, buffer_uri, options)`
445
- and a matching `_glb`: the one-triangle model with its four bufferViews compressed (positions, normals and
446
- uvs in mode 0, indices in mode 1) by the fixture's own minimal encoder, a `fallback: true`
447
- placeholder buffer with no URI, and `extensionsUsed` / `extensionsRequired` set. A spec then loads
448
- it through the real `AssetManager` and `GLTFSceneBundleAssetLoader` — as
449
- `GLTFSceneBundleAssetLoader.spec.js` already does — under **both** extension names, and asserts the
450
- resulting bundle's geometry equals the uncompressed fixture's. That covers the fallback-buffer path,
451
- the bufferView rewrite, and the fact that `load_gltf.js` needs no changes.
452
-
453
- That file, though, is one the *vendor* extension could have described just as well — the Khronos name
454
- on it and nothing else. `options` makes it a file only KHR defines: attribute streams at codec
455
- version 1 carrying a channel mode each (a rotated exclusive-or over the positions, byte deltas over
456
- the normals, 16-bit deltas over the texture coordinates), and a `COLOR`-filtered `COLOR_0` the mesh
457
- reader maps to `StandardAttributes.Color`. Each of the two is served on its own as well as together,
458
- so that a test watching the vendor extension refuse one is refusing *that* one — asserting against a
459
- file carrying both passes on either constraint, and then removing one of them from the vendor
460
- extension goes unnoticed.
461
-
462
- ### 5.5 What none of this covers
463
-
464
- No test here decodes a stream produced by `gltfpack`. Every byte under test was authored from a
465
- specification by me or by a fixture encoder I also wrote; a misreading shared between them survives.
466
- §5.1 is the only genuinely external oracle, and it covers one group encoding of one mode.
467
-
468
- **Recommendation to the sponsor: drop one `gltfpack -noq -cc` output (and one `-cc -vv` for codec
469
- version 1) into the repo, and add a golden test that decodes it and checks every `POSITION`
470
- accessor's values against that accessor's declared `min`/`max`, and every index against the vertex
471
- count.** Those bounds are written by the encoder, are not derivable from the compressed bytes, and
472
- would catch a systematic misreading immediately. Left out of this plan because it needs files only
473
- the sponsor can supply.
474
-
475
- ## 6. Adversarial review of this plan
476
-
477
- Each item is a way this plan is wrong or insufficient, and what it changes.
478
-
479
- ### 6.1 The tail was read from the wrong end
480
-
481
- The first draft of this plan had the baseline element at the **start** of a `max(stride, 32)`-byte
482
- tail, from EXT's "a baseline element stored verbatim, padded to 32 bytes", and cited a reading of
483
- the reference decoder that appeared to confirm it. Both were wrong, and for any `byteStride` below
484
- 32 — which is every attribute meshopt is actually used on — it decodes an entire model to garbage
485
- while every unit test written from the same misreading passes.
486
-
487
- What caught it was reading KHR, which reworded the same clause to "Tail padding, which pads the size
488
- of the *subsequent* tail block…" and added a second item to the tail block that forces the question.
489
- The corroborating detail is that the reference keeps two quantities, `tail_size` and
490
- `tail_size_pad`, uses the **unpadded** one to locate the baseline and the **padded** one to validate
491
- the remainder — a distinction that has no meaning at all under the wrong reading.
492
-
493
- **Changes:** §3.1 states both quantities and where each is used; §5.2's first vector is chosen
494
- specifically to discriminate them; and the general lesson is written into §6.11.
495
-
496
- ### 6.2 `Uint8Array` out-of-bounds reads return `undefined`, and `undefined & 0xff` is `0`
497
-
498
- The worst failure mode in the design. JavaScript does not fault on a typed-array read past the end —
499
- it yields `undefined`, and every bitwise operator coerces that to `0`. A truncated or malformed
500
- stream therefore decodes to *plausible-looking zeros* rather than an error, and the model loads
501
- wrong instead of failing. The reference is bounds-checked at every group and every index read for
502
- exactly this reason.
503
-
504
- **Change:** explicit bounds checks are not optional, and are not `assert` (stripped in production —
505
- this input is a file, not a caller). Real `throw` at the header, at each byte group against the
506
- 24-byte decode limit, at each literal and control-header read, at each index varint, and at the
507
- final data-lands-on-the-tail equality in all three modes. Reject-a-truncated-stream cases added to
508
- §5.2.
509
-
510
- ### 6.3 Mutating the bufferView descriptors races the image loader
511
-
512
- The first draft rewrote `json.bufferViews[i]` in place. `loadFromJson` builds the image promises
513
- *before* buffers resolve, and each one closes over its `bufferView` object and reads `.byteOffset` /
514
- `.byteLength` inside a `.then()` that runs *after* the rewrite. Mutating in place changes what an
515
- already-scheduled image read sees, from a different code path, with no visible link between the two.
516
-
517
- **Change:** §2.2 returns a new array of new descriptors and leaves the originals untouched. The
518
- image path keeps reading exactly what it reads today, whatever order the promises settle in. This is
519
- the reason for a design choice that otherwise looks like needless allocation, and it is recorded
520
- where the code lives.
521
-
522
- ### 6.4 `Math.round` is not the spec's `round`
523
-
524
- `Math.round(-2.5)` is `-2`. The filters round signed symmetric quantities and the reference rounds
525
- half away from zero. Half a quantisation step on normals is invisible in a screenshot and visible in
526
- a diff against any other decoder — exactly the kind of drift nobody attributes correctly six months
527
- later.
528
-
529
- **Change:** `round_half_away_from_zero` in `core/math`, used by every filter, with the asymmetry
530
- named in its JSDoc.
531
-
532
- ### 6.5 A green suite here does not mean a `gltfpack` file loads
533
-
534
- Two things sit between this feature and a real compressed asset, and neither is in scope:
535
-
536
- - **`KHR_mesh_quantization`.** `gltfpack`'s default output quantises as well as compresses, and meep
537
- does not implement that extension. Worse, quantised attributes are padded — a `VEC3`/`SHORT`
538
- position gets `byteStride` 8, not 6 — and `load_gltf.js` rejects any bufferView whose `byteStride`
539
- differs from `componentSize × componentCount` with `'Interleaved attributes are not supported'`.
540
- So a default `gltfpack` file will fail *after* decompressing correctly.
541
- - **Interleaved attributes**, same rejection, for the same reason.
542
-
543
- `gltfpack -noq -cc` produces meshopt-compressed, non-quantised, non-interleaved output, and that is
544
- the configuration this feature makes work. Stated here rather than discovered later; picking up
545
- `KHR_mesh_quantization` is separate work and is not silently folded into this one.
546
-
547
- ### 6.6 Pure JS is roughly an order of magnitude off the reference
548
-
549
- The reference reaches ~1 GB/s with WebAssembly SIMD. This will not, and the extension exists partly
550
- *because* decode is meant to be nearly free. Decompression is synchronous inside `loadFromJson`, so
551
- it lands on whichever thread is parsing — the main thread for a foreground load.
552
-
553
- Accepted, not designed around: the alternative is a WASM dependency, which the brief excludes.
554
- Mitigated by the shape the reference already uses — a module-static 8 KiB delta scratch (one
555
- attribute block's worth: `byte_stride × max_block_elements <= 8192` by construction) and a 256-byte
556
- group buffer, so the strided writes stay in cache and there is no per-block allocation. No
557
- performance claim is made without a measurement, and none has been taken.
558
-
559
- ### 6.7 The extension's `count` is not the accessor's `count`
560
-
561
- `count` is the number of *stride-sized elements in the bufferView*; for index modes that is the
562
- index count, not the triangle count. Reading it as either is a silent 3× error that only shows on
563
- non-triangle-aligned data.
564
-
565
- **Change:** each spec's own invariants become the validation list, checked before decode and thrown
566
- on. Parent `byteLength === byteStride × count`; parent `byteStride`, when present, equals the
567
- extension's; `ATTRIBUTES` → stride divisible by 4, `>= 4` (KHR) and `<= 256`; `TRIANGLES` → count
568
- divisible by 3; `TRIANGLES`/`INDICES` → stride 2 or 4 and filter absent or `NONE`; `OCTAHEDRAL` →
569
- stride 4 or 8; `QUATERNION` → stride 8; `EXPONENTIAL` → stride divisible by 4; `COLOR` → stride 4
570
- or 8 **and** the KHR name. Plus the source range lying inside the source buffer, which both specs
571
- leave implicit, and the KHR rule that a bufferView must not carry both extension names.
572
-
573
- ### 6.8 The fallback buffer is allocated at its declared `byteLength`
574
-
575
- Both specs require a placeholder large enough to hold every uncompressed view referencing it — a
576
- megabyte-scale allocation for a real model, of a buffer that by construction nothing reads once the
577
- views are rewritten.
578
-
579
- **Change:** it resolves to a **zero-length** buffer. A well-formed file never touches it; a
580
- malformed one — a view referencing the fallback without carrying the extension — fails loudly on an
581
- out-of-range typed-array construction, which is the correct outcome and is preferable to quietly
582
- handing out a megabyte of zeros that renders as a degenerate mesh.
583
-
584
- ### 6.9 Version and name policy has three different answers, and uniformity would be a bug
585
-
586
- The temptation is one rule for all three headers. They are not the same:
587
-
588
- - Mode 0 version 1 is a *different bitstream*, so decoding `0xa1` as `0xa0` is a silent wrong
589
- answer. It is supported, and it is rejected under the `EXT_` name, which does not define it.
590
- - Mode 1 and mode 2 versions 0 and 1 differ only in `fec_max`, which is read from the header, so
591
- both decode correctly and both are accepted under either name.
592
- - Filter `COLOR` is accepted only under the `KHR_` name.
593
-
594
- And two decode-time hazards are left alone on purpose, because the specs declare them unspecified
595
- and JavaScript's typed arrays already contain the damage: a colour element whose fourth component is
596
- zero (infinite scale, finite garbage bytes on store) and a quaternion whose retained components
597
- exceed unit length (already clamped at the radicand). Neither can produce a `NaN` that escapes into
598
- the scene, and neither gets a guard.
599
-
600
- ### 6.10 Nothing checks `extensionsRequired`
601
-
602
- The loader ignores `extensionsRequired` entirely, so a file requiring an extension meep does not
603
- implement loads and renders wrong. Pre-existing and out of scope — noted so it is not mistaken for
604
- something this change introduced or fixed.
605
-
606
- ### 6.11 The residual risk this plan cannot retire
607
-
608
- Three details are taken from questions put to the reference implementation rather than from
609
- specification text, and one is taken from an inference:
610
-
611
- - literal control mode 3 consumes the **group-aligned** element count per byte position, not the
612
- block's unaligned count (inferred: all four control modes must agree on the scratch stride);
613
- - channel mode 2 rotates **left** by `r` on decode;
614
- - the version 1 tail-padding minimum is 24 bytes, not 32.
615
-
616
- Each is a silent-garbage failure if wrong, and none is discriminated by any test in §5 — a fixture
617
- encoder written from the same understanding agrees with the decoder. They are the specific reason
618
- §5.5's ask matters: one real `gltfpack -cc -vv` file settles all three at once. Until there is one,
619
- **version 1 support is implemented and tested but not evidenced**, and this paragraph is the honest
620
- statement of that.
621
-
622
- ## 7. Commit sequence
623
-
624
- Each commit is independently green (`npm run test` from `H:/git/moh`).
625
-
626
- 1. `feat(math): rounding that breaks its ties away from zero`
627
- 2. `feat(binary): meshopt's attribute codec, against the bytes the spec itself decodes`
628
- — mode 0 version 0, the group and channel decoders, the varint, the two enums, specs.
629
- 3. `feat(binary): the attribute codec's second version, and the channels it decodes through`
630
- — mode 0 version 1: control header, control modes, 1-bit groups, channel modes, specs.
631
- 4. `feat(binary): meshopt's two index codecs, and the tail that checks them`
632
- — modes 1 and 2, specs.
633
- 5. `feat(binary): four meshopt filters, one of them meep's own octahedron`
634
- — filters 1/2/3/4, specs.
635
- 6. `feat(binary): one entry point per compressed buffer view`
636
- — `meshopt_decode` dispatch, spec.
637
- 7. `feat(gltf): a compressed buffer view becomes an ordinary one`
638
- — the binding module and its validation, under both extension names, spec.
639
- 8. `fix(gltf): a buffer with no URI is a placeholder, not a request`
640
- — the tiny-gltf buffer loop, GLB buffers past the chunk.
641
- 9. `feat(gltf): the loader decodes compressed views before an accessor reads one`
642
- — the `loadFromJson` call, the compressed-image-view throw, the end-to-end fixture and spec.
643
-
644
- ## 8. What execution changed
645
-
646
- Written after the work landed. The plan above is corrected in place where it was factually wrong
647
- about the format; everything else is recorded here rather than edited away, because a plan that
648
- quietly matches its outcome is not evidence of anything.
649
-
650
- ### 8.1 The plan was wrong about the `0xfe`/`0xff` ordering
651
-
652
- §3.2 claimed that computing and explicitly reading each of the three indices in turn "diverges on
653
- the first triangle that mixes them". It does not. An index in that branch is either fresh — and
654
- takes a turn at `next` — or explicit, and takes a varint; never both. The two passes are disjoint
655
- per index, so interleaving them is equivalent.
656
-
657
- Found by mutation: rewriting the branch to interleave them left all fifty-four tests green, and the
658
- question "which test should have caught this?" has the answer "none, because there is nothing to
659
- catch". What *is* order-dependent is the sequence of the explicit reads, because `last` chains
660
- through them; a test with a codeaux of `0xff`, where all three indices are explicit, now pins it.
661
-
662
- §3.2 also conflated two things about the conditional FIFO push. The *write* at a non-advancing
663
- offset is unobservable (no well-formed stream reads distance 16). The *non-advance* is very much
664
- observable, at any distance a later code reaches. Two tests now do.
665
-
666
- ### 8.2 A specification erratum, in both documents
667
-
668
- Of the three worked examples both extensions print for the varint encoding,
669
-
670
- ```
671
- 0x7f => 0x7f
672
- 0x81 0x04 => 0x201
673
- 0xff 0xa0 0x05 => 0x1fd005
674
- ```
675
-
676
- the third is wrong. Those bytes are the LEB128 encoding of `0x1fd005` written back to front; read as
677
- LEB128 they are `0x1507f`, and `0x1fd005` encodes as `0x85 0xa0 0x7f`. The example only works if the
678
- groups are read most significant first, which contradicts the example above it, the encoding the
679
- document names, and the reference implementation.
680
-
681
- `meshopt_read_uint_var.spec.js` pins both readings of both byte strings so that nobody later "fixes"
682
- the reader to match the printed line.
683
-
684
- ### 8.3 Two things the plan claimed mattered, which cannot be observed
685
-
686
- Both were found by mutating the implementation and watching the suite stay green, and both are now
687
- written down where they live rather than left to look like tested behaviour.
688
-
689
- - **§6.4, the rounding mode.** `round_half_away_from_zero` cannot be told from `Math.round` through
690
- any of the four filters. A renormalised octahedral component is a ratio with an irrational
691
- denominator and never lands halfway between two integers — checked exhaustively over the whole
692
- 8-bit input space, 8388477 component values, no ties — and the quaternion filter's scale is
693
- irrational for the same reason. The colour filter's scale is rational, but its inputs are
694
- non-negative for any valid element, and a positive tie rounds the same way either way. The helper
695
- is kept because it is what the specifications say; the claim that a test proves it is withdrawn,
696
- and a standing sweep now asserts the no-ties property that makes it moot.
697
- - **§3.4, the quaternion radicand's clamp.** The output goes through an `Int16Array`, and storing a
698
- `NaN` there yields the same zero the clamp produces. Kept so the function is total on its own
699
- rather than by a coincidence thirty lines downstream — which is exactly the kind of thing a
700
- refactor removes — but nothing tests it, and the spec now says so.
701
-
702
- ### 8.4 Structure
703
-
704
- - Planned commits 2 and 3 (attribute codec versions 0 and 1) landed as one. The block loop, the
705
- group decoder and the channel reconstruction are shared; splitting them would have meant writing
706
- the module twice.
707
- - The test-only encoder §5.3 put inline in a spec file became `__meshopt_test_streams.js`, because
708
- the end-to-end glTF fixtures need the same streams. `**/__**.js` is already how meep's coverage
709
- configuration spells "scaffolding".
710
- - Three test vectors in the first draft were wrong and the implementation was right: a quaternion
711
- component stored at full scale is `1/sqrt(2)` and not 1; a quaternion whose four components are
712
- equal has its dropped component absorb all three of the others' rounding, so it is up to three and
713
- a half quantisation steps out rather than half a step; and a colour alpha of `0x80` is the marker
714
- bit over an empty field, which is zero and not one. The bounds are now derived in the test from
715
- the quantisation step rather than picked.
716
-
717
- ### 8.5 The record
718
-
719
- Thirty-two mutations were applied to the finished implementation to check the suite says so. Thirty
720
- failed at least one test. The two that did not are §8.3, and are documented rather than papered over.
721
-
722
- `npm run test` from `H:/git/moh` covers all of it; the meshopt package and its glTF binding are 96
723
- tests across 12 files, plus 7 end-to-end through the real asset framework.
724
-
725
- ### 8.6 What is still owed
726
-
727
- §5.5 and §6.11 stand unchanged, and are the honest limit of this work:
728
-
729
- **No test here decodes a stream `gltfpack` produced.** Every byte under test was authored from a
730
- specification by me, or by a fixture encoder I also wrote. Three details — literal control mode 3's
731
- element count, channel mode 2's rotation direction, and version 1's 24-byte tail minimum — come from
732
- questions put to the reference rather than from specification text, and no test discriminates any of
733
- them.
734
-
735
- One `gltfpack -noq -cc` output and one `-cc -vv` output, checked in with a golden test that
736
- validates every `POSITION` accessor against its own declared `min`/`max` and every index against the
737
- vertex count, would settle all three at once. Those bounds are written by the encoder and are not
738
- derivable from the compressed bytes.
739
-
740
- Until then: version 0 is corroborated by the specification's own worked example, and **version 1 is
741
- implemented and tested but not evidenced.**
742
-
743
- ## 9. The seam this was first built on the wrong side of
744
-
745
- The first version put the whole glTF half in one module, `gltf_meshopt_compression.js`, exporting
746
- `gltf_meshopt_decode_buffer_views(buffer_views, buffers)`. The parser imported that by name and
747
- called it on every model it loaded.
748
-
749
- It worked, and every test above passed against it. It was still the wrong shape, for reasons worth
750
- writing down because none of them is a bug:
751
-
752
- - **The name described the caller's hope, not the function.** A thing called
753
- `gltf_meshopt_decode_buffer_views` does not decode bufferViews. It walks all of them, works out
754
- which are anybody's, decodes those, and rewrites the array. Three jobs under one codec's name.
755
- - **Detection was welded to decoding.** The parser assumed meshopt by importing it, and the check
756
- that it was meshopt happened *inside*, four frames down. Reading the call site told you nothing
757
- about whether a plain glTF paid anything — which is exactly the question it should answer.
758
- - **The second extension proved the point and the third would have made it.** `KHR_` was bolted on
759
- as `if (name === MESHOPT_COMPRESSION_EXT && ...)` inside the decoder. A Draco or a future codec
760
- would have been another module the parser imported by name, and another branch.
761
-
762
- What replaced it is in §2.2. The parser asks a set what claims a view; the set answers with an
763
- extension or with nothing; the walk is identical for all of them. `tiny-gltf.js` no longer contains
764
- the string "meshopt" anywhere, comments included.
765
-
766
- Two smaller things went the same way:
767
-
768
- - `meshopt_decode`'s mode and filter dispatch were a seven-branch `if / else if` chain. The three
769
- modes already share a signature and the filters already share theirs, so both are now arrays
770
- indexed by the enum, and "none" is a function that does nothing rather than a branch that asks
771
- whether to.
772
- - The extension validator was fourteen `if (...) throw` in a row, several of them comparing mode and
773
- filter names. The specifications state those constraints as a table, so it is a table: what each
774
- mode and each filter admits of a stride and a count, with the rule's own wording carried alongside
775
- for the message. Eight guards, none of them naming a mode.
776
-
777
- Eight mutations were applied to the new seams to check the suite says so — the walker decoding
778
- unclaimed views, the walker dropping its length backstop, the set taking the first claimant, the set
779
- forgetting placeholder buffers, meshopt admitting any filter it can name, one version ceiling for
780
- every mode, and each dispatch table shuffled. All eight fail at least one test.
781
-
782
- ## Addendum, 2026-08-20: a document's resolved buffers are `Uint8Array`
783
-
784
- Written into the plan as `ArrayBuffer`, and changed when the virtual-geometry builder started
785
- reading containers through the same layer. A buffer is a *range* of bytes: a `.glb`'s binary chunk
786
- is a range of the file it arrived in, and a buffer read off a filesystem starts wherever the runtime
787
- put it. Carrying the offset with the bytes is what lets the chunk be handed on without copying a
788
- model-sized allocation, and `Uint8Array.subarray` is what a decoder's source range wants anyway —
789
- `MeshoptBufferViewExtension` reads one with `subarray` rather than a three-argument constructor that
790
- can only be laid over an aligned offset.
791
-
792
- `decode()` answers with a `Uint8Array` for the same reason, and the length check over it is
793
- unchanged.
1
+ # `EXT_meshopt_compression` / `KHR_meshopt_compression` — implementation plan
2
+
3
+ Status: plan. Written 2026-08-20.
4
+
5
+ Scope: decode side of both extensions.
6
+
7
+ - `EXT_meshopt_compression` — ratified, Vendor.
8
+ <https://github.com/KhronosGroup/glTF/tree/main/extensions/2.0/Vendor/EXT_meshopt_compression>
9
+ - `KHR_meshopt_compression` — ratified, Khronos, merged 2026-01-23 (PR #2517).
10
+ <https://github.com/KhronosGroup/glTF/tree/main/extensions/2.0/Khronos/KHR_meshopt_compression>
11
+
12
+ Reference encoder/decoder: <https://github.com/zeux/meshoptimizer>. Consulted for questions the
13
+ specification text leaves ambiguous; **not vendored and not transcribed** — no new dependency, and
14
+ the bitstream below is implemented from the two specifications.
15
+
16
+ ## 1. What these extensions are, and why that shapes the split
17
+
18
+ Neither is a geometry extension. Both are *bufferView* extensions: a bufferView declares that its
19
+ bytes are produced by running a decoder over a byte range of some other buffer. Nothing about the
20
+ decode depends on what the bufferView is later read as — vertex attributes, index data, morph
21
+ deltas, animation keyframes and `EXT_mesh_gpu_instancing` transforms all go through the same three
22
+ modes and (now) five filters.
23
+
24
+ That is the seam. Everything except roughly two dozen lines is a **byte-array in, byte-array out**
25
+ codec with no knowledge of glTF at all:
26
+
27
+ ```
28
+ src/core/binary/meshopt/ pure codec — bytes in, bytes out.
29
+ ^ No glTF, no geometry, no engine.
30
+ | called by
31
+ src/.../gltf/ext/meshopt/ one bufferView's worth of meshopt: read the
32
+ ^ extension object, check it, return the bytes.
33
+ | called through GltfBufferViewExtension by
34
+ src/.../gltf/ext/ the generic bufferView-extension layer — which
35
+ ^ extension claims a view, and what becomes of what
36
+ | it produced. Names no codec.
37
+ | called by
38
+ src/shade/renderer/loader/gltf/tiny-gltf.js one call, after buffers resolve. Names no
39
+ extension at all.
40
+ ```
41
+
42
+ `core/binary` is the codec's right home: it is where meep already keeps byte-level codecs
43
+ (`base64/`, `base58/`, `half_to_float_uint16`, `BinaryBuffer`'s LEB128 `readUintVar`). The codec
44
+ imports nothing outside `core/`, so it is usable from a worker, a tool, or the USD loader without
45
+ dragging Shade in.
46
+
47
+ ### 1.1 KHR is EXT plus three things
48
+
49
+ The two extensions share a JSON shape, a `bufferView`/`buffer` model, fallback buffers, and modes
50
+ 1 and 2 byte for byte. KHR adds:
51
+
52
+ 1. **Attribute codec version 1** (header `0xa1`). A genuinely different bitstream for mode 0: a
53
+ per-block control header, four control modes, an extra 1-bit sentinel encoding, and three
54
+ *channel* modes that widen the delta from 8-bit to 16-bit or to a rotated 32-bit XOR.
55
+ Version 0 (`0xa0`) remains legal under KHR and is bit-identical to EXT.
56
+ 2. **Filter 4, `COLOR`** — YCoCg, `byteStride` 4 or 8.
57
+ 3. One extra validity rule (`ATTRIBUTES` requires `byteStride >= 4`) and the constraint that a
58
+ bufferView must not carry both extensions.
59
+
60
+ So there is one codec that decodes everything, and a glTF layer that enforces the per-name subset:
61
+ a `0xa1` stream or a `COLOR` filter under the `EXT_` name is an invalid file and is rejected.
62
+
63
+ ## 2. Modules
64
+
65
+ ### 2.1 `src/core/binary/meshopt/` — the codec
66
+
67
+ | File | Export |
68
+ |:--|:--|
69
+ | `MeshoptCompressionMode.js` | `@enum` — `Attributes: 0`, `Triangles: 1`, `Indices: 2` |
70
+ | `MeshoptCompressionFilter.js` | `@enum` — `None: 0`, `Octahedral: 1`, `Quaternion: 2`, `Exponential: 3`, `Color: 4` |
71
+ | `MESHOPT_GROUP_SIZE.js` | the group size, and the 24-byte bound a group read stays inside |
72
+ | `meshopt_decode_byte_group.js` | one group of 16 byte-deltas at a given sentinel width |
73
+ | `meshopt_decode_data_block.js` | one "data block": header bits + its groups, for one byte position |
74
+ | `meshopt_decode_vertex_buffer.js` | mode 0, versions 0 and 1 |
75
+ | `meshopt_decode_index_buffer.js` | mode 1 |
76
+ | `meshopt_decode_index_sequence.js` | mode 2 |
77
+ | `meshopt_decode_filter_octahedral.js` | filter 1, in place |
78
+ | `meshopt_decode_filter_quaternion.js` | filter 2, in place |
79
+ | `meshopt_decode_filter_exponential.js` | filter 3, in place |
80
+ | `meshopt_decode_filter_color.js` | filter 4, in place |
81
+ | `meshopt_decode.js` | dispatch: mode, then filter |
82
+ | `meshopt_read_uint_var.js` | bounded LEB128 over a `Uint8Array` |
83
+ | `__meshopt_test_streams.js` | test-only encoders, shared by the codec specs and the glTF fixtures |
84
+
85
+ Signatures:
86
+
87
+ ```js
88
+ meshopt_decode_vertex_buffer(destination, count, byte_stride, source)
89
+ meshopt_decode_index_buffer(destination, index_count, index_size, source)
90
+ meshopt_decode_index_sequence(destination, index_count, index_size, source)
91
+ meshopt_decode_filter_*(destination, count, byte_stride)
92
+ meshopt_decode(destination, count, byte_stride, mode, filter, source)
93
+ ```
94
+
95
+ `destination` and `source` are `Uint8Array` throughout — the codec never assumes an aligned
96
+ `ArrayBuffer` offset, because a compressed source range in a glTF is only byte-aligned. Index modes
97
+ and filters build their typed views internally from `index_size` / `byte_stride`.
98
+
99
+ Two additions outside the package, both genuinely generic and both matching meep's existing naming:
100
+
101
+ - `src/core/math/round_half_away_from_zero.js` — `Math.round` breaks ties toward `+Infinity`
102
+ (`Math.round(-2.5) === -2`). Four of the five filters specify `round()` on a signed symmetric
103
+ quantity and round half away from zero. Sits beside the existing `round_up.js`.
104
+ - nothing else: `msb_32` (`core/binary`) is already `findMSB` including its `-1` for zero, `exp2`
105
+ and `copysign` (`core/math`) already exist, and `decode_octahedron_to_unit`
106
+ (`core/geom/3d/normal/octahedron`) is reused by filter 1 — see §4.1.
107
+
108
+ ### 2.2 `src/shade/renderer/loader/gltf/ext/` — bufferView extensions, generically
109
+
110
+ A bufferView extension says "these bytes are not in the buffer I point at; run this to get them".
111
+ Meshopt is two of them; a future codec would be a third. The parser should know that shape and
112
+ nothing else, so the layer is split in two — see §9 for why this is not how it was first written.
113
+
114
+ | File | What it is |
115
+ |:--|:--|
116
+ | `GltfBufferViewExtension.js` | the contract one extension implements: a `name`, `decode()`, and whether it declares placeholder buffers |
117
+ | `GltfBufferViewExtensionSet.js` | which extensions a parser honours, and `claim(view)` — the *only* thing that decides whether anything happens |
118
+ | `gltf_apply_buffer_view_extensions.js` | the walk: claim, delegate, append the buffer, replace the descriptor. Identical for every extension |
119
+ | `gltf_buffer_view_extensions.js` | `GLTF_BUFFER_VIEW_EXTENSIONS`, the set the parser uses by default |
120
+ | `meshopt/MeshoptBufferViewExtension.js` | one class, two instances: `EXT_MESHOPT_COMPRESSION`, `KHR_MESHOPT_COMPRESSION` |
121
+
122
+ The walker:
123
+
124
+ 1. returns a **new** `bufferViews` array — claimed entries are replaced by fresh descriptors,
125
+ unclaimed entries pass through **by reference**,
126
+ 2. **appends** each decoded buffer to `buffers`, pointing the new descriptor at it with
127
+ `byteOffset: 0`,
128
+ 3. keeps `byteStride`, `target` and everything else from the parent, so accessor reads are unchanged,
129
+ 4. refuses a decoder that answered with the wrong number of bytes, whichever decoder it was.
130
+
131
+ Returning a new array rather than mutating the old descriptors is load-bearing, not taste — §6.3.
132
+
133
+ The difference between the two meshopt instances is two fields and no branches: which filter names
134
+ the extension defines, and the newest codec version each *mode* may carry. Per mode because both
135
+ index codecs' version 1 is legal under either extension; it is only the attribute codec that the
136
+ vendor extension pins at 0.
137
+
138
+ ### 2.3 `tiny-gltf.js` — the call site
139
+
140
+ Three edits, all in `loadFromJson`:
141
+
142
+ - **`~L422-448`, buffer resolution.** Today a buffer with no `uri` outside the GLB fast path is fed
143
+ to `resolveUri(undefined, baseUrl)` and fetched as `<baseUrl>undefined`. That is exactly the shape
144
+ of a meshopt *fallback* buffer (`{ "byteLength": N }`, no URI), so today a `gltfpack`-produced
145
+ `.gltf` cannot load at all. A buffer that is marked `fallback` or has no `uri` resolves to a
146
+ zero-length `ArrayBuffer` instead of a request (§6.8). Also: the GLB branch currently loads *only*
147
+ the binary chunk and ignores `buffers[1..n]`, which is where both extensions put the placeholder —
148
+ the branch becomes "buffer 0 is the chunk, the rest resolve normally".
149
+ - **`~L524-534`, an image sourced from a bufferView.** Throw if that bufferView is compressed. The
150
+ combination is legal in the abstract and pointless in practice (the payload is already a PNG or a
151
+ JPEG); the alternative to throwing is handing `createImageBitmap` the fallback buffer's bytes,
152
+ which is a silent wrong answer.
153
+ - **`~L557`, after `await Promise.all(pendingBuffers)`.** One call to
154
+ `gltf_apply_buffer_view_extensions` before `json.buffers` and `json.bufferViews` are published.
155
+
156
+ The parser names no extension: it asks `this.bufferViewExtensions` — a public field, defaulted to the
157
+ standard set and replaceable — and the set is the one place that knows what is implemented.
158
+
159
+ **Nothing in `load_gltf.js` changes.** It reads `gltf.bufferViews` / `gltf.buffers` inside
160
+ `process()`, which runs after `loadFromJson` has returned, so it sees decoded views and never learns
161
+ either extension exists. That is the point of doing this at the bufferView layer.
162
+
163
+ ## 3. The bitstream, as implemented
164
+
165
+ Written from the two specifications' Appendix A/B. Notes marked ⚠ are places where a plausible
166
+ reading is wrong.
167
+
168
+ ### 3.1 Mode 0 — attributes
169
+
170
+ ```
171
+ header 1 byte: 0xa0 (version 0) or 0xa1 (version 1, KHR only)
172
+ blocks one or more attribute blocks
173
+ tail padding zero bytes
174
+ tail block baseline element (byte_stride bytes)
175
+ channel modes (byte_stride / 4 bytes, version 1 only)
176
+ ```
177
+
178
+ ⚠ **The padding comes BEFORE the tail block; the tail block is flush against the end of the
179
+ stream.** So the baseline element starts at `byteLength - tail_size`, where
180
+
181
+ ```
182
+ tail_size = byte_stride + (version === 1 ? byte_stride / 4 : 0)
183
+ tail_size_pad = max(tail_size, version === 1 ? 24 : 32)
184
+ ```
185
+
186
+ and the decoder must have consumed exactly `byteLength - tail_size_pad` bytes when the blocks are
187
+ done. EXT's wording — "a baseline element stored verbatim, padded to 32 bytes" — reads equally well
188
+ as element-then-padding, which for any stride below 32 puts the baseline in the wrong place and
189
+ decodes garbage. KHR's rewording ("Tail padding, which pads the size of the *subsequent* tail
190
+ block…") settles it, and the reference decoder agrees: it takes the baseline from
191
+ `data_end - tail_size`, with `tail_size` **unpadded**, while validating the remainder against
192
+ `tail_size_pad`. Two different quantities that coincide only when `byte_stride >= 32`.
193
+
194
+ Block loop, identical in both versions:
195
+
196
+ ```
197
+ max_block_elements = min(floor(8192 / byte_stride) & ~15, 256)
198
+ block_elements = min(remaining, max_block_elements)
199
+ group_count = ceil(block_elements / 16)
200
+ ```
201
+
202
+ ⚠ `8192 / byte_stride` is integer division — `floor` before the mask. With `byte_stride <= 256` the
203
+ result is never below 32, so the loop always advances.
204
+
205
+ A block is, in order:
206
+
207
+ - a **control header** of `byte_stride / 4` bytes — **version 1 only**,
208
+ - `byte_stride` **data blocks**, one per byte position `k` of the element.
209
+
210
+ The control header packs a 2-bit *control mode* per byte position, low bits first:
211
+ `(c0 << 0) | (c1 << 2) | (c2 << 4) | (c3 << 6)`, one byte per aligned group of four byte positions.
212
+ The control mode selects what the data block for that byte position looks like:
213
+
214
+ | control mode | data block |
215
+ |:--|:--|
216
+ | 0 | header bits, group encodings `{zero, 1-bit, 2-bit, 4-bit}` |
217
+ | 1 | header bits, group encodings `{1-bit, 2-bit, 4-bit, raw}` |
218
+ | 2 | nothing at all — every delta byte is 0, no header bits, no bytes consumed |
219
+ | 3 | literal: `group_count * 16` delta bytes, no header bits |
220
+
221
+ Version 0 has no control header and behaves as a fixed table
222
+ `{zero, 2-bit, 4-bit, raw}` for every byte position.
223
+
224
+ Where header bits are present they are `ceil(group_count / 4)` bytes, 2 bits per group, packed
225
+ **low bits first**: `(g0 << 0) | (g1 << 2) | (g2 << 4) | (g3 << 6)`. Group encodings:
226
+
227
+ | encoding | packed bytes | sentinel | total |
228
+ |:--|:--|:--|:--|
229
+ | zero | 0 | — | 0 |
230
+ | 1-bit | 2 | `1` | 2..18 |
231
+ | 2-bit | 4 | `3` | 4..20 |
232
+ | 4-bit | 8 | `15` | 8..24 |
233
+ | raw | 16 | — | 16 |
234
+
235
+ ⚠ Bit order inside a packed byte is **not uniform**. 2-bit and 4-bit run high bits first —
236
+ `(d3 << 0) | (d2 << 2) | (d1 << 4) | (d0 << 6)` and `(d1 << 0) | (d0 << 4)` — while **1-bit runs low
237
+ bits first**, `(d0 << 0) | (d1 << 1) | … | (d7 << 7)`. The spec says so explicitly (it is there to
238
+ let SIMD implementations reuse a lookup table); it is not a transcription slip.
239
+
240
+ A delta equal to the sentinel means the real value is outside the bit range and is taken as a whole
241
+ byte from the run that follows the packed bytes, in order of appearance.
242
+
243
+ The delta bytes so recovered are then turned into values by the **channel mode**. Channels are
244
+ aligned groups of four byte positions; version 1 stores one mode byte per channel in the tail, and
245
+ version 0 behaves as though every channel were mode 0.
246
+
247
+ | channel mode | reconstruction |
248
+ |:--|:--|
249
+ | 0 | per byte: `v = (unzigzag8(d) + prev) & 0xff` |
250
+ | 1 | per aligned 2 bytes, little-endian: `v = (unzigzag16(d) + prev) & 0xffff` |
251
+ | 2 | per aligned 4 bytes, little-endian: `v = rotl32(d, r) ^ prev` |
252
+
253
+ `r` is the **high** 4 bits of the channel mode byte and applies only to mode 2. ⚠ The decoder
254
+ rotates **left by `r`** — the spec's `rotate(v, r) = (v << r) | (v >> ((32 - r) & 31))` is the
255
+ decode direction, despite the surrounding sentence describing how the encoder produced the delta.
256
+ A mode byte whose low nibble is 3 or above, or whose high nibble is non-zero for mode 0 or 1, makes
257
+ the stream invalid.
258
+
259
+ Groups always decode sixteen elements; anything past `block_elements` is discarded and does not
260
+ advance the delta chain. Each block ends by taking its **last decoded element** as the next block's
261
+ baseline.
262
+
263
+ The specification's own worked example is the acceptance test for the group decoder (§5.1).
264
+
265
+ ### 3.2 Mode 1 — triangles
266
+
267
+ ```
268
+ header 1 byte, (h & 0xf0) == 0xe0; version = h & 0x0f, 0 or 1 (both specs pin 0xe1)
269
+ codes index_count / 3 bytes, one per triangle
270
+ data variable, immediately after the codes
271
+ codeaux the last 16 bytes
272
+ ```
273
+
274
+ State: `next` (high-watermark, 0), `last` (0), a 16-entry edge FIFO and a 16-entry vertex FIFO, both
275
+ filled with `0xFFFFFFFF`. `data` must end exactly at the start of `codeaux` — that equality is the
276
+ stream's own checksum.
277
+
278
+ `fec_max` is 13 for version 1 and 15 for version 0; it is what makes codes `0xXd`/`0xXe` mean
279
+ `last - 1` / `last + 1` rather than two more FIFO slots. Reading it from the header rather than
280
+ hard-coding 13 is why both versions decode correctly.
281
+
282
+ ⚠ The two branches index the vertex FIFO differently: the `code < 0xf0` path reads
283
+ `(offset - 1 - fec) & 15`, the `0xf0..0xff` paths read `(offset - feb) & 15`. This follows from the
284
+ spec's own wording ("index Y" versus "index Z-1") and is not a slip.
285
+
286
+ ⚠ A conditional push writes the value at `offset` and then does not advance `offset`. Skipping the
287
+ write as well is *not* equivalent: every later FIFO read at distance `d` would see what belongs at
288
+ `d - 1`. Two tests reach back past a vertex that was not pushed, because until something does the
289
+ difference is invisible.
290
+
291
+ ⚠ The explicit indices in the `0xfe`/`0xff` branch are read in the order a, b, c, and `last` chains
292
+ through them, so that order is load-bearing. Their position relative to the `next++` allocations is
293
+ *not*: an index is either fresh or explicit, never both, so the two passes do not interfere. (The
294
+ plan asserted otherwise; see §8.)
295
+
296
+ ### 3.3 Mode 2 — indices
297
+
298
+ ```
299
+ header 1 byte, (h & 0xf0) == 0xd0 (both specs pin 0xd1)
300
+ deltas one LEB128 varint per index
301
+ tail 4 reserved bytes
302
+ ```
303
+
304
+ `v & 1` selects one of two running baselines; `v >> 1` is a zigzag delta applied to it. Two
305
+ baselines rather than one is what lets an encoder splice two monotonic runs (strips, line lists)
306
+ cheaply. Again `data` must land exactly on the 4-byte tail.
307
+
308
+ ### 3.4 Filters
309
+
310
+ All five are in place over the already-decoded bufferView, `count` elements of `byte_stride` bytes.
311
+
312
+ - **Octahedral** — `byte_stride` 4 → `Int8Array`, 8 → `Int16Array`. Components 0 and 1 are the
313
+ octahedral pair, component 2 encodes 1.0 at the element's own precision `K`, component 3 passes
314
+ through untouched. Output scaled by `max` = 127 or 32767. Reuses meep's own
315
+ `decode_octahedron_to_unit` — see §4.1.
316
+ - **Quaternion** — `byte_stride` 8, `Int16Array`. `one = input[3] | 3`,
317
+ `max_component = input[3] & 3`; outputs land at `(max_component + 1..3) & 3` for x/y/z and
318
+ `(max_component + 0) & 3` for w.
319
+ ⚠ `input[3]` is read for *both* purposes before any output is written — one of the four writes
320
+ lands on it.
321
+ ⚠ The radicand `1 - x² - y² - z²` is clamped at 0. meep already learned this in
322
+ `quat3_decode_from_uint32`; a NaN quaternion out of a loader poisons every transform downstream.
323
+ - **Exponential** — `byte_stride` divisible by 4. Each 32-bit word is `e = word >> 24` (signed),
324
+ `m = (word << 8) >> 8` (signed); the result `2^e · m` is written back as a float32. `e` is
325
+ spec-bounded to [-100, 100] and `|m| < 2^23`, so the product is exact in float32 and computing it
326
+ in JS doubles and storing through a `Float32Array` is bit-identical to the reference's
327
+ build-the-exponent-and-multiply.
328
+ - **Color** (KHR only) — `byte_stride` 4 → `Uint8Array`, 8 → `Uint16Array`. YCoCg:
329
+
330
+ ```
331
+ as = (1 << (msb_32(input[3]) + 1)) - 1
332
+ r = input[0] + int(input[1]) - int(input[2])
333
+ g = input[0] + int(input[2])
334
+ b = input[0] - int(input[1]) - int(input[2])
335
+ a = input[3] & (as >> 1); a = (a << 1) | (a & 1)
336
+ output = round(component * (UINTN_MAX / as))
337
+ ```
338
+
339
+ ⚠ Components 0 and 3 are **unsigned**, components 1 and 2 are **signed**, in the same element.
340
+ `msb_32` already returns `-1` for zero, so a malformed `input[3] === 0` yields `as = 0`, an
341
+ infinite scale, and finite garbage bytes once stored through a `Uint8Array` — defined, ugly, and
342
+ not worth a guard (§6.9).
343
+
344
+ ## 4. What is reused, and what deliberately is not
345
+
346
+ ### 4.1 Reused
347
+
348
+ - **`decode_octahedron_to_unit`** (`core/geom/3d/normal/octahedron`) implements filter 1's core.
349
+ meep's fold is the same arithmetic as the spec's `copysign` form (`x + t·sign(x)` either way) and
350
+ it renormalises, but it is written **Y-up**: meep's `(x, y, z)` is the spec's `(x, z, y)`. The
351
+ swizzle is the whole of the adaptation, and a spec checks the composition against the
352
+ specification's formula directly rather than against meep's.
353
+ - **`msb_32`** (`core/binary`) is `findMSB` for filter 4, `-1`-on-zero included.
354
+ - **`exp2`** and **`copysign`** (`core/math`).
355
+ - **`gltf_test_fixtures.js`** (`engine/asset/loaders`) already builds a one-triangle glTF and GLB by
356
+ hand; the end-to-end fixture extends it rather than introducing a second fixture vocabulary.
357
+
358
+ ### 4.2 Deliberately not
359
+
360
+ - **`BinaryBuffer.readUintVar`** is the same LEB128 scheme and reusing it would honour "use meep's
361
+ existing code". It is still wrong here: it reads through a `DataView` bound to a whole
362
+ `ArrayBuffer` where the compressed range is a slice, it is unbounded on malformed input where the
363
+ reference stops at five bytes, and `value |= (b & 0x7f) << shift` turns negative once `shift`
364
+ reaches 28 — which is inside the range mode 1 and mode 2 indices legitimately use. The deviation
365
+ and its three reasons are documented where `meshopt_read_uint_var` is defined, so the next reader
366
+ does not "fix" the duplication.
367
+ - **`quat3_decode_from_uint32`** is a different packing — 10-bit, fixed range, dropped component
368
+ inserted *at* index `max` — where filter 2 is 16-bit, variable precision and *cyclic*. Documented
369
+ as deliberately not reused rather than left to look overlooked.
370
+ - **`Vector3` / `Quaternion` / `vec3` helpers.** The filters run over hundreds of thousands of
371
+ elements through typed-array views; routing each through an object allocation would be the one
372
+ place in this feature where reuse costs more than it is worth. Scalars, module-static scratch.
373
+
374
+ ## 5. Tests
375
+
376
+ Every module gets a `.spec.js` beside it. House rules apply: black-box, no mocks, and no rejection
377
+ tests against `assert.*` (stripped in production) — everything that must reject bad *file* input
378
+ does so with a real `throw`, and those are tested.
379
+
380
+ ### 5.1 The independent oracle
381
+
382
+ The single most valuable test is free: **Appendix A of both specifications contains a worked
383
+ example** of the 4-bit sentinel encoding —
384
+
385
+ ```
386
+ 0x17 0x5f 0xf0 0xbc 0x77 0xa9 0x21 0x00 0x34 0xb5
387
+ -> -1 -4 -3 26 -91 0 -6 6 -4 -4 5 -5 1 -1 0 0
388
+ ```
389
+
390
+ — which pins the packed-nibble order, the sentinel value, the sentinel run's position and its
391
+ ordering, and the zigzag, all at once, from a document that is not this implementation. It is the
392
+ first test written, and the group decoder is developed against it. (Checked by hand while writing
393
+ this plan: the nibbles are `1 7 5 S S 0 11 12 7 7 10 9 2 1 0 0`, the two sentinels take `0x34` and
394
+ `0xb5`, and de-zigzagging reproduces the stated line exactly.)
395
+
396
+ ### 5.2 Hand-derived vectors
397
+
398
+ The remaining streams are small enough to author by hand from the spec, with the derivation in the
399
+ test as a comment. Worked out in advance so this plan can be checked before any code exists:
400
+
401
+ - **mode 0 v0, all-zero groups.** `byte_stride` 4, `count` 3 → one block, one group, four data
402
+ blocks each a single `0x00` header byte: `[0xa0, 0x00, 0x00, 0x00, 0x00]` then 28 zero bytes then
403
+ the 4 baseline bytes. All three elements equal the baseline. This is the test that fails if the
404
+ tail is read from the wrong end (§3.1 ⚠) — under the element-then-padding reading the baseline
405
+ comes out `0,0,0,0`.
406
+ - **mode 0 v1, control modes.** The same shape with header `0xa1`, one control byte, and one tail
407
+ channel-mode byte: control mode 2 (nothing stored) on every byte position; then control mode 3
408
+ (literal) with hand-written delta bytes; then control mode 0 with a 1-bit sentinel group, which
409
+ is the only place the low-bits-first packing is exercised.
410
+ - **mode 0 v1, channel modes 1 and 2.** `byte_stride` 4, one channel: a 16-bit delta pair that
411
+ wraps modulo 65536, and a rotated XOR whose `r` is non-zero — the two places where a
412
+ left-versus-right rotation or a byte-order slip is invisible at `r = 0`.
413
+ - **mode 1, one triangle.** `[0xe1, 0xf0]` + 16 `codeaux` bytes with `codeaux[0] = 0x00` →
414
+ `feb = fec = 0` → `a, b, c = next++, next++, next++` → `[0, 1, 2]`. 18 bytes, `1 + 6/3 + 16`;
415
+ `data` lands exactly on `codeaux`.
416
+ - **mode 1, two triangles sharing an edge.** Append code `0x00`: after triangle one the edge FIFO
417
+ holds `(1,0), (2,1), (0,2)` at offset 3, so `fe = 0` reads `(0, 2)` and `fec = 0` takes
418
+ `c = next = 3` → `[0, 1, 2, 0, 2, 3]`. This is the test that fails if the edge-FIFO push order is
419
+ wrong.
420
+ - **mode 1, the `0xXf` and `0xfe`/`0xff` paths** — explicit indices through `decodeIndex`, and the
421
+ `codeaux == 0` restart that resets `next`.
422
+ - **mode 2.** `[0xd1, 0x14, 0x08, 0, 0, 0, 0]` → `0x14 = 20`: baseline 0, zigzag 10, delta +5 → `5`;
423
+ `0x08 = 8`: baseline 0, zigzag 4, delta +2 → `7`. Output `[5, 7]`. Plus a vector that alternates
424
+ the baseline bit, which is the whole reason mode 2 exists.
425
+ - **filters.** Values computed from each spec's own pseudo-code in the test, not from the
426
+ implementation: unit ±X/±Y/±Z normals through octahedral at both strides, identity and
427
+ each-of-four-`max_component` quaternions, exponential words with negative exponents, negative
428
+ mantissas and `m = 0`, and for colour a grey, a saturated primary and a partial alpha at both
429
+ strides and at a `K` below the component width.
430
+ - **rejection.** Truncated streams, wrong header bytes, a `0xa1` stream offered under the `EXT_`
431
+ name, a `COLOR` filter under the `EXT_` name, an invalid channel mode byte, and a mode 1 stream
432
+ whose `data` does not land on `codeaux`.
433
+
434
+ ### 5.3 Round trip
435
+
436
+ A **test-only** mode 0 encoder in the spec file (raw-byte groups only, the simplest legal encoding)
437
+ gives a randomised round trip over strides 4/8/12/16/64 and counts that straddle the 16-element
438
+ group and 256-element block boundaries. It is deliberately *secondary*: it shares the layout
439
+ assumptions of the decoder, so a shared misreading passes. Its job is exercising the block and group
440
+ loop bounds, not proving the format. §5.1 and §5.2 prove the format.
441
+
442
+ ### 5.4 End to end
443
+
444
+ `gltf_test_fixtures.js` gains `build_meshopt_triangle_gltf_json(extension_name, buffer_uri, options)`
445
+ and a matching `_glb`: the one-triangle model with its four bufferViews compressed (positions, normals and
446
+ uvs in mode 0, indices in mode 1) by the fixture's own minimal encoder, a `fallback: true`
447
+ placeholder buffer with no URI, and `extensionsUsed` / `extensionsRequired` set. A spec then loads
448
+ it through the real `AssetManager` and `GLTFSceneBundleAssetLoader` — as
449
+ `GLTFSceneBundleAssetLoader.spec.js` already does — under **both** extension names, and asserts the
450
+ resulting bundle's geometry equals the uncompressed fixture's. That covers the fallback-buffer path,
451
+ the bufferView rewrite, and the fact that `load_gltf.js` needs no changes.
452
+
453
+ That file, though, is one the *vendor* extension could have described just as well — the Khronos name
454
+ on it and nothing else. `options` makes it a file only KHR defines: attribute streams at codec
455
+ version 1 carrying a channel mode each (a rotated exclusive-or over the positions, byte deltas over
456
+ the normals, 16-bit deltas over the texture coordinates), and a `COLOR`-filtered `COLOR_0` the mesh
457
+ reader maps to `StandardAttributes.Color`. Each of the two is served on its own as well as together,
458
+ so that a test watching the vendor extension refuse one is refusing *that* one — asserting against a
459
+ file carrying both passes on either constraint, and then removing one of them from the vendor
460
+ extension goes unnoticed.
461
+
462
+ ### 5.5 What none of this covers
463
+
464
+ No test here decodes a stream produced by `gltfpack`. Every byte under test was authored from a
465
+ specification by me or by a fixture encoder I also wrote; a misreading shared between them survives.
466
+ §5.1 is the only genuinely external oracle, and it covers one group encoding of one mode.
467
+
468
+ **Recommendation to the sponsor: drop one `gltfpack -noq -cc` output (and one `-cc -vv` for codec
469
+ version 1) into the repo, and add a golden test that decodes it and checks every `POSITION`
470
+ accessor's values against that accessor's declared `min`/`max`, and every index against the vertex
471
+ count.** Those bounds are written by the encoder, are not derivable from the compressed bytes, and
472
+ would catch a systematic misreading immediately. Left out of this plan because it needs files only
473
+ the sponsor can supply.
474
+
475
+ ## 6. Adversarial review of this plan
476
+
477
+ Each item is a way this plan is wrong or insufficient, and what it changes.
478
+
479
+ ### 6.1 The tail was read from the wrong end
480
+
481
+ The first draft of this plan had the baseline element at the **start** of a `max(stride, 32)`-byte
482
+ tail, from EXT's "a baseline element stored verbatim, padded to 32 bytes", and cited a reading of
483
+ the reference decoder that appeared to confirm it. Both were wrong, and for any `byteStride` below
484
+ 32 — which is every attribute meshopt is actually used on — it decodes an entire model to garbage
485
+ while every unit test written from the same misreading passes.
486
+
487
+ What caught it was reading KHR, which reworded the same clause to "Tail padding, which pads the size
488
+ of the *subsequent* tail block…" and added a second item to the tail block that forces the question.
489
+ The corroborating detail is that the reference keeps two quantities, `tail_size` and
490
+ `tail_size_pad`, uses the **unpadded** one to locate the baseline and the **padded** one to validate
491
+ the remainder — a distinction that has no meaning at all under the wrong reading.
492
+
493
+ **Changes:** §3.1 states both quantities and where each is used; §5.2's first vector is chosen
494
+ specifically to discriminate them; and the general lesson is written into §6.11.
495
+
496
+ ### 6.2 `Uint8Array` out-of-bounds reads return `undefined`, and `undefined & 0xff` is `0`
497
+
498
+ The worst failure mode in the design. JavaScript does not fault on a typed-array read past the end —
499
+ it yields `undefined`, and every bitwise operator coerces that to `0`. A truncated or malformed
500
+ stream therefore decodes to *plausible-looking zeros* rather than an error, and the model loads
501
+ wrong instead of failing. The reference is bounds-checked at every group and every index read for
502
+ exactly this reason.
503
+
504
+ **Change:** explicit bounds checks are not optional, and are not `assert` (stripped in production —
505
+ this input is a file, not a caller). Real `throw` at the header, at each byte group against the
506
+ 24-byte decode limit, at each literal and control-header read, at each index varint, and at the
507
+ final data-lands-on-the-tail equality in all three modes. Reject-a-truncated-stream cases added to
508
+ §5.2.
509
+
510
+ ### 6.3 Mutating the bufferView descriptors races the image loader
511
+
512
+ The first draft rewrote `json.bufferViews[i]` in place. `loadFromJson` builds the image promises
513
+ *before* buffers resolve, and each one closes over its `bufferView` object and reads `.byteOffset` /
514
+ `.byteLength` inside a `.then()` that runs *after* the rewrite. Mutating in place changes what an
515
+ already-scheduled image read sees, from a different code path, with no visible link between the two.
516
+
517
+ **Change:** §2.2 returns a new array of new descriptors and leaves the originals untouched. The
518
+ image path keeps reading exactly what it reads today, whatever order the promises settle in. This is
519
+ the reason for a design choice that otherwise looks like needless allocation, and it is recorded
520
+ where the code lives.
521
+
522
+ ### 6.4 `Math.round` is not the spec's `round`
523
+
524
+ `Math.round(-2.5)` is `-2`. The filters round signed symmetric quantities and the reference rounds
525
+ half away from zero. Half a quantisation step on normals is invisible in a screenshot and visible in
526
+ a diff against any other decoder — exactly the kind of drift nobody attributes correctly six months
527
+ later.
528
+
529
+ **Change:** `round_half_away_from_zero` in `core/math`, used by every filter, with the asymmetry
530
+ named in its JSDoc.
531
+
532
+ ### 6.5 A green suite here does not mean a `gltfpack` file loads
533
+
534
+ Two things sit between this feature and a real compressed asset, and neither is in scope:
535
+
536
+ - **`KHR_mesh_quantization`.** `gltfpack`'s default output quantises as well as compresses, and meep
537
+ does not implement that extension. Worse, quantised attributes are padded — a `VEC3`/`SHORT`
538
+ position gets `byteStride` 8, not 6 — and `load_gltf.js` rejects any bufferView whose `byteStride`
539
+ differs from `componentSize × componentCount` with `'Interleaved attributes are not supported'`.
540
+ So a default `gltfpack` file will fail *after* decompressing correctly.
541
+ - **Interleaved attributes**, same rejection, for the same reason.
542
+
543
+ `gltfpack -noq -cc` produces meshopt-compressed, non-quantised, non-interleaved output, and that is
544
+ the configuration this feature makes work. Stated here rather than discovered later; picking up
545
+ `KHR_mesh_quantization` is separate work and is not silently folded into this one.
546
+
547
+ ### 6.6 Pure JS is roughly an order of magnitude off the reference
548
+
549
+ The reference reaches ~1 GB/s with WebAssembly SIMD. This will not, and the extension exists partly
550
+ *because* decode is meant to be nearly free. Decompression is synchronous inside `loadFromJson`, so
551
+ it lands on whichever thread is parsing — the main thread for a foreground load.
552
+
553
+ Accepted, not designed around: the alternative is a WASM dependency, which the brief excludes.
554
+ Mitigated by the shape the reference already uses — a module-static 8 KiB delta scratch (one
555
+ attribute block's worth: `byte_stride × max_block_elements <= 8192` by construction) and a 256-byte
556
+ group buffer, so the strided writes stay in cache and there is no per-block allocation. No
557
+ performance claim is made without a measurement, and none has been taken.
558
+
559
+ ### 6.7 The extension's `count` is not the accessor's `count`
560
+
561
+ `count` is the number of *stride-sized elements in the bufferView*; for index modes that is the
562
+ index count, not the triangle count. Reading it as either is a silent 3× error that only shows on
563
+ non-triangle-aligned data.
564
+
565
+ **Change:** each spec's own invariants become the validation list, checked before decode and thrown
566
+ on. Parent `byteLength === byteStride × count`; parent `byteStride`, when present, equals the
567
+ extension's; `ATTRIBUTES` → stride divisible by 4, `>= 4` (KHR) and `<= 256`; `TRIANGLES` → count
568
+ divisible by 3; `TRIANGLES`/`INDICES` → stride 2 or 4 and filter absent or `NONE`; `OCTAHEDRAL` →
569
+ stride 4 or 8; `QUATERNION` → stride 8; `EXPONENTIAL` → stride divisible by 4; `COLOR` → stride 4
570
+ or 8 **and** the KHR name. Plus the source range lying inside the source buffer, which both specs
571
+ leave implicit, and the KHR rule that a bufferView must not carry both extension names.
572
+
573
+ ### 6.8 The fallback buffer is allocated at its declared `byteLength`
574
+
575
+ Both specs require a placeholder large enough to hold every uncompressed view referencing it — a
576
+ megabyte-scale allocation for a real model, of a buffer that by construction nothing reads once the
577
+ views are rewritten.
578
+
579
+ **Change:** it resolves to a **zero-length** buffer. A well-formed file never touches it; a
580
+ malformed one — a view referencing the fallback without carrying the extension — fails loudly on an
581
+ out-of-range typed-array construction, which is the correct outcome and is preferable to quietly
582
+ handing out a megabyte of zeros that renders as a degenerate mesh.
583
+
584
+ ### 6.9 Version and name policy has three different answers, and uniformity would be a bug
585
+
586
+ The temptation is one rule for all three headers. They are not the same:
587
+
588
+ - Mode 0 version 1 is a *different bitstream*, so decoding `0xa1` as `0xa0` is a silent wrong
589
+ answer. It is supported, and it is rejected under the `EXT_` name, which does not define it.
590
+ - Mode 1 and mode 2 versions 0 and 1 differ only in `fec_max`, which is read from the header, so
591
+ both decode correctly and both are accepted under either name.
592
+ - Filter `COLOR` is accepted only under the `KHR_` name.
593
+
594
+ And two decode-time hazards are left alone on purpose, because the specs declare them unspecified
595
+ and JavaScript's typed arrays already contain the damage: a colour element whose fourth component is
596
+ zero (infinite scale, finite garbage bytes on store) and a quaternion whose retained components
597
+ exceed unit length (already clamped at the radicand). Neither can produce a `NaN` that escapes into
598
+ the scene, and neither gets a guard.
599
+
600
+ ### 6.10 Nothing checks `extensionsRequired`
601
+
602
+ The loader ignores `extensionsRequired` entirely, so a file requiring an extension meep does not
603
+ implement loads and renders wrong. Pre-existing and out of scope — noted so it is not mistaken for
604
+ something this change introduced or fixed.
605
+
606
+ ### 6.11 The residual risk this plan cannot retire
607
+
608
+ Three details are taken from questions put to the reference implementation rather than from
609
+ specification text, and one is taken from an inference:
610
+
611
+ - literal control mode 3 consumes the **group-aligned** element count per byte position, not the
612
+ block's unaligned count (inferred: all four control modes must agree on the scratch stride);
613
+ - channel mode 2 rotates **left** by `r` on decode;
614
+ - the version 1 tail-padding minimum is 24 bytes, not 32.
615
+
616
+ Each is a silent-garbage failure if wrong, and none is discriminated by any test in §5 — a fixture
617
+ encoder written from the same understanding agrees with the decoder. They are the specific reason
618
+ §5.5's ask matters: one real `gltfpack -cc -vv` file settles all three at once. Until there is one,
619
+ **version 1 support is implemented and tested but not evidenced**, and this paragraph is the honest
620
+ statement of that.
621
+
622
+ ## 7. Commit sequence
623
+
624
+ Each commit is independently green (`npm run test` from `H:/git/moh`).
625
+
626
+ 1. `feat(math): rounding that breaks its ties away from zero`
627
+ 2. `feat(binary): meshopt's attribute codec, against the bytes the spec itself decodes`
628
+ — mode 0 version 0, the group and channel decoders, the varint, the two enums, specs.
629
+ 3. `feat(binary): the attribute codec's second version, and the channels it decodes through`
630
+ — mode 0 version 1: control header, control modes, 1-bit groups, channel modes, specs.
631
+ 4. `feat(binary): meshopt's two index codecs, and the tail that checks them`
632
+ — modes 1 and 2, specs.
633
+ 5. `feat(binary): four meshopt filters, one of them meep's own octahedron`
634
+ — filters 1/2/3/4, specs.
635
+ 6. `feat(binary): one entry point per compressed buffer view`
636
+ — `meshopt_decode` dispatch, spec.
637
+ 7. `feat(gltf): a compressed buffer view becomes an ordinary one`
638
+ — the binding module and its validation, under both extension names, spec.
639
+ 8. `fix(gltf): a buffer with no URI is a placeholder, not a request`
640
+ — the tiny-gltf buffer loop, GLB buffers past the chunk.
641
+ 9. `feat(gltf): the loader decodes compressed views before an accessor reads one`
642
+ — the `loadFromJson` call, the compressed-image-view throw, the end-to-end fixture and spec.
643
+
644
+ ## 8. What execution changed
645
+
646
+ Written after the work landed. The plan above is corrected in place where it was factually wrong
647
+ about the format; everything else is recorded here rather than edited away, because a plan that
648
+ quietly matches its outcome is not evidence of anything.
649
+
650
+ ### 8.1 The plan was wrong about the `0xfe`/`0xff` ordering
651
+
652
+ §3.2 claimed that computing and explicitly reading each of the three indices in turn "diverges on
653
+ the first triangle that mixes them". It does not. An index in that branch is either fresh — and
654
+ takes a turn at `next` — or explicit, and takes a varint; never both. The two passes are disjoint
655
+ per index, so interleaving them is equivalent.
656
+
657
+ Found by mutation: rewriting the branch to interleave them left all fifty-four tests green, and the
658
+ question "which test should have caught this?" has the answer "none, because there is nothing to
659
+ catch". What *is* order-dependent is the sequence of the explicit reads, because `last` chains
660
+ through them; a test with a codeaux of `0xff`, where all three indices are explicit, now pins it.
661
+
662
+ §3.2 also conflated two things about the conditional FIFO push. The *write* at a non-advancing
663
+ offset is unobservable (no well-formed stream reads distance 16). The *non-advance* is very much
664
+ observable, at any distance a later code reaches. Two tests now do.
665
+
666
+ ### 8.2 A specification erratum, in both documents
667
+
668
+ Of the three worked examples both extensions print for the varint encoding,
669
+
670
+ ```
671
+ 0x7f => 0x7f
672
+ 0x81 0x04 => 0x201
673
+ 0xff 0xa0 0x05 => 0x1fd005
674
+ ```
675
+
676
+ the third is wrong. Those bytes are the LEB128 encoding of `0x1fd005` written back to front; read as
677
+ LEB128 they are `0x1507f`, and `0x1fd005` encodes as `0x85 0xa0 0x7f`. The example only works if the
678
+ groups are read most significant first, which contradicts the example above it, the encoding the
679
+ document names, and the reference implementation.
680
+
681
+ `meshopt_read_uint_var.spec.js` pins both readings of both byte strings so that nobody later "fixes"
682
+ the reader to match the printed line.
683
+
684
+ ### 8.3 Two things the plan claimed mattered, which cannot be observed
685
+
686
+ Both were found by mutating the implementation and watching the suite stay green, and both are now
687
+ written down where they live rather than left to look like tested behaviour.
688
+
689
+ - **§6.4, the rounding mode.** `round_half_away_from_zero` cannot be told from `Math.round` through
690
+ any of the four filters. A renormalised octahedral component is a ratio with an irrational
691
+ denominator and never lands halfway between two integers — checked exhaustively over the whole
692
+ 8-bit input space, 8388477 component values, no ties — and the quaternion filter's scale is
693
+ irrational for the same reason. The colour filter's scale is rational, but its inputs are
694
+ non-negative for any valid element, and a positive tie rounds the same way either way. The helper
695
+ is kept because it is what the specifications say; the claim that a test proves it is withdrawn,
696
+ and a standing sweep now asserts the no-ties property that makes it moot.
697
+ - **§3.4, the quaternion radicand's clamp.** The output goes through an `Int16Array`, and storing a
698
+ `NaN` there yields the same zero the clamp produces. Kept so the function is total on its own
699
+ rather than by a coincidence thirty lines downstream — which is exactly the kind of thing a
700
+ refactor removes — but nothing tests it, and the spec now says so.
701
+
702
+ ### 8.4 Structure
703
+
704
+ - Planned commits 2 and 3 (attribute codec versions 0 and 1) landed as one. The block loop, the
705
+ group decoder and the channel reconstruction are shared; splitting them would have meant writing
706
+ the module twice.
707
+ - The test-only encoder §5.3 put inline in a spec file became `__meshopt_test_streams.js`, because
708
+ the end-to-end glTF fixtures need the same streams. `**/__**.js` is already how meep's coverage
709
+ configuration spells "scaffolding".
710
+ - Three test vectors in the first draft were wrong and the implementation was right: a quaternion
711
+ component stored at full scale is `1/sqrt(2)` and not 1; a quaternion whose four components are
712
+ equal has its dropped component absorb all three of the others' rounding, so it is up to three and
713
+ a half quantisation steps out rather than half a step; and a colour alpha of `0x80` is the marker
714
+ bit over an empty field, which is zero and not one. The bounds are now derived in the test from
715
+ the quantisation step rather than picked.
716
+
717
+ ### 8.5 The record
718
+
719
+ Thirty-two mutations were applied to the finished implementation to check the suite says so. Thirty
720
+ failed at least one test. The two that did not are §8.3, and are documented rather than papered over.
721
+
722
+ `npm run test` from `H:/git/moh` covers all of it; the meshopt package and its glTF binding are 96
723
+ tests across 12 files, plus 7 end-to-end through the real asset framework.
724
+
725
+ ### 8.6 What is still owed
726
+
727
+ §5.5 and §6.11 stand unchanged, and are the honest limit of this work:
728
+
729
+ **No test here decodes a stream `gltfpack` produced.** Every byte under test was authored from a
730
+ specification by me, or by a fixture encoder I also wrote. Three details — literal control mode 3's
731
+ element count, channel mode 2's rotation direction, and version 1's 24-byte tail minimum — come from
732
+ questions put to the reference rather than from specification text, and no test discriminates any of
733
+ them.
734
+
735
+ One `gltfpack -noq -cc` output and one `-cc -vv` output, checked in with a golden test that
736
+ validates every `POSITION` accessor against its own declared `min`/`max` and every index against the
737
+ vertex count, would settle all three at once. Those bounds are written by the encoder and are not
738
+ derivable from the compressed bytes.
739
+
740
+ Until then: version 0 is corroborated by the specification's own worked example, and **version 1 is
741
+ implemented and tested but not evidenced.**
742
+
743
+ ## 9. The seam this was first built on the wrong side of
744
+
745
+ The first version put the whole glTF half in one module, `gltf_meshopt_compression.js`, exporting
746
+ `gltf_meshopt_decode_buffer_views(buffer_views, buffers)`. The parser imported that by name and
747
+ called it on every model it loaded.
748
+
749
+ It worked, and every test above passed against it. It was still the wrong shape, for reasons worth
750
+ writing down because none of them is a bug:
751
+
752
+ - **The name described the caller's hope, not the function.** A thing called
753
+ `gltf_meshopt_decode_buffer_views` does not decode bufferViews. It walks all of them, works out
754
+ which are anybody's, decodes those, and rewrites the array. Three jobs under one codec's name.
755
+ - **Detection was welded to decoding.** The parser assumed meshopt by importing it, and the check
756
+ that it was meshopt happened *inside*, four frames down. Reading the call site told you nothing
757
+ about whether a plain glTF paid anything — which is exactly the question it should answer.
758
+ - **The second extension proved the point and the third would have made it.** `KHR_` was bolted on
759
+ as `if (name === MESHOPT_COMPRESSION_EXT && ...)` inside the decoder. A Draco or a future codec
760
+ would have been another module the parser imported by name, and another branch.
761
+
762
+ What replaced it is in §2.2. The parser asks a set what claims a view; the set answers with an
763
+ extension or with nothing; the walk is identical for all of them. `tiny-gltf.js` no longer contains
764
+ the string "meshopt" anywhere, comments included.
765
+
766
+ Two smaller things went the same way:
767
+
768
+ - `meshopt_decode`'s mode and filter dispatch were a seven-branch `if / else if` chain. The three
769
+ modes already share a signature and the filters already share theirs, so both are now arrays
770
+ indexed by the enum, and "none" is a function that does nothing rather than a branch that asks
771
+ whether to.
772
+ - The extension validator was fourteen `if (...) throw` in a row, several of them comparing mode and
773
+ filter names. The specifications state those constraints as a table, so it is a table: what each
774
+ mode and each filter admits of a stride and a count, with the rule's own wording carried alongside
775
+ for the message. Eight guards, none of them naming a mode.
776
+
777
+ Eight mutations were applied to the new seams to check the suite says so — the walker decoding
778
+ unclaimed views, the walker dropping its length backstop, the set taking the first claimant, the set
779
+ forgetting placeholder buffers, meshopt admitting any filter it can name, one version ceiling for
780
+ every mode, and each dispatch table shuffled. All eight fail at least one test.
781
+
782
+ ## Addendum, 2026-08-20: a document's resolved buffers are `Uint8Array`
783
+
784
+ Written into the plan as `ArrayBuffer`, and changed when the virtual-geometry builder started
785
+ reading containers through the same layer. A buffer is a *range* of bytes: a `.glb`'s binary chunk
786
+ is a range of the file it arrived in, and a buffer read off a filesystem starts wherever the runtime
787
+ put it. Carrying the offset with the bytes is what lets the chunk be handed on without copying a
788
+ model-sized allocation, and `Uint8Array.subarray` is what a decoder's source range wants anyway —
789
+ `MeshoptBufferViewExtension` reads one with `subarray` rather than a three-argument constructor that
790
+ can only be laid over an aligned offset.
791
+
792
+ `decode()` answers with a `Uint8Array` for the same reason, and the length check over it is
793
+ unchanged.