基于Java3D的虚拟现实建模方法
1引言
由于因特网和WWW应用的迅速发展,如何在因特网环境下实现虚拟现实系统已引起广泛的研究兴趣。虚拟现实(VirtualReality,VR)是计算机模拟的三维环境,用户可以走进这个环境(用鼠标控制浏览方向)并操纵场景中的对象。其图形渲染是“实时”的,这是它与动画制作的最大区别。这种“实时性”导致了在虚拟场景中的人机“可交互性”。虚拟现实技术开辟了人类交流新的领域。
Web上的3D再现技术在一些领域有着极其重要的作用,尤其是在电子商务领域。当顾客进行在线购物时,他们需要找到在现实购物经历中培养出来的那种“感觉”:当顾客步入商店,关注某件商品时,他会从各个角度观察商品,触摸或试穿,然后再购买。这种“感觉”仅仅凭借2D图像或其它非3D图像是无法达到的。与现实接近的3D图像将显著提高电子商务的可行性。3D图像对于游戏而言也相当重要。这一领域已经由于Web服务器的限制而举步维艰,因为Web服务器无力承受像Doom这样受欢迎的在线3D游戏。此外,更高质量的3D图像可以使包括科学家、学生、建筑师在内的许多人受益,他们可以在世界范围内更容易地交流其模型、研究成果和研究对象。
以往的虚拟现实建模一般采用OpenGL,VRML,DI-RECT3D等语言。由于OpenGL的跨平台特性,许多人利用OpenGL编写三维应用程序。不过对于一个非计算专业的人员来说,利用OpenGL编写出复杂的三维应用程序是比较困难的。VRML语言在网络上得到了广泛的应用。编写VRML程序非常简单,同时可以编写三维动画片、三维游戏、计算机辅助教学,因而其应用前景非常广阔,尤其适合在我国推广应用。不过由于VRML语言功能目前还不是很强(如没有形体之间的冲突检查功能),与Java等高级语言的连接较难掌握,因而失去了一些计算机高手的宠爱。DIRECT3D是Microsoft公司推出的三维图形编程API,它主要应用于三维游戏的编程,目前相关的学习资料难以获得。由于它一般需要VC等编程工具进行编程,需要编程人员具有较高的C++等高级语言的编程功底,因而难以普及。
新出现的虚拟现实建模语言Java3D综合了以上建模语言的优点,它是Javal.2的一个标准扩展,是Java语言中一个用于开发三维图形的API。它从高层次为开发者提供对三维实体的创建、操纵和着色,使开发工作变得较为简单。同时,Java3D的低级API是依赖于现有的三维图形系统的,DIRECT3D,OpenGL,QUICKDRAW3D和XGL等。Java3D的这种体系结构既可以使其开发的程序“到处运行”,又使其能充分利用系统的三维特性。用Java3D开发的基于Web的小程序可以与Internet很好地集成,在浏览器上观赏或对虚拟现实场景进行交互式操作时不需要下载相关的插件,因为Java3D在虚拟现实建模中的应用有很大的便利和通用性。下面本文给出基于Java3D的虚拟现实建模方法。
2VR的软件工程[1-2]
VR的软件工程包括虚拟物体的几何模型、运动模型、物理模型的建立,虚拟立体声的产生,模型管理技术及实时模拟技术等,如图1所示。
具体介绍如下:
(1)虚拟物体的几何模型。包括虚拟物体的形状、表面信息(如纹理、表面反射系数、颜色)及分辨率等。
(2)运动模型。仅对虚拟物体作静态描述是不够的,因为虚拟环境是一个动态的交互式环境。对虚拟物体运动的描述包括虚拟物体位置的变化,虚拟物体的碰撞、旋转、放大、缩小及表面变形等。
(3)3D虚拟立体声的模拟。
(4)物理模型。为使虚拟物体不仅具有视觉上的真实性。而且具有感觉上的真实性,必须考虑其物理特性。如虚拟物体的重量、表面光洁程度、软硬程度及畸变模式(弹性、塑性)等。
(5)输人输出映射。用于检测使用者的外部输人命令,如头部位置的变化、手的姿态命令,并相应作用于虚拟环境。
(6)模型的分割。它包括两部分:首先是虚拟环境的分割,将复杂的虚拟环境分解成若干个独立的小单元,只有当前单元中的物体可被感觉到;另一部分是对当前所观测到虚拟物体的距离远近进行分类,距离近的物体可采用高分辨率的显示方式,对距离远的物体可采用低分辨率的显示方式,这样可降低系统的软件复杂程度。
(7)虚拟现实模型管理技术。将现阶段任务分成若干个独立的部分,并分配相应的软硬件资源。
(8)虚拟环境数据库的建立与管理。它存放的是整个虚拟环境中所有物体的各方面信息。
3Java3D概述
Java3D给编写三维应用程序提供了非常完善的API,它可以帮助??生成简单或复杂的形体(也可以直接调用现有的三维形体),使形体具有颜色、透明效果、贴图;在三维环境中生成灯光、移动灯光;具有行为的处理判断能力(键盘、鼠标、定时等),可以生成雾、背景、声音等;使形体变形、移动、生成三维动画;编写非常复杂的应用程序,用于各种领域如VR。
三维图形技术的鼻祖是SGI公司推出的OpenGL三维图形库。Java3D则是在OpenGL基础上发展而来,因而Java3D的数据结构也和OpenGL-样,采用的是场景图的数据结构;但Java3D的场景图根据Java语言编程的特点,增加了一些新的内容,更易于实时处理及特殊三维效果的显示,更加方便最新的三维图形加速技术的应用。Java3D的场景图是DAG,具有方向性的不对称图形。Java3D的场景图由Java3D运行环境直接转换成具有三维显示效果的显示内存数据,从而在计算机上显示出三维效果。显示内存中的数据不断接收Java3D运行产生的最新结果,直接显示出来,从而产生三维动画效果o
Java3D的场景图中有很多线和线的交汇点。交汇点称为节点,不管什么节点,都是Java3D类的实例,即面向对象编程方式所生成的对象。线则表示各对象之间的关系。编写Java3D应用程序与画一棵大树很类似:先用准备好的笔画出各个交汇点;然后用各种颜色的彩笔画出所需要的树干和树枝。画交汇点就是定义好所需要的对象,如显示的是什么形体,有什么颜色,形体按照什么样的运动方式运动;画树干和树枝就是给出各对象之间的关系,例如谁是父节点,谁是子节点。Java3D的场景图中,最底层的节点是VirtualUniverse。每一个场景图只能有一个VirtualUniverse,好似一棵大树的树根,如图2所示。
图2Java3D的场景图VirtualUniverse的上面是Local节点,每个程序可以有一个或多个Local,但同时只能有一个Local处于显示状态,绝大数程序只有一个Local复杂的Java3D应用程序可以建立多个Local,由程序控制当前的Local是哪一个。每一个Local上面拥有~个到多个BranchGroup节点。一般来说,要想建立三维应用环境,必须定义所需要的形体,给出形体的外观及几何信息,再把它们摆放在BranchGroup节点上面。摆放的具体位置由节点TransfonnGrcmp设定。另外,摆放好三维形体后,还需要设定具体的观察位置及观察参数如视角。完成了这些工作,就算完成了三维场景图的建立。Java3D程序只要正确地定义了三维图形的具体观察位置及观察参数,建立了一个带有三维及其属性的一个场景图,就可以在计算机屏幕上显示程序的运行效果。
Java3D提供了100多个存放于.j3d程序包中的类及接口,这些是Java3D的核心类。除了核心包中的类及接口外,Java3D还提供了一个重要的有助于快速编程的应用类型的包,这就是包(U-tility)。可以在计算机JDK目录下阅读到这个包中各个类的源程序。Java3D所提供的Utility并不是Java3D编译环境的核心组成部分,可以不用它,但使用它会大大提高程序的编写效率。
用Java3D所提供的API函数库,可以在应用程序中构造简单的形体,而复杂的形体则很难直接通过编程实现。这时可以通过调用其它格式的三维图形文件获得复杂形体(如直接调用VRML2.0格式、OBJ格式的三维图形文件),通过处理,间接调用DWG,DXF,3DS格式的三维图形文件。这些格式的三维形体可以非常方便地应用在Java3D程序中,进而提高Java3D程序的编程效率。Java3D在直接调用各种格式的三维图形文件时,会碰到初始观察点的定位问题,这是因为外部的形体有大有小,按照D所提供的缺省观察位置观察,形体有时显得太大,有时太小,为此java3D编写的程序应能灵活地设置初始观察位置。这样,就可以根据所调用图形的大小,正确设置观察位置,生成较好的显示效果。
如下面的语句,可使坐标系发生比例变化,使物体成为原来大小的0.3倍:
Transform3Dc3d=newTransform3D();
e(0.3);
TransformGroupobjScale=newRransformGroup(c3d);
ObjRoot,addChild(objScale);
4Java3D在虚拟现实中的交互运用及冲突检测
虚拟现实中最重要的就是人与场景的交互性,Ja_va3D借助Java语言强大的事件处理功能,可用来编写复杂交互式的虚拟场景。JaVa3D的事件处理方法使用的是Javal.2版本的事件处理模型。Javal.2事件程序中,在类定义时,用implements说明该类实现的一个或多个监听器,如:
publicclassgameextendsAppletimplementsWindowListener,ActionLis-tener,ItemListener,CheckboxMenuListenerI[
但这种方法主要用于特定显示界面的设计及一些状态的变化处理方面。如果要编写更复杂的交互式三维应用程序,则需要用到Java3D的Behavior对象。Be?havior有Billboard,Lod,Interpolators等子类。
编写复杂的交互式三维对象时,经常会感到计算机速度不够,可以有多种方法解决速度慢的问题。Java3D编程可通过灵活应用L0D对象来提髙计算机的运行速度。其它三维图形技术也用到了L0D技术;VRML语言就用到了L0D技术;VRML语言就有L0D节点。Java3D的L0D对象通过设定,可以使计算机根据三维场景图的需要,在程序运行时有效处理复杂形体:当复杂物体离观察点很远时,就用一个简单的形体替代;当复杂形体离观察点不远不近时,就用一个近似的形体替代;当复杂物体离观察点很近时,就显示复杂形体自身,这样可以有效提髙计算机的运行速度。Billboard是Behavior的子类,利用Billboard可生成一个局部坐标系,此坐标系的+Z轴方向一直指向观察者的眼镜。这表示在三维空间移动位置及方向时,Billboard所在的局部坐标系中的形体将一直面向着我们,也即自动绕着局部坐标系的Y轴旋转。Interpolators可用于建立三维空间中形体绕着样条曲线运动的轨迹,这样,只要输人形体及多个关键点的数据,就可以控制形体绕着这几个关键点做空间的曲线运动,同时可以控制形体的比例变化及旋转。Interpola-tors在程序中的具体应用是生成一个TCBKeyFrame对象。TCBKeyFrame对象的应用方法是:
(1)据曲线的运动轨迹,定义相应的控制点的位置。
(2)据控制点的数目,生成一个TCBKeyFrame类型的数组,设置好里面的各个参数。
处理交互式问题时,利用监听器Listener和利用Be?havior方面的Utility,常常不能满足编程需要,这时可以利用定义新的Behavior对象的方法编写交互式Java3D程序。编写自定义的Behavior对象的三个步骤为:
①定义一个继承Behavior的新对象,同时给出新对象的构造方法。
②定义一个初始化所用的initialize!)方法。
③定义一个处理交互作用的processStimulus()方法。冲突检测与响应在物体的物理建模中是十分重要
的内容,。因为虚拟物体在运动过程中,可能发生相互碰撞、接触或其它形式的相互作用。如果出现这种情况,物体则不能按照原来的运动状态继续运动,否则虚拟环境中就会出现虚拟物体之间相互穿透、彼此重叠等不真实的现象。检测虚拟环境中虚拟物体是否发生了相互碰撞的过程称为冲突检测。检测到碰撞后,要对之作出正确的响应,修改虚拟物体的运动状态,确定物体的变形和损坏等,这就是冲突响应。冲突检测是虚拟现实、计算机动画、机器人学等领域的核心问题之一。Ja-va3D具有形体间冲突检查功能。为了编写具有这样功能的交互式应用程序,需要定义一个检查形体之间碰撞情况的行为对象,这时可用到Java3D提供的用于形体间冲突检查用的三个对象:WakeupOnCollisionEntry,Wake-upOnCollsionExit,WakeupOnCollisionMovement。Java3D的冲突检査功能还处于不断改进的阶段,这方面的计算需要较多的时间,有时会影响程序的运行速度。
5结束语
Java3D为虚拟现实技术的应用提供了很大的便利,很好地解决了虚拟现实建模中与平台的无关性、交互式操作、冲突检测等难点。此外,由于JaVa3D是基于Inter?net的网络开发平台,因而利用它来开发网络的VR具有很大的潜力。但由于硬件平台的限制,虚拟现实系统在复杂场景环境下的实时反应还不理想,还需要作进一步的探讨。