llviewercamera.cpp

Go to the documentation of this file.
00001 
00032 #include <iomanip> // for setprecision
00033 #include "llviewerprecompiledheaders.h"
00034 
00035 #include "llviewercamera.h"
00036 
00037 #include "llquaternion.h"
00038 
00039 #include "llagent.h"
00040 #include "llviewercontrol.h"
00041 #include "lldrawable.h"
00042 #include "llface.h"
00043 #include "llgl.h"
00044 #include "llglheaders.h"
00045 #include "llviewerobjectlist.h"
00046 #include "llviewerregion.h"
00047 #include "llviewerwindow.h"
00048 #include "llvovolume.h"
00049 #include "llworld.h"
00050 
00051 LLViewerCamera *gCamera = NULL;
00052 
00053 LLViewerCamera::LLViewerCamera() : LLCamera()
00054 {
00055         calcProjection(getFar());
00056         S32 i;
00057         for (i = 0; i < 16; i++)
00058         {
00059                 mGLProjectionMatrix[i] = 0.f;
00060         }
00061         mCameraFOVDefault = DEFAULT_FIELD_OF_VIEW;
00062         mPixelMeterRatio = 0.f;
00063         mScreenPixelArea = 0;
00064         mZoomFactor = 1.f;
00065         mZoomSubregion = 1;
00066 }
00067 
00068 void LLViewerCamera::updateCameraLocation(const LLVector3 &center,
00069                                                                                         const LLVector3 &up_direction,
00070                                                                                         const LLVector3 &point_of_interest)
00071 {
00072         LLVector3 last_position;
00073         LLVector3 last_axis;
00074         last_position = getOrigin();
00075         last_axis = getAtAxis();
00076 
00077         mLastPointOfInterest = point_of_interest;
00078 
00079         // constrain to max distance from avatar
00080         LLVector3 camera_offset = center - gAgent.getPositionAgent();
00081 
00082         setOriginAndLookAt(center, up_direction, point_of_interest);
00083 
00084         F32 dpos = (center - last_position).magVec();
00085         LLQuaternion rotation;
00086         rotation.shortestArc(last_axis, getAtAxis());
00087 
00088         F32 x, y, z;
00089         F32 drot;
00090         rotation.getAngleAxis(&drot, &x, &y, &z);
00091         mVelocityStat.addValue(dpos);
00092         mAngularVelocityStat.addValue(drot);
00093         // update pixel meter ratio using default fov, not modified one
00094         mPixelMeterRatio = mViewHeightInPixels / (2.f*tanf(mCameraFOVDefault*0.5));
00095         // update screen pixel area
00096         mScreenPixelArea =(S32)((F32)mViewHeightInPixels * ((F32)mViewHeightInPixels * mAspect));
00097 }
00098 
00099 // Handy copies of last good GL matrices
00100 F64     gGLModelView[16];
00101 F64 gGLProjection[16];
00102 S32     gGLViewport[4];
00103 
00104 const LLMatrix4 &LLViewerCamera::getProjection() const
00105 {
00106         calcProjection(getFar());
00107         return mProjectionMatrix;
00108 
00109 }
00110 
00111 const LLMatrix4 &LLViewerCamera::getModelview() const
00112 {
00113         LLMatrix4 cfr(OGL_TO_CFR_ROTATION);
00114         getMatrixToLocal(mModelviewMatrix);
00115         mModelviewMatrix *= cfr;
00116         return mModelviewMatrix;
00117 }
00118 
00119 void LLViewerCamera::calcProjection(const F32 far_distance) const
00120 {
00121         F32 fov_y, z_far, z_near, aspect, f;
00122         fov_y = getView();
00123         z_far = far_distance;
00124         z_near = getNear();
00125         aspect = getAspect();
00126 
00127         f = 1/tan(fov_y*0.5f);
00128 
00129         mProjectionMatrix.zero();
00130         mProjectionMatrix.mMatrix[0][0] = f/aspect;
00131         mProjectionMatrix.mMatrix[1][1] = f;
00132         mProjectionMatrix.mMatrix[2][2] = (z_far + z_near)/(z_near - z_far);
00133         mProjectionMatrix.mMatrix[3][2] = (2*z_far*z_near)/(z_near - z_far);
00134         mProjectionMatrix.mMatrix[2][3] = -1;
00135 }
00136 
00137 // Sets up opengl state for 3D drawing.  If for selection, also
00138 // sets up a pick matrix.  x and y are ignored if for_selection is false.
00139 // The picking region is centered on x,y and has the specified width and
00140 // height.
00141 
00142 LLMatrix4 gProjectionMat;
00143 
00144 //static
00145 void LLViewerCamera::updateFrustumPlanes(LLCamera& camera, BOOL ortho)
00146 {
00147         GLint viewport[4];
00148         GLdouble model[16];
00149         GLdouble proj[16];
00150         GLdouble objX,objY,objZ;
00151 
00152         LLVector3 frust[8];
00153 
00154         glGetIntegerv(GL_VIEWPORT, viewport);
00155         glGetDoublev(GL_MODELVIEW_MATRIX, model);
00156         glGetDoublev(GL_PROJECTION_MATRIX,proj);
00157 
00158         gluUnProject(viewport[0],viewport[1],0,model,proj,viewport,&objX,&objY,&objZ);
00159         frust[0].setVec((F32)objX,(F32)objY,(F32)objZ);
00160         gluUnProject(viewport[0]+viewport[2],viewport[1],0,model,proj,viewport,&objX,&objY,&objZ);
00161         frust[1].setVec((F32)objX,(F32)objY,(F32)objZ);
00162         gluUnProject(viewport[0]+viewport[2],viewport[1]+viewport[3],0,model,proj,viewport,&objX,&objY,&objZ);
00163         frust[2].setVec((F32)objX,(F32)objY,(F32)objZ);
00164         gluUnProject(viewport[0],viewport[1]+viewport[3],0,model,proj,viewport,&objX,&objY,&objZ);
00165         frust[3].setVec((F32)objX,(F32)objY,(F32)objZ);
00166         
00167         if (ortho)
00168         {
00169                 LLVector3 far_shift = LLVector3(camera.getFar()*2.0f,0,0);
00170                 for (U32 i = 0; i < 4; i++)
00171                 {
00172                         frust[i+4] = frust[i] + far_shift;
00173                 }
00174         }
00175         else
00176         {
00177                 for (U32 i = 0; i < 4; i++)
00178                 {
00179                         LLVector3 vec = frust[i] - camera.getOrigin();
00180                         vec.normVec();
00181                         frust[i+4] = camera.getOrigin() + vec*camera.getFar()*2.0f;
00182                 }
00183         }
00184 
00185         camera.calcAgentFrustumPlanes(frust);
00186 }
00187 
00188 void LLViewerCamera::setPerspective(BOOL for_selection,
00189                                                                         S32 x, S32 y_from_bot, S32 width, S32 height,
00190                                                                         BOOL limit_select_distance,
00191                                                                         F32 z_near, F32 z_far)
00192 {
00193         //********* UMICH 3D LAB **********
00194         F32 fov_y;//, aspect;
00195         //********* UMICH 3D LAB **********
00196         fov_y = RAD_TO_DEG * getView();
00197         BOOL z_default_near, z_default_far = FALSE;
00198         if (z_far <= 0)
00199         {
00200                 z_default_far = TRUE;
00201                 z_far = getFar();
00202         }
00203         if (z_near <= 0)
00204         {
00205                 z_default_near = TRUE;
00206                 z_near = getNear();
00207         }
00208         //********* UMICH 3D LAB **********
00209         //aspect = getAspect();
00210         //********* UMICH 3D LAB **********
00211 
00212         // Load camera view matrix
00213         glMatrixMode( GL_PROJECTION );
00214         glLoadIdentity();
00215 
00216         if (for_selection)
00217         {
00218                 // make a tiny little viewport
00219                 // anything drawn into this viewport will be "selected"
00220                 const U8        VIEWPORT_VECTOR_LEN = 4;
00221                 GLint           viewport[VIEWPORT_VECTOR_LEN];
00222                 glGetIntegerv(GL_VIEWPORT, viewport);
00223                 gluPickMatrix(x + width / 2, y_from_bot + height / 2, width, height, viewport);
00224 
00225                 if (limit_select_distance)
00226                 {
00227                         // ...select distance from control
00228                         z_far = gSavedSettings.getF32("MaxSelectDistance");
00229                 }
00230                 else
00231                 {
00232                         z_far = gAgent.mDrawDistance;
00233                 }
00234         }
00235         else
00236         {
00237                 // Only override the far clip if it's not passed in explicitly.
00238                 if (z_default_far)
00239                 {
00240                         z_far = MAX_FAR_CLIP;
00241                 }
00242                 glViewport(x, y_from_bot, width, height);
00243         }
00244         
00245         if (mZoomFactor > 1.f)
00246         {
00247                 float offset = mZoomFactor - 1.f;
00248                 int pos_y = mZoomSubregion / llceil(mZoomFactor);
00249                 int pos_x = mZoomSubregion - (pos_y*llceil(mZoomFactor));
00250                 glTranslatef(offset - (F32)pos_x * 2.f, offset - (F32)pos_y * 2.f, 0.f);
00251                 glScalef(mZoomFactor, mZoomFactor, 1.f);
00252         }
00253 
00254         //********* UMICH 3D LAB **********
00255         //calcProjection(z_far); // Update the projection matrix cache
00256 
00257         //gluPerspective(fov_y,
00258         //                               aspect,
00259         //                               z_near,
00260         //                               z_far);
00261         
00262         // compute the frustum planes for a better stereo effect
00263 
00264         F32 eye_separation = gSavedSettings.getF32("StereoEyeSeparation");
00265         F32 focal_distance = gSavedSettings.getF32("StereoFocalDistance");
00266 
00267         const float aspect       = (float)width / (float)height;
00268         const float rads         = 0.01745329251994329577f * (fov_y * .5f);
00269         const float wd2          = z_near * tan(rads);
00270         const float ndfl         = z_near / focal_distance;
00271 
00272         // define frustum
00273         float left   = -(aspect * wd2) + (eye_separation/2 * ndfl);
00274         float right  =  (aspect * wd2) + (eye_separation/2 * ndfl);
00275         float top    =  wd2;
00276         float bottom = -wd2;
00277 
00278         glFrustum(left, right, bottom, top, z_near, z_far);
00279         //********* UMICH 3D LAB **********
00280 
00281         glGetFloatv(GL_PROJECTION_MATRIX, (float*)&gProjectionMat);
00282         glMatrixMode( GL_MODELVIEW );
00283         glLoadMatrixf(OGL_TO_CFR_ROTATION);             // Load Cory's favorite reference frame
00284 
00285         GLfloat                 ogl_matrix[16];
00286         getOpenGLTransform(ogl_matrix);
00287         glMultMatrixf(ogl_matrix);
00288 
00289         if (for_selection && (width > 1 || height > 1))
00290         {
00291                 calculateFrustumPlanesFromWindow((F32)(x - width / 2) / (F32)gViewerWindow->getWindowWidth() - 0.5f,
00292                                                                 (F32)(y_from_bot - height / 2) / (F32)gViewerWindow->getWindowHeight() - 0.5f,
00293                                                                 (F32)(x + width / 2) / (F32)gViewerWindow->getWindowWidth() - 0.5f,
00294                                                                 (F32)(y_from_bot + height / 2) / (F32)gViewerWindow->getWindowHeight() - 0.5f);
00295 
00296         }
00297 
00298         // if not picking and not doing a snapshot, cache various GL matrices
00299         if (!for_selection && mZoomFactor == 1.f)
00300         {
00301                 // Save GL matrices for access elsewhere in code, especially project_world_to_screen
00302                 glGetDoublev(GL_PROJECTION_MATRIX, mGLProjectionMatrix);
00303                 glGetDoublev(GL_MODELVIEW_MATRIX, gGLModelView);
00304                 glGetIntegerv(GL_VIEWPORT, (GLint*)gGLViewport);
00305         }
00306 
00307         updateFrustumPlanes(*this);
00308 
00309         if (gSavedSettings.getBOOL("CameraOffset"))
00310         {
00311                 glMatrixMode(GL_PROJECTION);
00312                 glTranslatef(0,0,-50);
00313                 glRotatef(20.0,1,0,0);
00314                 glMatrixMode(GL_MODELVIEW);
00315         }
00316 }
00317 
00318 
00319 // Uses the last GL matrices set in set_perspective to project a point from
00320 // screen coordinates to the agent's region.
00321 void LLViewerCamera::projectScreenToPosAgent(const S32 screen_x, const S32 screen_y, LLVector3* pos_agent) const
00322 {
00323 
00324         GLdouble x, y, z;
00325         gluUnProject(
00326                 GLdouble(screen_x), GLdouble(screen_y), 0.0,
00327                 gGLModelView, mGLProjectionMatrix, (GLint*)gGLViewport,
00328                 &x,
00329                 &y,
00330                 &z );
00331         pos_agent->setVec( (F32)x, (F32)y, (F32)z );
00332 }
00333 
00334 // Uses the last GL matrices set in set_perspective to project a point from
00335 // the agent's region space to screen coordinates.  Returns TRUE if point in within
00336 // the current window.
00337 BOOL LLViewerCamera::projectPosAgentToScreen(const LLVector3 &pos_agent, LLCoordGL &out_point, const BOOL clamp) const
00338 {
00339         BOOL in_front = TRUE;
00340         GLdouble        x, y, z;                        // object's window coords, GL-style
00341 
00342         LLVector3 dir_to_point = pos_agent - getOrigin();
00343         dir_to_point /= dir_to_point.magVec();
00344 
00345         if (dir_to_point * getAtAxis() < 0.f)
00346         {
00347                 if (clamp)
00348                 {
00349                         return FALSE;
00350                 }
00351                 else
00352                 {
00353                         in_front = FALSE;
00354                 }
00355         }
00356 
00357         if (GL_TRUE == gluProject(pos_agent.mV[VX], pos_agent.mV[VY], pos_agent.mV[VZ],
00358                                                                 gGLModelView, mGLProjectionMatrix, (GLint*)gGLViewport,
00359                                                                 &x, &y, &z))
00360         {
00361                 // convert screen coordinates to virtual UI coordinates
00362                 x /= gViewerWindow->getDisplayScale().mV[VX];
00363                 y /= gViewerWindow->getDisplayScale().mV[VY];
00364 
00365                 // should now have the x,y coords of grab_point in screen space
00366                 const LLRect& window_rect = gViewerWindow->getWindowRect();
00367 
00368                 // ...sanity check
00369                 S32 int_x = lltrunc(x);
00370                 S32 int_y = lltrunc(y);
00371 
00372                 BOOL valid = TRUE;
00373 
00374                 if (clamp)
00375                 {
00376                         if (int_x < window_rect.mLeft)
00377                         {
00378                                 out_point.mX = window_rect.mLeft;
00379                                 valid = FALSE;
00380                         }
00381                         else if (int_x > window_rect.mRight)
00382                         {
00383                                 out_point.mX = window_rect.mRight;
00384                                 valid = FALSE;
00385                         }
00386                         else
00387                         {
00388                                 out_point.mX = int_x;
00389                         }
00390 
00391                         if (int_y < window_rect.mBottom)
00392                         {
00393                                 out_point.mY = window_rect.mBottom;
00394                                 valid = FALSE;
00395                         }
00396                         else if (int_y > window_rect.mTop)
00397                         {
00398                                 out_point.mY = window_rect.mTop;
00399                                 valid = FALSE;
00400                         }
00401                         else
00402                         {
00403                                 out_point.mY = int_y;
00404                         }
00405                         return valid;
00406                 }
00407                 else
00408                 {
00409                         out_point.mX = int_x;
00410                         out_point.mY = int_y;
00411 
00412                         if (int_x < window_rect.mLeft)
00413                         {
00414                                 valid = FALSE;
00415                         }
00416                         else if (int_x > window_rect.mRight)
00417                         {
00418                                 valid = FALSE;
00419                         }
00420                         if (int_y < window_rect.mBottom)
00421                         {
00422                                 valid = FALSE;
00423                         }
00424                         else if (int_y > window_rect.mTop)
00425                         {
00426                                 valid = FALSE;
00427                         }
00428 
00429                         return in_front && valid;
00430                 }
00431         }
00432         else
00433         {
00434                 return FALSE;
00435         }
00436 }
00437 
00438 // Uses the last GL matrices set in set_perspective to project a point from
00439 // the agent's region space to the nearest edge in screen coordinates.
00440 // Returns TRUE if projection succeeds.
00441 BOOL LLViewerCamera::projectPosAgentToScreenEdge(const LLVector3 &pos_agent,
00442                                                                                                 LLCoordGL &out_point) const
00443 {
00444         LLVector3 dir_to_point = pos_agent - getOrigin();
00445         dir_to_point /= dir_to_point.magVec();
00446 
00447         BOOL in_front = TRUE;
00448         if (dir_to_point * getAtAxis() < 0.f)
00449         {
00450                 in_front = FALSE;
00451         }
00452 
00453         GLdouble        x, y, z;                        // object's window coords, GL-style
00454         if (GL_TRUE == gluProject(pos_agent.mV[VX], pos_agent.mV[VY],
00455                                                           pos_agent.mV[VZ], gGLModelView,
00456                                                           mGLProjectionMatrix, (GLint*)gGLViewport,
00457                                                           &x, &y, &z))
00458         {
00459                 x /= gViewerWindow->getDisplayScale().mV[VX];
00460                 y /= gViewerWindow->getDisplayScale().mV[VY];
00461                 // should now have the x,y coords of grab_point in screen space
00462                 const LLRect& window_rect = gViewerWindow->getVirtualWindowRect();
00463 
00464                 // ...sanity check
00465                 S32 int_x = lltrunc(x);
00466                 S32 int_y = lltrunc(y);
00467 
00468                 // find the center
00469                 GLdouble center_x = (GLdouble)(0.5f * (window_rect.mLeft + window_rect.mRight));
00470                 GLdouble center_y = (GLdouble)(0.5f * (window_rect.mBottom + window_rect.mTop));
00471 
00472                 if (x == center_x  &&  y == center_y)
00473                 {
00474                         // can't project to edge from exact center
00475                         return FALSE;
00476                 }
00477 
00478                 // find the line from center to local
00479                 GLdouble line_x = x - center_x;
00480                 GLdouble line_y = y - center_y;
00481 
00482                 int_x = lltrunc(center_x);
00483                 int_y = lltrunc(center_y);
00484 
00485 
00486                 if (0.f == line_x)
00487                 {
00488                         // the slope of the line is undefined
00489                         if (line_y > 0.f)
00490                         {
00491                                 int_y = window_rect.mTop;
00492                         }
00493                         else
00494                         {
00495                                 int_y = window_rect.mBottom;
00496                         }
00497                 }
00498                 else if (0 == window_rect.getWidth())
00499                 {
00500                         // the diagonal slope of the view is undefined
00501                         if (y < window_rect.mBottom)
00502                         {
00503                                 int_y = window_rect.mBottom;
00504                         }
00505                         else if ( y > window_rect.mTop)
00506                         {
00507                                 int_y = window_rect.mTop;
00508                         }
00509                 }
00510                 else
00511                 {
00512                         F32 line_slope = (F32)(line_y / line_x);
00513                         F32 rect_slope = ((F32)window_rect.getHeight()) / ((F32)window_rect.getWidth());
00514 
00515                         if (fabs(line_slope) > rect_slope)
00516                         {
00517                                 if (line_y < 0.f)
00518                                 {
00519                                         // bottom
00520                                         int_y = window_rect.mBottom;
00521                                 }
00522                                 else
00523                                 {
00524                                         // top
00525                                         int_y = window_rect.mTop;
00526                                 }
00527                                 int_x = lltrunc(((GLdouble)int_y - center_y) / line_slope + center_x);
00528                         }
00529                         else if (fabs(line_slope) < rect_slope)
00530                         {
00531                                 if (line_x < 0.f)
00532                                 {
00533                                         // left
00534                                         int_x = window_rect.mLeft;
00535                                 }
00536                                 else
00537                                 {
00538                                         // right
00539                                         int_x = window_rect.mRight;
00540                                 }
00541                                 int_y = lltrunc(((GLdouble)int_x - center_x) * line_slope + center_y);
00542                         }
00543                         else
00544                         {
00545                                 // exactly parallel ==> push to the corners
00546                                 if (line_x > 0.f)
00547                                 {
00548                                         int_x = window_rect.mRight;
00549                                 }
00550                                 else
00551                                 {
00552                                         int_x = window_rect.mLeft;
00553                                 }
00554                                 if (line_y > 0.0f)
00555                                 {
00556                                         int_y = window_rect.mTop;
00557                                 }
00558                                 else
00559                                 {
00560                                         int_y = window_rect.mBottom;
00561                                 }
00562                         }
00563                 }
00564                 if (!in_front)
00565                 {
00566                         int_x = window_rect.mLeft + window_rect.mRight - int_x;
00567                         int_y = window_rect.mBottom + window_rect.mTop - int_y;
00568                 }
00569                 out_point.mX = int_x;
00570                 out_point.mY = int_y;
00571                 return TRUE;
00572         }
00573         return FALSE;
00574 }
00575 
00576 
00577 void LLViewerCamera::getPixelVectors(const LLVector3 &pos_agent, LLVector3 &up, LLVector3 &right)
00578 {
00579         LLVector3 to_vec = pos_agent - getOrigin();
00580 
00581         F32 at_dist = to_vec * getAtAxis();
00582 
00583         F32 height_meters = at_dist* (F32)tan(getView()/2.f);
00584         F32 height_pixels = getViewHeightInPixels()/2.f;
00585 
00586         F32 pixel_aspect = gViewerWindow->getWindow()->getPixelAspectRatio();
00587 
00588         F32 meters_per_pixel = height_meters / height_pixels;
00589         up = getUpAxis() * meters_per_pixel * gViewerWindow->getDisplayScale().mV[VY];
00590         right = -1.f * pixel_aspect * meters_per_pixel * getLeftAxis() * gViewerWindow->getDisplayScale().mV[VX];
00591 }
00592 
00593 LLVector3 LLViewerCamera::roundToPixel(const LLVector3 &pos_agent)
00594 {
00595         F32 dist = (pos_agent - getOrigin()).magVec();
00596         // Convert to screen space and back, preserving the depth.
00597         LLCoordGL screen_point;
00598         if (!projectPosAgentToScreen(pos_agent, screen_point, FALSE))
00599         {
00600                 // Off the screen, just return the original position.
00601                 return pos_agent;
00602         }
00603 
00604         LLVector3 ray_dir;
00605 
00606         projectScreenToPosAgent(screen_point.mX, screen_point.mY, &ray_dir);
00607         ray_dir -= getOrigin();
00608         ray_dir.normVec();
00609 
00610         LLVector3 pos_agent_rounded = getOrigin() + ray_dir*dist;
00611 
00612         /*
00613         LLVector3 pixel_x, pixel_y;
00614         getPixelVectors(pos_agent_rounded, pixel_y, pixel_x);
00615         pos_agent_rounded += 0.5f*pixel_x, 0.5f*pixel_y;
00616         */
00617         return pos_agent_rounded;
00618 }
00619 
00620 BOOL LLViewerCamera::cameraUnderWater() const
00621 {
00622         return getOrigin().mV[VZ] < gAgent.getRegion()->getWaterHeight();
00623 }
00624 
00625 BOOL LLViewerCamera::areVertsVisible(LLViewerObject* volumep, BOOL all_verts)
00626 {
00627         S32 i, num_faces;
00628         LLDrawable* drawablep = volumep->mDrawable;
00629 
00630         if (!drawablep)
00631         {
00632                 return FALSE;
00633         }
00634 
00635         LLVolume* volume = volumep->getVolume();
00636         if (!volume)
00637         {
00638                 return FALSE;
00639         }
00640 
00641         LLVOVolume* vo_volume = (LLVOVolume*) volumep;
00642 
00643         vo_volume->updateRelativeXform();
00644         LLMatrix4 mat = vo_volume->getRelativeXform();
00645         
00646         LLMatrix4 render_mat(vo_volume->getRenderRotation(), LLVector4(vo_volume->getRenderPosition()));
00647 
00648         num_faces = volume->getNumVolumeFaces();
00649         for (i = 0; i < num_faces; i++)
00650         {
00651                 const LLVolumeFace& face = volume->getVolumeFace(i);
00652                                 
00653                 for (U32 v = 0; v < face.mVertices.size(); v++)
00654                 {
00655                         LLVector4 vec = LLVector4(face.mVertices[v].mPosition) * mat;
00656 
00657                         if (drawablep->isActive())
00658                         {
00659                                 vec = vec * render_mat; 
00660                         }
00661 
00662                         BOOL in_frustum = pointInFrustum(LLVector3(vec)) > 0;
00663 
00664                         if ( !in_frustum && all_verts ||
00665                                  in_frustum && !all_verts)
00666                         {
00667                                 return !all_verts;
00668                         }
00669                 }
00670         }
00671         return all_verts;
00672 }
00673 
00674 //**************** UMICH 3D LAB **************
00675 void LLViewerCamera::updateStereoValues()
00676 {
00677         // get the current camera position to calculate the offsets
00678         mCameraTempPosition = this->getOrigin();
00679 
00680         // get the last point of iterest to calculate the focal point
00681         mStereoLastPOI = mLastPointOfInterest;
00682 }
00683 
00684 void LLViewerCamera::rotateToLeftEye()
00685 {
00686         // Calculate the new position and focal point for the camera (left eye)
00687         F32 eye_separation = gSavedSettings.getF32("StereoEyeSeparation");
00688         F32 focal_distance = gSavedSettings.getF32("StereoFocalDistance");
00689 
00690         // Translate camera position of half the distance between the 2 eyes
00691         LLVector3 new_pos = mCameraTempPosition + eye_separation/2 * (this->getLeftAxis());
00692         
00693         // New Point of Interest
00694         LLVector3 dir = mStereoLastPOI - mCameraTempPosition;
00695         dir.normVec();
00696         LLVector3 new_poi = mCameraTempPosition + dir * focal_distance;
00697     
00698         // lookat target
00699         this->updateCameraLocation(new_pos, getUpAxis(), new_poi);
00700 }
00701 
00702 void LLViewerCamera::rotateToRightEye()
00703 {
00704         // Calculate the new position and focal point for the camera (right eye)
00705         F32 eye_separation = gSavedSettings.getF32("StereoEyeSeparation");
00706         F32 focal_distance = gSavedSettings.getF32("StereoFocalDistance");
00707 
00708         // Translate camera position of half the distance between the 2 eyes
00709         LLVector3 new_pos = mCameraTempPosition - eye_separation/2 * (this->getLeftAxis());
00710 
00711         // New Point of Interest
00712         LLVector3 dir = mStereoLastPOI - mCameraTempPosition;
00713         dir.normVec();
00714         LLVector3 new_poi = mCameraTempPosition + dir * focal_distance;
00715 
00716         // lookat target
00717         this->updateCameraLocation(new_pos, getUpAxis(), new_poi);
00718 }
00719 
00720 //*************** UMICH 3D LAB ******************
00721 

Generated on Thu Jul 1 06:09:27 2010 for Second Life Viewer by  doxygen 1.4.7