easier to read Bullet to GLM conversions and back

This commit is contained in:
Andrew Meadows 2014-12-30 13:15:57 -08:00
parent 5e2246625b
commit 6f72d4ad81
5 changed files with 33 additions and 65 deletions

View file

@ -18,25 +18,20 @@
#include <glm/glm.hpp> #include <glm/glm.hpp>
#include <glm/gtc/quaternion.hpp> #include <glm/gtc/quaternion.hpp>
inline void bulletToGLM(const btVector3& b, glm::vec3& g) { inline glm::vec3 bulletToGLM(const btVector3& b) {
g = glm::vec3(b.getX(), b.getY(), b.getZ()); return glm::vec3(b.getX(), b.getY(), b.getZ());
} }
inline void bulletToGLM(const btQuaternion& b, glm::quat& g) { inline glm::quat bulletToGLM(const btQuaternion& b) {
g.x = b.getX(); return glm::quat(b.getW(), b.getX(), b.getY(), b.getZ());
g.y = b.getY();
g.z = b.getZ();
g.w = b.getW();
} }
inline void glmToBullet(const glm::vec3& g, btVector3& b) { inline btVector3 glmToBullet(const glm::vec3& g) {
b.setX(g.x); return btVector3(g.x, g.y, g.z);
b.setY(g.y);
b.setZ(g.z);
} }
inline void glmToBullet(const glm::quat& g, btQuaternion& b) { inline btQuaternion glmToBullet(const glm::quat& g) {
b = btQuaternion(g.x, g.y, g.z, g.w); return btQuaternion(g.x, g.y, g.z, g.w);
} }
#endif // USE_BULLET_PHYSICS #endif // USE_BULLET_PHYSICS

View file

