00001 
00032 #ifndef LL_CAMERA_H
00033 #define LL_CAMERA_H
00034 
00035 
00036 #include "llmath.h"
00037 #include "llcoordframe.h"
00038 #include "llplane.h"
00039 
00040 const F32 DEFAULT_FIELD_OF_VIEW         = 60.f * DEG_TO_RAD;
00041 const F32 DEFAULT_ASPECT_RATIO          = 640.f / 480.f;
00042 const F32 DEFAULT_NEAR_PLANE            = 0.25f;
00043 const F32 DEFAULT_FAR_PLANE             = 64.f; 
00044 
00045 const F32 MAX_FIELD_OF_VIEW = F_PI;
00046 const F32 MAX_ASPECT_RATIO      = 50.0f;
00047 const F32 MAX_NEAR_PLANE        = 10.f;
00048 const F32 MAX_FAR_PLANE         = 100000.0f; 
00049 const F32 MAX_FAR_CLIP          = 1024.0f;
00050 
00051 const F32 MIN_FIELD_OF_VIEW = 0.1f;
00052 const F32 MIN_ASPECT_RATIO      = 0.02f;
00053 const F32 MIN_NEAR_PLANE        = 0.1f;
00054 const F32 MIN_FAR_PLANE         = 0.2f;
00055 
00056 static const LLVector3 X_AXIS(1.f,0.f,0.f);
00057 static const LLVector3 Y_AXIS(0.f,1.f,0.f);
00058 static const LLVector3 Z_AXIS(0.f,0.f,1.f);
00059 
00060 static const LLVector3 NEG_X_AXIS(-1.f,0.f,0.f);
00061 static const LLVector3 NEG_Y_AXIS(0.f,-1.f,0.f);
00062 static const LLVector3 NEG_Z_AXIS(0.f,0.f,-1.f);
00063 
00064 
00065 
00066 
00067 
00068 
00069 
00070 
00071 
00072 
00073 
00074 
00075 class LLCamera
00076 :       public LLCoordFrame
00077 {
00078 public:
00079         enum {
00080                 PLANE_LEFT = 0,
00081                 PLANE_RIGHT = 1,
00082                 PLANE_BOTTOM = 2,
00083                 PLANE_TOP = 3,
00084                 PLANE_NUM = 4
00085         };
00086         enum {
00087                 PLANE_LEFT_MASK = (1<<PLANE_LEFT),
00088                 PLANE_RIGHT_MASK = (1<<PLANE_RIGHT),
00089                 PLANE_BOTTOM_MASK = (1<<PLANE_BOTTOM),
00090                 PLANE_TOP_MASK = (1<<PLANE_TOP),
00091                 PLANE_ALL_MASK = 0xf
00092         };
00093         enum {
00094                 HORIZ_PLANE_LEFT = 0,
00095                 HORIZ_PLANE_RIGHT = 1,
00096                 HORIZ_PLANE_NUM = 2
00097         };
00098         enum {
00099                 HORIZ_PLANE_LEFT_MASK = (1<<HORIZ_PLANE_LEFT),
00100                 HORIZ_PLANE_RIGHT_MASK = (1<<HORIZ_PLANE_RIGHT),
00101                 HORIZ_PLANE_ALL_MASK = 0x3
00102         };
00103 
00104 protected:
00105         F32 mView;                                      
00106         F32 mAspect;                            
00107         S32 mViewHeightInPixels;        
00108         F32 mNearPlane;
00109         F32 mFarPlane;
00110         LLPlane mLocalPlanes[4];
00111         F32 mFixedDistance;                     
00112         LLVector3 mFrustCenter;         
00113         F32 mFrustRadiusSquared;
00114         
00115         LLPlane mWorldPlanes[PLANE_NUM];
00116         LLPlane mHorizPlanes[HORIZ_PLANE_NUM];
00117         LLPlane mAgentPlanes[6];                
00118         U8 mAgentPlaneMask[6];
00119         LLVector3 mWorldPlanePos;               
00120 public:
00121         LLVector3 mAgentFrustum[8];
00122         
00123 public:
00124         LLCamera();
00125         LLCamera(F32 z_field_of_view, F32 aspect_ratio, S32 view_height_in_pixels, F32 near_plane, F32 far_plane);
00126 
00127         void setView(F32 new_view);
00128         void setViewHeightInPixels(S32 height);
00129         void setAspect(F32 new_aspect);
00130         void setNear(F32 new_near);
00131         void setFar(F32 new_far);
00132 
00133         F32 getView() const                                                     { return mView; }                               
00134         S32 getViewHeightInPixels() const                       { return mViewHeightInPixels; }
00135         F32 getAspect() const                                           { return mAspect; }                             
00136         F32 getNear() const                                                     { return mNearPlane; }                  
00137         F32 getFar() const                                                      { return mFarPlane; }                   
00138         
00139         F32 getYaw() const
00140         {
00141                 return atan2f(mXAxis[VY], mXAxis[VX]);
00142         }
00143         F32 getPitch() const
00144         {
00145                 F32 xylen = sqrtf(mXAxis[VX]*mXAxis[VX] + mXAxis[VY]*mXAxis[VY]);
00146                 return atan2f(mXAxis[VZ], xylen);
00147         }
00148 
00149         const LLPlane& getWorldPlane(S32 index) const   { return mWorldPlanes[index]; }
00150         const LLVector3& getWorldPlanePos() const               { return mWorldPlanePos; }
00151         
00152         
00153         
00154         size_t writeFrustumToBuffer(char *buffer) const;
00155 
00156         
00157         
00158         size_t readFrustumFromBuffer(const char *buffer);
00159         void calcAgentFrustumPlanes(LLVector3* frust);
00160         
00161         
00162         S32 sphereInFrustumOld(const LLVector3 ¢er, const F32 radius) const;
00163         S32 sphereInFrustum(const LLVector3 ¢er, const F32 radius) const;
00164         S32 pointInFrustum(const LLVector3 &point) const { return sphereInFrustum(point, 0.0f); }
00165         S32 sphereInFrustumFull(const LLVector3 ¢er, const F32 radius) const { return sphereInFrustum(center, radius); }
00166         S32 AABBInFrustum(const LLVector3 ¢er, const LLVector3& radius);
00167         
00168         S32 sphereInFrustumQuick(const LLVector3 &sphere_center, const F32 radius); 
00169 
00170         
00171         
00172         F32 heightInPixels(const LLVector3 ¢er, F32 radius ) const;
00173 
00174         
00175         F32 visibleDistance(const LLVector3 &pos, F32 rad, F32 fudgescale = 1.0f, U32 planemask = PLANE_ALL_MASK) const;
00176         F32 visibleHorizDistance(const LLVector3 &pos, F32 rad, F32 fudgescale = 1.0f, U32 planemask = HORIZ_PLANE_ALL_MASK) const;
00177         void setFixedDistance(F32 distance) { mFixedDistance = distance; }
00178         
00179         friend std::ostream& operator<<(std::ostream &s, const LLCamera &C);
00180 
00181 protected:
00182         void calculateFrustumPlanes();
00183         void calculateFrustumPlanes(F32 left, F32 right, F32 top, F32 bottom);
00184         void calculateFrustumPlanesFromWindow(F32 x1, F32 y1, F32 x2, F32 y2);
00185         void calculateWorldFrustumPlanes();
00186 };
00187 
00188 
00189 #endif
00190 
00191 
00192