http://dev.gameres.com/Program/Visual/3D/OgreOdeCharacter.mht
第一版 by SuperMegaMau
这个教程包括的代码和算法是作者自己的经验,也许不正确或不怎么准确,如果发现问题请纠正。
内容
- 1 介绍
- 2 创建物理模型
- 2.1 创建角色
- 2.2 获取 AABB
- 2.3 创建新空间
- 2.4 创建球
- 2.5 创建椭球
- 2.6 创建关节
- 3 移动角色
- 4 让角色爬起来
- 5 问题
|
介绍
我相信我不是第一人自问如何用OgreOde创建一个运动角色。搜索论坛和wiki后,我意识到这是一个很有用的信息。这个教程解释了如何创建一个可以在地形上行走的运动角色(包括其它meshes,如树和房屋)。
创建物理模型
我按照在Monster的方法用下图代表一个角色:
下面,我假设你对Ogre的SceneNodes, meshes 和AlignedBoxes都有所了解,并且会用SceneManager创建地形。
创建角色
首先创建一个SceneNode来放角色的mesh,在这个例子中我用了Ogre例子中的忍者模型。创建两个SceneNode并把它们连在一起。后面我会解释为什么是两个Node。
Entity* ninja = mSceneMgr->createEntity("ninja","ninja.mesh");
SceneNode* ninjaNode = mSceneMgr->getRootSceneNode()->createChildSceneNode("ninja");
SceneNode* modelNode = ninjaNode->createChildSceneNode("ninja_model");
modelNode->attachObject(ninja);
ninjaNode->setScale(0.05,0.05,0.05);
也许你已经注意到,ninjaNode被缩放得很小,这是因为如果mesh很大的话渲染的速度就变很慢(不知道为什么)。
获取 AABB(AxisAlignedBox, 轴对齐包围盒)
现在用AxisAlignedBox获取mesh的大小。
AxisAlignedBox aab = modelNode->getAttachedObject("ninja")->getBoundingBox();
Ogre::Vector3 min = aab.getMinimum()*ninjaNode->getScale();
Ogre::Vector3 max = aab.getMaximum()*ninjaNode->getScale();
Ogre::Vector3 center = aab.getCenter()*ninjaNode->getScale();
Ogre::Vector3 size(fabs(max.x-min.x),fabs(max.y-min.y),fabs(max.z-min.z));
float radius = (size.x>size.z)?size.z/2.0f:size.x/2.0f;
创建一个新空间
我们需要创建一个新空间把角色放在其中,并且取消内部碰撞检测。
OgreOde::SimpleSpace* dollSpace = new OgreOde::SimpleSpace(_world->getDefaultSpace());
dollSpace->setInternalCollisions(false);
创建球体(腿部)
现在有了两个SceneNodes, "ninjaNode" 和 "modelNode"。ninjaNode是代表你角色的节点,modelNode是你真正贴mesh的地方。这么做是因为mesh的中心总是在OgreOde::Body的中心,所以我们用ninjaNode来创建碰撞体的位置,然后根据ninjaNode和OgreOde::Body来获得mesh的正确位置。
左边图是用一个SceneNode所得到的效果,右边是用两个SceneNode。你可以注意到,左边的角色悬浮在半空中。下面代码创建了一个球体代表角色的脚部。我们需要一个SphereGeometry和一个TransformGeometry 将球体放到正确位置。
译注:注释为我的猜想,具体不知道步骤这么复杂,欢迎纠正。
(1) 创建一个碰撞体,命名为feet
(2) 设置碰撞体为球形物体,半径为AABB获得的半径
(3) SphereGeometry,半径为AABB获得的半径
(4) TransformGeometry,空间为刚才创建的空间, TransformGeometry似乎是为了包含某特定形状的几何体
(5) 改变modelNode相对于ninjiaNode的位置,以便让脚占到地上
(6) 让TransformGeometry包含一个OgreOde::Body和一个几何体
(7) 将Ogre::Body粘到ninjaNode上
|