【splishsplash】PBD探究

上次我们探究了PBD是如何引入plishsplash的,以及其控制流。

https://blog.csdn.net/weixin_43940314/article/details/127569870

这次我们来讲如何在自己新建的类中控制PBD刚体。

上回说到
Simulator\PositionBasedDynamicsWrapper\PBDWrapper.cpp
中的
void PBDWrapper::timeStep()
函数是控制PBD的关键。

在这里插入图片描述

PBD刚体对象的指针为
PBD::SimulationModel::RigidBodyVector &rb = m_model.getRigidBodies();

于是我们操作rb指针即可。

我们首先要看看rb对象能干什么
点开rb[i]->getVelocity()函数,跳转到

build\extern\install\PositionBasedDynamics\include\Simulation\RigidBody.h
在这里插入图片描述
这个函数里面的所有public方法就是可操作的。

其中我们比较关注的当然是setPosition

在这里插入图片描述
于是我们测试一下是否可以让刚体在我们点击的时候移动到我们点击的位置

获取点击位置

这一点我已经在下面的博文中说明了
https://chunleili.github.io/SPlisHSPlaSH/get_mouse

但是这还不是完整的。因为获取位置之后,我们不能单纯打印位置,而是应该将其传递给我们所需要的对象。因此我们新建一个类,叫做Interactive。让其获取鼠标位置。

对象和对象的数据传递方法请看
https://chunleili.github.io/cpp/data_transfer_OOP

这里我们采用单例模式的方法。

简单回顾下,就是在Simulator\GUI\imgui\Simulator_GUI_imgui.cpp之中

  1. 增加头文件,就是我们新建的类
    在这里插入图片描述

  2. 在selection函数当中的最后一行,给interactive传递数据并调用它进行操作。
    在这里插入图片描述
    其中,get_inter是个单例静态函数

在这里插入图片描述

获取刚体位置

对应代码在
Simulator\PositionBasedDynamicsWrapper\PBDWrapper.cpp
在这里插入图片描述
运行结果:
按空格运行之后打印
在这里插入图片描述
可以发现y坐标确实是下降的

控制刚体位置

将刚体位置指针传递给Interactive

我们要做的首先是将刚体位置的指针传递给Interactive,并打印该位置和地址以确定获取正确。

仍然在 Simulator\PositionBasedDynamicsWrapper\PBDWrapper.cpp 中

调用Interactive类的我们自己写的新的方法
在这里插入图片描述

SPlisHSPlasH\My\Interactive\Interactive.h
在这里插入图片描述
打印结果

在这里插入图片描述

发现地址是正确的,因此我们已经获取了刚体位置指针。

控制物体位置

Simulator\PositionBasedDynamicsWrapper\PBDWrapper.cpp

 void PBDWrapper::timeStep()
 {
	PBD::ParticleData &pd = m_model.getParticles();
	PBD::SimulationModel::RigidBodyVector &rb = m_model.getRigidBodies();
	PBD::TimeManager::getCurrent()->setTimeStepSize(SPH::TimeManager::getCurrent()->getTimeStepSize());
	PBD::TimeManager::getCurrent()->setTime(SPH::TimeManager::getCurrent()->getTime());

	m_timeStep->step(m_model);

	for (unsigned int i = 0; i < pd.size(); i++)
	{
		pd.getVelocity(i) *= (static_cast<Real>(1.0) - m_dampingCoeff);
	}
	for (unsigned int i = 0; i < rb.size(); i++)
	{
		rb[i]->getVelocity() *= (static_cast<Real>(1.0) - m_dampingCoeff);
		rb[i]->getAngularVelocity() *= (static_cast<Real>(1.0) - m_dampingCoeff);
	}

	//rb[0]是天空盒,所以rb[1]是第一个运动的刚体
	Vector3r & rb_pos = rb[1]->getPosition();

	Interactive::get_inter().set_rb_pos(rb_pos);
	
}

SPlisHSPlasH\My\Interactive\Interactive.h

#pragma once
#include "SPlisHSPlasH/Common.h"

//点击时获取鼠标位置
struct Interactive
{
    Vector3r mouse_pos;

    //a singleton method to get the object
    static Interactive& get_inter()
    {
        static Interactive inter;
        return inter;
    }
    
    void operation()
    {
        printf("mouse pos in Inter:(%.3f,\t%.3f,\t%.3f)\n", mouse_pos[0],mouse_pos[1],mouse_pos[2]);
    }

    //把mouse_pos从外界传递给Interactive内部
    void get_mouse_pos(const Vector3r& rhs)
    {
        mouse_pos[0] = rhs[0];
        mouse_pos[1] = rhs[1];
        mouse_pos[2] = rhs[2];
    }

    //获取刚体的控制权。
    void set_rb_pos(Vector3r& rb_pos)
    {
        (rb_pos) = mouse_pos; // 获取并设定位置
        
        std::cout<< "rb_pos: "<< (rb_pos)<<"\n";
    }
};

结果

在这里插入图片描述

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值