@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,1253 +1,1253 @@
|
|
|
1
|
-
import { assert } from "../../../../core/assert.js";
|
|
2
|
-
import { HashMap } from "../../../../core/collection/map/HashMap.js";
|
|
3
|
-
import { HashSet } from "../../../../core/collection/set/HashSet.js";
|
|
4
|
-
import { Color } from "../../../../core/color/Color.js";
|
|
5
|
-
import { Quaternion } from "../../../../core/geom/Quaternion.js";
|
|
6
|
-
import Vector3 from "../../../../core/geom/Vector3.js";
|
|
7
|
-
import { clamp } from "../../../../core/math/clamp.js";
|
|
8
|
-
import { clamp01 } from "../../../../core/math/clamp01.js";
|
|
9
|
-
import { computeObjectHash } from "../../../../core/math/hash/computeObjectHash.js";
|
|
10
|
-
import { inverseLerp } from "../../../../core/math/inverseLerp.js";
|
|
11
|
-
import { objectDeepEquals } from "../../../../core/model/object/objectDeepEquals.js";
|
|
12
|
-
import { number_format_by_thousands } from "../../../../core/primitives/numbers/number_format_by_thousands.js";
|
|
13
|
-
import { AnimationInterpolationKind } from "../../../../engine/animation/clip/AnimationInterpolationKind.js";
|
|
14
|
-
import { curve_from_track_data } from "../../../../engine/animation/clip/curve_from_track_data.js";
|
|
15
|
-
import { AnimationCurve } from "../../../../engine/animation/curve/AnimationCurve.js";
|
|
16
|
-
import { t64_look_rotation } from "../../../../engine/ecs/transform/t64_look_rotation.js";
|
|
17
|
-
import { t64_transform_direction } from "../../../../engine/ecs/transform/t64_transform_direction.js";
|
|
18
|
-
import { meshopt_optimizeVertexCache } from "../../../../engine/graphics/geometry/optimization/VertexCacheOptimizer.js";
|
|
19
|
-
import { ShadeAnimationChannel } from "../../animation/ShadeAnimationChannel.js";
|
|
20
|
-
import { ShadeAnimationClip } from "../../animation/ShadeAnimationClip.js";
|
|
21
|
-
import { Skin } from "../../animation/Skin.js";
|
|
22
|
-
import { Attribute } from "../../geometry/Attribute.js";
|
|
23
|
-
import { Geometry, GeometryFlags } from "../../geometry/Geometry.js";
|
|
24
|
-
import { meshlet_geometry_build_from_geometry } from "../../geometry/meshlet_geometry_build_from_geometry.js";
|
|
25
|
-
import { StandardAttributes } from "../../geometry/StandardAttributes.js";
|
|
26
|
-
import { normalize_attribute } from "../../geometry/util/normalize_attribute.js";
|
|
27
|
-
import { DirectionalLight } from "../../light/model/DirectionalLight.js";
|
|
28
|
-
import { PointLight } from "../../light/model/PointLight.js";
|
|
29
|
-
import { SpotLight } from "../../light/model/SpotLight.js";
|
|
30
|
-
|
|
31
|
-
import { StandardShadeMaterial } from "../../material/StandardShadeMaterial.js";
|
|
32
|
-
import { Node3DProperty } from "../../object_property/Node3DProperty.js";
|
|
33
|
-
import { Mesh } from "../../scene/Mesh.js";
|
|
34
|
-
import { Node3D } from "../../scene/Node3D.js";
|
|
35
|
-
import { SkinnedMesh } from "../../scene/SkinnedMesh.js";
|
|
36
|
-
import { ShadeTexture } from "../../texture/ShadeTexture.js";
|
|
37
|
-
import { ShadeImage } from "../../texture/source/ShadeImage.js";
|
|
38
|
-
import { TextureFilterType } from "../../texture/TextureFilterType.js";
|
|
39
|
-
import { TextureWrapType } from "../../texture/TextureWrapType.js";
|
|
40
|
-
import { SceneBundle } from "../SceneBundle.js";
|
|
41
|
-
import { coalesce_array_duplicates } from "./coalesce_array_duplicates.js";
|
|
42
|
-
import { fix_up_material_sides } from "./fix_up_material_sides.js";
|
|
43
|
-
import { GLTF_COMPONENT_TYPE } from "./gltf_component_type.js";
|
|
44
|
-
import { gltf_create_material } from "./gltf_create_material.js";
|
|
45
|
-
import { GLTF_PRIMITIVE_MODE, GLTF_PRIMITIVE_MODE_DEFAULT } from "./GLTF_PRIMITIVE_MODE.js";
|
|
46
|
-
import { gltf_read_accessor } from "./gltf_read_accessor.js";
|
|
47
|
-
import { gltf_used_image_indices } from "./gltf_used_image_indices.js";
|
|
48
|
-
import { TinyGltf } from "./tiny-gltf.js";
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
/**
|
|
52
|
-
* Somewhere to hand `canonicalize_quaternion_signs` a rest rotation it can read by component name —
|
|
53
|
-
* a `Transform64` addresses its rotation by index, and the function's contract is named components.
|
|
54
|
-
*
|
|
55
|
-
* @type {Quaternion}
|
|
56
|
-
*/
|
|
57
|
-
const SCRATCH_REST_ROTATION = new Quaternion();
|
|
58
|
-
|
|
59
|
-
/**
|
|
60
|
-
* Somewhere to read a light's facing before flipping it.
|
|
61
|
-
*
|
|
62
|
-
* @type {Vector3}
|
|
63
|
-
*/
|
|
64
|
-
const SCRATCH_DIRECTION = new Vector3();
|
|
65
|
-
const OPTIMIZE_GEOMETRIES = false;
|
|
66
|
-
|
|
67
|
-
const WEBGL_FILTER_NEAREST = 9728;
|
|
68
|
-
const WEBGL_FILTER_LINEAR = 9729;
|
|
69
|
-
const WEBGL_FILTER_NEAREST_MIPMAP_NEAREST = 9984;
|
|
70
|
-
const WEBGL_FILTER_LINEAR_MIPMAP_NEAREST = 9985;
|
|
71
|
-
const WEBGL_FILTER_NEAREST_MIPMAP_LINEAR = 9986;
|
|
72
|
-
const WEBGL_FILTER_LINEAR_MIPMAP_LINEAR = 9987;
|
|
73
|
-
|
|
74
|
-
const WEBGL_FILTERS = {
|
|
75
|
-
[WEBGL_FILTER_NEAREST]: TextureFilterType.Nearest,
|
|
76
|
-
[WEBGL_FILTER_LINEAR]: TextureFilterType.Linear,
|
|
77
|
-
[WEBGL_FILTER_NEAREST_MIPMAP_NEAREST]: TextureFilterType.Nearest,
|
|
78
|
-
[WEBGL_FILTER_LINEAR_MIPMAP_NEAREST]: TextureFilterType.Nearest,
|
|
79
|
-
[WEBGL_FILTER_NEAREST_MIPMAP_LINEAR]: TextureFilterType.Linear,
|
|
80
|
-
[WEBGL_FILTER_LINEAR_MIPMAP_LINEAR]: TextureFilterType.Linear
|
|
81
|
-
};
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
/**
|
|
85
|
-
*
|
|
86
|
-
* @param {number} filter
|
|
87
|
-
* @returns {boolean}
|
|
88
|
-
*/
|
|
89
|
-
function webgl_filter_mipmap_linear(filter) {
|
|
90
|
-
switch (filter) {
|
|
91
|
-
case WEBGL_FILTER_LINEAR_MIPMAP_NEAREST:
|
|
92
|
-
case WEBGL_FILTER_LINEAR_MIPMAP_LINEAR:
|
|
93
|
-
return true;
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
return false;
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
/**
|
|
100
|
-
*
|
|
101
|
-
* @param {number} minFilter
|
|
102
|
-
* @returns {TextureFilterType}
|
|
103
|
-
*/
|
|
104
|
-
function webgl_filter_mipmap(minFilter) {
|
|
105
|
-
if (minFilter === undefined || webgl_filter_mipmap_linear(minFilter)) {
|
|
106
|
-
return TextureFilterType.Linear;
|
|
107
|
-
}
|
|
108
|
-
|
|
109
|
-
return TextureFilterType.Nearest;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
const WEBGL_WRAPPINGS = {
|
|
113
|
-
33071: TextureWrapType.ClampToEdge,
|
|
114
|
-
33648: TextureWrapType.MirroredRepeat,
|
|
115
|
-
10497: TextureWrapType.Repeat
|
|
116
|
-
};
|
|
117
|
-
|
|
118
|
-
/**
|
|
119
|
-
* @see https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html
|
|
120
|
-
* @param {string} id
|
|
121
|
-
*/
|
|
122
|
-
function gltf_attribute_id_to_standard(id) {
|
|
123
|
-
switch (id) {
|
|
124
|
-
case "POSITION":
|
|
125
|
-
return StandardAttributes.Position;
|
|
126
|
-
case "NORMAL":
|
|
127
|
-
return StandardAttributes.Normal;
|
|
128
|
-
case "TEXCOORD_0":
|
|
129
|
-
return StandardAttributes.TextureCoordinates0;
|
|
130
|
-
case "TEXCOORD_1":
|
|
131
|
-
return StandardAttributes.TextureCoordinates1;
|
|
132
|
-
case "TANGENT":
|
|
133
|
-
return StandardAttributes.Tangent;
|
|
134
|
-
case "COLOR_0":
|
|
135
|
-
return StandardAttributes.Color;
|
|
136
|
-
case "JOINTS_0":
|
|
137
|
-
return StandardAttributes.SkinningJoints;
|
|
138
|
-
case "WEIGHTS_0":
|
|
139
|
-
return StandardAttributes.SkinningWeights;
|
|
140
|
-
default:
|
|
141
|
-
return id;
|
|
142
|
-
}
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
/**
|
|
146
|
-
* Map glTF `animation.channels[].target.path` to {@link Node3DProperty}.
|
|
147
|
-
* Returns `-1` for paths we don't yet drive (morph-target `weights`),
|
|
148
|
-
* so the caller can skip those channels without throwing.
|
|
149
|
-
*
|
|
150
|
-
* @param {string} path
|
|
151
|
-
* @returns {number}
|
|
152
|
-
*/
|
|
153
|
-
function gltf_animation_path_to_property(path) {
|
|
154
|
-
switch (path) {
|
|
155
|
-
case "translation":
|
|
156
|
-
return Node3DProperty.Translation;
|
|
157
|
-
case "rotation":
|
|
158
|
-
return Node3DProperty.Rotation;
|
|
159
|
-
case "scale":
|
|
160
|
-
return Node3DProperty.Scale;
|
|
161
|
-
default:
|
|
162
|
-
// "weights" (morph targets) lands here; we don't yet have
|
|
163
|
-
// morph-target support in the renderer.
|
|
164
|
-
return -1;
|
|
165
|
-
}
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
/**
|
|
169
|
-
* Number of scalar components per keyframe value for a given Node3D
|
|
170
|
-
* property — translation/scale = 3 (vec3), rotation = 4 (quaternion
|
|
171
|
-
* x/y/z/w).
|
|
172
|
-
*
|
|
173
|
-
* @param {number} property one of {@link Node3DProperty}
|
|
174
|
-
* @returns {number}
|
|
175
|
-
*/
|
|
176
|
-
function node3d_property_component_count(property) {
|
|
177
|
-
switch (property) {
|
|
178
|
-
case Node3DProperty.Translation:
|
|
179
|
-
case Node3DProperty.Scale:
|
|
180
|
-
return 3;
|
|
181
|
-
case Node3DProperty.Rotation:
|
|
182
|
-
return 4;
|
|
183
|
-
default:
|
|
184
|
-
throw new Error(`Unsupported animated property ${property}`);
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
|
|
188
|
-
/**
|
|
189
|
-
* Walk a flat keyframe-values buffer for a rotation channel and flip
|
|
190
|
-
* the sign of any keyframe whose val-quaternion has negative dot
|
|
191
|
-
* product with the previous keyframe's val-quaternion. The same flip
|
|
192
|
-
* is applied to that keyframe's in/out tangents in CUBICSPLINE mode
|
|
193
|
-
* so the cubic remains internally consistent.
|
|
194
|
-
*
|
|
195
|
-
* The flip preserves the rotation (q and -q encode the same
|
|
196
|
-
* orientation) while ensuring per-component interpolation between
|
|
197
|
-
* consecutive keyframes follows the short arc instead of passing
|
|
198
|
-
* through a near-zero quaternion mid-segment.
|
|
199
|
-
*
|
|
200
|
-
* The curve's leading sign is anchored against `rest_rotation` —
|
|
201
|
-
* the target node's authored local rest rotation: when the first
|
|
202
|
-
* keyframe's val-quat has negative dot product with the rest
|
|
203
|
-
* quaternion, the whole first keyframe block is negated (and the
|
|
204
|
-
* consecutive-keyframe pass propagates that sign down the curve).
|
|
205
|
-
* Every rotation curve targeting one node aligns against the same
|
|
206
|
-
* reference, so weighted multi-clip blends accumulate
|
|
207
|
-
* hemisphere-consistent contributions instead of cancelling toward
|
|
208
|
-
* a near-zero quaternion. Residual limitation: the anchor is the
|
|
209
|
-
* FIRST keyframe only — a curve that swings more than 90° away
|
|
210
|
-
* from the rest rotation mid-clip can still contribute opposite
|
|
211
|
-
* signs to another clip at those times; fixing that would need
|
|
212
|
-
* apply-time alignment, which the atomic pose accumulator cannot
|
|
213
|
-
* do order-independently.
|
|
214
|
-
*
|
|
215
|
-
* Mutates `values` in place. Safe to call on an output array that's
|
|
216
|
-
* a fresh copy of the source accessor (which is what
|
|
217
|
-
* {@link read_accessor_as_float32_array} produces).
|
|
218
|
-
*
|
|
219
|
-
* Exported for spec coverage; not part of the loader's public API.
|
|
220
|
-
*
|
|
221
|
-
* @param {Float32Array} values flat values: STEP/LINEAR uses 4
|
|
222
|
-
* floats/keyframe (x, y, z, w); CUBICSPLINE uses 12 (inX, inY,
|
|
223
|
-
* inZ, inW, valX, valY, valZ, valW, outX, outY, outZ, outW).
|
|
224
|
-
* @param {number} key_count
|
|
225
|
-
* @param {number} interpolation one of {@link AnimationInterpolationKind}
|
|
226
|
-
* @param {{x:number, y:number, z:number, w:number}} [rest_rotation]
|
|
227
|
-
* target node's authored local rest rotation; omitted → the
|
|
228
|
-
* leading sign is kept as authored.
|
|
229
|
-
*/
|
|
230
|
-
export function canonicalize_quaternion_signs(values, key_count, interpolation, rest_rotation) {
|
|
231
|
-
const is_cubic = interpolation === AnimationInterpolationKind.CubicTangents;
|
|
232
|
-
const stride = is_cubic ? 12 : 4;
|
|
233
|
-
// Offset into a keyframe block at which the val-quat sits.
|
|
234
|
-
// CUBICSPLINE has [in, val, out]; the val starts at offset 4 (i.e.
|
|
235
|
-
// after the 4-float in-tangent). STEP/LINEAR has just val at 0.
|
|
236
|
-
const val_offset = is_cubic ? 4 : 0;
|
|
237
|
-
|
|
238
|
-
if (key_count >= 1 && rest_rotation !== undefined) {
|
|
239
|
-
const rest_dot =
|
|
240
|
-
values[val_offset + 0] * rest_rotation.x +
|
|
241
|
-
values[val_offset + 1] * rest_rotation.y +
|
|
242
|
-
values[val_offset + 2] * rest_rotation.z +
|
|
243
|
-
values[val_offset + 3] * rest_rotation.w;
|
|
244
|
-
|
|
245
|
-
if (rest_dot < 0) {
|
|
246
|
-
// Negate the whole first keyframe block (value +
|
|
247
|
-
// tangents); the loop below carries the flip through
|
|
248
|
-
// the remaining keyframes.
|
|
249
|
-
for (let i = 0; i < stride; i++) {
|
|
250
|
-
values[i] = -values[i];
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
for (let k = 1; k < key_count; k++) {
|
|
256
|
-
const prev_base = (k - 1) * stride + val_offset;
|
|
257
|
-
const cur_base = k * stride + val_offset;
|
|
258
|
-
|
|
259
|
-
const dot =
|
|
260
|
-
values[prev_base + 0] * values[cur_base + 0] +
|
|
261
|
-
values[prev_base + 1] * values[cur_base + 1] +
|
|
262
|
-
values[prev_base + 2] * values[cur_base + 2] +
|
|
263
|
-
values[prev_base + 3] * values[cur_base + 3];
|
|
264
|
-
|
|
265
|
-
if (dot < 0) {
|
|
266
|
-
// Flip the whole keyframe block (value + tangents).
|
|
267
|
-
const start = k * stride;
|
|
268
|
-
const end = start + stride;
|
|
269
|
-
for (let i = start; i < end; i++) {
|
|
270
|
-
values[i] = -values[i];
|
|
271
|
-
}
|
|
272
|
-
}
|
|
273
|
-
}
|
|
274
|
-
}
|
|
275
|
-
|
|
276
|
-
/**
|
|
277
|
-
* Map glTF interpolation strings to the engine's enum. Defaults to
|
|
278
|
-
* LINEAR when missing — the glTF spec's default.
|
|
279
|
-
*
|
|
280
|
-
* @param {string|undefined} interpolation
|
|
281
|
-
* @returns {number} one of {@link AnimationInterpolationKind}
|
|
282
|
-
*/
|
|
283
|
-
function gltf_interpolation_to_kind(interpolation) {
|
|
284
|
-
switch (interpolation) {
|
|
285
|
-
case "STEP":
|
|
286
|
-
return AnimationInterpolationKind.Discrete;
|
|
287
|
-
case "CUBICSPLINE":
|
|
288
|
-
return AnimationInterpolationKind.CubicTangents;
|
|
289
|
-
case "LINEAR":
|
|
290
|
-
case undefined:
|
|
291
|
-
return AnimationInterpolationKind.Linear;
|
|
292
|
-
default:
|
|
293
|
-
throw new Error(`Unsupported interpolation '${interpolation}'`);
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
/**
|
|
298
|
-
* Input can be a .glb or .gltf file.
|
|
299
|
-
*
|
|
300
|
-
* Does not support most compression GLTF extensions such as draco, basis etc.
|
|
301
|
-
*
|
|
302
|
-
* Returns a {@link SceneBundle} that groups the parsed scene roots
|
|
303
|
-
* with any skins and animation clips extracted from the same asset.
|
|
304
|
-
* Callers add `bundle.scenes` to their scene, then pass the bundle's
|
|
305
|
-
* `skins` / `clips` to the scene's animation manager (e.g. via
|
|
306
|
-
* {@link GPUAnimationManager#register_skin} and
|
|
307
|
-
* {@link GPUAnimationManager#register_clip}) once `scene.build` has
|
|
308
|
-
* populated `id_mapping` for the joint and target nodes.
|
|
309
|
-
*
|
|
310
|
-
* @param {string} url un-resolved — the asset manager resolves network paths
|
|
311
|
-
* @param {Object} options
|
|
312
|
-
* @param {AssetManager} options.assetManager where the container, its buffers and its images come
|
|
313
|
-
* from. Required: a glTF is several files, and which of them are already in memory is not this
|
|
314
|
-
* parser's business to know.
|
|
315
|
-
* @param {AssetRequestScope} [options.scope] the load these requests belong to
|
|
316
|
-
* @param {Map<string, File|Blob|ArrayBuffer>} [options.fileMap] Map of relative paths to file data.
|
|
317
|
-
* When provided, buffer and image URIs in the GLTF are resolved from this map before the asset
|
|
318
|
-
* framework is asked. Enables multi-file GLTF loading from drag-and-drop.
|
|
319
|
-
* @return {Promise<SceneBundle>}
|
|
320
|
-
*/
|
|
321
|
-
export function load_gltf(url, { assetManager, scope, fileMap } = {}) {
|
|
322
|
-
// TODO
|
|
323
|
-
// apply some checks to the model, things like non-uniform scales, that can be fixed potentially
|
|
324
|
-
// see https://www.youtube.com/watch?v=FJRO5wFTEc8 for common ideas
|
|
325
|
-
// check for inverted normals
|
|
326
|
-
// check for duplicated vertices
|
|
327
|
-
// check for overlapping faces
|
|
328
|
-
|
|
329
|
-
async function process(gltf) {
|
|
330
|
-
// console.log(gltf);
|
|
331
|
-
|
|
332
|
-
/**
|
|
333
|
-
* @type {{type:string, componentType:number, count:number, bufferView:number, byteOffset:number, normalized:boolean, min?:number[], max?:number}[]}
|
|
334
|
-
*/
|
|
335
|
-
const accessors = gltf.accessors;
|
|
336
|
-
|
|
337
|
-
/**
|
|
338
|
-
* `aabb` is six numbers, `[x0, y0, z0, x1, y1, z1]`, in world space — and is absent on a node
|
|
339
|
-
* that bounds nothing, meaning neither it nor anything below it declared any.
|
|
340
|
-
*
|
|
341
|
-
* {{aabb?:Float64Array, mesh:number, worldMatrix:Float32Array}[]}
|
|
342
|
-
*/
|
|
343
|
-
const nodes = gltf.nodes;
|
|
344
|
-
|
|
345
|
-
/**
|
|
346
|
-
*
|
|
347
|
-
* @type {{aabb:Float64Array, primitives:({attributes:Object<number>,indices:number, material:number, mode:number}[])}[]}
|
|
348
|
-
*/
|
|
349
|
-
const meshes = gltf.meshes;
|
|
350
|
-
|
|
351
|
-
/**
|
|
352
|
-
*
|
|
353
|
-
* @type {{}[]}
|
|
354
|
-
*/
|
|
355
|
-
const scenes = gltf.scenes;
|
|
356
|
-
|
|
357
|
-
/**
|
|
358
|
-
* Engine Node3Ds indexed by glTF node index — populated lazily
|
|
359
|
-
* by {@link process_node} as the scene-graph recursion visits
|
|
360
|
-
* each node. Used afterwards to resolve skin joint references
|
|
361
|
-
* and animation channel targets (both of which point at glTF
|
|
362
|
-
* node indices, not at any in-memory object).
|
|
363
|
-
*
|
|
364
|
-
* @type {Node3D[]}
|
|
365
|
-
*/
|
|
366
|
-
const node3d_by_index = new Array((gltf.nodes ?? []).length);
|
|
367
|
-
|
|
368
|
-
/**
|
|
369
|
-
* Queue of pending `skin.meshes` pushes. process_node() can't
|
|
370
|
-
* resolve `node.skin → Skin` directly because skins[] is built
|
|
371
|
-
* *after* the recursion completes (the joint lookup needs
|
|
372
|
-
* node3d_by_index fully populated). So we enqueue the produced
|
|
373
|
-
* SkinnedMeshes here and drain into the matching skin once the
|
|
374
|
-
* walk finishes.
|
|
375
|
-
*
|
|
376
|
-
* @type {{ skin_index: number, meshes: Mesh[] }[]}
|
|
377
|
-
*/
|
|
378
|
-
const skin_mesh_pushes = [];
|
|
379
|
-
|
|
380
|
-
/**
|
|
381
|
-
* Primitive converted to JSON string serves as key
|
|
382
|
-
* @type {Map<string, MeshletGeometry>}
|
|
383
|
-
*/
|
|
384
|
-
const geometry_cache = new Map();
|
|
385
|
-
|
|
386
|
-
/**
|
|
387
|
-
*
|
|
388
|
-
* @type {HashSet<MeshletGeometry>}
|
|
389
|
-
*/
|
|
390
|
-
const geometry_cache_secondary = new HashSet();
|
|
391
|
-
|
|
392
|
-
/**
|
|
393
|
-
* Indexed as `gltf.images` is, and populated only where an image was actually fetched.
|
|
394
|
-
*
|
|
395
|
-
* Built from {@link gltf_used_image_indices} rather than by mapping the whole list, because
|
|
396
|
-
* that is the same function the fetch is filtered by: the two cannot drift into decoding one
|
|
397
|
-
* set and sampling another, and there is no slot here for an image that was never brought in.
|
|
398
|
-
*
|
|
399
|
-
* @type {ShadeImage[]}
|
|
400
|
-
*/
|
|
401
|
-
const mapped_images = [];
|
|
402
|
-
|
|
403
|
-
for (const index of gltf_used_image_indices(gltf)) {
|
|
404
|
-
mapped_images[index] = ShadeImage.fromImageBitmap(gltf.images[index]);
|
|
405
|
-
}
|
|
406
|
-
|
|
407
|
-
/**
|
|
408
|
-
* used when no material is specified
|
|
409
|
-
* @type {StandardShadeMaterial}
|
|
410
|
-
*/
|
|
411
|
-
const default_material = new StandardShadeMaterial();
|
|
412
|
-
|
|
413
|
-
/**
|
|
414
|
-
* Used when no sampler is present
|
|
415
|
-
* @type {{}}
|
|
416
|
-
*/
|
|
417
|
-
const default_sampler_description = {};
|
|
418
|
-
|
|
419
|
-
/**
|
|
420
|
-
*
|
|
421
|
-
* @type {ShadeTexture[]}
|
|
422
|
-
*/
|
|
423
|
-
const mapped_textures = (gltf.textures ?? []).map(gltf_texture => {
|
|
424
|
-
|
|
425
|
-
const sampler = gltf_texture.sampler;
|
|
426
|
-
|
|
427
|
-
let source;
|
|
428
|
-
|
|
429
|
-
const extensions = gltf_texture.extensions;
|
|
430
|
-
if (extensions !== undefined) {
|
|
431
|
-
|
|
432
|
-
source = extensions.EXT_texture_webp?.source;
|
|
433
|
-
|
|
434
|
-
}
|
|
435
|
-
|
|
436
|
-
if (source === undefined) {
|
|
437
|
-
source = gltf_texture.source;
|
|
438
|
-
}
|
|
439
|
-
|
|
440
|
-
const image = mapped_images[source];
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
/**
|
|
444
|
-
* @type {{magFilter:number, minFilter:number, wrapS:number, wrapT:number}}
|
|
445
|
-
*/
|
|
446
|
-
let sampler_descriptor;
|
|
447
|
-
|
|
448
|
-
if (gltf.samplers !== undefined && gltf.samplers[sampler] !== undefined) {
|
|
449
|
-
sampler_descriptor = gltf.samplers[sampler]
|
|
450
|
-
} else {
|
|
451
|
-
sampler_descriptor = default_sampler_description;
|
|
452
|
-
}
|
|
453
|
-
|
|
454
|
-
const texture = ShadeTexture.from(image);
|
|
455
|
-
|
|
456
|
-
texture.magFilter = WEBGL_FILTERS[sampler_descriptor.magFilter] ?? TextureFilterType.Linear;
|
|
457
|
-
texture.minFilter = WEBGL_FILTERS[sampler_descriptor.minFilter] ?? TextureFilterType.Linear;
|
|
458
|
-
texture.mipmapFilter = webgl_filter_mipmap(sampler_descriptor.minFilter);
|
|
459
|
-
|
|
460
|
-
texture.wrapS = WEBGL_WRAPPINGS[sampler_descriptor.wrapS] ?? TextureWrapType.Repeat;
|
|
461
|
-
texture.wrapT = WEBGL_WRAPPINGS[sampler_descriptor.wrapT] ?? TextureWrapType.Repeat;
|
|
462
|
-
|
|
463
|
-
return texture;
|
|
464
|
-
});
|
|
465
|
-
|
|
466
|
-
coalesce_array_duplicates(mapped_textures);
|
|
467
|
-
|
|
468
|
-
// account for materials missing
|
|
469
|
-
const gltf_materials = gltf.materials ?? [];
|
|
470
|
-
|
|
471
|
-
const mapped_materials = gltf_materials.map(gltf_mat => gltf_create_material(gltf_mat, mapped_textures));
|
|
472
|
-
|
|
473
|
-
// dedupe materials
|
|
474
|
-
coalesce_array_duplicates(mapped_materials);
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
/**
|
|
478
|
-
* One accessor as an attribute in the shape the renderer stores it.
|
|
479
|
-
*
|
|
480
|
-
* The read itself — stride, sparse overlay, a view-less accessor's zeroes — belongs to the
|
|
481
|
-
* format and is done by {@link gltf_read_accessor}; what is left here is the engine's own
|
|
482
|
-
* question of which storage type an attribute of this name is kept in.
|
|
483
|
-
*
|
|
484
|
-
* @param {number} accessor_index
|
|
485
|
-
* @param {string} name
|
|
486
|
-
* @returns {Attribute}
|
|
487
|
-
*/
|
|
488
|
-
function buffer_to_attribute(accessor_index, name) {
|
|
489
|
-
const data = gltf_read_accessor(gltf, accessor_index);
|
|
490
|
-
|
|
491
|
-
const raw_attribute = Attribute.from(data.values, data.components, name);
|
|
492
|
-
|
|
493
|
-
raw_attribute.spec.normalized = data.normalized;
|
|
494
|
-
|
|
495
|
-
return normalize_attribute(raw_attribute);
|
|
496
|
-
}
|
|
497
|
-
|
|
498
|
-
/**
|
|
499
|
-
*
|
|
500
|
-
* @type {HashMap<Object, Attribute>}
|
|
501
|
-
*/
|
|
502
|
-
const attribute_cache = new HashMap({
|
|
503
|
-
keyEqualityFunction: objectDeepEquals,
|
|
504
|
-
keyHashFunction: computeObjectHash
|
|
505
|
-
});
|
|
506
|
-
|
|
507
|
-
/**
|
|
508
|
-
*
|
|
509
|
-
* @param {number} attribute_accessor
|
|
510
|
-
* @param {string} name
|
|
511
|
-
* @returns {Attribute}
|
|
512
|
-
*/
|
|
513
|
-
function obtain_attribute(attribute_accessor, name) {
|
|
514
|
-
const key = {
|
|
515
|
-
attribute_accessor, name
|
|
516
|
-
};
|
|
517
|
-
|
|
518
|
-
let attribute = attribute_cache.get(key);
|
|
519
|
-
|
|
520
|
-
if (attribute === undefined) {
|
|
521
|
-
attribute = buffer_to_attribute(attribute_accessor, name);
|
|
522
|
-
attribute_cache.set(key, attribute);
|
|
523
|
-
} else {
|
|
524
|
-
// console.warn('attribute reuse')
|
|
525
|
-
}
|
|
526
|
-
|
|
527
|
-
return attribute;
|
|
528
|
-
}
|
|
529
|
-
|
|
530
|
-
/**
|
|
531
|
-
* A FLOAT-componentType accessor's values as a flat `Float32Array`. Used for animation
|
|
532
|
-
* sampler inputs/outputs (times, values) and the skin inverse-bind matrices, where
|
|
533
|
-
* downstream code wants a stride-free flat buffer.
|
|
534
|
-
*
|
|
535
|
-
* @param {number} accessor_index
|
|
536
|
-
* @returns {Float32Array}
|
|
537
|
-
*/
|
|
538
|
-
function read_accessor_as_float32_array(accessor_index) {
|
|
539
|
-
const accessor = accessors[accessor_index];
|
|
540
|
-
|
|
541
|
-
assert.equal(
|
|
542
|
-
accessor.componentType, GLTF_COMPONENT_TYPE.FLOAT,
|
|
543
|
-
`accessor[${accessor_index}].componentType must be FLOAT for read_accessor_as_float32_array`
|
|
544
|
-
);
|
|
545
|
-
|
|
546
|
-
return gltf_read_accessor(gltf, accessor_index).values;
|
|
547
|
-
}
|
|
548
|
-
|
|
549
|
-
/**
|
|
550
|
-
*
|
|
551
|
-
* @returns {MeshletGeometry}
|
|
552
|
-
*/
|
|
553
|
-
function primitive_to_geometry(primitive) {
|
|
554
|
-
const geometry = new Geometry();
|
|
555
|
-
|
|
556
|
-
const mode = primitive.mode ?? GLTF_PRIMITIVE_MODE_DEFAULT;
|
|
557
|
-
|
|
558
|
-
if (mode !== GLTF_PRIMITIVE_MODE.TRIANGLES) {
|
|
559
|
-
throw new Error('Unsupported draw method');
|
|
560
|
-
}
|
|
561
|
-
|
|
562
|
-
for (const attribute_key in primitive.attributes) {
|
|
563
|
-
|
|
564
|
-
const name = gltf_attribute_id_to_standard(attribute_key);
|
|
565
|
-
|
|
566
|
-
if (geometry.getAttribute(name) !== undefined) {
|
|
567
|
-
console.warn(`attribute '${name}' already exists, skipping. Primitive.attributes = ${JSON.stringify(primitive.attributes)}`)
|
|
568
|
-
}
|
|
569
|
-
|
|
570
|
-
/**
|
|
571
|
-
* @type {number}
|
|
572
|
-
*/
|
|
573
|
-
const attribute_accessor = primitive.attributes[attribute_key];
|
|
574
|
-
|
|
575
|
-
let attribute;
|
|
576
|
-
try {
|
|
577
|
-
attribute = obtain_attribute(attribute_accessor, name);
|
|
578
|
-
} catch (e) {
|
|
579
|
-
console.warn(`Failed to parse attribute '${name}'. Skipping`, e);
|
|
580
|
-
continue;
|
|
581
|
-
}
|
|
582
|
-
|
|
583
|
-
geometry.addAttribute(attribute);
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
if (attribute_key === "POSITION") {
|
|
587
|
-
// The spec mandates POSITION accessors carry min/max,
|
|
588
|
-
// so we can adopt them as the bounding box without
|
|
589
|
-
// walking the vertex data. The sphere is derived from
|
|
590
|
-
// the box inside meshlet_geometry_build_from_geometry,
|
|
591
|
-
// so we just clear the dirty flag here.
|
|
592
|
-
const accessor = accessors[attribute_accessor];
|
|
593
|
-
|
|
594
|
-
if (accessor.min !== undefined && accessor.max !== undefined) {
|
|
595
|
-
geometry.bounding_box.set([
|
|
596
|
-
...accessor.min,
|
|
597
|
-
...accessor.max
|
|
598
|
-
]);
|
|
599
|
-
|
|
600
|
-
geometry.clearFlag(GeometryFlags.BoundsNeedUpdate);
|
|
601
|
-
}
|
|
602
|
-
}
|
|
603
|
-
}
|
|
604
|
-
|
|
605
|
-
if (primitive.indices !== undefined) {
|
|
606
|
-
|
|
607
|
-
geometry.index = obtain_attribute(primitive.indices, 'index');
|
|
608
|
-
|
|
609
|
-
// geometry_fix_index(geometry.index, geometry.getVertexCount());
|
|
610
|
-
}
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
// vertex optimize
|
|
614
|
-
if (geometry.index !== null && OPTIMIZE_GEOMETRIES) {
|
|
615
|
-
meshopt_optimizeVertexCache(geometry.index.data, geometry.index.data, geometry.index.count, geometry.getVertexCount());
|
|
616
|
-
}
|
|
617
|
-
|
|
618
|
-
return meshlet_geometry_build_from_geometry(geometry);
|
|
619
|
-
}
|
|
620
|
-
|
|
621
|
-
function obtain_geometry_by_primitive(primitive) {
|
|
622
|
-
const key = JSON.stringify(primitive);
|
|
623
|
-
|
|
624
|
-
let geometry = geometry_cache.get(key);
|
|
625
|
-
|
|
626
|
-
if (geometry === undefined) {
|
|
627
|
-
geometry = primitive_to_geometry(primitive)
|
|
628
|
-
|
|
629
|
-
const secondary_cached = geometry_cache_secondary.get(geometry);
|
|
630
|
-
|
|
631
|
-
if (secondary_cached !== undefined) {
|
|
632
|
-
// found an equivalent geometry in the secondary cache, use it instead
|
|
633
|
-
geometry = secondary_cached;
|
|
634
|
-
// console.warn("secondary reuse");
|
|
635
|
-
} else {
|
|
636
|
-
geometry_cache_secondary.add(geometry);
|
|
637
|
-
}
|
|
638
|
-
|
|
639
|
-
geometry_cache.set(key, geometry);
|
|
640
|
-
} else {
|
|
641
|
-
// console.warn('geometry reuse');
|
|
642
|
-
}
|
|
643
|
-
|
|
644
|
-
return geometry;
|
|
645
|
-
}
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
/**
|
|
649
|
-
* Build the renderable mesh(es) for one glTF node.
|
|
650
|
-
*
|
|
651
|
-
* A glTF mesh is a list of primitives sharing a name and an
|
|
652
|
-
* `aabb`, and each primitive becomes one engine-side {@link Mesh}.
|
|
653
|
-
* When the owning glTF node references a skin, every primitive is
|
|
654
|
-
* instead constructed as a {@link SkinnedMesh} so the renderer
|
|
655
|
-
* routes it through a per-instance geometry clone for deformation.
|
|
656
|
-
*
|
|
657
|
-
* @param {number} mesh_index
|
|
658
|
-
* @param {{}} node
|
|
659
|
-
* @param {boolean} is_skinned
|
|
660
|
-
* @returns {Mesh[]}
|
|
661
|
-
*/
|
|
662
|
-
function process_mesh(mesh_index, node, is_skinned) {
|
|
663
|
-
|
|
664
|
-
const mesh = meshes[mesh_index];
|
|
665
|
-
|
|
666
|
-
const primitives = mesh.primitives;
|
|
667
|
-
|
|
668
|
-
const primitive_count = primitives.length;
|
|
669
|
-
|
|
670
|
-
/**
|
|
671
|
-
*
|
|
672
|
-
* @type {Mesh[]}
|
|
673
|
-
*/
|
|
674
|
-
const result = [];
|
|
675
|
-
|
|
676
|
-
for (let i = 0; i < primitive_count; i++) {
|
|
677
|
-
const primitive = primitives[i];
|
|
678
|
-
|
|
679
|
-
// build geometry
|
|
680
|
-
|
|
681
|
-
/**
|
|
682
|
-
* @type {MeshletGeometry}
|
|
683
|
-
*/
|
|
684
|
-
let geometry;
|
|
685
|
-
|
|
686
|
-
try {
|
|
687
|
-
geometry = obtain_geometry_by_primitive(primitive);
|
|
688
|
-
} catch (e) {
|
|
689
|
-
console.error(`Failed to obtain geometry for primitive [${i}] ${primitive}. `, e);
|
|
690
|
-
console.log('Ignoring mesh');
|
|
691
|
-
continue;
|
|
692
|
-
}
|
|
693
|
-
|
|
694
|
-
if (primitive_count === 1 && mesh.name !== undefined) {
|
|
695
|
-
geometry.name = mesh.name;
|
|
696
|
-
}
|
|
697
|
-
|
|
698
|
-
const material_id = primitive.material;
|
|
699
|
-
|
|
700
|
-
let material;
|
|
701
|
-
|
|
702
|
-
if (material_id !== undefined) {
|
|
703
|
-
material = mapped_materials[material_id];
|
|
704
|
-
|
|
705
|
-
if (material === undefined) {
|
|
706
|
-
console.warn(`specified material ${material_id} does not exist. Using default.`);
|
|
707
|
-
|
|
708
|
-
material = default_material;
|
|
709
|
-
}
|
|
710
|
-
|
|
711
|
-
} else {
|
|
712
|
-
// no material specified, use default
|
|
713
|
-
material = default_material;
|
|
714
|
-
}
|
|
715
|
-
|
|
716
|
-
const engine_mesh = is_skinned ? new SkinnedMesh() : new Mesh();
|
|
717
|
-
engine_mesh.geometry = geometry;
|
|
718
|
-
engine_mesh.material = material;
|
|
719
|
-
engine_mesh.transform_global.fromMatrix(node.worldMatrix);
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
if (mesh.name !== undefined) {
|
|
723
|
-
engine_mesh.name = mesh.name;
|
|
724
|
-
}
|
|
725
|
-
|
|
726
|
-
result.push(engine_mesh);
|
|
727
|
-
}
|
|
728
|
-
|
|
729
|
-
return result;
|
|
730
|
-
}
|
|
731
|
-
|
|
732
|
-
/**
|
|
733
|
-
*
|
|
734
|
-
* @param {number} light_index
|
|
735
|
-
* @param {{}} node
|
|
736
|
-
* @returns {AbstractLight}
|
|
737
|
-
*/
|
|
738
|
-
function process_light(light_index, node) {
|
|
739
|
-
|
|
740
|
-
// SPEC: https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_lights_punctual/README.md
|
|
741
|
-
|
|
742
|
-
const gltf_light = gltf.extensions.KHR_lights_punctual.lights[light_index];
|
|
743
|
-
|
|
744
|
-
// parse color
|
|
745
|
-
const color = new Color();
|
|
746
|
-
|
|
747
|
-
if (gltf_light.color !== undefined) {
|
|
748
|
-
color.fromArray(gltf_light.color);
|
|
749
|
-
} else {
|
|
750
|
-
color.setRGB(1, 1, 1);
|
|
751
|
-
}
|
|
752
|
-
|
|
753
|
-
const intensity = gltf_light.intensity ?? 1;
|
|
754
|
-
|
|
755
|
-
const name = gltf_light.name ?? "";
|
|
756
|
-
|
|
757
|
-
let light;
|
|
758
|
-
|
|
759
|
-
const type = gltf_light.type;
|
|
760
|
-
|
|
761
|
-
switch (type) {
|
|
762
|
-
case "directional":
|
|
763
|
-
light = new DirectionalLight();
|
|
764
|
-
break;
|
|
765
|
-
case "point":
|
|
766
|
-
light = new PointLight();
|
|
767
|
-
light.distance = gltf_light.range ?? 1e20; // default light radius
|
|
768
|
-
break;
|
|
769
|
-
case "spot":
|
|
770
|
-
light = new SpotLight();
|
|
771
|
-
|
|
772
|
-
const gltf_spot = gltf_light.spot;
|
|
773
|
-
|
|
774
|
-
const outerCone = gltf_spot?.outerConeAngle ?? (Math.PI / 4); // default PI/4
|
|
775
|
-
const innerCone = gltf_spot?.innerConeAngle ?? 0;
|
|
776
|
-
|
|
777
|
-
light.angle = clamp(
|
|
778
|
-
outerCone,
|
|
779
|
-
0,
|
|
780
|
-
Math.PI / 2
|
|
781
|
-
);
|
|
782
|
-
|
|
783
|
-
light.penumbra = clamp01(
|
|
784
|
-
inverseLerp(light.angle, 0, innerCone)
|
|
785
|
-
);
|
|
786
|
-
|
|
787
|
-
light.distance = gltf_light.range ?? 1e20;
|
|
788
|
-
// TODO rotation is messed up?
|
|
789
|
-
break;
|
|
790
|
-
default:
|
|
791
|
-
throw new Error(`Unsupported light type ${type}`);
|
|
792
|
-
}
|
|
793
|
-
|
|
794
|
-
light.color.copy(color);
|
|
795
|
-
light.intensity = intensity;
|
|
796
|
-
light.name = name;
|
|
797
|
-
|
|
798
|
-
// check for light radius
|
|
799
|
-
light.radius = gltf_light.extras?.radius ?? 0;
|
|
800
|
-
|
|
801
|
-
light.near_clip_distance = gltf_light.extras?.near_clip_distance ?? light.radius;
|
|
802
|
-
|
|
803
|
-
light.casts_shadow = true;
|
|
804
|
-
|
|
805
|
-
return light;
|
|
806
|
-
}
|
|
807
|
-
|
|
808
|
-
/**
|
|
809
|
-
*
|
|
810
|
-
* @param {Node3D} parent
|
|
811
|
-
* @param {number} node_index
|
|
812
|
-
*/
|
|
813
|
-
function process_node(parent, node_index) {
|
|
814
|
-
|
|
815
|
-
const node = nodes[node_index];
|
|
816
|
-
|
|
817
|
-
// glTF "skin" attaches at the node, not the mesh: every
|
|
818
|
-
// primitive of the referenced mesh becomes a SkinnedMesh
|
|
819
|
-
// bound to this skin. Resolved later (after the recursion
|
|
820
|
-
// is done) against `skins[]`, which we've already built
|
|
821
|
-
// — the joint Node3Ds may be visited *after* this node,
|
|
822
|
-
// so we just record the produced SkinnedMeshes here and
|
|
823
|
-
// push them into `skin.meshes` once the walk finishes.
|
|
824
|
-
const skin_index = typeof node.skin === "number" ? node.skin : -1;
|
|
825
|
-
|
|
826
|
-
let node3d;
|
|
827
|
-
let produced_skinned_meshes = null;
|
|
828
|
-
|
|
829
|
-
if (node.extensions !== undefined && node.extensions.KHR_lights_punctual !== undefined) {
|
|
830
|
-
const light_index = node.extensions.KHR_lights_punctual.light;
|
|
831
|
-
|
|
832
|
-
try {
|
|
833
|
-
node3d = process_light(light_index, node);
|
|
834
|
-
} catch (e) {
|
|
835
|
-
console.error("Failed to process light ", light_index, " ", e);
|
|
836
|
-
}
|
|
837
|
-
}
|
|
838
|
-
|
|
839
|
-
|
|
840
|
-
if (typeof node.mesh === "number") {
|
|
841
|
-
const meshes = process_mesh(node.mesh, node, skin_index !== -1);
|
|
842
|
-
|
|
843
|
-
if (meshes.length === 1) {
|
|
844
|
-
node3d = meshes[0];
|
|
845
|
-
} else if (meshes.length > 1) {
|
|
846
|
-
node3d = new Node3D();
|
|
847
|
-
|
|
848
|
-
node3d.addChildren(meshes)
|
|
849
|
-
}
|
|
850
|
-
|
|
851
|
-
if (skin_index !== -1) {
|
|
852
|
-
produced_skinned_meshes = meshes;
|
|
853
|
-
}
|
|
854
|
-
}
|
|
855
|
-
|
|
856
|
-
if (node3d === undefined) {
|
|
857
|
-
node3d = new Node3D();
|
|
858
|
-
}
|
|
859
|
-
|
|
860
|
-
// Stash by glTF index — joint refs and animation channel
|
|
861
|
-
// targets resolve through this lookup once the recursion
|
|
862
|
-
// unwinds.
|
|
863
|
-
node3d_by_index[node_index] = node3d;
|
|
864
|
-
|
|
865
|
-
if (node.name !== undefined) {
|
|
866
|
-
node3d.name = node.name;
|
|
867
|
-
}
|
|
868
|
-
|
|
869
|
-
if (node.matrix !== undefined) {
|
|
870
|
-
|
|
871
|
-
node3d.transform_local.fromMatrix(node.matrix);
|
|
872
|
-
|
|
873
|
-
} else {
|
|
874
|
-
|
|
875
|
-
const t = node3d.transform_local;
|
|
876
|
-
|
|
877
|
-
if (node.translation !== undefined) {
|
|
878
|
-
const v = node.translation;
|
|
879
|
-
|
|
880
|
-
t.setTranslation(v[0], v[1], v[2]);
|
|
881
|
-
}
|
|
882
|
-
|
|
883
|
-
if (node.rotation !== undefined) {
|
|
884
|
-
const q = node.rotation;
|
|
885
|
-
|
|
886
|
-
t.setRotation(q[0], q[1], q[2], q[3]);
|
|
887
|
-
}
|
|
888
|
-
|
|
889
|
-
if (node.scale !== undefined) {
|
|
890
|
-
const v = node.scale;
|
|
891
|
-
|
|
892
|
-
t.setScale(v[0], v[1], v[2]);
|
|
893
|
-
}
|
|
894
|
-
}
|
|
895
|
-
|
|
896
|
-
|
|
897
|
-
if (node3d.isDirectionalLight || node3d.isSpotLight) {
|
|
898
|
-
// glTF lights shine along their local -Z; engine convention is forward = shining direction
|
|
899
|
-
const t = node3d.transform_local;
|
|
900
|
-
|
|
901
|
-
// the direction is read off the matrix, and a Transform64 does not maintain its own
|
|
902
|
-
t.updateMatrix();
|
|
903
|
-
|
|
904
|
-
t64_transform_direction(SCRATCH_DIRECTION, t, 0, 0, 1);
|
|
905
|
-
|
|
906
|
-
t64_look_rotation(
|
|
907
|
-
t,
|
|
908
|
-
-SCRATCH_DIRECTION.x, -SCRATCH_DIRECTION.y, -SCRATCH_DIRECTION.z,
|
|
909
|
-
0, 1, 0
|
|
910
|
-
);
|
|
911
|
-
}
|
|
912
|
-
|
|
913
|
-
parent.addChild(node3d);
|
|
914
|
-
|
|
915
|
-
if (produced_skinned_meshes !== null) {
|
|
916
|
-
// Defer the `skin.meshes` push to after `skins[]` is
|
|
917
|
-
// built — we collect into a queue here and process it
|
|
918
|
-
// at the end of process().
|
|
919
|
-
skin_mesh_pushes.push({
|
|
920
|
-
skin_index,
|
|
921
|
-
meshes: produced_skinned_meshes,
|
|
922
|
-
});
|
|
923
|
-
}
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
if (node.children !== undefined) {
|
|
927
|
-
|
|
928
|
-
for (let i = 0; i < node.children.length; i++) {
|
|
929
|
-
const node_index = node.children[i];
|
|
930
|
-
|
|
931
|
-
process_node(node3d, node_index);
|
|
932
|
-
}
|
|
933
|
-
}
|
|
934
|
-
}
|
|
935
|
-
|
|
936
|
-
// console.time('parse-gltf');
|
|
937
|
-
// console.profile('parse-gltf');
|
|
938
|
-
|
|
939
|
-
/**
|
|
940
|
-
*
|
|
941
|
-
* @type {Node3D[]}
|
|
942
|
-
*/
|
|
943
|
-
const scene_nodes3d = [];
|
|
944
|
-
|
|
945
|
-
for (let i = 0; i < scenes.length; i++) {
|
|
946
|
-
const scene = scenes[i];
|
|
947
|
-
|
|
948
|
-
const scene_node3d = new Node3D();
|
|
949
|
-
|
|
950
|
-
scene_nodes3d.push(scene_node3d);
|
|
951
|
-
|
|
952
|
-
/**
|
|
953
|
-
* @type {number[]}
|
|
954
|
-
*/
|
|
955
|
-
const scene_nodes = scene.nodes;
|
|
956
|
-
|
|
957
|
-
const node_count = scene_nodes.length;
|
|
958
|
-
|
|
959
|
-
for (let i = 0; i < node_count; i++) {
|
|
960
|
-
const node_index = scene_nodes[i];
|
|
961
|
-
process_node(scene_node3d, node_index);
|
|
962
|
-
}
|
|
963
|
-
|
|
964
|
-
scene_node3d.updateMatrices();
|
|
965
|
-
}
|
|
966
|
-
|
|
967
|
-
// ── Skins ──────────────────────────────────────────────────
|
|
968
|
-
//
|
|
969
|
-
// Build {@link Skin} objects from `gltf.skins[]`. Joints
|
|
970
|
-
// resolve to Node3D refs through `node3d_by_index` (fully
|
|
971
|
-
// populated by the recursion above). Inverse-bind matrices
|
|
972
|
-
// come from a single MAT4 accessor — `joint_count * 16` f32s
|
|
973
|
-
// laid out column-major, copied into a flat Float32Array that
|
|
974
|
-
// the manager can subarray-view at registration time.
|
|
975
|
-
const skins = (gltf.skins ?? []).map((gltf_skin, skin_index) => {
|
|
976
|
-
const joint_indices = gltf_skin.joints;
|
|
977
|
-
const joint_count = joint_indices.length;
|
|
978
|
-
|
|
979
|
-
const joint_nodes = new Array(joint_count);
|
|
980
|
-
for (let i = 0; i < joint_count; i++) {
|
|
981
|
-
const joint_node_index = joint_indices[i];
|
|
982
|
-
const joint_node = node3d_by_index[joint_node_index];
|
|
983
|
-
|
|
984
|
-
assert.defined(
|
|
985
|
-
joint_node,
|
|
986
|
-
`skin[${skin_index}].joints[${i}] references unknown node index ${joint_node_index}`
|
|
987
|
-
);
|
|
988
|
-
|
|
989
|
-
joint_nodes[i] = joint_node;
|
|
990
|
-
}
|
|
991
|
-
|
|
992
|
-
// Inverse-bind matrices: glTF stores them MAT4-typed
|
|
993
|
-
// (column-major, 16 f32s per joint). When the accessor is
|
|
994
|
-
// omitted, the spec says every joint's IBM is identity —
|
|
995
|
-
// we materialise that here so the manager always sees a
|
|
996
|
-
// ready-to-use flat array.
|
|
997
|
-
let inverse_bind_matrices;
|
|
998
|
-
if (gltf_skin.inverseBindMatrices !== undefined) {
|
|
999
|
-
inverse_bind_matrices = read_accessor_as_float32_array(gltf_skin.inverseBindMatrices);
|
|
1000
|
-
} else {
|
|
1001
|
-
inverse_bind_matrices = new Float32Array(joint_count * 16);
|
|
1002
|
-
for (let i = 0; i < joint_count; i++) {
|
|
1003
|
-
inverse_bind_matrices[i * 16 + 0] = 1;
|
|
1004
|
-
inverse_bind_matrices[i * 16 + 5] = 1;
|
|
1005
|
-
inverse_bind_matrices[i * 16 + 10] = 1;
|
|
1006
|
-
inverse_bind_matrices[i * 16 + 15] = 1;
|
|
1007
|
-
}
|
|
1008
|
-
}
|
|
1009
|
-
|
|
1010
|
-
return Skin.from({
|
|
1011
|
-
name: gltf_skin.name ?? "",
|
|
1012
|
-
joints: joint_nodes,
|
|
1013
|
-
inverse_bind_matrices,
|
|
1014
|
-
meshes: [],
|
|
1015
|
-
});
|
|
1016
|
-
});
|
|
1017
|
-
|
|
1018
|
-
// Drain the deferred skin.meshes pushes captured during the
|
|
1019
|
-
// node walk.
|
|
1020
|
-
for (let i = 0; i < skin_mesh_pushes.length; i++) {
|
|
1021
|
-
const { skin_index, meshes: skin_meshes } = skin_mesh_pushes[i];
|
|
1022
|
-
skins[skin_index].meshes.push(...skin_meshes);
|
|
1023
|
-
}
|
|
1024
|
-
|
|
1025
|
-
// ── Animation clips ───────────────────────────────────────
|
|
1026
|
-
//
|
|
1027
|
-
// One glTF animation → one {@link ShadeAnimationClip}. Each
|
|
1028
|
-
// channel becomes a {@link ShadeAnimationChannel}; per-component
|
|
1029
|
-
// curves are built from the sampler's input (times) / output
|
|
1030
|
-
// (values) accessors via the engine's curve_from_track_data
|
|
1031
|
-
// helpers, which already handle STEP / LINEAR / CUBICSPLINE.
|
|
1032
|
-
const clips = [];
|
|
1033
|
-
const gltf_animations = gltf.animations ?? [];
|
|
1034
|
-
for (let a = 0; a < gltf_animations.length; a++) {
|
|
1035
|
-
const gltf_animation = gltf_animations[a];
|
|
1036
|
-
|
|
1037
|
-
const channels = [];
|
|
1038
|
-
|
|
1039
|
-
for (let c = 0; c < gltf_animation.channels.length; c++) {
|
|
1040
|
-
const gltf_channel = gltf_animation.channels[c];
|
|
1041
|
-
const target = gltf_channel.target;
|
|
1042
|
-
|
|
1043
|
-
const property = gltf_animation_path_to_property(target.path);
|
|
1044
|
-
if (property === -1) {
|
|
1045
|
-
// Morph-target weights or other unsupported paths.
|
|
1046
|
-
continue;
|
|
1047
|
-
}
|
|
1048
|
-
|
|
1049
|
-
if (target.node === undefined) {
|
|
1050
|
-
// Channels without a node target are a glTF
|
|
1051
|
-
// extension hook and not actionable here.
|
|
1052
|
-
continue;
|
|
1053
|
-
}
|
|
1054
|
-
|
|
1055
|
-
const target_node = node3d_by_index[target.node];
|
|
1056
|
-
|
|
1057
|
-
assert.defined(
|
|
1058
|
-
target_node,
|
|
1059
|
-
`animations[${a}].channels[${c}].target.node ${target.node} not resolved`
|
|
1060
|
-
);
|
|
1061
|
-
|
|
1062
|
-
const sampler = gltf_animation.samplers[gltf_channel.sampler];
|
|
1063
|
-
const times = read_accessor_as_float32_array(sampler.input);
|
|
1064
|
-
const values = read_accessor_as_float32_array(sampler.output);
|
|
1065
|
-
const interpolation = gltf_interpolation_to_kind(sampler.interpolation);
|
|
1066
|
-
const component_count = node3d_property_component_count(property);
|
|
1067
|
-
|
|
1068
|
-
// Canonicalize quaternion signs on rotation channels.
|
|
1069
|
-
//
|
|
1070
|
-
// glTF stores rotation keyframes as raw (x, y, z, w)
|
|
1071
|
-
// quaternions, but `q` and `-q` represent the same
|
|
1072
|
-
// orientation. Authoring tools (notably Mixamo) often
|
|
1073
|
-
// alternate signs across consecutive keyframes when a
|
|
1074
|
-
// bone passes through 180°. Per-component interpolation
|
|
1075
|
-
// between sign-mismatched keyframes — especially
|
|
1076
|
-
// CUBICSPLINE — passes through near-zero quaternions
|
|
1077
|
-
// mid-segment; the apply shader's `normalize(value)`
|
|
1078
|
-
// call then produces an effectively-identity quaternion
|
|
1079
|
-
// for one frame, which reads as a one-frame snap to
|
|
1080
|
-
// bind pose.
|
|
1081
|
-
//
|
|
1082
|
-
// Fix: flip the sign of every keyframe whose val-quat
|
|
1083
|
-
// has negative dot product with the prior keyframe's
|
|
1084
|
-
// val-quat. For CUBICSPLINE, flip the in/out tangents
|
|
1085
|
-
// alongside the value so the cubic stays consistent.
|
|
1086
|
-
// The leading sign is anchored against the target
|
|
1087
|
-
// node's authored rest rotation so all clips driving
|
|
1088
|
-
// one node land in the same hemisphere — required
|
|
1089
|
-
// for weighted multi-clip blends, where the pose
|
|
1090
|
-
// accumulator sums raw components across clips.
|
|
1091
|
-
// No-op when the property isn't Rotation, or when the
|
|
1092
|
-
// data was already canonicalized at export time.
|
|
1093
|
-
if (property === Node3DProperty.Rotation && times.length >= 1) {
|
|
1094
|
-
// `canonicalize_quaternion_signs` reads the rest rotation by component name,
|
|
1095
|
-
// which a `Transform64` does not offer — hand it a quaternion instead
|
|
1096
|
-
const rest = target_node.transform_local;
|
|
1097
|
-
|
|
1098
|
-
SCRATCH_REST_ROTATION.set(
|
|
1099
|
-
rest.rotation_x,
|
|
1100
|
-
rest.rotation_y,
|
|
1101
|
-
rest.rotation_z,
|
|
1102
|
-
rest.rotation_w
|
|
1103
|
-
);
|
|
1104
|
-
|
|
1105
|
-
canonicalize_quaternion_signs(
|
|
1106
|
-
values, times.length, interpolation,
|
|
1107
|
-
SCRATCH_REST_ROTATION
|
|
1108
|
-
);
|
|
1109
|
-
}
|
|
1110
|
-
|
|
1111
|
-
// Build the per-axis curves object. component_count
|
|
1112
|
-
// is property-driven (3 for Translation/Scale, 4 for
|
|
1113
|
-
// Rotation); slots beyond what the property uses are
|
|
1114
|
-
// omitted. The keys align with the GPU track's
|
|
1115
|
-
// (x, y, z, w) vec4f output — see ShadeAnimationChannel.
|
|
1116
|
-
const axis_keys = ['x', 'y', 'z', 'w'];
|
|
1117
|
-
const curves = {};
|
|
1118
|
-
for (let comp = 0; comp < component_count; comp++) {
|
|
1119
|
-
const curve = new AnimationCurve();
|
|
1120
|
-
curve_from_track_data(curve, interpolation, values, times, component_count, comp);
|
|
1121
|
-
curves[axis_keys[comp]] = curve;
|
|
1122
|
-
}
|
|
1123
|
-
|
|
1124
|
-
channels.push(ShadeAnimationChannel.from({
|
|
1125
|
-
target: target_node,
|
|
1126
|
-
property,
|
|
1127
|
-
curves,
|
|
1128
|
-
}));
|
|
1129
|
-
}
|
|
1130
|
-
|
|
1131
|
-
if (channels.length === 0) {
|
|
1132
|
-
// All channels were unsupported / unresolved — skip
|
|
1133
|
-
// the clip entirely so we don't emit a zero-channel
|
|
1134
|
-
// record the manager would reject.
|
|
1135
|
-
continue;
|
|
1136
|
-
}
|
|
1137
|
-
|
|
1138
|
-
const clip = ShadeAnimationClip.from({
|
|
1139
|
-
name: gltf_animation.name ?? "",
|
|
1140
|
-
channels,
|
|
1141
|
-
});
|
|
1142
|
-
|
|
1143
|
-
// Default optimization pass: strip channels that
|
|
1144
|
-
// evaluate to the identity transform and individual
|
|
1145
|
-
// per-axis curves that are constant at identity, then
|
|
1146
|
-
// key-reduce the survivors. glTF exporters often emit
|
|
1147
|
-
// redundant bind-pose channels (every joint gets a
|
|
1148
|
-
// translation channel even when only rotation is
|
|
1149
|
-
// animated), so this typically trims a sizeable
|
|
1150
|
-
// fraction of the channel + curve count. Behaviour
|
|
1151
|
-
// unchanged — applying the optimised clip produces
|
|
1152
|
-
// the same poses.
|
|
1153
|
-
//
|
|
1154
|
-
// Stats are computed by diffing channel + total-curve
|
|
1155
|
-
// counts before and after; the methods don't carry
|
|
1156
|
-
// them in their return values.
|
|
1157
|
-
const before_channels = clip.channels.length;
|
|
1158
|
-
let before_curves = 0;
|
|
1159
|
-
for (let i = 0; i < clip.channels.length; i++) {
|
|
1160
|
-
before_curves += clip.channels[i].curve_count;
|
|
1161
|
-
}
|
|
1162
|
-
|
|
1163
|
-
clip.optimize();
|
|
1164
|
-
|
|
1165
|
-
const after_channels = clip.channels.length;
|
|
1166
|
-
let after_curves = 0;
|
|
1167
|
-
for (let i = 0; i < clip.channels.length; i++) {
|
|
1168
|
-
after_curves += clip.channels[i].curve_count;
|
|
1169
|
-
}
|
|
1170
|
-
|
|
1171
|
-
const removed_channels = before_channels - after_channels;
|
|
1172
|
-
const removed_curves = before_curves - after_curves;
|
|
1173
|
-
if (removed_channels > 0 || removed_curves > 0) {
|
|
1174
|
-
// console.log(
|
|
1175
|
-
// `[load_gltf] optimised clip '${clip.name}': ` +
|
|
1176
|
-
// `removed ${removed_channels} track(s), ` +
|
|
1177
|
-
// `${removed_curves} curve(s)`
|
|
1178
|
-
// );
|
|
1179
|
-
}
|
|
1180
|
-
|
|
1181
|
-
clips.push(clip);
|
|
1182
|
-
}
|
|
1183
|
-
|
|
1184
|
-
// console.profileEnd('parse-gltf');
|
|
1185
|
-
// console.timeEnd('parse-gltf');
|
|
1186
|
-
|
|
1187
|
-
const bundle = new SceneBundle();
|
|
1188
|
-
bundle.scenes = scene_nodes3d;
|
|
1189
|
-
bundle.skins = skins;
|
|
1190
|
-
bundle.clips = clips;
|
|
1191
|
-
return bundle;
|
|
1192
|
-
}
|
|
1193
|
-
|
|
1194
|
-
/**
|
|
1195
|
-
*
|
|
1196
|
-
* @param {Node3D[]} scenes
|
|
1197
|
-
*/
|
|
1198
|
-
function fix_scene_material_sidedness(scenes) {
|
|
1199
|
-
const meshes = new Set();
|
|
1200
|
-
|
|
1201
|
-
for (const s of scenes) {
|
|
1202
|
-
s.traverse(node => {
|
|
1203
|
-
if (node.isMesh) {
|
|
1204
|
-
meshes.add(node);
|
|
1205
|
-
}
|
|
1206
|
-
});
|
|
1207
|
-
}
|
|
1208
|
-
|
|
1209
|
-
const { geometries_modified: fixed_count, primitives_delta } = fix_up_material_sides(Array.from(meshes));
|
|
1210
|
-
|
|
1211
|
-
if (fixed_count > 0) {
|
|
1212
|
-
console.warn(`Fixed ${fixed_count} geometries in accordance with material sidedness. Primitives added: ${number_format_by_thousands(primitives_delta)}`);
|
|
1213
|
-
}
|
|
1214
|
-
|
|
1215
|
-
return scenes;
|
|
1216
|
-
}
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
return load_gltf_document(url, { assetManager, scope, fileMap })
|
|
1220
|
-
.then(process)
|
|
1221
|
-
// .then(fix_scene_material_sidedness)
|
|
1222
|
-
// .then(prepare_lightmap)
|
|
1223
|
-
;
|
|
1224
|
-
}
|
|
1225
|
-
|
|
1226
|
-
/**
|
|
1227
|
-
* The same file, parsed and with its dependencies in memory, **without** being turned into anything
|
|
1228
|
-
* a renderer draws: the glTF's own JSON alongside `buffers` as `Uint8Array`s and `images` as
|
|
1229
|
-
* `ImageBitmap`s.
|
|
1230
|
-
*
|
|
1231
|
-
* The half of {@link load_gltf} that is not about pictures. A glTF carries more than a scene to draw
|
|
1232
|
-
* — collision hulls, navigation surfaces, spawn markers, whatever a tool reads accessors for — and
|
|
1233
|
-
* those consumers want the accessors and the bytes behind them, not a {@link SceneBundle} they would
|
|
1234
|
-
* have to take apart again.
|
|
1235
|
-
*
|
|
1236
|
-
* @param {string} url un-resolved — the asset manager resolves network paths
|
|
1237
|
-
* @param {Object} options
|
|
1238
|
-
* @param {AssetManager} options.assetManager
|
|
1239
|
-
* @param {AssetRequestScope} [options.scope]
|
|
1240
|
-
* @param {Map<string, File|Blob|ArrayBuffer>} [options.fileMap]
|
|
1241
|
-
* @returns {Promise<TinyGltf>}
|
|
1242
|
-
*/
|
|
1243
|
-
export function load_gltf_document(url, { assetManager, scope, fileMap } = {}) {
|
|
1244
|
-
const gltf = new TinyGltf(assetManager, scope);
|
|
1245
|
-
|
|
1246
|
-
if (fileMap) {
|
|
1247
|
-
gltf.fileMap = fileMap;
|
|
1248
|
-
}
|
|
1249
|
-
|
|
1250
|
-
return gltf.loadFromUrl(url);
|
|
1251
|
-
}
|
|
1252
|
-
|
|
1253
|
-
|
|
1
|
+
import { assert } from "../../../../core/assert.js";
|
|
2
|
+
import { HashMap } from "../../../../core/collection/map/HashMap.js";
|
|
3
|
+
import { HashSet } from "../../../../core/collection/set/HashSet.js";
|
|
4
|
+
import { Color } from "../../../../core/color/Color.js";
|
|
5
|
+
import { Quaternion } from "../../../../core/geom/Quaternion.js";
|
|
6
|
+
import Vector3 from "../../../../core/geom/Vector3.js";
|
|
7
|
+
import { clamp } from "../../../../core/math/clamp.js";
|
|
8
|
+
import { clamp01 } from "../../../../core/math/clamp01.js";
|
|
9
|
+
import { computeObjectHash } from "../../../../core/math/hash/computeObjectHash.js";
|
|
10
|
+
import { inverseLerp } from "../../../../core/math/inverseLerp.js";
|
|
11
|
+
import { objectDeepEquals } from "../../../../core/model/object/objectDeepEquals.js";
|
|
12
|
+
import { number_format_by_thousands } from "../../../../core/primitives/numbers/number_format_by_thousands.js";
|
|
13
|
+
import { AnimationInterpolationKind } from "../../../../engine/animation/clip/AnimationInterpolationKind.js";
|
|
14
|
+
import { curve_from_track_data } from "../../../../engine/animation/clip/curve_from_track_data.js";
|
|
15
|
+
import { AnimationCurve } from "../../../../engine/animation/curve/AnimationCurve.js";
|
|
16
|
+
import { t64_look_rotation } from "../../../../engine/ecs/transform/t64_look_rotation.js";
|
|
17
|
+
import { t64_transform_direction } from "../../../../engine/ecs/transform/t64_transform_direction.js";
|
|
18
|
+
import { meshopt_optimizeVertexCache } from "../../../../engine/graphics/geometry/optimization/VertexCacheOptimizer.js";
|
|
19
|
+
import { ShadeAnimationChannel } from "../../animation/ShadeAnimationChannel.js";
|
|
20
|
+
import { ShadeAnimationClip } from "../../animation/ShadeAnimationClip.js";
|
|
21
|
+
import { Skin } from "../../animation/Skin.js";
|
|
22
|
+
import { Attribute } from "../../geometry/Attribute.js";
|
|
23
|
+
import { Geometry, GeometryFlags } from "../../geometry/Geometry.js";
|
|
24
|
+
import { meshlet_geometry_build_from_geometry } from "../../geometry/meshlet_geometry_build_from_geometry.js";
|
|
25
|
+
import { StandardAttributes } from "../../geometry/StandardAttributes.js";
|
|
26
|
+
import { normalize_attribute } from "../../geometry/util/normalize_attribute.js";
|
|
27
|
+
import { DirectionalLight } from "../../light/model/DirectionalLight.js";
|
|
28
|
+
import { PointLight } from "../../light/model/PointLight.js";
|
|
29
|
+
import { SpotLight } from "../../light/model/SpotLight.js";
|
|
30
|
+
|
|
31
|
+
import { StandardShadeMaterial } from "../../material/StandardShadeMaterial.js";
|
|
32
|
+
import { Node3DProperty } from "../../object_property/Node3DProperty.js";
|
|
33
|
+
import { Mesh } from "../../scene/Mesh.js";
|
|
34
|
+
import { Node3D } from "../../scene/Node3D.js";
|
|
35
|
+
import { SkinnedMesh } from "../../scene/SkinnedMesh.js";
|
|
36
|
+
import { ShadeTexture } from "../../texture/ShadeTexture.js";
|
|
37
|
+
import { ShadeImage } from "../../texture/source/ShadeImage.js";
|
|
38
|
+
import { TextureFilterType } from "../../texture/TextureFilterType.js";
|
|
39
|
+
import { TextureWrapType } from "../../texture/TextureWrapType.js";
|
|
40
|
+
import { SceneBundle } from "../SceneBundle.js";
|
|
41
|
+
import { coalesce_array_duplicates } from "./coalesce_array_duplicates.js";
|
|
42
|
+
import { fix_up_material_sides } from "./fix_up_material_sides.js";
|
|
43
|
+
import { GLTF_COMPONENT_TYPE } from "./gltf_component_type.js";
|
|
44
|
+
import { gltf_create_material } from "./gltf_create_material.js";
|
|
45
|
+
import { GLTF_PRIMITIVE_MODE, GLTF_PRIMITIVE_MODE_DEFAULT } from "./GLTF_PRIMITIVE_MODE.js";
|
|
46
|
+
import { gltf_read_accessor } from "./gltf_read_accessor.js";
|
|
47
|
+
import { gltf_used_image_indices } from "./gltf_used_image_indices.js";
|
|
48
|
+
import { TinyGltf } from "./tiny-gltf.js";
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Somewhere to hand `canonicalize_quaternion_signs` a rest rotation it can read by component name —
|
|
53
|
+
* a `Transform64` addresses its rotation by index, and the function's contract is named components.
|
|
54
|
+
*
|
|
55
|
+
* @type {Quaternion}
|
|
56
|
+
*/
|
|
57
|
+
const SCRATCH_REST_ROTATION = new Quaternion();
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Somewhere to read a light's facing before flipping it.
|
|
61
|
+
*
|
|
62
|
+
* @type {Vector3}
|
|
63
|
+
*/
|
|
64
|
+
const SCRATCH_DIRECTION = new Vector3();
|
|
65
|
+
const OPTIMIZE_GEOMETRIES = false;
|
|
66
|
+
|
|
67
|
+
const WEBGL_FILTER_NEAREST = 9728;
|
|
68
|
+
const WEBGL_FILTER_LINEAR = 9729;
|
|
69
|
+
const WEBGL_FILTER_NEAREST_MIPMAP_NEAREST = 9984;
|
|
70
|
+
const WEBGL_FILTER_LINEAR_MIPMAP_NEAREST = 9985;
|
|
71
|
+
const WEBGL_FILTER_NEAREST_MIPMAP_LINEAR = 9986;
|
|
72
|
+
const WEBGL_FILTER_LINEAR_MIPMAP_LINEAR = 9987;
|
|
73
|
+
|
|
74
|
+
const WEBGL_FILTERS = {
|
|
75
|
+
[WEBGL_FILTER_NEAREST]: TextureFilterType.Nearest,
|
|
76
|
+
[WEBGL_FILTER_LINEAR]: TextureFilterType.Linear,
|
|
77
|
+
[WEBGL_FILTER_NEAREST_MIPMAP_NEAREST]: TextureFilterType.Nearest,
|
|
78
|
+
[WEBGL_FILTER_LINEAR_MIPMAP_NEAREST]: TextureFilterType.Nearest,
|
|
79
|
+
[WEBGL_FILTER_NEAREST_MIPMAP_LINEAR]: TextureFilterType.Linear,
|
|
80
|
+
[WEBGL_FILTER_LINEAR_MIPMAP_LINEAR]: TextureFilterType.Linear
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
*
|
|
86
|
+
* @param {number} filter
|
|
87
|
+
* @returns {boolean}
|
|
88
|
+
*/
|
|
89
|
+
function webgl_filter_mipmap_linear(filter) {
|
|
90
|
+
switch (filter) {
|
|
91
|
+
case WEBGL_FILTER_LINEAR_MIPMAP_NEAREST:
|
|
92
|
+
case WEBGL_FILTER_LINEAR_MIPMAP_LINEAR:
|
|
93
|
+
return true;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
return false;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
*
|
|
101
|
+
* @param {number} minFilter
|
|
102
|
+
* @returns {TextureFilterType}
|
|
103
|
+
*/
|
|
104
|
+
function webgl_filter_mipmap(minFilter) {
|
|
105
|
+
if (minFilter === undefined || webgl_filter_mipmap_linear(minFilter)) {
|
|
106
|
+
return TextureFilterType.Linear;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
return TextureFilterType.Nearest;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const WEBGL_WRAPPINGS = {
|
|
113
|
+
33071: TextureWrapType.ClampToEdge,
|
|
114
|
+
33648: TextureWrapType.MirroredRepeat,
|
|
115
|
+
10497: TextureWrapType.Repeat
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
/**
|
|
119
|
+
* @see https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html
|
|
120
|
+
* @param {string} id
|
|
121
|
+
*/
|
|
122
|
+
function gltf_attribute_id_to_standard(id) {
|
|
123
|
+
switch (id) {
|
|
124
|
+
case "POSITION":
|
|
125
|
+
return StandardAttributes.Position;
|
|
126
|
+
case "NORMAL":
|
|
127
|
+
return StandardAttributes.Normal;
|
|
128
|
+
case "TEXCOORD_0":
|
|
129
|
+
return StandardAttributes.TextureCoordinates0;
|
|
130
|
+
case "TEXCOORD_1":
|
|
131
|
+
return StandardAttributes.TextureCoordinates1;
|
|
132
|
+
case "TANGENT":
|
|
133
|
+
return StandardAttributes.Tangent;
|
|
134
|
+
case "COLOR_0":
|
|
135
|
+
return StandardAttributes.Color;
|
|
136
|
+
case "JOINTS_0":
|
|
137
|
+
return StandardAttributes.SkinningJoints;
|
|
138
|
+
case "WEIGHTS_0":
|
|
139
|
+
return StandardAttributes.SkinningWeights;
|
|
140
|
+
default:
|
|
141
|
+
return id;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Map glTF `animation.channels[].target.path` to {@link Node3DProperty}.
|
|
147
|
+
* Returns `-1` for paths we don't yet drive (morph-target `weights`),
|
|
148
|
+
* so the caller can skip those channels without throwing.
|
|
149
|
+
*
|
|
150
|
+
* @param {string} path
|
|
151
|
+
* @returns {number}
|
|
152
|
+
*/
|
|
153
|
+
function gltf_animation_path_to_property(path) {
|
|
154
|
+
switch (path) {
|
|
155
|
+
case "translation":
|
|
156
|
+
return Node3DProperty.Translation;
|
|
157
|
+
case "rotation":
|
|
158
|
+
return Node3DProperty.Rotation;
|
|
159
|
+
case "scale":
|
|
160
|
+
return Node3DProperty.Scale;
|
|
161
|
+
default:
|
|
162
|
+
// "weights" (morph targets) lands here; we don't yet have
|
|
163
|
+
// morph-target support in the renderer.
|
|
164
|
+
return -1;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
/**
|
|
169
|
+
* Number of scalar components per keyframe value for a given Node3D
|
|
170
|
+
* property — translation/scale = 3 (vec3), rotation = 4 (quaternion
|
|
171
|
+
* x/y/z/w).
|
|
172
|
+
*
|
|
173
|
+
* @param {number} property one of {@link Node3DProperty}
|
|
174
|
+
* @returns {number}
|
|
175
|
+
*/
|
|
176
|
+
function node3d_property_component_count(property) {
|
|
177
|
+
switch (property) {
|
|
178
|
+
case Node3DProperty.Translation:
|
|
179
|
+
case Node3DProperty.Scale:
|
|
180
|
+
return 3;
|
|
181
|
+
case Node3DProperty.Rotation:
|
|
182
|
+
return 4;
|
|
183
|
+
default:
|
|
184
|
+
throw new Error(`Unsupported animated property ${property}`);
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* Walk a flat keyframe-values buffer for a rotation channel and flip
|
|
190
|
+
* the sign of any keyframe whose val-quaternion has negative dot
|
|
191
|
+
* product with the previous keyframe's val-quaternion. The same flip
|
|
192
|
+
* is applied to that keyframe's in/out tangents in CUBICSPLINE mode
|
|
193
|
+
* so the cubic remains internally consistent.
|
|
194
|
+
*
|
|
195
|
+
* The flip preserves the rotation (q and -q encode the same
|
|
196
|
+
* orientation) while ensuring per-component interpolation between
|
|
197
|
+
* consecutive keyframes follows the short arc instead of passing
|
|
198
|
+
* through a near-zero quaternion mid-segment.
|
|
199
|
+
*
|
|
200
|
+
* The curve's leading sign is anchored against `rest_rotation` —
|
|
201
|
+
* the target node's authored local rest rotation: when the first
|
|
202
|
+
* keyframe's val-quat has negative dot product with the rest
|
|
203
|
+
* quaternion, the whole first keyframe block is negated (and the
|
|
204
|
+
* consecutive-keyframe pass propagates that sign down the curve).
|
|
205
|
+
* Every rotation curve targeting one node aligns against the same
|
|
206
|
+
* reference, so weighted multi-clip blends accumulate
|
|
207
|
+
* hemisphere-consistent contributions instead of cancelling toward
|
|
208
|
+
* a near-zero quaternion. Residual limitation: the anchor is the
|
|
209
|
+
* FIRST keyframe only — a curve that swings more than 90° away
|
|
210
|
+
* from the rest rotation mid-clip can still contribute opposite
|
|
211
|
+
* signs to another clip at those times; fixing that would need
|
|
212
|
+
* apply-time alignment, which the atomic pose accumulator cannot
|
|
213
|
+
* do order-independently.
|
|
214
|
+
*
|
|
215
|
+
* Mutates `values` in place. Safe to call on an output array that's
|
|
216
|
+
* a fresh copy of the source accessor (which is what
|
|
217
|
+
* {@link read_accessor_as_float32_array} produces).
|
|
218
|
+
*
|
|
219
|
+
* Exported for spec coverage; not part of the loader's public API.
|
|
220
|
+
*
|
|
221
|
+
* @param {Float32Array} values flat values: STEP/LINEAR uses 4
|
|
222
|
+
* floats/keyframe (x, y, z, w); CUBICSPLINE uses 12 (inX, inY,
|
|
223
|
+
* inZ, inW, valX, valY, valZ, valW, outX, outY, outZ, outW).
|
|
224
|
+
* @param {number} key_count
|
|
225
|
+
* @param {number} interpolation one of {@link AnimationInterpolationKind}
|
|
226
|
+
* @param {{x:number, y:number, z:number, w:number}} [rest_rotation]
|
|
227
|
+
* target node's authored local rest rotation; omitted → the
|
|
228
|
+
* leading sign is kept as authored.
|
|
229
|
+
*/
|
|
230
|
+
export function canonicalize_quaternion_signs(values, key_count, interpolation, rest_rotation) {
|
|
231
|
+
const is_cubic = interpolation === AnimationInterpolationKind.CubicTangents;
|
|
232
|
+
const stride = is_cubic ? 12 : 4;
|
|
233
|
+
// Offset into a keyframe block at which the val-quat sits.
|
|
234
|
+
// CUBICSPLINE has [in, val, out]; the val starts at offset 4 (i.e.
|
|
235
|
+
// after the 4-float in-tangent). STEP/LINEAR has just val at 0.
|
|
236
|
+
const val_offset = is_cubic ? 4 : 0;
|
|
237
|
+
|
|
238
|
+
if (key_count >= 1 && rest_rotation !== undefined) {
|
|
239
|
+
const rest_dot =
|
|
240
|
+
values[val_offset + 0] * rest_rotation.x +
|
|
241
|
+
values[val_offset + 1] * rest_rotation.y +
|
|
242
|
+
values[val_offset + 2] * rest_rotation.z +
|
|
243
|
+
values[val_offset + 3] * rest_rotation.w;
|
|
244
|
+
|
|
245
|
+
if (rest_dot < 0) {
|
|
246
|
+
// Negate the whole first keyframe block (value +
|
|
247
|
+
// tangents); the loop below carries the flip through
|
|
248
|
+
// the remaining keyframes.
|
|
249
|
+
for (let i = 0; i < stride; i++) {
|
|
250
|
+
values[i] = -values[i];
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
for (let k = 1; k < key_count; k++) {
|
|
256
|
+
const prev_base = (k - 1) * stride + val_offset;
|
|
257
|
+
const cur_base = k * stride + val_offset;
|
|
258
|
+
|
|
259
|
+
const dot =
|
|
260
|
+
values[prev_base + 0] * values[cur_base + 0] +
|
|
261
|
+
values[prev_base + 1] * values[cur_base + 1] +
|
|
262
|
+
values[prev_base + 2] * values[cur_base + 2] +
|
|
263
|
+
values[prev_base + 3] * values[cur_base + 3];
|
|
264
|
+
|
|
265
|
+
if (dot < 0) {
|
|
266
|
+
// Flip the whole keyframe block (value + tangents).
|
|
267
|
+
const start = k * stride;
|
|
268
|
+
const end = start + stride;
|
|
269
|
+
for (let i = start; i < end; i++) {
|
|
270
|
+
values[i] = -values[i];
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
/**
|
|
277
|
+
* Map glTF interpolation strings to the engine's enum. Defaults to
|
|
278
|
+
* LINEAR when missing — the glTF spec's default.
|
|
279
|
+
*
|
|
280
|
+
* @param {string|undefined} interpolation
|
|
281
|
+
* @returns {number} one of {@link AnimationInterpolationKind}
|
|
282
|
+
*/
|
|
283
|
+
function gltf_interpolation_to_kind(interpolation) {
|
|
284
|
+
switch (interpolation) {
|
|
285
|
+
case "STEP":
|
|
286
|
+
return AnimationInterpolationKind.Discrete;
|
|
287
|
+
case "CUBICSPLINE":
|
|
288
|
+
return AnimationInterpolationKind.CubicTangents;
|
|
289
|
+
case "LINEAR":
|
|
290
|
+
case undefined:
|
|
291
|
+
return AnimationInterpolationKind.Linear;
|
|
292
|
+
default:
|
|
293
|
+
throw new Error(`Unsupported interpolation '${interpolation}'`);
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
/**
|
|
298
|
+
* Input can be a .glb or .gltf file.
|
|
299
|
+
*
|
|
300
|
+
* Does not support most compression GLTF extensions such as draco, basis etc.
|
|
301
|
+
*
|
|
302
|
+
* Returns a {@link SceneBundle} that groups the parsed scene roots
|
|
303
|
+
* with any skins and animation clips extracted from the same asset.
|
|
304
|
+
* Callers add `bundle.scenes` to their scene, then pass the bundle's
|
|
305
|
+
* `skins` / `clips` to the scene's animation manager (e.g. via
|
|
306
|
+
* {@link GPUAnimationManager#register_skin} and
|
|
307
|
+
* {@link GPUAnimationManager#register_clip}) once `scene.build` has
|
|
308
|
+
* populated `id_mapping` for the joint and target nodes.
|
|
309
|
+
*
|
|
310
|
+
* @param {string} url un-resolved — the asset manager resolves network paths
|
|
311
|
+
* @param {Object} options
|
|
312
|
+
* @param {AssetManager} options.assetManager where the container, its buffers and its images come
|
|
313
|
+
* from. Required: a glTF is several files, and which of them are already in memory is not this
|
|
314
|
+
* parser's business to know.
|
|
315
|
+
* @param {AssetRequestScope} [options.scope] the load these requests belong to
|
|
316
|
+
* @param {Map<string, File|Blob|ArrayBuffer>} [options.fileMap] Map of relative paths to file data.
|
|
317
|
+
* When provided, buffer and image URIs in the GLTF are resolved from this map before the asset
|
|
318
|
+
* framework is asked. Enables multi-file GLTF loading from drag-and-drop.
|
|
319
|
+
* @return {Promise<SceneBundle>}
|
|
320
|
+
*/
|
|
321
|
+
export function load_gltf(url, { assetManager, scope, fileMap } = {}) {
|
|
322
|
+
// TODO
|
|
323
|
+
// apply some checks to the model, things like non-uniform scales, that can be fixed potentially
|
|
324
|
+
// see https://www.youtube.com/watch?v=FJRO5wFTEc8 for common ideas
|
|
325
|
+
// check for inverted normals
|
|
326
|
+
// check for duplicated vertices
|
|
327
|
+
// check for overlapping faces
|
|
328
|
+
|
|
329
|
+
async function process(gltf) {
|
|
330
|
+
// console.log(gltf);
|
|
331
|
+
|
|
332
|
+
/**
|
|
333
|
+
* @type {{type:string, componentType:number, count:number, bufferView:number, byteOffset:number, normalized:boolean, min?:number[], max?:number}[]}
|
|
334
|
+
*/
|
|
335
|
+
const accessors = gltf.accessors;
|
|
336
|
+
|
|
337
|
+
/**
|
|
338
|
+
* `aabb` is six numbers, `[x0, y0, z0, x1, y1, z1]`, in world space — and is absent on a node
|
|
339
|
+
* that bounds nothing, meaning neither it nor anything below it declared any.
|
|
340
|
+
*
|
|
341
|
+
* {{aabb?:Float64Array, mesh:number, worldMatrix:Float32Array}[]}
|
|
342
|
+
*/
|
|
343
|
+
const nodes = gltf.nodes;
|
|
344
|
+
|
|
345
|
+
/**
|
|
346
|
+
*
|
|
347
|
+
* @type {{aabb:Float64Array, primitives:({attributes:Object<number>,indices:number, material:number, mode:number}[])}[]}
|
|
348
|
+
*/
|
|
349
|
+
const meshes = gltf.meshes;
|
|
350
|
+
|
|
351
|
+
/**
|
|
352
|
+
*
|
|
353
|
+
* @type {{}[]}
|
|
354
|
+
*/
|
|
355
|
+
const scenes = gltf.scenes;
|
|
356
|
+
|
|
357
|
+
/**
|
|
358
|
+
* Engine Node3Ds indexed by glTF node index — populated lazily
|
|
359
|
+
* by {@link process_node} as the scene-graph recursion visits
|
|
360
|
+
* each node. Used afterwards to resolve skin joint references
|
|
361
|
+
* and animation channel targets (both of which point at glTF
|
|
362
|
+
* node indices, not at any in-memory object).
|
|
363
|
+
*
|
|
364
|
+
* @type {Node3D[]}
|
|
365
|
+
*/
|
|
366
|
+
const node3d_by_index = new Array((gltf.nodes ?? []).length);
|
|
367
|
+
|
|
368
|
+
/**
|
|
369
|
+
* Queue of pending `skin.meshes` pushes. process_node() can't
|
|
370
|
+
* resolve `node.skin → Skin` directly because skins[] is built
|
|
371
|
+
* *after* the recursion completes (the joint lookup needs
|
|
372
|
+
* node3d_by_index fully populated). So we enqueue the produced
|
|
373
|
+
* SkinnedMeshes here and drain into the matching skin once the
|
|
374
|
+
* walk finishes.
|
|
375
|
+
*
|
|
376
|
+
* @type {{ skin_index: number, meshes: Mesh[] }[]}
|
|
377
|
+
*/
|
|
378
|
+
const skin_mesh_pushes = [];
|
|
379
|
+
|
|
380
|
+
/**
|
|
381
|
+
* Primitive converted to JSON string serves as key
|
|
382
|
+
* @type {Map<string, MeshletGeometry>}
|
|
383
|
+
*/
|
|
384
|
+
const geometry_cache = new Map();
|
|
385
|
+
|
|
386
|
+
/**
|
|
387
|
+
*
|
|
388
|
+
* @type {HashSet<MeshletGeometry>}
|
|
389
|
+
*/
|
|
390
|
+
const geometry_cache_secondary = new HashSet();
|
|
391
|
+
|
|
392
|
+
/**
|
|
393
|
+
* Indexed as `gltf.images` is, and populated only where an image was actually fetched.
|
|
394
|
+
*
|
|
395
|
+
* Built from {@link gltf_used_image_indices} rather than by mapping the whole list, because
|
|
396
|
+
* that is the same function the fetch is filtered by: the two cannot drift into decoding one
|
|
397
|
+
* set and sampling another, and there is no slot here for an image that was never brought in.
|
|
398
|
+
*
|
|
399
|
+
* @type {ShadeImage[]}
|
|
400
|
+
*/
|
|
401
|
+
const mapped_images = [];
|
|
402
|
+
|
|
403
|
+
for (const index of gltf_used_image_indices(gltf)) {
|
|
404
|
+
mapped_images[index] = ShadeImage.fromImageBitmap(gltf.images[index]);
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
/**
|
|
408
|
+
* used when no material is specified
|
|
409
|
+
* @type {StandardShadeMaterial}
|
|
410
|
+
*/
|
|
411
|
+
const default_material = new StandardShadeMaterial();
|
|
412
|
+
|
|
413
|
+
/**
|
|
414
|
+
* Used when no sampler is present
|
|
415
|
+
* @type {{}}
|
|
416
|
+
*/
|
|
417
|
+
const default_sampler_description = {};
|
|
418
|
+
|
|
419
|
+
/**
|
|
420
|
+
*
|
|
421
|
+
* @type {ShadeTexture[]}
|
|
422
|
+
*/
|
|
423
|
+
const mapped_textures = (gltf.textures ?? []).map(gltf_texture => {
|
|
424
|
+
|
|
425
|
+
const sampler = gltf_texture.sampler;
|
|
426
|
+
|
|
427
|
+
let source;
|
|
428
|
+
|
|
429
|
+
const extensions = gltf_texture.extensions;
|
|
430
|
+
if (extensions !== undefined) {
|
|
431
|
+
|
|
432
|
+
source = extensions.EXT_texture_webp?.source;
|
|
433
|
+
|
|
434
|
+
}
|
|
435
|
+
|
|
436
|
+
if (source === undefined) {
|
|
437
|
+
source = gltf_texture.source;
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
const image = mapped_images[source];
|
|
441
|
+
|
|
442
|
+
|
|
443
|
+
/**
|
|
444
|
+
* @type {{magFilter:number, minFilter:number, wrapS:number, wrapT:number}}
|
|
445
|
+
*/
|
|
446
|
+
let sampler_descriptor;
|
|
447
|
+
|
|
448
|
+
if (gltf.samplers !== undefined && gltf.samplers[sampler] !== undefined) {
|
|
449
|
+
sampler_descriptor = gltf.samplers[sampler]
|
|
450
|
+
} else {
|
|
451
|
+
sampler_descriptor = default_sampler_description;
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
const texture = ShadeTexture.from(image);
|
|
455
|
+
|
|
456
|
+
texture.magFilter = WEBGL_FILTERS[sampler_descriptor.magFilter] ?? TextureFilterType.Linear;
|
|
457
|
+
texture.minFilter = WEBGL_FILTERS[sampler_descriptor.minFilter] ?? TextureFilterType.Linear;
|
|
458
|
+
texture.mipmapFilter = webgl_filter_mipmap(sampler_descriptor.minFilter);
|
|
459
|
+
|
|
460
|
+
texture.wrapS = WEBGL_WRAPPINGS[sampler_descriptor.wrapS] ?? TextureWrapType.Repeat;
|
|
461
|
+
texture.wrapT = WEBGL_WRAPPINGS[sampler_descriptor.wrapT] ?? TextureWrapType.Repeat;
|
|
462
|
+
|
|
463
|
+
return texture;
|
|
464
|
+
});
|
|
465
|
+
|
|
466
|
+
coalesce_array_duplicates(mapped_textures);
|
|
467
|
+
|
|
468
|
+
// account for materials missing
|
|
469
|
+
const gltf_materials = gltf.materials ?? [];
|
|
470
|
+
|
|
471
|
+
const mapped_materials = gltf_materials.map(gltf_mat => gltf_create_material(gltf_mat, mapped_textures));
|
|
472
|
+
|
|
473
|
+
// dedupe materials
|
|
474
|
+
coalesce_array_duplicates(mapped_materials);
|
|
475
|
+
|
|
476
|
+
|
|
477
|
+
/**
|
|
478
|
+
* One accessor as an attribute in the shape the renderer stores it.
|
|
479
|
+
*
|
|
480
|
+
* The read itself — stride, sparse overlay, a view-less accessor's zeroes — belongs to the
|
|
481
|
+
* format and is done by {@link gltf_read_accessor}; what is left here is the engine's own
|
|
482
|
+
* question of which storage type an attribute of this name is kept in.
|
|
483
|
+
*
|
|
484
|
+
* @param {number} accessor_index
|
|
485
|
+
* @param {string} name
|
|
486
|
+
* @returns {Attribute}
|
|
487
|
+
*/
|
|
488
|
+
function buffer_to_attribute(accessor_index, name) {
|
|
489
|
+
const data = gltf_read_accessor(gltf, accessor_index);
|
|
490
|
+
|
|
491
|
+
const raw_attribute = Attribute.from(data.values, data.components, name);
|
|
492
|
+
|
|
493
|
+
raw_attribute.spec.normalized = data.normalized;
|
|
494
|
+
|
|
495
|
+
return normalize_attribute(raw_attribute);
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
/**
|
|
499
|
+
*
|
|
500
|
+
* @type {HashMap<Object, Attribute>}
|
|
501
|
+
*/
|
|
502
|
+
const attribute_cache = new HashMap({
|
|
503
|
+
keyEqualityFunction: objectDeepEquals,
|
|
504
|
+
keyHashFunction: computeObjectHash
|
|
505
|
+
});
|
|
506
|
+
|
|
507
|
+
/**
|
|
508
|
+
*
|
|
509
|
+
* @param {number} attribute_accessor
|
|
510
|
+
* @param {string} name
|
|
511
|
+
* @returns {Attribute}
|
|
512
|
+
*/
|
|
513
|
+
function obtain_attribute(attribute_accessor, name) {
|
|
514
|
+
const key = {
|
|
515
|
+
attribute_accessor, name
|
|
516
|
+
};
|
|
517
|
+
|
|
518
|
+
let attribute = attribute_cache.get(key);
|
|
519
|
+
|
|
520
|
+
if (attribute === undefined) {
|
|
521
|
+
attribute = buffer_to_attribute(attribute_accessor, name);
|
|
522
|
+
attribute_cache.set(key, attribute);
|
|
523
|
+
} else {
|
|
524
|
+
// console.warn('attribute reuse')
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
return attribute;
|
|
528
|
+
}
|
|
529
|
+
|
|
530
|
+
/**
|
|
531
|
+
* A FLOAT-componentType accessor's values as a flat `Float32Array`. Used for animation
|
|
532
|
+
* sampler inputs/outputs (times, values) and the skin inverse-bind matrices, where
|
|
533
|
+
* downstream code wants a stride-free flat buffer.
|
|
534
|
+
*
|
|
535
|
+
* @param {number} accessor_index
|
|
536
|
+
* @returns {Float32Array}
|
|
537
|
+
*/
|
|
538
|
+
function read_accessor_as_float32_array(accessor_index) {
|
|
539
|
+
const accessor = accessors[accessor_index];
|
|
540
|
+
|
|
541
|
+
assert.equal(
|
|
542
|
+
accessor.componentType, GLTF_COMPONENT_TYPE.FLOAT,
|
|
543
|
+
`accessor[${accessor_index}].componentType must be FLOAT for read_accessor_as_float32_array`
|
|
544
|
+
);
|
|
545
|
+
|
|
546
|
+
return gltf_read_accessor(gltf, accessor_index).values;
|
|
547
|
+
}
|
|
548
|
+
|
|
549
|
+
/**
|
|
550
|
+
*
|
|
551
|
+
* @returns {MeshletGeometry}
|
|
552
|
+
*/
|
|
553
|
+
function primitive_to_geometry(primitive) {
|
|
554
|
+
const geometry = new Geometry();
|
|
555
|
+
|
|
556
|
+
const mode = primitive.mode ?? GLTF_PRIMITIVE_MODE_DEFAULT;
|
|
557
|
+
|
|
558
|
+
if (mode !== GLTF_PRIMITIVE_MODE.TRIANGLES) {
|
|
559
|
+
throw new Error('Unsupported draw method');
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
for (const attribute_key in primitive.attributes) {
|
|
563
|
+
|
|
564
|
+
const name = gltf_attribute_id_to_standard(attribute_key);
|
|
565
|
+
|
|
566
|
+
if (geometry.getAttribute(name) !== undefined) {
|
|
567
|
+
console.warn(`attribute '${name}' already exists, skipping. Primitive.attributes = ${JSON.stringify(primitive.attributes)}`)
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
/**
|
|
571
|
+
* @type {number}
|
|
572
|
+
*/
|
|
573
|
+
const attribute_accessor = primitive.attributes[attribute_key];
|
|
574
|
+
|
|
575
|
+
let attribute;
|
|
576
|
+
try {
|
|
577
|
+
attribute = obtain_attribute(attribute_accessor, name);
|
|
578
|
+
} catch (e) {
|
|
579
|
+
console.warn(`Failed to parse attribute '${name}'. Skipping`, e);
|
|
580
|
+
continue;
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
geometry.addAttribute(attribute);
|
|
584
|
+
|
|
585
|
+
|
|
586
|
+
if (attribute_key === "POSITION") {
|
|
587
|
+
// The spec mandates POSITION accessors carry min/max,
|
|
588
|
+
// so we can adopt them as the bounding box without
|
|
589
|
+
// walking the vertex data. The sphere is derived from
|
|
590
|
+
// the box inside meshlet_geometry_build_from_geometry,
|
|
591
|
+
// so we just clear the dirty flag here.
|
|
592
|
+
const accessor = accessors[attribute_accessor];
|
|
593
|
+
|
|
594
|
+
if (accessor.min !== undefined && accessor.max !== undefined) {
|
|
595
|
+
geometry.bounding_box.set([
|
|
596
|
+
...accessor.min,
|
|
597
|
+
...accessor.max
|
|
598
|
+
]);
|
|
599
|
+
|
|
600
|
+
geometry.clearFlag(GeometryFlags.BoundsNeedUpdate);
|
|
601
|
+
}
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
if (primitive.indices !== undefined) {
|
|
606
|
+
|
|
607
|
+
geometry.index = obtain_attribute(primitive.indices, 'index');
|
|
608
|
+
|
|
609
|
+
// geometry_fix_index(geometry.index, geometry.getVertexCount());
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
|
|
613
|
+
// vertex optimize
|
|
614
|
+
if (geometry.index !== null && OPTIMIZE_GEOMETRIES) {
|
|
615
|
+
meshopt_optimizeVertexCache(geometry.index.data, geometry.index.data, geometry.index.count, geometry.getVertexCount());
|
|
616
|
+
}
|
|
617
|
+
|
|
618
|
+
return meshlet_geometry_build_from_geometry(geometry);
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
function obtain_geometry_by_primitive(primitive) {
|
|
622
|
+
const key = JSON.stringify(primitive);
|
|
623
|
+
|
|
624
|
+
let geometry = geometry_cache.get(key);
|
|
625
|
+
|
|
626
|
+
if (geometry === undefined) {
|
|
627
|
+
geometry = primitive_to_geometry(primitive)
|
|
628
|
+
|
|
629
|
+
const secondary_cached = geometry_cache_secondary.get(geometry);
|
|
630
|
+
|
|
631
|
+
if (secondary_cached !== undefined) {
|
|
632
|
+
// found an equivalent geometry in the secondary cache, use it instead
|
|
633
|
+
geometry = secondary_cached;
|
|
634
|
+
// console.warn("secondary reuse");
|
|
635
|
+
} else {
|
|
636
|
+
geometry_cache_secondary.add(geometry);
|
|
637
|
+
}
|
|
638
|
+
|
|
639
|
+
geometry_cache.set(key, geometry);
|
|
640
|
+
} else {
|
|
641
|
+
// console.warn('geometry reuse');
|
|
642
|
+
}
|
|
643
|
+
|
|
644
|
+
return geometry;
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
|
|
648
|
+
/**
|
|
649
|
+
* Build the renderable mesh(es) for one glTF node.
|
|
650
|
+
*
|
|
651
|
+
* A glTF mesh is a list of primitives sharing a name and an
|
|
652
|
+
* `aabb`, and each primitive becomes one engine-side {@link Mesh}.
|
|
653
|
+
* When the owning glTF node references a skin, every primitive is
|
|
654
|
+
* instead constructed as a {@link SkinnedMesh} so the renderer
|
|
655
|
+
* routes it through a per-instance geometry clone for deformation.
|
|
656
|
+
*
|
|
657
|
+
* @param {number} mesh_index
|
|
658
|
+
* @param {{}} node
|
|
659
|
+
* @param {boolean} is_skinned
|
|
660
|
+
* @returns {Mesh[]}
|
|
661
|
+
*/
|
|
662
|
+
function process_mesh(mesh_index, node, is_skinned) {
|
|
663
|
+
|
|
664
|
+
const mesh = meshes[mesh_index];
|
|
665
|
+
|
|
666
|
+
const primitives = mesh.primitives;
|
|
667
|
+
|
|
668
|
+
const primitive_count = primitives.length;
|
|
669
|
+
|
|
670
|
+
/**
|
|
671
|
+
*
|
|
672
|
+
* @type {Mesh[]}
|
|
673
|
+
*/
|
|
674
|
+
const result = [];
|
|
675
|
+
|
|
676
|
+
for (let i = 0; i < primitive_count; i++) {
|
|
677
|
+
const primitive = primitives[i];
|
|
678
|
+
|
|
679
|
+
// build geometry
|
|
680
|
+
|
|
681
|
+
/**
|
|
682
|
+
* @type {MeshletGeometry}
|
|
683
|
+
*/
|
|
684
|
+
let geometry;
|
|
685
|
+
|
|
686
|
+
try {
|
|
687
|
+
geometry = obtain_geometry_by_primitive(primitive);
|
|
688
|
+
} catch (e) {
|
|
689
|
+
console.error(`Failed to obtain geometry for primitive [${i}] ${primitive}. `, e);
|
|
690
|
+
console.log('Ignoring mesh');
|
|
691
|
+
continue;
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
if (primitive_count === 1 && mesh.name !== undefined) {
|
|
695
|
+
geometry.name = mesh.name;
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
const material_id = primitive.material;
|
|
699
|
+
|
|
700
|
+
let material;
|
|
701
|
+
|
|
702
|
+
if (material_id !== undefined) {
|
|
703
|
+
material = mapped_materials[material_id];
|
|
704
|
+
|
|
705
|
+
if (material === undefined) {
|
|
706
|
+
console.warn(`specified material ${material_id} does not exist. Using default.`);
|
|
707
|
+
|
|
708
|
+
material = default_material;
|
|
709
|
+
}
|
|
710
|
+
|
|
711
|
+
} else {
|
|
712
|
+
// no material specified, use default
|
|
713
|
+
material = default_material;
|
|
714
|
+
}
|
|
715
|
+
|
|
716
|
+
const engine_mesh = is_skinned ? new SkinnedMesh() : new Mesh();
|
|
717
|
+
engine_mesh.geometry = geometry;
|
|
718
|
+
engine_mesh.material = material;
|
|
719
|
+
engine_mesh.transform_global.fromMatrix(node.worldMatrix);
|
|
720
|
+
|
|
721
|
+
|
|
722
|
+
if (mesh.name !== undefined) {
|
|
723
|
+
engine_mesh.name = mesh.name;
|
|
724
|
+
}
|
|
725
|
+
|
|
726
|
+
result.push(engine_mesh);
|
|
727
|
+
}
|
|
728
|
+
|
|
729
|
+
return result;
|
|
730
|
+
}
|
|
731
|
+
|
|
732
|
+
/**
|
|
733
|
+
*
|
|
734
|
+
* @param {number} light_index
|
|
735
|
+
* @param {{}} node
|
|
736
|
+
* @returns {AbstractLight}
|
|
737
|
+
*/
|
|
738
|
+
function process_light(light_index, node) {
|
|
739
|
+
|
|
740
|
+
// SPEC: https://github.com/KhronosGroup/glTF/blob/main/extensions/2.0/Khronos/KHR_lights_punctual/README.md
|
|
741
|
+
|
|
742
|
+
const gltf_light = gltf.extensions.KHR_lights_punctual.lights[light_index];
|
|
743
|
+
|
|
744
|
+
// parse color
|
|
745
|
+
const color = new Color();
|
|
746
|
+
|
|
747
|
+
if (gltf_light.color !== undefined) {
|
|
748
|
+
color.fromArray(gltf_light.color);
|
|
749
|
+
} else {
|
|
750
|
+
color.setRGB(1, 1, 1);
|
|
751
|
+
}
|
|
752
|
+
|
|
753
|
+
const intensity = gltf_light.intensity ?? 1;
|
|
754
|
+
|
|
755
|
+
const name = gltf_light.name ?? "";
|
|
756
|
+
|
|
757
|
+
let light;
|
|
758
|
+
|
|
759
|
+
const type = gltf_light.type;
|
|
760
|
+
|
|
761
|
+
switch (type) {
|
|
762
|
+
case "directional":
|
|
763
|
+
light = new DirectionalLight();
|
|
764
|
+
break;
|
|
765
|
+
case "point":
|
|
766
|
+
light = new PointLight();
|
|
767
|
+
light.distance = gltf_light.range ?? 1e20; // default light radius
|
|
768
|
+
break;
|
|
769
|
+
case "spot":
|
|
770
|
+
light = new SpotLight();
|
|
771
|
+
|
|
772
|
+
const gltf_spot = gltf_light.spot;
|
|
773
|
+
|
|
774
|
+
const outerCone = gltf_spot?.outerConeAngle ?? (Math.PI / 4); // default PI/4
|
|
775
|
+
const innerCone = gltf_spot?.innerConeAngle ?? 0;
|
|
776
|
+
|
|
777
|
+
light.angle = clamp(
|
|
778
|
+
outerCone,
|
|
779
|
+
0,
|
|
780
|
+
Math.PI / 2
|
|
781
|
+
);
|
|
782
|
+
|
|
783
|
+
light.penumbra = clamp01(
|
|
784
|
+
inverseLerp(light.angle, 0, innerCone)
|
|
785
|
+
);
|
|
786
|
+
|
|
787
|
+
light.distance = gltf_light.range ?? 1e20;
|
|
788
|
+
// TODO rotation is messed up?
|
|
789
|
+
break;
|
|
790
|
+
default:
|
|
791
|
+
throw new Error(`Unsupported light type ${type}`);
|
|
792
|
+
}
|
|
793
|
+
|
|
794
|
+
light.color.copy(color);
|
|
795
|
+
light.intensity = intensity;
|
|
796
|
+
light.name = name;
|
|
797
|
+
|
|
798
|
+
// check for light radius
|
|
799
|
+
light.radius = gltf_light.extras?.radius ?? 0;
|
|
800
|
+
|
|
801
|
+
light.near_clip_distance = gltf_light.extras?.near_clip_distance ?? light.radius;
|
|
802
|
+
|
|
803
|
+
light.casts_shadow = true;
|
|
804
|
+
|
|
805
|
+
return light;
|
|
806
|
+
}
|
|
807
|
+
|
|
808
|
+
/**
|
|
809
|
+
*
|
|
810
|
+
* @param {Node3D} parent
|
|
811
|
+
* @param {number} node_index
|
|
812
|
+
*/
|
|
813
|
+
function process_node(parent, node_index) {
|
|
814
|
+
|
|
815
|
+
const node = nodes[node_index];
|
|
816
|
+
|
|
817
|
+
// glTF "skin" attaches at the node, not the mesh: every
|
|
818
|
+
// primitive of the referenced mesh becomes a SkinnedMesh
|
|
819
|
+
// bound to this skin. Resolved later (after the recursion
|
|
820
|
+
// is done) against `skins[]`, which we've already built
|
|
821
|
+
// — the joint Node3Ds may be visited *after* this node,
|
|
822
|
+
// so we just record the produced SkinnedMeshes here and
|
|
823
|
+
// push them into `skin.meshes` once the walk finishes.
|
|
824
|
+
const skin_index = typeof node.skin === "number" ? node.skin : -1;
|
|
825
|
+
|
|
826
|
+
let node3d;
|
|
827
|
+
let produced_skinned_meshes = null;
|
|
828
|
+
|
|
829
|
+
if (node.extensions !== undefined && node.extensions.KHR_lights_punctual !== undefined) {
|
|
830
|
+
const light_index = node.extensions.KHR_lights_punctual.light;
|
|
831
|
+
|
|
832
|
+
try {
|
|
833
|
+
node3d = process_light(light_index, node);
|
|
834
|
+
} catch (e) {
|
|
835
|
+
console.error("Failed to process light ", light_index, " ", e);
|
|
836
|
+
}
|
|
837
|
+
}
|
|
838
|
+
|
|
839
|
+
|
|
840
|
+
if (typeof node.mesh === "number") {
|
|
841
|
+
const meshes = process_mesh(node.mesh, node, skin_index !== -1);
|
|
842
|
+
|
|
843
|
+
if (meshes.length === 1) {
|
|
844
|
+
node3d = meshes[0];
|
|
845
|
+
} else if (meshes.length > 1) {
|
|
846
|
+
node3d = new Node3D();
|
|
847
|
+
|
|
848
|
+
node3d.addChildren(meshes)
|
|
849
|
+
}
|
|
850
|
+
|
|
851
|
+
if (skin_index !== -1) {
|
|
852
|
+
produced_skinned_meshes = meshes;
|
|
853
|
+
}
|
|
854
|
+
}
|
|
855
|
+
|
|
856
|
+
if (node3d === undefined) {
|
|
857
|
+
node3d = new Node3D();
|
|
858
|
+
}
|
|
859
|
+
|
|
860
|
+
// Stash by glTF index — joint refs and animation channel
|
|
861
|
+
// targets resolve through this lookup once the recursion
|
|
862
|
+
// unwinds.
|
|
863
|
+
node3d_by_index[node_index] = node3d;
|
|
864
|
+
|
|
865
|
+
if (node.name !== undefined) {
|
|
866
|
+
node3d.name = node.name;
|
|
867
|
+
}
|
|
868
|
+
|
|
869
|
+
if (node.matrix !== undefined) {
|
|
870
|
+
|
|
871
|
+
node3d.transform_local.fromMatrix(node.matrix);
|
|
872
|
+
|
|
873
|
+
} else {
|
|
874
|
+
|
|
875
|
+
const t = node3d.transform_local;
|
|
876
|
+
|
|
877
|
+
if (node.translation !== undefined) {
|
|
878
|
+
const v = node.translation;
|
|
879
|
+
|
|
880
|
+
t.setTranslation(v[0], v[1], v[2]);
|
|
881
|
+
}
|
|
882
|
+
|
|
883
|
+
if (node.rotation !== undefined) {
|
|
884
|
+
const q = node.rotation;
|
|
885
|
+
|
|
886
|
+
t.setRotation(q[0], q[1], q[2], q[3]);
|
|
887
|
+
}
|
|
888
|
+
|
|
889
|
+
if (node.scale !== undefined) {
|
|
890
|
+
const v = node.scale;
|
|
891
|
+
|
|
892
|
+
t.setScale(v[0], v[1], v[2]);
|
|
893
|
+
}
|
|
894
|
+
}
|
|
895
|
+
|
|
896
|
+
|
|
897
|
+
if (node3d.isDirectionalLight || node3d.isSpotLight) {
|
|
898
|
+
// glTF lights shine along their local -Z; engine convention is forward = shining direction
|
|
899
|
+
const t = node3d.transform_local;
|
|
900
|
+
|
|
901
|
+
// the direction is read off the matrix, and a Transform64 does not maintain its own
|
|
902
|
+
t.updateMatrix();
|
|
903
|
+
|
|
904
|
+
t64_transform_direction(SCRATCH_DIRECTION, t, 0, 0, 1);
|
|
905
|
+
|
|
906
|
+
t64_look_rotation(
|
|
907
|
+
t,
|
|
908
|
+
-SCRATCH_DIRECTION.x, -SCRATCH_DIRECTION.y, -SCRATCH_DIRECTION.z,
|
|
909
|
+
0, 1, 0
|
|
910
|
+
);
|
|
911
|
+
}
|
|
912
|
+
|
|
913
|
+
parent.addChild(node3d);
|
|
914
|
+
|
|
915
|
+
if (produced_skinned_meshes !== null) {
|
|
916
|
+
// Defer the `skin.meshes` push to after `skins[]` is
|
|
917
|
+
// built — we collect into a queue here and process it
|
|
918
|
+
// at the end of process().
|
|
919
|
+
skin_mesh_pushes.push({
|
|
920
|
+
skin_index,
|
|
921
|
+
meshes: produced_skinned_meshes,
|
|
922
|
+
});
|
|
923
|
+
}
|
|
924
|
+
|
|
925
|
+
|
|
926
|
+
if (node.children !== undefined) {
|
|
927
|
+
|
|
928
|
+
for (let i = 0; i < node.children.length; i++) {
|
|
929
|
+
const node_index = node.children[i];
|
|
930
|
+
|
|
931
|
+
process_node(node3d, node_index);
|
|
932
|
+
}
|
|
933
|
+
}
|
|
934
|
+
}
|
|
935
|
+
|
|
936
|
+
// console.time('parse-gltf');
|
|
937
|
+
// console.profile('parse-gltf');
|
|
938
|
+
|
|
939
|
+
/**
|
|
940
|
+
*
|
|
941
|
+
* @type {Node3D[]}
|
|
942
|
+
*/
|
|
943
|
+
const scene_nodes3d = [];
|
|
944
|
+
|
|
945
|
+
for (let i = 0; i < scenes.length; i++) {
|
|
946
|
+
const scene = scenes[i];
|
|
947
|
+
|
|
948
|
+
const scene_node3d = new Node3D();
|
|
949
|
+
|
|
950
|
+
scene_nodes3d.push(scene_node3d);
|
|
951
|
+
|
|
952
|
+
/**
|
|
953
|
+
* @type {number[]}
|
|
954
|
+
*/
|
|
955
|
+
const scene_nodes = scene.nodes;
|
|
956
|
+
|
|
957
|
+
const node_count = scene_nodes.length;
|
|
958
|
+
|
|
959
|
+
for (let i = 0; i < node_count; i++) {
|
|
960
|
+
const node_index = scene_nodes[i];
|
|
961
|
+
process_node(scene_node3d, node_index);
|
|
962
|
+
}
|
|
963
|
+
|
|
964
|
+
scene_node3d.updateMatrices();
|
|
965
|
+
}
|
|
966
|
+
|
|
967
|
+
// ── Skins ──────────────────────────────────────────────────
|
|
968
|
+
//
|
|
969
|
+
// Build {@link Skin} objects from `gltf.skins[]`. Joints
|
|
970
|
+
// resolve to Node3D refs through `node3d_by_index` (fully
|
|
971
|
+
// populated by the recursion above). Inverse-bind matrices
|
|
972
|
+
// come from a single MAT4 accessor — `joint_count * 16` f32s
|
|
973
|
+
// laid out column-major, copied into a flat Float32Array that
|
|
974
|
+
// the manager can subarray-view at registration time.
|
|
975
|
+
const skins = (gltf.skins ?? []).map((gltf_skin, skin_index) => {
|
|
976
|
+
const joint_indices = gltf_skin.joints;
|
|
977
|
+
const joint_count = joint_indices.length;
|
|
978
|
+
|
|
979
|
+
const joint_nodes = new Array(joint_count);
|
|
980
|
+
for (let i = 0; i < joint_count; i++) {
|
|
981
|
+
const joint_node_index = joint_indices[i];
|
|
982
|
+
const joint_node = node3d_by_index[joint_node_index];
|
|
983
|
+
|
|
984
|
+
assert.defined(
|
|
985
|
+
joint_node,
|
|
986
|
+
`skin[${skin_index}].joints[${i}] references unknown node index ${joint_node_index}`
|
|
987
|
+
);
|
|
988
|
+
|
|
989
|
+
joint_nodes[i] = joint_node;
|
|
990
|
+
}
|
|
991
|
+
|
|
992
|
+
// Inverse-bind matrices: glTF stores them MAT4-typed
|
|
993
|
+
// (column-major, 16 f32s per joint). When the accessor is
|
|
994
|
+
// omitted, the spec says every joint's IBM is identity —
|
|
995
|
+
// we materialise that here so the manager always sees a
|
|
996
|
+
// ready-to-use flat array.
|
|
997
|
+
let inverse_bind_matrices;
|
|
998
|
+
if (gltf_skin.inverseBindMatrices !== undefined) {
|
|
999
|
+
inverse_bind_matrices = read_accessor_as_float32_array(gltf_skin.inverseBindMatrices);
|
|
1000
|
+
} else {
|
|
1001
|
+
inverse_bind_matrices = new Float32Array(joint_count * 16);
|
|
1002
|
+
for (let i = 0; i < joint_count; i++) {
|
|
1003
|
+
inverse_bind_matrices[i * 16 + 0] = 1;
|
|
1004
|
+
inverse_bind_matrices[i * 16 + 5] = 1;
|
|
1005
|
+
inverse_bind_matrices[i * 16 + 10] = 1;
|
|
1006
|
+
inverse_bind_matrices[i * 16 + 15] = 1;
|
|
1007
|
+
}
|
|
1008
|
+
}
|
|
1009
|
+
|
|
1010
|
+
return Skin.from({
|
|
1011
|
+
name: gltf_skin.name ?? "",
|
|
1012
|
+
joints: joint_nodes,
|
|
1013
|
+
inverse_bind_matrices,
|
|
1014
|
+
meshes: [],
|
|
1015
|
+
});
|
|
1016
|
+
});
|
|
1017
|
+
|
|
1018
|
+
// Drain the deferred skin.meshes pushes captured during the
|
|
1019
|
+
// node walk.
|
|
1020
|
+
for (let i = 0; i < skin_mesh_pushes.length; i++) {
|
|
1021
|
+
const { skin_index, meshes: skin_meshes } = skin_mesh_pushes[i];
|
|
1022
|
+
skins[skin_index].meshes.push(...skin_meshes);
|
|
1023
|
+
}
|
|
1024
|
+
|
|
1025
|
+
// ── Animation clips ───────────────────────────────────────
|
|
1026
|
+
//
|
|
1027
|
+
// One glTF animation → one {@link ShadeAnimationClip}. Each
|
|
1028
|
+
// channel becomes a {@link ShadeAnimationChannel}; per-component
|
|
1029
|
+
// curves are built from the sampler's input (times) / output
|
|
1030
|
+
// (values) accessors via the engine's curve_from_track_data
|
|
1031
|
+
// helpers, which already handle STEP / LINEAR / CUBICSPLINE.
|
|
1032
|
+
const clips = [];
|
|
1033
|
+
const gltf_animations = gltf.animations ?? [];
|
|
1034
|
+
for (let a = 0; a < gltf_animations.length; a++) {
|
|
1035
|
+
const gltf_animation = gltf_animations[a];
|
|
1036
|
+
|
|
1037
|
+
const channels = [];
|
|
1038
|
+
|
|
1039
|
+
for (let c = 0; c < gltf_animation.channels.length; c++) {
|
|
1040
|
+
const gltf_channel = gltf_animation.channels[c];
|
|
1041
|
+
const target = gltf_channel.target;
|
|
1042
|
+
|
|
1043
|
+
const property = gltf_animation_path_to_property(target.path);
|
|
1044
|
+
if (property === -1) {
|
|
1045
|
+
// Morph-target weights or other unsupported paths.
|
|
1046
|
+
continue;
|
|
1047
|
+
}
|
|
1048
|
+
|
|
1049
|
+
if (target.node === undefined) {
|
|
1050
|
+
// Channels without a node target are a glTF
|
|
1051
|
+
// extension hook and not actionable here.
|
|
1052
|
+
continue;
|
|
1053
|
+
}
|
|
1054
|
+
|
|
1055
|
+
const target_node = node3d_by_index[target.node];
|
|
1056
|
+
|
|
1057
|
+
assert.defined(
|
|
1058
|
+
target_node,
|
|
1059
|
+
`animations[${a}].channels[${c}].target.node ${target.node} not resolved`
|
|
1060
|
+
);
|
|
1061
|
+
|
|
1062
|
+
const sampler = gltf_animation.samplers[gltf_channel.sampler];
|
|
1063
|
+
const times = read_accessor_as_float32_array(sampler.input);
|
|
1064
|
+
const values = read_accessor_as_float32_array(sampler.output);
|
|
1065
|
+
const interpolation = gltf_interpolation_to_kind(sampler.interpolation);
|
|
1066
|
+
const component_count = node3d_property_component_count(property);
|
|
1067
|
+
|
|
1068
|
+
// Canonicalize quaternion signs on rotation channels.
|
|
1069
|
+
//
|
|
1070
|
+
// glTF stores rotation keyframes as raw (x, y, z, w)
|
|
1071
|
+
// quaternions, but `q` and `-q` represent the same
|
|
1072
|
+
// orientation. Authoring tools (notably Mixamo) often
|
|
1073
|
+
// alternate signs across consecutive keyframes when a
|
|
1074
|
+
// bone passes through 180°. Per-component interpolation
|
|
1075
|
+
// between sign-mismatched keyframes — especially
|
|
1076
|
+
// CUBICSPLINE — passes through near-zero quaternions
|
|
1077
|
+
// mid-segment; the apply shader's `normalize(value)`
|
|
1078
|
+
// call then produces an effectively-identity quaternion
|
|
1079
|
+
// for one frame, which reads as a one-frame snap to
|
|
1080
|
+
// bind pose.
|
|
1081
|
+
//
|
|
1082
|
+
// Fix: flip the sign of every keyframe whose val-quat
|
|
1083
|
+
// has negative dot product with the prior keyframe's
|
|
1084
|
+
// val-quat. For CUBICSPLINE, flip the in/out tangents
|
|
1085
|
+
// alongside the value so the cubic stays consistent.
|
|
1086
|
+
// The leading sign is anchored against the target
|
|
1087
|
+
// node's authored rest rotation so all clips driving
|
|
1088
|
+
// one node land in the same hemisphere — required
|
|
1089
|
+
// for weighted multi-clip blends, where the pose
|
|
1090
|
+
// accumulator sums raw components across clips.
|
|
1091
|
+
// No-op when the property isn't Rotation, or when the
|
|
1092
|
+
// data was already canonicalized at export time.
|
|
1093
|
+
if (property === Node3DProperty.Rotation && times.length >= 1) {
|
|
1094
|
+
// `canonicalize_quaternion_signs` reads the rest rotation by component name,
|
|
1095
|
+
// which a `Transform64` does not offer — hand it a quaternion instead
|
|
1096
|
+
const rest = target_node.transform_local;
|
|
1097
|
+
|
|
1098
|
+
SCRATCH_REST_ROTATION.set(
|
|
1099
|
+
rest.rotation_x,
|
|
1100
|
+
rest.rotation_y,
|
|
1101
|
+
rest.rotation_z,
|
|
1102
|
+
rest.rotation_w
|
|
1103
|
+
);
|
|
1104
|
+
|
|
1105
|
+
canonicalize_quaternion_signs(
|
|
1106
|
+
values, times.length, interpolation,
|
|
1107
|
+
SCRATCH_REST_ROTATION
|
|
1108
|
+
);
|
|
1109
|
+
}
|
|
1110
|
+
|
|
1111
|
+
// Build the per-axis curves object. component_count
|
|
1112
|
+
// is property-driven (3 for Translation/Scale, 4 for
|
|
1113
|
+
// Rotation); slots beyond what the property uses are
|
|
1114
|
+
// omitted. The keys align with the GPU track's
|
|
1115
|
+
// (x, y, z, w) vec4f output — see ShadeAnimationChannel.
|
|
1116
|
+
const axis_keys = ['x', 'y', 'z', 'w'];
|
|
1117
|
+
const curves = {};
|
|
1118
|
+
for (let comp = 0; comp < component_count; comp++) {
|
|
1119
|
+
const curve = new AnimationCurve();
|
|
1120
|
+
curve_from_track_data(curve, interpolation, values, times, component_count, comp);
|
|
1121
|
+
curves[axis_keys[comp]] = curve;
|
|
1122
|
+
}
|
|
1123
|
+
|
|
1124
|
+
channels.push(ShadeAnimationChannel.from({
|
|
1125
|
+
target: target_node,
|
|
1126
|
+
property,
|
|
1127
|
+
curves,
|
|
1128
|
+
}));
|
|
1129
|
+
}
|
|
1130
|
+
|
|
1131
|
+
if (channels.length === 0) {
|
|
1132
|
+
// All channels were unsupported / unresolved — skip
|
|
1133
|
+
// the clip entirely so we don't emit a zero-channel
|
|
1134
|
+
// record the manager would reject.
|
|
1135
|
+
continue;
|
|
1136
|
+
}
|
|
1137
|
+
|
|
1138
|
+
const clip = ShadeAnimationClip.from({
|
|
1139
|
+
name: gltf_animation.name ?? "",
|
|
1140
|
+
channels,
|
|
1141
|
+
});
|
|
1142
|
+
|
|
1143
|
+
// Default optimization pass: strip channels that
|
|
1144
|
+
// evaluate to the identity transform and individual
|
|
1145
|
+
// per-axis curves that are constant at identity, then
|
|
1146
|
+
// key-reduce the survivors. glTF exporters often emit
|
|
1147
|
+
// redundant bind-pose channels (every joint gets a
|
|
1148
|
+
// translation channel even when only rotation is
|
|
1149
|
+
// animated), so this typically trims a sizeable
|
|
1150
|
+
// fraction of the channel + curve count. Behaviour
|
|
1151
|
+
// unchanged — applying the optimised clip produces
|
|
1152
|
+
// the same poses.
|
|
1153
|
+
//
|
|
1154
|
+
// Stats are computed by diffing channel + total-curve
|
|
1155
|
+
// counts before and after; the methods don't carry
|
|
1156
|
+
// them in their return values.
|
|
1157
|
+
const before_channels = clip.channels.length;
|
|
1158
|
+
let before_curves = 0;
|
|
1159
|
+
for (let i = 0; i < clip.channels.length; i++) {
|
|
1160
|
+
before_curves += clip.channels[i].curve_count;
|
|
1161
|
+
}
|
|
1162
|
+
|
|
1163
|
+
clip.optimize();
|
|
1164
|
+
|
|
1165
|
+
const after_channels = clip.channels.length;
|
|
1166
|
+
let after_curves = 0;
|
|
1167
|
+
for (let i = 0; i < clip.channels.length; i++) {
|
|
1168
|
+
after_curves += clip.channels[i].curve_count;
|
|
1169
|
+
}
|
|
1170
|
+
|
|
1171
|
+
const removed_channels = before_channels - after_channels;
|
|
1172
|
+
const removed_curves = before_curves - after_curves;
|
|
1173
|
+
if (removed_channels > 0 || removed_curves > 0) {
|
|
1174
|
+
// console.log(
|
|
1175
|
+
// `[load_gltf] optimised clip '${clip.name}': ` +
|
|
1176
|
+
// `removed ${removed_channels} track(s), ` +
|
|
1177
|
+
// `${removed_curves} curve(s)`
|
|
1178
|
+
// );
|
|
1179
|
+
}
|
|
1180
|
+
|
|
1181
|
+
clips.push(clip);
|
|
1182
|
+
}
|
|
1183
|
+
|
|
1184
|
+
// console.profileEnd('parse-gltf');
|
|
1185
|
+
// console.timeEnd('parse-gltf');
|
|
1186
|
+
|
|
1187
|
+
const bundle = new SceneBundle();
|
|
1188
|
+
bundle.scenes = scene_nodes3d;
|
|
1189
|
+
bundle.skins = skins;
|
|
1190
|
+
bundle.clips = clips;
|
|
1191
|
+
return bundle;
|
|
1192
|
+
}
|
|
1193
|
+
|
|
1194
|
+
/**
|
|
1195
|
+
*
|
|
1196
|
+
* @param {Node3D[]} scenes
|
|
1197
|
+
*/
|
|
1198
|
+
function fix_scene_material_sidedness(scenes) {
|
|
1199
|
+
const meshes = new Set();
|
|
1200
|
+
|
|
1201
|
+
for (const s of scenes) {
|
|
1202
|
+
s.traverse(node => {
|
|
1203
|
+
if (node.isMesh) {
|
|
1204
|
+
meshes.add(node);
|
|
1205
|
+
}
|
|
1206
|
+
});
|
|
1207
|
+
}
|
|
1208
|
+
|
|
1209
|
+
const { geometries_modified: fixed_count, primitives_delta } = fix_up_material_sides(Array.from(meshes));
|
|
1210
|
+
|
|
1211
|
+
if (fixed_count > 0) {
|
|
1212
|
+
console.warn(`Fixed ${fixed_count} geometries in accordance with material sidedness. Primitives added: ${number_format_by_thousands(primitives_delta)}`);
|
|
1213
|
+
}
|
|
1214
|
+
|
|
1215
|
+
return scenes;
|
|
1216
|
+
}
|
|
1217
|
+
|
|
1218
|
+
|
|
1219
|
+
return load_gltf_document(url, { assetManager, scope, fileMap })
|
|
1220
|
+
.then(process)
|
|
1221
|
+
// .then(fix_scene_material_sidedness)
|
|
1222
|
+
// .then(prepare_lightmap)
|
|
1223
|
+
;
|
|
1224
|
+
}
|
|
1225
|
+
|
|
1226
|
+
/**
|
|
1227
|
+
* The same file, parsed and with its dependencies in memory, **without** being turned into anything
|
|
1228
|
+
* a renderer draws: the glTF's own JSON alongside `buffers` as `Uint8Array`s and `images` as
|
|
1229
|
+
* `ImageBitmap`s.
|
|
1230
|
+
*
|
|
1231
|
+
* The half of {@link load_gltf} that is not about pictures. A glTF carries more than a scene to draw
|
|
1232
|
+
* — collision hulls, navigation surfaces, spawn markers, whatever a tool reads accessors for — and
|
|
1233
|
+
* those consumers want the accessors and the bytes behind them, not a {@link SceneBundle} they would
|
|
1234
|
+
* have to take apart again.
|
|
1235
|
+
*
|
|
1236
|
+
* @param {string} url un-resolved — the asset manager resolves network paths
|
|
1237
|
+
* @param {Object} options
|
|
1238
|
+
* @param {AssetManager} options.assetManager
|
|
1239
|
+
* @param {AssetRequestScope} [options.scope]
|
|
1240
|
+
* @param {Map<string, File|Blob|ArrayBuffer>} [options.fileMap]
|
|
1241
|
+
* @returns {Promise<TinyGltf>}
|
|
1242
|
+
*/
|
|
1243
|
+
export function load_gltf_document(url, { assetManager, scope, fileMap } = {}) {
|
|
1244
|
+
const gltf = new TinyGltf(assetManager, scope);
|
|
1245
|
+
|
|
1246
|
+
if (fileMap) {
|
|
1247
|
+
gltf.fileMap = fileMap;
|
|
1248
|
+
}
|
|
1249
|
+
|
|
1250
|
+
return gltf.loadFromUrl(url);
|
|
1251
|
+
}
|
|
1252
|
+
|
|
1253
|
+
|