BBS水木清华 张杰
一. 生成平面的对象及其定义
JAVA3D可通过编程显示出面来,面有两种:三角形和四边形,相应的对象为Triangle
和Quad。
JAVA3D用于生成平面的对象有:
1.TriangleArray
TriangleArray (int vertexCount, int vertexFormat )
2.QuadArray
QuadArray (int vertexCount, int vertexFormat )
3.TriangleStripArray
TriangleStripArray ( int vertexCount , int vertexFormat,
int[] stripVertexCounts )
4.TriangleFanArray
TriangleFanArray ( int vertexCount ,int vetexFormat,
int[] stripVertexCounts )
5.IndexedTriangleArray
IndexedTriangleArray (int vertexCount , int vertexFormat,
int indexCount)
6.IndexedQuadArray
IndexedQuadArray (int vertexCount , int vertexFormat,
int indexCount )
7.IndexedTriangleStripArray
IndexedTriangleStripArray( int vertexCount, int vertexFormat,
int indexCount, int stripIndexCounts[])
8.IndexedTriangleFanArray
IndexedTriangleFanArray ( int vertexCount, int vertexFormat,
int indexCount, int stripIndexCounts[])
二. TriangleArray生成的面
和前面介绍的PointArray、LineArray一样,面也可以用
TriangleArray来生成,利用它可以生成三角片面我们先看一下TriangleArray的定义
:
TriangleArray (int vertexCount, int vertexFormat )
这里:
vertexCount表示顶点的个数(必须为三的倍数)
vertexFormat表示顶点的格式(第七讲有介绍)
下面我们看一个利用TriangleArray的例子,例子里有九个点。
--1-- --4----7--
--0----3----6--
--2-- --5----8--
//triShape1.java
import javax.media.j3d.*;
public class triShape1 extends Shape3D {
private float vert[] = {
-.8f , .0f ,0.0f,
-.4f , .8f ,0.0f,
-.4f , -.8f,0.0f,
-.2f , .0f ,0.0f,
0.2f , .8f ,0.0f,
0.2f , -.8f,0.0f,
0.4f , .0f ,0.0f,
0.8f , .8f ,0.0f,
0.8f , -.8f,0.0f,
};
private float color[] = {
0.0f,0.5f,1.0f,
0.5f,0.0f,1.0f,
0.0f,0.8f,2.0f,
1.0f,0.0f,0.3f,
0.0f,1.0f,0.3f,
0.3f,0.8f,0.0f,
0.0f,0.5f,1.0f,
0.5f,0.0f,1.0f,
0.0f,0.8f,2.0f,e3D {
int StripCount[] = new int[2];
private float vert[] = {
-.6f ,.8f , 0.0f,
-.6f , -.8f,0.2f,
-0.2f ,.5f,-.2f,
-0.2f , -.5f , 0.2f,
0.0f , -.5f,-.2f,
0.0f ,.5f ,.2f,
0.2f ,.0f, .0f,
0.2f ,.8f , 0.3f,
0.2f , -.8f, -0.3f,
0.6f ,.8f,0.0f,
0.6f , -.8f,0.5f,
0.8f , 0.0f ,.3f
};
private float color[] = {
1.0f,0.5f,0.0f,
1.0f,0.0f,0.5f,
1.0f,0.8f,0.0f,
5.0f,1.0f,0.0f,
0.0f,1.0f,0.5f,
0.9f,1.0f,0.0f,
0.5f,0.0f,1.0f,
0.0f,0.5f,1.0f,
1.0f,0.5f,0.0f,
1.0f,0.0f,0.5f,
1.0f,0.8f,0.0f,
};
public triShape3() {
StripCount[0] = 7;
StripCount[1] = 5;
TriangleStripArray tri = new TriangleStripArray(12,
TriangleStripArray.COORDINATES|
TriangleStripArray.COLOR_3 , StripCount);
tri.setCoordinates(0,vert);
tri.setColors(0,color);
PolygonAttributes pa = new PolygonAttributes();
pa.setCullFace(PolygonAttributes.CULL_NONE);
Appearance ap = new Appearance();
ap.setPolygonAttributes(pa);
this.setGeometry(tri);
this.setAppearance(ap);
this.setGeometry(tri);
}
}
//end of triShape3.java
五. TriangleFanArray生成的面
TriangleFanArray对象的定义为:
TriangleFanArray ( int vertexCount ,int vetexFormat,
int[] stripVertexCounts )
利用TriangleFanArray对象,我们可以生成多组三角片面,每组三角片面占用一定数
量的顶点,每个组在生成三角片面时,头三个顶点构成一个三角片面,其余的顶点和前面
的顶点及每组第一个顶点生成一个三角片面。下面的triShape4.java程序中,我们生成了
两组三角片面,头5个点生成了三个相连的三角片面,后6个点生成了四个相连的三角片面
。外形就像两把扇子,一大一小。
//triShape4.java
import javax.media.j3d.*;
public class triShape4 extends Shape3D {
int FanCount[] = new int[2];
private float vert[] = {
0.0f , 0.0f , 0.0f,
-0.3f , 0.3f , 0.02f,
-0.1f , 0.4f , -0.02f,
0.1f , 0.4f ,0.02f,
0.3f,0.3f ,-0.02f,
0.0f, -0.8f ,0.0f,
-0.6f, -0.2f,0.02f,
-0.3f, -0.1f , -0.02f,
.0f, -0.05f, 0.02f,
.3f, -0.1f, -0.02f,
.6f, -0.2f,0.02f
};
private float color[] = {
1.0f,0.5f,0.0f,
1.0f,0.0f,0.5f,
1.0f,0.8f,0.0f,
5.0f,1.0f,0.0f,
0.0f,1.0f,0.5f,
0.9f,1.0f,0.0f,
0.5f,0.0f,1.0f,
0.0f,0.5f,1.0f,
1.0f,0.5f,0.0f,
1.0f,0.0f,0.5f,
};
public triShape4() {
FanCount[0] = 5;
FanCount[1] = 6;
TriangleFanArray tri = new TriangleFanArray(11,
TriangleFanArray.COORDINATES|
TriangleFanArray.COLOR_3 , FanCount);
tri.setCoordinates(0,vert);
tri.setColors(0,color);
PolygonAttributes pa = new PolygonAttributes();
pa.setCullFace(PolygonAttributes.CULL_NONE);
Appearance ap = new Appearance();
ap.setPolygonAttributes(pa);
this.setGeometry(tri);
this.setAppearance(ap);
this.setGeometry(tri);
}
}
//end of triShape4.java
JAVA3D学习系列(八)--面的生成(下)
BBS水木清华张杰
一. IndexedTriangleArray生成的面
IndexedTriangleArray对象的定义为:
IndexedTriangleArray (int vertexCount , int vertexFormat,
int indexCount)
利用这个对象,我们可以从一个顶点数组中挑选一些顶点生成自己所需要的三角片面
。程序triShape5.java中,有一个10个点的数组,我们从这个数组中选择了8个点,生成了
三个面,其中有一个点用了两次,假如所挑选的点都只用一次,则选择的点的数目必须为
3的倍数。
另外,在编程时,我们要注重点的旋转顺序,逆时针旋转和顺时针旋转有时会产生不
同的效果。
程序中,vertexCount表示顶点数组顶点的总数,indexCount表示生成的面的顶点个数
,数值为面的个数的三倍,本例中,生成的面为三个,故vertexCount为9。
//triShape5.java
import javax.media.j3d.*;
public class triShape5 extends Shape3D {
private float vert[] = {
-.6f ,.6f ,.0f ,
-.6f , -.6f, .0f ,
-.3f ,.6f ,.0f ,
-.3f , -.6f, .0f ,
-.0f ,.6f ,.0f ,
-.0f , -.6f, .0f ,
.3f ,.6f ,.0f ,
.3f , -.6f, .0f ,
.6f ,.6f ,.0f ,
.6f , -.6f, .0f ,
};
private float color[] = {
1.0f,0.5f,0.0f,
1.0f,0.0f,0.5f,
1.0f,0.8f,0.0f,
5.0f,1.0f,0.0f,
0.0f,1.0f,0.5f,
0.9f,1.0f,0.0f,
0.5f,0.0f,1.0f,
0.0f,0.5f,1.0f,
1.0f,0.5f,0.0f,
1.0f,0.0f,0.5f,
};
public triShape5() {
int[] index={ 0 , 1 ,2 , 4 , 5 , 6 , 6 , 7 , 8 };
int VertexCount=9;
IndexedTriangleArray tri = new IndexedTriangleArray(10,
IndexedTriangleArray.COORDINATES|
IndexedTriangleArray.COLOR_3 , VertexCount);
tri.setCoordinates(0,vert);
tri.setColors(0,color);
tri.setCoordinateIndices(0,index);
tri.setColorIndices(0,index);
PolygonAttributes pa = new PolygonAttributes();
pa.setCullFace(PolygonAttributes.CULL_NONE);
Appearance ap = new Appearance();
ap.setPolygonAttributes(pa);
this.setGeometry(tri);
this.setAppearance(ap);
this.setGeometry(tri);
}
}
//end of triShape5.java
二. IndexedQuadArray生成的面
IndexedQuadArray对象的定义为:
IndexedQuadArray (int vertexCount , int vertexFormat,
int indexCount )
利用这个对象,我们可以从一个顶点数组中挑选一些顶点生成自己所需要的四个点所
构成的平面。程序quadShape2.java中,有一个10个点的数组,我们从这个数组中选择了7
个点,生成了两个面,其中有一个点用了两次,假如所挑选的点都只用一次,则选择的点
的数目必须为4的倍数。这些选中的点构成了数组index。在输入每一个顶点的坐标及颜色
时,我们用到了下面两种方法:
setCoordinateIndices(0,index);
setColorIndices(0,index);
程序中,vertexCount表示顶点数组顶点的总数,indexCount表示生成的面的顶点个数
,数值为面的个数的4倍,本例中,生成的面为两个,故vertexCount为8。
编写IndexedQuadArray应用程序时,我们仍然要注重下面几个问题。
首先是四点应当共面,假如不共面,程序仍然可以编译运行,但显示的内容为两个三
角面。
其次是四个点组成的面不应有凹点,这有点象VRML程序中的Extrusion、IndexedFace
Set里的情况,当然,在VRML程序中四个点构成的面可以有凹点,这时只需要在相应的节点
内加上一个参数:
convexTRUE
而在JAVA3D程序中,假如QuadArray生成的面有凹点时,程序的显示结果会不正确。
//quadShape2.java
import javax.media.j3d.*;
public class quadShape2 extends Shape3D {
private float vert[] = {
-.6f , .6f , .0f ,
-.6f , -.6f, .0f ,
-.3f , .6f , .0f ,
-.3f , -.6f, .0f ,
-.0f , .6f , .0f ,
-.0f , -.6f, .0f ,
.3f , .6f , .0f ,
.3f , -.6f, .0f ,
.6f , .6f , .0f ,
.6f , -.6f, .0f ,
};
private float color[] = {
1.0f,0.5f,0.0f,
1.0f,0.0f,0.5f,
1.0f,0.8f,0.0f,
5.0f,1.0f,0.0f,
0.0f,1.0f,0.5f,
0.9f,1.0f,0.0f,
0.5f,0.0f,1.0f,
0.0f,0.5f,1.0f,
1.0f,0.5f,0.0f,
1.0f,0.0f,0.5f,
};
public quadShape2() {
int[] index={ 2 , 1 , 3 , 4 , 4 , 7 , 9 , 6};
int VertexCount=8;
IndexedQuadArray quad = new IndexedQuadArray(10,
IndexedQuadArray.COORDINATES|
IndexedQuadArray.COLOR_3 , VertexCount);
quad.setCoordinates(0,vert);
quad.setColors(0,color);
quad.setCoordinateIndices(0,index);
quad.setColorIndices(0,index);
PolygonAttributes pa = new PolygonAttributes();
pa.setCullFace(PolygonAttributes.CULL_NONE);
Appearance ap = new Appearance();
ap.setPolygonAttributes(pa);
this.setGeometry(quad);
this.setAppearance(ap);
this.setGeometry(quad);
}
}
//end of quadShape2.java
三. IndexedTriangleStripArray生成的面
IndexedTriangleStripArray对象的定义为:
IndexedTriangleStripArray( int vertexCount, int vertexFormat,
int indexCount, int stripIndexCounts[])
利用IndexedTriangleStripArray对象,我们可以生成多组三角片面,对于每一组三角
片面来说,它的头三个点生成一个面,从第四个点开始,每一个点都和前两个点生成一个
新的面。这些点可以通过一个数组index从一个顶点数组中任意选取,它和TriangleStrip
Array的差别在于TriangleStripArray对顶点没有选择权,而IndexedTriangleStripArray
对顶点具有选择权,其它的都一样。
程序triShape6.java给出了一个16个数构成的顶点数组,从中挑选了两组数,每一组
都有6个顶点构成并生成了相连的四个三角片面。
//triShape6.java
import javax.media.j3d.*;
public class triShape6 extends Shape3D {
int StripCount[] = new int[2];
private float vert[] = {
-.6f ,.6f ,.1f ,
-.6f ,.2f ,.2f ,
-.6f , -.2f ,.1f ,
-.6f , -.6f ,.2f ,
-.0f ,.6f , -.1f ,
-.0f ,.2f , -.2f ,
-.0f , -.2f , -.1f ,
-.0f , -.6f , -.2f ,
.6f ,.6f ,.1f ,
.6f ,.2f ,.2f ,
.6f , -.2f ,.1f ,
.6f , -.6f ,.2f ,
};
private float color[] = {
1.0f,0.5f,0.0f,
1.0f,0.0f,0.5f,
1.0f,0.8f,0.0f,
5.0f,1.0f,0.0f,
0.0f,1.0f,0.5f,
0.9f,1.0f,0.0f,
0.5f,0.0f,1.0f,
0.0f,0.5f,1.0f,
1.0f,0.5f,0.0f,
1.0f,0.0f,0.5f,
0.9f,1.0f,0.0f,
0.5f,0.0f,1.0f,
};
public triShape6() {
int[] index={ 0 , 1 , 4 , 5 , 8 , 9 , 2 , 3 , 6 , 7 , 10};
StripCount[0] = 6;
StripCount[1] = 5;
int indexCount=11;
IndexedTriangleStripArray tri = new IndexedTriangleStripArray(12,
IndexedTriangleStripArray.COORDINATES|
IndexedTriangleStripArray.COLOR_3 , indexCount , StripCount);
tri.setCoordinates(0,vert);
tri.setColors(0,color);
tri.setCoordinateIndices(0,index);
tri.setColorIndices(0,index);
PolygonAttributes pa = new PolygonAttributes();
pa.setCullFace(PolygonAttributes.CULL_NONE);
Appearance ap = new Appearance();
ap.setPolygonAttributes(pa);
this.setGeometry(tri);
this.setAppearance(ap);
this.setGeometry(tri);
}
}
//end of Shape6.java
四. IndexedTriangleFanArray生成的面
IndexedTriangleFanArray对象的定义为:
IndexedTriangleFanArray ( int vertexCount, int vertexFormat,
int indexCount, int stripIndexCounts[])
利用这一对象,我们可以从一组顶点数组中挑选我们所需要的顶点,生成多组三角片
面,每组三角片面占用一定数量的顶点,每个组在生成三角片面时,头三个顶点构成一个
三角片面,其余的顶点和前面的顶点及每组第一个顶点生成一个三角片面。下面的triSha
pe7.java程序中,我们生成了两组三角片面,头5个点生成了三个相连的三角片面,后6个
点生成了四个相连的三角片面。外形就像两把扇子,一大一小。程序中所用的数组为20个
点的顶点数组。
IndexedTriangleFanArray对象和TriangleFanArray的应用方法很相似,它们之间的不
同在于IndexedTriangleFanArray对象可以从顶点数组中挑选自己所需要的顶点,而Trian
gleFanArray对象没有挑选权,只能被动地使用顶点数组中的数据。
//triShape7.java
import javax.media.j3d.*;
public class triShape7 extends Shape3D {
int StripCount[] = new int[2];
private float vert[] = {
-.6f , .8f , -.1f ,
-.6f , .4f , -.0f ,
-.6f , .0f ,.1f ,
-.6f , -.8f , -.1f ,
-.4f , .8f , .1f ,
-.4f , .4f , .1f ,
-.4f , .0f ,-.1f ,
-.4f , -.8f , .1f ,
-.0f , .8f , -.1f ,
-.0f , .4f , -.0f ,
-.0f , .0f ,.1f ,
-.0f , -.8f , -.1f ,
.4f , .8f , .1f ,
.4f , .4f , -.05f ,
.4f , .0f ,-.1f ,
.4f , -.8f , .1f ,
.6f , .8f , -.1f ,
.6f , .4f , -.0f ,
.6f , .0f ,.1f ,
.6f , -.8f , -.1f ,
};
private float color[] = {
1.0f,0.5f,0.0f,
1.0f,0.0f,0.5f,
1.0f,0.8f,0.0f,
0.5f,1.0f,0.0f,
0.0f,1.0f,0.5f,
0.9f,1.0f,0.0f,
0.5f,0.0f,1.0f,
0.0f,0.5f,1.0f,
1.0f,0.5f,0.0f,
1.0f,0.0f,0.5f,
0.9f,1.0f,0.0f,
0.5f,0.0f,1.0f,
0.0f,1.0f,0.5f,
0.9f,1.0f,0.0f,
0.5f,0.0f,1.0f,
0.0f,0.5f,1.0f,
1.0f,0.5f,0.0f,
1.0f,0.0f,0.5f,
0.9f,1.0f,0.0f,
0.5f,0.0f,1.0f,
};
public triShape7() {
int[] index={ 9 , 4 , 8 , 12 , 16 , 11 , 2 , 6 , 10 , 14 , 18};
StripCount[0] = 5;
StripCount[1] = 6;
int indexCount=11;
IndexedTriangleFanArray tri = new IndexedTriangleFanArray(20,
IndexedTriangleFanArray.COORDINATES|
IndexedTriangleFanArray.COLOR_3 , indexCount , StripCount);
tri.setCoordinates(0,vert);
tri.setColors(0,color);
tri.setCoordinateIndices(0,index);
tri.setColorIndices(0,index);
PolygonAttributes pa = new PolygonAttributes();
pa.setCullFace(PolygonAttributes.CULL_NONE);
Appearance ap = new Appearance();
ap.setPolygonAttributes(pa);
this.setGeometry(tri);
this.setAppearance(ap);
this.setGeometry(tri);
}
}
/end of triShape7.java
JAVA3D学习系列(九)---外部复杂形体的调用
张 杰
(Wavefront的OBJ,Lightwave的LWS和LWO,WRL,DWG,3DS)
我们可以利用前面介绍的方法生成我们所需要的基本形体,生成点、线、平面。但有
的时候,我们需要用到其它格式的三维形体,如VRML2.0格式的图形文件,AUTOCAD绘出的
DWG格式的三维形体,3DS MAX绘制出的复杂形体。对于这些形体,我们可以非常方便地将
其用到JAVA3D程序中去。下面我们介绍一些图形格式在JAVA3D中的应用方法。
一. Wavefront的OBJ格式的图形文件的调用
1. OBJ格式图形的简单调用
JAVA3D编译环境所带的UTILITY有两个LOADER,一个可用来调用Wavefront软件的OBJ格
式的三维图形格式文件,一个可用来调用Lightwave软件的LWS及LWO格式的三维图形格式文
件。
假设我们有一个OBJ格式的文件(JAVA3D附带有两个OBJ,文件名分别为galleon.obj和
p51_mustang.obj,以及调用它们的一个程序ObjLoad.java)。
我们编写的第一个程序Obj1.java介绍了OBJ图形的调用方法。
程序的便宜方法:
javac Obj1.java
程序的运行方法(假设图形在同一目录):
java Obj1 galleon.obj
//Obj1.java
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.*;
import java.applet.Applet;
import java.awt.BorderLayout;
import com.sun.j3d.utils.applet.MainFrame;
import com.sun.j3d.utils.universe.*;
import javax.media.j3d.*;
import javax.vecmath.*;
public class Obj1 extends Applet {
private String filename = null;
public BranchGroup createSceneGraph(String args[]){
BranchGroup objRoot = new BranchGroup();
Color3f light1Color = new Color3f(1.0f, 1.0f, 0.9f);
Vector3f light1Direction= new Vector3f(4.0f, -7.0f, -12.0f);
BoundingSphere bounds =
new BoundingSphere(ne罚?颐歉?隽耍?nbsp;
private double creaseAngle = 60.0;
------------------------------------------------
易都站注:上面的程序原文如此,肯定是出现了异常。作为弥补,下面我把以前从张
杰网站上收集来的二个相关的程序贴出来,供感爱好的网友参考:
//Obj1.java
import java.applet.Applet;
import java.awt.BorderLayout;
import com.sun.j3d.utils.applet.MainFrame;
import com.sun.j3d.utils.universe.*;
import javax.media.j3d.*;
import javax.vecmath.*;
import com.sun.j3d.loaders.Scene;
import com.sun.j3d.loaders.objectfile.ObjectFile;
public class Obj1 extends Applet {
public BranchGroup createSceneGraph() {
BranchGroup objRoot = new BranchGroup();
TransformGroup objScale = new TransformGroup();
Transform3D t3d = new Transform3D();
t3d.setScale(0.8);
objScale.setTransform(t3d);
objRoot.addChild(objScale);
BoundingSphere bounds = new BoundingSphere(new Point3d(0.0,0.0,0.0), 1
00.0);
Color3f lightColor = new Color3f(1.0f, 1.0f, 0.9f);
Vector3f lightDirection = new Vector3f(4.0f, -7.0f, -12.0f);
DirectionalLight light = new DirectionalLight(lightColor, lightDirecti
on);
light.setInfluencingBounds(bounds);
objRoot.addChild(light);
TransformGroup objTrans = new TransformGroup();
objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
objScale.addChild(objTrans);
BranchGroup b = new objLoad("galleon.obj");
objTrans.addChild(b);
Transform3D yAxis = new Transform3D();
Alpha rotationAlpha = new Alpha(-1, Alpha.INCREASING_ENABLE,
0, 0, 4000, 0, 0, 0, 0, 0);
RotationInterpolator rotator = new RotationInterpolator(rotationAlpha,
objTrans, yAxis, 0.0f, (float) Math.PI*2.0f);
rotator.setSchedulingBounds(bounds);
objTrans.addChild(rotator);
objRoot.compile();
return objRoot;
}
public Obj1(String args[]) {
setLayout(new BorderLayout());
Canvas3D c = new Canvas3D(null);
add("Center", c);
BranchGroup scene = createSceneGraph();
SimpleUniverse u = new SimpleUniverse(c);
u.getViewingPlatform().setNominalViewingTransform();
u.addBranchGraph(scene);
}
public static void main(String[] args) {
new MainFrame(new Obj1(args), 400,400);
}
}
//end of Obj1.java
//objLoad.java
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.*;
import javax.media.j3d.*;
public class objLoad extends BranchGroup{
public objLoad(String filename) {
BranchGroup obj = new BranchGroup( );
int flags = ObjectFile.RESIZE;
ObjectFile f = new ObjectFile(flags);
Scene s = null;
try {
s = f.load(filename);
}
catch (FileNotFoundException e) {
System.err.println(e);
System.exit(1);
}
catch (ParsingErrorException e) {
System.err.println(e);
System.exit(1);
}
catch (IncorrectFormatException e) {
System.err.println(e);
System.exit(1);
}
obj.addChild(s.getSceneGroup());
this.addChild(obj);
}
}
//end of objLoad.java
------------------------------------------------
它可以使程序运行时通过设定和VRML程序中同样的creaseAngle来提高或降低图形的显
示效果。给出了creaseAngle,f的定义也相应地有了变化,即调用的是ObjectFile的另一
个构造函数:
ObjectFile f = new ObjectFile(flags,(float)(creaseAngle * Math.PI / 180.0)
);
并在前面定义了flag:
int flags = ObjectFile.RESIZE;
本人未获得定义ObjectFile对象的源程序,故猜测ObjectFile.RESIZE可能是一个开关
参数,表示答应改变尺寸。
3.分成两个程序
上面给出的两个程序,程序不是很清楚,阅读起来比较困难,为此,我们将Obj2.jav
a分解成两个程序:
Obj3.java和objFile.java。
//Obj3.java
import java.applet.Applet;
import java.awt.BorderLayout;
import com.sun.j3d.utils.applet.MainFrame;
import com.sun.j3d.utils.universe.*;
import javax.media.j3d.*;
import javax.vecmath.*;
import com.sun.j3d.loaders.Scene;
import com.sun.j3d.loaders.objectfile.ObjectFile;
public class Obj3 extends Applet {
public BranchGroup createSceneGraph(){
BranchGroup objRoot = new BranchGroup();
TransformGroup objScale = new TransformGroup();
Transform3D t3d = new Transform3D();
t3d.setScale(0.3);
objScale.setTransform(t3d);
objRoot.addChild(objScale);
BoundingSphere bounds =
new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
Color3f bgColor = new Color3f(0.05f, 0.05f, 0.2f);
Background bg = new Background(bgColor);
bg.setApplicationBounds(bounds);
objRoot.addChild(bg);
Color3f light1Color = new Color3f(1.0f, 1.0f, 0.9f);
Vector3f light1Direction= new Vector3f(4.0f, -7.0f, -12.0f);
DirectionalLight light1
= new DirectionalLight(light1Color, light1Direction);
light1.setInfluencingBounds(bounds);
objRoot.addChild(light1);
TransformGroup objTrans = new TransformGroup();
objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
objScale.addChild(objTrans);
BranchGroup b1 = newobjFile("galleon.obj");
objTrans.addChild(b1);
Transform3D yAxis = new Transform3D();
Alpha rotationAlpha = new Alpha(-1, Alpha.INCREASING_ENABLE,
0, 0,
4000, 0, 0,
0, 0, 0);
RotationInterpolator rotator =
new RotationInterpolator(rotationAlpha, objTrans, yAxis,
0.0f, (float) Math.PI*2.0f);
rotator.setSchedulingBounds(bounds);
objTrans.addChild(rotator);
objRoot.compile();
return objRoot;
}
public Obj3(String args[]) {
setLayout(new BorderLayout());
Canvas3D c = new Canvas3D(null);
add("Center", c);
BranchGroup scene = createSceneGraph();
SimpleUniverse u = new SimpleUniverse(c);
u.getViewingPlatform().setNominalViewingTransform();
u.addBranchGraph(scene);
}
public static void main(String[] args) {
new MainFrame(new Obj3(args), 400,400);
}
}
//end of Obj3.java
--------------------------
//objFile.java
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.*;
import javax.media.j3d.*;
public class objFile extends BranchGroup{
private double creaseAngle = 60.0;
publicobjFile(String filename){
BranchGroup obj = new BranchGroup( );
int flags = ObjectFile.RESIZE;
ObjectFile f = new ObjectFile(flags,
(float)(creaseAngle * Math.PI / 180.0));
Scene s = null;
try {
s = f.load(filename);
}
catch (FileNotFoundException e) {
System.err.println(e);
System.exit(1);
}
catch (ParsingErrorException e) {
System.err.println(e);
System.exit(1);
}
catch (IncorrectFormatException e) {
System.err.println(e);
System.exit(1);
}
obj.addChild(s.getSceneGroup( ) );
this.addChild(obj);
}
}
//end of objFile.java
4.同时调用两个形体,两者单独旋转。
前面的程序中,形体只有一个,为此,我们编了一个程序,利用它可以调用两个OBJ形
体,一左一右,它们分别绕自身的轴旋转,当然,形体的生成仍然使用上面的objFile.ja
va程序。另外,我们还在程序中加了红色的背景。
//Obj4.java
import java.applet.Applet;
import java.awt.BorderLayout;
import com.sun.j3d.utils.applet.MainFrame;
import com.sun.j3d.utils.universe.*;
import javax.media.j3d.*;
import javax.vecmath.*;
import com.sun.j3d.loaders.Scene;
import com.sun.j3d.loaders.objectfile.ObjectFile;
public class Obj4 extends Applet {
public BranchGroup createSceneGraph(){
BranchGroup objRoot = new BranchGroup();
TransformGroup objScale = new TransformGroup();
Transform3D t3d = new Transform3D();
t3d.setScale(0.3);
objScale.setTransform(t3d);
objRoot.addChild(objScale);
BoundingSphere bounds =
new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
Color3f bgColor = new Color3f(1.05f, 0.00f, 0.0f);
Background bg = new Background(bgColor);
bg.setApplicationBounds(bounds);
objRoot.addChild(bg);
Color3f light1Color = new Color3f(1.0f, 1.0f, 0.9f);
Vector3f light1Direction= new Vector3f(4.0f, -7.0f, -12.0f);
DirectionalLight light1
= new DirectionalLight(light1Color, light1Direction);
light1.setInfluencingBounds(bounds);
objRoot.addChild(light1);
BranchGroup b1 = newobjFile("1.obj");
BranchGroup b2 = newobjFile("2.obj");
objScale.addChild(createObject (b1, -1.2f , 0.0f ));
objScale.addChild(createObject (b2, 1.2f , 0.0f ));
objRoot.compile();
return objRoot;
}
private GroupcreateObject (BranchGroup b, float xpos, float ypos ) {
Transform3Dt = newTransform3D ( );
t.setTranslation ( new Vector3f ( xpos, ypos, 0.0f ) );
TransformGroup objTrans = new TransformGroup(t);
TransformGroup spin = new TransformGroup();
spin.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
spin.addChild(b);
Transform3DyAxis = newTransform3D ( );
Alpha rotationAlpha = new Alpha(-1, Alpha.INCREASING_ENABLE,
0, 0,
4000, 0, 0,
0, 0, 0);
RotationInterpolator rotator =
new RotationInterpolator(rotationAlpha, spin, yAxis,
0.0f, (float) Math.PI*2.0f);
BoundingSphere bounds =
new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
rotator.setSchedulingBounds(bounds);
objTrans.addChild(rotator);
objTrans.addChild ( spin );
return objTrans ;
}
public Obj4(String args[]) {
setLayout(new BorderLayout());
Canvas3D c = new Canvas3D(null);
add("Center", c);
BranchGroup scene = createSceneGraph();
SimpleUniverse u = new SimpleUniverse(c);
u.getViewingPlatform().setNominalViewingTransform();
u.addBranchGraph(scene);
}
public static void main(String[] args) {
new MainFrame(new Obj4(args), 400,400);
}
}
//end of Obj4.java
JAVA3D学习系列(十)---DWG、WRL及3DS MAX图形的调用
BBS水木清华张杰
一. VRML2.0(VRML97)图形文件在JAVA3D中的应用简介
SUN公司为我们提供了一个VRML97的LOADER,利用它我们可以在JAVA3D程序中方便地调
用VRML图形。不过由于这个LOADER目前还不是很完善,因而没有放入JAVA3D之中,不过随
着它的完善,最终它会成为JAVA3D的一个组成部分,调用VRML97程序就象调用Wavefront的
OBJ一样简单。
我们可以从以下的网址下载(VRML97.ZIP)并安装,下载的网址为:
http://www.vrml.org/WorkingGroups/vrml-java3d/从这个网页上我们需要下载目前
大小为283KB的一个ZIP文件,VRML97.ZIP,利用解压程序将其解成VRML97.JAR,大小目前
为310KB,版本为0.90.2版,利用它可以让我们在JAVA3D程序中调用VRML97(VRML2.0)图
形。
二. VRML97.JAR的安装
获得VRML97.JAR后,假设我们的JDK1.2摆放的位置为目录JDK1.2,我们应将其放在下
面的子目录中:
C:\jdk1.2\lib
并在WINDOWS的AUTOEXEC.BAT文件中写入下面一行:
SET CLASSPATH=%CLASSPATH%;C:\JDK1.2\LIB\vrml97.jar
重新启动计算机,这样我们就可以利用它了。
当然,我们可以将VRML97.JAR放在一个目录中,利用下面的方法将其解开,不过所获
得的全为CLASS文件。
三. VRML97.JAR的应用
1.利用VRML971.JAR调用一个VRML文件,使VRML文件中的形体不停地
旋转,程序如下。
程序的编译方法:
javac Vrml1.java
程序的运行方法(假设图形在同一目录):
java Vrml1myShape.wrl
当然,假如所调用的形体非常大或非常小时,需要修改:
t3d.setScale(0.3);
中的数值。
//Vrml.java
import java.applet.Applet;
import java.awt.BorderLayout;
import com.sun.j3d.utils.applet.MainFrame;
import com.sun.j3d.utils.universe.*;
import javax.media.j3d.*;
import javax.vecmath.*;
import com.sun.j3d.loaders.vrml97.VrmlLoader;
import com.sun.j3d.loaders.Scene;
public class Vrml1 extends Applet {
private String filename = null;
public BranchGroup createSceneGraph(String args[]){
BranchGroup objRoot = new BranchGroup();
TransformGroup objScale = new TransformGroup();
Transform3D t3d = new Transform3D();
t3d.setScale(0.3);
objScale.setTransform(t3d);
objRoot.addChild(objScale);
Color3f light1Color = new Color3f(1.0f, 1.0f, 0.9f);
Vector3f light1Direction= new Vector3f(4.0f, -7.0f, -12.0f);
BoundingSphere bounds =
new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
DirectionalLight light1
= new DirectionalLight(light1Color, light1Direction);
light1.setInfluencingBounds(bounds);
objRoot.addChild(light1);
TransformGroup objTrans = new TransformGroup();
objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
objScale.addChild(objTrans);
VrmlLoader loader = new VrmlLoader();
Scene s = null;
try {
s = loader.load(filename);
} catch (Exception e) {
System.err.println(e);
System.exit(1);
}
objTrans.addChild(s.getSceneGroup());
Transform3D yAxis = new Transform3D();
Alpha rotationAlpha = new Alpha(-1, Alpha.INCREASING_ENABLE,
0, 0,
4000, 0, 0,
0, 0, 0);
RotationInterpolator rotator =
new RotationInterpolator(rotationAlpha, objTrans, yAxis,
0.0f, (float) Math.PI*2.0f);
rotator.setSchedulingBounds(bounds);
objTrans.addChild(rotator);
objRoot.compile();
return objRoot;
}
public Vrml1(String args[]) {
filename = args[0];
setLayout(new BorderLayout());
Canvas3D c = new Canvas3D(null);
add("Center", c);
BranchGroup scene = createSceneGraph(args);
SimpleUniverse u = new SimpleUniverse(c);
u.getViewingPlatform().setNominalViewingTransform();
u.addBranchGraph(scene);
}
public static void main(String[] args) {
new MainFrame(new Vrml1(args), 400,400);
}
}
//end of Vrml.java
可以看出,Vrml1.java和前面介绍的Obj2.java非常相似。
2.将Vrml.java分解成两个程序
上面的程序中,用于处理调用问题的部分我们可以提取出来,这样我们就可以多次重
复使用。
从下面的程序我们可以得知,Vrml2.java和前面介绍的Obj3.java除了Obj3改为Vrml2
,objFile改为vrmlLoad之外,其余什么也没有改变。vrmlLoad.java和objFile.java也非
常相似。
//Vrml2.java
import java.applet.Applet;
import java.awt.BorderLayout;
import com.sun.j3d.utils.applet.MainFrame;
import com.sun.j3d.utils.universe.*;
import javax.media.j3d.*;
import javax.vecmath.*;
import com.sun.j3d.loaders.Scene;
import com.sun.j3d.loaders.objectfile.ObjectFile;
public class Vrml2 extends Applet {
public BranchGroup createSceneGraph(){
BranchGroup objRoot = new BranchGroup();
TransformGroup objScale = new TransformGroup();
Transform3D t3d = new Transform3D();
t3d.setScale(0.3);
objScale.setTransform(t3d);
objRoot.addChild(objScale);
BoundingSphere bounds =
new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
Color3f bgColor = new Color3f(0.05f, 0.05f, 0.2f);
Background bg = new Background(bgColor);
bg.setApplicationBounds(bounds);
objRoot.addChild(bg);
Color3f light1Color = new Color3f(1.0f, 1.0f, 0.9f);
Vector3f light1Direction= new Vector3f(4.0f, -7.0f, -12.0f);
DirectionalLight light1
= new DirectionalLight(light1Color, light1Direction);
light1.setInfluencingBounds(bounds);
objRoot.addChild(light1);
TransformGroup objTrans = new TransformGroup();
objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
objScale.addChild(objTrans);
BranchGroup b1 = newvrmlLoad("7.wrl");
objTrans.addChild(b1);
Transform3D yAxis = new Transform3D();
Alpha rotationAlpha = new Alpha(-1, Alpha.INCREASING_ENABLE,
0, 0,
4000, 0, 0,
0, 0, 0);
RotationInterpolator rotator =
new RotationInterpolator(rotationAlpha, objTrans, yAxis,
0.0f, (float) Math.PI*2.0f);
rotator.setSchedulingBounds(bounds);
objTrans.addChild(rotator);
objRoot.compile();
return objRoot;
}
public Vrml2(String args[]) {
setLayout(new BorderLayout());
Canvas3D c = new Canvas3D(null);
add("Center", c);
BranchGroup scene = createSceneGraph();
SimpleUniverse u = new SimpleUniverse(c);
u.getViewingPlatform().setNominalViewingTransform();
u.addBranchGraph(scene);
}
public static void main(String[] args) {
new MainFrame(new Vrml2(args), 400,400);
}
}
//end of Vrml2.java
-----------------------------
//vrmlLoad.java
import javax.media.j3d.*;
import java.io.*;
import com.sun.j3d.loaders.vrml97.VrmlLoader;
import com.sun.j3d.loaders.Scene;
public class vrmlLoad extends BranchGroup{
publicvrmlLoad(String filename){
BranchGroup obj = new BranchGroup( );
VrmlLoader loader = new VrmlLoader();
Scene s = null;
try {
s = loader.load(filename);
} catch (Exception e) {
System.err.println(e);
System.exit(1);
}
obj.addChild(s.getSceneGroup( ) );
this.addChild(obj);
}
}
//end of vrmlLoad.java
3.调用两个VRML文件并使其放在不同的位置处旋转,编写这个程序非常简单,只需将
前面介绍的Obj4.java稍作修改即可,程序如下:
//Vrml3.java
import java.applet.Applet;
import java.awt.BorderLayout;
import com.sun.j3d.utils.applet.MainFrame;
import com.sun.j3d.utils.universe.*;
import javax.media.j3d.*;
import javax.vecmath.*;
public class Vrml3 extends Applet {
public BranchGroup createSceneGraph(){
BranchGroup objRoot = new BranchGroup();
TransformGroup objScale = new TransformGroup();
Transform3D t3d = new Transform3D();
t3d.setScale(0.1);
objScale.setTransform(t3d);
objRoot.addChild(objScale);
BoundingSphere bounds =
new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
Color3f bgColor = new Color3f(1.05f, 0.00f, 0.0f);
Background bg = new Background(bgColor);
bg.setApplicationBounds(bounds);
objRoot.addChild(bg);
Color3f light1Color = new Color3f(1.0f, 1.0f, 0.9f);
Vector3f light1Direction= new Vector3f(4.0f, -7.0f, -12.0f);
DirectionalLight light1
= new DirectionalLight(light1Color, light1Direction);
light1.setInfluencingBounds(bounds);
objRoot.addChild(light1);
BranchGroup b1 = newvrmlLoad("7.wrl");
BranchGroup b2 = newvrmlLoad("8.wrl");
objScale.addChild(createObject (b1, -1.2f , 0.0f ));
objScale.addChild(createObject (b2, 1.2f , 0.0f ));
objRoot.compile();
return objRoot;
}
private GroupcreateObject (BranchGroup b, float xpos, float ypos ) {
Transform3Dt = newTransform3D ( );
t.setTranslation ( new Vector3f ( xpos, ypos, 0.0f ) );
TransformGroup objTrans = new TransformGroup(t);
TransformGroup spin = new TransformGroup();
spin.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
spin.addChild(b);
Transform3DyAxis = newTransform3D ( );
Alpha rotationAlpha = new Alpha(-1, Alpha.INCREASING_ENABLE,
0, 0,
4000, 0, 0,
0, 0, 0);
RotationInterpolator rotator =
new RotationInterpolator(rotationAlpha, spin, yAxis,
0.0f, (float) Math.PI*2.0f);
BoundingSphere bounds =
new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
rotator.setSchedulingBounds(bounds);
objTrans.addChild(rotator);
objTrans.addChild ( spin );
return objTrans ;
}
public Vrml3(String args[]) {
setLayout(new BorderLayout());
Canvas3D c = new Canvas3D(null);
add("Center", c);
BranchGroup scene = createSceneGraph();
SimpleUniverse u = new SimpleUniverse(c);
u.getViewingPlatform().setNominalViewingTransform();
u.addBranchGraph(scene);
}
public static void main(String[] args) {
new MainFrame(new Vrml3(args), 400,400);
}
}
//end of Vrml3.java
四. AUTOCAD R14的DWG图形及3DS MAX图形在JAVA3D中的应用。
在三维图形生成过程中,国内目前大量使用AUTOCAD及3DS MAX等软件。如何将这些软
件生成的三维图形应用到JAVA3D上去呢?
对于3DS MAX软件,处理起来非常方便,因为3DS MAX可以将其图形直接输出成VRML97
格式,因而可以按本讲介绍的方法处理。
对于AUTOCAD R14来说,目前还不太方便,不知AUTOCAD 2000是否能直接输出VRML97图
形格式。本人从欧洲捷克一个站点拷得一个文件,可用来直接将AUTOCAD R14所绘制的三维
图形转换成VRML97(VRML2.0)格式,因而AUTOCAD软件生成的图形也可以非常方便地应用
到JAVA3D上面,为我们编写JAVA3D的复杂应用程序打下了良好的基础。此软件非常好用(
采用ARX技术编写)。
JAVA3D学习系列(十一)--形体的组合及几何坐标变换
BBS水木清华张杰
JAVA3D学习系列(13)---形体的组合及几何坐标变换
汕头大学机电系张杰(jzhang@mailserv.stu.edu.cn)
****************书名VRML2.0交互式三维图形编程******
JAVA3D学习系列中的例题将有非常多的VRML程序与之相比较,介绍JAVA3D的顺序也和
VRML2.0新书基本一致,欢迎购买VRML2.0新书。
非凡购书方式:
1。作者售书
1。网上订购(email address: jzhang@mailserv.stu.edu.cn)
2。可以先获书,后汇款(不满足可退书),
只需将通信地址及邮编告知作者,即可在最短的时间内得到书。
3。书价为25元/本,免收邮购费用。
4。书为16开本,正文161页。
5. 购书可获盖有出版社财务章的收据。
6. 假如需要书中所有的源程序,我可以email一个打包程序
*************书名VRML2.0交互式三维图形编程******
VRML2.0(VRML97)中,有两个用来组合各形体的组节点:
Transform、Group,其中的Group节点完全可以用Transform节点来代替。如何在JAVA
3D中实现Transform所提供的几何变换功能,是我们把握JAVA3D应用编程的基础。下面我们
对此给以具体的介绍。
我们首先来看一下VRML97的Transform节点的定义:
Transform节点的定义是:
Transform {
eventIn MFNodeaddChildren
eventIn MFNoderemoveChildren
exposedFieldSFVec3f center 0 0 0
exposedFieldMFNodechildren []
exposedFieldSFRotationrotation 0 0 10
exposedFieldSFVec3f scale1 1 1
exposedFieldSFRotation scaleOrientation0 0 10
exposedFieldSFVec3f translation0 0 0
field SFVec3f bboxCenter 0 0 0
field SFVec3f bboxSize -1 -1 -1
}
由定义我们可以看出,VRML程序中,我们可以通过设定translation、rotation、sca
le来使形体产生平移、旋转、比例变换。如VRML2.0交互式三维图形编程一书所给出的一个
生成一个小丑的程序Ex4_03.wrl,里面就对形体进行了平移、旋转、比例变换。我们先给
出Ex4_03.wrl程序(我们对书中的程序进行了修改,使生成的小丑能够旋转),再给出用
JAVA3D编写出来的Ex4_03.java。
//Ex4_03.wrl
#VRML V2.0 utf8
DEF T Transform{
children[
Transform {
scale 1 1.2 1
children Shape {
appearance Appearance{material Material
{diffuseColor 1 1 0 }}
geometry Sphere{}}}
Transform{
translation .5 .4 .6
scale 1 1 2
children Shape{
appearance Appearance{material Material
{diffuseColor 0 0 1}}
geometry Sphere{radius .2}}}
Transform {
translation -.5 .4 .6
scale 1 1 2
children Shape{
appearance Appearance{material Material
{diffuseColor 0 0 1}}
geometry Sphere {radius .2}}}
Transform{
translation 0 1 0
scale 1.1 .4 1.1
children Shape{
appearance Appearance{material Material
{diffuseColor 1 0 0}}
geometry Cone{}}}
Transform{
translation 1 0 0
scale .2 .4 .2
children Shape{
appearance Appearance{material Material
{diffuseColor 0 1 1}}
geometry Sphere{}}}
Transform{
translation -1 0 0
scale .2 .4 .2
children Shape{
appearance Appearance{material Material
{diffuseColor 0 1 1}}
geometry Sphere{}}}
Transform{
translation 0 0 1
scale .2 .4 .2
rotation 1 0 0 -.5
children Shape{
appearance Appearance{material Material
{diffuseColor 1 0 0}}
geometry Sphere{}}}
Transform{
translation 0 -.5 .9
scale .4 .1 .3
children Shape{
appearance Appearance{material Material
{diffuseColor 1 1 1}}
geometry Sphere{}}}
]}
DEF TS TimeSensor{
cycleInterval 8
loop TRUE}
DEF OI OrientationInterpolator{
key[0 .25 .5 .75 1]
keyValue [0 1 0 0, 0 1 01.57,0 1 0 3.14
0 1 0 4.71 0 1 06.28]}
ROUTE TS.fraction TO OI.fraction
ROUTE OI.value TO T.rotation
Background {skyColor 1 1 1}
//end of Ex4_03.wrl
------------------------------
//Ex4_03.java
import java.applet.Applet;
import java.awt.BorderLayout;
import com.sun.j3d.utils.applet.MainFrame;
import com.sun.j3d.utils.geometry.Cone;
import com.sun.j3d.utils.geometry.Sphere;
import com.sun.j3d.utils.geometry.Primitive;
import com.sun.j3d.utils.universe.*;
import javax.media.j3d.*;
import javax.vecmath.*;
public class Ex4_03 extends Applet{
public BranchGroup createSceneGraph() {
BranchGroup objRoot = new BranchGroup();
Transform3D t3d = new Transform3D();
t3d.setScale(0.3);
TransformGroup objScale = new TransformGroup();
objScale.setTransform(t3d);
Transform3D temp = new Transform3D();
TransformGroup obj = new TransformGroup();
obj.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
obj.setTransform(temp);
objScale.addChild(obj);
Alpha rotationAlpha = new Alpha(-1, Alpha.INCREASING_ENABLE,
0, 0,
4000, 0, 0,
0, 0, 0);
RotationInterpolator rotator =
new RotationInterpolator(rotationAlpha, obj, temp,
0.0f, (float) Math.PI*2.0f);
BoundingSphere bounds =
new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0);
rotator.setSchedulingBounds(bounds);
obj.addChild(rotator);
objRoot.addChild(objScale);
Color3f light1Color = new Color3f(1.0f, 1.0f, 0.9f);
Vector3f light1Direction= new Vector3f(4.0f, -7.0f, -12.0f);
DirectionalLight light1
= new DirectionalLight(light1Color, light1Direction);
light1.setInfluencingBounds(bounds);
objRoot.addChild(light1);
Appearance app_red = new Appearance();
Material material1 = new Material();
material1.setDiffuseColor(new Color3f(1.0f,0.0f,0.0f));
app_red.setMaterial(material1);
Appearance app_yellow = new Appearance();
Material material2 = new Material();
material2.setDiffuseColor(new Color3f(1.0f,1.0f,0.0f));
app_yellow.setMaterial(material2);
Appearance app_blue = new Appearance();
Material material3 = new Material();
material3.setDiffuseColor(new Color3f(0.0f,0.0f,1.0f));
app_blue.setMaterial(material3);
Appearance app_cyan = new Appearance();
Material material4 = new Material();
material4.setDiffuseColor(new Color3f(0.0f,1.0f,1.0f));
app_cyan.setMaterial(material4);
Appearance app_white = new Appearance();
Material material5 = new Material();
material5.setDiffuseColor(new Color3f(1.0f,1.0f,1.0f));
app_white.setMaterial(material5);
Cone c = new Cone(1.0f,2.0f,1,app_red);
Primitive s_1 = (Primitive) new Sphere(1.0f,app_yellow);
Primitive s_2 = (Primitive) new Sphere(.2f ,app_blue);
Primitive s_2b = (Primitive) new Sphere(.2f ,app_blue);
Primitive s_3 = (Primitive) new Sphere(1.0f,app_cyan);
Primitive s_3b = (Primitive) new Sphere(1.0f,app_cyan);
Primitive s_4 = (Primitive) new Sphere(1.0f,app_red);
Primitive s_5 = (Primitive) new Sphere(1.0f,app_white);
Transform3D t1 = new Transform3D();
t1.setScale(new Vector3d(1,1.2,1));
TransformGroup objTrans1 = new TransformGroup(t1);
objTrans1.addChild(s_1);
Transform3D t2 = new Transform3D();
t2.setScale(new Vector3d(1,1,2));
t2.setTranslation(new Vector3f(0.5f, 0.4f, 0.6f));
TransformGroup objTrans2 = new TransformGroup(t2);
objTrans2.addChild(s_2);
Transform3D t3 = new Transform3D();
t3.setScale(new Vector3d(1,1,2));
t3.setTranslation(new Vector3f(-0.5f, 0.4f, 0.6f));
TransformGroup objTrans3 = new TransformGroup(t3);
objTrans3.addChild(s_2b);
Transform3D t4 = new Transform3D();
t4.setScale(new Vector3d(1.1,0.4,1.1));
t4.setTranslation(new Vector3f(0.0f, 1.0f, 0.0f));
TransformGroup objTrans4 = new TransformGroup(t4);
objTrans4.addChild(c);
Transform3D t5 = new Transform3D();
t5.setScale(new Vector3d(0.2, 0.4, 0.2));
t5.setTranslation(new Vector3f(1.0f, 0.0f, 0.0f));
TransformGroup objTrans5 = new TransformGroup(t5);
objTrans5.addChild(s_3);
Transform3D t6 = new Transform3D();
t6.setScale(new Vector3d(0.2, 0.4, 0.2));
t6.setTranslation(new Vector3f(-1.0f, 0.0f, 0.0f));
TransformGroup objTrans6 = new TransformGroup(t6);
objTrans6.addChild(s_3b);
Transform3D t7 = new Transform3D();
t7.setScale(new Vector3d(0.2, 0.4, 0.2));
t7.setTranslation(new Vector3f(0.0f, 0.0f, 1.0f));
TransformGroup objTrans7 = new TransformGroup(t7);
objTrans7.addChild(s_4);
Transform3D t8 = new Transform3D();
t8.setScale(new Vector3d(0.4, 0.1, 0.3));
t8.setTranslation(new Vector3f(0.0f, -0.5f, 0.9f));
TransformGroup objTrans8 = new TransformGroup(t8);
objTrans8.addChild(s_5);
Color3f bgColor = new Color3f(1.0f, 1.0f, 1.0f);
Background bg = new Background(bgColor);
bg.setApplicationBounds(bounds);
objRoot.addChild(bg);
obj.addChild(objTrans1);
obj.addChild(objTrans2);
obj.addChild(objTrans3);
obj.addChild(objTrans4);
obj.addChild(objTrans5);
obj.addChild(objTrans6);
obj.addChild(objTrans7);
obj.addChild(objTrans8);
objRoot.compile();
return objRoot;
}
public Ex4_03() {
setLayout(new BorderLayout());
Canvas3D c = new Canvas3D(null);
add("Center", c);
BranchGroup scene = createSceneGraph();
SimpleUniverse u = new SimpleUniverse(c);
u.getViewingPlatform().setNominalViewingTransform();
u.addBranchGraph(scene);
}
public static void main(String[] args) {
new MainFrame(new Ex4_03(), 640, 480);
}
}
//end of Ex4_03.java
我们来仔细研究JAVA3D所提供的形体几何变换功能。前面我们主要介绍形体生成的方
法,其中,编写自己的形体用到的是Shape3D对象,VRML97与之对应的是Shape节点。同样
,JAVA3D对应于VRML97的Transform节点的对象是Transform3D。
VRML97编程中,形体的平移可以通过Transform节点的translation字段来设置;JAVA
3D编程时,形体的平移可以通过Transform3D的setTranslation方法完成。
VRML97编程中,形体的旋转可以通过Transform节点的rotation字段来设置;JAVA3D编
程时,形体的旋转可以通过Transform3D的setRotation方法完成。
VRML97编程中,形体的比例变化可以通过Transform节点的scale字段来设置;JAVA3D
编程时,形体的比例变化可以通过Transform3D的setScale方法完成,其中,当扩弧里只有
一个双精度数时,setScale对所有的方向均采用同一个比例,而当里面有三个双精度数时
,setScale对不同的方向可以采用不同的比例,双精度数后面不加符号,而单精度浮点数
后面要加一个f。
我们来看一下程序的主要内容:
程序一开始就定义了一个BranchGroup,后面所有的生成的内容如形体、形体的变换、
背景、灯光都放入其中。
为了使我们生成的图形有合适的大小,我们定义了一个TransformGroup对象objScale
,通过一个t3d使其按比例缩小,这相当于我们将视野往后移动。
为了使我们生成的小丑能够旋转,我们定义一个TransformGroup类型的obj,这相当于
定义了一个小丑所在的局部坐标系,设定此坐标系可以旋转,选转方式由一个Transform3
D类型的temp来确定,定义obj为objScale的一个子节点。
通过定义rotationAlpha、rotator地定义使得obj能够产生旋转。它们的作用类似于V
RML的时间传感器及方向内插器。
接下来我们在空间中定义了一个定向光、各种材质、形体,并将灯光、具有一定材质
的形体放入objRoot、obj之中,最后我们还定义了一个背景光。
通过这个程序的编写,我们把握了JAVA3D生成复杂形体的最基本概念,即如何进行形
体的几何坐标变换。把握了形体几何坐标变换方法,我们就具有了编写JAVA3D复杂应用程
序的能力。(完)
本文地址:http://www.cg3000.com/html/cgTutorials/VirtualReality/Java3D/20071205/JAVA3Dxuexixilie8__11_69310.shtml


当前位置 :