From 420b91db29485df39fd6e724e782c449158811cb Mon Sep 17 00:00:00 2001 From: James Cook Date: Tue, 2 Jan 2007 08:33:20 +0000 Subject: Print done when done. --- indra/newview/llfollowcam.cpp | 882 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 882 insertions(+) create mode 100644 indra/newview/llfollowcam.cpp (limited to 'indra/newview/llfollowcam.cpp') diff --git a/indra/newview/llfollowcam.cpp b/indra/newview/llfollowcam.cpp new file mode 100644 index 0000000000..6f1addcebb --- /dev/null +++ b/indra/newview/llfollowcam.cpp @@ -0,0 +1,882 @@ +/** + * @file llfollowcam.cpp + * @author Jeffrey Ventrella + * @brief LLFollowCam class implementation + * + * Copyright (c) 2005-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +#include "llviewerprecompiledheaders.h" +#include "llfollowcam.h" +#include "llagent.h" + +//------------------------------------------------------- +// class statics +//------------------------------------------------------- +std::map LLFollowCamMgr::sParamMap; +std::vector 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; + 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; + } +} + -- cgit v1.2.3