本文转至http://www.cnblogs.com/shapherd/archive/2010/08/10/osg.html
作者写的比较好,再次收藏,希望更多的人可以看到这个文章
互联网是是一个相互分形并学习的平台,我希望我每个人可以将我们认为有价值的东西,在不损害他人利益的情况下分享给更多的人。
交互过程
viewer的主要的功能是控制场景,它是场景的核心类,如果能响应键盘时得到viewer,那么也可以从键盘的响应中控制整个场景。viewer中有一个方法,名为addEventHandler就是专门做这件事情的。他会加入一个事件处理器。于是我们就想,一定要自己写一个事件处理器才行,这就必须要了解事件处理器的格式,只要有一个接口就可以了解它的格式,这个接口就是:osgGA::GUIEventHandler,于是我们可以写一个类A从该类公有派生出来,即:class A:public osgGA::GUIEventHandler,在里面处理好各种操作然后加入到viewer当中,即:viewer.addEventHadler(new A(里面可以有参数));这样就可以完成操作。
假如类A是一个事件处理类,那么加入类A可以这样理解,如图3.5:
事件类型与响应
代码 值 事件类型
NONE 0 无事件。
PUSH 1 鼠标某键按下,在上面代码28行有用到。
RELEASE 2 鼠标某键弹起。
DOUBLECLICK 4 鼠标某键双击。
DRAG 8 鼠标某键拖动。
MOVE 16 鼠标移动。
KEYDOWN 32 键盘上某键按下。
KEYUP 64 键盘上某键弹起。
FRAME 128 应该是鼠标每帧。没用过。
RESIZE 256 窗口大小改变时会有的事件。
SCROLL 512
鼠标轮滚动。
PEN_PRESSURE 1024 手写板的某事件?
PEN_PROXIMITY_ENTER 2048 手写板的某事件?
PEN_PROXIMITY_LEAVE 4096 手写板的某事件?
CLOSE_WINDOWS 8192 关闭窗口。
QUIT_APPLICATION 16384 退出程序。
USER 32768 用户定义。
至于为什么都用2的N次方,主要是因为它的二进制编码只有一位是一,判断事件时很好判断,只要年哪位是一就可以了。
PICK
pick主要是通过鼠标的点击来拾取一些物体,或者判断鼠标所点击的位置在哪里。Pick实现的思路如下图所示:
判断射线与viewer中物体相交的方法为发出射线并相交。在OSG中有库函数,osgViewer::View::computeIntersections他共有三个参数:第一个是x屏幕坐标,第二个是Y屏幕坐标,第三个是存放被交的结点以及相交的坐标结点路径等等相关信息。
判断相交结点为我想要的那个结点:只需要判断存放相交射线交场景的结果集中有没有要用的结点就可以了。