/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
- package away3d.animators.data
- {
- import away3d.arcane;
- import away3d.core.managers.Stage3DProxy;
- import away3d.materials.passes.MaterialPassBase;
- import flash.display3D.Context3D;
- use namespace arcane;
- /**
- * VertexAnimation defines an animation type that blends different poses (geometries) together to create a final pose.
- */
- public class VertexAnimation extends AnimationBase
- {
- arcane var _streamIndex : uint;
- arcane var _useNormals : Boolean;
- arcane var _useTangents : Boolean;
- arcane var _numPoses : uint;
- private var _blendMode : String;
- /**
- * Creates a new VertexAnimation object
- * @param numPoses The amount of poses to be blended together.
- * @param blendMode The type of blending to be performed by the animation. The following values are supported:
- * <ul>
- * <li>VertexAnimationMode.ADDITIVE: The pose is generated from a base mesh and a number of additive "difference" poses.</li>
- * <li>VertexAnimationMode.ABSOLUTE: The pose is generated by a weighted average of a number of poses.</li>
- * </ul>
- */
- public function VertexAnimation(numPoses : uint, blendMode : String)
- {
- super();
- _numPoses = numPoses;
- _blendMode = blendMode;
- }
- /**
- * The type of blending to be performed by the animation.
- */
- public function get blendMode() : String
- {
- return _blendMode;
- }
- /**
- * @inheritDoc
- */
- override arcane function createAnimationState() : AnimationStateBase
- {
- return new VertexAnimationState(this);
- }
- /**
- * @inheritDoc
- */
- override arcane function deactivate(stage3DProxy : Stage3DProxy, pass : MaterialPassBase) : void
- {
- stage3DProxy.setSimpleVertexBuffer(_streamIndex, null);
- if (_useNormals)
- stage3DProxy.setSimpleVertexBuffer(_streamIndex + 1, null);
- if (_useTangents)
- stage3DProxy.setSimpleVertexBuffer(_streamIndex + 2, null);
- }
- /**
- * @inheritDoc
- */
- override arcane function getAGALVertexCode(pass : MaterialPassBase) : String
- {
- if (_blendMode == VertexAnimationMode.ABSOLUTE)
- return getAbsoluteAGALCode(pass);
- else
- return getAdditiveAGALCode(pass);
- }
- /**
- * Generates the vertex AGAL code for absolute blending.
- */
- private function getAbsoluteAGALCode(pass : MaterialPassBase) : String
- {
- var attribs : Array = pass.getAnimationSourceRegisters();
- var targets : Array = pass.getAnimationTargetRegisters();
- var code : String = "";
- var temp1 : String = findTempReg(targets);
- var temp2 : String = findTempReg(targets, temp1);
- var regs : Array = ["x", "y", "z", "w"];
- var len : uint = attribs.length;
- _useNormals = len > 1;
- _useTangents = len > 2;
- if (len > 2) len = 2;
- _streamIndex = pass.numUsedStreams;
- var k : uint;
- for (var i : uint = 0; i < len; ++i) {
- for (var j : uint = 0; j < _numPoses; ++j) {
- if (j == 0) {
- code += "mul " + temp1 + ", " + attribs[i] + ", vc" + pass.numUsedVertexConstants + "." + regs[j] + "\n";
- }
- else {
- code += "mul " + temp2 + ", va" + (_streamIndex + k) + ", vc" + pass.numUsedVertexConstants + "." + regs[j] + "\n";
- if (j < _numPoses - 1) code += "add " + temp1 + ", " + temp1 + ", " + temp2 + "\n";
- else code += "add " + targets[i] + ", " + temp1 + ", " + temp2 + "\n";
- ++k;
- }
- }
- }
- if (_useTangents) {
- code += "dp3 " + temp1 + ".x, " + attribs[uint(2)] + ", " + targets[uint(1)] + "\n" +
- "mul " + temp1 + ", " + targets[uint(1)] + ", " + temp1 + ".x \n" +
- "sub " + targets[uint(2)] + ", " + attribs[uint(2)] + ", " + temp1 + "\n";
- }
- return code;
- }
- private function getAdditiveAGALCode(pass : MaterialPassBase) : String
- {
- var attribs : Array = pass.getAnimationSourceRegisters();
- var targets : Array = pass.getAnimationTargetRegisters();
- var code : String = "";
- var len : uint = attribs.length;
- var regs : Array = ["x", "y", "z", "w"];
- var temp1 : String = findTempReg(targets);
- var k : uint;
- _useNormals = len > 1;
- _useTangents = len > 2;
- if (len > 2) len = 2;
- code += "mov " + targets[0] + ", " + attribs[0] + "\n";
- if (_useNormals) code += "mov " + targets[1] + ", " + attribs[1] + "\n";
- for (var i : uint = 0; i < len; ++i) {
- for (var j : uint = 0; j < _numPoses; ++j) {
- code += "mul " + temp1 + ", va" + (_streamIndex + k) + ", vc" + pass.numUsedVertexConstants + "." + regs[j] + "\n" +
- "add " + targets[i] + ", " + targets[i] + ", " + temp1 + "\n";
- k++;
- }
- }
- if (_useTangents) {
- code += "dp3 " + temp1 + ".x, " + attribs[uint(2)] + ", " + targets[uint(1)] + "\n" +
- "mul " + temp1 + ", " + targets[uint(1)] + ", " + temp1 + ".x \n" +
- "sub " + targets[uint(2)] + ", " + attribs[uint(2)] + ", " + temp1 + "\n";
- }
- return code;
- }
- /**
- * Retrieves a temporary register that's still free.
- * @param exclude An array of non-free temporary registers
- * @param excludeAnother An additional register that's not free
- * @return A temporary register that can be used
- */
- private function findTempReg(exclude : Array, excludeAnother : String = null) : String
- {
- var i : uint;
- var reg : String;
- while (true) {
- reg = "vt" + i;
- if (exclude.indexOf(reg) == -1 && excludeAnother != reg) return reg;
- ++i;
- }
- // can't be reached
- return null;
- }
- }
- }