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