OgreODE入门
2010-03-03 13:24
204 查看
既然用了Ogre,那么一定是要有一个物理引擎的。最后选择了ODE,因为ODE在持续更新,文档稍微要多一些。
但是中文文档基本没有,为了以后能快速阅读,只好自己先翻一下了。
这只是一个介绍性的文档,其中的代码并不能形成一个完整的可执行程序。如果结合着OgreODE的Demo的代码看这篇文章,效果会很好的。
原文:http://www.ogre3d.org/wiki/index.php/First_steps_with_OgreODE
这是一个为OgreODE初学者所写的一个入门教程。因为这里(OGRE wiki)没有OgreODE的详尽的文档,所以写了这个教程,希望能对初学者有所指引和帮助。SimpleScenes是另一个学习的好地方,那里有7个带有实际代码的教程。本教程的所有代码都是从那7个教程里节选的。
一、初始化OgreODE,创建一个最简单的物理世界
在我们开始学习之前,你需要准备好:
1.带有一个sceneManager、一个camera、一些basic light的可工作的Ogre程序
2.OgreODE和ODE头文件
3.一个带有material and texture 的 Ogre mesh,比如一个平面或者一条街道之类的(基础世界)
4.一个盒装的带有material and texture 的 Ogre mesh(世界中的物体)
如果你学习完了Ogre Tutorials,那么你能很轻松地做到这些。
在一个最好是你申明了Ogre::Root的头文件里,包含上OgreODE的头文件,并申明以下变量:
OgreOde::World类似Ogre::Root,是OgreODE最顶层的对象。你所添加的每一个类,都会以某种方式添加到这个world中,因此这个世界中的物理定律就可以应用到添加的这个类上。但是要小心了,现在版本的OgreODE允许在一个程序中存在多个world。不过这种情况,只有在你确实需要复杂的"Prey-style"的重力效果时或做一些进阶性的优化时,才可能出现。
OgreOde::Space(碰撞空间)类似于一个所有对象(集合体更加特殊)的集合。这些对象可以与自己所在的space以及其它的space里的对象相碰撞,也可以不和任何对象发生碰撞。在大多数情况下,你将会创建一个有等级的碰撞空间——最重要节点的在顶部,很多次要的子节点附属在其下面。
在ODE里面有三种类型的碰撞空间——碰撞空间(Collision Space)、简单空间(Simple Space)和象限四分树空间(Quadtree Space)。碰撞空间和简单空间的差别很小(举个例子,设想碰撞空间是“根”空间,而简单空间是类似人物的手臂一样的“子”空间),而象限四分树空间是特别为大型项目的优化而设计的。所以如果你的场景有大于1000平方米的时候,象限四分树能提高10-20%的性能。(问题是,因为一些bug,象限四分树在OgreOde中还没有得到完好地实现,但这些bug是能被胸怀大志的开发者所修正的。)
OgreOde::StepHandler用于处理world中的时间,你将会使用它来更新事件(也就是说,stephandler时刻(比如每一帧)都在运行着,并且决定着哪一个物体运动到哪里以及与什么发生碰撞)。
二、改写你的.cpp文件
现在找到头文件所对应的cpp文件,让我们来创建一个华丽的新世界。
正如你所看到的,world注册到了场景管理器(scene manager),同时设定了重力加速度为9.81。这里请注意两个事情:重力加速度设为了“负”,也就是说对象是“下落”而不是“上浮”;关于世界单位——如果你使用的是“1 ogre 单位 = 1 米”那么重力加速度应设为-9.80665,如果你使用的是“1 ogre 单位 = 1 厘米”(也就是说缩小了100倍)那么重力加速度就应该设为-980.665(相应扩大了100倍)。
后面的两行(setCFM 和 setERP)的设定,影响了模拟现实中的的关节、弹力和摩擦等方面。这里不详细讨论这两个函数,就像代码一样写就可以了。
setAutoSleep设定了world启用它的自动优化(即如果一个对象不再移动,它就会停止重复移动)。
setAutoSleepAverageSamplesCount,用于修正AutoSleep。最好就是设其参数为10,我们将在后面来讨论这个。
setContactCorrectionVelocity,一个很重要的设定。如果不设置它的话,对象间可能会相互穿透。
下一步,添加如下代码:
最后一步是设定Stepper。你可以在StepHandler::QuickStep, StepHandler::BasicStep 和 StepHandler::FastStep中选择一种,但这里不做详细说明。你也可以在其它的不同类型的StepHandler中选择,但是这也是会在后面提到(尽管这个很重要)。
现在,我们有了一个带有重力的世界,但在这个世界里面什么东西都没有。让我们来改写它:
三、用一个盒子和一个平面来测试我们的重力系统
三、用一个箱子和一个平面来测试我们的重力系统
让我们在世界中添加一个平面和一个箱子(Crate)的实体/节点/主体,我们可以让这个箱子在我们设定的重力系统中进行自由落体运动。
在头文件中加入以下变量:
你应该已经知道最后两行的意思了。这些变量的第一个将会是ground上的平面,后面的三个变量是关于箱子的。
回到cpp文件,为创建平面添加如下代码:
这里创建的一个位于x-z面的平面。现在来创建箱子,首先我们需要常规的Ogre/Entity/Node:
然后创建箱子的body并将其“注册”到world和场景节点(scene node):
然后我们设定箱子的体积和质量。因为这是一个盒装的对象,所以我们设定OgreOde::BoxGeometry。其它的比如Sphere或者TriangleMesh在OgreODE也同样有效。
最后我们设定箱子的方向和位置。把它放置到摄像机(camera)前,方便看到它自由落体。
现在就有了一个悬在空中的箱子了。我们需要更新world的time steps。添加如下代码到主要的循环或gamestate::update 或你更新当前帧的地方:
如果你的代码里有一个类似"TimeSinceLastFrame"的值,设定"time"为这个值。现在就可以编译了,尝试去实现它!
如果你只看到一毫秒的急速运动的棕色的点,尝试将重力加速度除以100或1000,使用0.00981代替9.81。这个箱子应该会在这一点穿过平面,因为我们根本没有处理碰撞。关于碰撞的处理你可以在这里找到OgreOde Collision Handling。
但是中文文档基本没有,为了以后能快速阅读,只好自己先翻一下了。
这只是一个介绍性的文档,其中的代码并不能形成一个完整的可执行程序。如果结合着OgreODE的Demo的代码看这篇文章,效果会很好的。
原文:http://www.ogre3d.org/wiki/index.php/First_steps_with_OgreODE
这是一个为OgreODE初学者所写的一个入门教程。因为这里(OGRE wiki)没有OgreODE的详尽的文档,所以写了这个教程,希望能对初学者有所指引和帮助。SimpleScenes是另一个学习的好地方,那里有7个带有实际代码的教程。本教程的所有代码都是从那7个教程里节选的。
一、初始化OgreODE,创建一个最简单的物理世界
在我们开始学习之前,你需要准备好:
1.带有一个sceneManager、一个camera、一些basic light的可工作的Ogre程序
2.OgreODE和ODE头文件
3.一个带有material and texture 的 Ogre mesh,比如一个平面或者一条街道之类的(基础世界)
4.一个盒装的带有material and texture 的 Ogre mesh(世界中的物体)
如果你学习完了Ogre Tutorials,那么你能很轻松地做到这些。
在一个最好是你申明了Ogre::Root的头文件里,包含上OgreODE的头文件,并申明以下变量:
#include "OgreOde/OgreOde_Core.h" OgreOde::World *mWorld; OgreOde::Space *mSpace; OgreOde::StepHandler *mStepper;
OgreOde::World类似Ogre::Root,是OgreODE最顶层的对象。你所添加的每一个类,都会以某种方式添加到这个world中,因此这个世界中的物理定律就可以应用到添加的这个类上。但是要小心了,现在版本的OgreODE允许在一个程序中存在多个world。不过这种情况,只有在你确实需要复杂的"Prey-style"的重力效果时或做一些进阶性的优化时,才可能出现。
OgreOde::Space(碰撞空间)类似于一个所有对象(集合体更加特殊)的集合。这些对象可以与自己所在的space以及其它的space里的对象相碰撞,也可以不和任何对象发生碰撞。在大多数情况下,你将会创建一个有等级的碰撞空间——最重要节点的在顶部,很多次要的子节点附属在其下面。
在ODE里面有三种类型的碰撞空间——碰撞空间(Collision Space)、简单空间(Simple Space)和象限四分树空间(Quadtree Space)。碰撞空间和简单空间的差别很小(举个例子,设想碰撞空间是“根”空间,而简单空间是类似人物的手臂一样的“子”空间),而象限四分树空间是特别为大型项目的优化而设计的。所以如果你的场景有大于1000平方米的时候,象限四分树能提高10-20%的性能。(问题是,因为一些bug,象限四分树在OgreOde中还没有得到完好地实现,但这些bug是能被胸怀大志的开发者所修正的。)
OgreOde::StepHandler用于处理world中的时间,你将会使用它来更新事件(也就是说,stephandler时刻(比如每一帧)都在运行着,并且决定着哪一个物体运动到哪里以及与什么发生碰撞)。
二、改写你的.cpp文件
现在找到头文件所对应的cpp文件,让我们来创建一个华丽的新世界。
mWorld = new OgreOde::World(mSceneMgr); mWorld->setGravity(Ogre::Vector3(0,-9.80665,0)); mWorld->setCFM(10e-5); mWorld->setERP(0.8); mWorld->setAutoSleep(true); mWorld->setAutoSleepAverageSamplesCount(10); mWorld->setContactCorrectionVelocity(1.0); mSpace = mWorld->getDefaultSpace();
正如你所看到的,world注册到了场景管理器(scene manager),同时设定了重力加速度为9.81。这里请注意两个事情:重力加速度设为了“负”,也就是说对象是“下落”而不是“上浮”;关于世界单位——如果你使用的是“1 ogre 单位 = 1 米”那么重力加速度应设为-9.80665,如果你使用的是“1 ogre 单位 = 1 厘米”(也就是说缩小了100倍)那么重力加速度就应该设为-980.665(相应扩大了100倍)。
后面的两行(setCFM 和 setERP)的设定,影响了模拟现实中的的关节、弹力和摩擦等方面。这里不详细讨论这两个函数,就像代码一样写就可以了。
setAutoSleep设定了world启用它的自动优化(即如果一个对象不再移动,它就会停止重复移动)。
setAutoSleepAverageSamplesCount,用于修正AutoSleep。最好就是设其参数为10,我们将在后面来讨论这个。
setContactCorrectionVelocity,一个很重要的设定。如果不设置它的话,对象间可能会相互穿透。
下一步,添加如下代码:
const Ogre::Real _time_step = 0.5; const Ogre::Real time_scale = Ogre::Real(1.7); const Ogre::Real max_frame_time = Ogre::Real(1.0 / 4); mStepper = new OgreOde::StepHandler(mWorld, OgreOde::StepHandler::QuickStep, _time_step, max_frame_time, time_scale);
最后一步是设定Stepper。你可以在StepHandler::QuickStep, StepHandler::BasicStep 和 StepHandler::FastStep中选择一种,但这里不做详细说明。你也可以在其它的不同类型的StepHandler中选择,但是这也是会在后面提到(尽管这个很重要)。
现在,我们有了一个带有重力的世界,但在这个世界里面什么东西都没有。让我们来改写它:
三、用一个盒子和一个平面来测试我们的重力系统
三、用一个箱子和一个平面来测试我们的重力系统
让我们在世界中添加一个平面和一个箱子(Crate)的实体/节点/主体,我们可以让这个箱子在我们设定的重力系统中进行自由落体运动。
在头文件中加入以下变量:
OgreOde::InfinitePlaneGeometry *mGround; OgreOde::Body *mBody; OgreOde::Geometry *mGeom; OgreOde::BoxMass mMass; Ogre::SceneNode *mNode; Ogre::Entity *mEntity;
你应该已经知道最后两行的意思了。这些变量的第一个将会是ground上的平面,后面的三个变量是关于箱子的。
回到cpp文件,为创建平面添加如下代码:
mGround = new OgreOde::InfinitePlaneGeometry( Plane(Ogre::Vector3(0,1,0),0), mWorld, mWorld->getDefaultSpace()); // Use a load of meshes to represent the floor int i = 0; StaticGeometry* s; s = mSceneMgr->createStaticGeometry("StaticFloor"); s->setRegionDimensions(Ogre::Vector3(160.0, 100.0, 160.0)); // Set the region origin so the center is at 0 world s->setOrigin(Ogre::Vector3::ZERO); for (Real z = -80.0;z <= 80.0;z += 20.0) { for (Real x = -80.0;x <= 80.0;x += 20.0) { String name = String("Ground") + StringConverter::toString(i++); Entity* entity = mSceneMgr->createEntity(name, "plane.mesh"); entity->setQueryFlags (1<<4); entity->setUserObject(mGround); entity->setCastShadows(false); s->addEntity(entity, Ogre::Vector3(x,0,z)); } } s->build();
这里创建的一个位于x-z面的平面。现在来创建箱子,首先我们需要常规的Ogre/Entity/Node:
mEntity = mSceneMgr->createEntity("crate","crateCube.mesh"); mEntity->setQueryFlags (1<<2); mNode = mSceneMgr->getRootSceneNode()->createChildSceneNode("crate"); mNode->attachObject(mEntity); mEntity->setNormaliseNormals(true); mEntity->setCastShadows(true);
然后创建箱子的body并将其“注册”到world和场景节点(scene node):
mBody = new OgreOde::Body(mWorld); mNode->attachObject(mBody);
然后我们设定箱子的体积和质量。因为这是一个盒装的对象,所以我们设定OgreOde::BoxGeometry。其它的比如Sphere或者TriangleMesh在OgreODE也同样有效。
Vector3 size(10.0,10.0,10.0); OgreOde::BoxMass mMass(0.5,size); mMass.setDensity(5.0,size); mGeom = (OgreOde::Geometry*)new OgreOde::BoxGeometry( size, mWorld, mSpace); mNode->setScale(size.x * 0.1,size.y * 0.1,size.z * 0.1); mBody->setMass(mMass); mGeom->setBody(mBody); mEntity->setUserObject(mGeom);
最后我们设定箱子的方向和位置。把它放置到摄像机(camera)前,方便看到它自由落体。
mBody->setOrientation(Quaternion(Radian(5.0),Ogre::Vector3(0,0,0))); mBody->setPosition(Vector3(0,120,-20));
现在就有了一个悬在空中的箱子了。我们需要更新world的time steps。添加如下代码到主要的循环或gamestate::update 或你更新当前帧的地方:
Ogre::Real time = 0.1; if (mStepper->step(time)) { mWorld->synchronise(); }
如果你的代码里有一个类似"TimeSinceLastFrame"的值,设定"time"为这个值。现在就可以编译了,尝试去实现它!
如果你只看到一毫秒的急速运动的棕色的点,尝试将重力加速度除以100或1000,使用0.00981代替9.81。这个箱子应该会在这一点穿过平面,因为我们根本没有处理碰撞。关于碰撞的处理你可以在这里找到OgreOde Collision Handling。
相关文章推荐
- 【Ogre编程入门与进阶】第十四章 Ogre渲染目标
- 【Ogre编程入门与进阶】第六章 相机 灯光 阴影
- 【Ogre编程入门与进阶】第三章 Ogre框架配置及概要分析
- 【Ogre编程入门与进阶】第四章 Ogre的设计理念与特色
- OGRE 入门 一、 ubuntu 12.04 下编译
- OGRE 入门 三、Basic Tutorial 2 : Cameras, Lights, and Shadows
- 【Ogre编程入门与进阶】第一章 Ogre3D概述
- 【Ogre编程入门与进阶】第十五章 Ogre的“二维”与合成特效
- 【Ogre编程入门与进阶】第十章 Ogre场景管理
- OGREODE基础教程
- Ogre简单的demo程序 入门必备
- OGRE3D从新手到入门
- 【Ogre编程入门与进阶】第九章 动画
- OGRE3D从新手到入门周边工具集
- 【Ogre编程入门与进阶】第七章 帧监听与用户输入
- 【Ogre编程入门与进阶】第八章 地形、天空与雾化效果
- OGRE3D入门探索01:将渲染窗口嵌入到Win32主窗口
- OGRE入门学习整理1——使用Visula Studio 2008 创建可以带走的Ogre应用程序
- 【Ogre编程入门与进阶】第十二章 Ogre脚本、材质与纹理
- 【Ogre编程入门与进阶】第二章 Ogre相关知识回顾