PageRenderTime 405ms CodeModel.GetById 201ms app.highlight 11ms RepoModel.GetById 191ms app.codeStats 0ms

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