PageRenderTime 1056ms CodeModel.GetById 691ms app.highlight 138ms RepoModel.GetById 156ms app.codeStats 0ms

/src/away3d/animators/UVAnimator.as

http://github.com/away3d/away3d-core-fp11
ActionScript | 214 lines | 138 code | 37 blank | 39 comment | 18 complexity | 56fdc22f1daeef5bc1005b217e516897 MD5 | raw file
  1package away3d.animators
  2{
  3	import away3d.animators.data.*;
  4	import away3d.animators.states.*;
  5	import away3d.animators.transitions.*;
  6	import away3d.arcane;
  7	import away3d.cameras.Camera3D;
  8	import away3d.core.base.*;
  9	import away3d.core.managers.*;
 10	import away3d.core.math.MathConsts;
 11	import away3d.materials.*;
 12	import away3d.materials.passes.*;
 13	
 14	import flash.display3D.Context3DProgramType;
 15	import flash.geom.Matrix;
 16	
 17	use namespace arcane;
 18	
 19	/**
 20	 * Provides an interface for assigning uv-based animation data sets to mesh-based entity objects
 21	 * and controlling the various available states of animation through an interative playhead that can be
 22	 * automatically updated or manually triggered.
 23	 */
 24	public class UVAnimator extends AnimatorBase implements IAnimator
 25	{
 26		private var _uvAnimationSet:UVAnimationSet;
 27		private var _deltaFrame:UVAnimationFrame = new UVAnimationFrame();
 28		private var _activeUVState:IUVAnimationState;
 29		
 30		private var _uvTransform:Matrix;
 31		private var _matrix2d:Vector.<Number>;
 32		private var _translate:Vector.<Number>;
 33		
 34		private var _autoRotation:Boolean;
 35		private var _rotationIncrease:Number = 1;
 36		private var _autoTranslate:Boolean;
 37		private var _translateIncrease:Vector.<Number>;
 38		
 39		/**
 40		 * Creates a new <code>UVAnimator</code> object.
 41		 *
 42		 * @param uvAnimationSet The animation data set containing the uv animations used by the animator.
 43		 */
 44		public function UVAnimator(uvAnimationSet:UVAnimationSet)
 45		{
 46			super(uvAnimationSet);
 47			
 48			_uvTransform = new Matrix();
 49			_matrix2d = Vector.<Number>([1, 0, 0, 0, 1, 0, 0, 0]);
 50			_translate = Vector.<Number>([0, 0, 0.5, 0.5]);
 51			_uvAnimationSet = uvAnimationSet;
 52		}
 53		
 54		/**
 55		 * Defines if a rotation is performed automatically each update. The rotationIncrease value is added each iteration.
 56		 */
 57		public function set autoRotation(b:Boolean):void
 58		{
 59			_autoRotation = b;
 60		}
 61		
 62		public function get autoRotation():Boolean
 63		{
 64			return _autoRotation;
 65		}
 66		
 67		/**
 68		 * if autoRotation = true, the rotation is increased by the rotationIncrease value. Default is 1;
 69		 */
 70		public function set rotationIncrease(value:Number):void
 71		{
 72			_rotationIncrease = value;
 73		}
 74		
 75		public function get rotationIncrease():Number
 76		{
 77			return _rotationIncrease;
 78		}
 79		
 80		/**
 81		 * Defines if the animation is translated automatically each update. Ideal to scroll maps. Use setTranslateIncrease to define the offsets.
 82		 */
 83		public function set autoTranslate(b:Boolean):void
 84		{
 85			_autoTranslate = b;
 86			if (b && !_translateIncrease)
 87				_translateIncrease = Vector.<Number>([0, 0]);
 88		}
 89		
 90		public function get autoTranslate():Boolean
 91		{
 92			return _autoTranslate;
 93		}
 94		
 95		/**
 96		 * if autoTranslate = true, animation is translated automatically each update with the u and v values.
 97		 * Note if value are integers, no visible update will be performed. Values are expected to be in 0-1 range.
 98		 */
 99		public function setTranslateIncrease(u:Number, v:Number):void
100		{
101			if (!_translateIncrease)
102				_translateIncrease = Vector.<Number>([0, 0]);
103			_translateIncrease[0] = u;
104			_translateIncrease[1] = v;
105		}
106		
107		public function get translateIncrease():Vector.<Number>
108		{
109			return _translateIncrease;
110		}
111		
112		/**
113		 * @inheritDoc
114		 */
115		public function setRenderState(stage3DProxy:Stage3DProxy, renderable:IRenderable, vertexConstantOffset:int, vertexStreamOffset:int, camera:Camera3D):void
116		{
117			var material:TextureMaterial = renderable.material as TextureMaterial;
118			var subMesh:SubMesh = renderable as SubMesh;
119			
120			if (!material || !subMesh)
121				return;
122			
123			if (autoTranslate) {
124				_deltaFrame.offsetU += _translateIncrease[0];
125				_deltaFrame.offsetV += _translateIncrease[1];
126			}
127			
128			_translate[0] = _deltaFrame.offsetU;
129			_translate[1] = _deltaFrame.offsetV;
130			
131			stage3DProxy._context3D.setProgramConstantsFromVector(Context3DProgramType.VERTEX, vertexConstantOffset, _translate);
132			
133			_uvTransform.identity();
134			
135			if (_autoRotation)
136				_deltaFrame.rotation += _rotationIncrease;
137			
138			if (_deltaFrame.rotation != 0)
139				_uvTransform.rotate(_deltaFrame.rotation*MathConsts.DEGREES_TO_RADIANS);
140			if (_deltaFrame.scaleU != 1 || _deltaFrame.scaleV != 1)
141				_uvTransform.scale(_deltaFrame.scaleU, _deltaFrame.scaleV);
142			
143			_matrix2d[0] = _uvTransform.a;
144			_matrix2d[1] = _uvTransform.b;
145			_matrix2d[3] = _uvTransform.tx;
146			_matrix2d[4] = _uvTransform.c;
147			_matrix2d[5] = _uvTransform.d;
148			_matrix2d[7] = _uvTransform.ty;
149			
150			stage3DProxy._context3D.setProgramConstantsFromVector(Context3DProgramType.VERTEX, vertexConstantOffset + 4, _matrix2d);
151		
152		}
153		
154		/**
155		 * @inheritDoc
156		 */
157		public function play(name:String, transition:IAnimationTransition = null, offset:Number = NaN):void
158		{
159			transition = transition;
160			offset = offset;
161			if (_activeAnimationName == name)
162				return;
163			
164			_activeAnimationName = name;
165			
166			if (!_animationSet.hasAnimation(name))
167				throw new Error("Animation root node " + name + " not found!");
168			
169			_activeNode = _animationSet.getAnimation(name);
170			_activeState = getAnimationState(_activeNode);
171			_activeUVState = _activeState as IUVAnimationState;
172			
173			start();
174		}
175		
176		/**
177		 * Applies the calculated time delta to the active animation state node.
178		 */
179		override protected function updateDeltaTime(dt:Number):void
180		{
181			_absoluteTime += dt;
182			_activeUVState.update(_absoluteTime);
183			
184			var currentUVFrame:UVAnimationFrame = _activeUVState.currentUVFrame;
185			var nextUVFrame:UVAnimationFrame = _activeUVState.nextUVFrame;
186			var blendWeight:Number = _activeUVState.blendWeight;
187			
188			if (currentUVFrame && nextUVFrame) {
189				_deltaFrame.offsetU = currentUVFrame.offsetU + blendWeight*(nextUVFrame.offsetU - currentUVFrame.offsetU);
190				_deltaFrame.offsetV = currentUVFrame.offsetV + blendWeight*(nextUVFrame.offsetV - currentUVFrame.offsetV);
191				_deltaFrame.scaleU = currentUVFrame.scaleU + blendWeight*(nextUVFrame.scaleU - currentUVFrame.scaleU);
192				_deltaFrame.scaleV = currentUVFrame.scaleV + blendWeight*(nextUVFrame.scaleV - currentUVFrame.scaleV);
193				_deltaFrame.rotation = currentUVFrame.rotation + blendWeight*(nextUVFrame.rotation - currentUVFrame.rotation);
194			}
195		}
196		
197		/**
198		 * 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.
199		 * Needs to be called if gpu code is potentially required.
200		 */
201		public function testGPUCompatibility(pass:MaterialPassBase):void
202		{
203		}
204		
205		/**
206		 * @inheritDoc
207		 */
208		public function clone():IAnimator
209		{
210			return new UVAnimator(_uvAnimationSet);
211		}
212	
213	}
214}