PageRenderTime 63ms CodeModel.GetById 30ms app.highlight 15ms RepoModel.GetById 16ms app.codeStats 0ms

/src/away3d/animators/skeleton/SkeletonNaryLERPNode.as

http://github.com/away3d/away3d-core-fp11
ActionScript | 168 lines | 135 code | 25 blank | 8 comment | 17 complexity | e8f227ee771e76352e24693b4d23a517 MD5 | raw file
  1/**
  2 * Author: David Lenaerts
  3 */
  4package away3d.animators.skeleton
  5{
  6	import away3d.core.math.Quaternion;
  7
  8	import flash.geom.Vector3D;
  9
 10	public class SkeletonNaryLERPNode extends SkeletonTreeNode
 11	{
 12		/**
 13		 * The weights for each joint. The total needs to equal 1.
 14		 */
 15		private var _blendWeights : Vector.<Number>;
 16		private var _inputs : Vector.<SkeletonTreeNode>;
 17		private var _numInputs : uint;
 18
 19		public function SkeletonNaryLERPNode()
 20		{
 21			super();
 22			_inputs = new Vector.<SkeletonTreeNode>();
 23			_blendWeights = new Vector.<Number>();
 24		}
 25
 26		public function getInputIndex(input : SkeletonTreeNode) : int
 27		{
 28			return _inputs.indexOf(input);
 29		}
 30
 31		public function getInputAt(index : uint) : SkeletonTreeNode
 32		{
 33			return _inputs[index];
 34		}
 35
 36		public function addInput(input : SkeletonTreeNode) : void
 37		{
 38			_inputs[_numInputs] = input;
 39			_blendWeights[_numInputs++] = 0;
 40		}
 41
 42		override public function updatePose(skeleton : Skeleton) : void
 43		{
 44			var input : SkeletonTreeNode;
 45			var weight : Number;
 46			var endPoses : Vector.<JointPose> = skeletonPose.jointPoses;
 47			var poses : Vector.<JointPose>;
 48			var endPose : JointPose, pose : JointPose;
 49			var endTr : Vector3D, tr : Vector3D;
 50			var endQuat : Quaternion, q : Quaternion;
 51			var firstPose : Vector.<JointPose>;
 52			var i : uint;
 53			var w0 : Number, x0 : Number, y0 : Number, z0 : Number;
 54			var w1 : Number, x1 : Number, y1 : Number, z1 : Number;
 55			var numJoints : uint = skeleton.numJoints;
 56
 57			// :s
 58			if (endPoses.length != numJoints) endPoses.length = numJoints;
 59
 60			for (var j : uint = 0; j < _numInputs; ++j) {
 61				weight = _blendWeights[j];
 62				if (weight == 0) continue;
 63				input = _inputs[j];
 64				input.time = _time;
 65				input.direction = _direction;
 66				input.updatePose(skeleton);
 67
 68				poses = input.skeletonPose.jointPoses;
 69
 70				if (!firstPose) {
 71					firstPose = poses;
 72					for (i = 0; i < numJoints; ++i) {
 73						endPose = endPoses[i] ||= new JointPose();
 74						pose = poses[i];
 75						q = pose.orientation;
 76						tr = pose.translation;
 77
 78						endQuat = endPose.orientation;
 79
 80						endQuat.x = weight*q.x;
 81						endQuat.y = weight*q.y;
 82						endQuat.z = weight*q.z;
 83						endQuat.w = weight*q.w;
 84
 85						endTr = endPose.translation;
 86						endTr.x = weight*tr.x;
 87						endTr.y = weight*tr.y;
 88						endTr.z = weight*tr.z;
 89					}
 90				}
 91				else {
 92					for (i = 0; i < skeleton.numJoints; ++i) {
 93						endPose = endPoses[i];
 94						pose = poses[i];
 95
 96						q = firstPose[i].orientation;
 97						x0 = q.x; y0 = q.y; z0 = q.z; w0 = q.w;
 98
 99						q = pose.orientation;
100						tr = pose.translation;
101
102						x1 = q.x; y1 = q.y; z1 = q.z; w1 = q.w;
103						// find shortest direction
104						if (x0*x1 + y0*y1 + z0*z1 + w0*w1 < 0) {
105							x1 = -x1;
106							y1 = -y1;
107							z1 = -z1;
108							w1 = -w1;
109						}
110						endQuat = endPose.orientation;
111						endQuat.x += weight*x1;
112						endQuat.y += weight*y1;
113						endQuat.z += weight*z1;
114						endQuat.w += weight*w1;
115
116						endTr = endPose.translation;
117						endTr.x += weight*tr.x;
118						endTr.y += weight*tr.y;
119						endTr.z += weight*tr.z;
120					}
121				}
122			}
123
124			for (i = 0; i < skeleton.numJoints; ++i) {
125				endPoses[i].orientation.normalize();
126			}
127		}
128
129		override public function updatePositionData() : void
130		{
131			var delta : Vector3D;
132			var weight : Number;
133
134			rootDelta.x = 0;
135			rootDelta.y = 0;
136			rootDelta.z = 0;
137
138			for (var j : uint = 0; j < _numInputs; ++j) {
139				weight = _blendWeights[j];
140				if (weight == 0) continue;
141				_inputs[j].time = _time;
142				_inputs[j].updatePositionData();
143				delta = _inputs[j].rootDelta;
144				rootDelta.x += weight*delta.x;
145				rootDelta.y += weight*delta.y;
146				rootDelta.z += weight*delta.z;
147			}
148		}
149
150		public function get blendWeights() : Vector.<Number>
151		{
152			return _blendWeights;
153		}
154
155		public function updateWeights(weights : Vector.<Number>) : void
156		{
157			var weight : Number;
158
159			_duration = 0;
160			_blendWeights = weights;
161			for (var j : uint = 0; j < _numInputs; ++j) {
162				weight = _blendWeights[j];
163				if (weight == 0) continue;
164				_duration += weight*_inputs[j].duration;
165			}
166		}
167	}
168}