001: /*
002: * $RCSfile: TransparencyInterpolator.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:32 $
029: * $State: Exp $
030: */
031:
032: package javax.media.j3d;
033:
034: import java.util.Enumeration;
035:
036: /**
037: * TransparencyInterpolator behavior. This class defines a behavior
038: * that modifies the transparency of its target TransparencyAttributes
039: * object by linearly interpolating between a pair of specified
040: * transparency values (using the value generated by the specified
041: * Alpha object).
042: * <P>
043: * There are two forms of constructor to specify the
044: * type of transparency interpolation. The first constructor takes
045: * an Alpha and a TransparencyAttributes object and creates a transparency
046: * interpolator that maps an Alpha value of 1.0 to a transparency
047: * value of 1.0, and an Alpha value of 0.0 and maps it to a
048: * transparency value of 0.0. The second constructor takes an Alpha,
049: * a TransparencyAttributes object, a minimum transparency value and a
050: * maximum transparency value. This constructor provides more
051: * flexibility by specifying how the Alpha values are mapped
052: * to the transparency values - an Alpha of 1.0 maps to the
053: * maximum transparency value and an Alpha of 0.0 maps to the
054: * minimum transparency value.<P>
055: *
056: * @see Alpha
057: * @see TransparencyAttributes
058: */
059:
060: public class TransparencyInterpolator extends Interpolator {
061:
062: TransparencyAttributes target;
063: float minimumTransparency;
064: float maximumTransparency;
065:
066: // We can't use a boolean flag since it is possible
067: // that after alpha change, this procedure only run
068: // once at alpha.finish(). So the best way is to
069: // detect alpha value change.
070: private float prevAlphaValue = Float.NaN;
071: private WakeupCriterion passiveWakeupCriterion = (WakeupCriterion) new WakeupOnElapsedFrames(
072: 0, true);
073:
074: // non-public, default constructor used by cloneNode
075: TransparencyInterpolator() {
076: }
077:
078: /**
079: * Constructs a trivial transparency interpolator with a specified target,
080: * a minimum transparency of 0.0f and a maximum transparency of 1.0f.
081: * @param alpha the alpha object for this interpolator
082: * @param target the TransparencyAttributes component object affected
083: * by this interpolator
084: */
085: public TransparencyInterpolator(Alpha alpha,
086: TransparencyAttributes target) {
087:
088: super (alpha);
089:
090: this .target = target;
091: this .minimumTransparency = 0.0f;
092: this .maximumTransparency = 1.0f;
093: }
094:
095: /**
096: * Constructs a new transparency interpolator that varies the target
097: * material's transparency between the two transparency values.
098: * @param alpha the alpha object for this Interpolator
099: * @param target the TransparencyAttributes component object affected
100: * by this interpolator
101: * @param minimumTransparency the starting transparency
102: * @param maximumTransparency the ending transparency
103: */
104: public TransparencyInterpolator(Alpha alpha,
105: TransparencyAttributes target, float minimumTransparency,
106: float maximumTransparency) {
107:
108: super (alpha);
109:
110: this .target = target;
111: this .minimumTransparency = minimumTransparency;
112: this .maximumTransparency = maximumTransparency;
113: }
114:
115: /**
116: * This method sets the minimumTransparency for this interpolator.
117: * @param transparency the new minimum transparency
118: */
119: public void setMinimumTransparency(float transparency) {
120: this .minimumTransparency = transparency;
121: }
122:
123: /**
124: * This method retrieves this interpolator's minimumTransparency.
125: * @return the interpolator's minimum transparency value
126: */
127: public float getMinimumTransparency() {
128: return this .minimumTransparency;
129: }
130:
131: /**
132: * This method sets the maximumTransparency for this interpolator.
133: * @param transparency the new maximum transparency
134: */
135: public void setMaximumTransparency(float transparency) {
136: this .maximumTransparency = transparency;
137: }
138:
139: /**
140: * This method retrieves this interpolator's maximumTransparency.
141: * @return the interpolator's maximal transparency vslue
142: */
143: public float getMaximumTransparency() {
144: return this .maximumTransparency;
145: }
146:
147: /**
148: * This method sets the target TransparencyAttributes object
149: * for this interpolator.
150: * @param target the target TransparencyAttributes object
151: */
152: public void setTarget(TransparencyAttributes target) {
153: this .target = target;
154: }
155:
156: /**
157: * This method retrieves this interpolator's target reference.
158: * @return the interpolator's target TransparencyAttributes object
159: */
160: public TransparencyAttributes getTarget() {
161: return target;
162: }
163:
164: // The TransparencyInterpolator's initialize routine uses the default
165: // initialization routine.
166:
167: /**
168: * This method is invoked by the behavior scheduler every frame. It
169: * maps the alpha value that corresponds to the current time into a
170: * transparency value and updates the specified TransparencyAttributes
171: * object with this new transparency value.
172: * @param criteria an enumeration of the criteria that caused the
173: * stimulus
174: */
175: public void processStimulus(Enumeration criteria) {
176: // Handle stimulus
177: WakeupCriterion criterion = passiveWakeupCriterion;
178:
179: if (alpha != null) {
180: float value = alpha.value();
181:
182: if (value != prevAlphaValue) {
183: float val = (float) ((1.0 - value)
184: * minimumTransparency + value
185: * maximumTransparency);
186:
187: target.setTransparency(val);
188: prevAlphaValue = value;
189: }
190: if (!alpha.finished() && !alpha.isPaused()) {
191: criterion = defaultWakeupCriterion;
192: }
193: }
194: wakeupOn(criterion);
195: }
196:
197: /**
198: * Used to create a new instance of the node. This routine is called
199: * by <code>cloneTree</code> to duplicate the current node.
200: * @param forceDuplicate when set to <code>true</code>, causes the
201: * <code>duplicateOnCloneTree</code> flag to be ignored. When
202: * <code>false</code>, the value of each node's
203: * <code>duplicateOnCloneTree</code> variable determines whether
204: * NodeComponent data is duplicated or copied.
205: *
206: * @see Node#cloneTree
207: * @see Node#cloneNode
208: * @see Node#duplicateNode
209: * @see NodeComponent#setDuplicateOnCloneTree
210: */
211: public Node cloneNode(boolean forceDuplicate) {
212: TransparencyInterpolator ti = new TransparencyInterpolator();
213: ti.duplicateNode(this , forceDuplicate);
214: return ti;
215: }
216:
217: /**
218: * Copies all TransparencyInterpolator information from
219: * <code>originalNode</code> into
220: * the current node. This method is called from the
221: * <code>cloneNode</code> method which is, in turn, called by the
222: * <code>cloneTree</code> method.<P>
223: *
224: * @param originalNode the original node to duplicate.
225: * @param forceDuplicate when set to <code>true</code>, causes the
226: * <code>duplicateOnCloneTree</code> flag to be ignored. When
227: * <code>false</code>, the value of each node's
228: * <code>duplicateOnCloneTree</code> variable determines whether
229: * NodeComponent data is duplicated or copied.
230: *
231: * @exception RestrictedAccessException if this object is part of a live
232: * or compiled scenegraph.
233: *
234: * @see Node#duplicateNode
235: * @see Node#cloneTree
236: * @see NodeComponent#setDuplicateOnCloneTree
237: */
238: void duplicateAttributes(Node originalNode, boolean forceDuplicate) {
239: super .duplicateAttributes(originalNode, forceDuplicate);
240:
241: TransparencyInterpolator ti = (TransparencyInterpolator) originalNode;
242:
243: setMinimumTransparency(ti.getMinimumTransparency());
244: setMaximumTransparency(ti.getMaximumTransparency());
245:
246: // this reference will be updated in updateNodeReferences()
247: setTarget(ti.getTarget());
248: }
249:
250: /**
251: * Callback used to allow a node to check if any nodes referenced
252: * by that node have been duplicated via a call to <code>cloneTree</code>.
253: * This method is called by <code>cloneTree</code> after all nodes in
254: * the sub-graph have been duplicated. The cloned Leaf node's method
255: * will be called and the Leaf node can then look up any node references
256: * by using the <code>getNewObjectReference</code> method found in the
257: * <code>NodeReferenceTable</code> object. If a match is found, a
258: * reference to the corresponding Node in the newly cloned sub-graph
259: * is returned. If no corresponding reference is found, either a
260: * DanglingReferenceException is thrown or a reference to the original
261: * node is returned depending on the value of the
262: * <code>allowDanglingReferences</code> parameter passed in the
263: * <code>cloneTree</code> call.
264: * <p>
265: * NOTE: Applications should <i>not</i> call this method directly.
266: * It should only be called by the cloneTree method.
267: *
268: * @param referenceTable a NodeReferenceTableObject that contains the
269: * <code>getNewObjectReference</code> method needed to search for
270: * new object instances.
271: * @see NodeReferenceTable
272: * @see Node#cloneTree
273: * @see DanglingReferenceException
274: */
275: public void updateNodeReferences(NodeReferenceTable referenceTable) {
276: super .updateNodeReferences(referenceTable);
277:
278: // check TransparencyAttributes
279: NodeComponent nc = getTarget();
280:
281: if (nc != null) {
282: setTarget((TransparencyAttributes) referenceTable
283: .getNewObjectReference(nc));
284: }
285: }
286:
287: }
|