登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

聊天机器

Chatbot's private blog

 
 
 

日志

 
 

SceneNode, Entity, SceneManager  

2010-01-12 15:32:56|  分类: 程序理论 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

原始作者:Clay Culver

中文译者:Antking

  OGRE教程(一)

  OGRE教程(二)

注意:这篇文章是针对OGRE 1.0.0,如果你使用其他的版本,如果遇到问题请到论坛中讨论

目录

1 读者对象

2 简介

3 如何开始

4 OGRE如何工作

  4.1 SceneManager 基础

  4.2 Entity 基础

  4.3 SceneNode 基础

5 你的第一个OGRE程序

6 坐标和向量

7 添加另一个物体

8 Entities more in Depth

9 SceneNodes more in Depth

10 尝试

  10.1 Scale(变换)

  10.2 旋转

11 总结

12 你的想法?

http://en.wikipedia.org/wiki/Vector_%28spatial%29

笔者注:我建议大家在学习3D编程知识之前,看一下《线形代数》,《空间解析几何》。

关于向量的数学知识在以后的学习中将发挥重要的作用。

7 添加另一个物体

  前面,我们讲解了坐标系统的作用,下面我们回到我们的代码中来。在前面,我们添加的代码中,我们并没有明确表明我们的机器人出现的坐标。但在OGRE中,有许多的函数可以初始坐标。例如:

  SceneNode::createChildSceneNode 成员函数中,有三个参数:SceneNode的名字,SceneNode的坐标,和SceneNode的基本旋转。对于坐标,正如你所看到的,我们初始时为(0,0,0)。现在,我们建立另一个SceneNode,但是这次我们表明他的坐标为另一个值:

Entity *ent2 = mSceneMgr->createEntity( "Robot2", "robot.mesh" );

SceneNode *node2 = mSceneMgr->getRootSceneNode()->createChildSceneNode( "RobotNode2", Vector3( 50, 0, 0 ) );

node2->attachObject( ent2 );

  这看起来和前面我们定义的一样,只是有轻微的变化。首先,我们命名网格和SceneNode时,有很小的不同。第二件不同的是我们初始网格开始的位置偏离了根SceneNode50个单位(记住SceneNode所有的坐标和他们的父节点有关)。编译并运行,现在,你有两个机器人。

8 Entities more in Depth(深入Entities)

  Entities类功能非常强大,我在这里并不想覆盖的太宽,只讲一下他的基本。首先,我们不得不提一下Entities中的一些功能强大的成员函数。

  第一个是Entity::setVisible 和Entity::isVisible.你能把任何Entity 设置成可视。如果你需要先隐藏Entity ,然后又显示它,你可以不调用这个函数,而采用先删除Entity ,显示时又从新建立他。物体的网格和文理自动拷贝到内存中,不需要你自己保存他们。你需要保存的是Entity物体的建立和删除的东西。

  getName函数用于返回Entity的名字,getParentSceneNode函数用于返回与Entity相关的SceneNode。

9 SceneNodes more in Depth

  SceneNode 类非常复杂。在SceneNodes 上有许多的事情可以做,因此,我们在这里只覆盖到一些通用的功能。

  你能用SceneNode的getPosition,setPosition函数得到和设置SceneNode的点(通常和SceneNode的父节点有关)。你能用translate函数移动物体。

  SceneNode不仅能设置位置,还能管理物体的变换大小和旋转。你能设置变换大小用scale函数。你能用yaw,roll,pitch旋转物体。你也能用resetOrientation函数设置物体的旋转参数。你还能用setOrientation,getOrientation,rotate函数实现高质量的旋转。

  我们再来看一下attachObject函数,如果你想把物体系到SceneNode点上,这些相关函数将非常有用:numAttachedObjects,getAttachedObject(这个函数有多个版本),detatchObject(也有多个版本),detatchAllObjects.也有整个一组函数处理父和子SceneNode。

  所有的坐标和父SceneNode节点相关,我们能做两个相互移动的SceneNode节点。下面有一段代码:

Entity *ent1 = mSceneMgr->createEntity( "Robot", "robot.mesh" );

