PageRenderTime 431ms CodeModel.GetById 163ms app.highlight 11ms RepoModel.GetById 253ms app.codeStats 0ms

/src/away3d/cameras/lenses/LensBase.as

http://github.com/away3d/away3d-core-fp11
ActionScript | 215 lines | 137 code | 27 blank | 51 comment | 11 complexity | cbb1c67cf56b04b9265afe706066927d MD5 | raw file
  1package away3d.cameras.lenses
  2{
  3	import away3d.cameras.Camera3D;
  4	import away3d.core.math.Matrix3DUtils;
  5
  6	import flash.events.EventDispatcher;
  7	import flash.geom.Matrix3D;
  8	import flash.geom.Rectangle;
  9	import flash.geom.Vector3D;
 10	
 11	import away3d.arcane;
 12	import away3d.errors.AbstractMethodError;
 13	import away3d.events.LensEvent;
 14	
 15	use namespace arcane;
 16	
 17	/**
 18	 * An abstract base class for all lens classes. Lens objects provides a projection matrix that transforms 3D geometry to normalized homogeneous coordinates.
 19	 */
 20	public class LensBase extends EventDispatcher
 21	{
 22		protected var _matrix:Matrix3D;
 23		protected var _scissorRect:Rectangle = new Rectangle();
 24		protected var _viewPort:Rectangle = new Rectangle();
 25		protected var _near:Number = 20;
 26		protected var _far:Number = 3000;
 27		protected var _aspectRatio:Number = 1;
 28		
 29		protected var _matrixInvalid:Boolean = true;
 30		protected var _frustumCorners:Vector.<Number> = new Vector.<Number>(8*3, true);
 31		
 32		private var _unprojection:Matrix3D;
 33		private var _unprojectionInvalid:Boolean = true;
 34		/**
 35		 * Creates a new LensBase object.
 36		 */
 37		public function LensBase()
 38		{
 39			_matrix = new Matrix3D();
 40		}
 41		
 42		/**
 43		 * Retrieves the corner points of the lens frustum.
 44		 */
 45		public function get frustumCorners():Vector.<Number>
 46		{
 47			return _frustumCorners;
 48		}
 49		
 50		public function set frustumCorners(frustumCorners:Vector.<Number>):void
 51		{
 52			_frustumCorners = frustumCorners;
 53		}
 54		
 55		/**
 56		 * The projection matrix that transforms 3D geometry to normalized homogeneous coordinates.
 57		 */
 58		public function get matrix():Matrix3D
 59		{
 60			if (_matrixInvalid) {
 61				updateMatrix();
 62				_matrixInvalid = false;
 63			}
 64			return _matrix;
 65		}
 66		
 67		public function set matrix(value:Matrix3D):void
 68		{
 69			_matrix = value;
 70			invalidateMatrix();
 71		}
 72		
 73		/**
 74		 * The distance to the near plane of the frustum. Anything behind near plane will not be rendered.
 75		 */
 76		public function get near():Number
 77		{
 78			return _near;
 79		}
 80		
 81		public function set near(value:Number):void
 82		{
 83			if (value == _near)
 84				return;
 85			_near = value;
 86			invalidateMatrix();
 87		}
 88		
 89		/**
 90		 * The distance to the far plane of the frustum. Anything beyond the far plane will not be rendered.
 91		 */
 92		public function get far():Number
 93		{
 94			return _far;
 95		}
 96		
 97		public function set far(value:Number):void
 98		{
 99			if (value == _far)
100				return;
101			_far = value;
102			invalidateMatrix();
103		}
104		
105		/**
106		 * Calculates the normalised position in screen space of the given scene position relative to the camera.
107		 *
108		 * @param point3d the position vector of the scene coordinates to be projected.
109		 * @param v The destination Vector3D object
110		 * @return The normalised screen position of the given scene coordinates relative to the camera.
111		 */
112		public function project(point3d:Vector3D, v:Vector3D = null):Vector3D
113		{
114			if(!v) v = new Vector3D();
115			Matrix3DUtils.transformVector(matrix, point3d, v);
116			v.x = v.x/v.w;
117			v.y = -v.y/v.w;
118			
119			//z is unaffected by transform
120			v.z = point3d.z;
121			
122			return v;
123		}
124		
125		public function get unprojectionMatrix():Matrix3D
126		{
127			if (_unprojectionInvalid) {
128				_unprojection ||= new Matrix3D();
129				_unprojection.copyFrom(matrix);
130				_unprojection.invert();
131				_unprojectionInvalid = false;
132			}
133			
134			return _unprojection;
135		}
136		
137		/**
138		 * Calculates the scene position relative to the camera of the given normalized coordinates in screen space.
139		 *
140		 * @param nX The normalised x coordinate in screen space, -1 corresponds to the left edge of the viewport, 1 to the right.
141		 * @param nY The normalised y coordinate in screen space, -1 corresponds to the top edge of the viewport, 1 to the bottom.
142		 * @param sZ The z coordinate in screen space, representing the distance into the screen.
143		 * @param v The destination Vector3D object
144		 * @return The scene position relative to the camera of the given screen coordinates.
145		 */
146		public function unproject(nX:Number, nY:Number, sZ:Number, v:Vector3D = null):Vector3D
147		{
148			throw new AbstractMethodError();
149		}
150		
151		/**
152		 * Creates an exact duplicate of the lens
153		 */
154		public function clone():LensBase
155		{
156			throw new AbstractMethodError();
157		}
158		
159		/**
160		 * The aspect ratio (width/height) of the view. Set by the renderer.
161		 * @private
162		 */
163		arcane function get aspectRatio():Number
164		{
165			return _aspectRatio;
166		}
167		
168		arcane function set aspectRatio(value:Number):void
169		{
170			if (_aspectRatio == value || (value*0) != 0)
171				return;
172			_aspectRatio = value;
173			invalidateMatrix();
174		}
175		
176		/**
177		 * Invalidates the projection matrix, which will cause it to be updated on the next request.
178		 */
179		protected function invalidateMatrix():void
180		{
181			_matrixInvalid = true;
182			_unprojectionInvalid = true;
183			// notify the camera that the lens matrix is changing. this will mark the 
184			// viewProjectionMatrix in the camera as invalid, and force the matrix to
185			// be re-queried from the lens, and therefore rebuilt.
186			dispatchEvent(new LensEvent(LensEvent.MATRIX_CHANGED, this));
187		}
188
189		/**
190		 * Updates the matrix
191		 */
192		protected function updateMatrix():void
193		{
194			throw new AbstractMethodError();
195		}
196		
197		arcane function updateScissorRect(x:Number, y:Number, width:Number, height:Number):void
198		{
199			_scissorRect.x = x;
200			_scissorRect.y = y;
201			_scissorRect.width = width;
202			_scissorRect.height = height;
203			invalidateMatrix();
204		}
205		
206		arcane function updateViewport(x:Number, y:Number, width:Number, height:Number):void
207		{
208			_viewPort.x = x;
209			_viewPort.y = y;
210			_viewPort.width = width;
211			_viewPort.height = height;
212			invalidateMatrix();
213		}
214	}
215}