PageRenderTime 114ms CodeModel.GetById 99ms app.highlight 12ms RepoModel.GetById 1ms app.codeStats 0ms

/src/away3d/animators/skeleton/SkeletonRangeClipNode.as

http://github.com/away3d/away3d-core-fp11
ActionScript | 162 lines | 117 code | 20 blank | 25 comment | 24 complexity | ae30ea7277e7c3e9a2355a17a7c7a13e MD5 | raw file
  1/**
  2 * Author: David Lenaerts
  3 */
  4package away3d.animators.skeleton
  5{
  6	import away3d.arcane;
  7
  8	import flash.geom.Vector3D;
  9
 10	use namespace arcane;
 11
 12	/**
 13	 * SkeletonRangeClipNode represents a node in a skeleton tree containing a blending clip in which the keyframes
 14	 * represent poses along a range of values
 15	 */
 16	public class SkeletonRangeClipNode extends SkeletonClipNodeBase
 17	{
 18		/**
 19		 * The animation clip.
 20		 */
 21		private var _frame1 : int;
 22		private var _frame2 : int;
 23		private var _blendWeight : Number = .5;
 24		private var _framesInvalid : Boolean;
 25		private var _phase : Number;
 26
 27		/**
 28		 * Creates a new SkeletonPhaseClipNode object.
 29		 * @param numJoints The amount of joints in the target skeleton.
 30		 */
 31		public function SkeletonRangeClipNode()
 32		{
 33			super();
 34			_rootPos = new Vector3D();
 35		}
 36
 37		/**
 38		 * The normalized ratio of the state within the range. For example, for a clip that defines left, center and
 39		 * right aiming poses, 0 would be entirely left, 1 entirely right, and .5 the center.
 40		 */
 41		public function get phase() : Number
 42		{
 43			return _phase;
 44		}
 45
 46		public function set phase(value : Number) : void
 47		{
 48			if (_phase == value) return;
 49			_framesInvalid = true;
 50			_phase = value;
 51		}
 52
 53		/**
 54		 * @inheritDoc
 55		 */
 56		override public function updatePose(skeleton : Skeleton) : void
 57		{
 58			if (_clip.duration == 0) return;
 59			if (_framesInvalid) updateFrames(_phase);
 60
 61			var poses1 : Vector.<JointPose> = clip._frames[_frame1].jointPoses;
 62			var poses2 : Vector.<JointPose> = clip._frames[_frame2].jointPoses;
 63			var numJoints : uint = poses1.length;
 64			var p1 : Vector3D, p2 : Vector3D;
 65			var pose1 : JointPose, pose2 : JointPose;
 66			var endPoses : Vector.<JointPose> = skeletonPose.jointPoses;
 67			var endPose : JointPose;
 68			var tr : Vector3D;
 69
 70			// :s
 71			if (endPoses.length != numJoints) endPoses.length = numJoints;
 72
 73			for (var i : uint = 0; i < numJoints; ++i) {
 74				endPose = endPoses[i] ||= new JointPose();
 75				pose1 = poses1[i];
 76				pose2 = poses2[i];
 77				p1 = pose1.translation; p2 = pose2.translation;
 78
 79				if (_highQuality)
 80					endPose.orientation.slerp(pose1.orientation, pose2.orientation, _blendWeight);
 81				else
 82					endPose.orientation.lerp(pose1.orientation, pose2.orientation, _blendWeight);
 83
 84				if (i > 0) {
 85					tr = endPose.translation;
 86					tr.x = p1.x + _blendWeight*(p2.x - p1.x);
 87					tr.y = p1.y + _blendWeight*(p2.y - p1.y);
 88					tr.z = p1.z + _blendWeight*(p2.z - p1.z);
 89				}
 90			}
 91		}
 92
 93		/**
 94		 * @inheritDoc
 95		 */
 96		override public function updatePositionData() : void
 97		{
 98			if (_framesInvalid) updateFrames(_phase);
 99
100			var p1 : Vector3D = clip._frames[_frame1].jointPoses[0].translation,
101				p2 : Vector3D = clip._frames[_frame2].jointPoses[0].translation;
102
103			var dx : Number = _rootPos.x;
104			var dy : Number = _rootPos.y;
105			var dz : Number = _rootPos.z;
106			_rootPos.x = p1.x + _blendWeight*(p2.x - p1.x);
107			_rootPos.y = p1.y + _blendWeight*(p2.y - p1.y);
108			_rootPos.z = p1.z + _blendWeight*(p2.z - p1.z);
109			rootDelta.x = _rootPos.x - dx;
110			rootDelta.y = _rootPos.y - dy;
111			rootDelta.z = _rootPos.z - dz;
112		}
113
114		private function updateFrames(phase : Number) : void
115		{
116			var lastFrame : uint;
117			var dur : uint, frameTime : uint;
118			var frames : Vector.<SkeletonPose> = _clip._frames;
119			var durations : Vector.<uint> = _clip._durations;
120			var duration : uint = _clip._totalDuration;
121			var numFrames : uint = frames.length;
122
123			if (numFrames == 0) return;
124
125			if (phase >= 1) {
126				lastFrame = numFrames - 1;
127				_frame1 = lastFrame;
128				_frame2 = lastFrame;
129				_blendWeight = 0;
130			}
131			else if (phase < 0) {
132				_frame1 = 0;
133				_frame2 = 0;
134				_blendWeight = 0;
135			}
136			else if (_clip._fixedFrameRate) {
137				phase *= numFrames-1;
138				_frame1 = phase;
139				_frame2 = _frame1 + 1;
140				if (_frame2 == numFrames) _frame2 = _frame1;
141				_blendWeight = phase - _frame1;
142			}
143			else {
144				phase *= duration - durations[numFrames - 1];
145				do {
146					frameTime = dur;
147					dur += durations[_frame1];
148					_frame1 = _frame2++;
149				} while (phase > dur);
150
151				if (_frame2 == numFrames) {
152					_frame2 = _frame1;
153					_blendWeight = 0;
154				}
155				else
156					_blendWeight = (phase - frameTime) / durations[_frame1];
157			}
158
159			_framesInvalid = false;
160		}
161	}
162}