在其边缘旋转刚体?

Posted

技术标签:

【中文标题】在其边缘旋转刚体?【英文标题】:Rotate rigidBody on its edge? 【发布时间】:2015-08-28 22:17:29 【问题描述】:

我正在创建一个简单的游戏,该游戏涉及使用 c++ 中的子弹库来挥动球杆。但是,我无法按照我想要的方式旋转球杆(刚体)。

作为参考,这里是俱乐部的结构:

struct Club 
    btRigidBody *btPhys;    
    btScalar rotateAmount;
    btVector3 axis;

这是我轮换球杆的方式:

//Create a rotation matrix from the club's world transform 
btMatrix3x3 orn = club.btPhys->getWorldTransform().getBasis();
//Apply a rotation to the matrix
orn *= btMatrix3x3(btQuaternion( btVector3(0, 0, 1), btScalar(degreesToRads(club.rotationAmount))));
//Set the rotation of the club
club.btPhys->getWorldTransform().setBasis(orn);  

但是,这只是旋转球杆中心上的刚体。我希望刚体在其边缘(球杆的手柄)附近旋转。

所以我添加了一个变换,将球杆向上移动到枢轴点上方: (这段代码直接跟在前面的代码之后)

btTransform trans;
//Get the club's trasnform
club.btPhys->getMotionState()->getWorldTransform(trans);
float x, y, z;
x = trans.getOrigin().getX();
y = trans.getOrigin().getY();
z = trans.getOrigin().getZ();
//Set the transform to be 2 units above the club's origin (the club is 4 units long)
trans.setOrigin(btVector3(btScalar(x), btScalar(y + 2.0f), btScalar(z)));
//Apply the transform to the club
club.btPhys->getMotionState()->setWorldTransform(trans);

但是,这不会改变轴心点,它只是将球杆移动到轴心点上方(创建一个不需要的空间)。

简而言之,旋转矩阵只是围绕它的中心旋转刚体。我只想将轴心点从刚体的中心移动到刚体的边缘

【问题讨论】:

【参考方案1】:

MotionState 的 SetWorldTransform 始终围绕其质心变换身体。

有两种方法可以解决您的问题。如果你使用 btDefaultMotionState 作为你的运动状态,你可以在构造函数中指定质心的偏移量。这样,身体将围绕另一个点旋转。然而,这种方法有一个严重的副作用。与该对象的所有物理交互都将新的枢轴点视为质心。如果你的身体是运动的,那很好,但如果它是动态的,效果可能会与预期的效果不同。

另一种可能更安全的方法是将 3 个转换叠加在一起以实现您正在寻找的旋转。首先,将主体平移到所需枢轴的位置。接下来,旋转它。最后,把它翻译回应该是质心的地方。

【讨论】:

以上是关于在其边缘旋转刚体?的主要内容,如果未能解决你的问题,请参考以下文章

刚体变换与非刚体变换

描述三维刚体旋转

视觉SLAM三维空间刚体运动的描述

视觉SLAM三维空间刚体运动的描述

如何在子弹物理中获得刚体在 0 到 360 之间的欧拉旋转?

Bullet引擎刚体类 —— btRigidBody