home *** CD-ROM | disk | FTP | other *** search
/ IRIX 6.5 Applications 2004 May / SGI IRIX 6.5 Applications 2004 May.iso / dist / java3d.idb / usr / demos / java / j3d / programs / examples / SplineAnim / SplineAnim.java.z / SplineAnim.java
Encoding:
Java Source  |  2003-08-08  |  21.6 KB  |  597 lines

  1. /*
  2.  *    @(#)SplineAnim.java 1.13 02/10/21 13:55:30
  3.  *
  4.  * Copyright (c) 1996-2002 Sun Microsystems, Inc. All Rights Reserved.
  5.  *
  6.  * Redistribution and use in source and binary forms, with or without
  7.  * modification, are permitted provided that the following conditions
  8.  * are met:
  9.  *
  10.  * - Redistributions of source code must retain the above copyright
  11.  *   notice, this list of conditions and the following disclaimer.
  12.  *
  13.  * - Redistribution in binary form must reproduce the above copyright
  14.  *   notice, this list of conditions and the following disclaimer in
  15.  *   the documentation and/or other materials provided with the
  16.  *   distribution.
  17.  *
  18.  * Neither the name of Sun Microsystems, Inc. or the names of
  19.  * contributors may be used to endorse or promote products derived
  20.  * from this software without specific prior written permission.
  21.  *
  22.  * This software is provided "AS IS," without a warranty of any
  23.  * kind. ALL EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND
  24.  * WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF MERCHANTABILITY,
  25.  * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE HEREBY
  26.  * EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE LIABLE FOR ANY DAMAGES
  27.  * SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
  28.  * DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN
  29.  * OR ITS LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR
  30.  * FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR
  31.  * PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY OF
  32.  * LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE,
  33.  * EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
  34.  *
  35.  * You acknowledge that Software is not designed,licensed or intended
  36.  * for use in the design, construction, operation or maintenance of
  37.  * any nuclear facility.
  38.  */
  39.  
  40. import java.io.*;
  41. import java.applet.Applet;
  42. import java.awt.FlowLayout;
  43. import java.awt.*;
  44. import java.awt.event.*;
  45. import java.util.Hashtable;
  46. import javax.media.j3d.*;
  47. import javax.vecmath.*;
  48. import com.sun.j3d.utils.applet.MainFrame;
  49. import com.sun.j3d.utils.geometry.*;
  50. import com.sun.j3d.utils.universe.*;
  51. import com.sun.j3d.loaders.Scene;
  52. import com.sun.j3d.loaders.objectfile.ObjectFile;
  53. import com.sun.j3d.loaders.ParsingErrorException;
  54. import com.sun.j3d.loaders.IncorrectFormatException;
  55. import com.sun.j3d.utils.behaviors.vp.*;
  56. import com.sun.j3d.utils.behaviors.interpolators.*;
  57.  
  58.  
  59.  
  60. /*
  61.  * This program demonstrates the use of KBRotPosScaleSplinePathInterpolator 
  62.  * in order to to do spline animation paths using Kochanek-Bartels (also
  63.  * known as TCB or Tension-Continuity-Bias ) splines. A cone red cone 
  64.  * is animated along a spline path specified by 5 knot points, which 
  65.  * are showns as cyan spheres. 
  66.  *
  67.  * Use the left mouse button to changes orientation of scene. 
  68.  * Use the middle mouse button to zoom in/out
  69.  * Use the right mouse button to pan the scene 
  70.  */
  71. public class SplineAnim extends Applet implements ActionListener, 
  72.                                                   AdjustmentListener,
  73.                                                   ItemListener {
  74.  
  75.     // 3D Canvas
  76.     Canvas3D           canvas;
  77.  
  78.     // UI Components
  79.     Panel              controlPanel;
  80.     Panel              canvasPanel;
  81.     Button             animateButton;
  82.     Choice             interpChoice; 
  83.     Scrollbar          speedSlider;
  84.     Label              speedLabel;
  85.     Label              interpLabel;
  86.  
  87.     // Scene Graph
  88.     BoundingSphere     bounds;
  89.     BranchGroup        root;
  90.     BranchGroup        behaviorBranch;
  91.     Transform3D        sceneTransform;
  92.     TransformGroup     sceneTransformGroup;
  93.     Transform3D        objTransform;
  94.     TransformGroup     objTransformGroup;
  95.     Transform3D        lightTransform1;
  96.     Transform3D        lightTransform2;
  97.     TransformGroup     light1TransformGroup;
  98.     TransformGroup     light2TransformGroup;
  99.  
  100.     // Key Frames & Interpolator
  101.     int                                  duration = 5000;
  102.     Alpha                                animAlpha;
  103.     Transform3D                          yAxis;
  104.     KBKeyFrame[]                         linearKeyFrames = new KBKeyFrame[6];
  105.     KBKeyFrame[]                         splineKeyFrames = new KBKeyFrame[6];
  106.     KBRotPosScaleSplinePathInterpolator  splineInterpolator;
  107.     KBRotPosScaleSplinePathInterpolator  linearInterpolator;
  108.  
  109.     // Data: Knot positions & transform groups
  110.     Vector3f           pos0 = new Vector3f(-5.0f, -5.0f, 0.0f);
  111.     Vector3f           pos1 = new Vector3f(-5.0f,  5.0f, 0.0f);
  112.     Vector3f           pos2 = new Vector3f( 0.0f,  5.0f, 0.0f);
  113.     Vector3f           pos3 = new Vector3f( 0.0f, -5.0f, 0.0f);
  114.     Vector3f           pos4 = new Vector3f( 5.0f, -5.0f, 0.0f);
  115.     Vector3f           pos5 = new Vector3f( 5.0f,  5.0f, 0.0f);
  116.     TransformGroup     k0TransformGroup;
  117.     TransformGroup     k1TransformGroup;
  118.     TransformGroup     k2TransformGroup;
  119.     TransformGroup     k3TransformGroup;
  120.     TransformGroup     k4TransformGroup;
  121.     TransformGroup     k5TransformGroup;
  122.  
  123.     // Flags
  124.     boolean            animationOn = true; 
  125.     boolean            linear      = false;
  126.  
  127.     private SimpleUniverse u = null;
  128.                               
  129.     public SplineAnim() {
  130.     }
  131.  
  132.     public void init() {
  133.     this.setLayout(new FlowLayout());   
  134.  
  135.         // Create the canvas and the UI
  136.         canvasPanel = new Panel();
  137.         controlPanel = new Panel();
  138.         createCanvasPanel(canvasPanel); 
  139.         this.add(canvasPanel);
  140.         createControlPanel(controlPanel); 
  141.         this.add(controlPanel);
  142.  
  143.         // Create the scene. 
  144.         BranchGroup scene = createSceneGraph();
  145.  
  146.         // Setup keyframe data for our animation
  147.         setupSplineKeyFrames ();
  148.         setupLinearKeyFrames ();
  149.  
  150.         // Setup alpha, create the interpolators and start them. We
  151.         // create both a linear and a spline interpolator and turn on
  152.         // one depending on user selection. The default is spline.
  153.         setupAnimationData ();
  154.         createInterpolators();
  155.         startInterpolator();
  156.  
  157.         // Add viewing platform  
  158.         u = new SimpleUniverse(canvas);
  159.  
  160.     // add mouse behaviors to ViewingPlatform
  161.     ViewingPlatform viewingPlatform = u.getViewingPlatform();
  162.     
  163.         viewingPlatform.setNominalViewingTransform();
  164.  
  165.     // add orbit behavior to the ViewingPlatform
  166.     OrbitBehavior orbit = new OrbitBehavior(canvas,
  167.                         OrbitBehavior.REVERSE_ALL);
  168.     BoundingSphere bounds =
  169.         new BoundingSphere(new Point3d(0.0, 0.0, 0.0), 100.0);
  170.     orbit.setSchedulingBounds(bounds);
  171.     viewingPlatform.setViewPlatformBehavior(orbit);
  172.     
  173.         u.addBranchGraph(scene);
  174.     }
  175.  
  176.     public void destroy() {
  177.     u.cleanup();
  178.     }
  179.  
  180.     /*
  181.      * This creates the control panel which contains a choice menu to
  182.      * toggle between spline and linear interpolation, a slider to
  183.      * adjust the speed of the animation and a animation start/stop
  184.      * button.
  185.      */
  186.     private void createControlPanel(Panel p) {
  187.  
  188.         GridBagLayout      gl  = new GridBagLayout();
  189.         GridBagConstraints gbc = new GridBagConstraints();
  190.  
  191.         p.setLayout (gl);
  192.         gbc.weightx = 100;  gbc.weighty = 100;
  193.         gbc.fill = GridBagConstraints.BOTH;
  194.  
  195.         gbc.gridx = 0;  gbc.gridy = 0;
  196.         gbc.gridwidth = 1;  gbc.gridheight = 1;
  197.         interpLabel = new Label("Interpolation Type", Label.LEFT);
  198.         p.add(interpLabel, gbc);
  199.  
  200.         gbc.gridx = 1;  gbc.gridy = 0;
  201.         gbc.gridwidth = 1;  gbc.gridheight = 1;
  202.         interpChoice = new Choice();
  203.         interpChoice.add("Spline");
  204.         interpChoice.add("Linear");
  205.         p.add(interpChoice, gbc);
  206.         interpChoice.addItemListener (this);
  207.  
  208.         gbc.gridx = 0;  gbc.gridy = 2;
  209.         gbc.gridwidth = 2;  gbc.gridheight = 1;
  210.         speedSlider = new Scrollbar(Scrollbar.HORIZONTAL, 2, 1,  0, 11);
  211.         speedSlider.setUnitIncrement (1);
  212.         p.add(speedSlider, gbc);
  213.         speedSlider.addAdjustmentListener(this);
  214.  
  215.         gbc.gridx = 0;  gbc.gridy = 3;
  216.         gbc.gridwidth = 2;  gbc.gridheight = 1;
  217.         speedLabel = new Label(" - Animation Speed +", Label.CENTER);
  218.         p.add(speedLabel, gbc);
  219.  
  220.         gbc.gridx = 0;  gbc.gridy = 5;
  221.         gbc.gridwidth = 2;  gbc.gridheight = 1;
  222.         animateButton = new Button("Stop Animation");
  223.         p.add(animateButton, gbc);
  224.         animateButton.addActionListener (this);
  225.  
  226.  
  227.     }
  228.  
  229.     /*
  230.      * This creates the Java3D canvas
  231.      */
  232.     private void createCanvasPanel(Panel p) {
  233.  
  234.         GridBagLayout      gl  = new GridBagLayout();
  235.         GridBagConstraints gbc = new GridBagConstraints();
  236.  
  237.         p.setLayout(gl);
  238.         gbc.gridx = 0;  gbc.gridy = 0;
  239.         gbc.gridwidth = 5;  gbc.gridheight = 5;
  240.         GraphicsConfiguration config =
  241.            SimpleUniverse.getPreferredConfiguration();
  242.  
  243.         canvas = new Canvas3D(config);
  244.         canvas.setSize(490,490);
  245.         p.add(canvas,gbc);
  246.  
  247.     }
  248.  
  249.     /* 
  250.      * This creates the scene with 5 knot points represented by cyan 
  251.      * spheres, a cone obejct that will be transformed, and two directional
  252.      * lights + and ambient light.
  253.      */
  254.     public BranchGroup createSceneGraph() {
  255.  
  256.       // Colors for lights and objects
  257.       Color3f aColor     = new Color3f(0.2f, 0.2f, 0.2f);
  258.       Color3f eColor     = new Color3f(0.0f, 0.0f, 0.0f);
  259.       Color3f sColor     = new Color3f(1.0f, 1.0f, 1.0f);
  260.       Color3f coneColor  = new Color3f(0.9f, 0.1f, 0.1f);
  261.       Color3f sphereColor= new Color3f(0.1f, 0.7f, 0.9f);
  262.       Color3f bgColor    = new Color3f(0.0f, 0.0f, 0.0f);
  263.       Color3f lightColor = new Color3f(1.0f, 1.0f, 1.0f);
  264.  
  265.       // Root of the branch grsph
  266.       BranchGroup root = new BranchGroup();
  267.  
  268.       // Create transforms such that all objects appears in the scene
  269.       sceneTransform = new Transform3D();
  270.       sceneTransform.setScale(0.14f);
  271.       Transform3D yrot = new Transform3D(); 
  272.       yrot.rotY(-Math.PI/5.0d);
  273.       sceneTransform.mul(yrot);
  274.       sceneTransformGroup = new TransformGroup(sceneTransform);
  275.       sceneTransformGroup.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
  276.       sceneTransformGroup.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
  277.       root.addChild(sceneTransformGroup);
  278.  
  279.       // Create bounds for the background and lights
  280.       bounds =  new BoundingSphere(new Point3d(0.0,0.0,0.0), 100.0f);
  281.       
  282.       // Set up the background
  283.       Background bg = new Background(bgColor);
  284.       bg.setApplicationBounds(bounds);
  285.       sceneTransformGroup.addChild(bg);
  286.  
  287.       // Create the transform group node for the lights 
  288.       lightTransform1 = new Transform3D();
  289.       lightTransform2 = new Transform3D();
  290.       Vector3d lightPos1 =  new Vector3d(0.0, 0.0, 2.0);
  291.       Vector3d lightPos2 =  new Vector3d(1.0, 0.0, -2.0);
  292.       lightTransform1.set(lightPos1);
  293.       lightTransform2.set(lightPos2);
  294.       light1TransformGroup = new TransformGroup(lightTransform1);
  295.       light2TransformGroup = new TransformGroup(lightTransform2);
  296.       sceneTransformGroup.addChild(light1TransformGroup);
  297.       sceneTransformGroup.addChild(light2TransformGroup);
  298.  
  299.       // Create lights
  300.       AmbientLight ambLight = new AmbientLight(aColor);
  301.       Light        dirLight1;
  302.       Light        dirLight2;
  303.  
  304.       Vector3f lightDir1 = new Vector3f(lightPos1);
  305.       Vector3f lightDir2 = new Vector3f(lightPos2);
  306.       lightDir1.negate();
  307.       lightDir2.negate();
  308.       dirLight1 = new DirectionalLight(lightColor, lightDir1);
  309.       dirLight2 = new DirectionalLight(lightColor, lightDir2);
  310.  
  311.       // Set the influencing bounds
  312.       ambLight.setInfluencingBounds(bounds);
  313.       dirLight1.setInfluencingBounds(bounds);
  314.       dirLight2.setInfluencingBounds(bounds);
  315.  
  316.       // Add the lights into the scene graph
  317.       sceneTransformGroup.addChild(ambLight);
  318.       sceneTransformGroup.addChild(dirLight1);
  319.       sceneTransformGroup.addChild(dirLight2);
  320.  
  321.       // Create a cone and add it to the scene graph.
  322.       objTransform = new Transform3D();
  323.       objTransformGroup = new TransformGroup(objTransform);
  324.       objTransformGroup.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
  325.       sceneTransformGroup.addChild(objTransformGroup);
  326.  
  327.       Material m = new Material(coneColor, eColor, coneColor, sColor, 100.0f);
  328.       Appearance a = new Appearance();
  329.       m.setLightingEnable(true);
  330.       a.setMaterial(m);
  331.       Cone cone = new Cone(0.4f, 1.0f); 
  332.       cone.setAppearance(a);
  333.       objTransformGroup.addChild(cone);
  334.  
  335.       // Create transform groups for each knot point
  336.       // knot point 0 
  337.       Transform3D t3dKnot = new Transform3D();
  338.       t3dKnot.set (pos0);
  339.       TransformGroup k0TransformGroup = new TransformGroup(t3dKnot);
  340.       sceneTransformGroup.addChild(k0TransformGroup);
  341.  
  342.       // knot point 1 
  343.       t3dKnot = new Transform3D();
  344.       t3dKnot.set (pos1);
  345.       TransformGroup k1TransformGroup = new TransformGroup(t3dKnot);
  346.       sceneTransformGroup.addChild(k1TransformGroup);
  347.  
  348.       // knot point 2 
  349.       t3dKnot = new Transform3D();
  350.       t3dKnot.set (pos2);
  351.       TransformGroup k2TransformGroup = new TransformGroup(t3dKnot);
  352.       sceneTransformGroup.addChild(k2TransformGroup);
  353.  
  354.       // knot point 3 
  355.       t3dKnot = new Transform3D();
  356.       t3dKnot.set (pos3);
  357.       TransformGroup k3TransformGroup = new TransformGroup(t3dKnot);
  358.       sceneTransformGroup.addChild(k3TransformGroup);
  359.  
  360.       // knot point 4 
  361.       t3dKnot = new Transform3D();
  362.       t3dKnot.set (pos4);
  363.       TransformGroup k4TransformGroup = new TransformGroup(t3dKnot);
  364.       sceneTransformGroup.addChild(k4TransformGroup);
  365.  
  366.       // knot point 5 
  367.       t3dKnot = new Transform3D();
  368.       t3dKnot.set (pos5);
  369.       TransformGroup k5TransformGroup = new TransformGroup(t3dKnot);
  370.       sceneTransformGroup.addChild(k5TransformGroup);
  371.  
  372.       // Create spheres for each knot point's transform group
  373.       ColoringAttributes sphereColorAttr = new ColoringAttributes();
  374.       sphereColorAttr.setColor(sphereColor);
  375.       Appearance sphereAppearance = new Appearance();
  376.       sphereAppearance.setColoringAttributes(sphereColorAttr);
  377.       k0TransformGroup.addChild(new Sphere(0.10f, sphereAppearance));
  378.       k1TransformGroup.addChild(new Sphere(0.10f, sphereAppearance));
  379.       k2TransformGroup.addChild(new Sphere(0.10f, sphereAppearance));
  380.       k3TransformGroup.addChild(new Sphere(0.10f, sphereAppearance));
  381.       k4TransformGroup.addChild(new Sphere(0.10f, sphereAppearance));
  382.       k5TransformGroup.addChild(new Sphere(0.10f, sphereAppearance));
  383.  
  384.       return root;
  385.     }
  386.  
  387.     /*
  388.      * This sets up the key frame data for the spline interpolator. Each knot
  389.      * point has a scale and rotation component specified. The second argument
  390.      * to KBKeyFrame (in this case 0) tells the interpolator that this is
  391.      * to be interpolated using splines. The last three arguments to 
  392.      * KBKeyFrame are Tension, Continuity, and Bias components for each
  393.      * key frame.
  394.      */
  395.     private void setupSplineKeyFrames () {
  396.       // Prepare spline keyframe data
  397.       Point3f p   = new Point3f (pos0);            // position
  398.       float head  = (float)Math.PI/2.0f;           // heading
  399.       float pitch = 0.0f;                          // pitch 
  400.       float bank  = 0.0f;                          // bank 
  401.       Point3f s   = new Point3f(1.0f, 1.0f, 1.0f); // uniform scale
  402.       splineKeyFrames[0] = 
  403.          new KBKeyFrame(0.0f, 0, p, head, pitch, bank, s, 0.0f, 0.0f, 0.0f); 
  404.  
  405.       p = new Point3f (pos1);
  406.       head  = 0.0f;                               // heading
  407.       pitch = 0.0f;                               // pitch 
  408.       bank  = (float)-Math.PI/2.0f;               // bank 
  409.       s = new Point3f(1.0f, 1.0f, 1.0f);          // uniform scale
  410.       splineKeyFrames[1] = 
  411.          new KBKeyFrame(0.2f, 0, p, head, pitch, bank, s, 0.0f, 0.0f, 0.0f); 
  412.  
  413.       p = new Point3f (pos2);
  414.       head  = 0.0f;                               // heading
  415.       pitch = 0.0f;                               // pitch 
  416.       bank  = 0.0f;                               // bank 
  417.       s = new Point3f(0.7f, 0.7f, 0.7f);          // uniform scale
  418.       splineKeyFrames[2] = 
  419.          new KBKeyFrame(0.4f, 0, p, head, pitch, bank, s, 0.0f, 0.0f, 0.0f); 
  420.  
  421.       p = new Point3f (pos3);
  422.       head  = (float)Math.PI/2.0f;                // heading
  423.       pitch = 0.0f;                               // pitch 
  424.       bank  = (float)Math.PI/2.0f;                // bank 
  425.       s = new Point3f(0.5f, 0.5f, 0.5f);          // uniform scale
  426.       splineKeyFrames[3] = 
  427.          new KBKeyFrame(0.6f, 0, p, head, pitch, bank, s, 0.0f, 0.0f, 0.0f); 
  428.  
  429.       p = new Point3f (pos4);
  430.       head  = (float)-Math.PI/2.0f;               // heading
  431.       pitch = (float)-Math.PI/2.0f;               // pitch 
  432.       bank  = (float)Math.PI/2.0f;                // bank 
  433.       s = new Point3f(0.4f, 0.4f, 0.4f);          // uniform scale
  434.       splineKeyFrames[4] = 
  435.          new KBKeyFrame(0.8f, 0, p, head, pitch, bank, s, 0.0f, 0.0f, 0.0f); 
  436.  
  437.       p = new Point3f (pos5);
  438.       head  = 0.0f;                               // heading
  439.       pitch = 0.0f;                               // pitch 
  440.       bank  = 0.0f;                               // bank 
  441.       s = new Point3f(1.0f, 1.0f, 1.0f);          // uniform scale
  442.       splineKeyFrames[5] = 
  443.          new KBKeyFrame(1.0f, 0, p, head, pitch, bank, s, 0.0f, 0.0f, 0.0f); 
  444.     }
  445.  
  446.     /*
  447.      * This sets up the key frame data for the linear interpolator. Each knot
  448.      * point has a scale and rotation component specified. The second argument
  449.      * to KBKeyFrame (in this case 1) tells the interpolator that this is
  450.      * to be interpolated linearly. The last three arguments to TCBKeyFrame
  451.      * are Tension, Continuity, and Bias components for each key frame.
  452.      */
  453.     private void setupLinearKeyFrames () {
  454.       // Prepare linear keyframe data
  455.       Point3f p = new Point3f (pos0);
  456.       float head  = 0.0f;                          // heading
  457.       float pitch = 0.0f;                          // pitch 
  458.       float bank  = 0.0f;                          // bank 
  459.       Point3f s = new Point3f(1.0f, 1.0f, 1.0f);   // uniform scale
  460.       linearKeyFrames[0] = 
  461.          new KBKeyFrame(0.0f, 1, p, head, pitch, bank, s, 0.0f, 0.0f, 0.0f); 
  462.  
  463.       p = new Point3f (pos1);
  464.       linearKeyFrames[1] = 
  465.          new KBKeyFrame(0.2f, 1, p, head, pitch, bank, s, 0.0f, 0.0f, 0.0f); 
  466.  
  467.       p = new Point3f (pos2);
  468.       linearKeyFrames[2] = 
  469.          new KBKeyFrame(0.4f, 1, p, head, pitch, bank, s, 0.0f, 0.0f, 0.0f); 
  470.  
  471.       p = new Point3f (pos3);
  472.       linearKeyFrames[3] = 
  473.          new KBKeyFrame(0.6f, 1, p, head, pitch, bank, s, 0.0f, 0.0f, 0.0f); 
  474.  
  475.       p = new Point3f (pos4);
  476.       linearKeyFrames[4] = 
  477.          new KBKeyFrame(0.8f, 1, p, head, pitch, bank, s, 0.0f, 0.0f, 0.0f); 
  478.  
  479.       p = new Point3f (pos5);
  480.       linearKeyFrames[5] = 
  481.          new KBKeyFrame(1.0f, 1, p, head, pitch, bank, s, 0.0f, 0.0f, 0.0f); 
  482.     }
  483.  
  484.  
  485.     /* 
  486.      * This sets up alpha for the interpolator
  487.      */
  488.     private void setupAnimationData () {
  489.       yAxis = new Transform3D();
  490.       animAlpha = new Alpha (-1,Alpha.INCREASING_ENABLE,0,0,duration,0,0,0,0,0);
  491.     }
  492.  
  493.     /*
  494.      * create a spline and a linear interpolator, but we will activate only
  495.      * one in startInterpolator()
  496.      */
  497.     private void createInterpolators () {
  498.  
  499.       behaviorBranch = new BranchGroup();
  500.  
  501.       // create spline interpolator 
  502.       splineInterpolator =
  503.          new KBRotPosScaleSplinePathInterpolator(animAlpha, objTransformGroup,
  504.                                                   yAxis, splineKeyFrames); 
  505.       splineInterpolator.setSchedulingBounds(bounds);
  506.       behaviorBranch.addChild(splineInterpolator);
  507.        
  508.       // create linear interpolator 
  509.       linearInterpolator =
  510.          new KBRotPosScaleSplinePathInterpolator(animAlpha, objTransformGroup,
  511.                                                   yAxis, linearKeyFrames); 
  512.       linearInterpolator.setSchedulingBounds(bounds);
  513.       behaviorBranch.addChild(linearInterpolator);
  514.       objTransformGroup.addChild(behaviorBranch);
  515.  
  516.     }
  517.  
  518.     /*
  519.      * This activates one of the interpolators depending on the state of the
  520.      * linear boolean flag which may be toggled by the user using the choice
  521.      * menu.
  522.      */
  523.     public void startInterpolator () {
  524.       if (animationOn) {
  525.         if (linear) {
  526.           splineInterpolator.setEnable(false);
  527.           linearInterpolator.setEnable(true);
  528.         } else {
  529.           linearInterpolator.setEnable(false);
  530.           splineInterpolator.setEnable(true);
  531.         }
  532.       }
  533.     }
  534.  
  535.  
  536.     /* 
  537.      * Toggle animation  
  538.      */
  539.     public void actionPerformed (ActionEvent event) {
  540.       Object source = event.getSource();
  541.       if (source == animateButton) {
  542.         try {
  543.           // toggle animation
  544.           if (animationOn) {
  545.             animationOn = false;
  546.             splineInterpolator.setEnable(false);
  547.             linearInterpolator.setEnable(false);
  548.             animateButton.setLabel("Start Animation");
  549.           } else {
  550.             animationOn = true;
  551.             startInterpolator();
  552.             animateButton.setLabel("Stop Animation");
  553.           }
  554.         } catch (Exception e) {
  555.            System.err.println ("Exception " + e);
  556.         }
  557.       }
  558.     }
  559.  
  560.     /* 
  561.      * Toggle the interpolators  
  562.      */
  563.     public void itemStateChanged (ItemEvent event) {
  564.       Object source = event.getSource();
  565.       ItemSelectable ie = event.getItemSelectable();
  566.       if (source == interpChoice) {
  567.         try {
  568.           if (ie.getSelectedObjects()[0] == "Spline") {
  569.             linear = false;
  570.           }
  571.           if (ie.getSelectedObjects()[0] == "Linear") {
  572.             linear = true;
  573.           }
  574.           startInterpolator();
  575.         } catch (Exception e) {
  576.            System.err.println ("Exception " + e);
  577.         }
  578.       }
  579.     }
  580.  
  581.  
  582.     /* 
  583.      * Adjust the speed of the animations 
  584.      */
  585.     public void adjustmentValueChanged (AdjustmentEvent e) {
  586.       int value = e.getValue();
  587.       duration = 6000 - (500 * value);
  588.       animAlpha.setIncreasingAlphaDuration(duration);
  589.     }
  590.  
  591.  
  592.  
  593.     public static void main(String[] args) {
  594.         Frame frame = new MainFrame(new SplineAnim(), 500, 600);
  595.     }
  596. }
  597.