6
\$\begingroup\$

I'm trying to make my engine's camera a kinematic rigid body that can collide into other rigid bodies. I've overridden the btMotionState class and implemented setKinematicPos which updates the motion state's tranform. I use the overridden class when creating my kinematic body, but the collision detection fails. I'm doing this for fun trying to add collision detection and physics to Sean O' Neil's Procedural Universe

I referred to the bullet wiki on MotionStates for my CPhysicsMotionState class.

If it helps I can add the code for the Planetary rigid bodies, but I didn't want to clutter the post.

Here is my motion state class:

class CPhysicsMotionState: public btMotionState {
protected:
    // This is the transform with position and rotation of the camera
    CSRTTransform* m_srtTransform;
    btTransform m_btPos1;
public:
    CPhysicsMotionState(const btTransform &initialpos, CSRTTransform* srtTransform) {
        m_srtTransform = srtTransform;  
        m_btPos1 = initialpos;
    }

    virtual ~CPhysicsMotionState() {
        // TODO Auto-generated destructor stub
    }

    virtual void getWorldTransform(btTransform &worldTrans) const {
        worldTrans = m_btPos1;
    }

    void setKinematicPos(btQuaternion &rot, btVector3 &pos)
    {
        m_btPos1.setRotation(rot);
        m_btPos1.setOrigin(pos);
    }

    virtual void setWorldTransform(const btTransform &worldTrans) {
        btQuaternion rot = worldTrans.getRotation();
        btVector3 pos = worldTrans.getOrigin();

        m_srtTransform->m_qRotate = CQuaternion(rot.x(), rot.y(), rot.z(), rot.w());
        m_srtTransform->SetPosition(CVector(pos.x(), pos.y(), pos.z()));
        m_btPos1 = worldTrans;
    }
};

I add a rigid body for the camera:

// Create rigid body for camera
btCollisionShape* cameraShape = new btSphereShape(btScalar(5.0f));
btTransform startTransform;
startTransform.setIdentity(); // forgot to add this line
CVector vCamera = m_srtCamera.GetPosition();
startTransform.setOrigin(btVector3(vCamera.x, vCamera.y, vCamera.z));
m_msCamera = new CPhysicsMotionState(startTransform, &m_srtCamera);
btScalar tMass(80.7f);
bool isDynamic = (tMass != 0.f);
btVector3 localInertia(0,0,0);
if (isDynamic)
    cameraShape->calculateLocalInertia(tMass,localInertia);
btRigidBody::btRigidBodyConstructionInfo rbInfo(tMass, m_msCamera, cameraShape, localInertia);
m_rigidBody = new btRigidBody(rbInfo);
m_rigidBody->setCollisionFlags(m_rigidBody->getCollisionFlags() |
    btCollisionObject::CF_KINEMATIC_OBJECT);
m_rigidBody->setActivationState(DISABLE_DEACTIVATION);

This is the code in Update() that runs each frame:

CSRTTransform srtCamera = CCameraTask::GetPtr()->GetCamera();
Quaternion qRotate = srtCamera.m_qRotate;
btQuaternion rot = btQuaternion(qRotate.x, qRotate.y, qRotate.z, qRotate.w);
CVector vCamera = CCameraTask::GetPtr()->GetPosition();
btVector3 pos = btVector3(vCamera.x, vCamera.y, vCamera.z);
CPhysicsMotionState* cameraMotionState = CCameraTask::GetPtr()->GetMotionState();
cameraMotionState->setKinematicPos(rot, pos);
\$\endgroup\$
  • 2
    \$\begingroup\$ And what's your question? \$\endgroup\$ – Bartek Banachewicz Jan 14 '13 at 13:01
1
\$\begingroup\$

I would try this first.. You might be having trouble getting your projection and view into your class...

  1. Try running your code in the same program where your camera World, View, and Projection settings are located.
  2. Set your matrices to Matrix.Identity before you use them.
\$\endgroup\$

Not the answer you're looking for? Browse other questions tagged or ask your own question.