ImageVerifierCode 换一换
格式:DOCX , 页数:116 ,大小:90.80KB ,
资源ID:9785294      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/9785294.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(ogre中级教程.docx)为本站会员(b****8)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

ogre中级教程.docx

1、ogre中级教程Ogre中级教程(一): 动画, 两点间移动, 和四元数基础 分类: Ogre 2010-03-27 23:48 968人阅读 评论(1) 收藏 举报 Ogre中级教程中级教程一 来自 Ogre wiki 动画, 两点间移动, 和四元数基础 作者: Culver. 内容 目录 隐藏 1 介绍 2 前期准备 3 准备开始 4 设置场景 5 动画 6 移动角色 7 巩固练习 7.1 简单问题 7.2 中级问题 7.3 困难问题 7.4 专家问题 介绍 这个教程里包括怎么样得到一个模型,并添加模型动画,最后让模型可以在两个预先定义的点之间走动。在此将讲述如何用基本的四元数方法保持模型

2、移动的时候正面一直朝着我们指定的方向。你必须一点点的将代码加入到你的项目中,并在每次加入新代码后编译并察看demo运行的结果。 本课的最终代码在这里。 前期准备 首先,这个指南假设你已经知道如何设置Ogre的项目环境以及如何正确编译项目。该例子同样使用STL 中的queue数据结构。那么预先了解如何使用queue是必要的,至少你需要知道什么是模版。如果你不熟悉STL,那么我像你推荐STL参考ISBN 0596005563,它可以帮助你在将来花费更少的时间。 准备开始 首先,你需要为这个Demo创建一个新项目,在项目中添加一个名为MoveDemo.cpp的文件并加入如下代码: #include

3、ExampleApplication.h#include using namespace std;class MoveDemoListener : public ExampleFrameListenerpublic: MoveDemoListener(RenderWindow* win, Camera* cam, SceneNode *sn, Entity *ent, deque &walk) : ExampleFrameListener(win, cam, false, false), mNode(sn), mEntity(ent), mWalkList( walk ) / MoveDemo

4、Listener /* This function is called to start the object moving to the next position in mWalkList. */ bool nextLocation( ) return true; / nextLocation( ) bool frameStarted(const FrameEvent &evt) return ExampleFrameListener:frameStarted(evt); protected: Real mDistance; / The distance the object has le

5、ft to travel Vector3 mDirection; / The direction the object is moving Vector3 mDestination; / The destination the object is moving towards AnimationState *mAnimationState; / The current animation state of the object Entity *mEntity; / The Entity we are animating SceneNode *mNode; / The SceneNode tha

6、t the Entity is attached to std:deque mWalkList; / The list of points we are walking to Real mWalkSpeed; / The speed at which the object is moving;class MoveDemoApplication : public ExampleApplicationprotected:public: MoveDemoApplication() MoveDemoApplication() protected: Entity *mEntity; / The enti

7、ty of the object we are animating SceneNode *mNode; / The SceneNode of the object we are moving std:deque mWalkList; / A deque containing the waypoints void createScene(void) void createFrameListener(void) mFrameListener= new MoveDemoListener(mWindow, mCamera, mNode, mEntity, mWalkList); mFrameListe

8、ner-showDebugOverlay(true); mRoot-addFrameListener(mFrameListener); ;#if OGRE_PLATFORM = OGRE_PLATFORM_WIN32#define WIN32_LEAN_AND_MEAN#include windows.hINT WINAPI WinMain( HINSTANCE hInst, HINSTANCE, LPSTR strCmdLine, INT )#elseint main(int argc, char *argv)#endif / Create application object MoveDe

9、moApplication app; try app.go(); catch( Exception& e ) #if OGRE_PLATFORM = OGRE_PLATFORM_WIN32 MessageBox( NULL, e.getFullDescription().c_str(), An exception has occured!, MB_OK | MB_ICONERROR | MB_TASKMODAL);#else fprintf(stderr, An exception has occured: %s/n, e.getFullDescription().c_str();#endif

10、 return 0;在我们继续讲解之前,你可以编译这部分代码看下效果。 设置场景 在我们开始之前,需要注意的是已经在MoveDemoApplication中预先定义的三个变量。我们创建的entity实例保存在变量mEntity中,我们创建的node实例保存在mNode中,另外mWalkList包含了所有我们希望对象行走到的节点。 定位到MoveDemoApplication:createScene函数并且加入以下代码。首先,我们来设置环境光(ambient light)到最大,这样可以让我们看到我们放在场景中的所有对象。 / Set the default lighting. mSceneMg

