摘要: 互联网的出现及飞速发展使IT业的各个领域发生了深刻的变化,它必然引发一些新技术的出现。3D图形技术并不是一个新话题,在图形工作站以至于PC机上早已日臻成熟,并已应用到各个领域。然而互联网的出现,却使3D图形技术发生了和正在发生着微妙而深刻的变化。Web3D协会(前身是VRML协会)最先使用Web3D术语,这一术语的出现反映了这种变化的全貌,没有人能严格定义Web3D,在这里我们把Web3D理解为:互联网上的3D图形技术,互联网代表了未来的新技术,很明显,3D图形和动画将在互联网上占有重要的地位。Java3D API是Sun定义的用于实现3D显示的接口。使用Java 的重要理由之一是它的平台无关性。Java3D提供了基于Java的上层接口。Java3D把OpenGL和DirectX这些底层技术包装在Java接口中。这种全新的设计使3D技术变得不再繁琐并且可以加入到J2SE、J2EE的整套架构,这些特性保证了Java3D技术强大的扩展性本文以Java3D为开发平台,利用Java语言强大的网络功能,实现了在网页上对3D动画进行显示和操作。
关键字:
目录:
系统分析:
§3.1 总体设计
设计思想是:以JAVA3D为平台,使用JBuilder编译器,生成一个三维小场景,实现简单实体建模,物体运动,场景移动,各种灯光,雾等场景变换操作以及更换背景图片增加背景音乐等三维体系的基本功能。
§3.2 基本形体的生成
和VRML不同,JAVA3D没有基本形体类,因而在程序中无法直接生成大量应用的基本形体,如BOX、CONE、SPHERE等。我们可以通过复杂的编程生成这些基本形体,也可以直接调用JAVA3D为我们提供的geometry classes,利用它生成程序所需要的BOX、COLORCUBE、CONE、SPHERE、CYLINDER。下面是这些基本体的生成方法。
3.2.1平板的生成
1.Box():成一个各边尺寸均为2的BOX,要说明的是,BOX、COLORCUBE、SPHERE的坐标原点均在其中心点,CONE、CYLINDER的则在其轴线的中点上。2. Box(float xdim, float ydim, Appearance ap) :成一个给定尺寸、给定外观属性的BOX ,例Box(.5f, .6f, .4f, myApp)3. Box(float xdim, float ydim, float zdim, int primflags, Appearance ap):生成一个有特定说明的BOX,例如:Box(.4f,.6f,.3f,Primitive.ENABLE_APPEARANCE_MODIFY, ap)表示程序在运行时可以改变其外观属性。
3.2.2 立方体的生成
1. ColorCube(double scale)
3.2.3 圆锥的生成
2. Cone (float radius, float height)3. Cone (float radius, float height, int primflags, Appearance ap)4. Cone(float radius, float height, int primflags, int xdivision, int ydivision, Appearance ap)这里,xdivision、ydivision可用来表示圆锥的显示是高精度的显示,或是底精度的显示,缺省时的中等精度时xdivision = 15; ydivision = 1; 我们可利用这两个参数来改变显示的效果,使显示圆锥的三角片更多或更少些。
3.2.4 球体的生成
3. Sphere (float radius, Appearance ap)4. Sphere(float radius, int primflags, Appearance ap)5. Sphere(float radius, int primflags, int divisions)6. Sphere(float radius, int primflags, int divisions, Appearance ap)这里,divisions的作用和圆锥的xdivision、ydivision相似。
3.2.5.圆柱体的生成
2. Cylinder (float radius, float height) 3. Cylinder (float radius, float height, Appearance ap)4. Cylinder (float radius, float height, int primflags, Appearance ap) 5. Cylinder(float radius, float height, int primflags, int xdivision, int ydivision, Appearance ap)
§3.3 点、线、面的生成
3.3.1点的生成
编写JAVA3D程序实际上是编写一个特定的场景图,给出了场景图中带有形体及其属性的一个分支(BranchGroup)和表示观察位置等数据的另一个分支(View Platform)。一般来说,表示观测位置的分支可以用JAVA3D的UTILITY来完成,即createSceneGraph方法的定义。在这个方法里,程序先定义了一个分支objRoot,然后用数组的形式定义了顶点坐标vert和颜色color,再用PointArray 定义了一组点point,并将顶点坐标及颜色赋值给point,由于JAVA3D中的PointArray点是Shape3D的子类,它不能直接放入一个BranchGroup,因而我们还要先定义一个Shape3D对象shape,再将point赋予shape,这样point就可以放入BranchGroup类型的对象objRoot中了。JAVA3D提供的API中,可用于生成Point的对象有: PointArray IndexedPointArrayPointArray( int vertexCount, int vertexFormat );这里,vertexCount表示应生成的点的数目,vertexFormat表示所需要的顶点的格式。TEXTURE_COORDINATE_2 二维纹理坐标数组TEXTURE_COORDINATE_3 三维纹理坐标数组IndexedPointArray( int vertexCount, int vertexFormat,int indexCount );利用本函数,我们可以从众多的点中,选择特定的点来显示。这里,vertexCount表示顶点坐标数组所提供的点的总个数,indexCount表示最终应生成的点的个数。JAVA3D可以生成任意大小的点,并且可以使点为方点或圆点。
3.3.2直线的生成
利用JAVA3D的一些对象,生成各种直线。可以生成直线的对象有:我们可以根据各种不同的情况,生成不同的直线,如给定宽度的直线、虚线等。相应的的方法有:setLineWidth(float lineWidth)setLinePattern(int linePattern)setLineAntialiasingEnable(boolean state)int PATTERN_SOLID,int PATTERN_DASH,int PATTERN_DOT,int PATTERN_DASH_DOT
3.3.3面的生成
生成平面的对象及其定义 JAVA3D可通过编程显示出面来,面有两种:三角形和四边形,相应的对象为Triangle和Quad。6. IndexedTriangleStripArray7. IndexedTriangleFanArray
§3.4 外部复杂形体的调用
利用前面介绍的方法生成我们所需要的基本形体,生成点、线、平面。但有的时候,我们需要用到其它格式的三维形体,如VRML2.0格式的图形文件,AUTOCAD绘出的DWG格式的三维形体,3DS MAX绘制出的复杂形体。对于这些形体,我们可以非常方便地将其用到JAVA3D程序中去。下面我们介绍一些图形格式在JAVA3D中的应用方法。一. Wavefront的OBJ格式的图形文件的调用JAVA3D编译环境所带的UTILITY有两个LOADER,一个可用来调用Wavefront软件的OBJ格式的三维图形格式文件,一个可用来调用Lightwave软件的LWS及LWO格式的三维图形格式文件。为了使JAVA3D能够调用Wavefront的OBJ格式的图形文件,程序的头四行import语句就是用来处理Wavefront的OBJ格式的图形文件,第五行的import语句则是打开外部文件之用。import com.sun.j3d.loaders.objectfile.ObjectFile; import com.sun.j3d.loaders.ParsingErrorException; import com.sun.j3d.loaders.IncorrectFormatException; import com.sun.j3d.loaders.Scene; import java.io.*;二. VRML2.0(VRML97)图形文件在JAVA3D中的应用简介利用VRML97的LOADER我们可以在JAVA3D程序中方便地调用VRML图形。调用VRML97程序就象调用Wavefront的OBJ一样简单。 三. AUTOCAD R14的DWG图形及3DS MAX图形在JAVA3D中的应用。在三维图形生成过程中,国内目前大量使用AUTOCAD及3DS MAX等软件。对于3DS MAX软件,处理起来非常方便 3DS MAX可以将其图形直接输出成VRML97格式。对于AUTOCAD R14来说,目前还不太方便,需借助第三方软件转换成JAVA3D支持格式。
§3.5背景变换的实现方法
3.5.1 灯光
光用于照亮场景中的几何对象。有几种不同的光类型,它们都是抽象 Light 类的子类。所有光都有一个颜色值,即开/关位,以及一个描述它照亮的场景区域的绑定对象。在现实世界里,周围的对象被几个不同的光源照亮。从窗户射进的阳光和屋顶的灯光一起照亮了屋内的一切。两种光都会影响屋内对象的颜色和外观。在 Java 3D 中,可以通过使用多个光源来模拟实际的光照效果。环境光:在场景中 AmbientLight 无处不在。它不发自某个特定点,也不指向某个特定方向。Point Light 从一个指定位置向各个方向辐射,并随着距离的增加而减弱。点光源的一个例子是没有灯罩的台灯。void setPosition( Point3f pos )Spotlight PointLight的继承,是一种将光的范围限制在一个圆锥形内的点光源。聚光源的一个例子是手电筒。直射光:DirectionalLight 的光线射向某一个特定方向,却不发自任何特定的位置。这种定向光的所有光线都平行发射。虽然从技术上说,太阳是一个点光源,但使用 DirectionalLight 可以更准确地模拟太阳光。
AmbientLight PointLight
Spotlight DirectionalLight
所有的 Light 节点都是场景图中的叶节点。创建它们时,需要指定 Bounds 对象;我们使用 BoundingSphere。光将仅仅影响那些位于光的 BoundingSphere 所定义的空间内的几何对象,因此我们需要确保 BoundingSphere 足够大。在创建完光之后,我们用Scene1.addChild( Node );将其附加到场景图的顶部 BranchGroup。光、行为和材质都在场景图的上面添加。
3.5.2 纹理贴图
装入纹理 同光照一样,纹理贴图影响整个几何对象。再一次使用 Appearance 类来指定纹理贴图效果。Java 3D 简化了装入纹理图像的过程。TextureLoader 类位于 Java3D 实用类中。为了看起来更真实,请总是将纹理图像的宽度和高度设置成 2 的幂。其它的值会导致 TextureLoader 将纹理压变形。Primitive 类将生成纹理坐标――就象它们为计算光照生成法线一样。
3.5.3 雾
雾效果可以增添场景的真实感,也可以使远处的形体变模糊或是屏蔽它们,也可以使场景产生透视效果。Java3D中可以用ExponentialFog类添加雾效果。
§3.6 动画的生成
所有的内插器节点在使用时都需要与TimeSensor(时间传感器)配合使用。TimeSensor把给定的时间周期归一化,虽然时间的周期 cycleInterval 有给定的秒数,但计算机内部将其处理成从0.0到 1.0,即起始时间为0.0,终止时间为1.0,假如一个时间周期为 20(单位均为秒),则第6秒的归一化结果是0.3,第10秒的归一化结果是0.5,第20秒的归一化结果是1.0。 Alpha可以输出从0到1之间的数值给特定的内插对象,当Alpha输出的数值为0时,对应的特定内插对象的值为最小;当Alpha输出的数值为1时,对应的特定内插对象的值为最大;当Alpha输出的数值为0到1之间的数值时,对应的特定内插对象生成和Alpha成相同比例的数值。假设某一时刻Alpha输出的数值为0.2,则对应的特定内插对象的当前值为最小值加上最大最小值之差乘以0.2。(当前值-最小值)/(最大值-最小值)=0.2JAVA3D里的各种Interpolator对象可用来旋转形体、移动形体的坐标、变化形体的颜色等。假设我们要让一个形体在规定的时间内按照指定的方式运动,我们首先要给出时间段的大小,还要指出时间是否要循环。这些内容都是由Alpha类来完成的。基本上我们用它以及一个旋转内插器RotationInterpolator来使形体绕着其所在的局部坐标系不停地旋转。 本次毕业设计中实现一个JAVA3D场景,其中包括各类灯光的实现,三维场景的移动,任意物体的运动,场景背景变换,指数雾的实现以及与之配合的背景音乐.该3D场景设计中运用到立方体、圆锥及椭圆等基本形体,生成Temple和Tower;各种点、线、面生成地面及背景环境。以下即是其设计流程图: