0001: /*
0002: * $RCSfile: Alpha.java,v $
0003: *
0004: * Copyright 1997-2008 Sun Microsystems, Inc. All Rights Reserved.
0005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0006: *
0007: * This code is free software; you can redistribute it and/or modify it
0008: * under the terms of the GNU General Public License version 2 only, as
0009: * published by the Free Software Foundation. Sun designates this
0010: * particular file as subject to the "Classpath" exception as provided
0011: * by Sun in the LICENSE file that accompanied this code.
0012: *
0013: * This code is distributed in the hope that it will be useful, but WITHOUT
0014: * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0015: * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
0016: * version 2 for more details (a copy is included in the LICENSE file that
0017: * accompanied this code).
0018: *
0019: * You should have received a copy of the GNU General Public License version
0020: * 2 along with this work; if not, write to the Free Software Foundation,
0021: * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0022: *
0023: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
0024: * CA 95054 USA or visit www.sun.com if you need additional information or
0025: * have any questions.
0026: *
0027: * $Revision: 1.8 $
0028: * $Date: 2008/02/28 20:17:19 $
0029: * $State: Exp $
0030: */
0031:
0032: package javax.media.j3d;
0033:
0034: /**
0035: * The alpha NodeComponent object provides common methods for
0036: * converting a time value into an alpha value (a value in the range 0
0037: * to 1). The Alpha object is effectively a function of time that
0038: * generates alpha values in the range [0,1] when sampled: f(t) =
0039: * [0,1]. A primary use of the Alpha object is to provide alpha
0040: * values for Interpolator behaviors. The function f(t) and the
0041: * characteristics of the Alpha object are determined by
0042: * user-definable parameters:
0043: *
0044: * <p>
0045: * <ul>
0046: *
0047: * <code>loopCount</code> -- This is the number of times to run this
0048: * Alpha; a value of -1 specifies that the Alpha loops
0049: * indefinitely.<p>
0050: *
0051: * <code>triggerTime</code> -- This is the time in milliseconds since
0052: * the start time that this object first triggers. If (startTime +
0053: * triggerTime >= currentTime) then the Alpha object starts running.<p>
0054: *
0055: * <code>phaseDelayDuration</code> -- This is an additional number of
0056: * milliseconds to wait after triggerTime before actually starting
0057: * this Alpha.<p>
0058: *
0059: * <code>mode</code> -- This can be set to INCREASING_ENABLE,
0060: * DECREASING_ENABLE, or the Or'ed value of the two.
0061: * INCREASING_ENABLE activates the increasing Alpha parameters listed
0062: * below; DECREASING_ENABLE activates the decreasing Alpha parameters
0063: * listed below.<p>
0064: *
0065: * </ul> Increasing Alpha parameters:<p> <ul>
0066: *
0067: * <code>increasingAlphaDuration</code> -- This is the period of time
0068: * during which Alpha goes from zero to one. <p>
0069: *
0070: * <code>increasingAlphaRampDuration</code> -- This is the period of
0071: * time during which the Alpha step size increases at the beginning of
0072: * the increasingAlphaDuration and, correspondingly, decreases at the
0073: * end of the increasingAlphaDuration. This parameter is clamped to
0074: * half of increasingAlphaDuration. When this parameter is non-zero,
0075: * one gets constant acceleration while it is in effect; constant
0076: * positive acceleration at the beginning of the ramp and constant
0077: * negative acceleration at the end of the ramp. If this parameter is
0078: * zero, then the effective velocity of the Alpha value is constant
0079: * and the acceleration is zero (ie, a linearly increasing alpha
0080: * ramp).<p>
0081: *
0082: * <code>alphaAtOneDuration</code> -- This is the period of time that
0083: * Alpha stays at one.<p> </ul> Decreasing Alpha parameters:<p> <ul>
0084: *
0085: * <code>decreasingAlphaDuration</code> -- This is the period of time
0086: * during which Alpha goes from one to zero.<p>
0087: *
0088: * <code>decreasingAlphaRampDuration</code> -- This is the period of
0089: * time during which the Alpha step size increases at the beginning of
0090: * the decreasingAlphaDuration and, correspondingly, decreases at the
0091: * end of the decreasingAlphaDuration. This parameter is clamped to
0092: * half of decreasingAlphaDuration. When this parameter is non-zero,
0093: * one gets constant acceleration while it is in effect; constant
0094: * positive acceleration at the beginning of the ramp and constant
0095: * negative acceleration at the end of the ramp. If this parameter is
0096: * zero, the effective velocity of the Alpha value is constant and the
0097: * acceleration is zero (i.e., a linearly-decreasing alpha ramp).<p>
0098: *
0099: * <code>alphaAtZeroDuration</code> -- This is the period of time that
0100: * Alpha stays at zero.
0101: *
0102: * </ul>
0103: *
0104: * @see Interpolator
0105: */
0106:
0107: public class Alpha extends NodeComponent {
0108:
0109: // loopCount < -1 --> reserved
0110: // loopCount == -1 --> repeat forever
0111: // loopCount >= 0 --> repeat count
0112: private int loopCount;
0113:
0114: /**
0115: * Specifies that the increasing component of the alpha is used.
0116: */
0117: public static final int INCREASING_ENABLE = 1;
0118:
0119: /**
0120: * Specifies that the decreasing component of the alpha is used
0121: */
0122: public static final int DECREASING_ENABLE = 2;
0123:
0124: /**
0125: * This alpha's mode, specifies whether to process
0126: * increasing and decreasing alphas.
0127: */
0128: private int mode;
0129:
0130: private float triggerTime;
0131: private float phaseDelay;
0132: private float increasingAlpha;
0133: private long increasingAlphaRamp;
0134: private float incAlphaRampInternal;
0135: private float alphaAtOne;
0136: private float decreasingAlpha;
0137: private long decreasingAlphaRamp;
0138: private float decAlphaRampInternal;
0139: private float alphaAtZero;
0140:
0141: // For pausing and resuming Alpha
0142: private long pauseTime = 0L;
0143: private boolean paused = false;
0144:
0145: // Stop time gets used only for loopCount > 0
0146: private float stopTime;
0147:
0148: // Start time in milliseconds
0149: private long startTime = MasterControl.systemStartTime;
0150:
0151: /**
0152: * Constructs an Alpha object with default parameters. The default
0153: * values are as follows:
0154: * <ul>
0155: * loopCount : -1<br>
0156: * mode : INCREASING_ENABLE<br>
0157: * startTime : system start time<br>
0158: * triggerTime : 0<br>
0159: * phaseDelayDuration : 0<br>
0160: * increasingAlphaDuration : 1000<br>
0161: * increasingAlphaRampDuration : 0<br>
0162: * alphaAtOneDuration : 0<br>
0163: * decreasingAlphaDuration : 0<br>
0164: * decreasingAlphaRampDuration : 0<br>
0165: * alphaAtZeroDuration : 0<br>
0166: * isPaused : false<br>
0167: * pauseTime : 0<br>
0168: * </ul>
0169: */
0170: public Alpha() {
0171: loopCount = -1;
0172: mode = INCREASING_ENABLE;
0173: increasingAlpha = 1.0f; // converted to seconds internally
0174: /*
0175: // Java initialize them to zero by default
0176: triggerTime = 0L;
0177: phaseDelay = 0.0f;
0178: increasingAlphaRamp = 0.0f;
0179: alphaAtOne = 0.0f;
0180: decreasingAlpha = 0.0f;
0181: decreasingAlphaRamp = 0.0f;
0182: alphaAtZero = 0.0f;
0183: */
0184: }
0185:
0186: /**
0187: * This constructor takes all of the Alpha user-definable parameters.
0188: * @param loopCount number of times to run this alpha; a value
0189: * of -1 specifies that the alpha loops indefinitely
0190: * @param mode indicates whether the increasing alpha parameters or
0191: * the decreasing alpha parameters or both are active. This parameter
0192: * accepts the following values, INCREASING_ENABLE or
0193: * DECREASING_ENABLE, which may be ORed together to specify
0194: * that both are active.
0195: * The increasing alpha parameters are increasingAlphaDuration,
0196: * increasingAlphaRampDuration, and alphaAtOneDuration.
0197: * The decreasing alpha parameters are decreasingAlphaDuration,
0198: * decreasingAlphaRampDuration, and alphaAtZeroDuration.
0199: * @param triggerTime time in milliseconds since the start time
0200: * that this object first triggers
0201: * @param phaseDelayDuration number of milliseconds to wait after
0202: * triggerTime before actually starting this alpha
0203: * @param increasingAlphaDuration period of time during which alpha goes
0204: * from zero to one
0205: * @param increasingAlphaRampDuration period of time during which
0206: * the alpha step size increases at the beginning of the
0207: * increasingAlphaDuration and, correspondingly, decreases at the end
0208: * of the increasingAlphaDuration. This value is clamped to half of
0209: * increasingAlphaDuration. NOTE: a value of zero means that the alpha
0210: * step size remains constant during the entire increasingAlphaDuration.
0211: * @param alphaAtOneDuration period of time that alpha stays at one
0212: * @param decreasingAlphaDuration period of time during which alpha goes
0213: * from one to zero
0214: * @param decreasingAlphaRampDuration period of time during which
0215: * the alpha step size increases at the beginning of the
0216: * decreasingAlphaDuration and, correspondingly, decreases at the end
0217: * of the decreasingAlphaDuration. This value is clamped to half of
0218: * decreasingAlphaDuration. NOTE: a value of zero means that the alpha
0219: * step size remains constant during the entire decreasingAlphaDuration.
0220: * @param alphaAtZeroDuration period of time that alpha stays at zero
0221: */
0222: public Alpha(int loopCount, int mode, long triggerTime,
0223: long phaseDelayDuration, long increasingAlphaDuration,
0224: long increasingAlphaRampDuration, long alphaAtOneDuration,
0225: long decreasingAlphaDuration,
0226: long decreasingAlphaRampDuration, long alphaAtZeroDuration) {
0227:
0228: this .loopCount = loopCount;
0229: this .mode = mode;
0230: this .triggerTime = (float) triggerTime * .001f;
0231: phaseDelay = (float) phaseDelayDuration * .001f;
0232:
0233: increasingAlpha = (float) increasingAlphaDuration * .001f;
0234: alphaAtOne = (float) alphaAtOneDuration * .001f;
0235: increasingAlphaRamp = increasingAlphaRampDuration;
0236: incAlphaRampInternal = increasingAlphaRampDuration * .001f;
0237: if (incAlphaRampInternal > (0.5f * increasingAlpha)) {
0238: incAlphaRampInternal = 0.5f * increasingAlpha;
0239: }
0240:
0241: decreasingAlpha = (float) decreasingAlphaDuration * .001f;
0242: alphaAtZero = (float) alphaAtZeroDuration * .001f;
0243: decreasingAlphaRamp = decreasingAlphaRampDuration;
0244: decAlphaRampInternal = decreasingAlphaRampDuration * .001f;
0245: if (decAlphaRampInternal > (0.5f * decreasingAlpha)) {
0246: decAlphaRampInternal = 0.5f * decreasingAlpha;
0247: }
0248: computeStopTime();
0249: }
0250:
0251: /**
0252: * Constructs a new Alpha object that assumes that the mode is
0253: * INCREASING_ENABLE.
0254: *
0255: * @param loopCount number of times to run this alpha; a value
0256: * of -1 specifies that the alpha loops indefinitely.
0257: * @param triggerTime time in milliseconds since the start time
0258: * that this object first triggers
0259: * @param phaseDelayDuration number of milliseconds to wait after
0260: * triggerTime before actually starting this alpha
0261: * @param increasingAlphaDuration period of time during which alpha goes
0262: * from zero to one
0263: * @param increasingAlphaRampDuration period of time during which
0264: * the alpha step size increases at the beginning of the
0265: * increasingAlphaDuration and, correspondingly, decreases at the end
0266: * of the increasingAlphaDuration. This value is clamped to half of
0267: * increasingAlphaDuration. NOTE: a value of zero means that the alpha
0268: * step size remains constant during the entire increasingAlphaDuration.
0269: * @param alphaAtOneDuration period of time that alpha stays at one
0270: */
0271:
0272: public Alpha(int loopCount, long triggerTime,
0273: long phaseDelayDuration, long increasingAlphaDuration,
0274: long increasingAlphaRampDuration, long alphaAtOneDuration) {
0275: this (loopCount, INCREASING_ENABLE, triggerTime,
0276: phaseDelayDuration, increasingAlphaDuration,
0277: increasingAlphaRampDuration, alphaAtOneDuration, 0, 0,
0278: 0);
0279: }
0280:
0281: /**
0282: * This constructor takes only the loopCount and increasingAlphaDuration
0283: * as parameters and assigns the default values to all of the other
0284: * parameters.
0285: * @param loopCount number of times to run this alpha; a value
0286: * of -1 specifies that the alpha loops indefinitely
0287: * @param increasingAlphaDuration period of time during which alpha goes
0288: * from zero to one
0289: */
0290: public Alpha(int loopCount, long increasingAlphaDuration) {
0291: // defaults
0292: mode = INCREASING_ENABLE;
0293: increasingAlpha = (float) increasingAlphaDuration * .001f;
0294: this .loopCount = loopCount;
0295:
0296: if (loopCount >= 0) {
0297: stopTime = loopCount * increasingAlpha;
0298: }
0299: }
0300:
0301: /**
0302: * Pauses this alpha object. The current system time when this
0303: * method is called will be used in place of the actual current
0304: * time when calculating subsequent alpha values. This has the
0305: * effect of freezing the interpolator at the time the method is
0306: * called.
0307: *
0308: * @since Java 3D 1.3
0309: */
0310: public void pause() {
0311: pause(J3dClock.currentTimeMillis());
0312: }
0313:
0314: /**
0315: * Pauses this alpha object as of the specified time. The specified
0316: * time will be used in place of the actual current time when
0317: * calculating subsequent alpha values. This has the effect of freezing
0318: * the interpolator at the specified time. Note that specifying a
0319: * time in the future (that is, a time greater than
0320: * System.currentTimeMillis()) will cause the alpha to immediately
0321: * advance to that point before pausing. Similarly, specifying a
0322: * time in the past (that is, a time less than
0323: * System.currentTimeMillis()) will cause the alpha to immediately
0324: * revert to that point before pausing.
0325: *
0326: * @param time the time at which to pause the alpha
0327: *
0328: * @exception IllegalArgumentException if time <= 0
0329: *
0330: * @since Java 3D 1.3
0331: */
0332: public void pause(long time) {
0333: if (time <= 0L) {
0334: throw new IllegalArgumentException(J3dI18N
0335: .getString("Alpha0"));
0336: }
0337:
0338: paused = true;
0339: pauseTime = time;
0340: VirtualUniverse.mc.sendRunMessage(J3dThread.RENDER_THREAD);
0341: }
0342:
0343: /**
0344: * Resumes this alpha object. If the alpha
0345: * object was paused, the difference between the current
0346: * time and the pause time will be used to adjust the startTime of
0347: * this alpha. The equation is as follows:
0348: *
0349: * <ul>
0350: * <code>startTime += System.currentTimeMillis() - pauseTime</code>
0351: * </ul>
0352: *
0353: * Since the alpha object is no longer paused, this has the effect
0354: * of resuming the interpolator as of the current time. If the
0355: * alpha object is not paused when this method is called, then this
0356: * method does nothing--the start time is not adjusted in this case.
0357: *
0358: * @since Java 3D 1.3
0359: */
0360: public void resume() {
0361: resume(J3dClock.currentTimeMillis());
0362: }
0363:
0364: /**
0365: * Resumes this alpha object as of the specified time. If the alpha
0366: * object was paused, the difference between the specified
0367: * time and the pause time will be used to adjust the startTime of
0368: * this alpha. The equation is as follows:
0369: *
0370: * <ul><code>startTime += time - pauseTime</code></ul>
0371: *
0372: * Since the alpha object is no longer paused, this has the effect
0373: * of resuming the interpolator as of the specified time. If the
0374: * alpha object is not paused when this method is called, then this
0375: * method does nothing--the start time is not adjusted in this case.
0376: *
0377: * @param time the time at which to resume the alpha
0378: *
0379: * @exception IllegalArgumentException if time <= 0
0380: *
0381: * @since Java 3D 1.3
0382: */
0383: public void resume(long time) {
0384: if (time <= 0L) {
0385: throw new IllegalArgumentException(J3dI18N
0386: .getString("Alpha0"));
0387: }
0388:
0389: if (paused) {
0390: long newStartTime = startTime + time - pauseTime;
0391: paused = false;
0392: pauseTime = 0L;
0393: setStartTime(newStartTime);
0394: }
0395: }
0396:
0397: /**
0398: * Returns true if this alpha object is paused.
0399: * @return true if this alpha object is paused, false otherwise
0400: *
0401: * @since Java 3D 1.3
0402: */
0403: public boolean isPaused() {
0404: return paused;
0405: }
0406:
0407: /**
0408: * Returns the time at which this alpha was paused.
0409: * @return the pause time; returns 0 if this alpha is not paused
0410: *
0411: * @since Java 3D 1.3
0412: */
0413: public long getPauseTime() {
0414: return pauseTime;
0415: }
0416:
0417: /**
0418: * This method returns a value between 0.0 and 1.0 inclusive,
0419: * based on the current time and the time-to-alpha parameters
0420: * established for this alpha. If this alpha object is paused,
0421: * the value will be based on the pause time rather than the
0422: * current time.
0423: * This method will return the starting alpha value if the alpha
0424: * has not yet started (that is, if the current time is less
0425: * than startTime + triggerTime + phaseDelayDuration). This
0426: * method will return the ending alpha value if the alpha has
0427: * finished (that is, if the loop count has expired).
0428: *
0429: * @return a value between 0.0 and 1.0 based on the current time
0430: */
0431: public float value() {
0432: long currentTime = paused ? pauseTime : J3dClock
0433: .currentTimeMillis();
0434: return this .value(currentTime);
0435: }
0436:
0437: /**
0438: * This method returns a value between 0.0 and 1.0 inclusive,
0439: * based on the specified time and the time-to-alpha parameters
0440: * established for this alpha.
0441: * This method will return the starting alpha value if the alpha
0442: * has not yet started (that is, if the specified time is less
0443: * than startTime + triggerTime + phaseDelayDuration). This
0444: * method will return the ending alpha value if the alpha has
0445: * finished (that is, if the loop count has expired).
0446: *
0447: * @param atTime The time for which we wish to compute alpha
0448: * @return a value between 0.0 and 1.0 based on the specified time
0449: */
0450: public float value(long atTime) {
0451: float interpolatorTime = (float) (atTime - startTime) * .001f; // startTime is in millisec
0452: float alpha, a1, a2, dt, alphaRampDuration;
0453:
0454: // System.err.println("alpha mode: " + mode);
0455:
0456: // If non-looping and before start
0457: // if ((loopCount != -1) &&
0458: // interpolatorTime <= ( triggerTime + phaseDelay)) {
0459: //
0460: // if (( mode & INCREASING_ENABLE ) == 0 &&
0461: // ( mode & DECREASING_ENABLE) != 0)
0462: // alpha = 1.0f;
0463: // else
0464: // alpha = 0.0f;
0465: // return alpha;
0466: // }
0467:
0468: // Case of {constantly} moving forward, snap back, forward again
0469: if ((mode & INCREASING_ENABLE) != 0
0470: && (mode & DECREASING_ENABLE) == 0) {
0471:
0472: if (interpolatorTime <= (triggerTime + phaseDelay))
0473: return 0.0f;
0474:
0475: if ((loopCount != -1) && (interpolatorTime >= stopTime))
0476: return 1.0f;
0477:
0478: // Constant velocity case
0479: if (incAlphaRampInternal == 0.0f) {
0480:
0481: alpha = mfmod(
0482: (interpolatorTime - triggerTime - phaseDelay)
0483: + 6.0f * (increasingAlpha + alphaAtOne),
0484: (increasingAlpha + alphaAtOne))
0485: / increasingAlpha;
0486:
0487: if (alpha > 1.0f)
0488: alpha = 1.0f;
0489: return alpha;
0490: }
0491:
0492: // Ramped velocity case
0493: alphaRampDuration = incAlphaRampInternal;
0494:
0495: dt = mfmod((interpolatorTime - triggerTime - phaseDelay)
0496: + 6.0f * (increasingAlpha + alphaAtOne),
0497: (increasingAlpha + alphaAtOne));
0498: if (dt >= increasingAlpha) {
0499: alpha = 1.0f;
0500: return alpha;
0501: }
0502:
0503: // Original equation kept to help understand
0504: // computation logic - simplification saves
0505: // a multiply and an add
0506: // a1 = 1.0f/(alphaRampDuration*alphaRampDuration +
0507: // ( increasingAlpha - 2*alphaRampDuration)*
0508: // alphaRampDuration);
0509:
0510: a1 = 1.0f / (increasingAlpha * alphaRampDuration - alphaRampDuration
0511: * alphaRampDuration);
0512:
0513: if (dt < alphaRampDuration) {
0514: alpha = 0.5f * a1 * dt * dt;
0515: } else if (dt < increasingAlpha - alphaRampDuration) {
0516: alpha = 0.5f * a1 * alphaRampDuration
0517: * alphaRampDuration + (dt - alphaRampDuration)
0518: * a1 * alphaRampDuration;
0519: } else {
0520: alpha = a1 * alphaRampDuration * alphaRampDuration
0521: + (increasingAlpha - 2.0f * alphaRampDuration)
0522: * a1 * alphaRampDuration - 0.5f * a1
0523: * (increasingAlpha - dt)
0524: * (increasingAlpha - dt);
0525: }
0526: return alpha;
0527:
0528: } else
0529:
0530: // Case of {constantly} moving backward, snap forward, backward
0531: // again
0532: if ((mode & INCREASING_ENABLE) == 0
0533: && (mode & DECREASING_ENABLE) != 0) {
0534:
0535: // If non-looping and past end
0536: // if ((loopCount != -1)
0537: // && (interpolatorTime
0538: // >= (triggerTime + phaseDelay + decreasingAlpha))) {
0539: // alpha = 0.0f;
0540: // return alpha;
0541: // }
0542:
0543: if (interpolatorTime <= (triggerTime + phaseDelay))
0544: return 1.0f;
0545:
0546: if ((loopCount != -1) && (interpolatorTime >= stopTime))
0547: return 0.0f;
0548:
0549: // Constant velocity case
0550: if (decAlphaRampInternal == 0.0f) {
0551: alpha = mfmod(
0552: (interpolatorTime - triggerTime - phaseDelay)
0553: + 6.0f
0554: * (decreasingAlpha + alphaAtZero),
0555: (decreasingAlpha + alphaAtZero))
0556: / decreasingAlpha;
0557: if (alpha > 1.0f) {
0558: alpha = 0.0f;
0559: return alpha;
0560: }
0561: alpha = 1.0f - alpha;
0562: return alpha;
0563: }
0564:
0565: // Ramped velocity case
0566: alphaRampDuration = decAlphaRampInternal;
0567:
0568: dt = mfmod((interpolatorTime - triggerTime - phaseDelay)
0569: + 6.0f * (decreasingAlpha + alphaAtZero),
0570: (decreasingAlpha + alphaAtZero));
0571: if (dt >= decreasingAlpha) {
0572: alpha = 0.0f;
0573: return alpha;
0574: }
0575:
0576: // Original equation kept to help understand
0577: // computation logic - simplification saves
0578: // a multiply and an add
0579: // a1 = 1.0f/(alphaRampDuration*alphaRampDuration +
0580: // ( decreasingAlpha - 2*alphaRampDuration)*
0581: // alphaRampDuration);
0582:
0583: a1 = 1.0f / (decreasingAlpha * alphaRampDuration - alphaRampDuration
0584: * alphaRampDuration);
0585:
0586: if (dt < alphaRampDuration) {
0587: alpha = 0.5f * a1 * dt * dt;
0588: } else if (dt < decreasingAlpha - alphaRampDuration) {
0589: alpha = 0.5f * a1 * alphaRampDuration
0590: * alphaRampDuration + (dt - alphaRampDuration)
0591: * a1 * alphaRampDuration;
0592: } else {
0593: alpha = a1 * alphaRampDuration * alphaRampDuration
0594: + (decreasingAlpha - 2.0f * alphaRampDuration)
0595: * a1 * alphaRampDuration - 0.5f * a1
0596: * (decreasingAlpha - dt)
0597: * (decreasingAlpha - dt);
0598: }
0599: alpha = 1.0f - alpha;
0600: return alpha;
0601:
0602: } else
0603:
0604: // Case of {osscilating} increasing and decreasing alpha
0605: if ((mode & INCREASING_ENABLE) != 0
0606: && (mode & DECREASING_ENABLE) != 0) {
0607:
0608: // If non-looping and past end
0609: // if ((loopCount != -1) &&
0610: // (interpolatorTime >=
0611: // (triggerTime + phaseDelay + increasingAlpha +
0612: // alphaAtOne + decreasingAlpha))) {
0613: // alpha = 0.0f;
0614: // return alpha;
0615: // }
0616:
0617: // If non-looping and past end, we always end up at zero since
0618: // decreasing alpha has been requested.
0619: if (interpolatorTime <= (triggerTime + phaseDelay))
0620: return 0.0f;
0621:
0622: if ((loopCount != -1) && (interpolatorTime >= stopTime))
0623: return 0.0f;
0624:
0625: // Constant velocity case
0626: if (incAlphaRampInternal == 0.0f
0627: && decAlphaRampInternal == 0.0f) {
0628: dt = mfmod(interpolatorTime
0629: - triggerTime
0630: - phaseDelay
0631: + 6.0f
0632: * (increasingAlpha + alphaAtOne
0633: + decreasingAlpha + alphaAtZero),
0634: increasingAlpha + alphaAtOne + decreasingAlpha
0635: + alphaAtZero);
0636: alpha = dt / increasingAlpha;
0637: if (alpha < 1.0f)
0638: return alpha;
0639: // sub all increasing alpha time
0640: dt -= increasingAlpha;
0641: if (dt < alphaAtOne) {
0642: alpha = 1.0f;
0643: return alpha;
0644: }
0645: // sub out alpha @ 1 time
0646: dt -= alphaAtOne;
0647: alpha = dt / decreasingAlpha;
0648: if (alpha < 1.0f)
0649: alpha = 1.0f - alpha;
0650: else
0651: alpha = 0.0f;
0652: return alpha;
0653: }
0654:
0655: // Ramped velocity case
0656: alphaRampDuration = incAlphaRampInternal;
0657:
0658: // work around for bug 4308308
0659: if (alphaRampDuration == 0.0f)
0660: alphaRampDuration = .00001f;
0661:
0662: dt = mfmod(
0663: interpolatorTime
0664: - triggerTime
0665: - phaseDelay
0666: + 6.0f
0667: * (increasingAlpha + alphaAtOne
0668: + decreasingAlpha + alphaAtZero),
0669: increasingAlpha + alphaAtOne + decreasingAlpha
0670: + alphaAtZero);
0671: if (dt <= increasingAlpha) {
0672:
0673: // Original equation kept to help understand
0674: // computation logic - simplification saves
0675: // a multiply and an add
0676: // a1 = 1.0f/(alphaRampDuration*alphaRampDuration +
0677: // ( increasingAlpha - 2*alphaRampDuration)*
0678: // alphaRampDuration);
0679:
0680: a1 = 1.0f / (increasingAlpha * alphaRampDuration - alphaRampDuration
0681: * alphaRampDuration);
0682:
0683: if (dt < alphaRampDuration) {
0684: alpha = 0.5f * a1 * dt * dt;
0685: } else if (dt < increasingAlpha - alphaRampDuration) {
0686: alpha = 0.5f * a1 * alphaRampDuration
0687: * alphaRampDuration
0688: + (dt - alphaRampDuration) * a1
0689: * alphaRampDuration;
0690: } else {
0691: alpha = a1
0692: * alphaRampDuration
0693: * alphaRampDuration
0694: + (increasingAlpha - 2.0f * alphaRampDuration)
0695: * a1 * alphaRampDuration - 0.5f * a1
0696: * (increasingAlpha - dt)
0697: * (increasingAlpha - dt);
0698: }
0699: return alpha;
0700: } else if (dt <= increasingAlpha + alphaAtOne) {
0701: alpha = 1.0f;
0702: return alpha;
0703: } else if (dt >= increasingAlpha + alphaAtOne
0704: + decreasingAlpha) {
0705: alpha = 0.0f;
0706: return alpha;
0707: } else {
0708: dt -= increasingAlpha + alphaAtOne;
0709:
0710: alphaRampDuration = decAlphaRampInternal;
0711:
0712: // work around for bug 4308308
0713: if (alphaRampDuration == 0.0f)
0714: alphaRampDuration = .00001f;
0715:
0716: // Original equation kept to help understand
0717: // computation logic - simplification saves
0718: // a multiply and an add
0719: // a1 = 1.0f/(alphaRampDuration*alphaRampDuration +
0720: // ( decreasingAlpha - 2*alphaRampDuration)*
0721: // alphaRampDuration);
0722:
0723: a1 = 1.0f / (decreasingAlpha * alphaRampDuration - alphaRampDuration
0724: * alphaRampDuration);
0725:
0726: if (dt < alphaRampDuration) {
0727: alpha = 0.5f * a1 * dt * dt;
0728: } else if (dt < decreasingAlpha - alphaRampDuration) {
0729: alpha = 0.5f * a1 * alphaRampDuration
0730: * alphaRampDuration
0731: + (dt - alphaRampDuration) * a1
0732: * alphaRampDuration;
0733: } else {
0734: alpha = a1
0735: * alphaRampDuration
0736: * alphaRampDuration
0737: + (decreasingAlpha - 2.0f * alphaRampDuration)
0738: * a1 * alphaRampDuration - 0.5f * a1
0739: * (decreasingAlpha - dt)
0740: * (decreasingAlpha - dt);
0741: }
0742: alpha = 1.0f - alpha;
0743: return alpha;
0744: }
0745:
0746: }
0747: return 0.0f;
0748: }
0749:
0750: float mfmod(float a, float b) {
0751: float fm, ta = (a), tb = (b);
0752: int fmint;
0753: if (tb < 0.0f)
0754: tb = -tb;
0755: if (ta < 0.0f)
0756: ta = -ta;
0757:
0758: fmint = (int) (ta / tb);
0759: fm = ta - (float) fmint * tb;
0760:
0761: if ((a) < 0.0f)
0762: return ((b) - fm);
0763: else
0764: return fm;
0765: }
0766:
0767: /**
0768: * Retrieves this alpha's startTime, the base
0769: * for all relative time specifications; the default value
0770: * for startTime is the system start time.
0771: * @return this alpha's startTime.
0772: */
0773: public long getStartTime() {
0774: return this .startTime;
0775: }
0776:
0777: /**
0778: * Sets this alpha's startTime to that specified in the argument;
0779: * startTime sets the base (or zero) for all relative time
0780: * computations; the default value for startTime is the system
0781: * start time.
0782: * @param startTime the new startTime value
0783: */
0784: public void setStartTime(long startTime) {
0785: this .startTime = startTime;
0786: // This is used for passive wakeupOnElapsedFrame in
0787: // Interpolator to restart behavior after alpha.finished()
0788: VirtualUniverse.mc.sendRunMessage(J3dThread.RENDER_THREAD);
0789: }
0790:
0791: /**
0792: * Retrieves this alpha's loopCount.
0793: * @return this alpha's loopCount.
0794: */
0795: public int getLoopCount() {
0796: return this .loopCount;
0797: }
0798:
0799: /**
0800: * Set this alpha's loopCount to that specified in the argument.
0801: * @param loopCount the new loopCount value
0802: */
0803: public void setLoopCount(int loopCount) {
0804: this .loopCount = loopCount;
0805: computeStopTime();
0806: VirtualUniverse.mc.sendRunMessage(J3dThread.RENDER_THREAD);
0807: }
0808:
0809: /**
0810: * Retrieves this alpha's mode.
0811: * @return this alpha's mode: any combination of
0812: * INCREASING_ENABLE and DECREASING_ENABLE
0813: */
0814: public int getMode() {
0815: return this .mode;
0816: }
0817:
0818: /**
0819: * Set this alpha's mode to that specified in the argument.
0820: * @param mode indicates whether the increasing alpha parameters or
0821: * the decreasing alpha parameters or both are active. This parameter
0822: * accepts the following values, INCREASING_ENABLE or
0823: * DECREASING_ENABLE, which may be ORed together to specify
0824: * that both are active.
0825: * The increasing alpha parameters are increasingAlphaDuration,
0826: * increasingAlphaRampDuration, and alphaAtOneDuration.
0827: * The decreasing alpha parameters are decreasingAlphaDuration,
0828: * decreasingAlphaRampDuration, and alphaAtZeroDuration.
0829: */
0830: public void setMode(int mode) {
0831: this .mode = mode;
0832: computeStopTime();
0833: VirtualUniverse.mc.sendRunMessage(J3dThread.RENDER_THREAD);
0834: }
0835:
0836: /**
0837: * Retrieves this alpha's triggerTime.
0838: * @return this alpha's triggerTime.
0839: */
0840: public long getTriggerTime() {
0841: return (long) (this .triggerTime * 1000f);
0842: }
0843:
0844: /**
0845: * Set this alpha's triggerTime to that specified in the argument.
0846: * @param triggerTime the new triggerTime
0847: */
0848: public void setTriggerTime(long triggerTime) {
0849: this .triggerTime = (float) triggerTime * .001f;
0850: computeStopTime();
0851: VirtualUniverse.mc.sendRunMessage(J3dThread.RENDER_THREAD);
0852: }
0853:
0854: /**
0855: * Retrieves this alpha's phaseDelayDuration.
0856: * @return this alpha's phaseDelayDuration.
0857: */
0858: public long getPhaseDelayDuration() {
0859: return (long) (this .phaseDelay * 1000f);
0860: }
0861:
0862: /**
0863: * Set this alpha's phaseDelayDuration to that specified in
0864: * the argument.
0865: * @param phaseDelayDuration the new phaseDelayDuration
0866: */
0867: public void setPhaseDelayDuration(long phaseDelayDuration) {
0868: this .phaseDelay = (float) phaseDelayDuration * .001f;
0869: computeStopTime();
0870: VirtualUniverse.mc.sendRunMessage(J3dThread.RENDER_THREAD);
0871: }
0872:
0873: /**
0874: * Retrieves this alpha's increasingAlphaDuration.
0875: * @return this alpha's increasingAlphaDuration.
0876: */
0877: public long getIncreasingAlphaDuration() {
0878: return (long) (this .increasingAlpha * 1000f);
0879: }
0880:
0881: /**
0882: * Set this alpha's increasingAlphaDuration to that specified in
0883: * the argument.
0884: * @param increasingAlphaDuration the new increasingAlphaDuration
0885: */
0886: public void setIncreasingAlphaDuration(long increasingAlphaDuration) {
0887: this .increasingAlpha = (float) increasingAlphaDuration * .001f;
0888: computeStopTime();
0889: VirtualUniverse.mc.sendRunMessage(J3dThread.RENDER_THREAD);
0890: }
0891:
0892: /**
0893: * Retrieves this alpha's increasingAlphaRampDuration.
0894: * @return this alpha's increasingAlphaRampDuration.
0895: */
0896: public long getIncreasingAlphaRampDuration() {
0897: return increasingAlphaRamp;
0898: }
0899:
0900: /**
0901: * Set this alpha's increasingAlphaRampDuration to that specified
0902: * in the argument.
0903: * @param increasingAlphaRampDuration the new increasingAlphaRampDuration
0904: */
0905: public void setIncreasingAlphaRampDuration(
0906: long increasingAlphaRampDuration) {
0907: increasingAlphaRamp = increasingAlphaRampDuration;
0908: incAlphaRampInternal = (float) increasingAlphaRampDuration * .001f;
0909: if (incAlphaRampInternal > (0.5f * increasingAlpha)) {
0910: incAlphaRampInternal = 0.5f * increasingAlpha;
0911: }
0912: VirtualUniverse.mc.sendRunMessage(J3dThread.RENDER_THREAD);
0913: }
0914:
0915: /**
0916: * Retrieves this alpha's alphaAtOneDuration.
0917: * @return this alpha's alphaAtOneDuration.
0918: */
0919: public long getAlphaAtOneDuration() {
0920: return (long) (this .alphaAtOne * 1000f);
0921: }
0922:
0923: /**
0924: * Set this alpha object's alphaAtOneDuration to the specified
0925: * value.
0926: * @param alphaAtOneDuration the new alphaAtOneDuration
0927: */
0928: public void setAlphaAtOneDuration(long alphaAtOneDuration) {
0929: this .alphaAtOne = (float) alphaAtOneDuration * .001f;
0930: computeStopTime();
0931: VirtualUniverse.mc.sendRunMessage(J3dThread.RENDER_THREAD);
0932: }
0933:
0934: /**
0935: * Retrieves this alpha's decreasingAlphaDuration.
0936: * @return this alpha's decreasingAlphaDuration.
0937: */
0938: public long getDecreasingAlphaDuration() {
0939: return (long) (this .decreasingAlpha * 1000f);
0940: }
0941:
0942: /**
0943: * Set this alpha's decreasingAlphaDuration to that specified in
0944: * the argument.
0945: * @param decreasingAlphaDuration the new decreasingAlphaDuration
0946: */
0947: public void setDecreasingAlphaDuration(long decreasingAlphaDuration) {
0948: this .decreasingAlpha = (float) decreasingAlphaDuration * .001f;
0949: computeStopTime();
0950: VirtualUniverse.mc.sendRunMessage(J3dThread.RENDER_THREAD);
0951: }
0952:
0953: /**
0954: * Retrieves this alpha's decreasingAlphaRampDuration.
0955: * @return this alpha's decreasingAlphaRampDuration.
0956: */
0957: public long getDecreasingAlphaRampDuration() {
0958: return decreasingAlphaRamp;
0959: }
0960:
0961: /**
0962: * Set this alpha's decreasingAlphaRampDuration to that specified
0963: * in the argument.
0964: * @param decreasingAlphaRampDuration the new decreasingAlphaRampDuration
0965: */
0966: public void setDecreasingAlphaRampDuration(
0967: long decreasingAlphaRampDuration) {
0968: decreasingAlphaRamp = decreasingAlphaRampDuration;
0969: decAlphaRampInternal = (float) decreasingAlphaRampDuration * .001f;
0970: if (decAlphaRampInternal > (0.5f * decreasingAlpha)) {
0971: decAlphaRampInternal = 0.5f * decreasingAlpha;
0972: }
0973: VirtualUniverse.mc.sendRunMessage(J3dThread.RENDER_THREAD);
0974: }
0975:
0976: /**
0977: * Retrieves this alpha's alphaAtZeroDuration.
0978: * @return this alpha's alphaAtZeroDuration.
0979: */
0980: public long getAlphaAtZeroDuration() {
0981: return (long) (this .alphaAtZero * 1000f);
0982: }
0983:
0984: /**
0985: * Set this alpha object's alphaAtZeroDuration to the specified
0986: * value.
0987: * @param alphaAtZeroDuration the new alphaAtZeroDuration
0988: */
0989: public void setAlphaAtZeroDuration(long alphaAtZeroDuration) {
0990: this .alphaAtZero = (float) alphaAtZeroDuration * .001f;
0991: computeStopTime();
0992: VirtualUniverse.mc.sendRunMessage(J3dThread.RENDER_THREAD);
0993: }
0994:
0995: /**
0996: * Query to test if this alpha object is past its activity window,
0997: * that is, if it has finished looping.
0998: * @return true if no longer looping, false otherwise
0999: */
1000: public boolean finished() {
1001: long currentTime = paused ? pauseTime : J3dClock
1002: .currentTimeMillis();
1003: return ((loopCount != -1) && ((float) (currentTime - startTime) * .001f > stopTime));
1004: }
1005:
1006: final private void computeStopTime() {
1007: if (loopCount >= 0) {
1008: float sum = 0;
1009: if ((mode & INCREASING_ENABLE) != 0) {
1010: sum = increasingAlpha + alphaAtOne;
1011: }
1012: if ((mode & DECREASING_ENABLE) != 0) {
1013: sum += decreasingAlpha + alphaAtZero;
1014: }
1015: stopTime = this .triggerTime + phaseDelay + loopCount * sum;
1016: } else {
1017: stopTime = 0;
1018: }
1019: }
1020:
1021: /**
1022: * This internal method returns a clone of the Alpha
1023: *
1024: * @return a duplicate of this Alpha
1025: */
1026: Alpha cloneAlpha() {
1027: Alpha a = new Alpha();
1028: a.setStartTime(getStartTime());
1029: a.setLoopCount(getLoopCount());
1030: a.setMode(getMode());
1031: a.setTriggerTime(getTriggerTime());
1032: a.setPhaseDelayDuration(getPhaseDelayDuration());
1033: a.setIncreasingAlphaDuration(getIncreasingAlphaDuration());
1034: a
1035: .setIncreasingAlphaRampDuration(getIncreasingAlphaRampDuration());
1036: a.setAlphaAtOneDuration(getAlphaAtOneDuration());
1037: a.setDecreasingAlphaDuration(getDecreasingAlphaDuration());
1038: a
1039: .setDecreasingAlphaRampDuration(getDecreasingAlphaRampDuration());
1040: a.setAlphaAtZeroDuration(getAlphaAtZeroDuration());
1041: return a;
1042: }
1043:
1044: static {
1045: VirtualUniverse.loadLibraries();
1046: }
1047:
1048: }
|