动网论坛,站长建站首选,国内使用量最多的论坛软件 动网论坛官方技术讨论区 站长工具 申请属于您自己的免费论坛
首页 | 新闻资讯 | 网站运营 | 网络编程 | 数据库 | 服务器 | 网页设计 | 图像媒体 | 网络应用 | 搜索优化 | 资源下载 | 动网主机 | DVBOX
    本站内  互联网 ASP论坛  ASP.Net论坛  PHP论坛
   网页设计 → 阅读文章

 虚拟现实之高级技巧(四)

作者来源: 
阅读 数 139 人次 , 2006-4-18 15:10:00 


  ∥颐墙幼派弦黄绦致鬯婊シ诺奈锾澹热缢的憧梢陨杓颇愕某【埃庇没恳淮谓胧倍伎梢运婊シ乓恍┎煌谋尘耙衾郑庖桓鲈擞糜胛颐窃忍致鄣奈锾宓乃婊硕绯鲆徽蓿徽饫镂颐羌尤肓藄ound结点和AudioClip结点。

  首先来分析一下这个场景,当用户进入场景后,开始随机播放音乐,用户进入场景这是一次性的动作,这与连续运动不同它是非连续的,同时在我们需要先将音乐预设在场景中,由于篇幅有限,我们在这里只给出几步重要的步骤。

Sound {
maxFront 100
maxBack 5
source DEF AGENT_VOICE1 AudioClip {
loop FALSE
url "sound.wav"
}
}

  这是定义了一个场景中的Sound,声音文件包括在sound.wav里,注意它loop为FALSE,就是说声音是否播放需要通过AGENT_VOICE来触发。什么时间通过什么方式进行AGENT_VOICEDE的触发,同时这里又有一个判断用户是否在场景中的问题,需要对用户进行Fine-Grined跟踪,需要用到我们下面谈到的ProximitySensor结点,向大家介绍完Fine-Grined跟踪方式,大家自然知道随机播放声音的方法了。

  首先说明ProximitySensor结点是产生报告用户在场景中的位置和变化的方位,进行用户是否进入场景的判断只是它的一个用法,千万不要认为它只能进行判断,不清楚的地方大家可以看看结点指南中关于它的介绍。在ProximitySensor结点中,关键参数是Size字段,它定义了传感器的操作范围,只要在范围中,该结点就能判断用户的位置,一旦用户进入了范围,IsActive字段变为真,同时在enterTime中产生一个进入时间,Position_changed和Orientation_changed字段将随用户移动产生事件。在这里用到的主要是IsActive字段,通过它来触发AGENT_VOICE事件,播放音乐。将与JAVA程序产生更为复杂的动作,下面是Rodger Lea教授在他的构建VRML虚拟城市中,用到的一小段自动门程序,很具有代表性,看过后我们再向大家解释程序过程。
