PageRenderTime 365ms CodeModel.GetById 191ms app.highlight 15ms RepoModel.GetById 156ms app.codeStats 1ms

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