11、r-setAmbientLight( ColourValue( 1.0f, 1.0f, 1.0f ) );接下来我们来在屏幕上创建一个可以使用的机器人。要做到这点我们需要在创建SceneNode之前先为机器人创建一个entity使得我们可以对其进行旋转。 / Create the entity mEntity = mSceneMgr-createEntity( Robot, robot.mesh ); / Create the scene node mNode = mSceneMgr-getRootSceneNode( )- createChildSceneNode( RobotNode, V

12、ector3( 0.0f, 0.0f, 25.0f ) ); mNode-attachObject( mEntity );以上这些都是非常基础的,所以我认为不需要再对以上的描述做任何解释。在接下来的代码片断,我们将开始告诉机器人那些地方是它需要到达的。这里需要你们了解一些STL的知识,deque对象是一个高效的双端对列。我们只需要使用它的几个简单的方法。push_front和push_back方法分别将对象放入队列的前端和后端,front和back方法分别返回当前队列前端和后端的元素(PS:注意,这里最好有判空的习惯,用if( empty() ) )pop_front和pop_back两个方法

13、分别从队列两端移除对象。最后,empty方法返回该队列是否为空。下面这些代码添加了两个Vector到队列中,在后面我们移动robot的时候会用到它们。 / Create the walking list mWalkList.push_back( Vector3( 550.0f, 0.0f, 50.0f ) ); mWalkList.push_back( Vector3(-100.0f, 0.0f, -200.0f ) );接下来,我们在场景里放置一些物体,以标记这个机器人应该朝哪走去。这样使我们能看见机器人在场景里相对于其它物体进行移动。注意它们的位置的负Y部分,这些物体被放在机器人移动目的地

14、的正下方,当它到达指定地点时,它就站在这些物体上面。 / Create objects so we can see movement Entity *ent; SceneNode *node; ent = mSceneMgr-createEntity( Knot1, knot.mesh ); node = mSceneMgr-getRootSceneNode( )-createChildSceneNode( Knot1Node, Vector3( 0.0f, -10.0f, 25.0f ) ); node-attachObject( ent ); node-setScale( 0.1f, 0.

15、1f, 0.1f ); ent = mSceneMgr-createEntity( Knot2, knot.mesh ); node = mSceneMgr-getRootSceneNode( )-createChildSceneNode( Knot2Node, Vector3( 550.0f, -10.0f, 50.0f ) ); node-attachObject( ent ); node-setScale( 0.1f, 0.1f, 0.1f ); ent = mSceneMgr-createEntity( Knot3, knot.mesh ); node = mSceneMgr-getR

16、ootSceneNode( )-createChildSceneNode( Knot3Node, Vector3(-100.0f, -10.0f,-200.0f ) ); node-attachObject( ent ); node-setScale( 0.1f, 0.1f, 0.1f );最后,我们要创建一个摄像机从适合的角度来观察它。我们来把摄像机移动到更多的位置。 / Set the camera to look at our handywork mCamera-setPosition( 90.0f, 280.0f, 535.0f ); mCamera-pitch( Degree(-30

17、.0f) ); mCamera-yaw( Degree(-15.0f) );现在编译并运行代码。你应该能看到这个样子: 1 在进入下一个部分之前,注意一下MoveDemoListener的构造器,它在MoveDemoApplication:createFrameListener方法里的第一行被调用。除了传入BaseFrameListener的标准参数,还有场景节点、实体、双端队列。 动画 现在我们来设置一些基本的动画。在Ogre里动画是非常简单的。要做的话,你需要从实体对象里获取AnimationState,设置它的选项,并激活它。这样就能使动画活动起来,但你还必须在每一帧后给它添加时间,才能

18、让动画动起来。我们设置成每次移动一步。首先,找到MoveDemoListener的构造器,并添加以下代码: / Set idle animation mAnimationState = ent-getAnimationState(Idle); mAnimationState-setLoop(true); mAnimationState-setEnabled(true);第二行从实体中获取到了AnimationState。第三行我们调用setLoop( true ),让动画不停地循环。而在一些动画里(比如死亡动画),我们可能要把这个设置为false。第四行才把这个动画真正激活。但等等.我们从哪里

19、获取的“Idle”?这个魔术般的常量是怎么飞到这里来的?每个mesh都有它们自己定义的动画集。为了能够查看某个mesh的全部动画,你需要下载OgreMeshViewer才能看到。 现在,如果我们编译并运行这个demo,我们看见了.nothing! 这是因为我们还需要在每一帧里根据时间来更新这个动画的状态。找到MoveDemoListener:frameStarted方法,在方法的开头添加这一行: mAnimationState-addTime(evt.timeSinceLastFrame);现在来编译并运行程序。你应该可以看了一个机器人正在原地踏步了。 移动角色 现在我们执行棘手的任务,开始让

