/src/away3d/animators/VertexAnimator.as

http://github.com/away3d/away3d-core-fp11 · ActionScript · 163 lines · 98 code · 30 blank · 35 comment · 16 complexity · 48b034e2b43a0349fcfc6b4fd77453dc MD5 · raw file

  1. package away3d.animators
  2. {
  3. import away3d.arcane;
  4. import away3d.animators.states.*;
  5. import away3d.animators.transitions.*;
  6. import away3d.animators.data.*;
  7. import away3d.cameras.Camera3D;
  8. import away3d.core.base.*;
  9. import away3d.core.managers.*;
  10. import away3d.materials.passes.*;
  11. import flash.display3D.*;
  12. use namespace arcane;
  13. /**
  14. * Provides an interface for assigning vertex-based animation data sets to mesh-based entity objects
  15. * and controlling the various available states of animation through an interative playhead that can be
  16. * automatically updated or manually triggered.
  17. */
  18. public class VertexAnimator extends AnimatorBase implements IAnimator
  19. {
  20. private var _vertexAnimationSet:VertexAnimationSet;
  21. private var _poses:Vector.<Geometry> = new Vector.<Geometry>();
  22. private var _weights:Vector.<Number> = Vector.<Number>([1, 0, 0, 0]);
  23. private var _numPoses:uint;
  24. private var _blendMode:String;
  25. private var _activeVertexState:IVertexAnimationState;
  26. /**
  27. * Creates a new <code>VertexAnimator</code> object.
  28. *
  29. * @param vertexAnimationSet The animation data set containing the vertex animations used by the animator.
  30. */
  31. public function VertexAnimator(vertexAnimationSet:VertexAnimationSet)
  32. {
  33. super(vertexAnimationSet);
  34. _vertexAnimationSet = vertexAnimationSet;
  35. _numPoses = vertexAnimationSet.numPoses;
  36. _blendMode = vertexAnimationSet.blendMode;
  37. }
  38. /**
  39. * @inheritDoc
  40. */
  41. public function clone():IAnimator
  42. {
  43. return new VertexAnimator(_vertexAnimationSet);
  44. }
  45. /**
  46. * Plays a sequence with a given name. If the sequence is not found, it may not be loaded yet, and it will retry every frame.
  47. * @param sequenceName The name of the clip to be played.
  48. */
  49. public function play(name:String, transition:IAnimationTransition = null, offset:Number = NaN):void
  50. {
  51. if (_activeAnimationName != name) {
  52. _activeAnimationName = name;
  53. //TODO: implement transitions in vertex animator
  54. if (!_animationSet.hasAnimation(name))
  55. throw new Error("Animation root node " + name + " not found!");
  56. _activeNode = _animationSet.getAnimation(name);
  57. _activeState = getAnimationState(_activeNode);
  58. if (updatePosition) {
  59. //update straight away to reset position deltas
  60. _activeState.update(_absoluteTime);
  61. _activeState.positionDelta;
  62. }
  63. _activeVertexState = _activeState as IVertexAnimationState;
  64. }
  65. start();
  66. //apply a time offset if specified
  67. if (!isNaN(offset))
  68. reset(name, offset);
  69. }
  70. /**
  71. * @inheritDoc
  72. */
  73. override protected function updateDeltaTime(dt:Number):void
  74. {
  75. super.updateDeltaTime(dt);
  76. _poses[uint(0)] = _activeVertexState.currentGeometry;
  77. _poses[uint(1)] = _activeVertexState.nextGeometry;
  78. _weights[uint(0)] = 1 - (_weights[uint(1)] = _activeVertexState.blendWeight);
  79. }
  80. /**
  81. * @inheritDoc
  82. */
  83. public function setRenderState(stage3DProxy:Stage3DProxy, renderable:IRenderable, vertexConstantOffset:int, vertexStreamOffset:int, camera:Camera3D):void
  84. {
  85. // todo: add code for when running on cpu
  86. // if no poses defined, set temp data
  87. if (!_poses.length) {
  88. setNullPose(stage3DProxy, renderable, vertexConstantOffset, vertexStreamOffset);
  89. return;
  90. }
  91. // this type of animation can only be SubMesh
  92. var subMesh:SubMesh = SubMesh(renderable);
  93. var subGeom:ISubGeometry;
  94. var i:uint;
  95. var len:uint = _numPoses;
  96. stage3DProxy._context3D.setProgramConstantsFromVector(Context3DProgramType.VERTEX, vertexConstantOffset, _weights, 1);
  97. if (_blendMode == VertexAnimationMode.ABSOLUTE) {
  98. i = 1;
  99. subGeom = _poses[uint(0)].subGeometries[subMesh._index];
  100. // set the base sub-geometry so the material can simply pick up on this data
  101. if (subGeom)
  102. subMesh.subGeometry = subGeom;
  103. } else
  104. i = 0;
  105. for (; i < len; ++i) {
  106. subGeom = _poses[i].subGeometries[subMesh._index] || subMesh.subGeometry;
  107. subGeom.activateVertexBuffer(vertexStreamOffset++, stage3DProxy);
  108. if (_vertexAnimationSet.useNormals)
  109. subGeom.activateVertexNormalBuffer(vertexStreamOffset++, stage3DProxy);
  110. }
  111. }
  112. private function setNullPose(stage3DProxy:Stage3DProxy, renderable:IRenderable, vertexConstantOffset:int, vertexStreamOffset:int):void
  113. {
  114. stage3DProxy._context3D.setProgramConstantsFromVector(Context3DProgramType.VERTEX, vertexConstantOffset, _weights, 1);
  115. if (_blendMode == VertexAnimationMode.ABSOLUTE) {
  116. var len:uint = _numPoses;
  117. for (var i:uint = 1; i < len; ++i) {
  118. renderable.activateVertexBuffer(vertexStreamOffset++, stage3DProxy);
  119. if (_vertexAnimationSet.useNormals)
  120. renderable.activateVertexNormalBuffer(vertexStreamOffset++, stage3DProxy);
  121. }
  122. }
  123. // todo: set temp data for additive?
  124. }
  125. /**
  126. * Verifies if the animation will be used on cpu. Needs to be true for all passes for a material to be able to use it on gpu.
  127. * Needs to be called if gpu code is potentially required.
  128. */
  129. public function testGPUCompatibility(pass:MaterialPassBase):void
  130. {
  131. }
  132. }
  133. }