Java3D实现三维显示.docx
- 文档编号:10696435
- 上传时间:2023-02-22
- 格式:DOCX
- 页数:21
- 大小:107.39KB
Java3D实现三维显示.docx
《Java3D实现三维显示.docx》由会员分享,可在线阅读,更多相关《Java3D实现三维显示.docx(21页珍藏版)》请在冰豆网上搜索。
Java3D实现三维显示
Java3D用其自己定义的场景图和观察模式等技术构造了3D的上层结构,实现了在Java平台使用三维技术。
本文在原理上着重介绍Java3D特有的两个重要概念:
场景图(SceneGraph)、观察模式(ViewModel)。
在接口使用上的介绍分为两部分:
实例说明如何使用Java3D接口;说明如何将Java3D技术与Java原有的Web技术(JSP、Serverlet)相结合,在网页上实现三维显示。
关于Java3D
1.1Java3D简介
Java3DAPI是Sun定义的用于实现3D显示的接口。
3D技术是底层的显示技术,Java3D提供了基于Java的上层接口。
Java3D把OpenGL和DirectX这些底层技术包装在Java接口中。
这种全新的设计使3D技术变得不再繁琐并且可以加入到J2SE、J2EE的整套架构,这些特性保证了Java3D技术强大的扩展性。
JAVA3D建立在JAVA2(JAVA1.2)基础之上,JAVA语言的简单性使JAVA3D的推广有了可能。
它实现了以下三维显示能够用到的功能:
∙生成简单或复杂的形体(也可以调用现有的三维形体)
∙使形体具有颜色、透明效果、贴图。
∙在三维环境中生成灯光、移动灯光。
∙具有行为的处理判断能力(键盘、鼠标、定时等)。
∙生成雾、背景、声音。
∙使形体变形、移动、生成三维动画。
∙编写非常复杂的应用程序,用于各种领域如VR(虚拟现实)。
J2SE在其标准开发包中并不提供Java3D的API,Java3D是一个独立的可选组件,可以单独下载。
Java3D现在(截止到2003年5月)提供的正式版本是1.3.0,可以在下载该开发工具包。
Java3D1.3有7个不同的可下载版本:
Java3DforWindows(DirectXversion)SDKforJDK(includeRuntime);
Java3DforWindows(OpenGLversion)SDKforJDK(includeRuntime);
Java3DforSolaris/SPARCRuntimeforJDK(includeRuntime);
Java3DforWindows(DirectXversion)RuntimeforJRE;
Java3DforWindows(OpenGLversion)RuntimeforJRE;
Java3DforSolaris/SPARCSDKforJRE;
Java3DforSolarisRuntime64bitsupport;
其中前三个版本是开发包。
第4、5、6个版本是Java3D运行期支持程序包。
最后一个是支持Solaris64bit操作平台运行Java3D的程序包。
前三个的开发包包含了各自对应的运行期支持包。
Java语言本身具有跨平台特性,无论使用上述哪个版本的开发包,概念和实现代码都会保持完全一致。
这里我们使用Java3DforWindows(OpenGLversion)SDKforJDK(includeRuntime);版本作为我们讨论、实现Java3D的工具包。
注意在安装此版本SDK前要保证下列环境:
Java2(RuntimeorSDK)version1.3.1或更后的版本
OpenGL1.1或更后的版本,并且是Microsoft支持的显卡厂商
WindowsNT4.0only:
ServicePack3或更后的版本(Window2000、WindowXP)
1.2Java3D与其他三维技术的比较
JAVA3D可应用在三维动画、三维游戏、机械CAD等多个领域。
但作为三维显示实现技术,它并不是唯一选择而且是一个新面孔。
在Java3D之前已经存在很多三维技术,这些三维技术在实现的技术、使用的语言以及适用的情况上各有不同,我们主要介绍与Java3D又密切关系的三种技术:
OpenGL、DIRECT3D、VRML
OpenGL是业界最为流行也是支持最广泛的一个底层3D技术,几乎所有的显卡厂商都在底层实现了对OpenGL的支持和优化。
OpenGL同时也定义了一系列接口用于编程实现三维应用程序,但是这些接口使用C(C++)语言实现并且很复杂。
掌握针对OpenGL的编程技术需要花费大量时间精力。
DIRECT3D是Microsoft公司推出的三维图形编程API,它主要应用于三维游戏的编程。
众多优秀的三维游戏都是由这个接口实现。
与OpenGL一样,Direct3D的实现主要使用C++语言。
VRML2.0(VRML97)自1997年12月正式成为国际标准之后,在网络上得到了广泛的应用,这是一种比BASIC、JAVASCRIPT等还要简单的语言。
脚本化的语句可以编写三维动画片、三维游戏、计算机三维辅助教学。
它最大的优势在于可以嵌在网页中显示,但这种简单的语言功能较弱(如目前没有形体之间的碰撞检查功能),与JAVA语言等其它高级语言的连接较难掌握,因而逐渐被淹没在竞争激烈的网络三维技术中。
表1是Java3D与其它三维技术的比较图,可以从中直观的看出他们相互间的区别:
表1:
3D技术对招表
技术
实现层次
开发技术(难度)
扩展性
最适合应用领域
Java3D
中层(JVM)
Java(较易)
J2SE标准扩展(好)
网上三维显示实现…
OpenGL
底层(显卡)
C\C++(难)
各大厂商支持(较好)
三维设计软件…
Direct3D
底层(操作系统)
C++(较难)
Windows平台(差)
三维游戏…
VRML
上层(网页)
标记语言(容易)
安装插件支持(一般)
网上虚拟现实…
Java3D的场景图结构
Java3D实际上是Java语言在三维图形领域的扩展,与Java一样,Java3D有纯粹的面向对象结构。
Java3D的数据结构采用的是SceneGraphsStructure(场景图),就是一些具有方向性的不对称图形组成的树状结构(图1)。
我们在一个Java3D应用程序看到的逼真三维场景从程序的角度看来,实际就是由Java3D定义的一系列的对象,这些对象不是杂乱无序,对象之间也不是毫无关系。
如果想让三维图像正常显示,必须在这两点上遵循Java3D场景图的规定。
观察图1,Java3D场景图的树结构由各种各样的对象组成:
在图中出现的这些对象都实现了Java3D中有重要的意义的类,从逻辑上我们将它们分为三类:
∙根节点(Root):
VirtualUniverseObject
∙节点(Node):
LocalObject、BranchGroupNodes、BehaviorNode、Shape3DNode…
∙叶子节点(Leaf):
Appearance、Geomery..
图1:
在应用中的Java3D场景图
场景图中线和线的交汇点称为节点(Node),这些节点都是Java3D类的实例(InstanceofClass),节点之间的线表示各个实例之间的关系。
∙VirtualUniverse是根节点,每一个场景图的VirtualUniverse是唯一的。
∙在VirtualUniverse下面是Locale节点,每个程序可以有一个或多个Locale,但同时只能有一个Locale处于显示状态,就好象一个三维世界非常大,有很多个景点,但我们同时只能在一个景点进行观察。
Java3D允许从一个Locale跳到另一个Locale,不过绝大多数程序只有一个Locale。
∙每一个Locale可以拥有多个BranchGroup节点。
所有三维形体的其位置信息(TransformGroupNodes)都建立在BranchGroup节点之上。
∙TransformGroupNode用来设定Shape3D在VirtualUniverse中的位置。
∙Spape3DNode是三维图形节点,这个节点的实体放映在最后的显示画面中,就是三维世界中的每个形体。
包括正方体、球体以及任何形状和外观的三维形体。
∙位于场景图最下层的是两个叶子节点:
三维体的外观(Appearance)和几何信息(Geometry),这两个节点定义了一个三维体的显示效果。
∙ViewPlatform位于图1的另一个分枝上,与前面所有描述三维体的性质的概念不同,ViewPlatform和View都是用来定义观察者的信息。
上面所列的概念很多,但是对于建立一个简单的Java3D程序,我们至少需要了解三个概念:
虚拟宇宙(VirtualUniverse)、场景(Locale)、坐标系统。
2.1虚拟宇宙(VirtualUniverse)
在Java3D中,虚拟宇宙被定义为结合一系列对象的三维空间。
虚拟宇宙被用作最大的聚集体表现单位,同时也可被看作一个数据库。
不管是在物理空间还是逻辑内容,虚拟宇宙都可以很大。
实际上在大多数情况下,一个虚拟宇宙就可以满足一个应用程序所有的需求。
虚拟宇宙是各自独立的个体,原因是在任何时候一个结点对象都不能在超过一个的虚拟宇宙中存在。
同样的,在一个虚拟宇宙中的结点对象也不能在其他的虚拟宇宙中可见或者与其他的对象结合。
对于一个Java3D应用程序,必须定义一个虚拟宇宙才可以在这个"宇宙"中显示三维图像。
2.2Java3D的坐标系统
默认情况下,Java3D的坐标系统是右旋的,用方位语义学来解释就是:
正y方向是本地重力的上,正x方向是水平的右,正z是这对着观察者的方向。
默认的单位是米。
双精度浮点、单精度浮点甚至是定点来表示的三维坐标都足够来表示和显示丰富的3D场景。
不幸的是,场景不是真实世界,更不必说整个宇宙了。
如果使用单精度坐标,有可能出现下列情景:
1.离原点仅有一百公里的距离,被描绘得相当量子化,所能达到的最好效果就是三分之一英寸,在实际应用中这样的精度比要求的粗糙的多。
2.如果要缩小到一个很小的尺寸(例如表现集成电路的大小),甚至在离原点很近的地方就会出现同坐标问题。
为了支持一个大型的邻接虚拟宇宙,Java3D选择了有256位的高分辨率坐标:
Java3D高分辨率坐标由三个256位的定点数组成,分别表示x、y、z。
定点被固定在第128位,并且值1.0被定义为真实的1米。
这个坐标系统足够用来描述一个超过几百万光年距离的宇宙,也可以定义小于一质子大小(小于一普朗克长度)的对象。
在Java3D中,高分辨率坐标仅仅用于将更加传统的浮点坐标系统嵌入更高分辨率的底层系统。
用这种方法,可以创造出一个具有任意大小和规模的在视觉上无缝的虚拟宇宙,而且可以不必担心数字上的精度。
(参看表2)
一个256位的定点数还具有能够直接表示几乎任何的合理适当的单精度浮点值。
Java3D用有符号的、两位补码的256位定点数字来表示高分标率坐标。
尽管Java3D保持内部高分辨率坐标表示的不透明,但用户用有八个整型变量的数组来表示256位的坐标。
Java3D把数组中从索引号由0到7分别看作高分辨率坐标的从高到底位上的数。
第128位上是二进制的小数点,也可以说在索引号为3和4的整数之间。
高分辨率坐标的1.0就是1米。
如果是"小"的虚拟宇宙(类似于相对比例的几百米),在虚拟宇宙对象下的(0.0,0.0,0.0)点建立一个带有高分辨率坐标的Locale作为根节点就足够使用了;装入程序在装入过程中能自动构建结点,而在高分辨率坐标下的点不需要任何外部文件的直接描述。
大一些的虚拟宇宙期待被构建为有如同计算机文件那样的层次,这意味着一个根宇宙要包含由外部文件引用的嵌入虚拟宇宙。
就这样,文件引用的对象(用户指定的Java3D组或高分辨率结点)定义了被读入现存虚拟宇宙的数据的位置。
表2-1:
Java3D高分辨率坐标
Java3D高分辨率坐标
2nMeters
Units
87.29
Universe(20billionlightyears)
69.68
Galaxy(100000lightyears)
53.07
Lightyear
43.43
Solarsystemdiameter
23.60
Earthdiameter
10.65
Mile
9.97
Kilometer
0.00
Meter
-19.93
Micron
-33.22
Angstrom
-115.57
Plancklength
2.3场景(Locale)
为了支持大型虚拟宇宙,Java3D提出了"Locale"的概念。
Locale把高分辨率坐标作为起源。
把高分辨率坐标看作精确的定位,它在高分辨率坐标的影响范围之内使用精度较低的浮点坐标指定对象的位置。
一个Locale和与它结合的高分辨率坐标一起组成了在虚拟宇宙之下的一个表现层。
所有虚拟宇宙包含一个或多个高分辨率Locale。
而所有其他的对象都是附加在一个Locale上的。
在整个体系中,高分辨率坐标扮演的是上层的仅供翻译的转换结点。
例如,附加到一个特定Locale的所有对象的坐标都会与这个Locale位置的高分辨率坐标有关。
(图2)
图2:
高分辨率坐标指定场景
如果一个虚拟宇宙与传统的计算机图像的概念相近,给定的虚拟宇宙可能会变得太大。
所以在通常情况下最好把一个场景图看作是一个高分辨率坐标场景的子结点。
构造一个三维场景,程序员必须运行一个Java3D程序。
这个Java3D应用程序必须首先创建一个虚拟宇宙对象并且至少把一个Locale对象附加之上。
然后,构建出需要的场景图像,它由一个分支组结点开始并且包括至少一个观察平台对象,而场景图就是附加于这个观察平台。
当一个包含场景图的观察对象被附加于一个虚拟宇宙,Java3D的渲染循环就开始工作。
这样,场景就会和它的观察对象一起被绘制在画布上。
2.4编程实现一个三维世界
这一部分描述怎样调用VirtualUniverse、Locale和HiResCoord对象的编程接口实现建立一个完整的"三维世界"。
注意,这个三维世界有原点、坐标,是实现三维显示程序的第一步。
1.VirtualUniverse对象有下列构造函数:
publicVirtualUniverse()
这个函数构造了一个新的VirtualUniverse对象,这个对象可以用来创建Locale对象。
2.Locale对象有下列构建器:
publicLocale(VirtualUniverseuniverse)
publicLocale(VirtualUniverseuniverse,intx[],inty[],int z[])
publicLocale(VirtualUniverseuniverse,HiResCoordhiRes)
这三个构建器在指定的VirtualUniverse中创建了一个新的高分辨率Locale对象。
其中第一个形成了一个在(0.0,0.0,0.0)的Locale对象。
其他的两个构建器在指定的坐标上建立了Locale对象。
在第二种形式里,参数x,y,z是含八个32位整数的数组,这些数组指定了各自的高分辨率坐标。
HiResCoord对象定义了一个使用三个高分辨率坐标的点,而每一个坐标又由三个定点数组成。
每个高分辨率坐标数共有256位,第128位是二进制小数点。
Java3D使用长度为八的整数数组来定义或提取一个256位的坐标值。
Java3D用数组内的第一个整数来表示高32位,最后一个整数来表示低32位。
3.HiResCoord对象有以下的构建函数:
publicHiResCoord(intx[],inty[],intz[])
publicHiResCoord(HiResCoordhc)
publicHiResCoord()
第一个构造函数从输入的三个长度为八的整数数组生成高分辨率坐标。
整数数组定义了与其同名坐标对象的值。
第二个构造函数通过复制另外一个坐标创建一个新的坐标。
第三个构造函数创建了一个值为(0.0,0.0,0.0)的坐标。
所有Java3D程序都会首先建立VirtualUniverse和Locale对象,也就是说都会包含表3所示的代码。
为了方便使用,Java3D为最原始的VirtualUniverse创建了几个子类:
SimpleUniverse、ConfiguredUniverse,这些子类保证了可以将三维图像轻易的在通过Canvas3D的对象在Applet或Frame中显示。
其中最常用到的是SimpleUnivese对象,这个类位于包com.sun.j3d.utils.universe中。
u=newSimpleUniverse(v,viewer);
u.getViewingPlatform();
ViewingPlatformviewingPlatform=u.getViewingPlatform();
例1初始化VirtualUniverse和Locale代码
Java3D的观察模式
Java3D引入了一种新的观察模式,这种模式使Java编写的显示效果符合"编写一次,随处运行"的原则。
Java3D还把这种功能推广到显示设备或六等级自由度输入外部设备,例如跟踪摄像头。
这种新的观察模式的"一次编写,随处观察"的特性意味着用Java3D观察模式编写的应用程序和Applet可以广泛应用于各种各样的显示设备。
在不修改场景图的条件下,图像可以在包括标准电脑显示、多放射显示空间和安装摄像头设备的显示设备上被渲染。
这也意味着在不需要修改场景图的情况下,同一个应用程序既能够渲染立体景象,还能通过摄像头的输入控制渲染过的观察图。
Java3D的观察模式通过完全分离虚拟和现实世界来实现这种多功能性。
这种模式区分了以下两种情况:
1.一个应用程序通过控制观察平台的位置和方向在虚拟宇宙中对一个观察台对象(ViewPlatform)定位、定向和设定比例尺;
2.渲染器使用已知位置和方向计算出要使用的观察对象,对终端用户物理环境的描述确定用户在物理环境中的位置和方向。
3.1为什么使用一个新的模式
在底层的编程接口中可以找到基于照相机的观察模式,开发者通过它可以控制所有渲染图的参数。
它可以应付处理常规的应用程序,但是处理有更广阔的适应性的系统的时候就显得力不从心,这些系统包括:
把整个世界作为一个单元装入和显示的观察器或浏览器、可供终端用户观察、操纵、显示、甚至与虚拟世界交互的系统。
基于照相机的观察模式仿效在虚拟世界中放置一个照相机而不是一个人。
开发者必须持续重新配置一个照相机来模拟"在虚拟世界中有一个人"。
Java3D观察模式直接和跟踪摄像头结合。
在有摄像头的情况下,用户会有好像他们是真实的存在在那个虚拟世界的错觉,而开发者可以不做任何附加的工作就可以为用户带来这种效果。
在没有摄像头并且只是用来表现一个单一的标准显示的情况下,Java3D观察模式表现得更像传统的基于照相机的观察模式,只是加上了能够产生立体透视图的功能。
在一个需要由物理环境规定一些观察参数的系统中,让应用程序来控制所有的观察参数并不合理。
例子就是:
一个带有摄像头的显示设备可以用其光系统直接决定应用程序中的观察领域。
不同的设备有不同的光系统,程序开发者硬绑定这样的参数或允许终端用户改变这样的参数都是不合理的。
另外一个例子是:
一个可以由用户当前的头部位置自动计算出观察参数的系统。
只有一个对世界的说明和一条预先定义的轨迹可能不会严密的定义一个终端对象的观察。
对于有摄像头设备用户,他们可能会期待在沿着一条固定的路线前进的时候能够看到他们左右两旁的物体。
就好像在一个游乐场中,游客乘坐观光车按照固定的路线参观游乐场,但是在这过程中,游客可以持续转动他们的头。
由于依靠终端用户的具体物理环境,观察的各个参数,尤其是观察和投影的基体变化很大。
影响观察和投影基体的因素包括显示设备的物理尺寸,显示设备的安装方法(在用户的桌面或用户的头顶上),计算机是否知道用户的头在三维空间的位置,头顶装置真实的观察领域,显示设备上每平方英寸的像素数,还有其他类似的参数。
Java3D建立的观察模式完全可以满足上述所有的需求。
3.2分离物理和虚拟
Java3D分离了虚拟环境和物理环境:
应用程序在虚拟环境中按照一定关系放置对象,而用户存在在物理环境之中,看计算机显示器并操纵输入设备。
Java3D也定义了用户所在的物理世界和图像程序所在的虚拟世界之间最基本的通信。
这种"物理到虚拟世界"的通信定义了一个单一的公共空间,在这个空间中用户的动作影响虚拟世界中的对象,而在虚拟世界中的任何活动都会影响最终用户的观察。
虚拟世界是虚拟对象存在的通用空间。
虚拟世界的坐标系统相对于每个Locale对象的高分辨率坐标存在,它定义了所有附加于这个Locale的虚拟世界坐标原点。
包含当前活动的观察平台对象的Local定义了用来绘图的虚拟世界坐标。
Java3D最后把所有图像单元的坐标转换到通用的虚拟世界空间中。
物理世界就是指真实的世界。
这是真实的用户存在和移动他(她)的头和手的空间。
这也是使用任何物理追踪仪可以定义他们的局部坐标和几个标准的坐标系统被描述的空间。
物理世界是一个空间,而不是Java3D不同的程序执行实例之间的通用坐标系统。
所以当两个不同的计算机在世界上两个不同的地方同时运行同一个程序的时候,Java3D中没有直接来描述它们在物理世界坐标系统中相对位置的机制。
因为标准问题,当地的跟踪系统仅仅定义了特定的Java3D应用程序实例的物理坐标系统。
3.3Java3D中用来定义观察的对象
Java3D通过几个对象来发布它的观察模式。
特别是View对象和与它相关的组件对象:
PhysicalBody对象、PhysicalEnvironment对象、Canvas3D对象、Screen3D对象。
图3描述了View对象的中心角色和组件对象的辅助角色。
观察有关的对象都在图3中,它们起的作用如下:
ViewPlatform(观察平台):
一个view用一个叶子结点来在场景图为自己定位。
观察平台的起始结点指定了它的位置、方向和在虚拟世界中的比例尺。
View(观察):
主要的观察对象包含了很多观察的状态。
Canvas3D:
抽象窗口工具箱中画布对象的3D版本。
它描绘了一个可以让Java3D在上面画图像的窗口。
它包括了一个对Screen3D对象的引用和描述一个Canvas3D要用到的尺寸、形状和位置信息。
Screen3D:
一个包含描述显示荧屏物理属性信息的对象。
Java3D把显示荧屏信息分别放在单独的对象中,这样做可以防止在每一个Canvas3D对象中不同的显示屏幕信息共享一个屏幕。
PhysicalBody:
一个包含刻度信息的对象,它描述了用户的物理身体。
PhysicalEnvironment:
一个包含刻度信息的对象,它描述了物理世界。
主要的信息描述了环境的六自由度硬件。
图3:
View和它的组件对象以及它们的相互联系
这些对象一起描述观察的几何体胜于明白的提供观察或投影基体。
Java3D的表现工具用这个信息来构造适合的观察和投影基体。
这些观察对象的几何中心为产生一个观察提供
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- Java3D 实现 三维 显示