Salva实战:如何搭配Rapier用一段代码打造可交互的流体水箱
Salva实战如何搭配Rapier用一段代码打造可交互的流体水箱【免费下载链接】salva2 and 3-dimensional fluid simulation library in Rust.项目地址: https://gitcode.com/gh_mirrors/sa/salvaSalva 是一款用 Rust 编写的 2D/3D 粒子流体模拟库基于 SPH 方法可与 Rapier 物理引擎双向耦合。本文带你用不到 60 行代码搭建一个可以扔东西进去、水会泼溅的可交互流体水箱并讲清楚粒子半径、平滑因子、黏度等关键参数的调优技巧适合想在游戏或动画中加入真实流体效果的新手。为什么选 Salva RapierSalva的核心能力压力求解DFSPH 与 IISPH 两种 SPH 压力解法黏度DFSPH 黏度、人工黏度、XSPH 黏度表面张力WCSPH、He et al. 2014、Akinci et al. 2013 三种方法弹性Becker et al. 2009 弹性体模型多相流体混合不同密度/黏度的流体WASM 支持官方示例全部跑在浏览器里而Rapier负责刚体、碰撞与交互。Salva 通过ColliderCouplingSet把 Rapier 的碰撞体采样成边界粒子实现真正的双向耦合——水会推动浮块浮块也会挤压水。核心实现位于 src/integrations/rapier/fluids_pipeline.rs。一键安装与运行示例仓库中examples2d/与examples3d/目录提供了完整可玩的 Demogit clone https://gitcode.com/gh_mirrors/sa/salva cd salva cargo run --release --manifest-path examples3d/Cargo.toml --bin basic3运行后你会看到一个 3D 水箱水块落入盒中可以按键盘抓取刚体、拨动水面。2D 版本运行examples2d/Cargo.toml中的basic2即可。⚡ 提示工作区默认开启了opt-level 1流体模拟对性能敏感演示时建议始终加--release编译。一段代码搭建可交互流体水箱下面基于 examples3d/basic3.rs 提炼出最核心的五步其余都是样板代码。第 1 步创建流体管线。FluidsPipeline是 Salva 对外的总入口两个参数分别控制粒子半径和 SPH 核函数半径核半径 粒子半径 × 平滑因子 × 2let mut fluids_pipeline FluidsPipeline::new(PARTICLE_RADIUS /* 0.05 */, SMOOTHING_FACTOR /* 2.0 */);第 2 步生成流体。Fluid::new接收一组粒子位置、粒子半径、密度再挂上非压力力如人工黏度let mut fluid helper::cube_fluid(15, 15, 15, PARTICLE_RADIUS, 1000.0); fluid.nonpressure_forces.push(Box::new(ArtificialViscosity::new(1.0, 0.0))); let fluid_handle fluids_pipeline.liquid_world.add_fluid(fluid);cube_fluid只是按网格排布 15×15×15 个粒子完整实现见 examples3d/helper.rs。第 3 步创建容器。水箱底部和四壁都是 Rapier 的静态碰撞体cuboid 刚体 SharedShape::cuboid。第 4 步注册耦合。关键一步——用shape_surface_ray_sample在碰撞体表面采样出边界粒子再调用register_coupling把碰撞体 ↔ 边界绑定起来let samples shape_surface_ray_sample(*wall_shape, PARTICLE_RADIUS).unwrap(); let bo_handle fluids_pipeline.liquid_world .add_boundary(Boundary::new(Vec::new(), InteractionGroups::default())); fluids_pipeline.coupling.register_coupling( bo_handle, co_handle, ColliderSampling::StaticSampling(samples), );采样算法位于 src/sampling/ray_sampling.rs。静态碰撞体用StaticSampling采样一次即可动态刚体建议用DynamicContactSampling按接触点动态生成边界粒子参考 examples2d/basic2.rs 中浮块的做法。第 5 步挂载插件并设置时间步。把管线交给测试床插件每帧自动完成流体推进与渲染let mut plugin FluidsTestbedPlugin::new(); plugin.set_pipeline(fluids_pipeline); plugin.set_fluid_color(fluid_handle, Point3::new(0.8, 0.7, 1.0)); testbed.add_plugin(plugin); testbed.integration_parameters_mut().dt 1.0 / 200.0;渲染插件支持三种模式纯色、按速度着色、速度箭头源码见 src/integrations/rapier/testbed_plugin.rs。关键 API 速查表用途类型/函数所在模块流体世界LiquidWorld/add_fluidsrc/liquid_world.rs粒子流体Fluid::new(点集, 半径, 密度)src/object/fluid.rs边界容器Boundary::newregister_couplingsrc/object/boundary.rs表面采样shape_surface_ray_samplesrc/sampling/ray_sampling.rsRapier 插件FluidsTestbedPlugin/FluidsHarnessPluginsrc/integrations/rapier/压力求解器DFSPH / IISPHsrc/solver/pressure/黏度与表面张力XSPH / WCSPH / Akinci2013src/solver/viscosity/、src/solver/surface_tension/流体水箱调参指南粒子半径PARTICLE_RADIUS越小越细腻但越慢。3D 示例用0.05想要更精细可参考 examples3d/faucet3.rs 的0.025/2.0。平滑因子SMOOTHING_FACTOR一般保持2.0控制邻居粒子的影响范围。时间步dt示例统一为1/200秒显式 SPH 步长过大容易爆炸粒子乱飞。黏度系数ArtificialViscosity::new(mu, sigma)的mu越大水流越黏稠想要清亮的水花可以调低或改用 XSPH。密度cube_fluid传入的1000.0即水密度kg/m³多相流体就是给不同Fluid传不同值。性能examples3d的parallelfeature 可开启 rayon 并行见 examples3d/Cargo.toml。下一步把水放进来想让水箱持续进水而不是倒一坨水块看 examples3d/faucet3.rs 的水龙头示例通过plugin.add_callback注册每帧回调每 0.06 秒add_particles一批新粒子同时删除y -2.0的粒子防止内存无限增长。再搭配XSPHViscosityAkinci2013SurfaceTension就能得到带表面张力的水柱。其他值得运行的 Demoelasticity3弹性体入水、surface_tension3表面张力、heightfield3地形高度场都在 examples3d/ 目录下2D 版本同理见 examples2d/。祝调参愉快【免费下载链接】salva2 and 3-dimensional fluid simulation library in Rust.项目地址: https://gitcode.com/gh_mirrors/sa/salva创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考