llfollowcam.cpp

Go to the documentation of this file.
00001 
00033 #include "llviewerprecompiledheaders.h"
00034 #include "llfollowcam.h"
00035 #include "llagent.h"
00036 
00037 //-------------------------------------------------------
00038 // class statics
00039 //-------------------------------------------------------
00040 std::map<LLUUID, LLFollowCamParams*> LLFollowCamMgr::sParamMap;
00041 std::vector<LLFollowCamParams*> LLFollowCamMgr::sParamStack;
00042 
00043 //-------------------------------------------------------
00044 // constants
00045 //-------------------------------------------------------
00046 const F32 ONE_HALF                                                      = 0.5; 
00047 const F32 FOLLOW_CAM_ZOOM_FACTOR                        = 0.1f;
00048 const F32 FOLLOW_CAM_MIN_ZOOM_AMOUNT            = 0.1f;
00049 const F32 DISTANCE_EPSILON                                      = 0.0001f;
00050 const F32 DEFAULT_MAX_DISTANCE_FROM_SUBJECT     = 1000.0;       // this will be correctly set on me by my caller
00051 
00052 //----------------------------------------------------------------------------------------
00053 // This is how slowly the camera position moves to its ideal position 
00054 //----------------------------------------------------------------------------------------
00055 const F32 FOLLOW_CAM_MIN_POSITION_LAG           = 0.0f;         
00056 const F32 FOLLOW_CAM_DEFAULT_POSITION_LAG       = 0.1f;  
00057 const F32 FOLLOW_CAM_MAX_POSITION_LAG           = 3.0f;
00058 
00059 //----------------------------------------------------------------------------------------
00060 // This is how slowly the camera focus moves to its subject
00061 //----------------------------------------------------------------------------------------
00062 const F32 FOLLOW_CAM_MIN_FOCUS_LAG              = 0.0f;
00063 const F32 FOLLOW_CAM_DEFAULT_FOCUS_LAG  = 0.1f;
00064 const F32 FOLLOW_CAM_MAX_FOCUS_LAG              = 3.0f;
00065 
00066 //----------------------------------------------------------------------------------------
00067 // This is far the position can get from its IDEAL POSITION before it starts getting pulled
00068 //----------------------------------------------------------------------------------------
00069 const F32 FOLLOW_CAM_MIN_POSITION_THRESHOLD             = 0.0f;
00070 const F32 FOLLOW_CAM_DEFAULT_POSITION_THRESHOLD = 1.0f;
00071 const F32 FOLLOW_CAM_MAX_POSITION_THRESHOLD             = 4.0f;
00072 
00073 //----------------------------------------------------------------------------------------
00074 // This is far the focus can get from the subject before it starts getting pulled
00075 //----------------------------------------------------------------------------------------
00076 const F32 FOLLOW_CAM_MIN_FOCUS_THRESHOLD                = 0.0f;
00077 const F32 FOLLOW_CAM_DEFAULT_FOCUS_THRESHOLD    = 1.0f;
00078 const F32 FOLLOW_CAM_MAX_FOCUS_THRESHOLD                = 4.0f;
00079 
00080 //----------------------------------------------------------------------------------------
00081 // This is the distance the camera wants to be from the subject
00082 //----------------------------------------------------------------------------------------
00083 const F32 FOLLOW_CAM_MIN_DISTANCE               = 0.5f;
00084 const F32 FOLLOW_CAM_DEFAULT_DISTANCE   = 3.0f;
00085 //const F32 FOLLOW_CAM_MAX_DISTANCE             = 10.0f; // from now on I am using mMaxCameraDistantFromSubject
00086 
00087 //----------------------------------------------------------------------------------------
00088 // this is an angluar value
00089 // It affects the angle that the camera rises (pitches) in relation 
00090 // to the horizontal plane
00091 //----------------------------------------------------------------------------------------
00092 const F32 FOLLOW_CAM_MIN_PITCH          = -45.0f; 
00093 const F32 FOLLOW_CAM_DEFAULT_PITCH      =   0.0f;
00094 const F32 FOLLOW_CAM_MAX_PITCH          =  80.0f;       // keep under 90 degrees - avoid gimble lock!
00095 
00096 
00097 //----------------------------------------------------------------------------------------
00098 // how high or low the camera considers its ideal focus to be (relative to its subject)
00099 //----------------------------------------------------------------------------------------
00100 const F32 FOLLOW_CAM_MIN_FOCUS_OFFSET           = -10.0f;
00101 const LLVector3 FOLLOW_CAM_DEFAULT_FOCUS_OFFSET =  LLVector3(1.0f, 0.f, 0.f);
00102 const F32 FOLLOW_CAM_MAX_FOCUS_OFFSET           =  10.0f;
00103 
00104 //----------------------------------------------------------------------------------------
00105 // This affects the rate at which the camera adjusts to stay behind the subject
00106 //----------------------------------------------------------------------------------------
00107 const F32 FOLLOW_CAM_MIN_BEHINDNESS_LAG         = 0.0f;
00108 const F32 FOLLOW_CAM_DEFAULT_BEHINDNESS_LAG             = 0.f;
00109 const F32 FOLLOW_CAM_MAX_BEHINDNESS_LAG         = 3.0f;
00110 
00111 //---------------------------------------------------------------------------------------------------------------------
00112 // in  degrees: This is the size of the pie slice behind the subject matter within which the camera is free to move
00113 //---------------------------------------------------------------------------------------------------------------------
00114 const F32 FOLLOW_CAM_MIN_BEHINDNESS_ANGLE               = 0.0f;
00115 const F32 FOLLOW_CAM_DEFAULT_BEHINDNESS_ANGLE   = 10.0f;
00116 const F32 FOLLOW_CAM_MAX_BEHINDNESS_ANGLE               = 180.0f;
00117 const F32 FOLLOW_CAM_BEHINDNESS_EPSILON                 = 1.0f;
00118 
00119 //------------------------------------
00120 // Constructor
00121 //------------------------------------
00122 LLFollowCamParams::LLFollowCamParams()
00123 {
00124         mMaxCameraDistantFromSubject            = DEFAULT_MAX_DISTANCE_FROM_SUBJECT;
00125         mPositionLocked                                         = false;
00126         mFocusLocked                                            = false;
00127         mUsePosition                                            = false;
00128         mUseFocus                                                       = false;
00129 
00130         //------------------------------------------------------
00131         // setting the attributes to their defaults
00132         //------------------------------------------------------
00133         setPositionLag          ( FOLLOW_CAM_DEFAULT_POSITION_LAG                       );
00134         setFocusLag                     ( FOLLOW_CAM_DEFAULT_FOCUS_LAG                          );
00135         setPositionThreshold( FOLLOW_CAM_DEFAULT_POSITION_THRESHOLD             );
00136         setFocusThreshold       ( FOLLOW_CAM_DEFAULT_FOCUS_THRESHOLD            );
00137         setBehindnessLag        ( FOLLOW_CAM_DEFAULT_BEHINDNESS_LAG             );
00138         setDistance                     ( FOLLOW_CAM_DEFAULT_DISTANCE                           );
00139         setPitch                        ( FOLLOW_CAM_DEFAULT_PITCH                                      );
00140         setFocusOffset          ( FOLLOW_CAM_DEFAULT_FOCUS_OFFSET       );
00141         setBehindnessAngle      ( FOLLOW_CAM_DEFAULT_BEHINDNESS_ANGLE           );
00142         setPositionThreshold( FOLLOW_CAM_DEFAULT_POSITION_THRESHOLD             );
00143         setFocusThreshold       ( FOLLOW_CAM_DEFAULT_FOCUS_THRESHOLD            );
00144 
00145 }
00146 
00147 LLFollowCamParams::~LLFollowCamParams() { }
00148 
00149 //---------------------------------------------------------
00150 // buncho set methods
00151 //---------------------------------------------------------
00152 
00153 //---------------------------------------------------------
00154 void LLFollowCamParams::setPositionLag( F32 p ) 
00155 { 
00156         mPositionLag = llclamp(p, FOLLOW_CAM_MIN_POSITION_LAG, FOLLOW_CAM_MAX_POSITION_LAG); 
00157 }
00158 
00159 
00160 //---------------------------------------------------------
00161 void LLFollowCamParams::setFocusLag( F32 f ) 
00162 { 
00163         mFocusLag = llclamp(f, FOLLOW_CAM_MIN_FOCUS_LAG, FOLLOW_CAM_MAX_FOCUS_LAG); 
00164 }
00165 
00166 
00167 //---------------------------------------------------------
00168 void LLFollowCamParams::setPositionThreshold( F32 p ) 
00169 { 
00170         mPositionThreshold = llclamp(p, FOLLOW_CAM_MIN_POSITION_THRESHOLD, FOLLOW_CAM_MAX_POSITION_THRESHOLD); 
00171 }
00172 
00173 
00174 //---------------------------------------------------------
00175 void LLFollowCamParams::setFocusThreshold( F32 f ) 
00176 { 
00177         mFocusThreshold = llclamp(f, FOLLOW_CAM_MIN_FOCUS_THRESHOLD, FOLLOW_CAM_MAX_FOCUS_THRESHOLD); 
00178 }
00179 
00180 
00181 //---------------------------------------------------------
00182 void LLFollowCamParams::setPitch( F32 p ) 
00183 { 
00184         mPitch = llclamp(p, FOLLOW_CAM_MIN_PITCH, FOLLOW_CAM_MAX_PITCH); 
00185 }
00186 
00187 
00188 //---------------------------------------------------------
00189 void LLFollowCamParams::setBehindnessLag( F32 b ) 
00190 { 
00191         mBehindnessLag = llclamp(b, FOLLOW_CAM_MIN_BEHINDNESS_LAG, FOLLOW_CAM_MAX_BEHINDNESS_LAG); 
00192 }
00193 
00194 //---------------------------------------------------------
00195 void LLFollowCamParams::setBehindnessAngle( F32 b ) 
00196 { 
00197         mBehindnessMaxAngle = llclamp(b, FOLLOW_CAM_MIN_BEHINDNESS_ANGLE, FOLLOW_CAM_MAX_BEHINDNESS_ANGLE); 
00198 }
00199 
00200 //---------------------------------------------------------
00201 void LLFollowCamParams::setDistance( F32 d ) 
00202 { 
00203         mDistance = llclamp(d, FOLLOW_CAM_MIN_DISTANCE, mMaxCameraDistantFromSubject); 
00204 }
00205 
00206 //---------------------------------------------------------
00207 void LLFollowCamParams::setPositionLocked( bool l ) 
00208 {
00209         mPositionLocked = l;
00210 }
00211 
00212 //---------------------------------------------------------
00213 void LLFollowCamParams::setFocusLocked( bool l ) 
00214 {
00215         mFocusLocked = l;
00216 
00217 }
00218 
00219 //---------------------------------------------------------
00220 void LLFollowCamParams::setFocusOffset( const LLVector3& v ) 
00221 { 
00222         mFocusOffset = v; 
00223         mFocusOffset.clamp(FOLLOW_CAM_MIN_FOCUS_OFFSET, FOLLOW_CAM_MAX_FOCUS_OFFSET);
00224 }
00225 
00226 //---------------------------------------------------------
00227 void LLFollowCamParams::setPosition( const LLVector3& p ) 
00228 { 
00229         mUsePosition = true;
00230         mPosition = p;
00231 }
00232 
00233 //---------------------------------------------------------
00234 void LLFollowCamParams::setFocus( const LLVector3& f ) 
00235 { 
00236         mUseFocus = true;
00237         mFocus = f;
00238 }
00239 
00240 //---------------------------------------------------------
00241 // buncho get methods
00242 //---------------------------------------------------------
00243 F32                     LLFollowCamParams::getPositionLag               () const { return mPositionLag;                 }
00244 F32                     LLFollowCamParams::getFocusLag                  () const { return mFocusLag;                    }
00245 F32                     LLFollowCamParams::getPositionThreshold () const { return mPositionThreshold;   }
00246 F32                     LLFollowCamParams::getFocusThreshold    () const { return mFocusThreshold;              }
00247 F32                     LLFollowCamParams::getDistance                  () const { return mDistance;                    }
00248 F32                     LLFollowCamParams::getPitch                             () const { return mPitch;                               }
00249 LLVector3       LLFollowCamParams::getFocusOffset               () const { return mFocusOffset;                 }
00250 F32                     LLFollowCamParams::getBehindnessAngle   () const { return mBehindnessMaxAngle;  }
00251 F32                     LLFollowCamParams::getBehindnessLag             () const { return mBehindnessLag;               }
00252 LLVector3       LLFollowCamParams::getPosition                  () const { return mPosition;                    }
00253 LLVector3       LLFollowCamParams::getFocus                             () const { return mFocus;                               }
00254 bool            LLFollowCamParams::getPositionLocked    () const { return mPositionLocked;              }
00255 bool            LLFollowCamParams::getFocusLocked               () const { return mFocusLocked;                 }
00256 
00257 //------------------------------------
00258 // Constructor
00259 //------------------------------------
00260 LLFollowCam::LLFollowCam() : LLFollowCamParams()
00261 {
00262         mUpVector                                                       = LLVector3::z_axis;
00263         mSubjectPosition                                        = LLVector3::zero;
00264         mSubjectRotation                                        = LLQuaternion::DEFAULT;
00265 
00266         mZoomedToMinimumDistance                        = false;
00267         mPitchSineAndCosineNeedToBeUpdated      = true; 
00268 
00269         mSimulatedDistance = mDistance;
00270 }
00271 
00272 void LLFollowCam::copyParams(LLFollowCamParams& params)
00273 {
00274         setPositionLag(params.getPositionLag());
00275         setFocusLag(params.getFocusLag());
00276         setFocusThreshold( params.getFocusThreshold());
00277         setPositionThreshold(params.getPositionThreshold());
00278         setPitch(params.getPitch());
00279         setFocusOffset(params.getFocusOffset());
00280         setBehindnessAngle(params.getBehindnessAngle());
00281         setBehindnessLag(params.getBehindnessLag());
00282 
00283         setPositionLocked(params.getPositionLocked());
00284         setFocusLocked(params.getFocusLocked());
00285 
00286         setDistance(params.getDistance());      
00287         if (params.getUsePosition())
00288         {
00289                 setPosition(params.getPosition());
00290         }
00291         if (params.getUseFocus())
00292         {
00293                 setFocus(params.getFocus());
00294         }
00295 }
00296 
00297 //---------------------------------------------------------------------------------------------------------
00298 void LLFollowCam::update()
00299 {
00300         //####################################################################################
00301         // update Focus
00302         //####################################################################################
00303         LLVector3 offsetSubjectPosition = mSubjectPosition + (mFocusOffset * mSubjectRotation);
00304 
00305         LLVector3 simulated_pos_agent = gAgent.getPosAgentFromGlobal(mSimulatedPositionGlobal);
00306         LLVector3 vectorFromCameraToSubject = offsetSubjectPosition - simulated_pos_agent;
00307         F32 distanceFromCameraToSubject = vectorFromCameraToSubject.magVec();
00308 
00309         LLVector3 whereFocusWantsToBe = mFocus;
00310         LLVector3 focus_pt_agent = gAgent.getPosAgentFromGlobal(mSimulatedFocusGlobal);
00311         if ( mFocusLocked ) // if focus is locked, only relative focus needs to be updated
00312         {
00313                 mRelativeFocus = (focus_pt_agent - mSubjectPosition) * ~mSubjectRotation;
00314         }
00315         else
00316         {
00317                 LLVector3 focusOffset = offsetSubjectPosition - focus_pt_agent;
00318                 F32 focusOffsetDistance = focusOffset.magVec();
00319 
00320                 LLVector3 focusOffsetDirection = focusOffset / focusOffsetDistance;
00321                 whereFocusWantsToBe = focus_pt_agent + 
00322                         (focusOffsetDirection * (focusOffsetDistance - mFocusThreshold));
00323                 if ( focusOffsetDistance > mFocusThreshold )
00324                 {
00325                         // this version normalizes focus threshold by distance 
00326                         // so that the effect is not changed with distance
00327                         /*
00328                         F32 focusThresholdNormalizedByDistance = distanceFromCameraToSubject * mFocusThreshold;
00329                         if ( focusOffsetDistance > focusThresholdNormalizedByDistance )
00330                         {
00331                                 LLVector3 focusOffsetDirection = focusOffset / focusOffsetDistance;
00332                                 F32 force = focusOffsetDistance - focusThresholdNormalizedByDistance;
00333                         */
00334 
00335                         F32 focusLagLerp = LLCriticalDamp::getInterpolant( mFocusLag );
00336                         focus_pt_agent = lerp( focus_pt_agent, whereFocusWantsToBe, focusLagLerp );
00337                         mSimulatedFocusGlobal = gAgent.getPosGlobalFromAgent(focus_pt_agent);
00338                 }
00339                 mRelativeFocus = lerp(mRelativeFocus, (focus_pt_agent - mSubjectPosition) * ~mSubjectRotation, LLCriticalDamp::getInterpolant(0.05f));
00340         }// if focus is not locked ---------------------------------------------
00341 
00342 
00343         LLVector3 whereCameraPositionWantsToBe = gAgent.getPosAgentFromGlobal(mSimulatedPositionGlobal);
00344         if (  mPositionLocked )
00345         {
00346                 mRelativePos = (whereCameraPositionWantsToBe - mSubjectPosition) * ~mSubjectRotation;
00347         }
00348         else
00349         {
00350                 //####################################################################################
00351                 // update Position
00352                 //####################################################################################
00353                 //-------------------------------------------------------------------------
00354                 // I determine the horizontal vector from the camera to the subject
00355                 //-------------------------------------------------------------------------
00356                 LLVector3 horizontalVectorFromCameraToSubject = vectorFromCameraToSubject;
00357                 horizontalVectorFromCameraToSubject.mV[VZ] = 0.0f;
00358 
00359                 //---------------------------------------------------------
00360                 // Now I determine the horizontal distance
00361                 //---------------------------------------------------------
00362                 F32 horizontalDistanceFromCameraToSubject = horizontalVectorFromCameraToSubject.magVec();  
00363 
00364                 //---------------------------------------------------------
00365                 // Then I get the (normalized) horizontal direction...
00366                 //---------------------------------------------------------
00367                 LLVector3 horizontalDirectionFromCameraToSubject;       
00368                 if ( horizontalDistanceFromCameraToSubject < DISTANCE_EPSILON )
00369                 {
00370                         // make sure we still have a normalized vector if distance is really small 
00371                         // (this case is rare and fleeting)
00372                         horizontalDirectionFromCameraToSubject = LLVector3::z_axis;
00373                 }
00374                 else
00375                 {
00376                         // I'm not using the "normalize" method, because I can just divide by horizontalDistanceFromCameraToSubject
00377                         horizontalDirectionFromCameraToSubject = horizontalVectorFromCameraToSubject / horizontalDistanceFromCameraToSubject;
00378                 }
00379 
00380                 //------------------------------------------------------------------------------------------------------------
00381                 // Here is where I determine an offset relative to subject position in oder to set the ideal position. 
00382                 //------------------------------------------------------------------------------------------------------------
00383                 if ( mPitchSineAndCosineNeedToBeUpdated )
00384                 {
00385                         calculatePitchSineAndCosine();
00386                         mPitchSineAndCosineNeedToBeUpdated = false;
00387                 }
00388 
00389                 LLVector3 positionOffsetFromSubject;
00390                 positionOffsetFromSubject.setVec
00391                         ( 
00392                                 horizontalDirectionFromCameraToSubject.mV[ VX ] * mPitchCos,
00393                                 horizontalDirectionFromCameraToSubject.mV[ VY ] * mPitchCos,
00394                                 -mPitchSin
00395                         );
00396 
00397                 positionOffsetFromSubject *= mSimulatedDistance;
00398 
00399                 //----------------------------------------------------------------------
00400                 // Finally, ideal position is set by taking the subject position and 
00401                 // extending the positionOffsetFromSubject from that
00402                 //----------------------------------------------------------------------
00403                 LLVector3 idealCameraPosition = offsetSubjectPosition - positionOffsetFromSubject;
00404 
00405                 //--------------------------------------------------------------------------------
00406                 // Now I prepare to move the current camera position towards its ideal position...
00407                 //--------------------------------------------------------------------------------
00408                 LLVector3 vectorFromPositionToIdealPosition = idealCameraPosition - simulated_pos_agent;
00409                 F32 distanceFromPositionToIdealPosition = vectorFromPositionToIdealPosition.magVec();
00410                 
00411                 //put this inside of the block?         
00412                 LLVector3 normalFromPositionToIdealPosition = vectorFromPositionToIdealPosition / distanceFromPositionToIdealPosition;
00413                 
00414                 whereCameraPositionWantsToBe = simulated_pos_agent + 
00415                         (normalFromPositionToIdealPosition * (distanceFromPositionToIdealPosition - mPositionThreshold));
00416                 //-------------------------------------------------------------------------------------------------
00417                 // The following method takes the target camera position and resets it so that it stays "behind" the subject, 
00418                 // using behindness angle and behindness force as parameters affecting the exact behavior
00419                 //-------------------------------------------------------------------------------------------------
00420                 if ( distanceFromPositionToIdealPosition > mPositionThreshold )
00421                 {
00422                         F32 positionPullLerp = LLCriticalDamp::getInterpolant( mPositionLag );
00423                         simulated_pos_agent = lerp( simulated_pos_agent, whereCameraPositionWantsToBe, positionPullLerp );
00424                 }
00425 
00426                 //--------------------------------------------------------------------
00427                 // don't let the camera get farther than its official max distance
00428                 //--------------------------------------------------------------------
00429                 if ( distanceFromCameraToSubject > mMaxCameraDistantFromSubject )
00430                 {
00431                         LLVector3 directionFromCameraToSubject = vectorFromCameraToSubject / distanceFromCameraToSubject;
00432                         simulated_pos_agent = offsetSubjectPosition - directionFromCameraToSubject * mMaxCameraDistantFromSubject;
00433                 }
00434 
00439                 updateBehindnessConstraint(gAgent.getPosAgentFromGlobal(mSimulatedFocusGlobal), simulated_pos_agent);
00440                 mSimulatedPositionGlobal = gAgent.getPosGlobalFromAgent(simulated_pos_agent);
00441 
00442                 mRelativePos = lerp(mRelativePos, (simulated_pos_agent - mSubjectPosition) * ~mSubjectRotation, LLCriticalDamp::getInterpolant(0.05f));
00443         } // if position is not locked -----------------------------------------------------------
00444 
00445 
00446         //####################################################################################
00447         // update UpVector
00448         //####################################################################################
00449         // this just points upward for now, but I anticipate future effects requiring 
00450         // some rolling ("banking" effects for fun, swoopy vehicles, etc.)
00451         mUpVector = LLVector3::z_axis;
00452 }
00453 
00454 
00455 
00456 //-------------------------------------------------------------------------------------
00457 BOOL LLFollowCam::updateBehindnessConstraint(LLVector3 focus, LLVector3& cam_position)
00458 {
00459         BOOL constraint_active = FALSE;
00460         // only apply this stuff if the behindness angle is something other than opened up all the way
00461         if ( mBehindnessMaxAngle < FOLLOW_CAM_MAX_BEHINDNESS_ANGLE - FOLLOW_CAM_BEHINDNESS_EPSILON )
00462         {
00463                 //--------------------------------------------------------------
00464                 // horizontalized vector from focus to camera 
00465                 //--------------------------------------------------------------
00466                 LLVector3 horizontalVectorFromFocusToCamera;
00467                 horizontalVectorFromFocusToCamera.setVec(cam_position - focus);
00468                 horizontalVectorFromFocusToCamera.mV[ VZ ] = 0.0f; 
00469                 F32 cameraZ = cam_position.mV[ VZ ];
00470 
00471                 //--------------------------------------------------------------
00472                 // distance of horizontalized vector
00473                 //--------------------------------------------------------------
00474                 F32 horizontalDistance = horizontalVectorFromFocusToCamera.magVec();
00475 
00476                 //--------------------------------------------------------------------------------------------------
00477                 // calculate horizontalized back vector of the subject and scale by horizontalDistance
00478                 //--------------------------------------------------------------------------------------------------
00479                 LLVector3 horizontalSubjectBack( -1.0f, 0.0f, 0.0f );
00480                 horizontalSubjectBack *= mSubjectRotation;
00481                 horizontalSubjectBack.mV[ VZ ] = 0.0f; 
00482                 horizontalSubjectBack.normVec(); // because horizontalizing might make it shorter than 1
00483                 horizontalSubjectBack *= horizontalDistance;
00484 
00485                 //--------------------------------------------------------------------------------------------------
00486                 // find the angle (in degrees) between these vectors
00487                 //--------------------------------------------------------------------------------------------------
00488                 F32 cameraOffsetAngle = 0.f;
00489                 LLVector3 cameraOffsetRotationAxis;
00490                 LLQuaternion camera_offset_rotation;
00491                 camera_offset_rotation.shortestArc(horizontalSubjectBack, horizontalVectorFromFocusToCamera);
00492                 camera_offset_rotation.getAngleAxis(&cameraOffsetAngle, cameraOffsetRotationAxis);
00493                 cameraOffsetAngle *= RAD_TO_DEG;
00494 
00495                 if ( cameraOffsetAngle > mBehindnessMaxAngle )
00496                 {
00497                         F32 fraction = ((cameraOffsetAngle - mBehindnessMaxAngle) / cameraOffsetAngle) * LLCriticalDamp::getInterpolant(mBehindnessLag);
00498                         cam_position = focus + horizontalSubjectBack * (slerp(fraction, camera_offset_rotation, LLQuaternion::DEFAULT));
00499                         cam_position.mV[VZ] = cameraZ; // clamp z value back to what it was before we started messing with it
00500                         constraint_active = TRUE;
00501                 }
00502         }
00503         return constraint_active;
00504 }
00505 
00506 
00507 //---------------------------------------------------------
00508 void LLFollowCam::calculatePitchSineAndCosine()
00509 {
00510         F32 radian = mPitch * DEG_TO_RAD;
00511         mPitchCos = cos( radian );
00512         mPitchSin = sin( radian );
00513 }
00514 
00515 //---------------------------------------------------------
00516 void LLFollowCam::setSubjectPositionAndRotation( const LLVector3 p, const LLQuaternion r )
00517 {
00518         mSubjectPosition = p;
00519         mSubjectRotation = r;
00520 }
00521 
00522 
00523 //---------------------------------------------------------
00524 void LLFollowCam::zoom( S32 z ) 
00525 { 
00526         F32 zoomAmount = z * mSimulatedDistance * FOLLOW_CAM_ZOOM_FACTOR;
00527 
00528         if (( zoomAmount <  FOLLOW_CAM_MIN_ZOOM_AMOUNT )
00529         &&  ( zoomAmount > -FOLLOW_CAM_MIN_ZOOM_AMOUNT ))
00530         {
00531                 if ( zoomAmount < 0.0f )
00532                 {
00533                         zoomAmount = -FOLLOW_CAM_MIN_ZOOM_AMOUNT;
00534                 }
00535                 else
00536                 {
00537                         zoomAmount = FOLLOW_CAM_MIN_ZOOM_AMOUNT;
00538                 }
00539         }
00540 
00541         mSimulatedDistance += zoomAmount;
00542 
00543         mZoomedToMinimumDistance = false;
00544         if ( mSimulatedDistance < FOLLOW_CAM_MIN_DISTANCE ) 
00545         {
00546                 mSimulatedDistance = FOLLOW_CAM_MIN_DISTANCE;
00547 
00548                 // if zoomAmount is negative (i.e., getting closer), then
00549                 // this signifies having hit the minimum:
00550                 if ( zoomAmount < 0.0f )
00551                 {
00552                         mZoomedToMinimumDistance = true;
00553                 }
00554         }
00555         else if ( mSimulatedDistance > mMaxCameraDistantFromSubject ) 
00556         {
00557                 mSimulatedDistance = mMaxCameraDistantFromSubject;
00558         }
00559 }
00560 
00561 
00562 //---------------------------------------------------------
00563 bool LLFollowCam::isZoomedToMinimumDistance()
00564 {
00565         return mZoomedToMinimumDistance;
00566 }
00567 
00568 
00569 //---------------------------------------------------------
00570 void LLFollowCam::reset( const LLVector3 p, const LLVector3 f , const LLVector3 u )
00571 {
00572         setPosition(p);
00573         setFocus(f);
00574         mUpVector       = u;
00575 }
00576 
00577 //---------------------------------------------------------
00578 void LLFollowCam::setMaxCameraDistantFromSubject( F32 m )
00579 {
00580         mMaxCameraDistantFromSubject = m;
00581 }
00582 
00583 
00584 void LLFollowCam::setPitch( F32 p ) 
00585 { 
00586         LLFollowCamParams::setPitch(p);
00587         mPitchSineAndCosineNeedToBeUpdated = true; // important
00588 }
00589 
00590 void LLFollowCam::setDistance( F32 d ) 
00591 { 
00592         if (d != mDistance)
00593         {
00594                 LLFollowCamParams::setDistance(d);
00595                 mSimulatedDistance = d;
00596                 mZoomedToMinimumDistance = false; 
00597         }
00598 }
00599 
00600 void LLFollowCam::setPosition( const LLVector3& p ) 
00601 { 
00602         if (p != mPosition)
00603         {
00604                 LLFollowCamParams::setPosition(p);
00605                 mSimulatedPositionGlobal = gAgent.getPosGlobalFromAgent(mPosition);
00606                 if (mPositionLocked)
00607                 {
00608                         mRelativePos = (mPosition - mSubjectPosition) * ~mSubjectRotation;
00609                 }
00610         }
00611 }
00612 
00613 void LLFollowCam::setFocus( const LLVector3& f ) 
00614 { 
00615         if (f != mFocus)
00616         {
00617                 LLFollowCamParams::setFocus(f);
00618                 mSimulatedFocusGlobal = gAgent.getPosGlobalFromAgent(f);
00619                 if (mFocusLocked)
00620                 {
00621                         mRelativeFocus = (mFocus - mSubjectPosition) * ~mSubjectRotation;
00622                 }
00623         }
00624 }
00625 
00626 void LLFollowCam::setPositionLocked( bool locked )
00627 {
00628         LLFollowCamParams::setPositionLocked(locked);
00629         if (locked)
00630         {
00631                 // propagate set position to relative position
00632                 mRelativePos = (gAgent.getPosAgentFromGlobal(mSimulatedPositionGlobal) - mSubjectPosition) * ~mSubjectRotation;
00633         }
00634 }
00635 
00636 void LLFollowCam::setFocusLocked( bool locked )
00637 {
00638         LLFollowCamParams::setFocusLocked(locked);
00639         if (locked)     
00640         {
00641                 // propagate set position to relative position
00642                 mRelativeFocus = (gAgent.getPosAgentFromGlobal(mSimulatedFocusGlobal) - mSubjectPosition) * ~mSubjectRotation;
00643         }
00644 }
00645 
00646 
00647 LLVector3       LLFollowCam::getSimulatedPosition() const 
00648 { 
00649         // return simulated position
00650         return mSubjectPosition + (mRelativePos * mSubjectRotation);
00651 }
00652 
00653 LLVector3       LLFollowCam::getSimulatedFocus() const 
00654 { 
00655         // return simulated focus point
00656         return mSubjectPosition + (mRelativeFocus * mSubjectRotation);
00657 }
00658 
00659 LLVector3       LLFollowCam::getUpVector() 
00660 { 
00661         return mUpVector;                       
00662 }
00663 
00664 
00665 //------------------------------------
00666 // Destructor
00667 //------------------------------------
00668 LLFollowCam::~LLFollowCam()
00669 {
00670 }
00671 
00672 
00673 //-------------------------------------------------------
00674 // LLFollowCamMgr
00675 //-------------------------------------------------------
00676 //static
00677 void LLFollowCamMgr::cleanupClass()
00678 {
00679         for (param_map_t::iterator iter = sParamMap.begin(); iter != sParamMap.end(); ++iter)
00680         {
00681                 LLFollowCamParams* params = iter->second;
00682                 delete params;
00683         }
00684         sParamMap.clear();
00685 }
00686 
00687 //static
00688 void LLFollowCamMgr::setPositionLag( const LLUUID& source, F32 lag)
00689 {
00690         LLFollowCamParams* paramsp = getParamsForID(source);
00691         if (paramsp)
00692         {
00693                 paramsp->setPositionLag(lag);
00694         }
00695 }
00696 
00697 //static
00698 void LLFollowCamMgr::setFocusLag( const LLUUID& source, F32 lag)
00699 {
00700         LLFollowCamParams* paramsp = getParamsForID(source);
00701         if (paramsp)
00702         {
00703                 paramsp->setFocusLag(lag);
00704         }
00705 }
00706 
00707 //static
00708 void LLFollowCamMgr::setFocusThreshold( const LLUUID& source, F32 threshold)
00709 {
00710         LLFollowCamParams* paramsp = getParamsForID(source);
00711         if (paramsp)
00712         {
00713                 paramsp->setFocusThreshold(threshold);
00714         }
00715 
00716 }
00717 
00718 //static
00719 void LLFollowCamMgr::setPositionThreshold( const LLUUID& source, F32 threshold)
00720 {
00721         LLFollowCamParams* paramsp = getParamsForID(source);
00722         if (paramsp)
00723         {
00724                 paramsp->setPositionThreshold(threshold);
00725         }
00726 }
00727 
00728 //static
00729 void LLFollowCamMgr::setDistance( const LLUUID& source, F32 distance)
00730 {
00731         LLFollowCamParams* paramsp = getParamsForID(source);
00732         if (paramsp)
00733         {
00734                 paramsp->setDistance(distance);
00735         }
00736 }
00737 
00738 //static
00739 void LLFollowCamMgr::setPitch( const LLUUID& source, F32 pitch)
00740 {
00741         LLFollowCamParams* paramsp = getParamsForID(source);
00742         if (paramsp)
00743         {
00744                 paramsp->setPitch(pitch);
00745         }
00746 }
00747 
00748 //static
00749 void LLFollowCamMgr::setFocusOffset( const LLUUID& source, const LLVector3& offset)
00750 {
00751         LLFollowCamParams* paramsp = getParamsForID(source);
00752         if (paramsp)
00753         {
00754                 paramsp->setFocusOffset(offset);
00755         }
00756 }
00757 
00758 //static
00759 void LLFollowCamMgr::setBehindnessAngle( const LLUUID& source, F32 angle)
00760 {
00761         LLFollowCamParams* paramsp = getParamsForID(source);
00762         if (paramsp)
00763         {
00764                 paramsp->setBehindnessAngle(angle);
00765         }
00766 }
00767 
00768 //static
00769 void LLFollowCamMgr::setBehindnessLag( const LLUUID& source, F32 force)
00770 {
00771         LLFollowCamParams* paramsp = getParamsForID(source);
00772         if (paramsp)
00773         {
00774                 paramsp->setBehindnessLag(force);
00775         }
00776 }
00777 
00778 //static
00779 void LLFollowCamMgr::setPosition( const LLUUID& source, const LLVector3 position)
00780 {
00781         LLFollowCamParams* paramsp = getParamsForID(source);
00782         if (paramsp)
00783         {
00784                 paramsp->setPosition(position);
00785         }
00786 }
00787 
00788 //static
00789 void LLFollowCamMgr::setFocus( const LLUUID& source, const LLVector3 focus)
00790 {
00791         LLFollowCamParams* paramsp = getParamsForID(source);
00792         if (paramsp)
00793         {
00794                 paramsp->setFocus(focus);
00795         }
00796 }
00797 
00798 //static
00799 void LLFollowCamMgr::setPositionLocked( const LLUUID& source, bool locked)
00800 {
00801         LLFollowCamParams* paramsp = getParamsForID(source);
00802         if (paramsp)
00803         {
00804                 paramsp->setPositionLocked(locked);
00805         }
00806 }
00807 
00808 //static
00809 void LLFollowCamMgr::setFocusLocked( const LLUUID& source, bool locked )
00810 {
00811         LLFollowCamParams* paramsp = getParamsForID(source);
00812         if (paramsp)
00813         {
00814                 paramsp->setFocusLocked(locked);
00815         }
00816 }
00817 
00818 //static 
00819 LLFollowCamParams* LLFollowCamMgr::getParamsForID(const LLUUID& source)
00820 {
00821         LLFollowCamParams* params = NULL;
00822 
00823         param_map_t::iterator found_it = sParamMap.find(source);
00824         if (found_it == sParamMap.end()) // didn't find it?
00825         {
00826                 params = new LLFollowCamParams();
00827                 sParamMap[source] = params;
00828         }
00829         else
00830         {
00831                 params = found_it->second;
00832         }
00833 
00834         return params;
00835 }
00836 
00837 //static
00838 LLFollowCamParams* LLFollowCamMgr::getActiveFollowCamParams()
00839 {
00840         if (sParamStack.empty())
00841         {
00842                 return NULL;
00843         }
00844 
00845         return sParamStack.back();
00846 }
00847 
00848 //static 
00849 void LLFollowCamMgr::setCameraActive( const LLUUID& source, bool active )
00850 {
00851         LLFollowCamParams* params = getParamsForID(source);
00852         param_stack_t::iterator found_it = std::find(sParamStack.begin(), sParamStack.end(), params);
00853         if (found_it != sParamStack.end())
00854         {
00855                 sParamStack.erase(found_it);
00856         }
00857         // put on top of stack
00858         if(active)
00859         {
00860                 sParamStack.push_back(params);
00861         }
00862 }
00863 
00864 //static
00865 void LLFollowCamMgr::removeFollowCamParams(const LLUUID& source)
00866 {
00867         setCameraActive(source, FALSE);
00868         LLFollowCamParams* params = getParamsForID(source);
00869         sParamMap.erase(source);
00870         delete params;
00871 }
00872 
00873 //static
00874 bool LLFollowCamMgr::isScriptedCameraSource(const LLUUID& source)
00875 {
00876         param_map_t::iterator found_it = sParamMap.find(source);
00877         return (found_it != sParamMap.end());
00878 }
00879 
00880 //static 
00881 void LLFollowCamMgr::dump()
00882 {
00883         S32 param_count = 0;
00884         llinfos << "Scripted camera active stack" << llendl;
00885         for (param_stack_t::iterator param_it = sParamStack.begin();
00886                 param_it != sParamStack.end();
00887                 ++param_it)
00888         {
00889                 llinfos << param_count++ << 
00890                         " rot_limit: " << (*param_it)->getBehindnessAngle() << 
00891                         " rot_lag: " << (*param_it)->getBehindnessLag() << 
00892                         " distance: " << (*param_it)->getDistance() << 
00893                         " focus: " << (*param_it)->getFocus() << 
00894                         " foc_lag: " << (*param_it)->getFocusLag() << 
00895                         " foc_lock: " << ((*param_it)->getFocusLocked() ? "Y" : "N") << 
00896                         " foc_offset: " << (*param_it)->getFocusOffset() << 
00897                         " foc_thresh: " << (*param_it)->getFocusThreshold() << 
00898                         " pitch: " << (*param_it)->getPitch() << 
00899                         " pos: " << (*param_it)->getPosition() << 
00900                         " pos_lag: " << (*param_it)->getPositionLag() << 
00901                         " pos_lock: " << ((*param_it)->getPositionLocked() ? "Y" : "N") << 
00902                         " pos_thresh: " << (*param_it)->getPositionThreshold() << llendl;
00903         }
00904 }
00905 

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