查看: 3286|回复: 7
打印 上一主题 下一主题

[Java3D] 快来看啊!!Java3D实现三维显示(1)

[复制链接]

1026

主题

1

听众

6011

积分

高级设计师

Rank: 6Rank: 6

纳金币
5996
精华
1

最佳新人 活跃会员 热心会员 灌水之王 突出贡献

跳转到指定楼层
楼主
发表于 2011-8-2 20:24:13 |只看该作者 |倒序浏览
关于Java3D
1.1 Java3D简介
Java3D API是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,可以在 http://java.sun.com/products/java-media/3D/download.html 下载该开发工具包。
Java3D 1.3有7个不同的可下载版本:
Java3D for Windows(DirectX version)SDK for JDK(include Runtime);

Java3D for Windows(OpenGL version)SDK for JDK(include Runtime);

Java3D for Solaris/SPARC Runtime for JDK(include Runtime);

Java3D for Windows(DirectX version)Runtime for JRE;

Java3D for Windows(OpenGL version)Runtime for JRE;

Java3D for Solaris/SPARC SDK for JRE;

Java3D for Solaris Runtime 64 bit support;
其中前三个版本是开发包。第4、5、6个版本是Java3D运行期支持程序包。最后一个是支持Solaris 64 bit操作平台运行Java3D的程序包。前三个的开发包包含了各自对应的运行期支持包。Java语言本身具有跨平台特性,无论使用上述哪个版本的开发包,概念和实现代码都会保持完全一致。这里我们使用Java3D for Windows(OpenGL version)SDK for JDK(include Runtime);版本作为我们讨论、实现Java3D的工具包。注意在安装此版本SDK前要保证下列环境:
Java 2 (Runtime or SDK) version 1.3.1 或更后的版本
OpenGL 1.1 或更后的版本,并且是Microsoft支持的显卡厂商
Windows NT 4.0 only: Service Pack 3 或更后的版本(Window2000、WindowXP)
1.2 Java3D与其他三维技术的比较
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
            底层(显卡)
            CC++(难)
            各大厂商支持(较好)
            三维设计软件…
        
        
            Direct3D
            底层(操作系统)
            C++(较难)
            Windows平台(差)
            三维游戏…
        
        
            VRML
            上层(网页)
            标记语言(容易)
            安装插件支持(一般)
            网上虚拟现实…
        
   



回页首
Java3D的场景图结构
Java3D实际上是Java语言在三维图形领域的扩展,与Java一样,Java3D有纯粹的面向对象结构。Java3D的数据结构采用的是Scene Graphs Structure(场景图),就是一些具有方向性的不对称图形组成的树状结构(图1)。
我们在一个Java3D应用程序看到的逼真三维场景从程序的角度看来,实际就是由Java3D定义的一系列的对象,这些对象不是杂乱无序,对象之间也不是毫无关系。如果想让三维图像正常显示,必须在这两点上遵循Java3D场景图的规定。观察图1,Java3D场景图的树结构由各种各样的对象组成:
在图中出现的这些对象都实现了Java3D中有重要的意义的类,从逻辑上我们将它们分为三类:

    根节点(Root):Virtual Universe Object
    节点(Node):Local Object、Branch Group Nodes、Behavior Node、Shape3D Node…
    叶子节点(Leaf):Appearance、Geomery..



图1:在应用中的Java3D场景图



场景图中线和线的交汇点称为节点(Node),这些节点都是Java3D类的实例(Instance of Class),节点之间的线表示各个实例之间的关系。

    Virtual Universe是根节点,每一个场景图的Virtual Universe是唯一的。
    在Virtual Universe下面是Locale节点,每个程序可以有一个或多个Locale,但同时只能有一个Locale处于显示状态,就好象一个三维世界非常大,有很多个景点,但我们同时只能在一个景点进行观察。Java3D允许从一个Locale跳到另一个Locale,不过绝大多数程序只有一个Locale。
    每一个Locale可以拥有多个BranchGroup节点。所有三维形体的其位置信息(Transform Group Nodes)都建立在BranchGroup节点之上。
    TransformGroup Node用来设定Shape3D在Virtual Universe中的位置。
    Spape3D Node是三维图形节点,这个节点的实体放映在最后的显示画面中,就是三维世界中的每个形体。包括正方体、球体以及任何形状和外观的三维形体。
    位于场景图最下层的是两个叶子节点:三维体的外观(Appearance)和几何信息(Geometry),这两个节点定义了一个三维体的显示效果。
    View Platform位于图1的另一个分枝上,与前面所有描述三维体的性质的概念不同,View Platform和View都是用来定义观察者的信息。

