secondlife/viewer#1200 Avatar rotates 360 degrees when viewed from the top and below
parent
e5b14e4c2c
commit
0d4f52b778
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
Loading…
Reference in New Issue