001: /*
002: * $RCSfile: RotationInterpolator.java,v $
003: *
004: * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
006: *
007: * This code is free software; you can redistribute it and/or modify it
008: * under the terms of the GNU General Public License version 2 only, as
009: * published by the Free Software Foundation. Sun designates this
010: * particular file as subject to the "Classpath" exception as provided
011: * by Sun in the LICENSE file that accompanied this code.
012: *
013: * This code is distributed in the hope that it will be useful, but WITHOUT
014: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
015: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
016: * version 2 for more details (a copy is included in the LICENSE file that
017: * accompanied this code).
018: *
019: * You should have received a copy of the GNU General Public License version
020: * 2 along with this work; if not, write to the Free Software Foundation,
021: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
022: *
023: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
024: * CA 95054 USA or visit www.sun.com if you need additional information or
025: * have any questions.
026: *
027: * $Revision: 1.5 $
028: * $Date: 2008/02/28 20:17:29 $
029: * $State: Exp $
030: */
031:
032: package javax.media.j3d;
033:
034: /**
035: * Rotation interpolator behavior. This class defines a behavior
036: * that modifies the rotational component of its target TransformGroup
037: * by linearly interpolating between a pair of specified angles
038: * (using the value generated by the specified Alpha object).
039: * The interpolated angle is used to generate a rotation transform
040: * about the local Y-axis of this interpolator.
041: */
042:
043: public class RotationInterpolator extends TransformInterpolator {
044:
045: float minimumAngle;
046: float maximumAngle;
047: private Transform3D rotation = new Transform3D();
048:
049: // We can't use a boolean flag since it is possible
050: // that after alpha change, this procedure only run
051: // once at alpha.finish(). So the best way is to
052: // detect alpha value change.
053: private float prevAlphaValue = Float.NaN;
054: private WakeupCriterion passiveWakeupCriterion = (WakeupCriterion) new WakeupOnElapsedFrames(
055: 0, true);
056:
057: // non-public, default constructor used by cloneNode
058: RotationInterpolator() {
059: }
060:
061: /**
062: * Constructs a trivial rotation interpolator with a specified target,
063: * an default axisOfTranform set to identity, a minimum angle of 0.0f, and
064: * a maximum angle of 2*pi radians.
065: * @param alpha The alpha object for this Interpolator
066: * @param target The target for this rotation Interpolator
067: */
068: public RotationInterpolator(Alpha alpha, TransformGroup target) {
069: super (alpha, target);
070: this .minimumAngle = 0.0f;
071: this .maximumAngle = 2.0f * (float) Math.PI;
072: }
073:
074: /**
075: * Constructs a new rotation interpolator that varies the target
076: * transform node's rotational component.
077: * @param alpha the alpha generator to use in the rotation computation
078: * @param target the TransformGroup node affected by this interpolator
079: * @param axisOfTransform the transform that defines the local coordinate
080: * system in which this interpolator operates. The rotation is done
081: * about the Y-axis of this local coordinate system.
082: * @param minimumAngle the starting angle in radians
083: * @param maximumAngle the ending angle in radians
084: */
085: public RotationInterpolator(Alpha alpha, TransformGroup target,
086: Transform3D axisOfTransform, float minimumAngle,
087: float maximumAngle) {
088: super (alpha, target, axisOfTransform);
089: this .minimumAngle = minimumAngle;
090: this .maximumAngle = maximumAngle;
091: }
092:
093: /**
094: * This method sets the minimumAngle for this interpolator, in
095: * radians.
096: * @param angle the new minimal angle
097: */
098: public void setMinimumAngle(float angle) {
099: this .minimumAngle = angle;
100: }
101:
102: /**
103: * This method retrieves this interpolator's minimumAngle, in
104: * radians.
105: * @return the interpolator's minimal angle value
106: */
107: public float getMinimumAngle() {
108: return this .minimumAngle;
109: }
110:
111: /**
112: * This method sets the maximumAngle for this interpolator, in
113: * radians.
114: * @param angle the new maximal angle value
115: */
116: public void setMaximumAngle(float angle) {
117: this .maximumAngle = angle;
118: }
119:
120: /**
121: * This method retrieves this interpolator's maximumAngle, in
122: * radians.
123: * @return the interpolator's maximal angle value
124: */
125: public float getMaximumAngle() {
126: return this .maximumAngle;
127: }
128:
129: /**
130: * @deprecated As of Java 3D version 1.3, replaced by
131: * <code>TransformInterpolator.setTransformAxis(Transform3D)</code>
132: */
133: public void setAxisOfRotation(Transform3D axisOfRotation) {
134: setTransformAxis(axisOfRotation);
135: }
136:
137: /**
138: * @deprecated As of Java 3D version 1.3, replaced by
139: * <code>TransformInterpolator.getTransformAxis()</code>
140: */
141: public Transform3D getAxisOfRotation() {
142: return getTransformAxis();
143: }
144:
145: /**
146: * Computes the new transform for this interpolator for a given
147: * alpha value.
148: *
149: * @param alphaValue alpha value between 0.0 and 1.0
150: * @param transform object that receives the computed transform for
151: * the specified alpha value
152: *
153: * @since Java 3D 1.3
154: */
155: public void computeTransform(float alphaValue, Transform3D transform) {
156: double val = (1.0 - alphaValue) * minimumAngle + alphaValue
157: * maximumAngle;
158:
159: // construct a Transform3D from: axis * rotation * axisInverse
160: rotation.rotY(val);
161: transform.mul(axis, rotation);
162: transform.mul(transform, axisInverse);
163: }
164:
165: /**
166: * Used to create a new instance of the node. This routine is called
167: * by <code>cloneTree</code> to duplicate the current node.
168: * @param forceDuplicate when set to <code>true</code>, causes the
169: * <code>duplicateOnCloneTree</code> flag to be ignored. When
170: * <code>false</code>, the value of each node's
171: * <code>duplicateOnCloneTree</code> variable determines whether
172: * NodeComponent data is duplicated or copied.
173: *
174: * @see Node#cloneTree
175: * @see Node#cloneNode
176: * @see Node#duplicateNode
177: * @see NodeComponent#setDuplicateOnCloneTree
178: */
179: public Node cloneNode(boolean forceDuplicate) {
180: RotationInterpolator ri = new RotationInterpolator();
181: ri.duplicateNode(this , forceDuplicate);
182: return ri;
183: }
184:
185: /**
186: * Copies all RotationInterpolator information from
187: * <code>originalNode</code> into
188: * the current node. This method is called from the
189: * <code>cloneNode</code> method which is, in turn, called by the
190: * <code>cloneTree</code> method.<P>
191: *
192: * @param originalNode the original node to duplicate.
193: * @param forceDuplicate when set to <code>true</code>, causes the
194: * <code>duplicateOnCloneTree</code> flag to be ignored. When
195: * <code>false</code>, the value of each node's
196: * <code>duplicateOnCloneTree</code> variable determines whether
197: * NodeComponent data is duplicated or copied.
198: *
199: * @exception RestrictedAccessException if this object is part of a live
200: * or compiled scenegraph.
201: *
202: * @see Node#duplicateNode
203: * @see Node#cloneTree
204: * @see NodeComponent#setDuplicateOnCloneTree
205: */
206: void duplicateAttributes(Node originalNode, boolean forceDuplicate) {
207: super .duplicateAttributes(originalNode, forceDuplicate);
208:
209: RotationInterpolator ri = (RotationInterpolator) originalNode;
210:
211: setMinimumAngle(ri.getMinimumAngle());
212: setMaximumAngle(ri.getMaximumAngle());
213:
214: }
215:
216: }
|