【splishsplash】PBDWrapper分析

控制流

init

从mian.cpp开始

Simulator\main.cpp
在这里插入图片描述

到getPBDWrapper是返回PBDWrapper的指针。

Simulator\PositionBasedDynamicsWrapper\PBDBoundarySimulator.h
在这里插入图片描述
这符合对象组合传递数据的模式,类似于责任链模式

让我们回到main.cpp

于是gui指针得到了PBD_Simulator_GUI_imgui类的对象。
这个对象里面包含m_pbdWrapper指针,也就是PBDWrapper的对象。

based->setGui只不过把gui指针传递给SimulatorBase的对象内部的指针m_gui而已。

来到SimulatorBase::run()
在这里插入图片描述
initSimulation中
在这里插入图片描述

初始化了boundarySimulator

让我们跳转到 Simulator\BoundarySimulator.h
在这里插入图片描述

发现除了
updateBoundaryForces()是被定义了的。其余的都是虚函数。定义推迟到子类。

因此这个类的意义就是一个接口。

那么真正实现它功能的子类是:
Simulator\PositionBasedDynamicsWrapper\PBDBoundarySimulator.h
在这里插入图片描述

它的init函数无非是ScenceLoader
在这里插入图片描述

run

让我们跳回最开始的SimulatorBase::run()
在这里插入图片描述

下一个就是runSimulation()

这个函数也没什么可说的,直接跳到其中的
在这里插入图片描述
即可
这次会跳转到Simulator_GUI_Base类下面的run

Simulator\GUI\Simulator_GUI_Base.h
在这里插入图片描述
同样的,这只是个接口类。

真正起作用的是
Simulator\GUI\imgui\Simulator_GUI_imgui.h

跳到run

在这里插入图片描述

跳到MiniGL的mainLoop

GUI\OpenGL\MiniGL.cpp
在这里插入图片描述
其中idleFunc是timeStep函数
它通过setClientIdleFunc来设定函数指针
在这里插入图片描述
它是在
Simulator\GUI\imgui\Simulator_GUI_imgui.cpp
中绑定的函数指针
在这里插入图片描述
所以idleFunc就是SimulatorBase::timeStep

timeStep

于是跳转到
Simulator\SimulatorBase.cpp
在这里插入图片描述
看图中的倒数第二行
在这里插入图片描述

这就是PBD的timeStep被调用的地方。

跳转到
Simulator\BoundarySimulator.h
在这里插入图片描述
这就是刚才那个边界类的接口。具体的实现在它的子类
Simulator\PositionBasedDynamicsWrapper\PBDBoundarySimulator.h
在这里插入图片描述

看这个实现类中的timeStep函数
在这里插入图片描述
他做了两件事:

  1. 调用子对象m_pbdWrapper中的timeStep
  2. 根据不同的BoundaryHandling方法选择不同的update方式。

rb指针:刚体对象

我们先来看第一件事
跳转到子对象的类PBDWrapper
Simulator\PositionBasedDynamicsWrapper\PBDWrapper.h
在这里插入图片描述

在这里插入图片描述

跳转到其timeStep方法
在这里插入图片描述
这里面两个对象指针:
pd是ParticleData
rb是rigidBody

我们其实现在就已经了解了如何控制刚体了
通过

PBD::SimulationModel::RigidBodyVector &rb = m_model.getRigidBodies();

这个语句有点复杂,我们解释一下:

前面的PBD::SimulationModel::RigidBodyVector是它的类型
其中
在这里插入图片描述
是build\extern\install\PositionBasedDynamics\include\Simulation\SimulationModel.h
中的一个指针数组。

后面的getRigidBodies是SimulationModel类的一个方法。
同样位于
build\extern\PositionBasedDynamics\src\Ext_PBD\Simulation\SimulationModel.cpp

他们都是第三方的库的类。
在这里插入图片描述

如何知晓外界PBD库的?

注意!PBD::SimulationModel这个类是外界的PBD库。
那么编译器是怎么找到这个外界类的呢?

这就是CMake配置的问题了。
首先必定是#include了响应的头文件
头文件为
在这里插入图片描述
那么,CMake是怎么知道这个Simulation是PBD外界库的Simulation类而非Splishsplash内部的类呢?

这就让我们来到
Simulator\CMakeLists.txt

在这里插入图片描述
先设定一个变量SIMULATION_LINK_LIBRARIES,保存所有链接的对象。
同时设定SIMULATION_DEPENDENCIES

然后将SimulatorBase添加为一个目标,编译成静态库
在这里插入图片描述
然后把SIMULATION_LINK_LIBRARIES
链接到目标的静态库SimulatorBase上面。

其中add_dependencies这个命令的作用只是让SIMULATION_DEPENDENCIES先编译,从而保证链接库的时候,依赖项是存在的。

在这里插入图片描述

最后增加一个可执行目标,即SPHSimulator。我们所有的程序都是从这个目标开始的。
在这里插入图片描述
回归我们的原问题:include的时候怎么知道这个Simulation类是PBD的?

我们要搜索PBD_includes
在这里插入图片描述

跳转到 CMake\SetUpExternalProjects.cmake

发现最后一句是target_include_directories
在这里插入图片描述

这就是直接include到Simulation的秘密:

因为编译SimulartorBase静态库的时候,是和splishsplash这个目标(也是个静态库)互不干涉的。

TimeStepController::step

让我们回到PBDWrapper类
发现m_timeStep指针指向TimeStepController对象

在这里插入图片描述

这个类位于
build\extern\PositionBasedDynamics\src\Ext_PBD\Simulation\TimeStepController.h
在这里插入图片描述
于是step就是跳转到
在这里插入图片描述

在这里插入图片描述

注意看下面的positionConstraintProjection(model);

这个就是约束投影

因此这个就是PBD的模拟实现。
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值