PageRenderTime 52ms CodeModel.GetById 16ms RepoModel.GetById 0ms app.codeStats 0ms

/src/away3d/animators/AnimatorBase.as

http://github.com/away3d/away3d-core-fp11
ActionScript | 349 lines | 184 code | 52 blank | 113 comment | 18 complexity | 8ace496f54a36ed9ce84173a87300e75 MD5 | raw file
Possible License(s): Apache-2.0
  1. package away3d.animators
  2. {
  3. import flash.display.Sprite;
  4. import flash.events.Event;
  5. import flash.geom.Vector3D;
  6. import flash.utils.Dictionary;
  7. import flash.utils.getTimer;
  8. import away3d.arcane;
  9. import away3d.animators.nodes.AnimationNodeBase;
  10. import away3d.animators.states.AnimationStateBase;
  11. import away3d.animators.states.IAnimationState;
  12. import away3d.entities.Mesh;
  13. import away3d.events.AnimatorEvent;
  14. import away3d.library.assets.AssetType;
  15. import away3d.library.assets.IAsset;
  16. import away3d.library.assets.NamedAssetBase;
  17. use namespace arcane;
  18. /**
  19. * Dispatched when playback of an animation inside the animator object starts.
  20. *
  21. * @eventType away3d.events.AnimatorEvent
  22. */
  23. [Event(name="start", type="away3d.events.AnimatorEvent")]
  24. /**
  25. * Dispatched when playback of an animation inside the animator object stops.
  26. *
  27. * @eventType away3d.events.AnimatorEvent
  28. */
  29. [Event(name="stop", type="away3d.events.AnimatorEvent")]
  30. /**
  31. * Dispatched when playback of an animation reaches the end of an animation.
  32. *
  33. * @eventType away3d.events.AnimatorEvent
  34. */
  35. [Event(name="cycle_complete", type="away3d.events.AnimatorEvent")]
  36. /**
  37. * Provides an abstract base class for animator classes that control animation output from a data set subtype of <code>AnimationSetBase</code>.
  38. *
  39. * @see away3d.animators.AnimationSetBase
  40. */
  41. public class AnimatorBase extends NamedAssetBase implements IAsset
  42. {
  43. private var _broadcaster:Sprite = new Sprite();
  44. private var _isPlaying:Boolean;
  45. private var _autoUpdate:Boolean = true;
  46. private var _startEvent:AnimatorEvent;
  47. private var _stopEvent:AnimatorEvent;
  48. private var _cycleEvent:AnimatorEvent;
  49. private var _time:int;
  50. private var _playbackSpeed:Number = 1;
  51. protected var _animationSet:IAnimationSet;
  52. protected var _owners:Vector.<Mesh> = new Vector.<Mesh>();
  53. protected var _activeNode:AnimationNodeBase;
  54. protected var _activeState:IAnimationState;
  55. protected var _activeAnimationName:String;
  56. protected var _absoluteTime:Number = 0;
  57. private var _animationStates:Dictionary = new Dictionary(true);
  58. /**
  59. * Enables translation of the animated mesh from data returned per frame via the positionDelta property of the active animation node. Defaults to true.
  60. *
  61. * @see away3d.animators.states.IAnimationState#positionDelta
  62. */
  63. public var updatePosition:Boolean = true;
  64. public function getAnimationState(node:AnimationNodeBase):AnimationStateBase
  65. {
  66. var className:Class = node.stateClass;
  67. return _animationStates[node] ||= new className(this, node);
  68. }
  69. public function getAnimationStateByName(name:String):AnimationStateBase
  70. {
  71. return getAnimationState(_animationSet.getAnimation(name));
  72. }
  73. /**
  74. * Returns the internal absolute time of the animator, calculated by the current time and the playback speed.
  75. *
  76. * @see #time
  77. * @see #playbackSpeed
  78. */
  79. public function get absoluteTime():Number
  80. {
  81. return _absoluteTime;
  82. }
  83. /**
  84. * Returns the animation data set in use by the animator.
  85. */
  86. public function get animationSet():IAnimationSet
  87. {
  88. return _animationSet;
  89. }
  90. /**
  91. * Returns the current active animation state.
  92. */
  93. public function get activeState():IAnimationState
  94. {
  95. return _activeState;
  96. }
  97. /**
  98. * Returns the current active animation node.
  99. */
  100. public function get activeAnimation():AnimationNodeBase
  101. {
  102. return _animationSet.getAnimation(_activeAnimationName);
  103. }
  104. /**
  105. * Returns the current active animation node.
  106. */
  107. public function get activeAnimationName():String
  108. {
  109. return _activeAnimationName;
  110. }
  111. /**
  112. * Determines whether the animators internal update mechanisms are active. Used in cases
  113. * where manual updates are required either via the <code>time</code> property or <code>update()</code> method.
  114. * Defaults to true.
  115. *
  116. * @see #time
  117. * @see #update()
  118. */
  119. public function get autoUpdate():Boolean
  120. {
  121. return _autoUpdate;
  122. }
  123. public function set autoUpdate(value:Boolean):void
  124. {
  125. if (_autoUpdate == value)
  126. return;
  127. _autoUpdate = value;
  128. if (_autoUpdate)
  129. start();
  130. else
  131. stop();
  132. }
  133. /**
  134. * Gets and sets the internal time clock of the animator.
  135. */
  136. public function get time():int
  137. {
  138. return _time;
  139. }
  140. public function set time(value:int):void
  141. {
  142. if (_time == value)
  143. return;
  144. update(value);
  145. }
  146. /**
  147. * Sets the animation phase of the current active state's animation clip(s).
  148. *
  149. * @param value The phase value to use. 0 represents the beginning of an animation clip, 1 represents the end.
  150. */
  151. public function phase(value:Number):void
  152. {
  153. _activeState.phase(value);
  154. }
  155. /**
  156. * Creates a new <code>AnimatorBase</code> object.
  157. *
  158. * @param animationSet The animation data set to be used by the animator object.
  159. */
  160. public function AnimatorBase(animationSet:IAnimationSet)
  161. {
  162. _animationSet = animationSet;
  163. }
  164. /**
  165. * The amount by which passed time should be scaled. Used to slow down or speed up animations. Defaults to 1.
  166. */
  167. public function get playbackSpeed():Number
  168. {
  169. return _playbackSpeed;
  170. }
  171. public function set playbackSpeed(value:Number):void
  172. {
  173. _playbackSpeed = value;
  174. }
  175. /**
  176. * Resumes the automatic playback clock controling the active state of the animator.
  177. */
  178. public function start():void
  179. {
  180. if (_isPlaying || !_autoUpdate)
  181. return;
  182. _time = _absoluteTime = getTimer();
  183. _isPlaying = true;
  184. if (!_broadcaster.hasEventListener(Event.ENTER_FRAME))
  185. _broadcaster.addEventListener(Event.ENTER_FRAME, onEnterFrame);
  186. if (!hasEventListener(AnimatorEvent.START))
  187. return;
  188. dispatchEvent(_startEvent ||= new AnimatorEvent(AnimatorEvent.START, this));
  189. }
  190. /**
  191. * Pauses the automatic playback clock of the animator, in case manual updates are required via the
  192. * <code>time</code> property or <code>update()</code> method.
  193. *
  194. * @see #time
  195. * @see #update()
  196. */
  197. public function stop():void
  198. {
  199. if (!_isPlaying)
  200. return;
  201. _isPlaying = false;
  202. if (_broadcaster.hasEventListener(Event.ENTER_FRAME))
  203. _broadcaster.removeEventListener(Event.ENTER_FRAME, onEnterFrame);
  204. if (!hasEventListener(AnimatorEvent.STOP))
  205. return;
  206. dispatchEvent(_stopEvent || (_stopEvent = new AnimatorEvent(AnimatorEvent.STOP, this)));
  207. }
  208. /**
  209. * Provides a way to manually update the active state of the animator when automatic
  210. * updates are disabled.
  211. *
  212. * @see #stop()
  213. * @see #autoUpdate
  214. */
  215. public function update(time:int):void
  216. {
  217. var dt:Number = (time - _time)*playbackSpeed;
  218. updateDeltaTime(dt);
  219. _time = time;
  220. }
  221. public function reset(name:String, offset:Number = 0):void
  222. {
  223. getAnimationState(_animationSet.getAnimation(name)).offset(offset + _absoluteTime);
  224. }
  225. /**
  226. * Used by the mesh object to which the animator is applied, registers the owner for internal use.
  227. *
  228. * @private
  229. */
  230. public function addOwner(mesh:Mesh):void
  231. {
  232. _owners.push(mesh);
  233. }
  234. /**
  235. * Used by the mesh object from which the animator is removed, unregisters the owner for internal use.
  236. *
  237. * @private
  238. */
  239. public function removeOwner(mesh:Mesh):void
  240. {
  241. _owners.splice(_owners.indexOf(mesh), 1);
  242. }
  243. /**
  244. * Internal abstract method called when the time delta property of the animator's contents requires updating.
  245. *
  246. * @private
  247. */
  248. protected function updateDeltaTime(dt:Number):void
  249. {
  250. _absoluteTime += dt;
  251. _activeState.update(_absoluteTime);
  252. if (updatePosition)
  253. applyPositionDelta();
  254. }
  255. /**
  256. * Enter frame event handler for automatically updating the active state of the animator.
  257. */
  258. private function onEnterFrame(event:Event = null):void
  259. {
  260. update(getTimer());
  261. }
  262. private function applyPositionDelta():void
  263. {
  264. var delta:Vector3D = _activeState.positionDelta;
  265. var dist:Number = delta.length;
  266. var len:uint;
  267. if (dist > 0) {
  268. len = _owners.length;
  269. for (var i:uint = 0; i < len; ++i)
  270. _owners[i].translateLocal(delta, dist);
  271. }
  272. }
  273. /**
  274. * for internal use.
  275. *
  276. * @private
  277. */
  278. public function dispatchCycleEvent():void
  279. {
  280. if (hasEventListener(AnimatorEvent.CYCLE_COMPLETE))
  281. dispatchEvent(_cycleEvent || (_cycleEvent = new AnimatorEvent(AnimatorEvent.CYCLE_COMPLETE, this)));
  282. }
  283. /**
  284. * @inheritDoc
  285. */
  286. public function dispose():void
  287. {
  288. }
  289. /**
  290. * @inheritDoc
  291. */
  292. public function get assetType():String
  293. {
  294. return AssetType.ANIMATOR;
  295. }
  296. }
  297. }