llfollowcam.cpp
上传用户:king477883
上传日期:2021-03-01
资源大小:9553k
文件大小:31k
- /**
- * @file llfollowcam.cpp
- * @author Jeffrey Ventrella
- * @brief LLFollowCam class implementation
- *
- * $LicenseInfo:firstyear=2005&license=viewergpl$
- *
- * Copyright (c) 2005-2010, Linden Research, Inc.
- *
- * Second Life Viewer Source Code
- * The source code in this file ("Source Code") is provided by Linden Lab
- * to you under the terms of the GNU General Public License, version 2.0
- * ("GPL"), unless you have obtained a separate licensing agreement
- * ("Other License"), formally executed by you and Linden Lab. Terms of
- * the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
- *
- * There are special exceptions to the terms and conditions of the GPL as
- * it is applied to this Source Code. View the full text of the exception
- * in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at
- * http://secondlifegrid.net/programs/open_source/licensing/flossexception
- *
- * By copying, modifying or distributing this software, you acknowledge
- * that you have read and understood your obligations described above,
- * and agree to abide by those obligations.
- *
- * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
- * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
- * COMPLETENESS OR PERFORMANCE.
- * $/LicenseInfo$
- */
- #include "llviewerprecompiledheaders.h"
- #include "llfollowcam.h"
- #include "llagent.h"
- //-------------------------------------------------------
- // class statics
- //-------------------------------------------------------
- std::map<LLUUID, LLFollowCamParams*> LLFollowCamMgr::sParamMap;
- std::vector<LLFollowCamParams*> LLFollowCamMgr::sParamStack;
- //-------------------------------------------------------
- // constants
- //-------------------------------------------------------
- const F32 ONE_HALF = 0.5;
- const F32 FOLLOW_CAM_ZOOM_FACTOR = 0.1f;
- const F32 FOLLOW_CAM_MIN_ZOOM_AMOUNT = 0.1f;
- const F32 DISTANCE_EPSILON = 0.0001f;
- const F32 DEFAULT_MAX_DISTANCE_FROM_SUBJECT = 1000.0; // this will be correctly set on me by my caller
- //----------------------------------------------------------------------------------------
- // This is how slowly the camera position moves to its ideal position
- //----------------------------------------------------------------------------------------
- const F32 FOLLOW_CAM_MIN_POSITION_LAG = 0.0f;
- const F32 FOLLOW_CAM_DEFAULT_POSITION_LAG = 0.1f;
- const F32 FOLLOW_CAM_MAX_POSITION_LAG = 3.0f;
- //----------------------------------------------------------------------------------------
- // This is how slowly the camera focus moves to its subject
- //----------------------------------------------------------------------------------------
- const F32 FOLLOW_CAM_MIN_FOCUS_LAG = 0.0f;
- const F32 FOLLOW_CAM_DEFAULT_FOCUS_LAG = 0.1f;
- const F32 FOLLOW_CAM_MAX_FOCUS_LAG = 3.0f;
- //----------------------------------------------------------------------------------------
- // This is far the position can get from its IDEAL POSITION before it starts getting pulled
- //----------------------------------------------------------------------------------------
- const F32 FOLLOW_CAM_MIN_POSITION_THRESHOLD = 0.0f;
- const F32 FOLLOW_CAM_DEFAULT_POSITION_THRESHOLD = 1.0f;
- const F32 FOLLOW_CAM_MAX_POSITION_THRESHOLD = 4.0f;
- //----------------------------------------------------------------------------------------
- // This is far the focus can get from the subject before it starts getting pulled
- //----------------------------------------------------------------------------------------
- const F32 FOLLOW_CAM_MIN_FOCUS_THRESHOLD = 0.0f;
- const F32 FOLLOW_CAM_DEFAULT_FOCUS_THRESHOLD = 1.0f;
- const F32 FOLLOW_CAM_MAX_FOCUS_THRESHOLD = 4.0f;
- //----------------------------------------------------------------------------------------
- // This is the distance the camera wants to be from the subject
- //----------------------------------------------------------------------------------------
- const F32 FOLLOW_CAM_MIN_DISTANCE = 0.5f;
- const F32 FOLLOW_CAM_DEFAULT_DISTANCE = 3.0f;
- //const F32 FOLLOW_CAM_MAX_DISTANCE = 10.0f; // from now on I am using mMaxCameraDistantFromSubject
- //----------------------------------------------------------------------------------------
- // this is an angluar value
- // It affects the angle that the camera rises (pitches) in relation
- // to the horizontal plane
- //----------------------------------------------------------------------------------------
- const F32 FOLLOW_CAM_MIN_PITCH = -45.0f;
- const F32 FOLLOW_CAM_DEFAULT_PITCH = 0.0f;
- const F32 FOLLOW_CAM_MAX_PITCH = 80.0f; // keep under 90 degrees - avoid gimble lock!
- //----------------------------------------------------------------------------------------
- // how high or low the camera considers its ideal focus to be (relative to its subject)
- //----------------------------------------------------------------------------------------
- const F32 FOLLOW_CAM_MIN_FOCUS_OFFSET = -10.0f;
- const LLVector3 FOLLOW_CAM_DEFAULT_FOCUS_OFFSET = LLVector3(1.0f, 0.f, 0.f);
- const F32 FOLLOW_CAM_MAX_FOCUS_OFFSET = 10.0f;
- //----------------------------------------------------------------------------------------
- // This affects the rate at which the camera adjusts to stay behind the subject
- //----------------------------------------------------------------------------------------
- const F32 FOLLOW_CAM_MIN_BEHINDNESS_LAG = 0.0f;
- const F32 FOLLOW_CAM_DEFAULT_BEHINDNESS_LAG = 0.f;
- const F32 FOLLOW_CAM_MAX_BEHINDNESS_LAG = 3.0f;
- //---------------------------------------------------------------------------------------------------------------------
- // in degrees: This is the size of the pie slice behind the subject matter within which the camera is free to move
- //---------------------------------------------------------------------------------------------------------------------
- const F32 FOLLOW_CAM_MIN_BEHINDNESS_ANGLE = 0.0f;
- const F32 FOLLOW_CAM_DEFAULT_BEHINDNESS_ANGLE = 10.0f;
- const F32 FOLLOW_CAM_MAX_BEHINDNESS_ANGLE = 180.0f;
- const F32 FOLLOW_CAM_BEHINDNESS_EPSILON = 1.0f;
- //------------------------------------
- // Constructor
- //------------------------------------
- LLFollowCamParams::LLFollowCamParams()
- {
- mMaxCameraDistantFromSubject = DEFAULT_MAX_DISTANCE_FROM_SUBJECT;
- mPositionLocked = false;
- mFocusLocked = false;
- mUsePosition = false;
- mUseFocus = false;
- //------------------------------------------------------
- // setting the attributes to their defaults
- //------------------------------------------------------
- setPositionLag ( FOLLOW_CAM_DEFAULT_POSITION_LAG );
- setFocusLag ( FOLLOW_CAM_DEFAULT_FOCUS_LAG );
- setPositionThreshold( FOLLOW_CAM_DEFAULT_POSITION_THRESHOLD );
- setFocusThreshold ( FOLLOW_CAM_DEFAULT_FOCUS_THRESHOLD );
- setBehindnessLag ( FOLLOW_CAM_DEFAULT_BEHINDNESS_LAG );
- setDistance ( FOLLOW_CAM_DEFAULT_DISTANCE );
- setPitch ( FOLLOW_CAM_DEFAULT_PITCH );
- setFocusOffset ( FOLLOW_CAM_DEFAULT_FOCUS_OFFSET );
- setBehindnessAngle ( FOLLOW_CAM_DEFAULT_BEHINDNESS_ANGLE );
- setPositionThreshold( FOLLOW_CAM_DEFAULT_POSITION_THRESHOLD );
- setFocusThreshold ( FOLLOW_CAM_DEFAULT_FOCUS_THRESHOLD );
- }
- LLFollowCamParams::~LLFollowCamParams() { }
- //---------------------------------------------------------
- // buncho set methods
- //---------------------------------------------------------
- //---------------------------------------------------------
- void LLFollowCamParams::setPositionLag( F32 p )
- {
- mPositionLag = llclamp(p, FOLLOW_CAM_MIN_POSITION_LAG, FOLLOW_CAM_MAX_POSITION_LAG);
- }
- //---------------------------------------------------------
- void LLFollowCamParams::setFocusLag( F32 f )
- {
- mFocusLag = llclamp(f, FOLLOW_CAM_MIN_FOCUS_LAG, FOLLOW_CAM_MAX_FOCUS_LAG);
- }
- //---------------------------------------------------------
- void LLFollowCamParams::setPositionThreshold( F32 p )
- {
- mPositionThreshold = llclamp(p, FOLLOW_CAM_MIN_POSITION_THRESHOLD, FOLLOW_CAM_MAX_POSITION_THRESHOLD);
- }
- //---------------------------------------------------------
- void LLFollowCamParams::setFocusThreshold( F32 f )
- {
- mFocusThreshold = llclamp(f, FOLLOW_CAM_MIN_FOCUS_THRESHOLD, FOLLOW_CAM_MAX_FOCUS_THRESHOLD);
- }
- //---------------------------------------------------------
- void LLFollowCamParams::setPitch( F32 p )
- {
- mPitch = llclamp(p, FOLLOW_CAM_MIN_PITCH, FOLLOW_CAM_MAX_PITCH);
- }
- //---------------------------------------------------------
- void LLFollowCamParams::setBehindnessLag( F32 b )
- {
- mBehindnessLag = llclamp(b, FOLLOW_CAM_MIN_BEHINDNESS_LAG, FOLLOW_CAM_MAX_BEHINDNESS_LAG);
- }
- //---------------------------------------------------------
- void LLFollowCamParams::setBehindnessAngle( F32 b )
- {
- mBehindnessMaxAngle = llclamp(b, FOLLOW_CAM_MIN_BEHINDNESS_ANGLE, FOLLOW_CAM_MAX_BEHINDNESS_ANGLE);
- }
- //---------------------------------------------------------
- void LLFollowCamParams::setDistance( F32 d )
- {
- mDistance = llclamp(d, FOLLOW_CAM_MIN_DISTANCE, mMaxCameraDistantFromSubject);
- }
- //---------------------------------------------------------
- void LLFollowCamParams::setPositionLocked( bool l )
- {
- mPositionLocked = l;
- }
- //---------------------------------------------------------
- void LLFollowCamParams::setFocusLocked( bool l )
- {
- mFocusLocked = l;
- }
- //---------------------------------------------------------
- void LLFollowCamParams::setFocusOffset( const LLVector3& v )
- {
- mFocusOffset = v;
- mFocusOffset.clamp(FOLLOW_CAM_MIN_FOCUS_OFFSET, FOLLOW_CAM_MAX_FOCUS_OFFSET);
- }
- //---------------------------------------------------------
- void LLFollowCamParams::setPosition( const LLVector3& p )
- {
- mUsePosition = true;
- mPosition = p;
- }
- //---------------------------------------------------------
- void LLFollowCamParams::setFocus( const LLVector3& f )
- {
- mUseFocus = true;
- mFocus = f;
- }
- //---------------------------------------------------------
- // buncho get methods
- //---------------------------------------------------------
- F32 LLFollowCamParams::getPositionLag () const { return mPositionLag; }
- F32 LLFollowCamParams::getFocusLag () const { return mFocusLag; }
- F32 LLFollowCamParams::getPositionThreshold () const { return mPositionThreshold; }
- F32 LLFollowCamParams::getFocusThreshold () const { return mFocusThreshold; }
- F32 LLFollowCamParams::getDistance () const { return mDistance; }
- F32 LLFollowCamParams::getPitch () const { return mPitch; }
- LLVector3 LLFollowCamParams::getFocusOffset () const { return mFocusOffset; }
- F32 LLFollowCamParams::getBehindnessAngle () const { return mBehindnessMaxAngle; }
- F32 LLFollowCamParams::getBehindnessLag () const { return mBehindnessLag; }
- LLVector3 LLFollowCamParams::getPosition () const { return mPosition; }
- LLVector3 LLFollowCamParams::getFocus () const { return mFocus; }
- bool LLFollowCamParams::getPositionLocked () const { return mPositionLocked; }
- bool LLFollowCamParams::getFocusLocked () const { return mFocusLocked; }
- //------------------------------------
- // Constructor
- //------------------------------------
- LLFollowCam::LLFollowCam() : LLFollowCamParams()
- {
- mUpVector = LLVector3::z_axis;
- mSubjectPosition = LLVector3::zero;
- mSubjectRotation = LLQuaternion::DEFAULT;
- mZoomedToMinimumDistance = false;
- mPitchCos = mPitchSin = 0.f;
- mPitchSineAndCosineNeedToBeUpdated = true;
- mSimulatedDistance = mDistance;
- }
- void LLFollowCam::copyParams(LLFollowCamParams& params)
- {
- setPositionLag(params.getPositionLag());
- setFocusLag(params.getFocusLag());
- setFocusThreshold( params.getFocusThreshold());
- setPositionThreshold(params.getPositionThreshold());
- setPitch(params.getPitch());
- setFocusOffset(params.getFocusOffset());
- setBehindnessAngle(params.getBehindnessAngle());
- setBehindnessLag(params.getBehindnessLag());
- setPositionLocked(params.getPositionLocked());
- setFocusLocked(params.getFocusLocked());
- setDistance(params.getDistance());
- if (params.getUsePosition())
- {
- setPosition(params.getPosition());
- }
- if (params.getUseFocus())
- {
- setFocus(params.getFocus());
- }
- }
- //---------------------------------------------------------------------------------------------------------
- void LLFollowCam::update()
- {
- //####################################################################################
- // update Focus
- //####################################################################################
- LLVector3 offsetSubjectPosition = mSubjectPosition + (mFocusOffset * mSubjectRotation);
- LLVector3 simulated_pos_agent = gAgent.getPosAgentFromGlobal(mSimulatedPositionGlobal);
- LLVector3 vectorFromCameraToSubject = offsetSubjectPosition - simulated_pos_agent;
- F32 distanceFromCameraToSubject = vectorFromCameraToSubject.magVec();
- LLVector3 whereFocusWantsToBe = mFocus;
- LLVector3 focus_pt_agent = gAgent.getPosAgentFromGlobal(mSimulatedFocusGlobal);
- if ( mFocusLocked ) // if focus is locked, only relative focus needs to be updated
- {
- mRelativeFocus = (focus_pt_agent - mSubjectPosition) * ~mSubjectRotation;
- }
- else
- {
- LLVector3 focusOffset = offsetSubjectPosition - focus_pt_agent;
- F32 focusOffsetDistance = focusOffset.magVec();
- LLVector3 focusOffsetDirection = focusOffset / focusOffsetDistance;
- whereFocusWantsToBe = focus_pt_agent +
- (focusOffsetDirection * (focusOffsetDistance - mFocusThreshold));
- if ( focusOffsetDistance > mFocusThreshold )
- {
- // this version normalizes focus threshold by distance
- // so that the effect is not changed with distance
- /*
- F32 focusThresholdNormalizedByDistance = distanceFromCameraToSubject * mFocusThreshold;
- if ( focusOffsetDistance > focusThresholdNormalizedByDistance )
- {
- LLVector3 focusOffsetDirection = focusOffset / focusOffsetDistance;
- F32 force = focusOffsetDistance - focusThresholdNormalizedByDistance;
- */
- F32 focusLagLerp = LLCriticalDamp::getInterpolant( mFocusLag );
- focus_pt_agent = lerp( focus_pt_agent, whereFocusWantsToBe, focusLagLerp );
- mSimulatedFocusGlobal = gAgent.getPosGlobalFromAgent(focus_pt_agent);
- }
- mRelativeFocus = lerp(mRelativeFocus, (focus_pt_agent - mSubjectPosition) * ~mSubjectRotation, LLCriticalDamp::getInterpolant(0.05f));
- }// if focus is not locked ---------------------------------------------
- LLVector3 whereCameraPositionWantsToBe = gAgent.getPosAgentFromGlobal(mSimulatedPositionGlobal);
- if ( mPositionLocked )
- {
- mRelativePos = (whereCameraPositionWantsToBe - mSubjectPosition) * ~mSubjectRotation;
- }
- else
- {
- //####################################################################################
- // update Position
- //####################################################################################
- //-------------------------------------------------------------------------
- // I determine the horizontal vector from the camera to the subject
- //-------------------------------------------------------------------------
- LLVector3 horizontalVectorFromCameraToSubject = vectorFromCameraToSubject;
- horizontalVectorFromCameraToSubject.mV[VZ] = 0.0f;
- //---------------------------------------------------------
- // Now I determine the horizontal distance
- //---------------------------------------------------------
- F32 horizontalDistanceFromCameraToSubject = horizontalVectorFromCameraToSubject.magVec();
- //---------------------------------------------------------
- // Then I get the (normalized) horizontal direction...
- //---------------------------------------------------------
- LLVector3 horizontalDirectionFromCameraToSubject;
- if ( horizontalDistanceFromCameraToSubject < DISTANCE_EPSILON )
- {
- // make sure we still have a normalized vector if distance is really small
- // (this case is rare and fleeting)
- horizontalDirectionFromCameraToSubject = LLVector3::z_axis;
- }
- else
- {
- // I'm not using the "normalize" method, because I can just divide by horizontalDistanceFromCameraToSubject
- horizontalDirectionFromCameraToSubject = horizontalVectorFromCameraToSubject / horizontalDistanceFromCameraToSubject;
- }
- //------------------------------------------------------------------------------------------------------------
- // Here is where I determine an offset relative to subject position in oder to set the ideal position.
- //------------------------------------------------------------------------------------------------------------
- if ( mPitchSineAndCosineNeedToBeUpdated )
- {
- calculatePitchSineAndCosine();
- mPitchSineAndCosineNeedToBeUpdated = false;
- }
- LLVector3 positionOffsetFromSubject;
- positionOffsetFromSubject.setVec
- (
- horizontalDirectionFromCameraToSubject.mV[ VX ] * mPitchCos,
- horizontalDirectionFromCameraToSubject.mV[ VY ] * mPitchCos,
- -mPitchSin
- );
- positionOffsetFromSubject *= mSimulatedDistance;
- //----------------------------------------------------------------------
- // Finally, ideal position is set by taking the subject position and
- // extending the positionOffsetFromSubject from that
- //----------------------------------------------------------------------
- LLVector3 idealCameraPosition = offsetSubjectPosition - positionOffsetFromSubject;
- //--------------------------------------------------------------------------------
- // Now I prepare to move the current camera position towards its ideal position...
- //--------------------------------------------------------------------------------
- LLVector3 vectorFromPositionToIdealPosition = idealCameraPosition - simulated_pos_agent;
- F32 distanceFromPositionToIdealPosition = vectorFromPositionToIdealPosition.magVec();
-
- //put this inside of the block?
- LLVector3 normalFromPositionToIdealPosition = vectorFromPositionToIdealPosition / distanceFromPositionToIdealPosition;
-
- whereCameraPositionWantsToBe = simulated_pos_agent +
- (normalFromPositionToIdealPosition * (distanceFromPositionToIdealPosition - mPositionThreshold));
- //-------------------------------------------------------------------------------------------------
- // The following method takes the target camera position and resets it so that it stays "behind" the subject,
- // using behindness angle and behindness force as parameters affecting the exact behavior
- //-------------------------------------------------------------------------------------------------
- if ( distanceFromPositionToIdealPosition > mPositionThreshold )
- {
- F32 positionPullLerp = LLCriticalDamp::getInterpolant( mPositionLag );
- simulated_pos_agent = lerp( simulated_pos_agent, whereCameraPositionWantsToBe, positionPullLerp );
- }
- //--------------------------------------------------------------------
- // don't let the camera get farther than its official max distance
- //--------------------------------------------------------------------
- if ( distanceFromCameraToSubject > mMaxCameraDistantFromSubject )
- {
- LLVector3 directionFromCameraToSubject = vectorFromCameraToSubject / distanceFromCameraToSubject;
- simulated_pos_agent = offsetSubjectPosition - directionFromCameraToSubject * mMaxCameraDistantFromSubject;
- }
- ////-------------------------------------------------------------------------------------------------
- //// The following method takes mSimulatedPositionGlobal and resets it so that it stays "behind" the subject,
- //// using behindness angle and behindness force as parameters affecting the exact behavior
- ////-------------------------------------------------------------------------------------------------
- updateBehindnessConstraint(gAgent.getPosAgentFromGlobal(mSimulatedFocusGlobal), simulated_pos_agent);
- mSimulatedPositionGlobal = gAgent.getPosGlobalFromAgent(simulated_pos_agent);
- mRelativePos = lerp(mRelativePos, (simulated_pos_agent - mSubjectPosition) * ~mSubjectRotation, LLCriticalDamp::getInterpolant(0.05f));
- } // if position is not locked -----------------------------------------------------------
- //####################################################################################
- // update UpVector
- //####################################################################################
- // this just points upward for now, but I anticipate future effects requiring
- // some rolling ("banking" effects for fun, swoopy vehicles, etc.)
- mUpVector = LLVector3::z_axis;
- }
- //-------------------------------------------------------------------------------------
- BOOL LLFollowCam::updateBehindnessConstraint(LLVector3 focus, LLVector3& cam_position)
- {
- BOOL constraint_active = FALSE;
- // only apply this stuff if the behindness angle is something other than opened up all the way
- if ( mBehindnessMaxAngle < FOLLOW_CAM_MAX_BEHINDNESS_ANGLE - FOLLOW_CAM_BEHINDNESS_EPSILON )
- {
- //--------------------------------------------------------------
- // horizontalized vector from focus to camera
- //--------------------------------------------------------------
- LLVector3 horizontalVectorFromFocusToCamera;
- horizontalVectorFromFocusToCamera.setVec(cam_position - focus);
- horizontalVectorFromFocusToCamera.mV[ VZ ] = 0.0f;
- F32 cameraZ = cam_position.mV[ VZ ];
- //--------------------------------------------------------------
- // distance of horizontalized vector
- //--------------------------------------------------------------
- F32 horizontalDistance = horizontalVectorFromFocusToCamera.magVec();
- //--------------------------------------------------------------------------------------------------
- // calculate horizontalized back vector of the subject and scale by horizontalDistance
- //--------------------------------------------------------------------------------------------------
- LLVector3 horizontalSubjectBack( -1.0f, 0.0f, 0.0f );
- horizontalSubjectBack *= mSubjectRotation;
- horizontalSubjectBack.mV[ VZ ] = 0.0f;
- horizontalSubjectBack.normVec(); // because horizontalizing might make it shorter than 1
- horizontalSubjectBack *= horizontalDistance;
- //--------------------------------------------------------------------------------------------------
- // find the angle (in degrees) between these vectors
- //--------------------------------------------------------------------------------------------------
- F32 cameraOffsetAngle = 0.f;
- LLVector3 cameraOffsetRotationAxis;
- LLQuaternion camera_offset_rotation;
- camera_offset_rotation.shortestArc(horizontalSubjectBack, horizontalVectorFromFocusToCamera);
- camera_offset_rotation.getAngleAxis(&cameraOffsetAngle, cameraOffsetRotationAxis);
- cameraOffsetAngle *= RAD_TO_DEG;
- if ( cameraOffsetAngle > mBehindnessMaxAngle )
- {
- F32 fraction = ((cameraOffsetAngle - mBehindnessMaxAngle) / cameraOffsetAngle) * LLCriticalDamp::getInterpolant(mBehindnessLag);
- cam_position = focus + horizontalSubjectBack * (slerp(fraction, camera_offset_rotation, LLQuaternion::DEFAULT));
- cam_position.mV[VZ] = cameraZ; // clamp z value back to what it was before we started messing with it
- constraint_active = TRUE;
- }
- }
- return constraint_active;
- }
- //---------------------------------------------------------
- void LLFollowCam::calculatePitchSineAndCosine()
- {
- F32 radian = mPitch * DEG_TO_RAD;
- mPitchCos = cos( radian );
- mPitchSin = sin( radian );
- }
- //---------------------------------------------------------
- void LLFollowCam::setSubjectPositionAndRotation( const LLVector3 p, const LLQuaternion r )
- {
- mSubjectPosition = p;
- mSubjectRotation = r;
- }
- //---------------------------------------------------------
- void LLFollowCam::zoom( S32 z )
- {
- F32 zoomAmount = z * mSimulatedDistance * FOLLOW_CAM_ZOOM_FACTOR;
- if (( zoomAmount < FOLLOW_CAM_MIN_ZOOM_AMOUNT )
- && ( zoomAmount > -FOLLOW_CAM_MIN_ZOOM_AMOUNT ))
- {
- if ( zoomAmount < 0.0f )
- {
- zoomAmount = -FOLLOW_CAM_MIN_ZOOM_AMOUNT;
- }
- else
- {
- zoomAmount = FOLLOW_CAM_MIN_ZOOM_AMOUNT;
- }
- }
- mSimulatedDistance += zoomAmount;
- mZoomedToMinimumDistance = false;
- if ( mSimulatedDistance < FOLLOW_CAM_MIN_DISTANCE )
- {
- mSimulatedDistance = FOLLOW_CAM_MIN_DISTANCE;
- // if zoomAmount is negative (i.e., getting closer), then
- // this signifies having hit the minimum:
- if ( zoomAmount < 0.0f )
- {
- mZoomedToMinimumDistance = true;
- }
- }
- else if ( mSimulatedDistance > mMaxCameraDistantFromSubject )
- {
- mSimulatedDistance = mMaxCameraDistantFromSubject;
- }
- }
- //---------------------------------------------------------
- bool LLFollowCam::isZoomedToMinimumDistance()
- {
- return mZoomedToMinimumDistance;
- }
- //---------------------------------------------------------
- void LLFollowCam::reset( const LLVector3 p, const LLVector3 f , const LLVector3 u )
- {
- setPosition(p);
- setFocus(f);
- mUpVector = u;
- }
- //---------------------------------------------------------
- void LLFollowCam::setMaxCameraDistantFromSubject( F32 m )
- {
- mMaxCameraDistantFromSubject = m;
- }
- void LLFollowCam::setPitch( F32 p )
- {
- LLFollowCamParams::setPitch(p);
- mPitchSineAndCosineNeedToBeUpdated = true; // important
- }
- void LLFollowCam::setDistance( F32 d )
- {
- if (d != mDistance)
- {
- LLFollowCamParams::setDistance(d);
- mSimulatedDistance = d;
- mZoomedToMinimumDistance = false;
- }
- }
- void LLFollowCam::setPosition( const LLVector3& p )
- {
- if (p != mPosition)
- {
- LLFollowCamParams::setPosition(p);
- mSimulatedPositionGlobal = gAgent.getPosGlobalFromAgent(mPosition);
- if (mPositionLocked)
- {
- mRelativePos = (mPosition - mSubjectPosition) * ~mSubjectRotation;
- }
- }
- }
- void LLFollowCam::setFocus( const LLVector3& f )
- {
- if (f != mFocus)
- {
- LLFollowCamParams::setFocus(f);
- mSimulatedFocusGlobal = gAgent.getPosGlobalFromAgent(f);
- if (mFocusLocked)
- {
- mRelativeFocus = (mFocus - mSubjectPosition) * ~mSubjectRotation;
- }
- }
- }
- void LLFollowCam::setPositionLocked( bool locked )
- {
- LLFollowCamParams::setPositionLocked(locked);
- if (locked)
- {
- // propagate set position to relative position
- mRelativePos = (gAgent.getPosAgentFromGlobal(mSimulatedPositionGlobal) - mSubjectPosition) * ~mSubjectRotation;
- }
- }
- void LLFollowCam::setFocusLocked( bool locked )
- {
- LLFollowCamParams::setFocusLocked(locked);
- if (locked)
- {
- // propagate set position to relative position
- mRelativeFocus = (gAgent.getPosAgentFromGlobal(mSimulatedFocusGlobal) - mSubjectPosition) * ~mSubjectRotation;
- }
- }
- LLVector3 LLFollowCam::getSimulatedPosition() const
- {
- // return simulated position
- return mSubjectPosition + (mRelativePos * mSubjectRotation);
- }
- LLVector3 LLFollowCam::getSimulatedFocus() const
- {
- // return simulated focus point
- return mSubjectPosition + (mRelativeFocus * mSubjectRotation);
- }
- LLVector3 LLFollowCam::getUpVector()
- {
- return mUpVector;
- }
- //------------------------------------
- // Destructor
- //------------------------------------
- LLFollowCam::~LLFollowCam()
- {
- }
- //-------------------------------------------------------
- // LLFollowCamMgr
- //-------------------------------------------------------
- //static
- void LLFollowCamMgr::cleanupClass()
- {
- for (param_map_t::iterator iter = sParamMap.begin(); iter != sParamMap.end(); ++iter)
- {
- LLFollowCamParams* params = iter->second;
- delete params;
- }
- sParamMap.clear();
- }
- //static
- void LLFollowCamMgr::setPositionLag( const LLUUID& source, F32 lag)
- {
- LLFollowCamParams* paramsp = getParamsForID(source);
- if (paramsp)
- {
- paramsp->setPositionLag(lag);
- }
- }
- //static
- void LLFollowCamMgr::setFocusLag( const LLUUID& source, F32 lag)
- {
- LLFollowCamParams* paramsp = getParamsForID(source);
- if (paramsp)
- {
- paramsp->setFocusLag(lag);
- }
- }
- //static
- void LLFollowCamMgr::setFocusThreshold( const LLUUID& source, F32 threshold)
- {
- LLFollowCamParams* paramsp = getParamsForID(source);
- if (paramsp)
- {
- paramsp->setFocusThreshold(threshold);
- }
- }
- //static
- void LLFollowCamMgr::setPositionThreshold( const LLUUID& source, F32 threshold)
- {
- LLFollowCamParams* paramsp = getParamsForID(source);
- if (paramsp)
- {
- paramsp->setPositionThreshold(threshold);
- }
- }
- //static
- void LLFollowCamMgr::setDistance( const LLUUID& source, F32 distance)
- {
- LLFollowCamParams* paramsp = getParamsForID(source);
- if (paramsp)
- {
- paramsp->setDistance(distance);
- }
- }
- //static
- void LLFollowCamMgr::setPitch( const LLUUID& source, F32 pitch)
- {
- LLFollowCamParams* paramsp = getParamsForID(source);
- if (paramsp)
- {
- paramsp->setPitch(pitch);
- }
- }
- //static
- void LLFollowCamMgr::setFocusOffset( const LLUUID& source, const LLVector3& offset)
- {
- LLFollowCamParams* paramsp = getParamsForID(source);
- if (paramsp)
- {
- paramsp->setFocusOffset(offset);
- }
- }
- //static
- void LLFollowCamMgr::setBehindnessAngle( const LLUUID& source, F32 angle)
- {
- LLFollowCamParams* paramsp = getParamsForID(source);
- if (paramsp)
- {
- paramsp->setBehindnessAngle(angle);
- }
- }
- //static
- void LLFollowCamMgr::setBehindnessLag( const LLUUID& source, F32 force)
- {
- LLFollowCamParams* paramsp = getParamsForID(source);
- if (paramsp)
- {
- paramsp->setBehindnessLag(force);
- }
- }
- //static
- void LLFollowCamMgr::setPosition( const LLUUID& source, const LLVector3 position)
- {
- LLFollowCamParams* paramsp = getParamsForID(source);
- if (paramsp)
- {
- paramsp->setPosition(position);
- }
- }
- //static
- void LLFollowCamMgr::setFocus( const LLUUID& source, const LLVector3 focus)
- {
- LLFollowCamParams* paramsp = getParamsForID(source);
- if (paramsp)
- {
- paramsp->setFocus(focus);
- }
- }
- //static
- void LLFollowCamMgr::setPositionLocked( const LLUUID& source, bool locked)
- {
- LLFollowCamParams* paramsp = getParamsForID(source);
- if (paramsp)
- {
- paramsp->setPositionLocked(locked);
- }
- }
- //static
- void LLFollowCamMgr::setFocusLocked( const LLUUID& source, bool locked )
- {
- LLFollowCamParams* paramsp = getParamsForID(source);
- if (paramsp)
- {
- paramsp->setFocusLocked(locked);
- }
- }
- //static
- LLFollowCamParams* LLFollowCamMgr::getParamsForID(const LLUUID& source)
- {
- LLFollowCamParams* params = NULL;
- param_map_t::iterator found_it = sParamMap.find(source);
- if (found_it == sParamMap.end()) // didn't find it?
- {
- params = new LLFollowCamParams();
- sParamMap[source] = params;
- }
- else
- {
- params = found_it->second;
- }
- return params;
- }
- //static
- LLFollowCamParams* LLFollowCamMgr::getActiveFollowCamParams()
- {
- if (sParamStack.empty())
- {
- return NULL;
- }
- return sParamStack.back();
- }
- //static
- void LLFollowCamMgr::setCameraActive( const LLUUID& source, bool active )
- {
- LLFollowCamParams* params = getParamsForID(source);
- param_stack_t::iterator found_it = std::find(sParamStack.begin(), sParamStack.end(), params);
- if (found_it != sParamStack.end())
- {
- sParamStack.erase(found_it);
- }
- // put on top of stack
- if(active)
- {
- sParamStack.push_back(params);
- }
- }
- //static
- void LLFollowCamMgr::removeFollowCamParams(const LLUUID& source)
- {
- setCameraActive(source, FALSE);
- LLFollowCamParams* params = getParamsForID(source);
- sParamMap.erase(source);
- delete params;
- }
- //static
- bool LLFollowCamMgr::isScriptedCameraSource(const LLUUID& source)
- {
- param_map_t::iterator found_it = sParamMap.find(source);
- return (found_it != sParamMap.end());
- }
- //static
- void LLFollowCamMgr::dump()
- {
- S32 param_count = 0;
- llinfos << "Scripted camera active stack" << llendl;
- for (param_stack_t::iterator param_it = sParamStack.begin();
- param_it != sParamStack.end();
- ++param_it)
- {
- llinfos << param_count++ <<
- " rot_limit: " << (*param_it)->getBehindnessAngle() <<
- " rot_lag: " << (*param_it)->getBehindnessLag() <<
- " distance: " << (*param_it)->getDistance() <<
- " focus: " << (*param_it)->getFocus() <<
- " foc_lag: " << (*param_it)->getFocusLag() <<
- " foc_lock: " << ((*param_it)->getFocusLocked() ? "Y" : "N") <<
- " foc_offset: " << (*param_it)->getFocusOffset() <<
- " foc_thresh: " << (*param_it)->getFocusThreshold() <<
- " pitch: " << (*param_it)->getPitch() <<
- " pos: " << (*param_it)->getPosition() <<
- " pos_lag: " << (*param_it)->getPositionLag() <<
- " pos_lock: " << ((*param_it)->getPositionLocked() ? "Y" : "N") <<
- " pos_thresh: " << (*param_it)->getPositionThreshold() << llendl;
- }
- }