@woosh/meep-engine 3.22.0 → 3.23.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/package.json +1 -1
- package/src/core/geom/3d/hash-grid/PointHashGrid3.d.ts +118 -0
- package/src/core/geom/3d/hash-grid/PointHashGrid3.d.ts.map +1 -0
- package/src/core/geom/3d/hash-grid/PointHashGrid3.js +283 -0
- package/src/core/geom/3d/shape/BoxShape3D.d.ts.map +1 -1
- package/src/core/geom/3d/shape/BoxShape3D.js +6 -17
- package/src/core/geom/3d/shape/CapsuleShape3D.d.ts.map +1 -1
- package/src/core/geom/3d/shape/CapsuleShape3D.js +3 -14
- package/src/core/geom/3d/shape/CylinderShape3D.d.ts.map +1 -1
- package/src/core/geom/3d/shape/CylinderShape3D.js +3 -21
- package/src/core/geom/3d/shape/PlaneShape3D.d.ts +105 -0
- package/src/core/geom/3d/shape/PlaneShape3D.d.ts.map +1 -0
- package/src/core/geom/3d/shape/PlaneShape3D.js +251 -0
- package/src/core/geom/3d/shape/SphereShape3D.js +3 -3
- package/src/core/geom/3d/shape/json/shape_to_type.d.ts.map +1 -1
- package/src/core/geom/3d/shape/json/shape_to_type.js +3 -0
- package/src/core/geom/3d/shape/json/type_adapters.d.ts +14 -0
- package/src/core/geom/3d/shape/json/type_adapters.d.ts.map +1 -1
- package/src/core/geom/3d/shape/json/type_adapters.js +15 -0
- package/src/core/geom/3d/shape/sdf/sdf3_box.d.ts +51 -0
- package/src/core/geom/3d/shape/sdf/sdf3_box.d.ts.map +1 -0
- package/src/core/geom/3d/shape/sdf/sdf3_box.js +113 -0
- package/src/core/geom/3d/shape/sdf/sdf3_capsule.d.ts +46 -0
- package/src/core/geom/3d/shape/sdf/sdf3_capsule.d.ts.map +1 -0
- package/src/core/geom/3d/shape/sdf/sdf3_capsule.js +82 -0
- package/src/core/geom/3d/shape/sdf/sdf3_cylinder.d.ts +60 -0
- package/src/core/geom/3d/shape/sdf/sdf3_cylinder.d.ts.map +1 -0
- package/src/core/geom/3d/shape/sdf/sdf3_cylinder.js +126 -0
- package/src/core/geom/3d/shape/sdf/sdf3_degenerate_normal.d.ts +50 -0
- package/src/core/geom/3d/shape/sdf/sdf3_degenerate_normal.d.ts.map +1 -0
- package/src/core/geom/3d/shape/sdf/sdf3_degenerate_normal.js +53 -0
- package/src/core/geom/3d/shape/sdf/sdf3_plane.d.ts +52 -0
- package/src/core/geom/3d/shape/sdf/sdf3_plane.d.ts.map +1 -0
- package/src/core/geom/3d/shape/sdf/sdf3_plane.js +61 -0
- package/src/core/geom/3d/shape/sdf/sdf3_sphere.d.ts +41 -0
- package/src/core/geom/3d/shape/sdf/sdf3_sphere.d.ts.map +1 -0
- package/src/core/geom/3d/shape/sdf/sdf3_sphere.js +71 -0
- package/src/core/process/ConcurrencyGate.d.ts +103 -0
- package/src/core/process/ConcurrencyGate.d.ts.map +1 -0
- package/src/core/process/ConcurrencyGate.js +207 -0
- package/src/engine/asset/AssetManager.d.ts +10 -0
- package/src/engine/asset/AssetManager.d.ts.map +1 -1
- package/src/engine/asset/AssetManager.js +10 -0
- package/src/engine/graphics/CONTEXT_LOSS_RECOVERY_PLAN.md +30 -13
- package/src/engine/graphics3/pose/collect_entity_playbacks.d.ts +26 -0
- package/src/engine/graphics3/pose/collect_entity_playbacks.d.ts.map +1 -0
- package/src/engine/graphics3/pose/collect_entity_playbacks.js +40 -0
- 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 +74 -101
- package/src/engine/physics/cloth/MEASUREMENTS.md +1287 -4
- package/src/engine/physics/cloth/PLAN.md +1967 -1581
- package/src/engine/physics/cloth/build/ClothProxy.d.ts +147 -0
- package/src/engine/physics/cloth/build/ClothProxy.d.ts.map +1 -0
- package/src/engine/physics/cloth/build/ClothProxy.js +207 -0
- package/src/engine/physics/cloth/build/cloth_proxy_from_joints.d.ts +70 -0
- package/src/engine/physics/cloth/build/cloth_proxy_from_joints.d.ts.map +1 -0
- package/src/engine/physics/cloth/build/cloth_proxy_from_joints.js +256 -0
- package/src/engine/physics/cloth/collider/ClothColliderIndex.d.ts +176 -0
- package/src/engine/physics/cloth/collider/ClothColliderIndex.d.ts.map +1 -0
- package/src/engine/physics/cloth/collider/ClothColliderIndex.js +435 -0
- package/src/engine/physics/cloth/collider/ClothColliderKind.d.ts +12 -0
- package/src/engine/physics/cloth/collider/ClothColliderKind.d.ts.map +1 -0
- package/src/engine/physics/cloth/collider/ClothColliderKind.js +38 -0
- package/src/engine/physics/cloth/collider/ClothColliderRecord.d.ts +120 -0
- package/src/engine/physics/cloth/collider/ClothColliderRecord.d.ts.map +1 -0
- package/src/engine/physics/cloth/collider/ClothColliderRecord.js +137 -0
- package/src/engine/physics/cloth/collider/cloth_collider_bounds.d.ts +25 -0
- package/src/engine/physics/cloth/collider/cloth_collider_bounds.d.ts.map +1 -0
- package/src/engine/physics/cloth/collider/cloth_collider_bounds.js +190 -0
- package/src/engine/physics/cloth/collider/cloth_collider_pack.d.ts +44 -0
- package/src/engine/physics/cloth/collider/cloth_collider_pack.d.ts.map +1 -0
- package/src/engine/physics/cloth/collider/cloth_collider_pack.js +173 -0
- package/src/engine/physics/cloth/collider/cloth_collider_sdf.d.ts +94 -0
- package/src/engine/physics/cloth/collider/cloth_collider_sdf.d.ts.map +1 -0
- package/src/engine/physics/cloth/collider/cloth_collider_sdf.js +275 -0
- package/src/engine/physics/cloth/ecs/ClothCollider.d.ts +126 -0
- package/src/engine/physics/cloth/ecs/ClothCollider.d.ts.map +1 -0
- package/src/engine/physics/cloth/ecs/ClothCollider.js +199 -0
- package/src/engine/physics/cloth/ecs/ClothColliderFlags.d.ts +9 -0
- package/src/engine/physics/cloth/ecs/ClothColliderFlags.d.ts.map +1 -0
- package/src/engine/physics/cloth/ecs/ClothColliderFlags.js +32 -0
- package/src/engine/physics/cloth/ecs/ClothColliderSystem.d.ts +114 -0
- package/src/engine/physics/cloth/ecs/ClothColliderSystem.d.ts.map +1 -0
- package/src/engine/physics/cloth/ecs/ClothColliderSystem.js +243 -0
- package/src/engine/physics/cloth/ecs/ClothDynamicsFlags.js +66 -57
- package/src/engine/physics/cloth/ecs/ClothInstance.d.ts +109 -1
- package/src/engine/physics/cloth/ecs/ClothInstance.d.ts.map +1 -1
- package/src/engine/physics/cloth/ecs/ClothInstance.js +479 -363
- package/src/engine/physics/cloth/ecs/ClothRig.d.ts +95 -0
- package/src/engine/physics/cloth/ecs/ClothRig.d.ts.map +1 -0
- package/src/engine/physics/cloth/ecs/ClothRig.js +140 -0
- package/src/engine/physics/cloth/ecs/ClothSystem.d.ts +30 -1
- package/src/engine/physics/cloth/ecs/ClothSystem.d.ts.map +1 -1
- package/src/engine/physics/cloth/ecs/ClothSystem.js +1021 -773
- package/src/engine/physics/cloth/ecs/cloth_build_rows.d.ts +90 -0
- package/src/engine/physics/cloth/ecs/cloth_build_rows.d.ts.map +1 -0
- package/src/engine/physics/cloth/ecs/cloth_build_rows.js +374 -0
- package/src/engine/physics/cloth/ecs/cloth_dynamics_library.d.ts +32 -3
- package/src/engine/physics/cloth/ecs/cloth_dynamics_library.d.ts.map +1 -1
- package/src/engine/physics/cloth/ecs/cloth_dynamics_library.js +283 -254
- package/src/engine/physics/cloth/ecs/cloth_gather_colliders.d.ts +59 -0
- package/src/engine/physics/cloth/ecs/cloth_gather_colliders.d.ts.map +1 -0
- package/src/engine/physics/cloth/ecs/cloth_gather_colliders.js +328 -0
- package/src/engine/physics/cloth/ecs/cloth_reconstruct_pose.d.ts +13 -0
- package/src/engine/physics/cloth/ecs/cloth_reconstruct_pose.d.ts.map +1 -0
- package/src/engine/physics/cloth/ecs/cloth_reconstruct_pose.js +288 -0
- package/src/engine/physics/cloth/ecs/cloth_seed_rig.d.ts +58 -0
- package/src/engine/physics/cloth/ecs/cloth_seed_rig.d.ts.map +1 -0
- package/src/engine/physics/cloth/ecs/cloth_seed_rig.js +199 -0
- package/src/engine/physics/cloth/ecs/cloth_seed_subtree.d.ts +8 -63
- package/src/engine/physics/cloth/ecs/cloth_seed_subtree.d.ts.map +1 -1
- package/src/engine/physics/cloth/ecs/cloth_seed_subtree.js +317 -645
- package/src/engine/physics/cloth/ecs/cloth_write_back.d.ts +61 -0
- package/src/engine/physics/cloth/ecs/cloth_write_back.d.ts.map +1 -1
- package/src/engine/physics/cloth/ecs/cloth_write_back.js +212 -449
- package/src/engine/physics/cloth/ecs/cloth_write_back_rig.d.ts +49 -0
- package/src/engine/physics/cloth/ecs/cloth_write_back_rig.d.ts.map +1 -0
- package/src/engine/physics/cloth/ecs/cloth_write_back_rig.js +115 -0
- package/src/engine/physics/cloth/playground/README.md +155 -1
- package/src/engine/physics/cloth/playground/collide.html +178 -0
- package/src/engine/physics/cloth/playground/collide_build.d.ts +95 -0
- package/src/engine/physics/cloth/playground/collide_build.d.ts.map +1 -0
- package/src/engine/physics/cloth/playground/collide_build.js +315 -0
- package/src/engine/physics/cloth/playground/collide_main.d.ts +2 -0
- package/src/engine/physics/cloth/playground/collide_main.d.ts.map +1 -0
- package/src/engine/physics/cloth/playground/collide_main.js +720 -0
- package/src/engine/physics/cloth/playground/garment.html +182 -0
- package/src/engine/physics/cloth/playground/garment_build.d.ts +78 -0
- package/src/engine/physics/cloth/playground/garment_build.d.ts.map +1 -0
- package/src/engine/physics/cloth/playground/garment_build.js +359 -0
- package/src/engine/physics/cloth/playground/garment_main.d.ts +2 -0
- package/src/engine/physics/cloth/playground/garment_main.d.ts.map +1 -0
- package/src/engine/physics/cloth/playground/garment_main.js +633 -0
- package/src/engine/physics/cloth/solver/ClothState.d.ts +208 -5
- package/src/engine/physics/cloth/solver/ClothState.d.ts.map +1 -1
- package/src/engine/physics/cloth/solver/ClothState.js +302 -8
- package/src/engine/physics/cloth/solver/cloth_contact_find.d.ts +87 -0
- package/src/engine/physics/cloth/solver/cloth_contact_find.d.ts.map +1 -0
- package/src/engine/physics/cloth/solver/cloth_contact_find.js +343 -0
- package/src/engine/physics/cloth/solver/cloth_self_find.d.ts +112 -0
- package/src/engine/physics/cloth/solver/cloth_self_find.d.ts.map +1 -0
- package/src/engine/physics/cloth/solver/cloth_self_find.js +448 -0
- package/src/engine/physics/cloth/solver/cloth_solve_vertex.d.ts +4 -1
- package/src/engine/physics/cloth/solver/cloth_solve_vertex.d.ts.map +1 -1
- package/src/engine/physics/cloth/solver/cloth_solve_vertex.js +16 -1
- package/src/engine/physics/cloth/solver/cloth_solver_constants.d.ts +112 -5
- package/src/engine/physics/cloth/solver/cloth_solver_constants.d.ts.map +1 -1
- package/src/engine/physics/cloth/solver/cloth_solver_constants.js +117 -6
- package/src/engine/physics/cloth/solver/cloth_step.d.ts +40 -9
- package/src/engine/physics/cloth/solver/cloth_step.d.ts.map +1 -1
- package/src/engine/physics/cloth/solver/cloth_step.js +122 -10
- package/src/engine/physics/cloth/solver/constraint/cloth_backstop_row.d.ts +95 -0
- package/src/engine/physics/cloth/solver/constraint/cloth_backstop_row.d.ts.map +1 -0
- package/src/engine/physics/cloth/solver/constraint/cloth_backstop_row.js +285 -0
- package/src/engine/physics/cloth/solver/constraint/cloth_contact_row.d.ts +129 -0
- package/src/engine/physics/cloth/solver/constraint/cloth_contact_row.d.ts.map +1 -0
- package/src/engine/physics/cloth/solver/constraint/cloth_contact_row.js +501 -0
- package/src/engine/physics/cloth/solver/constraint/cloth_self_row.d.ts +75 -0
- package/src/engine/physics/cloth/solver/constraint/cloth_self_row.d.ts.map +1 -0
- package/src/engine/physics/cloth/solver/constraint/cloth_self_row.js +202 -0
- package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
- package/src/shade/playground/vgeo_viewer/README.md +18 -0
- package/src/shade/playground/vgeo_viewer/main.js +87 -50
- package/src/shade/renderer/buffer/table/GPUDatabase.d.ts.map +1 -1
- package/src/shade/renderer/buffer/table/GPUDatabase.js +191 -62
- package/src/shade/renderer/buffer/table/GPUTypedTable.d.ts +94 -2
- package/src/shade/renderer/buffer/table/GPUTypedTable.d.ts.map +1 -1
- package/src/shade/renderer/buffer/table/GPUTypedTable.js +414 -2
- package/src/shade/renderer/buffer/table/GPU_TABLE_PARTIAL_UPLOAD_DESCRIPTOR_WORDS.d.ts +14 -0
- package/src/shade/renderer/buffer/table/GPU_TABLE_PARTIAL_UPLOAD_DESCRIPTOR_WORDS.d.ts.map +1 -0
- package/src/shade/renderer/buffer/table/GPU_TABLE_PARTIAL_UPLOAD_DESCRIPTOR_WORDS.js +13 -0
- package/src/shade/renderer/buffer/table/gpu_table_partial_upload_shader.d.ts +17 -0
- package/src/shade/renderer/buffer/table/gpu_table_partial_upload_shader.d.ts.map +1 -0
- package/src/shade/renderer/buffer/table/gpu_table_partial_upload_shader.js +116 -0
- package/src/shade/renderer/geometry/bvh/GPUGeometryBVHManager.d.ts +9 -4
- package/src/shade/renderer/geometry/bvh/GPUGeometryBVHManager.d.ts.map +1 -1
- package/src/shade/renderer/geometry/bvh/GPUGeometryBVHManager.js +843 -734
- package/src/shade/renderer/geometry/bvh/GPUGeometryMeshletsBVH.d.ts +12 -0
- package/src/shade/renderer/geometry/bvh/GPUGeometryMeshletsBVH.d.ts.map +1 -1
- package/src/shade/renderer/geometry/bvh/GPUGeometryMeshletsBVH.js +13 -0
- package/src/shade/renderer/geometry/meshlet/GPUMeshletManager.d.ts +17 -0
- package/src/shade/renderer/geometry/meshlet/GPUMeshletManager.d.ts.map +1 -1
- package/src/shade/renderer/geometry/meshlet/GPUMeshletManager.js +185 -30
- package/src/shade/renderer/geometry/virtual/MICRON_COMPARISON_2026_08_20.md +17 -0
- package/src/shade/renderer/geometry/virtual/VGEO_FORMAT.md +141 -24
- package/src/shade/renderer/geometry/virtual/VIRTUAL_GEOMETRY_DESIGN.md +204 -64
- package/src/shade/renderer/geometry/virtual/VIRTUAL_GEOMETRY_PLAN.md +110 -10
- package/src/shade/renderer/geometry/virtual/VK_LOD_CLUSTERS_COMPARISON_2026_08_20.md +19 -0
- package/src/shade/renderer/geometry/virtual/format/read/VGeoByteSource.d.ts +19 -6
- package/src/shade/renderer/geometry/virtual/format/read/VGeoByteSource.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/format/read/VGeoByteSource.js +26 -7
- package/src/shade/renderer/geometry/virtual/format/read/VGeoContainerReader.d.ts +173 -14
- package/src/shade/renderer/geometry/virtual/format/read/VGeoContainerReader.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/format/read/VGeoContainerReader.js +458 -51
- package/src/shade/renderer/geometry/virtual/format/read/VGeoReadOptions.d.ts +49 -13
- package/src/shade/renderer/geometry/virtual/format/read/VGeoReadOptions.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/format/read/VGeoReadOptions.js +52 -14
- package/src/shade/renderer/geometry/virtual/format/read/tool/VGEO_MAX_AUDIT_BYTES.d.ts +20 -0
- package/src/shade/renderer/geometry/virtual/format/read/tool/VGEO_MAX_AUDIT_BYTES.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/format/read/tool/VGEO_MAX_AUDIT_BYTES.js +19 -0
- package/src/shade/renderer/geometry/virtual/format/read/tool/vgeo_audit_container.d.ts +27 -0
- package/src/shade/renderer/geometry/virtual/format/read/tool/vgeo_audit_container.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/format/read/tool/vgeo_audit_container.js +48 -0
- package/src/shade/renderer/geometry/virtual/format/read/tool/vgeo_install_all_pages.d.ts +29 -0
- package/src/shade/renderer/geometry/virtual/format/read/tool/vgeo_install_all_pages.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/format/read/tool/vgeo_install_all_pages.js +60 -0
- package/src/shade/renderer/geometry/virtual/format/read/vgeo_fetch_byte_source.d.ts +8 -1
- package/src/shade/renderer/geometry/virtual/format/read/vgeo_fetch_byte_source.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/format/read/vgeo_fetch_byte_source.js +32 -2
- package/src/shade/renderer/geometry/virtual/residency/VGeoResidencyManager.d.ts +258 -0
- package/src/shade/renderer/geometry/virtual/residency/VGeoResidencyManager.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/residency/VGeoResidencyManager.js +723 -0
- package/src/shade/renderer/geometry/virtual/residency/VGeoResidencyOptions.d.ts +49 -0
- package/src/shade/renderer/geometry/virtual/residency/VGeoResidencyOptions.d.ts.map +1 -0
- package/src/shade/renderer/geometry/virtual/residency/VGeoResidencyOptions.js +50 -0
- package/src/shade/renderer/loader/gltf/tiny-gltf.d.ts +1 -1
- package/src/shade/renderer/postprocess/nss/NSS.d.ts +1 -1
- package/src/shade/renderer/texture/bindless/GPUBindlessTextureManager.d.ts +3 -0
- package/src/shade/renderer/texture/bindless/GPUBindlessTextureManager.d.ts.map +1 -1
- package/src/shade/renderer/texture/bindless/GPUBindlessTextureManager.js +121 -21
- package/src/shade/renderer/texture/virtual/README.md +6 -4
- package/src/shade/renderer/texture/virtual/VirtualTextureManager.d.ts.map +1 -1
- package/src/shade/renderer/texture/virtual/VirtualTextureManager.js +7 -0
- package/src/shade/renderer/texture/virtual/source/VTSourceTiled.d.ts +3 -3
- package/src/shade/renderer/texture/virtual/source/VTSourceTiled.js +3 -3
- package/src/engine/ecs/system/SystemExecutionPhase.d.ts +0 -9
- package/src/engine/ecs/system/SystemExecutionPhase.d.ts.map +0 -1
- package/src/engine/graphics/texture/virtual/NOTES.md +0 -128
- package/src/engine/graphics/texture/virtual/VT_DEFAULT_PAGE_RESOLUTION.d.ts +0 -6
- package/src/engine/graphics/texture/virtual/VT_DEFAULT_PAGE_RESOLUTION.d.ts.map +0 -1
- package/src/engine/graphics/texture/virtual/VT_DEFAULT_PAGE_RESOLUTION.js +0 -5
- package/src/engine/graphics/texture/virtual/VirtualTextureTileLoader.d.ts +0 -49
- package/src/engine/graphics/texture/virtual/VirtualTextureTileLoader.d.ts.map +0 -1
- package/src/engine/graphics/texture/virtual/VirtualTextureTileLoader.js +0 -264
- package/src/engine/graphics/texture/virtual/VirtualTextureUsage.d.ts +0 -44
- package/src/engine/graphics/texture/virtual/VirtualTextureUsage.d.ts.map +0 -1
- package/src/engine/graphics/texture/virtual/VirtualTextureUsage.js +0 -228
- package/src/engine/graphics/texture/virtual/VirtualTextureUsageShader.d.ts +0 -3
- package/src/engine/graphics/texture/virtual/VirtualTextureUsageShader.d.ts.map +0 -1
- package/src/engine/graphics/texture/virtual/VirtualTextureUsageShader.js +0 -73
- package/src/engine/graphics/texture/virtual/debug/ResidencyDebugView.d.ts +0 -14
- package/src/engine/graphics/texture/virtual/debug/ResidencyDebugView.d.ts.map +0 -1
- package/src/engine/graphics/texture/virtual/debug/ResidencyDebugView.js +0 -85
- package/src/engine/graphics/texture/virtual/debug/UsageDebugView.d.ts +0 -12
- package/src/engine/graphics/texture/virtual/debug/UsageDebugView.d.ts.map +0 -1
- package/src/engine/graphics/texture/virtual/debug/UsageDebugView.js +0 -63
- package/src/engine/graphics/texture/virtual/debug/UsagePyramidDebugView.d.ts +0 -12
- package/src/engine/graphics/texture/virtual/debug/UsagePyramidDebugView.d.ts.map +0 -1
- package/src/engine/graphics/texture/virtual/debug/UsagePyramidDebugView.js +0 -243
- package/src/engine/graphics/texture/virtual/tile/VirtualTextureTile.d.ts +0 -30
- package/src/engine/graphics/texture/virtual/tile/VirtualTextureTile.d.ts.map +0 -1
- package/src/engine/graphics/texture/virtual/tile/VirtualTextureTile.js +0 -39
- package/src/engine/graphics/texture/virtual/tile/compose_finger_print.d.ts +0 -9
- package/src/engine/graphics/texture/virtual/tile/compose_finger_print.d.ts.map +0 -1
- package/src/engine/graphics/texture/virtual/tile/compose_finger_print.js +0 -24
- package/src/engine/graphics/texture/virtual/tile/compose_tile_address.d.ts +0 -9
- package/src/engine/graphics/texture/virtual/tile/compose_tile_address.d.ts.map +0 -1
- package/src/engine/graphics/texture/virtual/tile/compose_tile_address.js +0 -26
- package/src/engine/graphics/texture/virtual/tile/decompose_finger_print.d.ts +0 -11
- package/src/engine/graphics/texture/virtual/tile/decompose_finger_print.d.ts.map +0 -1
- package/src/engine/graphics/texture/virtual/tile/decompose_finger_print.js +0 -12
- package/src/engine/graphics/texture/virtual/tile/finger_print_to_tile_address.d.ts +0 -7
- package/src/engine/graphics/texture/virtual/tile/finger_print_to_tile_address.d.ts.map +0 -1
- package/src/engine/graphics/texture/virtual/tile/finger_print_to_tile_address.js +0 -16
- package/src/engine/graphics/texture/virtual/tile/tile_address_to_finger_print.d.ts +0 -7
- package/src/engine/graphics/texture/virtual/tile/tile_address_to_finger_print.d.ts.map +0 -1
- package/src/engine/graphics/texture/virtual/tile/tile_address_to_finger_print.js +0 -35
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {import("../../../../core/binary/allocator/OffsetAllocator.js").Allocation} Allocation
|
|
3
|
+
*/
|
|
1
4
|
export class GPUGeometryMeshletsBVH {
|
|
2
5
|
/**
|
|
3
6
|
* The tree's bytes as they were copied into the arena, once they have been. Not taken at
|
|
@@ -14,6 +17,14 @@ export class GPUGeometryMeshletsBVH {
|
|
|
14
17
|
* @type {number}
|
|
15
18
|
*/
|
|
16
19
|
address: number;
|
|
20
|
+
/**
|
|
21
|
+
* The arena region {@link address} names, as the allocator handed it out — kept so the
|
|
22
|
+
* region can be given back when this tree is released. `null` until the nodes are
|
|
23
|
+
* resident, and again once they have been released.
|
|
24
|
+
*
|
|
25
|
+
* @type {Allocation|null}
|
|
26
|
+
*/
|
|
27
|
+
allocation: Allocation | null;
|
|
17
28
|
/**
|
|
18
29
|
* The shape of this tree — parents and leaf positions — shared with every other copy of the same
|
|
19
30
|
* geometry, because a copy differs only in where its bounds are.
|
|
@@ -46,4 +57,5 @@ export class GPUGeometryMeshletsBVH {
|
|
|
46
57
|
*/
|
|
47
58
|
released: boolean;
|
|
48
59
|
}
|
|
60
|
+
export type Allocation = import("../../../../core/binary/allocator/OffsetAllocator.js").Allocation;
|
|
49
61
|
//# sourceMappingURL=GPUGeometryMeshletsBVH.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GPUGeometryMeshletsBVH.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/geometry/bvh/GPUGeometryMeshletsBVH.js"],"names":[],"mappings":"AAAA;IAEI;;;;;;OAMG;IACH,KAFU,WAAW,GAAC,SAAS,CAE3B;IAEJ;;;;;OAKG;IACH,SAFU,MAAM,CAEJ;IAEZ;;;;;OAKG;IACH,UAFU,MAAM,CAEP;IAET;;;;;;OAMG;IACH,UAFU,OAAO,CAEA;IAEjB;;;;;;;OAOG;IACH,sBAFU,MAAM,CAES;IAEzB;;;;;OAKG;IACH,UAFU,OAAO,CAEA;CACpB"}
|
|
1
|
+
{"version":3,"file":"GPUGeometryMeshletsBVH.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/geometry/bvh/GPUGeometryMeshletsBVH.js"],"names":[],"mappings":"AAAA;;GAEG;AAEH;IAEI;;;;;;OAMG;IACH,KAFU,WAAW,GAAC,SAAS,CAE3B;IAEJ;;;;;OAKG;IACH,SAFU,MAAM,CAEJ;IAEZ;;;;;;OAMG;IACH,YAFU,UAAU,GAAC,IAAI,CAEP;IAElB;;;;;OAKG;IACH,UAFU,MAAM,CAEP;IAET;;;;;;OAMG;IACH,UAFU,OAAO,CAEA;IAEjB;;;;;;;OAOG;IACH,sBAFU,MAAM,CAES;IAEzB;;;;;OAKG;IACH,UAFU,OAAO,CAEA;CACpB;yBAjEY,OAAO,sDAAsD,EAAE,UAAU"}
|
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @typedef {import("../../../../core/binary/allocator/OffsetAllocator.js").Allocation} Allocation
|
|
3
|
+
*/
|
|
4
|
+
|
|
1
5
|
export class GPUGeometryMeshletsBVH {
|
|
2
6
|
|
|
3
7
|
/**
|
|
@@ -17,6 +21,15 @@ export class GPUGeometryMeshletsBVH {
|
|
|
17
21
|
*/
|
|
18
22
|
address = 0;
|
|
19
23
|
|
|
24
|
+
/**
|
|
25
|
+
* The arena region {@link address} names, as the allocator handed it out — kept so the
|
|
26
|
+
* region can be given back when this tree is released. `null` until the nodes are
|
|
27
|
+
* resident, and again once they have been released.
|
|
28
|
+
*
|
|
29
|
+
* @type {Allocation|null}
|
|
30
|
+
*/
|
|
31
|
+
allocation = null;
|
|
32
|
+
|
|
20
33
|
/**
|
|
21
34
|
* The shape of this tree — parents and leaf positions — shared with every other copy of the same
|
|
22
35
|
* geometry, because a copy differs only in where its bounds are.
|
|
@@ -15,6 +15,23 @@ export class GPUMeshletManager {
|
|
|
15
15
|
get buffer_metadata(): GPUBuffer;
|
|
16
16
|
compact(): void;
|
|
17
17
|
/**
|
|
18
|
+
* Enlarge the data and metadata arenas, leaving every batch exactly where it is.
|
|
19
|
+
*
|
|
20
|
+
* Growth appends. {@link OffsetAllocator#grow} files the new tail as free space and moves
|
|
21
|
+
* nothing, and each buffer's old contents go into the larger one at offset 0 in a single copy —
|
|
22
|
+
* so no record's `data.offset` or `metadata.offset` changes, no meshlet's `address` field needs
|
|
23
|
+
* re-patching, and no {@link MeshletBatchAllocationRecord#changed} fires. Compare {@link compact},
|
|
24
|
+
* which makes room by re-packing instead, and pays all three of those for every record it moves.
|
|
25
|
+
*
|
|
26
|
+
* Growing closes no holes, which is why it leaves {@link #deallocations_since_last_rebuild}
|
|
27
|
+
* alone: the holes it did not close are still there for a later {@link compact} to close.
|
|
28
|
+
*
|
|
29
|
+
* The arena an allocator is asked for is a little larger than the shortfall, because the bins
|
|
30
|
+
* round free runs down and requests up, up to 9/8 apart — room for exactly `extra_data_size`
|
|
31
|
+
* can still be refused the allocation that asked for it. And no larger than
|
|
32
|
+
* `maxBufferSize`: growth stops at what the device will hand out, so an arena that cannot
|
|
33
|
+
* hold the request reports that through the caller's failed allocation rather than through a
|
|
34
|
+
* buffer that is not there.
|
|
18
35
|
*
|
|
19
36
|
* @param {number} extra_data_size in words (4 bytes)
|
|
20
37
|
* @param {number} extra_metadata_size in metadata elements
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"GPUMeshletManager.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/geometry/meshlet/GPUMeshletManager.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"GPUMeshletManager.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/geometry/meshlet/GPUMeshletManager.js"],"names":[],"mappings":"AAmFA;IAqEI;;;;;;OAMG;IACH;QAJ8B,MAAM;QACR,qBAAqB,GAAtC,MAAM;QACW,yBAAyB,GAA1C,MAAM;OAkChB;IAzFD,6BAEC;IAOD,iCAEC;IAgFD,gBAKC;IAED;;;;;;;;;;;;;;;;;;;;;OAqBG;IACH,sBAHW,MAAM,uBACN,MAAM,QAuHhB;IAqRD;;;;;;;;;;;OAWG;IACH,qBAJW,4BAA4B,GAE1B,OAAO,CAmBnB;IAgCD;;;;;;;;;;;;;;;;;;;;;;;;OAwBG;IACH,+BAHW,4BAA4B,GAC1B,4BAA4B,CA8BxC;IAED;;;;;;;;;;;;OAYG;IACH,gBAFW,sBAAsB,QA8GhC;IAED,gBAGC;IAED;;;;OAIG;IACH,iBAHW,YAAY,GACV,4BAA4B,CA6BxC;IAED,mCASC;IAED,wCAQC;IAED,+BAYC;;CACJ;yBA/4BY,OAAO,sDAAsD,EAAE,UAAU;qCACzE,OAAO,2CAA2C,EAAE,sBAAsB;2BAC1E,OAAO,mBAAmB,EAAE,YAAY;AA6BrD;IACI;;OAEG;IACH,UAFU,UAAU,CAEZ;IACR;;OAEG;IACH,MAFU,UAAU,CAEhB;IAEJ;;;OAGG;IACH,WAFU,MAAM,CAEF;IAEd;;;OAGG;IACH,eAFU,MAAM,CAEE;IAElB;;;OAGG;IACH,0BAFU,WAAW,CAEI;IAEzB;;;OAGG;IACH,aAAsB;CACzB"}
|
|
@@ -32,6 +32,20 @@ const DEFAULT_METADATA_CAPACITY = 128 * 1024;
|
|
|
32
32
|
*/
|
|
33
33
|
const DEFAULT_DATA_CAPACITY = 32 * MEGABYTE;
|
|
34
34
|
|
|
35
|
+
/**
|
|
36
|
+
* Node budget both allocators are built with — the ceiling on how many ranges either can be
|
|
37
|
+
* describing at once, live allocations and free holes together.
|
|
38
|
+
*
|
|
39
|
+
* {@link OffsetAllocator#grow} cannot raise it: the node table cannot be enlarged in place, and the
|
|
40
|
+
* allocation count a caller needs does not follow from the arena's size anyway. So a manager that
|
|
41
|
+
* grows keeps whatever it was constructed with, where one that rebuilt got the number re-picked
|
|
42
|
+
* every time. It loses nothing by that — {@link #rebuild} re-picks the larger of this and twice the
|
|
43
|
+
* live batch count, which only exceeds this past 65,536 batches.
|
|
44
|
+
*
|
|
45
|
+
* @type {number}
|
|
46
|
+
*/
|
|
47
|
+
const ALLOCATION_LIMIT = 128 * 1024;
|
|
48
|
+
|
|
35
49
|
class MeshletBatchAllocationRecord {
|
|
36
50
|
/**
|
|
37
51
|
* @type {Allocation}
|
|
@@ -123,10 +137,11 @@ export class GPUMeshletManager {
|
|
|
123
137
|
* commands and N `(record_index, address_delta)` patch entries.
|
|
124
138
|
*
|
|
125
139
|
* Entries name the two records, not the addresses they held when the
|
|
126
|
-
* clone was queued: a {@link compact}
|
|
127
|
-
*
|
|
128
|
-
*
|
|
129
|
-
* {@link remove_batch}
|
|
140
|
+
* clone was queued: a {@link compact} in between migrates both, and
|
|
141
|
+
* {@link update} reads where they ended up. ({@link grow} moves
|
|
142
|
+
* nothing, so it needs nothing of them.) What an entry does require
|
|
143
|
+
* is that neither record is handed back to {@link remove_batch}
|
|
144
|
+
* before the flush.
|
|
130
145
|
*
|
|
131
146
|
* @type {{
|
|
132
147
|
* source: MeshletBatchAllocationRecord,
|
|
@@ -159,9 +174,8 @@ export class GPUMeshletManager {
|
|
|
159
174
|
|
|
160
175
|
const data_buffer_size_words = Math.ceil(initial_data_capacity / 4);
|
|
161
176
|
|
|
162
|
-
|
|
163
|
-
this.#
|
|
164
|
-
this.#allocator_metadata = new OffsetAllocator(initial_metadata_capacity);
|
|
177
|
+
this.#allocator_data = new OffsetAllocator(data_buffer_size_words, ALLOCATION_LIMIT);
|
|
178
|
+
this.#allocator_metadata = new OffsetAllocator(initial_metadata_capacity, ALLOCATION_LIMIT);
|
|
165
179
|
|
|
166
180
|
this.#meshlet_data_buffer = device.createBuffer({
|
|
167
181
|
label: 'GPUMeshletManager/data',
|
|
@@ -185,6 +199,23 @@ export class GPUMeshletManager {
|
|
|
185
199
|
}
|
|
186
200
|
|
|
187
201
|
/**
|
|
202
|
+
* Enlarge the data and metadata arenas, leaving every batch exactly where it is.
|
|
203
|
+
*
|
|
204
|
+
* Growth appends. {@link OffsetAllocator#grow} files the new tail as free space and moves
|
|
205
|
+
* nothing, and each buffer's old contents go into the larger one at offset 0 in a single copy —
|
|
206
|
+
* so no record's `data.offset` or `metadata.offset` changes, no meshlet's `address` field needs
|
|
207
|
+
* re-patching, and no {@link MeshletBatchAllocationRecord#changed} fires. Compare {@link compact},
|
|
208
|
+
* which makes room by re-packing instead, and pays all three of those for every record it moves.
|
|
209
|
+
*
|
|
210
|
+
* Growing closes no holes, which is why it leaves {@link #deallocations_since_last_rebuild}
|
|
211
|
+
* alone: the holes it did not close are still there for a later {@link compact} to close.
|
|
212
|
+
*
|
|
213
|
+
* The arena an allocator is asked for is a little larger than the shortfall, because the bins
|
|
214
|
+
* round free runs down and requests up, up to 9/8 apart — room for exactly `extra_data_size`
|
|
215
|
+
* can still be refused the allocation that asked for it. And no larger than
|
|
216
|
+
* `maxBufferSize`: growth stops at what the device will hand out, so an arena that cannot
|
|
217
|
+
* hold the request reports that through the caller's failed allocation rather than through a
|
|
218
|
+
* buffer that is not there.
|
|
188
219
|
*
|
|
189
220
|
* @param {number} extra_data_size in words (4 bytes)
|
|
190
221
|
* @param {number} extra_metadata_size in metadata elements
|
|
@@ -198,11 +229,13 @@ export class GPUMeshletManager {
|
|
|
198
229
|
return;
|
|
199
230
|
}
|
|
200
231
|
|
|
201
|
-
const
|
|
202
|
-
|
|
232
|
+
const device = this.#device;
|
|
233
|
+
|
|
234
|
+
const old_buffer_data = this.#meshlet_data_buffer;
|
|
235
|
+
const old_buffer_metadata = this.#meshlet_metadata_buffer;
|
|
203
236
|
|
|
204
|
-
const current_buffer_size_words =
|
|
205
|
-
const current_metadata_buffer_size_elements = Math.ceil(
|
|
237
|
+
const current_buffer_size_words = old_buffer_data.size >> 2;
|
|
238
|
+
const current_metadata_buffer_size_elements = Math.ceil(old_buffer_metadata.size / MESHLET_METADATA_STRUCT.aligned_size);
|
|
206
239
|
|
|
207
240
|
const DATA_GROWTH_STEP = 16 * 1024;
|
|
208
241
|
const METADATA_GROWTH_STEP = 256;
|
|
@@ -214,7 +247,7 @@ export class GPUMeshletManager {
|
|
|
214
247
|
} else {
|
|
215
248
|
// grow
|
|
216
249
|
new_data_size = Math.max(
|
|
217
|
-
current_buffer_size_words + extra_data_size,
|
|
250
|
+
current_buffer_size_words + Math.ceil(extra_data_size * 9 / 8),
|
|
218
251
|
current_buffer_size_words + DATA_GROWTH_STEP,
|
|
219
252
|
Math.ceil(current_buffer_size_words * GROWTH_MULTIPLIER)
|
|
220
253
|
);
|
|
@@ -226,16 +259,84 @@ export class GPUMeshletManager {
|
|
|
226
259
|
} else {
|
|
227
260
|
// grow
|
|
228
261
|
new_metadata_size = Math.max(
|
|
229
|
-
current_metadata_buffer_size_elements + extra_metadata_size,
|
|
262
|
+
current_metadata_buffer_size_elements + Math.ceil(extra_metadata_size * 9 / 8),
|
|
230
263
|
current_metadata_buffer_size_elements + METADATA_GROWTH_STEP,
|
|
231
|
-
current_metadata_buffer_size_elements * GROWTH_MULTIPLIER
|
|
264
|
+
Math.ceil(current_metadata_buffer_size_elements * GROWTH_MULTIPLIER)
|
|
232
265
|
);
|
|
233
266
|
}
|
|
234
267
|
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
268
|
+
// `createBuffer` answers a size past the device's limit with an *invalid* buffer rather than
|
|
269
|
+
// an exception. Swapping one of those in would destroy the arena, leave the allocator sized
|
|
270
|
+
// for space that does not exist, and throw nothing on the way. Capping means a growth gets
|
|
271
|
+
// as far as the device allows, which is often still enough — and when it is not, the caller's
|
|
272
|
+
// allocation is what fails.
|
|
273
|
+
const max_buffer_size = device.limits.maxBufferSize;
|
|
274
|
+
|
|
275
|
+
new_data_size = Math.min(new_data_size, Math.floor(max_buffer_size / 4));
|
|
276
|
+
new_metadata_size = Math.min(
|
|
277
|
+
new_metadata_size,
|
|
278
|
+
Math.floor(max_buffer_size / MESHLET_METADATA_STRUCT.aligned_size)
|
|
238
279
|
);
|
|
280
|
+
|
|
281
|
+
// A buffer is left alone when its arena did not change, so growing one of the two costs
|
|
282
|
+
// nothing on the other — and an arena already at the cap is left alone by the same test.
|
|
283
|
+
const grows_data = new_data_size > current_buffer_size_words;
|
|
284
|
+
const grows_metadata = new_metadata_size > current_metadata_buffer_size_elements;
|
|
285
|
+
|
|
286
|
+
if (!grows_data && !grows_metadata) {
|
|
287
|
+
// both are as large as this device will allow
|
|
288
|
+
return;
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
// Buffers first. `OffsetAllocator#grow` cannot be undone, so nothing irreversible happens
|
|
292
|
+
// until the space it is about to describe exists.
|
|
293
|
+
const new_buffer_data = grows_data
|
|
294
|
+
? device.createBuffer({
|
|
295
|
+
label: old_buffer_data.label,
|
|
296
|
+
usage: old_buffer_data.usage,
|
|
297
|
+
size: new_data_size * 4,
|
|
298
|
+
})
|
|
299
|
+
: null;
|
|
300
|
+
|
|
301
|
+
const new_buffer_metadata = grows_metadata
|
|
302
|
+
? device.createBuffer({
|
|
303
|
+
label: old_buffer_metadata.label,
|
|
304
|
+
usage: old_buffer_metadata.usage,
|
|
305
|
+
size: new_metadata_size * MESHLET_METADATA_STRUCT.aligned_size,
|
|
306
|
+
})
|
|
307
|
+
: null;
|
|
308
|
+
|
|
309
|
+
const encoder = device.createCommandEncoder({
|
|
310
|
+
label: "GPUMeshletManager/grow",
|
|
311
|
+
});
|
|
312
|
+
|
|
313
|
+
if (new_buffer_data !== null) {
|
|
314
|
+
this.#allocator_data.grow(new_data_size);
|
|
315
|
+
|
|
316
|
+
// One copy of the whole arena at offset 0. No offset moved, so the bytes land back under
|
|
317
|
+
// the addresses the records already hold — and the metadata addressing them stays right.
|
|
318
|
+
encoder.copyBufferToBuffer(old_buffer_data, 0, new_buffer_data, 0, old_buffer_data.size);
|
|
319
|
+
}
|
|
320
|
+
|
|
321
|
+
if (new_buffer_metadata !== null) {
|
|
322
|
+
this.#allocator_metadata.grow(new_metadata_size);
|
|
323
|
+
|
|
324
|
+
encoder.copyBufferToBuffer(old_buffer_metadata, 0, new_buffer_metadata, 0, old_buffer_metadata.size);
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
device.queue.submit([encoder.finish()]);
|
|
328
|
+
|
|
329
|
+
if (new_buffer_data !== null) {
|
|
330
|
+
old_buffer_data.destroy();
|
|
331
|
+
|
|
332
|
+
this.#meshlet_data_buffer = new_buffer_data;
|
|
333
|
+
}
|
|
334
|
+
|
|
335
|
+
if (new_buffer_metadata !== null) {
|
|
336
|
+
old_buffer_metadata.destroy();
|
|
337
|
+
|
|
338
|
+
this.#meshlet_metadata_buffer = new_buffer_metadata;
|
|
339
|
+
}
|
|
239
340
|
}
|
|
240
341
|
|
|
241
342
|
/**
|
|
@@ -305,7 +406,7 @@ export class GPUMeshletManager {
|
|
|
305
406
|
const record_count = records.length;
|
|
306
407
|
const new_allocator_data = new OffsetAllocator(
|
|
307
408
|
new_data_size,
|
|
308
|
-
Math.max(record_count * 2,
|
|
409
|
+
Math.max(record_count * 2, ALLOCATION_LIMIT)
|
|
309
410
|
);
|
|
310
411
|
|
|
311
412
|
const old_buffer_data = this.#meshlet_data_buffer;
|
|
@@ -317,7 +418,7 @@ export class GPUMeshletManager {
|
|
|
317
418
|
|
|
318
419
|
const new_allocator_metadata = new OffsetAllocator(
|
|
319
420
|
new_metadata_size,
|
|
320
|
-
Math.max(record_count * 2,
|
|
421
|
+
Math.max(record_count * 2, ALLOCATION_LIMIT)
|
|
321
422
|
);
|
|
322
423
|
|
|
323
424
|
const old_buffer_metadata = this.#meshlet_metadata_buffer;
|
|
@@ -396,15 +497,21 @@ export class GPUMeshletManager {
|
|
|
396
497
|
|
|
397
498
|
/**
|
|
398
499
|
* Allocate `data_size_words` in the data buffer and `meshlet_count`
|
|
399
|
-
* in the metadata buffer,
|
|
400
|
-
* Throws if the third attempt still can't satisfy both. The two
|
|
500
|
+
* in the metadata buffer, growing or compacting on failure and trying
|
|
501
|
+
* again. Throws if the third attempt still can't satisfy both. The two
|
|
401
502
|
* allocations are kept in lockstep — partial successes are released
|
|
402
503
|
* before retrying so we never leak.
|
|
403
504
|
*
|
|
404
|
-
*
|
|
405
|
-
*
|
|
406
|
-
*
|
|
407
|
-
*
|
|
505
|
+
* Which of the two a failure gets is decided by what the failure is.
|
|
506
|
+
* {@link grow} appends a contiguous run and moves nothing, so it is
|
|
507
|
+
* the cheap and complete answer to an arena that is merely full.
|
|
508
|
+
* {@link compact} adds no space at all — it closes holes — and pays a
|
|
509
|
+
* migration of every allocation, a CPU metadata rewrite each and a
|
|
510
|
+
* `changed` for every moved address to do it, so it is reserved for
|
|
511
|
+
* the failure it is the only answer to: the room is already there and
|
|
512
|
+
* merely scattered. Queued clone work is carried through either —
|
|
513
|
+
* {@link #pending_clones} names records, not addresses — so an
|
|
514
|
+
* allocation made while a clone is pending is safe.
|
|
408
515
|
*
|
|
409
516
|
* @param {number} data_size_words
|
|
410
517
|
* @param {number} meshlet_count
|
|
@@ -440,14 +547,30 @@ export class GPUMeshletManager {
|
|
|
440
547
|
metadata_allocation.metadata = ALLOCATOR_NO_SPACE;
|
|
441
548
|
}
|
|
442
549
|
|
|
443
|
-
|
|
444
|
-
|
|
550
|
+
// An allocator holding enough free space for the request it just refused is one whose
|
|
551
|
+
// space is scattered, and closing the holes is the only thing that helps. Anything else
|
|
552
|
+
// is a shortfall, which growth covers by appending. The margin is the bins': a free run
|
|
553
|
+
// the allocator rounds down can still be refused a request it rounds up, so "enough"
|
|
554
|
+
// has to mean 9/8 of it, or a compaction could hand back a single run and still refuse.
|
|
555
|
+
const data_is_fragmented = !data_ok
|
|
556
|
+
&& this.#allocator_data.freeStorage >= Math.ceil(data_size_words * 9 / 8);
|
|
557
|
+
|
|
558
|
+
const metadata_is_fragmented = !metadata_ok
|
|
559
|
+
&& this.#allocator_metadata.freeStorage >= Math.ceil(meshlet_count * 9 / 8);
|
|
560
|
+
|
|
561
|
+
// #rebuild zeroes the counter, so a compaction that does not free the request through
|
|
562
|
+
// leaves the next pass to grow — the loop always makes progress
|
|
563
|
+
if (
|
|
564
|
+
this.#deallocations_since_last_rebuild > 0
|
|
565
|
+
&& (data_is_fragmented || metadata_is_fragmented)
|
|
566
|
+
) {
|
|
445
567
|
this.compact();
|
|
568
|
+
|
|
446
569
|
continue;
|
|
447
570
|
}
|
|
448
571
|
|
|
449
|
-
|
|
450
|
-
|
|
572
|
+
const grow_data_size = data_ok ? 0 : data_size_words;
|
|
573
|
+
const grow_metadata_size = metadata_ok ? 0 : meshlet_count;
|
|
451
574
|
|
|
452
575
|
this.grow(grow_data_size, grow_metadata_size);
|
|
453
576
|
|
|
@@ -511,6 +634,8 @@ export class GPUMeshletManager {
|
|
|
511
634
|
return false;
|
|
512
635
|
}
|
|
513
636
|
|
|
637
|
+
this.#cancel_pending_clones_naming(record);
|
|
638
|
+
|
|
514
639
|
this.#allocator_data.free(record.data);
|
|
515
640
|
this.#allocator_metadata.free(record.metadata);
|
|
516
641
|
|
|
@@ -520,6 +645,36 @@ export class GPUMeshletManager {
|
|
|
520
645
|
return true;
|
|
521
646
|
}
|
|
522
647
|
|
|
648
|
+
/**
|
|
649
|
+
* Drop the queued clone copies that name `record`, because it is about to stop owning the
|
|
650
|
+
* ranges they were going to read from or write to.
|
|
651
|
+
*
|
|
652
|
+
* A queued copy holds records, not addresses, precisely so a rebuild can move them under it —
|
|
653
|
+
* but a *released* record keeps the offsets it had while the allocator hands those same
|
|
654
|
+
* ranges to whoever asks next. Flushing such a copy writes a stale source over a live batch's
|
|
655
|
+
* vertices, or copies a live batch's vertices into a clone, with nothing to say it happened.
|
|
656
|
+
* This was unreachable while nothing released a clone; it became reachable the moment
|
|
657
|
+
* {@link GPUGeometryManager#remove_clone} did.
|
|
658
|
+
*
|
|
659
|
+
* Cancelling by source as well as by clone gives up the copy rather than reading a region the
|
|
660
|
+
* source no longer owns. The clone is left holding its ranges with nothing written into them,
|
|
661
|
+
* which renders as whatever those bytes were — wrong, but bounded, and it is what removing a
|
|
662
|
+
* geometry out from under a clone of it already asks for.
|
|
663
|
+
*
|
|
664
|
+
* @param {MeshletBatchAllocationRecord} record
|
|
665
|
+
*/
|
|
666
|
+
#cancel_pending_clones_naming(record) {
|
|
667
|
+
const pending = this.#pending_clones;
|
|
668
|
+
|
|
669
|
+
for (let i = pending.length - 1; i >= 0; i--) {
|
|
670
|
+
const entry = pending[i];
|
|
671
|
+
|
|
672
|
+
if (entry.clone === record || entry.source === record) {
|
|
673
|
+
pending.splice(i, 1);
|
|
674
|
+
}
|
|
675
|
+
}
|
|
676
|
+
}
|
|
677
|
+
|
|
523
678
|
/**
|
|
524
679
|
* Allocate a fresh (data, metadata) pair sized to mirror `source`,
|
|
525
680
|
* and queue a GPU-side clone: the source's data and metadata are
|
|
@@ -569,7 +724,7 @@ export class GPUMeshletManager {
|
|
|
569
724
|
// hold right now. Both are in `#records`, so a rebuild between
|
|
570
725
|
// this call and the flush moves them and the flush still reads
|
|
571
726
|
// where they went — which is what lets a clone be queued in the
|
|
572
|
-
// same frame as the
|
|
727
|
+
// same frame as the compaction another geometry's arrival forces.
|
|
573
728
|
this.#pending_clones.push({ source, clone: record });
|
|
574
729
|
|
|
575
730
|
return record;
|
|
@@ -12,6 +12,11 @@ Paths below are relative to the Micron root.
|
|
|
12
12
|
> scheduled but not yet built, all live in
|
|
13
13
|
> [VIRTUAL_GEOMETRY_PLAN.md](./VIRTUAL_GEOMETRY_PLAN.md) — that file is the one to act on.
|
|
14
14
|
> This one is kept as the analysis behind those decisions.
|
|
15
|
+
>
|
|
16
|
+
> It is a **snapshot dated in its filename** and is not maintained against the code. Statements
|
|
17
|
+
> about meep that have since gone stale are corrected inline in block quotes like this one,
|
|
18
|
+
> rather than edited away — the argument that was made at the time is the reason the decision
|
|
19
|
+
> was taken, and rewriting it hides that.
|
|
15
20
|
|
|
16
21
|
## 1. Where the two already agree
|
|
17
22
|
|
|
@@ -108,6 +113,11 @@ meep hard-gates on an error band and falls back to a full sweep when the band ha
|
|
|
108
113
|
The soft form has no escape hatch to justify, and would work as a tie-breaker *inside* a
|
|
109
114
|
band, which is where meep currently uses shared-boundary weight alone.
|
|
110
115
|
|
|
116
|
+
> **Since this was written**: not alone any more. The adjacency edge weight is shared boundary
|
|
117
|
+
> *times* `compactness()` (plan §1), so the tie-break slot this proposes is occupied — by a
|
|
118
|
+
> spatial term rather than an error-similarity one. A level tie-break would now have to argue
|
|
119
|
+
> its way past compactness, not past nothing.
|
|
120
|
+
|
|
111
121
|
```js
|
|
112
122
|
normal_score = 1 - merged_cone_angle² / π²
|
|
113
123
|
```
|
|
@@ -116,6 +126,13 @@ Prefers merging co-facing patches, which keeps the normal cone tight. meep reser
|
|
|
116
126
|
`cone_reserved` in the cluster record and has no producer; if the cone ever lands, the
|
|
117
127
|
grouping should be aware of it or the cones will be useless at coarse levels.
|
|
118
128
|
|
|
129
|
+
> **Since this was written**: moot — **backface cone culling is declined** (plan §5). The
|
|
130
|
+
> warning above turned out to be the argument against the whole idea rather than a caveat on
|
|
131
|
+
> implementing it: making cones tight enough to be worth testing means letting cone angle
|
|
132
|
+
> distort grouping, to feed a cull the two-pass HZB was already performing on evidence. The
|
|
133
|
+
> producer did land in the meantime and has no callers
|
|
134
|
+
> (`bt_face_cluster_compute_normal_bounding_cone`); `cone_reserved` stays 0 for good.
|
|
135
|
+
|
|
119
136
|
The weighting itself should **not** be copied: the terms are heterogeneous in scale and
|
|
120
137
|
`shared_vertex_count` enters unnormalized, so it dominates everything else. The terms are
|
|
121
138
|
the finding, not the sum.
|