20、这个机器人从一点走到另一点。在我们开始之前,我想介绍一下保存在MoveDemoListener类里的成员变量。我们将使用4个变量来完成移动机器人的任务。首先,我们把机器人移动的方向保存到mDirection里面。我们再把当前机器人前往的目的地保存在mDestination里。然后在mDistance保存机器人离目的地的距离。最后,在mWalkSpeed里我们保存机器人的移动速度。 首先清空MoveDemoListener构造器,我们会用稍微不同的代码来替换。我们要做的第一件事是设置这个类的变量。我们将把行走速度设为每秒35个单位。有一个大问题要注意,我们故意把mDirection设成零向量,因

21、为后面我们会用它来判断机器人是否正在行走。 / Set default values for variables mWalkSpeed = 35.0f; mDirection = Vector3:ZERO;好了,搞定了。我们要让机器人动起来。为了让机器人移动,我们只须告诉它改变动画。然而,我们只想要若存在另一个要移动到的地点,就让机器人开始移动。为了这个目的,我们调用nextLocation 函数。把代码加到MoveDemoListener:frameStarted方法的顶部,在调用AnimationState:addTime之前: if (mDirection = Vector3:ZERO)

22、 if (nextLocation() / Set walking animation mAnimationState = mEntity-getAnimationState(Walk); mAnimationState-setLoop(true); mAnimationState-setEnabled(true); 如果你现在编译并运行,这个机器人将原地行走。这是由于机器人是以ZERO方向出发的,而我们的MoveDemoListener:nextLocation函数总是返回true。在后面的步骤中,我们将给MoveDemoListener:nextLocation函数添加更多的一点智能。 现

23、在,我们准备要真正在场景里移动机器人了。为了这样做,我们需要在每一帧里让我移动一点点。找到MoveDemoListener:frameStarted方法,我们将在调用AnimationState:addTime之前,我们先前的if语句之后,添加以下代码。这段代码将处理当机器人实际移动的情况;mDirection != Vector3:ZERO。 else Real move = mWalkSpeed * evt.timeSinceLastFrame; mDistance -= move;现在,我们要检测一下我们是否“走过”了目标地点。即,如果现在mDistance小于0,我们需要“跳”到这点上

24、,并设置移动到下一个地点。注意,我们把mDirection设置成零向量。如果nextLocation方法不改变mDirection(即没有其它地方可去),我们就不再四处移动了。 if (mDistance setPosition(mDestination); mDirection = Vector3:ZERO;现在我们移动到了这个点,我们需要设置运动到下一个点。只要我们知道有否需要移动到下一个地点,我们就能设置正确的动画;如果有其它地点要去,就行走。如果没有其它目的地,则停滞。 / Set animation based on if the robot has another point to

25、 walk to. if (! nextLocation() / Set Idle animation mAnimationState = mEntity-getAnimationState(Idle); mAnimationState-setLoop(true); mAnimationState-setEnabled(true); else / Rotation Code will go here later 注意,如果queue里已经没有更多的地点要走的话,我们没有必要再次设置行走动画。既然机器人已经在行走了,没有必要再告诉他这么做。然而,如果机器人还要走向另一个地点,我们就要把它旋转以面

26、对那个地点。现在,我们在else括号旁边留下注释占位符;记住这个地点,因为我们后面还要回来。 这里考虑的是当我们离目标地点很近的时候。现在我们需要处理一般情况,当我们正在到达而没有到达的时候。为此,我们在机器人的行走方向上对它进行平移,用move变量指定的值。通过添加以下代码来实现: else mNode-translate(mDirection * move); / else / if我们差不多做完了,除了还要设置运动需要的变量。如果我们正确地设置了运动变量,我们的机器人就会朝它该去的方向行走。看看MoveDemoListener:nextLocation方法,如果我们用完了所有的地点,它返

27、回false。这是函数的第一行。(注意你要保留函数底部的return true语句) if (mWalkList.empty() return false;现在我们来设置变量。首先我们从双端队列里取出一个向量。通过目标向量减去场景节点的当前向量,我们得取方向向量。然而我们仍有一个问题,还记得我们要在frameStarted方法里用mDirection乘以移动量吗?如果我们这么做,我们必须把方向向量转换成单位向量(即,它的长度等于一)。normalise函数为我们做了这些事,并返回向量的原始长度。唾手可得,我们需要设置到目的地的距离。 mDestination = mWalkList.front()

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1