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