接着上篇写

http://www.cnblogs.com/songliquan/p/3294902.html

  旋转

这里有必要看一下关于旋转的源代码:

   virtual void pitch(const Radian& angle, TransformSpace relativeTo = TS_LOCAL);

   virtual void yaw(const Radian& angle, TransformSpace relativeTo = TS_LOCAL);

   virtual void roll(const Radian& angle, TransformSpace relativeTo = TS_LOCAL);

   virtual void translate(const Matrix3& axes, Real x, Real y, Real z, TransformSpace relativeTo = TS_PARENT);

  由以上代码可看出,pitch,yaw,roll旋转是默认是按照局部坐标空间旋转的,而translate则是默认按照父空间坐标平移的。这样下面理解就简单了。

 

 将createScene()的代码删除,为实现旋转,可添加如下代码:

      //旋转
2 //1 原始状态,未旋转
Ogre::Entity *ent1 = mSceneMgr->createEntity("penguin","penguin.mesh");//
Ogre::SceneNode *node1 = mSceneMgr->getRootSceneNode()->createChildSceneNode();//
node1->setPosition(-,,);//设置位置
node1->attachObject(ent1);//添加到场景节点
//2 向右平移,并绕X轴旋转90度
Ogre::Entity *ent2 = mSceneMgr->createEntity("penguin","penguin.mesh");//
Ogre::SceneNode *node2 = mSceneMgr->getRootSceneNode()->createChildSceneNode();//
node2->attachObject(ent2);//
node2->translate(-,,);//平移到(-20,0,0)
node2->pitch(Ogre::Radian(Ogre::Math::HALF_PI));//绕着x轴旋转90度
//3 设置位置,并绕Y轴旋转90度
Ogre::Entity *ent3 = mSceneMgr->createEntity("penguin","penguin.mesh");//
Ogre::SceneNode *node3 = mSceneMgr->getRootSceneNode()->createChildSceneNode();//
node3->setPosition(,,);//
node3->yaw(Ogre::Degree(90.0f));//绕着y主旋转90度
node3->attachObject(ent3);
//4 设置位置,并绕Z轴旋转90度
Ogre::Entity *ent4 = mSceneMgr->createEntity("penguin","penguin.mesh");//
Ogre::SceneNode *node4 = mSceneMgr->getRootSceneNode()->createChildSceneNode();//
node4->setPosition(,,);
node4->roll(Ogre::Radian(-Ogre::Math::HALF_PI));//绕着z轴旋转90度
node4->attachObject(ent4);//

  效果如下:可看到四个小企鹅:  

  代码解释:

  pitch() 让节点绕着x轴绕着逆时针方向旋转90度,c参数Radian代表弧度,math代表数学类,而HALP_PI代表弧度为90。

  yaw() 绕y轴旋转指定的度数,Degree代表角度类

  roll() 绕z轴旋转指定的角度,参数如上

  缩放

  代码如下,主要用到scale()函数

         //缩放比例
//1 原始比例
Ogre::Entity *ent1 = mSceneMgr->createEntity("penguin1","penguin.mesh");
Ogre::SceneNode * node1 = mSceneMgr->getRootSceneNode()->createChildSceneNode();//创建子节点
node1->setPosition(,,);
node1->attachObject(ent1);//将实体对象绑定到场景节点
//2 放大2倍
Ogre::Entity *ent2 = mSceneMgr->createEntity("penguin2","penguin.mesh");
Ogre::SceneNode *node2 = mSceneMgr->getRootSceneNode()->createChildSceneNode();//创建子场景节点
node2->setPosition(,,);
node2->scale(,,);//放大2倍
node2->attachObject(ent2);//将实体对象绑定到场景节点
//3 缩小一半
Ogre::Entity *ent3 = mSceneMgr->createEntity("penguin3","penguin.mesh");
Ogre::SceneNode *node3 = mSceneMgr->getRootSceneNode()->createChildSceneNode();//创建子场景节点
node3->setPosition(-,,);
node3->scale(0.5,0.5,0.5);//缩小一半
node3->attachObject(ent3);//将实体对象绑定到场景节点

  效果如图:

  代码解释:

  scale() --- 对实体进行缩放,参数也比较简单。

 

 空间变换

  世界坐标空间和父坐标空间的变换:

         //空间坐标