SceneNode *node1 = mSceneMgr->getRootSceneNode()->createChildSceneNode( "RobotNode" );

node1->attachObject( ent1 );

Entity *ent2 = mSceneMgr->createEntity( "Robot2", "robot.mesh" );

SceneNode *node2 = mSceneMgr->getRootSceneNode()->createChildSceneNode( "RobotNode2", Vector3( 50, 0, 0 ) );

node2->attachObject( ent2 );

如果我们把第六行:

SceneNode *node2 = mSceneMgr->getRootSceneNode()->createChildSceneNode( "RobotNode2", Vector3( 50, 0, 0 ) );

变化如下:

SceneNode *node2 = node1->createChildSceneNode( "RobotNode2", Vector3( 50, 0, 0 ) );

然后把RobotNode2 作为RobotNode的子节点。如果你移动node1就将移动node2.例如,下面的代码移动RobotNode2 :

node2->translate( Vector3( 10, 0, 10 ) );

下面的代码可以移动RobotNode,因为RobotNode2是RobotNode的子节点,RobotNode2也将跟随移动:

node1->translate( Vector3( 25, 0, 0 ) );

  如果,你在这里有麻烦,我们可以理解成从根SceneNode 自顶向下。在这里,我们开始node1从(0,0,0),然后转移到(25,0,0),因此,node1的坐标为(25,0,0)。node2开始在(50,0,0),加上(10,0,0)。因此新坐标为(60,0,10)。

  现在,让我们来计算这些物体的真正坐标。从根SceneNode 节点开始,他的位置总是(0,0,0)。现在,node1的坐标为(root+node1):(0,0,0)+(25,0,0)=(25, 0, 0). 而node2是node1子节点,因此,他的坐标为(root + node1 + node2): (0, 0, 0) + (25, 0, 0) + (60, 0, 10) = (85, 0, 10). 这只是描述关于SceneNode坐标层次的一个例子。

  你能通过getSceneNode,getEntity函数得到SceneNodes and Entities 的名字。这两个函数是SceneManager中的方法,因此,你不需要在你建立的每个SceneNode中保持一个指针。你只需要悬挂你经常用的那个。

10 尝试

  通过这章的学习,我们学习了Entities, SceneNodes, and the SceneManager. 的基本知识。下面,我将给出他们的一些例程。在这个例子中,我们在场景中建立一组机器人。

Scale

下面的代码是通过SceneNode中的scale函数旋转网格。

Entity *ent = mSceneMgr->createEntity( "Robot", "robot.mesh" );

SceneNode *node = mSceneMgr->getRootSceneNode()->createChildSceneNode( "RobotNode" );

node->attachObject( ent );

node->scale( .5, 1, 2 );

ent = mSceneMgr->createEntity( "Robot2", "robot.mesh" );

node = mSceneMgr->getRootSceneNode()->createChildSceneNode( "RobotNode2", Vector3( 50, 0, 0 ) );

node->attachObject( ent );

node->scale( 1, 2, 1 );

旋转

下面的代码是通过角度和半径,用the yaw, pitch, and roll 函数旋转物体。

Entity *ent = mSceneMgr->createEntity( "Robot", "robot.mesh" );

SceneNode *node = mSceneMgr->getRootSceneNode()->createChildSceneNode( "RobotNode", Vector3( -100, 0, 0 ) );

node->attachObject( ent );

node->yaw( Degree( -90 ) );

ent = mSceneMgr->createEntity( "Robot2", "robot.mesh" );

node = mSceneMgr->getRootSceneNode()->createChildSceneNode( "RobotNode2");

node->attachObject( ent );

node->pitch( Degree( -90 ) );

ent = mSceneMgr->createEntity( "Robot3", "robot.mesh" );

node = mSceneMgr->getRootSceneNode()->createChildSceneNode( "RobotNode3", Vector3( 100, 0, 0 ) );

node->attachObject( ent );

node->roll( Degree( -90 ) );

11 总结

  在一章中,我们学习了一些关于SceneManager, SceneNode, and Entity 类的基本知识。但对文中提到的函数,不是很了解,在下一章中,我们将详细讲解这些函数。

  评论这张
 
阅读(320)| 评论(2)

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018