package creatures.parts { public class SegmentAnimation { private var _currentFrame:int = 0; private var _totalFrames:int; private var rotationKeyframes:Array = new Array(); public function SegmentAnimation(totalFrames:int = 100, keyframes:Array = null) { _totalFrames = totalFrames; rotationKeyframes = keyframes; } public function step():void { _currentFrame++; _currentFrame %= _totalFrames; } public function applyTo(segment:Segment, frameOffset:int = 0):void { var currFrame:int = (_currentFrame + frameOffset) % _totalFrames; var rotKeyFrames:int = rotationKeyframes.length; var progress:Number = currFrame/_totalFrames; var currKeyFrame:int = Math.floor(rotKeyFrames*progress); var nextKeyFrame:int = (currKeyFrame + 1) % rotKeyFrames; var tweenProgress:Number = rotKeyFrames*(progress % (1/rotKeyFrames)); var levels:int = rotationKeyframes[nextKeyFrame].length; var children:Array; var segmentIndex:int = 0; do { segment.rotation = (rotKeyFrames > 1) ? rotationTween(currKeyFrame, nextKeyFrame, segmentIndex, tweenProgress) : rotationKeyframes[currKeyFrame][segmentIndex]; children = segment.children; segment = children.length ? children[0] : null; segmentIndex++; } while (segment && levels > segmentIndex); } public function rotationTween(currKeyFrame:int, nextKeyFrame:int, segmentIndex:int, progress:Number):Number { var diff:Number = rotationKeyframes[nextKeyFrame][segmentIndex] - rotationKeyframes[currKeyFrame][segmentIndex]; if (diff < -Math.PI) { diff += Math.PI*2; }else if (diff > Math.PI) { diff -= Math.PI*2; } return rotationKeyframes[currKeyFrame][segmentIndex] + diff*progress; } } }