Skip to content

secondlife/viewer#1200 Avatar rotates 360 degrees when viewed from the top and below #1327

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 25, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
83 changes: 51 additions & 32 deletions indra/newview/llagent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}


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
Loading