Graphics 版 (精华区)

发信人: seaman (翩翩少年), 信区: Graphics
标  题: JAVA3D学习系列(17)--动画的生成(下)
发信站: 哈工大紫丁香 (Tue Sep 28 19:18:21 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),100.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),100.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
对象则可以在实现平移运动的同时使形体按指定的方式绕特
定的轴旋转。例如下面的程序就是在Pos.java程序的基础之
上加了一个Quat4f数组,用来定义形体的旋转方式。使形体
在每一个knots数值之下都有一个旋转角度相对应。程序的其
它地方没有变化。
    立方体在顺时针或反时针移动时,都要绕着自身先正转
90度,再反转90度。
    RotPosPathInterpolator对象可以由下面两个对象代替:
      PositionPathInterpolator
      RotationInterpolator

//Rot.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 Rot 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),    };
       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_ENABLE,
                              0, 0,10000, 0, 2000, 10000, 0, 2000);
        RotPosPathInterpolator tran =
            new RotPosPathInterpolator(xtranAlpha, translation, tr,           
                                     knot,quat , pos);
        tran.setSchedulingBounds(bound);
        translation.addChild(tran);

        return objRoot;
    }

    public Rot() {
        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 Rot(), 640,480);
    }
}

//end of Rot.java
    我们将Rot.java变成VRML程序Rot.wrl

#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 PositionInterp.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_ENABLE,
                              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 水木清华站 bbs.net.tsinghua.edu.cn·[FROM: 202.192.158.102]

--
☆ 来源:.哈工大紫丁香 bbs.hit.edu.cn.[FROM: sunsoft.bbs@bbs.net.]
[百宝箱] [返回首页] [上级目录] [根目录] [返回顶部] [刷新] [返回]
Powered by KBS BBS 2.0 (http://dev.kcn.cn)
页面执行时间:204.851毫秒