1 /**
  2  * Copyright (C) 2009-2012 Klaus Reimer <k@ailis.de>
  3  * See LICENSE.txt for licensing information
  4  * 
  5  * @require threedee.js
  6  * @use threedee/Vector.js
  7  * @use threedee/rendering/Plane.js
  8  */
  9 
 10 /**
 11  * Constructs a new view frustum for the specified screen size and scale
 12  * factor. Optionaly you can specify the near and far clipping distance.
 13  * 
 14  * @param {number} width
 15  *            The screen width in pixels
 16  * @param {number} height
 17  *            The screen height in pixels
 18  * @param {number} scale
 19  *            The scale factor. This is the factor you multiply the X and Y
 20  *            coordinates with before dividing them by the Z coordinate to
 21  *            project the 3D coordinates to 2D coordinates
 22  * @param {number=} far
 23  *            The optional far clipping distance. Defaults to null which
 24  *            means no far clipping is performed.
 25  * @param {number=} near
 26  *            The optional near clipping distance. Defaults to 10
 27  *
 28  * @constructor
 29  * @class
 30  * A frustum.
 31  */
 32 threedee.Frustum = function(width, height, scale, far, near)
 33 {
 34     var xAngle, yAngle, sh, sv, ch, cv;
 35     
 36     xAngle = Math.atan2(width / 2, scale) - 0.0001;
 37     yAngle = Math.atan2(height / 2, scale) - 0.0001;
 38     sh = Math.sin(xAngle);
 39     sv = Math.sin(yAngle);
 40     ch = Math.cos(xAngle);
 41     cv = Math.cos(yAngle);    
 42 
 43     // Create the clipping planes
 44     this.left = new threedee.Plane(new threedee.Vector(ch, 0, sh), 0);
 45     this.right = new threedee.Plane(new threedee.Vector(-ch, 0, sh), 0);
 46     this.top = new threedee.Plane(new threedee.Vector(0, -cv, sv), 0);
 47     this.bottom = new threedee.Plane(new threedee.Vector(0, cv, sv), 0);
 48     this.near = new threedee.Plane(new threedee.Vector(0, 0, 1), -(near ? near : 10));
 49     if (far) this.far = new threedee.Plane(new threedee.Vector(0, 0, -1), -far);
 50 };
 51 
 52 /** 
 53  * The left plane. 
 54  * @private 
 55  * @type {!threedee.Plane} 
 56  */
 57 threedee.Frustum.prototype.left;
 58 
 59 /** 
 60  * The right plane. 
 61  * @private 
 62  * @type {!threedee.Plane} 
 63  */
 64 threedee.Frustum.prototype.right;
 65 
 66 /** 
 67  * The top plane. 
 68  * @private 
 69  * @type {!threedee.Plane} 
 70  */
 71 threedee.Frustum.prototype.top;
 72 
 73 /** 
 74  * The bottom plane. 
 75  * @private 
 76  * @type {!threedee.Plane} 
 77  */
 78 threedee.Frustum.prototype.bottom;
 79 
 80 /** 
 81  * The near plane. 
 82  * @private 
 83  * @type {!threedee.Plane} 
 84  */
 85 threedee.Frustum.prototype.near;
 86 
 87 /** 
 88  * The far plane. 
 89  * @private 
 90  * @type {!threedee.Plane} 
 91  */
 92 threedee.Frustum.prototype.far;
 93 
 94 /**
 95  * Clips the specified polygon. Returns false if polygon was completely
 96  * clipped away and true if it is still visible.
 97  * 
 98  * @param {threedee.RenderPolygon} polygon
 99  *            The polygon to clip.
100  * @return {boolean} 
101  *            False if polygon is still visible, true if it was completely 
102  *            clipped away.
103  */
104 threedee.Frustum.prototype.clipPolygon = function(polygon)
105 {
106     if (polygon.clip(this.near)) return true;
107     if (this.far) if (polygon.clip(this.far)) return true;
108     if (polygon.clip(this.left)) return true;
109     if (polygon.clip(this.right)) return true;
110     if (polygon.clip(this.top)) return true;
111     if (polygon.clip(this.bottom)) return true;
112     return false;
113 };
114