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