Skip to content

Commit

Permalink
#1200 Avatar rotates 360 degrees when viewed from the top and below
Browse files Browse the repository at this point in the history
  • Loading branch information
LLGuru committed Apr 15, 2024
1 parent 5118ba7 commit 3b04c12
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 32 deletions.
86 changes: 54 additions & 32 deletions indra/newview/llagent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1453,48 +1453,70 @@ LLVector3 LLAgent::getReferenceUpVector()
return up_vector;
}


#pragma optimize("", off)
// 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
if (gAgentCamera.getCameraMode() == CAMERA_MODE_THIRD_PERSON ||
gAgentCamera.getCameraMode() == CAMERA_MODE_MOUSELOOK)
{
// 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
LLVector3 skyward = getReferenceUpVector();
F32 agent_angle_from_skyward = acos(newCoordFrame.getAtAxis() * skyward) * RAD_TO_DEG;

if (fabs(angle) > 1e-4)
{
mFrameAgent.pitch(angle);
}
F32 min_angle = 1;
F32 max_angle = 179;
bool check_camera = false;

if (gAgentCamera.getCameraMode() == CAMERA_MODE_THIRD_PERSON)
{
if (gAgentCamera.getCameraPreset() == CAMERA_PRESET_REAR_VIEW)
{
min_angle = 10;
check_camera = true;
}
else if (gAgentCamera.getCameraPreset() == CAMERA_PRESET_GROUP_VIEW)
{
min_angle = 10;
max_angle = 170;
check_camera = true;
}
}

if ((angle < 0 && agent_angle_from_skyward < min_angle) ||
(angle > 0 && agent_angle_from_skyward > max_angle))
return;

if (check_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 camera_angle_from_skyward = angle_between(look_dir, skyward) * RAD_TO_DEG;
if ((angle < 0 && camera_angle_from_skyward < min_angle) ||
(angle > 0 && camera_angle_from_skyward > max_angle))
return;
}
}

mFrameAgent = newCoordFrame;
}


Expand Down
1 change: 1 addition & 0 deletions indra/newview/llagentcamera.h
Original file line number Diff line number Diff line change
Expand Up @@ -112,6 +112,7 @@ class LLAgentCamera
//--------------------------------------------------------------------
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 */
Expand Down

0 comments on commit 3b04c12

Please sign in to comment.