Java 版 (精华区)
发信人: bali (阿奔), 信区: Java
标 题: JAVA3D学习系列(17)--动画的生成(下)
发信站: 紫 丁 香 (Fri Mar 24 11:07:14 2000), 转信
cc发信人: vrml (3d), 信区: Java
标 题: JAV3D学习系列(17)--动画的生成(下)
发信站: BBS 水木清华站 (Mon Apr 26 11:48:56 1999)
JAVA3D学习系列(17)--动画的生成(下)
汕头大学机电系 张杰(jzhang@mailserv.stu.edu.cn)
一. TransparnecyInterpolator对象
TransparencyInterpolator对象的构造函数有两个:
public TransparencyInterpolator(Alpha alpha,
TransparencyAttributes target)
public TransparencyInterpolator(Alpha alpha,
TransparencyAttributes target,
float minimumTransparency,
float maximumTransparency)
它的方法有:
public void setMinimumTransparency(float transparency)
public float getMinimumTransparency()
public void setMaximumTransparency(float transparency)
public float getMaximumTransparency()
public void setTarget(TransparencyAttributes target)
public TransparencyAttributes getTarget()
public void processStimulus(Enumeration criteria)
利用这个对象,我们可以在给定的时间内,使某一个形体的透明度
按照Alpha提供的方式在两个数值之间变化,VRML语言中我们可以用
ScalarInterpolator节点来实现同样的效果。
如果我们使用的是第一个构造函数,则透明度的最大值为1.0f,
最小值为0.0f。
下面是一个应用此方法的JAVA3D程序和一个相对应的VRML程序。
为了看出透明的效果,我们设定背景为白色。
//Tra.java
import java.applet.Applet;
import java.awt.BorderLayout;
import com.sun.j3d.utils.applet.MainFrame;
import com.sun.j3d.utils.image.TextureLoader;
import com.sun.j3d.utils.universe.*;
import com.sun.j3d.utils.geometry.*;
import javax.media.j3d.*;
import javax.vecmath.*;
public class Tra extends Applet {
private BranchGroup createSceneGraph() {
BranchGroup objRoot = new BranchGroup();
objRoot.addChild(createObject());
BoundingSphere bounds=new BoundingSphere(new Point3d(0.0,0.0,0.0),10
0.0);
Background bg=new Background(new Color3f(1.0f,1.0f,1.0f));
bg.setApplicationBounds(bounds);
objRoot.addChild(bg);
objRoot.compile();
return objRoot;
}
private Group createObject() {
Transform3D t = new Transform3D();
TransformGroup objTrans = new TransformGroup(t);
objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
Appearance ap=new Appearance();
Color3f ambient=new Color3f(1.0f,0.0f,0.0f);
Color3f emissive = new Color3f(0.8f,0.2f,0.2f);
Color3f diffuse=new Color3f(1.f,1.f,0.f);
Color3f specular = new Color3f(1.0f,1.0f,1.0f);
ap.setMaterial(new Material(ambient,emissive,diffuse,specular,100.0f)
);
PolygonAttributes pa = new PolygonAttributes();
pa.setCullFace(PolygonAttributes.CULL_NONE);
ap.setPolygonAttributes(pa);
TransparencyAttributes ta=new TransparencyAttributes();
ta.setCapability(TransparencyAttributes.ALLOW_VALUE_WRITE);
ta.setTransparencyMode(ta.BLENDED);
ta.setTransparency(.0f);
ap.setTransparencyAttributes(ta);
Alpha alpha = new Alpha(-1,
Alpha.INCREASING_ENABLE|Alpha.DECREASING_ENABLE,
0, 0, 8000, 0, 0, 8000, 0, 0);
TransparencyInterpolator transparency=
new TransparencyInterpolator(alpha,ta,.0f,1.f);
BoundingSphere bounds=new BoundingSphere(new Point3d(0.0,0.0,0.0),10
0.0);
transparency.setSchedulingBounds(bounds);
Shape3D shape = new myShape();
shape.setAppearance(ap);
objTrans.addChild(shape);
objTrans.addChild(transparency);
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);
return objTrans;
}
public Tra() {
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 Tra(), 540,361);
}
}
//end of Tra.java
---------
#VRML V2.0 utf8
DEF T Transform{
children Shape{
appearance Appearance{material DEF M Material{diffuseColor 0 1 0}}
geometry IndexedFaceSet{
coord Coordinate{point [-0.3 -0.3 0,-0.3 0.3 0,
-0.1 -0.3 0,-0.1 0.3 0,
0.1 -0.3 0, 0.1 0.3 0,
0.3 -0.3 0, 0.3 0.3 0,
0.4 0.4 0]}
coordIndex[0 3 1 -1, 2 5 4 -1, 6 8 7]
solid FALSE
}
}
}
DEF TS TimeSensor{
loop TRUE
cycleInterval 8}
DEF SI ScalarInterpolator{
key[0 .5 1]
keyValue[ 1, 0, 1]
}
DEF OI OrientationInterpolator{
key[0 .5 1]
keyValue[ 0 1 0 0 , 0 1 0 3.14, 0 1 0 6.28]
}
Viewpoint {
position 0 .3 1
orientation 1 0 0 -.3}
Background{skyColor 1 1 1}
ROUTE TS.fraction TO SI.fraction
ROUTE TS.fraction TO OI.fraction
ROUTE SI.value TO M.transparency
ROUTE OI.value TO T.rotation
#end of tra.wrl
二. PathInterpolator对象
我们在后面将要介绍下面这些对象:
PositionPathInterpolator
RotPosPathInterpolator
RotPosScalePathInterpolator
RotationPathInterpolator
它们都是PathInterpolator的子类。为此,我们先介绍一下
PathInterpolator对象的作用。
PathInterpolator是Interpolator类的子类,就好象我们
上面介绍的所有的内插对象是Interpolator类的子类一样。
PathInterpolator的子类能够借助于父类的下面的这个方法:
computePathInterpolation()
来完成所需要的计算。
PathInterpolator还有以下几个方法:
getArrayLengths()
public void setKnot(int index, float knot)
public float getKnot(int index)
三. PositionPathInterpolator对象
PositionPathInterpolator对象的构造函数为:
public PositionPathInterpolator(Alpha alpha,
TransformGroup target,
Transform3D axisOfTranslation,
float knots[],
Point3f positions[])
它的方法有:
public void setPosition(int index, Point3f position)
public void getPosition(int index, Point3f position)
public void setAxisOfTranslation(Transform3D axis)
public Transform3D getAxisOfTranslation()
public void setTarget(TransformGroup target)
public TransformGroup getTarget()
public void processStimulus(Enumeration criteria)
利用这个对象,我们可以对某一个局部坐标系按照指定的路径、
指定的运动方式进行坐标系的移动。
positions[]给出了指定的路径。
knots[]、alpha给出了指定的运动方式。
下面我们利用这个对象编写一个使某个立方体按指定路径,按
指定运动方式的位移运动。
由程序我们得知,立方体围绕着由pos[]定义的一个长方形平移。
轨迹的第一个点和最后一个点重合。在从第一个点到最后一个点运动
过程中,每一个点都对应一个knot值,第一个knot值为0.0f,最后一
个knot值为1.0f,knot值必须从小到大排列,它用来给各个点分配由
Alpha对象定义的上升时间段和下降时间段。每一个点的时间可以由
对应的knot的数值算出。
运行JAVA3D程序,我们会看到立方体绕着一个长方形的四个
顶点旋转。如果我们将程序中的xtranAlpha改写成下面的内容:
Alpha xtranAlpha = new Alpha(-1,
Alpha.INCREASING_ENABLE|Alpha.DECREASING_ENABLE,
0, 0,10000, 0, 2000, 10000, 0, 2000);
则每一个循环的运行结果为:立方体先顺时针转一圈(10秒),
暂停2秒,再逆时针旋转一圈(10秒),再暂停2秒。
我们可以用VRML语言编写同样的处理程序,这时我们应用的节点
是PositionInterpolator。由此可以得知,JAVA3D程序中的knot对应
于VRML程序中PositionInterpolator节点的key字段,而pos对应于
VRML程序中PositionInterpolator节点的keyValue字段。因而我们同时
编写了一个VRML程序。
//Pos.java
import com.sun.j3d.utils.geometry.ColorCube;
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 Pos extends Applet {
float knot[] = {0.0f,0.25f,0.5f,0.75f,1.0f};
Point3f pos[] = {
new Point3f(-.8f,-.6f,0.0f),
new Point3f(-.8f,.6f, 0.0f),
new Point3f(.8f, .6f, 0.0f),
new Point3f(.8f, -.6f,0.0f),
new Point3f(-.8f,-.6f,0.0f), };
private BranchGroup createSceneGraph() {
BranchGroup objRoot = new BranchGroup();
TransformGroup objTran=new TransformGroup();
objTran.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
Transform3D t3d=new Transform3D();
t3d.setScale(.3);
objTran.setTransform(t3d);
objRoot.addChild(objTran);
BoundingSphere bound=new BoundingSphere(
new Point3d(0.0,0.0,0.0),50.);
Transform3D tr=new Transform3D();
TransformGroup translation=new TransformGroup(tr);
translation.addChild(new ColorCube(.2));
objTran.addChild(translation);
translation.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
Alpha xtranAlpha = new Alpha(-1,
Alpha.INCREASING_ENABLE,
0, 0,10000, 0, 0, 0, 0, 0);
PositionPathInterpolator tran =
new PositionPathInterpolator(xtranAlpha, translation, tr,
knot,pos);
tran.setSchedulingBounds(bound);
translation.addChild(tran);
return objRoot;
}
public Pos() {
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 Pos(), 640,480);
}
}
//end of Pos.java
------------------------------
#VRML V2.0 utf8
DEF T Transform{
children Shape{
appearance Appearance{
material Material{diffuseColor 1 0 0}}
geometry Box{}}}
DEF TS TimeSensor{
loop TRUE
cycleInterval 10}
DEF PI PositionInterpolator{
key[0 .25 .5 .75 1]
keyValue[-.8 -.6 0 , -.8 .6 0,
.8 .6 0, .8 -.6 0, -.8 -.6 0]}
ROUTE TS.fraction TO PI.fraction
ROUTE PI.value TO T.translation
Background{skyColor 1 1 1}
Viewpoint{
position 0 2 8
orientation 1 0 0 -.3}
#end of Pos.wrl
四. RotPosPathInterpolator对象
RotPosPathInterpolator对象的构造函数为:
public RotPosPathInterpolator(Alpha alpha,
TransformGroup target,
Transform3D axisOfRotPos,
float knots[],
Quat4f quats[],
Point3f positions[])
它的方法有:
public void setQuat(int index, Quat4f quat)
public void getQuat(int index, Quat4f quat)
public void setPosition(int index, Point3f position)
public void getPosition(int index, Point3f position)
public void setAxisOfRotPos(Transform3D axisOfRotPos)
public Transform3D getAxisOfRotPos()
public void setTarget(TransformGroup target)
public TransformGroup getTarget()
public void processStimulus(Enumeration criteria)
我们上面介绍的PositionPathInterpolator对象可以
使形体按指定的路径平移,而利用RotPosPathInterpolator
对象则可以在实现平移运动
RotPosScalePathInterpolator tran =
new RotPosScalePathInterpolator(xtranAlpha, translation, tr,
knot,quat , pos , scale);
tran.setSchedulingBounds(bound);
translation.addChild(tran);
return objRoot;
}
public Sca() {
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 Sca(), 640,480);
}
}
//end of Sca.java
相应的VRML程序如下:
#VRML V2.0 utf8
DEF T Transform{
children Shape{
appearance Appearance{
material Material{diffuseColor 1 0 0}}
geometry Box{size .5 .5 .5}}
}
DEF TS TimeSensor{
loop TRUE
cycleInterval 10}
DEF PI PositionInterpolator{
key[0 .125 .25 .375 .5 .625 .75 .875 1]
keyValue[-.8 -.6 0 , -.8 .6 0,
.8 .6 0, .8 -.6 0, -.8 -.6 0
.8 -.6 0, .8 .6 0, -.8 .6 0
-.8 -.6 0]}
DEF OI OrientationInterpolator{
key[0 .125 .25 .375 .5 .625 .75 .875 1]
keyValue[0 1 0 0,0 1 0 .78,0 1 0 1.57, 0 1 0 0.78,
0 1 0 0, 0 1 0 0.78, 0 1 0 1.57, 0 1 0 0.78
0 1 0 0]}
DEF PI2 PositionInterpolator{
key[0 .125 .25 .375 .5 .625 .75 .875 1]
keyValue[1 1 1,1.5 1.5 1.5,2 2 2,1.5 1.5 1.5,1 1 1,
1.5 1.5 1.5,2 2 2,1.5 1.5 1.5,1 1 1]}
Background{skyColor 1 1 1}
Viewpoint{
position 0 2 8
orientation 1 0 0 -.3}
ROUTE TS.fraction TO PI.fraction
ROUTE PI.value TO T.translation
ROUTE TS.fraction TO PI2.fraction
ROUTE PI2.value TO T.scale
ROUTE TS.fraction TO OI.fraction
ROUTE OI.value TO T.rotation
#end of Sca.wrl
六. RotationPathInterpolator对象
RotationPathInterpolator对象的构造函数如下:
public RotationPathInterpolator(Alpha alpha,
TransformGroup target,
Transform3D axisOfRotation,
float knots[],
Quat4f quats[])
它的方法有:
public void setQuat(int index, Quat4f quat)
public void getQuat(int index, Quat4f quat)
public void setAxisOfRotation(Transform3D axisOfRotation)
public Transform3D getAxisOfRotation()
public void setTarget(TransformGroup target)
public TransformGroup getTarget()
public void processStimulus(Enumeration criteria)
前面我们已经介绍了一个RotationInterpolator对象,利用
它可以使形体按Alpha指定的方式绕着特定的轴旋转,旋转的速度
可以由Alpha的一些参数控制,但具体时间的角度无法控制。这时
我们就可以利用RotationPathInterpolator对象,利用quats数组,
控制具体时间的形体旋转角度。
下面的程序是由上面介绍的Sca.java程序经过一定的处理得来
的,没有增加什么,只是将用于位移及比例变化的部分去掉了。
//Rot2.java
import com.sun.j3d.utils.geometry.ColorCube;
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 Rot2 extends Applet {
float knot[] = {0.0f,0.25f,0.5f,0.75f,1.0f};
Quat4f quat[ ] = {
new Quat4f( 0.0f ,1.0f ,0.0f ,0.0f),
new Quat4f(0.0f ,1.0f ,0.0f ,0.78f ),
new Quat4f(0.0f ,1.0f, 0.0f , 1.57f ),
new Quat4f(0.0f, 1.0f ,0.0f, 0.78f ),
new Quat4f( 0.0f ,1.0f, 0.0f, 0.0f )};
private BranchGroup createSceneGraph() {
BranchGroup objRoot = new BranchGroup();
TransformGroup objTran=new TransformGroup();
objTran.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
Transform3D t3d=new Transform3D();
t3d.setScale(.3);
objTran.setTransform(t3d);
objRoot.addChild(objTran);
BoundingSphere bound=new BoundingSphere(
new Point3d(0.0,0.0,0.0),50.);
Transform3D tr=new Transform3D();
TransformGroup translation=new TransformGroup(tr);
translation.addChild(new ColorCube(.2));
objTran.addChild(translation);
translation.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
Alpha xtranAlpha = new Alpha(-1,
Alpha.INCREASING_ENABLE|Alpha.DECREASING_ENABL
E,
0, 0,10000, 0, 2000, 10000, 0, 2000);
RotationPathInterpolator tran =
new RotationPathInterpolator(xtranAlpha, translation, tr,
knot,quat);
tran.setSchedulingBounds(bound);
translation.addChild(tran);
return objRoot;
}
public Rot2() {
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 Rot2(), 640,480);
}
}
//end of Rot2.java
--------------------
相应的VRML程序如下:
#VRML V2.0 utf8
DEF T Transform{
children Shape{
appearance Appearance{
material Material{diffuseColor 1 0 0}}
geometry Box{ }}
}
DEF TS TimeSensor{
loop TRUE
cycleInterval 10}
DEF OI OrientationInterpolator{
key[0 .125 .25 .375 .5 .625 .75 .875 1]
keyValue[0 1 0 0,0 1 0 .78,0 1 0 1.57, 0 1 0 0.78,
0 1 0 0, 0 1 0 0.78, 0 1 0 1.57, 0 1 0 0.78
0 1 0 0]}
Background{skyColor 1 1 1}
Viewpoint{
position 0 2 8
orientation 1 0 0 -.3}
ROUTE TS.fraction TO OI.fraction
ROUTE OI.value TO T.rotation
# end of Rot2.wrl
--
※ 来源:.紫 丁 香 bbs.hit.edu.cn.[FROM: 202.118.243.89]
Powered by KBS BBS 2.0 (http://dev.kcn.cn)
页面执行时间:204.442毫秒