上面所列的概念很多,但是对于建立一个简单的Java3D程序,我们至少需要了解三个概念:虚拟宇宙(Virtual Universe)、场景(Locale)、坐标系统。
2.1 虚拟宇宙(Virtual Universe)
在Java3D中,虚拟宇宙被定义为结合一系列对象的三维空间。虚拟宇宙被用作最大的聚集体表现单位,同时也可被看作一个数据库。不管是在物理空间还是逻辑内容,虚拟宇宙都可以很大。实际上在大多数情况下,一个虚拟宇宙就可以满足一个应用程序所有的需求。
虚拟宇宙是各自独立的个体,原因是在任何时候一个结点对象都不能在超过一个的虚拟宇宙中存在。同样的,在一个虚拟宇宙中的结点对象也不能在其他的虚拟宇宙中可见或者与其他的对象结合。
对于一个Java3D应用程序,必须定义一个虚拟宇宙才可以在这个"宇宙"中显示三维图像。
2.2 Java3D的坐标系统
默认情况下,Java3D的坐标系统是右旋的,用方位语义学来解释就是:正y方向是本地重力的上,正x方向是水平的右,正z是这对着观察者的方向。默认的单位是米。
双精度浮点、单精度浮点甚至是定点来表示的三维坐标都足够来表示和显示丰富的3D场景。不幸的是,场景不是真实世界,更不必说整个宇宙了。如果使用单精度坐标,有可能出现下列情景:

    离原点仅有一百公里的距离,被描绘得相当量子化,所能达到的最好效果就是三分之一英寸,在实际应用中这样的精度比要求的粗糙的多。
    如果要缩小到一个很小的尺寸(例如表现集成电路的大小),甚至在离原点很近的地方就会出现同坐标问题。

为了支持一个大型的邻接虚拟宇宙,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:Java 3D 高分辨率坐标


   
        
            Java 3D 高分辨率坐标
        
        
            2n Meters
            Units
        
        
            87.29
            Universe (20 billion light years)
        
        
            69.68
            Galaxy (100000 light years)
        
        
            53.07
            Light year
        
        
            43.43
            Solar system diameter
        
        
            23.60
            Earth diameter
        
        
            10.65
            Mile
        
        
            9.97
            Kilometer
        
        
            0.00
            Meter
        
        
            -19.93
            Micron
        
        
            -33.22
            Angstrom
        
        
            -115.57
            Planck length
        
   

2.3 场景(Locale)
为了支持大型虚拟宇宙,Java3D提出了"Locale"的概念。Locale把高分辨率坐标作为起源。把高分辨率坐标看作精确的定位,它在高分辨率坐标的影响范围之内使用精度较低的浮点坐标指定对象的位置。
一个Locale和与它结合的高分辨率坐标一起组成了在虚拟宇宙之下的一个表现层。所有虚拟宇宙包含一个或多个高分辨率Locale。而所有其他的对象都是附加在一个Locale上的。在整个体系中,高分辨率坐标扮演的是上层的仅供翻译的转换结点。例如,附加到一个特定Locale的所有对象的坐标都会与这个Locale位置的高分辨率坐标有关。(图2)


图2:高分辨率坐标指定场景



如果一个虚拟宇宙与传统的计算机图像的概念相近,给定的虚拟宇宙可能会变得太大。所以在通常情况下最好把一个场景图看作是一个高分辨率坐标场景的子结点。
构造一个三维场景,程序员必须运行一个Java3D程序。这个Java3D应用程序必须首先创建一个虚拟宇宙对象并且至少把一个Locale对象附加之上。然后,构建出需要的场景图像,它由一个分支组结点开始并且包括至少一个观察平台对象,而场景图就是附加于这个观察平台。当一个包含场景图的观察对象被附加于一个虚拟宇宙,Java3D的渲染循环就开始工作。这样,场景就会和它的观察对象一起被绘制在画布上。
2.4 编程实现一个三维世界
这一部分描述怎样调用VirtualUniverse、Locale和HiResCoord对象的编程接口实现建立一个完整的"三维世界"。注意,这个三维世界有原点、坐标,是实现三维显示程序的第一步。

    VirtualUniverse对象有下列构造函数:
   
        
            
               
               
public VirtualUniverse()

               
            
        
   
   

    这个函数构造了一个新的VirtualUniverse对象,这个对象可以用来创建Locale对象。
   
    Locale对象有下列构建器:
   
        
            
               
               