#VRML V2.0 utf8
# automatic door
# when the light is turned on, the door opens / closes automatically.
# turn off the headlight
NavigationInfo{
headlight FALSE
}
# initial viewpoint
Viewpoint{
position 0 2 5
}
# room
Shape{
geometry IndexedFaceSet{
solid FALSE # double face
coord Coordinate{
point[ 2 0 , #0
10 0 -10, #1
10 0 10, #2
-10 0 10, #3
-10 0 -10, #4
-2 0 -10, #5
2 3 -10, #6
10 3 -10, #7
10 3 10, #8
-10 3 10, #9
-10 3 -10, #10
-2 3 -10 #11
]
}
coordIndex[ 6, 0, 1, 7, -1, #0
7, 1, 2, 8, -1, #1
8, 2, 3, 9, -1, #2
9, 3, 4, 10, -1, #3
10, 4, 5, 11, -1, #4
4, 3, 2, 1 #5 (floor)
]
color Color{
color[ 1 1 0, #0 (wall)
0 0.2 1.0 #1 (floor)
]
}
  colorPerVertex FALSE
colorIndex[ 0, 0, 0, 0, 0, 1]
}
}
DEF LIGHT1 DirectionalLight{
on FALSE
}
DEF LIGHT2 DirectionalLight{
direction 0 0 1
on FALSE
}
Transform{
translation 0 4 0
children[
# lamp shade
DEF LAMP_SHADE Shape{
geometry Cone{
height 2
bottomRadius 2
}
},
# sensor to turn the light on / off
DEF LIGHT_ON_SWITCH TouchSensor{}
]
}
Transform{
translation 0 1.5 -10.1
children[
# door
DEF DOOR Transform{
children[
Shape{geometry Box{size 4 3 0.1}}
]
},
DEF PROX_SENSOR ProximitySensor{
size 8 3 15
}
]
}
DEF DOOR_OPEN_TIME TimeSensor{
cycleInterval 2
}
DEF DOOR_OPEN_INTP PositionInterpolator{
key [ 0, 1]
keyValue [0 0 0, 3.5 0 0]
}
DEF DOOR_CLOSE_TIME TimeSensor{
cycleInterval 2
}
DEF DOOR_CLOSE_INTP PositionInterpolator{
key [ 0, 1]
keyValue [3.5 0 0, 0 0 0]
}
  DEF DOOR_SCRIPT Script{
url "AutomaticDoor.class"

# light control
eventIn SFTime touched
eventOut SFBool turnOnLight
# door control
eventIn SFTime enterArea
eventOut SFTime openDoor
eventIn SFTime exitArea
eventOut SFTime closeDoor
}
ROUTE LIGHT_ON_SWITCH.touchTime TO DOOR_SCRIPT.touched
ROUTE DOOR_SCRIPT.turnOnLight TO LIGHT1.on
ROUTE DOOR_SCRIPT.turnOnLight TO LIGHT2.on
ROUTE PROX_SENSOR.enterTime TO DOOR_SCRIPT.enterArea
ROUTE DOOR_SCRIPT.openDoor TO DOOR_OPEN_TIME.set_startTime
ROUTE DOOR_OPEN_TIME.fraction_changed TO DOOR_OPEN_INTP.set_fraction
ROUTE DOOR_OPEN_INTP.value_changed TO DOOR.set_translation
ROUTE PROX_SENSOR.exitTime TO DOOR_SCRIPT.exitArea
ROUTE DOOR_SCRIPT.closeDoor TO DOOR_CLOSE_TIME.set_startTime
ROUTE DOOR_CLOSE_TIME.fraction_changed TO DOOR_CLOSE_INTP.set_fraction
ROUTE DOOR_CLOSE_INTP.value_changed TO DOOR.set_translation
JAVA程序部分:
// toggle the light state.
// control the automatic door.
import vrml.*;
import vrml.node.*;
import vrml.field.*;
public class AutomaticDoor extends Script{
SFBool turnOnLight;
SFTime openDoor;
SFTime closeDoor;
// light state.
boolean onOff = false;
public void initialize(){
// get the reference of the event out "turnOnLight".
turnOnLight = (SFBool)getEventOut("turnOnLight");
// get the reference of the event out "openDoor".
openDoor = (SFTime)getEventOut("openDoor");
// get the reference of the event out "closeDoor".
closeDoor = (SFTime)getEventOut("closeDoor");
}
public void processEvent(Event e){
if(e.getName().equals("touched") == true){
// toggle the light state.
onOff = !onOff;
// send the event.
turnOnLight.setValue(onOff);
}else if(e.getName().equals("enterArea") == true){
if(true == onOff){
// open the door if the light is on.
openDoor.setValue(((ConstSFTime)e.getValue()).getValue());
}
}else if(e.getName().equals("exitArea") == true){
// close the door.
closeDoor.setValue(((ConstSFTime)e.getValue()).getValue());
}
}
}

  这段程序比较长,讨论的是一个用户在虚拟城市中,走到一个商店前,商店门自动打开,用户进入商店的内容,但在用户进入商店之前,要进行一个时间判断,当用户在容许的时间段内,门上的灯将点亮,用户可以进入商店,如果在容许的时间段外,门上的灯将熄灭,就算用户走近门,商店门也不会打开。这段程序中构建了一个商店,两个灯和自动门这些实体,路线分为三个部分,一个是设置灯的,使script可以控制灯的开关并记录当前的状态。第二部分是设置开门的路线,第三部分设置关门的路线。当用户进入ProximitySensor结点的size定义的区域后,发送一个enterTime事件,命名为DOOR_SCRIPT.ProximitySensor。Java程序判断灯的状态,如果灯亮,开始TimeSensor并返回当前时间给Script结点,Script结点驱动DOOR_OPEN_INIP插入器开门,如果灯为灭,那么就没有TimeSensor返回事件。当用户离开门附近时,传感器发送一个exitTime给Script结点,这时同样的Java程序返回一个当前时间给Script,然后Script结点又驱动DOOR_CLOSE_INIP插入器关门。

  在构建你的场景时一定要仔细考察实现中的情况,同时灵活运用VRML与Java结合。   
 
 收藏本文  打印本文  论坛讨论  关闭窗口
· 上一篇:评论:RSS为何让微软如此青睐有加
· 下一篇:虚拟现实之高级技巧(一)
· 理解Java应用服务器的七种武器
· 在 DW 中插入 Flash 的参数详解(一)
· SEO:大型企业网站外部链接数量的调查分析
· DreamwaverMX与ASP.NET(十一)
· JavaScript基础实例:如何计算24点(2)


关于本站 | 联系我们 | 业务合作 | 客户案例 | 诚聘英才 | 广告合作 | 收藏本站
海口动网先锋网络科技有限公司版权所有
Copyright © 2000 - 2006 Cndw.Com
中华人民共和国电信与信息服务业务经营许可证编号 琼 ICP 020077