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

加入VIP,免费下载
 

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

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

下载须知

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

版权提示 | 免责声明

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

新版第四章场景的节点与数据结构课件doc.docx

1、新版第四章场景的节点与数据结构课件doc第四章 场景的节点与数据结构 如果将场景比作房间,那么场景的节点就是房间里的床、桌、灯、柜等设施。著名的3D软件开发工具Open Inventor将应用程序抽象成“a scene graph plus a set of actions”,所有的图形对象、属性、事件响应全由场景的节点来处理,十分适合于图形的交互式绘制。Intra3D 2.0借鉴了Open Inventor的节点设计。本章讲述Intra3D 2.0的节点基类、形体节点、相机节点、光源节点和组节点的设计与实现。4.1 场景图与节点的概念从数据结构角度讲,场景是一个有向无环图,称为Scene G

2、raph。场景的交互式绘制就是对Scene Graph各个节点的遍历绘制。节点可分为组节点与叶子节点两大类,Scene Graph的根节点总是组节点。以下“伪代码”用于创建图4.1所示的Scene Graph :图4.1 Scene Graph 的组节点与叶子节点 GroupNode *node1 = new GroupNode ; GroupNode *node2 = new GroupNode ; GroupNode *node4 = new GroupNode ; GroupNode *node7 = new GroupNode ; LeafNode *node3 = new LeafN

3、ode ; LeafNode *node5 = new LeafNode ; LeafNode *node6 = new LeafNode ; LeafNode *node8 = new LeafNode ; LeafNode *node9 = new LeafNode ; LeafNode *node10 = new LeafNode ; node1-AddChild(node2); node1-AddChild(node6); node1-AddChild(node7); node1-AddChild(node9); node1-AddChild(node10); node2-AddChi

4、ld(node3); node2-AddChild(node4); node4-AddChild(node5); node7-AddChild(node8); 如果用深度优先的方法遍历图4.1的Scene Graph,则节点的遍历顺序是1、2、3、4、5、6、7、8、9与10。 Scene Grpah 中的叶子节点可以被多个组节点引用,如图4.2所示。当Scene Grpah比较复杂时,节点之间的引用关系也变得复杂,因此Scene Grpah需要用“对象引用计数”方法来管理节点的内存(见2.5节)。节点可以显式使用new来创建,但不可显式使用delete删除节点,应该用节点的Release函数

5、。图4.2 叶子节点可以被多个组节点引用 Intra3D 将Scene Graph节点分为组节点(GroupNode),形体节点(ShapeNode),光源节点(DirLightNode、PointLightNode、SpotLightNode)和相机节点(CameraNode)。所有上述节点均从基类节点SceneNode派生。SceneNode节点中定义了坐标系与丰富的3D交互功能。由于C+类支持数据(Data)和代码(Implementation)的继承,SceneNode节点功能可以被派生类节点继承。但是COM对象仅支持接口继承(本质上是继承虚函数的声明),不支持数据和代码的继承。只能在

6、派生节点中包容ISceneNode并将ISceneNode的函数重新封装为当前节点的函数。COM库中的节点程序要比C+类库的复杂,4.3节将以ShapeNode为例分别论述类与COM对象的程序设计。 相机是否该成为一种节点是值得商讨的话题。直观地讲,相机等同于观察者的眼睛,的确不是场景的组成部分。如果应用程序不涉及相机的交互,那么只需调用OpenGL的几个投影函数就可以实现图形学概念中的相机变换(请参考 Intra3D 的Window3D程序)。如果应用程序涉及复杂的相机交互,例如多个相机的切换,场景的漫游;此时将相机作为节点插入Scene Graph中,可以享用到在SceneNode定义的交

7、互功能(请参考 Intra3D 的SceneView程序)。使用了相机节点的SceneView程序要比不使用相机节点的 Window3D程序复杂。4.2 场 景 节 点 的 基 类C+类库中的SceneNode程序见Intra3D-DLLIncludeLayer3SceneNode.h和Intra3D-DLLLayer3SceneNode.cpp。COM库的程序见Intra3D-COMLayer3SceneNode.h和SceneNode.cpp。本节主要论述类SceneNode的设计。SceneNode为场景的交互式绘制提供了两大功能:一是坐标系统的定义与图形变换;二是节点的拾取与绘制。类S

8、ceneNode是Container的公有派生类,其数据结构并不复杂,但运算函数较多。其主要数据成员如下:protected: SceneNode *m_pParent ; char m_strNodeName32 ; VECTOR m_position, m_oldPosition ; ROTATION m_rotation, m_oldRotation ; VECTOR m_scale, m_oldScale ; Trackball m_trackball ; / 跟踪球 BOOL m_bSelected ; / 当前节点被拾取的标志4.2.1 坐标系统的定义与图形变换每个节点都有标定自己

