@woosh/meep-engine 3.11.3 → 3.12.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/README.md +14 -18
- package/editor/SelectionVisualizer.js +127 -127
- package/editor/entity_world_bounds.js +27 -27
- package/editor/particles/rebuildParticleEmitter.js +31 -31
- package/editor/process/SymbolicDisplayProcess.js +1 -1
- package/editor/process/symbolic/CameraSymbolicDisplay.js +146 -146
- package/editor/process/symbolic/LightSymbolicDisplay.js +172 -172
- 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/tools/v2/TransformControls.js +971 -971
- package/package.json +1 -1
- package/src/engine/Engine.d.ts +3 -3
- package/src/engine/Engine.d.ts.map +1 -1
- package/src/engine/Engine.js +726 -726
- package/src/engine/EngineHarness.d.ts +1 -1
- package/src/engine/EngineHarness.js +590 -590
- package/src/engine/ecs/HIERARCHY_REVIEW.md +717 -717
- package/src/engine/ecs/terrain/ecs/BuildLightTexture.d.ts +1 -1
- package/src/engine/ecs/terrain/ecs/BuildLightTexture.js +27 -27
- package/src/engine/ecs/terrain/ecs/Terrain.d.ts +1 -5
- 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/util/loadVisibleTerrainTiles.js +129 -129
- package/src/engine/graphics/ecs/camera/camera_find_active.d.ts +1 -1
- package/src/engine/graphics/ecs/camera/camera_find_active.js +28 -28
- package/src/engine/graphics/ecs/mesh-v2/ShadedGeometry.d.ts +1 -1
- package/src/engine/graphics/ecs/mesh-v2/ShadedGeometry.js +428 -428
- package/src/engine/graphics/ecs/water/Water.d.ts +1 -1
- package/src/engine/graphics/ecs/water/Water.js +104 -104
- package/src/engine/graphics/particles/particular/engine/emitter/ParticleEmitter.d.ts +1 -1
- package/src/engine/graphics/particles/particular/engine/emitter/ParticleEmitter.js +1 -1
- package/src/engine/graphics3/AnimationGraphSystem.d.ts +65 -0
- package/src/engine/graphics3/AnimationGraphSystem.d.ts.map +1 -0
- package/src/engine/graphics3/AnimationGraphSystem.js +329 -0
- package/src/engine/graphics3/AnimationGraphSystem3.d.ts +6 -61
- package/src/engine/graphics3/AnimationGraphSystem3.d.ts.map +1 -1
- package/src/engine/graphics3/AnimationGraphSystem3.js +6 -325
- package/src/engine/graphics3/AnimationSystem.d.ts +76 -0
- package/src/engine/graphics3/AnimationSystem.d.ts.map +1 -0
- package/src/engine/graphics3/AnimationSystem.js +352 -0
- package/src/engine/graphics3/AnimationSystem3.d.ts +6 -72
- package/src/engine/graphics3/AnimationSystem3.d.ts.map +1 -1
- package/src/engine/graphics3/AnimationSystem3.js +6 -348
- package/src/engine/graphics3/CameraSystem.d.ts +49 -0
- package/src/engine/graphics3/CameraSystem.d.ts.map +1 -0
- package/src/engine/graphics3/CameraSystem.js +170 -0
- package/src/engine/graphics3/CameraSystem3.d.ts +6 -45
- package/src/engine/graphics3/CameraSystem3.d.ts.map +1 -1
- package/src/engine/graphics3/CameraSystem3.js +6 -166
- package/src/engine/graphics3/DebugDrawSystem.d.ts +72 -0
- package/src/engine/graphics3/DebugDrawSystem.d.ts.map +1 -0
- package/src/engine/graphics3/DebugDrawSystem.js +205 -0
- package/src/engine/graphics3/DebugDrawSystem3.d.ts +6 -68
- package/src/engine/graphics3/DebugDrawSystem3.d.ts.map +1 -1
- package/src/engine/graphics3/DebugDrawSystem3.js +6 -201
- package/src/engine/graphics3/DecalSystem.d.ts +81 -0
- package/src/engine/graphics3/DecalSystem.d.ts.map +1 -0
- package/src/engine/graphics3/DecalSystem.js +441 -0
- package/src/engine/graphics3/DecalSystem3.d.ts +6 -77
- package/src/engine/graphics3/DecalSystem3.d.ts.map +1 -1
- package/src/engine/graphics3/DecalSystem3.js +6 -437
- package/src/engine/graphics3/FogOfWarSystem.d.ts +74 -0
- package/src/engine/graphics3/FogOfWarSystem.d.ts.map +1 -0
- package/src/engine/graphics3/FogOfWarSystem.js +265 -0
- package/src/engine/graphics3/FogOfWarSystem3.d.ts +6 -70
- package/src/engine/graphics3/FogOfWarSystem3.d.ts.map +1 -1
- package/src/engine/graphics3/FogOfWarSystem3.js +6 -261
- package/src/engine/graphics3/GraphicsEngine.d.ts +340 -0
- package/src/engine/graphics3/GraphicsEngine.d.ts.map +1 -0
- package/src/engine/graphics3/GraphicsEngine.js +790 -0
- package/src/engine/graphics3/GraphicsEngine3.d.ts +6 -336
- package/src/engine/graphics3/GraphicsEngine3.d.ts.map +1 -1
- package/src/engine/graphics3/GraphicsEngine3.js +6 -786
- package/src/engine/graphics3/HighlightSystem.d.ts +82 -0
- package/src/engine/graphics3/HighlightSystem.d.ts.map +1 -0
- package/src/engine/graphics3/HighlightSystem.js +241 -0
- package/src/engine/graphics3/HighlightSystem3.d.ts +6 -78
- package/src/engine/graphics3/HighlightSystem3.d.ts.map +1 -1
- package/src/engine/graphics3/HighlightSystem3.js +6 -237
- package/src/engine/graphics3/LightSystem.d.ts +40 -0
- package/src/engine/graphics3/LightSystem.d.ts.map +1 -0
- package/src/engine/graphics3/LightSystem.js +211 -0
- package/src/engine/graphics3/LightSystem3.d.ts +6 -36
- package/src/engine/graphics3/LightSystem3.d.ts.map +1 -1
- package/src/engine/graphics3/LightSystem3.js +6 -207
- package/src/engine/graphics3/MeshSystem.d.ts +106 -0
- package/src/engine/graphics3/MeshSystem.d.ts.map +1 -0
- package/src/engine/graphics3/MeshSystem.js +647 -0
- package/src/engine/graphics3/MeshSystem3.d.ts +6 -102
- package/src/engine/graphics3/MeshSystem3.d.ts.map +1 -1
- package/src/engine/graphics3/MeshSystem3.js +6 -642
- package/src/engine/graphics3/ParticipatingMedia.d.ts +2 -2
- package/src/engine/graphics3/ParticipatingMedia.js +203 -203
- package/src/engine/graphics3/ParticipatingMediaSystem.d.ts +87 -0
- package/src/engine/graphics3/ParticipatingMediaSystem.d.ts.map +1 -0
- package/src/engine/graphics3/ParticipatingMediaSystem.js +184 -0
- package/src/engine/graphics3/ParticipatingMediaSystem3.d.ts +6 -83
- package/src/engine/graphics3/ParticipatingMediaSystem3.d.ts.map +1 -1
- package/src/engine/graphics3/ParticipatingMediaSystem3.js +6 -180
- package/src/engine/graphics3/ParticleEmitterSystem.d.ts +76 -0
- package/src/engine/graphics3/ParticleEmitterSystem.d.ts.map +1 -0
- package/src/engine/graphics3/ParticleEmitterSystem.js +289 -0
- package/src/engine/graphics3/ParticleEmitterSystem3.d.ts +6 -72
- package/src/engine/graphics3/ParticleEmitterSystem3.d.ts.map +1 -1
- package/src/engine/graphics3/ParticleEmitterSystem3.js +6 -285
- package/src/engine/graphics3/PathDisplaySystem.d.ts +70 -0
- package/src/engine/graphics3/PathDisplaySystem.d.ts.map +1 -0
- package/src/engine/graphics3/PathDisplaySystem.js +309 -0
- package/src/engine/graphics3/PathDisplaySystem3.d.ts +6 -66
- package/src/engine/graphics3/PathDisplaySystem3.d.ts.map +1 -1
- package/src/engine/graphics3/PathDisplaySystem3.js +6 -305
- package/src/engine/graphics3/Pickable.d.ts +1 -1
- package/src/engine/graphics3/Pickable.js +65 -65
- package/src/engine/graphics3/PickingQuery.d.ts +1 -1
- package/src/engine/graphics3/PickingQuery.js +48 -48
- package/src/engine/graphics3/PickingSystem.d.ts +67 -0
- package/src/engine/graphics3/PickingSystem.d.ts.map +1 -0
- package/src/engine/graphics3/PickingSystem.js +273 -0
- package/src/engine/graphics3/PickingSystem3.d.ts +6 -63
- package/src/engine/graphics3/PickingSystem3.d.ts.map +1 -1
- package/src/engine/graphics3/PickingSystem3.js +6 -269
- package/src/engine/graphics3/ShadedGeometrySystem.d.ts +47 -0
- package/src/engine/graphics3/ShadedGeometrySystem.d.ts.map +1 -0
- package/src/engine/graphics3/ShadedGeometrySystem.js +169 -0
- package/src/engine/graphics3/ShadedGeometrySystem3.d.ts +6 -43
- package/src/engine/graphics3/ShadedGeometrySystem3.d.ts.map +1 -1
- package/src/engine/graphics3/ShadedGeometrySystem3.js +6 -165
- package/src/engine/graphics3/TerrainSystem.d.ts +80 -0
- package/src/engine/graphics3/TerrainSystem.d.ts.map +1 -0
- package/src/engine/graphics3/TerrainSystem.js +566 -0
- package/src/engine/graphics3/TerrainSystem3.d.ts +6 -76
- package/src/engine/graphics3/TerrainSystem3.d.ts.map +1 -1
- package/src/engine/graphics3/TerrainSystem3.js +6 -562
- package/src/engine/graphics3/TooltipComponentSystem.d.ts +65 -0
- package/src/engine/graphics3/TooltipComponentSystem.d.ts.map +1 -0
- package/src/engine/graphics3/TooltipComponentSystem.js +328 -0
- package/src/engine/graphics3/TooltipComponentSystem3.d.ts +6 -61
- package/src/engine/graphics3/TooltipComponentSystem3.d.ts.map +1 -1
- package/src/engine/graphics3/TooltipComponentSystem3.js +6 -324
- package/src/engine/graphics3/Trail3DSystem.d.ts +73 -0
- package/src/engine/graphics3/Trail3DSystem.d.ts.map +1 -0
- package/src/engine/graphics3/Trail3DSystem.js +221 -0
- package/src/engine/graphics3/Trail3DSystem3.d.ts +6 -69
- package/src/engine/graphics3/Trail3DSystem3.d.ts.map +1 -1
- package/src/engine/graphics3/Trail3DSystem3.js +6 -217
- package/src/engine/graphics3/VolumetricLightMap.d.ts +2 -2
- package/src/engine/graphics3/VolumetricLightMap.js +2 -2
- package/src/engine/graphics3/VolumetricLightMapSystem.d.ts +98 -0
- package/src/engine/graphics3/VolumetricLightMapSystem.d.ts.map +1 -0
- package/src/engine/graphics3/VolumetricLightMapSystem.js +261 -0
- package/src/engine/graphics3/VolumetricLightMapSystem3.d.ts +6 -94
- package/src/engine/graphics3/VolumetricLightMapSystem3.d.ts.map +1 -1
- package/src/engine/graphics3/VolumetricLightMapSystem3.js +10 -261
- package/src/engine/graphics3/WaterSystem.d.ts +59 -0
- package/src/engine/graphics3/WaterSystem.d.ts.map +1 -0
- package/src/engine/graphics3/WaterSystem.js +293 -0
- package/src/engine/graphics3/WaterSystem3.d.ts +6 -55
- package/src/engine/graphics3/WaterSystem3.d.ts.map +1 -1
- package/src/engine/graphics3/WaterSystem3.js +6 -289
- package/src/engine/graphics3/animation/AnimationGraphController.d.ts +1 -1
- package/src/engine/graphics3/animation/AnimationGraphController.js +518 -518
- package/src/engine/graphics3/animation/ClipListPlayer.d.ts +1 -1
- package/src/engine/graphics3/animation/ClipListPlayer.js +263 -263
- package/src/engine/graphics3/animation/ClipPlayback.d.ts +2 -2
- package/src/engine/graphics3/animation/ClipPlayback.js +84 -84
- package/src/engine/graphics3/decal/graph_build_decal_clusters.d.ts.map +1 -1
- package/src/engine/graphics3/decal/graph_build_decal_clusters.js +6 -8
- package/src/engine/graphics3/decal/shader_cluster_assign_decals.d.ts +0 -7
- package/src/engine/graphics3/decal/shader_cluster_assign_decals.d.ts.map +1 -1
- package/src/engine/graphics3/decal/shader_cluster_assign_decals.js +1 -1
- package/src/engine/graphics3/decal/shader_cull_decals_frustum.d.ts +0 -4
- package/src/engine/graphics3/decal/shader_cull_decals_frustum.d.ts.map +1 -1
- package/src/engine/graphics3/decal/shader_cull_decals_frustum.js +1 -1
- package/src/engine/graphics3/highlight/pack_highlight_table.d.ts +2 -2
- package/src/engine/graphics3/highlight/pack_highlight_table.d.ts.map +1 -1
- package/src/engine/graphics3/highlight/pack_highlight_table.js +74 -74
- package/src/engine/graphics3/pose/query_entity_node_world_pose.d.ts +1 -1
- package/src/engine/graphics3/pose/query_entity_node_world_pose.js +101 -101
- package/src/engine/graphics3/preview/make_model_thumbnail.d.ts +3 -3
- package/src/engine/graphics3/preview/make_model_thumbnail.d.ts.map +1 -1
- package/src/engine/graphics3/preview/make_model_thumbnail.js +48 -48
- package/src/engine/graphics3/shade_camera_projection_ray.d.ts +1 -1
- package/src/engine/graphics3/shade_camera_projection_ray.js +77 -77
- package/src/engine/graphics3/shade_node_to_entity_composition.d.ts +1 -1
- package/src/engine/graphics3/shade_node_to_entity_composition.js +84 -84
- package/src/shade/playground/skinned_blas_refit/shader_blas_audit_leaf_triangles.d.ts.map +1 -1
- package/src/shade/playground/skinned_blas_refit/shader_blas_audit_leaf_triangles.js +0 -1
- package/src/shade/playground/skinned_blas_refit/shader_blas_audit_points.d.ts.map +1 -1
- package/src/shade/playground/skinned_blas_refit/shader_blas_audit_points.js +0 -1
- package/src/shade/playground/skinned_blas_refit/shader_blas_audit_visibility.d.ts.map +1 -1
- package/src/shade/playground/skinned_blas_refit/shader_blas_audit_visibility.js +133 -134
- package/src/shade/playground/skinned_blas_refit/verify_leaf_triangles.js +202 -202
- package/src/shade/playground/skinned_blas_refit/verify_traversal_reachability.js +249 -249
- package/src/shade/renderer/STATIC_GRAPHICS_ENGINE_ASSETS.js +1 -1
- package/src/shade/renderer/animation/pose/PosePlayback.d.ts +2 -1
- package/src/shade/renderer/animation/pose/PosePlayback.d.ts.map +1 -1
- package/src/shade/renderer/animation/pose/PosePlayback.js +2 -1
- package/src/shade/renderer/animation/shader_animation_apply.d.ts.map +1 -1
- package/src/shade/renderer/animation/shader_animation_apply.js +128 -129
- package/src/shade/renderer/animation/shader_animation_pose_resolve.d.ts.map +1 -1
- package/src/shade/renderer/animation/shader_animation_pose_resolve.js +176 -177
- package/src/shade/renderer/animation/shader_animation_tick.d.ts.map +1 -1
- package/src/shade/renderer/animation/shader_animation_tick.js +125 -126
- package/src/shade/renderer/animation/skinning/bounds_refresh/shader_geometry_sphere_derive.d.ts.map +1 -1
- package/src/shade/renderer/animation/skinning/bounds_refresh/shader_geometry_sphere_derive.js +98 -99
- package/src/shade/renderer/animation/skinning/bounds_refresh/shader_meshlet_bounds_reduce.d.ts.map +1 -1
- package/src/shade/renderer/animation/skinning/bounds_refresh/shader_meshlet_bounds_reduce.js +212 -213
- package/src/shade/renderer/animation/skinning/bounds_refresh/shader_meshlet_bounds_scatter.d.ts.map +1 -1
- package/src/shade/renderer/animation/skinning/bounds_refresh/shader_meshlet_bounds_scatter.js +120 -121
- package/src/shade/renderer/animation/skinning/bounds_refresh/shader_skinned_mesh_bounds_refresh.d.ts.map +1 -1
- package/src/shade/renderer/animation/skinning/bounds_refresh/shader_skinned_mesh_bounds_refresh.js +75 -76
- package/src/shade/renderer/animation/skinning/shader_meshlet_apply_skinning.d.ts.map +1 -1
- package/src/shade/renderer/animation/skinning/shader_meshlet_apply_skinning.js +371 -372
- package/src/shade/renderer/animation/skinning/shader_skin_matrix_prep.d.ts.map +1 -1
- package/src/shade/renderer/animation/skinning/shader_skin_matrix_prep.js +104 -105
- package/src/shade/renderer/atmosphere/shader_multiscatter_lut.d.ts.map +1 -1
- package/src/shade/renderer/atmosphere/shader_multiscatter_lut.js +0 -1
- package/src/shade/renderer/buffer/graph_inspect_gpu_buffer.js +136 -136
- package/src/shade/renderer/buffer/table/GPUDatabase.d.ts.map +1 -1
- package/src/shade/renderer/buffer/table/GPUDatabase.js +2 -3
- package/src/shade/renderer/buffer/table/single/GPUSingleTypeTable.js +319 -319
- package/src/shade/renderer/buffer/util/shader_buffer_copy_storage_to_storage.d.ts.map +1 -1
- package/src/shade/renderer/buffer/util/shader_buffer_copy_storage_to_storage.js +41 -42
- package/src/shade/renderer/buffer/util/shader_buffer_intra_copy_regions.d.ts.map +1 -1
- package/src/shade/renderer/buffer/util/shader_buffer_intra_copy_regions.js +83 -84
- package/src/shade/renderer/dynamic/shader_dynamic_mesh.d.ts.map +1 -1
- package/src/shade/renderer/dynamic/shader_dynamic_mesh.js +177 -170
- package/src/shade/renderer/extension/RENDER_EXTENSION_DESIGN.md +918 -918
- package/src/shade/renderer/geometry/bvh/record_blas_refit.js +4 -4
- package/src/shade/renderer/geometry/bvh/shader_blas_refit_leaf_bounds.d.ts.map +1 -1
- package/src/shade/renderer/geometry/bvh/shader_blas_refit_leaf_bounds.js +121 -122
- package/src/shade/renderer/geometry/meshlet/GPUMeshletManager.js +774 -774
- package/src/shade/renderer/geometry/meshlet/shader_meshlet_metadata_address_patch.d.ts +1 -1
- package/src/shade/renderer/geometry/meshlet/shader_meshlet_metadata_address_patch.d.ts.map +1 -1
- package/src/shade/renderer/geometry/meshlet/shader_meshlet_metadata_address_patch.js +69 -70
- package/src/shade/renderer/global_illumination/lpv/placement/graph_generate_probe_locations.js +367 -367
- package/src/shade/renderer/global_illumination/probe/octahedral/convolve/graph_lvp_atlas_to_sh.js +184 -184
- package/src/shade/renderer/gpu_primitive/bvh/GPU_BVH_BUILD_PLAN.md +1115 -1115
- package/src/shade/renderer/gpu_primitive/bvh/graph_bvh_build_lbvh.js +217 -217
- package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_emit_hierarchy.d.ts.map +1 -1
- package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_emit_hierarchy.js +142 -143
- package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_morton.d.ts.map +1 -1
- package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_morton.js +0 -1
- package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_refit.d.ts.map +1 -1
- package/src/shade/renderer/gpu_primitive/bvh/shader_bvh_refit.js +140 -141
- package/src/shade/renderer/gpu_primitive/sort/shader_radix_sort_histogram.d.ts.map +1 -1
- package/src/shade/renderer/gpu_primitive/sort/shader_radix_sort_histogram.js +0 -1
- package/src/shade/renderer/gpu_primitive/sort/shader_radix_sort_scatter.d.ts.map +1 -1
- package/src/shade/renderer/gpu_primitive/sort/shader_radix_sort_scatter.js +0 -1
- package/src/shade/renderer/light/cluster/cull/graph_cull_lights.d.ts.map +1 -1
- package/src/shade/renderer/light/cluster/cull/graph_cull_lights.js +191 -198
- package/src/shade/renderer/light/cluster/cull/shader_cull_lights_frustum.d.ts +0 -6
- package/src/shade/renderer/light/cluster/cull/shader_cull_lights_frustum.d.ts.map +1 -1
- package/src/shade/renderer/light/cluster/cull/shader_cull_lights_frustum.js +120 -120
- package/src/shade/renderer/light/cluster/cull/shader_cull_lights_hzb.d.ts +0 -4
- package/src/shade/renderer/light/cluster/cull/shader_cull_lights_hzb.d.ts.map +1 -1
- package/src/shade/renderer/light/cluster/cull/shader_cull_lights_hzb.js +112 -112
- package/src/shade/renderer/light/cluster/graph_assign_clsuters.d.ts.map +1 -1
- package/src/shade/renderer/light/cluster/graph_assign_clsuters.js +4 -7
- package/src/shade/renderer/light/cluster/shader_cluster_assign_lights.d.ts +0 -6
- package/src/shade/renderer/light/cluster/shader_cluster_assign_lights.d.ts.map +1 -1
- package/src/shade/renderer/light/cluster/shader_cluster_assign_lights.js +1 -1
- package/src/shade/renderer/lightmap/bake/raster/shader_lightmap_to_viz_buffer.js +222 -222
- package/src/shade/renderer/lightmap/bake/tile/shader_lightmap_tile_composit.js +81 -81
- package/src/shade/renderer/material/GPUMaterialContext.js +380 -380
- package/src/shade/renderer/material/standard/fragment_gbuffer_vt.js +169 -169
- package/src/shade/renderer/object_property/shader_object_property_process.d.ts.map +1 -1
- package/src/shade/renderer/object_property/shader_object_property_process.js +83 -84
- package/src/shade/renderer/object_property/shader_refresh_all_mesh_bounds.d.ts.map +1 -1
- package/src/shade/renderer/object_property/shader_refresh_all_mesh_bounds.js +57 -58
- package/src/shade/renderer/particles/prototypeParticleSystem.js +2 -3
- package/src/shade/renderer/particles/shaders/shader_particle_emit.d.ts.map +1 -1
- package/src/shade/renderer/particles/shaders/shader_particle_emit.js +117 -118
- package/src/shade/renderer/particles/shaders/shader_particle_finalize.d.ts.map +1 -1
- package/src/shade/renderer/particles/shaders/shader_particle_finalize.js +77 -79
- package/src/shade/renderer/particles/shaders/shader_particle_render.d.ts.map +1 -1
- package/src/shade/renderer/particles/shaders/shader_particle_render.js +190 -183
- package/src/shade/renderer/particles/shaders/shader_particle_simulate.d.ts.map +1 -1
- package/src/shade/renderer/particles/shaders/shader_particle_simulate.js +99 -100
- package/src/shade/renderer/particles/sort/shader_particle_sort.d.ts.map +1 -1
- package/src/shade/renderer/particles/sort/shader_particle_sort.js +158 -161
- package/src/shade/renderer/path_tracer/graph_path_trace_scene.js +184 -184
- package/src/shade/renderer/postprocess/denoise/graph_atorus_denoise_luma.js +119 -119
- package/src/shade/renderer/postprocess/dof/raymarch/graph_postprocess_dof.js +3 -4
- package/src/shade/renderer/postprocess/dof/raymarch/shader_dof_raymarch_compute.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/dof/raymarch/shader_dof_raymarch_compute.js +266 -267
- package/src/shade/renderer/postprocess/dof/raymarch/shader_dof_slice_compute.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/dof/raymarch/shader_dof_slice_compute.js +270 -271
- package/src/shade/renderer/postprocess/nss/shader_nss_concat.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/nss/shader_nss_concat.js +68 -69
- package/src/shade/renderer/postprocess/nss/shader_nss_conv_layer.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/nss/shader_nss_conv_layer.js +225 -226
- package/src/shade/renderer/postprocess/nss/shader_nss_extract_feedback.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/nss/shader_nss_extract_feedback.js +49 -50
- package/src/shade/renderer/postprocess/nss/shader_nss_postprocess.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/nss/shader_nss_postprocess.js +291 -292
- package/src/shade/renderer/postprocess/nss/shader_nss_preprocess.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/nss/shader_nss_preprocess.js +230 -231
- package/src/shade/renderer/postprocess/ssr/reproject/shader_ffx_denoiser_reflections_reproject.d.ts +16 -2
- package/src/shade/renderer/postprocess/ssr/reproject/shader_ffx_denoiser_reflections_reproject.d.ts.map +1 -1
- package/src/shade/renderer/postprocess/ssr/reproject/shader_ffx_denoiser_reflections_reproject.js +12 -12
- package/src/shade/renderer/rasterize/bucket/prepare_meshlet_draw_commands_by_material.js +2 -2
- package/src/shade/renderer/rasterize/bucket/shader_count_meshlets_by_material.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/bucket/shader_count_meshlets_by_material.js +68 -69
- package/src/shade/renderer/rasterize/bucket/shader_make_meshlet_indirect_draw_commands_by_material.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/bucket/shader_make_meshlet_indirect_draw_commands_by_material.js +59 -60
- package/src/shade/renderer/rasterize/bucket/shader_read_out_bucket.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/bucket/shader_read_out_bucket.js +0 -1
- package/src/shade/renderer/rasterize/bucket/shader_sort_meshlets_by_material.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/bucket/shader_sort_meshlets_by_material.js +64 -65
- package/src/shade/renderer/rasterize/compute/graph_mesh_frustum_cull.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/compute/graph_mesh_frustum_cull.js +168 -169
- package/src/shade/renderer/rasterize/compute/graph_mesh_sphere_cull.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/compute/graph_mesh_sphere_cull.js +160 -161
- package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_mesh_filter_2way.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_mesh_filter_2way.js +109 -110
- package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_meshlet_filter_1way_full.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/cull/hzb/shader_hzb_meshlet_filter_1way_full.js +115 -116
- package/src/shade/renderer/rasterize/expand/bucket/mesh/shader_instances_classify_bucket.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/expand/bucket/mesh/shader_instances_classify_bucket.js +139 -140
- package/src/shade/renderer/rasterize/expand/bucket/mesh/shader_instances_count_by_rasterization_bucket.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/expand/bucket/mesh/shader_instances_count_by_rasterization_bucket.js +91 -92
- package/src/shade/renderer/rasterize/expand/bucket/mesh/shader_instances_rasterization_bucket_sort.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/expand/bucket/mesh/shader_instances_rasterization_bucket_sort.js +88 -89
- package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_count_by_rasterization_bucket.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_count_by_rasterization_bucket.js +90 -91
- package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_extract_bucket.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_extract_bucket.js +65 -66
- package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_rasterization_bucket_sort.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/expand/bucket/meshlet/shader_meshlets_rasterization_bucket_sort.js +89 -90
- package/src/shade/renderer/rasterize/expand/graph_mesh_filter_one_way.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/expand/graph_mesh_filter_one_way.js +169 -170
- package/src/shade/renderer/rasterize/expand/mesh/shader_mesh_expand_to_meshlets_prefix.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/expand/mesh/shader_mesh_expand_to_meshlets_prefix.js +89 -90
- package/src/shade/renderer/rasterize/expand/mesh/shader_meshes_to_meshlet_counts.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/expand/mesh/shader_meshes_to_meshlet_counts.js +61 -62
- package/src/shade/renderer/rasterize/expand/pass1/filter_meshlets.2-way.compute.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/expand/pass1/filter_meshlets.2-way.compute.js +153 -154
- package/src/shade/renderer/rasterize/native/depth/shadow_rasterization_alpha_tested_pass_descriptor.js +144 -144
- package/src/shade/renderer/rasterize/native/depth/shadow_rasterization_pass_descriptor.js +88 -88
- package/src/shade/renderer/rasterize/native/oit/shader_oit_generate_moments.js +217 -217
- package/src/shade/renderer/rasterize/native/oit/shader_oit_resolve_moments.js +179 -179
- package/src/shade/renderer/rasterize/native/oit/shader_oit_resolve_moments_ibl.js +178 -178
- package/src/shade/renderer/rasterize/native/viz/viz_rasterization_alpha_tested_pass_descriptor.js +194 -194
- package/src/shade/renderer/rasterize/native/viz/viz_rasterization_opaque_pass_descriptor.js +76 -76
- package/src/shade/renderer/restir/di/shader_restir_di_denoise.d.ts.map +1 -1
- package/src/shade/renderer/restir/di/shader_restir_di_denoise.js +136 -137
- package/src/shade/renderer/restir/di/shader_restir_di_resample.d.ts.map +1 -1
- package/src/shade/renderer/restir/di/shader_restir_di_resample.js +129 -130
- package/src/shade/renderer/restir/di/shader_restir_di_resolve.d.ts.map +1 -1
- package/src/shade/renderer/restir/di/shader_restir_di_resolve.js +99 -100
- package/src/shade/renderer/restir/di/shader_restir_di_spatial.d.ts.map +1 -1
- package/src/shade/renderer/restir/di/shader_restir_di_spatial.js +116 -117
- package/src/shade/renderer/scene/GPUInstancesAccelerationStructure.js +383 -383
- package/src/shade/renderer/scene/hierarchy/graph_scene_update_transform_hierarchy_naive.js +123 -123
- package/src/shade/renderer/scene/hierarchy/shader_nodes_record_input_positions.d.ts.map +1 -1
- package/src/shade/renderer/scene/hierarchy/shader_nodes_record_input_positions.js +64 -65
- package/src/shade/renderer/scene/hierarchy/shader_nodes_update_transform_hierarchy.d.ts.map +1 -1
- package/src/shade/renderer/scene/hierarchy/shader_nodes_update_transform_hierarchy.js +372 -373
- package/src/shade/renderer/scene/hierarchy/shader_nodes_update_transform_hierarchy_naive.d.ts.map +1 -1
- package/src/shade/renderer/scene/hierarchy/shader_nodes_update_transform_hierarchy_naive.js +111 -112
- package/src/shade/renderer/scene/shader_bvh_extract_instance_leaves.d.ts.map +1 -1
- package/src/shade/renderer/scene/shader_bvh_extract_instance_leaves.js +0 -1
- package/src/shade/renderer/shader/ComputeShader.d.ts +24 -3
- package/src/shade/renderer/shader/ComputeShader.d.ts.map +1 -1
- package/src/shade/renderer/shader/ComputeShader.js +350 -296
- package/src/shade/renderer/shader/ImageShader.js +217 -217
- package/src/shade/renderer/shader/ShaderDescriptor.d.ts +5 -0
- package/src/shade/renderer/shader/ShaderDescriptor.d.ts.map +1 -1
- package/src/shade/renderer/shader/ShaderDescriptor.js +20 -0
- package/src/shade/renderer/shader/util/compute_infer_workgroup_size_from_source.d.ts +47 -0
- package/src/shade/renderer/shader/util/compute_infer_workgroup_size_from_source.d.ts.map +1 -0
- package/src/shade/renderer/shader/util/compute_infer_workgroup_size_from_source.js +448 -0
- package/src/shade/renderer/shadow/map/csm/graph_csm_setup_cascades.js +3 -3
- package/src/shade/renderer/shadow/ray/staged/gen/graph_gen_rays.js +3 -3
- package/src/shade/renderer/shadow/ray/staged/trace/graph_trace_rays.js +2 -2
- package/src/shade/renderer/shadow/sdf/cascade/CascadedSceneSDF.js +4 -4
- package/src/shade/renderer/texture/virtual/build_shader_vt_feedback.d.ts.map +1 -1
- package/src/shade/renderer/texture/virtual/build_shader_vt_feedback.js +231 -232
- package/src/shade/renderer/volumetrics/GPUViewVolumetrics.js +1 -1
- package/src/shade/renderer/volumetrics/graph_build_volumetrics.d.ts.map +1 -1
- package/src/shade/renderer/volumetrics/graph_build_volumetrics.js +12 -15
- package/src/shade/renderer/volumetrics/shader_volumetrics_build_lighting.d.ts +3 -2
- package/src/shade/renderer/volumetrics/shader_volumetrics_build_lighting.d.ts.map +1 -1
- package/src/shade/renderer/volumetrics/shader_volumetrics_build_lighting.js +3 -2
- package/src/shade/renderer/volumetrics/taa/shader_volumetrics_taa.d.ts +0 -2
- package/src/shade/renderer/volumetrics/taa/shader_volumetrics_taa.d.ts.map +1 -1
- package/src/shade/renderer/volumetrics/taa/shader_volumetrics_taa.js +17 -6
- package/src/shade/renderer/water/shader_water.js +246 -246
- package/src/shade/vitest.setup.mjs +1 -1
- package/src/shade/wgsl/emulator/ComputeShaderEmulator.js +291 -291
- package/src/view/minimap/Minimap.d.ts +2 -2
- package/src/view/minimap/Minimap.d.ts.map +1 -1
- package/src/view/minimap/Minimap.js +225 -225
- package/src/view/minimap/dom/MinimapCameraView.d.ts +3 -3
- package/src/view/minimap/dom/MinimapCameraView.d.ts.map +1 -1
- package/src/view/minimap/dom/MinimapCameraView.js +206 -206
- package/src/shade/renderer/shadow/map/csm/shader/shader_setup_cascades.d.ts +0 -3
- package/src/shade/renderer/shadow/map/csm/shader/shader_setup_cascades.d.ts.map +0 -1
- package/src/shade/renderer/shadow/map/csm/shader/shader_setup_cascades.js +0 -20
|
@@ -0,0 +1,647 @@
|
|
|
1
|
+
import { assert } from "../../core/assert.js";
|
|
2
|
+
import { aabb3_array_combine } from "../../core/geom/3d/aabb/aabb3_array_combine.js";
|
|
3
|
+
import { SignalBinding } from "../../core/events/signal/SignalBinding.js";
|
|
4
|
+
import { Scene } from "../../shade/renderer/scene/Scene.js";
|
|
5
|
+
import { instantiate_scene_bundle } from "./instantiate_scene_bundle.js";
|
|
6
|
+
import {
|
|
7
|
+
register_instance_animation,
|
|
8
|
+
unregister_instance_animation
|
|
9
|
+
} from "./register_instance_animation.js";
|
|
10
|
+
import { System } from "../ecs/System.js";
|
|
11
|
+
import { Transform } from "../ecs/transform/Transform.js";
|
|
12
|
+
import { t64_copy_from_transform } from "../ecs/transform/t64_copy_from_transform.js";
|
|
13
|
+
import { ParentEntity } from "../ecs/parent/ParentEntity.js";
|
|
14
|
+
import { ShadedGeometry } from "../graphics/ecs/mesh-v2/ShadedGeometry.js";
|
|
15
|
+
import { SGMesh } from "../graphics/ecs/mesh-v2/aggregate/SGMesh.js";
|
|
16
|
+
import { shade_bundle_to_entity_composition } from "./shade_node_to_entity_composition.js";
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Puts entities into Shade's scene and keeps them where the ECS says they are.
|
|
20
|
+
*
|
|
21
|
+
* **It owns the scene and tells the facade to draw it**, rather than the facade handing a graph out
|
|
22
|
+
* for anyone to write into — that coupling is what §2.1 retires along with `GraphicsEngine.scene`.
|
|
23
|
+
*
|
|
24
|
+
* Placement is a `Transform` copied into `Node3D.transform_local`, through
|
|
25
|
+
* {@link t64_copy_from_transform} because the node's transform is a `Transform64` since S2 and the
|
|
26
|
+
* two types stay deliberately distinct. `transform_global` is **derived** — `updateMatrices`
|
|
27
|
+
* recomputes it from the local transform and the parent chain — so writing it directly would be
|
|
28
|
+
* undone by the next refresh, and the entity is placed through the local one.
|
|
29
|
+
*
|
|
30
|
+
* What makes this affordable is S1: the scene database takes row-level updates, so moving one
|
|
31
|
+
* entity writes one row. Nothing here rebuilds anything.
|
|
32
|
+
*
|
|
33
|
+
* **It also hands each instance to the GPU's animation manager** ({@link update}), because it is
|
|
34
|
+
* what builds instances and therefore the only thing that knows when one exists. Driving those
|
|
35
|
+
* clips is not its business — that is the animation systems' — but a clip nothing has registered
|
|
36
|
+
* cannot be driven by anyone.
|
|
37
|
+
*/
|
|
38
|
+
export class MeshSystem extends System {
|
|
39
|
+
/**
|
|
40
|
+
* @type {GraphicsEngine}
|
|
41
|
+
*/
|
|
42
|
+
#graphics;
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* The scene this system writes into and the facade draws.
|
|
46
|
+
*
|
|
47
|
+
* Received rather than created: lights come from a system of their own, and both have to be
|
|
48
|
+
* putting content into the same scene for either to be visible.
|
|
49
|
+
*
|
|
50
|
+
* @type {Scene}
|
|
51
|
+
*/
|
|
52
|
+
#scene;
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Loaded model bundles, by url. A level places the same model many times over, and loading it
|
|
56
|
+
* once per placement would be the dominant cost of opening one.
|
|
57
|
+
*
|
|
58
|
+
* @type {Map<string, Promise<SceneBundle>>}
|
|
59
|
+
*/
|
|
60
|
+
#bundles = new Map();
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* What each entity has in the scene, and the signal bindings keeping it in step.
|
|
64
|
+
*
|
|
65
|
+
* `instance` and `animation` are null until the model has loaded and until the GPU has been
|
|
66
|
+
* told about it respectively — two different waits, which is why they are two fields.
|
|
67
|
+
*
|
|
68
|
+
* @type {Map<number, {nodes: Node3D[], bindings: SignalBinding[], instance: SceneBundleInstance|null, animation: InstanceAnimationRegistration|null}>}
|
|
69
|
+
*/
|
|
70
|
+
#entries = new Map();
|
|
71
|
+
|
|
72
|
+
/**
|
|
73
|
+
* Shade's GPU state for {@link scene}, as of the last {@link update}.
|
|
74
|
+
*
|
|
75
|
+
* Held to answer one question: has the renderer been replaced since the last frame, so that
|
|
76
|
+
* everything placed has to be registered again. **Which manager a particular registration
|
|
77
|
+
* belongs to is the registration's own to say** — it carries the context that issued it — so
|
|
78
|
+
* this is not consulted when ids are handed back.
|
|
79
|
+
*
|
|
80
|
+
* @type {GPUSceneContext|null}
|
|
81
|
+
*/
|
|
82
|
+
#context = null;
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Entries whose instance is not registered with {@link #context} — either because it has just
|
|
86
|
+
* loaded, or because a restart invalidated what it had.
|
|
87
|
+
*
|
|
88
|
+
* A queue rather than a scan over every entity, because this is per-frame work in a level that
|
|
89
|
+
* places hundreds of models and the answer is almost always "nothing to do".
|
|
90
|
+
*
|
|
91
|
+
* @type {object[]}
|
|
92
|
+
*/
|
|
93
|
+
#unregistered = [];
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Entities whose `SGMesh` carried no url when it was linked.
|
|
97
|
+
*
|
|
98
|
+
* `SGMesh.url` is an accessor with no change signal behind it, and the game assigns it late as a
|
|
99
|
+
* matter of
|
|
100
|
+
* course: `GeneratedArmySystem` puts the component on an army entity and fills the url in from
|
|
101
|
+
* a promise, once the army it generated has picked the leader whose model the army wears. So a
|
|
102
|
+
* url that is missing at link time is the normal path to a model rather than an edge case, and
|
|
103
|
+
* the only way to notice one arriving is to look again.
|
|
104
|
+
*
|
|
105
|
+
* A list rather than a scan over every entity, and it is short: it holds only what has no model
|
|
106
|
+
* yet, and an entry leaves it for good the moment one is asked for.
|
|
107
|
+
*
|
|
108
|
+
* @type {{entity: number, model: SGMesh, transform: Transform}[]}
|
|
109
|
+
*/
|
|
110
|
+
#awaiting_url = [];
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* Loads a glTF into Shade's own representation. Injected rather than imported so that the
|
|
114
|
+
* system can be driven in a spec without a network or a device — the loader is the one genuine
|
|
115
|
+
* boundary here.
|
|
116
|
+
*
|
|
117
|
+
* @type {function(string): Promise<SceneBundle>}
|
|
118
|
+
*/
|
|
119
|
+
#load;
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* @param {GraphicsEngine} graphics
|
|
123
|
+
* @param {Scene} scene
|
|
124
|
+
* @param {function(string): Promise<SceneBundle>} load
|
|
125
|
+
*/
|
|
126
|
+
constructor(graphics, scene, load) {
|
|
127
|
+
super();
|
|
128
|
+
|
|
129
|
+
assert.defined(graphics, 'graphics');
|
|
130
|
+
assert.equal(scene.isScene, true, 'scene.isScene !== true');
|
|
131
|
+
assert.typeOf(load, 'function', 'load');
|
|
132
|
+
|
|
133
|
+
this.#graphics = graphics;
|
|
134
|
+
this.#scene = scene;
|
|
135
|
+
this.#load = load;
|
|
136
|
+
|
|
137
|
+
this.dependencies = [SGMesh, Transform];
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* @returns {Scene}
|
|
142
|
+
*/
|
|
143
|
+
get scene() {
|
|
144
|
+
return this.#scene;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* Visit every node of an entity's model that carries geometry.
|
|
149
|
+
*
|
|
150
|
+
* The nodes are what the scene database keys on, so anything that has to say something about a
|
|
151
|
+
* particular entity's meshes — which rows they occupy, which of them the visibility buffer will
|
|
152
|
+
* name — starts here. A grouping node is skipped, because it has no geometry and therefore no
|
|
153
|
+
* row of its own.
|
|
154
|
+
*
|
|
155
|
+
* @param {number} entity
|
|
156
|
+
* @param {function(SGMesh): void} visitor
|
|
157
|
+
* @returns {boolean} `false` when the entity has nothing in the scene — never seen, or still
|
|
158
|
+
* loading, and neither is an error
|
|
159
|
+
*/
|
|
160
|
+
traverse_meshes(entity, visitor) {
|
|
161
|
+
const entry = this.#entries.get(entity);
|
|
162
|
+
|
|
163
|
+
if (entry === undefined) {
|
|
164
|
+
return false;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
for (let i = 0; i < entry.nodes.length; i++) {
|
|
168
|
+
entry.nodes[i].traverse(node => {
|
|
169
|
+
if (node.isMesh === true) {
|
|
170
|
+
visitor(node);
|
|
171
|
+
}
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
this.#traverse_expanded(entry, visitor);
|
|
176
|
+
|
|
177
|
+
return true;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* The rows of a model that became entities.
|
|
182
|
+
*
|
|
183
|
+
* Its primitives are components on descendants rather than nodes this system holds, and each one
|
|
184
|
+
* carries the row `ShadedGeometrySystem` put it in — so the walk is over the composition and the
|
|
185
|
+
* answer is the same kind of node the instance path yields. A primitive whose system has not
|
|
186
|
+
* linked it yet has no row and contributes nothing, which is the same "still loading" silence
|
|
187
|
+
* every reader here already tolerates.
|
|
188
|
+
*
|
|
189
|
+
* @param {object} entry
|
|
190
|
+
* @param {function(Mesh): void} visitor
|
|
191
|
+
*/
|
|
192
|
+
#traverse_expanded(entry, visitor) {
|
|
193
|
+
const composition = entry.composition;
|
|
194
|
+
|
|
195
|
+
if (composition === null) {
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
composition.traverse(node => {
|
|
200
|
+
const geometry = node.entity.getComponent(ShadedGeometry);
|
|
201
|
+
|
|
202
|
+
if (geometry === null || geometry === undefined) {
|
|
203
|
+
return;
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
if (geometry.node === null) {
|
|
207
|
+
return;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
visitor(geometry.node);
|
|
211
|
+
});
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* The private copy of the model an entity is showing — its clips among other things, which is
|
|
216
|
+
* where their names and their durations come from.
|
|
217
|
+
*
|
|
218
|
+
* Handed out rather than copied because an animation driver has to know *which* instance it is
|
|
219
|
+
* bound to: a model swap builds a new one, and a driver still holding the old one would be
|
|
220
|
+
* driving nodes that left the scene. The object's identity is the only signal that says so.
|
|
221
|
+
*
|
|
222
|
+
* @param {number} entity
|
|
223
|
+
* @returns {SceneBundleInstance|null} `null` for an entity this system has never seen, or one
|
|
224
|
+
* whose model has not finished loading
|
|
225
|
+
*/
|
|
226
|
+
instance_of(entity) {
|
|
227
|
+
const entry = this.#entries.get(entity);
|
|
228
|
+
|
|
229
|
+
if (entry === undefined) {
|
|
230
|
+
return null;
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
return entry.instance;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/**
|
|
237
|
+
* What the GPU's animation manager gave back for that instance — the skin and clip ids, in the
|
|
238
|
+
* instance's own order.
|
|
239
|
+
*
|
|
240
|
+
* Same reasoning as {@link instance_of} and a stronger version of it: these ids belong to one
|
|
241
|
+
* renderer, and a restart voids every one of them. The object is replaced when that happens, so
|
|
242
|
+
* a driver that compares it against what it bound against notices in the same frame.
|
|
243
|
+
*
|
|
244
|
+
* @param {number} entity
|
|
245
|
+
* @returns {InstanceAnimationRegistration|null} `null` while there is nothing registered — no
|
|
246
|
+
* model yet, no device yet, or a renderer restart that has not been drained
|
|
247
|
+
*/
|
|
248
|
+
animation_of(entity) {
|
|
249
|
+
const entry = this.#entries.get(entity);
|
|
250
|
+
|
|
251
|
+
if (entry === undefined) {
|
|
252
|
+
return null;
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
return entry.animation;
|
|
256
|
+
}
|
|
257
|
+
|
|
258
|
+
/**
|
|
259
|
+
* Where an entity's model is, in world space.
|
|
260
|
+
*
|
|
261
|
+
* This is what makes picking possible without a second copy of the geometry: Shade already keeps
|
|
262
|
+
* a world bounding box per mesh, refreshed as part of the `updateMatrices` that places it, so the
|
|
263
|
+
* answer is a walk over what the entity has in the scene and nothing is recomputed.
|
|
264
|
+
*
|
|
265
|
+
* @param {ArrayLike<number>|number[]|Float32Array} target aabb3, order `x0,y0,z0,x1,y1,z1`
|
|
266
|
+
* @param {number} entity
|
|
267
|
+
* @returns {boolean} `false` when the entity has nothing in the scene — it may be an entity this
|
|
268
|
+
* system has never seen, or one whose model is still loading, and neither is an error
|
|
269
|
+
*/
|
|
270
|
+
compute_world_bounds(target, entity) {
|
|
271
|
+
const entry = this.#entries.get(entity);
|
|
272
|
+
|
|
273
|
+
if (entry === undefined) {
|
|
274
|
+
return false;
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
let found = false;
|
|
278
|
+
|
|
279
|
+
/**
|
|
280
|
+
* @param {Mesh} node
|
|
281
|
+
*/
|
|
282
|
+
const combine = node => {
|
|
283
|
+
const bounds = node.bounding_box;
|
|
284
|
+
|
|
285
|
+
// combining the first box with itself is how it lands in `target` — one operation
|
|
286
|
+
// for both cases, rather than a copy that only ever runs once
|
|
287
|
+
aabb3_array_combine(target, 0, found ? target : bounds, 0, bounds, 0);
|
|
288
|
+
|
|
289
|
+
found = true;
|
|
290
|
+
};
|
|
291
|
+
|
|
292
|
+
for (let i = 0; i < entry.nodes.length; i++) {
|
|
293
|
+
entry.nodes[i].traverse(node => {
|
|
294
|
+
if (node.isMesh !== true) {
|
|
295
|
+
// a grouping node carries no geometry, so it has no bounds of its own
|
|
296
|
+
return;
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
combine(node);
|
|
300
|
+
});
|
|
301
|
+
}
|
|
302
|
+
|
|
303
|
+
this.#traverse_expanded(entry, combine);
|
|
304
|
+
|
|
305
|
+
return found;
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
async startup(entityManager) {
|
|
309
|
+
this.entityManager = entityManager;
|
|
310
|
+
|
|
311
|
+
this.#graphics.set_scene(this.#scene);
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
async shutdown(entityManager) {
|
|
315
|
+
for (const entity of Array.from(this.#entries.keys())) {
|
|
316
|
+
this.#drop(entity);
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
this.#bundles.clear();
|
|
320
|
+
|
|
321
|
+
this.#context = null;
|
|
322
|
+
this.#unregistered.length = 0;
|
|
323
|
+
}
|
|
324
|
+
|
|
325
|
+
/**
|
|
326
|
+
* Tell the GPU about the models that have arrived since the last frame.
|
|
327
|
+
*
|
|
328
|
+
* **This is where an instance's skins and clips reach `GPUAnimationManager`** — the manager
|
|
329
|
+
* hangs off the scene's GPU context, which exists only while there is a device, so registration
|
|
330
|
+
* cannot happen where instances are built (a model loads whenever it loads, including before
|
|
331
|
+
* the renderer has started). Registration is documented eventually-consistent at both entry
|
|
332
|
+
* points, so a frame of latency here costs nothing: the ids are live immediately and the chains
|
|
333
|
+
* that drive deformation are built when every joint has a row.
|
|
334
|
+
*
|
|
335
|
+
* A restart is the same event seen from here: the context object changes, every id the old one
|
|
336
|
+
* issued is void, and everything currently placed queues up again.
|
|
337
|
+
*
|
|
338
|
+
* @param {number} time_delta_seconds
|
|
339
|
+
*/
|
|
340
|
+
update(time_delta_seconds) {
|
|
341
|
+
this.#collect_arrived_urls();
|
|
342
|
+
|
|
343
|
+
const context = this.#graphics.scene_context(this.#scene);
|
|
344
|
+
|
|
345
|
+
if (context === null) {
|
|
346
|
+
// No device — before the first start, or after a stop. Nothing is registered while
|
|
347
|
+
// this holds, and the next context to arrive is a change like any other.
|
|
348
|
+
return;
|
|
349
|
+
}
|
|
350
|
+
|
|
351
|
+
if (context !== this.#context) {
|
|
352
|
+
this.#invalidate_registrations(context);
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
const waiting = this.#unregistered;
|
|
356
|
+
|
|
357
|
+
if (waiting.length === 0) {
|
|
358
|
+
return;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
/*
|
|
362
|
+
**A throw in here does not cost one model, it costs the session.** The list is cleared after
|
|
363
|
+
the loop, so a registration that throws partway leaves the entries before it *already
|
|
364
|
+
registered* and *still queued*: the next update registers them a second time, `bind` finds
|
|
365
|
+
the mesh already bound to another skin, and that assertion then fires once a frame for as
|
|
366
|
+
long as the game runs. Meanwhile the entry that threw never gets an `animation`, so `#drop`
|
|
367
|
+
has nothing to give back and its skinning bindings outlive their model — which is how a
|
|
368
|
+
`SkinnedMesh` ends up with no meshes-table row a hundred frames later.
|
|
369
|
+
|
|
370
|
+
Seen for real: a second skinned model arriving in one frame used to overrun the meshlet
|
|
371
|
+
buffers while a clone was queued (fixed in `GPUMeshletManager`), and the cascade above is
|
|
372
|
+
what turned that one throw into a dead animation layer. Registering one entry at a time and
|
|
373
|
+
taking it off the list as it succeeds is the shape of the fix; what to do with an entry that
|
|
374
|
+
*cannot* be registered is the open question, which is why it is written down here rather
|
|
375
|
+
than fixed. The throw that exposed it is fixed (`ac5e430e3`); the amplifier is not, and any
|
|
376
|
+
future failure in registration reproduces the same cascade.
|
|
377
|
+
*/
|
|
378
|
+
for (let i = 0; i < waiting.length; i++) {
|
|
379
|
+
const entry = waiting[i];
|
|
380
|
+
|
|
381
|
+
entry.animation = register_instance_animation(context, entry.instance);
|
|
382
|
+
}
|
|
383
|
+
|
|
384
|
+
waiting.length = 0;
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
/**
|
|
388
|
+
* Load the models of entities whose url has turned up since the last frame.
|
|
389
|
+
*
|
|
390
|
+
* Ahead of everything the device gates, because a model arrives whenever it arrives and there
|
|
391
|
+
* may be no renderer yet — the same bargain {@link #attach} makes with registration.
|
|
392
|
+
*/
|
|
393
|
+
#collect_arrived_urls() {
|
|
394
|
+
const waiting = this.#awaiting_url;
|
|
395
|
+
|
|
396
|
+
for (let i = waiting.length - 1; i >= 0; i--) {
|
|
397
|
+
const pending = waiting[i];
|
|
398
|
+
|
|
399
|
+
if (pending.model.url === null) {
|
|
400
|
+
continue;
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
waiting.splice(i, 1);
|
|
404
|
+
|
|
405
|
+
this.#attach(pending.entity, pending.model.url, pending.transform);
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
/**
|
|
410
|
+
* A different renderer is drawing this scene now, so nothing that has been registered still is.
|
|
411
|
+
*
|
|
412
|
+
* @param {GPUSceneContext} context
|
|
413
|
+
*/
|
|
414
|
+
#invalidate_registrations(context) {
|
|
415
|
+
this.#context = context;
|
|
416
|
+
|
|
417
|
+
const waiting = this.#unregistered;
|
|
418
|
+
|
|
419
|
+
waiting.length = 0;
|
|
420
|
+
|
|
421
|
+
for (const entry of this.#entries.values()) {
|
|
422
|
+
if (entry.instance === null) {
|
|
423
|
+
continue;
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
entry.animation = null;
|
|
427
|
+
|
|
428
|
+
waiting.push(entry);
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
/**
|
|
433
|
+
* @param {SGMesh} model
|
|
434
|
+
* @param {Transform} transform
|
|
435
|
+
* @param {number} entity
|
|
436
|
+
*/
|
|
437
|
+
link(model, transform, entity) {
|
|
438
|
+
const entry = { nodes: [], bindings: [], instance: null, animation: null, composition: null };
|
|
439
|
+
|
|
440
|
+
this.#entries.set(entity, entry);
|
|
441
|
+
|
|
442
|
+
// The entity is placed the moment its transform moves, not on a poll: a transform that has
|
|
443
|
+
// not changed costs nothing, which is the same bargain the scene database makes downstream.
|
|
444
|
+
const place = () => this.#place(entity, transform);
|
|
445
|
+
|
|
446
|
+
for (const component of [transform.position, transform.rotation, transform.scale]) {
|
|
447
|
+
const binding = new SignalBinding(component.onChanged, place);
|
|
448
|
+
|
|
449
|
+
binding.link();
|
|
450
|
+
|
|
451
|
+
entry.bindings.push(binding);
|
|
452
|
+
}
|
|
453
|
+
|
|
454
|
+
if (model.url === null) {
|
|
455
|
+
// nothing to show yet; {@link update} watches for the url arriving
|
|
456
|
+
this.#awaiting_url.push({ entity, model, transform });
|
|
457
|
+
|
|
458
|
+
return;
|
|
459
|
+
}
|
|
460
|
+
|
|
461
|
+
this.#attach(entity, model.url, transform);
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
/**
|
|
465
|
+
* @param {SGMesh} model
|
|
466
|
+
* @param {Transform} transform
|
|
467
|
+
* @param {number} entity
|
|
468
|
+
*/
|
|
469
|
+
unlink(model, transform, entity) {
|
|
470
|
+
this.#drop(entity);
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
/**
|
|
474
|
+
* Load the model if it has not been seen, then put a copy of it in the scene.
|
|
475
|
+
*
|
|
476
|
+
* @param {number} entity
|
|
477
|
+
* @param {string} url
|
|
478
|
+
* @param {Transform} transform
|
|
479
|
+
*/
|
|
480
|
+
async #attach(entity, url, transform) {
|
|
481
|
+
/*
|
|
482
|
+
Which entry this load is for, decided before the wait rather than after it. A load is in
|
|
483
|
+
flight for as long as a fetch and a decode take, and the entity can leave and come back
|
|
484
|
+
inside that window — so asking `#entries` afterwards answers "the entry this entity has
|
|
485
|
+
now", which may be a different one. Attaching to that leaves the scene holding a second
|
|
486
|
+
model nothing owns, and its skins registered with the GPU under a record that has already
|
|
487
|
+
been overwritten.
|
|
488
|
+
*/
|
|
489
|
+
const started_for = this.#entries.get(entity);
|
|
490
|
+
|
|
491
|
+
let bundle = this.#bundles.get(url);
|
|
492
|
+
|
|
493
|
+
if (bundle === undefined) {
|
|
494
|
+
bundle = this.#load(url);
|
|
495
|
+
|
|
496
|
+
this.#bundles.set(url, bundle);
|
|
497
|
+
}
|
|
498
|
+
|
|
499
|
+
const loaded = await bundle;
|
|
500
|
+
|
|
501
|
+
const entry = this.#entries.get(entity);
|
|
502
|
+
|
|
503
|
+
if (entry !== started_for) {
|
|
504
|
+
// the entity left while its model was in flight, or left and came back as another
|
|
505
|
+
// entry — both ordinary at level-load rates
|
|
506
|
+
return;
|
|
507
|
+
}
|
|
508
|
+
|
|
509
|
+
if (loaded.skins.length === 0 && loaded.clips.length === 0) {
|
|
510
|
+
this.#expand(entity, loaded, transform);
|
|
511
|
+
|
|
512
|
+
return;
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
const instance = instantiate_scene_bundle(loaded);
|
|
516
|
+
|
|
517
|
+
entry.instance = instance;
|
|
518
|
+
|
|
519
|
+
for (const node of instance.roots) {
|
|
520
|
+
entry.nodes.push(node);
|
|
521
|
+
|
|
522
|
+
this.#scene.add(node);
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
this.#place(entity, transform);
|
|
526
|
+
|
|
527
|
+
// The GPU hears about it on the next update rather than here: a model finishes loading
|
|
528
|
+
// whenever it finishes, and there may be no device to tell.
|
|
529
|
+
this.#unregistered.push(entry);
|
|
530
|
+
}
|
|
531
|
+
|
|
532
|
+
/**
|
|
533
|
+
* Put a model into the dataset as entities.
|
|
534
|
+
*
|
|
535
|
+
* **This is what placing a model means in an ECS** (D47): meep has no scene graph to hand a file
|
|
536
|
+
* to, so the file's nodes become entities — parented, named, placed, and carrying a
|
|
537
|
+
* `ShadedGeometry` where they draw — and `ShadedGeometrySystem` gives each of those a row.
|
|
538
|
+
* Nothing here touches the scene, and no copy of the model is made: the entities name the
|
|
539
|
+
* bundle's own geometry and material, so a model placed two hundred times is one of each.
|
|
540
|
+
*
|
|
541
|
+
* **Only a model that neither deforms nor animates comes this way.** A skinned one deforms
|
|
542
|
+
* against a skeleton the renderer owns and the GPU poses; an animated one has clips that drive
|
|
543
|
+
* the nodes of an instance, and `GPUAnimationManager` addresses those nodes rather than
|
|
544
|
+
* entities. Making joints entities, or moving playback onto entity transforms, are both designs
|
|
545
|
+
* outside this program (D47) — so anything with a skin or a clip keeps the instance path above,
|
|
546
|
+
* exactly as Phase 4 built it.
|
|
547
|
+
*
|
|
548
|
+
* @param {number} entity
|
|
549
|
+
* @param {SceneBundle} bundle
|
|
550
|
+
* @param {Transform} transform
|
|
551
|
+
*/
|
|
552
|
+
#expand(entity, bundle, transform) {
|
|
553
|
+
const entry = this.#entries.get(entity);
|
|
554
|
+
|
|
555
|
+
const composition = shade_bundle_to_entity_composition(bundle);
|
|
556
|
+
|
|
557
|
+
composition.entity.add(ParentEntity.from(entity));
|
|
558
|
+
|
|
559
|
+
const follow = () => composition.transform.copy(transform);
|
|
560
|
+
|
|
561
|
+
follow();
|
|
562
|
+
|
|
563
|
+
composition.build(this.entityManager.dataset);
|
|
564
|
+
|
|
565
|
+
transform.subscribe(follow);
|
|
566
|
+
|
|
567
|
+
composition.on.destroyed.addOne(() => transform.unsubscribe(follow));
|
|
568
|
+
|
|
569
|
+
entry.composition = composition;
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
/**
|
|
573
|
+
* @param {number} entity
|
|
574
|
+
* @param {Transform} transform
|
|
575
|
+
*/
|
|
576
|
+
#place(entity, transform) {
|
|
577
|
+
const entry = this.#entries.get(entity);
|
|
578
|
+
|
|
579
|
+
if (entry === undefined) {
|
|
580
|
+
return;
|
|
581
|
+
}
|
|
582
|
+
|
|
583
|
+
const nodes = entry.nodes;
|
|
584
|
+
|
|
585
|
+
for (let i = 0; i < nodes.length; i++) {
|
|
586
|
+
const node = nodes[i];
|
|
587
|
+
|
|
588
|
+
t64_copy_from_transform(node.transform_local, transform);
|
|
589
|
+
|
|
590
|
+
// recomputes transform_global down the subtree, and bumps the version the scene
|
|
591
|
+
// database reads to decide what to upload
|
|
592
|
+
node.updateMatrices();
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
/**
|
|
597
|
+
* @param {number} entity
|
|
598
|
+
*/
|
|
599
|
+
#drop(entity) {
|
|
600
|
+
const entry = this.#entries.get(entity);
|
|
601
|
+
|
|
602
|
+
if (entry === undefined) {
|
|
603
|
+
return;
|
|
604
|
+
}
|
|
605
|
+
|
|
606
|
+
for (let i = 0; i < entry.bindings.length; i++) {
|
|
607
|
+
entry.bindings[i].unlink();
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
for (let i = 0; i < entry.nodes.length; i++) {
|
|
611
|
+
this.#scene.remove(entry.nodes[i]);
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
if (entry.composition !== null) {
|
|
615
|
+
// the entities the model became are the model, so they go with it
|
|
616
|
+
entry.composition.destroy();
|
|
617
|
+
|
|
618
|
+
entry.composition = null;
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
const waiting = this.#unregistered.indexOf(entry);
|
|
622
|
+
|
|
623
|
+
if (waiting !== -1) {
|
|
624
|
+
// it left before the GPU was ever told about it
|
|
625
|
+
this.#unregistered.splice(waiting, 1);
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
const awaiting = this.#awaiting_url.findIndex(pending => pending.entity === entity);
|
|
629
|
+
|
|
630
|
+
if (awaiting !== -1) {
|
|
631
|
+
// it left before it ever had a model to load
|
|
632
|
+
this.#awaiting_url.splice(awaiting, 1);
|
|
633
|
+
}
|
|
634
|
+
|
|
635
|
+
const registration = entry.animation;
|
|
636
|
+
|
|
637
|
+
if (registration !== null) {
|
|
638
|
+
if (this.#graphics.scene_context(this.#scene) === registration.context) {
|
|
639
|
+
unregister_instance_animation(registration);
|
|
640
|
+
}
|
|
641
|
+
|
|
642
|
+
entry.animation = null;
|
|
643
|
+
}
|
|
644
|
+
|
|
645
|
+
this.#entries.delete(entity);
|
|
646
|
+
}
|
|
647
|
+
}
|