diff --git a/indra/newview/llagentcamera.cpp b/indra/newview/llagentcamera.cpp index 56f1ac6b81..b7b8038654 100644 --- a/indra/newview/llagentcamera.cpp +++ b/indra/newview/llagentcamera.cpp @@ -150,6 +150,8 @@ LLAgentCamera::LLAgentCamera() : mSitCameraEnabled(false), mCameraSmoothingLastPositionGlobal(), mCameraSmoothingLastPositionAgent(), + mCameraSmoothingLastFocusGlobal(), + mCameraSmoothingLastFocusValid(false), mCameraSmoothingStop(false), mCameraUpVector(LLVector3::z_axis), // default is straight up @@ -1052,6 +1054,13 @@ void LLAgentCamera::cameraOrbitIn(const F32 meters) } } +void LLAgentCamera::setCameraSmoothingLastPositionGlobal(const LLVector3d& camera_position_global) +{ + mCameraSmoothingLastPositionGlobal = camera_position_global; + mCameraSmoothingLastFocusGlobal = mFocusGlobal; + mCameraSmoothingLastFocusValid = true; +} + //----------------------------------------------------------------------------- // cameraPanIn() //----------------------------------------------------------------------------- @@ -1067,7 +1076,7 @@ void LLAgentCamera::cameraPanIn(F32 meters) // don't enforce zoom constraints as this is the only way for users to get past them easily updateFocusOffset(); // NOTE: panning movements expect the camera to move exactly with the focus target, not animated behind -Nyx - mCameraSmoothingLastPositionGlobal = calcCameraPositionTargetGlobal(); + setCameraSmoothingLastPositionGlobal(calcCameraPositionTargetGlobal()); } //----------------------------------------------------------------------------- @@ -1089,7 +1098,7 @@ void LLAgentCamera::cameraPanLeft(F32 meters) cameraZoomIn(1.f); updateFocusOffset(); // NOTE: panning movements expect the camera to move exactly with the focus target, not animated behind - Nyx - mCameraSmoothingLastPositionGlobal = calcCameraPositionTargetGlobal(); + setCameraSmoothingLastPositionGlobal(calcCameraPositionTargetGlobal()); } //----------------------------------------------------------------------------- @@ -1111,7 +1120,7 @@ void LLAgentCamera::cameraPanUp(F32 meters) cameraZoomIn(1.f); updateFocusOffset(); // NOTE: panning movements expect the camera to move exactly with the focus target, not animated behind -Nyx - mCameraSmoothingLastPositionGlobal = calcCameraPositionTargetGlobal(); + setCameraSmoothingLastPositionGlobal(calcCameraPositionTargetGlobal()); } void LLAgentCamera::resetCameraPan() @@ -1124,7 +1133,7 @@ void LLAgentCamera::resetCameraPan() cameraZoomIn(1.f); updateFocusOffset(); - mCameraSmoothingLastPositionGlobal = calcCameraPositionTargetGlobal(); + setCameraSmoothingLastPositionGlobal(calcCameraPositionTargetGlobal()); resetPanDiff(); } @@ -1466,6 +1475,21 @@ void LLAgentCamera::updateCamera() camera_pos_global = camera_pos_agent + agent_pos; } } + else if (mTrackFocusObject && mFocusObject.notNull()) + { + // Keep tracked-object translation exact and smooth only changes + // to the camera offset, as is done in avatar-relative mode. + LLVector3d camera_pos_focus = camera_pos_global - mFocusGlobal; + LLVector3d last_camera_pos_focus = + mCameraSmoothingLastPositionGlobal - mCameraSmoothingLastFocusGlobal; + LLVector3d delta = camera_pos_focus - last_camera_pos_focus; + if (mCameraSmoothingLastFocusValid && + delta.magVec() < MAX_CAMERA_SMOOTH_DISTANCE) + { + camera_pos_focus = lerp(last_camera_pos_focus, camera_pos_focus, smoothing); + camera_pos_global = camera_pos_focus + mFocusGlobal; + } + } else { LLVector3d delta = camera_pos_global - mCameraSmoothingLastPositionGlobal; @@ -1476,7 +1500,7 @@ void LLAgentCamera::updateCamera() } } - mCameraSmoothingLastPositionGlobal = camera_pos_global; + setCameraSmoothingLastPositionGlobal(camera_pos_global); mCameraSmoothingLastPositionAgent = camera_pos_agent; mCameraSmoothingStop = false; } diff --git a/indra/newview/llagentcamera.h b/indra/newview/llagentcamera.h index 384ed29245..4b5afb544e 100644 --- a/indra/newview/llagentcamera.h +++ b/indra/newview/llagentcamera.h @@ -149,6 +149,7 @@ class LLAgentCamera const LLVector3& getCameraUpVector() const { return mCameraUpVector; } private: LLVector3 getAvatarRootPosition(); + void setCameraSmoothingLastPositionGlobal(const LLVector3d& camera_position_global); F32 mCurrentCameraDistance; // Current camera offset from avatar F32 mTargetCameraDistance; // Target camera offset from avatar @@ -159,6 +160,8 @@ class LLAgentCamera LLVector3 mCameraVirtualPositionAgent; // Camera virtual position (target) before performing FOV zoom LLVector3d mCameraSmoothingLastPositionGlobal; LLVector3d mCameraSmoothingLastPositionAgent; + LLVector3d mCameraSmoothingLastFocusGlobal; + bool mCameraSmoothingLastFocusValid; bool mCameraSmoothingStop; LLVector3 mCameraLag; // Third person camera lag LLVector3 mCameraUpVector; // Camera's up direction in world coordinates (determines the 'roll' of the view)