//1 节点1
Ogre::Entity *ent1 = mSceneMgr->createEntity("Sinbad1","Sinbad.mesh");
Ogre::SceneNode * node1 = mSceneMgr->createSceneNode("node1");//创建节点
node1->setPosition(,,);
node1->yaw(Ogre::Degree(180.0f));//旋转180度,节点1 z轴方向指向屏幕内
mSceneMgr->getRootSceneNode()->addChild(node1);
node1->attachObject(ent1);//将实体对象绑定到场景节点
//2 节点2
Ogre::Entity *ent2 = mSceneMgr->createEntity("Sinbad2","Sinbad.mesh");
Ogre::SceneNode *node2 = node1->createChildSceneNode("node2");//创建子场景节点
node2->setPosition(,,);
//node2->translate(0,0,20,Node::TS_WORLD);//相对于世界坐标空间,而世界坐标空间始终指向屏幕外,故向指向屏幕方向移动20单位
14 node2->translate(0,0,20);//相对于父节点移动,而node1 z轴方向指向屏幕内,故屏幕内移动20单位

node2->attachObject(ent2);//将实体对象绑定到场景节点  

 效果如图 node2->translate(0,0,20);这样的话是相对于父节点移动,而node1 z轴方向指向屏幕内,故屏幕内移动20单位。

  将代码改为node2->translate(0,0,20,Node::TS_WORLD);这样是相对于世界坐标空间,而世界坐标空间始终指向屏幕外,故向指向屏幕方向移动20单位。效果如图:

 局部坐标空间和父坐标空间

  局部坐标空间 ---- 是针对模型自身的,可用一下代码实验。

  代码如下:

         //局部坐标空间变换
Ogre::Entity *ent1 = mSceneMgr->createEntity("Sinbad1","Sinbad.mesh");
Ogre::SceneNode * node1 = mSceneMgr->createSceneNode("node1");//创建节点
node1->setPosition(,,);
node1->yaw(Ogre::Degree(180.0f));//绕y轴顺时针旋转180度,节点1 z轴方向指向屏幕内
node1->pitch(Ogre::Degree(-90.0f));//绕x轴顺时针旋转90度
mSceneMgr->getRootSceneNode()->addChild(node1);
node1->attachObject(ent1);//将实体对象绑定到场景节点 Ogre::Entity *ent2 = mSceneMgr->createEntity("Sinbad2","Sinbad.mesh");
Ogre::SceneNode *node2 = node1->createChildSceneNode("node2");
node2->yaw(Ogre::Degree());//绕y轴旋转45度
node2->translate(,,);//沿z轴正方向平移20 单位,以父坐标空间为基准
node2->attachObject(ent2); Ogre::Entity*ent3 =mSceneMgr->createEntity("ent3","Sinbad.mesh");
Ogre::SceneNode*node3 =node1->createChildSceneNode("node3");
node3->yaw(Ogre::Degree());//绕y轴旋转45度
node3->translate(,,,Ogre::Node::TS_LOCAL);//以自身坐标空间为基准,沿下图中箭头所指方向平移20单位
node3->attachObject(ent3);

  效果图如下:

代码解释:

  可以这样比喻,第一人首先向后转,然后我们切换视角,从上往下看,然后第二人在第一人的基础上直走20单位,而第三人在第一人的基础上,自己先左转了45度,然后直走20单位。

  

  这个空间旋转太绕了,迷了一天终于迷过来了。原来如此。

 

