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          = 512.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 
00118         typedef struct 
00119         {
00120                 LLPlane p;
00121                 U8 mask;
00122         } frustum_plane;
00123         frustum_plane mAgentPlanes[7];  //frustum planes in agent space a la gluUnproject (I'm a bastard, I know) - DaveP
00124                                                                         
00125         U32 mPlaneCount;  //defaults to 6, if setUserClipPlane is called, uses user supplied clip plane in
00126 
00127         LLVector3 mWorldPlanePos;               // Position of World Planes (may be offset from camera)
00128 public:
00129         LLVector3 mAgentFrustum[8];  //8 corners of 6-plane frustum
00130         F32     mFrustumCornerDist;             //distance to corner of frustum against far clip plane
00131         
00132 public:
00133         LLCamera();
00134         LLCamera(F32 z_field_of_view, F32 aspect_ratio, S32 view_height_in_pixels, F32 near_plane, F32 far_plane);
00135 
00136         void setUserClipPlane(LLPlane plane);
00137         void disableUserClipPlane();
00138         U8 calcPlaneMask(const LLPlane& plane);
00139         void setView(F32 new_view);
00140         void setViewHeightInPixels(S32 height);
00141         void setAspect(F32 new_aspect);
00142         void setNear(F32 new_near);
00143         void setFar(F32 new_far);
00144 
00145         F32 getView() const                                                     { return mView; }                               // vertical FOV in radians
00146         S32 getViewHeightInPixels() const                       { return mViewHeightInPixels; }
00147         F32 getAspect() const                                           { return mAspect; }                             // width / height
00148         F32 getNear() const                                                     { return mNearPlane; }                  // meters
00149         F32 getFar() const                                                      { return mFarPlane; }                   // meters
00150         
00151         F32 getYaw() const
00152         {
00153                 return atan2f(mXAxis[VY], mXAxis[VX]);
00154         }
00155         F32 getPitch() const
00156         {
00157                 F32 xylen = sqrtf(mXAxis[VX]*mXAxis[VX] + mXAxis[VY]*mXAxis[VY]);
00158                 return atan2f(mXAxis[VZ], xylen);
00159         }
00160 
00161         const LLPlane& getWorldPlane(S32 index) const   { return mWorldPlanes[index]; }
00162         const LLVector3& getWorldPlanePos() const               { return mWorldPlanePos; }
00163         
00164         // Copy mView, mAspect, mNearPlane, and mFarPlane to buffer.
00165         // Return number of bytes copied.
00166         size_t writeFrustumToBuffer(char *buffer) const;
00167 
00168         // Copy mView, mAspect, mNearPlane, and mFarPlane from buffer.
00169         // Return number of bytes copied.
00170         size_t readFrustumFromBuffer(const char *buffer);
00171         void calcAgentFrustumPlanes(LLVector3* frust);
00172         // Returns 1 if partly in, 2 if fully in.
00173         // NOTE: 'center' is in absolute frame.
00174         S32 sphereInFrustumOld(const LLVector3 &center, const F32 radius) const;
00175         S32 sphereInFrustum(const LLVector3 &center, const F32 radius) const;
00176         S32 pointInFrustum(const LLVector3 &point) const { return sphereInFrustum(point, 0.0f); }
00177         S32 sphereInFrustumFull(const LLVector3 &center, const F32 radius) const { return sphereInFrustum(center, radius); }
00178         S32 AABBInFrustum(const LLVector3 &center, const LLVector3& radius);
00179         S32 AABBInFrustumNoFarClip(const LLVector3 &center, const LLVector3& radius);
00180 
00181         //does a quick 'n dirty sphere-sphere check
00182         S32 sphereInFrustumQuick(const LLVector3 &sphere_center, const F32 radius); 
00183 
00184         // Returns height of object in pixels (must be height because field of view
00185         // is based on window height).
00186         F32 heightInPixels(const LLVector3 &center, F32 radius ) const;
00187 
00188         // return the distance from pos to camera if visible (-distance if not visible)
00189         F32 visibleDistance(const LLVector3 &pos, F32 rad, F32 fudgescale = 1.0f, U32 planemask = PLANE_ALL_MASK) const;
00190         F32 visibleHorizDistance(const LLVector3 &pos, F32 rad, F32 fudgescale = 1.0f, U32 planemask = HORIZ_PLANE_ALL_MASK) const;
00191         void setFixedDistance(F32 distance) { mFixedDistance = distance; }
00192         
00193         friend std::ostream& operator<<(std::ostream &s, const LLCamera &C);
00194 
00195 protected:
00196         void calculateFrustumPlanes();
00197         void calculateFrustumPlanes(F32 left, F32 right, F32 top, F32 bottom);
00198         void calculateFrustumPlanesFromWindow(F32 x1, F32 y1, F32 x2, F32 y2);
00199         void calculateWorldFrustumPlanes();
00200 };
00201 
00202 
00203 #endif
00204 
00205 
00206 

Generated on Fri May 16 08:32:14 2008 for SecondLife by  doxygen 1.5.5