开发平台是windows7,IDE:visual studio 2008 sp1,Ogre版本号是:1.7.2,Ode版本号是:0.11.1,OgreOde版本:0.0.3.0
首先需要申明的是现在这个OgreOde好像已经很久没有人维护了,最新的源代码下载下来在Ogre1.7.2下要编译通过的话还需要修改源代码中的某些地方。具体怎么改这不属于本文章所应该讲的内容。
写这篇文章完全是因为官方的教程已经out了,不知道那是那个年代的Ogre版本的ode教程。不过大部分代码是不变的。第一章就讲点入门级别的东西。
首先二话不说,先包含以下头文件:OgreOde_Core.h
为了方便学习嘛,直接在全局定义下面几个变量:
OgreOde::World* m_ppWorld;
OgreOde::Space* m_ppSpace;(这个space变量在这个程序中好像没有用处)
OgreOde::StepHandler* m_pphStep;//用于处理world中的时间,使用它来更新事件(也就是说,stepHandler时刻(比如每一帧)都在运行着,
//并且决定着哪一个物体运动到哪里已经与什么发生碰撞)
OgreOde_Prefab::Vehicle* m_ppVehicle;
OgreOde_Loader::DotLoader* m_ppDotLoader;
对,为了方便,我直接使用了OgreOde例子程序中的模型文件,一个跑道和一个汽车。
不然就得像官方文档中那样一堆代码去构建一个地面,突出不了本文章的重点,本文重点在于使用OgreOde而不是使用Ogre。
然后再createScene函数中将上面那些东西初始化。
m_ppWorld=new OgreOde::World(m_pSceneMgr);
m_ppWorld->setGravity(Vector3(0,(Real)-9.80665,0));
m_ppWorld->setCFM((Real)10e-5);
m_ppWorld->setERP((Real)0.8);
m_ppWorld->setAutoSleep(true);
m_ppWorld->setAutoSleepAverageSamplesCount(10);
m_ppWorld->setContactCorrectionVelocity(1.0);
//create something that will step the world automatically
m_ppWorld->setCollisionListener(this);
m_ppSpace=m_ppWorld->getDefaultSpace();
SceneNode *track_node = m_pSceneMgr->getRootSceneNode()->createChildSceneNode("track");
Entity *track_mesh = m_pSceneMgr->createEntity("track","racingcircuit.mesh");
track_node->attachObject(track_mesh);
OgreOde::TriangleMeshGeometry *_track;
OgreOde::EntityInformer ei(track_mesh);
_track = ei.createStaticTriangleMesh(m_ppWorld, m_ppWorld->getDefaultSpace());
track_mesh->setUserAny(Ogre::Any(_track));
m_ppDotLoader=new OgreOde_Loader::DotLoader(m_ppWorld);
const int _stepper_mode_choice = 2;
const int _stepper_choice = 2;
const Ogre::Real time_scale = Ogre::Real(1.0);
const Ogre::Real max_frame_time = Ogre::Real(1.0 / 4);
const Ogre::Real frame_rate = Ogre::Real(1.0 / 60);
OgreOde::StepHandler::StepModeType stepModeType=OgreOde::StepHandler::QuickStep;
m_pphStep = new OgreOde::ForwardFixedStepHandler(
m_ppWorld,
stepModeType,
(Real)0.01,
max_frame_time,
time_scale);
m_pphStep->setAutomatic(OgreOde::StepHandler::AutoMode_PostFrame,m_pRoot);
m_pRoot->setFrameSmoothingPeriod(5.0f);
m_ppVehicle=static_cast<OgreOde_Prefab::Vehicle*> (m_ppDotLoader->loadObject("subaru.ogreode","Subaru"));
m_ppVehicle->setPosition(m_pCamera->getPosition()+m_pCamera->getDirection()*15.0);
通过上面的代码,你的物理世界已经构建好了,而且物理世界与渲染世界的联系已经搭建起来了,剩下的就是更新了。
其实本文章中采取了自动更新的方式:
m_pphStep->setAutomatic(OgreOde::StepHandler::AutoMode_PostFrame,m_pRoot);
如果你把这句话注释掉,那么你就需要去bool frameRenderingQueued(const Ogre::FrameEvent& evt);中使用另一种方式去使得物理世界更新,并通过物理世界操作渲染世界中模型的位置.
bool frameRenderingQueued(const Ogre::FrameEvent& evt);
{
......
if (mStepper->step(evt.TimeSinceLastFrame))
{
mWorld->synchronise();
}
.....
}
然后下一步就重要了,这一步会给世界加入碰撞检测,以免物体穿透物体。
class FrameView:public Ogre::FrameListener, public Ogre::WindowEventListener, public OIS::KeyListener, public OIS::MouseListener,public OgreOde::CollisionListener
{
private:
........
public:
.......
void go(void);
void createScene(void); // Override me!
bool frameStarted(const FrameEvent& evt);
bool frameRenderingQueued(const Ogre::FrameEvent& evt);
bool collision(OgreOde::Contact* contact);
};
ok,大家如果是稍微看过一点Ogre代码就知道应该怎么做了吧。就是让你得Ogre显示窗口类继承一下OgreOde::CollsionListener。然后重载collision函数。
下面我们来看看collision函数是如何定义的吧,也很简单,就三行代码:
bool vwFrameView::collision(OgreOde::Contact* contact)
{
if(!OgreOde_Prefab::Vehicle::handleTireCollision(contact))
{
contact->setBouncyness(0.0);
contact->setCoulombFriction(18.0);
}
return true;
}
这样就Ok了,运行程序,你就会看见一个小车子从天上掉到了跑到上,然后滑行了一小会就停下来了。

至于细节部分,就自己去体会吧,总之按照这个例程你已经可以让一个简单的物理世界加入到你的程序中了,通过该程序你已经入门了,这文章页旨在使完全不会的人入门。只要你自己会配置编译器。
注:转载源地址