@woosh/meep-engine 3.23.0 → 3.24.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/editor/entity_world_bounds.d.ts +9 -3
- package/editor/entity_world_bounds.d.ts.map +1 -1
- package/editor/entity_world_bounds.js +61 -4
- package/package.json +1 -1
- package/src/core/binary/allocator/OffsetAllocator.d.ts +40 -2
- package/src/core/binary/allocator/OffsetAllocator.d.ts.map +1 -1
- package/src/core/binary/allocator/OffsetAllocator.js +124 -29
- package/src/core/collection/map/u32_index.d.ts +83 -0
- package/src/core/collection/map/u32_index.d.ts.map +1 -0
- package/src/core/collection/map/u32_index.js +247 -0
- package/src/engine/asset/loaders/GLTFSceneBundleAssetLoader.d.ts +2 -2
- package/src/engine/asset/loaders/GLTFSceneBundleAssetLoader.js +2 -2
- package/src/engine/asset/loaders/USDSceneBundleAssetLoader.d.ts +1 -2
- package/src/engine/asset/loaders/USDSceneBundleAssetLoader.d.ts.map +1 -1
- package/src/engine/asset/loaders/USDSceneBundleAssetLoader.js +4 -12
- package/src/engine/ecs/gpu/GPUStateAuthority.d.ts +55 -0
- package/src/engine/ecs/gpu/GPUStateAuthority.d.ts.map +1 -0
- package/src/engine/ecs/gpu/GPUStateAuthority.js +72 -0
- package/src/engine/ecs/gpu/GPUStateAuthorityFlags.d.ts +40 -0
- package/src/engine/ecs/gpu/GPUStateAuthorityFlags.d.ts.map +1 -0
- package/src/engine/ecs/gpu/GPUStateAuthorityFlags.js +79 -0
- package/src/engine/ecs/gpu/gpu_authority_assert_cpu.d.ts +18 -0
- package/src/engine/ecs/gpu/gpu_authority_assert_cpu.d.ts.map +1 -0
- package/src/engine/ecs/gpu/gpu_authority_assert_cpu.js +27 -0
- package/src/engine/ecs/gpu/gpu_authority_declare.d.ts +23 -0
- package/src/engine/ecs/gpu/gpu_authority_declare.d.ts.map +1 -0
- package/src/engine/ecs/gpu/gpu_authority_declare.js +39 -0
- package/src/engine/ecs/gpu/gpu_authority_grant.d.ts +15 -0
- package/src/engine/ecs/gpu/gpu_authority_grant.d.ts.map +1 -0
- package/src/engine/ecs/gpu/gpu_authority_grant.js +38 -0
- package/src/engine/ecs/gpu/gpu_authority_has.d.ts +18 -0
- package/src/engine/ecs/gpu/gpu_authority_has.d.ts.map +1 -0
- package/src/engine/ecs/gpu/gpu_authority_has.js +28 -0
- package/src/engine/ecs/gpu/gpu_authority_revoke.d.ts +24 -0
- package/src/engine/ecs/gpu/gpu_authority_revoke.d.ts.map +1 -0
- package/src/engine/ecs/gpu/gpu_authority_revoke.js +49 -0
- package/src/engine/ecs/ik/IKProblem.d.ts +14 -0
- package/src/engine/ecs/ik/IKProblem.d.ts.map +1 -1
- package/src/engine/ecs/ik/IKProblem.js +16 -0
- package/src/engine/ecs/ik/InverseKinematicsSystem.d.ts.map +1 -1
- package/src/engine/ecs/ik/InverseKinematicsSystem.js +19 -0
- package/src/engine/ecs/ik/OneBoneSurfaceAlignmentSolver.js +2 -2
- package/src/engine/ecs/ik/TwoBoneInverseKinematicsSolver.js +2 -2
- package/src/engine/ecs/ik/ik_bone_chain.d.ts +11 -2
- package/src/engine/ecs/ik/ik_bone_chain.d.ts.map +1 -1
- package/src/engine/ecs/ik/ik_bone_chain.js +47 -2
- package/src/engine/ecs/ik/ik_write_local_rotation.d.ts.map +1 -1
- package/src/engine/ecs/ik/ik_write_local_rotation.js +6 -0
- package/src/engine/ecs/speaker/VoiceSystem.d.ts.map +1 -1
- package/src/engine/ecs/speaker/VoiceSystem.js +6 -0
- package/src/engine/ecs/transform/T64WorldCache.d.ts +50 -0
- package/src/engine/ecs/transform/T64WorldCache.d.ts.map +1 -0
- package/src/engine/ecs/transform/T64WorldCache.js +139 -0
- package/src/engine/ecs/transform/t64_evaluate_world.d.ts +31 -0
- package/src/engine/ecs/transform/t64_evaluate_world.d.ts.map +1 -0
- package/src/engine/ecs/transform/t64_evaluate_world.js +126 -0
- package/src/engine/ecs/transform-attachment/TransformAttachmentSystem.d.ts +8 -0
- package/src/engine/ecs/transform-attachment/TransformAttachmentSystem.d.ts.map +1 -1
- package/src/engine/ecs/transform-attachment/TransformAttachmentSystem.js +59 -30
- package/src/engine/graphics/ecs/highlight/system/ShadedGeometryHighlightSystem.d.ts.map +1 -1
- package/src/engine/graphics/ecs/highlight/system/ShadedGeometryHighlightSystem.js +4 -11
- package/src/engine/graphics/ecs/mesh-v2/SHADED_GEOMETRY_EVENT_CHANGE.d.ts +14 -0
- package/src/engine/graphics/ecs/mesh-v2/SHADED_GEOMETRY_EVENT_CHANGE.d.ts.map +1 -0
- package/src/engine/graphics/ecs/mesh-v2/SHADED_GEOMETRY_EVENT_CHANGE.js +13 -0
- package/src/engine/graphics/ecs/mesh-v2/ShadedGeometry.d.ts +2 -14
- package/src/engine/graphics/ecs/mesh-v2/ShadedGeometry.d.ts.map +1 -1
- package/src/engine/graphics/ecs/mesh-v2/ShadedGeometry.js +11 -21
- package/src/engine/graphics/ecs/mesh-v2/ShadedGeometryFlags.d.ts +1 -0
- package/src/engine/graphics/ecs/mesh-v2/ShadedGeometryFlags.js +7 -0
- package/src/engine/graphics/ecs/mesh-v2/aggregate/SGMeshHighlightSystem.d.ts +5 -6
- package/src/engine/graphics/ecs/mesh-v2/aggregate/SGMeshHighlightSystem.d.ts.map +1 -1
- package/src/engine/graphics/ecs/mesh-v2/aggregate/SGMeshHighlightSystem.js +13 -11
- package/src/engine/graphics/ecs/mesh-v2/shaded_geometry_announce_change.d.ts +14 -0
- package/src/engine/graphics/ecs/mesh-v2/shaded_geometry_announce_change.d.ts.map +1 -0
- package/src/engine/graphics/ecs/mesh-v2/shaded_geometry_announce_change.js +21 -0
- package/src/engine/graphics/ecs/particles/ParticleEffect.d.ts +1 -1
- package/src/engine/graphics/ecs/particles/ParticleEffect.js +1 -1
- package/src/engine/graphics/sh3/path_tracer/populate_path_traced_scene_from_ecd.d.ts +1 -1
- package/src/engine/graphics/sh3/path_tracer/populate_path_traced_scene_from_ecd.js +1 -1
- package/src/engine/graphics3/AnimationGraphSystem.js +3 -3
- package/src/engine/graphics3/AnimationSystem.js +2 -2
- package/src/engine/graphics3/DebugDrawSystem.d.ts.map +1 -1
- package/src/engine/graphics3/DebugDrawSystem.js +2 -4
- package/src/engine/graphics3/GPUParticleEmitterSystem.d.ts +34 -27
- package/src/engine/graphics3/GPUParticleEmitterSystem.d.ts.map +1 -1
- package/src/engine/graphics3/GPUParticleEmitterSystem.js +185 -85
- package/src/engine/graphics3/HighlightOutlineSystem.d.ts +4 -3
- package/src/engine/graphics3/HighlightOutlineSystem.d.ts.map +1 -1
- package/src/engine/graphics3/HighlightOutlineSystem.js +7 -9
- package/src/engine/graphics3/LightSystem.d.ts +7 -5
- package/src/engine/graphics3/LightSystem.d.ts.map +1 -1
- package/src/engine/graphics3/LightSystem.js +36 -22
- package/src/engine/graphics3/MeshSystem.d.ts +43 -39
- package/src/engine/graphics3/MeshSystem.d.ts.map +1 -1
- package/src/engine/graphics3/MeshSystem.js +324 -331
- package/src/engine/graphics3/PathDisplaySystem.d.ts.map +1 -1
- package/src/engine/graphics3/PathDisplaySystem.js +2 -4
- package/src/engine/graphics3/PickingQuery.d.ts +15 -21
- package/src/engine/graphics3/PickingQuery.d.ts.map +1 -1
- package/src/engine/graphics3/PickingQuery.js +21 -25
- package/src/engine/graphics3/PickingSystem.d.ts +60 -31
- package/src/engine/graphics3/PickingSystem.d.ts.map +1 -1
- package/src/engine/graphics3/PickingSystem.js +416 -273
- package/src/engine/graphics3/ShadedGeometrySystem.d.ts +22 -12
- package/src/engine/graphics3/ShadedGeometrySystem.d.ts.map +1 -1
- package/src/engine/graphics3/ShadedGeometrySystem.js +309 -174
- package/src/engine/graphics3/TerrainSystem.d.ts +19 -11
- package/src/engine/graphics3/TerrainSystem.d.ts.map +1 -1
- package/src/engine/graphics3/TerrainSystem.js +102 -53
- package/src/engine/graphics3/TooltipComponentSystem.d.ts.map +1 -1
- package/src/engine/graphics3/TooltipComponentSystem.js +2 -14
- package/src/engine/graphics3/Trail3DSystem.d.ts.map +1 -1
- package/src/engine/graphics3/Trail3DSystem.js +2 -4
- package/src/engine/graphics3/animation/ClipListPlayer.d.ts +4 -4
- package/src/engine/graphics3/animation/ClipListPlayer.d.ts.map +1 -1
- package/src/engine/graphics3/animation/ClipListPlayer.js +2 -2
- package/src/engine/graphics3/highlight/pack_highlight_table.d.ts +9 -11
- package/src/engine/graphics3/highlight/pack_highlight_table.d.ts.map +1 -1
- package/src/engine/graphics3/highlight/pack_highlight_table.js +11 -18
- package/src/engine/graphics3/pose/query_entity_node_world_pose.d.ts +4 -3
- package/src/engine/graphics3/pose/query_entity_node_world_pose.d.ts.map +1 -1
- package/src/engine/graphics3/pose/query_entity_node_world_pose.js +75 -74
- package/src/engine/graphics3/prefab/Prefab.d.ts +130 -0
- package/src/engine/graphics3/prefab/Prefab.d.ts.map +1 -0
- package/src/engine/graphics3/prefab/Prefab.js +162 -0
- package/src/engine/graphics3/prefab/PrefabInstance.d.ts +72 -0
- package/src/engine/graphics3/prefab/PrefabInstance.d.ts.map +1 -0
- package/src/engine/graphics3/prefab/PrefabInstance.js +80 -0
- package/src/engine/graphics3/prefab/prefab_compile.d.ts +23 -0
- package/src/engine/graphics3/prefab/prefab_compile.d.ts.map +1 -0
- package/src/engine/graphics3/prefab/prefab_compile.js +334 -0
- package/src/engine/graphics3/prefab/prefab_instantiate.d.ts +46 -0
- package/src/engine/graphics3/prefab/prefab_instantiate.d.ts.map +1 -0
- package/src/engine/graphics3/prefab/prefab_instantiate.js +230 -0
- package/src/engine/graphics3/prefab/prefab_normalize_skin_frames.d.ts +70 -0
- package/src/engine/graphics3/prefab/prefab_normalize_skin_frames.d.ts.map +1 -0
- package/src/engine/graphics3/prefab/prefab_normalize_skin_frames.js +210 -0
- package/src/engine/graphics3/prefab/prefab_place.d.ts +60 -0
- package/src/engine/graphics3/prefab/prefab_place.d.ts.map +1 -0
- package/src/engine/graphics3/prefab/prefab_place.js +130 -0
- package/src/engine/graphics3/prefab/prefab_skin_clip_scale_conflicts.d.ts +60 -0
- package/src/engine/graphics3/prefab/prefab_skin_clip_scale_conflicts.d.ts.map +1 -0
- package/src/engine/graphics3/prefab/prefab_skin_clip_scale_conflicts.js +128 -0
- package/src/engine/graphics3/prefab/prefab_skin_frame.d.ts +40 -0
- package/src/engine/graphics3/prefab/prefab_skin_frame.d.ts.map +1 -0
- package/src/engine/graphics3/prefab/prefab_skin_frame.js +116 -0
- package/src/engine/graphics3/preview/make_model_preview_scene.d.ts +16 -14
- package/src/engine/graphics3/preview/make_model_preview_scene.d.ts.map +1 -1
- package/src/engine/graphics3/preview/make_model_preview_scene.js +126 -154
- package/src/engine/graphics3/preview/make_model_thumbnail.js +1 -1
- package/src/engine/graphics3/register_instance_animation.d.ts +6 -6
- package/src/engine/graphics3/register_instance_animation.d.ts.map +1 -1
- package/src/engine/graphics3/register_instance_animation.js +4 -4
- package/src/engine/graphics3/shade_bundle_bounds.d.ts +2 -6
- package/src/engine/graphics3/shade_bundle_bounds.d.ts.map +1 -1
- package/src/engine/graphics3/shade_bundle_bounds.js +47 -55
- package/src/engine/graphics3/terrain/pack_terrain_row_table.d.ts +11 -18
- package/src/engine/graphics3/terrain/pack_terrain_row_table.d.ts.map +1 -1
- package/src/engine/graphics3/terrain/pack_terrain_row_table.js +48 -53
- package/src/engine/physics/cloth/build/cloth_proxy_from_joints.d.ts +17 -2
- package/src/engine/physics/cloth/build/cloth_proxy_from_joints.d.ts.map +1 -1
- package/src/engine/physics/cloth/build/cloth_proxy_from_joints.js +284 -256
- package/src/engine/physics/cloth/ecs/ClothInstance.d.ts +13 -15
- package/src/engine/physics/cloth/ecs/ClothInstance.d.ts.map +1 -1
- package/src/engine/physics/cloth/ecs/ClothInstance.js +12 -14
- package/src/engine/physics/cloth/ecs/ClothRig.d.ts +7 -8
- package/src/engine/physics/cloth/ecs/ClothRig.d.ts.map +1 -1
- package/src/engine/physics/cloth/ecs/ClothRig.js +7 -8
- package/src/engine/physics/cloth/ecs/ClothSystem.d.ts +5 -4
- package/src/engine/physics/cloth/ecs/ClothSystem.d.ts.map +1 -1
- package/src/engine/physics/cloth/ecs/ClothSystem.js +11 -12
- package/src/engine/physics/cloth/ecs/cloth_seed_rig.d.ts +19 -23
- package/src/engine/physics/cloth/ecs/cloth_seed_rig.d.ts.map +1 -1
- package/src/engine/physics/cloth/ecs/cloth_seed_rig.js +201 -199
- package/src/engine/physics/cloth/ecs/cloth_seed_subtree.d.ts.map +1 -1
- package/src/engine/physics/cloth/ecs/cloth_seed_subtree.js +8 -0
- package/src/engine/physics/cloth/ecs/cloth_write_back_rig.d.ts +18 -34
- package/src/engine/physics/cloth/ecs/cloth_write_back_rig.d.ts.map +1 -1
- package/src/engine/physics/cloth/ecs/cloth_write_back_rig.js +58 -115
- package/src/engine/physics/cloth/playground/README.md +11 -11
- package/src/engine/physics/cloth/playground/garment_build.d.ts +0 -1
- package/src/engine/physics/cloth/playground/garment_build.d.ts.map +1 -1
- package/src/engine/physics/cloth/playground/garment_build.js +64 -58
- package/src/engine/physics/cloth/playground/garment_main.js +59 -33
- package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
- package/src/shade/RENDERER_CONTRACT.md +85 -53
- package/src/shade/device/ShadeGPUCommandContext.d.ts +23 -0
- package/src/shade/device/ShadeGPUCommandContext.d.ts.map +1 -1
- package/src/shade/device/ShadeGPUCommandContext.js +36 -0
- package/src/shade/playground/add_random_meshes.d.ts +4 -4
- package/src/shade/playground/add_random_meshes.d.ts.map +1 -1
- package/src/shade/playground/add_random_meshes.js +20 -16
- package/src/shade/playground/avboit/main.d.ts +1 -0
- package/src/shade/playground/avboit/main.d.ts.map +1 -1
- package/src/shade/playground/avboit/main.js +916 -875
- package/src/shade/playground/basis_textures/main.d.ts.map +1 -1
- package/src/shade/playground/basis_textures/main.js +22 -8
- package/src/shade/playground/basis_textures/texture_inventory.d.ts +2 -2
- package/src/shade/playground/basis_textures/texture_inventory.d.ts.map +1 -1
- package/src/shade/playground/basis_textures/texture_inventory.js +6 -7
- package/src/shade/playground/ground_seam/main.d.ts.map +1 -1
- package/src/shade/playground/ground_seam/main.js +13 -4
- package/src/shade/playground/ground_seam/make_ground.d.ts +13 -4
- package/src/shade/playground/ground_seam/make_ground.d.ts.map +1 -1
- package/src/shade/playground/ground_seam/make_ground.js +21 -16
- package/src/shade/playground/particle_ecs/bonfire_editor.js +3 -3
- package/src/shade/playground/particle_system/main.js +11 -10
- package/src/shade/playground/particle_system/particle_prototype.d.ts +15 -10
- package/src/shade/playground/particle_system/particle_prototype.d.ts.map +1 -1
- package/src/shade/playground/particle_system/particle_prototype.js +56 -15
- package/src/shade/playground/particle_system/particle_scene.d.ts +68 -28
- package/src/shade/playground/particle_system/particle_scene.d.ts.map +1 -1
- package/src/shade/playground/particle_system/particle_scene.js +149 -53
- package/src/shade/playground/readback_crossover/index.html +41 -0
- package/src/shade/playground/readback_crossover/main.d.ts +2 -0
- package/src/shade/playground/readback_crossover/main.d.ts.map +1 -0
- package/src/shade/playground/readback_crossover/main.js +372 -0
- package/src/shade/playground/skinned_blas_refit/README.md +11 -7
- package/src/shade/playground/skinned_blas_refit/add_floor.d.ts +13 -44
- package/src/shade/playground/skinned_blas_refit/add_floor.d.ts.map +1 -1
- package/src/shade/playground/skinned_blas_refit/add_floor.js +19 -59
- package/src/shade/playground/skinned_blas_refit/main.d.ts.map +1 -1
- package/src/shade/playground/skinned_blas_refit/main.js +67 -58
- package/src/shade/playground/skinned_blas_refit/place_character.d.ts +40 -54
- package/src/shade/playground/skinned_blas_refit/place_character.d.ts.map +1 -1
- package/src/shade/playground/skinned_blas_refit/place_character.js +47 -74
- package/src/shade/playground/skinned_blas_refit/sweep_views.d.ts +3 -3
- package/src/shade/playground/skinned_blas_refit/sweep_views.d.ts.map +1 -1
- package/src/shade/playground/skinned_blas_refit/sweep_views.js +4 -3
- package/src/shade/playground/skinned_blas_refit/verify_clone_leaves.d.ts +3 -3
- package/src/shade/playground/skinned_blas_refit/verify_clone_leaves.d.ts.map +1 -1
- package/src/shade/playground/skinned_blas_refit/verify_clone_leaves.js +11 -4
- package/src/shade/playground/skinned_blas_refit/verify_instance_bounds.d.ts.map +1 -1
- package/src/shade/playground/skinned_blas_refit/verify_instance_bounds.js +38 -9
- package/src/shade/playground/skinned_blas_refit/verify_skinned_blas_refit.d.ts +3 -3
- package/src/shade/playground/skinned_blas_refit/verify_skinned_blas_refit.d.ts.map +1 -1
- package/src/shade/playground/skinned_blas_refit/verify_skinned_blas_refit.js +9 -6
- package/src/shade/playground/skinned_blas_refit/verify_traversal_reachability.d.ts +3 -3
- package/src/shade/playground/skinned_blas_refit/verify_traversal_reachability.d.ts.map +1 -1
- package/src/shade/playground/skinned_blas_refit/verify_traversal_reachability.js +3 -3
- package/src/shade/playground/skinned_mesh_soup/README.md +6 -6
- package/src/shade/playground/skinned_mesh_soup/main.d.ts.map +1 -1
- package/src/shade/playground/skinned_mesh_soup/main.js +44 -102
- package/src/shade/playground/skinned_mesh_soup/verify_clone_vertices.d.ts +5 -5
- package/src/shade/playground/skinned_mesh_soup/verify_clone_vertices.d.ts.map +1 -1
- package/src/shade/playground/skinned_mesh_soup/verify_clone_vertices.js +42 -33
- package/src/shade/playground/sponza_path_trace/main.d.ts +1 -0
- package/src/shade/playground/sponza_path_trace/main.d.ts.map +1 -1
- package/src/shade/playground/sponza_path_trace/main.js +393 -363
- package/src/shade/playground/ssr_reprojection/main.js +11 -9
- package/src/shade/playground/ssr_reprojection/scene.d.ts +15 -4
- package/src/shade/playground/ssr_reprojection/scene.d.ts.map +1 -1
- package/src/shade/playground/ssr_reprojection/scene.js +32 -11
- package/src/shade/playground/ssr_variance/main.js +1 -1
- package/src/shade/playground/ssr_variance/scene.d.ts +10 -4
- package/src/shade/playground/ssr_variance/scene.d.ts.map +1 -1
- package/src/shade/playground/ssr_variance/scene.js +39 -15
- package/src/shade/playground/vgeo_viewer/main.js +6 -2
- package/src/shade/playground/volumetrics_froxel/main.d.ts.map +1 -1
- package/src/shade/playground/volumetrics_froxel/main.js +936 -922
- package/src/shade/renderer/GraphicsContext.d.ts +7 -0
- package/src/shade/renderer/GraphicsContext.d.ts.map +1 -1
- package/src/shade/renderer/GraphicsContext.js +11 -0
- package/src/shade/renderer/Renderer.d.ts +3 -2
- package/src/shade/renderer/Renderer.d.ts.map +1 -1
- package/src/shade/renderer/Renderer.js +3 -2
- package/src/shade/renderer/animation/GPUAnimationManager.d.ts +39 -47
- package/src/shade/renderer/animation/GPUAnimationManager.d.ts.map +1 -1
- package/src/shade/renderer/animation/GPUAnimationManager.js +319 -256
- package/src/shade/renderer/animation/ShadeAnimationChannel.d.ts +26 -22
- package/src/shade/renderer/animation/ShadeAnimationChannel.d.ts.map +1 -1
- package/src/shade/renderer/animation/ShadeAnimationChannel.js +28 -23
- package/src/shade/renderer/animation/ShadeAnimationClip.d.ts +14 -6
- package/src/shade/renderer/animation/ShadeAnimationClip.d.ts.map +1 -1
- package/src/shade/renderer/animation/ShadeAnimationClip.js +20 -8
- package/src/shade/renderer/animation/Skin.d.ts +19 -19
- package/src/shade/renderer/animation/Skin.d.ts.map +1 -1
- package/src/shade/renderer/animation/Skin.js +15 -13
- package/src/shade/renderer/animation/pose/pose_evaluate_local.d.ts +6 -5
- package/src/shade/renderer/animation/pose/pose_evaluate_local.d.ts.map +1 -1
- package/src/shade/renderer/animation/pose/pose_evaluate_local.js +9 -9
- package/src/shade/renderer/animation/skin_clip_scale_conflicts.d.ts +5 -59
- package/src/shade/renderer/animation/skin_clip_scale_conflicts.d.ts.map +1 -1
- package/src/shade/renderer/animation/skin_clip_scale_conflicts.js +8 -132
- package/src/shade/renderer/animation/skinning/GPUMeshSkinningContext.d.ts +65 -62
- package/src/shade/renderer/animation/skinning/GPUMeshSkinningContext.d.ts.map +1 -1
- package/src/shade/renderer/animation/skinning/GPUMeshSkinningContext.js +148 -194
- package/src/shade/renderer/animation/skinning/SKINNING_BINDING_STRUCT.d.ts.map +1 -1
- package/src/shade/renderer/animation/skinning/SKINNING_BINDING_STRUCT.js +4 -7
- package/src/shade/renderer/animation/skinning/chunk_skin_blend_mesh_local.d.ts +2 -2
- package/src/shade/renderer/animation/skinning/chunk_skin_blend_mesh_local.js +2 -2
- package/src/shade/renderer/buffer/GPUBufferReadbackAllocator.d.ts +74 -0
- package/src/shade/renderer/buffer/GPUBufferReadbackAllocator.d.ts.map +1 -0
- package/src/shade/renderer/buffer/GPUBufferReadbackAllocator.js +240 -0
- package/src/shade/renderer/buffer/table/GPUDatabase.d.ts +14 -0
- package/src/shade/renderer/buffer/table/GPUDatabase.d.ts.map +1 -1
- package/src/shade/renderer/buffer/table/GPUDatabase.js +64 -6
- package/src/shade/renderer/buffer/table/GPUDatabaseReadback.d.ts +190 -0
- package/src/shade/renderer/buffer/table/GPUDatabaseReadback.d.ts.map +1 -0
- package/src/shade/renderer/buffer/table/GPUDatabaseReadback.js +1323 -0
- package/src/shade/renderer/buffer/table/GPUPageMetadata.d.ts +10 -0
- package/src/shade/renderer/buffer/table/GPUPageMetadata.d.ts.map +1 -1
- package/src/shade/renderer/buffer/table/GPUPageMetadata.js +12 -0
- package/src/shade/renderer/buffer/table/GPUReadbackStagingRing.d.ts +96 -0
- package/src/shade/renderer/buffer/table/GPUReadbackStagingRing.d.ts.map +1 -0
- package/src/shade/renderer/buffer/table/GPUReadbackStatus.d.ts +15 -0
- package/src/shade/renderer/buffer/table/GPUReadbackStatus.d.ts.map +1 -0
- package/src/shade/renderer/buffer/table/GPUReadbackStatus.js +34 -0
- package/src/shade/renderer/buffer/table/GPUTypedTable.d.ts +75 -7
- package/src/shade/renderer/buffer/table/GPUTypedTable.d.ts.map +1 -1
- package/src/shade/renderer/buffer/table/GPUTypedTable.js +518 -135
- package/src/shade/renderer/buffer/table/GPU_TABLE_GATHER_DESCRIPTOR_WORDS.d.ts +19 -0
- package/src/shade/renderer/buffer/table/GPU_TABLE_GATHER_DESCRIPTOR_WORDS.d.ts.map +1 -0
- package/src/shade/renderer/buffer/table/GPU_TABLE_GATHER_DESCRIPTOR_WORDS.js +18 -0
- package/src/shade/renderer/buffer/table/WordViews.d.ts +39 -0
- package/src/shade/renderer/buffer/table/WordViews.d.ts.map +1 -0
- package/src/shade/renderer/buffer/table/WordViews.js +62 -0
- package/src/shade/renderer/buffer/table/gpu_table_gather_shader.d.ts +27 -0
- package/src/shade/renderer/buffer/table/gpu_table_gather_shader.d.ts.map +1 -0
- package/src/shade/renderer/buffer/table/gpu_table_gather_shader.js +117 -0
- package/src/shade/renderer/buffer/table/serde/generate_record_writer.d.ts +121 -0
- package/src/shade/renderer/buffer/table/serde/generate_record_writer.d.ts.map +1 -0
- package/src/shade/renderer/buffer/table/serde/generate_record_writer.js +395 -0
- package/src/shade/renderer/buffer/table/single/GPUSingleTypeTable.d.ts.map +1 -1
- package/src/shade/renderer/buffer/table/single/GPUSingleTypeTable.js +70 -20
- package/src/shade/renderer/dynamic/GPUDynamicMeshResidency.js +1 -1
- package/src/shade/renderer/geometry/bvh/GPUGeometryBVHManager.d.ts.map +1 -1
- package/src/shade/renderer/geometry/bvh/GPUGeometryBVHManager.js +6 -5
- package/src/shade/renderer/geometry/meshlet/GPUMeshletManager.d.ts +3 -3
- package/src/shade/renderer/geometry/meshlet/GPUMeshletManager.d.ts.map +1 -1
- package/src/shade/renderer/geometry/meshlet/GPUMeshletManager.js +15 -11
- package/src/shade/renderer/global_illumination/brick4/cpu/brick4_bake_for_scene.d.ts +1 -1
- package/src/shade/renderer/global_illumination/brick4/cpu/brick4_bake_for_scene.js +4 -4
- package/src/shade/renderer/global_illumination/brick4/cpu/brick4_generate_tree_from_scene.d.ts +1 -3
- package/src/shade/renderer/global_illumination/brick4/cpu/brick4_generate_tree_from_scene.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/brick4/cpu/brick4_generate_tree_from_scene.js +5 -4
- package/src/shade/renderer/global_illumination/brick4/gpu/bake/brick4_bake_basic.js +1 -1
- package/src/shade/renderer/global_illumination/lpv/bake/GPULightProbeVolumeRenderer.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/lpv/bake/GPULightProbeVolumeRenderer.js +1 -4
- package/src/shade/renderer/global_illumination/lpv/lpv_visualise_probes.d.ts +8 -3
- package/src/shade/renderer/global_illumination/lpv/lpv_visualise_probes.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/lpv/lpv_visualise_probes.js +19 -14
- package/src/shade/renderer/global_illumination/lpv/placement/graph_generate_probe_locations.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/lpv/placement/graph_generate_probe_locations.js +9 -1
- package/src/shade/renderer/global_illumination/lpv/placement/software/lpv_generate_probe_locations2.d.ts +3 -3
- package/src/shade/renderer/global_illumination/lpv/placement/software/lpv_generate_probe_locations2.d.ts.map +1 -1
- package/src/shade/renderer/global_illumination/lpv/placement/software/lpv_generate_probe_locations2.js +12 -5
- package/src/shade/renderer/global_illumination/probe/octahedral/GPUProbeAtlas.js +1 -1
- package/src/shade/renderer/light/GPULightCollection.d.ts +29 -0
- package/src/shade/renderer/light/GPULightCollection.d.ts.map +1 -1
- package/src/shade/renderer/light/GPULightCollection.js +444 -329
- package/src/shade/renderer/light/LIGHT_DATABASE_SPEC.d.ts.map +1 -1
- package/src/shade/renderer/light/LIGHT_DATABASE_SPEC.js +7 -1
- package/src/shade/renderer/light/LightCollection.d.ts +29 -1
- package/src/shade/renderer/light/LightCollection.d.ts.map +1 -1
- package/src/shade/renderer/light/LightCollection.js +50 -1
- package/src/shade/renderer/light/make_sunlight.js +2 -2
- package/src/shade/renderer/light/model/Light.d.ts +29 -2
- package/src/shade/renderer/light/model/Light.d.ts.map +1 -1
- package/src/shade/renderer/light/model/Light.js +30 -2
- package/src/shade/renderer/light/model/io/light_record_directional.d.ts +3 -1
- package/src/shade/renderer/light/model/io/light_record_directional.d.ts.map +1 -1
- package/src/shade/renderer/light/model/io/light_record_directional.js +8 -5
- package/src/shade/renderer/light/model/io/light_record_point.d.ts +3 -1
- package/src/shade/renderer/light/model/io/light_record_point.d.ts.map +1 -1
- package/src/shade/renderer/light/model/io/light_record_point.js +5 -2
- package/src/shade/renderer/light/model/io/light_record_spot.d.ts +4 -1
- package/src/shade/renderer/light/model/io/light_record_spot.d.ts.map +1 -1
- package/src/shade/renderer/light/model/io/light_record_spot.js +10 -6
- package/src/shade/renderer/light/place_light.d.ts +16 -0
- package/src/shade/renderer/light/place_light.d.ts.map +1 -0
- package/src/shade/renderer/light/place_light.js +36 -0
- package/src/shade/renderer/light/shader_refresh_light_poses.d.ts +44 -0
- package/src/shade/renderer/light/shader_refresh_light_poses.d.ts.map +1 -0
- package/src/shade/renderer/light/shader_refresh_light_poses.js +154 -0
- package/src/shade/renderer/lightmap/GPULightMap.js +1 -1
- package/src/shade/renderer/lightmap/bake/raster/graph_draw_lightmap_viz_buffer.d.ts.map +1 -1
- package/src/shade/renderer/lightmap/bake/raster/graph_draw_lightmap_viz_buffer.js +12 -14
- package/src/shade/renderer/loader/SceneBundle.d.ts +53 -28
- package/src/shade/renderer/loader/SceneBundle.d.ts.map +1 -1
- package/src/shade/renderer/loader/SceneBundle.js +111 -56
- package/src/shade/renderer/loader/SceneNode.d.ts +81 -0
- package/src/shade/renderer/loader/SceneNode.d.ts.map +1 -0
- package/src/shade/renderer/loader/SceneNode.js +114 -0
- package/src/shade/renderer/loader/gltf/load_gltf.d.ts +3 -2
- package/src/shade/renderer/loader/gltf/load_gltf.d.ts.map +1 -1
- package/src/shade/renderer/loader/gltf/load_gltf.js +110 -142
- package/src/shade/renderer/loader/gltf/tiny-gltf.d.ts +1 -1
- package/src/shade/renderer/loader/usd/UsdExtensionRegistry.d.ts +4 -4
- package/src/shade/renderer/loader/usd/UsdExtensionRegistry.d.ts.map +1 -1
- package/src/shade/renderer/loader/usd/UsdExtensionRegistry.js +2 -2
- package/src/shade/renderer/loader/usd/load_usd.d.ts +3 -2
- package/src/shade/renderer/loader/usd/load_usd.d.ts.map +1 -1
- package/src/shade/renderer/loader/usd/load_usd.js +4 -5
- package/src/shade/renderer/loader/usd/usd_build_scene.d.ts +3 -3
- package/src/shade/renderer/loader/usd/usd_build_scene.d.ts.map +1 -1
- package/src/shade/renderer/loader/usd/usd_build_scene.js +47 -55
- package/src/shade/renderer/material/GPUMaterialManager.js +1 -1
- package/src/shade/renderer/material/resident/GPUResidentMaterialContext.d.ts +5 -4
- package/src/shade/renderer/material/resident/GPUResidentMaterialContext.d.ts.map +1 -1
- package/src/shade/renderer/material/resident/GPUResidentMaterialContext.js +8 -15
- package/src/shade/renderer/object_property/shader_refresh_all_mesh_bounds.d.ts +15 -13
- 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 +40 -21
- package/src/shade/renderer/particles/DESIGN.md +53 -50
- package/src/shade/renderer/particles/GPUParticleSystem.d.ts +31 -17
- package/src/shade/renderer/particles/GPUParticleSystem.d.ts.map +1 -1
- package/src/shade/renderer/particles/GPUParticleSystem.js +54 -91
- package/src/shade/renderer/particles/runtime/EmitterRegistry.d.ts +12 -11
- package/src/shade/renderer/particles/runtime/EmitterRegistry.d.ts.map +1 -1
- package/src/shade/renderer/particles/runtime/EmitterRegistry.js +12 -11
- package/src/shade/renderer/particles/runtime/GPUParticleEmitterContext.d.ts +13 -19
- package/src/shade/renderer/particles/runtime/GPUParticleEmitterContext.d.ts.map +1 -1
- package/src/shade/renderer/particles/runtime/GPUParticleEmitterContext.js +19 -25
- package/src/shade/renderer/particles/runtime/ParticleEmitter.d.ts +34 -24
- package/src/shade/renderer/particles/runtime/ParticleEmitter.d.ts.map +1 -1
- package/src/shade/renderer/particles/runtime/ParticleEmitter.js +53 -40
- package/src/shade/renderer/path_tracer/accumulating/AccumulatingPathTracer.js +1 -1
- package/src/shade/renderer/path_tracer/graph_path_trace_scene.js +1 -1
- package/src/shade/renderer/postprocess/nss/NSS.d.ts +1 -1
- package/src/shade/renderer/rasterize/expand/bucket/mesh/graph_meshes_classify_buckets.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/expand/bucket/mesh/graph_meshes_classify_buckets.js +2 -1
- package/src/shade/renderer/rasterize/expand/bucket/mesh/graph_scene_meshes_cull_and_classify_buckets.d.ts.map +1 -1
- package/src/shade/renderer/rasterize/expand/bucket/mesh/graph_scene_meshes_cull_and_classify_buckets.js +5 -2
- package/src/shade/renderer/rasterize/fast/graph_rasterize_scene_fast.js +1 -1
- package/src/shade/renderer/rasterize/native/avboit/graph_rasterize_meshes_transparent_avboit.js +1 -1
- package/src/shade/renderer/rasterize/native/graph_rasterize_meshes_alpha_tested.js +1 -1
- package/src/shade/renderer/rasterize/native/oit/graph_rasterize_meshes_transparent_oit.js +1 -1
- package/src/shade/renderer/rasterize/standard/graph_rasterize_scene.js +1 -1
- package/src/shade/renderer/scene/DynamicMesh.d.ts +13 -4
- package/src/shade/renderer/scene/DynamicMesh.d.ts.map +1 -1
- package/src/shade/renderer/scene/DynamicMesh.js +14 -4
- package/src/shade/renderer/scene/GPUInstancesAccelerationStructure.d.ts +38 -18
- package/src/shade/renderer/scene/GPUInstancesAccelerationStructure.d.ts.map +1 -1
- package/src/shade/renderer/scene/GPUInstancesAccelerationStructure.js +112 -60
- package/src/shade/renderer/scene/GPUSceneContext.d.ts +55 -48
- package/src/shade/renderer/scene/GPUSceneContext.d.ts.map +1 -1
- package/src/shade/renderer/scene/GPUSceneContext.js +594 -928
- package/src/shade/renderer/scene/NODE3D_STRUCT.d.ts +5 -5
- package/src/shade/renderer/scene/NODE3D_STRUCT.js +5 -5
- package/src/shade/renderer/scene/Node3D.d.ts +27 -8
- package/src/shade/renderer/scene/Node3D.d.ts.map +1 -1
- package/src/shade/renderer/scene/Node3DDirtyList.d.ts +59 -0
- package/src/shade/renderer/scene/Node3DDirtyList.d.ts.map +1 -0
- package/src/shade/renderer/scene/Scene.d.ts +18 -60
- package/src/shade/renderer/scene/Scene.d.ts.map +1 -1
- package/src/shade/renderer/scene/Scene.js +53 -146
- package/src/shade/renderer/scene/SkinnedMesh.d.ts +10 -93
- package/src/shade/renderer/scene/SkinnedMesh.d.ts.map +1 -1
- package/src/shade/renderer/scene/bvh/StaticSceneBVH.d.ts +24 -3
- package/src/shade/renderer/scene/bvh/StaticSceneBVH.d.ts.map +1 -1
- package/src/shade/renderer/scene/bvh/StaticSceneBVH.js +53 -13
- package/src/shade/renderer/scene/hierarchy/graph_scene_update_transform_hierarchy.d.ts +5 -6
- package/src/shade/renderer/scene/hierarchy/graph_scene_update_transform_hierarchy.d.ts.map +1 -1
- package/src/shade/renderer/scene/hierarchy/graph_scene_update_transform_hierarchy.js +5 -6
- package/src/shade/renderer/scene/optimization/scene_optimize.d.ts +10 -2
- package/src/shade/renderer/scene/optimization/scene_optimize.d.ts.map +1 -1
- package/src/shade/renderer/scene/optimization/scene_optimize.js +266 -230
- package/src/shade/renderer/scene/rows/GPUEntityBoundsReadback.d.ts +53 -0
- package/src/shade/renderer/scene/rows/GPUEntityBoundsReadback.d.ts.map +1 -0
- package/src/shade/renderer/scene/rows/GPUEntityBoundsReadback.js +144 -0
- package/src/shade/renderer/scene/rows/GPUSceneRows.d.ts +227 -0
- package/src/shade/renderer/scene/rows/GPUSceneRows.d.ts.map +1 -0
- package/src/shade/renderer/scene/rows/GPUSceneRows.js +1136 -0
- package/src/shade/renderer/scene/rows/place_primitive.d.ts +48 -0
- package/src/shade/renderer/scene/rows/place_primitive.d.ts.map +1 -0
- package/src/shade/renderer/scene/rows/place_primitive.js +98 -0
- package/src/shade/renderer/scene/serialization/deserialize_scene.d.ts +10 -8
- package/src/shade/renderer/scene/serialization/deserialize_scene.d.ts.map +1 -1
- package/src/shade/renderer/scene/serialization/deserialize_scene.js +24 -27
- package/src/shade/renderer/scene/serialization/serialize_scene.d.ts +9 -2
- package/src/shade/renderer/scene/serialization/serialize_scene.d.ts.map +1 -1
- package/src/shade/renderer/scene/serialization/serialize_scene.js +25 -4
- package/src/shade/renderer/scene/verify_gpu_tlas_build.js +2 -2
- package/src/shade/renderer/shader/chunk/light/DIRECTIONAL_LIGHT_STRUCT.d.ts.map +1 -1
- package/src/shade/renderer/shader/chunk/light/DIRECTIONAL_LIGHT_STRUCT.js +5 -0
- package/src/shade/renderer/shader/chunk/light/POINT_LIGHT_STRUCT.d.ts.map +1 -1
- package/src/shade/renderer/shader/chunk/light/POINT_LIGHT_STRUCT.js +5 -0
- package/src/shade/renderer/shader/chunk/light/SPOT_LIGHT_STRUCT.d.ts.map +1 -1
- package/src/shade/renderer/shader/chunk/light/SPOT_LIGHT_STRUCT.js +5 -0
- package/src/shade/renderer/shadow/map/DirectionalLightShadowmap.d.ts +39 -0
- package/src/shade/renderer/shadow/map/DirectionalLightShadowmap.d.ts.map +1 -1
- package/src/shade/renderer/shadow/map/DirectionalLightShadowmap.js +112 -64
- package/src/shade/renderer/shadow/map/GPUSceneShadowmapContext.d.ts +7 -0
- package/src/shade/renderer/shadow/map/GPUSceneShadowmapContext.d.ts.map +1 -1
- package/src/shade/renderer/shadow/map/GPUSceneShadowmapContext.js +1541 -1352
- package/src/shade/renderer/shadow/map/PointLightShadowmap.js +1 -1
- package/src/shade/renderer/shadow/map/SpotLightShadowmap.js +1 -1
- package/src/shade/renderer/shadow/map/TetrahedronPointLightShadowmap.js +1 -1
- package/src/shade/renderer/shadow/map/csm/CSM_CASTER_RANGE_STRUCT.d.ts +29 -0
- package/src/shade/renderer/shadow/map/csm/CSM_CASTER_RANGE_STRUCT.d.ts.map +1 -0
- package/src/shade/renderer/shadow/map/csm/CSM_CASTER_RANGE_STRUCT.js +43 -0
- package/src/shade/renderer/shadow/map/csm/SHADOWMAP_CSM_CASTER_RANGE_MARGIN_FRACTION.d.ts +13 -0
- package/src/shade/renderer/shadow/map/csm/SHADOWMAP_CSM_CASTER_RANGE_MARGIN_FRACTION.d.ts.map +1 -0
- package/src/shade/renderer/shadow/map/csm/SHADOWMAP_CSM_CASTER_RANGE_MARGIN_FRACTION.js +12 -0
- package/src/shade/renderer/shadow/map/csm/shader/shader_csm_caster_range.d.ts +49 -0
- package/src/shade/renderer/shadow/map/csm/shader/shader_csm_caster_range.d.ts.map +1 -0
- package/src/shade/renderer/shadow/map/csm/shader/shader_csm_caster_range.js +194 -0
- package/src/shade/renderer/shadow/map/csm_debug_draw_preview.js +1 -1
- package/src/shade/renderer/shadow/map/shadowmap_update_score.js +1 -1
- package/src/shade/renderer/shadow/ray/RTXShadows.js +1 -1
- package/src/shade/renderer/shadow/ray/staged/trace/graph_trace_rays.js +1 -1
- package/src/shade/renderer/shadow/sdf/cascade/CascadedSceneSDF.d.ts.map +1 -1
- package/src/shade/renderer/shadow/sdf/cascade/CascadedSceneSDF.js +3 -1
- package/src/shade/renderer/texture/bindless/GPUBindlessTextureManager.js +8 -8
- package/src/shade/renderer/volumetrics/GPUViewVolumetrics.d.ts.map +1 -1
- package/src/shade/renderer/volumetrics/GPUViewVolumetrics.js +4 -3
- package/src/engine/graphics3/instantiate_scene_bundle.js +0 -164
- package/src/engine/graphics3/shade_node_to_entity_composition.js +0 -88
- package/src/shade/renderer/animation/compute_skin_world_bounds.js +0 -146
- package/src/shade/renderer/animation/compute_skinned_mesh_clip_bounding_sphere.js +0 -531
- package/src/shade/renderer/animation/pose/pose_evaluate_world.js +0 -76
- package/src/shade/renderer/animation/skin_bind_transform.js +0 -33
- package/src/shade/renderer/animation/skin_frame_defect.js +0 -132
- package/src/shade/renderer/animation/skin_joint_matrix.js +0 -46
- package/src/shade/renderer/animation/skin_normalize_mesh_frame.js +0 -216
- package/src/shade/renderer/scene/InstanceBatch.js +0 -235
- package/src/shade/renderer/scene/Mesh.js +0 -168
- package/src/shade/renderer/scene/Node3D.js +0 -263
- package/src/shade/renderer/scene/SceneNodeBinding.js +0 -56
- package/src/shade/renderer/scene/SkinnedMesh.js +0 -170
- package/src/shade/renderer/scene/TransformAuthority.js +0 -33
|
@@ -1,928 +1,594 @@
|
|
|
1
|
-
import { assert } from "../../../core/assert.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
10
|
-
import {
|
|
11
|
-
import {
|
|
12
|
-
import {
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
import {
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
*
|
|
70
|
-
*/
|
|
71
|
-
export class GPUSceneContext {
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* @readonly
|
|
75
|
-
* @type {number}
|
|
76
|
-
*/
|
|
77
|
-
id = id_counter++;
|
|
78
|
-
|
|
79
|
-
/**
|
|
80
|
-
* @type {GPUGeometryManager}
|
|
81
|
-
*/
|
|
82
|
-
geometries;
|
|
83
|
-
|
|
84
|
-
/**
|
|
85
|
-
* @type {GPUMaterialManager}
|
|
86
|
-
*/
|
|
87
|
-
materials;
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
/**
|
|
91
|
-
* @type {Brick4LightMap}
|
|
92
|
-
*/
|
|
93
|
-
volumetric_light_map;
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
/**
|
|
97
|
-
*
|
|
98
|
-
* @type {Scene}
|
|
99
|
-
*/
|
|
100
|
-
#scene;
|
|
101
|
-
|
|
102
|
-
/**
|
|
103
|
-
*
|
|
104
|
-
* @return {Scene}
|
|
105
|
-
*/
|
|
106
|
-
get scene() {
|
|
107
|
-
return this.#scene;
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
/**
|
|
111
|
-
* @type {GPUSceneVolumetrics}
|
|
112
|
-
*/
|
|
113
|
-
#volumetrics;
|
|
114
|
-
|
|
115
|
-
get volumetrics() {
|
|
116
|
-
return this.#volumetrics;
|
|
117
|
-
}
|
|
118
|
-
|
|
119
|
-
/**
|
|
120
|
-
* @type {GPULightCollection}
|
|
121
|
-
*/
|
|
122
|
-
#lights;
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
/**
|
|
126
|
-
*
|
|
127
|
-
* @returns {GPULightCollection}
|
|
128
|
-
*/
|
|
129
|
-
get lights() {
|
|
130
|
-
return this.#lights;
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
/**
|
|
134
|
-
* @type {GPULightProbeVolume}
|
|
135
|
-
*/
|
|
136
|
-
#light_probe_volume;
|
|
137
|
-
|
|
138
|
-
/**
|
|
139
|
-
*
|
|
140
|
-
* @returns {GPULightProbeVolume}
|
|
141
|
-
*/
|
|
142
|
-
get light_probe_volume() {
|
|
143
|
-
return this.#light_probe_volume;
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
/**
|
|
147
|
-
* @type {GPUInstancesAccelerationStructure}
|
|
148
|
-
*/
|
|
149
|
-
#tlas
|
|
150
|
-
|
|
151
|
-
/**
|
|
152
|
-
*
|
|
153
|
-
* @returns {GPUInstancesAccelerationStructure}
|
|
154
|
-
*/
|
|
155
|
-
get tlas() {
|
|
156
|
-
return this.#tlas;
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
/**
|
|
160
|
-
* GPU-resident scene database — mesh metadata in the `meshes` table,
|
|
161
|
-
*
|
|
162
|
-
*
|
|
163
|
-
*
|
|
164
|
-
* `
|
|
165
|
-
*
|
|
166
|
-
* @type {GPUDatabase}
|
|
167
|
-
*/
|
|
168
|
-
#scene_database;
|
|
169
|
-
|
|
170
|
-
/**
|
|
171
|
-
*
|
|
172
|
-
*
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
*
|
|
180
|
-
*
|
|
181
|
-
*
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
*
|
|
187
|
-
*
|
|
188
|
-
*
|
|
189
|
-
* @
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
*
|
|
199
|
-
*
|
|
200
|
-
*
|
|
201
|
-
*
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
*
|
|
211
|
-
*
|
|
212
|
-
*
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
this.#
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
this.#
|
|
239
|
-
|
|
240
|
-
this
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
});
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
#
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
* @
|
|
267
|
-
*/
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
*
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
*
|
|
285
|
-
*
|
|
286
|
-
*
|
|
287
|
-
* @
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
get
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
return
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
*
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
*
|
|
354
|
-
*
|
|
355
|
-
*
|
|
356
|
-
*
|
|
357
|
-
*
|
|
358
|
-
*
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
*
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
}
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
//
|
|
404
|
-
//
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
//
|
|
472
|
-
|
|
473
|
-
//
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
*
|
|
496
|
-
*
|
|
497
|
-
*
|
|
498
|
-
*
|
|
499
|
-
*
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
*
|
|
509
|
-
*
|
|
510
|
-
*
|
|
511
|
-
*
|
|
512
|
-
*
|
|
513
|
-
*
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
const
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
* @param {Node3D} node
|
|
596
|
-
* @param {number} parent_row
|
|
597
|
-
* @param {GPUTypedTable} transforms_table
|
|
598
|
-
* @returns {number}
|
|
599
|
-
*/
|
|
600
|
-
#add_transform_row(node, parent_row, transforms_table) {
|
|
601
|
-
const row = transforms_table.add(EMPTY_TRANSFORM_RECORD);
|
|
602
|
-
|
|
603
|
-
this.#seed_published_global(node, row);
|
|
604
|
-
|
|
605
|
-
transforms_table.set(row, this.#write_transform_record(node, row, parent_row));
|
|
606
|
-
|
|
607
|
-
return row;
|
|
608
|
-
}
|
|
609
|
-
|
|
610
|
-
/**
|
|
611
|
-
* Take a node's rows back. The rows are freed, not reassigned — see {@link SceneNodeBinding}.
|
|
612
|
-
*
|
|
613
|
-
* @param {Node3D} node
|
|
614
|
-
* @param {SceneNodeBinding} binding
|
|
615
|
-
* @param {GPUTypedTable} transforms_table
|
|
616
|
-
* @param {GPUTypedTable} meshes_table
|
|
617
|
-
*/
|
|
618
|
-
#remove_node(node, binding, transforms_table, meshes_table) {
|
|
619
|
-
if (node.isMesh === true) {
|
|
620
|
-
const mesh_row = binding.mesh_row;
|
|
621
|
-
|
|
622
|
-
meshes_table.remove(mesh_row);
|
|
623
|
-
this.#tlas.instance_remove(mesh_row);
|
|
624
|
-
|
|
625
|
-
this.#mesh_rows_version++;
|
|
626
|
-
|
|
627
|
-
this.#instance_metadata[mesh_row * 2] = 0;
|
|
628
|
-
this.#instance_metadata[mesh_row * 2 + 1] = 0;
|
|
629
|
-
|
|
630
|
-
// A skinned mesh renders a per-instance copy of its geometry, and the row just
|
|
631
|
-
// given back was the only thing naming it. This is where that copy — its vertex
|
|
632
|
-
// region, its BLAS and its prev-position slice — goes back too; nothing else in
|
|
633
|
-
// the engine sees a mesh leave, and unbinding deliberately does not free it.
|
|
634
|
-
if (node.isSkinnedMesh === true) {
|
|
635
|
-
this.skinning.release_clone(node);
|
|
636
|
-
}
|
|
637
|
-
}
|
|
638
|
-
|
|
639
|
-
transforms_table.remove(binding.transform_row);
|
|
640
|
-
|
|
641
|
-
this.id_mapping.delete(node.id);
|
|
642
|
-
this.#bindings.delete(node);
|
|
643
|
-
}
|
|
644
|
-
|
|
645
|
-
/**
|
|
646
|
-
* Bring the database's membership in line with the scene's: nodes that arrived get rows, nodes
|
|
647
|
-
* that left give theirs back. Runs only when the batch reports a change, so the per-frame path
|
|
648
|
-
* never pays for it.
|
|
649
|
-
*
|
|
650
|
-
* @param {GPUTypedTable} transforms_table
|
|
651
|
-
* @param {GPUTypedTable} meshes_table
|
|
652
|
-
* @returns {number} rows written
|
|
653
|
-
*/
|
|
654
|
-
#sync_membership(transforms_table, meshes_table) {
|
|
655
|
-
const epoch = ++this.#epoch;
|
|
656
|
-
|
|
657
|
-
let written = 0;
|
|
658
|
-
|
|
659
|
-
const scene = this.#scene;
|
|
660
|
-
|
|
661
|
-
// The scene root must land at row 0 — it is both the hierarchy walk's terminator and the
|
|
662
|
-
// natural value of any zero-initialised buffer.
|
|
663
|
-
let scene_binding = this.#bindings.get(scene);
|
|
664
|
-
|
|
665
|
-
if (scene_binding === undefined) {
|
|
666
|
-
scene_binding = this.#add_node(scene, transforms_table, meshes_table);
|
|
667
|
-
|
|
668
|
-
assert.equal(scene_binding.transform_row, NODE3D_SCENE_ID, 'scene must land at transforms table row 0');
|
|
669
|
-
|
|
670
|
-
written++;
|
|
671
|
-
}
|
|
672
|
-
|
|
673
|
-
scene_binding.epoch = epoch;
|
|
674
|
-
|
|
675
|
-
const nodes = this.#scene.instances.nodes;
|
|
676
|
-
const node_count = nodes.length;
|
|
677
|
-
|
|
678
|
-
// Nodes whose parent had not been placed when they were. `Scene.add` walks parents before
|
|
679
|
-
// children, so this is empty unless a caller added a child to the scene ahead of its
|
|
680
|
-
// parent.
|
|
681
|
-
const orphaned = [];
|
|
682
|
-
|
|
683
|
-
for (let i = 0; i < node_count; i++) {
|
|
684
|
-
const node = nodes[i];
|
|
685
|
-
|
|
686
|
-
let binding = this.#bindings.get(node);
|
|
687
|
-
|
|
688
|
-
if (binding === undefined) {
|
|
689
|
-
binding = this.#add_node(node, transforms_table, meshes_table);
|
|
690
|
-
|
|
691
|
-
written++;
|
|
692
|
-
|
|
693
|
-
if (node.parent !== null && this.id_mapping.get(node.parent.id) === undefined) {
|
|
694
|
-
orphaned.push(node);
|
|
695
|
-
}
|
|
696
|
-
}
|
|
697
|
-
|
|
698
|
-
binding.epoch = epoch;
|
|
699
|
-
}
|
|
700
|
-
|
|
701
|
-
for (let i = 0; i < orphaned.length; i++) {
|
|
702
|
-
const node = orphaned[i];
|
|
703
|
-
const parent_row = this.id_mapping.get(node.parent.id);
|
|
704
|
-
|
|
705
|
-
if (parent_row === undefined) {
|
|
706
|
-
// the parent really is not in this scene — the scene root stands
|
|
707
|
-
continue;
|
|
708
|
-
}
|
|
709
|
-
|
|
710
|
-
const binding = this.#bindings.get(node);
|
|
711
|
-
|
|
712
|
-
transforms_table.set(
|
|
713
|
-
binding.transform_row,
|
|
714
|
-
this.#write_transform_record(node, binding.transform_row, parent_row)
|
|
715
|
-
);
|
|
716
|
-
}
|
|
717
|
-
|
|
718
|
-
for (const [node, binding] of this.#bindings) {
|
|
719
|
-
if (binding.epoch !== epoch) {
|
|
720
|
-
this.#remove_node(node, binding, transforms_table, meshes_table);
|
|
721
|
-
|
|
722
|
-
written++;
|
|
723
|
-
}
|
|
724
|
-
}
|
|
725
|
-
|
|
726
|
-
return written;
|
|
727
|
-
}
|
|
728
|
-
|
|
729
|
-
/**
|
|
730
|
-
* Push every node that has moved since its row was last written, and nothing else.
|
|
731
|
-
*
|
|
732
|
-
* Rows the GPU owns are left alone entirely — see {@link TransformAuthority}. Their nodes still
|
|
733
|
-
* report movement (a CPU-driven parent recursing through `updateMatrices` is enough to mark
|
|
734
|
-
* every joint under it), and acting on that report is exactly the collision authority exists to
|
|
735
|
-
* prevent.
|
|
736
|
-
*
|
|
737
|
-
* @param {GPUTypedTable} transforms_table
|
|
738
|
-
* @param {GPUTypedTable} meshes_table
|
|
739
|
-
* @returns {number} rows written
|
|
740
|
-
*/
|
|
741
|
-
#sync_transforms(transforms_table, meshes_table) {
|
|
742
|
-
let written = 0;
|
|
743
|
-
|
|
744
|
-
for (const [node, binding] of this.#bindings) {
|
|
745
|
-
const authority = node.transform_authority;
|
|
746
|
-
const handed_back = authority !== binding.authority && authority === TransformAuthority.CPU;
|
|
747
|
-
|
|
748
|
-
binding.authority = authority;
|
|
749
|
-
|
|
750
|
-
if (authority === TransformAuthority.GPU) {
|
|
751
|
-
continue;
|
|
752
|
-
}
|
|
753
|
-
|
|
754
|
-
const version = node.version;
|
|
755
|
-
|
|
756
|
-
// A row just handed back has to be written whatever the version says: nothing moved it
|
|
757
|
-
// while the GPU held it, so there is no change to notice, and the row it is taking over
|
|
758
|
-
// holds a pose the CPU never wrote.
|
|
759
|
-
if (version === binding.version && !handed_back) {
|
|
760
|
-
continue;
|
|
761
|
-
}
|
|
762
|
-
|
|
763
|
-
if (handed_back) {
|
|
764
|
-
// Taking over from an unknown pose — seed the published matrix the way a fresh row
|
|
765
|
-
// is seeded, so the first frame back reports no velocity rather than a jump.
|
|
766
|
-
this.#seed_published_global(node, binding.transform_row);
|
|
767
|
-
}
|
|
768
|
-
|
|
769
|
-
binding.version = version;
|
|
770
|
-
written++;
|
|
771
|
-
|
|
772
|
-
const transform_row = binding.transform_row;
|
|
773
|
-
|
|
774
|
-
transforms_table.set(
|
|
775
|
-
transform_row,
|
|
776
|
-
this.#write_transform_record(node, transform_row, this.#resolve_parent_row(node))
|
|
777
|
-
);
|
|
778
|
-
|
|
779
|
-
if (node.isMesh !== true) {
|
|
780
|
-
continue;
|
|
781
|
-
}
|
|
782
|
-
|
|
783
|
-
// World-space bounds moved with the node, and culling reads them off the mesh row.
|
|
784
|
-
const mesh_row = binding.mesh_row;
|
|
785
|
-
|
|
786
|
-
meshes_table.set(mesh_row, this.#write_mesh_record(node, transform_row));
|
|
787
|
-
|
|
788
|
-
this.#instance_metadata[mesh_row * 2 + 1] = version;
|
|
789
|
-
|
|
790
|
-
this.#tlas.instance_update(mesh_row, node);
|
|
791
|
-
}
|
|
792
|
-
|
|
793
|
-
return written;
|
|
794
|
-
}
|
|
795
|
-
|
|
796
|
-
/**
|
|
797
|
-
* Bring the GPU scene database in line with the scene, writing only the rows that changed.
|
|
798
|
-
*
|
|
799
|
-
* Membership is reconciled when the batch says it moved; transforms are checked every frame,
|
|
800
|
-
* because a node moving does not touch the batch. Both walk the scene once and write nothing
|
|
801
|
-
* for a node that has not changed.
|
|
802
|
-
*/
|
|
803
|
-
build() {
|
|
804
|
-
|
|
805
|
-
const batch = this.#scene.instances;
|
|
806
|
-
|
|
807
|
-
const meshes_table = this.#scene_database.get('meshes');
|
|
808
|
-
const transforms_table = this.#scene_database.get('transforms');
|
|
809
|
-
|
|
810
|
-
let written = 0;
|
|
811
|
-
|
|
812
|
-
if (this.#instances_version !== batch.version) {
|
|
813
|
-
written += this.#sync_membership(transforms_table, meshes_table);
|
|
814
|
-
|
|
815
|
-
this.#instances_version = batch.version;
|
|
816
|
-
}
|
|
817
|
-
|
|
818
|
-
written += this.#sync_transforms(transforms_table, meshes_table);
|
|
819
|
-
|
|
820
|
-
if (written === 0) {
|
|
821
|
-
return;
|
|
822
|
-
}
|
|
823
|
-
|
|
824
|
-
// Flush the scene database — only the rows that changed carry an upload record.
|
|
825
|
-
const cmd = ShadeGPUCommandContext.create(this.#graphics, 'GPUSceneContext/database-build');
|
|
826
|
-
|
|
827
|
-
// Also flush the global geometry manager. The first time a scene
|
|
828
|
-
// sees a new mesh, scene.build's `obtain_geometry_index` calls
|
|
829
|
-
// `geometries.add(...)` which registers the source MeshletGeometry
|
|
830
|
-
// and flips `geometries.__needs_update = true`. The next per-frame
|
|
831
|
-
// `graphics.update()` would normally rebuild
|
|
832
|
-
// `geometries.buffer_metadata` to reflect those new entries — but
|
|
833
|
-
// `graphics.update()` runs at the *head* of `Renderer.#begin_frame`,
|
|
834
|
-
// *before* this scene.build, so the buffer_metadata stays whatever
|
|
835
|
-
// it was at the start of the frame (often the zero-record placeholder
|
|
836
|
-
// from the renderer's startup build, when the scene's geometries
|
|
837
|
-
// hadn't been registered yet).
|
|
838
|
-
//
|
|
839
|
-
// Any pass reading `geometries[mesh.geometry]` later in the frame
|
|
840
|
-
// (rasterization meshlet expansion, `shader_refresh_all_mesh_bounds`,
|
|
841
|
-
// etc.) sees zeros — `meshlets_count = 0` produces no triangles and
|
|
842
|
-
// `bounding_box = (0,0,0)-(0,0,0)` collapses world bounds to a
|
|
843
|
-
// single point in `shader_refresh_all_mesh_bounds`, which then writes
|
|
844
|
-
// those collapsed bounds back into `meshes_table`. Subsequent frames
|
|
845
|
-
// get a correct `buffer_metadata` from the next `graphics.update()`,
|
|
846
|
-
// but the `meshes_table` bounds stay collapsed until refresh_all
|
|
847
|
-
// overwrites them again — and frustum cull on the collapsed bounds
|
|
848
|
-
// can drop meshes whose collapsed point sits outside the frustum.
|
|
849
|
-
//
|
|
850
|
-
// Symptom: stress test rendered ground (whose collapsed point at the
|
|
851
|
-
// origin survives the cull) but dropped most trees (whose collapsed
|
|
852
|
-
// points scattered across the grid trigger cull edge cases).
|
|
853
|
-
//
|
|
854
|
-
// Calling `geometries.update(cmd)` here ensures the new buffer is in
|
|
855
|
-
// place before any pass in the same frame reads it. Idempotent / no-op
|
|
856
|
-
// when nothing's queued, so the per-frame `graphics.update` head call
|
|
857
|
-
// and this build-time call together leave the buffer in the right
|
|
858
|
-
// state under both lifetimes.
|
|
859
|
-
this.geometries.update(cmd);
|
|
860
|
-
|
|
861
|
-
this.#scene_database.update(cmd);
|
|
862
|
-
cmd.finish();
|
|
863
|
-
}
|
|
864
|
-
|
|
865
|
-
/**
|
|
866
|
-
*
|
|
867
|
-
* @param {GraphicsContext} ctx
|
|
868
|
-
*/
|
|
869
|
-
update(ctx) {
|
|
870
|
-
assert.defined(ctx, 'ctx');
|
|
871
|
-
|
|
872
|
-
// TODO add a fast update check, so that calling this multiple times per frame can be fast.
|
|
873
|
-
|
|
874
|
-
this.#light_probe_volume.update();
|
|
875
|
-
this.#lights.update(ctx);
|
|
876
|
-
this.#volumetrics.update(ctx, 0);
|
|
877
|
-
|
|
878
|
-
// Per-frame animation database flush — picks up any new clips,
|
|
879
|
-
// tracks, skins, or per-frame `set_time` writes queued since
|
|
880
|
-
// last frame. Idempotent / cheap when nothing's queued.
|
|
881
|
-
const animation_cmd = ShadeGPUCommandContext.create(this.#graphics, 'GPUSceneContext/animation-flush');
|
|
882
|
-
this.#animation_manager.update(animation_cmd);
|
|
883
|
-
animation_cmd.finish();
|
|
884
|
-
|
|
885
|
-
// TODO update SDF
|
|
886
|
-
|
|
887
|
-
this.build();
|
|
888
|
-
|
|
889
|
-
// After the build, which is what feeds the TLAS this frame's arrivals, departures and moves —
|
|
890
|
-
// and, for the GPU build, writes the world AABBs it reads out of the `meshes` table.
|
|
891
|
-
this.#tlas.update(this.scene_database_buffer);
|
|
892
|
-
}
|
|
893
|
-
|
|
894
|
-
/**
|
|
895
|
-
* Per-frame animation tick — drains pending registrations,
|
|
896
|
-
* advances `clip.time` on the GPU, runs apply → resolve →
|
|
897
|
-
* hierarchy propagate → skin-matrix prep → skinning. Thin
|
|
898
|
-
* passthrough to {@link GPUAnimationManager#tick}; lives here
|
|
899
|
-
* so the renderer can call it on every scene it renders without
|
|
900
|
-
* reaching past `GPUSceneContext` for an internal manager.
|
|
901
|
-
*
|
|
902
|
-
* `dt_seconds` is wall-clock seconds since the last call (the
|
|
903
|
-
* renderer's `time_delta_seconds` argument to `render()`).
|
|
904
|
-
*
|
|
905
|
-
* @param {ShadeGPUCommandContext} cmd_ctx
|
|
906
|
-
* @param {number} dt_seconds wall-clock seconds since last call
|
|
907
|
-
*/
|
|
908
|
-
tick(cmd_ctx, dt_seconds) {
|
|
909
|
-
this.#animation_manager.tick(cmd_ctx, dt_seconds);
|
|
910
|
-
}
|
|
911
|
-
|
|
912
|
-
destroy() {
|
|
913
|
-
this.#scene_database.destroy();
|
|
914
|
-
this.#lights.destroy();
|
|
915
|
-
this.#light_probe_volume.destroy();
|
|
916
|
-
this.#animation_manager.destroy();
|
|
917
|
-
if (this.#skinning !== null) {
|
|
918
|
-
this.#skinning.destroy();
|
|
919
|
-
}
|
|
920
|
-
}
|
|
921
|
-
|
|
922
|
-
}
|
|
923
|
-
|
|
924
|
-
/**
|
|
925
|
-
* @readonly
|
|
926
|
-
* @type {boolean}
|
|
927
|
-
*/
|
|
928
|
-
GPUSceneContext.prototype.isGPUSceneContext = true;
|
|
1
|
+
import { assert } from "../../../core/assert.js";
|
|
2
|
+
import { ShadeGPUCommandContext } from "../../device/ShadeGPUCommandContext.js";
|
|
3
|
+
import { GPUAnimationManager } from "../animation/GPUAnimationManager.js";
|
|
4
|
+
import { GPUDatabase } from "../buffer/table/GPUDatabase.js";
|
|
5
|
+
import { Brick4LightMap } from "../global_illumination/brick4/Brick4LightMap.js";
|
|
6
|
+
import { GPULightProbeVolume } from "../global_illumination/lpv/GPULightProbeVolume.js";
|
|
7
|
+
import { GPULightCollection } from "../light/GPULightCollection.js";
|
|
8
|
+
import { GPUSceneVolumetrics } from "../volumetrics/GPUSceneVolumetrics.js";
|
|
9
|
+
import { Scene } from "./Scene.js";
|
|
10
|
+
import { GPUInstancesAccelerationStructure } from "./GPUInstancesAccelerationStructure.js";
|
|
11
|
+
import { GPUMeshSkinningContext } from "../animation/skinning/GPUMeshSkinningContext.js";
|
|
12
|
+
import {
|
|
13
|
+
shader_refresh_all_mesh_bounds,
|
|
14
|
+
WORKGROUP_SIZE as REFRESH_ALL_MESH_BOUNDS_WORKGROUP_SIZE
|
|
15
|
+
} from "../object_property/shader_refresh_all_mesh_bounds.js";
|
|
16
|
+
import { GPUEntityBoundsReadback } from "./rows/GPUEntityBoundsReadback.js";
|
|
17
|
+
import { GPUSceneRows } from "./rows/GPUSceneRows.js";
|
|
18
|
+
import { generate_record_writer } from "../buffer/table/serde/generate_record_writer.js";
|
|
19
|
+
import { NODE3D_SCENE_ID, NODE3D_STRUCT } from "./NODE3D_STRUCT.js";
|
|
20
|
+
import { SCENE_DATABASE_SPEC } from "./SCENE_DATABASE_SPEC.js";
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* @typedef {import("../GraphicsContext.js").GraphicsContext} GraphicsContext
|
|
24
|
+
* @typedef {import("../geometry/GPUGeometryManager.js").GPUGeometryManager} GPUGeometryManager
|
|
25
|
+
* @typedef {import("../material/GPUMaterialManager.js").GPUMaterialManager} GPUMaterialManager
|
|
26
|
+
* @typedef {import("../material/ShadeMaterial.js").ShadeMaterial} ShadeMaterial
|
|
27
|
+
* @typedef {import("../buffer/table/serde/generate_record_writer.js").GPURecordWriter} GPURecordWriter
|
|
28
|
+
*/
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
let id_counter = 0;
|
|
32
|
+
|
|
33
|
+
/**
|
|
34
|
+
* Row 0 of the `transforms` table: the scene root. Identity, and its own parent — which is what the
|
|
35
|
+
* hierarchy pass takes as "no further ancestor" — so an entity whose attachment names no entity
|
|
36
|
+
* with a row is posed under it in world space, and the composition is exact. Written once, at the
|
|
37
|
+
* first {@link GPUSceneContext.build}, so it goes up with the first rows rather than being left to
|
|
38
|
+
* whatever the buffer held.
|
|
39
|
+
*/
|
|
40
|
+
const ROOT_RECORD = {
|
|
41
|
+
local_translation: new Float32Array([0, 0, 0]),
|
|
42
|
+
local_rotation: new Float32Array([0, 0, 0, 1]),
|
|
43
|
+
local_scale: new Float32Array([1, 1, 1]),
|
|
44
|
+
global: new Float32Array([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]),
|
|
45
|
+
prev_global: new Float32Array([1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1]),
|
|
46
|
+
parent: NODE3D_SCENE_ID,
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* @type {GPURecordWriter}
|
|
51
|
+
*/
|
|
52
|
+
const ROOT_RECORD_WRITER = generate_record_writer(NODE3D_STRUCT);
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* What a scene with no rows draws with.
|
|
56
|
+
*
|
|
57
|
+
* @type {ShadeMaterial[]}
|
|
58
|
+
*/
|
|
59
|
+
const NO_MATERIALS = Object.freeze([]);
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* The GPU side of one {@link Scene}: its database — the `transforms` and `meshes` tables, one row
|
|
63
|
+
* per entity that is drawn or posed, at `entity + 1` — and what is built over that database each
|
|
64
|
+
* frame: the lights' records, the probe volume, the volumetrics, the animation, the TLAS.
|
|
65
|
+
*
|
|
66
|
+
* Nothing here holds a hierarchy of its own. An entity's row names its parent's row and the GPU
|
|
67
|
+
* composes the chain each frame, derives every mesh row's bounds under the composed matrix and
|
|
68
|
+
* builds the tree over them — see {@link tick}. What the CPU writes is what it owns: an entity's
|
|
69
|
+
* local TRS and the row of its parent, through {@link rows}.
|
|
70
|
+
*/
|
|
71
|
+
export class GPUSceneContext {
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* @readonly
|
|
75
|
+
* @type {number}
|
|
76
|
+
*/
|
|
77
|
+
id = id_counter++;
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* @type {GPUGeometryManager}
|
|
81
|
+
*/
|
|
82
|
+
geometries;
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* @type {GPUMaterialManager}
|
|
86
|
+
*/
|
|
87
|
+
materials;
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
/**
|
|
91
|
+
* @type {Brick4LightMap}
|
|
92
|
+
*/
|
|
93
|
+
volumetric_light_map;
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
*
|
|
98
|
+
* @type {Scene}
|
|
99
|
+
*/
|
|
100
|
+
#scene;
|
|
101
|
+
|
|
102
|
+
/**
|
|
103
|
+
*
|
|
104
|
+
* @return {Scene}
|
|
105
|
+
*/
|
|
106
|
+
get scene() {
|
|
107
|
+
return this.#scene;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* @type {GPUSceneVolumetrics}
|
|
112
|
+
*/
|
|
113
|
+
#volumetrics;
|
|
114
|
+
|
|
115
|
+
get volumetrics() {
|
|
116
|
+
return this.#volumetrics;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* @type {GPULightCollection}
|
|
121
|
+
*/
|
|
122
|
+
#lights;
|
|
123
|
+
|
|
124
|
+
|
|
125
|
+
/**
|
|
126
|
+
*
|
|
127
|
+
* @returns {GPULightCollection}
|
|
128
|
+
*/
|
|
129
|
+
get lights() {
|
|
130
|
+
return this.#lights;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* @type {GPULightProbeVolume}
|
|
135
|
+
*/
|
|
136
|
+
#light_probe_volume;
|
|
137
|
+
|
|
138
|
+
/**
|
|
139
|
+
*
|
|
140
|
+
* @returns {GPULightProbeVolume}
|
|
141
|
+
*/
|
|
142
|
+
get light_probe_volume() {
|
|
143
|
+
return this.#light_probe_volume;
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* @type {GPUInstancesAccelerationStructure}
|
|
148
|
+
*/
|
|
149
|
+
#tlas
|
|
150
|
+
|
|
151
|
+
/**
|
|
152
|
+
*
|
|
153
|
+
* @returns {GPUInstancesAccelerationStructure}
|
|
154
|
+
*/
|
|
155
|
+
get tlas() {
|
|
156
|
+
return this.#tlas;
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* GPU-resident scene database — mesh metadata in the `meshes` table,
|
|
161
|
+
* transforms in the `transforms` table, one row per entity in each.
|
|
162
|
+
* Consumers bind `scene_database.buffer` as `array<u32>` and read
|
|
163
|
+
* records via `scene_read_mesh` / `scene_read_node` (see
|
|
164
|
+
* `chunk_scene_database_access`).
|
|
165
|
+
*
|
|
166
|
+
* @type {GPUDatabase}
|
|
167
|
+
*/
|
|
168
|
+
#scene_database;
|
|
169
|
+
|
|
170
|
+
/**
|
|
171
|
+
* Entities as rows of {@link scene_database} — see {@link rows}. Built the first time it is
|
|
172
|
+
* asked for, which needs the scene to name its dataset by then.
|
|
173
|
+
*
|
|
174
|
+
* @type {GPUSceneRows|null}
|
|
175
|
+
*/
|
|
176
|
+
#rows = null;
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Whether {@link ROOT_RECORD} has been written to row 0 — once, at the first build.
|
|
180
|
+
*
|
|
181
|
+
* @type {boolean}
|
|
182
|
+
*/
|
|
183
|
+
#root_written = false;
|
|
184
|
+
|
|
185
|
+
/**
|
|
186
|
+
* Per-scene skinning state — clone-index cache today, plus
|
|
187
|
+
* Skin-bindings and the per-frame skinning compute dispatch in
|
|
188
|
+
* later phases. Lazily constructed because it depends on
|
|
189
|
+
* {@link geometries}, which {@link SceneManager#create} assigns
|
|
190
|
+
* externally after this constructor runs. See {@link skinning} for
|
|
191
|
+
* access.
|
|
192
|
+
*
|
|
193
|
+
* @type {GPUMeshSkinningContext|null}
|
|
194
|
+
*/
|
|
195
|
+
#skinning = null;
|
|
196
|
+
|
|
197
|
+
/**
|
|
198
|
+
* Per-scene animation system — clips, tracks, curves, skins, and
|
|
199
|
+
* the skin-matrix scratch buffer. Owned here (rather than passed
|
|
200
|
+
* in) so that consumers fetching `gpu_scene.animation_manager`
|
|
201
|
+
* always see the same instance, and so per-frame database flush
|
|
202
|
+
* can be wired into {@link update} alongside the rest of the
|
|
203
|
+
* scene's bookkeeping.
|
|
204
|
+
*
|
|
205
|
+
* @type {GPUAnimationManager}
|
|
206
|
+
*/
|
|
207
|
+
#animation_manager;
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
*
|
|
211
|
+
* @param {GraphicsContext} graphics
|
|
212
|
+
* @param {Scene} scene
|
|
213
|
+
*/
|
|
214
|
+
constructor(graphics, scene) {
|
|
215
|
+
assert.defined(scene, 'scene');
|
|
216
|
+
assert.isObject(scene, 'scene');
|
|
217
|
+
assert.equal(scene.isScene, true, 'scene.isScene !== true');
|
|
218
|
+
|
|
219
|
+
const device = graphics.device;
|
|
220
|
+
|
|
221
|
+
this.#scene = scene;
|
|
222
|
+
this.#device = device;
|
|
223
|
+
this.#graphics = graphics;
|
|
224
|
+
|
|
225
|
+
this.#tlas = new GPUInstancesAccelerationStructure(graphics);
|
|
226
|
+
|
|
227
|
+
// Pass `this` so the light collection (and its child shadow context) can use
|
|
228
|
+
// this scene's GPUSceneContext when building its own ViewManager — avoids
|
|
229
|
+
// threading the renderer-level ViewManager / SceneManager through every layer.
|
|
230
|
+
this.#lights = new GPULightCollection(graphics, this);
|
|
231
|
+
|
|
232
|
+
this.#scene_database = new GPUDatabase({
|
|
233
|
+
device,
|
|
234
|
+
definition: SCENE_DATABASE_SPEC,
|
|
235
|
+
label: "GPUSceneContext/Database",
|
|
236
|
+
});
|
|
237
|
+
|
|
238
|
+
this.#light_probe_volume = new GPULightProbeVolume(device, scene.light_probe_volume);
|
|
239
|
+
|
|
240
|
+
this.volumetric_light_map = new Brick4LightMap(device);
|
|
241
|
+
|
|
242
|
+
this.#volumetrics = new GPUSceneVolumetrics(device, scene.volumetrics);
|
|
243
|
+
|
|
244
|
+
this.#animation_manager = new GPUAnimationManager(device, `GPUSceneContext[${this.id}]/Animation`, this);
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
/**
|
|
248
|
+
* @returns {GPUAnimationManager}
|
|
249
|
+
*/
|
|
250
|
+
get animation_manager() {
|
|
251
|
+
return this.#animation_manager;
|
|
252
|
+
}
|
|
253
|
+
|
|
254
|
+
/**
|
|
255
|
+
* @type {GPUDevice}
|
|
256
|
+
*/
|
|
257
|
+
#device;
|
|
258
|
+
|
|
259
|
+
/**
|
|
260
|
+
* @type {GraphicsContext}
|
|
261
|
+
*/
|
|
262
|
+
#graphics;
|
|
263
|
+
|
|
264
|
+
/**
|
|
265
|
+
*
|
|
266
|
+
* @returns {GPUDatabase}
|
|
267
|
+
*/
|
|
268
|
+
get scene_database() {
|
|
269
|
+
return this.#scene_database;
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
/**
|
|
273
|
+
* The underlying buffer that backs {@link scene_database} — bind this
|
|
274
|
+
* as `array<u32>` in shaders that read mesh / transform records.
|
|
275
|
+
*
|
|
276
|
+
* @returns {GPUBuffer}
|
|
277
|
+
*/
|
|
278
|
+
get scene_database_buffer() {
|
|
279
|
+
return this.#scene_database.buffer;
|
|
280
|
+
}
|
|
281
|
+
|
|
282
|
+
/**
|
|
283
|
+
* Per-scene skinning subsystem. Routes skinned rows through
|
|
284
|
+
* per-instance geometry clones; later phases grow Skin-binding
|
|
285
|
+
* management and the per-frame skinning compute onto it.
|
|
286
|
+
*
|
|
287
|
+
* Lazy because it depends on {@link geometries}, which is assigned
|
|
288
|
+
* externally after this object's constructor returns
|
|
289
|
+
* (see {@link SceneManager}). The first access happens during
|
|
290
|
+
* {@link build}, which runs well after that assignment.
|
|
291
|
+
*
|
|
292
|
+
* @returns {GPUMeshSkinningContext}
|
|
293
|
+
*/
|
|
294
|
+
get skinning() {
|
|
295
|
+
if (this.#skinning === null) {
|
|
296
|
+
this.#skinning = new GPUMeshSkinningContext({
|
|
297
|
+
geometries: this.geometries,
|
|
298
|
+
animation_manager: this.#animation_manager,
|
|
299
|
+
scene_context: this,
|
|
300
|
+
device: this.#device,
|
|
301
|
+
});
|
|
302
|
+
}
|
|
303
|
+
return this.#skinning;
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
get gpu_memory_usage(){
|
|
307
|
+
let r = 0;
|
|
308
|
+
|
|
309
|
+
r+= this.#scene_database.gpu_memory_usage;
|
|
310
|
+
|
|
311
|
+
r += this.#lights.gpu_memory_usage;
|
|
312
|
+
r += this.#light_probe_volume.gpu_memory_usage;
|
|
313
|
+
r += this.volumetric_light_map.gpu_memory_usage;
|
|
314
|
+
|
|
315
|
+
return r;
|
|
316
|
+
}
|
|
317
|
+
|
|
318
|
+
/**
|
|
319
|
+
* Entities as rows of the scene database, at `entity + 1` in both tables.
|
|
320
|
+
*
|
|
321
|
+
* A system that places an entity acquires its row here and marks it on the dataset's change
|
|
322
|
+
* events; a scene with no systems places through `prefab_place` and `place_primitive`, which
|
|
323
|
+
* do the same by hand; and {@link build} flushes what was marked. The scene has to name its
|
|
324
|
+
* dataset ({@link Scene.dataset}) before this is first asked for, because the rows are written
|
|
325
|
+
* from that dataset's components.
|
|
326
|
+
*
|
|
327
|
+
* @returns {GPUSceneRows}
|
|
328
|
+
*/
|
|
329
|
+
get rows() {
|
|
330
|
+
return this.#obtain_rows();
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
/**
|
|
334
|
+
* An entity's world bounds as the GPU holds them, read back — what a consumer that wants the
|
|
335
|
+
* box that is drawn asks, a frame or two behind the device. Built on demand, over the rows.
|
|
336
|
+
*
|
|
337
|
+
* @returns {GPUEntityBoundsReadback}
|
|
338
|
+
*/
|
|
339
|
+
get bounds() {
|
|
340
|
+
if (this.#bounds === null) {
|
|
341
|
+
this.#bounds = new GPUEntityBoundsReadback(this.#scene_database.readback, this.rows);
|
|
342
|
+
}
|
|
343
|
+
|
|
344
|
+
return this.#bounds;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
/**
|
|
348
|
+
* @type {GPUEntityBoundsReadback|null}
|
|
349
|
+
*/
|
|
350
|
+
#bounds = null;
|
|
351
|
+
|
|
352
|
+
/**
|
|
353
|
+
* Every material something in the scene draws with, each once — the rows' own list, kept
|
|
354
|
+
* current as meshes attach and detach. What the rasterizers iterate to decide which buckets
|
|
355
|
+
* and pipelines a frame needs. The array is reused until the set changes; a scene with no
|
|
356
|
+
* rows draws with nothing.
|
|
357
|
+
*
|
|
358
|
+
* @returns {ShadeMaterial[]}
|
|
359
|
+
*/
|
|
360
|
+
get drawn_materials() {
|
|
361
|
+
return this.#rows === null ? NO_MATERIALS : this.#rows.materials;
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
/**
|
|
365
|
+
* @returns {GPUSceneRows}
|
|
366
|
+
*/
|
|
367
|
+
#obtain_rows() {
|
|
368
|
+
if (this.#rows === null) {
|
|
369
|
+
const dataset = this.#scene.dataset;
|
|
370
|
+
|
|
371
|
+
assert.notNull(dataset, 'the scene names no dataset — set Scene.dataset before asking for its rows');
|
|
372
|
+
assert.defined(dataset, 'the scene names no dataset — set Scene.dataset before asking for its rows');
|
|
373
|
+
|
|
374
|
+
this.#rows = new GPUSceneRows({
|
|
375
|
+
dataset,
|
|
376
|
+
transforms: this.#scene_database.get('transforms'),
|
|
377
|
+
meshes: this.#scene_database.get('meshes'),
|
|
378
|
+
geometries: this.geometries,
|
|
379
|
+
materials: this.materials,
|
|
380
|
+
tlas: this.#tlas,
|
|
381
|
+
skinning: () => this.skinning,
|
|
382
|
+
});
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
return this.#rows;
|
|
386
|
+
}
|
|
387
|
+
|
|
388
|
+
/**
|
|
389
|
+
* Bring the GPU scene database in line with the scene, writing only the rows that changed:
|
|
390
|
+
* the scene root's, once; a light's, as it arrives; and every entity's row that a system
|
|
391
|
+
* marked since the last build. Nothing is walked — the rows keep what was marked.
|
|
392
|
+
*/
|
|
393
|
+
build() {
|
|
394
|
+
let written = 0;
|
|
395
|
+
|
|
396
|
+
if (!this.#root_written) {
|
|
397
|
+
this.#scene_database.get('transforms').set_record(NODE3D_SCENE_ID, ROOT_RECORD, ROOT_RECORD_WRITER);
|
|
398
|
+
|
|
399
|
+
this.#root_written = true;
|
|
400
|
+
written++;
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
// Entities are rows — marked by the systems that place them, written here. Built on demand
|
|
404
|
+
// because the scene may name its dataset after this context was made.
|
|
405
|
+
if (this.#rows === null && this.#scene.dataset !== null && this.#scene.dataset !== undefined) {
|
|
406
|
+
this.rows;
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
if (this.#rows !== null) {
|
|
410
|
+
// A light is an entity's row, held here on the light collection's behalf — before the
|
|
411
|
+
// flush, so a light that arrived this frame is written this frame.
|
|
412
|
+
this.#lights.sync_rows(this.#rows);
|
|
413
|
+
|
|
414
|
+
written += this.#rows.flush();
|
|
415
|
+
} else {
|
|
416
|
+
assert.equal(this.#scene.lights.elements.length, 0, 'the scene has lights and names no dataset; a light is an entity of one');
|
|
417
|
+
}
|
|
418
|
+
|
|
419
|
+
if (written === 0) {
|
|
420
|
+
return;
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
// Flush the scene database — only the rows that changed carry an upload record.
|
|
424
|
+
const cmd = ShadeGPUCommandContext.create(this.#graphics, 'GPUSceneContext/database-build');
|
|
425
|
+
|
|
426
|
+
// Also flush the global geometry manager. The first time a scene
|
|
427
|
+
// sees a new mesh, the rows' flush calls `geometries.add(...)`,
|
|
428
|
+
// which registers the source MeshletGeometry and flips
|
|
429
|
+
// `geometries.__needs_update = true`. The next per-frame
|
|
430
|
+
// `graphics.update()` would normally rebuild
|
|
431
|
+
// `geometries.buffer_metadata` to reflect those new entries — but
|
|
432
|
+
// `graphics.update()` runs at the *head* of `Renderer.#begin_frame`,
|
|
433
|
+
// *before* this scene.build, so the buffer_metadata stays whatever
|
|
434
|
+
// it was at the start of the frame (often the zero-record placeholder
|
|
435
|
+
// from the renderer's startup build, when the scene's geometries
|
|
436
|
+
// hadn't been registered yet).
|
|
437
|
+
//
|
|
438
|
+
// Any pass reading `geometries[mesh.geometry]` later in the frame
|
|
439
|
+
// (rasterization meshlet expansion, `shader_refresh_all_mesh_bounds`,
|
|
440
|
+
// etc.) sees zeros — `meshlets_count = 0` produces no triangles and
|
|
441
|
+
// `bounding_box = (0,0,0)-(0,0,0)` collapses world bounds to a
|
|
442
|
+
// single point in `shader_refresh_all_mesh_bounds`, which then writes
|
|
443
|
+
// those collapsed bounds back into `meshes_table`. Subsequent frames
|
|
444
|
+
// get a correct `buffer_metadata` from the next `graphics.update()`,
|
|
445
|
+
// but the `meshes_table` bounds stay collapsed until refresh_all
|
|
446
|
+
// overwrites them again — and frustum cull on the collapsed bounds
|
|
447
|
+
// can drop meshes whose collapsed point sits outside the frustum.
|
|
448
|
+
//
|
|
449
|
+
// Symptom: stress test rendered ground (whose collapsed point at the
|
|
450
|
+
// origin survives the cull) but dropped most trees (whose collapsed
|
|
451
|
+
// points scattered across the grid trigger cull edge cases).
|
|
452
|
+
//
|
|
453
|
+
// Calling `geometries.update(cmd)` here ensures the new buffer is in
|
|
454
|
+
// place before any pass in the same frame reads it. Idempotent / no-op
|
|
455
|
+
// when nothing's queued, so the per-frame `graphics.update` head call
|
|
456
|
+
// and this build-time call together leave the buffer in the right
|
|
457
|
+
// state under both lifetimes.
|
|
458
|
+
this.geometries.update(cmd);
|
|
459
|
+
|
|
460
|
+
this.#scene_database.update(cmd);
|
|
461
|
+
cmd.finish();
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
/**
|
|
465
|
+
*
|
|
466
|
+
* @param {GraphicsContext} ctx
|
|
467
|
+
*/
|
|
468
|
+
update(ctx) {
|
|
469
|
+
assert.defined(ctx, 'ctx');
|
|
470
|
+
|
|
471
|
+
// TODO add a fast update check, so that calling this multiple times per frame can be fast.
|
|
472
|
+
|
|
473
|
+
// The apply point of the scene database's readback: whatever the device has answered since
|
|
474
|
+
// — an entity's drawn bounds, asked for through {@link bounds} — is delivered before
|
|
475
|
+
// anything this frame reads it, and never mid-update.
|
|
476
|
+
this.#scene_database.readback.apply();
|
|
477
|
+
|
|
478
|
+
this.#light_probe_volume.update();
|
|
479
|
+
this.#lights.update(ctx);
|
|
480
|
+
this.#volumetrics.update(ctx, 0);
|
|
481
|
+
|
|
482
|
+
// Per-frame animation database flush — picks up any new clips,
|
|
483
|
+
// tracks, skins, or per-frame `set_time` writes queued since
|
|
484
|
+
// last frame. Idempotent / cheap when nothing's queued.
|
|
485
|
+
const animation_cmd = ShadeGPUCommandContext.create(this.#graphics, 'GPUSceneContext/animation-flush');
|
|
486
|
+
this.#animation_manager.update(animation_cmd);
|
|
487
|
+
animation_cmd.finish();
|
|
488
|
+
|
|
489
|
+
// TODO update SDF
|
|
490
|
+
|
|
491
|
+
this.build();
|
|
492
|
+
}
|
|
493
|
+
|
|
494
|
+
/**
|
|
495
|
+
* Per-frame GPU-side scene update, once per scene per frame, after every view's {@link update}
|
|
496
|
+
* has flushed what the CPU changed:
|
|
497
|
+
*
|
|
498
|
+
* 1. the animation tick — pending registrations drained, `clip.time` advanced, apply → resolve
|
|
499
|
+
* → hierarchy propagate → skin-matrix prep → skinning, through {@link GPUAnimationManager#tick};
|
|
500
|
+
* 2. render bounds — every mesh row's world box and sphere, derived from its geometry under
|
|
501
|
+
* the `global` the hierarchy pass just composed, because the CPU does not hold that matrix
|
|
502
|
+
* for a subtree the GPU drives;
|
|
503
|
+
* 3. light poses — every light record's position and direction, from its entity's row, for
|
|
504
|
+
* the same reason;
|
|
505
|
+
* 4. the TLAS — rebuilt from those bounds when anything moved, on either side.
|
|
506
|
+
*
|
|
507
|
+
* All four into `cmd_ctx`, in that order, so the tree the frame's ray passes traverse is built
|
|
508
|
+
* over this frame's bounds rather than last frame's, and what lights the frame is where it is
|
|
509
|
+
* this frame.
|
|
510
|
+
*
|
|
511
|
+
* `dt_seconds` is wall-clock seconds since the last call (the renderer's `time_delta_seconds`
|
|
512
|
+
* argument to `render()`).
|
|
513
|
+
*
|
|
514
|
+
* @param {ShadeGPUCommandContext} cmd_ctx
|
|
515
|
+
* @param {number} dt_seconds wall-clock seconds since last call
|
|
516
|
+
*/
|
|
517
|
+
tick(cmd_ctx, dt_seconds) {
|
|
518
|
+
const animated = this.#animation_manager.tick(cmd_ctx, dt_seconds);
|
|
519
|
+
|
|
520
|
+
this.#refresh_mesh_bounds(cmd_ctx);
|
|
521
|
+
|
|
522
|
+
this.#lights.refresh_poses(cmd_ctx, this.scene_database_buffer);
|
|
523
|
+
|
|
524
|
+
if (animated) {
|
|
525
|
+
// Rows moved on the GPU, where no version was bumped: a clip resolved into a TRS, a
|
|
526
|
+
// skinning pass moved a clone's vertices. The bounds pass just re-derived their boxes,
|
|
527
|
+
// and the tree is built over boxes.
|
|
528
|
+
this.#tlas.invalidate();
|
|
529
|
+
}
|
|
530
|
+
|
|
531
|
+
this.#tlas.update(this.scene_database_buffer, cmd_ctx);
|
|
532
|
+
|
|
533
|
+
// What was asked of the scene database this frame is copied out at the tail of the
|
|
534
|
+
// database's own update when rows were written this frame, and here — after the bounds
|
|
535
|
+
// pass — when none were; either way what lands, at the head of a later frame's update, is
|
|
536
|
+
// the box the GPU held when the copy ran.
|
|
537
|
+
this.#scene_database.readback.encode(cmd_ctx);
|
|
538
|
+
}
|
|
539
|
+
|
|
540
|
+
/**
|
|
541
|
+
* Recompute every mesh row's world bounds from its geometry under its composed `global`.
|
|
542
|
+
* Skipped when there is no mesh row; otherwise one thread per slot of the `meshes` table's
|
|
543
|
+
* pages, occupancy-masked.
|
|
544
|
+
*
|
|
545
|
+
* @param {ShadeGPUCommandContext} cmd_ctx
|
|
546
|
+
*/
|
|
547
|
+
#refresh_mesh_bounds(cmd_ctx) {
|
|
548
|
+
const meshes_table = this.#scene_database.get('meshes');
|
|
549
|
+
|
|
550
|
+
const group_count = meshes_table.dispatch_group_count(REFRESH_ALL_MESH_BOUNDS_WORKGROUP_SIZE);
|
|
551
|
+
|
|
552
|
+
if (group_count === 0) {
|
|
553
|
+
return;
|
|
554
|
+
}
|
|
555
|
+
|
|
556
|
+
const geometries = this.geometries.buffer_metadata;
|
|
557
|
+
|
|
558
|
+
if (geometries === null) {
|
|
559
|
+
// a mesh row names a geometry, and a geometry is registered before its row is written
|
|
560
|
+
// — so this is a scene whose first frame has not flushed the geometry manager yet
|
|
561
|
+
return;
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
shader_refresh_all_mesh_bounds.dispatch({
|
|
565
|
+
encoder: cmd_ctx,
|
|
566
|
+
group_count_x: group_count,
|
|
567
|
+
bindings: {
|
|
568
|
+
scene_database: this.scene_database_buffer,
|
|
569
|
+
geometries,
|
|
570
|
+
},
|
|
571
|
+
});
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
destroy() {
|
|
575
|
+
if (this.#rows !== null) {
|
|
576
|
+
this.#rows.destroy();
|
|
577
|
+
}
|
|
578
|
+
|
|
579
|
+
this.#scene_database.destroy();
|
|
580
|
+
this.#lights.destroy();
|
|
581
|
+
this.#light_probe_volume.destroy();
|
|
582
|
+
this.#animation_manager.destroy();
|
|
583
|
+
if (this.#skinning !== null) {
|
|
584
|
+
this.#skinning.destroy();
|
|
585
|
+
}
|
|
586
|
+
}
|
|
587
|
+
|
|
588
|
+
}
|
|
589
|
+
|
|
590
|
+
/**
|
|
591
|
+
* @readonly
|
|
592
|
+
* @type {boolean}
|
|
593
|
+
*/
|
|
594
|
+
GPUSceneContext.prototype.isGPUSceneContext = true;
|