summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--indra/newview/llagent.cpp83
-rw-r--r--indra/newview/llagentcamera.h1
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 */