OSG的Dragger系统架构与算法分析090413.doc_第1页
OSG的Dragger系统架构与算法分析090413.doc_第2页
OSG的Dragger系统架构与算法分析090413.doc_第3页
OSG的Dragger系统架构与算法分析090413.doc_第4页
OSG的Dragger系统架构与算法分析090413.doc_第5页
已阅读5页,还剩3页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

OSG的Dragger系统架构与算法分析 (magicstone & Simbaforrest)开放合作很高兴能够和Simbaforrest筒子合作,让我们开放合作来把大家对于OSG的分析记录下来,对于OSG的在国内的普及和让OSG服务于国内的软件行业的发展敬一份微薄的力量。同时也在这里倡议大家能够一起来把OSG的分析合作整理出来,发挥各自的力量!Dragger系统作用论述Dragger系统主要用来对模型空间位移信息的编辑,这个系统在3D空间的场景中给美术创作人员起到很大的帮助。Dragger算法原理简述Dragger主要是将用户在屏幕窗口的鼠标消息,通过对应的Projector算法来求出各种类型Projector对应的空间位置,这样记录用户的屏幕窗口消息的变化,求出3D空间中位移的变化,得出用户对3D模型在空间中位移变化的操作。Dragger程序架构主体架构Dragger系统架构信息处理描述聚合了所有的各种类型的Dragger,是Dragger系统的核心,其在Dragger系统中的作用是处理外设的输入消息。通过算法,将鼠标的窗口坐标信息转换到PointInfo结构信息。根据鼠标的点击事件类型,转换到对应的Dragger事件类型,同时根据鼠标点击选择拣选出选中的Dragger来处理,根据多态的机制,对应有具体的类型Dragger来具体处理。每个Dragger对应有自身的窗口屏幕鼠标位移到3D坐标空间的位移的Projector映射算法,通过Projector算出来此次位移的3D空间位置或者旋转量,此后通过Command命令模式,将具体的Dragger空间相对变换量,打包到具体的Command中去,然后由CommandManager来负责将各种类型的Command调用其执行命令接口,其实就是将其自身传递到Selection处理Command接口处理。Selection中接受到各种不同命令时,根据命令不同获取命令空间的变化量信息,将Selection对象空间做位移。上面大致描述了Dragger系统的运作,具体其实可以用动态图来具体呈现,但是其实这个系统挺简单的,所以也就简单描述下,相信有些程序经验的也都能明白_。Selection架构与作用论述从Selection类的继承层次关系我们就可以看出来,从Selection名字顾名思义也可以看出来,Selection是用来在场景中被选中并做3D空间位移与外部交互的类。该类还可以是一个场景图的组,可以加入和管理其他的子节点。该类函数处理各种空间位移命令,也即把各种空间位移命令中记录的空间位移变化信息使用到该节点的空间变化中来。Command架构与作用论述记录各种类型的空间位移变化量,采用了命令模式。Constraint架构与作用论述约束器对于空间位移起到移动的约束作用,比如位移需要按照2个单位来位移,那么就可以对具体的Command中的空间位移变化数据来做修改操作,从而起到约束的作用,在这里不得不说OSG设计采用了很多好的模式啦_。Projector架构与作用论述Projector用来对窗口屏幕的2D坐标根据一定得规则映射到具体的3D坐标,看上图可以发现有很多种的Projector映射模式,线的,面得,球的等等,这些是2D屏幕坐标转换到3D空间坐标的具体规则类型。具体的算法分析还得看 Simbaforrest筒子的分析,_,当然这些具体的算法是本Dragger系统的最最核心的技术,看Simbaforrest筒子的努力啦。Simbaforrest:好,那我就继续班门弄斧一回:)Dragger中的Projector花开两朵,各表一枝,各位看官应该还记得上回(见OSG拖拽器 Dragger简介之二PointerInfo)我们说要到Translate1DDragger中的handle函数看PointerInfo用法,结果发现其中的Projector才是真正的主角,不错,我们今天就先来好好看看这个handle中的Projector到底是何方神圣。来到Translate1DDragger:handle中,可以看到函数主体框架如下:switch (ea.getEventType()/ Pick start.case (osgGA:GUIEventAdapter:PUSH): 1If(2) 3/Pick movecase(osgGA:GUIEventAdapter:DRAG): If(2) 3/Pick finishcase(osgGA:GUIEventAdapter:RELEASE): If(2) 3其中“*”的字样表示该部分使用了Projector。“1”中的语句作了这么一个简单的事情:获得本Dragger到世界坐标系的变换矩阵localToWorld;“2”中的语句是重头戏,调用了Projector的project函数,虽然我们现在还不太清楚这个函数是干啥的,但是大概可以猜到:它通过第一个参数PointerInfo中的信息,进行一些计算,得到一个3维点通过第二个参数传出。其具体原理,我们待会再说;“3”中的调用Projector的语句就是A piece of cake了,不过它是配合着MotionCommand使用的,具体如何使用这里就不详细说了。看了这些,各位应该对Projector有了一个初步的认识,接下来我们就进入正题,来看“另一支花”Projector。Projector类概述来到Projector头文件Projector类,跳过其他简单函数,我们看到这样的注释:/* * Calculates the object/world coordinates (projectedPoint) of a window * coordinate (pointToProject) when projected onto some shape or * geometry (implemented in derived classes). SceneView in used for i * projecting window coordinates into object coordinates and vice versa. * Returns true on successful projection.*/* * 当某一个窗口坐标(pointToProject)投影到某个形状或是几何体上时, * 计算该窗口坐标对应的模型/世界坐标(该方法在子类中实现)。 * 成功投影则返回true*/ virtual bool project(const PointerInfo& pi, osg:Vec3& projectedPoint) const = 0;好吧,为了看看Projector:project到底怎么用,我们去看看其子类LineProjector中的实现(Translate1DDragger中使用的即是LineProjector):bool LineProjector:project(const PointerInfo& pi, osg:Vec3& projectedPoint) const if (!_line-valid() osg:notify(osg:WARN) Warning: Invalid line set. LineProjector:project() failed.std:endl; return false; / Transform the line to world/object coordinate space./由成员line及设置好的LocalToWorld矩阵获得其在世界坐标系下的对应objectLine osg:ref_ptr objectLine = new osg:LineSegment; objectLine-mult(*_line, getLocalToWorld();/ Get the near and far points for the mouse point./获得鼠标的远近点,这下我们就知道PointerInfo中为什么要记录这个信息了 osg:Vec3 nearPoint, farPoint; pi.getNearFarPoints(nearPoint,farPoint); osg:ref_ptr pointerLine = new osg:LineSegment(nearPoint,farPoint);/又新建一条线段pointerLine,从鼠标近点指向远点/求得objectLine上距离pointerLine最近的点closestPtLine,注意,因为是线段,所/以有最近点;若两线段平行,返回false osg:Vec3 closestPtLine, closestPtProjWorkingLine; if (! computeClosestPoints(*objectLine, *pointerLine, closestPtLine, closestPtProjWorkingLine)/这个函数的具体算法这里就不细说了,有兴趣的可以自己推一下,或者Google之 return false;/由于求得的是世界坐标系下的坐标,通过WorldToLocal矩阵反算出局部坐标系下/的最近点 osg:Vec3 localClosestPtLine = closestPtLine * getWorldToLocal();/所以说,传出参数projectedPoint是鼠标点到的LineSegment上最近的点 projectedPoint = localClosestPtLine; return true;我们进一步通过图示来解释:Dragger架构与作用论述Dragger类的设计看上去倒是很简单了,主要是两种,一种是直接继承自Dragger的子类,这种子类通过自己的handle函数接口直接处理了鼠标外设消息,算出空间的位移转换信息,并且调动了Command系统和Projector系统来运

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论