llcamera.cpp

Go to the documentation of this file.
00001 
00032 #include "linden_common.h"
00033 
00034 #include "llmath.h"
00035 #include "llcamera.h"
00036 
00037 // ---------------- Constructors and destructors ----------------
00038 
00039 LLCamera::LLCamera() :
00040         LLCoordFrame(),
00041         mView(DEFAULT_FIELD_OF_VIEW),
00042         mAspect(DEFAULT_ASPECT_RATIO),
00043         mViewHeightInPixels( -1 ),                      // invalid height
00044         mNearPlane(DEFAULT_NEAR_PLANE),
00045         mFarPlane(DEFAULT_FAR_PLANE),
00046         mFixedDistance(-1.f),
00047         mPlaneCount(6)
00048 {
00049         calculateFrustumPlanes();
00050 } 
00051 
00052 
00053 LLCamera::LLCamera(F32 z_field_of_view, F32 aspect_ratio, S32 view_height_in_pixels, F32 near_plane, F32 far_plane) :
00054         LLCoordFrame(),
00055         mView(z_field_of_view),
00056         mAspect(aspect_ratio),
00057         mViewHeightInPixels(view_height_in_pixels),
00058         mNearPlane(near_plane),
00059         mFarPlane(far_plane),
00060         mFixedDistance(-1.f),
00061         mPlaneCount(6)
00062 {
00063         if (mView < MIN_FIELD_OF_VIEW)                  { mView = MIN_FIELD_OF_VIEW; }
00064         else if (mView > MAX_FIELD_OF_VIEW)             { mView = MAX_FIELD_OF_VIEW; }
00065 
00066         if (mAspect < MIN_ASPECT_RATIO)                 { mAspect = MIN_ASPECT_RATIO; }
00067         else if (mAspect > MAX_ASPECT_RATIO)    { mAspect = MAX_ASPECT_RATIO; }
00068 
00069         if (mNearPlane < MIN_NEAR_PLANE)                { mNearPlane = MIN_NEAR_PLANE; }
00070         else if (mNearPlane > MAX_NEAR_PLANE)   { mNearPlane = MAX_NEAR_PLANE; }
00071 
00072         if (mFarPlane < 0)                                              { mFarPlane = DEFAULT_FAR_PLANE; }
00073         else if (mFarPlane < MIN_FAR_PLANE)             { mFarPlane = MIN_FAR_PLANE; }
00074         else if (mFarPlane > MAX_FAR_PLANE)             { mFarPlane = MAX_FAR_PLANE; }
00075 
00076         calculateFrustumPlanes();
00077 } 
00078 
00079 
00080 
00081 // ---------------- LLCamera::setFoo() member functions ----------------
00082 
00083 void LLCamera::setUserClipPlane(LLPlane plane)
00084 {
00085         mPlaneCount = 7;
00086         mAgentPlanes[6].p = plane;
00087         mAgentPlanes[6].mask = calcPlaneMask(plane);
00088 }
00089 
00090 void LLCamera::disableUserClipPlane()
00091 {
00092         mPlaneCount = 6;
00093 }
00094 
00095 void LLCamera::setView(F32 field_of_view) 
00096 {
00097         mView = field_of_view;
00098         if (mView < MIN_FIELD_OF_VIEW)                  { mView = MIN_FIELD_OF_VIEW; }
00099         else if (mView > MAX_FIELD_OF_VIEW)             { mView = MAX_FIELD_OF_VIEW; }
00100         calculateFrustumPlanes();
00101 }
00102 
00103 void LLCamera::setViewHeightInPixels(S32 height)
00104 {
00105         mViewHeightInPixels = height;
00106 
00107         // Don't really need to do this, but update the pixel meter ratio with it.
00108         calculateFrustumPlanes();
00109 }
00110 
00111 void LLCamera::setAspect(F32 aspect_ratio) 
00112 {
00113         mAspect = aspect_ratio;
00114         if (mAspect < MIN_ASPECT_RATIO)                 { mAspect = MIN_ASPECT_RATIO; }
00115         else if (mAspect > MAX_ASPECT_RATIO)    { mAspect = MAX_ASPECT_RATIO; }
00116         calculateFrustumPlanes();
00117 }
00118 
00119 
00120 void LLCamera::setNear(F32 near_plane) 
00121 {
00122         mNearPlane = near_plane;
00123         if (mNearPlane < MIN_NEAR_PLANE)                { mNearPlane = MIN_NEAR_PLANE; }
00124         else if (mNearPlane > MAX_NEAR_PLANE)   { mNearPlane = MAX_NEAR_PLANE; }
00125         calculateFrustumPlanes();
00126 }
00127 
00128 
00129 void LLCamera::setFar(F32 far_plane) 
00130 {
00131         mFarPlane = far_plane;
00132         if (mFarPlane < MIN_FAR_PLANE)                  { mFarPlane = MIN_FAR_PLANE; }
00133         else if (mFarPlane > MAX_FAR_PLANE)             { mFarPlane = MAX_FAR_PLANE; }
00134         calculateFrustumPlanes();
00135 }
00136 
00137 
00138 // ---------------- read/write to buffer ---------------- 
00139 
00140 size_t LLCamera::writeFrustumToBuffer(char *buffer) const
00141 {
00142         memcpy(buffer, &mView, sizeof(F32));            /* Flawfinder: ignore */                
00143         buffer += sizeof(F32);
00144         memcpy(buffer, &mAspect, sizeof(F32));          /* Flawfinder: ignore */
00145         buffer += sizeof(F32);
00146         memcpy(buffer, &mNearPlane, sizeof(F32));       /* Flawfinder: ignore */
00147         buffer += sizeof(F32);
00148         memcpy(buffer, &mFarPlane, sizeof(F32));                /* Flawfinder: ignore */
00149         return 4*sizeof(F32);
00150 }
00151 
00152 size_t LLCamera::readFrustumFromBuffer(const char *buffer)
00153 {
00154         memcpy(&mView, buffer, sizeof(F32));            /* Flawfinder: ignore */
00155         buffer += sizeof(F32);
00156         memcpy(&mAspect, buffer, sizeof(F32));          /* Flawfinder: ignore */
00157         buffer += sizeof(F32);
00158         memcpy(&mNearPlane, buffer, sizeof(F32));       /* Flawfinder: ignore */
00159         buffer += sizeof(F32);
00160         memcpy(&mFarPlane, buffer, sizeof(F32));                /* Flawfinder: ignore */
00161         return 4*sizeof(F32);
00162 }
00163 
00164 
00165 // ---------------- test methods  ---------------- 
00166 
00167 S32 LLCamera::AABBInFrustum(const LLVector3 &center, const LLVector3& radius) 
00168 {
00169         static const LLVector3 scaler[] = {
00170                 LLVector3(-1,-1,-1),
00171                 LLVector3( 1,-1,-1),
00172                 LLVector3(-1, 1,-1),
00173                 LLVector3( 1, 1,-1),
00174                 LLVector3(-1,-1, 1),
00175                 LLVector3( 1,-1, 1),
00176                 LLVector3(-1, 1, 1),
00177                 LLVector3( 1, 1, 1)
00178         };
00179 
00180         U8 mask = 0;
00181         S32 result = 2;
00182 
00183         for (U32 i = 0; i < mPlaneCount; i++)
00184         {
00185                 mask = mAgentPlanes[i].mask;
00186                 LLPlane p = mAgentPlanes[i].p;
00187                 LLVector3 n = LLVector3(p);
00188                 float d = p.mV[3];
00189                 LLVector3 rscale = radius.scaledVec(scaler[mask]);
00190 
00191                 LLVector3 minp = center - rscale;
00192                 LLVector3 maxp = center + rscale;
00193 
00194                 if (n * minp > -d) 
00195                 {
00196                         return 0;
00197                 }
00198         
00199                 if (n * maxp > -d)
00200                 {
00201                         result = 1;
00202                 }
00203         }
00204 
00205         return result;
00206 }
00207 
00208 S32 LLCamera::AABBInFrustumNoFarClip(const LLVector3 &center, const LLVector3& radius) 
00209 {
00210         static const LLVector3 scaler[] = {
00211                 LLVector3(-1,-1,-1),
00212                 LLVector3( 1,-1,-1),
00213                 LLVector3(-1, 1,-1),
00214                 LLVector3( 1, 1,-1),
00215                 LLVector3(-1,-1, 1),
00216                 LLVector3( 1,-1, 1),
00217                 LLVector3(-1, 1, 1),
00218                 LLVector3( 1, 1, 1)
00219         };
00220 
00221         U8 mask = 0;
00222         S32 result = 2;
00223 
00224         for (U32 i = 0; i < mPlaneCount; i++)
00225         {
00226                 if (i == 5)
00227                 {
00228                         continue;
00229                 }
00230 
00231                 mask = mAgentPlanes[i].mask;
00232                 LLPlane p = mAgentPlanes[i].p;
00233                 LLVector3 n = LLVector3(p);
00234                 float d = p.mV[3];
00235                 LLVector3 rscale = radius.scaledVec(scaler[mask]);
00236 
00237                 LLVector3 minp = center - rscale;
00238                 LLVector3 maxp = center + rscale;
00239 
00240                 if (n * minp > -d) 
00241                 {
00242                         return 0;
00243                 }
00244         
00245                 if (n * maxp > -d)
00246                 {
00247                         result = 1;
00248                 }
00249         }
00250 
00251         return result;
00252 }
00253 
00254 int LLCamera::sphereInFrustumQuick(const LLVector3 &sphere_center, const F32 radius) 
00255 {
00256         LLVector3 dist = sphere_center-mFrustCenter;
00257         float dsq = dist * dist;
00258         float rsq = mFarPlane*0.5f + radius;
00259         rsq *= rsq;
00260 
00261         if (dsq < rsq) 
00262         {
00263                 return 1;
00264         }
00265         
00266         return 0;       
00267 }
00268 
00269 // HACK: This version is still around because the version below doesn't work
00270 // unless the agent planes are initialized.
00271 // Return 1 if sphere is in frustum, 2 if fully in frustum, otherwise 0.
00272 // NOTE: 'center' is in absolute frame.
00273 int LLCamera::sphereInFrustumOld(const LLVector3 &sphere_center, const F32 radius) const 
00274 {
00275         // Returns 1 if sphere is in frustum, 0 if not.
00276         // modified so that default view frust is along X with Z vertical
00277         F32 x, y, z, rightDist, leftDist, topDist, bottomDist;
00278 
00279         // Subtract the view position 
00280         //LLVector3 relative_center;
00281         //relative_center = sphere_center - getOrigin();
00282         LLVector3 rel_center(sphere_center);
00283         rel_center -= mOrigin;
00284 
00285         bool all_in = TRUE;
00286 
00287         // Transform relative_center.x to camera frame
00288         x = mXAxis * rel_center;
00289         if (x < MIN_NEAR_PLANE - radius)
00290         {
00291                 return 0;
00292         }
00293         else if (x < MIN_NEAR_PLANE + radius)
00294         {
00295                 all_in = FALSE;
00296         }
00297 
00298         if (x > mFarPlane + radius)
00299         {
00300                 return 0;
00301         }
00302         else if (x > mFarPlane - radius)
00303         {
00304                 all_in = FALSE;
00305         }
00306 
00307         // Transform relative_center.y to camera frame
00308         y = mYAxis * rel_center;
00309 
00310         // distance to plane is the dot product of (x, y, 0) * plane_normal
00311         rightDist = x * mLocalPlanes[PLANE_RIGHT][VX] + y * mLocalPlanes[PLANE_RIGHT][VY];
00312         if (rightDist < -radius)
00313         {
00314                 return 0;
00315         }
00316         else if (rightDist < radius)
00317         {
00318                 all_in = FALSE;
00319         }
00320 
00321         leftDist = x * mLocalPlanes[PLANE_LEFT][VX] + y * mLocalPlanes[PLANE_LEFT][VY];
00322         if (leftDist < -radius)
00323         {
00324                 return 0;
00325         }
00326         else if (leftDist < radius)
00327         {
00328                 all_in = FALSE;
00329         }
00330 
00331         // Transform relative_center.y to camera frame
00332         z = mZAxis * rel_center;
00333 
00334         topDist = x * mLocalPlanes[PLANE_TOP][VX] + z * mLocalPlanes[PLANE_TOP][VZ];
00335         if (topDist < -radius)
00336         {
00337                 return 0;
00338         }
00339         else if (topDist < radius)
00340         {
00341                 all_in = FALSE;
00342         }
00343 
00344         bottomDist = x * mLocalPlanes[PLANE_BOTTOM][VX] + z * mLocalPlanes[PLANE_BOTTOM][VZ];
00345         if (bottomDist < -radius)
00346         {
00347                 return 0;
00348         }
00349         else if (bottomDist < radius)
00350         {
00351                 all_in = FALSE;
00352         }
00353 
00354         if (all_in)
00355         {
00356                 return 2;
00357         }
00358 
00359         return 1;
00360 }
00361 
00362 
00363 // HACK: This (presumably faster) version only currently works if you set up the
00364 // frustum planes using GL.  At some point we should get those planes through another
00365 // mechanism, and then we can get rid of the "old" version above.
00366 
00367 // Return 1 if sphere is in frustum, 2 if fully in frustum, otherwise 0.
00368 // NOTE: 'center' is in absolute frame.
00369 int LLCamera::sphereInFrustum(const LLVector3 &sphere_center, const F32 radius) const 
00370 {
00371         // Returns 1 if sphere is in frustum, 0 if not.
00372         int res = 2;
00373         for (int i = 0; i < 6; i++)
00374         {
00375                 float d = mAgentPlanes[i].p.dist(sphere_center);
00376 
00377                 if (d > radius) 
00378                 {
00379                         return 0;
00380                 }
00381 
00382                 if (d > -radius)
00383                 {
00384                         res = 1;
00385                 }
00386         }
00387 
00388         return res;
00389 }
00390 
00391 
00392 // return height of a sphere of given radius, located at center, in pixels
00393 F32 LLCamera::heightInPixels(const LLVector3 &center, F32 radius ) const
00394 {
00395         if (radius == 0.f) return 0.f;
00396 
00397         // If height initialized
00398         if (mViewHeightInPixels > -1)
00399         {
00400                 // Convert sphere to coord system with 0,0,0 at camera
00401                 LLVector3 vec = center - mOrigin;
00402 
00403                 // Compute distance to sphere
00404                 F32 dist = vec.magVec();
00405 
00406                 // Calculate angle of whole object
00407                 F32 angle = 2.0f * (F32) atan2(radius, dist);
00408 
00409                 // Calculate fraction of field of view
00410                 F32 fraction_of_fov = angle / mView;
00411 
00412                 // Compute number of pixels tall, based on vertical field of view
00413                 return (fraction_of_fov * mViewHeightInPixels);
00414         }
00415         else
00416         {
00417                 // return invalid height
00418                 return -1.0f;
00419         }
00420 }
00421 
00422 // If pos is visible, return the distance from pos to the camera.
00423 // Use fudge distance to scale rad against top/bot/left/right planes
00424 // Otherwise, return -distance
00425 F32 LLCamera::visibleDistance(const LLVector3 &pos, F32 rad, F32 fudgedist, U32 planemask) const
00426 {
00427         if (mFixedDistance > 0)
00428         {
00429                 return mFixedDistance;
00430         }
00431         LLVector3 dvec = pos - mOrigin;
00432         // Check visibility
00433         F32 dist = dvec.magVec();
00434         if (dist > rad)
00435         {
00436                 F32 dp,tdist;
00437                 dp = dvec * mXAxis;
00438                 if (dp < -rad)
00439                         return -dist;
00440 
00441                 rad *= fudgedist;
00442                 LLVector3 tvec(pos);
00443                 for (int p=0; p<PLANE_NUM; p++)
00444                 {
00445                         if (!(planemask & (1<<p)))
00446                                 continue;
00447                         tdist = -(mWorldPlanes[p].dist(tvec));
00448                         if (tdist > rad)
00449                                 return -dist;
00450                 }
00451         }
00452         return dist;
00453 }
00454 
00455 // Like visibleDistance, except uses mHorizPlanes[], which are left and right
00456 //  planes perpindicular to (0,0,1) in world space
00457 F32 LLCamera::visibleHorizDistance(const LLVector3 &pos, F32 rad, F32 fudgedist, U32 planemask) const
00458 {
00459         if (mFixedDistance > 0)
00460         {
00461                 return mFixedDistance;
00462         }
00463         LLVector3 dvec = pos - mOrigin;
00464         // Check visibility
00465         F32 dist = dvec.magVec();
00466         if (dist > rad)
00467         {
00468                 rad *= fudgedist;
00469                 LLVector3 tvec(pos);
00470                 for (int p=0; p<HORIZ_PLANE_NUM; p++)
00471                 {
00472                         if (!(planemask & (1<<p)))
00473                                 continue;
00474                         F32 tdist = -(mHorizPlanes[p].dist(tvec));
00475                         if (tdist > rad)
00476                                 return -dist;
00477                 }
00478         }
00479         return dist;
00480 }
00481 
00482 // ---------------- friends and operators ----------------  
00483 
00484 std::ostream& operator<<(std::ostream &s, const LLCamera &C) 
00485 {
00486         s << "{ \n";
00487         s << "  Center = " << C.getOrigin() << "\n";
00488         s << "  AtAxis = " << C.getXAxis() << "\n";
00489         s << "  LeftAxis = " << C.getYAxis() << "\n";
00490         s << "  UpAxis = " << C.getZAxis() << "\n";
00491         s << "  View = " << C.getView() << "\n";
00492         s << "  Aspect = " << C.getAspect() << "\n";
00493         s << "  NearPlane   = " << C.mNearPlane << "\n";
00494         s << "  FarPlane    = " << C.mFarPlane << "\n";
00495         s << "  TopPlane    = " << C.mLocalPlanes[LLCamera::PLANE_TOP][VX] << "  " 
00496                                                         << C.mLocalPlanes[LLCamera::PLANE_TOP][VY] << "  " 
00497                                                         << C.mLocalPlanes[LLCamera::PLANE_TOP][VZ] << "\n";
00498         s << "  BottomPlane = " << C.mLocalPlanes[LLCamera::PLANE_BOTTOM][VX] << "  " 
00499                                                         << C.mLocalPlanes[LLCamera::PLANE_BOTTOM][VY] << "  " 
00500                                                         << C.mLocalPlanes[LLCamera::PLANE_BOTTOM][VZ] << "\n";
00501         s << "  LeftPlane   = " << C.mLocalPlanes[LLCamera::PLANE_LEFT][VX] << "  " 
00502                                                         << C.mLocalPlanes[LLCamera::PLANE_LEFT][VY] << "  " 
00503                                                         << C.mLocalPlanes[LLCamera::PLANE_LEFT][VZ] << "\n";
00504         s << "  RightPlane  = " << C.mLocalPlanes[LLCamera::PLANE_RIGHT][VX] << "  " 
00505                                                         << C.mLocalPlanes[LLCamera::PLANE_RIGHT][VY] << "  " 
00506                                                         << C.mLocalPlanes[LLCamera::PLANE_RIGHT][VZ] << "\n";
00507         s << "}";
00508         return s;
00509 }
00510 
00511 
00512 
00513 // ----------------  private member functions ----------------
00514 
00515 void LLCamera::calculateFrustumPlanes() 
00516 {
00517         // The planes only change when any of the frustum descriptions change.
00518         // They are not affected by changes of the position of the Frustum
00519         // because they are known in the view frame and the position merely
00520         // provides information on how to get from the absolute frame to the 
00521         // view frame.
00522 
00523         F32 left,right,top,bottom;
00524         top = mFarPlane * (F32)tanf(0.5f * mView);
00525         bottom = -top;
00526         left = top * mAspect;
00527         right = -left;
00528 
00529         calculateFrustumPlanes(left, right, top, bottom);
00530 }
00531 
00532 LLPlane planeFromPoints(LLVector3 p1, LLVector3 p2, LLVector3 p3)
00533 {
00534         LLVector3 n = ((p2-p1)%(p3-p1));
00535         n.normVec();
00536 
00537         return LLPlane(p1, n);
00538 }
00539 
00540 U8 LLCamera::calcPlaneMask(const LLPlane& plane)
00541 {
00542         U8 mask = 0;
00543         
00544         if (plane.mV[0] >= 0)
00545         {
00546                 mask |= 1;
00547         }
00548         if (plane.mV[1] >= 0)
00549         {
00550                 mask |= 2;
00551         }
00552         if (plane.mV[2] >= 0)
00553         {
00554                 mask |= 4;
00555         }
00556 
00557         return mask;
00558 }
00559 
00560 void LLCamera::calcAgentFrustumPlanes(LLVector3* frust)
00561 {
00562 
00563         for (int i = 0; i < 8; i++)
00564         {
00565                 mAgentFrustum[i] = frust[i];
00566         }
00567 
00568         mFrustumCornerDist = (frust[5] - getOrigin()).magVec();
00569 
00570         //frust contains the 8 points of the frustum, calculate 6 planes
00571 
00572         //order of planes is important, keep most likely to fail in the front of the list
00573 
00574         //near - frust[0], frust[1], frust[2]
00575         mAgentPlanes[2].p = planeFromPoints(frust[0], frust[1], frust[2]);
00576 
00577         //far  
00578         mAgentPlanes[5].p = planeFromPoints(frust[5], frust[4], frust[6]);
00579 
00580         //left  
00581         mAgentPlanes[0].p = planeFromPoints(frust[4], frust[0], frust[7]);
00582 
00583         //right  
00584         mAgentPlanes[1].p = planeFromPoints(frust[1], frust[5], frust[6]);
00585 
00586         //top  
00587         mAgentPlanes[4].p = planeFromPoints(frust[3], frust[2], frust[6]);
00588 
00589         //bottom  
00590         mAgentPlanes[3].p = planeFromPoints(frust[1], frust[0], frust[4]);
00591 
00592         //cache plane octant facing mask for use in AABBInFrustum
00593         for (U32 i = 0; i < mPlaneCount; i++)
00594         {
00595                 mAgentPlanes[i].mask = calcPlaneMask(mAgentPlanes[i].p);
00596         }
00597 }
00598 
00599 void LLCamera::calculateFrustumPlanes(F32 left, F32 right, F32 top, F32 bottom)
00600 {
00601         LLVector3 a, b, c;
00602 
00603         // For each plane we need to define 3 points (LLVector3's) in camera view space.  
00604         // The order in which we pass the points to planeFromPoints() matters, because the 
00605         // plane normal has a degeneracy of 2; we want it pointing _into_ the frustum. 
00606 
00607         a.setVec(0.0f, 0.0f, 0.0f);
00608         b.setVec(mFarPlane, right, top);
00609         c.setVec(mFarPlane, right, bottom);
00610         mLocalPlanes[PLANE_RIGHT].setVec(a, b, c);
00611 
00612         c.setVec(mFarPlane, left, top);
00613         mLocalPlanes[PLANE_TOP].setVec(a, c, b);
00614 
00615         b.setVec(mFarPlane, left, bottom);
00616         mLocalPlanes[PLANE_LEFT].setVec(a, b, c);
00617 
00618         c.setVec(mFarPlane, right, bottom);
00619         mLocalPlanes[PLANE_BOTTOM].setVec( a, c, b); 
00620 
00621         //calculate center and radius squared of frustum in world absolute coordinates
00622         mFrustCenter = X_AXIS*mFarPlane*0.5f;
00623         mFrustCenter = transformToAbsolute(mFrustCenter);
00624         mFrustRadiusSquared = mFarPlane*0.5f;
00625         mFrustRadiusSquared *= mFrustRadiusSquared * 1.05f; //pad radius squared by 5%
00626 }
00627 
00628 // x and y are in WINDOW space, so x = Y-Axis (left/right), y= Z-Axis(Up/Down)
00629 void LLCamera::calculateFrustumPlanesFromWindow(F32 x1, F32 y1, F32 x2, F32 y2)
00630 {
00631         F32 bottom, top, left, right;
00632         F32 view_height = (F32)tanf(0.5f * mView) * mFarPlane;
00633         F32 view_width = view_height * mAspect;
00634         
00635         left =   x1 * -2.f * view_width;
00636         right =  x2 * -2.f * view_width;
00637         bottom = y1 * 2.f * view_height; 
00638         top =    y2 * 2.f * view_height;
00639 
00640         calculateFrustumPlanes(left, right, top, bottom);
00641 }
00642 
00643 void LLCamera::calculateWorldFrustumPlanes() 
00644 {
00645         F32 d;
00646         LLVector3 center = mOrigin - mXAxis*mNearPlane;
00647         mWorldPlanePos = center;
00648         for (int p=0; p<4; p++)
00649         {
00650                 LLVector3 pnorm = LLVector3(mLocalPlanes[p]);
00651                 LLVector3 norm = rotateToAbsolute(pnorm);
00652                 norm.normVec();
00653                 d = -(center * norm);
00654                 mWorldPlanes[p] = LLPlane(norm, d);
00655         }
00656         // horizontal planes, perpindicular to (0,0,1);
00657         LLVector3 zaxis(0, 0, 1.0f);
00658         F32 yaw = getYaw();
00659         {
00660                 LLVector3 tnorm = LLVector3(mLocalPlanes[PLANE_LEFT]);
00661                 tnorm.rotVec(yaw, zaxis);
00662                 d = -(mOrigin * tnorm);
00663                 mHorizPlanes[HORIZ_PLANE_LEFT] = LLPlane(tnorm, d);
00664         }
00665         {
00666                 LLVector3 tnorm = LLVector3(mLocalPlanes[PLANE_RIGHT]);
00667                 tnorm.rotVec(yaw, zaxis);
00668                 d = -(mOrigin * tnorm);
00669                 mHorizPlanes[HORIZ_PLANE_RIGHT] = LLPlane(tnorm, d);
00670         }
00671 }
00672 
00673 // NOTE: this is the OpenGL matrix that will transform the default OpenGL view 
00674 // (-Z=at, Y=up) to the default view of the LLCamera class (X=at, Z=up):
00675 // 
00676 // F32 cfr_transform =  {  0.f,  0.f, -1.f,  0.f,   // -Z becomes X
00677 //                                                -1.f,  0.f,  0.f,  0.f,   // -X becomes Y
00678 //                                         0.f,  1.f,  0.f,  0.f,   //  Y becomes Z
00679 //                                                 0.f,  0.f,  0.f,  1.f };

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