/* * This file is part of Matter Overdrive * Copyright (c) 2015., Simeon Radivoev, All rights reserved. * * Matter Overdrive is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Matter Overdrive is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with Matter Overdrive. If not, see <http://www.gnu.org/licenses>. */ package matteroverdrive.util.animation; import matteroverdrive.util.math.MOMathHelper; import net.minecraft.util.MathHelper; import java.util.ArrayList; import java.util.List; /** * Created by Simeon on 11/20/2015. */ public class MOAnimationTimeline { boolean autoLength; boolean isPlaying; List<Slice> slices = new ArrayList<>(); private float maxTime; private boolean repeat; private float time; private float defaultValue; public MOAnimationTimeline(float maxTime, boolean repeat,boolean autoPlay,float defaultValue) { this.maxTime = maxTime; this.repeat = repeat; isPlaying = autoPlay; this.defaultValue = defaultValue; } public void addSlice(Slice slice) { slices.add(slice); } public void getActiveSlices(int time,List<Slice> list) { for (Slice slice : this.slices) { if (time <= slice.from + slice.length && time >= slice.from) { list.add(slice); } } } public List<Slice> getActiveSlices(int time) { List<Slice> slices = new ArrayList<>(); getActiveSlices(time,slices); return slices; } public float getValueAt(float time) { float value = defaultValue; for (Slice slice : this.slices) { if (time <= slice.from + slice.length && time >= slice.from) { float localTime = slice.getLocalTime(time); value = slice.valueFrom + localTime*(slice.valueTo-slice.valueFrom); } } return value; } public void recalculateTime() { if (autoLength) { float maxTime = 0; for (Slice slice : slices) { if (slice.from + slice.length > time) { maxTime = slice.from + slice.length; } } this.maxTime = maxTime; } } public float getCurrentValue() { return getValueAt(time); } public void play() { recalculateTime(); isPlaying = true; if (time >= maxTime) { time = 0; } } public void replay() { time = 0; play(); } public void stop() { recalculateTime(); isPlaying = false; time = 0; } public void pause() { isPlaying = false; } public void tick() { tick(1); } public void tick(float tick) { if (isPlaying) { if (time < maxTime) { time = MathHelper.clamp_float(time+tick,0,maxTime); } else if (repeat) { time = 0; }else { pause(); } } } public void sort() { float lastFinish = 0; for (Slice slice : slices) { slice.from = lastFinish; lastFinish += slice.length; } } public void setTime(float time) { this.time = time; } public boolean isPlaying() { return isPlaying; } public void setAutoLength(boolean autoLength){this.autoLength = true;} public boolean isAutoLength(){return this.autoLength;} public float getTime() { return time; } public float getMaxTime(){return maxTime;} public Slice getSlice(int index) { return slices.get(index); } public static class Slice { private float valueFrom,valueTo; private float from,length; public Easing getEasing() { return easing; } public void setEasing(Easing easing) { this.easing = easing; } public float getValueFrom() { return valueFrom; } public void setValueFrom(float valueFrom) { this.valueFrom = valueFrom; } public float getValueTo() { return valueTo; } public void setValueTo(float valueTo) { this.valueTo = valueTo; } public float getFrom() { return from; } public void setFrom(float from) { this.from = from; } public float getLength() { return length; } public void setLength(float length) { this.length = length; } private Easing easing; public Slice(float valueFrom,float valueTo,float from,float length,Easing easing) { this.valueFrom = valueFrom; this.valueTo = valueTo; this.from = from; this.length = length; this.easing = easing; } public float getLocalTime(float time) { if(easing != null) { return MathHelper.clamp_float(easing.calculate(time - from, 0, 1, length), 0, 1); }else { return MOMathHelper.Lerp(0,1,(time - from)/length); } } } public abstract static class Easing { public abstract float calculate(float t,float b , float c, float d); public static class QuadEaseIn extends Easing { @Override public float calculate(float t,float b , float c, float d) { return c*(t/=d)*t + b; } } public static class QuadEaseOut extends Easing { @Override public float calculate(float t,float b , float c, float d) { return -c *(t/=d)*(t-2) + b; } } public static class QuadEaseInOut extends Easing { @Override public float calculate(float t,float b , float c, float d) { if ((t/=d/2) < 1) return c/2*t*t + b; return -c/2 * ((--t)*(t-2) - 1) + b; } } } }