Moving backward with SpatialTransformer

Has anyone been able to successfully play a SpatialTransformer backwards? I tried playing around with the HelloAnimation test class and I add this line to the end of the simpleInitGame():


        // Let the controller play in reverse
        st.setNewAnimationTimes(st.getMaxTime(), st.getMinTime());


The result is that the animation appears directly at the final location without animating its way there. Is there something wrong with reverse animations on the SpatialTransformer, or have I used the API incorrectly?

Maybe this will help:



http://www.jmonkeyengine.com/jmeforum/index.php?topic=6873.0

duenez said:

Maybe this will help:

http://www.jmonkeyengine.com/jmeforum/index.php?topic=6873.0


Nope, that didn't help. I believe that thread is discussing a different type of controller. I really don't think I should need to invert the keyframe list in the SpatialTransformer to get it to move backwards, especially since the javadoc for setNewAnimationTimes(float,float) reads:

"Sets the new animation boundaries for this controller. This will start at newBeginTime and proceed in the direction of newEndTime (either forwards or backwards)..."

Maybe you need to set negative speed? i.e setSpeed(-5.0f)

Momoko_Fan said:

Maybe you need to set negative speed? i.e setSpeed(-5.0f)


Yes, this will work but only if I don't use setNewAnimationTimes(). Also, its functionality is limited because I need to let the animation play forward once, and then invert the speed and let it play again to get it in reverse:


st.setActive(true);
.
. // animation playing forward
.
st.setSpeed(-st.getSpeed());
st.setActive(true);
.
. // animation playing in reverse
.



So I guess this technique can be used, but only if I play the sequence forward at least one time. If, for example, I wanted to start with the reverse animation, it would not be possible.

Looking at the setNewAnimationTimes() method there was clearly an intention for backward motion:


    /**
     * Sets the new animation boundaries for this controller. This will start at
     * newBeginTime and proceed in the direction of newEndTime (either forwards
     * or backwards). If both are the same, then the animation is set to their
     * time and turned off, otherwise the animation is turned on to start the
     * animation acording to the repeat type. If either BeginTime or EndTime are
     * invalid times (less than 0 or greater than the maximum set keyframe time)
     * then a warning is set and nothing happens. <br>
     * It is suggested that this function be called if new animation boundaries
     * need to be set, instead of setMinTime and setMaxTime directly.
     *
     * @param newBeginTime
     *            The starting time
     * @param newEndTime
     *            The ending time
     */
    public void setNewAnimationTimes(float newBeginTime, float newEndTime) {
        if (newBeginTime < 0
                || newBeginTime > keyframes
                        .get(keyframes.size() - 1).time) {
            logger.warning("Attempt to set invalid begintime:" + newBeginTime);
            return;
        }
        if (newEndTime < 0
                || newEndTime > keyframes
                        .get(keyframes.size() - 1).time) {
            logger.warning("Attempt to set invalid endtime:" + newEndTime);
            return;
        }
        setMinTime(newBeginTime);
        setMaxTime(newEndTime);
        setActive(true);
        if (newBeginTime <= newEndTime) { // Moving forward
            curTime = newBeginTime;
            if (newBeginTime == newEndTime) {
                update(0);
                setActive(false);
            }
        } else { // Moving backwards
            curTime = newEndTime;
        }
    }



The last else block has a comment saying "moving backwards". So I assumed I must have been using this API incorrectly since it was not working. I guess this may be an actual bug.