159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta/*
259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * Copyright (c) 2009-2010 jMonkeyEngine
359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * All rights reserved.
459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *
559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * Redistribution and use in source and binary forms, with or without
659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * modification, are permitted provided that the following conditions are
759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * met:
859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *
959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * * Redistributions of source code must retain the above copyright
1059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *   notice, this list of conditions and the following disclaimer.
1159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *
1259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * * Redistributions in binary form must reproduce the above copyright
1359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *   notice, this list of conditions and the following disclaimer in the
1459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *   documentation and/or other materials provided with the distribution.
1559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *
1659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * * Neither the name of 'jMonkeyEngine' nor the names of its contributors
1759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *   may be used to endorse or promote products derived from this software
1859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *   without specific prior written permission.
1959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *
2059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
2259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
2359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
2459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
2559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
2659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
2759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
2859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
2959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
3059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */
3259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
3359b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartapackage com.jme3.animation;
3459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
3559b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.math.FastMath;
3659b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport com.jme3.util.TempVars;
3759b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartaimport java.util.BitSet;
3859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
3959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta/**
4059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * <code>AnimChannel</code> provides controls, such as play, pause,
4159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * fast forward, etc, for an animation. The animation
4259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * channel may influence the entire model or specific bones of the model's
4359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * skeleton. A single model may have multiple animation channels influencing
4459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * various parts of its body. For example, a character model may have an
4559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * animation channel for its feet, and another for its torso, and
4659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * the animations for each channel are controlled independently.
4759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta *
4859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta * @author Kirill Vainer
4959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta */
5059b2e6871c65f58fdad78cd7229c292f6a177578Scott Bartapublic final class AnimChannel {
5159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
5259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private static final float DEFAULT_BLEND_TIME = 0.15f;
5359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
5459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private AnimControl control;
5559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
5659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private BitSet affectedBones;
5759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
5859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private Animation animation;
5959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private Animation blendFrom;
6059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private float time;
6159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private float speed;
6259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private float timeBlendFrom;
6359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private float speedBlendFrom;
6459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
6559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private LoopMode loopMode, loopModeBlendFrom;
6659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
6759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private float blendAmount = 1f;
6859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private float blendRate   = 0;
6959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
7059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    private static float clampWrapTime(float t, float max, LoopMode loopMode){
7159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (max == Float.POSITIVE_INFINITY)
7259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return t;
7359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
7459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (t < 0f){
7559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            //float tMod = -(-t % max);
7659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            switch (loopMode){
7759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                case DontLoop:
7859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    return 0;
7959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                case Cycle:
8059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    return t;
8159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                case Loop:
8259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    return max - t;
8359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
8459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }else if (t > max){
8559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            switch (loopMode){
8659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                case DontLoop:
8759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    return max;
8859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                case Cycle:
8959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    return /*-max;*/-(2f * max - t);
9059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                case Loop:
9159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                    return t - max;
9259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
9359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
9459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
9559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return t;
9659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
9759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
9859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    AnimChannel(AnimControl control){
9959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.control = control;
10059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
10159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
10259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
10359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Returns the parent control of this AnimChannel.
10459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
10559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return the parent control of this AnimChannel.
10659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @see AnimControl
10759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
10859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public AnimControl getControl() {
10959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return control;
11059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
11159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
11259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
11359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return The name of the currently playing animation, or null if
11459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * none is assigned.
11559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
11659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @see AnimChannel#setAnim(java.lang.String)
11759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
11859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public String getAnimationName() {
11959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return animation != null ? animation.getName() : null;
12059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
12159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
12259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
12359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return The loop mode currently set for the animation. The loop mode
12459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * determines what will happen to the animation once it finishes
12559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * playing.
12659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
12759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * For more information, see the LoopMode enum class.
12859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @see LoopMode
12959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @see AnimChannel#setLoopMode(com.jme3.animation.LoopMode)
13059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
13159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public LoopMode getLoopMode() {
13259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return loopMode;
13359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
13459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
13559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
13659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param loopMode Set the loop mode for the channel. The loop mode
13759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * determines what will happen to the animation once it finishes
13859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * playing.
13959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
14059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * For more information, see the LoopMode enum class.
14159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @see LoopMode
14259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
14359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void setLoopMode(LoopMode loopMode) {
14459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.loopMode = loopMode;
14559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
14659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
14759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
14859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return The speed that is assigned to the animation channel. The speed
14959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * is a scale value starting from 0.0, at 1.0 the animation will play
15059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * at its default speed.
15159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
15259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @see AnimChannel#setSpeed(float)
15359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
15459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public float getSpeed() {
15559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return speed;
15659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
15759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
15859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
15959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param speed Set the speed of the animation channel. The speed
16059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * is a scale value starting from 0.0, at 1.0 the animation will play
16159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * at its default speed.
16259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
16359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void setSpeed(float speed) {
16459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.speed = speed;
16559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
16659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
16759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
16859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return The time of the currently playing animation. The time
16959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * starts at 0 and continues on until getAnimMaxTime().
17059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
17159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @see AnimChannel#setTime(float)
17259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
17359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public float getTime() {
17459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return time;
17559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
17659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
17759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
17859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param time Set the time of the currently playing animation, the time
17959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * is clamped from 0 to {@link #getAnimMaxTime()}.
18059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
18159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void setTime(float time) {
18259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        this.time = FastMath.clamp(time, 0, getAnimMaxTime());
18359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
18459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
18559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
18659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @return The length of the currently playing animation, or zero
18759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * if no animation is playing.
18859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
18959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @see AnimChannel#getTime()
19059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
19159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public float getAnimMaxTime(){
19259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return animation != null ? animation.getLength() : 0f;
19359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
19459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
19559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
19659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Set the current animation that is played by this AnimChannel.
19759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * <p>
19859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * This resets the time to zero, and optionally blends the animation
19959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * over <code>blendTime</code> seconds with the currently playing animation.
20059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Notice that this method will reset the control's speed to 1.0.
20159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
20259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param name The name of the animation to play
20359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param blendTime The blend time over which to blend the new animation
20459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * with the old one. If zero, then no blending will occur and the new
20559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * animation will be applied instantly.
20659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
20759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void setAnim(String name, float blendTime){
20859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (name == null)
20959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            throw new NullPointerException();
21059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
21159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (blendTime < 0f)
21259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            throw new IllegalArgumentException("blendTime cannot be less than zero");
21359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
21459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        Animation anim = control.animationMap.get(name);
21559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (anim == null)
21659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            throw new IllegalArgumentException("Cannot find animation named: '"+name+"'");
21759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
21859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        control.notifyAnimChange(this, name);
21959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
22059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (animation != null && blendTime > 0f){
22159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            // activate blending
22259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            blendFrom = animation;
22359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            timeBlendFrom = time;
22459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            speedBlendFrom = speed;
22559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            loopModeBlendFrom = loopMode;
22659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            blendAmount = 0f;
22759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            blendRate   = 1f / blendTime;
22859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
22959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
23059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        animation = anim;
23159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        time = 0;
23259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        speed = 1f;
23359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        loopMode = LoopMode.Loop;
23459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
23559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
23659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
23759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Set the current animation that is played by this AnimChannel.
23859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * <p>
23959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * See {@link #setAnim(java.lang.String, float)}.
24059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * The blendTime argument by default is 150 milliseconds.
24159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     *
24259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * @param name The name of the animation to play
24359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
24459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void setAnim(String name){
24559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        setAnim(name, DEFAULT_BLEND_TIME);
24659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
24759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
24859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
24959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Add all the bones of the model's skeleton to be
25059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * influenced by this animation channel.
25159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
25259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void addAllBones() {
25359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        affectedBones = null;
25459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
25559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
25659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
25759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Add a single bone to be influenced by this animation channel.
25859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
25959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void addBone(String name) {
26059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        addBone(control.getSkeleton().getBone(name));
26159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
26259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
26359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
26459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Add a single bone to be influenced by this animation channel.
26559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
26659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void addBone(Bone bone) {
26759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        int boneIndex = control.getSkeleton().getBoneIndex(bone);
26859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if(affectedBones == null) {
26959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            affectedBones = new BitSet(control.getSkeleton().getBoneCount());
27059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
27159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        affectedBones.set(boneIndex);
27259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
27359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
27459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
27559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Add bones to be influenced by this animation channel starting from the
27659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * given bone name and going toward the root bone.
27759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
27859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void addToRootBone(String name) {
27959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        addToRootBone(control.getSkeleton().getBone(name));
28059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
28159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
28259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
28359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Add bones to be influenced by this animation channel starting from the
28459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * given bone and going toward the root bone.
28559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
28659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void addToRootBone(Bone bone) {
28759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        addBone(bone);
28859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        while (bone.getParent() != null) {
28959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            bone = bone.getParent();
29059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            addBone(bone);
29159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
29259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
29359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
29459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
29559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Add bones to be influenced by this animation channel, starting
29659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * from the given named bone and going toward its children.
29759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
29859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void addFromRootBone(String name) {
29959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        addFromRootBone(control.getSkeleton().getBone(name));
30059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
30159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
30259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    /**
30359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * Add bones to be influenced by this animation channel, starting
30459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     * from the given bone and going toward its children.
30559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta     */
30659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    public void addFromRootBone(Bone bone) {
30759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        addBone(bone);
30859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (bone.getChildren() == null)
30959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return;
31059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        for (Bone childBone : bone.getChildren()) {
31159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            addBone(childBone);
31259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            addFromRootBone(childBone);
31359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
31459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
31559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
31659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    BitSet getAffectedBones(){
31759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        return affectedBones;
31859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
31959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
32059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    void update(float tpf, TempVars vars) {
32159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (animation == null)
32259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            return;
32359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
32459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (blendFrom != null){
32559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            blendFrom.setTime(timeBlendFrom, 1f - blendAmount, control, this, vars);
32659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            //blendFrom.setTime(timeBlendFrom, control.skeleton, 1f - blendAmount, affectedBones);
32759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            timeBlendFrom += tpf * speedBlendFrom;
32859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            timeBlendFrom = clampWrapTime(timeBlendFrom,
32959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                                          blendFrom.getLength(),
33059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                                          loopModeBlendFrom);
33159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (timeBlendFrom < 0){
33259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                timeBlendFrom = -timeBlendFrom;
33359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                speedBlendFrom = -speedBlendFrom;
33459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
33559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
33659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            blendAmount += tpf * blendRate;
33759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (blendAmount > 1f){
33859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                blendAmount = 1f;
33959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                blendFrom = null;
34059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
34159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
34259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
34359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        animation.setTime(time, blendAmount, control, this, vars);
34459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        //animation.setTime(time, control.skeleton, blendAmount, affectedBones);
34559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        time += tpf * speed;
34659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
34759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (animation.getLength() > 0){
34859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            if (time >= animation.getLength()) {
34959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                control.notifyAnimCycleDone(this, animation.getName());
35059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            } else if (time < 0) {
35159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta                control.notifyAnimCycleDone(this, animation.getName());
35259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            }
35359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
35459b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
35559b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        time = clampWrapTime(time, animation.getLength(), loopMode);
35659b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        if (time < 0){
35759b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            time = -time;
35859b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta            speed = -speed;
35959b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta        }
36059b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
36159b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta
36259b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta    }
36359b2e6871c65f58fdad78cd7229c292f6a177578Scott Barta}
364