bmoss

PerspectiveOffCenterLens

Nov 23rd, 2012
276
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /*
  2. Usage:
  3. _lens = new PerspectiveOffCenterLens(45);
  4. _lens.left = 0.3;  // move projection center to 0.3 * width of viewPort
  5. _lens.top = 0.5; // center of y-axis (0.5 * with of viewPort)
  6. _view = new View3D(null, new Camera3D(_lens))
  7. */
  8. package ait.components.object3d.camera.lens
  9. {
  10.     import away3d.cameras.lenses.LensBase;
  11.     import away3d.core.math.Matrix3DUtils;
  12.    
  13.     import flash.geom.Vector3D;
  14.    
  15.     public class PerspectiveOffCenterLens extends LensBase
  16.     {
  17.         private var _fieldOfView : Number;
  18.         private var _focalLengthInv : Number;
  19.         private var _yMax : Number;
  20.         private var _xMax : Number;
  21.         private var _left:Number;
  22.         private var _top:Number;
  23.        
  24.        
  25.         public function PerspectiveOffCenterLens(fieldOfView : Number = 60, left:Number = 0.5, top:Number = 0.5)
  26.         {
  27.             this.fieldOfView = fieldOfView;
  28.             this.left = left;
  29.             this.top = top;
  30.         }
  31.        
  32.         public override function project(point3d : Vector3D) : Vector3D
  33.         {
  34.             //In dev version of Away3D 4.1.0 - LensBase.as
  35.             //TODO this function was affected by commit 21a6cea0fa644d812c418aca665e31ab5fb1f73e, applied reverting override
  36.            
  37.             var v : Vector3D = matrix.transformVector(point3d);
  38.                 v.x = v.x/v.w;
  39.                 v.y = -v.y/v.w;
  40.            
  41.                 //z is unaffected by transform
  42.                 //v.z = point3d.z;
  43.            
  44.             return v;
  45.         }
  46.        
  47.         /**
  48.          * Calculates the position of the given normalized coordinates relative to the camera.
  49.          * @param mX The x coordinate relative to the View3D. -1 corresponds to the utter left side of the viewport, 1 to the right.
  50.          * @param mY The y coordinate relative to the View3D. -1 corresponds to the top side of the viewport, 1 to the bottom.
  51.          * @param mZ The distance from the projection plane.
  52.          * @return The scene position of the given screen coordinates.
  53.          */
  54.         public override function unproject(mX:Number, mY:Number, mZ : Number):Vector3D
  55.         {
  56.             //In dev version of Away3D 4.1.0 - LensBase.as
  57.             //TODO this function was affected by commit 21a6cea0fa644d812c418aca665e31ab5fb1f73e, applied reverting override
  58.            
  59.             var v : Vector3D = new Vector3D(mX, -mY, mZ, 1.0);
  60.            
  61.             v = unprojectionMatrix.transformVector(v);
  62.            
  63.             var inv : Number = 1/v.w;
  64.            
  65.             v.x *= inv;
  66.             v.y *= inv;
  67.             v.z *= inv;
  68.             v.w = 1.0;
  69.            
  70.             return v;
  71.         }
  72.        
  73.        
  74.         public function get fieldOfView() : Number { return _fieldOfView; }
  75.         public function get left():Number { return _left };
  76.         public function get top():Number { return _top };
  77.        
  78.         public function set fieldOfView(value : Number) : void
  79.         {
  80.             if (value == _fieldOfView) return;
  81.             _fieldOfView = value;
  82.            
  83.             _focalLengthInv = Math.tan(_fieldOfView*Math.PI/360);
  84.             invalidateMatrix();
  85.         }
  86.        
  87.         /**
  88.          *  
  89.          * @param value
  90.          *
  91.          */    
  92.         public function set left(value:Number):void
  93.         {
  94.             _left = value;
  95.             invalidateMatrix();
  96.         }
  97.        
  98.         /**
  99.          *  
  100.          * @param value
  101.          *
  102.          */    
  103.         public function set top(value:Number):void
  104.         {
  105.             _top = value;
  106.             invalidateMatrix();
  107.         }
  108.        
  109.         /**
  110.          *  
  111.          *
  112.          */    
  113.         override protected function updateMatrix() : void
  114.         {
  115.             var yScale:Number = (1.0/Math.tan( (fieldOfView*Math.PI/360)));
  116.             var xScale:Number = (yScale / _aspectRatio);
  117.            
  118.             var xScaleTotal:Number = 2 * _near / xScale;
  119.             var left:Number = - _left * xScaleTotal;
  120.             var right:Number = (1 - _left) * xScaleTotal;
  121.            
  122.             var yScaleTotal:Number = 2 * _near / yScale;
  123.             var bottom:Number = (_top - 1) * yScaleTotal;
  124.             var top:Number = _top * yScaleTotal;
  125.            
  126.            
  127.             var raw : Vector.<Number> = Matrix3DUtils.RAW_DATA_CONTAINER;
  128.            
  129.             // assume symmetric frustum
  130.             raw[uint(0)] = 2.0*_near/(right-left);
  131.             raw[uint(5)] = -2.0*_near/(bottom-top);
  132.             raw[uint(8)] = -1.0-2.0*left/(right-left);
  133.             raw[uint(9)] = 1.0+2.0*top/(bottom-top);
  134.             raw[uint(5)] = -2.0*_near/(bottom-top);
  135.             raw[uint(10)] = -_far/(_near-_far);
  136.             raw[uint(11)] = 1;
  137.             raw[uint(1)] = raw[uint(2)] = raw[uint(3)] = raw[uint(4)] =
  138.                 raw[uint(6)] = raw[uint(7)] =
  139.                 raw[uint(12)] = raw[uint(13)] = raw[uint(15)] = 0;
  140.             raw[uint(14)] = (_near*_far)/(_near-_far);
  141.            
  142.             _matrix.copyRawDataFrom(raw);
  143.            
  144.             _yMax = _near * _focalLengthInv;
  145.             _xMax = _yMax * _aspectRatio;
  146.            
  147.             var yMaxFar:Number = _far * _focalLengthInv;
  148.             var xMaxFar:Number = yMaxFar * _aspectRatio;
  149.            
  150.             _frustumCorners[0] = _frustumCorners[9] = -_xMax * _left;
  151.             _frustumCorners[3] = _frustumCorners[6] = _xMax * (1 - _left);
  152.             _frustumCorners[1] = _frustumCorners[4] = -_yMax * _top;
  153.             _frustumCorners[7] = _frustumCorners[10] = _yMax * (1 - _top);
  154.            
  155.             _frustumCorners[12] = _frustumCorners[21] = -xMaxFar * _left;
  156.             _frustumCorners[15] = _frustumCorners[18] = xMaxFar * (1 - _left);
  157.             _frustumCorners[13] = _frustumCorners[16] = -yMaxFar * _top;
  158.             _frustumCorners[19] = _frustumCorners[22] = yMaxFar * (1 - _top);
  159.            
  160.             _frustumCorners[2] = _frustumCorners[5] = _frustumCorners[8] = _frustumCorners[11] = _near;
  161.             _frustumCorners[14] = _frustumCorners[17] = _frustumCorners[20] = _frustumCorners[23] = _far;
  162.            
  163.             _matrixInvalid = false;
  164.         }
  165.     }
  166. }
Advertisement
Add Comment
Please, Sign In to add comment