9、的坐标系,称为对象坐标系(Object Coordinate System)。在2.1节已经论述了可用旋转结构(ROTATION)、平移矢量、比例矢量来确定图形变换的状态与过程。m_position、m_rotation与m_scale三个量分别表示该节点在父节点坐标系中的位置量、旋转量与比例量,执行节点的图形变换函数将改变上述量。m_oldPosition、 m_odlRotation与m_oldScale用于记录原始状态,便于恢复。节点的相互连接构成了Scene Graph,为了有统一的参照系,把Scene Graph的根节点的坐标系称为世界坐标系(World Coordinate Sys

10、tem)。场景最后投影到窗口中,即执行了相机变换。观察者用鼠标对场景节点直接拖动、旋转等操作,实质是执行了相机坐标系(Camera Coordinate System)的图形变换。因此场景的3D交互包含了节点在对象坐标系与相机坐标系的图形变换。用于定义坐标系统与图形变换的主要函数有: public: / 定义坐标系统的函数 void SetPosition(float x, float y, float z); void SetRotation(float angle, float nx, float ny, float nz); void SetScale(float sx, float s

11、y, float sz); / 对象坐标系的图形变换函数 void Translate(VECTOR trans);void Rotate(float angle, VECTOR axis); void Scale(float sx, float sy, float sz); virtual void ResetTransform(void); / 相机坐标系的图形变换函数 void TranslateInCamera(VECTOR trans); void RotateInCamera(float angle, VECTOR axis); void MouseTrackStart(int i

12、ViewportWidth, int iViewportHeight, int mx, int my); void MouseTracking(int dx, int dy); protected: / FWTO : From World Coordinate To Object Coordinate / FOTW : From Object Coordinate To World Coordinate / FCTO : From Camera To Coordinate Object Coordinate / FOTC : From Object Coordinate To Camera C

13、oordinate / 对象坐标系、世界坐标系、相机坐标系之间的顶点换算 void VertexTransform_FWTO(float *x, float *y, float *z); void VertexTransform_FOTW(float *x, float *y, float *z); void VertexTransform_FCTO(float *x, float *y, float *z); void VertexTransform_FOTC(float *x, float *y, float *z); / 对象坐标系、世界坐标系、相机坐标系之间的矢量换算 void Vec

14、torTransform_FWTO(VECTOR *V); void VectorTransform_FOTW(VECTOR *V); void VectorTransform_FCTO(VECTOR *V); void VectorTransform_FOTC(VECTOR *V); 函数SetPosition、SetRotation与SetScale用于设置该节点在父节点坐标系中的位置量、旋转量与比例量。void SceneNode:SetPosition(float x, float y, float z) m_position.x=x; m_position.y=y; m_positi

15、on.z=z; m_oldPosition=m_position; / 记录原始状态void SceneNode:SetRotation(float angle, float nx, float ny, float nz) m_rotation.angle=angle; m_rotation.axis.x=nx; m_rotation.axis.y=ny; m_rotation.axis.z=nz; VectorNormalize(&m_rotation.axis); m_oldRotation=m_rotation; / 记录原始状态void SceneNode:SetScale(float

16、 sx, float sy, float sz) m_scale.x=sx; m_scale.y=sy; m_scale.z=sz; m_oldScale=m_scale; / 记录原始状态函数Translate、Rotate与Scale用于实现对象坐标系中的平移变换、旋转变换与比例变换。ResetTransform函数用于恢复原始状态。void SceneNode:Translate(VECTOR trans) / 注意理解为什么要用 VectorTransform trans=VectorTransform(trans, m_rotation); / 见Rotation.h m_posit

17、ion.x += trans.x; m_position.y += trans.y; m_position.z += trans.z;void SceneNode:Rotate(float angle, VECTOR axis) ROTATION R(axis, angle); VectorNormalize(&R.axis); / 注意理解为什么要用 VectorTransform R.axis=VectorTransform(R.axis, m_rotation); m_rotation=m_rotation*R; / 见Rotation.hvoid SceneNode:Scale(flo

18、at sx, float sy, float sz) m_scale.x *= sx; m_scale.y *= sy; m_scale.z *= sz;void SceneNode:ResetTransform(void) / 恢复初始状态 m_position= m_oldPosition; m_rotation = m_oldRotation; m_scale = m_oldScale; TranslateInCamera与RotateInCamera是相机坐标系的平移变换与旋转变换函数。MouseTrackStart 与MouseTracking用于鼠标跟踪球交互。void Scene

