@woosh/meep-engine 3.40.0 → 3.42.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/build/bundle-worker-image-decoder.js +1 -1
- package/build/bundle-worker-terrain.js +1 -1
- package/editor/selection/editor_pick.d.ts.map +1 -1
- package/editor/selection/editor_pick.js +2 -1
- package/editor/tools/TransformToolV2.d.ts.map +1 -1
- package/editor/tools/TransformToolV2.js +7 -1
- package/editor/tools/engine/ToolEngine.d.ts.map +1 -1
- package/editor/tools/engine/ToolEngine.js +10 -0
- package/editor/tools/v2/TransformControls.d.ts.map +1 -1
- package/editor/tools/v2/TransformControls.js +7 -20
- package/editor/tools/v2/handle/gizmo_drag_plane.d.ts.map +1 -1
- package/editor/tools/v2/handle/gizmo_drag_plane.js +4 -0
- package/editor/view/ecs/EntityEditor.d.ts.map +1 -1
- package/editor/view/ecs/EntityEditor.js +3 -1
- package/editor/view/node-graph/NodeGraphView.d.ts.map +1 -1
- package/editor/view/node-graph/NodeGraphView.js +28 -12
- package/package.json +1 -1
- package/samples/engine/first-scene/index.html +4 -1
- package/samples/engine/first-scene/main.js +14 -9
- package/src/core/binary/utf8/utf8_decode.js +3 -3
- package/src/core/bvh2/binary/2/bvh32_query_user_data_ray.d.ts.map +1 -1
- package/src/core/bvh2/binary/2/bvh32_query_user_data_ray.js +112 -113
- package/src/core/bvh2/bvh3/ebvh_nodes_sort_sah_local4.js +2 -2
- package/src/core/cache/wtinylfu/benchmark/CacheWTinylfu.bench.md +14 -14
- package/src/core/collection/RingBuffer.d.ts.map +1 -1
- package/src/core/collection/RingBuffer.js +4 -0
- package/src/core/collection/array/array_contains_duplicates.d.ts.map +1 -1
- package/src/core/collection/array/array_contains_duplicates.js +2 -1
- package/src/core/collection/array/array_copy.d.ts.map +1 -1
- package/src/core/collection/array/array_copy.js +23 -0
- package/src/core/collection/array/typed/sparse_typed_array_hash.d.ts +2 -2
- package/src/core/collection/array/typed/sparse_typed_array_hash.d.ts.map +1 -1
- package/src/core/collection/array/typed/sparse_typed_array_hash.js +9 -8
- package/src/core/collection/array/typed/uint16_array_hash.d.ts +2 -2
- package/src/core/collection/array/typed/uint16_array_hash.js +4 -4
- package/src/core/collection/array/typed/uint8_array_hash.d.ts +2 -2
- package/src/core/collection/array/typed/uint8_array_hash.js +4 -4
- package/src/core/collection/array/weightedRandomFromArray.d.ts +1 -0
- package/src/core/collection/array/weightedRandomFromArray.d.ts.map +1 -1
- package/src/core/collection/array/weightedRandomFromArray.js +9 -1
- package/src/core/collection/heap/BinaryHeap.d.ts.map +1 -1
- package/src/core/collection/heap/BinaryHeap.js +4 -0
- package/src/core/collection/list/List.d.ts.map +1 -1
- package/src/core/collection/list/List.js +4 -2
- package/src/core/collection/set/ArraySet.js +1 -1
- package/src/core/collection/set/HashSet.d.ts +1 -1
- package/src/core/collection/set/HashSet.d.ts.map +1 -1
- package/src/core/collection/set/HashSet.js +4 -2
- package/src/core/debug/matchers/IsEqual.js +1 -1
- package/src/core/debug/matchers/IsIterableContaining.d.ts.map +1 -1
- package/src/core/debug/matchers/IsIterableContaining.js +61 -74
- package/src/core/events/signal/SignalBinding.js +101 -101
- package/src/core/function/extractFunctionBody.js +13 -13
- package/src/core/function/objectsEqual.d.ts.map +1 -1
- package/src/core/function/objectsEqual.js +15 -14
- package/src/core/geom/3d/frustum/frustum3_compute_closest_point.d.ts.map +1 -1
- package/src/core/geom/3d/frustum/frustum3_compute_closest_point.js +207 -172
- package/src/core/geom/3d/gjk/gjk_epa_penetration.d.ts.map +1 -1
- package/src/core/geom/3d/gjk/gjk_epa_penetration.js +5 -4
- package/src/core/geom/3d/line/line3_compute_segment_point_distance_eikonal.d.ts.map +1 -1
- package/src/core/geom/3d/line/line3_compute_segment_point_distance_eikonal.js +8 -2
- package/src/core/geom/3d/quaternion/swing_twist_clamp.d.ts +24 -0
- package/src/core/geom/3d/quaternion/swing_twist_clamp.d.ts.map +1 -0
- package/src/core/geom/3d/quaternion/swing_twist_clamp.js +62 -0
- package/src/core/geom/3d/quaternion/swing_twist_compose.d.ts +15 -0
- package/src/core/geom/3d/quaternion/swing_twist_compose.d.ts.map +1 -0
- package/src/core/geom/3d/quaternion/swing_twist_compose.js +36 -0
- package/src/core/geom/3d/quaternion/swing_twist_error.d.ts +39 -0
- package/src/core/geom/3d/quaternion/swing_twist_error.d.ts.map +1 -0
- package/src/core/geom/3d/quaternion/swing_twist_error.js +85 -0
- package/src/core/geom/3d/triangle/tri3_ray_intersection.d.ts +20 -0
- package/src/core/geom/3d/triangle/tri3_ray_intersection.d.ts.map +1 -1
- package/src/core/geom/3d/triangle/tri3_ray_intersection.js +182 -0
- package/src/core/geom/vec3/v3_rigid_align_paired_unit_vectors.d.ts +11 -6
- package/src/core/geom/vec3/v3_rigid_align_paired_unit_vectors.d.ts.map +1 -1
- package/src/core/geom/vec3/v3_rigid_align_paired_unit_vectors.js +27 -13
- package/src/core/math/linalg/eigen/matrix_symmetric_4x4_eigen.d.ts +25 -0
- package/src/core/math/linalg/eigen/matrix_symmetric_4x4_eigen.d.ts.map +1 -0
- package/src/core/math/linalg/eigen/matrix_symmetric_4x4_eigen.js +166 -0
- package/src/core/math/linalg/eigen/matrix_top_eigenvector_power_iteration.d.ts +5 -3
- package/src/core/math/linalg/eigen/matrix_top_eigenvector_power_iteration.d.ts.map +1 -1
- package/src/core/math/linalg/eigen/matrix_top_eigenvector_power_iteration.js +5 -3
- package/src/core/math/noise/curl_noise_3dt.d.ts.map +1 -1
- package/src/core/math/noise/curl_noise_3dt.js +20 -10
- package/src/core/math/noise/sdnoise.d.ts +16 -5
- package/src/core/math/noise/sdnoise.d.ts.map +1 -1
- package/src/core/math/noise/sdnoise.js +43 -9
- package/src/core/math/spline/spline3_hermite_nearest_point.d.ts +16 -1
- package/src/core/math/spline/spline3_hermite_nearest_point.d.ts.map +1 -1
- package/src/core/math/spline/spline3_hermite_nearest_point.js +44 -3
- package/src/engine/Engine.d.ts.map +1 -1
- package/src/engine/Engine.js +6 -2
- package/src/engine/animation/curve/AnimationCurve.d.ts +3 -0
- package/src/engine/animation/curve/AnimationCurve.d.ts.map +1 -1
- package/src/engine/animation/curve/AnimationCurve.js +6 -1
- package/src/engine/control/first-person/FirstPersonPlayerController.d.ts +9 -0
- package/src/engine/control/first-person/FirstPersonPlayerController.d.ts.map +1 -1
- package/src/engine/control/first-person/FirstPersonPlayerControllerConfig.d.ts +26 -0
- package/src/engine/control/first-person/FirstPersonPlayerControllerConfig.d.ts.map +1 -1
- package/src/engine/control/first-person/FirstPersonPlayerControllerConfig.js +2 -0
- package/src/engine/control/first-person/abilities/AbilitySet.d.ts.map +1 -1
- package/src/engine/control/first-person/abilities/AbilitySet.js +9 -0
- package/src/engine/control/first-person/abilities/LedgeGrab.d.ts.map +1 -1
- package/src/engine/control/first-person/abilities/LedgeGrab.js +6 -0
- package/src/engine/control/first-person/abilities/Slide.d.ts.map +1 -1
- package/src/engine/control/first-person/abilities/Slide.js +1 -0
- package/src/engine/control/first-person/abilities/WallRun.d.ts +4 -1
- package/src/engine/control/first-person/abilities/WallRun.d.ts.map +1 -1
- package/src/engine/control/first-person/abilities/WallRun.js +13 -1
- package/src/engine/control/first-person/mastery/SlideInitiationTimingEvaluator.d.ts +1 -1
- package/src/engine/control/first-person/mastery/SlideInitiationTimingEvaluator.d.ts.map +1 -1
- package/src/engine/control/first-person/mastery/SlideInitiationTimingEvaluator.js +6 -5
- package/src/engine/control/first-person/mastery/StrideTimingJumpEvaluator.d.ts +3 -3
- package/src/engine/control/first-person/mastery/StrideTimingJumpEvaluator.d.ts.map +1 -1
- package/src/engine/control/first-person/mastery/StrideTimingJumpEvaluator.js +9 -8
- package/src/engine/control/first-person/sensors/FirstPersonSensorsSystem.d.ts.map +1 -1
- package/src/engine/control/first-person/sensors/FirstPersonSensorsSystem.js +13 -4
- package/src/engine/ecs/EntityManager.d.ts +9 -1
- package/src/engine/ecs/EntityManager.d.ts.map +1 -1
- package/src/engine/ecs/EntityManager.js +44 -42
- package/src/engine/ecs/dynamic_actions/rules/DynamicRuleDescription.d.ts.map +1 -1
- package/src/engine/ecs/dynamic_actions/rules/DynamicRuleDescription.js +2 -1
- package/src/engine/ecs/dynamic_actions/rules/DynamicRuleDescriptionTable.d.ts.map +1 -1
- package/src/engine/ecs/dynamic_actions/rules/DynamicRuleDescriptionTable.js +1 -0
- package/src/engine/ecs/fow/FogOfWarRevealerSystem.d.ts.map +1 -1
- package/src/engine/ecs/fow/FogOfWarRevealerSystem.js +3 -0
- package/src/engine/ecs/gpu/GPUStateAuthority.d.ts +20 -0
- package/src/engine/ecs/gpu/GPUStateAuthority.d.ts.map +1 -1
- package/src/engine/ecs/gpu/GPUStateAuthority.js +21 -0
- package/src/engine/ecs/gpu/GPU_AUTHORITY_EVENT_HOLD_CHANGE.d.ts +13 -0
- package/src/engine/ecs/gpu/GPU_AUTHORITY_EVENT_HOLD_CHANGE.d.ts.map +1 -0
- package/src/engine/ecs/gpu/GPU_AUTHORITY_EVENT_HOLD_CHANGE.js +12 -0
- package/src/engine/ecs/gpu/gpu_authority_grant.d.ts +6 -0
- package/src/engine/ecs/gpu/gpu_authority_grant.d.ts.map +1 -1
- package/src/engine/ecs/gpu/gpu_authority_grant.js +7 -1
- package/src/engine/ecs/gpu/gpu_authority_held.d.ts +14 -0
- package/src/engine/ecs/gpu/gpu_authority_held.d.ts.map +1 -0
- package/src/engine/ecs/gpu/gpu_authority_held.js +23 -0
- package/src/engine/ecs/gpu/gpu_authority_hold.d.ts +23 -0
- package/src/engine/ecs/gpu/gpu_authority_hold.d.ts.map +1 -0
- package/src/engine/ecs/gpu/gpu_authority_hold.js +41 -0
- package/src/engine/ecs/gpu/gpu_authority_unhold.d.ts +14 -0
- package/src/engine/ecs/gpu/gpu_authority_unhold.d.ts.map +1 -0
- package/src/engine/ecs/gpu/gpu_authority_unhold.js +32 -0
- package/src/engine/ecs/ik/IKGoal.d.ts +59 -0
- package/src/engine/ecs/ik/IKGoal.d.ts.map +1 -0
- package/src/engine/ecs/ik/IKGoal.js +83 -0
- package/src/engine/ecs/ik/IKGoalSystem.d.ts +75 -0
- package/src/engine/ecs/ik/IKGoalSystem.d.ts.map +1 -0
- package/src/engine/ecs/ik/IKGoalSystem.js +1456 -0
- package/src/engine/ecs/ik/PLAN.md +179 -0
- package/src/engine/ecs/parent/EntityNode.js +3 -3
- package/src/engine/ecs/speaker/VoiceSystem.d.ts +2 -2
- package/src/engine/ecs/speaker/VoiceSystem.d.ts.map +1 -1
- package/src/engine/ecs/speaker/VoiceSystem.js +4 -0
- package/src/engine/ecs/storage/BinaryBufferDeSerializer.js +5 -5
- package/src/engine/ecs/storage/BinaryBufferSerializer.d.ts.map +1 -1
- package/src/engine/ecs/storage/BinaryBufferSerializer.js +4 -5
- package/src/engine/ecs/storage/binary/BinarySerializationRegistry.d.ts.map +1 -1
- package/src/engine/ecs/storage/binary/BinarySerializationRegistry.js +3 -2
- package/src/engine/ecs/storage/binary/SERIALIZATION_COVERAGE.md +7 -3
- package/src/engine/ecs/storage/binary/object/BinaryObjectSerializationAdapter2.js +1 -1
- package/src/engine/ecs/storage/binary/object-v2/BinaryObjectDeSerializer.d.ts.map +1 -1
- package/src/engine/ecs/storage/binary/object-v2/BinaryObjectDeSerializer.js +8 -1
- package/src/engine/ecs/storage/populateEngineSerializationRegistry.d.ts.map +1 -1
- package/src/engine/ecs/storage/populateEngineSerializationRegistry.js +9 -2
- package/src/engine/ecs/system/orderSystemsByDeclaredAccess.d.ts +33 -0
- package/src/engine/ecs/system/orderSystemsByDeclaredAccess.d.ts.map +1 -0
- package/src/engine/ecs/system/orderSystemsByDeclaredAccess.js +282 -0
- package/src/engine/ecs/terrain/ecs/cling/ClingToTerrainSystem.d.ts.map +1 -1
- package/src/engine/ecs/terrain/ecs/cling/ClingToTerrainSystem.js +5 -2
- package/src/engine/ecs/terrain/ecs/layers/TerrainLayers.d.ts.map +1 -1
- package/src/engine/ecs/terrain/ecs/layers/TerrainLayers.js +3 -0
- package/src/engine/ecs/terrain/ecs/splat/SplatMapping.d.ts.map +1 -1
- package/src/engine/ecs/terrain/ecs/splat/SplatMapping.js +1 -0
- package/src/engine/ecs/terrain/overlay/TerrainOverlay.js +1 -1
- package/src/engine/ecs/terrain/tiles/TerrainTile.d.ts.map +1 -1
- package/src/engine/ecs/terrain/tiles/TerrainTile.js +13 -1
- package/src/engine/ecs/terrain/tiles/TerrainTileManager.d.ts.map +1 -1
- package/src/engine/ecs/terrain/tiles/TerrainTileManager.js +1 -0
- package/src/engine/ecs/transform/T64WorldCache.js +139 -139
- package/src/engine/ecs/transform/t64_evaluate_local.d.ts +25 -0
- package/src/engine/ecs/transform/t64_evaluate_local.d.ts.map +1 -0
- package/src/engine/ecs/transform/t64_evaluate_local.js +35 -0
- package/src/engine/ecs/transform/t64_evaluate_world.d.ts +5 -3
- package/src/engine/ecs/transform/t64_evaluate_world.d.ts.map +1 -1
- package/src/engine/ecs/transform/t64_evaluate_world.js +128 -126
- package/src/engine/graphics/ecs/light/LightSerializationAdapter.d.ts.map +1 -1
- package/src/engine/graphics/ecs/light/LightSerializationAdapter.js +13 -1
- package/src/engine/graphics/ecs/light/LightSerializationUpgrader_0_1.d.ts +5 -0
- package/src/engine/graphics/ecs/light/LightSerializationUpgrader_0_1.d.ts.map +1 -0
- package/src/engine/graphics/ecs/light/LightSerializationUpgrader_0_1.js +27 -0
- package/src/engine/graphics/ecs/water/Water.d.ts +11 -0
- package/src/engine/graphics/ecs/water/Water.d.ts.map +1 -1
- package/src/engine/graphics/ecs/water/Water.js +17 -0
- package/src/engine/graphics/ecs/water/WaterSerializationAdapter.d.ts.map +1 -1
- package/src/engine/graphics/ecs/water/WaterSerializationAdapter.js +3 -1
- package/src/engine/graphics/ecs/water/WaterSerializationUpgrader_4_5.d.ts +9 -0
- package/src/engine/graphics/ecs/water/WaterSerializationUpgrader_4_5.d.ts.map +1 -0
- package/src/engine/graphics/ecs/water/WaterSerializationUpgrader_4_5.js +24 -0
- package/src/engine/graphics/ecs/water/WaterWaves.d.ts +30 -9
- package/src/engine/graphics/ecs/water/WaterWaves.d.ts.map +1 -1
- package/src/engine/graphics/ecs/water/WaterWaves.js +41 -9
- package/src/engine/graphics/ecs/water/WaterWavesSerializationAdapter.d.ts.map +1 -1
- package/src/engine/graphics/ecs/water/WaterWavesSerializationAdapter.js +30 -26
- package/src/engine/graphics/ecs/water/WaterWavesSerializationUpgrader_0_1.d.ts +6 -0
- package/src/engine/graphics/ecs/water/WaterWavesSerializationUpgrader_0_1.d.ts.map +1 -0
- package/src/engine/graphics/ecs/water/WaterWavesSerializationUpgrader_0_1.js +22 -0
- package/src/engine/graphics/geometry/buffered/query/bvh32_geometry_raycast.d.ts.map +1 -1
- package/src/engine/graphics/geometry/buffered/query/bvh32_geometry_raycast.js +3 -5
- package/src/engine/graphics/texture/3d/scs3d_sample_linear3.d.ts +20 -0
- package/src/engine/graphics/texture/3d/scs3d_sample_linear3.d.ts.map +1 -1
- package/src/engine/graphics/texture/3d/scs3d_sample_linear3.js +36 -0
- package/src/engine/graphics3/AnimationGraphSystem.d.ts +2 -0
- package/src/engine/graphics3/AnimationGraphSystem.d.ts.map +1 -1
- package/src/engine/graphics3/AnimationGraphSystem.js +337 -329
- package/src/engine/graphics3/AnimationSystem.d.ts +2 -0
- package/src/engine/graphics3/AnimationSystem.d.ts.map +1 -1
- package/src/engine/graphics3/AnimationSystem.js +360 -352
- package/src/engine/graphics3/WaterSystem.d.ts +12 -3
- package/src/engine/graphics3/WaterSystem.d.ts.map +1 -1
- package/src/engine/graphics3/WaterSystem.js +78 -46
- package/src/engine/input/devices/PointerDevice.d.ts.map +1 -1
- package/src/engine/input/devices/PointerDevice.js +29 -4
- package/src/engine/intelligence/behavior/selector/WeightedRandomBehavior.d.ts +1 -0
- package/src/engine/intelligence/behavior/selector/WeightedRandomBehavior.d.ts.map +1 -1
- package/src/engine/intelligence/behavior/selector/WeightedRandomBehavior.js +14 -3
- package/src/engine/physics/cloth/MEASUREMENTS.md +130 -0
- package/src/engine/physics/cloth/PLAN.md +16 -1
- package/src/engine/physics/cloth/ecs/ClothColliderSystem.d.ts +5 -6
- package/src/engine/physics/cloth/ecs/ClothColliderSystem.d.ts.map +1 -1
- package/src/engine/physics/cloth/ecs/ClothColliderSystem.js +5 -6
- package/src/engine/physics/cloth/ecs/ClothInstance.d.ts +4 -7
- package/src/engine/physics/cloth/ecs/ClothInstance.d.ts.map +1 -1
- package/src/engine/physics/cloth/ecs/ClothInstance.js +4 -7
- package/src/engine/physics/cloth/ecs/ClothSystem.d.ts +4 -3
- package/src/engine/physics/cloth/ecs/ClothSystem.d.ts.map +1 -1
- package/src/engine/physics/cloth/ecs/ClothSystem.js +4 -3
- package/src/engine/physics/cloth/ecs/ClothWorld.d.ts.map +1 -1
- package/src/engine/physics/cloth/ecs/ClothWorld.js +10 -0
- package/src/engine/physics/cloth/ecs/cloth_seed_rig.d.ts +24 -24
- package/src/engine/physics/cloth/ecs/cloth_seed_rig.d.ts.map +1 -1
- package/src/engine/physics/cloth/ecs/cloth_seed_rig.js +46 -43
- package/src/engine/physics/cloth/ecs/cloth_write_back.d.ts +1 -1
- package/src/engine/physics/cloth/ecs/cloth_write_back.js +1 -1
- package/src/engine/physics/constraint/solve_constraints.d.ts +0 -35
- package/src/engine/physics/constraint/solve_constraints.d.ts.map +1 -1
- package/src/engine/physics/constraint/solve_constraints.js +1 -83
- package/src/engine/physics/ecs/ContactProbe.d.ts +73 -0
- package/src/engine/physics/ecs/ContactProbe.d.ts.map +1 -0
- package/src/engine/physics/ecs/ContactProbe.js +103 -0
- package/src/engine/physics/ecs/ContactProbeSystem.d.ts +44 -0
- package/src/engine/physics/ecs/ContactProbeSystem.d.ts.map +1 -0
- package/src/engine/physics/ecs/ContactProbeSystem.js +397 -0
- package/src/engine/physics/fluid/ecs/FluidComponent.d.ts +1 -1
- package/src/engine/physics/fluid/ecs/FluidComponent.js +1 -1
- package/src/engine/physics/fluid/ecs/FluidObstacleSystem.d.ts +4 -4
- package/src/engine/physics/fluid/solver/v3_grid_advect_maccormack_velocity.d.ts.map +1 -1
- package/src/engine/physics/fluid/solver/v3_grid_advect_maccormack_velocity.js +12 -3
- package/src/engine/physics/fluid/solver/v3_grid_advect_sl_velocity.d.ts.map +1 -1
- package/src/engine/physics/fluid/solver/v3_grid_advect_sl_velocity.js +8 -2
- package/src/engine/physics/fluid/solver/v3_grid_sample_scalar_masked.d.ts +19 -0
- package/src/engine/physics/fluid/solver/v3_grid_sample_scalar_masked.d.ts.map +1 -1
- package/src/engine/physics/fluid/solver/v3_grid_sample_scalar_masked.js +41 -2
- package/src/engine/physics/fluid/solver/v3_mac_advect_scalar.d.ts.map +1 -1
- package/src/engine/physics/fluid/solver/v3_mac_advect_scalar.js +9 -3
- package/src/engine/physics/fluid/solver/v3_mac_advect_sl_velocity.d.ts.map +1 -1
- package/src/engine/physics/fluid/solver/v3_mac_advect_sl_velocity.js +26 -10
- package/src/engine/physics/inverse_kinematics/frame_fabrik/FrameFabrikProblem.d.ts +205 -0
- package/src/engine/physics/inverse_kinematics/frame_fabrik/FrameFabrikProblem.d.ts.map +1 -0
- package/src/engine/physics/inverse_kinematics/frame_fabrik/FrameFabrikProblem.js +245 -0
- package/src/engine/physics/inverse_kinematics/frame_fabrik/frame_fabrik_limit_from_joint.d.ts +21 -0
- package/src/engine/physics/inverse_kinematics/frame_fabrik/frame_fabrik_limit_from_joint.d.ts.map +1 -0
- package/src/engine/physics/inverse_kinematics/frame_fabrik/frame_fabrik_limit_from_joint.js +63 -0
- package/src/engine/physics/inverse_kinematics/frame_fabrik/frame_fabrik_solve.d.ts +33 -0
- package/src/engine/physics/inverse_kinematics/frame_fabrik/frame_fabrik_solve.d.ts.map +1 -0
- package/src/engine/physics/inverse_kinematics/frame_fabrik/frame_fabrik_solve.js +874 -0
- package/src/engine/physics/inverse_kinematics/joint_hinge_mid_axis.d.ts +27 -0
- package/src/engine/physics/inverse_kinematics/joint_hinge_mid_axis.d.ts.map +1 -0
- package/src/engine/physics/inverse_kinematics/joint_hinge_mid_axis.js +77 -0
- package/src/engine/physics/inverse_kinematics/two_bone_path_solve.d.ts +36 -0
- package/src/engine/physics/inverse_kinematics/two_bone_path_solve.d.ts.map +1 -0
- package/src/engine/physics/inverse_kinematics/two_bone_path_solve.js +97 -0
- package/src/engine/physics/inverse_kinematics/two_joint_ik.d.ts +33 -11
- package/src/engine/physics/inverse_kinematics/two_joint_ik.d.ts.map +1 -1
- package/src/engine/physics/inverse_kinematics/two_joint_ik.js +158 -67
- package/src/engine/sound/sopra/definition/clip/RandomContainerAudioClip.d.ts +3 -6
- package/src/engine/sound/sopra/definition/clip/RandomContainerAudioClip.d.ts.map +1 -1
- package/src/engine/sound/sopra/definition/clip/RandomContainerAudioClip.js +22 -9
- package/src/engine/ui/DraggableAspect.d.ts +5 -1
- package/src/engine/ui/DraggableAspect.d.ts.map +1 -1
- package/src/engine/ui/DraggableAspect.js +61 -4
- package/src/format/image/avif/heif/ItemProperty.d.ts +1 -1
- package/src/format/image/avif/heif/ItemProperty.js +1 -1
- package/src/format/image/png/chunk/png_chunk_decode_iTXt.d.ts.map +1 -1
- package/src/format/image/png/chunk/png_chunk_decode_iTXt.js +17 -6
- package/src/shade/device/mock/SoftwareGPUDevice.d.ts +2 -4
- package/src/shade/device/mock/SoftwareGPUDevice.d.ts.map +1 -1
- package/src/shade/device/mock/SoftwareGPUDevice.js +20 -13
- package/src/shade/playground/skinned_blas_refit/sweep_views.d.ts.map +1 -1
- package/src/shade/playground/skinned_blas_refit/sweep_views.js +2 -1
- package/src/shade/playground/water_refraction/README.md +10 -11
- package/src/shade/playground/water_refraction/main.js +9 -8
- package/src/shade/playground/water_refraction/world.js +1 -1
- package/src/shade/playground/water_surface/README.md +43 -0
- package/src/shade/playground/water_surface/index.html +30 -0
- package/src/shade/playground/water_surface/main.d.ts +2 -0
- package/src/shade/playground/water_surface/main.d.ts.map +1 -0
- package/src/shade/playground/water_surface/main.js +154 -0
- package/src/shade/playground/water_surface/world.d.ts +44 -0
- package/src/shade/playground/water_surface/world.d.ts.map +1 -0
- package/src/shade/playground/water_surface/world.js +160 -0
- package/src/shade/renderer/animation/ANIMATION_TRACK_BINDING_STRUCT.d.ts.map +1 -1
- package/src/shade/renderer/animation/ANIMATION_TRACK_BINDING_STRUCT.js +10 -1
- package/src/shade/renderer/animation/GPUAnimationManager.d.ts +10 -4
- package/src/shade/renderer/animation/GPUAnimationManager.d.ts.map +1 -1
- package/src/shade/renderer/animation/GPUAnimationManager.js +251 -23
- package/src/shade/renderer/animation/POSE_ACCUMULATOR_LAYOUT.d.ts +12 -4
- package/src/shade/renderer/animation/POSE_ACCUMULATOR_LAYOUT.d.ts.map +1 -1
- package/src/shade/renderer/animation/POSE_ACCUMULATOR_LAYOUT.js +12 -4
- package/src/shade/renderer/animation/chunk_pose_accumulator.d.ts.map +1 -1
- package/src/shade/renderer/animation/chunk_pose_accumulator.js +14 -1
- package/src/shade/renderer/animation/pose/PoseChannelIndex.d.ts +78 -0
- package/src/shade/renderer/animation/pose/PoseChannelIndex.d.ts.map +1 -0
- package/src/shade/renderer/animation/pose/PoseChannelIndex.js +274 -0
- package/src/shade/renderer/animation/pose/PosePlayback.d.ts +40 -3
- package/src/shade/renderer/animation/pose/PosePlayback.d.ts.map +1 -1
- package/src/shade/renderer/animation/pose/PosePlayback.js +77 -3
- package/src/shade/renderer/animation/pose/pose_evaluate_local.d.ts +21 -3
- package/src/shade/renderer/animation/pose/pose_evaluate_local.d.ts.map +1 -1
- package/src/shade/renderer/animation/pose/pose_evaluate_local.js +79 -11
- package/src/shade/renderer/animation/shader_animation_apply.js +1 -1
- package/src/shade/renderer/animation/shader_animation_pose_resolve.d.ts +3 -2
- package/src/shade/renderer/animation/shader_animation_pose_resolve.d.ts.map +1 -1
- package/src/shade/renderer/animation/shader_animation_pose_resolve.js +187 -176
- package/src/shade/renderer/animation/skinning/GPUMeshSkinningContext.d.ts.map +1 -1
- package/src/shade/renderer/animation/skinning/GPUMeshSkinningContext.js +5 -0
- package/src/shade/renderer/binding/BufferBinding.js +2 -2
- package/src/shade/renderer/buffer/table/GPUTypedTable.d.ts.map +1 -1
- package/src/shade/renderer/buffer/table/GPUTypedTable.js +5 -3
- package/src/shade/renderer/buffer/table/GPUTypedTableDescriptor.d.ts +10 -3
- package/src/shade/renderer/buffer/table/GPUTypedTableDescriptor.d.ts.map +1 -1
- package/src/shade/renderer/buffer/table/GPUTypedTableDescriptor.js +17 -9
- package/src/shade/renderer/camera/orbital/OrbitalCameraInput.d.ts +3 -0
- package/src/shade/renderer/camera/orbital/OrbitalCameraInput.d.ts.map +1 -1
- package/src/shade/renderer/camera/orbital/OrbitalCameraInput.js +16 -0
- package/src/shade/renderer/camera/orbital/OrbitalCameraRig.d.ts +2 -0
- package/src/shade/renderer/camera/orbital/OrbitalCameraRig.d.ts.map +1 -1
- package/src/shade/renderer/camera/orbital/OrbitalCameraRig.js +11 -0
- package/src/shade/renderer/geometry/meshlet/build/meshoptimizer/geometry_to_meshlets_meshoptimizer.d.ts +1 -1
- package/src/shade/renderer/geometry/meshlet/build/meshoptimizer/geometry_to_meshlets_meshoptimizer.d.ts.map +1 -1
- package/src/shade/renderer/geometry/meshlet/build/meshoptimizer/geometry_to_meshlets_meshoptimizer.js +9 -3
- package/src/shade/renderer/geometry/util/geometry_simplify_redundant_topology.d.ts.map +1 -1
- package/src/shade/renderer/geometry/util/geometry_simplify_redundant_topology.js +2 -2
- package/src/shade/renderer/geometry/virtual/format/vgeo_validate_container.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/format/vgeo_validate_container.js +85 -0
- package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryRuntime.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/runtime/GPUVirtualGeometryRuntime.js +12 -6
- package/src/shade/renderer/geometry/virtual/runtime/VGeoPageFetcher.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/runtime/VGeoPageFetcher.js +7 -0
- package/src/shade/renderer/geometry/virtual/runtime/VGeoRuntimeTables.d.ts.map +1 -1
- package/src/shade/renderer/geometry/virtual/runtime/VGeoRuntimeTables.js +3 -1
- package/src/shade/renderer/loader/gltf/tiny-gltf.d.ts +1 -1
- package/src/shade/renderer/object_property/chunk_write_object_property.d.ts +3 -1
- package/src/shade/renderer/object_property/chunk_write_object_property.d.ts.map +1 -1
- package/src/shade/renderer/object_property/chunk_write_object_property.js +5 -2
- package/src/shade/renderer/object_property/chunk_write_object_property_node3d.d.ts +4 -0
- package/src/shade/renderer/object_property/chunk_write_object_property_node3d.d.ts.map +1 -1
- package/src/shade/renderer/object_property/chunk_write_object_property_node3d.js +6 -1
- package/src/shade/renderer/postprocess/nss/NSS.d.ts +1 -1
- package/src/shade/renderer/scene/SCENE_DATABASE_SPEC.js +2 -1
- package/src/shade/renderer/scene/optimization/geometry/geometry_deduplicate.d.ts +1 -1
- package/src/shade/renderer/scene/optimization/geometry/geometry_deduplicate.d.ts.map +1 -1
- package/src/shade/renderer/scene/optimization/geometry/geometry_deduplicate.js +135 -73
- package/src/shade/renderer/scene/optimization/geometry/internal/cover_greedy.d.ts +7 -0
- package/src/shade/renderer/scene/optimization/geometry/internal/cover_greedy.d.ts.map +1 -1
- package/src/shade/renderer/scene/optimization/geometry/internal/cover_greedy.js +29 -1
- package/src/shade/renderer/scene/optimization/geometry/internal/face_neighbourhood_hash.d.ts +19 -0
- package/src/shade/renderer/scene/optimization/geometry/internal/face_neighbourhood_hash.d.ts.map +1 -0
- package/src/shade/renderer/scene/optimization/geometry/internal/face_neighbourhood_hash.js +167 -0
- package/src/shade/renderer/scene/optimization/geometry/internal/neighbourhood_anchor_index.d.ts +25 -0
- package/src/shade/renderer/scene/optimization/geometry/internal/neighbourhood_anchor_index.d.ts.map +1 -0
- package/src/shade/renderer/scene/optimization/geometry/internal/neighbourhood_anchor_index.js +124 -0
- package/src/shade/renderer/scene/optimization/geometry/internal/seed_correspondence_from_face_pair.d.ts +19 -0
- package/src/shade/renderer/scene/optimization/geometry/internal/seed_correspondence_from_face_pair.d.ts.map +1 -0
- package/src/shade/renderer/scene/optimization/geometry/internal/seed_correspondence_from_face_pair.js +48 -0
- package/src/shade/renderer/scene/rows/GPUSceneRows.d.ts +17 -1
- package/src/shade/renderer/scene/rows/GPUSceneRows.d.ts.map +1 -1
- package/src/shade/renderer/scene/rows/GPUSceneRows.js +29 -3
- package/src/shade/renderer/shader/chunk/math/fft/chunk_fft128_inverse.d.ts +13 -0
- package/src/shade/renderer/shader/chunk/math/fft/chunk_fft128_inverse.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/math/fft/chunk_fft128_inverse.js +42 -0
- package/src/shade/renderer/shader/chunk/math/fft/chunk_fft128x4_inverse_workgroup.d.ts +15 -0
- package/src/shade/renderer/shader/chunk/math/fft/chunk_fft128x4_inverse_workgroup.d.ts.map +1 -0
- package/src/shade/renderer/shader/chunk/math/fft/chunk_fft128x4_inverse_workgroup.js +39 -0
- package/src/shade/renderer/shader/resource/ShaderResourceSetDescriptor.d.ts.map +1 -1
- package/src/shade/renderer/shader/resource/ShaderResourceSetDescriptor.js +2 -0
- package/src/shade/renderer/water/GPUWaterRenderer.d.ts +15 -0
- package/src/shade/renderer/water/GPUWaterRenderer.d.ts.map +1 -1
- package/src/shade/renderer/water/GPUWaterRenderer.js +110 -30
- package/src/shade/renderer/water/medium/GPUWaterBodies.d.ts +16 -8
- package/src/shade/renderer/water/medium/GPUWaterBodies.d.ts.map +1 -1
- package/src/shade/renderer/water/medium/GPUWaterBodies.js +31 -26
- package/src/shade/renderer/water/medium/shader_water_meshlets.d.ts +0 -1
- package/src/shade/renderer/water/medium/shader_water_meshlets.d.ts.map +1 -1
- package/src/shade/renderer/water/medium/shader_water_meshlets.js +1 -39
- package/src/shade/renderer/water/shader_water.d.ts +0 -1
- package/src/shade/renderer/water/shader_water.d.ts.map +1 -1
- package/src/shade/renderer/water/shader_water.js +201 -72
- package/src/shade/renderer/water/surface/GPUWaterSurface.d.ts +70 -0
- package/src/shade/renderer/water/surface/GPUWaterSurface.d.ts.map +1 -0
- package/src/shade/renderer/water/surface/GPUWaterSurface.js +199 -0
- package/src/shade/renderer/water/surface/WATER_WAVE_RECORD_STRUCT.d.ts +5 -2
- package/src/shade/renderer/water/surface/WATER_WAVE_RECORD_STRUCT.d.ts.map +1 -1
- package/src/shade/renderer/water/surface/WATER_WAVE_RECORD_STRUCT.js +32 -12
- package/src/shade/renderer/water/surface/chunk_water_surface_sample.d.ts +22 -0
- package/src/shade/renderer/water/surface/chunk_water_surface_sample.d.ts.map +1 -0
- package/src/shade/renderer/water/surface/chunk_water_surface_sample.js +217 -0
- package/src/shade/renderer/water/surface/graph_water_tessellation.d.ts +65 -11
- package/src/shade/renderer/water/surface/graph_water_tessellation.d.ts.map +1 -1
- package/src/shade/renderer/water/surface/graph_water_tessellation.js +163 -28
- package/src/shade/renderer/water/surface/lod/WATER_LOD.d.ts +51 -0
- package/src/shade/renderer/water/surface/lod/WATER_LOD.d.ts.map +1 -0
- package/src/shade/renderer/water/surface/lod/WATER_LOD.js +95 -0
- package/src/shade/renderer/water/surface/lod/chunk_water_lod.d.ts +10 -0
- package/src/shade/renderer/water/surface/lod/chunk_water_lod.d.ts.map +1 -0
- package/src/shade/renderer/water/surface/lod/chunk_water_lod.js +127 -0
- package/src/shade/renderer/water/surface/lod/chunk_water_lod_cell.d.ts +17 -0
- package/src/shade/renderer/water/surface/lod/chunk_water_lod_cell.d.ts.map +1 -0
- package/src/shade/renderer/water/surface/lod/chunk_water_lod_cell.js +246 -0
- package/src/shade/renderer/water/surface/lod/shader_water_lod.d.ts +118 -0
- package/src/shade/renderer/water/surface/lod/shader_water_lod.d.ts.map +1 -0
- package/src/shade/renderer/water/surface/lod/shader_water_lod.js +727 -0
- package/src/shade/renderer/water/surface/particles/GPUWaterParticles.d.ts +60 -0
- package/src/shade/renderer/water/surface/particles/GPUWaterParticles.d.ts.map +1 -0
- package/src/shade/renderer/water/surface/particles/GPUWaterParticles.js +228 -0
- package/src/shade/renderer/water/surface/particles/WATER_PARTICLE_STRUCT.d.ts +17 -0
- package/src/shade/renderer/water/surface/particles/WATER_PARTICLE_STRUCT.d.ts.map +1 -0
- package/src/shade/renderer/water/surface/particles/WATER_PARTICLE_STRUCT.js +49 -0
- package/src/shade/renderer/water/surface/particles/chunk_water_particle.d.ts +22 -0
- package/src/shade/renderer/water/surface/particles/chunk_water_particle.d.ts.map +1 -0
- package/src/shade/renderer/water/surface/particles/chunk_water_particle.js +143 -0
- package/src/shade/renderer/water/surface/particles/chunk_water_particle_step.d.ts +15 -0
- package/src/shade/renderer/water/surface/particles/chunk_water_particle_step.d.ts.map +1 -0
- package/src/shade/renderer/water/surface/particles/chunk_water_particle_step.js +121 -0
- package/src/shade/renderer/water/surface/particles/shader_water_particles.d.ts +83 -0
- package/src/shade/renderer/water/surface/particles/shader_water_particles.d.ts.map +1 -0
- package/src/shade/renderer/water/surface/particles/shader_water_particles.js +502 -0
- package/src/shade/renderer/water/surface/shader_water_cull.d.ts +42 -0
- package/src/shade/renderer/water/surface/shader_water_cull.d.ts.map +1 -0
- package/src/shade/renderer/water/surface/shader_water_cull.js +269 -0
- package/src/shade/renderer/water/surface/shader_water_waves_combine.d.ts +15 -0
- package/src/shade/renderer/water/surface/shader_water_waves_combine.d.ts.map +1 -0
- package/src/shade/renderer/water/surface/shader_water_waves_combine.js +73 -0
- package/src/shade/renderer/water/surface/shader_water_waves_derive.d.ts +11 -0
- package/src/shade/renderer/water/surface/shader_water_waves_derive.d.ts.map +1 -0
- package/src/shade/renderer/water/surface/shader_water_waves_derive.js +78 -0
- package/src/shade/renderer/water/surface/spectrum/GPUWaterSpectrum.d.ts +35 -0
- package/src/shade/renderer/water/surface/spectrum/GPUWaterSpectrum.d.ts.map +1 -0
- package/src/shade/renderer/water/surface/spectrum/GPUWaterSpectrum.js +103 -0
- package/src/shade/renderer/water/surface/spectrum/WATER_BAND_STATE.d.ts +22 -0
- package/src/shade/renderer/water/surface/spectrum/WATER_BAND_STATE.d.ts.map +1 -0
- package/src/shade/renderer/water/surface/spectrum/WATER_BAND_STATE.js +57 -0
- package/src/shade/renderer/water/surface/spectrum/WATER_SPECTRUM.d.ts +22 -0
- package/src/shade/renderer/water/surface/spectrum/WATER_SPECTRUM.d.ts.map +1 -0
- package/src/shade/renderer/water/surface/spectrum/WATER_SPECTRUM.js +25 -0
- package/src/shade/renderer/water/surface/spectrum/chunk_water_jonswap.d.ts +14 -0
- package/src/shade/renderer/water/surface/spectrum/chunk_water_jonswap.d.ts.map +1 -0
- package/src/shade/renderer/water/surface/spectrum/chunk_water_jonswap.js +48 -0
- package/src/shade/renderer/water/surface/spectrum/chunk_water_spectrum.d.ts +23 -0
- package/src/shade/renderer/water/surface/spectrum/chunk_water_spectrum.d.ts.map +1 -0
- package/src/shade/renderer/water/surface/spectrum/chunk_water_spectrum.js +169 -0
- package/src/shade/renderer/water/surface/spectrum/shader_water_spectrum.d.ts +26 -0
- package/src/shade/renderer/water/surface/spectrum/shader_water_spectrum.d.ts.map +1 -0
- package/src/shade/renderer/water/surface/spectrum/shader_water_spectrum.js +161 -0
- package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.d.ts.map +1 -1
- package/src/shade/wgsl/emulator/WGSLJavaScriptCompiler.js +18 -6
- package/src/shade/wgsl/emulator/WGSLLanguageCore.d.ts.map +1 -1
- package/src/shade/wgsl/emulator/WGSLLanguageCore.js +11 -3
- package/src/core/geom/2d/polygon/polygon2_triangulate.corpus.d.ts +0 -28
- package/src/core/geom/2d/polygon/polygon2_triangulate.corpus.d.ts.map +0 -1
- package/src/core/geom/2d/polygon/polygon2_triangulate.corpus.js +0 -86
- package/src/engine/ecs/ik/IKConstraint.d.ts +0 -52
- package/src/engine/ecs/ik/IKConstraint.d.ts.map +0 -1
- package/src/engine/ecs/ik/IKConstraint.js +0 -95
- package/src/engine/ecs/ik/IKProblem.d.ts +0 -45
- package/src/engine/ecs/ik/IKProblem.d.ts.map +0 -1
- package/src/engine/ecs/ik/IKProblem.js +0 -58
- package/src/engine/ecs/ik/IKSolver.d.ts +0 -8
- package/src/engine/ecs/ik/IKSolver.d.ts.map +0 -1
- package/src/engine/ecs/ik/IKSolver.js +0 -9
- package/src/engine/ecs/ik/InverseKinematics.d.ts +0 -48
- package/src/engine/ecs/ik/InverseKinematics.d.ts.map +0 -1
- package/src/engine/ecs/ik/InverseKinematics.js +0 -119
- package/src/engine/ecs/ik/InverseKinematicsSerializationAdapter.d.ts +0 -19
- package/src/engine/ecs/ik/InverseKinematicsSerializationAdapter.d.ts.map +0 -1
- package/src/engine/ecs/ik/InverseKinematicsSerializationAdapter.js +0 -72
- package/src/engine/ecs/ik/InverseKinematicsSystem.d.ts +0 -54
- package/src/engine/ecs/ik/InverseKinematicsSystem.d.ts.map +0 -1
- package/src/engine/ecs/ik/InverseKinematicsSystem.js +0 -212
- package/src/engine/ecs/ik/OneBoneSurfaceAlignmentSolver.d.ts +0 -8
- package/src/engine/ecs/ik/OneBoneSurfaceAlignmentSolver.d.ts.map +0 -1
- package/src/engine/ecs/ik/OneBoneSurfaceAlignmentSolver.js +0 -153
- package/src/engine/ecs/ik/TwoBoneInverseKinematicsSolver.d.ts +0 -5
- package/src/engine/ecs/ik/TwoBoneInverseKinematicsSolver.d.ts.map +0 -1
- package/src/engine/ecs/ik/TwoBoneInverseKinematicsSolver.js +0 -120
- package/src/engine/ecs/ik/ik_bone_chain.d.ts +0 -64
- package/src/engine/ecs/ik/ik_bone_chain.d.ts.map +0 -1
- package/src/engine/ecs/ik/ik_bone_chain.js +0 -142
- package/src/engine/ecs/ik/ik_probe_terrain_contact.d.ts +0 -42
- package/src/engine/ecs/ik/ik_probe_terrain_contact.d.ts.map +0 -1
- package/src/engine/ecs/ik/ik_probe_terrain_contact.js +0 -123
- package/src/engine/ecs/ik/ik_write_local_rotation.d.ts +0 -18
- package/src/engine/ecs/ik/ik_write_local_rotation.d.ts.map +0 -1
- package/src/engine/ecs/ik/ik_write_local_rotation.js +0 -32
- package/src/engine/ecs/storage/binary/object-v2/serializerTestHarness.d.ts +0 -29
- package/src/engine/ecs/storage/binary/object-v2/serializerTestHarness.d.ts.map +0 -1
- package/src/engine/ecs/storage/binary/object-v2/serializerTestHarness.js +0 -44
- package/src/shade/renderer/water/medium/shader_water_bodies_derive.d.ts +0 -4
- package/src/shade/renderer/water/medium/shader_water_bodies_derive.d.ts.map +0 -1
- package/src/shade/renderer/water/medium/shader_water_bodies_derive.js +0 -32
- package/src/shade/renderer/water/surface/GPUWaterWaveSimulation.d.ts +0 -25
- package/src/shade/renderer/water/surface/GPUWaterWaveSimulation.d.ts.map +0 -1
- package/src/shade/renderer/water/surface/GPUWaterWaveSimulation.js +0 -128
- package/src/shade/renderer/water/surface/chunk_water_tessellation.d.ts +0 -9
- package/src/shade/renderer/water/surface/chunk_water_tessellation.d.ts.map +0 -1
- package/src/shade/renderer/water/surface/chunk_water_tessellation.js +0 -144
- package/src/shade/renderer/water/surface/chunk_water_wave.d.ts +0 -13
- package/src/shade/renderer/water/surface/chunk_water_wave.d.ts.map +0 -1
- package/src/shade/renderer/water/surface/chunk_water_wave.js +0 -40
- package/src/shade/renderer/water/surface/shader_water_tiles.d.ts +0 -4
- package/src/shade/renderer/water/surface/shader_water_tiles.d.ts.map +0 -1
- package/src/shade/renderer/water/surface/shader_water_tiles.js +0 -123
- package/src/shade/renderer/water/surface/shader_water_wave_batch.d.ts +0 -6
- package/src/shade/renderer/water/surface/shader_water_wave_batch.d.ts.map +0 -1
- package/src/shade/renderer/water/surface/shader_water_wave_batch.js +0 -85
- package/src/shade/renderer/water/surface/shader_water_wave_domain.d.ts +0 -6
- package/src/shade/renderer/water/surface/shader_water_wave_domain.d.ts.map +0 -1
- package/src/shade/renderer/water/surface/shader_water_wave_domain.js +0 -83
|
@@ -0,0 +1,502 @@
|
|
|
1
|
+
import { ComputeShader } from "../../../shader/ComputeShader.js";
|
|
2
|
+
import { CodeChunk } from "../../../shader/compiler/CodeChunk.js";
|
|
3
|
+
import { ShaderResourceSetDescriptor } from "../../../shader/resource/ShaderResourceSetDescriptor.js";
|
|
4
|
+
import { WebGPUArray } from "../../../shader/type/WebGPUArray.js";
|
|
5
|
+
import { WebGPUStruct } from "../../../shader/type/WebGPUStruct.js";
|
|
6
|
+
import { WGSLAttribute } from "../../../shader/type/WGSLAttribute.js";
|
|
7
|
+
import { WGSLAttributes } from "../../../shader/type/WGSLAttributes.js";
|
|
8
|
+
import { WGSLStructField } from "../../../shader/type/WGSLStructField.js";
|
|
9
|
+
import { atomic_u32, f32, u32 } from "../../../shader/type/WEBGPU_WGSL_PRIMITIVE_TYPES.js";
|
|
10
|
+
import { COLLECTION_U32_STRUCT_READ } from "../../../gpu_primitive/COLLECTION_U32_STRUCT_READ.js";
|
|
11
|
+
import { GEOMETRY_METADATA_STRUCT } from "../../../geometry/GEOMETRY_METADATA_STRUCT.js";
|
|
12
|
+
import { MESHLET_METADATA_STRUCT } from "../../../geometry/meshlet/encoding/MESHLET_METADATA_STRUCT.js";
|
|
13
|
+
import { BVH2_NODE_STRUCT } from "../../../shader/chunk/bvh/BVH2_NODE_STRUCT.js";
|
|
14
|
+
import { chunk_folded_workgroup_index } from "../../../shader/chunk/grid/chunk_folded_workgroup_index.js";
|
|
15
|
+
import { chunk_scene_database_access, chunk_scene_database_access_rw } from "../../../scene/chunk_scene_database_access.js";
|
|
16
|
+
import { WaterActivity } from "../shader_water_cull.js";
|
|
17
|
+
import { WATER_WAVES_TABLE as waves } from "../../medium/chunk_water_bodies.js";
|
|
18
|
+
import { WATER_PARTICLE_BODY_BOUNDS_STRIDE } from "../shader_water_waves_combine.js";
|
|
19
|
+
import { WATER_PARTICLE_ENTRY_STRUCT, WATER_PARTICLE_STRUCT } from "./WATER_PARTICLE_STRUCT.js";
|
|
20
|
+
import { WATER_WAVE_IMPULSE_LIMIT } from "../WATER_WAVE_RECORD_STRUCT.js";
|
|
21
|
+
import { chunk_water_particle } from "./chunk_water_particle.js";
|
|
22
|
+
import { chunk_water_particle_step } from "./chunk_water_particle_step.js";
|
|
23
|
+
|
|
24
|
+
/** A particle array with its live count in front, as the indirect commands read it. */
|
|
25
|
+
export const WATER_PARTICLE_ARRAY_STRUCT = WebGPUStruct.fromFields(
|
|
26
|
+
WGSLStructField.from("count", u32),
|
|
27
|
+
WGSLStructField.from("elements", WebGPUArray.from(WATER_PARTICLE_STRUCT), WGSLAttribute.from(WGSLAttributes.Align, 16)),
|
|
28
|
+
);
|
|
29
|
+
|
|
30
|
+
/** The same array where emitters append by an atomic count. */
|
|
31
|
+
export const WATER_PARTICLE_ARRAY_APPEND_STRUCT = WebGPUStruct.fromFields(
|
|
32
|
+
WGSLStructField.from("count", atomic_u32),
|
|
33
|
+
WGSLStructField.from("elements", WebGPUArray.from(WATER_PARTICLE_STRUCT), WGSLAttribute.from(WGSLAttributes.Align, 16)),
|
|
34
|
+
);
|
|
35
|
+
|
|
36
|
+
/** Bucket counts while binning: the table size in front, atomic counters behind. */
|
|
37
|
+
export const WATER_PARTICLE_BUCKETS_STRUCT = WebGPUStruct.fromFields(
|
|
38
|
+
WGSLStructField.from("count", u32),
|
|
39
|
+
WGSLStructField.from("elements", WebGPUArray.from(atomic_u32), WGSLAttribute.from(WGSLAttributes.Align, 16)),
|
|
40
|
+
);
|
|
41
|
+
|
|
42
|
+
/** Smallest hash table, so an idle frame scans little. */
|
|
43
|
+
export const WATER_PARTICLE_TABLE_MIN = 1024;
|
|
44
|
+
|
|
45
|
+
/** Bucket entries one particle can take: the 2×2 cells its support overlaps. */
|
|
46
|
+
export const WATER_PARTICLE_CORNERS = 4;
|
|
47
|
+
|
|
48
|
+
/** Buckets ordered by particle; a crowded bucket past this keeps its arrival order. */
|
|
49
|
+
export const WATER_PARTICLE_RANK_LIMIT = 64;
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Packets a crowded cell keeps: where more crowd a cell, each is drawn by its share of the cell's summed steepness
|
|
53
|
+
* times this, so about this many stay, the steepest whole. Well under the surface sampler's gather budget and the rank
|
|
54
|
+
* limit, so a point reads all of its cell and every bucket keeps the particles' order.
|
|
55
|
+
*/
|
|
56
|
+
export const WATER_PARTICLE_CELL_SHARE = 16;
|
|
57
|
+
|
|
58
|
+
/** Width of the ramp a thinned packet fades over, a fraction of its share. */
|
|
59
|
+
export const WATER_PARTICLE_THINNING_RAMP = 0.25;
|
|
60
|
+
|
|
61
|
+
/** Fixed-point scale of a packet's steepness in its cells' sums. */
|
|
62
|
+
const WATER_PARTICLE_WEIGHT_SCALE = 1 << 20;
|
|
63
|
+
|
|
64
|
+
const STRIDE = WATER_PARTICLE_BODY_BOUNDS_STRIDE;
|
|
65
|
+
|
|
66
|
+
/** The step's settings: one immediate per entry point. */
|
|
67
|
+
export const WATER_PARTICLE_STEP_STRUCT = WebGPUStruct.from({ dt: f32, capacity: u32 }, 'WaterParticleStepSettings');
|
|
68
|
+
|
|
69
|
+
/** The pool's limits for the frame's finalize. */
|
|
70
|
+
export const WATER_PARTICLE_LIMITS_STRUCT = WebGPUStruct.from({ capacity: u32, table_limit: u32 }, 'WaterParticleLimits');
|
|
71
|
+
|
|
72
|
+
const update_resources = new ShaderResourceSetDescriptor();
|
|
73
|
+
update_resources.setImmediate('frame', WATER_PARTICLE_STEP_STRUCT);
|
|
74
|
+
update_resources.createGroup()
|
|
75
|
+
.addStorageBuffer('particles', WATER_PARTICLE_ARRAY_STRUCT, true)
|
|
76
|
+
.addStorageBuffer('children', COLLECTION_U32_STRUCT_READ, true)
|
|
77
|
+
.addStorageBuffer('activity', WebGPUArray.u32)
|
|
78
|
+
.addStorageBuffer('scene_database', WebGPUArray.u32)
|
|
79
|
+
.addStorageBuffer('geometries', WebGPUArray.from(GEOMETRY_METADATA_STRUCT))
|
|
80
|
+
.addStorageBuffer('blas_lookup', WebGPUArray.u32)
|
|
81
|
+
.addStorageBuffer('blas_data', WebGPUArray.from(BVH2_NODE_STRUCT))
|
|
82
|
+
.addStorageBuffer('meshlet_metadata', WebGPUArray.from(MESHLET_METADATA_STRUCT))
|
|
83
|
+
.addStorageBuffer('meshlet_data', WebGPUArray.from(f32));
|
|
84
|
+
|
|
85
|
+
/**
|
|
86
|
+
* Advance every live particle of a body simulated this frame in place and count what it leaves: 0, 1 or 3. A paused
|
|
87
|
+
* body's particles stand still and leave themselves.
|
|
88
|
+
*/
|
|
89
|
+
export const shader_water_particles_update = ComputeShader.from({ label: 'Water / particles update', resources: update_resources,
|
|
90
|
+
body: CodeChunk.from(/* language=WGSL */ `
|
|
91
|
+
@compute @workgroup_size(64)
|
|
92
|
+
fn main(@builtin(workgroup_id) group: vec3u, @builtin(local_invocation_index) lane: u32) {
|
|
93
|
+
let i = folded_workgroup_index(group) * 64u + lane;
|
|
94
|
+
let count = min(particles.count, frame.capacity);
|
|
95
|
+
if (i >= count) { return; }
|
|
96
|
+
var particle = particles.elements[i];
|
|
97
|
+
var left = 0u;
|
|
98
|
+
let node = ${waves.marshalling_method_read_field('node')}(&scene_database, particle.body);
|
|
99
|
+
if ((activity[particle.body] & ${WaterActivity.Active}u) == 0u) {
|
|
100
|
+
left = 1u;
|
|
101
|
+
} else if (node != 0u && node != ~0u) {
|
|
102
|
+
let global = scene_read_node(&scene_database, node).global;
|
|
103
|
+
let scale = max(vec2<f32>(length(global[0].xyz), length(global[2].xyz)), vec2<f32>(1e-20));
|
|
104
|
+
let threshold = water_particle_threshold(${waves.marshalling_method_read_field('slope_variance')}(&scene_database, particle.body),
|
|
105
|
+
count, frame.capacity);
|
|
106
|
+
let advanced = water_particle_advance(particle, frame.dt, ${waves.marshalling_method_read_field('geometry')}(&scene_database, particle.body),
|
|
107
|
+
scale, ${waves.marshalling_method_read_field('wind')}(&scene_database, particle.body).w, threshold);
|
|
108
|
+
particle = advanced.particle;
|
|
109
|
+
left = advanced.children;
|
|
110
|
+
}
|
|
111
|
+
particles.elements[i] = particle;
|
|
112
|
+
children.elements[i] = left;
|
|
113
|
+
}
|
|
114
|
+
`, [chunk_water_particle_step, chunk_scene_database_access, waves.chunk_read_field('node'), waves.chunk_read_field('slope_variance'),
|
|
115
|
+
waves.chunk_read_field('geometry'), waves.chunk_read_field('wind'), chunk_folded_workgroup_index]) });
|
|
116
|
+
|
|
117
|
+
const split_resources = new ShaderResourceSetDescriptor();
|
|
118
|
+
split_resources.setImmediate('capacity', u32);
|
|
119
|
+
split_resources.createGroup()
|
|
120
|
+
.addStorageBuffer('particles', WATER_PARTICLE_ARRAY_STRUCT)
|
|
121
|
+
.addStorageBuffer('children', COLLECTION_U32_STRUCT_READ)
|
|
122
|
+
.addStorageBuffer('next', WATER_PARTICLE_ARRAY_STRUCT, true);
|
|
123
|
+
|
|
124
|
+
/**
|
|
125
|
+
* Write what each particle leaves into the next array at its scanned offset, in order: a split particle's
|
|
126
|
+
* three at θ − β/3, θ, θ + β/3 with β/3 each. Past capacity, the tail is dropped.
|
|
127
|
+
*/
|
|
128
|
+
export const shader_water_particles_split = ComputeShader.from({ label: 'Water / particles split', resources: split_resources,
|
|
129
|
+
body: CodeChunk.from(/* language=WGSL */ `
|
|
130
|
+
@compute @workgroup_size(64)
|
|
131
|
+
fn main(@builtin(workgroup_id) group: vec3u, @builtin(local_invocation_index) lane: u32) {
|
|
132
|
+
let i = folded_workgroup_index(group) * 64u + lane;
|
|
133
|
+
let count = min(particles.count, capacity);
|
|
134
|
+
if (i >= count) { return; }
|
|
135
|
+
let end = children.elements[i];
|
|
136
|
+
var start = 0u;
|
|
137
|
+
if (i > 0u) { start = children.elements[i - 1u]; }
|
|
138
|
+
let particle = particles.elements[i];
|
|
139
|
+
if (end - start == 1u) {
|
|
140
|
+
if (start < capacity) { next.elements[start] = particle; }
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
for (var k = start; k < end && k < capacity; k++) {
|
|
144
|
+
var child = particle;
|
|
145
|
+
child.dispersion = particle.dispersion / 3.0;
|
|
146
|
+
child.angle = particle.angle + (f32(k - start) - 1.0) * child.dispersion;
|
|
147
|
+
next.elements[k] = child;
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
`, [WATER_PARTICLE_STRUCT.declaration_chunk, chunk_folded_workgroup_index]) });
|
|
151
|
+
|
|
152
|
+
const total_resources = new ShaderResourceSetDescriptor();
|
|
153
|
+
total_resources.setImmediate('capacity', u32);
|
|
154
|
+
total_resources.createGroup()
|
|
155
|
+
.addStorageBuffer('children', COLLECTION_U32_STRUCT_READ)
|
|
156
|
+
.addStorageBuffer('next', WATER_PARTICLE_ARRAY_STRUCT, true);
|
|
157
|
+
|
|
158
|
+
/** The next array's count: everything the scan placed, up to capacity. */
|
|
159
|
+
export const shader_water_particles_total = ComputeShader.from({ label: 'Water / particles total', resources: total_resources,
|
|
160
|
+
body: CodeChunk.from(/* language=WGSL */ `
|
|
161
|
+
@compute @workgroup_size(1)
|
|
162
|
+
fn main() {
|
|
163
|
+
let total = select(0u, children.elements[max(children.count, 1u) - 1u], children.count > 0u);
|
|
164
|
+
next.count = min(total, capacity);
|
|
165
|
+
}
|
|
166
|
+
`, [WATER_PARTICLE_STRUCT.declaration_chunk]) });
|
|
167
|
+
|
|
168
|
+
const emit_resources = new ShaderResourceSetDescriptor();
|
|
169
|
+
emit_resources.setImmediate('capacity', u32);
|
|
170
|
+
emit_resources.createGroup()
|
|
171
|
+
.addStorageBuffer('scene_database', WebGPUArray.u32, true)
|
|
172
|
+
.addStorageBuffer('emit_rows', COLLECTION_U32_STRUCT_READ)
|
|
173
|
+
.addStorageBuffer('steep', WebGPUArray.from(u32))
|
|
174
|
+
.addStorageBuffer('activity', WebGPUArray.u32)
|
|
175
|
+
.addStorageBuffer('particle_bounds', WebGPUArray.u32, true)
|
|
176
|
+
.addStorageBuffer('next', WATER_PARTICLE_ARRAY_APPEND_STRUCT, true);
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* Each queued splash of a row on the culling pass's emit list becomes a ring
|
|
180
|
+
* (WATER_SURFACE_SIMULATION_PLAN_2026_10_06.md §5.3): packets of the splash's radius r, two radii out from its centre,
|
|
181
|
+
* a front's width apart, ridge height strength·r/c (a vertical velocity over the time a crest takes to cross the
|
|
182
|
+
* packet), no steeper than 0.1. The row's queue is spent. A paused body's ring stands still with its other particles,
|
|
183
|
+
* which this frame's binning does not visit, so the ring's bound is added to the body's own here.
|
|
184
|
+
*/
|
|
185
|
+
export const shader_water_particles_emit = ComputeShader.from({ label: 'Water / particles emit', resources: emit_resources,
|
|
186
|
+
body: CodeChunk.from(/* language=WGSL */ `
|
|
187
|
+
@compute @workgroup_size(64)
|
|
188
|
+
fn main(@builtin(workgroup_id) group: vec3u, @builtin(local_invocation_index) lane: u32) {
|
|
189
|
+
let index = folded_workgroup_index(group) * 64u + lane;
|
|
190
|
+
if (index >= emit_rows.count) { return; }
|
|
191
|
+
let row = emit_rows.elements[index];
|
|
192
|
+
let wave = ${waves.marshalling_method_read_rw}(&scene_database, row);
|
|
193
|
+
${waves.marshalling_method_write_field('impulse_count')}(&scene_database, row, 0u);
|
|
194
|
+
if (wave.node == 0u || wave.node == ~0u || steep[row] != 0u) { return; }
|
|
195
|
+
let global = scene_read_node_rw(&scene_database, wave.node).global;
|
|
196
|
+
let scale = vec2<f32>(length(global[0].xyz), length(global[2].xyz));
|
|
197
|
+
let paused = (activity[row] & ${WaterActivity.Active}u) == 0u;
|
|
198
|
+
var held = 0.0;
|
|
199
|
+
for (var j = 0u; j < min(wave.impulse_count, ${WATER_WAVE_IMPULSE_LIMIT}u); j++) {
|
|
200
|
+
let impulse = wave.impulses[j];
|
|
201
|
+
let radius = clamp(impulse.z, 1e-3, 16.0);
|
|
202
|
+
let height = clamp(impulse.w * radius / water_particle_phase_speed(radius), -0.1 * radius, 0.1 * radius);
|
|
203
|
+
let reach = 2.0 * radius;
|
|
204
|
+
let count = u32(ceil(WATER_TAU * reach / (2.0 * radius)));
|
|
205
|
+
let dispersion = WATER_TAU / f32(count);
|
|
206
|
+
let age = reach / water_particle_group_speed(radius);
|
|
207
|
+
let base = atomicAdd(&next.count, count);
|
|
208
|
+
// a ring that does not fit whole is not emitted: an arc of it would break its front's partition of unity.
|
|
209
|
+
// The slots it took up to capacity hold flat packets, which the next step drops.
|
|
210
|
+
let ridge = select(0.0, height, base + count <= capacity);
|
|
211
|
+
for (var k = 0u; k < count; k++) {
|
|
212
|
+
if (base + k >= capacity) { break; }
|
|
213
|
+
next.elements[base + k] = ${WATER_PARTICLE_STRUCT.wgsl_ref}(impulse.xy * scale, f32(k) * dispersion, age, ridge, radius, dispersion, row);
|
|
214
|
+
}
|
|
215
|
+
held += f32(count) * abs(ridge);
|
|
216
|
+
}
|
|
217
|
+
if (paused && held > 0.0) {
|
|
218
|
+
// level 0's slot, and its bit, so that the culling pass, which reads the slots only of the levels set, counts it
|
|
219
|
+
let at = row * ${STRIDE}u;
|
|
220
|
+
particle_bounds[at] |= 1u;
|
|
221
|
+
particle_bounds[at + 1u] = bitcast<u32>(bitcast<f32>(particle_bounds[at + 1u]) + held);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
`, [waves.chunk_read_rw, waves.wgsl_gen_write_field_code('impulse_count'), chunk_water_particle, chunk_scene_database_access_rw,
|
|
225
|
+
chunk_folded_workgroup_index]) });
|
|
226
|
+
|
|
227
|
+
const finalize_resources = new ShaderResourceSetDescriptor();
|
|
228
|
+
finalize_resources.setImmediate('limits', WATER_PARTICLE_LIMITS_STRUCT);
|
|
229
|
+
finalize_resources.createGroup()
|
|
230
|
+
.addStorageBuffer('next', WATER_PARTICLE_ARRAY_STRUCT, true)
|
|
231
|
+
.addStorageBuffer('offsets', COLLECTION_U32_STRUCT_READ, true);
|
|
232
|
+
|
|
233
|
+
/**
|
|
234
|
+
* The live count, clamped to capacity (emitters append past it), and the frame's hash table size: twice the
|
|
235
|
+
* entries the particles can take, a power of two, at least ${WATER_PARTICLE_TABLE_MIN}.
|
|
236
|
+
*/
|
|
237
|
+
export const shader_water_particles_finalize = ComputeShader.from({ label: 'Water / particles finalize', resources: finalize_resources,
|
|
238
|
+
body: CodeChunk.from(/* language=WGSL */ `
|
|
239
|
+
@compute @workgroup_size(1)
|
|
240
|
+
fn main() {
|
|
241
|
+
let live = min(next.count, limits.capacity);
|
|
242
|
+
next.count = live;
|
|
243
|
+
let wanted = max(2u * ${WATER_PARTICLE_CORNERS}u * live, ${WATER_PARTICLE_TABLE_MIN}u);
|
|
244
|
+
offsets.count = min(1u << (32u - countLeadingZeros(wanted - 1u)), limits.table_limit);
|
|
245
|
+
}
|
|
246
|
+
`, [WATER_PARTICLE_STRUCT.declaration_chunk]) });
|
|
247
|
+
|
|
248
|
+
/**
|
|
249
|
+
* A live particle's place in the hash this frame: its kernel at this time, its level and the cells its
|
|
250
|
+
* support overlaps (one or two a side, the level's cell being at least the support's diameter).
|
|
251
|
+
*/
|
|
252
|
+
const chunk_water_particle_cells = CodeChunk.from(/* language=WGSL */ `
|
|
253
|
+
struct WaterParticleCells {
|
|
254
|
+
entry: ${WATER_PARTICLE_ENTRY_STRUCT.wgsl_ref},
|
|
255
|
+
level: u32,
|
|
256
|
+
first: vec2<i32>,
|
|
257
|
+
span: vec2<u32>,
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
fn water_particle_cells(particle: ${WATER_PARTICLE_STRUCT.wgsl_ref}, source: u32) -> WaterParticleCells {
|
|
261
|
+
var cells: WaterParticleCells;
|
|
262
|
+
let position = water_particle_position(particle);
|
|
263
|
+
let width = water_particle_width(particle);
|
|
264
|
+
let support = water_particle_support(particle.radius, width);
|
|
265
|
+
cells.level = water_particle_level(support);
|
|
266
|
+
let size = water_particle_cell_size(cells.level);
|
|
267
|
+
cells.first = vec2<i32>(floor((position - vec2<f32>(support)) / size));
|
|
268
|
+
let last = vec2<i32>(floor((position + vec2<f32>(support)) / size));
|
|
269
|
+
cells.span = vec2<u32>(clamp(last - cells.first, vec2<i32>(0), vec2<i32>(1))) + vec2<u32>(1u);
|
|
270
|
+
cells.entry = ${WATER_PARTICLE_ENTRY_STRUCT.wgsl_ref}(position, cells.first, particle.angle, particle.amplitude, particle.radius,
|
|
271
|
+
width, water_particle_phase(particle), (particle.body << 4u) | cells.level, source, 0u);
|
|
272
|
+
return cells;
|
|
273
|
+
}
|
|
274
|
+
|
|
275
|
+
fn water_particle_corner_cell(cells: WaterParticleCells, corner: u32) -> vec2<i32> {
|
|
276
|
+
return cells.first + vec2<i32>(i32(corner & 1u), i32(corner >> 1u));
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
fn water_particle_has_corner(cells: WaterParticleCells, corner: u32) -> bool {
|
|
280
|
+
return all(vec2<u32>(corner & 1u, corner >> 1u) < cells.span);
|
|
281
|
+
}
|
|
282
|
+
|
|
283
|
+
// A packet's claim on its cells: its steepness, fixed point.
|
|
284
|
+
fn water_particle_weight(particle: ${WATER_PARTICLE_STRUCT.wgsl_ref}) -> u32 {
|
|
285
|
+
return u32(min(abs(particle.amplitude) / max(particle.radius, 1e-6), 1.0) * ${WATER_PARTICLE_WEIGHT_SCALE}.0);
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
// A number in [0, 1) that stays with a packet while it travels: from its front's centre and direction.
|
|
289
|
+
fn water_particle_lot(particle: ${WATER_PARTICLE_STRUCT.wgsl_ref}) -> f32 {
|
|
290
|
+
let bits = pcg3d(vec3<u32>(bitcast<u32>(particle.origin.x), bitcast<u32>(particle.origin.y), bitcast<u32>(particle.angle)));
|
|
291
|
+
return f32(bits.x >> 8u) * (1.0 / 16777216.0);
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
// How much of a packet its crowd leaves drawn, from its share of the most crowded of its cells: all of it from a share
|
|
295
|
+
// of one, and below that, all of it while its lot is under its share, fading to none a ramp of that share above. So a
|
|
296
|
+
// cell keeps about its share whatever its crowd.
|
|
297
|
+
fn water_particle_visibility(share: f32, lot: f32) -> f32 {
|
|
298
|
+
return clamp((share - lot) / (${WATER_PARTICLE_THINNING_RAMP} * share) + 1.0, 0.0, 1.0);
|
|
299
|
+
}
|
|
300
|
+
`, [chunk_water_particle]);
|
|
301
|
+
|
|
302
|
+
const weigh_resources = new ShaderResourceSetDescriptor();
|
|
303
|
+
weigh_resources.createGroup()
|
|
304
|
+
.addStorageBuffer('next', WATER_PARTICLE_ARRAY_STRUCT)
|
|
305
|
+
.addStorageBuffer('activity', WebGPUArray.u32)
|
|
306
|
+
.addStorageBuffer('offsets', COLLECTION_U32_STRUCT_READ)
|
|
307
|
+
.addStorageBuffer('bucket_weight', WebGPUArray.from(atomic_u32), true);
|
|
308
|
+
|
|
309
|
+
/**
|
|
310
|
+
* Each particle of a body simulated this frame adds its steepness to every cell its support overlaps: how crowded a
|
|
311
|
+
* cell is, for the bin pass to thin it by.
|
|
312
|
+
*/
|
|
313
|
+
export const shader_water_particles_weigh = ComputeShader.from({ label: 'Water / particles weigh', resources: weigh_resources,
|
|
314
|
+
body: CodeChunk.from(/* language=WGSL */ `
|
|
315
|
+
@compute @workgroup_size(64)
|
|
316
|
+
fn main(@builtin(workgroup_id) group: vec3u, @builtin(local_invocation_index) lane: u32) {
|
|
317
|
+
let i = folded_workgroup_index(group) * 64u + lane;
|
|
318
|
+
if (i >= next.count) { return; }
|
|
319
|
+
let particle = next.elements[i];
|
|
320
|
+
if ((activity[particle.body] & ${WaterActivity.Active}u) == 0u) { return; }
|
|
321
|
+
let cells = water_particle_cells(particle, i);
|
|
322
|
+
let weight = water_particle_weight(particle);
|
|
323
|
+
for (var corner = 0u; corner < ${WATER_PARTICLE_CORNERS}u; corner++) {
|
|
324
|
+
if (!water_particle_has_corner(cells, corner)) { continue; }
|
|
325
|
+
atomicAdd(&bucket_weight[water_particle_bucket(particle.body, cells.level, water_particle_corner_cell(cells, corner), offsets.count)], weight);
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
`, [chunk_water_particle_cells, chunk_folded_workgroup_index]) });
|
|
329
|
+
|
|
330
|
+
const bin_resources = new ShaderResourceSetDescriptor();
|
|
331
|
+
bin_resources.createGroup()
|
|
332
|
+
.addStorageBuffer('next', WATER_PARTICLE_ARRAY_STRUCT)
|
|
333
|
+
.addStorageBuffer('activity', WebGPUArray.u32)
|
|
334
|
+
.addStorageBuffer('buckets', WATER_PARTICLE_BUCKETS_STRUCT, true)
|
|
335
|
+
.addStorageBuffer('slots', WebGPUArray.u32, true)
|
|
336
|
+
.addStorageBuffer('bucket_amplitude', WebGPUArray.from(atomic_u32), true)
|
|
337
|
+
.addStorageBuffer('body_bounds', WebGPUArray.from(atomic_u32), true)
|
|
338
|
+
.addStorageBuffer('bucket_weight', WebGPUArray.u32)
|
|
339
|
+
.addStorageBuffer('visible', WebGPUArray.from(f32), true);
|
|
340
|
+
|
|
341
|
+
/**
|
|
342
|
+
* Enter each particle of a body simulated this frame in every hash cell its support overlaps: count it into the cell's
|
|
343
|
+
* bucket, keep its slot there, raise the bucket's largest |a| to its own, and mark its level on its body. One atomic
|
|
344
|
+
* each: no compare-exchange loop a crowded bucket would serialize. A paused body's particles take no slot: nothing
|
|
345
|
+
* draws them this frame.
|
|
346
|
+
*
|
|
347
|
+
* Where cells are crowded (the weigh pass), a particle is drawn by how much its most crowded cell leaves it
|
|
348
|
+
* ({@link WATER_PARTICLE_CELL_SHARE}): one decision for all its cells, so the surface stays continuous across them, and
|
|
349
|
+
* from its own lot, so it does not change with the order particles arrive in. One left out takes no slot.
|
|
350
|
+
*/
|
|
351
|
+
export const shader_water_particles_bin = ComputeShader.from({ label: 'Water / particles bin', resources: bin_resources,
|
|
352
|
+
body: CodeChunk.from(/* language=WGSL */ `
|
|
353
|
+
@compute @workgroup_size(64)
|
|
354
|
+
fn main(@builtin(workgroup_id) group: vec3u, @builtin(local_invocation_index) lane: u32) {
|
|
355
|
+
let i = folded_workgroup_index(group) * 64u + lane;
|
|
356
|
+
if (i >= next.count) { return; }
|
|
357
|
+
let particle = next.elements[i];
|
|
358
|
+
if ((activity[particle.body] & ${WaterActivity.Active}u) == 0u) {
|
|
359
|
+
for (var corner = 0u; corner < ${WATER_PARTICLE_CORNERS}u; corner++) { slots[i * ${WATER_PARTICLE_CORNERS}u + corner] = ~0u; }
|
|
360
|
+
return;
|
|
361
|
+
}
|
|
362
|
+
let cells = water_particle_cells(particle, i);
|
|
363
|
+
let weight = f32(water_particle_weight(particle));
|
|
364
|
+
var share = 1e30;
|
|
365
|
+
for (var corner = 0u; corner < ${WATER_PARTICLE_CORNERS}u; corner++) {
|
|
366
|
+
if (!water_particle_has_corner(cells, corner)) { continue; }
|
|
367
|
+
let total = f32(bucket_weight[water_particle_bucket(particle.body, cells.level, water_particle_corner_cell(cells, corner), buckets.count)]);
|
|
368
|
+
if (total > 0.0) { share = min(share, ${WATER_PARTICLE_CELL_SHARE}.0 * weight / total); }
|
|
369
|
+
}
|
|
370
|
+
let visibility = water_particle_visibility(share, water_particle_lot(particle));
|
|
371
|
+
visible[i] = visibility;
|
|
372
|
+
if (!(visibility > 0.0)) {
|
|
373
|
+
for (var corner = 0u; corner < ${WATER_PARTICLE_CORNERS}u; corner++) { slots[i * ${WATER_PARTICLE_CORNERS}u + corner] = ~0u; }
|
|
374
|
+
return;
|
|
375
|
+
}
|
|
376
|
+
atomicOr(&body_bounds[particle.body * ${STRIDE}u], 1u << cells.level);
|
|
377
|
+
for (var corner = 0u; corner < ${WATER_PARTICLE_CORNERS}u; corner++) {
|
|
378
|
+
var slot = ~0u;
|
|
379
|
+
if (water_particle_has_corner(cells, corner)) {
|
|
380
|
+
let bucket = water_particle_bucket(particle.body, cells.level, water_particle_corner_cell(cells, corner), buckets.count);
|
|
381
|
+
slot = atomicAdd(&buckets.elements[bucket], 1u);
|
|
382
|
+
// non-negative floats order as their bits do
|
|
383
|
+
atomicMax(&bucket_amplitude[bucket], bitcast<u32>(abs(particle.amplitude) * visibility));
|
|
384
|
+
}
|
|
385
|
+
slots[i * ${WATER_PARTICLE_CORNERS}u + corner] = slot;
|
|
386
|
+
}
|
|
387
|
+
}
|
|
388
|
+
`, [chunk_water_particle_cells, chunk_folded_workgroup_index]) });
|
|
389
|
+
|
|
390
|
+
const scatter_resources = new ShaderResourceSetDescriptor();
|
|
391
|
+
scatter_resources.createGroup()
|
|
392
|
+
.addStorageBuffer('next', WATER_PARTICLE_ARRAY_STRUCT)
|
|
393
|
+
.addStorageBuffer('offsets', COLLECTION_U32_STRUCT_READ)
|
|
394
|
+
.addStorageBuffer('slots', WebGPUArray.u32)
|
|
395
|
+
.addStorageBuffer('visible', WebGPUArray.from(f32))
|
|
396
|
+
.addStorageBuffer('staging', WebGPUArray.from(WATER_PARTICLE_ENTRY_STRUCT), true);
|
|
397
|
+
|
|
398
|
+
/** Each entry to its bucket's range, in arrival order, at the height its crowd leaves it; the rank pass orders it. */
|
|
399
|
+
export const shader_water_particles_scatter = ComputeShader.from({ label: 'Water / particles scatter', resources: scatter_resources,
|
|
400
|
+
body: CodeChunk.from(/* language=WGSL */ `
|
|
401
|
+
@compute @workgroup_size(64)
|
|
402
|
+
fn main(@builtin(workgroup_id) group: vec3u, @builtin(local_invocation_index) lane: u32) {
|
|
403
|
+
let i = folded_workgroup_index(group) * 64u + lane;
|
|
404
|
+
if (i >= next.count) { return; }
|
|
405
|
+
let particle = next.elements[i];
|
|
406
|
+
let cells = water_particle_cells(particle, i);
|
|
407
|
+
for (var corner = 0u; corner < ${WATER_PARTICLE_CORNERS}u; corner++) {
|
|
408
|
+
let slot = slots[i * ${WATER_PARTICLE_CORNERS}u + corner];
|
|
409
|
+
if (slot == ~0u) { continue; }
|
|
410
|
+
let cell = water_particle_corner_cell(cells, corner);
|
|
411
|
+
let bucket = water_particle_bucket(particle.body, cells.level, cell, offsets.count);
|
|
412
|
+
var start = 0u;
|
|
413
|
+
if (bucket > 0u) { start = offsets.elements[bucket - 1u]; }
|
|
414
|
+
var entry = cells.entry;
|
|
415
|
+
entry.cell = cell;
|
|
416
|
+
entry.amplitude *= visible[i];
|
|
417
|
+
staging[start + slot] = entry;
|
|
418
|
+
}
|
|
419
|
+
}
|
|
420
|
+
`, [chunk_water_particle_cells, chunk_folded_workgroup_index]) });
|
|
421
|
+
|
|
422
|
+
const rank_resources = new ShaderResourceSetDescriptor();
|
|
423
|
+
rank_resources.createGroup()
|
|
424
|
+
.addStorageBuffer('next', WATER_PARTICLE_ARRAY_STRUCT)
|
|
425
|
+
.addStorageBuffer('offsets', COLLECTION_U32_STRUCT_READ)
|
|
426
|
+
.addStorageBuffer('slots', WebGPUArray.u32)
|
|
427
|
+
.addStorageBuffer('staging', WebGPUArray.from(WATER_PARTICLE_ENTRY_STRUCT))
|
|
428
|
+
.addStorageBuffer('entries', WebGPUArray.from(WATER_PARTICLE_ENTRY_STRUCT), true);
|
|
429
|
+
|
|
430
|
+
/**
|
|
431
|
+
* Order every bucket by particle index then cell, so a gather that runs out of budget drops the same
|
|
432
|
+
* entries every frame (the particle array keeps its order from frame to frame). A bucket of more than
|
|
433
|
+
* ${WATER_PARTICLE_RANK_LIMIT} keeps its arrival order: a fixed budget of comparisons per entry.
|
|
434
|
+
*/
|
|
435
|
+
export const shader_water_particles_rank = ComputeShader.from({ label: 'Water / particles rank', resources: rank_resources,
|
|
436
|
+
body: CodeChunk.from(/* language=WGSL */ `
|
|
437
|
+
fn water_entry_before(a: ${WATER_PARTICLE_ENTRY_STRUCT.wgsl_ref}, b: ${WATER_PARTICLE_ENTRY_STRUCT.wgsl_ref}) -> bool {
|
|
438
|
+
if (a.source != b.source) { return a.source < b.source; }
|
|
439
|
+
if (a.cell.x != b.cell.x) { return a.cell.x < b.cell.x; }
|
|
440
|
+
return a.cell.y < b.cell.y;
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
@compute @workgroup_size(64)
|
|
444
|
+
fn main(@builtin(workgroup_id) group: vec3u, @builtin(local_invocation_index) lane: u32) {
|
|
445
|
+
let i = folded_workgroup_index(group) * 64u + lane;
|
|
446
|
+
if (i >= next.count) { return; }
|
|
447
|
+
let particle = next.elements[i];
|
|
448
|
+
let cells = water_particle_cells(particle, i);
|
|
449
|
+
for (var corner = 0u; corner < ${WATER_PARTICLE_CORNERS}u; corner++) {
|
|
450
|
+
let slot = slots[i * ${WATER_PARTICLE_CORNERS}u + corner];
|
|
451
|
+
if (slot == ~0u) { continue; }
|
|
452
|
+
let bucket = water_particle_bucket(particle.body, cells.level, water_particle_corner_cell(cells, corner), offsets.count);
|
|
453
|
+
var start = 0u;
|
|
454
|
+
if (bucket > 0u) { start = offsets.elements[bucket - 1u]; }
|
|
455
|
+
let end = offsets.elements[bucket];
|
|
456
|
+
let entry = staging[start + slot];
|
|
457
|
+
var rank = slot;
|
|
458
|
+
if (end - start <= ${WATER_PARTICLE_RANK_LIMIT}u) {
|
|
459
|
+
rank = 0u;
|
|
460
|
+
for (var j = start; j < end; j++) { rank += select(0u, 1u, water_entry_before(staging[j], entry)); }
|
|
461
|
+
}
|
|
462
|
+
entries[start + rank] = entry;
|
|
463
|
+
}
|
|
464
|
+
}
|
|
465
|
+
`, [chunk_water_particle_cells, chunk_folded_workgroup_index]) });
|
|
466
|
+
|
|
467
|
+
const bounds_resources = new ShaderResourceSetDescriptor();
|
|
468
|
+
bounds_resources.createGroup()
|
|
469
|
+
.addStorageBuffer('next', WATER_PARTICLE_ARRAY_STRUCT)
|
|
470
|
+
.addStorageBuffer('activity', WebGPUArray.u32)
|
|
471
|
+
.addStorageBuffer('offsets', COLLECTION_U32_STRUCT_READ)
|
|
472
|
+
.addStorageBuffer('bucket_amplitude', WebGPUArray.u32)
|
|
473
|
+
.addStorageBuffer('body_bounds', WebGPUArray.from(atomic_u32), true);
|
|
474
|
+
|
|
475
|
+
/**
|
|
476
|
+
* Each body's bound per level: the largest of count × max |a| over the buckets its particles are in, which is
|
|
477
|
+
* at least the bucket's Σ|a|. Every particle that reaches a point is in that point's cell's bucket, and neither
|
|
478
|
+
* its height nor its horizontal displacement exceeds |a|, so the bound holds everywhere; a hash collision only
|
|
479
|
+
* adds to it.
|
|
480
|
+
*/
|
|
481
|
+
export const shader_water_particles_bounds = ComputeShader.from({ label: 'Water / particles bounds', resources: bounds_resources,
|
|
482
|
+
body: CodeChunk.from(/* language=WGSL */ `
|
|
483
|
+
@compute @workgroup_size(64)
|
|
484
|
+
fn main(@builtin(workgroup_id) group: vec3u, @builtin(local_invocation_index) lane: u32) {
|
|
485
|
+
let i = folded_workgroup_index(group) * 64u + lane;
|
|
486
|
+
if (i >= next.count) { return; }
|
|
487
|
+
let particle = next.elements[i];
|
|
488
|
+
// a paused body keeps the bounds its particles last had
|
|
489
|
+
if ((activity[particle.body] & ${WaterActivity.Active}u) == 0u) { return; }
|
|
490
|
+
let cells = water_particle_cells(particle, i);
|
|
491
|
+
var largest = 0.0;
|
|
492
|
+
for (var corner = 0u; corner < ${WATER_PARTICLE_CORNERS}u; corner++) {
|
|
493
|
+
if (!water_particle_has_corner(cells, corner)) { continue; }
|
|
494
|
+
let bucket = water_particle_bucket(particle.body, cells.level, water_particle_corner_cell(cells, corner), offsets.count);
|
|
495
|
+
var start = 0u;
|
|
496
|
+
if (bucket > 0u) { start = offsets.elements[bucket - 1u]; }
|
|
497
|
+
largest = max(largest, f32(offsets.elements[bucket] - start) * bitcast<f32>(bucket_amplitude[bucket]));
|
|
498
|
+
}
|
|
499
|
+
// non-negative floats order as their bits do
|
|
500
|
+
atomicMax(&body_bounds[particle.body * ${STRIDE}u + 1u + cells.level], bitcast<u32>(largest));
|
|
501
|
+
}
|
|
502
|
+
`, [chunk_water_particle_cells, chunk_folded_workgroup_index]) });
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/** Workgroup size of the culling pass and of the passes over its lists. */
|
|
2
|
+
export const WATER_CULL_WORKGROUP_SIZE: 64;
|
|
3
|
+
/** Bits of a wave row's activity word. */
|
|
4
|
+
export const WaterActivity: Readonly<{
|
|
5
|
+
/** Its displaced surface may meet the frame's view. */
|
|
6
|
+
Visible: 1;
|
|
7
|
+
/** It is simulated this frame: visible, or simulated while hidden. */
|
|
8
|
+
Active: 2;
|
|
9
|
+
}>;
|
|
10
|
+
/** What the culling pass is told about the frame. */
|
|
11
|
+
export const WATER_CULL_STRUCT: WebGPUStruct;
|
|
12
|
+
/** A list the culling pass appends rows to. */
|
|
13
|
+
export const WATER_LIST_APPEND_STRUCT: WebGPUStruct;
|
|
14
|
+
/** Bytes of a list's header: its count, padded to its elements' alignment. */
|
|
15
|
+
export const WATER_LIST_HEADER_BYTES: 16;
|
|
16
|
+
/**
|
|
17
|
+
* The frame's culling pass (WATER_SURFACE_DISTANCE_LOD_PROPOSAL_2026_10_06.md §3.1), one thread a water body, before
|
|
18
|
+
* anything simulates. Against the frustum of the view the frame is recorded for, with a prior bound on the body's
|
|
19
|
+
* displacement, it decides whether the body is visible and whether it is simulated this frame, and lists it for the
|
|
20
|
+
* passes that follow. On the way it does the per-body work that used to be passes of its own over every row: weights
|
|
21
|
+
* when the wind or the fetch changed, the wind's turn for a body that is simulated, optics when they were edited.
|
|
22
|
+
* A visible body ORs the bands it can draw into the frame's band mask.
|
|
23
|
+
*/
|
|
24
|
+
export const shader_water_cull: ComputeShader;
|
|
25
|
+
/** Commands the finalize pass writes, in order, 16 bytes apart. */
|
|
26
|
+
export const WaterSurfaceCommand: Readonly<{
|
|
27
|
+
SpectrumRows: 0;
|
|
28
|
+
SpectrumColumns: 1;
|
|
29
|
+
Active: 2;
|
|
30
|
+
Emit: 3;
|
|
31
|
+
}>;
|
|
32
|
+
export const WATER_SURFACE_COMMAND_STRIDE: 16;
|
|
33
|
+
export const WATER_SURFACE_COMMAND_COUNT: 4;
|
|
34
|
+
/**
|
|
35
|
+
* After the culling pass: which bands this frame's spectrum evaluates — those the visible bodies can draw that do not
|
|
36
|
+
* already hold this time (all of them once, when a device's envelopes are seeded) — and the indirect commands for the
|
|
37
|
+
* spectrum and for the passes over the active and emit lists. Commands sit 16 bytes apart.
|
|
38
|
+
*/
|
|
39
|
+
export const shader_water_cull_finalize: ComputeShader;
|
|
40
|
+
import { WebGPUStruct } from "../../shader/type/WebGPUStruct.js";
|
|
41
|
+
import { ComputeShader } from "../../shader/ComputeShader.js";
|
|
42
|
+
//# sourceMappingURL=shader_water_cull.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"shader_water_cull.d.ts","sourceRoot":"","sources":["../../../../../../src/shade/renderer/water/surface/shader_water_cull.js"],"names":[],"mappings":"AAoCA,2EAA2E;AAC3E,2CAA4C;AAE5C,0CAA0C;AAC1C;IACI,uDAAuD;;IAEvD,sEAAsE;;GAEvE;AAEH,qDAAqD;AACrD,6CAOuB;AAEvB,+CAA+C;AAC/C,oDAGE;AAEF,8EAA8E;AAC9E,yCAA0C;AA6C1C;;;;;;;GAOG;AACH,8CAsGiG;AAEjG,mEAAmE;AACnE;;;;;GAKG;AACH,8CAA+C;AAC/C,4CAA6C;AAW7C;;;;GAIG;AACH,uDAuBM;6BA9PuB,mCAAmC;8BAVlC,+BAA+B"}
|