@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
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
import { assert } from "../../../assert.js";
|
|
2
|
+
import { hash_mix2 } from "../../../math/hash/hash_mix2.js";
|
|
3
|
+
import { hash_mix3 } from "../../../math/hash/hash_mix3.js";
|
|
4
|
+
import { computeHashFloat } from "../../../primitives/numbers/computeHashFloat.js";
|
|
5
|
+
import { AbstractShape3D } from "./AbstractShape3D.js";
|
|
6
|
+
import { sdf3_plane, sdf3_plane_gradient } from "./sdf/sdf3_plane.js";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* # An infinite half-space
|
|
10
|
+
*
|
|
11
|
+
* The solid is `{ p : n·p − offset ≤ 0 }` — everything on the far side of the
|
|
12
|
+
* boundary plane from the direction {@link normal} points in. So `normal` is
|
|
13
|
+
* the **outward** surface normal, exactly as it is for every other shape's
|
|
14
|
+
* signed-distance gradient, and `offset` is how far along it the boundary sits
|
|
15
|
+
* from the body's local origin.
|
|
16
|
+
*
|
|
17
|
+
* A ground plane is `normal = (0, 1, 0), offset = 0`: solid below, open above.
|
|
18
|
+
*
|
|
19
|
+
* ## Why a shape rather than a very large box
|
|
20
|
+
*
|
|
21
|
+
* A box standing in for a ground plane has to be large enough that nothing ever
|
|
22
|
+
* reaches its edge and thin enough that nothing tunnels through it, and those
|
|
23
|
+
* two requirements pull against each other in `Float32`. It also costs a
|
|
24
|
+
* six-face field evaluation where the honest answer is one dot product, and its
|
|
25
|
+
* gradient has creases that the thing it is standing in for does not.
|
|
26
|
+
*
|
|
27
|
+
* ## What it deliberately does not implement, and why that is the honest answer
|
|
28
|
+
*
|
|
29
|
+
* A half-space is convex and **unbounded**, and three of
|
|
30
|
+
* {@link AbstractShape3D}'s methods are only meaningful on a bounded set:
|
|
31
|
+
*
|
|
32
|
+
* - {@link support} — GJK's operand. `argmax(p·d)` over a half-space is at
|
|
33
|
+
* infinity for all but one direction, so a plane is not a GJK operand and
|
|
34
|
+
* pretending otherwise with a large finite point would silently produce wrong
|
|
35
|
+
* contact manifolds rather than a loud failure. Left unimplemented, which
|
|
36
|
+
* makes the base class's `Not Implemented` the answer.
|
|
37
|
+
* - {@link sample_random_point_in_volume} — the base class's rejection sampler
|
|
38
|
+
* needs a finite bounding box. There is no uniform distribution on an
|
|
39
|
+
* infinite volume.
|
|
40
|
+
* - {@link volume} and {@link surface_area} — both `Infinity`, stated rather
|
|
41
|
+
* than thrown, because a caller summing volumes gets an answer that is true.
|
|
42
|
+
*
|
|
43
|
+
* {@link compute_bounding_box} **does** answer, with `±Infinity` on the
|
|
44
|
+
* unbounded axes. That is what the set is. A consumer that cannot hold an
|
|
45
|
+
* infinite AABB — a BVH leaf, a broadphase grid — must not be handed a plane,
|
|
46
|
+
* and the cloth collider index that motivated this shape derives a plane's
|
|
47
|
+
* bounds from its normal rather than by projecting this box (`aabb3_matrix4_project`
|
|
48
|
+
* would multiply an infinity by a zero matrix element and get `NaN`).
|
|
49
|
+
*
|
|
50
|
+
* @author Alex Goldring
|
|
51
|
+
* @copyright Company Named Limited (c) 2026
|
|
52
|
+
*/
|
|
53
|
+
export class PlaneShape3D extends AbstractShape3D {
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Outward unit normal, x.
|
|
57
|
+
* @type {number}
|
|
58
|
+
*/
|
|
59
|
+
normal_x = 0;
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Outward unit normal, y.
|
|
63
|
+
* @type {number}
|
|
64
|
+
*/
|
|
65
|
+
normal_y = 1;
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* Outward unit normal, z.
|
|
69
|
+
* @type {number}
|
|
70
|
+
*/
|
|
71
|
+
normal_z = 0;
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Distance from the local origin to the boundary plane, along
|
|
75
|
+
* {@link normal_x}/{@link normal_y}/{@link normal_z}.
|
|
76
|
+
* @type {number}
|
|
77
|
+
*/
|
|
78
|
+
offset = 0;
|
|
79
|
+
|
|
80
|
+
/**
|
|
81
|
+
* @param {number} normal_x
|
|
82
|
+
* @param {number} normal_y
|
|
83
|
+
* @param {number} normal_z
|
|
84
|
+
* @param {number} [offset]
|
|
85
|
+
* @returns {PlaneShape3D}
|
|
86
|
+
*/
|
|
87
|
+
static from(normal_x, normal_y, normal_z, offset = 0) {
|
|
88
|
+
assert.isNumber(normal_x, 'normal_x');
|
|
89
|
+
assert.isNumber(normal_y, 'normal_y');
|
|
90
|
+
assert.isNumber(normal_z, 'normal_z');
|
|
91
|
+
assert.isNumber(offset, 'offset');
|
|
92
|
+
|
|
93
|
+
const length = Math.sqrt(normal_x * normal_x + normal_y * normal_y + normal_z * normal_z);
|
|
94
|
+
|
|
95
|
+
assert.greaterThan(length, 0, 'plane normal length');
|
|
96
|
+
|
|
97
|
+
const r = new PlaneShape3D();
|
|
98
|
+
|
|
99
|
+
// Normalised on construction rather than trusted, because every method
|
|
100
|
+
// below reads the field as a *distance* field and an unnormalised
|
|
101
|
+
// normal makes all of them wrong by a scale rather than imprecise.
|
|
102
|
+
const inverse = 1 / length;
|
|
103
|
+
|
|
104
|
+
r.normal_x = normal_x * inverse;
|
|
105
|
+
r.normal_y = normal_y * inverse;
|
|
106
|
+
r.normal_z = normal_z * inverse;
|
|
107
|
+
r.offset = offset;
|
|
108
|
+
|
|
109
|
+
return r;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
get volume() {
|
|
113
|
+
return Infinity;
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
get surface_area() {
|
|
117
|
+
return Infinity;
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
signed_distance_at_point(point) {
|
|
121
|
+
return sdf3_plane(
|
|
122
|
+
point[0], point[1], point[2],
|
|
123
|
+
this.normal_x, this.normal_y, this.normal_z, this.offset
|
|
124
|
+
);
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
signed_distance_gradient_at_point(result, point) {
|
|
128
|
+
return sdf3_plane_gradient(
|
|
129
|
+
result, 0,
|
|
130
|
+
point[0], point[1], point[2],
|
|
131
|
+
this.normal_x, this.normal_y, this.normal_z, this.offset
|
|
132
|
+
);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
nearest_point_on_surface(result, reference) {
|
|
136
|
+
const distance = this.signed_distance_at_point(reference);
|
|
137
|
+
|
|
138
|
+
result[0] = reference[0] - this.normal_x * distance;
|
|
139
|
+
result[1] = reference[1] - this.normal_y * distance;
|
|
140
|
+
result[2] = reference[2] - this.normal_z * distance;
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
contains_point(point) {
|
|
144
|
+
return this.signed_distance_at_point(point) < 0;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
/**
|
|
148
|
+
* The half-space's own bounds: finite on the one axis the normal is aligned
|
|
149
|
+
* with when it is axis-aligned, infinite everywhere else. See the class
|
|
150
|
+
* docblock for what a consumer is expected to do with that.
|
|
151
|
+
*
|
|
152
|
+
* @param {number[]|ArrayLike<number>|Float32Array|Float64Array} result
|
|
153
|
+
*/
|
|
154
|
+
compute_bounding_box(result) {
|
|
155
|
+
result[0] = -Infinity;
|
|
156
|
+
result[1] = -Infinity;
|
|
157
|
+
result[2] = -Infinity;
|
|
158
|
+
result[3] = Infinity;
|
|
159
|
+
result[4] = Infinity;
|
|
160
|
+
result[5] = Infinity;
|
|
161
|
+
|
|
162
|
+
// A general normal makes every axis unbounded. An axis-aligned one — the
|
|
163
|
+
// overwhelmingly common case, and every ground plane — bounds exactly
|
|
164
|
+
// one of them, and saying so is what lets a caller cull against a floor.
|
|
165
|
+
if (this.normal_x === 1) { result[3] = this.offset; }
|
|
166
|
+
else if (this.normal_x === -1) { result[0] = -this.offset; }
|
|
167
|
+
else if (this.normal_y === 1) { result[4] = this.offset; }
|
|
168
|
+
else if (this.normal_y === -1) { result[1] = -this.offset; }
|
|
169
|
+
else if (this.normal_z === 1) { result[5] = this.offset; }
|
|
170
|
+
else if (this.normal_z === -1) { result[2] = -this.offset; }
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
/**
|
|
174
|
+
* Ray ↔ half-space, in the shape's local frame. A ray that starts inside
|
|
175
|
+
* the solid is already in contact and reports a hit at `t = 0` with the
|
|
176
|
+
* boundary normal, which is the convention every other shape here follows
|
|
177
|
+
* for an origin inside it.
|
|
178
|
+
*
|
|
179
|
+
* @param {Float32Array|number[]} hit
|
|
180
|
+
* @param {Ray3} ray
|
|
181
|
+
* @returns {boolean}
|
|
182
|
+
*/
|
|
183
|
+
raycast(hit, ray) {
|
|
184
|
+
const nx = this.normal_x;
|
|
185
|
+
const ny = this.normal_y;
|
|
186
|
+
const nz = this.normal_z;
|
|
187
|
+
|
|
188
|
+
const distance = ray[0] * nx + ray[1] * ny + ray[2] * nz - this.offset;
|
|
189
|
+
|
|
190
|
+
const along = ray[3] * nx + ray[4] * ny + ray[5] * nz;
|
|
191
|
+
|
|
192
|
+
let t;
|
|
193
|
+
|
|
194
|
+
if (distance <= 0) {
|
|
195
|
+
t = 0;
|
|
196
|
+
} else if (along >= 0) {
|
|
197
|
+
// Outside and travelling away from — or exactly along — the plane.
|
|
198
|
+
return false;
|
|
199
|
+
} else {
|
|
200
|
+
t = -distance / along;
|
|
201
|
+
|
|
202
|
+
if (t > ray[6]) {
|
|
203
|
+
return false;
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
hit[0] = ray[0] + ray[3] * t;
|
|
208
|
+
hit[1] = ray[1] + ray[4] * t;
|
|
209
|
+
hit[2] = ray[2] + ray[5] * t;
|
|
210
|
+
hit[3] = nx;
|
|
211
|
+
hit[4] = ny;
|
|
212
|
+
hit[5] = nz;
|
|
213
|
+
|
|
214
|
+
return true;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
equals(other) {
|
|
218
|
+
return super.equals(other)
|
|
219
|
+
&& this.normal_x === other.normal_x
|
|
220
|
+
&& this.normal_y === other.normal_y
|
|
221
|
+
&& this.normal_z === other.normal_z
|
|
222
|
+
&& this.offset === other.offset;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
hash() {
|
|
226
|
+
return hash_mix2(
|
|
227
|
+
hash_mix3(
|
|
228
|
+
computeHashFloat(this.normal_x),
|
|
229
|
+
computeHashFloat(this.normal_y),
|
|
230
|
+
computeHashFloat(this.normal_z)
|
|
231
|
+
),
|
|
232
|
+
computeHashFloat(this.offset)
|
|
233
|
+
);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* Fast type-check marker, following {@link SphereShape3D#isSphereShape3D}. A
|
|
239
|
+
* consumer that cannot hold an unbounded shape tests this rather than reaching
|
|
240
|
+
* for `instanceof` across a module boundary.
|
|
241
|
+
* @readonly
|
|
242
|
+
* @type {boolean}
|
|
243
|
+
*/
|
|
244
|
+
PlaneShape3D.prototype.isPlaneShape3D = true;
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* The ground: solid below `y = 0`, open above it. Shared and immutable, in the
|
|
248
|
+
* same spirit as {@link UnitSphereShape3D}`.INSTANCE`.
|
|
249
|
+
* @type {PlaneShape3D}
|
|
250
|
+
*/
|
|
251
|
+
PlaneShape3D.GROUND = PlaneShape3D.from(0, 1, 0, 0);
|
|
@@ -3,7 +3,7 @@ import { random_point_in_sphere } from "../../random/random_point_in_sphere.js";
|
|
|
3
3
|
import { sphere_raycast } from "../sphere/sphere_raycast.js";
|
|
4
4
|
import { v3_length } from "../../vec3/v3_length.js";
|
|
5
5
|
import { AbstractShape3D } from "./AbstractShape3D.js";
|
|
6
|
-
import {
|
|
6
|
+
import { sdf3_sphere, sdf3_sphere_gradient } from "./sdf/sdf3_sphere.js";
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* Sphere of arbitrary `radius`, centred at the body's local origin.
|
|
@@ -98,11 +98,11 @@ export class SphereShape3D extends AbstractShape3D {
|
|
|
98
98
|
}
|
|
99
99
|
|
|
100
100
|
signed_distance_gradient_at_point(result, point) {
|
|
101
|
-
return
|
|
101
|
+
return sdf3_sphere_gradient(result, 0, point[0], point[1], point[2], this.radius);
|
|
102
102
|
}
|
|
103
103
|
|
|
104
104
|
signed_distance_at_point(point) {
|
|
105
|
-
return
|
|
105
|
+
return sdf3_sphere(point[0], point[1], point[2], this.radius);
|
|
106
106
|
}
|
|
107
107
|
|
|
108
108
|
contains_point(point) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"shape_to_type.d.ts","sourceRoot":"","sources":["../../../../../../../src/core/geom/3d/shape/json/shape_to_type.js"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"shape_to_type.d.ts","sourceRoot":"","sources":["../../../../../../../src/core/geom/3d/shape/json/shape_to_type.js"],"names":[],"mappings":"AAQA;;;;GAIG;AACH,uDAFa,MAAM,CAsBlB"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { CapsuleShape3D } from "../CapsuleShape3D.js";
|
|
2
2
|
import { CylinderShape3D } from "../CylinderShape3D.js";
|
|
3
|
+
import { PlaneShape3D } from "../PlaneShape3D.js";
|
|
3
4
|
import { SphereShape3D } from "../SphereShape3D.js";
|
|
4
5
|
import { TransformedShape3D } from "../TransformedShape3D.js";
|
|
5
6
|
import { UnionShape3D } from "../UnionShape3D.js";
|
|
@@ -25,6 +26,8 @@ export function shape_to_type(shape) {
|
|
|
25
26
|
return 'capsule';
|
|
26
27
|
} else if (shape instanceof CylinderShape3D) {
|
|
27
28
|
return 'cylinder';
|
|
29
|
+
} else if (shape instanceof PlaneShape3D) {
|
|
30
|
+
return 'plane';
|
|
28
31
|
} else {
|
|
29
32
|
throw new Error('Unsupported shape');
|
|
30
33
|
}
|
|
@@ -44,6 +44,19 @@ export namespace type_adapters {
|
|
|
44
44
|
height: number;
|
|
45
45
|
};
|
|
46
46
|
}
|
|
47
|
+
namespace plane {
|
|
48
|
+
function read({ normal, offset }: {
|
|
49
|
+
normal: any;
|
|
50
|
+
offset: any;
|
|
51
|
+
}): PlaneShape3D;
|
|
52
|
+
/**
|
|
53
|
+
* @param {PlaneShape3D} object
|
|
54
|
+
*/
|
|
55
|
+
function write(object: PlaneShape3D): {
|
|
56
|
+
normal: number[];
|
|
57
|
+
offset: number;
|
|
58
|
+
};
|
|
59
|
+
}
|
|
47
60
|
namespace transform {
|
|
48
61
|
function read({ transform, subject }: {
|
|
49
62
|
transform: any;
|
|
@@ -75,6 +88,7 @@ import { UnitCubeShape3D } from "../UnitCubeShape3D.js";
|
|
|
75
88
|
import { SphereShape3D } from "../SphereShape3D.js";
|
|
76
89
|
import { CapsuleShape3D } from "../CapsuleShape3D.js";
|
|
77
90
|
import { CylinderShape3D } from "../CylinderShape3D.js";
|
|
91
|
+
import { PlaneShape3D } from "../PlaneShape3D.js";
|
|
78
92
|
import { TransformedShape3D } from "../TransformedShape3D.js";
|
|
79
93
|
import { UnionShape3D } from "../UnionShape3D.js";
|
|
80
94
|
//# sourceMappingURL=type_adapters.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"type_adapters.d.ts","sourceRoot":"","sources":["../../../../../../../src/core/geom/3d/shape/json/type_adapters.js"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"type_adapters.d.ts","sourceRoot":"","sources":["../../../../../../../src/core/geom/3d/shape/json/type_adapters.js"],"names":[],"mappings":";;QAaQ,iCAEC;QACD,qBAEC;;;QAGD;;0BAQC;QACD;;WAEG;QACH;;;;UAIC;;;QAGD;;;2BAEC;QACD;;;WAGG;QACH;;;UAKC;;;QAGD;;;4BAEC;QACD;;;WAGG;QACH;;;UAKC;;;QAGD;;;yBAEC;QACD;;WAEG;QACH;;;UAKC;;;QAGD;;;+BAIC;QACD;;;WAGG;QACH;;;UAKC;;;QAGD;;yBAIC;QACD;;;WAGG;QACH;;UAIC;;;gCA5GuB,uBAAuB;8BAHzB,qBAAqB;+BAHpB,sBAAsB;gCACrB,uBAAuB;6BAC1B,oBAAoB;mCAEd,0BAA0B;6BAChC,oBAAoB"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { CapsuleShape3D } from "../CapsuleShape3D.js";
|
|
2
2
|
import { CylinderShape3D } from "../CylinderShape3D.js";
|
|
3
|
+
import { PlaneShape3D } from "../PlaneShape3D.js";
|
|
3
4
|
import { SphereShape3D } from "../SphereShape3D.js";
|
|
4
5
|
import { TransformedShape3D } from "../TransformedShape3D.js";
|
|
5
6
|
import { UnionShape3D } from "../UnionShape3D.js";
|
|
@@ -66,6 +67,20 @@ export const type_adapters = {
|
|
|
66
67
|
};
|
|
67
68
|
}
|
|
68
69
|
},
|
|
70
|
+
'plane': {
|
|
71
|
+
read({ normal, offset }) {
|
|
72
|
+
return PlaneShape3D.from(normal[0], normal[1], normal[2], offset);
|
|
73
|
+
},
|
|
74
|
+
/**
|
|
75
|
+
* @param {PlaneShape3D} object
|
|
76
|
+
*/
|
|
77
|
+
write(object) {
|
|
78
|
+
return {
|
|
79
|
+
normal: [object.normal_x, object.normal_y, object.normal_z],
|
|
80
|
+
offset: object.offset
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
},
|
|
69
84
|
'transform': {
|
|
70
85
|
read({ transform, subject }) {
|
|
71
86
|
const subject_shape = shape_from_json(subject);
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* # Axis-aligned box — signed distance and its analytic gradient
|
|
3
|
+
*
|
|
4
|
+
* A box centred at the origin of its own frame, spanning `±half_extent` on each
|
|
5
|
+
* axis. Inigo Quilez's exact box field, with `q = |x| − h`:
|
|
6
|
+
*
|
|
7
|
+
* d(x) = ‖max(q, 0)‖ + min(max(qx, qy, qz), 0)
|
|
8
|
+
*
|
|
9
|
+
* The gradient has two regimes and that is the whole of the derivation:
|
|
10
|
+
*
|
|
11
|
+
* - **Outside** (some component of `q` is positive) the field is the distance
|
|
12
|
+
* to the nearest point on the box, so the gradient is the unit vector from
|
|
13
|
+
* that point — `sign(x) · max(q, 0)` normalised.
|
|
14
|
+
* - **Inside** (every component of `q` is negative) the field is
|
|
15
|
+
* `max(qx, qy, qz)`, a plain maximum, so the gradient is the signed unit axis
|
|
16
|
+
* of whichever component attains it — the nearest face.
|
|
17
|
+
*
|
|
18
|
+
* Inside a box the field is not differentiable on the medial surface, where two
|
|
19
|
+
* faces are equidistant. The maximum picks one, which is the standard answer
|
|
20
|
+
* and is what a caller wants: a consistent nearest face, not an average of two.
|
|
21
|
+
*
|
|
22
|
+
* @author Alex Goldring
|
|
23
|
+
* @copyright Company Named Limited (c) 2026
|
|
24
|
+
*/
|
|
25
|
+
/**
|
|
26
|
+
* Signed distance from a point to a box's surface: negative inside.
|
|
27
|
+
*
|
|
28
|
+
* @param {number} x
|
|
29
|
+
* @param {number} y
|
|
30
|
+
* @param {number} z
|
|
31
|
+
* @param {number} half_x
|
|
32
|
+
* @param {number} half_y
|
|
33
|
+
* @param {number} half_z
|
|
34
|
+
* @returns {number}
|
|
35
|
+
*/
|
|
36
|
+
export function sdf3_box(x: number, y: number, z: number, half_x: number, half_y: number, half_z: number): number;
|
|
37
|
+
/**
|
|
38
|
+
* Signed distance and the unit outward gradient, written to `out`.
|
|
39
|
+
*
|
|
40
|
+
* @param {Float32Array|Float64Array|number[]} out gradient destination
|
|
41
|
+
* @param {number} out_offset
|
|
42
|
+
* @param {number} x
|
|
43
|
+
* @param {number} y
|
|
44
|
+
* @param {number} z
|
|
45
|
+
* @param {number} half_x
|
|
46
|
+
* @param {number} half_y
|
|
47
|
+
* @param {number} half_z
|
|
48
|
+
* @returns {number} the signed distance
|
|
49
|
+
*/
|
|
50
|
+
export function sdf3_box_gradient(out: Float32Array | Float64Array | number[], out_offset: number, x: number, y: number, z: number, half_x: number, half_y: number, half_z: number): number;
|
|
51
|
+
//# sourceMappingURL=sdf3_box.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sdf3_box.d.ts","sourceRoot":"","sources":["../../../../../../../src/core/geom/3d/shape/sdf/sdf3_box.js"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH;;;;;;;;;;GAUG;AACH,4BARW,MAAM,KACN,MAAM,KACN,MAAM,UACN,MAAM,UACN,MAAM,UACN,MAAM,GACJ,MAAM,CAkBlB;AAED;;;;;;;;;;;;GAYG;AACH,uCAVW,YAAY,GAAC,YAAY,GAAC,MAAM,EAAE,cAClC,MAAM,KACN,MAAM,KACN,MAAM,KACN,MAAM,UACN,MAAM,UACN,MAAM,UACN,MAAM,GACJ,MAAM,CA6ClB"}
|
|
@@ -0,0 +1,113 @@
|
|
|
1
|
+
import { SDF3_EPSILON } from "./sdf3_degenerate_normal.js";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* # Axis-aligned box — signed distance and its analytic gradient
|
|
5
|
+
*
|
|
6
|
+
* A box centred at the origin of its own frame, spanning `±half_extent` on each
|
|
7
|
+
* axis. Inigo Quilez's exact box field, with `q = |x| − h`:
|
|
8
|
+
*
|
|
9
|
+
* d(x) = ‖max(q, 0)‖ + min(max(qx, qy, qz), 0)
|
|
10
|
+
*
|
|
11
|
+
* The gradient has two regimes and that is the whole of the derivation:
|
|
12
|
+
*
|
|
13
|
+
* - **Outside** (some component of `q` is positive) the field is the distance
|
|
14
|
+
* to the nearest point on the box, so the gradient is the unit vector from
|
|
15
|
+
* that point — `sign(x) · max(q, 0)` normalised.
|
|
16
|
+
* - **Inside** (every component of `q` is negative) the field is
|
|
17
|
+
* `max(qx, qy, qz)`, a plain maximum, so the gradient is the signed unit axis
|
|
18
|
+
* of whichever component attains it — the nearest face.
|
|
19
|
+
*
|
|
20
|
+
* Inside a box the field is not differentiable on the medial surface, where two
|
|
21
|
+
* faces are equidistant. The maximum picks one, which is the standard answer
|
|
22
|
+
* and is what a caller wants: a consistent nearest face, not an average of two.
|
|
23
|
+
*
|
|
24
|
+
* @author Alex Goldring
|
|
25
|
+
* @copyright Company Named Limited (c) 2026
|
|
26
|
+
*/
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* Signed distance from a point to a box's surface: negative inside.
|
|
30
|
+
*
|
|
31
|
+
* @param {number} x
|
|
32
|
+
* @param {number} y
|
|
33
|
+
* @param {number} z
|
|
34
|
+
* @param {number} half_x
|
|
35
|
+
* @param {number} half_y
|
|
36
|
+
* @param {number} half_z
|
|
37
|
+
* @returns {number}
|
|
38
|
+
*/
|
|
39
|
+
export function sdf3_box(x, y, z, half_x, half_y, half_z) {
|
|
40
|
+
const qx = Math.abs(x) - half_x;
|
|
41
|
+
const qy = Math.abs(y) - half_y;
|
|
42
|
+
const qz = Math.abs(z) - half_z;
|
|
43
|
+
|
|
44
|
+
const ex = qx > 0 ? qx : 0;
|
|
45
|
+
const ey = qy > 0 ? qy : 0;
|
|
46
|
+
const ez = qz > 0 ? qz : 0;
|
|
47
|
+
|
|
48
|
+
let inner = qx > qy ? qx : qy;
|
|
49
|
+
|
|
50
|
+
if (qz > inner) {
|
|
51
|
+
inner = qz;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
return Math.sqrt(ex * ex + ey * ey + ez * ez) + (inner < 0 ? inner : 0);
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Signed distance and the unit outward gradient, written to `out`.
|
|
59
|
+
*
|
|
60
|
+
* @param {Float32Array|Float64Array|number[]} out gradient destination
|
|
61
|
+
* @param {number} out_offset
|
|
62
|
+
* @param {number} x
|
|
63
|
+
* @param {number} y
|
|
64
|
+
* @param {number} z
|
|
65
|
+
* @param {number} half_x
|
|
66
|
+
* @param {number} half_y
|
|
67
|
+
* @param {number} half_z
|
|
68
|
+
* @returns {number} the signed distance
|
|
69
|
+
*/
|
|
70
|
+
export function sdf3_box_gradient(out, out_offset, x, y, z, half_x, half_y, half_z) {
|
|
71
|
+
const qx = Math.abs(x) - half_x;
|
|
72
|
+
const qy = Math.abs(y) - half_y;
|
|
73
|
+
const qz = Math.abs(z) - half_z;
|
|
74
|
+
|
|
75
|
+
const ex = qx > 0 ? qx : 0;
|
|
76
|
+
const ey = qy > 0 ? qy : 0;
|
|
77
|
+
const ez = qz > 0 ? qz : 0;
|
|
78
|
+
|
|
79
|
+
const outside = Math.sqrt(ex * ex + ey * ey + ez * ez);
|
|
80
|
+
|
|
81
|
+
if (outside > SDF3_EPSILON) {
|
|
82
|
+
const inverse = 1 / outside;
|
|
83
|
+
|
|
84
|
+
out[out_offset] = (x < 0 ? -ex : ex) * inverse;
|
|
85
|
+
out[out_offset + 1] = (y < 0 ? -ey : ey) * inverse;
|
|
86
|
+
out[out_offset + 2] = (z < 0 ? -ez : ez) * inverse;
|
|
87
|
+
|
|
88
|
+
return outside;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
// Inside, or exactly on the surface. The field is `max(q)` and its gradient
|
|
92
|
+
// is the signed unit axis of the component that attains it — the nearest
|
|
93
|
+
// face, and the direction that leaves the box soonest.
|
|
94
|
+
out[out_offset] = 0;
|
|
95
|
+
out[out_offset + 1] = 0;
|
|
96
|
+
out[out_offset + 2] = 0;
|
|
97
|
+
|
|
98
|
+
if (qx >= qy && qx >= qz) {
|
|
99
|
+
out[out_offset] = x < 0 ? -1 : 1;
|
|
100
|
+
|
|
101
|
+
return qx;
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (qy >= qz) {
|
|
105
|
+
out[out_offset + 1] = y < 0 ? -1 : 1;
|
|
106
|
+
|
|
107
|
+
return qy;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
out[out_offset + 2] = z < 0 ? -1 : 1;
|
|
111
|
+
|
|
112
|
+
return qz;
|
|
113
|
+
}
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* # Capsule — signed distance and its analytic gradient
|
|
3
|
+
*
|
|
4
|
+
* A capsule about the **Y axis** of its own frame: a segment of length
|
|
5
|
+
* `height` — so `±height/2` — swept by a sphere of `radius`. This is
|
|
6
|
+
* {@link CapsuleShape3D}'s parameterisation, and the total extent along Y is
|
|
7
|
+
* `height + 2·radius`.
|
|
8
|
+
*
|
|
9
|
+
* d(x) = ‖x − c(x)‖ − r, c(x) = (0, clamp(y, −h/2, +h/2), 0)
|
|
10
|
+
* ∇d(x) = (x − c(x))/‖x − c(x)‖
|
|
11
|
+
*
|
|
12
|
+
* The gradient is a sphere's gradient about the nearest point on the segment,
|
|
13
|
+
* which is the whole reason a capsule is cheap: collapsing Y onto the segment
|
|
14
|
+
* turns it into the sphere case, exactly once, with no branch on which cap.
|
|
15
|
+
*
|
|
16
|
+
* Degenerate on the segment itself, where the distance is zero and no direction
|
|
17
|
+
* is nearer than any other. See `sdf3_degenerate_normal.js`.
|
|
18
|
+
*
|
|
19
|
+
* @author Alex Goldring
|
|
20
|
+
* @copyright Company Named Limited (c) 2026
|
|
21
|
+
*/
|
|
22
|
+
/**
|
|
23
|
+
* Signed distance from a point to a capsule's surface: negative inside.
|
|
24
|
+
*
|
|
25
|
+
* @param {number} x
|
|
26
|
+
* @param {number} y
|
|
27
|
+
* @param {number} z
|
|
28
|
+
* @param {number} radius
|
|
29
|
+
* @param {number} height length of the central segment — total extent is `height + 2·radius`
|
|
30
|
+
* @returns {number}
|
|
31
|
+
*/
|
|
32
|
+
export function sdf3_capsule(x: number, y: number, z: number, radius: number, height: number): number;
|
|
33
|
+
/**
|
|
34
|
+
* Signed distance and the unit outward gradient, written to `out`.
|
|
35
|
+
*
|
|
36
|
+
* @param {Float32Array|Float64Array|number[]} out gradient destination
|
|
37
|
+
* @param {number} out_offset
|
|
38
|
+
* @param {number} x
|
|
39
|
+
* @param {number} y
|
|
40
|
+
* @param {number} z
|
|
41
|
+
* @param {number} radius
|
|
42
|
+
* @param {number} height
|
|
43
|
+
* @returns {number} the signed distance
|
|
44
|
+
*/
|
|
45
|
+
export function sdf3_capsule_gradient(out: Float32Array | Float64Array | number[], out_offset: number, x: number, y: number, z: number, radius: number, height: number): number;
|
|
46
|
+
//# sourceMappingURL=sdf3_capsule.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sdf3_capsule.d.ts","sourceRoot":"","sources":["../../../../../../../src/core/geom/3d/shape/sdf/sdf3_capsule.js"],"names":[],"mappings":"AAOA;;;;;;;;;;;;;;;;;;;;GAoBG;AAEH;;;;;;;;;GASG;AACH,gCAPW,MAAM,KACN,MAAM,KACN,MAAM,UACN,MAAM,UACN,MAAM,GACJ,MAAM,CAQlB;AAED;;;;;;;;;;;GAWG;AACH,2CATW,YAAY,GAAC,YAAY,GAAC,MAAM,EAAE,cAClC,MAAM,KACN,MAAM,KACN,MAAM,KACN,MAAM,UACN,MAAM,UACN,MAAM,GACJ,MAAM,CAwBlB"}
|
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import {
|
|
2
|
+
SDF3_DEGENERATE_NORMAL_X,
|
|
3
|
+
SDF3_DEGENERATE_NORMAL_Y,
|
|
4
|
+
SDF3_DEGENERATE_NORMAL_Z,
|
|
5
|
+
SDF3_EPSILON
|
|
6
|
+
} from "./sdf3_degenerate_normal.js";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* # Capsule — signed distance and its analytic gradient
|
|
10
|
+
*
|
|
11
|
+
* A capsule about the **Y axis** of its own frame: a segment of length
|
|
12
|
+
* `height` — so `±height/2` — swept by a sphere of `radius`. This is
|
|
13
|
+
* {@link CapsuleShape3D}'s parameterisation, and the total extent along Y is
|
|
14
|
+
* `height + 2·radius`.
|
|
15
|
+
*
|
|
16
|
+
* d(x) = ‖x − c(x)‖ − r, c(x) = (0, clamp(y, −h/2, +h/2), 0)
|
|
17
|
+
* ∇d(x) = (x − c(x))/‖x − c(x)‖
|
|
18
|
+
*
|
|
19
|
+
* The gradient is a sphere's gradient about the nearest point on the segment,
|
|
20
|
+
* which is the whole reason a capsule is cheap: collapsing Y onto the segment
|
|
21
|
+
* turns it into the sphere case, exactly once, with no branch on which cap.
|
|
22
|
+
*
|
|
23
|
+
* Degenerate on the segment itself, where the distance is zero and no direction
|
|
24
|
+
* is nearer than any other. See `sdf3_degenerate_normal.js`.
|
|
25
|
+
*
|
|
26
|
+
* @author Alex Goldring
|
|
27
|
+
* @copyright Company Named Limited (c) 2026
|
|
28
|
+
*/
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Signed distance from a point to a capsule's surface: negative inside.
|
|
32
|
+
*
|
|
33
|
+
* @param {number} x
|
|
34
|
+
* @param {number} y
|
|
35
|
+
* @param {number} z
|
|
36
|
+
* @param {number} radius
|
|
37
|
+
* @param {number} height length of the central segment — total extent is `height + 2·radius`
|
|
38
|
+
* @returns {number}
|
|
39
|
+
*/
|
|
40
|
+
export function sdf3_capsule(x, y, z, radius, height) {
|
|
41
|
+
const half = height * 0.5;
|
|
42
|
+
|
|
43
|
+
const dy = y < -half ? y + half : (y > half ? y - half : 0);
|
|
44
|
+
|
|
45
|
+
return Math.sqrt(x * x + dy * dy + z * z) - radius;
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
/**
|
|
49
|
+
* Signed distance and the unit outward gradient, written to `out`.
|
|
50
|
+
*
|
|
51
|
+
* @param {Float32Array|Float64Array|number[]} out gradient destination
|
|
52
|
+
* @param {number} out_offset
|
|
53
|
+
* @param {number} x
|
|
54
|
+
* @param {number} y
|
|
55
|
+
* @param {number} z
|
|
56
|
+
* @param {number} radius
|
|
57
|
+
* @param {number} height
|
|
58
|
+
* @returns {number} the signed distance
|
|
59
|
+
*/
|
|
60
|
+
export function sdf3_capsule_gradient(out, out_offset, x, y, z, radius, height) {
|
|
61
|
+
const half = height * 0.5;
|
|
62
|
+
|
|
63
|
+
const dy = y < -half ? y + half : (y > half ? y - half : 0);
|
|
64
|
+
|
|
65
|
+
const length = Math.sqrt(x * x + dy * dy + z * z);
|
|
66
|
+
|
|
67
|
+
if (length < SDF3_EPSILON) {
|
|
68
|
+
out[out_offset] = SDF3_DEGENERATE_NORMAL_X;
|
|
69
|
+
out[out_offset + 1] = SDF3_DEGENERATE_NORMAL_Y;
|
|
70
|
+
out[out_offset + 2] = SDF3_DEGENERATE_NORMAL_Z;
|
|
71
|
+
|
|
72
|
+
return -radius;
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
const inverse = 1 / length;
|
|
76
|
+
|
|
77
|
+
out[out_offset] = x * inverse;
|
|
78
|
+
out[out_offset + 1] = dy * inverse;
|
|
79
|
+
out[out_offset + 2] = z * inverse;
|
|
80
|
+
|
|
81
|
+
return length - radius;
|
|
82
|
+
}
|