@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
|
@@ -0,0 +1,1136 @@
|
|
|
1
|
+
import { assert } from "../../../../core/assert.js";
|
|
2
|
+
import { BitSet } from "../../../../core/binary/BitSet.js";
|
|
3
|
+
import { GPUStateAuthority } from "../../../../engine/ecs/gpu/GPUStateAuthority.js";
|
|
4
|
+
import { GPUStateAuthorityFlags } from "../../../../engine/ecs/gpu/GPUStateAuthorityFlags.js";
|
|
5
|
+
import { TransformAttachment } from "../../../../engine/ecs/transform-attachment/TransformAttachment.js";
|
|
6
|
+
import { aabb3_matrix4_project } from "../../../../core/geom/3d/aabb/aabb3_matrix4_project.js";
|
|
7
|
+
import { Transform64 } from "../../../../engine/ecs/transform/Transform64.js";
|
|
8
|
+
import { generate_record_writer } from "../../buffer/table/serde/generate_record_writer.js";
|
|
9
|
+
import { MESH_INSTANCE_METADATA_STRUCT } from "../MESH_INSTANCE_METADATA_STRUCT.js";
|
|
10
|
+
import { NODE3D_SCENE_ID, NODE3D_STRUCT } from "../NODE3D_STRUCT.js";
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* @typedef {import("../../../../engine/ecs/EntityComponentDataset.js").EntityComponentDataset} EntityComponentDataset
|
|
14
|
+
* @typedef {import("../../buffer/table/GPUTypedTable.js").GPUTypedTable} GPUTypedTable
|
|
15
|
+
* @typedef {import("../../geometry/GPUGeometryManager.js").GPUGeometryManager} GPUGeometryManager
|
|
16
|
+
* @typedef {import("../../material/GPUMaterialManager.js").GPUMaterialManager} GPUMaterialManager
|
|
17
|
+
* @typedef {import("../GPUInstancesAccelerationStructure.js").GPUInstancesAccelerationStructure} GPUInstancesAccelerationStructure
|
|
18
|
+
* @typedef {import("../../animation/skinning/GPUMeshSkinningContext.js").GPUMeshSkinningContext} GPUMeshSkinningContext
|
|
19
|
+
* @typedef {import("../../geometry/MeshletGeometry.js").MeshletGeometry} MeshletGeometry
|
|
20
|
+
* @typedef {import("../../material/ShadeMaterial.js").ShadeMaterial} ShadeMaterial
|
|
21
|
+
* @typedef {import("../../../../core/geom/3d/aabb/AABB3.js").AABB3} AABB3
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* The row an entity occupies in both scene tables.
|
|
26
|
+
*
|
|
27
|
+
* Row 0 is the scene root — the hierarchy walk's terminator and the natural value of a
|
|
28
|
+
* zero-initialised buffer — so entity 0 lands at row 1 and every entity after it one row on. There
|
|
29
|
+
* is no mapping to consult and nothing to keep in step: the identity is the arithmetic.
|
|
30
|
+
*
|
|
31
|
+
* @param {number} entity
|
|
32
|
+
* @returns {number}
|
|
33
|
+
*/
|
|
34
|
+
export function row_of_entity(entity) {
|
|
35
|
+
return entity + 1;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
/**
|
|
39
|
+
* The inverse of {@link row_of_entity}, for a row the renderer produced — a visibility-buffer
|
|
40
|
+
* pixel, a ray hit.
|
|
41
|
+
*
|
|
42
|
+
* @param {number} row
|
|
43
|
+
* @returns {number} the entity, or -1 for row 0
|
|
44
|
+
*/
|
|
45
|
+
export function entity_of_row(row) {
|
|
46
|
+
return row - 1;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* Why an entity is on the dirty list. Carried as bits, because one frame can bring several
|
|
51
|
+
* reasons and the flush wants the union.
|
|
52
|
+
*/
|
|
53
|
+
const MARK_LOCAL = 1;
|
|
54
|
+
const MARK_WORLD = 2;
|
|
55
|
+
const MARK_MESH = 4;
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Staging for one `transforms` row, reused across every write. `global` and `prev_global` are read
|
|
59
|
+
* only on a row's first write.
|
|
60
|
+
*/
|
|
61
|
+
const TRANSFORM_RECORD = {
|
|
62
|
+
local_translation: new Float32Array(3),
|
|
63
|
+
local_rotation: new Float32Array(4),
|
|
64
|
+
local_scale: new Float32Array(3),
|
|
65
|
+
global: new Float32Array(16),
|
|
66
|
+
prev_global: new Float32Array(16),
|
|
67
|
+
parent: NODE3D_SCENE_ID,
|
|
68
|
+
};
|
|
69
|
+
|
|
70
|
+
/**
|
|
71
|
+
* What a `meshes` row's bounds hold until the bounds pass has derived them, which it does every
|
|
72
|
+
* tick for every occupied row, under the `global` the hierarchy pass composed — before anything
|
|
73
|
+
* culls, traces or reads them back. This side never computes a render box: for a subtree the GPU
|
|
74
|
+
* drives it does not hold the matrix the box needs, and a box it could compute would be one the
|
|
75
|
+
* pass overwrites within the frame.
|
|
76
|
+
*
|
|
77
|
+
* @type {Float32Array}
|
|
78
|
+
*/
|
|
79
|
+
const UNDERIVED_BOUNDING_BOX = new Float32Array(6);
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* @type {Float32Array}
|
|
83
|
+
*/
|
|
84
|
+
const UNDERIVED_BOUNDING_SPHERE = new Float32Array(4);
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* One mesh entry's geometry box under its entity's world matrix, for
|
|
88
|
+
* {@link GPUSceneRows.compute_world_bounds}.
|
|
89
|
+
*
|
|
90
|
+
* @type {Float64Array}
|
|
91
|
+
*/
|
|
92
|
+
const SCRATCH_WORLD_BOX = new Float64Array(6);
|
|
93
|
+
|
|
94
|
+
/**
|
|
95
|
+
* Staging for one `meshes` row.
|
|
96
|
+
*/
|
|
97
|
+
const MESH_RECORD = {
|
|
98
|
+
geometry: 0,
|
|
99
|
+
material: 0,
|
|
100
|
+
node: NODE3D_SCENE_ID,
|
|
101
|
+
bounding_box: UNDERIVED_BOUNDING_BOX,
|
|
102
|
+
bounding_sphere: UNDERIVED_BOUNDING_SPHERE,
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* The fields of a row this side owns: its local TRS and the row of its parent. `global` and
|
|
107
|
+
* `prev_global` are composed by the hierarchy pass every frame for every row, whoever owns the TRS
|
|
108
|
+
* — see `GPUSceneContext` for why writing them here would be wrong as well as wasteful.
|
|
109
|
+
*
|
|
110
|
+
* @type {GPURecordWriter}
|
|
111
|
+
*/
|
|
112
|
+
const TRANSFORM_LOCAL_WRITER = generate_record_writer(NODE3D_STRUCT, [
|
|
113
|
+
'local_translation',
|
|
114
|
+
'local_rotation',
|
|
115
|
+
'local_scale',
|
|
116
|
+
'parent',
|
|
117
|
+
]);
|
|
118
|
+
|
|
119
|
+
/**
|
|
120
|
+
* Only the parent row: what changes when a parent gains or loses a row of its own while the
|
|
121
|
+
* entity's local offset is somebody else's to write.
|
|
122
|
+
*
|
|
123
|
+
* @type {GPURecordWriter}
|
|
124
|
+
*/
|
|
125
|
+
const TRANSFORM_PARENT_WRITER = generate_record_writer(NODE3D_STRUCT, ['parent']);
|
|
126
|
+
|
|
127
|
+
/**
|
|
128
|
+
* The whole row, for its first write: `global` and `prev_global` are seeded to the entity's world
|
|
129
|
+
* matrix so its first frame reports no motion instead of a jump from the origin.
|
|
130
|
+
*
|
|
131
|
+
* @type {GPURecordWriter}
|
|
132
|
+
*/
|
|
133
|
+
const TRANSFORM_RECORD_WRITER = generate_record_writer(NODE3D_STRUCT);
|
|
134
|
+
|
|
135
|
+
/**
|
|
136
|
+
* @type {GPURecordWriter}
|
|
137
|
+
*/
|
|
138
|
+
const MESH_RECORD_WRITER = generate_record_writer(MESH_INSTANCE_METADATA_STRUCT);
|
|
139
|
+
|
|
140
|
+
/**
|
|
141
|
+
* What one entity has in the `meshes` table.
|
|
142
|
+
*/
|
|
143
|
+
class MeshEntry {
|
|
144
|
+
/**
|
|
145
|
+
* @type {MeshletGeometry}
|
|
146
|
+
*/
|
|
147
|
+
geometry = null;
|
|
148
|
+
|
|
149
|
+
/**
|
|
150
|
+
* @type {ShadeMaterial}
|
|
151
|
+
*/
|
|
152
|
+
material = null;
|
|
153
|
+
|
|
154
|
+
/**
|
|
155
|
+
* Whether the row draws a per-instance clone the skinning pass deforms, rather than the
|
|
156
|
+
* shared source. The clone is the skinning context's, made when the row is first written.
|
|
157
|
+
*
|
|
158
|
+
* @type {boolean}
|
|
159
|
+
*/
|
|
160
|
+
skinned = false;
|
|
161
|
+
|
|
162
|
+
/**
|
|
163
|
+
* Whether the row has been written — and therefore whether the TLAS knows the row.
|
|
164
|
+
*
|
|
165
|
+
* @type {boolean}
|
|
166
|
+
*/
|
|
167
|
+
written = false;
|
|
168
|
+
|
|
169
|
+
/**
|
|
170
|
+
* The material the written row draws with — the one its hold in the rows' material list is
|
|
171
|
+
* on. `null` until the row is written, and again once it is given back.
|
|
172
|
+
*
|
|
173
|
+
* @type {ShadeMaterial|null}
|
|
174
|
+
*/
|
|
175
|
+
held = null;
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Entities as rows of the scene database.
|
|
180
|
+
*
|
|
181
|
+
* **The entity is the row**, at {@link row_of_entity}. An entity that something in the renderer
|
|
182
|
+
* needs — a primitive, a joint, a parent of either — is {@link acquire}d, and from then until
|
|
183
|
+
* {@link release} its `transforms` row is written from its own components: `TransformAttachment`
|
|
184
|
+
* when it has one and its parent has a row, in which case the row holds the local offset and the
|
|
185
|
+
* parent's row and the GPU composes the world; the world `Transform64` otherwise, under the scene
|
|
186
|
+
* root, which is exact because the ECS composes every chain on the CPU regardless. A primitive
|
|
187
|
+
* {@link attach_mesh}es and takes the `meshes` row of the same index.
|
|
188
|
+
*
|
|
189
|
+
* **Change flow is mark, then flush.** The systems that place entities listen to the dataset's
|
|
190
|
+
* change events and {@link mark_local} or {@link mark_world}; nothing is read at mark time. The
|
|
191
|
+
* flush, in `GPUSceneContext.build`, reads each marked entity's components once, consults
|
|
192
|
+
* `GPUStateAuthority` then, writes the ranges the CPU owns, and clears the list. A world mark on
|
|
193
|
+
* an attached entity whose parent has a row writes nothing: its local offset and its parent are
|
|
194
|
+
* unchanged, and the GPU composes the rest. That is what stops a root's move from costing a row
|
|
195
|
+
* per descendant.
|
|
196
|
+
*
|
|
197
|
+
* **Render bounds are never written from this side.** They are derived on the GPU every tick from
|
|
198
|
+
* the composed world matrix, because the CPU does not hold that matrix for a subtree the GPU
|
|
199
|
+
* drives; a row is written with them underived, and the bounds pass has filled them in before
|
|
200
|
+
* anything reads them. What a consumer on this side wants is the readback (`GPUSceneContext.bounds`).
|
|
201
|
+
*/
|
|
202
|
+
export class GPUSceneRows {
|
|
203
|
+
|
|
204
|
+
/**
|
|
205
|
+
* @type {EntityComponentDataset}
|
|
206
|
+
*/
|
|
207
|
+
#dataset;
|
|
208
|
+
|
|
209
|
+
/**
|
|
210
|
+
* @type {GPUTypedTable}
|
|
211
|
+
*/
|
|
212
|
+
#transforms;
|
|
213
|
+
|
|
214
|
+
/**
|
|
215
|
+
* @type {GPUTypedTable}
|
|
216
|
+
*/
|
|
217
|
+
#meshes;
|
|
218
|
+
|
|
219
|
+
/**
|
|
220
|
+
* @type {GPUGeometryManager}
|
|
221
|
+
*/
|
|
222
|
+
#geometries;
|
|
223
|
+
|
|
224
|
+
/**
|
|
225
|
+
* @type {GPUMaterialManager}
|
|
226
|
+
*/
|
|
227
|
+
#materials;
|
|
228
|
+
|
|
229
|
+
/**
|
|
230
|
+
* How many written mesh rows draw with each material. A material is listed while the count is
|
|
231
|
+
* above zero — what the rasterizers iterate to decide which buckets and pipelines a frame needs.
|
|
232
|
+
*
|
|
233
|
+
* @type {Map<ShadeMaterial, number>}
|
|
234
|
+
*/
|
|
235
|
+
#material_holds = new Map();
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* Moves when a material enters or leaves {@link #material_holds}; not when a count changes
|
|
239
|
+
* between two positive values.
|
|
240
|
+
*
|
|
241
|
+
* @type {number}
|
|
242
|
+
*/
|
|
243
|
+
#materials_version = 0;
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* @type {ShadeMaterial[]}
|
|
247
|
+
*/
|
|
248
|
+
#cached_materials = [];
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* @type {number}
|
|
252
|
+
*/
|
|
253
|
+
#cached_materials_version = -1;
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* @type {GPUInstancesAccelerationStructure}
|
|
257
|
+
*/
|
|
258
|
+
#tlas;
|
|
259
|
+
|
|
260
|
+
/**
|
|
261
|
+
* The scene's skinning context, asked for when a skinned row is written — a function, because
|
|
262
|
+
* the context is built on first use and the rows may be here first.
|
|
263
|
+
*
|
|
264
|
+
* @type {function(): GPUMeshSkinningContext}
|
|
265
|
+
*/
|
|
266
|
+
#skinning;
|
|
267
|
+
|
|
268
|
+
/**
|
|
269
|
+
* Entities holding a `transforms` row, from the first {@link acquire} to the last
|
|
270
|
+
* {@link release}.
|
|
271
|
+
*
|
|
272
|
+
* @type {BitSet}
|
|
273
|
+
*/
|
|
274
|
+
#acquired = new BitSet();
|
|
275
|
+
|
|
276
|
+
/**
|
|
277
|
+
* How many holders each acquired entity has. A model holds every one of its entities' rows and
|
|
278
|
+
* a primitive holds its own, and the row goes when the last of them lets go. Indexed by entity.
|
|
279
|
+
*
|
|
280
|
+
* @type {Uint16Array}
|
|
281
|
+
*/
|
|
282
|
+
#holds = new Uint16Array(256);
|
|
283
|
+
|
|
284
|
+
/**
|
|
285
|
+
* Entities whose row has been written at least once — whose next write is a patch rather than
|
|
286
|
+
* the seeding write.
|
|
287
|
+
*
|
|
288
|
+
* @type {BitSet}
|
|
289
|
+
*/
|
|
290
|
+
#written = new BitSet();
|
|
291
|
+
|
|
292
|
+
/**
|
|
293
|
+
* Why each marked entity is marked, or zero. Indexed by entity.
|
|
294
|
+
*
|
|
295
|
+
* @type {Uint8Array}
|
|
296
|
+
*/
|
|
297
|
+
#reason = new Uint8Array(256);
|
|
298
|
+
|
|
299
|
+
/**
|
|
300
|
+
* The marked entities, in the order they were first marked this frame.
|
|
301
|
+
*
|
|
302
|
+
* @type {number[]}
|
|
303
|
+
*/
|
|
304
|
+
#marked = [];
|
|
305
|
+
|
|
306
|
+
/**
|
|
307
|
+
* The `parent` field each written row currently holds. Indexed by entity, meaningful for
|
|
308
|
+
* written rows only. Lets the flush notice a parent that gained or lost its row, which is a
|
|
309
|
+
* change to the child's row that no component write announces.
|
|
310
|
+
*
|
|
311
|
+
* @type {Uint32Array}
|
|
312
|
+
*/
|
|
313
|
+
#parent_row = new Uint32Array(256);
|
|
314
|
+
|
|
315
|
+
/**
|
|
316
|
+
* Which entity each row's attachment named when it was last flushed, or -1. Indexed by entity.
|
|
317
|
+
* Maintains {@link #children}.
|
|
318
|
+
*
|
|
319
|
+
* @type {Int32Array}
|
|
320
|
+
*/
|
|
321
|
+
#parent_entity = new Int32Array(256).fill(-1);
|
|
322
|
+
|
|
323
|
+
/**
|
|
324
|
+
* Acquired entities by the entity their attachment names, whether or not that entity has a row
|
|
325
|
+
* itself. When it acquires or releases one, these are the rows that have to change shape.
|
|
326
|
+
*
|
|
327
|
+
* @type {Map<number, Set<number>>}
|
|
328
|
+
*/
|
|
329
|
+
#children = new Map();
|
|
330
|
+
|
|
331
|
+
/**
|
|
332
|
+
* @type {Map<number, MeshEntry>}
|
|
333
|
+
*/
|
|
334
|
+
#mesh_entries = new Map();
|
|
335
|
+
|
|
336
|
+
/**
|
|
337
|
+
* @type {number}
|
|
338
|
+
*/
|
|
339
|
+
#mesh_rows_version = 0;
|
|
340
|
+
|
|
341
|
+
/**
|
|
342
|
+
* @param {object} options
|
|
343
|
+
* @param {EntityComponentDataset} options.dataset
|
|
344
|
+
* @param {GPUTypedTable} options.transforms
|
|
345
|
+
* @param {GPUTypedTable} options.meshes
|
|
346
|
+
* @param {GPUGeometryManager} options.geometries
|
|
347
|
+
* @param {GPUMaterialManager} options.materials
|
|
348
|
+
* @param {GPUInstancesAccelerationStructure} options.tlas
|
|
349
|
+
* @param {function(): GPUMeshSkinningContext} options.skinning
|
|
350
|
+
*/
|
|
351
|
+
constructor({ dataset, transforms, meshes, geometries, materials, tlas, skinning }) {
|
|
352
|
+
assert.defined(dataset, 'dataset');
|
|
353
|
+
assert.equal(dataset.isEntityComponentDataset, true, 'dataset.isEntityComponentDataset !== true');
|
|
354
|
+
assert.defined(transforms, 'transforms');
|
|
355
|
+
assert.defined(meshes, 'meshes');
|
|
356
|
+
assert.defined(geometries, 'geometries');
|
|
357
|
+
assert.defined(materials, 'materials');
|
|
358
|
+
assert.defined(tlas, 'tlas');
|
|
359
|
+
assert.typeOf(skinning, 'function', 'skinning');
|
|
360
|
+
|
|
361
|
+
this.#dataset = dataset;
|
|
362
|
+
this.#transforms = transforms;
|
|
363
|
+
this.#meshes = meshes;
|
|
364
|
+
this.#geometries = geometries;
|
|
365
|
+
this.#materials = materials;
|
|
366
|
+
this.#tlas = tlas;
|
|
367
|
+
this.#skinning = skinning;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
/**
|
|
371
|
+
* @returns {EntityComponentDataset}
|
|
372
|
+
*/
|
|
373
|
+
get dataset() {
|
|
374
|
+
return this.#dataset;
|
|
375
|
+
}
|
|
376
|
+
|
|
377
|
+
/**
|
|
378
|
+
* Bumped every time the `meshes` table gains or loses an entity's row. A row read and kept is
|
|
379
|
+
* only as valid as this number.
|
|
380
|
+
*
|
|
381
|
+
* @returns {number}
|
|
382
|
+
*/
|
|
383
|
+
get mesh_rows_version() {
|
|
384
|
+
return this.#mesh_rows_version;
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
/**
|
|
388
|
+
* Whether the entity holds a `transforms` row — acquired and not yet released, written or not.
|
|
389
|
+
*
|
|
390
|
+
* @param {number} entity
|
|
391
|
+
* @returns {boolean}
|
|
392
|
+
*/
|
|
393
|
+
has(entity) {
|
|
394
|
+
return this.#acquired.get(entity);
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
/**
|
|
398
|
+
* Whether the entity holds a `meshes` row.
|
|
399
|
+
*
|
|
400
|
+
* @param {number} entity
|
|
401
|
+
* @returns {boolean}
|
|
402
|
+
*/
|
|
403
|
+
has_mesh(entity) {
|
|
404
|
+
return this.#mesh_entries.has(entity);
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
/**
|
|
408
|
+
* Every entity holding a `meshes` row, with what the row draws — what a tool that walks the
|
|
409
|
+
* scene's primitives on this side (a CPU bake, a verifier) iterates. The order is the order
|
|
410
|
+
* the meshes were attached in.
|
|
411
|
+
*
|
|
412
|
+
* @param {function(number, MeshletGeometry, ShadeMaterial, boolean): void} visitor entity,
|
|
413
|
+
* geometry, material, whether the row draws a skinned clone
|
|
414
|
+
*/
|
|
415
|
+
for_each_mesh(visitor) {
|
|
416
|
+
assert.isFunction(visitor, 'visitor');
|
|
417
|
+
|
|
418
|
+
for (const [entity, entry] of this.#mesh_entries) {
|
|
419
|
+
visitor(entity, entry.geometry, entry.material, entry.skinned);
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
|
|
423
|
+
/**
|
|
424
|
+
* The box around everything the rows draw, as this side can compose it: each mesh entry's
|
|
425
|
+
* geometry box projected under its entity's own `Transform64` — the ECS's world pose, exact
|
|
426
|
+
* for what the CPU placed and a frame behind for a subtree the GPU drives — and the union of
|
|
427
|
+
* them. What a consumer that sizes a volume once asks for; the box that is drawn is the GPU's,
|
|
428
|
+
* read back through `GPUSceneContext.bounds`.
|
|
429
|
+
*
|
|
430
|
+
* @param {AABB3} target set to the union, or to the empty box when nothing draws
|
|
431
|
+
* @returns {boolean} whether anything draws
|
|
432
|
+
*/
|
|
433
|
+
compute_world_bounds(target) {
|
|
434
|
+
assert.defined(target, 'target');
|
|
435
|
+
|
|
436
|
+
target.setNegativelyInfiniteBounds();
|
|
437
|
+
|
|
438
|
+
let any = false;
|
|
439
|
+
|
|
440
|
+
for (const [entity, entry] of this.#mesh_entries) {
|
|
441
|
+
const world = this.#dataset.getComponent(entity, Transform64);
|
|
442
|
+
|
|
443
|
+
assert.defined(world, `entity ${entity} holds a mesh row and carries no Transform64`);
|
|
444
|
+
|
|
445
|
+
aabb3_matrix4_project(SCRATCH_WORLD_BOX, entry.geometry.bounding_box, world.matrix);
|
|
446
|
+
|
|
447
|
+
target._expandToFit(
|
|
448
|
+
SCRATCH_WORLD_BOX[0], SCRATCH_WORLD_BOX[1], SCRATCH_WORLD_BOX[2],
|
|
449
|
+
SCRATCH_WORLD_BOX[3], SCRATCH_WORLD_BOX[4], SCRATCH_WORLD_BOX[5],
|
|
450
|
+
);
|
|
451
|
+
|
|
452
|
+
any = true;
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
return any;
|
|
456
|
+
}
|
|
457
|
+
|
|
458
|
+
/**
|
|
459
|
+
* Hold the entity's `transforms` row. The first hold takes the row: it is written at the next
|
|
460
|
+
* flush, from the entity's components as they are then, and the entity must carry a
|
|
461
|
+
* `Transform64` by then. Every hold is matched by a {@link release}, and the row goes with the
|
|
462
|
+
* last one.
|
|
463
|
+
*
|
|
464
|
+
* Children already holding rows are re-marked on the first hold, so that they point at this
|
|
465
|
+
* one from the next flush instead of carrying their world pose under the scene root.
|
|
466
|
+
*
|
|
467
|
+
* @param {number} entity
|
|
468
|
+
*/
|
|
469
|
+
acquire(entity) {
|
|
470
|
+
assert.isNonNegativeInteger(entity, 'entity');
|
|
471
|
+
|
|
472
|
+
this.#ensure_capacity(entity);
|
|
473
|
+
|
|
474
|
+
if (this.#acquired.get(entity)) {
|
|
475
|
+
this.#holds[entity]++;
|
|
476
|
+
|
|
477
|
+
return;
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
this.#acquired.set(entity, true);
|
|
481
|
+
this.#written.set(entity, false);
|
|
482
|
+
this.#holds[entity] = 1;
|
|
483
|
+
|
|
484
|
+
this.#parent_entity[entity] = -1;
|
|
485
|
+
|
|
486
|
+
/*
|
|
487
|
+
Indexed under its attachment's parent from the start rather than at the first flush: the
|
|
488
|
+
animation manager walks the rows below a joint the moment a clip binds to it, which is
|
|
489
|
+
the same update the rows were acquired in. The flush re-registers, so a parent that
|
|
490
|
+
changes later is still followed.
|
|
491
|
+
*/
|
|
492
|
+
const dataset = this.#dataset;
|
|
493
|
+
const attachment_index = dataset.computeComponentTypeIndex(TransformAttachment);
|
|
494
|
+
|
|
495
|
+
if (attachment_index !== -1) {
|
|
496
|
+
const attachment = dataset.getComponentByIndex(entity, attachment_index);
|
|
497
|
+
|
|
498
|
+
if (attachment !== undefined && attachment !== null) {
|
|
499
|
+
this.#register_child(entity, attachment.parent);
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
this.#mark(entity, MARK_LOCAL);
|
|
504
|
+
|
|
505
|
+
this.#mark_children(entity);
|
|
506
|
+
}
|
|
507
|
+
|
|
508
|
+
/**
|
|
509
|
+
* Let go of the entity's `transforms` row. The last holder to let go takes it back — and its
|
|
510
|
+
* `meshes` row with it, if it had one. Children keep theirs and are re-marked, to be written
|
|
511
|
+
* under the scene root from their world pose.
|
|
512
|
+
*
|
|
513
|
+
* Safe on an entity that holds nothing.
|
|
514
|
+
*
|
|
515
|
+
* @param {number} entity
|
|
516
|
+
*/
|
|
517
|
+
release(entity) {
|
|
518
|
+
assert.isNonNegativeInteger(entity, 'entity');
|
|
519
|
+
|
|
520
|
+
if (!this.#acquired.get(entity)) {
|
|
521
|
+
return;
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
if (--this.#holds[entity] > 0) {
|
|
525
|
+
return;
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
this.#free_mesh(entity);
|
|
529
|
+
|
|
530
|
+
if (this.#written.get(entity)) {
|
|
531
|
+
this.#transforms.remove(row_of_entity(entity));
|
|
532
|
+
}
|
|
533
|
+
|
|
534
|
+
this.#acquired.set(entity, false);
|
|
535
|
+
this.#written.set(entity, false);
|
|
536
|
+
this.#reason[entity] = 0;
|
|
537
|
+
|
|
538
|
+
this.#unregister_child(entity);
|
|
539
|
+
|
|
540
|
+
this.#mark_children(entity);
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
/**
|
|
544
|
+
* The entity's local offset or its attachment changed — what its own row holds.
|
|
545
|
+
*
|
|
546
|
+
* @param {number} entity
|
|
547
|
+
*/
|
|
548
|
+
mark_local(entity) {
|
|
549
|
+
this.#mark(entity, MARK_LOCAL);
|
|
550
|
+
}
|
|
551
|
+
|
|
552
|
+
/**
|
|
553
|
+
* The entity's world transform changed. For an entity the GPU composes under a parent row this
|
|
554
|
+
* is nothing to write; for one carrying its world pose it is the row's contents.
|
|
555
|
+
*
|
|
556
|
+
* @param {number} entity
|
|
557
|
+
*/
|
|
558
|
+
mark_world(entity) {
|
|
559
|
+
this.#mark(entity, MARK_WORLD);
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
/**
|
|
563
|
+
* Every material some written mesh row draws with, each once. The array is reused until the set
|
|
564
|
+
* changes — compare {@link materials_version} to know whether it did.
|
|
565
|
+
*
|
|
566
|
+
* @returns {ShadeMaterial[]}
|
|
567
|
+
*/
|
|
568
|
+
get materials() {
|
|
569
|
+
if (this.#cached_materials_version !== this.#materials_version) {
|
|
570
|
+
this.#cached_materials = Array.from(this.#material_holds.keys());
|
|
571
|
+
this.#cached_materials_version = this.#materials_version;
|
|
572
|
+
}
|
|
573
|
+
|
|
574
|
+
return this.#cached_materials;
|
|
575
|
+
}
|
|
576
|
+
|
|
577
|
+
/**
|
|
578
|
+
* Moves when a material enters or leaves {@link materials}.
|
|
579
|
+
*
|
|
580
|
+
* @returns {number}
|
|
581
|
+
*/
|
|
582
|
+
get materials_version() {
|
|
583
|
+
return this.#materials_version;
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
/**
|
|
587
|
+
* @param {ShadeMaterial} material
|
|
588
|
+
*/
|
|
589
|
+
#hold_material(material) {
|
|
590
|
+
const holds = this.#material_holds;
|
|
591
|
+
const count = holds.get(material);
|
|
592
|
+
|
|
593
|
+
if (count === undefined) {
|
|
594
|
+
holds.set(material, 1);
|
|
595
|
+
|
|
596
|
+
this.#materials_version++;
|
|
597
|
+
} else {
|
|
598
|
+
holds.set(material, count + 1);
|
|
599
|
+
}
|
|
600
|
+
}
|
|
601
|
+
|
|
602
|
+
/**
|
|
603
|
+
* @param {ShadeMaterial} material
|
|
604
|
+
*/
|
|
605
|
+
#release_material(material) {
|
|
606
|
+
const holds = this.#material_holds;
|
|
607
|
+
const count = holds.get(material);
|
|
608
|
+
|
|
609
|
+
assert.isNonNegativeInteger(count, 'count');
|
|
610
|
+
assert.greaterThan(count, 0, 'count');
|
|
611
|
+
|
|
612
|
+
if (count === 1) {
|
|
613
|
+
holds.delete(material);
|
|
614
|
+
|
|
615
|
+
this.#materials_version++;
|
|
616
|
+
} else {
|
|
617
|
+
holds.set(material, count - 1);
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
/**
|
|
622
|
+
* Give the entity a `meshes` row for one primitive, at the same index as its `transforms` row,
|
|
623
|
+
* which it takes as well if it does not have it yet. Replacing what it draws is the same call.
|
|
624
|
+
*
|
|
625
|
+
* A skinned primitive draws a per-instance clone of `geometry`, deformed by the skinning pass
|
|
626
|
+
* against whatever skin the entity is bound to; the clone is made when the row is written and
|
|
627
|
+
* given back with the row.
|
|
628
|
+
*
|
|
629
|
+
* The mesh is one hold on the `transforms` row, released by {@link detach_mesh}.
|
|
630
|
+
*
|
|
631
|
+
* @param {number} entity
|
|
632
|
+
* @param {MeshletGeometry} geometry
|
|
633
|
+
* @param {ShadeMaterial} material
|
|
634
|
+
* @param {boolean} [skinned]
|
|
635
|
+
*/
|
|
636
|
+
attach_mesh(entity, geometry, material, skinned = false) {
|
|
637
|
+
assert.isNonNegativeInteger(entity, 'entity');
|
|
638
|
+
assert.defined(geometry, 'geometry');
|
|
639
|
+
assert.equal(geometry.isMeshletGeometry, true, 'geometry.isMeshletGeometry !== true');
|
|
640
|
+
assert.defined(material, 'material');
|
|
641
|
+
assert.isBoolean(skinned, 'skinned');
|
|
642
|
+
|
|
643
|
+
let entry = this.#mesh_entries.get(entity);
|
|
644
|
+
|
|
645
|
+
if (entry === undefined) {
|
|
646
|
+
this.acquire(entity);
|
|
647
|
+
|
|
648
|
+
entry = new MeshEntry();
|
|
649
|
+
|
|
650
|
+
this.#mesh_entries.set(entity, entry);
|
|
651
|
+
} else if (entry.written && (entry.skinned !== skinned || (skinned && entry.geometry !== geometry))) {
|
|
652
|
+
// a different clone, or none: the one the row draws goes back with the next write
|
|
653
|
+
this.#skinning().release_clone(entity);
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
entry.geometry = geometry;
|
|
657
|
+
entry.material = material;
|
|
658
|
+
entry.skinned = skinned;
|
|
659
|
+
|
|
660
|
+
this.#mark(entity, MARK_MESH);
|
|
661
|
+
}
|
|
662
|
+
|
|
663
|
+
/**
|
|
664
|
+
* Take the entity's `meshes` row back, and let go of the hold the mesh had on its
|
|
665
|
+
* `transforms` row — which stays if anything else holds it. Safe on an entity that has none.
|
|
666
|
+
*
|
|
667
|
+
* @param {number} entity
|
|
668
|
+
*/
|
|
669
|
+
detach_mesh(entity) {
|
|
670
|
+
if (!this.#mesh_entries.has(entity)) {
|
|
671
|
+
return;
|
|
672
|
+
}
|
|
673
|
+
|
|
674
|
+
this.#free_mesh(entity);
|
|
675
|
+
|
|
676
|
+
this.release(entity);
|
|
677
|
+
}
|
|
678
|
+
|
|
679
|
+
/**
|
|
680
|
+
* Give a `meshes` row back without touching the holds on the entity's `transforms` row.
|
|
681
|
+
*
|
|
682
|
+
* @param {number} entity
|
|
683
|
+
*/
|
|
684
|
+
#free_mesh(entity) {
|
|
685
|
+
const entry = this.#mesh_entries.get(entity);
|
|
686
|
+
|
|
687
|
+
if (entry === undefined) {
|
|
688
|
+
return;
|
|
689
|
+
}
|
|
690
|
+
|
|
691
|
+
this.#mesh_entries.delete(entity);
|
|
692
|
+
|
|
693
|
+
if (!entry.written) {
|
|
694
|
+
return;
|
|
695
|
+
}
|
|
696
|
+
|
|
697
|
+
const row = row_of_entity(entity);
|
|
698
|
+
|
|
699
|
+
this.#meshes.remove(row);
|
|
700
|
+
this.#tlas.instance_remove(row);
|
|
701
|
+
|
|
702
|
+
this.#release_material(entry.held);
|
|
703
|
+
|
|
704
|
+
entry.held = null;
|
|
705
|
+
|
|
706
|
+
if (entry.skinned) {
|
|
707
|
+
// the row was the only thing naming the clone; its skin binding is kept, so a row
|
|
708
|
+
// that comes back is deformed again
|
|
709
|
+
this.#skinning().release_clone(entity);
|
|
710
|
+
}
|
|
711
|
+
|
|
712
|
+
this.#mesh_rows_version++;
|
|
713
|
+
}
|
|
714
|
+
|
|
715
|
+
/**
|
|
716
|
+
* Write every marked entity's rows from its components, and clear the list.
|
|
717
|
+
*
|
|
718
|
+
* @returns {number} rows written
|
|
719
|
+
*/
|
|
720
|
+
flush() {
|
|
721
|
+
const marked = this.#marked;
|
|
722
|
+
const count = marked.length;
|
|
723
|
+
|
|
724
|
+
if (count === 0) {
|
|
725
|
+
return 0;
|
|
726
|
+
}
|
|
727
|
+
|
|
728
|
+
const dataset = this.#dataset;
|
|
729
|
+
const reason = this.#reason;
|
|
730
|
+
|
|
731
|
+
const transform_index = dataset.computeComponentTypeIndex(Transform64);
|
|
732
|
+
const attachment_index = dataset.computeComponentTypeIndex(TransformAttachment);
|
|
733
|
+
const authority_index = dataset.computeComponentTypeIndex(GPUStateAuthority);
|
|
734
|
+
|
|
735
|
+
let written = 0;
|
|
736
|
+
|
|
737
|
+
for (let i = 0; i < count; i++) {
|
|
738
|
+
const entity = marked[i];
|
|
739
|
+
const why = reason[entity];
|
|
740
|
+
|
|
741
|
+
reason[entity] = 0;
|
|
742
|
+
|
|
743
|
+
if (why === 0 || !this.#acquired.get(entity)) {
|
|
744
|
+
// released since it was marked
|
|
745
|
+
continue;
|
|
746
|
+
}
|
|
747
|
+
|
|
748
|
+
assert.ok(dataset.entityExists(entity), `entity ${entity} holds a row but is not in the dataset — release its row before removing it`);
|
|
749
|
+
assert.notEqual(transform_index, -1, 'Transform64 is not a registered component type of the dataset');
|
|
750
|
+
|
|
751
|
+
const world = dataset.getComponentByIndex(entity, transform_index);
|
|
752
|
+
|
|
753
|
+
assert.defined(world, `entity ${entity} holds a row and no Transform64`);
|
|
754
|
+
|
|
755
|
+
const attachment = attachment_index === -1
|
|
756
|
+
? undefined
|
|
757
|
+
: dataset.getComponentByIndex(entity, attachment_index);
|
|
758
|
+
|
|
759
|
+
const authority = authority_index === -1
|
|
760
|
+
? undefined
|
|
761
|
+
: dataset.getComponentByIndex(entity, authority_index);
|
|
762
|
+
|
|
763
|
+
const flags = authority === undefined ? 0 : authority.flags;
|
|
764
|
+
|
|
765
|
+
written += this.#flush_transform(entity, why, world, attachment, flags);
|
|
766
|
+
written += this.#flush_mesh(entity, why);
|
|
767
|
+
}
|
|
768
|
+
|
|
769
|
+
marked.length = 0;
|
|
770
|
+
|
|
771
|
+
return written;
|
|
772
|
+
}
|
|
773
|
+
|
|
774
|
+
/**
|
|
775
|
+
* @param {number} entity
|
|
776
|
+
* @param {number} why
|
|
777
|
+
* @param {Transform64} world
|
|
778
|
+
* @param {TransformAttachment|undefined} attachment
|
|
779
|
+
* @param {number} flags
|
|
780
|
+
* @returns {number} rows written
|
|
781
|
+
*/
|
|
782
|
+
#flush_transform(entity, why, world, attachment, flags) {
|
|
783
|
+
const row = row_of_entity(entity);
|
|
784
|
+
|
|
785
|
+
const parent = attachment === undefined ? -1 : attachment.parent;
|
|
786
|
+
|
|
787
|
+
this.#register_child(entity, parent);
|
|
788
|
+
|
|
789
|
+
const parent_has_row = parent >= 0 && this.#acquired.get(parent);
|
|
790
|
+
|
|
791
|
+
const parent_row = parent_has_row ? row_of_entity(parent) : NODE3D_SCENE_ID;
|
|
792
|
+
|
|
793
|
+
// What the row's local TRS is: the offset from the parent row when there is one, the world
|
|
794
|
+
// pose under the scene root when there is not. The second is exact — the ECS composed it.
|
|
795
|
+
const local = parent_has_row ? attachment.transform : world;
|
|
796
|
+
|
|
797
|
+
const first = !this.#written.get(entity);
|
|
798
|
+
|
|
799
|
+
if (first) {
|
|
800
|
+
this.#transforms.set_record(row, this.#seed_record(local, parent_row, world), TRANSFORM_RECORD_WRITER);
|
|
801
|
+
|
|
802
|
+
this.#written.set(entity, true);
|
|
803
|
+
this.#parent_row[entity] = parent_row;
|
|
804
|
+
|
|
805
|
+
return 1;
|
|
806
|
+
}
|
|
807
|
+
|
|
808
|
+
const parent_changed = this.#parent_row[entity] !== parent_row;
|
|
809
|
+
|
|
810
|
+
if ((flags & GPUStateAuthorityFlags.TransformAttachment) !== 0) {
|
|
811
|
+
// The GPU writes this row's TRS — a clip, a pose the CPU never sees — and a CPU that
|
|
812
|
+
// wrote it too would race what the animation just resolved. The parent row is still
|
|
813
|
+
// this side's, and changes only when the parent's own row comes or goes.
|
|
814
|
+
if (!parent_changed) {
|
|
815
|
+
return 0;
|
|
816
|
+
}
|
|
817
|
+
|
|
818
|
+
TRANSFORM_RECORD.parent = parent_row;
|
|
819
|
+
|
|
820
|
+
this.#transforms.set_fields(row, TRANSFORM_RECORD, TRANSFORM_PARENT_WRITER);
|
|
821
|
+
|
|
822
|
+
this.#parent_row[entity] = parent_row;
|
|
823
|
+
|
|
824
|
+
return 1;
|
|
825
|
+
}
|
|
826
|
+
|
|
827
|
+
const moved = parent_has_row
|
|
828
|
+
? (why & MARK_LOCAL) !== 0
|
|
829
|
+
: (why & (MARK_LOCAL | MARK_WORLD)) !== 0;
|
|
830
|
+
|
|
831
|
+
if (!moved && !parent_changed) {
|
|
832
|
+
return 0;
|
|
833
|
+
}
|
|
834
|
+
|
|
835
|
+
this.#transforms.set_fields(row, this.#local_record(local, parent_row), TRANSFORM_LOCAL_WRITER);
|
|
836
|
+
|
|
837
|
+
this.#parent_row[entity] = parent_row;
|
|
838
|
+
|
|
839
|
+
return 1;
|
|
840
|
+
}
|
|
841
|
+
|
|
842
|
+
/**
|
|
843
|
+
* @param {number} entity
|
|
844
|
+
* @param {number} why
|
|
845
|
+
* @returns {number} rows written
|
|
846
|
+
*/
|
|
847
|
+
#flush_mesh(entity, why) {
|
|
848
|
+
const entry = this.#mesh_entries.get(entity);
|
|
849
|
+
|
|
850
|
+
if (entry === undefined) {
|
|
851
|
+
return 0;
|
|
852
|
+
}
|
|
853
|
+
|
|
854
|
+
const row = row_of_entity(entity);
|
|
855
|
+
|
|
856
|
+
if (entry.written && (why & MARK_MESH) === 0) {
|
|
857
|
+
if ((why & (MARK_WORLD | MARK_LOCAL)) !== 0) {
|
|
858
|
+
// The row's bounds are the GPU's — the bounds pass derives them under the composed
|
|
859
|
+
// global — and nothing on this side keeps a copy; what moved is the tree, which is
|
|
860
|
+
// rebuilt over them.
|
|
861
|
+
this.#tlas.instance_update(row);
|
|
862
|
+
}
|
|
863
|
+
|
|
864
|
+
return 0;
|
|
865
|
+
}
|
|
866
|
+
|
|
867
|
+
const geometry = entry.geometry;
|
|
868
|
+
|
|
869
|
+
this.#geometries.add(geometry);
|
|
870
|
+
this.#materials.obtain(entry.material);
|
|
871
|
+
|
|
872
|
+
if (entry.held !== entry.material) {
|
|
873
|
+
if (entry.held !== null) {
|
|
874
|
+
this.#release_material(entry.held);
|
|
875
|
+
}
|
|
876
|
+
|
|
877
|
+
this.#hold_material(entry.material);
|
|
878
|
+
|
|
879
|
+
entry.held = entry.material;
|
|
880
|
+
}
|
|
881
|
+
|
|
882
|
+
MESH_RECORD.geometry = entry.skinned
|
|
883
|
+
? this.#skinning().obtain_clone(entity, geometry).index
|
|
884
|
+
: this.#geometries.getAddress(geometry);
|
|
885
|
+
MESH_RECORD.material = entry.material.id;
|
|
886
|
+
MESH_RECORD.node = row;
|
|
887
|
+
|
|
888
|
+
this.#meshes.set_record(row, MESH_RECORD, MESH_RECORD_WRITER);
|
|
889
|
+
|
|
890
|
+
if (entry.written) {
|
|
891
|
+
this.#tlas.instance_update(row);
|
|
892
|
+
} else {
|
|
893
|
+
entry.written = true;
|
|
894
|
+
|
|
895
|
+
this.#tlas.instance_add(row);
|
|
896
|
+
|
|
897
|
+
this.#mesh_rows_version++;
|
|
898
|
+
}
|
|
899
|
+
|
|
900
|
+
return 1;
|
|
901
|
+
}
|
|
902
|
+
|
|
903
|
+
/**
|
|
904
|
+
* @param {Transform64} local
|
|
905
|
+
* @param {number} parent_row
|
|
906
|
+
* @returns {object} the module-static record, valid until the next call
|
|
907
|
+
*/
|
|
908
|
+
#local_record(local, parent_row) {
|
|
909
|
+
// through the scalar accessors: the vector properties are live views, freshly allocated
|
|
910
|
+
// on every access, and this runs once per changed row per frame
|
|
911
|
+
TRANSFORM_RECORD.local_translation[0] = local.translation_x;
|
|
912
|
+
TRANSFORM_RECORD.local_translation[1] = local.translation_y;
|
|
913
|
+
TRANSFORM_RECORD.local_translation[2] = local.translation_z;
|
|
914
|
+
|
|
915
|
+
TRANSFORM_RECORD.local_rotation[0] = local.rotation_x;
|
|
916
|
+
TRANSFORM_RECORD.local_rotation[1] = local.rotation_y;
|
|
917
|
+
TRANSFORM_RECORD.local_rotation[2] = local.rotation_z;
|
|
918
|
+
TRANSFORM_RECORD.local_rotation[3] = local.rotation_w;
|
|
919
|
+
|
|
920
|
+
TRANSFORM_RECORD.local_scale[0] = local.scale_x;
|
|
921
|
+
TRANSFORM_RECORD.local_scale[1] = local.scale_y;
|
|
922
|
+
TRANSFORM_RECORD.local_scale[2] = local.scale_z;
|
|
923
|
+
|
|
924
|
+
TRANSFORM_RECORD.parent = parent_row;
|
|
925
|
+
|
|
926
|
+
return TRANSFORM_RECORD;
|
|
927
|
+
}
|
|
928
|
+
|
|
929
|
+
/**
|
|
930
|
+
* @param {Transform64} local
|
|
931
|
+
* @param {number} parent_row
|
|
932
|
+
* @param {Transform64} world
|
|
933
|
+
* @returns {object} the module-static record, valid until the next call
|
|
934
|
+
*/
|
|
935
|
+
#seed_record(local, parent_row, world) {
|
|
936
|
+
this.#local_record(local, parent_row);
|
|
937
|
+
|
|
938
|
+
for (let i = 0; i < 16; i++) {
|
|
939
|
+
TRANSFORM_RECORD.global[i] = world[i];
|
|
940
|
+
TRANSFORM_RECORD.prev_global[i] = world[i];
|
|
941
|
+
}
|
|
942
|
+
|
|
943
|
+
return TRANSFORM_RECORD;
|
|
944
|
+
}
|
|
945
|
+
|
|
946
|
+
/**
|
|
947
|
+
* @param {number} entity
|
|
948
|
+
* @param {number} why
|
|
949
|
+
*/
|
|
950
|
+
#mark(entity, why) {
|
|
951
|
+
assert.isNonNegativeInteger(entity, 'entity');
|
|
952
|
+
|
|
953
|
+
if (!this.#acquired.get(entity)) {
|
|
954
|
+
// nothing to write for an entity holding no row; a mark is not an acquire
|
|
955
|
+
return;
|
|
956
|
+
}
|
|
957
|
+
|
|
958
|
+
const reason = this.#reason;
|
|
959
|
+
|
|
960
|
+
if (reason[entity] === 0) {
|
|
961
|
+
this.#marked.push(entity);
|
|
962
|
+
}
|
|
963
|
+
|
|
964
|
+
reason[entity] |= why;
|
|
965
|
+
}
|
|
966
|
+
|
|
967
|
+
/**
|
|
968
|
+
* Re-mark every acquired entity whose attachment names `parent`.
|
|
969
|
+
*
|
|
970
|
+
* @param {number} parent
|
|
971
|
+
*/
|
|
972
|
+
/**
|
|
973
|
+
* Visit every entity holding a row below `entity`, parents before their children.
|
|
974
|
+
*
|
|
975
|
+
* The index behind this is the one the rows keep for re-marking a subtree when its parent's
|
|
976
|
+
* row appears or goes; an entity with no row is not in it, and neither are its children.
|
|
977
|
+
*
|
|
978
|
+
* @param {number} entity
|
|
979
|
+
* @param {function(number): void} visitor
|
|
980
|
+
*/
|
|
981
|
+
for_each_descendant(entity, visitor) {
|
|
982
|
+
assert.isNonNegativeInteger(entity, 'entity');
|
|
983
|
+
assert.typeOf(visitor, 'function', 'visitor');
|
|
984
|
+
|
|
985
|
+
const children = this.#children.get(entity);
|
|
986
|
+
|
|
987
|
+
if (children === undefined) {
|
|
988
|
+
return;
|
|
989
|
+
}
|
|
990
|
+
|
|
991
|
+
for (const child of children) {
|
|
992
|
+
visitor(child);
|
|
993
|
+
|
|
994
|
+
this.for_each_descendant(child, visitor);
|
|
995
|
+
}
|
|
996
|
+
}
|
|
997
|
+
|
|
998
|
+
#mark_children(parent) {
|
|
999
|
+
const children = this.#children.get(parent);
|
|
1000
|
+
|
|
1001
|
+
if (children === undefined) {
|
|
1002
|
+
return;
|
|
1003
|
+
}
|
|
1004
|
+
|
|
1005
|
+
for (const child of children) {
|
|
1006
|
+
this.#mark(child, MARK_LOCAL);
|
|
1007
|
+
}
|
|
1008
|
+
}
|
|
1009
|
+
|
|
1010
|
+
/**
|
|
1011
|
+
* Keep {@link #children} in step with what the entity's attachment names.
|
|
1012
|
+
*
|
|
1013
|
+
* @param {number} entity
|
|
1014
|
+
* @param {number} parent the entity its attachment names, or -1
|
|
1015
|
+
*/
|
|
1016
|
+
#register_child(entity, parent) {
|
|
1017
|
+
const previous = this.#parent_entity[entity];
|
|
1018
|
+
|
|
1019
|
+
if (previous === parent) {
|
|
1020
|
+
return;
|
|
1021
|
+
}
|
|
1022
|
+
|
|
1023
|
+
this.#unregister_child(entity);
|
|
1024
|
+
|
|
1025
|
+
if (parent < 0) {
|
|
1026
|
+
return;
|
|
1027
|
+
}
|
|
1028
|
+
|
|
1029
|
+
let children = this.#children.get(parent);
|
|
1030
|
+
|
|
1031
|
+
if (children === undefined) {
|
|
1032
|
+
children = new Set();
|
|
1033
|
+
|
|
1034
|
+
this.#children.set(parent, children);
|
|
1035
|
+
}
|
|
1036
|
+
|
|
1037
|
+
children.add(entity);
|
|
1038
|
+
|
|
1039
|
+
this.#parent_entity[entity] = parent;
|
|
1040
|
+
}
|
|
1041
|
+
|
|
1042
|
+
/**
|
|
1043
|
+
* @param {number} entity
|
|
1044
|
+
*/
|
|
1045
|
+
#unregister_child(entity) {
|
|
1046
|
+
const previous = this.#parent_entity[entity];
|
|
1047
|
+
|
|
1048
|
+
if (previous < 0) {
|
|
1049
|
+
return;
|
|
1050
|
+
}
|
|
1051
|
+
|
|
1052
|
+
const children = this.#children.get(previous);
|
|
1053
|
+
|
|
1054
|
+
if (children !== undefined) {
|
|
1055
|
+
children.delete(entity);
|
|
1056
|
+
|
|
1057
|
+
if (children.size === 0) {
|
|
1058
|
+
this.#children.delete(previous);
|
|
1059
|
+
}
|
|
1060
|
+
}
|
|
1061
|
+
|
|
1062
|
+
this.#parent_entity[entity] = -1;
|
|
1063
|
+
}
|
|
1064
|
+
|
|
1065
|
+
/**
|
|
1066
|
+
* Grow the per-entity arrays to cover `entity`. Doubling, so a dataset that grows steadily
|
|
1067
|
+
* pays for this a logarithmic number of times.
|
|
1068
|
+
*
|
|
1069
|
+
* @param {number} entity
|
|
1070
|
+
*/
|
|
1071
|
+
#ensure_capacity(entity) {
|
|
1072
|
+
const length = this.#reason.length;
|
|
1073
|
+
|
|
1074
|
+
if (entity < length) {
|
|
1075
|
+
return;
|
|
1076
|
+
}
|
|
1077
|
+
|
|
1078
|
+
let size = length;
|
|
1079
|
+
|
|
1080
|
+
while (size <= entity) {
|
|
1081
|
+
size *= 2;
|
|
1082
|
+
}
|
|
1083
|
+
|
|
1084
|
+
const reason = new Uint8Array(size);
|
|
1085
|
+
reason.set(this.#reason);
|
|
1086
|
+
this.#reason = reason;
|
|
1087
|
+
|
|
1088
|
+
const holds = new Uint16Array(size);
|
|
1089
|
+
holds.set(this.#holds);
|
|
1090
|
+
this.#holds = holds;
|
|
1091
|
+
|
|
1092
|
+
const parent_row = new Uint32Array(size);
|
|
1093
|
+
parent_row.set(this.#parent_row);
|
|
1094
|
+
this.#parent_row = parent_row;
|
|
1095
|
+
|
|
1096
|
+
const parent_entity = new Int32Array(size).fill(-1);
|
|
1097
|
+
parent_entity.set(this.#parent_entity);
|
|
1098
|
+
this.#parent_entity = parent_entity;
|
|
1099
|
+
}
|
|
1100
|
+
|
|
1101
|
+
/**
|
|
1102
|
+
* Forget everything, freeing every row. For the context's own teardown.
|
|
1103
|
+
*/
|
|
1104
|
+
destroy() {
|
|
1105
|
+
for (const [entity, entry] of this.#mesh_entries) {
|
|
1106
|
+
if (entry.written) {
|
|
1107
|
+
const row = row_of_entity(entity);
|
|
1108
|
+
|
|
1109
|
+
this.#meshes.remove(row);
|
|
1110
|
+
this.#tlas.instance_remove(row);
|
|
1111
|
+
|
|
1112
|
+
if (entry.skinned) {
|
|
1113
|
+
this.#skinning().release_clone(entity);
|
|
1114
|
+
}
|
|
1115
|
+
}
|
|
1116
|
+
}
|
|
1117
|
+
|
|
1118
|
+
this.#mesh_entries.clear();
|
|
1119
|
+
|
|
1120
|
+
const acquired = this.#acquired;
|
|
1121
|
+
|
|
1122
|
+
for (let entity = acquired.nextSetBit(0); entity !== -1; entity = acquired.nextSetBit(entity + 1)) {
|
|
1123
|
+
if (this.#written.get(entity)) {
|
|
1124
|
+
this.#transforms.remove(row_of_entity(entity));
|
|
1125
|
+
}
|
|
1126
|
+
}
|
|
1127
|
+
|
|
1128
|
+
acquired.reset();
|
|
1129
|
+
this.#written.reset();
|
|
1130
|
+
this.#reason.fill(0);
|
|
1131
|
+
this.#holds.fill(0);
|
|
1132
|
+
this.#marked.length = 0;
|
|
1133
|
+
this.#children.clear();
|
|
1134
|
+
this.#parent_entity.fill(-1);
|
|
1135
|
+
}
|
|
1136
|
+
}
|