Fixed snapping of rotation in the edge-on case
Patch by https://codereview.secondlife.com/users/cron.stardust/ Jira: https://jira.secondlife.com/browse/STORM-1919
This commit is contained in:
@@ -248,6 +248,7 @@ Celierra Darling
|
||||
VWR-6975
|
||||
Cron Stardust
|
||||
VWR-10579
|
||||
STORM-1919
|
||||
Cypren Christenson
|
||||
SNOW-129
|
||||
SNOW-140
|
||||
|
||||
@@ -1381,74 +1381,28 @@ LLQuaternion LLManipRotate::dragConstrained( S32 x, S32 y )
|
||||
BOOL hit = getMousePointOnPlaneAgent(projected_mouse, x, y, snap_plane_center, constraint_axis);
|
||||
projected_mouse -= snap_plane_center;
|
||||
|
||||
S32 snap_plane = 0;
|
||||
|
||||
F32 dot = cam_to_snap_plane * constraint_axis;
|
||||
if (llabs(dot) < 0.01f)
|
||||
{
|
||||
// looking at ring edge on, project onto view plane and check if mouse is past ring
|
||||
getMousePointOnPlaneAgent(projected_mouse, x, y, snap_plane_center, cam_to_snap_plane);
|
||||
projected_mouse -= snap_plane_center;
|
||||
dot = projected_mouse * constraint_axis;
|
||||
if (projected_mouse * constraint_axis > 0)
|
||||
{
|
||||
snap_plane = 1;
|
||||
}
|
||||
projected_mouse -= dot * constraint_axis;
|
||||
}
|
||||
else if (dot > 0.f)
|
||||
{
|
||||
// look for mouse position outside and in front of snap circle
|
||||
if (hit && projected_mouse.magVec() > SNAP_GUIDE_INNER_RADIUS * mRadiusMeters && projected_mouse * cam_to_snap_plane < 0.f)
|
||||
{
|
||||
snap_plane = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// look for mouse position inside or in back of snap circle
|
||||
if (projected_mouse.magVec() < SNAP_GUIDE_INNER_RADIUS * mRadiusMeters || projected_mouse * cam_to_snap_plane > 0.f || !hit)
|
||||
{
|
||||
snap_plane = 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (snap_plane == 0)
|
||||
{
|
||||
// try other plane
|
||||
snap_plane_center = (center - (constraint_axis * mRadiusMeters * 0.5f));
|
||||
if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD)
|
||||
{
|
||||
cam_to_snap_plane.setVec(1.f, 0.f, 0.f);
|
||||
}
|
||||
else
|
||||
{
|
||||
cam_to_snap_plane = snap_plane_center - gAgentCamera.getCameraPositionAgent();
|
||||
cam_to_snap_plane.normVec();
|
||||
}
|
||||
|
||||
hit = getMousePointOnPlaneAgent(projected_mouse, x, y, snap_plane_center, constraint_axis);
|
||||
projected_mouse -= snap_plane_center;
|
||||
|
||||
dot = cam_to_snap_plane * constraint_axis;
|
||||
if (gSavedSettings.getBOOL("SnapEnabled")) {
|
||||
S32 snap_plane = 0;
|
||||
|
||||
F32 dot = cam_to_snap_plane * constraint_axis;
|
||||
if (llabs(dot) < 0.01f)
|
||||
{
|
||||
// looking at ring edge on, project onto view plane and check if mouse is past ring
|
||||
getMousePointOnPlaneAgent(projected_mouse, x, y, snap_plane_center, cam_to_snap_plane);
|
||||
projected_mouse -= snap_plane_center;
|
||||
dot = projected_mouse * constraint_axis;
|
||||
if (projected_mouse * constraint_axis < 0)
|
||||
if (projected_mouse * constraint_axis > 0)
|
||||
{
|
||||
snap_plane = 2;
|
||||
snap_plane = 1;
|
||||
}
|
||||
projected_mouse -= dot * constraint_axis;
|
||||
}
|
||||
else if (dot < 0.f)
|
||||
else if (dot > 0.f)
|
||||
{
|
||||
// look for mouse position outside and in front of snap circle
|
||||
if (hit && projected_mouse.magVec() > SNAP_GUIDE_INNER_RADIUS * mRadiusMeters && projected_mouse * cam_to_snap_plane < 0.f)
|
||||
{
|
||||
snap_plane = 2;
|
||||
snap_plane = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
@@ -1456,78 +1410,136 @@ LLQuaternion LLManipRotate::dragConstrained( S32 x, S32 y )
|
||||
// look for mouse position inside or in back of snap circle
|
||||
if (projected_mouse.magVec() < SNAP_GUIDE_INNER_RADIUS * mRadiusMeters || projected_mouse * cam_to_snap_plane > 0.f || !hit)
|
||||
{
|
||||
snap_plane = 2;
|
||||
snap_plane = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (snap_plane > 0)
|
||||
{
|
||||
LLVector3 cam_at_axis;
|
||||
if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD)
|
||||
|
||||
if (snap_plane == 0)
|
||||
{
|
||||
cam_at_axis.setVec(1.f, 0.f, 0.f);
|
||||
// try other plane
|
||||
snap_plane_center = (center - (constraint_axis * mRadiusMeters * 0.5f));
|
||||
if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD)
|
||||
{
|
||||
cam_to_snap_plane.setVec(1.f, 0.f, 0.f);
|
||||
}
|
||||
else
|
||||
{
|
||||
cam_to_snap_plane = snap_plane_center - gAgentCamera.getCameraPositionAgent();
|
||||
cam_to_snap_plane.normVec();
|
||||
}
|
||||
|
||||
hit = getMousePointOnPlaneAgent(projected_mouse, x, y, snap_plane_center, constraint_axis);
|
||||
projected_mouse -= snap_plane_center;
|
||||
|
||||
dot = cam_to_snap_plane * constraint_axis;
|
||||
if (llabs(dot) < 0.01f)
|
||||
{
|
||||
// looking at ring edge on, project onto view plane and check if mouse is past ring
|
||||
getMousePointOnPlaneAgent(projected_mouse, x, y, snap_plane_center, cam_to_snap_plane);
|
||||
projected_mouse -= snap_plane_center;
|
||||
dot = projected_mouse * constraint_axis;
|
||||
if (projected_mouse * constraint_axis < 0)
|
||||
{
|
||||
snap_plane = 2;
|
||||
}
|
||||
projected_mouse -= dot * constraint_axis;
|
||||
}
|
||||
else if (dot < 0.f)
|
||||
{
|
||||
// look for mouse position outside and in front of snap circle
|
||||
if (hit && projected_mouse.magVec() > SNAP_GUIDE_INNER_RADIUS * mRadiusMeters && projected_mouse * cam_to_snap_plane < 0.f)
|
||||
{
|
||||
snap_plane = 2;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// look for mouse position inside or in back of snap circle
|
||||
if (projected_mouse.magVec() < SNAP_GUIDE_INNER_RADIUS * mRadiusMeters || projected_mouse * cam_to_snap_plane > 0.f || !hit)
|
||||
{
|
||||
snap_plane = 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
cam_at_axis = snap_plane_center - gAgentCamera.getCameraPositionAgent();
|
||||
cam_at_axis.normVec();
|
||||
}
|
||||
|
||||
// first, project mouse onto screen plane at point tangent to rotation radius.
|
||||
getMousePointOnPlaneAgent(projected_mouse, x, y, snap_plane_center, cam_at_axis);
|
||||
// project that point onto rotation plane
|
||||
projected_mouse -= snap_plane_center;
|
||||
projected_mouse -= projected_vec(projected_mouse, constraint_axis);
|
||||
|
||||
F32 mouse_lateral_dist = llmin(SNAP_GUIDE_INNER_RADIUS * mRadiusMeters, projected_mouse.magVec());
|
||||
F32 mouse_depth = SNAP_GUIDE_INNER_RADIUS * mRadiusMeters;
|
||||
if (llabs(mouse_lateral_dist) > 0.01f)
|
||||
{
|
||||
mouse_depth = sqrtf((SNAP_GUIDE_INNER_RADIUS * mRadiusMeters) * (SNAP_GUIDE_INNER_RADIUS * mRadiusMeters) -
|
||||
(mouse_lateral_dist * mouse_lateral_dist));
|
||||
}
|
||||
LLVector3 projected_camera_at = cam_at_axis - projected_vec(cam_at_axis, constraint_axis);
|
||||
projected_mouse -= mouse_depth * projected_camera_at;
|
||||
|
||||
if (!mInSnapRegime)
|
||||
{
|
||||
mSmoothRotate = TRUE;
|
||||
}
|
||||
mInSnapRegime = TRUE;
|
||||
// 0 to 360 deg
|
||||
F32 mouse_angle = fmodf(atan2(projected_mouse * axis1, projected_mouse * axis2) * RAD_TO_DEG + 360.f, 360.f);
|
||||
|
||||
F32 relative_mouse_angle = fmodf(mouse_angle + (SNAP_ANGLE_DETENTE / 2), SNAP_ANGLE_INCREMENT);
|
||||
//fmodf(llround(mouse_angle * RAD_TO_DEG, 7.5f) + 360.f, 360.f);
|
||||
|
||||
LLVector3 object_axis;
|
||||
getObjectAxisClosestToMouse(object_axis);
|
||||
object_axis = object_axis * first_object_node->mSavedRotation;
|
||||
|
||||
// project onto constraint plane
|
||||
object_axis = object_axis - (object_axis * getConstraintAxis()) * getConstraintAxis();
|
||||
object_axis.normVec();
|
||||
|
||||
if (relative_mouse_angle < SNAP_ANGLE_DETENTE)
|
||||
if (snap_plane > 0)
|
||||
{
|
||||
F32 quantized_mouse_angle = mouse_angle - (relative_mouse_angle - (SNAP_ANGLE_DETENTE * 0.5f));
|
||||
angle = (quantized_mouse_angle * DEG_TO_RAD) - atan2(object_axis * axis1, object_axis * axis2);
|
||||
LLVector3 cam_at_axis;
|
||||
if (mObjectSelection->getSelectType() == SELECT_TYPE_HUD)
|
||||
{
|
||||
cam_at_axis.setVec(1.f, 0.f, 0.f);
|
||||
}
|
||||
else
|
||||
{
|
||||
cam_at_axis = snap_plane_center - gAgentCamera.getCameraPositionAgent();
|
||||
cam_at_axis.normVec();
|
||||
}
|
||||
|
||||
// first, project mouse onto screen plane at point tangent to rotation radius.
|
||||
getMousePointOnPlaneAgent(projected_mouse, x, y, snap_plane_center, cam_at_axis);
|
||||
// project that point onto rotation plane
|
||||
projected_mouse -= snap_plane_center;
|
||||
projected_mouse -= projected_vec(projected_mouse, constraint_axis);
|
||||
|
||||
F32 mouse_lateral_dist = llmin(SNAP_GUIDE_INNER_RADIUS * mRadiusMeters, projected_mouse.magVec());
|
||||
F32 mouse_depth = SNAP_GUIDE_INNER_RADIUS * mRadiusMeters;
|
||||
if (llabs(mouse_lateral_dist) > 0.01f)
|
||||
{
|
||||
mouse_depth = sqrtf((SNAP_GUIDE_INNER_RADIUS * mRadiusMeters) * (SNAP_GUIDE_INNER_RADIUS * mRadiusMeters) -
|
||||
(mouse_lateral_dist * mouse_lateral_dist));
|
||||
}
|
||||
LLVector3 projected_camera_at = cam_at_axis - projected_vec(cam_at_axis, constraint_axis);
|
||||
projected_mouse -= mouse_depth * projected_camera_at;
|
||||
|
||||
if (!mInSnapRegime)
|
||||
{
|
||||
mSmoothRotate = TRUE;
|
||||
}
|
||||
mInSnapRegime = TRUE;
|
||||
// 0 to 360 deg
|
||||
F32 mouse_angle = fmodf(atan2(projected_mouse * axis1, projected_mouse * axis2) * RAD_TO_DEG + 360.f, 360.f);
|
||||
|
||||
F32 relative_mouse_angle = fmodf(mouse_angle + (SNAP_ANGLE_DETENTE / 2), SNAP_ANGLE_INCREMENT);
|
||||
//fmodf(llround(mouse_angle * RAD_TO_DEG, 7.5f) + 360.f, 360.f);
|
||||
|
||||
LLVector3 object_axis;
|
||||
getObjectAxisClosestToMouse(object_axis);
|
||||
object_axis = object_axis * first_object_node->mSavedRotation;
|
||||
|
||||
// project onto constraint plane
|
||||
object_axis = object_axis - (object_axis * getConstraintAxis()) * getConstraintAxis();
|
||||
object_axis.normVec();
|
||||
|
||||
if (relative_mouse_angle < SNAP_ANGLE_DETENTE)
|
||||
{
|
||||
F32 quantized_mouse_angle = mouse_angle - (relative_mouse_angle - (SNAP_ANGLE_DETENTE * 0.5f));
|
||||
angle = (quantized_mouse_angle * DEG_TO_RAD) - atan2(object_axis * axis1, object_axis * axis2);
|
||||
}
|
||||
else
|
||||
{
|
||||
angle = (mouse_angle * DEG_TO_RAD) - atan2(object_axis * axis1, object_axis * axis2);
|
||||
}
|
||||
return LLQuaternion( -angle, constraint_axis );
|
||||
}
|
||||
else
|
||||
{
|
||||
angle = (mouse_angle * DEG_TO_RAD) - atan2(object_axis * axis1, object_axis * axis2);
|
||||
if (mInSnapRegime)
|
||||
{
|
||||
mSmoothRotate = TRUE;
|
||||
}
|
||||
mInSnapRegime = FALSE;
|
||||
}
|
||||
return LLQuaternion( -angle, constraint_axis );
|
||||
}
|
||||
else
|
||||
{
|
||||
else {
|
||||
if (mInSnapRegime)
|
||||
{
|
||||
mSmoothRotate = TRUE;
|
||||
}
|
||||
mInSnapRegime = FALSE;
|
||||
|
||||
}
|
||||
|
||||
if (!mInSnapRegime)
|
||||
{
|
||||
LLVector3 up_from_axis = mCenterToCamNorm % constraint_axis;
|
||||
up_from_axis.normVec();
|
||||
LLVector3 cur_intersection;
|
||||
|
||||
Reference in New Issue
Block a user