@woosh/meep-engine 3.0.2 → 3.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +188 -188
- package/README.md +152 -145
- package/editor/Editor.js +598 -598
- package/editor/EditorCameraNavigation.js +205 -205
- package/editor/EditorKeyMap.js +182 -182
- package/editor/SelectionVisualizer.js +127 -127
- package/editor/actions/concrete/ActionInvalidateSampler.js +27 -27
- package/editor/actions/concrete/PatchTerrainHeightAction.js +85 -85
- package/editor/camera/camera_framing.js +104 -104
- package/editor/clipboard.js +184 -184
- package/editor/ecs/component/editors/ObservedIntegerEditor.js +22 -22
- package/editor/ecs/component/editors/ObservedStringEditor.js +34 -34
- package/editor/ecs/component/editors/common/two_way_sync.js +50 -50
- package/editor/ecs/component/editors/ecs/GridObstacleEditor.js +19 -19
- package/editor/ecs/component/editors/ecs/ParameterLookupTableEditor.js +35 -35
- package/editor/ecs/component/editors/ecs/ParameterTrackEditor.js +17 -17
- package/editor/ecs/component/editors/ecs/SGMeshEditor.js +24 -24
- package/editor/ecs/component/editors/ecs/ShadedGeometryEditor.js +33 -33
- package/editor/ecs/component/editors/ecs/Trail3DEditor.js +45 -45
- package/editor/ecs/component/editors/ecs/buildGridObstaclePreview.js +19 -19
- package/editor/ecs/component/editors/ecs/terrain/TerrainEditor.js +72 -72
- package/editor/ecs/component/editors/shade/MeshletGeometryEditor.js +30 -30
- package/editor/ecs/component/editors/shade/ShadeImageEditor.js +70 -70
- package/editor/ecs/component/editors/shade/ShadeMaterialEditor.js +34 -34
- package/editor/ecs/component/editors/shade/ShadeTextureEditor.js +46 -46
- package/editor/ecs/component/editors/shade/StandardShadeMaterialEditor.js +24 -24
- package/editor/ecs/component/prototypeObjectEditor.js +265 -265
- package/editor/ecs/component/registerBasicTypeEditors.js +100 -100
- package/editor/ecs/component/registerEngineComponentEditors.js +95 -95
- package/editor/entity_world_bounds.js +27 -27
- package/editor/particles/lut_ops.js +148 -148
- package/editor/particles/particleEditEvents.js +12 -12
- package/editor/particles/rebuildParticleEmitter.js +31 -31
- package/editor/persistence/EditorLayoutStore.js +71 -71
- package/editor/persistence/SceneMetadata.js +52 -52
- package/editor/persistence/SceneSlotManager.js +144 -144
- package/editor/persistence/buildNewSceneDataset.js +67 -67
- package/editor/persistence/files.js +68 -68
- package/editor/persistence/scene_import.js +143 -143
- package/editor/persistence/scene_serialization.js +79 -79
- package/editor/persistence/string_buffer_codec.js +41 -41
- package/editor/process/GridDisplayProcess.js +125 -125
- package/editor/process/SymbolicDisplayProcess.js +106 -108
- package/editor/process/symbolic/CameraSymbolicDisplay.js +146 -146
- package/editor/process/symbolic/LightSymbolicDisplay.js +172 -172
- package/editor/process/symbolic/PathSymbolicDisplay.js +118 -118
- package/editor/process/symbolic/PositionedMarkerSymbolicDisplay.js +79 -79
- package/editor/process/symbolic/SoundEmitterSymbolicDisplay.js +57 -57
- package/editor/process/symbolic/SymbolicDisplay.js +62 -62
- package/editor/process/symbolic/gizmo_draw_wire_box_oriented.js +85 -85
- package/editor/process/symbolic/gizmo_draw_wire_circle.js +53 -53
- package/editor/prototypeEditorShell.js +156 -156
- package/editor/selection/editor_pick.js +130 -130
- package/editor/selection/screen_rect_frustum.js +119 -119
- package/editor/style/controls.scss +168 -168
- package/editor/style/inspector.scss +223 -223
- package/editor/templates/entity_templates.js +167 -167
- package/editor/tools/GridPaintTool.js +273 -273
- package/editor/tools/SelectionTool.js +307 -307
- package/editor/tools/TransformToolV2.js +378 -378
- package/editor/tools/engine/ToolEngine.js +188 -188
- package/editor/tools/paint/TerrainTexturePaintTool.js +250 -250
- package/editor/tools/v2/BlenderCameraOrientationGizmo.js +501 -501
- package/editor/tools/v2/TransformControls.js +971 -971
- package/editor/tools/v2/handle/gizmo_drag_plane.js +141 -141
- package/editor/tools/v2/handle/gizmo_draw.js +399 -399
- package/editor/tools/v2/handle/gizmo_handles.js +364 -364
- package/editor/tools/v2/handle/gizmo_ray_shapes.js +239 -239
- package/editor/view/ecs/HierarchicalEntityListView.js +339 -339
- package/editor/view/ecs/components/DatGuiController.js +2 -2
- package/editor/view/ecs/components/common/AutoCanvasView.js +100 -100
- package/editor/view/ecs/components/common/TextController.js +59 -59
- package/editor/view/library/MeshLibraryView.js +175 -175
- package/editor/view/library/mesh_library_drag.js +63 -63
- package/editor/view/library/model_thumbnail_source.js +86 -86
- package/editor/view/makeEntityDecorators.js +125 -125
- package/editor/view/node-graph/NodeGraphSelection.js +89 -89
- package/editor/view/node-graph/NodeView.js +211 -211
- package/editor/view/node-graph/actions/ConnectionDeleteAction.js +36 -36
- package/editor/view/node-graph/actions/NodesMoveAction.js +41 -41
- package/editor/view/node-graph/connection_wire_geometry.js +107 -107
- package/editor/view/particles/ColorLutGradientView.js +291 -291
- package/editor/view/particles/ScalarLutCurveView.js +279 -279
- package/editor/view/prepareMeshLibrary.js +188 -188
- package/editor/view/shell/SceneTreePanelView.js +119 -119
- package/editor/view/v2/SplitView.js +2 -2
- package/package.json +94 -94
- package/samples/generation/generators/interactive/mir_generator_place_buff_objects.js +362 -362
- package/src/DUPLICATION_AUDIT_2026_08_07/00_core_reuse_surface.md +738 -738
- package/src/DUPLICATION_AUDIT_2026_08_07/A_core_math_geom.md +79 -79
- package/src/DUPLICATION_AUDIT_2026_08_07/B_core_data.md +93 -93
- package/src/DUPLICATION_AUDIT_2026_08_07/C_gfx_render.md +80 -80
- package/src/DUPLICATION_AUDIT_2026_08_07/D_gfx_features.md +164 -164
- package/src/DUPLICATION_AUDIT_2026_08_07/E_physics.md +69 -69
- package/src/DUPLICATION_AUDIT_2026_08_07/F_sound.md +102 -102
- package/src/DUPLICATION_AUDIT_2026_08_07/G_net_save.md +129 -129
- package/src/DUPLICATION_AUDIT_2026_08_07/H_engine_misc.md +72 -72
- package/src/DUPLICATION_AUDIT_2026_08_07/I_generation_view.md +74 -74
- package/src/DUPLICATION_AUDIT_2026_08_07/K_crosscutting.md +169 -169
- package/src/DUPLICATION_AUDIT_2026_08_07.md +254 -254
- package/src/DUPLICATION_AUDIT_REMEDIATION.md +250 -250
- package/src/REVIEW_2026_08_06/adv-core.md +511 -511
- package/src/REVIEW_2026_08_06/adv-gfx.md +480 -480
- package/src/REVIEW_2026_08_06/adv-view.md +446 -446
- package/src/REVIEW_2026_08_06/api-core.md +296 -296
- package/src/REVIEW_2026_08_06/api-engine.md +195 -195
- package/src/REVIEW_2026_08_06/bvh-phys-sound-net.md +507 -507
- package/src/REVIEW_2026_08_06/core-binary.md +348 -348
- package/src/REVIEW_2026_08_06/core-collection.md +376 -376
- package/src/REVIEW_2026_08_06/core-math.md +221 -221
- package/src/REVIEW_2026_08_06/core-process.md +266 -266
- package/src/REVIEW_2026_08_06/core-science.md +223 -223
- package/src/REVIEW_2026_08_06/engine-ai-nav.md +279 -279
- package/src/REVIEW_2026_08_06/engine-animation.md +167 -167
- package/src/REVIEW_2026_08_06/engine-asset.md +166 -166
- package/src/REVIEW_2026_08_06/engine-ecs.md +920 -920
- package/src/REVIEW_2026_08_06/engine-input.md +197 -197
- package/src/REVIEW_2026_08_06/engine-misc.md +248 -248
- package/src/REVIEW_2026_08_06/engine-terrain.md +52 -52
- package/src/REVIEW_2026_08_06/generation.md +176 -176
- package/src/REVIEW_2026_08_06/geom-2d.md +434 -434
- package/src/REVIEW_2026_08_06/geom-3d.md +117 -117
- package/src/REVIEW_2026_08_06/gfx-gi.md +143 -143
- package/src/REVIEW_2026_08_06/gfx-render.md +740 -740
- package/src/REVIEW_2026_08_06/gfx-texture.md +690 -690
- package/src/REVIEW_2026_08_06/prior-criticals.md +49 -49
- package/src/REVIEW_2026_08_06/prior-highs.md +138 -138
- package/src/REVIEW_2026_08_06/test-gaps.md +364 -364
- package/src/REVIEW_2026_08_06/view.md +667 -667
- package/src/REVIEW_2026_08_06.md +610 -610
- package/src/avif/codec/dec/avif_dec.cpp +233 -233
- package/src/avif/codec/dec/avif_dec.js +16 -16
- package/src/core/binary/BitImage2.js +246 -246
- package/src/core/binary/align_32.js +21 -21
- package/src/core/binary/data_view/DataType2DataViewReaders.js +23 -23
- package/src/core/binary/data_view/DataType2DataViewWriters.js +25 -25
- package/src/core/binary/hash/XXH128Hash.js +55 -55
- package/src/core/binary/hash/XXH3_SECRET.js +25 -25
- package/src/core/binary/hash/xxh3_128.js +341 -341
- package/src/core/binary/hash/xxh3_64.js +241 -241
- package/src/core/binary/hash/xxh3_common.js +476 -476
- package/src/core/binary/lz4/LZ4_MAX_INPUT_SIZE.js +9 -9
- package/src/core/binary/lz4/lz4_compress_block.js +385 -385
- package/src/core/binary/lz4/lz4_compress_bound.js +25 -25
- package/src/core/binary/lz4/lz4_decompress_block.js +139 -139
- package/src/core/binary/lz4/lz4_decompress_bound.js +30 -30
- package/src/core/binary/meshopt/MESHOPT_GROUP_SIZE.js +18 -18
- package/src/core/binary/meshopt/MeshoptCompressionFilter.js +30 -30
- package/src/core/binary/meshopt/MeshoptCompressionMode.js +21 -21
- package/src/core/binary/meshopt/__meshopt_test_streams.js +237 -237
- package/src/core/binary/meshopt/meshopt_decode.js +73 -73
- package/src/core/binary/meshopt/meshopt_decode_byte_group.js +67 -67
- package/src/core/binary/meshopt/meshopt_decode_data_block.js +59 -59
- package/src/core/binary/meshopt/meshopt_decode_filter_color.js +69 -69
- package/src/core/binary/meshopt/meshopt_decode_filter_exponential.js +43 -43
- package/src/core/binary/meshopt/meshopt_decode_filter_octahedral.js +60 -60
- package/src/core/binary/meshopt/meshopt_decode_filter_quaternion.js +71 -71
- package/src/core/binary/meshopt/meshopt_decode_index_buffer.js +294 -294
- package/src/core/binary/meshopt/meshopt_decode_index_sequence.js +115 -115
- package/src/core/binary/meshopt/meshopt_decode_vertex_buffer.js +381 -381
- package/src/core/binary/meshopt/meshopt_read_uint_var.js +59 -59
- package/src/core/binary/reinterpret_float32_as_uint32.js +13 -13
- package/src/core/binary/reinterpret_uint32_as_float32.js +14 -14
- package/src/core/binary/type/DataType2TypedArrayConstructorMapping.js +35 -35
- package/src/core/bvh2/bvh3/ebvh_geometry_query_any_triangle_ray.js +149 -149
- package/src/core/bvh2/bvh3/ebvh_sort_for_traversal_depth_first.js +96 -96
- package/src/core/bvh2/bvh3/query/bvh_query_depth_range_in_frustum.js +101 -101
- package/src/core/bvh2/bvh3/query/bvh_query_leaves_generic.js +77 -77
- package/src/core/bvh2/bvh3/query/bvh_query_leaves_ray.js +90 -90
- package/src/core/bvh2/bvh3/query/bvh_query_leaves_ray_segment.js +94 -94
- package/src/core/bvh2/bvh3/query/bvh_query_user_data_generic.js +86 -86
- package/src/core/bvh2/bvh3/query/bvh_query_user_data_intersects_capsule.js +101 -101
- package/src/core/bvh2/bvh3/query/bvh_query_user_data_intersects_sphere.js +92 -92
- package/src/core/bvh2/bvh3/query/bvh_query_user_data_ray.js +96 -96
- package/src/core/bvh2/bvh3/query/bvh_query_user_data_ray_segment.js +100 -100
- package/src/core/bvh2/visual/BVHGeometry.js +131 -131
- package/src/core/bvh8/BVH8.js +436 -436
- package/src/core/bvh8/aabb3_round_to_float32.js +22 -22
- package/src/core/bvh8/build/BVH8Converter.js +588 -588
- package/src/core/bvh8/build/TriangleCluster.js +122 -122
- package/src/core/bvh8/build/aabb3_compute_merge_cost.js +28 -28
- package/src/core/bvh8/build/aabb3_from_triangle_by_index.js +17 -17
- package/src/core/bvh8/build/bvh8_build_for_geometry.js +303 -303
- package/src/core/bvh8/build/bvh8_from_proxy.js +256 -256
- package/src/core/bvh8/build/byte.js +9 -9
- package/src/core/bvh8/build/encode_bounds_e.js +11 -11
- package/src/core/bvh8/bvh8_convert_to_dot.js +132 -132
- package/src/core/bvh8/bvh8_count_primitives.js +98 -98
- package/src/core/bvh8/bvh8_geometry_validate.js +138 -138
- package/src/core/bvh8/bvh8_geometry_validate_indirect.js +166 -166
- package/src/core/bvh8/bvh8_get_node_bounds.js +34 -34
- package/src/core/bvh8/bvh8_get_node_child_bounds.js +52 -52
- package/src/core/bvh8/bvh8_node_child_surface_area.js +18 -18
- package/src/core/bvh8/bvh8_node_count_triangles.js +27 -27
- package/src/core/bvh8/bvh8_quality.js +72 -72
- package/src/core/bvh8/bvh8_validate_structure.js +87 -87
- package/src/core/clipboard/obtainClipBoard.js +29 -29
- package/src/core/clipboard/safeClipboardReadText.js +55 -55
- package/src/core/clipboard/safeClipboardWriteText.js +23 -23
- package/src/core/collection/array/typed/typed_array_value_denormalize.js +52 -52
- package/src/core/collection/array/typed/typed_array_value_normalize.js +51 -51
- package/src/core/collection/union-find/union_find.js +79 -79
- package/src/core/color/YCoCg/rgb_to_ycocg.js +20 -20
- package/src/core/color/YCoCg/ycocg_to_rgb.js +17 -17
- package/src/core/color/colormap/MAGMA_LUT.js +26 -26
- package/src/core/color/illuminant/D65_TRISTIMULUS_XYZ.js +19 -19
- package/src/core/color/lab/lab_apply_hunt_adjustment.js +27 -27
- package/src/core/color/lab/lab_distance_hyab.js +23 -23
- package/src/core/color/lab/xyz_to_lab.js +62 -62
- package/src/core/color/operations/color_darken.js +24 -24
- package/src/core/color/operations/color_desaturate.js +24 -24
- package/src/core/color/operations/color_lighten.js +24 -24
- package/src/core/color/operations/color_saturate.js +24 -24
- package/src/core/color/operations/color_scale_okhsv_channel.js +45 -45
- package/src/core/color/tonemap/tonemap_aces.js +41 -41
- package/src/core/color/ycxcz/xyz_to_ycxcz.js +28 -28
- package/src/core/color/ycxcz/ycxcz_to_xyz.js +19 -19
- package/src/core/dom/isImageBitmap.js +12 -12
- package/src/core/function/frameThrottle.js +23 -23
- package/src/core/geom/2d/aabb/aabb2_array_combine.js +7 -7
- package/src/core/geom/2d/aabb/aabb2_compute_area.js +7 -7
- package/src/core/geom/2d/aabb/aabb2_compute_center_from_multiple.js +7 -7
- package/src/core/geom/2d/aabb/aabb2_compute_overlap.js +7 -7
- package/src/core/geom/2d/aabb/aabb2_from_v2_array.js +7 -7
- package/src/core/geom/2d/aabb/aabb2_intersects_point.js +7 -7
- package/src/core/geom/2d/aabb/aabb2_overlap_exists.js +7 -7
- package/src/core/geom/2d/circle/circle_compute_circle_intersection.js +7 -7
- package/src/core/geom/2d/circle/circle_compute_circle_penetration.js +7 -7
- package/src/core/geom/2d/circle/circle_intersects_point.js +7 -7
- package/src/core/geom/2d/compute_polygon_area_2d.js +7 -7
- package/src/core/geom/2d/convex-hull/fixed_convex_hull_humus.js +7 -7
- package/src/core/geom/2d/convex-hull/fixed_convex_hull_relaxation.js +7 -7
- package/src/core/geom/2d/convex-hull/orientation3_array.js +7 -7
- package/src/core/geom/2d/intersect_ray_2d.js +7 -7
- package/src/core/geom/2d/line/line2_distance_to_point_sqr.js +7 -7
- package/src/core/geom/2d/line/line2_segment_intersection_fraction_2d.js +44 -44
- package/src/core/geom/2d/line/line_segment_compute_line_segment_intersection_2d.js +7 -7
- package/src/core/geom/2d/line/line_segment_compute_line_segment_intersection_array_2d.js +7 -7
- package/src/core/geom/2d/line/line_segment_compute_line_segment_intersection_vectors_2d.js +7 -7
- package/src/core/geom/2d/line/line_segment_compute_line_segment_intersection_vectors_array_2d.js +7 -7
- package/src/core/geom/2d/line/line_segment_intersection_fraction_2d.js +7 -7
- package/src/core/geom/2d/line/line_segment_line_segment_intersection_exists_2d.js +7 -7
- package/src/core/geom/2d/line/segment2_intersects_segment2_2d.js +25 -25
- package/src/core/geom/2d/line/segment2_segment_compute_intersection_array_2d.js +46 -46
- package/src/core/geom/2d/line/segment2_segment_intersection_fractions.js +52 -52
- package/src/core/geom/2d/oriented-box/min_area_rect_2d.js +69 -69
- package/src/core/geom/2d/polygon/TRIANGULATION_DESIGN.md +433 -433
- package/src/core/geom/2d/polygon/polygon2_clip_axis_halfplane.js +51 -51
- package/src/core/geom/2d/polygon/polygon2_clip_halfplane.js +50 -50
- package/src/core/geom/2d/polygon/polygon2_is_counter_clockwise.js +84 -84
- package/src/core/geom/2d/polygon/polygon2_signed_area.js +52 -52
- package/src/core/geom/2d/polygon/polygon2_triangulate.corpus.js +86 -86
- package/src/core/geom/2d/polygon/polygon2_triangulate.js +1280 -1280
- package/src/core/geom/2d/polygon/polygon2_triangulation_deviation.js +77 -77
- package/src/core/geom/2d/quad-tree/qt_collect_by_circle.js +39 -39
- package/src/core/geom/2d/quad-tree/qt_match_data_by_circle.js +101 -101
- package/src/core/geom/2d/quad-tree/qt_query_data_nearest_to_point.js +7 -7
- package/src/core/geom/2d/rectangle_to_aabb.js +7 -7
- package/src/core/geom/2d/spline_bezier2_2d.js +7 -7
- package/src/core/geom/2d/triangle/tri2_rasterize_conservative.js +99 -99
- package/src/core/geom/2d/triangle/tri2_signed_area.js +35 -35
- package/src/core/geom/2d/triangle2d_compute_area.js +7 -7
- package/src/core/geom/2d/triangle2d_contains_point.js +7 -7
- package/src/core/geom/2d/triangle2d_get_barycentric.js +7 -7
- package/src/core/geom/2d/v2_morton_encode.js +23 -23
- package/src/core/geom/3d/aabb/aabb3_array_intersects_frustum_degree.js +7 -7
- package/src/core/geom/3d/aabb/aabb3_box_surface_area_2.js +7 -7
- package/src/core/geom/3d/aabb/aabb3_build_frustum.js +5 -5
- package/src/core/geom/3d/aabb/aabb3_closest_point_on_surface.js +57 -57
- package/src/core/geom/3d/aabb/aabb3_combined_surface_area.js +7 -7
- package/src/core/geom/3d/aabb/aabb3_compute_half_surface_area.js +7 -7
- package/src/core/geom/3d/aabb/aabb3_compute_projected_area.js +7 -7
- package/src/core/geom/3d/aabb/aabb3_compute_surface_area.js +7 -7
- package/src/core/geom/3d/aabb/aabb3_detailed_volume_intersection.js +7 -7
- package/src/core/geom/3d/aabb/aabb3_estimate_projected_area2.js +7 -7
- package/src/core/geom/3d/aabb/aabb3_from_threejs_geometry.js +7 -7
- package/src/core/geom/3d/aabb/aabb3_from_triangle_group.js +46 -46
- package/src/core/geom/3d/aabb/aabb3_intersects_frustum_degree.js +7 -7
- package/src/core/geom/3d/aabb/aabb3_intersects_line_segment.js +7 -7
- package/src/core/geom/3d/aabb/aabb3_near_distance_to_intersection_ray_segment.js +7 -7
- package/src/core/geom/3d/aabb/aabb3_nearest_point_on_surface.js +7 -7
- package/src/core/geom/3d/aabb/aabb3_ray_segment_entry_distance.js +95 -95
- package/src/core/geom/3d/aabb/aabb3_raycast.js +7 -7
- package/src/core/geom/3d/aabb/aabb3_transform_oriented.js +93 -93
- package/src/core/geom/3d/aabb/aabb3_transform_oriented_inverse.js +82 -82
- package/src/core/geom/3d/aabb/compute_aabb_from_points.js +7 -7
- package/src/core/geom/3d/aabb/compute_triangle_group_aabb3.js +7 -7
- package/src/core/geom/3d/atlas/ATLAS_PORT_PLAN.md +486 -486
- package/src/core/geom/3d/atlas/BFF_PLAN.md +174 -174
- package/src/core/geom/3d/atlas/Chart.js +77 -77
- package/src/core/geom/3d/atlas/REVIEW_02.md +392 -392
- package/src/core/geom/3d/atlas/atlas_bench_lib.js +315 -315
- package/src/core/geom/3d/atlas/atlas_chart_type.js +16 -16
- package/src/core/geom/3d/atlas/atlas_compute_charts.js +188 -188
- package/src/core/geom/3d/atlas/atlas_extract_chart.js +107 -107
- package/src/core/geom/3d/atlas/atlas_generate.js +50 -50
- package/src/core/geom/3d/atlas/atlas_test_fixtures.js +266 -266
- package/src/core/geom/3d/atlas/atlas_write_chart_uvs.js +36 -36
- package/src/core/geom/3d/atlas/data/atlas_build_edge_dihedrals.js +62 -62
- package/src/core/geom/3d/atlas/data/atlas_build_edge_lengths.js +33 -33
- package/src/core/geom/3d/atlas/data/atlas_build_face_areas.js +50 -50
- package/src/core/geom/3d/atlas/io/atlas_mesh_weld_colocals.js +39 -39
- package/src/core/geom/3d/atlas/io/bt_loop_uv.js +35 -35
- package/src/core/geom/3d/atlas/pack/ChartPlacement.js +46 -46
- package/src/core/geom/3d/atlas/param/atlas_chart_parameterize_bff.js +269 -269
- package/src/core/geom/3d/atlas/param/atlas_chart_parameterize_lscm.js +209 -209
- package/src/core/geom/3d/atlas/param/atlas_chart_parameterize_ortho.js +38 -38
- package/src/core/geom/3d/atlas/param/atlas_chart_stretch_metric.js +86 -86
- package/src/core/geom/3d/atlas/param/atlas_piecewise_resegment.js +183 -183
- package/src/core/geom/3d/atlas/param/fit_plane_basis.js +66 -66
- package/src/core/geom/3d/atlas/segment/RegionGraph.js +40 -40
- package/src/core/geom/3d/atlas/segment/atlas_build_region_graph.js +136 -136
- package/src/core/geom/3d/atlas/segment/atlas_chart_roundness_delta.js +30 -30
- package/src/core/geom/3d/atlas/segment/atlas_compute_planar_regions.js +77 -77
- package/src/core/geom/3d/atlas/segment/atlas_merge_charts.js +116 -116
- package/src/core/geom/3d/atlas/segment/atlas_segment_charts.js +271 -271
- package/src/core/geom/3d/atlas/segment/atlas_segment_charts_atomic.js +191 -191
- package/src/core/geom/3d/box/box3_projected_half_extent.js +35 -35
- package/src/core/geom/3d/capsule/capsule_intersects_aabb3_closed.js +67 -67
- package/src/core/geom/3d/capsule/capsule_intersects_aabb3_iterative.js +137 -137
- package/src/core/geom/3d/compute_circle_bounding_box.js +7 -7
- package/src/core/geom/3d/cone/computeConeBoundingBox.js +7 -7
- package/src/core/geom/3d/cone/computeConePlaneSide.js +7 -7
- package/src/core/geom/3d/cone/compute_bounding_cone_of_2_cones.js +7 -7
- package/src/core/geom/3d/cylinder/cylinder3_raycast.d.ts +38 -0
- package/src/core/geom/3d/cylinder/cylinder3_raycast.d.ts.map +1 -0
- package/src/core/geom/3d/cylinder/cylinder3_raycast.js +105 -0
- package/src/core/geom/3d/equirectangular/equirectangular_direction_to_uv.js +18 -18
- package/src/core/geom/3d/equirectangular/equirectangular_uv_to_direction.js +24 -24
- package/src/core/geom/3d/frustum/clipping_volume_matrix4_project.js +7 -7
- package/src/core/geom/3d/frustum/frustum3_computeNearestPointToPoint.js +7 -7
- package/src/core/geom/3d/frustum/frustum3_compute_closest_point.js +117 -117
- package/src/core/geom/3d/frustum/frustum_matrix4_project.js +7 -7
- package/src/core/geom/3d/frustum/hexahedron_from_aabb.js +7 -7
- package/src/core/geom/3d/frustum/read_frustum_corner.js +17 -17
- package/src/core/geom/3d/frustum/read_three_planes_to_array.js +7 -7
- package/src/core/geom/3d/frustum/slice_frustum_linear_to_points.js +7 -7
- package/src/core/geom/3d/gjk/GJK_REVIEW_NOTES.md +146 -146
- package/src/core/geom/3d/gjk/gjk.js +430 -430
- package/src/core/geom/3d/gjk/gjk_epa_penetration.js +520 -520
- package/src/core/geom/3d/gjk/minkowski_support.js +71 -71
- package/src/core/geom/3d/gjk/mpr.js +368 -368
- package/src/core/geom/3d/line/line3_closest_points_segment_segment.js +7 -7
- package/src/core/geom/3d/line/line3_compute_nearest_point_to_point.js +7 -7
- package/src/core/geom/3d/line/line3_compute_point_segment_point_distance_unfolded.js +64 -64
- package/src/core/geom/3d/line/line3_compute_segment_closest_point_to_aabb3_t.js +153 -153
- package/src/core/geom/3d/line/line3_compute_segment_nearest_point_to_aabb3_t.js +7 -7
- package/src/core/geom/3d/line/line3_compute_segment_nearest_point_to_point_t.js +7 -7
- package/src/core/geom/3d/line/line3_compute_segment_segment_closest_points.js +88 -88
- package/src/core/geom/3d/line/line3_segment_segment_closest_point_pair.js +71 -71
- package/src/core/geom/3d/line/segment3_point_distance_to_segments.js +25 -25
- package/src/core/geom/3d/mat4/allocate_m4.js +7 -7
- package/src/core/geom/3d/mat4/apply_mat4_transform_to_direction_v3_array.js +7 -7
- package/src/core/geom/3d/mat4/apply_mat4_transform_to_v3_array.js +7 -7
- package/src/core/geom/3d/mat4/compose_matrix4_array.js +7 -7
- package/src/core/geom/3d/mat4/decompose_matrix_4_array.js +7 -7
- package/src/core/geom/3d/mat4/eulerAnglesFromMatrix.js +7 -7
- package/src/core/geom/3d/mat4/m4_compose.js +22 -22
- package/src/core/geom/3d/mat4/m4_compute_normal_matrix3.js +7 -7
- package/src/core/geom/3d/mat4/m4_decompose.js +64 -64
- package/src/core/geom/3d/mat4/m4_decompose_array.js +157 -157
- package/src/core/geom/3d/mat4/m4_from_rotation_translation_scale.js +32 -32
- package/src/core/geom/3d/mat4/m4_from_rotation_translation_scale_scalar.js +67 -67
- package/src/core/geom/3d/mat4/m4_linear_matrix3.js +29 -29
- package/src/core/geom/3d/mat4/m4_look_at.js +96 -96
- package/src/core/geom/3d/mat4/m4_make_rotation_x.js +47 -47
- package/src/core/geom/3d/mat4/m4_make_rotation_y.js +47 -47
- package/src/core/geom/3d/mat4/m4_make_rotation_z.js +47 -47
- package/src/core/geom/3d/mat4/m4_normal_matrix3.js +39 -39
- package/src/core/geom/3d/mat4/m4_perspective.js +66 -66
- package/src/core/geom/3d/mat4/m4_transpose.js +48 -48
- package/src/core/geom/3d/morton/mortonEncode_LUT.js +7 -7
- package/src/core/geom/3d/morton/mortonEncode_magicbits.js +7 -7
- package/src/core/geom/3d/normal/hemioct/encode_unit3_hemioct.js +5 -5
- package/src/core/geom/3d/normal/hemioct/encode_unit_to_hemioct.js +28 -28
- package/src/core/geom/3d/normal/lambert_azimuth/decode_azimuth_to_unit.js +30 -30
- package/src/core/geom/3d/normal/lambert_azimuth/encode_unit_to_azimuth.js +19 -19
- package/src/core/geom/3d/normal/spherical/decode_spheremap_to_unit.js +38 -38
- package/src/core/geom/3d/normal/spherical/encode_unit_to_spheremap.js +30 -30
- package/src/core/geom/3d/plane/is_point_within_planes.js +7 -7
- package/src/core/geom/3d/plane/orient3d_fast_point.js +47 -47
- package/src/core/geom/3d/plane/plane3_compute_convex_3_plane_intersection.js +7 -7
- package/src/core/geom/3d/plane/plane3_compute_plane_intersection.js +7 -7
- package/src/core/geom/3d/plane/plane3_intersect_plane.js +7 -7
- package/src/core/geom/3d/plane/plane3_three_compute_convex_3_plane_intersection.js +7 -7
- package/src/core/geom/3d/point/point3_raycast.d.ts +33 -0
- package/src/core/geom/3d/point/point3_raycast.d.ts.map +1 -0
- package/src/core/geom/3d/point/point3_raycast.js +47 -0
- package/src/core/geom/3d/polygon/polygon3_compute_normal.js +60 -60
- package/src/core/geom/3d/polygon/polygon3_triangulate.js +94 -94
- package/src/core/geom/3d/polyhedron/convex_polyhedron3_raycast.d.ts +40 -0
- package/src/core/geom/3d/polyhedron/convex_polyhedron3_raycast.d.ts.map +1 -0
- package/src/core/geom/3d/polyhedron/convex_polyhedron3_raycast.js +94 -0
- package/src/core/geom/3d/quadric/QUADRIC3_SIZE.js +14 -14
- package/src/core/geom/3d/quadric/Quadric3.js +282 -282
- package/src/core/geom/3d/quadric/quadric3_add.js +33 -33
- package/src/core/geom/3d/quadric/quadric3_clear.js +25 -25
- package/src/core/geom/3d/quadric/quadric3_copy.js +27 -27
- package/src/core/geom/3d/quadric/quadric3_distance.js +36 -36
- package/src/core/geom/3d/quadric/quadric3_evaluate.js +25 -25
- package/src/core/geom/3d/quadric/quadric3_optimize.js +45 -45
- package/src/core/geom/3d/quadric/quadric3_scale.js +32 -32
- package/src/core/geom/3d/quadric/quadric3_set_from_plane_through_point.js +30 -30
- package/src/core/geom/3d/quadric/quadric3_set_from_vector4.js +35 -35
- package/src/core/geom/3d/quadric/quadric3_sub.js +36 -36
- package/src/core/geom/3d/quadric/quadric3_to_tensor_m3.js +28 -28
- package/src/core/geom/3d/quadric/quadric3_to_tensor_m3_inverse.js +56 -56
- package/src/core/geom/3d/quadric/quadric3_to_vector3.js +19 -19
- package/src/core/geom/3d/quaternion/quat3_createFromAxisAngle.js +7 -7
- package/src/core/geom/3d/quaternion/quat3_integrate.js +62 -62
- package/src/core/geom/3d/quaternion/quat3_multiply.js +31 -31
- package/src/core/geom/3d/quaternion/quat3_nlerp.js +72 -72
- package/src/core/geom/3d/quaternion/quat3_to_matrix3.js +69 -69
- package/src/core/geom/3d/quaternion/quat_decode_from_uint32.js +7 -7
- package/src/core/geom/3d/quaternion/quat_encode_to_uint32.js +7 -7
- package/src/core/geom/3d/ray/ray3_array_compose.js +7 -7
- package/src/core/geom/3d/ray/ray3_compute_nearest_point_to_point.js +7 -7
- package/src/core/geom/3d/ray/ray3_distance_to_point.js +7 -7
- package/src/core/geom/3d/ray/ray3_shift_origin_along_direction.js +7 -7
- package/src/core/geom/3d/shape/ConvexHullShape3D.d.ts +17 -0
- package/src/core/geom/3d/shape/ConvexHullShape3D.d.ts.map +1 -1
- package/src/core/geom/3d/shape/ConvexHullShape3D.js +43 -0
- package/src/core/geom/3d/shape/CylinderShape3D.d.ts +1 -0
- package/src/core/geom/3d/shape/CylinderShape3D.d.ts.map +1 -1
- package/src/core/geom/3d/shape/CylinderShape3D.js +21 -0
- package/src/core/geom/3d/shape/PointShape3D.d.ts +7 -0
- package/src/core/geom/3d/shape/PointShape3D.d.ts.map +1 -1
- package/src/core/geom/3d/shape/PointShape3D.js +88 -63
- package/src/core/geom/3d/shape/PosedShape3D.d.ts +6 -0
- package/src/core/geom/3d/shape/PosedShape3D.d.ts.map +1 -1
- package/src/core/geom/3d/shape/PosedShape3D.js +27 -0
- package/src/core/geom/3d/shape/TransformedShape3D.d.ts +10 -0
- package/src/core/geom/3d/shape/TransformedShape3D.d.ts.map +1 -1
- package/src/core/geom/3d/shape/TransformedShape3D.js +13 -0
- package/src/core/geom/3d/shape/Triangle3D.d.ts +1 -0
- package/src/core/geom/3d/shape/Triangle3D.d.ts.map +1 -1
- package/src/core/geom/3d/shape/Triangle3D.js +26 -0
- package/src/core/geom/3d/shape/UnionShape3D.d.ts +6 -0
- package/src/core/geom/3d/shape/UnionShape3D.d.ts.map +1 -1
- package/src/core/geom/3d/shape/UnionShape3D.js +7 -0
- package/src/core/geom/3d/shape/UnitCubeShape3D.js +45 -45
- package/src/core/geom/3d/shape/UnitSphereShape3D.js +44 -44
- package/src/core/geom/3d/shape/shape3_mesh_from_geometry.js +64 -64
- package/src/core/geom/3d/shape/shape_mesh_from_geometry.js +7 -7
- package/src/core/geom/3d/shape/util/compute_signed_distance_gradient_by_sampling.js +51 -51
- package/src/core/geom/3d/shape/util/shape3d_voxelize_to_grid.js +7 -7
- package/src/core/geom/3d/sphere/compute_bounding_sphere_of_2_spheres.js +7 -7
- package/src/core/geom/3d/sphere/harmonics/sh3_convolve_with_zh.js +53 -53
- package/src/core/geom/3d/sphere/harmonics/sh3_ggx_zh.js +30 -30
- package/src/core/geom/3d/sphere/harmonics/sh3_rotate_bl.js +7 -7
- package/src/core/geom/3d/sphere/harmonics/sh_compute_K.js +7 -7
- package/src/core/geom/3d/sphere/sphere_array_intersects_point.js +7 -7
- package/src/core/geom/3d/sphere/sphere_array_intersects_ray.js +7 -7
- package/src/core/geom/3d/sphere/sphere_intersects_point.js +7 -7
- package/src/core/geom/3d/sphere/sphere_matrix4_transform.js +5 -5
- package/src/core/geom/3d/sphere/sphere_projected_sphere_radius_sqr.js +7 -7
- package/src/core/geom/3d/sphere/sphere_radius_sqr_from_v3_array_transformed.js +7 -7
- package/src/core/geom/3d/sphere/spherical_from_cartesian.js +7 -7
- package/src/core/geom/3d/tetrahedra/compute_tetrahedral_mesh_from_surface.js +174 -174
- package/src/core/geom/3d/tetrahedra/compute_tetrahedron_quality.js +7 -7
- package/src/core/geom/3d/tetrahedra/compute_tetrahedron_volume.js +7 -7
- package/src/core/geom/3d/tetrahedra/delaunay/fill_in_a_cavity.js +7 -7
- package/src/core/geom/3d/tetrahedra/graphics/build_tetrahedral_mesh_geometry.js +39 -39
- package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_build_vertex_to_tets_map.js +48 -48
- package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_carve_outside_surface.js +173 -173
- package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_compute_tet_quality.js +22 -22
- package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_find_tets_around_edge.js +146 -146
- package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_flip_23.js +232 -232
- package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_flip_32.js +255 -255
- package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_improve_quality.js +387 -387
- package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_smooth_vertex.js +140 -140
- package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_tet_get_neighbours.js +7 -7
- package/src/core/geom/3d/tetrahedra/tetrahedral_mesh_vertex_is_boundary.js +97 -97
- package/src/core/geom/3d/tetrahedra/tetrahedron_compute_quality.js +66 -66
- package/src/core/geom/3d/tetrahedra/triangle/triangle_decode_depth.js +59 -59
- package/src/core/geom/3d/tetrahedra/triangle/triangle_rasterized_depth_sample_index.js +54 -54
- package/src/core/geom/3d/tetrahedra/validate_neighbour.js +70 -70
- package/src/core/geom/3d/topology/struct/binary/BinaryDataBlock.js +314 -314
- package/src/core/geom/3d/topology/struct/binary/BinaryDataLayer.js +364 -364
- package/src/core/geom/3d/topology/struct/binary/BinaryElementPool.js +567 -567
- package/src/core/geom/3d/topology/struct/binary/BinaryTopology.js +1085 -1085
- package/src/core/geom/3d/topology/struct/binary/io/bt_boundary_loop.js +73 -73
- package/src/core/geom/3d/topology/struct/binary/io/bt_loop_kill.js +35 -35
- package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_append.js +119 -119
- package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_close_boundary_holes.js +84 -84
- package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_compact.js +172 -172
- package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_compute_face_normals.js +56 -56
- package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_compute_vertex_quadratics.js +7 -7
- package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_compute_vertex_quadrics.js +227 -227
- package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_face_decouple.js +161 -161
- package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_face_island_erode.js +490 -490
- package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_fill_small_holes.js +120 -120
- package/src/core/geom/3d/topology/struct/binary/io/bt_mesh_from_indexed_geometry.js +120 -120
- package/src/core/geom/3d/topology/struct/binary/io/edge/bt_edge_collapse.js +52 -52
- package/src/core/geom/3d/topology/struct/binary/io/edge/bt_edge_create.js +115 -115
- package/src/core/geom/3d/topology/struct/binary/io/edge/bt_edge_flip.js +142 -142
- package/src/core/geom/3d/topology/struct/binary/io/edge/bt_edge_get_or_create.js +21 -21
- package/src/core/geom/3d/topology/struct/binary/io/edge/bt_edge_kill_parallels.js +92 -92
- package/src/core/geom/3d/topology/struct/binary/io/edge/bt_edge_split.js +179 -179
- package/src/core/geom/3d/topology/struct/binary/io/edge/bt_edge_swap_vertex_slots.js +28 -28
- package/src/core/geom/3d/topology/struct/binary/io/edge/bt_kill_only_edge.js +8 -8
- package/src/core/geom/3d/topology/struct/binary/io/edge/bt_mesh_fuse_duplicate_edges.js +83 -83
- package/src/core/geom/3d/topology/struct/binary/io/edge/bt_mesh_kill_short_edges.js +89 -89
- package/src/core/geom/3d/topology/struct/binary/io/face/bt_face_kill.js +25 -25
- package/src/core/geom/3d/topology/struct/binary/io/face/bt_face_poke.js +127 -127
- package/src/core/geom/3d/topology/struct/binary/io/face/bt_face_triangulate.js +268 -268
- package/src/core/geom/3d/topology/struct/binary/io/face/bt_kill_only_face.js +8 -8
- package/src/core/geom/3d/topology/struct/binary/io/face/bt_mesh_kill_degenerate_faces.js +72 -72
- package/src/core/geom/3d/topology/struct/binary/io/vertex/bt_kill_only_vert.js +7 -7
- package/src/core/geom/3d/topology/struct/binary/io/vertex/bt_merge_verts_by_distance.js +7 -7
- package/src/core/geom/3d/topology/struct/binary/io/vertex/bt_mesh_relative_merge_distance.js +48 -48
- package/src/core/geom/3d/topology/struct/binary/io/vertex/bt_mesh_split_pinched_vertices.js +256 -256
- package/src/core/geom/3d/topology/struct/binary/io/vertex/bt_mesh_vertex_merge_distance.js +77 -77
- package/src/core/geom/3d/topology/struct/binary/io/vertex/bt_vert_fuse_duplicate_edges.js +7 -7
- package/src/core/geom/3d/topology/struct/binary/io/vertex/bt_vert_kill.js +7 -7
- package/src/core/geom/3d/topology/struct/binary/io/vertex/bt_vertex_fuse_duplicate_edges.js +148 -148
- package/src/core/geom/3d/topology/struct/binary/io/vertex/bt_vertex_kill_only.js +7 -7
- package/src/core/geom/3d/topology/struct/binary/query/bt_collect_boundary_segments.js +29 -29
- package/src/core/geom/3d/topology/struct/binary/query/bt_edge_collapse_breaks_link_condition.js +107 -107
- package/src/core/geom/3d/topology/struct/binary/query/bt_edge_flip_is_legal.js +41 -41
- package/src/core/geom/3d/topology/struct/binary/query/bt_edge_flip_would_fold.js +120 -120
- package/src/core/geom/3d/topology/struct/binary/query/bt_edge_get.js +42 -42
- package/src/core/geom/3d/topology/struct/binary/query/bt_edge_is_boundary.js +20 -20
- package/src/core/geom/3d/topology/struct/binary/query/bt_edge_read_diamond.js +96 -96
- package/src/core/geom/3d/topology/struct/binary/query/bt_face_compute_newell_normal.js +72 -72
- package/src/core/geom/3d/topology/struct/binary/query/bt_face_get_attached_faces.js +7 -7
- package/src/core/geom/3d/topology/struct/binary/query/bt_face_get_edge_adjacent_faces.js +39 -39
- package/src/core/geom/3d/topology/struct/binary/query/bt_face_get_edge_adjacent_faces_weighted.js +93 -93
- package/src/core/geom/3d/topology/struct/binary/query/bt_face_get_neighbour_faces.js +7 -7
- package/src/core/geom/3d/topology/struct/binary/query/bt_face_get_shared_loop.js +48 -48
- package/src/core/geom/3d/topology/struct/binary/query/bt_face_island_flood_fill.js +45 -45
- package/src/core/geom/3d/topology/struct/binary/query/bt_face_read_triangle.js +66 -66
- package/src/core/geom/3d/topology/struct/binary/query/bt_faces_shared_loop.js +7 -7
- package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_assert_valid.js +44 -44
- package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_build_boundary_euclidean_distance_field.js +32 -32
- package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_compute_face_islands.js +53 -53
- package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_face_find_path.js +703 -703
- package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_sample_interior_grid_points.js +181 -181
- package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_segment_penetrates_surface.js +133 -133
- package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_surface_ray_parity.js +82 -82
- package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_validate.js +599 -599
- package/src/core/geom/3d/topology/struct/binary/query/bt_mesh_walk_boundary_loops.js +108 -108
- package/src/core/geom/3d/topology/struct/binary/query/bt_query_edge_is_boundary.js +7 -7
- package/src/core/geom/3d/triangle/computeTriangleClosestPointToPointBarycentric.js +7 -7
- package/src/core/geom/3d/triangle/computeTriangleRayIntersection.js +7 -7
- package/src/core/geom/3d/triangle/computeTriangleRayIntersectionBarycentric.js +7 -7
- package/src/core/geom/3d/triangle/computeTriangleRayIntersectionBarycentricEdge.js +7 -7
- package/src/core/geom/3d/triangle/computeTriangleRayIntersectionBarycentricGeometry.js +7 -7
- package/src/core/geom/3d/triangle/compute_triangle_area_3d.js +7 -7
- package/src/core/geom/3d/triangle/compute_triangle_normal.js +7 -7
- package/src/core/geom/3d/triangle/rayTriangleIntersection.js +7 -7
- package/src/core/geom/3d/triangle/tri3_closest_point.js +65 -65
- package/src/core/geom/3d/triangle/tri3_closest_point_barycentric.js +171 -171
- package/src/core/geom/3d/triangle/tri3_flatten_isometric.js +79 -79
- package/src/core/geom/3d/triangle/tri3_ray_intersection.js +160 -160
- package/src/core/geom/3d/triangle/tri3_ray_intersection_barycentric.js +96 -96
- package/src/core/geom/3d/triangle/tri3_raycast.d.ts +42 -0
- package/src/core/geom/3d/triangle/tri3_raycast.d.ts.map +1 -0
- package/src/core/geom/3d/triangle/tri3_raycast.js +94 -0
- package/src/core/geom/3d/triangle/triangle3_incenter.js +7 -7
- package/src/core/geom/3d/triangle/triangle_compute_plane_side.js +7 -7
- package/src/core/geom/3d/triangle/triangle_compute_signed_volume.js +7 -7
- package/src/core/geom/3d/triangle/triangle_intersects_clipping_volume.js +7 -7
- package/src/core/geom/3d/triangle/triangle_mesh_compute_signed_volume.js +7 -7
- package/src/core/geom/3d/triangle/v3_compute_triangle_normal.js +7 -7
- package/src/core/geom/3d/util/make_justified_point_grid.js +7 -7
- package/src/core/geom/GEOMETRY_REVIEW_002_API_ISSUES.md +381 -381
- package/src/core/geom/GEOMETRY_REVIEW_002_NAMING.md +684 -684
- package/src/core/geom/MANIFOLD_COMPARISON_2026_08_01.md +554 -554
- package/src/core/geom/mat3/m3_cm_from_translation.js +7 -7
- package/src/core/geom/mat3/m3_cm_invert.js +7 -7
- package/src/core/geom/mat3/m3_make_rotation.js +5 -5
- package/src/core/geom/mat3/m3_make_rotation_TBN.js +31 -31
- package/src/core/geom/mat3/m3_multiply_vec3.js +7 -7
- package/src/core/geom/packing/computeBoundingSphereOfSpheres.js +7 -7
- package/src/core/geom/packing/max-rect/cost/costByBestShortSide.js +7 -7
- package/src/core/geom/packing/max-rect/cost/costByRemainingArea.js +7 -7
- package/src/core/geom/packing/max-rect/cutArea.js +7 -7
- package/src/core/geom/packing/max-rect/findBestContainer.js +7 -7
- package/src/core/geom/packing/max-rect/packMaxRectangles.js +7 -7
- package/src/core/geom/packing/max-rect/packOneBox.js +7 -7
- package/src/core/geom/packing/max-rect/removeRedundantBoxes.js +7 -7
- package/src/core/geom/packing/max-rect/removeRedundantBoxesArray.js +7 -7
- package/src/core/geom/random/randomPointInBox.js +7 -7
- package/src/core/geom/random/randomPointInCircle.js +7 -7
- package/src/core/geom/random/randomPointInPoint.js +7 -7
- package/src/core/geom/random/randomPointInSphere.js +7 -7
- package/src/core/geom/random/randomPointOnBox.js +7 -7
- package/src/core/geom/random/randomPointOnSphere.js +7 -7
- package/src/core/geom/random/random_orthonormal_basis.js +31 -31
- package/src/core/geom/vec/vector_axpy.js +15 -15
- package/src/core/geom/vec/vector_axpy_offset.js +20 -20
- package/src/core/geom/vec/vector_copy.js +7 -7
- package/src/core/geom/vec/vector_dot_offset.js +25 -25
- package/src/core/geom/vec/vector_scale_array.js +7 -7
- package/src/core/geom/vec2/v2_rotate.js +21 -21
- package/src/core/geom/vec2/v2_rotate_cos_sin.js +21 -21
- package/src/core/geom/vec3/v3_angle_atan2_between.js +7 -7
- package/src/core/geom/vec3/v3_angle_between.js +7 -7
- package/src/core/geom/vec3/v3_angle_cos_between.js +7 -7
- package/src/core/geom/vec3/v3_array_add_in_place.js +7 -7
- package/src/core/geom/vec3/v3_array_centroid.js +7 -7
- package/src/core/geom/vec3/v3_array_copy.js +7 -7
- package/src/core/geom/vec3/v3_array_displace_in_direction.js +7 -7
- package/src/core/geom/vec3/v3_array_equals.js +7 -7
- package/src/core/geom/vec3/v3_array_immediate_add.js +7 -7
- package/src/core/geom/vec3/v3_array_matrix4_rotate.js +7 -7
- package/src/core/geom/vec3/v3_array_normalize.js +7 -7
- package/src/core/geom/vec3/v3_array_scale.js +7 -7
- package/src/core/geom/vec3/v3_compute_interior_angle.js +7 -7
- package/src/core/geom/vec3/v3_cotangent.js +33 -33
- package/src/core/geom/vec3/v3_dot_array_array.js +7 -7
- package/src/core/geom/vec3/v3_matrix3_multiply.js +30 -30
- package/src/core/geom/vec3/v3_matrix3_rotate.js +49 -49
- package/src/core/geom/vec3/v3_matrix4_rotate.js +7 -7
- package/src/core/geom/vec3/v3_multiply.js +23 -23
- package/src/core/geom/vec3/v3_multiply_scalar.js +7 -7
- package/src/core/geom/vec3/v3_orthonormal_matrix_from_normal.js +49 -49
- package/src/core/geom/vec3/v3_quat3_apply.js +7 -7
- package/src/core/geom/vec3/v3_quat3_apply_inverse.js +7 -7
- package/src/core/geom/vec3/v3_quaternion_apply.js +39 -39
- package/src/core/geom/vec3/v3_quaternion_apply_inverse.js +41 -41
- package/src/core/geom/vec3/v3_reflect.js +24 -24
- package/src/core/geom/vec3/v3_scale_array.js +18 -18
- package/src/core/geom/vec3/v3_triple_cross.js +45 -45
- package/src/core/geom/vec3/v3_triple_cross_product.js +7 -7
- package/src/core/geom/vec3/v3_uniform_sample_cone.js +21 -21
- package/src/core/geom/vec4/v4_multiply_mat4.js +7 -7
- package/src/core/graph/csr/csr_graph_build_distance_field.js +112 -112
- package/src/core/graph/csr/csr_graph_find_edge.js +25 -25
- package/src/core/graph/csr/csr_graph_find_shortest_path.js +105 -105
- package/src/core/graph/csr/csr_graph_from_undirected_edge_list.js +94 -94
- package/src/core/graph/graph_k_means_cluster.js +250 -250
- package/src/core/graph/layout/CircleLayout.js +1 -1
- package/src/core/graph/layout/box/BoxLayouter.js +1 -1
- package/src/core/graph/layout/graph_peel_topological_layer.js +45 -45
- package/src/core/graph/metis/BinaryTopologyFaceGraph.js +49 -49
- package/src/core/graph/metis/bt_mesh_build_face_graph.js +111 -111
- package/src/core/graph/metis/cluster_mesh_metis.js +137 -137
- package/src/core/graph/metis/native/bisection/bisect_graph.js +100 -100
- package/src/core/graph/metis/native/bisection/compute_2way_params.js +86 -86
- package/src/core/graph/metis/native/bisection/fm_2way.js +297 -297
- package/src/core/graph/metis/native/bisection/grow_bisection.js +137 -137
- package/src/core/graph/metis/native/bisection/split_graph_two_way.js +119 -119
- package/src/core/graph/metis/native/coarsen/coarsen_graph.js +94 -94
- package/src/core/graph/metis/native/coarsen/create_coarse_graph.js +158 -158
- package/src/core/graph/metis/native/coarsen/match_shem.js +175 -175
- package/src/core/graph/metis/native/initial/initial_kway_bfs.js +122 -122
- package/src/core/graph/metis/native/initial/initial_kway_recursive_bisection.js +170 -170
- package/src/core/graph/metis/native/metis_partition_kway.js +126 -126
- package/src/core/graph/metis/native/refine/RefinementScratch.js +53 -53
- package/src/core/graph/metis/native/refine/fm_kway.js +487 -487
- package/src/core/graph/metis/native/refine/project_kway.js +43 -43
- package/src/core/graph/metis/native/refine/refine_kway.js +43 -43
- package/src/core/lang/reactive/pegjs/parser.js +3458 -3458
- package/src/core/math/complex/complex_horner_eval.js +31 -31
- package/src/core/math/computeWholeDivisorLow.js +33 -33
- package/src/core/math/f32_next_down.js +24 -24
- package/src/core/math/f32_next_up.js +27 -27
- package/src/core/math/hash/hash_mix2.js +22 -22
- package/src/core/math/hash/hash_mix3.js +19 -19
- package/src/core/math/linalg/cg/cg_solve.js +106 -106
- package/src/core/math/linalg/cg/cg_solve_normal_equations.js +59 -59
- package/src/core/math/linalg/cubic_residual_times_derivative_accumulate.js +43 -43
- package/src/core/math/linalg/eigen/matrix_householder_in_place.js +122 -122
- package/src/core/math/linalg/eigen/matrix_qr_in_place.js +190 -190
- package/src/core/math/linalg/eigen/matrix_symmetric_3x3_eigen.js +117 -117
- package/src/core/math/linalg/givens/givens_apply_rows.js +28 -28
- package/src/core/math/linalg/givens/givens_apply_rows_offset.js +30 -30
- package/src/core/math/linalg/givens/givens_rotation_coefficients.js +39 -39
- package/src/core/math/linalg/lu_factor_linear_system.js +108 -108
- package/src/core/math/linalg/lu_solve_linear_system.js +53 -53
- package/src/core/math/linalg/polynomial_add_into.js +29 -29
- package/src/core/math/linalg/polynomial_complex_roots_aberth_ehrlich.js +159 -159
- package/src/core/math/linalg/polynomial_cubic_derivative_eval.js +16 -16
- package/src/core/math/linalg/polynomial_cubic_horner_eval.js +19 -19
- package/src/core/math/linalg/polynomial_cubic_second_derivative_eval.js +14 -14
- package/src/core/math/linalg/polynomial_multiply.js +41 -41
- package/src/core/math/linalg/polynomial_real_roots_in_interval.js +211 -211
- package/src/core/math/linalg/polynomial_root_bound_cauchy.js +30 -30
- package/src/core/math/linalg/polynomial_scale_into.js +17 -17
- package/src/core/math/linalg/polynomial_sub_into.js +29 -29
- package/src/core/math/linalg/solve_linear_system_GEPP_2x2.js +96 -96
- package/src/core/math/linalg/sor_optimal_omega.js +42 -42
- package/src/core/math/linalg/sparse/SparseMatrixCSR.js +88 -88
- package/src/core/math/linalg/sparse/spm_matvec.js +22 -22
- package/src/core/math/linalg/sparse/spm_matvec_transpose.js +29 -29
- package/src/core/math/lookup/LUT_HEATMAP.js +30 -30
- package/src/core/math/lookup/ParameterLookupTable.js +495 -495
- package/src/core/math/lookup/ParameterLookupTableFlags.js +6 -6
- package/src/core/math/noise/curl_noise_3d.js +18 -18
- package/src/core/math/physics/brdf/cone_cosine_from_roughness.js +28 -28
- package/src/core/math/physics/brdf/reflection_sample_weight.js +48 -48
- package/src/core/math/physics/kinematics/computeInterceptPoint.js +79 -79
- package/src/core/math/random/randomSeed.js +16 -16
- package/src/core/math/random/random_pick_weighted_index.js +26 -26
- package/src/core/math/round_half_away_from_zero.js +13 -13
- package/src/core/math/spline/spline3_hermite_apply_transform.js +107 -107
- package/src/core/math/spline/spline3_hermite_intersection_spline3_hermite_1d.js +125 -125
- package/src/core/math/spline/spline3_hermite_intersects_spline3_hermite.js +50 -50
- package/src/core/math/spline/spline3_hermite_reverse.js +49 -49
- package/src/core/math/spline/spline3_hermite_to_monomial.js +37 -37
- package/src/core/math/statistics/hammersley_sequence.js +53 -53
- package/src/core/model/reactive/model/util/createRandomReactiveExpression.js +185 -185
- package/src/core/path/convertPathToURL.js +107 -107
- package/src/core/process/delay.js +16 -16
- package/src/core/science/units/MEASUREMENT_UNITS_SCIENTIFIC.js +87 -87
- package/src/core/science/units/MEASUREMENT_UNITS_SI.js +17 -17
- package/src/core/science/units/NamedUnit.js +48 -48
- package/src/core/science/units/UNIT_DIMENSION_MAPPING.js +29 -29
- package/src/core/science/units/UnitDimension.js +28 -28
- package/src/core/science/units/format_quantity.js +74 -74
- package/src/core/science/units/magnitude_prefix.js +127 -127
- package/src/core/science/units/si/AMPERE.js +13 -13
- package/src/core/science/units/si/CANDELA.js +13 -13
- package/src/core/science/units/si/DIMENSIONLESS.js +14 -14
- package/src/core/science/units/si/KELVIN.js +13 -13
- package/src/core/science/units/si/KILOGRAM.js +13 -13
- package/src/core/science/units/si/METER.js +13 -13
- package/src/core/science/units/si/MOLE.js +13 -13
- package/src/core/science/units/si/SECOND.js +13 -13
- package/src/core/science/units/si/derived/BECQUEREL.js +16 -16
- package/src/core/science/units/si/derived/COULOMB.js +13 -13
- package/src/core/science/units/si/derived/FARAD.js +13 -13
- package/src/core/science/units/si/derived/GRAY.js +16 -16
- package/src/core/science/units/si/derived/HENRY.js +13 -13
- package/src/core/science/units/si/derived/HERTZ.js +16 -16
- package/src/core/science/units/si/derived/JOULE.js +13 -13
- package/src/core/science/units/si/derived/KATAL.js +13 -13
- package/src/core/science/units/si/derived/LUMEN.js +14 -14
- package/src/core/science/units/si/derived/LUX.js +13 -13
- package/src/core/science/units/si/derived/NEWTON.js +13 -13
- package/src/core/science/units/si/derived/OHM.js +13 -13
- package/src/core/science/units/si/derived/PASCAL.js +13 -13
- package/src/core/science/units/si/derived/SIEMENS.js +13 -13
- package/src/core/science/units/si/derived/SIEVERT.js +16 -16
- package/src/core/science/units/si/derived/TESLA.js +13 -13
- package/src/core/science/units/si/derived/VOLT.js +13 -13
- package/src/core/science/units/si/derived/WATT.js +13 -13
- package/src/core/science/units/si/derived/WEBER.js +13 -13
- package/src/core/science/units/unit_matrix_to_string.js +403 -403
- package/src/engine/Engine.js +726 -726
- package/src/engine/EngineHarness.js +590 -590
- package/src/engine/REVIEW_2026_07_03.md +211 -211
- package/src/engine/animation/AnimatedActions.js +81 -81
- package/src/engine/animation/AnimationUtils.js +252 -252
- package/src/engine/animation/async/TimeSeries.js +300 -300
- package/src/engine/animation/curve/animation_curve_binary_codec.js +60 -60
- package/src/engine/animation/curve/draw/canvas_point_to_curve.js +22 -22
- package/src/engine/animation/curve/draw/curve_point_to_canvas.js +38 -38
- package/src/engine/animation/curve/draw/position_canvas_to_curve.js +22 -22
- package/src/engine/animation/curve/draw/position_curve_to_canvas.js +22 -22
- package/src/engine/asset/GameAssetType.d.ts +0 -1
- package/src/engine/asset/GameAssetType.js +0 -1
- package/src/engine/asset/load_model_scene_bundle.js +27 -27
- package/src/engine/asset/loaders/font/FontAsset.js +21 -21
- package/src/engine/asset/loaders/font/FontAssetLoader.js +20 -20
- package/src/engine/asset/loaders/gltf_test_fixtures.js +358 -358
- package/src/engine/asset/loaders/image/ImageBitmapAssetLoader.js +52 -52
- package/src/engine/asset/loaders/image/ImageRGBADataLoader.js +94 -94
- package/src/engine/asset/loaders/image/png/filter/png_filter_unFilterAverage.js +59 -59
- package/src/engine/asset/loaders/image/png/filter/png_filter_unFilterNone.js +55 -55
- package/src/engine/asset/loaders/image/png/filter/png_filter_unFilterPaeth.js +74 -74
- package/src/engine/asset/loaders/image/png/filter/png_filter_unFilterSub.js +34 -34
- package/src/engine/asset/loaders/image/png/filter/png_filter_unFilterUp.js +46 -46
- package/src/engine/control/first-person/DESIGN.md +640 -640
- package/src/engine/control/first-person/DESIGN_EXTENSIONS.md +563 -563
- package/src/engine/control/first-person/FirstPersonMotionPhase.js +134 -134
- package/src/engine/control/first-person/FirstPersonPlayerControllerSystem.js +2045 -2045
- package/src/engine/control/first-person/mastery/DecisionPoint.js +30 -30
- package/src/engine/control/first-person/math/Spring.js +71 -71
- package/src/engine/control/first-person/math/computeJumpFromApex.js +23 -23
- package/src/engine/control/first-person/math/computeLRCBreathRate.js +41 -41
- package/src/engine/control/first-person/math/computeMassRatios.js +44 -44
- package/src/engine/control/first-person/math/criticallyDampedSpring.js +34 -34
- package/src/engine/control/first-person/math/dampedSpringStep.js +72 -72
- package/src/engine/control/first-person/math/jumpDynamics.js +108 -108
- package/src/engine/control/first-person/math/stepTowards.js +20 -20
- package/src/engine/control/first-person/pose/FirstPersonPose.js +137 -137
- package/src/engine/control/first-person/pose/FirstPersonPosture.js +27 -27
- package/src/engine/control/first-person/test/buildTestPlayer.js +36 -36
- package/src/engine/ecs/ASYNC_SYSTEMS_PROPOSAL.md +531 -531
- package/src/engine/ecs/EntityManager.d.ts +7 -3
- package/src/engine/ecs/EntityManager.d.ts.map +1 -1
- package/src/engine/ecs/EntityManager.js +10 -5
- package/src/engine/ecs/HIERARCHY_REVIEW.md +717 -717
- package/src/engine/ecs/async/SystemWorkerHost.js +329 -329
- package/src/engine/ecs/async/SystemWorkerLoopback.js +143 -143
- package/src/engine/ecs/async/WORKER_SYSTEM_PLAN.md +246 -246
- package/src/engine/ecs/async/WorkerSystem.js +702 -702
- package/src/engine/ecs/async/WorkerSystemProtocol.js +150 -150
- package/src/engine/ecs/fow/FogOfWar.js +707 -707
- package/src/engine/ecs/fow/FogOfWarEdgeMode.js +40 -40
- package/src/engine/ecs/fow/fog_of_war_mask_world_bounds.js +24 -24
- package/src/engine/ecs/fow/fog_of_war_uv_transform.js +30 -30
- package/src/engine/ecs/gui/hud/testHudEdgeStick.js +132 -134
- package/src/engine/ecs/hierarchy/EntityChildIndex.js +140 -140
- package/src/engine/ecs/ik/IKProblem.js +42 -42
- package/src/engine/ecs/ik/InverseKinematicsSystem.js +193 -193
- package/src/engine/ecs/ik/OneBoneSurfaceAlignmentSolver.js +134 -134
- package/src/engine/ecs/ik/TwoBoneInverseKinematicsSolver.js +97 -97
- package/src/engine/ecs/ik/ik_bone_chain.js +85 -85
- package/src/engine/ecs/ik/ik_probe_terrain_contact.js +119 -119
- package/src/engine/ecs/parent/EntityNode.d.ts +1 -1
- package/src/engine/ecs/parent/EntityNode.js +2 -2
- package/src/engine/ecs/parent/ParentEntitySystem.js +255 -255
- package/src/engine/ecs/speaker/VoiceSystem.d.ts +2 -2
- package/src/engine/ecs/speaker/VoiceSystem.d.ts.map +1 -1
- package/src/engine/ecs/speaker/VoiceSystem.js +13 -7
- package/src/engine/ecs/storage/binary/SERIALIZATION_COVERAGE.md +269 -269
- package/src/engine/ecs/storage/binary/object-v2/BinaryObjectDeSerializer.js +315 -315
- package/src/engine/ecs/storage/binary/object-v2/BinaryObjectSerializer.js +331 -331
- package/src/engine/ecs/storage/binary/object-v2/DESIGN.md +199 -199
- package/src/engine/ecs/storage/binary/object-v2/ObjectBinaryFormat.js +57 -57
- package/src/engine/ecs/storage/binary/object-v2/ObjectSerializationAdapter.js +56 -56
- package/src/engine/ecs/storage/binary/object-v2/README.md +110 -110
- package/src/engine/ecs/storage/binary/object-v2/objectStringCodec.js +48 -48
- package/src/engine/ecs/storage/binary/object-v2/serializerTestHarness.js +44 -44
- package/src/engine/ecs/storage/populateEngineSerializationRegistry.js +265 -265
- package/src/engine/ecs/terrain/TerrainClouds.js +97 -97
- package/src/engine/ecs/terrain/ecs/StubTerrainBuildWorker.js +65 -65
- package/src/engine/ecs/terrain/ecs/Terrain.d.ts +4 -0
- package/src/engine/ecs/terrain/ecs/Terrain.d.ts.map +1 -1
- package/src/engine/ecs/terrain/ecs/Terrain.js +790 -790
- package/src/engine/ecs/terrain/ecs/TerrainSystem.js +209 -209
- package/src/engine/ecs/terrain/ecs/cling/ClingToTerrainSystem.js +316 -316
- package/src/engine/ecs/terrain/ecs/layers/TerrainLayers.js +416 -416
- package/src/engine/ecs/terrain/ecs/splat/SplatMapping.js +525 -525
- package/src/engine/ecs/terrain/overlay/TerrainOverlay.js +302 -302
- package/src/engine/ecs/terrain/tiles/TerrainTile.js +561 -561
- package/src/engine/ecs/terrain/tiles/TerrainTileManager.js +896 -896
- package/src/engine/ecs/terrain/tiles/tile_geometry_to_meshlets.js +36 -36
- package/src/engine/ecs/terrain/util/loadVisibleTerrainTiles.js +129 -129
- package/src/engine/ecs/transform/Transform64.js +814 -814
- package/src/engine/ecs/transform/t64_copy_from_transform.js +35 -35
- package/src/engine/ecs/transform/t64_equals_transform.js +55 -55
- package/src/engine/ecs/transform/t64_look_rotation.js +36 -36
- package/src/engine/ecs/transform/t64_transform_direction.js +25 -25
- package/src/engine/ecs/transform/transform_copy_from_t64.js +28 -28
- package/src/engine/ecs/transform-attachment/TransformAttachmentSystem.js +345 -345
- package/src/engine/ecs/transform-attachment/transform_attachment_find_descendant_by_name.js +65 -65
- package/src/engine/ecs/transform-attachment/transform_attachment_parent_of.js +24 -24
- package/src/engine/ecs/util/hideEntityGracefully.js +208 -208
- package/src/engine/graphics/CONTEXT_LOSS_RECOVERY_PLAN.md +446 -446
- package/src/engine/graphics/FULL_SCREEN_QUAD_VERTEX_SHADER.js +14 -14
- package/src/engine/graphics/FrameThrottle.js +2 -2
- package/src/engine/graphics/ecs/animation/animator/graph/AnimationState.js +207 -207
- package/src/engine/graphics/ecs/animation/animator/graph/AnimationTransition.js +151 -151
- package/src/engine/graphics/ecs/animation/animator/graph/definition/serialization/AnimationGraphDefinitionAssetLoader.js +22 -22
- package/src/engine/graphics/ecs/camera/Camera.js +165 -165
- package/src/engine/graphics/ecs/camera/camera_active_frustum.js +25 -25
- package/src/engine/graphics/ecs/camera/camera_find_active.js +28 -28
- package/src/engine/graphics/ecs/camera/camera_traverse_active.js +18 -18
- package/src/engine/graphics/ecs/camera/pp/PerfectPanner.js +170 -170
- package/src/engine/graphics/ecs/camera/serialization/CameraSerializationAdapter.js +68 -68
- package/src/engine/graphics/ecs/camera/topdown/TopDownCameraController.js +296 -296
- package/src/engine/graphics/ecs/decal/v2/Decal.js +220 -220
- package/src/engine/graphics/ecs/decal/v2/DecalSerializationAdapter.js +56 -56
- package/src/engine/graphics/ecs/decal/v2/DecalSerializationUpgrader_0_1.js +38 -38
- package/src/engine/graphics/ecs/light/shadow/compute_view_frustum_aabb_in_space.js +62 -62
- package/src/engine/graphics/ecs/light/shadow/extend_shadow_camera_near_for_casters.js +77 -77
- package/src/engine/graphics/ecs/make_bvh_depth_range_computer.js +33 -33
- package/src/engine/graphics/ecs/mesh-v2/DeferredBoundsQueue.js +88 -88
- package/src/engine/graphics/ecs/mesh-v2/ShadedGeometry.js +428 -428
- package/src/engine/graphics/ecs/mesh-v2/aggregate/SGMesh.js +303 -303
- package/src/engine/graphics/ecs/mesh-v2/aggregate/SGMeshSystem.d.ts +1 -1
- package/src/engine/graphics/ecs/mesh-v2/aggregate/serialization/SGMeshSerializationAdapter.js +39 -39
- package/src/engine/graphics/ecs/mesh-v2/sg_hierarchy_compute_bounding_box_via_parent_entity.js +36 -36
- package/src/engine/graphics/ecs/path/tube/build/GeometryStream.js +94 -94
- package/src/engine/graphics/ecs/path/tube/build/build_stream_catmullrom.js +310 -310
- package/src/engine/graphics/ecs/path/tube/build/build_stream_linear.js +73 -73
- package/src/engine/graphics/ecs/path/tube/build/computeFrenetFrames.js +199 -199
- package/src/engine/graphics/ecs/path/tube/build/makeTubeStream.js +217 -217
- package/src/engine/graphics/ecs/path/tube/build/make_cap.js +340 -340
- package/src/engine/graphics/ecs/path/tube/build/make_ring_faces.js +40 -40
- package/src/engine/graphics/ecs/path/tube/build/make_ring_vertices.js +153 -153
- package/src/engine/graphics/ecs/render_layers_compute_depth_range.js +64 -64
- package/src/engine/graphics/ecs/trail3d/Trail3D.js +483 -483
- package/src/engine/graphics/ecs/trail3d/Trail3DFlags.js +26 -26
- package/src/engine/graphics/ecs/trail3d/advance_trail.js +42 -42
- package/src/engine/graphics/ecs/trail3d/make_gradient_stroke.js +58 -58
- package/src/engine/graphics/ecs/trail3d/seed_trail_stroke.js +90 -90
- package/src/engine/graphics/ecs/trail3d/seed_trail_tube.js +75 -75
- package/src/engine/graphics/ecs/trail3d/trail_head_position.js +19 -19
- package/src/engine/graphics/ecs/water/Water.js +104 -104
- package/src/engine/graphics/geometry/AttributeData.js +84 -84
- package/src/engine/graphics/geometry/buffered/geometry_compute_vertex_normals_indexed.js +49 -49
- package/src/engine/graphics/geometry/buffered/query/GeometrySpatialQueryAccelerator.js +288 -288
- package/src/engine/graphics/geometry/buffered/query/nearest_point_on_triangle_record.js +87 -87
- package/src/engine/graphics/geometry/buffered/read_triangle_vertices.js +102 -102
- package/src/engine/graphics/geometry/bvh/buffered/bvh32_from_buffered_geometry.js +52 -52
- package/src/engine/graphics/geometry/bvh/buffered/bvh32_from_indexed_geometry.js +20 -20
- package/src/engine/graphics/geometry/bvh/buffered/bvh32_from_unindexed_geometry.js +19 -19
- package/src/engine/graphics/geometry/optimization/geometry_optimize_uv_tension.js +135 -135
- package/src/engine/graphics/impostors/voxel/README.md +149 -149
- package/src/engine/graphics/impostors/voxel/VoxelImpostorDescription.js +141 -141
- package/src/engine/graphics/particles/node-based/codegen/glsl/getTypeByteSize.js +20 -20
- package/src/engine/graphics/particles/node-based/nodes/FloatConstant.d.ts +2 -0
- package/src/engine/graphics/particles/node-based/nodes/FloatConstant.d.ts.map +1 -1
- package/src/engine/graphics/particles/node-based/nodes/ReadFloatUniform.d.ts +2 -0
- package/src/engine/graphics/particles/node-based/nodes/ReadFloatUniform.d.ts.map +1 -1
- package/src/engine/graphics/particles/node-based/nodes/ReadVelocity.d.ts +2 -0
- package/src/engine/graphics/particles/node-based/nodes/ReadVelocity.d.ts.map +1 -1
- package/src/engine/graphics/particles/node-based/nodes/ShaderNode.d.ts +1 -2
- package/src/engine/graphics/particles/node-based/nodes/ShaderNode.d.ts.map +1 -1
- package/src/engine/graphics/particles/node-based/nodes/Vector3Constant.d.ts +2 -0
- package/src/engine/graphics/particles/node-based/nodes/Vector3Constant.d.ts.map +1 -1
- package/src/engine/graphics/particles/node-based/nodes/Vector3Merge.d.ts +2 -0
- package/src/engine/graphics/particles/node-based/nodes/Vector3Merge.d.ts.map +1 -1
- package/src/engine/graphics/particles/node-based/nodes/Vector3Split.d.ts +2 -0
- package/src/engine/graphics/particles/node-based/nodes/Vector3Split.d.ts.map +1 -1
- package/src/engine/graphics/particles/node-based/nodes/WriteVelocity.d.ts +2 -0
- package/src/engine/graphics/particles/node-based/nodes/WriteVelocity.d.ts.map +1 -1
- package/src/engine/graphics/particles/node-based/nodes/attribute/ReadVector3Attribute.d.ts +2 -0
- package/src/engine/graphics/particles/node-based/nodes/attribute/ReadVector3Attribute.d.ts.map +1 -1
- package/src/engine/graphics/particles/node-based/nodes/attribute/WriteVector3Attribute.d.ts +2 -0
- package/src/engine/graphics/particles/node-based/nodes/attribute/WriteVector3Attribute.d.ts.map +1 -1
- package/src/engine/graphics/particles/node-based/nodes/math/AddFloatNode.d.ts +2 -0
- package/src/engine/graphics/particles/node-based/nodes/math/AddFloatNode.d.ts.map +1 -1
- package/src/engine/graphics/particles/node-based/nodes/math/Vector3Add.d.ts +2 -0
- package/src/engine/graphics/particles/node-based/nodes/math/Vector3Add.d.ts.map +1 -1
- package/src/engine/graphics/particles/node-based/nodes/math/Vector3Divide.d.ts +2 -0
- package/src/engine/graphics/particles/node-based/nodes/math/Vector3Divide.d.ts.map +1 -1
- package/src/engine/graphics/particles/node-based/nodes/math/Vector3Multiply.d.ts +2 -0
- package/src/engine/graphics/particles/node-based/nodes/math/Vector3Multiply.d.ts.map +1 -1
- package/src/engine/graphics/particles/node-based/nodes/math/Vector3Subtract.d.ts +2 -0
- package/src/engine/graphics/particles/node-based/nodes/math/Vector3Subtract.d.ts.map +1 -1
- package/src/engine/graphics/particles/node-based/nodes/noise/CurlNoiseNode.d.ts +2 -0
- package/src/engine/graphics/particles/node-based/nodes/noise/CurlNoiseNode.d.ts.map +1 -1
- package/src/engine/graphics/particles/node-based/nodes/particle_data_type_component_count.js +45 -45
- package/src/engine/graphics/particles/particular/engine/ParticularEngine.js +229 -229
- package/src/engine/graphics/particles/particular/engine/emitter/ParticleEmitter.d.ts +2 -10
- package/src/engine/graphics/particles/particular/engine/emitter/ParticleEmitter.d.ts.map +1 -1
- package/src/engine/graphics/particles/particular/engine/emitter/ParticleEmitter.js +1149 -1149
- package/src/engine/graphics/particles/particular/engine/emitter/ParticlePool.js +472 -472
- package/src/engine/graphics/particles/particular/engine/parameter/ParameterLookupTable.js +2 -2
- package/src/engine/graphics/particles/particular/engine/parameter/ParameterLookupTableFlags.js +2 -2
- package/src/engine/graphics/particles/particular/engine/parameter/ParameterSet.d.ts.map +1 -1
- package/src/engine/graphics/particles/particular/engine/parameter/ParameterSet.js +3 -5
- package/src/engine/graphics/particles/particular/engine/shader/ShaderManager.js +135 -135
- package/src/engine/graphics/particles/particular/engine/utils/distribute_points_on_indexed_triangles.js +168 -168
- package/src/engine/graphics/render/forward_plus/plugin/forwardPlusMaterialMarker.js +18 -18
- package/src/engine/graphics/render/forward_plus/read_frustum_corner.js +2 -2
- package/src/engine/graphics/render/frame_graph/FRAME_GRAPH_RECOMMENDATIONS.md +219 -219
- package/src/engine/graphics/render/frame_graph/FrameGraph.js +900 -900
- package/src/engine/graphics/render/frame_graph/FrameGraphScope.js +72 -72
- package/src/engine/graphics/render/frame_graph/FrameGraphState.js +39 -39
- package/src/engine/graphics/render/frame_graph/ResourceEntry.js +96 -96
- package/src/engine/graphics/render/gizmo/GizmoShapeBuffer.js +105 -105
- package/src/engine/graphics/render/gizmo/GizmoShapeRenderingInterface.js +162 -162
- package/src/engine/graphics/render/layers/RenderLayer.js +95 -95
- package/src/engine/graphics/sh3/build_injected_shader.js +56 -56
- package/src/engine/graphics/sh3/grid_dilate_average.js +175 -175
- package/src/engine/graphics/sh3/path_tracer/BufferedGeometryBVH.js +506 -506
- package/src/engine/graphics/sh3/path_tracer/PathTracedMesh.js +161 -161
- package/src/engine/graphics/sh3/path_tracer/PathTracedRenderer.js +205 -205
- package/src/engine/graphics/sh3/path_tracer/PathTracedScene.js +698 -698
- package/src/engine/graphics/sh3/path_tracer/REVIEW_001_ACTION_PLAN.md +490 -490
- package/src/engine/graphics/sh3/path_tracer/geometry/compute_triangle_group_aabb3.js +2 -2
- package/src/engine/graphics/sh3/path_tracer/make_sky_hosek.js +45 -45
- package/src/engine/graphics/sh3/path_tracer/populate_path_traced_scene_from_ecd.js +73 -73
- package/src/engine/graphics/sh3/path_tracer/ray_hit_apply_transform.js +32 -32
- package/src/engine/graphics/sh3/path_tracer/texture/apply_texture_clamping_to_coordinate.js +28 -28
- package/src/engine/graphics/sh3/path_tracer/texture/sample_material.js +142 -142
- package/src/engine/graphics/sh3/sky/hosek/render_hosek_sky_to_equirectangular.js +70 -70
- package/src/engine/graphics/sh3/sky/hosek/sky_hosek_compute_irradiance_by_direction.js +388 -388
- package/src/engine/graphics/shaders/chunks/glsl_octahedral_impostor.js +277 -277
- package/src/engine/graphics/shaders/chunks/glsl_voxel_impostor_splat.js +57 -57
- package/src/engine/graphics/shadows/vsm.glsl.js +43 -43
- package/src/engine/graphics/texture/3d/scs3d_sample_linear3.js +81 -81
- package/src/engine/graphics/texture/EnvironmentTextureProjection.js +15 -15
- package/src/engine/graphics/texture/channel_count_to_format_prefix.js +26 -26
- package/src/engine/graphics/texture/isImageBitmap.js +2 -2
- package/src/engine/graphics/texture/reflection/convolve_equirectangular_reflection.js +189 -189
- package/src/engine/graphics/texture/reflection/equirectangular_reflection_roughness.js +51 -51
- package/src/engine/graphics/texture/sampler/HarmonicDiffusionGrid.js +145 -145
- package/src/engine/graphics/texture/sampler/Sampler2DArray.js +172 -172
- package/src/engine/graphics/texture/sampler/compare/FLIP_IMPLEMENTATION_PLAN.md +466 -466
- package/src/engine/graphics/texture/sampler/compare/flip/FlipParameters.js +18 -18
- package/src/engine/graphics/texture/sampler/compare/flip/FlipPooling.js +33 -33
- package/src/engine/graphics/texture/sampler/compare/flip/flip_build_feature_kernel.js +147 -147
- package/src/engine/graphics/texture/sampler/compare/flip/flip_build_spatial_kernel.js +177 -177
- package/src/engine/graphics/texture/sampler/compare/flip/flip_compute_color_difference.js +104 -104
- package/src/engine/graphics/texture/sampler/compare/flip/flip_compute_feature_difference.js +76 -76
- package/src/engine/graphics/texture/sampler/compare/flip/flip_compute_pixels_per_degree.js +34 -34
- package/src/engine/graphics/texture/sampler/compare/flip/flip_constants.js +77 -77
- package/src/engine/graphics/texture/sampler/compare/flip/flip_filter_feature.js +48 -48
- package/src/engine/graphics/texture/sampler/compare/flip/flip_filter_spatial.js +86 -86
- package/src/engine/graphics/texture/sampler/compare/flip/flip_pool.js +71 -71
- package/src/engine/graphics/texture/sampler/compare/flip/flip_srgb_to_ycxcz.js +55 -55
- package/src/engine/graphics/texture/sampler/compare/flip/sampler2d_flip_ldr.js +80 -80
- package/src/engine/graphics/texture/sampler/filter/SeparableKernel.js +82 -82
- package/src/engine/graphics/texture/sampler/filter/sampler2d_convolve_separable.js +122 -122
- package/src/engine/graphics/texture/sampler/resize/sampler2d_scale_down_lanczos.js +148 -148
- package/src/engine/graphics/texture/sampler/sampler2d_channel_apply_lut.js +82 -82
- package/src/engine/graphics/texture/sampler/sampler2d_combine.js +67 -67
- package/src/engine/graphics/texture/sampler/sampler2d_linear_f16_to_srgb_u8.js +54 -54
- package/src/engine/graphics/texture/sampler/sampler2d_sample_equirectangular_direction.js +63 -63
- package/src/engine/graphics/texture/sampler/sampler2d_srgb_to_linear.js +33 -33
- package/src/engine/graphics/texture/sampler/sampler2d_srgb_u8_to_linear_f16.js +68 -68
- package/src/engine/graphics/texture/shade_image_preview.js +103 -103
- package/src/engine/graphics/trail/TrailSpawnMode.js +20 -20
- package/src/engine/graphics/trail/tube/TubeX.js +573 -573
- package/src/engine/graphics/trail/tube/TubeXMaterialSpec.js +58 -58
- package/src/engine/graphics/trail/tube/simulator/TubeXFixedPhysicsSimulator.js +34 -34
- package/src/engine/graphics/trail/tube/tube_attributes_spec.js +69 -69
- package/src/engine/graphics/trail/tube/tube_frame.js +83 -83
- package/src/engine/graphics3/AnimationGraphSystem3.js +329 -329
- package/src/engine/graphics3/AnimationSystem3.js +352 -352
- package/src/engine/graphics3/CameraSystem3.js +170 -170
- package/src/engine/graphics3/DecalSystem3.js +441 -441
- package/src/engine/graphics3/FogOfWarSystem3.js +265 -265
- package/src/engine/graphics3/GraphicsEngine3.js +776 -776
- package/src/engine/graphics3/HighlightSystem3.js +241 -241
- package/src/engine/graphics3/LightSystem3.js +211 -211
- package/src/engine/graphics3/MeshSystem3.js +646 -646
- package/src/engine/graphics3/ParticleEmitterSystem3.js +289 -289
- package/src/engine/graphics3/PathDisplaySystem3.js +309 -309
- package/src/engine/graphics3/PickingQuery.js +48 -48
- package/src/engine/graphics3/PickingResult.js +47 -47
- package/src/engine/graphics3/PickingSystem3.js +273 -273
- package/src/engine/graphics3/ShadeCameraAdapter.js +55 -55
- package/src/engine/graphics3/ShadedGeometrySystem3.js +169 -169
- package/src/engine/graphics3/TerrainSystem3.js +566 -566
- package/src/engine/graphics3/TooltipComponentSystem3.js +328 -328
- package/src/engine/graphics3/Trail3DSystem3.js +221 -221
- package/src/engine/graphics3/WaterSystem3.js +293 -293
- package/src/engine/graphics3/animation/ClipPlayback.js +84 -84
- package/src/engine/graphics3/animation/wrap_clip_time.js +23 -23
- package/src/engine/graphics3/animation/write_graph_playback.js +48 -48
- package/src/engine/graphics3/camera_sync_from_transform.js +29 -29
- package/src/engine/graphics3/debug/gizmo_view_from_camera.js +48 -48
- package/src/engine/graphics3/decal/DECAL_CLUSTER.js +61 -61
- package/src/engine/graphics3/decal/DECAL_GPU_RECORD.js +117 -117
- package/src/engine/graphics3/decal/DecalAtlas.js +194 -194
- package/src/engine/graphics3/decal/DecalAtlasFill.js +32 -32
- package/src/engine/graphics3/decal/GPUDecalRenderer.js +360 -360
- package/src/engine/graphics3/decal/chunk_decal_intersects_frustum.js +59 -59
- package/src/engine/graphics3/decal/chunk_decal_sampling_info.js +57 -57
- package/src/engine/graphics3/decal/chunk_decal_surface_frame.js +54 -54
- package/src/engine/graphics3/decal/decal_atlas_border.js +69 -69
- package/src/engine/graphics3/decal/decal_gpu_records.js +120 -120
- package/src/engine/graphics3/decal/decal_material_samplers.js +109 -109
- package/src/engine/graphics3/decal/graph_build_decal_clusters.js +212 -212
- package/src/engine/graphics3/decal/shader_cluster_assign_decals.js +207 -207
- package/src/engine/graphics3/decal/shader_cull_decals_frustum.js +108 -108
- package/src/engine/graphics3/highlight/GPUHighlightRenderer.js +151 -151
- package/src/engine/graphics3/highlight/HIGHLIGHT_OUTLINE.js +23 -23
- package/src/engine/graphics3/highlight/chunk_highlight_lookup.js +53 -53
- package/src/engine/graphics3/highlight/pack_highlight_color.js +44 -44
- package/src/engine/graphics3/highlight/pack_highlight_table.js +74 -74
- package/src/engine/graphics3/highlight/shader_highlight_outline.js +150 -150
- package/src/engine/graphics3/load_cube_environment.js +68 -68
- package/src/engine/graphics3/make_default_environment.js +107 -107
- package/src/engine/graphics3/particles/particle_gpu_records.js +221 -221
- package/src/engine/graphics3/path/build_tube_path_streams.js +98 -98
- package/src/engine/graphics3/path/tube_stream_write_geometry.js +90 -90
- package/src/engine/graphics3/preview/ModelPreviewFraming.js +35 -35
- package/src/engine/graphics3/preview/make_model_preview_scene.js +154 -154
- package/src/engine/graphics3/preview/make_model_thumbnail.js +48 -48
- package/src/engine/graphics3/preview/model_preview_framing.js +70 -70
- package/src/engine/graphics3/shade_bundle_bounds.js +55 -55
- package/src/engine/graphics3/shade_camera_projection_ray.js +77 -77
- package/src/engine/graphics3/shade_node_to_entity_composition.js +84 -84
- package/src/engine/graphics3/terrain/GPUTerrainSplatRenderer.js +481 -481
- package/src/engine/graphics3/terrain/chunk_terrain_grid_overlay.js +61 -61
- package/src/engine/graphics3/terrain/chunk_terrain_splat_mix.js +66 -66
- package/src/engine/graphics3/terrain/pack_terrain_row_table.js +53 -53
- package/src/engine/graphics3/terrain/shader_terrain_splat.js +215 -215
- package/src/engine/graphics3/trail/trail_tube_write_geometry.js +158 -158
- package/src/engine/grid/grid2transform/GridPosition2TransformSystem.d.ts +2 -2
- package/src/engine/grid/grid2transform/GridPosition2TransformSystem.d.ts.map +1 -1
- package/src/engine/input/GAMEPAD_API_PROPOSAL.md +717 -717
- package/src/engine/input/analog/apply_radial_dead_zone.js +38 -38
- package/src/engine/input/devices/GamepadDevice.js +466 -466
- package/src/engine/input/devices/ManualInputDevice.js +152 -152
- package/src/engine/input/devices/PointerCoordinates.js +26 -26
- package/src/engine/input/devices/events/GamepadEvents.js +10 -10
- package/src/engine/input/devices/gamepad/GamepadAxes.js +19 -19
- package/src/engine/input/devices/gamepad/GamepadButtons.js +29 -29
- package/src/engine/input/devices/gamepad/GamepadCoordinates.js +17 -17
- package/src/engine/input/devices/gamepad/GamepadDeviceLayout.js +323 -323
- package/src/engine/input/devices/gamepad/GamepadHandle.js +286 -286
- package/src/engine/input/devices/gamepad/GamepadLayout.js +160 -160
- package/src/engine/input/devices/gamepad/GamepadStandardMapping.js +31 -31
- package/src/engine/input/devices/gamepad/GamepadStick.js +169 -169
- package/src/engine/input/devices/gamepad/GamepadStickCalibration.js +119 -119
- package/src/engine/input/devices/gamepad/GamepadStickCalibrator.js +250 -250
- package/src/engine/input/devices/gamepad/gamepad_layout_database.js +144 -144
- package/src/engine/input/devices/gamepad/gamepad_read_hat_axis.js +61 -61
- package/src/engine/input/devices/gamepad/gamepad_write_dpad_vector.js +30 -30
- package/src/engine/input/devices/gamepad/prototypeGamepadTester.js +2124 -2124
- package/src/engine/input/devices/mouse/MouseButtons.js +22 -22
- package/src/engine/input/ecs/components/Input.js +118 -118
- package/src/engine/input/ecs/components/InputController.js +78 -78
- package/src/engine/input/ecs/ism/ISM_DESIGN.md +1523 -1523
- package/src/engine/input/ecs/ism/ISM_IMPLEMENTATION_PLAN.md +627 -627
- package/src/engine/input/ecs/ism/InputActionEvent.js +40 -40
- package/src/engine/input/ecs/ism/InputBinding.js +71 -71
- package/src/engine/input/ecs/ism/InputCoordinateKind.js +25 -25
- package/src/engine/input/ecs/ism/InputCoordinateSource.js +86 -86
- package/src/engine/input/ecs/ism/InputDirection.js +33 -33
- package/src/engine/input/ecs/ism/InputMapProgram.js +236 -236
- package/src/engine/input/ecs/ism/InputMapSystem.js +976 -976
- package/src/engine/input/ecs/ism/InputOcclusion.js +31 -31
- package/src/engine/input/ecs/ism/InputSource.js +67 -67
- package/src/engine/input/ecs/ism/InputSourceTable.js +107 -107
- package/src/engine/input/ecs/ism/coordinate/InputCoordinateChannel.js +93 -93
- package/src/engine/input/ecs/ism/coordinate/InputCoordinateChannelType.js +11 -11
- package/src/engine/input/ecs/ism/coordinate/InputCoordinateDevice.js +153 -153
- package/src/engine/input/ecs/ism/coordinate/InputCoordinateSwitches.js +160 -160
- package/src/engine/input/ecs/ism/device/GAMEPAD_INPUT_DEVICE_ID.js +9 -9
- package/src/engine/input/ecs/ism/device/GamepadInputDeviceAdapter.js +88 -88
- package/src/engine/input/ecs/ism/device/InputDeviceAdapter.js +72 -72
- package/src/engine/input/ecs/ism/device/KEYBOARD_INPUT_DEVICE_ID.js +9 -9
- package/src/engine/input/ecs/ism/device/KeyboardInputDeviceAdapter.js +63 -63
- package/src/engine/input/ecs/ism/device/ManualInputDeviceAdapter.js +55 -55
- package/src/engine/input/ecs/ism/device/POINTER_INPUT_DEVICE_ID.js +9 -9
- package/src/engine/input/ecs/ism/device/PointerInputDeviceAdapter.js +160 -160
- package/src/engine/input/ecs/ism/map/InputBinding.js +88 -88
- package/src/engine/input/ecs/ism/map/InputCoordinateBinding.js +102 -102
- package/src/engine/input/ecs/ism/map/InputLayer.js +220 -220
- package/src/engine/input/ecs/ism/map/InputMap.js +331 -331
- package/src/engine/input/ecs/ism/prototypeInputMap.js +309 -309
- package/src/engine/input/ecs/ism/trigger/InputTrigger.js +148 -148
- package/src/engine/input/ecs/ism/trigger/InputTriggerChord.js +173 -173
- package/src/engine/input/ecs/ism/trigger/InputTriggerGamepadButton.js +37 -37
- package/src/engine/input/ecs/ism/trigger/InputTriggerHold.js +176 -176
- package/src/engine/input/ecs/ism/trigger/InputTriggerKey.js +39 -39
- package/src/engine/input/ecs/ism/trigger/InputTriggerMouseButton.js +38 -38
- package/src/engine/input/ecs/ism/trigger/InputTriggerRelease.js +120 -120
- package/src/engine/input/ecs/ism/trigger/InputTriggerSequence.js +315 -315
- package/src/engine/input/ecs/ism/trigger/InputTriggerSwitch.js +105 -105
- package/src/engine/input/ecs/ism/trigger/InputTriggerType.js +17 -17
- package/src/engine/input/ecs/systems/InputControllerSystem.js +253 -253
- package/src/engine/input/ecs/systems/InputSystem.js +162 -162
- package/src/engine/intelligence/behavior/primitive/FailingBehaviorSerializationAdapter.js +25 -25
- package/src/engine/intelligence/behavior/primitive/SucceedingBehaviorSerializationAdapter.js +26 -26
- package/src/engine/intelligence/behavior/util/AsynchronousDelayAction.js +55 -55
- package/src/engine/interpolation/BinaryInterpolationAdapter.js +56 -56
- package/src/engine/interpolation/Interpoland.js +49 -49
- package/src/engine/interpolation/Interpolated.js +149 -149
- package/src/engine/interpolation/PoseInterpolationAdapter.js +61 -61
- package/src/engine/interpolation/TransformPoseSerializationAdapter.js +57 -57
- package/src/engine/interpolation/pose_interpoland.js +27 -27
- package/src/engine/navigation/ecs/path_following/PathFollower.js +222 -222
- package/src/engine/navigation/mesh/NavigationMesh.js +145 -145
- package/src/engine/navigation/mesh/OVERLAPPING_SURFACES_2026_08_25.md +661 -0
- package/src/engine/navigation/mesh/PATHFINDING_PLAN.md +229 -229
- package/src/engine/navigation/mesh/build/clip_soup_against_overhangs.d.ts.map +1 -1
- package/src/engine/navigation/mesh/build/clip_soup_against_overhangs.js +628 -520
- package/src/engine/network/CONGESTION_CONTROL.md +87 -87
- package/src/engine/network/README.md +52 -52
- package/src/engine/network/adapters/QuaternionInterpolationAdapter.js +43 -43
- package/src/engine/network/adapters/TransformInterpolationAdapter.js +84 -84
- package/src/engine/network/adapters/TransformReplicationAdapter.js +87 -87
- package/src/engine/network/adapters/Vector3InterpolationAdapter.js +46 -46
- package/src/engine/network/convertPathToURL.js +2 -2
- package/src/engine/network/core/MalformedPacketError.js +26 -26
- package/src/engine/network/core/quantize/quantize_float.js +73 -73
- package/src/engine/network/core/quantize/quantize_position.js +65 -65
- package/src/engine/network/core/sequence/ack_bitfield.js +77 -77
- package/src/engine/network/core/sequence/seq16.js +69 -69
- package/src/engine/network/core/sequence/seq32.js +73 -73
- package/src/engine/network/ecs/NetworkSystem.js +84 -84
- package/src/engine/network/ecs/components/NetworkIdentity.js +73 -73
- package/src/engine/network/ecs/owner_authorization.js +55 -55
- package/src/engine/network/ecs/serialization/NetworkIdentitySerializationAdapter.js +64 -64
- package/src/engine/network/replication/ScopeFilter.js +71 -71
- package/src/engine/network/sim/ActionLog.js +152 -152
- package/src/engine/network/sim/SimAction.js +273 -273
- package/src/engine/network/sim/Snapshotter.js +222 -222
- package/src/engine/network/state/FrameBufferRing.js +168 -168
- package/src/engine/network/state/InputRing.js +134 -134
- package/src/engine/network/state/PriorityAccumulator.js +180 -180
- package/src/engine/network/time/TimeDilation.js +62 -62
- package/src/engine/network/transport/Channel.js +336 -336
- package/src/engine/network/transport/Transport.js +203 -203
- package/src/engine/network/transport/adapters/NodeUDPTransport.js +186 -186
- package/src/engine/network/transport/adapters/WebRTCDataChannelTransport.js +105 -105
- package/src/engine/network/transport/fragments/fragment_send.js +147 -147
- package/src/engine/network/transport/fragments/packet_size.js +101 -101
- package/src/engine/network/xhr.js +23 -23
- package/src/engine/physics/BULLET_REVIEW.md +945 -945
- package/src/engine/physics/CANNON_REVIEW.md +1300 -1300
- package/src/engine/physics/CONSTRAINT_SOLVER_BENCH_LOG.md +208 -208
- package/src/engine/physics/CONSTRAINT_SOLVER_IMPROVEMENTS_PLAN.md +364 -364
- package/src/engine/physics/INTEPOLATION_SYSTEM_PLAN.md +287 -287
- package/src/engine/physics/JOLT_REVIEW.md +913 -913
- package/src/engine/physics/PLAN.md +1120 -1094
- package/src/engine/physics/RAPIER_REVIEW.md +934 -934
- package/src/engine/physics/REVIEW_001_ACTION_PLAN.md +642 -642
- package/src/engine/physics/REVIEW_002.md +151 -151
- package/src/engine/physics/REVIEW_003.md +166 -166
- package/src/engine/physics/broadphase/compute_fat_world_aabb.js +97 -97
- package/src/engine/physics/constraint/DofMode.js +35 -35
- package/src/engine/physics/constraint/solve_constraints.js +1 -1
- package/src/engine/physics/contact/combine_material.js +35 -35
- package/src/engine/physics/ecs/BodyKind.js +29 -29
- package/src/engine/physics/ecs/Collider.js +177 -177
- package/src/engine/physics/ecs/ColliderFlags.js +15 -15
- package/src/engine/physics/ecs/ColliderSerializationAdapter.js +37 -37
- package/src/engine/physics/ecs/Joint.js +475 -475
- package/src/engine/physics/ecs/JointSerializationAdapter.js +72 -72
- package/src/engine/physics/ecs/PhysicsSystem.d.ts +3 -0
- package/src/engine/physics/ecs/PhysicsSystem.d.ts.map +1 -1
- package/src/engine/physics/ecs/PhysicsSystem.js +7 -2
- package/src/engine/physics/ecs/RigidBodySerializationUpgrader_0_1.js +37 -37
- package/src/engine/physics/ecs/SleepState.js +12 -12
- package/src/engine/physics/ecs/find_non_finite_physics_state.js +76 -76
- package/src/engine/physics/fluid/FluidField.js +867 -867
- package/src/engine/physics/fluid/FluidSimulator.js +832 -832
- package/src/engine/physics/fluid/REVIEW_02_PLAN.md +243 -243
- package/src/engine/physics/fluid/SliceVisualiser.js +190 -190
- package/src/engine/physics/fluid/ecs/FluidComponent.js +239 -239
- package/src/engine/physics/fluid/ecs/FluidEffectorsComponent.js +89 -89
- package/src/engine/physics/fluid/ecs/FluidObstacle.js +97 -97
- package/src/engine/physics/fluid/ecs/FluidObstacleSystem.js +348 -348
- package/src/engine/physics/fluid/ecs/FluidSystem.js +142 -142
- package/src/engine/physics/fluid/ecs/FluidWorkerCore.js +123 -123
- package/src/engine/physics/fluid/ecs/WorkerFluidSystem.js +395 -395
- package/src/engine/physics/fluid/ecs/fluid.worker.js +12 -12
- package/src/engine/physics/fluid/ecs/fluid_build_world_to_grid.js +32 -32
- package/src/engine/physics/fluid/ecs/fluid_gather_visible_effectors.js +47 -47
- package/src/engine/physics/fluid/ecs/fluid_reanchor_field.js +85 -85
- package/src/engine/physics/fluid/ecs/fluid_sync_effectors_from_transform.js +16 -16
- package/src/engine/physics/fluid/ecs/fluid_worker_protocol.js +111 -111
- package/src/engine/physics/fluid/ecs/makeFluidWorker.js +18 -18
- package/src/engine/physics/fluid/effector/AbstractFluidEffector.js +81 -81
- package/src/engine/physics/fluid/effector/GlobalFluidEffector.js +202 -202
- package/src/engine/physics/fluid/effector/ImpulseFluidEffector.js +257 -257
- package/src/engine/physics/fluid/effector/WakeFluidEffector.js +405 -405
- package/src/engine/physics/fluid/prototype.js +126 -126
- package/src/engine/physics/fluid/solver/v3_grid_advect_maccormack_scalar.js +143 -143
- package/src/engine/physics/fluid/solver/v3_grid_advect_maccormack_velocity.js +162 -162
- package/src/engine/physics/fluid/solver/v3_grid_advect_sl_velocity.js +107 -107
- package/src/engine/physics/fluid/solver/v3_grid_apply_vorticity_confinement.js +131 -131
- package/src/engine/physics/fluid/solver/v3_grid_compute_solid_neighbour_mask.js +90 -90
- package/src/engine/physics/fluid/solver/v3_grid_limit8_at_indices.js +38 -38
- package/src/engine/physics/fluid/solver/v3_grid_patch_edges_constant.js +77 -77
- package/src/engine/physics/fluid/solver/v3_grid_patch_edges_uniform.js +113 -113
- package/src/engine/physics/fluid/solver/v3_grid_sample_scalar_masked.js +92 -92
- package/src/engine/physics/fluid/solver/v3_grid_shift_in_place.js +107 -107
- package/src/engine/physics/fluid/solver/v3_grid_solve_pressure.js +135 -135
- package/src/engine/physics/fluid/solver/v3_grid_solve_pressure_pcg.js +511 -511
- package/src/engine/physics/fluid/solver/v3_grid_subtract_pressure_gradient.js +108 -108
- package/src/engine/physics/fluid/solver/v3_mac_advect_maccormack_velocity.js +317 -317
- package/src/engine/physics/fluid/solver/v3_mac_advect_scalar.js +236 -236
- package/src/engine/physics/fluid/solver/v3_mac_advect_sl_velocity.js +217 -217
- package/src/engine/physics/fluid/solver/v3_mac_apply_vorticity_confinement.js +174 -174
- package/src/engine/physics/fluid/solver/v3_mac_clip_trace.js +95 -95
- package/src/engine/physics/fluid/solver/v3_mac_compute_divergence.js +77 -77
- package/src/engine/physics/fluid/solver/v3_mac_compute_face_solid.js +131 -131
- package/src/engine/physics/fluid/solver/v3_mac_subtract_pressure_gradient.js +104 -104
- package/src/engine/physics/inertia/world_inverse_inertia.js +160 -160
- package/src/engine/physics/integration/integrate_position.js +97 -97
- package/src/engine/physics/narrowphase/box_box_manifold.js +681 -681
- package/src/engine/physics/narrowphase/box_triangle_contact.js +906 -906
- package/src/engine/physics/narrowphase/capsule_triangle_contact.js +395 -395
- package/src/engine/physics/narrowphase/compute_penetration.js +369 -369
- package/src/engine/physics/narrowphase/decomposition/decompose_to_triangles.js +55 -55
- package/src/engine/physics/narrowphase/decomposition/triangle_buffer_layout.js +37 -37
- package/src/engine/physics/narrowphase/mesh_mesh_tet_manifold.js +117 -117
- package/src/engine/physics/narrowphase/narrowphase_step.js +1738 -1738
- package/src/engine/physics/narrowphase/reduce_manifold_contacts.js +74 -74
- package/src/engine/physics/narrowphase/refine_ray_hit.d.ts +12 -11
- package/src/engine/physics/narrowphase/refine_ray_hit.d.ts.map +1 -1
- package/src/engine/physics/narrowphase/refine_ray_hit.js +228 -36
- package/src/engine/physics/narrowphase/sphere_sphere_contact.js +52 -52
- package/src/engine/physics/narrowphase/sphere_triangle_contact.js +138 -138
- package/src/engine/physics/persistence/solver_caches.js +309 -309
- package/src/engine/physics/queries/overlap_shape.js +187 -187
- package/src/engine/physics/queries/raycast.d.ts +7 -4
- package/src/engine/physics/queries/raycast.d.ts.map +1 -1
- package/src/engine/physics/queries/raycast.js +11 -5
- package/src/engine/physics/queries/shape_cast.js +417 -417
- package/src/engine/physics/solver/apply_impulse_to_body.js +86 -86
- package/src/engine/physics/solver/friction_cone.js +37 -37
- package/src/engine/physics/solver/solve_contacts.js +1 -1
- package/src/engine/platform/WebEnginePlatform.d.ts.map +1 -1
- package/src/engine/platform/WebEnginePlatform.js +1 -2
- package/src/engine/scene/SerializedScene.d.ts +2 -2
- package/src/engine/scene/SerializedScene.d.ts.map +1 -1
- package/src/engine/scene/transitionToScene.js +121 -121
- package/src/engine/simulation/Ticker.d.ts.map +1 -1
- package/src/engine/simulation/Ticker.js +33 -0
- package/src/engine/sound/ecs/audio/LiveEmitterSet.js +345 -345
- package/src/engine/sound/ecs/audio/SpatialAudioIndex.js +140 -140
- package/src/engine/sound/simulation/AcousticSimulator.js +646 -646
- package/src/engine/sound/simulation/IMPLEMENTATION_PLAN.md +432 -432
- package/src/engine/sound/simulation/PROBE_PLACEMENT.md +250 -250
- package/src/engine/sound/simulation/PROBE_TRANSFER_RESEARCH.md +322 -322
- package/src/engine/sound/simulation/README.md +277 -277
- package/src/engine/sound/simulation/REFLECTION_IR_PLAN.md +261 -261
- package/src/engine/sound/simulation/VISIBILITY_GRAPH_PLAN.md +121 -121
- package/src/engine/sound/simulation/configureAcousticSimulation.js +48 -48
- package/src/engine/sound/simulation/core/AcousticMedium.js +113 -113
- package/src/engine/sound/simulation/core/AcousticMediumSerializationAdapter.js +27 -27
- package/src/engine/sound/simulation/core/AcousticOccluderIndex.js +312 -312
- package/src/engine/sound/simulation/core/AcousticRegionIndex.js +159 -159
- package/src/engine/sound/simulation/core/AcousticSolution.js +90 -90
- package/src/engine/sound/simulation/core/AcousticSourceState.js +109 -109
- package/src/engine/sound/simulation/core/AcousticVolumeRegion.js +73 -73
- package/src/engine/sound/simulation/core/OcclusionSolver.js +112 -112
- package/src/engine/sound/simulation/core/RayHit.js +50 -50
- package/src/engine/sound/simulation/core/VolumeField.js +149 -149
- package/src/engine/sound/simulation/definition/AcousticDirectivity.js +114 -114
- package/src/engine/sound/simulation/definition/AcousticDirectivitySerializationAdapter.js +30 -30
- package/src/engine/sound/simulation/definition/AcousticMaterial.js +122 -122
- package/src/engine/sound/simulation/definition/AcousticMaterialSerializationAdapter.js +32 -32
- package/src/engine/sound/simulation/ecs/AcousticBody.js +48 -48
- package/src/engine/sound/simulation/ecs/AcousticBodySerializationAdapter.js +34 -34
- package/src/engine/sound/simulation/ecs/AcousticProbeFieldSystem.js +64 -64
- package/src/engine/sound/simulation/ecs/AcousticSimulationSystem.js +75 -75
- package/src/engine/sound/simulation/ecs/AcousticVolume.js +74 -74
- package/src/engine/sound/simulation/ecs/AcousticVolumeSerializationAdapter.js +37 -37
- package/src/engine/sound/simulation/ecs/AcousticVolumeSystem.js +66 -66
- package/src/engine/sound/simulation/probe/AcousticProbeField.js +578 -578
- package/src/engine/sound/simulation/probe/AcousticProbeFieldSerializationAdapter.js +60 -60
- package/src/engine/sound/simulation/probe/ProbeFieldPathingSolution.js +64 -64
- package/src/engine/sound/simulation/probe/ProbeVisibilityRecheck.js +132 -132
- package/src/engine/sound/simulation/probe/acoustic_probe_transfer.js +103 -103
- package/src/engine/sound/simulation/probe/acoustic_trace_energy.js +136 -136
- package/src/engine/sound/simulation/probe/bakeProbeField.js +169 -169
- package/src/engine/sound/simulation/probe/bakeProbeReflectors.js +110 -110
- package/src/engine/sound/simulation/probe/bakeReverbBands.js +110 -110
- package/src/engine/sound/simulation/probe/bakeVisibility.js +148 -148
- package/src/engine/sound/simulation/probe/echogram_band_rt60.js +83 -83
- package/src/engine/sound/simulation/probe/probe_delaunay_edges.js +215 -215
- package/src/engine/sound/simulation/probe/probe_densify_portals.js +140 -140
- package/src/engine/sound/simulation/probe/probe_detect_portals.js +196 -196
- package/src/engine/sound/simulation/probe/probe_edge_key.js +38 -38
- package/src/engine/sound/simulation/probe/probe_edge_visible.js +41 -41
- package/src/engine/sound/simulation/probe/probe_place_sdf_cover.js +82 -82
- package/src/engine/sound/simulation/probe/probe_refine_connectivity.js +181 -181
- package/src/engine/sound/simulation/probe/probe_sdf_grid.js +171 -171
- package/src/engine/sound/simulation/probe/probe_visibility_augment.js +146 -146
- package/src/engine/sound/simulation/probe/probe_visibility_bridge_components.js +167 -167
- package/src/engine/sound/simulation/render/FoaProbeReverbRenderer.js +354 -354
- package/src/engine/sound/simulation/render/ProbeReverbRenderer.js +231 -231
- package/src/engine/sound/simulation/render/foaReverbImpulseResponse.js +105 -105
- package/src/engine/sound/simulation/render/reverbImpulseResponse.js +66 -66
- package/src/engine/sound/simulation/render/reverb_band_tails.js +93 -93
- package/src/engine/sound/simulation/serialization/populateAcousticSerializationRegistry.js +25 -25
- package/src/engine/sound/sopra/README.md +643 -643
- package/src/engine/sound/sopra/SopraEngine.js +432 -432
- package/src/engine/sound/sopra/asset/AssetManagerBufferProvider.js +71 -71
- package/src/engine/sound/sopra/asset/BufferProvider.js +29 -29
- package/src/engine/sound/sopra/asset/StubBufferProvider.js +58 -58
- package/src/engine/sound/sopra/definition/BusDefinition.js +142 -142
- package/src/engine/sound/sopra/definition/BusDefinitionSerializationAdapter.js +54 -54
- package/src/engine/sound/sopra/definition/DuckingRule.js +106 -106
- package/src/engine/sound/sopra/definition/DuckingRuleSerializationAdapter.js +31 -31
- package/src/engine/sound/sopra/definition/EventDescription.js +262 -262
- package/src/engine/sound/sopra/definition/EventDescriptionSerializationAdapter.js +55 -55
- package/src/engine/sound/sopra/definition/MixerSnapshot.js +83 -83
- package/src/engine/sound/sopra/definition/MixerSnapshotSerializationAdapter.js +39 -39
- package/src/engine/sound/sopra/definition/ParameterDefinition.js +117 -117
- package/src/engine/sound/sopra/definition/ParameterDefinitionSerializationAdapter.js +31 -31
- package/src/engine/sound/sopra/definition/VoiceStealMode.js +18 -18
- package/src/engine/sound/sopra/definition/clip/AbstractAudioClip.js +109 -109
- package/src/engine/sound/sopra/definition/clip/BlendContainerAudioClip.js +185 -185
- package/src/engine/sound/sopra/definition/clip/BlendContainerAudioClipSerializationAdapter.js +59 -59
- package/src/engine/sound/sopra/definition/clip/ContainerAudioClip.js +128 -128
- package/src/engine/sound/sopra/definition/clip/RandomContainerAudioClip.js +226 -226
- package/src/engine/sound/sopra/definition/clip/RandomContainerAudioClipSerializationAdapter.js +54 -54
- package/src/engine/sound/sopra/definition/clip/SampleAudioClip.js +191 -191
- package/src/engine/sound/sopra/definition/clip/SampleAudioClipSerializationAdapter.js +39 -39
- package/src/engine/sound/sopra/definition/clip/SequenceContainerAudioClip.js +79 -79
- package/src/engine/sound/sopra/definition/clip/SequenceContainerAudioClipSerializationAdapter.js +42 -42
- package/src/engine/sound/sopra/definition/clip/SilenceAudioClip.js +77 -77
- package/src/engine/sound/sopra/definition/clip/SilenceAudioClipSerializationAdapter.js +27 -27
- package/src/engine/sound/sopra/definition/clip/SwitchContainerAudioClip.d.ts +5 -0
- package/src/engine/sound/sopra/definition/clip/SwitchContainerAudioClip.d.ts.map +1 -1
- package/src/engine/sound/sopra/definition/clip/SwitchContainerAudioClip.js +125 -125
- package/src/engine/sound/sopra/definition/clip/SwitchContainerAudioClipSerializationAdapter.js +41 -41
- package/src/engine/sound/sopra/definition/effect/AbstractAudioEffect.js +24 -24
- package/src/engine/sound/sopra/definition/effect/CompressorEffect.js +120 -120
- package/src/engine/sound/sopra/definition/effect/CompressorEffectSerializationAdapter.js +31 -31
- package/src/engine/sound/sopra/definition/effect/EqEffect.js +128 -128
- package/src/engine/sound/sopra/definition/effect/EqEffectSerializationAdapter.js +29 -29
- package/src/engine/sound/sopra/definition/effect/ReverbEffect.js +113 -113
- package/src/engine/sound/sopra/definition/effect/ReverbEffectSerializationAdapter.js +25 -25
- package/src/engine/sound/sopra/runtime/BusGraph.js +231 -231
- package/src/engine/sound/sopra/runtime/ParameterStore.js +98 -98
- package/src/engine/sound/sopra/runtime/SopraPlaybackContext.js +68 -68
- package/src/engine/sound/sopra/runtime/Voice.js +145 -145
- package/src/engine/sound/sopra/runtime/VoiceManager.js +136 -136
- package/src/engine/sound/sopra/runtime/VoicePool.js +17 -17
- package/src/engine/sound/sopra/serialization/populateSopraSerializationRegistry.js +42 -42
- package/src/engine/sound/sopra/serialization/sopraJSON.js +99 -99
- package/src/engine/sound/sopra/serialization/sopraSerializationHarness.js +49 -49
- package/src/engine/sound/sopra/util/MockAudioContext.js +224 -224
- package/src/engine/sound/sopra/util/fadeOutAndStop.js +60 -60
- package/src/engine/ui/DraggableAspect.js +115 -115
- package/src/engine/ui/apply_pointer_tilt_3d.js +50 -50
- package/src/generation/COORDINATES.md +54 -54
- package/src/generation/GridGenerationResource.js +24 -24
- package/src/generation/GridTaskGroup.js +214 -214
- package/src/generation/REVIEW_01_ACTION_PLAN.md +628 -628
- package/src/generation/automata/CaveGeneratorCellularAutomata.js +79 -79
- package/src/generation/automata/CellularAutomata.js +22 -22
- package/src/generation/compute_writes_union.js +25 -25
- package/src/generation/filtering/CellFilter.js +117 -117
- package/src/generation/filtering/core/CellFilterBinaryOperation.js +37 -37
- package/src/generation/filtering/core/CellFilterOperationTertiary.js +43 -43
- package/src/generation/filtering/core/CellFilterUnaryOperation.js +29 -29
- package/src/generation/filtering/numeric/process/computeCellFilterSobel.js +36 -36
- package/src/generation/filtering/numeric/process/computeFilterSurfaceNormal.js +42 -42
- package/src/generation/filtering/numeric/util/populateSampler2DFromCellFilter.js +18 -18
- package/src/generation/filtering/numeric/util/write_cell_filter_to_sampler2d.js +47 -47
- package/src/generation/filtering/util/cell_filter_weights_pick.js +54 -54
- package/src/generation/grid/GridData.js +233 -233
- package/src/generation/grid/coords/grid_to_texel.js +10 -10
- package/src/generation/grid/coords/texel_to_grid.js +10 -10
- package/src/generation/grid/generation/GridTaskApplyActionToCells.js +90 -90
- package/src/generation/grid/generation/GridTaskDensityMarkerDistribution.js +388 -388
- package/src/generation/grid/generation/GridTaskExecuteRuleTimes.js +127 -127
- package/src/generation/grid/generation/GridTaskSequence.js +58 -58
- package/src/generation/grid/generation/NoopGridTaskGenerator.js +12 -12
- package/src/generation/grid/generation/discrete/GridTaskActionRuleSet.js +48 -48
- package/src/generation/grid/generation/discrete/GridTaskCellularAutomata.js +146 -146
- package/src/generation/grid/generation/discrete/GridTaskConnectRooms.js +540 -540
- package/src/generation/grid/generation/discrete/layer/GridTaskBuildSourceDistanceMap.js +222 -222
- package/src/generation/grid/generation/grid/GridTaskAddNodesFixed.js +44 -44
- package/src/generation/grid/generation/road/GridTaskGenerateRoads.js +614 -614
- package/src/generation/markers/GridCellActionPlaceMarker.js +244 -244
- package/src/generation/markers/GridCellActionPlaceMarkerGroup.js +86 -86
- package/src/generation/markers/actions/terrain/MarkerNodeActionPaintTerrain.js +266 -266
- package/src/generation/markers/emitter/MarkerNodeEmitterGridCellAction.js +49 -49
- package/src/generation/placement/GridCellActionTransformNearbyMarkers.js +120 -120
- package/src/generation/placement/action/GridCellAction.js +45 -45
- package/src/generation/placement/action/GridCellActionPlaceTags.js +140 -140
- package/src/generation/placement/action/GridCellActionWriteFilterToLayer.js +89 -89
- package/src/generation/placement/action/random/CellActionSelectRandom.js +69 -69
- package/src/generation/placement/action/random/weighted/CellActionSelectWeightedRandom.js +91 -91
- package/src/generation/placement/action/util/GridCellActionSequence.js +61 -61
- package/src/generation/placement/action/util/GridCellDisplacedAction.js +61 -61
- package/src/generation/rules/cell/CellMatcherRemovalPreservesConnectivity.js +183 -183
- package/src/generation/theme/ThemeEngine.js +666 -666
- package/src/shade/RENDERER_CONTRACT.md +568 -0
- package/src/shade/descriptor/texture/format/gpu_texture_format_info.js +267 -267
- package/src/shade/device/ShadeDeviceFailure.js +104 -104
- package/src/shade/device/ShadeDeviceFailureReason.js +41 -41
- package/src/shade/device/mock/IMPLEMENTATION_PLAN.md +255 -255
- package/src/shade/device/mock/REVIEW_2026_08_22.md +527 -527
- package/src/shade/device/mock/SoftwareGPUBindGroup.js +23 -23
- package/src/shade/device/mock/SoftwareGPUBindGroupLayout.js +22 -22
- package/src/shade/device/mock/SoftwareGPUError.js +63 -63
- package/src/shade/device/mock/SoftwareGPUPipeline.js +75 -75
- package/src/shade/device/mock/SoftwareGPUQuerySet.js +113 -113
- package/src/shade/device/mock/SoftwareGPUSampler.js +30 -30
- package/src/shade/device/mock/SoftwareGPUShaderModule.js +32 -32
- package/src/shade/device/mock/SoftwareGPUTextureView.js +22 -22
- package/src/shade/device/mock/SoftwareGPUUncapturedErrorEvent.js +23 -23
- package/src/shade/device/mock/normalize_dynamic_offsets.js +26 -26
- package/src/shade/device/mock/texture_copy.js +287 -287
- package/src/shade/device/timing/GPUTimer.js +285 -285
- package/src/shade/device/timing/GPUTimerArray.js +205 -205
- package/src/shade/playground/add_random_lights.js +49 -49
- package/src/shade/playground/add_random_meshes.js +83 -83
- package/src/shade/playground/animation_prototype.js +508 -508
- package/src/shade/playground/animation_prototype_skinning.js +647 -647
- package/src/shade/playground/animation_prototype_stress.js +765 -765
- package/src/shade/playground/enable_picker.js +59 -59
- package/src/shade/playground/gltf_skinned_prototype.js +560 -560
- package/src/shade/playground/gltf_skinned_stress_prototype.js +387 -387
- package/src/shade/playground/gltf_viewer.js +282 -282
- package/src/shade/playground/load_default_environment.js +19 -19
- package/src/shade/playground/main.js +2727 -2727
- package/src/shade/playground/make_animated_instances.js +117 -117
- package/src/shade/playground/prototype_virtual_texture.js +274 -274
- package/src/shade/playground/prototype_volumetrics_01.js +206 -206
- package/src/shade/playground/sample.js +234 -234
- package/src/shade/playground/sample_load_gltf.js +102 -102
- package/src/shade/playground/spread_node3d_grid.js +19 -19
- package/src/shade/renderer/Renderer.js +2436 -2436
- package/src/shade/renderer/ShadeIndirectLightingMode.js +14 -14
- package/src/shade/renderer/animation/ShadeAnimationChannel.js +414 -414
- package/src/shade/renderer/animation/compute_skinned_mesh_clip_bounding_sphere.js +531 -531
- package/src/shade/renderer/animation/pose/PosePlayback.js +55 -55
- package/src/shade/renderer/animation/pose/pose_evaluate_local.js +179 -179
- package/src/shade/renderer/animation/pose/pose_evaluate_world.js +76 -76
- package/src/shade/renderer/animation/skinning/GPUMeshSkinningContext.js +1024 -1024
- package/src/shade/renderer/animation/skinning/SKINNING_BINDING_STRUCT.js +79 -79
- package/src/shade/renderer/animation/skinning/chunk_skin_blend_mesh_local.js +56 -56
- package/src/shade/renderer/binding/BindGroupManager.js +282 -282
- package/src/shade/renderer/binding/adapt_cache_capacity.js +25 -25
- package/src/shade/renderer/buffer/GPUBufferAllocator.js +116 -116
- package/src/shade/renderer/buffer/buffer_pool_ops.js +123 -123
- package/src/shade/renderer/buffer/table/GPU_DATABASE_PAGE_SIZE.js +9 -9
- package/src/shade/renderer/buffer/table/GPU_DATABASE_UPLOAD_BUFFER_LIMIT.js +8 -8
- package/src/shade/renderer/buffer/table/PageBufferPool.js +71 -71
- package/src/shade/renderer/buffer/table/PageSlotAllocator.js +95 -95
- package/src/shade/renderer/camera/Camera.js +281 -281
- package/src/shade/renderer/camera/GPUCameraContext.js +233 -233
- package/src/shade/renderer/camera/orbital/README.md +84 -84
- package/src/shade/renderer/deferred/shader_composite_volumetrics.js +75 -75
- package/src/shade/renderer/dynamic/DYNAMIC_MESH_VERTEX.js +25 -25
- package/src/shade/renderer/dynamic/GPUDynamicMeshRenderer.js +342 -342
- package/src/shade/renderer/dynamic/GPUDynamicMeshResidency.js +167 -167
- package/src/shade/renderer/dynamic/shader_dynamic_mesh.js +170 -170
- package/src/shade/renderer/extension/FrameContext.js +263 -263
- package/src/shade/renderer/extension/FramePhase.js +104 -104
- package/src/shade/renderer/extension/FrameRecord.js +126 -126
- package/src/shade/renderer/extension/GBufferTextures.js +83 -83
- package/src/shade/renderer/extension/PresentTarget.js +34 -34
- package/src/shade/renderer/extension/RENDER_EXTENSION_DESIGN.md +918 -918
- package/src/shade/renderer/extension/RenderExtension.js +69 -69
- package/src/shade/renderer/extension/RenderExtensionRegistry.js +319 -319
- package/src/shade/renderer/extension/SceneColor.js +40 -40
- package/src/shade/renderer/extension/ViewTextures.js +78 -78
- package/src/shade/renderer/fow/GPUFogOfWarRenderer.js +182 -182
- package/src/shade/renderer/geometry/Geometry.js +608 -608
- package/src/shade/renderer/geometry/geometry_build_from_meshlet_geometry.js +342 -342
- package/src/shade/renderer/geometry/meshlet_geometry_transfer.js +41 -41
- package/src/shade/renderer/geometry/primitives/make_box_geometry.js +153 -153
- package/src/shade/renderer/geometry/primitives/make_cylinder_geometry.js +240 -240
- package/src/shade/renderer/geometry/primitives/make_plane_geometry.js +145 -145
- package/src/shade/renderer/geometry/primitives/make_polyhedron_geometry.js +327 -327
- package/src/shade/renderer/geometry/primitives/make_torus_geometry.js +107 -107
- package/src/shade/renderer/geometry/primitives/make_torus_knot_geometry.js +165 -165
- package/src/shade/renderer/geometry/virtual/VGEO_FORMAT.md +607 -607
- package/src/shade/renderer/geometry/virtual/build/VGeoBuildOptions.js +66 -66
- package/src/shade/renderer/geometry/virtual/build/VGeoBuildResult.js +32 -32
- package/src/shade/renderer/geometry/virtual/build/VGeoFaceGraph.js +103 -103
- package/src/shade/renderer/geometry/virtual/build/VGeoGatheredFaces.js +25 -25
- package/src/shade/renderer/geometry/virtual/build/VGeoLevel.js +33 -33
- package/src/shade/renderer/geometry/virtual/build/VGeoLevelOptions.js +62 -62
- package/src/shade/renderer/geometry/virtual/build/VGeoLevelSummary.js +49 -49
- package/src/shade/renderer/geometry/virtual/build/VGeoSubmesh.js +20 -20
- package/src/shade/renderer/geometry/virtual/build/VirtualGeometryMesh.js +214 -214
- package/src/shade/renderer/geometry/virtual/build/gltf/GltfByteSource.js +122 -122
- package/src/shade/renderer/geometry/virtual/build/gltf/GltfCollectReport.js +29 -29
- package/src/shade/renderer/geometry/virtual/build/gltf/GltfDocument.js +210 -210
- package/src/shade/renderer/geometry/virtual/build/gltf/GltfGeometry.js +48 -48
- package/src/shade/renderer/geometry/virtual/build/gltf/GltfGeometryInstance.js +25 -25
- package/src/shade/renderer/geometry/virtual/build/gltf/GltfGeometrySelection.js +28 -28
- package/src/shade/renderer/geometry/virtual/build/gltf/gltf_collect_geometries.js +296 -296
- package/src/shade/renderer/geometry/virtual/build/gltf/gltf_open_document.js +166 -166
- package/src/shade/renderer/geometry/virtual/build/gltf/gltf_read_geometry.js +199 -199
- package/src/shade/renderer/geometry/virtual/build/vgeo_assemble_pages.js +173 -173
- package/src/shade/renderer/geometry/virtual/build/vgeo_bounding_sphere.js +28 -28
- package/src/shade/renderer/geometry/virtual/build/vgeo_build.js +200 -200
- package/src/shade/renderer/geometry/virtual/build/vgeo_build_levels.js +1786 -1786
- package/src/shade/renderer/geometry/virtual/build/vgeo_build_page_nodes.js +157 -157
- package/src/shade/renderer/geometry/virtual/build/vgeo_build_root_group.js +26 -26
- package/src/shade/renderer/geometry/virtual/build/vgeo_compute_vertex_normals.js +75 -75
- package/src/shade/renderer/geometry/virtual/build/vgeo_compute_vertex_tangents.js +143 -143
- package/src/shade/renderer/geometry/virtual/build/vgeo_containing_sphere.js +44 -44
- package/src/shade/renderer/geometry/virtual/build/vgeo_extract_submesh.js +41 -41
- package/src/shade/renderer/geometry/virtual/build/vgeo_gather_faces.js +71 -71
- package/src/shade/renderer/geometry/virtual/build/vgeo_graph_components.js +123 -123
- package/src/shade/renderer/geometry/virtual/build/vgeo_narrow_indices.js +26 -26
- package/src/shade/renderer/geometry/virtual/build/vgeo_normalize_source.js +112 -112
- package/src/shade/renderer/geometry/virtual/build/vgeo_partition_graph.js +56 -56
- package/src/shade/renderer/geometry/virtual/build/vgeo_sphere_inflate_to_contain.js +70 -70
- package/src/shade/renderer/geometry/virtual/build/vgeo_split_face_set.js +187 -187
- package/src/shade/renderer/geometry/virtual/build/vgeo_split_face_set_packed.js +207 -207
- package/src/shade/renderer/geometry/virtual/format/VGEO_DEFECT.js +18 -18
- package/src/shade/renderer/geometry/virtual/format/VGeoDefect.js +38 -38
- package/src/shade/renderer/geometry/virtual/format/VGeoWriteOptions.js +64 -64
- package/src/shade/renderer/geometry/virtual/format/attribute/VGEO_ATTRIBUTE.js +13 -13
- package/src/shade/renderer/geometry/virtual/format/attribute/VGEO_ATTRIBUTES.js +50 -50
- package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_attribute_allocate.js +28 -28
- package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_attribute_mask.js +23 -23
- package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_attributes_read.js +31 -31
- package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_copy_vertex.js +32 -32
- package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_declare.js +46 -46
- package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_like.js +19 -19
- package/src/shade/renderer/geometry/virtual/format/attribute/vgeo_layers_test_fixtures.js +27 -27
- package/src/shade/renderer/geometry/virtual/format/checksum/vgeo_asset_id_preimage.js +62 -62
- package/src/shade/renderer/geometry/virtual/format/checksum/vgeo_compute_asset_id.js +13 -13
- package/src/shade/renderer/geometry/virtual/format/checksum/vgeo_compute_directory_block_checksum.js +41 -41
- package/src/shade/renderer/geometry/virtual/format/checksum/vgeo_compute_frame_checksum.js +41 -41
- package/src/shade/renderer/geometry/virtual/format/checksum/vgeo_compute_header_checksum.js +25 -25
- package/src/shade/renderer/geometry/virtual/format/cluster/VGEO_CLUSTER_OFFSET.js +20 -20
- package/src/shade/renderer/geometry/virtual/format/cluster/VGEO_CLUSTER_RECORD_SIZE.js +5 -5
- package/src/shade/renderer/geometry/virtual/format/cluster/VGEO_MAX_CHILD_REF.js +5 -5
- package/src/shade/renderer/geometry/virtual/format/cluster/VGEO_MAX_CLUSTER_TRIANGLE_COUNT.js +5 -5
- package/src/shade/renderer/geometry/virtual/format/cluster/VGEO_MAX_CLUSTER_VERTEX_COUNT.js +5 -5
- package/src/shade/renderer/geometry/virtual/format/cluster/VGEO_NO_CHILD.js +5 -5
- package/src/shade/renderer/geometry/virtual/format/cluster/VGEO_NO_GROUP.js +5 -5
- package/src/shade/renderer/geometry/virtual/format/cluster/VGEO_SAME_PAGE.js +6 -6
- package/src/shade/renderer/geometry/virtual/format/dag/VirtualGeometryCluster.js +81 -81
- package/src/shade/renderer/geometry/virtual/format/dag/VirtualGeometryGroup.js +37 -37
- package/src/shade/renderer/geometry/virtual/format/dag/VirtualGeometryPageNode.js +55 -55
- package/src/shade/renderer/geometry/virtual/format/directory/VGEO_DIRECTORY_BLOCK_RECORDS.js +5 -5
- package/src/shade/renderer/geometry/virtual/format/directory/VGEO_DIRECTORY_FLAG_ROOT_PAGE.js +5 -5
- package/src/shade/renderer/geometry/virtual/format/directory/VGEO_DIRECTORY_RECORD_SIZE.js +5 -5
- package/src/shade/renderer/geometry/virtual/format/directory/vgeo_directory_block_count.js +12 -12
- package/src/shade/renderer/geometry/virtual/format/frame/VGEO_CHILD_OFFSET.js +11 -11
- package/src/shade/renderer/geometry/virtual/format/frame/VGEO_CHILD_TABLE_ENTRY_SIZE.js +5 -5
- package/src/shade/renderer/geometry/virtual/format/frame/VGEO_CODEC_LZ4.js +11 -11
- package/src/shade/renderer/geometry/virtual/format/frame/VGEO_CODEC_RAW.js +5 -5
- package/src/shade/renderer/geometry/virtual/format/frame/VGEO_FRAME_ALIGNMENT.js +5 -5
- package/src/shade/renderer/geometry/virtual/format/frame/VGEO_FRAME_HEADER_SIZE.js +5 -5
- package/src/shade/renderer/geometry/virtual/format/frame/VGEO_FRAME_OFFSET.js +13 -13
- package/src/shade/renderer/geometry/virtual/format/frame/VGEO_PAGE_MAGIC.js +5 -5
- package/src/shade/renderer/geometry/virtual/format/frame/VGeoFrameBlob.js +21 -21
- package/src/shade/renderer/geometry/virtual/format/frame/VGeoFrameExtent.js +59 -59
- package/src/shade/renderer/geometry/virtual/format/frame/vgeo_codec_name.js +27 -27
- package/src/shade/renderer/geometry/virtual/format/frame/vgeo_decode_frame_blob.js +84 -84
- package/src/shade/renderer/geometry/virtual/format/frame/vgeo_encode_frame_blob.js +56 -56
- package/src/shade/renderer/geometry/virtual/format/frame/vgeo_frame_decode_bound.js +35 -35
- package/src/shade/renderer/geometry/virtual/format/frame/vgeo_scan_frames.js +74 -74
- package/src/shade/renderer/geometry/virtual/format/header/VGEO_FORMAT_VERSION.js +6 -6
- package/src/shade/renderer/geometry/virtual/format/header/VGEO_HASH_ALGO_XXH3.js +5 -5
- package/src/shade/renderer/geometry/virtual/format/header/VGEO_HEADER_OFFSET.js +31 -31
- package/src/shade/renderer/geometry/virtual/format/header/VGEO_HEADER_SIZE.js +5 -5
- package/src/shade/renderer/geometry/virtual/format/header/VGEO_LEVEL_OFFSET.js +20 -20
- package/src/shade/renderer/geometry/virtual/format/header/VGEO_LEVEL_RECORD_SIZE.js +9 -9
- package/src/shade/renderer/geometry/virtual/format/header/VGEO_MAGIC.js +5 -5
- package/src/shade/renderer/geometry/virtual/format/header/VGEO_MIN_READER_VERSION.js +5 -5
- package/src/shade/renderer/geometry/virtual/format/header/VGEO_PAYLOAD_ENCODING_SHADE_MESHLET_V1.js +5 -5
- package/src/shade/renderer/geometry/virtual/format/header/VGeoLevelRecord.js +41 -41
- package/src/shade/renderer/geometry/virtual/format/page/VGEO_GROUP_RECORD_SIZE.js +5 -5
- package/src/shade/renderer/geometry/virtual/format/page/VGEO_MAX_GROUP_CLUSTER_COUNT.js +6 -6
- package/src/shade/renderer/geometry/virtual/format/page/VGEO_METRIC_OFFSET.js +21 -21
- package/src/shade/renderer/geometry/virtual/format/page/VGEO_METRIC_SIZE.js +5 -5
- package/src/shade/renderer/geometry/virtual/format/page/VGEO_NODE_FANOUT.js +9 -9
- package/src/shade/renderer/geometry/virtual/format/page/VGEO_NODE_FLAG_LEAF.js +5 -5
- package/src/shade/renderer/geometry/virtual/format/page/VGEO_NODE_OFFSET.js +10 -10
- package/src/shade/renderer/geometry/virtual/format/page/VGEO_NODE_RECORD_SIZE.js +5 -5
- package/src/shade/renderer/geometry/virtual/format/page/VGEO_PAGE_HEADER_SIZE.js +5 -5
- package/src/shade/renderer/geometry/virtual/format/page/VGEO_PAGE_OFFSET.js +16 -16
- package/src/shade/renderer/geometry/virtual/format/payload/VGEO_ENCODING_FLAGS_MASK.js +6 -6
- package/src/shade/renderer/geometry/virtual/format/payload/VGeoEncodedPayload.js +18 -18
- package/src/shade/renderer/geometry/virtual/format/payload/vgeo_encode_cluster_payload.js +200 -200
- package/src/shade/renderer/geometry/virtual/format/payload/vgeo_payload_attribute_offset.js +39 -39
- package/src/shade/renderer/geometry/virtual/format/payload/vgeo_payload_size.js +20 -20
- package/src/shade/renderer/geometry/virtual/format/prototypeVGEOFormatViewer.js +2063 -2063
- package/src/shade/renderer/geometry/virtual/format/vgeo_validate_container.js +1622 -1622
- package/src/shade/renderer/geometry/virtual/format/vgeo_write_container.js +485 -485
- package/src/shade/renderer/gpu_primitive/sort/ffx/graph_radix_sort.js +115 -115
- package/src/shade/renderer/gpu_primitive/sort/one_sweep/verify_radix_sort_one_sweep.js +110 -110
- package/src/shade/renderer/light/environment/octahedral_resample_kernel.js +50 -50
- package/src/shade/renderer/light/environment/octahedral_uv_to_direction.js +30 -30
- package/src/shade/renderer/light/environment/resample_cube_to_octahedral.js +157 -157
- package/src/shade/renderer/light/make_sunlight.js +35 -35
- package/src/shade/renderer/light/model/io/light_record_point.js +39 -39
- package/src/shade/renderer/loader/gltf/GLTF_PRIMITIVE_MODE.js +23 -23
- package/src/shade/renderer/loader/gltf/MESHOPT_COMPRESSION_PLAN.md +793 -793
- package/src/shade/renderer/loader/gltf/ext/GltfBufferViewExtension.js +54 -54
- package/src/shade/renderer/loader/gltf/ext/GltfBufferViewExtensionSet.js +109 -109
- package/src/shade/renderer/loader/gltf/ext/gltf_apply_buffer_view_extensions.js +69 -69
- package/src/shade/renderer/loader/gltf/ext/gltf_buffer_view_extensions.js +22 -22
- package/src/shade/renderer/loader/gltf/ext/gltf_geometry_extensions.js +39 -39
- package/src/shade/renderer/loader/gltf/ext/meshopt/MeshoptBufferViewExtension.js +301 -301
- package/src/shade/renderer/loader/gltf/gltf_component_type.js +223 -223
- package/src/shade/renderer/loader/gltf/gltf_node_world_matrices.js +137 -137
- package/src/shade/renderer/loader/gltf/gltf_parse_container.js +241 -241
- package/src/shade/renderer/loader/gltf/gltf_read_accessor.js +294 -294
- package/src/shade/renderer/loader/gltf/gltf_used_image_indices.js +49 -49
- package/src/shade/renderer/loader/gltf/load_gltf.js +1253 -1253
- package/src/shade/renderer/loader/gltf/tiny-gltf.js +646 -646
- package/src/shade/renderer/loader/usd/UsdError.js +33 -33
- package/src/shade/renderer/loader/usd/UsdExtensionRegistry.js +69 -69
- package/src/shade/renderer/loader/usd/load_usd.js +226 -226
- package/src/shade/renderer/loader/usd/parse_usda.js +931 -931
- package/src/shade/renderer/loader/usd/unpack_usdz.js +106 -106
- package/src/shade/renderer/loader/usd/usd_build_scene.js +658 -658
- package/src/shade/renderer/loader/usd/usd_compose_transform.js +258 -258
- package/src/shade/renderer/loader/usd/usd_decode_image.js +384 -384
- package/src/shade/renderer/loader/usd/usd_lz4.js +182 -182
- package/src/shade/renderer/loader/usd/usd_triangulate.js +159 -159
- package/src/shade/renderer/material/ShadeMaterial.d.ts +2 -2
- package/src/shade/renderer/material/ShadeMaterial.js +2 -2
- package/src/shade/renderer/material/standard/fragment_gbuffer.js +334 -334
- package/src/shade/renderer/material/standard/fragment_gbuffer_vt.js +169 -169
- package/src/shade/renderer/material/standard/material_gbuffer_vertex.js +45 -45
- package/src/shade/renderer/material/standard_material_to_struct.js +23 -23
- package/src/shade/renderer/particles/prototypeParticleSystem.js +450 -450
- package/src/shade/renderer/particles/runtime/spawn_request_encoding.js +52 -52
- package/src/shade/renderer/pool/TransientResourcePool.js +392 -392
- package/src/shade/renderer/postprocess/bloom/bloom_chain_resolution.js +29 -29
- package/src/shade/renderer/postprocess/bloom/graph_bloom_downsample.js +109 -109
- package/src/shade/renderer/postprocess/bloom/graph_postprocess_bloom.js +155 -155
- package/src/shade/renderer/postprocess/cas/shader_ffx_rcas.js +114 -114
- package/src/shade/renderer/postprocess/dof/DOF_AUTOFOCUS_PARAMS_STRUCT.js +25 -25
- package/src/shade/renderer/postprocess/dof/DOF_FOCUS_STATE_STRUCT.js +23 -23
- package/src/shade/renderer/postprocess/dof/DOF_PRESETS.js +27 -27
- package/src/shade/renderer/postprocess/dof/chunk_dof_coc_band_diameter.js +41 -41
- package/src/shade/renderer/postprocess/dof/chunk_dof_coc_band_radius.js +32 -32
- package/src/shade/renderer/postprocess/dof/chunk_dof_coc_coefficient.js +26 -26
- package/src/shade/renderer/postprocess/dof/compute_dof_autofocus_params.js +64 -64
- package/src/shade/renderer/postprocess/dof/compute_dof_uniform.js +54 -54
- package/src/shade/renderer/postprocess/dof/gather/DOF2_CONFIG.js +91 -91
- package/src/shade/renderer/postprocess/dof/gather/DOF2_PRESETS.js +9 -9
- package/src/shade/renderer/postprocess/dof/gather/DOF2_SETTINGS_STRUCT.js +66 -66
- package/src/shade/renderer/postprocess/dof/gather/DOF2_TEXTURE_FORMAT.js +22 -22
- package/src/shade/renderer/postprocess/dof/gather/DepthOfFieldU.js +292 -292
- package/src/shade/renderer/postprocess/dof/gather/chunk_dof2_coc_to_near_far.js +25 -25
- package/src/shade/renderer/postprocess/dof/gather/chunk_dof2_gather_weight.js +30 -30
- package/src/shade/renderer/postprocess/dof/gather/compute_dof2_uniform.js +54 -54
- package/src/shade/renderer/postprocess/dof/gather/graph_postprocess_dof2.js +194 -194
- package/src/shade/renderer/postprocess/dof/gather/shader_dof2_fill.js +68 -68
- package/src/shade/renderer/postprocess/dof/gather/shader_dof2_gather_far.js +140 -140
- package/src/shade/renderer/postprocess/dof/gather/shader_dof2_gather_near.js +142 -142
- package/src/shade/renderer/postprocess/dof/gather/shader_dof2_recombine.js +99 -99
- package/src/shade/renderer/postprocess/dof/gather/shader_dof2_setup.js +102 -102
- package/src/shade/renderer/postprocess/dof/gather/shader_dof2_tile_dilate.js +75 -75
- package/src/shade/renderer/postprocess/dof/gather/shader_dof2_tile_max.js +73 -73
- package/src/shade/renderer/postprocess/dof/raymarch/DOF_SETTINGS_STRUCT.js +49 -49
- package/src/shade/renderer/postprocess/dof/raymarch/DepthOfField.js +298 -298
- package/src/shade/renderer/postprocess/dof/raymarch/graph_postprocess_dof.js +244 -244
- package/src/shade/renderer/postprocess/dof/raymarch/shader_dof_composite.js +91 -91
- package/src/shade/renderer/postprocess/dof/raymarch/shader_dof_firefly_cleanup.js +61 -61
- package/src/shade/renderer/postprocess/dof/raymarch/shader_dof_prefilter.js +90 -90
- package/src/shade/renderer/postprocess/dof/raymarch/shader_dof_raymarch_compute.js +267 -267
- package/src/shade/renderer/postprocess/dof/raymarch/shader_dof_slice_compute.js +271 -271
- package/src/shade/renderer/postprocess/dof/raymarch/shader_dof_tile_dilate.js +70 -70
- package/src/shade/renderer/postprocess/dof/raymarch/shader_dof_tile_max.js +72 -72
- package/src/shade/renderer/postprocess/dof/shader_dof_autofocus.js +99 -99
- package/src/shade/renderer/postprocess/gtao/generate_magic_square_noise.js +51 -51
- package/src/shade/renderer/postprocess/motion_blur/MotionBlur.js +56 -56
- package/src/shade/renderer/postprocess/upscale-dither/NOTES.md +78 -78
- package/src/shade/renderer/postprocess/upscale-dither/UpscaleDither.js +95 -95
- package/src/shade/renderer/postprocess/upscale-dither/fragment_shader_upscale_dither.js +204 -204
- package/src/shade/renderer/rasterize/bucket/construct_primitive_state.js +58 -58
- package/src/shade/renderer/rasterize/fast/graph_rasterize_scene_fast.js +230 -230
- package/src/shade/renderer/rasterize/native/graph_rasterize_meshes_alpha_tested.js +278 -278
- package/src/shade/renderer/rasterize/native/oit/chunk_material_side_should_draw.js +26 -26
- package/src/shade/renderer/rasterize/native/oit/shader_oit_resolve_moments_ibl.js +178 -178
- package/src/shade/renderer/rasterize/standard/graph_rasterize_partial_opaque.js +235 -235
- package/src/shade/renderer/rasterize/standard/graph_rasterize_remaining_opaque.js +208 -208
- package/src/shade/renderer/rasterize/standard/graph_rasterize_scene.js +206 -206
- package/src/shade/renderer/scene/DynamicMesh.js +70 -70
- package/src/shade/renderer/scene/DynamicMeshBatch.js +90 -90
- package/src/shade/renderer/scene/GPUSceneContext.js +901 -901
- package/src/shade/renderer/scene/SceneNodeBinding.js +56 -56
- package/src/shade/renderer/scene/SkinnedMesh.js +55 -55
- package/src/shade/renderer/scene/TransformAuthority.js +33 -33
- package/src/shade/renderer/scene/optimization/deduplicate_geometries.js +38 -38
- package/src/shade/renderer/scene/optimization/deduplicate_images.js +93 -93
- package/src/shade/renderer/scene/optimization/geometry/internal/match_refit_validate.js +127 -127
- package/src/shade/renderer/scene/optimization/geometry/internal/match_solve_transform.js +492 -492
- package/src/shade/renderer/scene/optimization/optimize_texture_set.js +81 -81
- package/src/shade/renderer/scene/optimization/source_to_sampler2d.js +21 -21
- package/src/shade/renderer/scene/serialization/STANDARD_MATERIAL_SERIALIZED_BYTE_SIZE.js +12 -12
- package/src/shade/renderer/shader/chunk/geometry/quaternion/dual/chunk_dual_quat_transform_point.js +26 -26
- package/src/shade/renderer/shader/chunk/noise/chunk_interleaved_gradient_noise.js +20 -20
- package/src/shade/renderer/shader/chunk/spherical_harmonics/dering/chunk_sh2_dering_optimize_positive.js +61 -61
- package/src/shade/renderer/shader/chunk/texture/chunk_texture_filter_fxaa_lite.js +225 -225
- package/src/shade/renderer/shader/chunk/texture/dither/chunk_dither_color_8bit_gradient_noise.js +25 -25
- package/src/shade/renderer/shadow/map/DirectionalLightShadowmap.js +384 -384
- package/src/shade/renderer/shadow/map/PointLightShadowmap.js +105 -105
- package/src/shade/renderer/shadow/map/SpotLightShadowmap.js +63 -63
- package/src/shade/renderer/shadow/map/TetrahedronPointLightShadowmap.js +89 -89
- package/src/shade/renderer/shadow/map/shadowmap_update_score.js +232 -232
- package/src/shade/renderer/texture/GPUTextureAllocator.js +85 -85
- package/src/shade/renderer/texture/texture_pool_ops.js +171 -171
- package/src/shade/renderer/texture/virtual/PageTableQuadAllocator.js +253 -253
- package/src/shade/renderer/texture/virtual/README.md +276 -276
- package/src/shade/renderer/texture/virtual/VTPageTable.js +330 -330
- package/src/shade/renderer/texture/virtual/VTPhysicalCache.js +349 -349
- package/src/shade/renderer/texture/virtual/VT_CONSTANTS.js +154 -154
- package/src/shade/renderer/texture/virtual/VT_STACK_INFO_STRUCT.js +20 -20
- package/src/shade/renderer/texture/virtual/VirtualTextureManager.js +1276 -1276
- package/src/shade/renderer/texture/virtual/VirtualTextureStack.js +106 -106
- package/src/shade/renderer/texture/virtual/build_chunk_vt_lookup.js +150 -150
- package/src/shade/renderer/texture/virtual/build_shader_vt_feedback.js +232 -232
- package/src/shade/renderer/texture/virtual/chunk_vt_request_key.js +28 -28
- package/src/shade/renderer/texture/virtual/source/VTSourceImage.js +207 -207
- package/src/shade/renderer/texture/virtual/source/VTSourceProcedural.js +135 -135
- package/src/shade/renderer/texture/virtual/source/VTSourceTiled.js +132 -132
- package/src/shade/renderer/water/GPUWaterRenderer.js +167 -167
- package/src/shade/renderer/water/shader_water.js +246 -246
- package/src/shade/renderer/water/water_height_texture_from_sampler.js +56 -56
- package/src/shade/vitest.setup.mjs +89 -89
- package/src/shade/wgsl/validate_wgsl_source.js +316 -316
- package/src/view/controller/controls/NumericIntervalControl.js +90 -90
- package/src/view/controller/controls/Vector2Control.js +83 -83
- package/src/view/controller/controls/Vector3Control.js +90 -90
- package/src/view/elements/Group.js +56 -56
- package/src/view/elements/drawCheckers.js +33 -33
- package/src/view/elements/windrose/WindRoseDiagram.js +369 -369
- package/src/view/graphics/WebGLContextFailureView.js +76 -76
- package/src/view/layout/DockPanel.js +51 -51
- package/src/view/layout/SplitView.js +365 -365
- package/src/view/layout/show_popup_menu.js +81 -81
- package/src/view/minimap/MinimapCanvasView.js +411 -411
- package/src/view/minimap/MinimapImageCache.js +88 -88
- package/src/view/minimap/MinimapMarkerCollection.d.ts +0 -1
- package/src/view/minimap/MinimapMarkerCollection.d.ts.map +1 -1
- package/src/view/minimap/MinimapMarkerCollection.js +180 -180
- package/src/view/minimap/dom/MinimapCameraView.js +206 -206
- package/src/view/minimap/minimap_focus_area.js +97 -97
- package/editor/process/symbolic/SocketsSymbolicDisplay.js +0 -192
- package/src/core/geom/3d/topology/struct/binary/io/moved_tests.txt +0 -37
- package/src/engine/ecs/attachment/Attachment.d.ts +0 -40
- package/src/engine/ecs/attachment/Attachment.d.ts.map +0 -1
- package/src/engine/ecs/attachment/Attachment.js +0 -57
- package/src/engine/ecs/attachment/AttachmentBinding.d.ts +0 -28
- package/src/engine/ecs/attachment/AttachmentBinding.d.ts.map +0 -1
- package/src/engine/ecs/attachment/AttachmentBinding.js +0 -41
- package/src/engine/ecs/attachment/AttachmentSystem.d.ts +0 -61
- package/src/engine/ecs/attachment/AttachmentSystem.d.ts.map +0 -1
- package/src/engine/ecs/attachment/AttachmentSystem.js +0 -307
- package/src/engine/ecs/attachment/BoneAttachmentBinding.d.ts +0 -27
- package/src/engine/ecs/attachment/BoneAttachmentBinding.d.ts.map +0 -1
- package/src/engine/ecs/attachment/BoneAttachmentBinding.js +0 -69
- package/src/engine/ecs/attachment/TransformAttachmentBinding.d.ts +0 -4
- package/src/engine/ecs/attachment/TransformAttachmentBinding.d.ts.map +0 -1
- package/src/engine/ecs/attachment/TransformAttachmentBinding.js +0 -51
- package/src/engine/ecs/sockets/AttachmentSocket.d.ts +0 -32
- package/src/engine/ecs/sockets/AttachmentSocket.d.ts.map +0 -1
- package/src/engine/ecs/sockets/AttachmentSocket.js +0 -60
- package/src/engine/ecs/sockets/AttachmentSocketType.d.ts +0 -6
- package/src/engine/ecs/sockets/AttachmentSocketType.d.ts.map +0 -1
- package/src/engine/ecs/sockets/AttachmentSocketType.js +0 -8
- package/src/engine/ecs/sockets/AttachmentSockets.d.ts +0 -57
- package/src/engine/ecs/sockets/AttachmentSockets.d.ts.map +0 -1
- package/src/engine/ecs/sockets/AttachmentSockets.js +0 -130
- package/src/engine/ecs/sockets/BoneAttachmentSocket.d.ts +0 -29
- package/src/engine/ecs/sockets/BoneAttachmentSocket.d.ts.map +0 -1
- package/src/engine/ecs/sockets/BoneAttachmentSocket.js +0 -56
- package/src/engine/ecs/sockets/serialization/AttachmentSocketsAssetLoader.d.ts +0 -6
- package/src/engine/ecs/sockets/serialization/AttachmentSocketsAssetLoader.d.ts.map +0 -1
- package/src/engine/ecs/sockets/serialization/AttachmentSocketsAssetLoader.js +0 -19
- package/src/shade/renderer/animation/_dump_resolve.d.mts +0 -2
- package/src/shade/renderer/animation/_dump_resolve.d.mts.map +0 -1
- package/src/shade/renderer/animation/_dump_resolve.mjs +0 -5
|
@@ -1,432 +1,432 @@
|
|
|
1
|
-
# Acoustic Simulation — Implementation Plan
|
|
2
|
-
|
|
3
|
-
> A geometry-driven acoustic **simulation** layer for meep that feeds the **sopra** sound engine.
|
|
4
|
-
> Steam-Audio-equivalent in *role* (occlusion, transmission, medium, later reflections / reverb /
|
|
5
|
-
> pathing), built ECS-first and almost entirely in JS for **real-time, in-browser** use. The simulation
|
|
6
|
-
> computes scalars / IRs against meep geometry; **sopra renders them through WebAudio**. The two never
|
|
7
|
-
> blur: this folder produces data, sopra turns data into sound.
|
|
8
|
-
>
|
|
9
|
-
> Status: **P0–P6 BUILT + GREEN, all render paths wired** (full `engine/sound` suite 360 pass / 0
|
|
10
|
-
> regressions). The simulation engine + the occlusion/transmission/medium RENDER seam + the **probe-baked
|
|
11
|
-
> reverb RENDER** + the **corner-leakage (pathing) RENDER** are complete and wired into sopra + the ECS
|
|
12
|
-
> (`AudioEmitterSystem`). Reverb render uses **option B** — a new acoustic-owned `ProbeReverbRenderer`
|
|
13
|
-
> (its own double-buffered ConvolverNode crossfade, IR from the nearest probe's baked decay), leaving
|
|
14
|
-
> sopra's static `ReverbEffect` untouched. Pathing render is an **engine-wide `AcousticSimulator.pathing`
|
|
15
|
-
> toggle** (off by default, zero cost when off): one single-source Dijkstra from the listener per frame
|
|
16
|
-
> (`AcousticPathGraph.computeExitField`) gives every probe its exit point; each occluded source routes a
|
|
17
|
-
> second exit-spatialized send (`EventInstance` path branch). No per-source flag — threaded from the
|
|
18
|
-
> engine config like `acoustic`. **ECS WIRING HELPER LANDED (2026-06-20):** `configureAcousticSimulation`
|
|
19
|
-
> (`simulation/configureAcousticSimulation.js`) — one call from a config builds/reuses the shared
|
|
20
|
-
> `AcousticSimulator`, adds `AcousticSimulationSystem` + `AcousticVolumeSystem` (via `addManySystems`),
|
|
21
|
-
> and injects the simulator (+ optional `ProbeReverbRenderer`) into the `AudioEmitterSystem`. So the only
|
|
22
|
-
> meep-internal integration is done; **Remaining:** the EXTERNAL config call (`makeMirEngineConfig`, in moh
|
|
23
|
-
> — out of meep scope) + save/load serialization registration, both gated on the sopra strangler
|
|
24
|
-
> migration. Serialization adapters are deliberately NOT built yet — they mirror `AudioEmitter`, which has
|
|
25
|
-
> none either (the new sound stack defers binary save integration); the acoustic components carry JSON
|
|
26
|
-
> `toJSON`/`fromJSON` + `typeName` for when the migration lands. To wire reverb: connect a sopra bus send →
|
|
27
|
-
> `ProbeReverbRenderer.input`, pass `probeReverb` to `configureAcousticSimulation` (or set
|
|
28
|
-
> `system.probeReverb`) + `renderer.setProbeField(bakedField)`. To wire pathing: `sim.pathing = true` +
|
|
29
|
-
> `sim.setPathGraph(bakeVisibility(probeField, sim.occluderIndex))`.
|
|
30
|
-
>
|
|
31
|
-
> **What landed per phase:**
|
|
32
|
-
> - **P0** — `AcousticMaterial`, `RayHit`, `AcousticOccluderIndex` (per-body local ebvh BLAS, O(1) `setTransform`).
|
|
33
|
-
> - **P1** — `OcclusionSolver` (volumetric fibonacci rays + seeded jitter + EMA), `VolumeField`, `AcousticMedium`/`AcousticSolution`/`AcousticSourceState`.
|
|
34
|
-
> - **P2** — `AcousticBody` + `AcousticSimulationSystem` (reactive); `AcousticSimulator`; occluder shapes raycast directly via `AbstractShape3D.raycast` (no triangulation).
|
|
35
|
-
> - **P3** — `EventInstance.setAcoustic` + node insert (occlusion gain + lowpass + transmission); `AudioEmitter.acoustic`; `AudioEmitterSystem` apply + `LiveEmitterSet` acoustic threading. **First audible occlusion — wired.**
|
|
36
|
-
> - **P4** — `AcousticVolume` + `AcousticVolumeSystem` (medium, blended, live-tracked).
|
|
37
|
-
> - **P5** — world-AABB broadphase (measurement-driven via `bench/occlusion.bench.spec.js`); temporal amortization proven.
|
|
38
|
-
> - **P6** — `AcousticProbe` + `bakeReverb` + `ProbeField` + `bakeProbeField` (geometry-derived reverb, density knob, serialized); `AcousticPathGraph` + `bakeVisibility` + `findAcousticPath` (probe-visibility routing around obstacles).
|
|
39
|
-
>
|
|
40
|
-
> **Post-P6 cleanup + accel pass (2026-06-20, all committed, `engine/sound` 373 pass):** the occluder
|
|
41
|
-
> index now **raycasts shapes directly** via `AbstractShape3D.raycast` (no triangulation;
|
|
42
|
-
> `acoustic_geometry_from_shape` deleted) and sits behind a **TLAS** — a dynamic BVH over the bodies'
|
|
43
|
-
> world AABBs (P5's deferred TLAS, landed early). `RayHit` carries the world hit **point + normal** (no
|
|
44
|
-
> `hit` flag, no `triangleIndex`). Per-source state is **pooled** in a `BinaryElementPool`
|
|
45
|
-
> (`Map<EventInstance, id>`, flyweight cursor) instead of a `Map<…, AcousticSourceState>`. The probe
|
|
46
|
-
> substrate moved to **`RowFirstTable` + a probe BVH** (nearest via `bvh_query_user_data_nearest_to_point`)
|
|
47
|
-
> and **`CSRGraph`** connectivity. `sourceRadius` moved onto `AudioEmitter`/`EventInstance`;
|
|
48
|
-
> `pathMaxDistance` was removed (path falloff now derives from the source's authored attenuation curve);
|
|
49
|
-
> `AcousticSolution.exit` is a vector. Below, §3.1 / §4 / D5 / P5 describe the v1 triangle-BLAS +
|
|
50
|
-
> linear-scan design that this pass superseded — read them as history. The remaining headline work is the
|
|
51
|
-
> ray-traced reflection IR (see `REFLECTION_IR_PLAN.md`).
|
|
52
|
-
>
|
|
53
|
-
> **FOA directional reverb LANDED (2026-06-20):** the first of P6's two premium tiers — the **FOA
|
|
54
|
-
> (first-order ambisonic / B-format) directional reverb field**. The bake now captures, per band, the
|
|
55
|
-
> energy-weighted **arrival direction** (a 0..1 anisotropy vector) by reciprocity — a ray's reverberant
|
|
56
|
-
> energy arrives from its launch direction (`acoustic_trace_energy` accumulates it, `bakeReverbBands`
|
|
57
|
-
> normalises it). `ProbeField` widened stride 6→15 to store the three per-band direction vectors (JSON
|
|
58
|
-
> round-trips them). Render: a new `render/FoaProbeReverbRenderer` convolves the mono send into a B-format
|
|
59
|
-
> set (`foaReverbImpulseResponse` — `W` omni + `X/Y/Z` steered by the baked direction, one-factor W-energy
|
|
60
|
-
> normalised) and decodes to stereo by **rotating the decoder, not the soundfield** (two virtual cardioids
|
|
61
|
-
> whose look dirs are rotated into world space by the listener orientation — six decode gains/frame, the IR
|
|
62
|
-
> re-baked only on probe-cell change). `AudioEmitterSystem` now threads the listener rotation to
|
|
63
|
-
> `probeReverb.update()` (the scalar `ProbeReverbRenderer` ignores it). Stereo decode is isolated so a
|
|
64
|
-
> binaural/HRTF (SOFA) decoder can replace it later.
|
|
65
|
-
>
|
|
66
|
-
> **Source directivity LANDED (2026-06-20):** the second of P6's premium tiers. `AcousticDirectivity`
|
|
67
|
-
> (`simulation/definition/`) is the Steam-Audio dipole model — `gain = |(1−w) + w·cosθ|^p`
|
|
68
|
-
> (`w` = `dipoleWeight` 0=omni/0.5=cardioid/1=dipole, `p` = `dipolePower`), `cosθ` = source forward · the
|
|
69
|
-
> source→listener direction. Authored on `AudioEmitter.directivity` (default omni → zero cost; `isOmni`
|
|
70
|
-
> short-circuits). The simulator's `apply` computes it per non-omni source (forward = `Vector3.forward`
|
|
71
|
-
> rotated by the source's orientation) into `AcousticSolution.directivityGain`, which `EventInstance.setAcoustic`
|
|
72
|
-
> multiplies into the direct-path gain. Orientation (shared `Transform.rotation` ref) + the directivity ref
|
|
73
|
-
> plumb through `playEvent`/`LiveEmitterSet` exactly like `sourceRadius`/`position`. **P6 premium tiers now
|
|
74
|
-
> both done;** the only remaining acoustic work is the external `makeMirEngineConfig` activation + save/load
|
|
75
|
-
> serialization (gated on the sopra strangler migration) and the deferred optional refinements (NEE early
|
|
76
|
-
> reflections, pathing live-recheck, door variants, binaural/SOFA decode).
|
|
77
|
-
>
|
|
78
|
-
> **DISTANCE AIR ABSORPTION LANDED (2026-06-20):** "low frequencies travel further." `AcousticMedium.airAbsorption`
|
|
79
|
-
> is now **dB/metre**; `VolumeField.integrateAbsorption` line-integrates it over the source→listener path
|
|
80
|
-
> (`∫ α ds`; no-region case is closed-form `ambient·distance`, else 8-midpoint march reusing `sample`) into the
|
|
81
|
-
> new `AcousticSolution.airLoss[3]` (per-band total dB). The point-sampled `AcousticSolution.medium` was
|
|
82
|
-
> REMOVED (superseding §6's `airAbsLP.frequency ← solution.medium.airAbsorption` — air is now path-integrated,
|
|
83
|
-
> not point-sampled). Render (`EventInstance.setAcoustic`) anchors the tilt at the LOW band — only
|
|
84
|
-
> `airLoss[high] − airLoss[low]` darkens the cutoff (`OPEN·2^(−tilt/6dB-oct)`, floored), so a uniform loss (the
|
|
85
|
-
> distance **attenuation curve's** job, a windowed/irradiance falloff — *not* physical) causes no darkening:
|
|
86
|
-
> the curve owns loudness, air owns the spectral tilt, and the two compose via separate series nodes. Default
|
|
87
|
-
> ambient = a small low-anchored atmosphere (`DEFAULT_AIR_ABSORPTION [0, 0.03, 0.1] dB/m`, tunable). Applied to
|
|
88
|
-
> the DIRECT path only (the leak send's longer path is a deferred refinement, like directivity-on-leak).
|
|
89
|
-
>
|
|
90
|
-
> **CORNER-LEAK REFINEMENTS + DYNAMIC RECHECK + SERIALIZATION LANDED (2026-06-21):** the three corner-leak
|
|
91
|
-
> gaps are closed, plus the acoustic binary adapters. (1) **Leak now carries directivity + air.**
|
|
92
|
-
> `AcousticSimulator.#applyPath` walks the leaked polyline ONCE (source→…→listener via
|
|
93
|
-
> `ProbeFieldPathingSolution.next`) and does three things: integrates air per leg
|
|
94
|
-
> (`VolumeField.integrateAbsorption`) into the new `AcousticSolution.pathAirLoss[3]`; folds **directivity toward
|
|
95
|
-
> the FIRST hop** (the corner the source radiates into, not the blocked listener — `#directivityGainToward`)
|
|
96
|
-
> into `pathGain`; and marks each traversed edge for the recheck. `EventInstance`'s leak branch renders through
|
|
97
|
-
> its own 3-band crossover (`#leak3Band`), gained per band by `(1 − transmission[b])` × the `pathAirLoss`
|
|
98
|
-
> low-anchored tilt (so a longer routed leak darkens more, and a band-selective wall leaks only its blocked
|
|
99
|
-
> bands around the corner — consistent with the direct path's 3-band render).
|
|
100
|
-
> (2) **Budgeted dynamic-geometry recheck** (`AcousticSimulator.pathingRecheck` + `recheckBudget`, off by
|
|
101
|
-
> default): `ProbeVisibilityRecheck` re-verifies (within budget, FIFO round-robin) the edges leaks traverse
|
|
102
|
-
> against live geometry (`probe_edge_visible`, extracted + shared with `bakeVisibility`); a now-blocked edge →
|
|
103
|
-
> `EDGE_WEIGHT_BLOCKED` (Float32 max — finite, no topology change, blows the path distance past audibility),
|
|
104
|
-
> restored to the inter-probe distance when it re-opens. No structural mutation; the baked graph self-heals.
|
|
105
|
-
> (3) **Binary serialization** adapters for `AcousticMaterial`/`AcousticMedium`/`AcousticDirectivity` (value
|
|
106
|
-
> types) + `AcousticBody`/`AcousticVolume` (components, delegating; shape omitted like `toJSON`), with
|
|
107
|
-
> `populateAcousticSerializationRegistry`. (`AudioEmitter`'s own adapter — needing the full sopra
|
|
108
|
-
> `EventDescription` clip-graph chain — is still deferred.) Plus a **two-rooms-and-a-corridor integration
|
|
109
|
-
> test** (`two_rooms_corridor.spec.js`) verifying bake (per-band reverb), reachability, leak direction
|
|
110
|
-
> (emerges from the corridor, not through the wall), routed-vs-straight attenuation, and a sealed-divider
|
|
111
|
-
> disconnection control. **Remaining deferred** (optional/premium): NEE early reflections, binaural/SOFA
|
|
112
|
-
> decode, opt-in door variants + re-bake-on-streaming, region-aware air over the leak polyline, the full
|
|
113
|
-
> external `makeMirEngineConfig` activation (gated on the sopra strangler migration).
|
|
114
|
-
|
|
115
|
-
---
|
|
116
|
-
|
|
117
|
-
## 0. The one rule: simulation vs. render
|
|
118
|
-
|
|
119
|
-
```
|
|
120
|
-
SIMULATION (this folder — engine geometry, JS, no WebAudio) RENDER (sopra — WebAudio)
|
|
121
|
-
─────────────────────────────────────────────────────────── ─────────────────────────
|
|
122
|
-
AcousticBody (occluder shapes + material) ─┐
|
|
123
|
-
AcousticVolume (medium) ├─► AcousticSolution ─► EventInstance.setAcoustic()
|
|
124
|
-
ebvh rays + Ray3 + sphere_fibonacci_point ───┘ (a class) (gain + biquad insert)
|
|
125
|
-
```
|
|
126
|
-
|
|
127
|
-
`simulation/core` and `simulation/ecs` import **no WebAudio**. The *only* WebAudio touch is the seam
|
|
128
|
-
where `AudioEmitterSystem` hands an `AcousticSolution` to `EventInstance.setAcoustic(...)` (that method
|
|
129
|
-
lives in sopra, where the node chain already lives). Consequence: the whole simulation is unit-testable
|
|
130
|
-
on real geometry with **zero `MockAudioContext`** — only the one render seam needs it.
|
|
131
|
-
|
|
132
|
-
We do **not** put medium on `EventDescription`. An event is a recipe for *a source*; the medium (air,
|
|
133
|
-
room) is a property of *the world*. Medium lives on `AcousticVolume` components; a source merely **opts
|
|
134
|
-
in** to simulation via one flag (`AudioEmitter.acoustic`). No god-object `AcousticScene` — the occluder
|
|
135
|
-
set is just the entities that have an `AcousticBody`, indexed by a system-owned acceleration structure.
|
|
136
|
-
This is an ECS engine at the top level; the data model is components.
|
|
137
|
-
|
|
138
|
-
---
|
|
139
|
-
|
|
140
|
-
## 1. Layout
|
|
141
|
-
|
|
142
|
-
```
|
|
143
|
-
sound/simulation/
|
|
144
|
-
IMPLEMENTATION_PLAN.md
|
|
145
|
-
definition/ authored, immutable, serializable (sopra/definition style)
|
|
146
|
-
AcousticMaterial.js value class: absorption[3], scattering, transmission[3]
|
|
147
|
-
AcousticMaterialSerializationAdapter.js
|
|
148
|
-
core/ ECS-agnostic AND WebAudio-agnostic — the testable heart
|
|
149
|
-
RayHit.js result class: t / material / bodyHandle / world position + normal
|
|
150
|
-
AcousticOccluderIndex.js OccluderBody shapes + world transform behind a TLAS BVH; closestHit / anyHit
|
|
151
|
-
AcousticMedium.js value class: airAbsorption (per-band)
|
|
152
|
-
AcousticSolution.js result class the render seam consumes: occlusion, transmission[3], medium
|
|
153
|
-
AcousticSourceState.js transient per-source accumulation (rolling occlusion, smoothing)
|
|
154
|
-
OcclusionSolver.js solve(listener, source, index, rayCount, state, out) — explicit args, out-param
|
|
155
|
-
VolumeField.js sample(volumes, x, y, z, out) — out-param, no allocation
|
|
156
|
-
sampleDirections.js sphere_fibonacci_point set + per-tick seededRandom rotation
|
|
157
|
-
ecs/ thin ECS binding (real-component tested)
|
|
158
|
-
AcousticBody.js component: AcousticMaterial + "is occluder"; pairs with Collider + Transform
|
|
159
|
-
AcousticBodySerializationAdapter.js
|
|
160
|
-
AcousticVolume.js component: AbstractShape3D + AcousticMedium + transition band
|
|
161
|
-
AcousticVolumeSerializationAdapter.js
|
|
162
|
-
AcousticSimulationSystem.js System: maintain index + volume set (reactive); apply(liveInstances, listener)
|
|
163
|
-
probe/ P6 — the baked substrate for reverb + pathing (see D6)
|
|
164
|
-
bench/
|
|
165
|
-
occlusion.bench.spec.js rays/tick + ms/tick calibration (raycast.bench methodology)
|
|
166
|
-
```
|
|
167
|
-
|
|
168
|
-
The render-side additions (`EventInstance.setAcoustic`, the node insert, `AudioEmitter.acoustic`) live in
|
|
169
|
-
**sopra**, not here — see §6.
|
|
170
|
-
|
|
171
|
-
---
|
|
172
|
-
|
|
173
|
-
## 2. Reused meep primitives (verified to exist)
|
|
174
|
-
|
|
175
|
-
| Primitive | Path | Used for |
|
|
176
|
-
|---|---|---|
|
|
177
|
-
| `ebvh_geometry_query_nearest_triangle_ray` | `core/bvh2/bvh3/` | closest-hit ray → `[triangleIndex,u,v,t]` |
|
|
178
|
-
| `ebvh_build_for_geometry_morton` | `core/bvh2/bvh3/` | build a body's BLAS from its triangle soup |
|
|
179
|
-
| `BVH` | `core/bvh2/bvh3/BVH.js` | the per-body tree (`new BVH()`, `release_all`, `allocate_linear`, `root`) |
|
|
180
|
-
| `Ray3` (`Float32Array(7)`: o,d,tMax) | `core/geom/3d/ray/Ray3.js` | the ray type; slots into the ebvh query as-is; `applyMatrix4` for local transform |
|
|
181
|
-
| `m4_invert` / `m4_inverse_rotation_translation` | `core/geom/3d/mat4/` | per-body world→local inverse |
|
|
182
|
-
| `sphere_fibonacci_point` | `core/geom/3d/sphere/` | even source-sphere / hemisphere sampling |
|
|
183
|
-
| `v3_orthonormal_matrix_from_normal` + `v3_matrix3_rotate` | `core/geom/vec3/` | hemisphere sampling around a normal (P6) |
|
|
184
|
-
| `seededRandom` (Mulberry32) | `core/math/random/` | per-tick ray jitter; **never `Math.random`** |
|
|
185
|
-
| `AbstractShape3D.signed_distance_at_point` / `contains_point` | `core/geom/3d/shape/` | `AcousticVolume` boundary blend |
|
|
186
|
-
| `AnimationCurve` | `engine/animation/curve/` | distance→cutoff curves (reuse, don't invent) |
|
|
187
|
-
| `BinarySerializationRegistry` + adapter pattern | `ecs/storage/binary/` | serialize materials/bodies/volumes |
|
|
188
|
-
| SH toolkit (`sh3_rotate_bl`, `sh3_sample_by_direction`, `sh3_add`) | `core/geom/3d/sphere/harmonics/` | ambisonic field (P6) |
|
|
189
|
-
| `AssetManager` + `OfflineAudioContext` | `engine/asset/` / browser | baked probe data + offline IR (P6) |
|
|
190
|
-
|
|
191
|
-
---
|
|
192
|
-
|
|
193
|
-
## 3. Encapsulation (the clean core)
|
|
194
|
-
|
|
195
|
-
**Two non-negotiables, applied everywhere below:**
|
|
196
|
-
- **No opaque config bags.** Tunables (`rayCount`, …) are passed as explicit arguments. Configuration
|
|
197
|
-
objects rot — a function that needs a ray count takes a ray count.
|
|
198
|
-
- **No magic structs / `@typedef`.** Every result/value shape is a real **class** (`RayHit`,
|
|
199
|
-
`AcousticSolution`, `AcousticMedium`, `AcousticSourceState`, `AcousticMaterial`). Hot-path queries are
|
|
200
|
-
**allocation-free**: the caller allocates the result and passes it in; the function writes into it.
|
|
201
|
-
|
|
202
|
-
### 3.1 `AcousticOccluderIndex.js` — the (internal) acceleration structure, fully dynamic
|
|
203
|
-
Not a public "scene". Owns a list of **bodies**, each a *local-space* triangle BLAS (`BVH` built once via
|
|
204
|
-
`ebvh_build_for_geometry_morton`) plus a world transform (and its cached inverse) and one
|
|
205
|
-
`AcousticMaterial`. API:
|
|
206
|
-
|
|
207
|
-
```js
|
|
208
|
-
addBody(positions, indices, material, matrix?) → handle // BLAS built once from local triangles
|
|
209
|
-
setTransform(handle, matrix) // O(1): store matrix + recompute inverse
|
|
210
|
-
removeBody(handle)
|
|
211
|
-
closestHit(ray /* Ray3 */, out /* RayHit */) → boolean // nearest hit across all bodies, into `out`
|
|
212
|
-
anyHit(ray /* Ray3 */) → boolean // early-out
|
|
213
|
-
```
|
|
214
|
-
|
|
215
|
-
`closestHit` transforms the world ray into each body's local frame (a module-static `Ray3` scratch +
|
|
216
|
-
`applyMatrix4(inverse)`), runs the ebvh query against that body's BLAS bounded by the running best-`t`,
|
|
217
|
-
and keeps the nearest; `out` receives `{ t, material, bodyHandle, triangleIndex }`. **Fully dynamic**:
|
|
218
|
-
a moving body is just `setTransform` (O(1), no rebuild) — the ECS layer drives it from
|
|
219
|
-
`Transform.position.onChanged`. Material is **per body** (a wall has one material); per-triangle
|
|
220
|
-
materials are a later refinement, not a v1 need. *Precondition: rigid transforms (no scale), so local
|
|
221
|
-
`t` equals world `t`* (documented, not guarded — see house rules). A body-level BVH (TLAS) over the bodies
|
|
222
|
-
is the **P5** scaling step; v1 linear-scans the (few) bodies, BLAS does the real work.
|
|
223
|
-
|
|
224
|
-
### 3.2 `OcclusionSolver.js` — the per-source solve (pure, explicit args, out-param)
|
|
225
|
-
```js
|
|
226
|
-
solve(listenerPose, sourceX, sourceY, sourceZ, sourceRadius, index, rayCount, state, out) → void
|
|
227
|
-
```
|
|
228
|
-
Shoots `rayCount` rays from the listener toward a `sphere_fibonacci_point` set over the source's sphere
|
|
229
|
-
(`sourceRadius`), rotated per tick by a `seededRandom` orientation (so accumulation covers the sphere).
|
|
230
|
-
Each ray is bounded (`tMax` = listener→sample distance) so far subtrees prune. Blocked-ray fraction →
|
|
231
|
-
instantaneous occlusion; blocked rays' materials accumulate the transmission 3-band. Folded into `state`
|
|
232
|
-
(`AcousticSourceState`, a rolling window) and smoothed; written into `out` (`AcousticSolution`).
|
|
233
|
-
**Pure function of geometry + state**, deterministic for a seed; no ECS, no WebAudio, no allocation.
|
|
234
|
-
|
|
235
|
-
### 3.3 `VolumeField.js` — medium zones (pure, out-param)
|
|
236
|
-
```js
|
|
237
|
-
sample(volumes, x, y, z, out /* AcousticMedium */) → void
|
|
238
|
-
```
|
|
239
|
-
Each `AcousticVolume` has an `AbstractShape3D` and a `transition` band. Weight =
|
|
240
|
-
`smooth(-signed_distance / transition)` clamped to `[0,1]` (1 deep inside, 0 outside, smooth across the
|
|
241
|
-
boundary). Normalize weights over overlapping volumes; blend the medium into `out`. A few
|
|
242
|
-
`signed_distance_at_point` evals per query — cheap. Queried at the listener every tick; at sources
|
|
243
|
-
optionally. **Pure**, allocation-free.
|
|
244
|
-
|
|
245
|
-
### 3.4 result + state classes
|
|
246
|
-
`RayHit`, `AcousticSolution`, `AcousticMedium`, `AcousticSourceState`, `AcousticMaterial` are all real
|
|
247
|
-
classes with named fields and a `reset()`/`clear()` where they are reused. The system owns a
|
|
248
|
-
`Map<EventInstance, AcousticSourceState>`, dropped on `instance.onEnded` — so `EventInstance` stays
|
|
249
|
-
ignorant of solver internals.
|
|
250
|
-
|
|
251
|
-
---
|
|
252
|
-
|
|
253
|
-
## 4. The component model (ECS)
|
|
254
|
-
|
|
255
|
-
### `AcousticBody` (occluder) — pairs with `Collider` + `Transform`
|
|
256
|
-
Serializable component carrying an `AcousticMaterial` and the "this entity occludes audio" semantic. The
|
|
257
|
-
**shape** comes from the entity's existing `Collider`/mesh; `AcousticBody` contributes the acoustic
|
|
258
|
-
*properties*. The system triangulates the body's collider shape once into the occluder index (local
|
|
259
|
-
space) and drives its transform reactively. Tagging a wall = adding the component; nothing
|
|
260
|
-
acoustically-inert occludes unless tagged — that closes the "physics BVH contains everything" problem the
|
|
261
|
-
ECS way.
|
|
262
|
-
|
|
263
|
-
### `AcousticVolume` (medium) — pairs with `Transform`
|
|
264
|
-
Serializable component: an `AbstractShape3D` (its region), a `transition` distance (boundary blend band),
|
|
265
|
-
and an `AcousticMedium` (air-absorption coefficients). Volumes overlap and blend (§3.3). **Medium only —
|
|
266
|
-
no reverb here.** (Authored "reverb zones" are the wrong primitive; real reverb is the geometry-traced /
|
|
267
|
-
baked output of the probe volume in P6. Until then, sopra's existing reverb stands unchanged.)
|
|
268
|
-
|
|
269
|
-
### `AcousticSimulationSystem` — the binding
|
|
270
|
-
`extends System`, `dependencies` covering `AcousticBody`/`AcousticVolume`:
|
|
271
|
-
- `link/unlink AcousticBody` → `index.addBody/removeBody` + subscribe `transform.position.onChanged`
|
|
272
|
-
(and rotation) → `index.setTransform`. **Reactive, no per-tick refit loop** (mirrors
|
|
273
|
-
`SpatialAudioIndex`).
|
|
274
|
-
- `link/unlink AcousticVolume` → add/remove from the volume list.
|
|
275
|
-
- `apply(liveInstances, listenerPose)` — **called by `AudioEmitterSystem`** between `liveSet.refresh`
|
|
276
|
-
and `sopra.update`. Samples the listener medium once, then for each **live 3D** instance opted into
|
|
277
|
-
acoustics: `OcclusionSolver.solve(...)` (+ optional per-source `VolumeField.sample`) into a pooled
|
|
278
|
-
`AcousticSolution` → `instance.setAcoustic(solution)`. Bounded to ≤ budget (consumes the live set,
|
|
279
|
-
never iterates all registered emitters).
|
|
280
|
-
|
|
281
|
-
`AudioEmitterSystem` takes an **optional injected** `acousticSim` collaborator (default none → behaviour
|
|
282
|
-
identical to today). Feature is off-by-default and testable in isolation.
|
|
283
|
-
|
|
284
|
-
---
|
|
285
|
-
|
|
286
|
-
## 5. Key decisions
|
|
287
|
-
|
|
288
|
-
- **D1 — Event carries no medium; one opt-in flag.** `AudioEmitter.acoustic` (default `false`) plumbs to
|
|
289
|
-
the instance; `EventInstance` builds the acoustic nodes only when set; `setAcoustic` is a no-op
|
|
290
|
-
otherwise. `EventDescription` stays medium-free. (Owner-directed.)
|
|
291
|
-
- **D2 — No `AcousticScene`; geometry is `AcousticBody` components, indexed internally.**
|
|
292
|
-
- **D3 — `AcousticVolume` is medium-only.** No authored reverb zones. Reverb is the P6 traced/baked
|
|
293
|
-
output; sopra's existing reverb stands until then.
|
|
294
|
-
- **D4 — `simulation/` imports no WebAudio.** It emits `AcousticSolution`s; sopra renders. The whole
|
|
295
|
-
simulation is testable without `MockAudioContext`.
|
|
296
|
-
- **D5 — Occluders are fully dynamic.** No static merge. Per-body local BLAS + an O(1) `setTransform`;
|
|
297
|
-
the ECS layer refits reactively via `Transform.onChanged` (meep is reactive end-to-end — there is no
|
|
298
|
-
static/dynamic flag and no per-tick iteration). A body-level TLAS is the P5 scaling step, not a
|
|
299
|
-
correctness requirement.
|
|
300
|
-
- **D6 — Using the sim requires a built probe volume; the bake is automatic.** When acoustics is enabled
|
|
301
|
-
for a scene, a **probe volume** must be built (it is the substrate for reverb + pathing). The bake is
|
|
302
|
-
**fully automatic** save for a few knobs (chiefly **maximum probe density**): it places probes across
|
|
303
|
-
the playable space, computes their data (reflection/reverb IR + inter-probe visibility for pathing),
|
|
304
|
-
and **serializes** the result. Triggering the bake is the user's responsibility (an explicit call /
|
|
305
|
-
editor action — it is not free), but the user authors no probes by hand. Runtime then just loads and
|
|
306
|
-
selects/blends baked probe data. (This is why pathing/reverb are P6: they consume the probe volume.)
|
|
307
|
-
- **D7 — No opaque config bags; explicit args.** Tunables are parameters, not config objects.
|
|
308
|
-
- **D8 — No magic structs; classes + caller-allocated out-params.** Hot-path queries allocate nothing.
|
|
309
|
-
- **D9 — Cosmetic-only, so no determinism gate.** Rays use `seededRandom` (reproducible tests, clean
|
|
310
|
-
jitter), but there is no lockstep/networking requirement. If acoustics ever become gameplay-affecting
|
|
311
|
-
(AI hearing), that is a different project with a different bar.
|
|
312
|
-
- **D10 — Bounded, amortized, allocation-free.** Work is capped to the ≤ budget (64) live voices;
|
|
313
|
-
`rayCount` is amortized across frames into `AcousticSourceState`; apply is throttleable; results +
|
|
314
|
-
scratch are pooled. JS constant factors are accepted; the budget is the contract.
|
|
315
|
-
|
|
316
|
-
---
|
|
317
|
-
|
|
318
|
-
## 6. Render seam (in sopra — the only WebAudio change)
|
|
319
|
-
|
|
320
|
-
`EventInstance.#buildOutputChain` (today `voices → instanceGain → attenuationGain → panner → bus`) gains,
|
|
321
|
-
**only when the instance is acoustic**, an insert + a parallel transmission branch:
|
|
322
|
-
|
|
323
|
-
```
|
|
324
|
-
voices → instanceGain → attenuationGain → airAbsLP → occlusionGain → occlusionLP → panner → bus
|
|
325
|
-
└→ transmission 3-band (parallel GainNodes) ─┘
|
|
326
|
-
```
|
|
327
|
-
|
|
328
|
-
`EventInstance.setAcoustic(solution)` ramps those `AudioParam`s (smoothing — no zipper):
|
|
329
|
-
`occlusionGain ← 1-occlusion`, `occlusionLP.frequency ← f(occlusion)`, the three transmission band gains
|
|
330
|
-
← `(1-occlusion) + occlusion·transmission[band]` (**parallel crossover, not series shelves** — band gains
|
|
331
|
-
are independent and linear), `airAbsLP.frequency ← solution.medium.airAbsorption`. All nodes default to
|
|
332
|
-
unity / open → an acoustics-off or 2D event is byte-identical to today. (Reverb is untouched here; it is
|
|
333
|
-
the P6 probe-driven concern.)
|
|
334
|
-
|
|
335
|
-
---
|
|
336
|
-
|
|
337
|
-
## 7. Phased plan
|
|
338
|
-
|
|
339
|
-
Each phase ships behind black-box `*.spec.js` run from `H:/git/moh` root
|
|
340
|
-
(`npx jest --config jest.conf.json engine/sound/simulation`). Real objects per house rules; the WebAudio
|
|
341
|
-
boundary (only P3+) uses `MockAudioContext`.
|
|
342
|
-
|
|
343
|
-
- **P0 — Core occluder substrate (no ECS, no WebAudio). ← building now.** `AcousticMaterial` class +
|
|
344
|
-
adapter; `RayHit` class; `AcousticOccluderIndex` (per-body local BLAS via `ebvh_build_for_geometry_morton`,
|
|
345
|
-
`Ray3`-based `closestHit`/`anyHit` into a caller `RayHit`, O(1) `setTransform`).
|
|
346
|
-
*Exit:* a hand-built box room answers closest-hit + per-body material correctly; a ray through an
|
|
347
|
-
opening misses; moving a body via `setTransform` changes the result; `anyHit` early-outs; material
|
|
348
|
-
round-trips. Zero ECS/WebAudio.
|
|
349
|
-
- **P1 — `OcclusionSolver` + `VolumeField` + state (still no ECS/WebAudio).** Volumetric sampling
|
|
350
|
-
(`sphere_fibonacci_point` + `seededRandom` rotation), temporal accumulation in `AcousticSourceState`,
|
|
351
|
-
smoothing; `VolumeField` blend with `AcousticMedium`.
|
|
352
|
-
*Exit:* occlusion monotonic vs. wall coverage; fully walled → 1 with the wall's material in
|
|
353
|
-
transmission; open → 0; frame-stable; deterministic for a seed; volume blend + boundary interpolation
|
|
354
|
-
correct. Pure functions on geometry, allocation-free.
|
|
355
|
-
- **P2 — ECS binding for occlusion.** `AcousticBody` + adapter; `AcousticSimulationSystem`
|
|
356
|
-
(reactive link/unlink + `setTransform`; `apply` loops live 3D instances → solver; owns the per-instance
|
|
357
|
-
state map).
|
|
358
|
-
*Exit:* real `EntityManager` + real `AcousticBody`/`Transform`/`Collider`; add/remove/move a body
|
|
359
|
-
changes the solution; cost bounded to ≤ budget. No WebAudio (assert on returned solutions).
|
|
360
|
-
- **P3 — Render seam (first audible occlusion + transmission).** `EventInstance.setAcoustic` + the
|
|
361
|
-
no-op-default node insert; `AudioEmitter.acoustic` flag; `AudioEmitterSystem` calls `acousticSim.apply`
|
|
362
|
-
between `refresh` and `sopra.update`.
|
|
363
|
-
*Exit (MockAudioContext):* occlusion moves the gain + lowpass; transmission bands respond to material;
|
|
364
|
-
acoustics-off events identical to today; off-by-default.
|
|
365
|
-
- **P4 — `AcousticVolume` (medium).** Component + adapter; `VolumeField` wired so air-absorption follows
|
|
366
|
-
the listener's blended volume.
|
|
367
|
-
*Exit:* blend weights + boundary interpolation correct; air absorption follows the listener's volume;
|
|
368
|
-
no pop crossing a boundary.
|
|
369
|
-
- **P5 — Perf hardening + occluder TLAS.** Amortization/throttle knobs; scratch-pool audit (zero
|
|
370
|
-
per-frame alloc); a body-level BVH (TLAS) so `closestHit` is O(log bodies); `bench/` calibrating
|
|
371
|
-
ms/tick + rays/tick at budget=64.
|
|
372
|
-
*Exit:* measured ≤ target ms/tick; no GC churn; many-body scenes scale.
|
|
373
|
-
- **P6 — Probe volume + premium tiers (gated).** The automatic probe-volume **bake** (D6: density-knobbed
|
|
374
|
-
probe placement over the playable space, per-probe reflection/reverb IR + inter-probe visibility,
|
|
375
|
-
serialized via the registry, user-triggered) → **reverb** (probe IR into a double-buffered
|
|
376
|
-
`ConvolverNode` on sopra's reverb send bus, crossfaded as the listener crosses probe cells) and
|
|
377
|
-
**pathing** (baked probe-visibility graph — **NOT** navmesh; navmesh connectivity ≠ acoustic
|
|
378
|
-
connectivity: a window/cliff/ramp carries sound with no navmesh edge). Plus **FOA directional reverb
|
|
379
|
-
field** (✓ LANDED 2026-06-20 — per-band baked arrival direction + B-format `FoaProbeReverbRenderer`; see
|
|
380
|
-
the dated note up top) and **source directivity** (✓ LANDED 2026-06-20 — `AcousticDirectivity`
|
|
381
|
-
monopole/dipole on `AudioEmitter`, solved into `directivityGain`; see the dated note up top).
|
|
382
|
-
|
|
383
|
-
---
|
|
384
|
-
|
|
385
|
-
## 8. Runtime cost (the contract)
|
|
386
|
-
|
|
387
|
-
Bounded by the ≤ 64 live voices, **world-size-independent**. Calibration constant `c` = per-ray ebvh
|
|
388
|
-
closest-hit (≈1 µs occlusion in JS — measure with `bench/`). Occlusion+transmission =
|
|
389
|
-
`liveVoices × rayCount × c`: 8 rays/voice ≈ 0.5 ms, 16 ≈ 1.0 ms; temporal amortization (rayCount spread
|
|
390
|
-
over F frames) + throttle (15–20 Hz) cut it 3–4×. Medium (air absorption) + volume blend are closed-form
|
|
391
|
-
(< 0.05 ms). Realistic v1 (occlusion + transmission + medium, reverb still sopra's existing) ≈
|
|
392
|
-
**0.3–1.0 ms/tick** main-thread, dominated by occlusion ray count. Render adds ~5 native nodes per
|
|
393
|
-
acoustic voice on the **separate** audio thread. The lever is `liveVoices × rayCount`; the only spike
|
|
394
|
-
(traced reflections, P6) is precomputed into the probe volume and never on the per-frame path.
|
|
395
|
-
|
|
396
|
-
---
|
|
397
|
-
|
|
398
|
-
## 9. Integration & blast radius
|
|
399
|
-
|
|
400
|
-
| Touch | Change | Risk |
|
|
401
|
-
|---|---|---|
|
|
402
|
-
| `AudioEmitterSystem` | optional injected `acousticSim`; one `apply()` call between refresh & tick; read `listenerTransform.rotation` | low |
|
|
403
|
-
| `LiveEmitterSet` | +1 accessor to enumerate live instances (bounded) | low |
|
|
404
|
-
| `EventInstance` (sopra) | `setAcoustic` + no-op-default node insert in `#buildOutputChain` | **med** (hot chain — unity default, re-run `spatialization.spec`) |
|
|
405
|
-
| `AudioEmitter` | `acoustic` opt-in flag (+ later `directivity`) | low |
|
|
406
|
-
| `ReverbEffect`/`BusGraph` (sopra) | double-buffered convolver for probe reverb (**P6 only**) | med (reverb path, deferred) |
|
|
407
|
-
| **New** | all of `sound/simulation/**` | n/a (self-contained) |
|
|
408
|
-
|
|
409
|
-
**Untouched:** `SopraEngine` public API, the clip graph / containers / parameters / `VoiceManager` /
|
|
410
|
-
voice-stealing / bus tree / snapshots / ducking, the `SpatialAudioIndex`/`LiveEmitterSet` cull+budget
|
|
411
|
-
logic, the legacy `SoundEmitter` path, save-format back-compat. The simulation **consumes** the live set;
|
|
412
|
-
it never alters culling, polyphony, or the mixer graph. `EventDescription` carries no medium.
|
|
413
|
-
|
|
414
|
-
**Gate:** lands on the `AudioEmitter`/`AudioEmitterSystem` path, not yet in `makeMirEngineConfig`. Nothing
|
|
415
|
-
here is observable in-game until the sopra strangler cut-over completes.
|
|
416
|
-
|
|
417
|
-
---
|
|
418
|
-
|
|
419
|
-
## ECS wiring notes (probe field + regions)
|
|
420
|
-
|
|
421
|
-
**`AcousticProbeFieldSystem` — single field (v1).** The baked `AcousticProbeField` is an ECS component
|
|
422
|
-
(`typeName` + `toJSON`/`fromJSON` + `AcousticProbeFieldSerializationAdapter`); the system links it and wires
|
|
423
|
-
it into the simulator (`setProbeField`) for pathing + probe reverb. **Only one field is supported for now:**
|
|
424
|
-
the FIRST linked field is wired, any others are silently ignored (no error). TODO — **multiple probe fields**:
|
|
425
|
-
e.g. per-region / streamed fields with the active field selected by listener position, or merged into one
|
|
426
|
-
graph. Needs a field registry + a selection rule on the simulator (today `setProbeField` holds exactly one).
|
|
427
|
-
Until then a scene has exactly one probe field.
|
|
428
|
-
|
|
429
|
-
**Region index refit.** `AcousticRegionIndex` is BVH-backed (O(log n) blend queries); regions track
|
|
430
|
-
`Transform.position` by reference, so the simulator re-fits ALL region leaves once per frame in `apply()`.
|
|
431
|
-
TODO — refit only the regions that actually moved (needs move tracking on `AcousticVolumeSystem`, like the
|
|
432
|
-
occluder system's `onChanged` subscription); fine while region counts are small.
|
|
1
|
+
# Acoustic Simulation — Implementation Plan
|
|
2
|
+
|
|
3
|
+
> A geometry-driven acoustic **simulation** layer for meep that feeds the **sopra** sound engine.
|
|
4
|
+
> Steam-Audio-equivalent in *role* (occlusion, transmission, medium, later reflections / reverb /
|
|
5
|
+
> pathing), built ECS-first and almost entirely in JS for **real-time, in-browser** use. The simulation
|
|
6
|
+
> computes scalars / IRs against meep geometry; **sopra renders them through WebAudio**. The two never
|
|
7
|
+
> blur: this folder produces data, sopra turns data into sound.
|
|
8
|
+
>
|
|
9
|
+
> Status: **P0–P6 BUILT + GREEN, all render paths wired** (full `engine/sound` suite 360 pass / 0
|
|
10
|
+
> regressions). The simulation engine + the occlusion/transmission/medium RENDER seam + the **probe-baked
|
|
11
|
+
> reverb RENDER** + the **corner-leakage (pathing) RENDER** are complete and wired into sopra + the ECS
|
|
12
|
+
> (`AudioEmitterSystem`). Reverb render uses **option B** — a new acoustic-owned `ProbeReverbRenderer`
|
|
13
|
+
> (its own double-buffered ConvolverNode crossfade, IR from the nearest probe's baked decay), leaving
|
|
14
|
+
> sopra's static `ReverbEffect` untouched. Pathing render is an **engine-wide `AcousticSimulator.pathing`
|
|
15
|
+
> toggle** (off by default, zero cost when off): one single-source Dijkstra from the listener per frame
|
|
16
|
+
> (`AcousticPathGraph.computeExitField`) gives every probe its exit point; each occluded source routes a
|
|
17
|
+
> second exit-spatialized send (`EventInstance` path branch). No per-source flag — threaded from the
|
|
18
|
+
> engine config like `acoustic`. **ECS WIRING HELPER LANDED (2026-06-20):** `configureAcousticSimulation`
|
|
19
|
+
> (`simulation/configureAcousticSimulation.js`) — one call from a config builds/reuses the shared
|
|
20
|
+
> `AcousticSimulator`, adds `AcousticSimulationSystem` + `AcousticVolumeSystem` (via `addManySystems`),
|
|
21
|
+
> and injects the simulator (+ optional `ProbeReverbRenderer`) into the `AudioEmitterSystem`. So the only
|
|
22
|
+
> meep-internal integration is done; **Remaining:** the EXTERNAL config call (`makeMirEngineConfig`, in moh
|
|
23
|
+
> — out of meep scope) + save/load serialization registration, both gated on the sopra strangler
|
|
24
|
+
> migration. Serialization adapters are deliberately NOT built yet — they mirror `AudioEmitter`, which has
|
|
25
|
+
> none either (the new sound stack defers binary save integration); the acoustic components carry JSON
|
|
26
|
+
> `toJSON`/`fromJSON` + `typeName` for when the migration lands. To wire reverb: connect a sopra bus send →
|
|
27
|
+
> `ProbeReverbRenderer.input`, pass `probeReverb` to `configureAcousticSimulation` (or set
|
|
28
|
+
> `system.probeReverb`) + `renderer.setProbeField(bakedField)`. To wire pathing: `sim.pathing = true` +
|
|
29
|
+
> `sim.setPathGraph(bakeVisibility(probeField, sim.occluderIndex))`.
|
|
30
|
+
>
|
|
31
|
+
> **What landed per phase:**
|
|
32
|
+
> - **P0** — `AcousticMaterial`, `RayHit`, `AcousticOccluderIndex` (per-body local ebvh BLAS, O(1) `setTransform`).
|
|
33
|
+
> - **P1** — `OcclusionSolver` (volumetric fibonacci rays + seeded jitter + EMA), `VolumeField`, `AcousticMedium`/`AcousticSolution`/`AcousticSourceState`.
|
|
34
|
+
> - **P2** — `AcousticBody` + `AcousticSimulationSystem` (reactive); `AcousticSimulator`; occluder shapes raycast directly via `AbstractShape3D.raycast` (no triangulation).
|
|
35
|
+
> - **P3** — `EventInstance.setAcoustic` + node insert (occlusion gain + lowpass + transmission); `AudioEmitter.acoustic`; `AudioEmitterSystem` apply + `LiveEmitterSet` acoustic threading. **First audible occlusion — wired.**
|
|
36
|
+
> - **P4** — `AcousticVolume` + `AcousticVolumeSystem` (medium, blended, live-tracked).
|
|
37
|
+
> - **P5** — world-AABB broadphase (measurement-driven via `bench/occlusion.bench.spec.js`); temporal amortization proven.
|
|
38
|
+
> - **P6** — `AcousticProbe` + `bakeReverb` + `ProbeField` + `bakeProbeField` (geometry-derived reverb, density knob, serialized); `AcousticPathGraph` + `bakeVisibility` + `findAcousticPath` (probe-visibility routing around obstacles).
|
|
39
|
+
>
|
|
40
|
+
> **Post-P6 cleanup + accel pass (2026-06-20, all committed, `engine/sound` 373 pass):** the occluder
|
|
41
|
+
> index now **raycasts shapes directly** via `AbstractShape3D.raycast` (no triangulation;
|
|
42
|
+
> `acoustic_geometry_from_shape` deleted) and sits behind a **TLAS** — a dynamic BVH over the bodies'
|
|
43
|
+
> world AABBs (P5's deferred TLAS, landed early). `RayHit` carries the world hit **point + normal** (no
|
|
44
|
+
> `hit` flag, no `triangleIndex`). Per-source state is **pooled** in a `BinaryElementPool`
|
|
45
|
+
> (`Map<EventInstance, id>`, flyweight cursor) instead of a `Map<…, AcousticSourceState>`. The probe
|
|
46
|
+
> substrate moved to **`RowFirstTable` + a probe BVH** (nearest via `bvh_query_user_data_nearest_to_point`)
|
|
47
|
+
> and **`CSRGraph`** connectivity. `sourceRadius` moved onto `AudioEmitter`/`EventInstance`;
|
|
48
|
+
> `pathMaxDistance` was removed (path falloff now derives from the source's authored attenuation curve);
|
|
49
|
+
> `AcousticSolution.exit` is a vector. Below, §3.1 / §4 / D5 / P5 describe the v1 triangle-BLAS +
|
|
50
|
+
> linear-scan design that this pass superseded — read them as history. The remaining headline work is the
|
|
51
|
+
> ray-traced reflection IR (see `REFLECTION_IR_PLAN.md`).
|
|
52
|
+
>
|
|
53
|
+
> **FOA directional reverb LANDED (2026-06-20):** the first of P6's two premium tiers — the **FOA
|
|
54
|
+
> (first-order ambisonic / B-format) directional reverb field**. The bake now captures, per band, the
|
|
55
|
+
> energy-weighted **arrival direction** (a 0..1 anisotropy vector) by reciprocity — a ray's reverberant
|
|
56
|
+
> energy arrives from its launch direction (`acoustic_trace_energy` accumulates it, `bakeReverbBands`
|
|
57
|
+
> normalises it). `ProbeField` widened stride 6→15 to store the three per-band direction vectors (JSON
|
|
58
|
+
> round-trips them). Render: a new `render/FoaProbeReverbRenderer` convolves the mono send into a B-format
|
|
59
|
+
> set (`foaReverbImpulseResponse` — `W` omni + `X/Y/Z` steered by the baked direction, one-factor W-energy
|
|
60
|
+
> normalised) and decodes to stereo by **rotating the decoder, not the soundfield** (two virtual cardioids
|
|
61
|
+
> whose look dirs are rotated into world space by the listener orientation — six decode gains/frame, the IR
|
|
62
|
+
> re-baked only on probe-cell change). `AudioEmitterSystem` now threads the listener rotation to
|
|
63
|
+
> `probeReverb.update()` (the scalar `ProbeReverbRenderer` ignores it). Stereo decode is isolated so a
|
|
64
|
+
> binaural/HRTF (SOFA) decoder can replace it later.
|
|
65
|
+
>
|
|
66
|
+
> **Source directivity LANDED (2026-06-20):** the second of P6's premium tiers. `AcousticDirectivity`
|
|
67
|
+
> (`simulation/definition/`) is the Steam-Audio dipole model — `gain = |(1−w) + w·cosθ|^p`
|
|
68
|
+
> (`w` = `dipoleWeight` 0=omni/0.5=cardioid/1=dipole, `p` = `dipolePower`), `cosθ` = source forward · the
|
|
69
|
+
> source→listener direction. Authored on `AudioEmitter.directivity` (default omni → zero cost; `isOmni`
|
|
70
|
+
> short-circuits). The simulator's `apply` computes it per non-omni source (forward = `Vector3.forward`
|
|
71
|
+
> rotated by the source's orientation) into `AcousticSolution.directivityGain`, which `EventInstance.setAcoustic`
|
|
72
|
+
> multiplies into the direct-path gain. Orientation (shared `Transform.rotation` ref) + the directivity ref
|
|
73
|
+
> plumb through `playEvent`/`LiveEmitterSet` exactly like `sourceRadius`/`position`. **P6 premium tiers now
|
|
74
|
+
> both done;** the only remaining acoustic work is the external `makeMirEngineConfig` activation + save/load
|
|
75
|
+
> serialization (gated on the sopra strangler migration) and the deferred optional refinements (NEE early
|
|
76
|
+
> reflections, pathing live-recheck, door variants, binaural/SOFA decode).
|
|
77
|
+
>
|
|
78
|
+
> **DISTANCE AIR ABSORPTION LANDED (2026-06-20):** "low frequencies travel further." `AcousticMedium.airAbsorption`
|
|
79
|
+
> is now **dB/metre**; `VolumeField.integrateAbsorption` line-integrates it over the source→listener path
|
|
80
|
+
> (`∫ α ds`; no-region case is closed-form `ambient·distance`, else 8-midpoint march reusing `sample`) into the
|
|
81
|
+
> new `AcousticSolution.airLoss[3]` (per-band total dB). The point-sampled `AcousticSolution.medium` was
|
|
82
|
+
> REMOVED (superseding §6's `airAbsLP.frequency ← solution.medium.airAbsorption` — air is now path-integrated,
|
|
83
|
+
> not point-sampled). Render (`EventInstance.setAcoustic`) anchors the tilt at the LOW band — only
|
|
84
|
+
> `airLoss[high] − airLoss[low]` darkens the cutoff (`OPEN·2^(−tilt/6dB-oct)`, floored), so a uniform loss (the
|
|
85
|
+
> distance **attenuation curve's** job, a windowed/irradiance falloff — *not* physical) causes no darkening:
|
|
86
|
+
> the curve owns loudness, air owns the spectral tilt, and the two compose via separate series nodes. Default
|
|
87
|
+
> ambient = a small low-anchored atmosphere (`DEFAULT_AIR_ABSORPTION [0, 0.03, 0.1] dB/m`, tunable). Applied to
|
|
88
|
+
> the DIRECT path only (the leak send's longer path is a deferred refinement, like directivity-on-leak).
|
|
89
|
+
>
|
|
90
|
+
> **CORNER-LEAK REFINEMENTS + DYNAMIC RECHECK + SERIALIZATION LANDED (2026-06-21):** the three corner-leak
|
|
91
|
+
> gaps are closed, plus the acoustic binary adapters. (1) **Leak now carries directivity + air.**
|
|
92
|
+
> `AcousticSimulator.#applyPath` walks the leaked polyline ONCE (source→…→listener via
|
|
93
|
+
> `ProbeFieldPathingSolution.next`) and does three things: integrates air per leg
|
|
94
|
+
> (`VolumeField.integrateAbsorption`) into the new `AcousticSolution.pathAirLoss[3]`; folds **directivity toward
|
|
95
|
+
> the FIRST hop** (the corner the source radiates into, not the blocked listener — `#directivityGainToward`)
|
|
96
|
+
> into `pathGain`; and marks each traversed edge for the recheck. `EventInstance`'s leak branch renders through
|
|
97
|
+
> its own 3-band crossover (`#leak3Band`), gained per band by `(1 − transmission[b])` × the `pathAirLoss`
|
|
98
|
+
> low-anchored tilt (so a longer routed leak darkens more, and a band-selective wall leaks only its blocked
|
|
99
|
+
> bands around the corner — consistent with the direct path's 3-band render).
|
|
100
|
+
> (2) **Budgeted dynamic-geometry recheck** (`AcousticSimulator.pathingRecheck` + `recheckBudget`, off by
|
|
101
|
+
> default): `ProbeVisibilityRecheck` re-verifies (within budget, FIFO round-robin) the edges leaks traverse
|
|
102
|
+
> against live geometry (`probe_edge_visible`, extracted + shared with `bakeVisibility`); a now-blocked edge →
|
|
103
|
+
> `EDGE_WEIGHT_BLOCKED` (Float32 max — finite, no topology change, blows the path distance past audibility),
|
|
104
|
+
> restored to the inter-probe distance when it re-opens. No structural mutation; the baked graph self-heals.
|
|
105
|
+
> (3) **Binary serialization** adapters for `AcousticMaterial`/`AcousticMedium`/`AcousticDirectivity` (value
|
|
106
|
+
> types) + `AcousticBody`/`AcousticVolume` (components, delegating; shape omitted like `toJSON`), with
|
|
107
|
+
> `populateAcousticSerializationRegistry`. (`AudioEmitter`'s own adapter — needing the full sopra
|
|
108
|
+
> `EventDescription` clip-graph chain — is still deferred.) Plus a **two-rooms-and-a-corridor integration
|
|
109
|
+
> test** (`two_rooms_corridor.spec.js`) verifying bake (per-band reverb), reachability, leak direction
|
|
110
|
+
> (emerges from the corridor, not through the wall), routed-vs-straight attenuation, and a sealed-divider
|
|
111
|
+
> disconnection control. **Remaining deferred** (optional/premium): NEE early reflections, binaural/SOFA
|
|
112
|
+
> decode, opt-in door variants + re-bake-on-streaming, region-aware air over the leak polyline, the full
|
|
113
|
+
> external `makeMirEngineConfig` activation (gated on the sopra strangler migration).
|
|
114
|
+
|
|
115
|
+
---
|
|
116
|
+
|
|
117
|
+
## 0. The one rule: simulation vs. render
|
|
118
|
+
|
|
119
|
+
```
|
|
120
|
+
SIMULATION (this folder — engine geometry, JS, no WebAudio) RENDER (sopra — WebAudio)
|
|
121
|
+
─────────────────────────────────────────────────────────── ─────────────────────────
|
|
122
|
+
AcousticBody (occluder shapes + material) ─┐
|
|
123
|
+
AcousticVolume (medium) ├─► AcousticSolution ─► EventInstance.setAcoustic()
|
|
124
|
+
ebvh rays + Ray3 + sphere_fibonacci_point ───┘ (a class) (gain + biquad insert)
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
`simulation/core` and `simulation/ecs` import **no WebAudio**. The *only* WebAudio touch is the seam
|
|
128
|
+
where `AudioEmitterSystem` hands an `AcousticSolution` to `EventInstance.setAcoustic(...)` (that method
|
|
129
|
+
lives in sopra, where the node chain already lives). Consequence: the whole simulation is unit-testable
|
|
130
|
+
on real geometry with **zero `MockAudioContext`** — only the one render seam needs it.
|
|
131
|
+
|
|
132
|
+
We do **not** put medium on `EventDescription`. An event is a recipe for *a source*; the medium (air,
|
|
133
|
+
room) is a property of *the world*. Medium lives on `AcousticVolume` components; a source merely **opts
|
|
134
|
+
in** to simulation via one flag (`AudioEmitter.acoustic`). No god-object `AcousticScene` — the occluder
|
|
135
|
+
set is just the entities that have an `AcousticBody`, indexed by a system-owned acceleration structure.
|
|
136
|
+
This is an ECS engine at the top level; the data model is components.
|
|
137
|
+
|
|
138
|
+
---
|
|
139
|
+
|
|
140
|
+
## 1. Layout
|
|
141
|
+
|
|
142
|
+
```
|
|
143
|
+
sound/simulation/
|
|
144
|
+
IMPLEMENTATION_PLAN.md
|
|
145
|
+
definition/ authored, immutable, serializable (sopra/definition style)
|
|
146
|
+
AcousticMaterial.js value class: absorption[3], scattering, transmission[3]
|
|
147
|
+
AcousticMaterialSerializationAdapter.js
|
|
148
|
+
core/ ECS-agnostic AND WebAudio-agnostic — the testable heart
|
|
149
|
+
RayHit.js result class: t / material / bodyHandle / world position + normal
|
|
150
|
+
AcousticOccluderIndex.js OccluderBody shapes + world transform behind a TLAS BVH; closestHit / anyHit
|
|
151
|
+
AcousticMedium.js value class: airAbsorption (per-band)
|
|
152
|
+
AcousticSolution.js result class the render seam consumes: occlusion, transmission[3], medium
|
|
153
|
+
AcousticSourceState.js transient per-source accumulation (rolling occlusion, smoothing)
|
|
154
|
+
OcclusionSolver.js solve(listener, source, index, rayCount, state, out) — explicit args, out-param
|
|
155
|
+
VolumeField.js sample(volumes, x, y, z, out) — out-param, no allocation
|
|
156
|
+
sampleDirections.js sphere_fibonacci_point set + per-tick seededRandom rotation
|
|
157
|
+
ecs/ thin ECS binding (real-component tested)
|
|
158
|
+
AcousticBody.js component: AcousticMaterial + "is occluder"; pairs with Collider + Transform
|
|
159
|
+
AcousticBodySerializationAdapter.js
|
|
160
|
+
AcousticVolume.js component: AbstractShape3D + AcousticMedium + transition band
|
|
161
|
+
AcousticVolumeSerializationAdapter.js
|
|
162
|
+
AcousticSimulationSystem.js System: maintain index + volume set (reactive); apply(liveInstances, listener)
|
|
163
|
+
probe/ P6 — the baked substrate for reverb + pathing (see D6)
|
|
164
|
+
bench/
|
|
165
|
+
occlusion.bench.spec.js rays/tick + ms/tick calibration (raycast.bench methodology)
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
The render-side additions (`EventInstance.setAcoustic`, the node insert, `AudioEmitter.acoustic`) live in
|
|
169
|
+
**sopra**, not here — see §6.
|
|
170
|
+
|
|
171
|
+
---
|
|
172
|
+
|
|
173
|
+
## 2. Reused meep primitives (verified to exist)
|
|
174
|
+
|
|
175
|
+
| Primitive | Path | Used for |
|
|
176
|
+
|---|---|---|
|
|
177
|
+
| `ebvh_geometry_query_nearest_triangle_ray` | `core/bvh2/bvh3/` | closest-hit ray → `[triangleIndex,u,v,t]` |
|
|
178
|
+
| `ebvh_build_for_geometry_morton` | `core/bvh2/bvh3/` | build a body's BLAS from its triangle soup |
|
|
179
|
+
| `BVH` | `core/bvh2/bvh3/BVH.js` | the per-body tree (`new BVH()`, `release_all`, `allocate_linear`, `root`) |
|
|
180
|
+
| `Ray3` (`Float32Array(7)`: o,d,tMax) | `core/geom/3d/ray/Ray3.js` | the ray type; slots into the ebvh query as-is; `applyMatrix4` for local transform |
|
|
181
|
+
| `m4_invert` / `m4_inverse_rotation_translation` | `core/geom/3d/mat4/` | per-body world→local inverse |
|
|
182
|
+
| `sphere_fibonacci_point` | `core/geom/3d/sphere/` | even source-sphere / hemisphere sampling |
|
|
183
|
+
| `v3_orthonormal_matrix_from_normal` + `v3_matrix3_rotate` | `core/geom/vec3/` | hemisphere sampling around a normal (P6) |
|
|
184
|
+
| `seededRandom` (Mulberry32) | `core/math/random/` | per-tick ray jitter; **never `Math.random`** |
|
|
185
|
+
| `AbstractShape3D.signed_distance_at_point` / `contains_point` | `core/geom/3d/shape/` | `AcousticVolume` boundary blend |
|
|
186
|
+
| `AnimationCurve` | `engine/animation/curve/` | distance→cutoff curves (reuse, don't invent) |
|
|
187
|
+
| `BinarySerializationRegistry` + adapter pattern | `ecs/storage/binary/` | serialize materials/bodies/volumes |
|
|
188
|
+
| SH toolkit (`sh3_rotate_bl`, `sh3_sample_by_direction`, `sh3_add`) | `core/geom/3d/sphere/harmonics/` | ambisonic field (P6) |
|
|
189
|
+
| `AssetManager` + `OfflineAudioContext` | `engine/asset/` / browser | baked probe data + offline IR (P6) |
|
|
190
|
+
|
|
191
|
+
---
|
|
192
|
+
|
|
193
|
+
## 3. Encapsulation (the clean core)
|
|
194
|
+
|
|
195
|
+
**Two non-negotiables, applied everywhere below:**
|
|
196
|
+
- **No opaque config bags.** Tunables (`rayCount`, …) are passed as explicit arguments. Configuration
|
|
197
|
+
objects rot — a function that needs a ray count takes a ray count.
|
|
198
|
+
- **No magic structs / `@typedef`.** Every result/value shape is a real **class** (`RayHit`,
|
|
199
|
+
`AcousticSolution`, `AcousticMedium`, `AcousticSourceState`, `AcousticMaterial`). Hot-path queries are
|
|
200
|
+
**allocation-free**: the caller allocates the result and passes it in; the function writes into it.
|
|
201
|
+
|
|
202
|
+
### 3.1 `AcousticOccluderIndex.js` — the (internal) acceleration structure, fully dynamic
|
|
203
|
+
Not a public "scene". Owns a list of **bodies**, each a *local-space* triangle BLAS (`BVH` built once via
|
|
204
|
+
`ebvh_build_for_geometry_morton`) plus a world transform (and its cached inverse) and one
|
|
205
|
+
`AcousticMaterial`. API:
|
|
206
|
+
|
|
207
|
+
```js
|
|
208
|
+
addBody(positions, indices, material, matrix?) → handle // BLAS built once from local triangles
|
|
209
|
+
setTransform(handle, matrix) // O(1): store matrix + recompute inverse
|
|
210
|
+
removeBody(handle)
|
|
211
|
+
closestHit(ray /* Ray3 */, out /* RayHit */) → boolean // nearest hit across all bodies, into `out`
|
|
212
|
+
anyHit(ray /* Ray3 */) → boolean // early-out
|
|
213
|
+
```
|
|
214
|
+
|
|
215
|
+
`closestHit` transforms the world ray into each body's local frame (a module-static `Ray3` scratch +
|
|
216
|
+
`applyMatrix4(inverse)`), runs the ebvh query against that body's BLAS bounded by the running best-`t`,
|
|
217
|
+
and keeps the nearest; `out` receives `{ t, material, bodyHandle, triangleIndex }`. **Fully dynamic**:
|
|
218
|
+
a moving body is just `setTransform` (O(1), no rebuild) — the ECS layer drives it from
|
|
219
|
+
`Transform.position.onChanged`. Material is **per body** (a wall has one material); per-triangle
|
|
220
|
+
materials are a later refinement, not a v1 need. *Precondition: rigid transforms (no scale), so local
|
|
221
|
+
`t` equals world `t`* (documented, not guarded — see house rules). A body-level BVH (TLAS) over the bodies
|
|
222
|
+
is the **P5** scaling step; v1 linear-scans the (few) bodies, BLAS does the real work.
|
|
223
|
+
|
|
224
|
+
### 3.2 `OcclusionSolver.js` — the per-source solve (pure, explicit args, out-param)
|
|
225
|
+
```js
|
|
226
|
+
solve(listenerPose, sourceX, sourceY, sourceZ, sourceRadius, index, rayCount, state, out) → void
|
|
227
|
+
```
|
|
228
|
+
Shoots `rayCount` rays from the listener toward a `sphere_fibonacci_point` set over the source's sphere
|
|
229
|
+
(`sourceRadius`), rotated per tick by a `seededRandom` orientation (so accumulation covers the sphere).
|
|
230
|
+
Each ray is bounded (`tMax` = listener→sample distance) so far subtrees prune. Blocked-ray fraction →
|
|
231
|
+
instantaneous occlusion; blocked rays' materials accumulate the transmission 3-band. Folded into `state`
|
|
232
|
+
(`AcousticSourceState`, a rolling window) and smoothed; written into `out` (`AcousticSolution`).
|
|
233
|
+
**Pure function of geometry + state**, deterministic for a seed; no ECS, no WebAudio, no allocation.
|
|
234
|
+
|
|
235
|
+
### 3.3 `VolumeField.js` — medium zones (pure, out-param)
|
|
236
|
+
```js
|
|
237
|
+
sample(volumes, x, y, z, out /* AcousticMedium */) → void
|
|
238
|
+
```
|
|
239
|
+
Each `AcousticVolume` has an `AbstractShape3D` and a `transition` band. Weight =
|
|
240
|
+
`smooth(-signed_distance / transition)` clamped to `[0,1]` (1 deep inside, 0 outside, smooth across the
|
|
241
|
+
boundary). Normalize weights over overlapping volumes; blend the medium into `out`. A few
|
|
242
|
+
`signed_distance_at_point` evals per query — cheap. Queried at the listener every tick; at sources
|
|
243
|
+
optionally. **Pure**, allocation-free.
|
|
244
|
+
|
|
245
|
+
### 3.4 result + state classes
|
|
246
|
+
`RayHit`, `AcousticSolution`, `AcousticMedium`, `AcousticSourceState`, `AcousticMaterial` are all real
|
|
247
|
+
classes with named fields and a `reset()`/`clear()` where they are reused. The system owns a
|
|
248
|
+
`Map<EventInstance, AcousticSourceState>`, dropped on `instance.onEnded` — so `EventInstance` stays
|
|
249
|
+
ignorant of solver internals.
|
|
250
|
+
|
|
251
|
+
---
|
|
252
|
+
|
|
253
|
+
## 4. The component model (ECS)
|
|
254
|
+
|
|
255
|
+
### `AcousticBody` (occluder) — pairs with `Collider` + `Transform`
|
|
256
|
+
Serializable component carrying an `AcousticMaterial` and the "this entity occludes audio" semantic. The
|
|
257
|
+
**shape** comes from the entity's existing `Collider`/mesh; `AcousticBody` contributes the acoustic
|
|
258
|
+
*properties*. The system triangulates the body's collider shape once into the occluder index (local
|
|
259
|
+
space) and drives its transform reactively. Tagging a wall = adding the component; nothing
|
|
260
|
+
acoustically-inert occludes unless tagged — that closes the "physics BVH contains everything" problem the
|
|
261
|
+
ECS way.
|
|
262
|
+
|
|
263
|
+
### `AcousticVolume` (medium) — pairs with `Transform`
|
|
264
|
+
Serializable component: an `AbstractShape3D` (its region), a `transition` distance (boundary blend band),
|
|
265
|
+
and an `AcousticMedium` (air-absorption coefficients). Volumes overlap and blend (§3.3). **Medium only —
|
|
266
|
+
no reverb here.** (Authored "reverb zones" are the wrong primitive; real reverb is the geometry-traced /
|
|
267
|
+
baked output of the probe volume in P6. Until then, sopra's existing reverb stands unchanged.)
|
|
268
|
+
|
|
269
|
+
### `AcousticSimulationSystem` — the binding
|
|
270
|
+
`extends System`, `dependencies` covering `AcousticBody`/`AcousticVolume`:
|
|
271
|
+
- `link/unlink AcousticBody` → `index.addBody/removeBody` + subscribe `transform.position.onChanged`
|
|
272
|
+
(and rotation) → `index.setTransform`. **Reactive, no per-tick refit loop** (mirrors
|
|
273
|
+
`SpatialAudioIndex`).
|
|
274
|
+
- `link/unlink AcousticVolume` → add/remove from the volume list.
|
|
275
|
+
- `apply(liveInstances, listenerPose)` — **called by `AudioEmitterSystem`** between `liveSet.refresh`
|
|
276
|
+
and `sopra.update`. Samples the listener medium once, then for each **live 3D** instance opted into
|
|
277
|
+
acoustics: `OcclusionSolver.solve(...)` (+ optional per-source `VolumeField.sample`) into a pooled
|
|
278
|
+
`AcousticSolution` → `instance.setAcoustic(solution)`. Bounded to ≤ budget (consumes the live set,
|
|
279
|
+
never iterates all registered emitters).
|
|
280
|
+
|
|
281
|
+
`AudioEmitterSystem` takes an **optional injected** `acousticSim` collaborator (default none → behaviour
|
|
282
|
+
identical to today). Feature is off-by-default and testable in isolation.
|
|
283
|
+
|
|
284
|
+
---
|
|
285
|
+
|
|
286
|
+
## 5. Key decisions
|
|
287
|
+
|
|
288
|
+
- **D1 — Event carries no medium; one opt-in flag.** `AudioEmitter.acoustic` (default `false`) plumbs to
|
|
289
|
+
the instance; `EventInstance` builds the acoustic nodes only when set; `setAcoustic` is a no-op
|
|
290
|
+
otherwise. `EventDescription` stays medium-free. (Owner-directed.)
|
|
291
|
+
- **D2 — No `AcousticScene`; geometry is `AcousticBody` components, indexed internally.**
|
|
292
|
+
- **D3 — `AcousticVolume` is medium-only.** No authored reverb zones. Reverb is the P6 traced/baked
|
|
293
|
+
output; sopra's existing reverb stands until then.
|
|
294
|
+
- **D4 — `simulation/` imports no WebAudio.** It emits `AcousticSolution`s; sopra renders. The whole
|
|
295
|
+
simulation is testable without `MockAudioContext`.
|
|
296
|
+
- **D5 — Occluders are fully dynamic.** No static merge. Per-body local BLAS + an O(1) `setTransform`;
|
|
297
|
+
the ECS layer refits reactively via `Transform.onChanged` (meep is reactive end-to-end — there is no
|
|
298
|
+
static/dynamic flag and no per-tick iteration). A body-level TLAS is the P5 scaling step, not a
|
|
299
|
+
correctness requirement.
|
|
300
|
+
- **D6 — Using the sim requires a built probe volume; the bake is automatic.** When acoustics is enabled
|
|
301
|
+
for a scene, a **probe volume** must be built (it is the substrate for reverb + pathing). The bake is
|
|
302
|
+
**fully automatic** save for a few knobs (chiefly **maximum probe density**): it places probes across
|
|
303
|
+
the playable space, computes their data (reflection/reverb IR + inter-probe visibility for pathing),
|
|
304
|
+
and **serializes** the result. Triggering the bake is the user's responsibility (an explicit call /
|
|
305
|
+
editor action — it is not free), but the user authors no probes by hand. Runtime then just loads and
|
|
306
|
+
selects/blends baked probe data. (This is why pathing/reverb are P6: they consume the probe volume.)
|
|
307
|
+
- **D7 — No opaque config bags; explicit args.** Tunables are parameters, not config objects.
|
|
308
|
+
- **D8 — No magic structs; classes + caller-allocated out-params.** Hot-path queries allocate nothing.
|
|
309
|
+
- **D9 — Cosmetic-only, so no determinism gate.** Rays use `seededRandom` (reproducible tests, clean
|
|
310
|
+
jitter), but there is no lockstep/networking requirement. If acoustics ever become gameplay-affecting
|
|
311
|
+
(AI hearing), that is a different project with a different bar.
|
|
312
|
+
- **D10 — Bounded, amortized, allocation-free.** Work is capped to the ≤ budget (64) live voices;
|
|
313
|
+
`rayCount` is amortized across frames into `AcousticSourceState`; apply is throttleable; results +
|
|
314
|
+
scratch are pooled. JS constant factors are accepted; the budget is the contract.
|
|
315
|
+
|
|
316
|
+
---
|
|
317
|
+
|
|
318
|
+
## 6. Render seam (in sopra — the only WebAudio change)
|
|
319
|
+
|
|
320
|
+
`EventInstance.#buildOutputChain` (today `voices → instanceGain → attenuationGain → panner → bus`) gains,
|
|
321
|
+
**only when the instance is acoustic**, an insert + a parallel transmission branch:
|
|
322
|
+
|
|
323
|
+
```
|
|
324
|
+
voices → instanceGain → attenuationGain → airAbsLP → occlusionGain → occlusionLP → panner → bus
|
|
325
|
+
└→ transmission 3-band (parallel GainNodes) ─┘
|
|
326
|
+
```
|
|
327
|
+
|
|
328
|
+
`EventInstance.setAcoustic(solution)` ramps those `AudioParam`s (smoothing — no zipper):
|
|
329
|
+
`occlusionGain ← 1-occlusion`, `occlusionLP.frequency ← f(occlusion)`, the three transmission band gains
|
|
330
|
+
← `(1-occlusion) + occlusion·transmission[band]` (**parallel crossover, not series shelves** — band gains
|
|
331
|
+
are independent and linear), `airAbsLP.frequency ← solution.medium.airAbsorption`. All nodes default to
|
|
332
|
+
unity / open → an acoustics-off or 2D event is byte-identical to today. (Reverb is untouched here; it is
|
|
333
|
+
the P6 probe-driven concern.)
|
|
334
|
+
|
|
335
|
+
---
|
|
336
|
+
|
|
337
|
+
## 7. Phased plan
|
|
338
|
+
|
|
339
|
+
Each phase ships behind black-box `*.spec.js` run from `H:/git/moh` root
|
|
340
|
+
(`npx jest --config jest.conf.json engine/sound/simulation`). Real objects per house rules; the WebAudio
|
|
341
|
+
boundary (only P3+) uses `MockAudioContext`.
|
|
342
|
+
|
|
343
|
+
- **P0 — Core occluder substrate (no ECS, no WebAudio). ← building now.** `AcousticMaterial` class +
|
|
344
|
+
adapter; `RayHit` class; `AcousticOccluderIndex` (per-body local BLAS via `ebvh_build_for_geometry_morton`,
|
|
345
|
+
`Ray3`-based `closestHit`/`anyHit` into a caller `RayHit`, O(1) `setTransform`).
|
|
346
|
+
*Exit:* a hand-built box room answers closest-hit + per-body material correctly; a ray through an
|
|
347
|
+
opening misses; moving a body via `setTransform` changes the result; `anyHit` early-outs; material
|
|
348
|
+
round-trips. Zero ECS/WebAudio.
|
|
349
|
+
- **P1 — `OcclusionSolver` + `VolumeField` + state (still no ECS/WebAudio).** Volumetric sampling
|
|
350
|
+
(`sphere_fibonacci_point` + `seededRandom` rotation), temporal accumulation in `AcousticSourceState`,
|
|
351
|
+
smoothing; `VolumeField` blend with `AcousticMedium`.
|
|
352
|
+
*Exit:* occlusion monotonic vs. wall coverage; fully walled → 1 with the wall's material in
|
|
353
|
+
transmission; open → 0; frame-stable; deterministic for a seed; volume blend + boundary interpolation
|
|
354
|
+
correct. Pure functions on geometry, allocation-free.
|
|
355
|
+
- **P2 — ECS binding for occlusion.** `AcousticBody` + adapter; `AcousticSimulationSystem`
|
|
356
|
+
(reactive link/unlink + `setTransform`; `apply` loops live 3D instances → solver; owns the per-instance
|
|
357
|
+
state map).
|
|
358
|
+
*Exit:* real `EntityManager` + real `AcousticBody`/`Transform`/`Collider`; add/remove/move a body
|
|
359
|
+
changes the solution; cost bounded to ≤ budget. No WebAudio (assert on returned solutions).
|
|
360
|
+
- **P3 — Render seam (first audible occlusion + transmission).** `EventInstance.setAcoustic` + the
|
|
361
|
+
no-op-default node insert; `AudioEmitter.acoustic` flag; `AudioEmitterSystem` calls `acousticSim.apply`
|
|
362
|
+
between `refresh` and `sopra.update`.
|
|
363
|
+
*Exit (MockAudioContext):* occlusion moves the gain + lowpass; transmission bands respond to material;
|
|
364
|
+
acoustics-off events identical to today; off-by-default.
|
|
365
|
+
- **P4 — `AcousticVolume` (medium).** Component + adapter; `VolumeField` wired so air-absorption follows
|
|
366
|
+
the listener's blended volume.
|
|
367
|
+
*Exit:* blend weights + boundary interpolation correct; air absorption follows the listener's volume;
|
|
368
|
+
no pop crossing a boundary.
|
|
369
|
+
- **P5 — Perf hardening + occluder TLAS.** Amortization/throttle knobs; scratch-pool audit (zero
|
|
370
|
+
per-frame alloc); a body-level BVH (TLAS) so `closestHit` is O(log bodies); `bench/` calibrating
|
|
371
|
+
ms/tick + rays/tick at budget=64.
|
|
372
|
+
*Exit:* measured ≤ target ms/tick; no GC churn; many-body scenes scale.
|
|
373
|
+
- **P6 — Probe volume + premium tiers (gated).** The automatic probe-volume **bake** (D6: density-knobbed
|
|
374
|
+
probe placement over the playable space, per-probe reflection/reverb IR + inter-probe visibility,
|
|
375
|
+
serialized via the registry, user-triggered) → **reverb** (probe IR into a double-buffered
|
|
376
|
+
`ConvolverNode` on sopra's reverb send bus, crossfaded as the listener crosses probe cells) and
|
|
377
|
+
**pathing** (baked probe-visibility graph — **NOT** navmesh; navmesh connectivity ≠ acoustic
|
|
378
|
+
connectivity: a window/cliff/ramp carries sound with no navmesh edge). Plus **FOA directional reverb
|
|
379
|
+
field** (✓ LANDED 2026-06-20 — per-band baked arrival direction + B-format `FoaProbeReverbRenderer`; see
|
|
380
|
+
the dated note up top) and **source directivity** (✓ LANDED 2026-06-20 — `AcousticDirectivity`
|
|
381
|
+
monopole/dipole on `AudioEmitter`, solved into `directivityGain`; see the dated note up top).
|
|
382
|
+
|
|
383
|
+
---
|
|
384
|
+
|
|
385
|
+
## 8. Runtime cost (the contract)
|
|
386
|
+
|
|
387
|
+
Bounded by the ≤ 64 live voices, **world-size-independent**. Calibration constant `c` = per-ray ebvh
|
|
388
|
+
closest-hit (≈1 µs occlusion in JS — measure with `bench/`). Occlusion+transmission =
|
|
389
|
+
`liveVoices × rayCount × c`: 8 rays/voice ≈ 0.5 ms, 16 ≈ 1.0 ms; temporal amortization (rayCount spread
|
|
390
|
+
over F frames) + throttle (15–20 Hz) cut it 3–4×. Medium (air absorption) + volume blend are closed-form
|
|
391
|
+
(< 0.05 ms). Realistic v1 (occlusion + transmission + medium, reverb still sopra's existing) ≈
|
|
392
|
+
**0.3–1.0 ms/tick** main-thread, dominated by occlusion ray count. Render adds ~5 native nodes per
|
|
393
|
+
acoustic voice on the **separate** audio thread. The lever is `liveVoices × rayCount`; the only spike
|
|
394
|
+
(traced reflections, P6) is precomputed into the probe volume and never on the per-frame path.
|
|
395
|
+
|
|
396
|
+
---
|
|
397
|
+
|
|
398
|
+
## 9. Integration & blast radius
|
|
399
|
+
|
|
400
|
+
| Touch | Change | Risk |
|
|
401
|
+
|---|---|---|
|
|
402
|
+
| `AudioEmitterSystem` | optional injected `acousticSim`; one `apply()` call between refresh & tick; read `listenerTransform.rotation` | low |
|
|
403
|
+
| `LiveEmitterSet` | +1 accessor to enumerate live instances (bounded) | low |
|
|
404
|
+
| `EventInstance` (sopra) | `setAcoustic` + no-op-default node insert in `#buildOutputChain` | **med** (hot chain — unity default, re-run `spatialization.spec`) |
|
|
405
|
+
| `AudioEmitter` | `acoustic` opt-in flag (+ later `directivity`) | low |
|
|
406
|
+
| `ReverbEffect`/`BusGraph` (sopra) | double-buffered convolver for probe reverb (**P6 only**) | med (reverb path, deferred) |
|
|
407
|
+
| **New** | all of `sound/simulation/**` | n/a (self-contained) |
|
|
408
|
+
|
|
409
|
+
**Untouched:** `SopraEngine` public API, the clip graph / containers / parameters / `VoiceManager` /
|
|
410
|
+
voice-stealing / bus tree / snapshots / ducking, the `SpatialAudioIndex`/`LiveEmitterSet` cull+budget
|
|
411
|
+
logic, the legacy `SoundEmitter` path, save-format back-compat. The simulation **consumes** the live set;
|
|
412
|
+
it never alters culling, polyphony, or the mixer graph. `EventDescription` carries no medium.
|
|
413
|
+
|
|
414
|
+
**Gate:** lands on the `AudioEmitter`/`AudioEmitterSystem` path, not yet in `makeMirEngineConfig`. Nothing
|
|
415
|
+
here is observable in-game until the sopra strangler cut-over completes.
|
|
416
|
+
|
|
417
|
+
---
|
|
418
|
+
|
|
419
|
+
## ECS wiring notes (probe field + regions)
|
|
420
|
+
|
|
421
|
+
**`AcousticProbeFieldSystem` — single field (v1).** The baked `AcousticProbeField` is an ECS component
|
|
422
|
+
(`typeName` + `toJSON`/`fromJSON` + `AcousticProbeFieldSerializationAdapter`); the system links it and wires
|
|
423
|
+
it into the simulator (`setProbeField`) for pathing + probe reverb. **Only one field is supported for now:**
|
|
424
|
+
the FIRST linked field is wired, any others are silently ignored (no error). TODO — **multiple probe fields**:
|
|
425
|
+
e.g. per-region / streamed fields with the active field selected by listener position, or merged into one
|
|
426
|
+
graph. Needs a field registry + a selection rule on the simulator (today `setProbeField` holds exactly one).
|
|
427
|
+
Until then a scene has exactly one probe field.
|
|
428
|
+
|
|
429
|
+
**Region index refit.** `AcousticRegionIndex` is BVH-backed (O(log n) blend queries); regions track
|
|
430
|
+
`Transform.position` by reference, so the simulator re-fits ALL region leaves once per frame in `apply()`.
|
|
431
|
+
TODO — refit only the regions that actually moved (needs move tracking on `AcousticVolumeSystem`, like the
|
|
432
|
+
occluder system's `onChanged` subscription); fine while region counts are small.
|