(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:
- class testListener: public Ogre::FrameListener{}
- class OgreRigidObject{}
- class OgreObjectState{}
- 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