ogre3D程序实例解析1-平移旋转与缩放的更多相关文章

  1. 实验与作业(Python)-03 Python程序实例解析

    截止日期: 要求: 下周实验课前上交,做好后在实验课上检查可获取平时分. 做出进阶或选做的的请用清晰的标致标识出来,方便老师批改 本次作业:可提交也可不提交.作业算平时成绩. 本次作业内容量较大,请组 ...

  2. 实验与作业(Python)-03 Python程序实例解析(函数、循环、range、turtle)

    截止日期: 要求: 下周实验课前上交,做好后在实验课上检查可获取平时分. 做出进阶或选做的的请用清晰的标致标识出来,方便老师批改 本次作业:可提交也可不提交.作业算平时成绩. 本次作业内容量较大,请组 ...

  3. Python语言程序设计基础(2)—— Python程序实例解析

    温度转换 def tempConvert(ValueStr): if ValueStr[-1] in ['F','f']: ans = (eval(ValueStr[0:-1]) - 32)/1.8 ...

  4. [ Python ] Flask 基于 Web开发 大型程序的结构实例解析

    作为一个编程入门新手,Flask是我接触到的第一个Web框架.想要深入学习,就从<FlaskWeb开发:基于Python的Web应用开发实战>这本书入手,本书由于是翻译过来的中文版,理解起 ...

  5. 【转载】Unity中矩阵的平移、旋转、缩放

    By:克森 简介 在这篇文章中,我们将会学到几个概念:平移矩阵.旋转矩阵.缩放矩阵.在学这几个基本概念的同时,我们会用到 Mesh(网格).数学运算.4x4矩阵的一些简单的操作.但由于克森也是新手,文 ...

  6. exec函数族实例解析

    exec函数族实例解析 fork()函数通过系统调用创建一个与原来进程(父进程)几乎完全相同的进程(子进程是父进程的副本,它将获得父进程数据空间.堆.栈等资源的副本.注意,子进程持有的是上述存储空间的 ...

  7. [Reprint]C++普通函数指针与成员函数指针实例解析

    这篇文章主要介绍了C++普通函数指针与成员函数指针,很重要的知识点,需要的朋友可以参考下   C++的函数指针(function pointer)是通过指向函数的指针间接调用函数.相信很多人对指向一般 ...

  8. Android实例-Delphi开发蓝牙官方实例解析(XE10+小米2+小米5)

    相关资料:1.http://blog.csdn.net/laorenshen/article/details/411498032.http://www.cnblogs.com/findumars/p/ ...

  9. Android开发之IPC进程间通信-AIDL介绍及实例解析

    一.IPC进程间通信 IPC是进程间通信方法的统称,Linux IPC包括以下方法,Android的进程间通信主要采用是哪些方法呢? 1. 管道(Pipe)及有名管道(named pipe):管道可用 ...

随机推荐

  1. Spring 基础知识 - 依赖注入

    所谓的依赖注入是指容器负责创建对象和维护对象间的依赖关系,而不是通过对象本身负责自己的创建和解决自己的依赖. 依赖注入主要目的是为了解耦,体现了一种“组合”的理念. 无论是xml配置.注解配置还是Ja ...

  2. css样式优先级问题

    官方表述的CSS样式优先级如下: 通用选择器(*) < 元素(类型)选择器 < 类选择器 < 属性选择器 < 伪类 < ID 选择器 < 内联样式 那么,我们来举个 ...

  3. 为什么要用mallloc

    为什么要用malloc函数申请内存空间? 有的程序往往在运行时才知道要动态分配多大的内存,例如: void foo(char *str, int n) { char buf[?]; strncpy(b ...

  4. 重写strcat函数,以实现strcat的功能

    char * strcatTest(char *dst,const char *src);Action(){ char a[]="come on"; char b[]=" ...

  5. ThreadLocal的内存泄露

    ThreadLocal的目的就是为每一个使用ThreadLocal的线程都提供一个值,让该值和使用它的线程绑定,当然每一个线程都可以独立地改变它绑定的值.如果需要隔离多个线程之间的共享冲突,可以使用T ...

  6. Python + selenium之组织unittest单元测试用例

    当增加被测功能和相应的测试用例之后unittest单元测试框架如何扩展和组织新增的测试用例的. # coding =utf-8 # calculator class Count (): def __i ...

  7. linux下杀毒工具clamav

    ClamAV 杀毒是Linux平台最受欢迎的杀毒软件,ClamAV属于免费开源产品,支持多种平台,如:Linux/Unix.MAC OS X.Windows.OpenVMS.ClamAV是基于病毒扫描 ...

  8. 有关mybatis的动态sql

    一般地,实现动态SQL都是在xml中使用等标签实现的. 我们在这里使用SQL构造器的方式, 即由abstract sql写出sql的过程, 当然感觉本质上还是一个StringBuilder, 来手动生 ...

  9. MVC的验证码

    后台: /// <summary> /// 创建验证码的图片 /// </summary> /// <param name="validateCode" ...

  10. UVA11090 Going in Cycle (二分+判负环)

    二分法+spfa判负环.如果存在一个环sum(wi)<k*x,i=0,1,2...,k,那么每条边减去x以后会形成负环.因此可用spfa来判负环. 一般spfa判负环dfs最快,用stack次之 ...