public Locale(VirtualUniverse universe)
public Locale(VirtualUniverse universe, int x[], int y[], int  z[])
public Locale(VirtualUniverse universe, HiResCoord hiRes)

               
            
        
   
   

    这三个构建器在指定的VirtualUniverse中创建了一个新的高分辨率Locale对象。其中第一个形成了一个在(0.0,0.0,0.0)的Locale对象。其他的两个构建器在指定的坐标上建立了Locale对象。在第二种形式里,参数x,y,z是含八个32位整数的数组,这些数组指定了各自的高分辨率坐标。
    HiResCoord对象定义了一个使用三个高分辨率坐标的点,而每一个坐标又由三个定点数组成。每个高分辨率坐标数共有256位,第128位是二进制小数点。Java3D使用长度为八的整数数组来定义或提取一个256位的坐标值。Java3D用数组内的第一个整数来表示高32位,最后一个整数来表示低32位。
   
    HiResCoord 对象有以下的构建函数:
   
        
            
               
               
public HiResCoord(int x[], int y[], int z[])
public HiResCoord(HiResCoord hc)
public HiResCoord()

               
            
        
   
   

    第一个构造函数从输入的三个长度为八的整数数组生成高分辨率坐标。整数数组定义了与其同名坐标对象的值。第二个构造函数通过复制另外一个坐标创建一个新的坐标。第三个构造函数创建了一个值为(0.0,0.0,0.0)的坐标。
    所有Java3D程序都会首先建立VirtualUniverse和Locale对象,也就是说都会包含表3所示的代码。为了方便使用,Java3D为最原始的VirtualUniverse创建了几个子类:SimpleUniverse 、ConfiguredUniverse,这些子类保证了可以将三维图像轻易的在通过Canvas3D的对象在Applet或Frame中显示。其中最常用到的是SimpleUnivese对象,这个类位于包com.sun.j3d.utils.universe中。
   
        
            
               
               
u = new SimpleUniverse(v,viewer);
u.getViewingPlatform();
ViewingPlatform viewingPlatform = u.getViewingPlatform();

               
            
        
   
   

    例1 初始化VirtualUniverse和Locale代码



回页首
Java3D的观察模式
Java3D引入了一种新的观察模式,这种模式使Java编写的显示效果符合"编写一次,随处运行"的原则。Java3D还把这种功能推广到显示设备或六等级自由度输入外部设备,例如跟踪摄像头。这种新的观察模式的"一次编写,随处观察"的特性意味着用Java3D观察模式编写的应用程序和Applet可以广泛应用于各种各样的显示设备。在不修改场景图的条件下,图像可以在包括标准电脑显示、多放射显示空间和安装摄像头设备的显示设备上被渲染。这也意味着在不需要修改场景图的情况下,同一个应用程序既能够渲染立体景象,还能通过摄像头的输入控制渲染过的观察图。
Java3D的观察模式通过完全分离虚拟和现实世界来实现这种多功能性。这种模式区分了以下两种情况:

    一个应用程序通过控制观察平台的位置和方向在虚拟宇宙中对一个观察台对象(ViewPlatform)定位、定向和设定比例尺;
    渲染器使用已知位置和方向计算出要使用的观察对象,对终端用户物理环境的描述确定用户在物理环境中的位置和方向。

