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
experimental
rem..om 11 years ago
parent 87b84949ab
commit 743e5d1963
  1. 62
      engine/src/core/com/jme3/animation/AnimChannel.java
  2. 67
      engine/src/core/com/jme3/animation/AnimationUtils.java
  3. 7
      engine/src/core/com/jme3/cinematic/events/AbstractCinematicEvent.java
  4. 7
      engine/src/core/com/jme3/cinematic/events/MotionEvent.java

@ -68,64 +68,6 @@ public final class AnimChannel {
private float blendAmount = 1f; private float blendAmount = 1f;
private float blendRate = 0; 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){ AnimChannel(AnimControl control){
this.control = control; this.control = control;
} }
@ -385,7 +327,7 @@ public final class AnimChannel {
blendFrom.setTime(timeBlendFrom, 1f - blendAmount, control, this, vars); blendFrom.setTime(timeBlendFrom, 1f - blendAmount, control, this, vars);
timeBlendFrom += tpf * speedBlendFrom; timeBlendFrom += tpf * speedBlendFrom;
timeBlendFrom = clampWrapTime(timeBlendFrom, timeBlendFrom = AnimationUtils.clampWrapTime(timeBlendFrom,
blendFrom.getLength(), blendFrom.getLength(),
loopModeBlendFrom); loopModeBlendFrom);
if (timeBlendFrom < 0){ if (timeBlendFrom < 0){
@ -414,7 +356,7 @@ public final class AnimChannel {
} }
} }
time += tpf * speed; time += tpf * speed;
time = clampWrapTime(time, animation.getLength(), loopMode); time = AnimationUtils.clampWrapTime(time, animation.getLength(), loopMode);
if (time < 0){ if (time < 0){
// Negative time indicates that speed should be inverted // Negative time indicates that speed should be inverted
// (for cycle loop mode only) // (for cycle loop mode only)

@ -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;
}
}

@ -31,6 +31,7 @@
*/ */
package com.jme3.cinematic.events; package com.jme3.cinematic.events;
import com.jme3.animation.AnimationUtils;
import com.jme3.animation.LoopMode; import com.jme3.animation.LoopMode;
import com.jme3.app.Application; import com.jme3.app.Application;
import com.jme3.cinematic.Cinematic; import com.jme3.cinematic.Cinematic;
@ -138,6 +139,12 @@ public abstract class AbstractCinematicEvent implements CinematicEvent {
stop(); stop();
} else if(time >= initialDuration && loopMode == LoopMode.Loop){ } else if(time >= initialDuration && loopMode == LoopMode.Loop){
setTime(0); setTime(0);
}else{
time = AnimationUtils.clampWrapTime(time, initialDuration, loopMode);
if(time<0){
speed = - speed;
time = - time;
}
} }
} }

@ -31,6 +31,7 @@
*/ */
package com.jme3.cinematic.events; package com.jme3.cinematic.events;
import com.jme3.animation.AnimationUtils;
import com.jme3.animation.LoopMode; import com.jme3.animation.LoopMode;
import com.jme3.app.Application; import com.jme3.app.Application;
import com.jme3.cinematic.Cinematic; import com.jme3.cinematic.Cinematic;
@ -67,6 +68,7 @@ public class MotionEvent extends AbstractCinematicEvent implements Control {
protected Direction directionType = Direction.None; protected Direction directionType = Direction.None;
protected MotionPath path; protected MotionPath path;
private boolean isControl = true; private boolean isControl = true;
private int travelDirection = 1;
/** /**
* the distance traveled by the spatial on the path * the distance traveled by the spatial on the path
*/ */
@ -178,6 +180,11 @@ public class MotionEvent extends AbstractCinematicEvent implements Control {
} }
stop(); stop();
} else { } else {
time = AnimationUtils.clampWrapTime(time, initialDuration, loopMode);
if(time<0){
speed = - speed;
time = - time;
}
onUpdate(tpf); onUpdate(tpf);
} }
} }

Loading…
Cancel
Save