19、Node:TranslateInCamera(VECTOR trans) if(GetType() != CAMERA_NODE) VectorTransform_FCTO(&trans); Translate(trans);void SceneNode:RotateInCamera(float angle, VECTOR axis) if(GetType() != CAMERA_NODE) VectorTransform_FCTO(&axis); Rotate(angle, axis);void SceneNode:MouseTrackStart(int width, int height,

20、 int mx, int my) / 计算旋转中心在窗口中的坐标 float cx=0, cy=0, cz=0; if(GetType() = CAMERA_NODE) cx=width/2.0; cy=height/2.0; else VertexTransform_ObjectToWindow(&cx, &cy, &cz); cy=height-cy; / OpenGL Window 与 MFC Window 在Y方向反向 m_trackball.SetTrackWindow(width, height, int(cx), int(cy); m_trackball.Start(mx, my

21、);void SceneNode:MouseTracking(int dx, int dy) VECTOR axis; float angle; m_trackball.Tracking(dx, dy, &axis, &angle); RotateInCamera(angle, axis);4.2.2 节点的拾取与绘制用于拾取与绘制节点的主要函数有: public: virtual SceneNode *Search(char *name)return NULL; virtual void Selected(void)m_bSelected=TRUE; virtual void Unselec

22、ted(void)m_bSelected=FALSE; virtual void Draw(void); virtual void DrawForMouseSelect(void); void LoadMatrix(void); / 在Draw, DrawForMouseSelect 之前调用 一般情况下,节点用Draw函数绘制。当场景的节点处于拾取状态时,OpenGL的绘制模式为GL_SELECT,此时要用DrawForMouseSelect函数绘制节点。在执行Draw或DrawForMouseSelect函数前,应调用LoadMatrix函数。Search、Selected、Unselec

23、ted、Draw与DrawForMouseSelect均为虚函数,具体行为由派生类定义。void SceneNode:LoadMatrix(void) glTranslatef(m_position.x, m_position.y, m_position.z); glRotatef(m_rotation.angle,m_rotation.axis.x, m_rotation.axis.y, m_rotation.axis.z); glScalef(m_scale.x, m_scale.y, m_scale.z); COM接口ISceneNode定义如下: interface ISceneNod

24、e : IDispatch HRESULT SetName(BSTR strName);HRESULT GetName(BSTR *strName);HRESULT SetPosition(float x, float y, float z);HRESULT GetPosition(out float *x, out float *y, out float *z);HRESULT SetRotation(float angle, float nx, float ny, float nz);HRESULT GetRotation(out float *angle, out float *nx,

25、out float *ny, out float *nz);HRESULT SetScale(float sx, float sy, float sz);HRESULT GetScale(out float *sx, out float *sy, out float *sz);HRESULT SetRotateStep(float fRotateStep);HRESULT GetRotateStep(out,retval float *step);HRESULT GetTranslateStep(out,retval float *step);HRESULT SetTranslateStep(

26、float fTransStep);HRESULT SetScaleStep(float fScaleStep);HRESULT GetScaleStep(out,retval float *step);HRESULT ResetTransform();HRESULT Scale(float sx, float sy, float sz);HRESULT Translate(float dx, float dy, float dz);HRESULT Rotate(float angle, float nx, float ny, float nz);HRESULT TranslateInCame

27、ra(float dx, float dy, float dz);HRESULT RotateInCamera(float angle, float nx, float ny, float nz);HRESULT MouseTrackStart(int iViewportWidth, int iViewportHeight, int mx, int my);HRESULT MouseTracking(int dx, int dy);HRESULT LoadMatrix();HRESULT LoadInverseMatrix();HRESULT LoadMatrix_FWTO();HRESULT

28、 LoadMatrix_FOTW();HRESULT VertexTransform_FWTO(in,out float *x, in,out float *y, in,out float *z);HRESULT VertexTransform_FOTW(in,out float *x, in,out float *y, in,out float *z);HRESULT VertexTransform_FCTO(in,out float *x, in,out float *y, in,out float *z);HRESULT VertexTransform_FOTC(in,out float

29、 *x, in,out float *y, in,out float *z);HRESULT SetParent(ISceneNode *node);HRESULT GetParent(out,retval ISceneNode *node);HRESULT GetType(out,retval EnumNodeType *type);HRESULT Search(BSTR name, out, retval ISceneNode *node);HRESULT Draw();HRESULT DrawForMouseSelect();HRESULT Selected();HRESULT Unse

30、lected();HRESULT IsSelected(out,retval BOOL *bFlag); ;4.3 形 体 节 点形体节点可以引用图形对象,3D交互由节点提供,绘制则由所引用的图形对象实现。这样设计可使形体节点既简单又通用。C+类库中的ShapeNode程序见Intra3D-DLL IncludeLayer3ShapeNode.h和Intra3D-DLLLayer3ShapeNode.cpp。COM库中的程序见Intra3D-COMLayer3ShapeNode.h和ShapeNode.cpp。 类ShapeNode的声明如下:class ShapeNode : public

31、SceneNodepublic: void SetBoundColor(float red, float green, float blue); void ShowBoundBox(void); void HideBoundBox(void); void SetGraphicalObject(GraphicalObject *object); virtual void Draw(void); virtual void DrawForMouseSelect(void); .protected: virtual void FinalRelease(void); / Container.hprotec

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

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