/* * Moonlight|3D * Copyright (C) 2006 The Moonlight|3D team * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * Created on May 2, 2006 */ package ml.backend.anim; import java.util.ArrayList; import ml.backend.anim.KeyframeAnimationTrack.KeyValuePair; import ml.core.exceptions.Exception; import ml.core.helper.Value; import ml.core.helper.Value.Type; import ml.math.Vector3D; public class LinearValueInterpolator implements KeyframeInterpolator { public boolean isAppliciable(Type valueType) { if(valueType==Type.Boolean || valueType==Type.Integer || valueType==Type.Float || valueType==Type.Vector3D) { return true; } return false; } private boolean interpolateBoolean(boolean start, boolean end, double fraction) { if(fraction<0.5) { return start; } return end; } private int interpolateInteger(int start, int end, double fraction) { return (int)(start+(end-start)*fraction); } private double interpolateFloat(double start, double end, double fraction) { return start+(end-start)*fraction; } private Vector3D interpolateVector3D(Vector3D start, Vector3D end, double fraction) { Vector3D result=new Vector3D(); result.X1=start.X1+(end.X1-start.X1)*fraction; result.X2=start.X2+(end.X2-start.X2)*fraction; result.X3=start.X3+(end.X3-start.X3)*fraction; return result; } private Value interpolateValue(Value start, Value end, double fraction) { Value result=new Value(); result.setType(start.getType()); if(start.getType()==Type.Boolean) { try { result.setValue(interpolateBoolean(start.getBooleanValue(),end.getBooleanValue(),fraction)); } catch (Exception e) { // this exception cannot happen here - this is typesafe e.printStackTrace(); } } else if(start.getType()==Type.Integer) { try { result.setValue(interpolateInteger(start.getIntegerValue(),end.getIntegerValue(),fraction)); } catch (Exception e) { // this exception cannot happen here - this is typesafe e.printStackTrace(); } } else if(start.getType()==Type.Float) { try { result.setValue(interpolateFloat(start.getFloatValue(),end.getFloatValue(),fraction)); } catch (Exception e) { // this exception cannot happen here - this is typesafe e.printStackTrace(); } } else if(start.getType()==Type.Vector3D) { try { result.setValue(interpolateVector3D(start.getVectorValue(),end.getVectorValue(),fraction)); } catch (Exception e) { // this exception cannot happen here - this is typesafe e.printStackTrace(); } } return result; } public Value interpolate(KeyframeAnimationTrack track, double time) { ArrayList keys=track.getKeyList(); if(keys.size()==0) { return track.getDefaultValue(); } else if(keys.size()==1) { return keys.get(0).value; } if(keys.get(0).time>time) { double fraction=(time-keys.get(0).time)/(keys.get(1).time-keys.get(0).time); return interpolateValue(keys.get(0).value,keys.get(1).value,fraction); } if(time>keys.get(keys.size()-2).time) { double fraction=(time-keys.get(keys.size()-2).time)/(keys.get(keys.size()-1).time-keys.get(keys.size()-2).time); return interpolateValue(keys.get(keys.size()-2).value,keys.get(keys.size()-1).value,fraction); } for(int i=0;ikeys.get(i).time) { double fraction=(time-keys.get(i).time)/(keys.get(i+1).time-keys.get(i).time); return interpolateValue(keys.get(i).value,keys.get(i+1).value,fraction); } } return null; // this line should never be reached } public String getType() { return "LinearInterpolator"; } }