/src/away3d/animators/data/VertexAnimation.as

http://github.com/away3d/away3d-core-fp11 · ActionScript · 173 lines · 118 code · 21 blank · 34 comment · 23 complexity · 3c8e78d0891b10f88b4b3188dca9c0f8 MD5 · raw file

  1. package away3d.animators.data
  2. {
  3. import away3d.arcane;
  4. import away3d.core.managers.Stage3DProxy;
  5. import away3d.materials.passes.MaterialPassBase;
  6. import flash.display3D.Context3D;
  7. use namespace arcane;
  8. /**
  9. * VertexAnimation defines an animation type that blends different poses (geometries) together to create a final pose.
  10. */
  11. public class VertexAnimation extends AnimationBase
  12. {
  13. arcane var _streamIndex : uint;
  14. arcane var _useNormals : Boolean;
  15. arcane var _useTangents : Boolean;
  16. arcane var _numPoses : uint;
  17. private var _blendMode : String;
  18. /**
  19. * Creates a new VertexAnimation object
  20. * @param numPoses The amount of poses to be blended together.
  21. * @param blendMode The type of blending to be performed by the animation. The following values are supported:
  22. * <ul>
  23. * <li>VertexAnimationMode.ADDITIVE: The pose is generated from a base mesh and a number of additive "difference" poses.</li>
  24. * <li>VertexAnimationMode.ABSOLUTE: The pose is generated by a weighted average of a number of poses.</li>
  25. * </ul>
  26. */
  27. public function VertexAnimation(numPoses : uint, blendMode : String)
  28. {
  29. super();
  30. _numPoses = numPoses;
  31. _blendMode = blendMode;
  32. }
  33. /**
  34. * The type of blending to be performed by the animation.
  35. */
  36. public function get blendMode() : String
  37. {
  38. return _blendMode;
  39. }
  40. /**
  41. * @inheritDoc
  42. */
  43. override arcane function createAnimationState() : AnimationStateBase
  44. {
  45. return new VertexAnimationState(this);
  46. }
  47. /**
  48. * @inheritDoc
  49. */
  50. override arcane function deactivate(stage3DProxy : Stage3DProxy, pass : MaterialPassBase) : void
  51. {
  52. stage3DProxy.setSimpleVertexBuffer(_streamIndex, null);
  53. if (_useNormals)
  54. stage3DProxy.setSimpleVertexBuffer(_streamIndex + 1, null);
  55. if (_useTangents)
  56. stage3DProxy.setSimpleVertexBuffer(_streamIndex + 2, null);
  57. }
  58. /**
  59. * @inheritDoc
  60. */
  61. override arcane function getAGALVertexCode(pass : MaterialPassBase) : String
  62. {
  63. if (_blendMode == VertexAnimationMode.ABSOLUTE)
  64. return getAbsoluteAGALCode(pass);
  65. else
  66. return getAdditiveAGALCode(pass);
  67. }
  68. /**
  69. * Generates the vertex AGAL code for absolute blending.
  70. */
  71. private function getAbsoluteAGALCode(pass : MaterialPassBase) : String
  72. {
  73. var attribs : Array = pass.getAnimationSourceRegisters();
  74. var targets : Array = pass.getAnimationTargetRegisters();
  75. var code : String = "";
  76. var temp1 : String = findTempReg(targets);
  77. var temp2 : String = findTempReg(targets, temp1);
  78. var regs : Array = ["x", "y", "z", "w"];
  79. var len : uint = attribs.length;
  80. _useNormals = len > 1;
  81. _useTangents = len > 2;
  82. if (len > 2) len = 2;
  83. _streamIndex = pass.numUsedStreams;
  84. var k : uint;
  85. for (var i : uint = 0; i < len; ++i) {
  86. for (var j : uint = 0; j < _numPoses; ++j) {
  87. if (j == 0) {
  88. code += "mul " + temp1 + ", " + attribs[i] + ", vc" + pass.numUsedVertexConstants + "." + regs[j] + "\n";
  89. }
  90. else {
  91. code += "mul " + temp2 + ", va" + (_streamIndex + k) + ", vc" + pass.numUsedVertexConstants + "." + regs[j] + "\n";
  92. if (j < _numPoses - 1) code += "add " + temp1 + ", " + temp1 + ", " + temp2 + "\n";
  93. else code += "add " + targets[i] + ", " + temp1 + ", " + temp2 + "\n";
  94. ++k;
  95. }
  96. }
  97. }
  98. if (_useTangents) {
  99. code += "dp3 " + temp1 + ".x, " + attribs[uint(2)] + ", " + targets[uint(1)] + "\n" +
  100. "mul " + temp1 + ", " + targets[uint(1)] + ", " + temp1 + ".x \n" +
  101. "sub " + targets[uint(2)] + ", " + attribs[uint(2)] + ", " + temp1 + "\n";
  102. }
  103. return code;
  104. }
  105. private function getAdditiveAGALCode(pass : MaterialPassBase) : String
  106. {
  107. var attribs : Array = pass.getAnimationSourceRegisters();
  108. var targets : Array = pass.getAnimationTargetRegisters();
  109. var code : String = "";
  110. var len : uint = attribs.length;
  111. var regs : Array = ["x", "y", "z", "w"];
  112. var temp1 : String = findTempReg(targets);
  113. var k : uint;
  114. _useNormals = len > 1;
  115. _useTangents = len > 2;
  116. if (len > 2) len = 2;
  117. code += "mov " + targets[0] + ", " + attribs[0] + "\n";
  118. if (_useNormals) code += "mov " + targets[1] + ", " + attribs[1] + "\n";
  119. for (var i : uint = 0; i < len; ++i) {
  120. for (var j : uint = 0; j < _numPoses; ++j) {
  121. code += "mul " + temp1 + ", va" + (_streamIndex + k) + ", vc" + pass.numUsedVertexConstants + "." + regs[j] + "\n" +
  122. "add " + targets[i] + ", " + targets[i] + ", " + temp1 + "\n";
  123. k++;
  124. }
  125. }
  126. if (_useTangents) {
  127. code += "dp3 " + temp1 + ".x, " + attribs[uint(2)] + ", " + targets[uint(1)] + "\n" +
  128. "mul " + temp1 + ", " + targets[uint(1)] + ", " + temp1 + ".x \n" +
  129. "sub " + targets[uint(2)] + ", " + attribs[uint(2)] + ", " + temp1 + "\n";
  130. }
  131. return code;
  132. }
  133. /**
  134. * Retrieves a temporary register that's still free.
  135. * @param exclude An array of non-free temporary registers
  136. * @param excludeAnother An additional register that's not free
  137. * @return A temporary register that can be used
  138. */
  139. private function findTempReg(exclude : Array, excludeAnother : String = null) : String
  140. {
  141. var i : uint;
  142. var reg : String;
  143. while (true) {
  144. reg = "vt" + i;
  145. if (exclude.indexOf(reg) == -1 && excludeAnother != reg) return reg;
  146. ++i;
  147. }
  148. // can't be reached
  149. return null;
  150. }
  151. }
  152. }