From 743e5d1963893a92847469f6561abef21bdb0a9c Mon Sep 17 00:00:00 2001 From: "rem..om" Date: Sun, 2 Mar 2014 08:52:39 +0000 Subject: [PATCH] LoopMode.Cycle is now properly supported by MotionEvent and CinematicEvent. Used AnimChannel's clampWrapTime method for consistency, and refactored it in an AnimationUtils utility class. git-svn-id: https://jmonkeyengine.googlecode.com/svn/trunk@11065 75d07b2b-3a1a-0410-a2c5-0572b91ccdca --- .../core/com/jme3/animation/AnimChannel.java | 62 +---------------- .../com/jme3/animation/AnimationUtils.java | 67 +++++++++++++++++++ .../events/AbstractCinematicEvent.java | 7 ++ .../jme3/cinematic/events/MotionEvent.java | 9 ++- 4 files changed, 84 insertions(+), 61 deletions(-) create mode 100644 engine/src/core/com/jme3/animation/AnimationUtils.java diff --git a/engine/src/core/com/jme3/animation/AnimChannel.java b/engine/src/core/com/jme3/animation/AnimChannel.java index 6a74b1864..7605db937 100644 --- a/engine/src/core/com/jme3/animation/AnimChannel.java +++ b/engine/src/core/com/jme3/animation/AnimChannel.java @@ -68,64 +68,6 @@ public final class AnimChannel { private float blendAmount = 1f; private float blendRate = 0; - private static float clampWrapTime(float t, float max, LoopMode loopMode){ - if (t == 0) { - return 0; // prevent division by 0 errors - } - - switch (loopMode) { - case Cycle: - boolean sign = ((int) (t / max) % 2) != 0; - float result; - -// if (t < 0){ -// result = sign ? t % max : -(max + (t % max)); -// } else { - // NOTE: This algorithm seems stable for both high and low - // tpf so for now its a keeper. - result = sign ? -(max - (t % max)) : t % max; -// } - -// if (result <= 0 || result >= max) { -// System.out.println("SIGN: " + sign + ", RESULT: " + result + ", T: " + t + ", M: " + max); -// } - - return result; - case DontLoop: - return t > max ? max : (t < 0 ? 0 : t); - case Loop: - return t % max; - } - return t; - - -// if (max == Float.POSITIVE_INFINITY) -// return t; -// -// if (t < 0f){ -// //float tMod = -(-t % max); -// switch (loopMode){ -// case DontLoop: -// return 0; -// case Cycle: -// return t; -// case Loop: -// return max - t; -// } -// }else if (t > max){ -// switch (loopMode){ -// case DontLoop: -// return max; -// case Cycle: -// return -(2f * max - t) % max; -// case Loop: -// return t % max; -// } -// } -// -// return t; - } - AnimChannel(AnimControl control){ this.control = control; } @@ -385,7 +327,7 @@ public final class AnimChannel { blendFrom.setTime(timeBlendFrom, 1f - blendAmount, control, this, vars); timeBlendFrom += tpf * speedBlendFrom; - timeBlendFrom = clampWrapTime(timeBlendFrom, + timeBlendFrom = AnimationUtils.clampWrapTime(timeBlendFrom, blendFrom.getLength(), loopModeBlendFrom); if (timeBlendFrom < 0){ @@ -414,7 +356,7 @@ public final class AnimChannel { } } time += tpf * speed; - time = clampWrapTime(time, animation.getLength(), loopMode); + time = AnimationUtils.clampWrapTime(time, animation.getLength(), loopMode); if (time < 0){ // Negative time indicates that speed should be inverted // (for cycle loop mode only) diff --git a/engine/src/core/com/jme3/animation/AnimationUtils.java b/engine/src/core/com/jme3/animation/AnimationUtils.java new file mode 100644 index 000000000..9272fe5e3 --- /dev/null +++ b/engine/src/core/com/jme3/animation/AnimationUtils.java @@ -0,0 +1,67 @@ +/* + * Copyright (c) 2009-2012 jMonkeyEngine + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * * Neither the name of 'jMonkeyEngine' nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR + * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, + * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, + * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package com.jme3.animation; + +import static com.jme3.animation.LoopMode.Cycle; +import static com.jme3.animation.LoopMode.DontLoop; +import static com.jme3.animation.LoopMode.Loop; + +/** + * + * @author Nehon + */ +public class AnimationUtils { + + + /** + * Clamps the time according to duration and loopMode + * @param time + * @param duration + * @param loopMode + * @return + */ + public static float clampWrapTime(float time, float duration, LoopMode loopMode){ + if (time == 0) { + return 0; // prevent division by 0 errors + } + switch (loopMode) { + case Cycle: + boolean sign = ((int) (time / duration) % 2) != 0; + return sign ? -(duration - (time % duration)) : time % duration; + case DontLoop: + return time > duration ? duration : (time < 0 ? 0 : time); + case Loop: + return time % duration; + } + return time; + } +} diff --git a/engine/src/core/com/jme3/cinematic/events/AbstractCinematicEvent.java b/engine/src/core/com/jme3/cinematic/events/AbstractCinematicEvent.java index 8acd12708..69206eecf 100644 --- a/engine/src/core/com/jme3/cinematic/events/AbstractCinematicEvent.java +++ b/engine/src/core/com/jme3/cinematic/events/AbstractCinematicEvent.java @@ -31,6 +31,7 @@ */ package com.jme3.cinematic.events; +import com.jme3.animation.AnimationUtils; import com.jme3.animation.LoopMode; import com.jme3.app.Application; import com.jme3.cinematic.Cinematic; @@ -138,6 +139,12 @@ public abstract class AbstractCinematicEvent implements CinematicEvent { stop(); } else if(time >= initialDuration && loopMode == LoopMode.Loop){ setTime(0); + }else{ + time = AnimationUtils.clampWrapTime(time, initialDuration, loopMode); + if(time<0){ + speed = - speed; + time = - time; + } } } diff --git a/engine/src/core/com/jme3/cinematic/events/MotionEvent.java b/engine/src/core/com/jme3/cinematic/events/MotionEvent.java index edd4990f5..ff6ca5feb 100644 --- a/engine/src/core/com/jme3/cinematic/events/MotionEvent.java +++ b/engine/src/core/com/jme3/cinematic/events/MotionEvent.java @@ -31,6 +31,7 @@ */ package com.jme3.cinematic.events; +import com.jme3.animation.AnimationUtils; import com.jme3.animation.LoopMode; import com.jme3.app.Application; import com.jme3.cinematic.Cinematic; @@ -67,6 +68,7 @@ public class MotionEvent extends AbstractCinematicEvent implements Control { protected Direction directionType = Direction.None; protected MotionPath path; private boolean isControl = true; + private int travelDirection = 1; /** * the distance traveled by the spatial on the path */ @@ -171,13 +173,18 @@ public class MotionEvent extends AbstractCinematicEvent implements Control { time = time + (tpf * speed); if (loopMode == loopMode.Loop && time < 0) { time = initialDuration; - } + } if ((time >= initialDuration || time < 0) && loopMode == loopMode.DontLoop) { if (time >= initialDuration) { path.triggerWayPointReach(path.getNbWayPoints() - 1, this); } stop(); } else { + time = AnimationUtils.clampWrapTime(time, initialDuration, loopMode); + if(time<0){ + speed = - speed; + time = - time; + } onUpdate(tpf); } }