@ -56,25 +56,15 @@ MotionType EntityMotionState::computeMotionType() const {
// (2) at the beginning of each simulation frame for KINEMATIC RigidBody's -- // (2) at the beginning of each simulation frame for KINEMATIC RigidBody's --
// it is an opportunity for outside code to update the object's simulation position // it is an opportunity for outside code to update the object's simulation position
void EntityMotionState::getWorldTransform(btTransform& worldTrans) const { void EntityMotionState::getWorldTransform(btTransform& worldTrans) const {
btVector3 pos; worldTrans.setOrigin(glmToBullet(_entity->getPositionInMeters() - ObjectMotionState::getWorldOffset()));
glmToBullet(_entity->getPositionInMeters() - ObjectMotionState::getWorldOffset(), pos); worldTrans.setRotation(glmToBullet(_entity->getRotation()));
worldTrans.setOrigin(pos);
btQuaternion rot;
glmToBullet(_entity->getRotation(), rot);
worldTrans.setRotation(rot);
} }
// This callback is invoked by the physics simulation at the end of each simulation frame... // This callback is invoked by the physics simulation at the end of each simulation frame...
// iff the corresponding RigidBody is DYNAMIC and has moved. // iff the corresponding RigidBody is DYNAMIC and has moved.
void EntityMotionState::setWorldTransform(const btTransform& worldTrans) { void EntityMotionState::setWorldTransform(const btTransform& worldTrans) {
glm::vec3 pos; _entity->setPositionInMeters(bulletToGLM(worldTrans.getOrigin()) + ObjectMotionState::getWorldOffset());
bulletToGLM(worldTrans.getOrigin(), pos); _entity->setRotation(bulletToGLM(worldTrans.getRotation()));
_entity->setPositionInMeters(pos + ObjectMotionState::getWorldOffset());
glm::quat rot;
bulletToGLM(worldTrans.getRotation(), rot);
_entity->setRotation(rot);
glm::vec3 v; glm::vec3 v;
getVelocity(v); getVelocity(v);
@ -118,17 +108,17 @@ void EntityMotionState::sendUpdate(OctreeEditPacketSender* packetSender, uint32_
if (_outgoingPacketFlags & EntityItem::DIRTY_POSITION) { if (_outgoingPacketFlags & EntityItem::DIRTY_POSITION) {
btTransform worldTrans = _body->getWorldTransform(); btTransform worldTrans = _body->getWorldTransform();
bulletToGLM(worldTrans.getOrigin(), _sentPosition); _sentPosition = bulletToGLM(worldTrans.getOrigin());
properties.setPosition(_sentPosition + ObjectMotionState::getWorldOffset()); properties.setPosition(_sentPosition + ObjectMotionState::getWorldOffset());
bulletToGLM(worldTrans.getRotation(), _sentRotation); _sentRotation = bulletToGLM(worldTrans.getRotation());
properties.setRotation(_sentRotation); properties.setRotation(_sentRotation);
} }
if (_outgoingPacketFlags & EntityItem::DIRTY_VELOCITY) { if (_outgoingPacketFlags & EntityItem::DIRTY_VELOCITY) {
if (_body->isActive()) { if (_body->isActive()) {
bulletToGLM(_body->getLinearVelocity(), _sentVelocity); _sentVelocity = bulletToGLM(_body->getLinearVelocity());
bulletToGLM(_body->getAngularVelocity(), _sentAngularVelocity); _sentAngularVelocity = bulletToGLM(_body->getAngularVelocity());
// if the speeds are very small we zero them out // if the speeds are very small we zero them out
const float MINIMUM_EXTRAPOLATION_SPEED_SQUARED = 4.0e-6f; // 2mm/sec const float MINIMUM_EXTRAPOLATION_SPEED_SQUARED = 4.0e-6f; // 2mm/sec
@ -148,7 +138,7 @@ void EntityMotionState::sendUpdate(OctreeEditPacketSender* packetSender, uint32_
_sentMoving = false; _sentMoving = false;
} }
properties.setVelocity(_sentVelocity); properties.setVelocity(_sentVelocity);
bulletToGLM(_body->getGravity(), _sentAcceleration); _sentAcceleration = bulletToGLM(_body->getGravity());
properties.setGravity(_sentAcceleration); properties.setGravity(_sentAcceleration);
properties.setAngularVelocity(_sentAngularVelocity); properties.setAngularVelocity(_sentAngularVelocity);
} }

View file

@ -84,29 +84,23 @@ void ObjectMotionState::setVolume(float volume) {
} }
void ObjectMotionState::setVelocity(const glm::vec3& velocity) const { void ObjectMotionState::setVelocity(const glm::vec3& velocity) const {
btVector3 v; _body->setLinearVelocity(glmToBullet(velocity));
glmToBullet(velocity, v);
_body->setLinearVelocity(v);
} }
void ObjectMotionState::setAngularVelocity(const glm::vec3& velocity) const { void ObjectMotionState::setAngularVelocity(const glm::vec3& velocity) const {
btVector3 v; _body->setAngularVelocity(glmToBullet(velocity));
glmToBullet(velocity, v);
_body->setAngularVelocity(v);
} }
void ObjectMotionState::setGravity(const glm::vec3& gravity) const { void ObjectMotionState::setGravity(const glm::vec3& gravity) const {
btVector3 g; _body->setGravity(glmToBullet(gravity));
glmToBullet(gravity, g);
_body->setGravity(g);
} }
void ObjectMotionState::getVelocity(glm::vec3& velocityOut) const { void ObjectMotionState::getVelocity(glm::vec3& velocityOut) const {
bulletToGLM(_body->getLinearVelocity(), velocityOut); velocityOut = bulletToGLM(_body->getLinearVelocity());
} }
void ObjectMotionState::getAngularVelocity(glm::vec3& angularVelocityOut) const { void ObjectMotionState::getAngularVelocity(glm::vec3& angularVelocityOut) const {
bulletToGLM(_body->getAngularVelocity(), angularVelocityOut); angularVelocityOut = bulletToGLM(_body->getAngularVelocity());
} }
// RELIABLE_SEND_HACK: until we have truly reliable resends of non-moving updates // RELIABLE_SEND_HACK: until we have truly reliable resends of non-moving updates
@ -154,9 +148,8 @@ bool ObjectMotionState::shouldSendUpdate(uint32_t simulationFrame, float subStep
// compute position error // compute position error
glm::vec3 extrapolatedPosition = _sentPosition + dt * (_sentVelocity + (0.5f * dt) * _sentAcceleration); glm::vec3 extrapolatedPosition = _sentPosition + dt * (_sentVelocity + (0.5f * dt) * _sentAcceleration);
glm::vec3 position;
btTransform worldTrans = _body->getWorldTransform(); btTransform worldTrans = _body->getWorldTransform();
bulletToGLM(worldTrans.getOrigin(), position); glm::vec3 position = bulletToGLM(worldTrans.getOrigin());
float dx2 = glm::distance2(position, extrapolatedPosition); float dx2 = glm::distance2(position, extrapolatedPosition);
const float MAX_POSITION_ERROR_SQUARED = 0.001f; // 0.001 m^2 ~~> 0.03 m const float MAX_POSITION_ERROR_SQUARED = 0.001f; // 0.001 m^2 ~~> 0.03 m
@ -173,8 +166,7 @@ bool ObjectMotionState::shouldSendUpdate(uint32_t simulationFrame, float subStep
extrapolatedRotation = glm::angleAxis(dt * spin, axis) * _sentRotation; extrapolatedRotation = glm::angleAxis(dt * spin, axis) * _sentRotation;
} }
const float MIN_ROTATION_DOT = 0.98f; const float MIN_ROTATION_DOT = 0.98f;
glm::quat actualRotation; glm::quat actualRotation = bulletToGLM(worldTrans.getRotation());
bulletToGLM(worldTrans.getRotation(), actualRotation);
return (glm::dot(actualRotation, extrapolatedRotation) < MIN_ROTATION_DOT); return (glm::dot(actualRotation, extrapolatedRotation) < MIN_ROTATION_DOT);
} }

View file

@ -62,9 +62,7 @@ void ShapeInfoUtil::collectInfoFromShape(const btCollisionShape* shape, ShapeInf
switch(type) { switch(type) {
case BOX_SHAPE: { case BOX_SHAPE: {
const btBoxShape* boxShape = static_cast<const btBoxShape*>(shape); const btBoxShape* boxShape = static_cast<const btBoxShape*>(shape);
glm::vec3 halfExtents; info.setBox(bulletToGLM(boxShape->getHalfExtentsWithMargin()));
bulletToGLM(boxShape->getHalfExtentsWithMargin(), halfExtents);
info.setBox(halfExtents);
} }
break; break;
case SPHERE_SHAPE: { case SPHERE_SHAPE: {
@ -99,9 +97,8 @@ btCollisionShape* ShapeInfoUtil::createShapeFromInfo(const ShapeInfo& info) {
const QVector<glm::vec3>& data = info.getData(); const QVector<glm::vec3>& data = info.getData();
switch(info.getType()) { switch(info.getType()) {
case BOX_SHAPE: { case BOX_SHAPE: {
btVector3 halfExtents; // data[0] is halfExtents
glmToBullet(data[0], halfExtents); shape = new btBoxShape(glmToBullet(data[0]));
shape = new btBoxShape(halfExtents);
} }
break; break;
case SPHERE_SHAPE: { case SPHERE_SHAPE: {
@ -110,11 +107,9 @@ btCollisionShape* ShapeInfoUtil::createShapeFromInfo(const ShapeInfo& info) {
} }
break; break;
case CYLINDER_SHAPE: { case CYLINDER_SHAPE: {
btVector3 halfExtents;
glmToBullet(data[0], halfExtents);
// NOTE: default cylinder has (UpAxis = 1) axis along yAxis and radius stored in X // NOTE: default cylinder has (UpAxis = 1) axis along yAxis and radius stored in X
// halfExtents = btVector3(radius, halfHeight, unused) // data[0] = btVector3(radius, halfHeight, unused)
shape = new btCylinderShape(halfExtents); shape = new btCylinderShape(glmToBullet(data[0]));
} }
break; break;
case CAPSULE_SHAPE: { case CAPSULE_SHAPE: {

View file

@ -19,8 +19,7 @@
#ifdef USE_BULLET_PHYSICS #ifdef USE_BULLET_PHYSICS
void BulletUtilTests::fromBulletToGLM() { void BulletUtilTests::fromBulletToGLM() {
btVector3 bV(1.23f, 4.56f, 7.89f); btVector3 bV(1.23f, 4.56f, 7.89f);
glm::vec3 gV; glm::vec3 gV = bulletToGLM(bV);
bulletToGLM(bV, gV);
if (gV.x != bV.getX()) { if (gV.x != bV.getX()) {
std::cout << __FILE__ << ":" << __LINE__ std::cout << __FILE__ << ":" << __LINE__
<< " ERROR: x mismatch bullet.x = " << bV.getX() << " != glm.x = " << gV.x << std::endl; << " ERROR: x mismatch bullet.x = " << bV.getX() << " != glm.x = " << gV.x << std::endl;
@ -39,8 +38,7 @@ void BulletUtilTests::fromBulletToGLM() {
axis.normalize(); axis.normalize();
btQuaternion bQ(axis, angle); btQuaternion bQ(axis, angle);
glm::quat gQ; glm::quat gQ = bulletToGLM(bQ);
bulletToGLM(bQ, gQ);
if (gQ.x != bQ.getX()) { if (gQ.x != bQ.getX()) {
std::cout << __FILE__ << ":" << __LINE__ std::cout << __FILE__ << ":" << __LINE__
<< " ERROR: x mismatch bullet.x = " << bQ.getX() << " != glm.x = " << gQ.x << std::endl; << " ERROR: x mismatch bullet.x = " << bQ.getX() << " != glm.x = " << gQ.x << std::endl;
@ -61,8 +59,7 @@ void BulletUtilTests::fromBulletToGLM() {
void BulletUtilTests::fromGLMToBullet() { void BulletUtilTests::fromGLMToBullet() {
glm::vec3 gV(1.23f, 4.56f, 7.89f); glm::vec3 gV(1.23f, 4.56f, 7.89f);
btVector3 bV; btVector3 bV = glmToBullet(gV);
glmToBullet(gV, bV);
if (gV.x != bV.getX()) { if (gV.x != bV.getX()) {
std::cout << __FILE__ << ":" << __LINE__ std::cout << __FILE__ << ":" << __LINE__
<< " ERROR: x mismatch glm.x = " << gV.x << " != bullet.x = " << bV.getX() << std::endl; << " ERROR: x mismatch glm.x = " << gV.x << " != bullet.x = " << bV.getX() << std::endl;
@ -81,8 +78,7 @@ void BulletUtilTests::fromGLMToBullet() {
axis.normalize(); axis.normalize();
btQuaternion bQ(axis, angle); btQuaternion bQ(axis, angle);
glm::quat gQ; glm::quat gQ = bulletToGLM(bQ);
bulletToGLM(bQ, gQ);
if (gQ.x != bQ.getX()) { if (gQ.x != bQ.getX()) {
std::cout << __FILE__ << ":" << __LINE__ std::cout << __FILE__ << ":" << __LINE__
<< " ERROR: x mismatch glm.x = " << gQ.x << " != bullet.x = " << bQ.getX() << std::endl; << " ERROR: x mismatch glm.x = " << gQ.x << " != bullet.x = " << bQ.getX() << std::endl;