基于粒子的流体模拟

1、基于粒子的流体模拟

案例位置examples/Cuda/Tutorials/GL_ParticleFluid

功能介绍:该案例主要用于测试基于粒子的流体仿真功能。案例展示了 ParticleFluid 类的的基本使用。SPH方法将连续的流体用相互作用的粒子来描述,各个粒子上承载各种物理量,包括质量、速度和压强等。通过求解粒子的动力学方程,并跟踪每个粒子的运动轨迹,求得整个系统的力学行为。理论上,只要粒子的数量足够多的,就能精确地描述力学过程。

案例说明:案例中展示了流体粒子落入碗中后飞溅出来的效果。在仿真过程中给每个粒子速度赋予了颜色属性。

2、程序实现

接下来介绍案例的实现过程:

  • 创建场景图:
	std::shared_ptr<SceneGraph> scn = std::make_shared<SceneGraph>();
  • 创建仿真边界以及粒子流体节点,这里的边界是一个静态的碗模型:
 	auto boundary = scn->addNode(std::make_shared<StaticBoundary<DataType3f>>()); ;
	boundary->loadCube(Vec3f(-0.5, 0, -0.5), Vec3f(1.5, 2, 1.5), 0.02, true);
	boundary->loadSDF("../../data/bowl/bowl.sdf", false);

    auto fluid = scn->addNode(std::make_shared<ParticleFluid<DataType3f>>());
	fluid->loadParticles(Vec3f(0.5, 0.2, 0.4), Vec3f(0.7, 1.5, 0.6), 0.005);
	fluid->connect(boundary->importParticleSystems());
  • 计算法线:
    auto calculateNorm = std::make_shared<CalculateNorm<DataType3f>>();
	fluid->stateVelocity()->connect(calculateNorm->inVec());
	fluid->graphicsPipeline()->pushModule(calculateNorm);
  • 创建渲染节点:
	auto colorMapper = std::make_shared<ColorMapping<DataType3f>>();
	colorMapper->varMax()->setValue(5.0f);
	calculateNorm->outNorm()->connect(colorMapper->inScalar());
	fluid->graphicsPipeline()->pushModule(colorMapper);

	auto ptRender = std::make_shared<GLPointVisualModule>();
	ptRender->setColor(Vec3f(1, 0, 0));
	ptRender->setColorMapMode(GLPointVisualModule::PER_VERTEX_SHADER);
	ptRender->setColorMapRange(0, 5);

	fluid->currentTopology()->connect(ptRender->inPointSet());
	colorMapper->outColor()->connect(ptRender->inColor());

	fluid->graphicsPipeline()->pushModule(ptRender);

  • 创建一个colorBar,在显示的时候,会将不同速度的粒子渲染成不同的颜色:
// A simple color bar widget for node
	auto colorBar = std::make_shared<ImColorbar>();
	colorBar->varMax()->setValue(5.0f);
	calculateNorm->outNorm()->connect(colorBar->inScalar());
	// add the widget to app
	fluid->graphicsPipeline()->pushModule(colorBar);