Bullet教程 Bullet大开发 第二章——对物体进行操作

Bullet教程 Bullet大开发 第二章——对物体进行操作

前言

光是只进行物体下落的模拟,那多没意思呀!这反而让我们觉得我们的“世界”还是一如既往的静态……现在是时候来实现对物体的操作,为世界增添一点活力吧!

使用MotionState对刚体进行变换操作(刚体运动)

要想实现对物体(也就是刚体)的移动,首先需要对刚体进行一些设置:

btRigidBody* body = ……;
body->setCollisionFlags(body->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT);
body->setActivationState(DISABLE_DEACTIVATION);

其实这两条语句我真的讲不出它们有什么意思(Bullet用户手册和API文档也没有讲清楚),但这并不是重点,你只需要知道对刚体对象进行这些设置后,刚体对象就无法进行自由运动。

由于刚体对象没法进行自由移动,这时就需要我们来操控刚体对象了。MotionState就是用于操控刚体对象进行移动的工具,它翻译过来就是“运动状态”。btMotionState有一个方法setWorldTransform用于设置btMotionState所属的刚体对象相对于世界坐标系的变换。
在下面代码示例中,我们让刚体对象随着时间的流逝而缓缓上升:

btRigidBody* body = ……;
btTransform trans;
trans.setIdentity();
trans.setOrigin(btVector3(0.0f, time, 0.0f));		// time是一个时间变量
body->getMotionState()->setWorldTransform(trans);

除了进行位移变换之外,我们还可以对刚体对象进行旋转变换。

要想进行旋转变换,这时候就需要我们接触一个新类了——btQuaternion。我们可以在对其进行构造的同时,对其进行设置:

btQuaternion quaternion = btQuaternion(btVector3(0.0f, 1.0f, 0.0f), 45.0f / 90.0f);

第一个参数表示要绕其旋转的轴;第二个参数为旋转的角度,1.0f表示90度。
除了在构造时进行设置外,我们还可以用方法setRotaton在构造函数外进行单独设置,其参数如上所示。需要注意的是,绕轴旋转的设置只以最后一次设置为基准,也就是说下面两条语句中只有第二句有效:

quaternion.setRotation(btVector3(0.0f, 1.0f, 0.0f), 35.0f / 90.0f);		// 无效
quaternion.setRotation(btVector3(1.0f, 0.0f, 0.0f), 60.0f / 90.0f);		// 有效

除了方法setRotation外,还有方法setEuler和方法setEulerZYX,具体内容请自行查找API文档。
当我们对btQuaternion类进行设置完之后,就需要在btTransform中设置一下了:

trans.setRotation(quaternion);

之后再在MotionState中设置一下,就可以看见刚体对象旋转了。

btTransform类还有一个很有用的方法——setFromOpenGLMatrix。这个方法用于将OpenGL的4x4矩阵(不一定是OpenGL)设置为btTransform的矩阵数据,该方法接受指向OpenGL矩阵数据的指针。通过这个方法,可以增强btTransform变换的灵活性。

当我们不再需要操控刚体对象,想要让其进行自由移动,我们该怎么办呢?答案就是将刚体对象的设置恢复为初始状态:

int defaultFlags = body->getCollisionFlags();		// 初始设置值
body->setCollisionFlags(body->getCollisionFlags() | btCollisionObject::CF_KINEMATIC_OBJECT);
body->setActivationState(DISABLE_DEACTIVATION);
/* 进行移动变换操作 */
// 恢复设置
body->setCollisionFlags(defaultFlags);
body->setActivationState(DISABLE_SIMULATION);

对刚体进行直接变换

对刚体的变换,实际上我们还可以使用刚体对象的一个方法——proceedToTransform。该方法只接受一个btTransform类作为参数。
与MotionState不同的是,方法proceedToTransform不能用于表示刚体的移动状态,即使强行使用proceedToTransform进行移动变换,结果会让你失望的。
但proceedToTransform有个优点就是在使用该方法前,不必对刚体对象进行奇怪的设置;并且在变换之后,刚体仍能进行自由移动。出于这个优点,我们可以使用这个方法来使刚体对象瞬移。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值