3.1 为什么使用一个新的模式
在底层的编程接口中可以找到基于照相机的观察模式,开发者通过它可以控制所有渲染图的参数。它可以应付处理常规的应用程序,但是处理有更广阔的适应性的系统的时候就显得力不从心,这些系统包括:把整个世界作为一个单元装入和显示的观察器或浏览器、可供终端用户观察、操纵、显示、甚至与虚拟世界交互的系统。
基于照相机的观察模式仿效在虚拟世界中放置一个照相机而不是一个人。开发者必须持续重新配置一个照相机来模拟"在虚拟世界中有一个人"。
Java3D观察模式直接和跟踪摄像头结合。在有摄像头的情况下,用户会有好像他们是真实的存在在那个虚拟世界的错觉,而开发者可以不做任何附加的工作就可以为用户带来这种效果。
在没有摄像头并且只是用来表现一个单一的标准显示的情况下,Java3D观察模式表现得更像传统的基于照相机的观察模式,只是加上了能够产生立体透视图的功能。
在一个需要由物理环境规定一些观察参数的系统中,让应用程序来控制所有的观察参数并不合理。
例子就是:一个带有摄像头的显示设备可以用其光系统直接决定应用程序中的观察领域。不同的设备有不同的光系统,程序开发者硬绑定这样的参数或允许终端用户改变这样的参数都是不合理的。
另外一个例子是:一个可以由用户当前的头部位置自动计算出观察参数的系统。只有一个对世界的说明和一条预先定义的轨迹可能不会严密的定义一个终端对象的观察。对于有摄像头设备用户,他们可能会期待在沿着一条固定的路线前进的时候能够看到他们左右两旁的物体。就好像在一个游乐场中,游客乘坐观光车按照固定的路线参观游乐场,但是在这过程中,游客可以持续转动他们的头。
由于依靠终端用户的具体物理环境,观察的各个参数,尤其是观察和投影的基体变化很大。影响观察和投影基体的因素包括显示设备的物理尺寸,显示设备的安装方法(在用户的桌面或用户的头顶上),计算机是否知道用户的头在三维空间的位置,头顶装置真实的观察领域,显示设备上每平方英寸的像素数,还有其他类似的参数。
Java3D建立的观察模式完全可以满足上述所有的需求。
3.2 分离物理和虚拟
Java3D分离了虚拟环境和物理环境:应用程序在虚拟环境中按照一定关系放置对象,而用户存在在物理环境之中,看计算机显示器并操纵输入设备。
Java3D也定义了用户所在的物理世界和图像程序所在的虚拟世界之间最基本的通信。这种"物理到虚拟世界"的通信定义了一个单一的公共空间,在这个空间中用户的动作影响虚拟世界中的对象,而在虚拟世界中的任何活动都会影响最终用户的观察。
虚拟世界是虚拟对象存在的通用空间。虚拟世界的坐标系统相对于每个Locale对象的高分辨率坐标存在,它定义了所有附加于这个Locale的虚拟世界坐标原点。包含当前活动的观察平台对象的Local定义了用来绘图的虚拟世界坐标。Java3D最后把所有图像单元的坐标转换到通用的虚拟世界空间中。
物理世界就是指真实的世界。这是真实的用户存在和移动他(她)的头和手的空间。这也是使用任何物理追踪仪可以定义他们的局部坐标和几个标准的坐标系统被描述的空间。
物理世界是一个空间,而不是Java3D不同的程序执行实例之间的通用坐标系统。所以当两个不同的计算机在世界上两个不同的地方同时运行同一个程序的时候,Java3D中没有直接来描述它们在物理世界坐标系统中相对位置的机制。因为标准问题,当地的跟踪系统仅仅定义了特定的Java3D应用程序实例的物理坐标系统。
分享到: QQ好友和群QQ好友和群 腾讯微博腾讯微博 腾讯朋友腾讯朋友 微信微信
转播转播0 分享淘帖0 收藏收藏0 支持支持0 反对反对0
回复

使用道具 举报

Asen    

867

主题

0

听众

1万

积分

外协人员

Rank: 7Rank: 7Rank: 7

纳金币
17488
精华
1
沙发
发表于 2011-8-18 11:05:47 |只看该作者

               
回复

使用道具 举报

1023

主题

3

听众

359

积分

设计实习生

Rank: 2

纳金币
335582
精华
0

最佳新人

板凳
发表于 2011-12-30 18:23:24 |只看该作者
很经典,很实用,学习了!
回复

使用道具 举报

   

671

主题

1

听众

3247

积分

中级设计师

Rank: 5Rank: 5

纳金币
324742
精华
0

最佳新人 活跃会员 热心会员 灌水之王 突出贡献

地板
发表于 2012-1-6 19:09:33 |只看该作者
呵呵,很漂亮啊
回复

使用道具 举报

5969

主题

1

听众

39万

积分

首席设计师

Rank: 8Rank: 8

纳金币
-1
精华
0

最佳新人 活跃会员 热心会员 灌水之王 突出贡献

5#
发表于 2012-3-30 23:20:58 |只看该作者
水。。。
回复

使用道具 举报

tc    

5089

主题

1

听众

33万

积分

首席设计师

Rank: 8Rank: 8

纳金币
-1
精华
0

最佳新人 活跃会员 热心会员 灌水之王 突出贡献

6#
发表于 2012-4-24 23:31:12 |只看该作者
佩服,好多阿 ,哈哈
回复

使用道具 举报

   

671

主题

1

听众

3247

积分

中级设计师

Rank: 5Rank: 5

纳金币
324742
精华
0

最佳新人 活跃会员 热心会员 灌水之王 突出贡献

7#
发表于 2012-6-5 23:27:22 |只看该作者
很经典,很实用,学习了!
回复

使用道具 举报

tc    

5089

主题

1

听众

33万

积分

首席设计师

Rank: 8Rank: 8

纳金币
-1
精华
0

最佳新人 活跃会员 热心会员 灌水之王 突出贡献

8#
发表于 2012-11-14 04:01:43 |只看该作者
读铁系缘分,顶铁系友情
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

关闭

站长推荐上一条 /1 下一条

手机版|纳金网 ( 闽ICP备08008928号

GMT+8, 2024-5-18 00:16 , Processed in 0.110842 second(s), 29 queries .

Powered by Discuz!-创意设计 X2.5

© 2008-2019 Narkii Inc.

回顶部