llcamera.h

Go to the documentation of this file.
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; // far reaches across two horizontal, not diagonal, regions
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; //1000000.0f; // Max allowed. Not good Z precision though.
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 // An LLCamera is an LLCoorFrame with a view frustum.
00066 // This means that it has several methods for moving it around 
00067 // that are inherited from the LLCoordFrame() class :
00068 //
00069 // setOrigin(), setAxes()
00070 // translate(), rotate()
00071 // roll(), pitch(), yaw()
00072 // etc...
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;                                      // angle between top and bottom frustum planes in radians.
00106         F32 mAspect;                            // width/height
00107         S32 mViewHeightInPixels;        // for ViewHeightInPixels() only
00108         F32 mNearPlane;
00109         F32 mFarPlane;
00110         LLPlane mLocalPlanes[4];
00111         F32 mFixedDistance;                     // Always return this distance, unless < 0
00112         LLVector3 mFrustCenter;         // center of frustum and radius squared for ultra-quick exclusion test
00113         F32 mFrustRadiusSquared;
00114         
00115         LLPlane mWorldPlanes[PLANE_NUM];
00116         LLPlane mHorizPlanes[HORIZ_PLANE_NUM];
00117         LLPlane mAgentPlanes[6];                //frustum in agent space a la gluUnproject (I'm a bastard, I know) - DaveP
00118         U8 mAgentPlaneMask[6];
00119         LLVector3 mWorldPlanePos;               // Position of World Planes (may be offset from camera)
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; }                               // vertical FOV in radians
00134         S32 getViewHeightInPixels() const                       { return mViewHeightInPixels; }
00135         F32 getAspect() const                                           { return mAspect; }                             // width / height
00136         F32 getNear() const                                                     { return mNearPlane; }                  // meters
00137         F32 getFar() const                                                      { return mFarPlane; }                   // meters
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         // Copy mView, mAspect, mNearPlane, and mFarPlane to buffer.
00153         // Return number of bytes copied.
00154         size_t writeFrustumToBuffer(char *buffer) const;
00155 
00156         // Copy mView, mAspect, mNearPlane, and mFarPlane from buffer.
00157         // Return number of bytes copied.
00158         size_t readFrustumFromBuffer(const char *buffer);
00159         void calcAgentFrustumPlanes(LLVector3* frust);
00160         // Returns 1 if partly in, 2 if fully in.
00161         // NOTE: 'center' is in absolute frame.
00162         S32 sphereInFrustumOld(const LLVector3 &center, const F32 radius) const;
00163         S32 sphereInFrustum(const LLVector3 &center, const F32 radius) const;
00164         S32 pointInFrustum(const LLVector3 &point) const { return sphereInFrustum(point, 0.0f); }
00165         S32 sphereInFrustumFull(const LLVector3 &center, const F32 radius) const { return sphereInFrustum(center, radius); }
00166         S32 AABBInFrustum(const LLVector3 &center, const LLVector3& radius);
00167         //does a quick 'n dirty sphere-sphere check
00168         S32 sphereInFrustumQuick(const LLVector3 &sphere_center, const F32 radius); 
00169 
00170         // Returns height of object in pixels (must be height because field of view
00171         // is based on window height).
00172         F32 heightInPixels(const LLVector3 &center, F32 radius ) const;
00173 
00174         // return the distance from pos to camera if visible (-distance if not visible)
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 

Generated on Thu Jul 1 06:08:21 2010 for Second Life Viewer by  doxygen 1.4.7