/src/away3d/animators/skeleton/SkeletonTimelineClipNode.as

http://github.com/away3d/away3d-core-fp11 · ActionScript · 204 lines · 159 code · 23 blank · 22 comment · 42 complexity · fe71692ddde9582d3538d1698e7ac852 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. * SkeletonTimelineClipNode represents a node in a skeleton tree containing a blending clip for which the keyframes
  11. * are laid out on a timeline. As such, the pose is determined by the time property.
  12. */
  13. public class SkeletonTimelineClipNode extends SkeletonClipNodeBase
  14. {
  15. private var _timeDir : Number;
  16. private var _frame1 : int;
  17. private var _frame2 : int;
  18. private var _blendWeight : Number = 0;
  19. private var _framesInvalid : Boolean;
  20. private var _resetTime : Boolean;
  21. private var _startTime : Number = 0;
  22. private var _lastFrame : int;
  23. /**
  24. * Creates a new SkeletonTimelineClipNode object.
  25. * @param numJoints The amount of joints in the target skeleton.
  26. */
  27. public function SkeletonTimelineClipNode()
  28. {
  29. super();
  30. }
  31. public function reset() : void
  32. {
  33. if (!clip.looping)
  34. _resetTime = true;
  35. }
  36. override public function set time(value : Number) : void
  37. {
  38. if (_resetTime) {
  39. _startTime = value;
  40. _resetTime = false;
  41. }
  42. if (_time == value) return;
  43. _framesInvalid = true;
  44. _timeDir = value - _time;
  45. super.time = value;
  46. }
  47. /**
  48. * @inheritDoc
  49. */
  50. override public function updatePose(skeleton : Skeleton) : void
  51. {
  52. if (_clip.duration == 0) return;
  53. if (_framesInvalid) updateFrames(_time-_startTime);
  54. var poses1 : Vector.<JointPose> = clip._frames[_frame1].jointPoses;
  55. var poses2 : Vector.<JointPose> = clip._frames[_frame2].jointPoses;
  56. var numJoints : uint = skeleton.numJoints;
  57. var p1 : Vector3D, p2 : Vector3D;
  58. var pose1 : JointPose, pose2 : JointPose;
  59. var endPoses : Vector.<JointPose> = skeletonPose.jointPoses;
  60. var endPose : JointPose;
  61. var tr : Vector3D;
  62. // :s
  63. if (endPoses.length != numJoints) endPoses.length = numJoints;
  64. if ((numJoints != poses1.length) || (numJoints != poses2.length))
  65. throw new Error("joint counts don't match!");
  66. for (var i : uint = 0; i < numJoints; ++i) {
  67. endPose = endPoses[i] ||= new JointPose();
  68. pose1 = poses1[i];
  69. pose2 = poses2[i];
  70. p1 = pose1.translation; p2 = pose2.translation;
  71. if (_highQuality)
  72. endPose.orientation.slerp(pose1.orientation, pose2.orientation, _blendWeight);
  73. else
  74. endPose.orientation.lerp(pose1.orientation, pose2.orientation, _blendWeight);
  75. if (i > 0) {
  76. tr = endPose.translation;
  77. tr.x = p1.x + _blendWeight*(p2.x - p1.x);
  78. tr.y = p1.y + _blendWeight*(p2.y - p1.y);
  79. tr.z = p1.z + _blendWeight*(p2.z - p1.z);
  80. }
  81. }
  82. }
  83. /**
  84. * @inheritDoc
  85. */
  86. override public function updatePositionData() : void
  87. {
  88. if (_framesInvalid) updateFrames(_time-_startTime);
  89. var p1 : Vector3D = clip._frames[_frame1].jointPoses[0].translation,
  90. p2 : Vector3D = clip._frames[_frame2].jointPoses[0].translation;
  91. if ((_timeDir > 0 && _frame2 > _lastFrame) || (_timeDir < 0 && _frame1 < _lastFrame)) {
  92. var dx : Number = _rootPos.x;
  93. var dy : Number = _rootPos.y;
  94. var dz : Number = _rootPos.z;
  95. _rootPos.x = p1.x + _blendWeight*(p2.x - p1.x);
  96. _rootPos.y = p1.y + _blendWeight*(p2.y - p1.y);
  97. _rootPos.z = p1.z + _blendWeight*(p2.z - p1.z);
  98. rootDelta.x = _rootPos.x - dx;
  99. rootDelta.y = _rootPos.y - dy;
  100. rootDelta.z = _rootPos.z - dz;
  101. }
  102. // jumping back, need to reset position
  103. else {
  104. _rootPos.x = p1.x + _blendWeight*(p2.x - p1.x);
  105. _rootPos.y = p1.y + _blendWeight*(p2.y - p1.y);
  106. _rootPos.z = p1.z + _blendWeight*(p2.z - p1.z);
  107. rootDelta.x = 0;
  108. rootDelta.y = 0;
  109. rootDelta.z = 0;
  110. }
  111. _lastFrame = _timeDir > 0? _frame1 : _frame2;
  112. }
  113. private function updateFrames(time : Number) : void
  114. {
  115. var lastFrame : uint;
  116. var dur : uint, frameTime : uint;
  117. var frames : Vector.<SkeletonPose> = _clip._frames;
  118. var durations : Vector.<uint> = _clip._durations;
  119. var duration : uint = _clip._totalDuration;
  120. var looping : Boolean = _clip.looping;
  121. var numFrames : uint = frames.length;
  122. if (numFrames == 0) return;
  123. lastFrame = numFrames - 1;
  124. if (looping) {
  125. if (time >= 1) time -= int(time);
  126. if (time < 0) time -= int(time)-1;
  127. if (_clip._fixedFrameRate) {
  128. time *= lastFrame;
  129. _frame1 = time;
  130. _blendWeight = time - _frame1;
  131. _frame2 = _frame1 + 1;
  132. }
  133. else {
  134. do {
  135. frameTime = dur;
  136. dur += durations[_frame1];
  137. _frame1 = _frame2;
  138. if (++_frame2 == numFrames) {
  139. _frame1 = 0;
  140. _frame2 = 1;
  141. }
  142. } while (time > dur);
  143. _blendWeight = (time - frameTime) / durations[_frame1];
  144. }
  145. }
  146. else {
  147. if (time >= 1) {
  148. clip.notifyPlaybackComplete();
  149. //if the animation has different frame count, set the frame to the lastframe return an error
  150. _frame1 = lastFrame;
  151. _frame2 = lastFrame;
  152. // _frame1 = 0;
  153. // _frame2 = 0;
  154. _blendWeight = 0;
  155. }
  156. else if (_clip._fixedFrameRate) {
  157. time *= lastFrame;
  158. _frame1 = time;
  159. _frame2 = _frame1 + 1;
  160. if (_frame2 == numFrames) _frame2 = _frame1;
  161. _blendWeight = time - _frame1;
  162. }
  163. else {
  164. time *= duration - durations[lastFrame];
  165. do {
  166. frameTime = dur;
  167. dur += durations[_frame1];
  168. _frame1 = _frame2++;
  169. } while (time > dur);
  170. if (_frame2 == numFrames) {
  171. _frame2 = _frame1;
  172. _blendWeight = 0;
  173. }
  174. else
  175. _blendWeight = (time - frameTime) / durations[_frame1];
  176. }
  177. }
  178. _framesInvalid = false;
  179. }
  180. }
  181. }