Pages

mercredi 18 août 2010

引擎结构 Structure of OgreBullet Integration for Rigid Objects Dynamics

Code is from Q-Avril for testing OgreBullet integration.
(1) use the graphical pipe line  in Ogre: concepts of scene manager and Scene node, etc;\
(2) use the physical pipe line of dynamics in Bullet: concepts of creating dynamics world and algorithms of implementing collision detection.

The structure is followed.
In main() function, two important parts is implemented.
     (1)One is starting Bullet.
         ---

     (2)The other is starting Ogre. (Note that this code is not derived from Class ExampleApplication)
         ---Creating a root for Ogre;
         ---Choosing rendering system and initialization;
         ---Creating rendering window;
         ---Creating a scene manager;
         ---Creating camera and viewport;
         ---Adding resource file;
         ---Creating a framelistener and register it;
         ---Adding entities to the scene;
         ---Starting rendering.
               Call "Root::StartRendering" or call "Root::RenderOneFrame".
    
In order to connect the two engines (Ogre and Bullet), several classes (or saying interfaces) should be created. In this example code, 4 classes are created for the interfaces between Ogre and Bullet:

  1.     class testListener: public Ogre::FrameListener{}
  2.     class OgreRigidObject{}
  3.     class  OgreObjectState{}
  4.     class EntityWraper{}


Of cource, class testListener : Ogre::FrameListener{} must be created.

class testListener : public Ogre::FrameListener
{
public:
//@@member variables!
btDynamicsWorld *mWorld;
Ogre::Camera    *mCamera;
RenderWindow    *mWindow;
OIS::Keyboard   *mKey;
OIS::Mouse      *mMouse;


//@@Constructor AND destructor!
testListener(Camera *cam, RenderWindow *win);


//@@
virtual ~testListener();


//@@Override virtual function IN CLASS FrameListener!
virtual bool frameStarted(const FrameEvent& evt);
};










Then, in order to load rigid bodies to be managed by Ogre, class OgreRigidObject{} is created.

class OgreRigidObject
{
public:
//@@To describe rigid-bodies by three properties!
btRigidBody*       mBody;
btCollisionShape*  mShape;
btTriangleMesh*    mTriMesh;


SceneNode*         mNode;
OgreObjectState*   mState;


//@@
OgreRigidObject(String name, SceneManager *mgr, const Vector3 pos, const Quaternion quat);


~OgreRigidObject();


//@@
void createBody(btDynamicsWorld *world);


//@@
void createMeshCollider(Ogre::Mesh *ptr, btDynamicsWorld *world);
};




Since in Bullet,  In btDynamicsWorld by calling "stepSimulation",its sub-class btDiscreteDynamicsWorld would call stepSimulation to compute timestep,
btDiscreteDynamicsWorld .
stepSimulation would do collision detection and physics,by calling "setWorldTransform " of btMotionState to update the state of objects in dynamics world!

So, Class OgreObjectState is created!


class OgreObjectState : public btMotionState
{
OgreRigidObject *mObject;


public:
OgreObjectState(OgreRigidObject *parent);
~OgreObjectState();




//@@Override the two pure virtual function from abstract class btMotionState!
virtual void getWorldTransform(btTransform& worldTrans ) const;
virtual void setWorldTransform(const btTransform& worldTrans);
};





Another class is Class EntityWraper for wrapering some code in Ogre.
For example, creating entity, attached object, etc.
class EntityWrapper
{
public:

//@@
    EntityWrapper(  String name, 
String meshName, 
btDynamicsWorld* world, 
SceneManager *mgr, 
const Vector3 pos, 
const Quaternion quat,
bool staticMesh
             );

//@@
~EntityWrapper();

//@@
EntityWrapper     *clone();
OgreRigidObject   *getRigidBody();

private:
OgreRigidObject*  mRigidBody;
SceneManager*     mManager;
btDynamicsWorld*  mWorld;

Entity*           mEnt;
String            mMeshName;
};


Aucun commentaire:

Enregistrer un commentaire