总体导航图
学习指南
主要内容
网页制作软件

当前位置:多媒体应用基础 >> 网络多媒体应用设计 >> 增加交互能力

增加交互能力

    上一节我们学习了用几何体建立虚拟境界以及为几何体赋予色彩和材质的方法, 这样建立的虚拟境界是静态的。这一节我们将使一个几何体(为了更具一般性,下面我们称之为对象)能够根据用户动作做出反应,即交互能力,这是VRML2.0最突出的特征。

1.检测器
    在VRML中,检测器(Sensor)节点是交互能力的基础。检测器节点共 九种。在场景图中,检测器节点一般是以其它节点的子节点的身份而存在的,它的父节点称为可触发节点,触发条件和时机由检测器节点类型确定。接触检测器(TouchSensor)是最常用的检测器之一,最典型的应用例子是开关。其它检测器将在后续教程中陆续介绍。
    这里我们定义一个开关节点lightSwitch(这是一个组节点),并定义一个 接触检测器作为它的子节点:
DEF lightSwitch Group { children [ 各几何造型子节点...
DEF touchSwitch TouchSensor {} ] }

    这样开关节点lightSwitch就是一个可触发节点。当然,检测器存在的理由是它被触发时能够引起某种变化,所以在更深入讨论开关节点之前,我们先讨论一下场景变化。

2.视点
    最常见的变化是视点的变化,在我们的第一个境界中你可能已经体验到 视点变化:当你拖动鼠标或按动箭头键时(按照vrml术语,称为航行),虚拟境界就会旋转或缩放,这实际上是在调整你的视点位置或视角。在虚拟场景的重要位置可以定义视点节点(Viewpoint),它们是境界作者给用户推荐的上佳观赏方位,在cosmoplayer浏览器中,用户就可以通过鼠标右键选择作者推荐的各个视点。这里我们定义两个视点节点:
DEF view1 Viewpoint { position 0 0 20 description "view1" }
DEF view2 Viewpoint { position 5 0 20 description "view2" }


    我们的潜在目的是使用户可以通过触发开关节点来切换视点。现在先研究一下 这两个视点节点,其中的坐标表示视点在场景中的位置,坐标的单位是米,这在前面已经提到过,视点的名称将会在浏览器菜单中提示出来供用户选择。把 上述视点说明加入helloworld.wrl中(放在Group节点之前),并把其中的方块节点修改成可触发节点: DEF box Tranform { children [ Shape { .... Box ...} DEF touchBox TouchSensor {} ] } 把修改过的文件另存为“touchme.wrl”。

3.事件传递
    下面我们把触发(用鼠标箭头按动方块)和场景变化 (视点切换)这两件事情联系起来,在场景图中,除节点构成的层次体系外,还有一个“事件体系”,事件体系由相互通讯的节点组成。能够接收事件的节点都应具有事件入口(eventIn),如果它要接收多种类型的事件(称为入事件),它就应该具有多个事件入口,也就是说,事件入口 像节点的域一样是有类型的。同样,发送事件的节点应有事件出口(eventOut),事件出口也是有类型的。例如Viewpoint节点就有一个事件入口set_bind, 当向此事件送入一个值“TRUE”(即所谓的入事件)时,该Viewpoint节点成为当前视点。又如,接触检测器TouchSensor有一个事件出口isActive,当受到用户触发后它就从此出口送出一个“TRUE”(即所谓的出事件),补充一句,在下一个事件发送之前,此事件一直保存在事件出口中(作为记录)。事件出口和事件入口通过路径相连,这就是VRML文件中除节点以外的另一基本组成部分:ROUTE 语句。ROUTE语句把事件出口和事件入口联系在一起,从而构成事件体系。在这里,我们是把接触检测器touchBox的事件出口isActive连接到视点节点view2的事件入口set_bind: ROUTE touchBox.isActive to view2.set_bind 好了!现在我们得到的VRML文件是:

#VRML V2.0 utf8
DEF view1 Viewpoint {position 0 0 20
description "view1" }
DEF view2 Viewpoint {position 5 0 20
description "view2" }
Group { children [
DEF box Transform { translation 5 0 0 children [
Shape { appearance Appearance { material Material { diffusecolor 1 0 0} }
geometry Box {} }
DEF touchBox TouchSensor {} ] }
DEF sphere Transform { translation 0 0 0 children [
Shape { appearance Appearance { material Material { diffusecolor 0 1 0} }
geometry Sphere {} } ] }
DEF cone Transform { translation -5 0 0 children [
Shape { appearance Appearance { material Material { diffusecolor 0 0 1 } }
geometry Cone {} } ] }
] # end of Group children
}
ROUTE touchBox.isActive TO view2.set_bind

    

    把这个文件调入浏览器,然后把鼠标指向方块并按下左钮(先别松开!),可以看到视点已经变为view2,内部的机制我们已经很清楚:左钮按下时方块节点的接触检测器被触发,接着接触检测器从事件出口isActive送出一个事件“TRUE” ,这个事件通过路由进入视点节点view2的事件入口set_bind,view2收到“TRUE” 后成为当前视点,所以在我们眼前场景发生了变化。现在松开左钮,可以看到场景恢复到原来方位,这种功能称为视点回跳,其原因是松开左钮后接触检测器向view2发送了一个“FALSE”事件,这样view2当前的地位被解除,原来的视点成为系统视点栈的栈顶节点(即当前视点),详细说明可参见标准中对视点节点的专门论述。如果我们不想视点回跳,就想停留在view2视点,那该怎么办呢?这种非系统缺省功能要自己来定义。

 

相关知识点
VRML学习

精品展示

浏览器插件