topical media & game development

talk show tell print

student-ar-org-ascollada-core-DaeAnimationCurve.ax

student-ar-org-ascollada-core-DaeAnimationCurve.ax [swf] flex


  /*
   * Copyright 2007 (c) Tim Knip, ascollada.org.
   *
   * Permission is hereby granted, free of charge, to any person
   * obtaining a copy of this software and associated documentation
   * files (the "Software"), to deal in the Software without
   * restriction, including without limitation the rights to use,
   * copy, modify, merge, publish, distribute, sublicense, and/or sell
   * copies of the Software, and to permit persons to whom the
   * Software is furnished to do so, subject to the following
   * conditions:
   *
   * The above copyright notice and this permission notice shall be
   * included in all copies or substantial portions of the Software.
   *
   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
   * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
   * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
   * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
   * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
   * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
   * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
   * OTHER DEALINGS IN THE SOFTWARE.
   */
   
  package org.ascollada.core
  {
          import org.ascollada.core.DaeEntity;
          
          

  
          public class @ax-student-ar-org-ascollada-core-DaeAnimationCurve extends DaeEntity
          {
                  public static const INTERPOLATION_STEP:uint = 0; //equivalent to no interpolation
                  public static const INTERPOLATION_LINEAR:uint = 1;
                  public static const INTERPOLATION_BEZIER:uint = 2;
                  public static const INTERPOLATION_TCB:uint = 3;
                  public static const INTERPOLATION_UNKNOWN:uint = 4;
                  public static const INTERPOLATION_DEFAULT:uint = 0;
                  
                  public static const INFINITY_CONSTANT:uint = 0;
                  public static const INFINITY_LINEAR:uint = 1;
                  public static const INFINITY_CYCLE:uint = 2;
                  public static const INFINITY_CYCLE_RELATIVE:uint = 3;
                  public static const INFINITY_OSCILLATE:uint = 4;
                  public static const INFINITY_UNKNOWN:uint = 5;
                  public static const INFINITY_DEFAULT:uint = 0;
                  
                  public var keys:Array;
                  public var keyValues:Array;
                  
                  public var interpolations:Array;
                  
                  public var inTangents:Array;
                  
                  public var outTangents:Array;
                  
                  public var tcbParameters:Array;
                  
                  public var easeInOuts:Array;
                  
                  public var preInfinity:uint = 0;
                  
                  public var postInfinity:uint = 0;
                  
                  public var interpolationType:uint = 1;
                  
                  
@param keys @param keyValues

  
                  public function @ax-student-ar-org-ascollada-core-DaeAnimationCurve( keys:Array = null, keyValues:Array = null ):void
                  {                        
                          this.keys = keys || new Array();
                          this.keyValues = keyValues || new Array();
                          this.interpolations = new Array();
                  }
                  
                  
main workhorse for the animation system. @param time @return

  
                  public function evaluate( dt:Number ):Number
                  {
                          // Check for empty curves and poses (curves with 1 key).
                          if( !this.keys.length ) return 0.0;
                          if( this.keys.length == 1 ) return this.keyValues[0];
                          
                          var i:int;
                          var outputStart:Number = this.keyValues[0];
                          var outputEnd:Number = this.keyValues[this.keyValues.length-1];
                          var inputStart:Number = this.keys[0];
                          var inputEnd:Number = this.keys[this.keys.length-1];
                          var inputSpan:Number = inputEnd - inputStart;
                          var cycleCount:Number;
                          
                          dt = dt % inputEnd;
                                                  
                          // Account for pre-infinity mode
                          var outputOffset:Number = 0.0;
                          
                          if( dt <= inputStart )
                          {
                                  switch( preInfinity )
                                  {
                                          case INFINITY_CONSTANT: return outputStart;
                                          case INFINITY_LINEAR: return outputStart + (dt - inputStart) * (keyValues[1] - outputStart) / (keys[1] - inputStart);
                                          case INFINITY_CYCLE: { cycleCount = Math.ceil((inputStart - dt) / inputSpan); dt += cycleCount * inputSpan; break; }
                                          case INFINITY_CYCLE_RELATIVE: { cycleCount = Math.ceil((inputStart - dt) / inputSpan); dt += cycleCount * inputSpan; outputOffset -= cycleCount * (outputEnd - outputStart); break; }
                                          case INFINITY_OSCILLATE: { cycleCount = Math.ceil((inputStart - dt) / (2.0 * inputSpan)); dt += cycleCount * 2.0 * inputSpan; dt = inputEnd - Math.abs(dt - inputEnd); break; }
                                          case INFINITY_UNKNOWN: default: return outputStart;
                                  }
                          }
                          else if (dt >= inputEnd)
                          {
                                  // Account for post-infinity mode
                                  switch (postInfinity)
                                  {
                                          case INFINITY_CONSTANT: return outputEnd;
                                          case INFINITY_LINEAR: return outputEnd + (dt - inputEnd) * (keyValues[keys.length - 2] - outputEnd) / (keys[keys.length - 2] - inputEnd);
                                          case INFINITY_CYCLE: { cycleCount = Math.ceil((dt - inputEnd) / inputSpan); dt -= cycleCount * inputSpan; break; }
                                          case INFINITY_CYCLE_RELATIVE: { cycleCount = Math.ceil((dt - inputEnd) / inputSpan); dt -= cycleCount * inputSpan; outputOffset += cycleCount * (outputEnd - outputStart); break; }
                                          case INFINITY_OSCILLATE: { cycleCount = Math.ceil((dt - inputEnd) / (2.0 * inputSpan)); dt -= cycleCount * 2.0 * inputSpan; dt = inputStart + Math.abs(dt - inputStart); break; }
                                          case INFINITY_UNKNOWN: default: return outputEnd;
                                  }
                          }
                          
                          // speed up interval search
                          var approxi:int = Math.ceil((dt/inputEnd) * this.keys.length);
                          
                          // Find the current interval
                          for( i = approxi; i < this.keys.length; ++i )
                                  if( this.keys[i] > dt ) break;
                          var index:int = i;
                          
                          // Get the keys and values for this interval
                          var endKey:Number = this.keys[index];
                          var startKey:Number = this.keys[index - 1];
                          var endValue:Number = this.keyValues[index];
                          var startValue:Number = this.keyValues[index - 1];
                          var output:Number;
                          
                          switch( interpolationType )
                          {
                                  case INTERPOLATION_LINEAR:
                                          output = (dt - startKey) / (endKey - startKey) * (endValue - startValue) + startValue;
                                          break;
                                          
                                  case INTERPOLATION_STEP:
                                  default:
                                          output = startValue;
                                          break;
                          }
  
                          return outputOffset + output;
                  }
          }
  }


(C) Æliens 27/08/2009

You may not copy or print any of this material without explicit permission of the author or the publisher. In case of other copyright issues, contact the author.