diff options
-rw-r--r-- | indra/newview/llagent.cpp | 83 | ||||
-rw-r--r-- | indra/newview/llagentcamera.h | 1 |
2 files changed, 52 insertions, 32 deletions
diff --git a/indra/newview/llagent.cpp b/indra/newview/llagent.cpp index 13501833b2..192bd9cccd 100644 --- a/indra/newview/llagent.cpp +++ b/indra/newview/llagent.cpp @@ -1453,48 +1453,67 @@ LLVector3 LLAgent::getReferenceUpVector() return up_vector; } - // Radians, positive is forward into ground //----------------------------------------------------------------------------- // pitch() //----------------------------------------------------------------------------- void LLAgent::pitch(F32 angle) { - // don't let user pitch if pointed almost all the way down or up + if (fabs(angle) <= 1e-4) + return; - // A dot B = mag(A) * mag(B) * cos(angle between A and B) - // so... cos(angle between A and B) = A dot B / mag(A) / mag(B) - // = A dot B for unit vectors + LLCoordFrame newCoordFrame(mFrameAgent); + newCoordFrame.pitch(angle); - LLVector3 skyward = getReferenceUpVector(); + // don't let user pitch if rotated 180 degree around the vertical axis + if ((newCoordFrame.getXAxis()[VX] * mFrameAgent.getXAxis()[VX] < 0) && + (newCoordFrame.getXAxis()[VY] * mFrameAgent.getXAxis()[VY] < 0)) + return; - // clamp pitch to limits - if (angle >= 0.f) - { - const F32 look_down_limit = 179.f * DEG_TO_RAD; - F32 angle_from_skyward = acos(mFrameAgent.getAtAxis() * skyward); - if (angle_from_skyward + angle > look_down_limit) - { - angle = look_down_limit - angle_from_skyward; - } - } - else if (angle < 0.f) - { - const F32 look_up_limit = 5.f * DEG_TO_RAD; - const LLVector3& viewer_camera_pos = LLViewerCamera::getInstance()->getOrigin(); - LLVector3 agent_focus_pos = getPosAgentFromGlobal(gAgentCamera.calcFocusPositionTargetGlobal()); - LLVector3 look_dir = agent_focus_pos - viewer_camera_pos; - F32 angle_from_skyward = angle_between(look_dir, skyward); - if (angle_from_skyward + angle < look_up_limit) - { - angle = look_up_limit - angle_from_skyward; - } - } + // don't let user pitch if pointed almost all the way down or up + LLVector3 skyward = getReferenceUpVector(); - if (fabs(angle) > 1e-4) - { - mFrameAgent.pitch(angle); - } + // A dot B = mag(A) * mag(B) * cos(angle between A and B) + // so... cos(angle between A and B) = A dot B / mag(A) / mag(B) + // = A dot B for unit vectors + F32 agent_camera_angle_from_skyward = acos(newCoordFrame.getAtAxis() * skyward) * RAD_TO_DEG; + + F32 min_angle = 1; + F32 max_angle = 179; + bool check_viewer_camera = false; + + if (gAgentCamera.getCameraMode() == CAMERA_MODE_THIRD_PERSON) + { + // These values of min_angle and max_angle are obtained purely empirically + if (gAgentCamera.getCameraPreset() == CAMERA_PRESET_REAR_VIEW) + { + min_angle = 10; + check_viewer_camera = true; + } + else if (gAgentCamera.getCameraPreset() == CAMERA_PRESET_GROUP_VIEW) + { + min_angle = 10; + max_angle = 170; + check_viewer_camera = true; + } + } + + if ((angle < 0 && agent_camera_angle_from_skyward < min_angle) || + (angle > 0 && agent_camera_angle_from_skyward > max_angle)) + return; + + if (check_viewer_camera) + { + const LLVector3& viewer_camera_pos = LLViewerCamera::getInstance()->getOrigin(); + LLVector3 agent_focus_pos = getPosAgentFromGlobal(gAgentCamera.calcFocusPositionTargetGlobal()); + LLVector3 look_dir = agent_focus_pos - viewer_camera_pos; + F32 viewer_camera_angle_from_skyward = angle_between(look_dir, skyward) * RAD_TO_DEG; + if ((angle < 0 && viewer_camera_angle_from_skyward < min_angle) || + (angle > 0 && viewer_camera_angle_from_skyward > max_angle)) + return; + } + + mFrameAgent = newCoordFrame; } diff --git a/indra/newview/llagentcamera.h b/indra/newview/llagentcamera.h index d27cdb0c5c..4fab5f5d92 100644 --- a/indra/newview/llagentcamera.h +++ b/indra/newview/llagentcamera.h @@ -112,6 +112,7 @@ private: //-------------------------------------------------------------------- public: void switchCameraPreset(ECameraPreset preset); + ECameraPreset getCameraPreset() const { return mCameraPreset; } /** Determines default camera offset depending on the current camera preset */ LLVector3 getCameraOffsetInitial(); /** Determines default focus offset depending on the current camera preset */ |