SOCIAL-530 WIP When double clicking a nearby location I want my avatar to walk to that spot

can drag objects in front of avatar in opposite direction now
reliably release mouse capture
min rotation radius is now scaled by camera distance from rotation center
meow-7.2.2
Richard Linden 2011-03-11 00:21:22 -08:00
parent d48a0f38ac
commit 1c5d2516e0
2 changed files with 49 additions and 74 deletions

View File

@ -102,7 +102,7 @@ BOOL LLToolPie::handleMouseDown(S32 x, S32 y, MASK mask)
mMouseOutsideSlop = FALSE;
mMouseDownX = x;
mMouseDownY = y;
mLastYaw = 0.f;
//left mouse down always picks transparent
mPick = gViewerWindow->pickImmediate(x, y, TRUE);
mPick.mKeyMask = mask;
@ -612,11 +612,6 @@ BOOL LLToolPie::handleMouseUp(S32 x, S32 y, MASK mask)
LLViewerObject* obj = mPick.getObject();
U8 click_action = final_click_action(obj);
if (hasMouseCapture())
{
setMouseCapture(FALSE);
}
bool media_handled_click = handleMediaMouseUp() || LLViewerMediaFocus::getInstance()->getFocus();
bool mouse_moved = mMouseOutsideSlop;
mMouseOutsideSlop = FALSE;
@ -634,6 +629,10 @@ BOOL LLToolPie::handleMouseUp(S32 x, S32 y, MASK mask)
}
}
gViewerWindow->setCursor(UI_CURSOR_ARROW);
if (hasMouseCapture())
{
setMouseCapture(FALSE);
}
LLToolMgr::getInstance()->clearTransientTool();
gAgentCamera.setLookAt(LOOKAT_TARGET_CONVERSATION, obj); // maybe look at object/person clicked on
@ -1657,28 +1656,16 @@ void LLToolPie::showVisualContextMenuEffect()
}
LLVector3 intersect_ray_with_sphere( const LLVector3& ray_pt, const LLVector3& ray_dir, const LLVector3& sphere_center, F32 sphere_radius)
bool intersect_ray_with_sphere( const LLVector3& ray_pt, const LLVector3& ray_dir, const LLVector3& sphere_center, F32 sphere_radius, LLVector3& intersection_pt)
{
// from http://www.siggraph.org/education/materials/HyperGraph/raytrace/rtinter1.htm
// do ray/sphere intersection by solving quadratic equation
LLVector3 sphere_to_ray_start_vec = ray_pt - sphere_center;
F32 B = 2.f * ray_dir * sphere_to_ray_start_vec;
F32 C = sphere_to_ray_start_vec.lengthSquared() - (sphere_radius * sphere_radius);
LLVector3 intersection_pt;
F32 discriminant = B*B - 4.f*C;
if (discriminant < 0.f)
{
// no intersection, compute closest intersection point
LLVector3 ray_to_sphere(sphere_to_ray_start_vec * -1.f);
LLVector3 ray_orthogonal_dir = ray_pt + projected_vec(ray_to_sphere, ray_dir) - sphere_center;
ray_orthogonal_dir.normalize();
intersection_pt = sphere_center + ray_orthogonal_dir * sphere_radius;
}
else
{
if (discriminant > 0.f)
{ // intersection detected, now find closest one
F32 t0 = (-B - sqrtf(discriminant)) / 2.f;
if (t0 > 0.f)
{
@ -1689,49 +1676,25 @@ LLVector3 intersect_ray_with_sphere( const LLVector3& ray_pt, const LLVector3& r
F32 t1 = (-B + sqrtf(discriminant)) / 2.f;
intersection_pt = ray_pt + ray_dir * t1;
}
return true;
}
return intersection_pt;
//LLVector3 ray_pt_to_center = sphere_center - ray_pt;
//F32 center_distance = ray_pt_to_center.normVec();
//F32 dot = ray_dir * ray_pt_to_center;
//if (dot == 0.f)
//{
// return LLVector3::zero;
//}
//// point which ray hits plane centered on sphere origin, facing ray origin
//LLVector3 intersection_sphere_plane = ray_pt + (ray_dir * center_distance / dot);
//// vector from sphere origin to the point, normalized to sphere radius
//LLVector3 sphere_center_to_intersection = (intersection_sphere_plane - sphere_center) / sphere_radius;
//F32 dist_squared = sphere_center_to_intersection.magVecSquared();
//LLVector3 result;
//if (dist_squared > 1.f)
//{
// result = sphere_center_to_intersection;
// result.normVec();
//}
//else
//{
// result = sphere_center_to_intersection - ray_dir * sqrtf(1.f - dist_squared);
//}
//return sphere_center + (result * sphere_radius);
return false;
}
void LLToolPie::startCameraSteering()
{
mMouseSteerX = mMouseDownX;
mMouseSteerY = mMouseDownY;
const LLVector3 camera_to_rotation_center = gAgent.getFrameAgent().getOrigin() - LLViewerCamera::instance().getOrigin();
const LLVector3 rotation_center_to_pick = gAgent.getPosAgentFromGlobal(mDragPick.mPosGlobal) - gAgent.getFrameAgent().getOrigin();
mClockwise = camera_to_rotation_center * rotation_center_to_pick < 0.f;
}
void LLToolPie::steerCameraWithMouse(S32 x, S32 y)
{
const F32 MIN_ROTATION_RADIUS = 1.f;
const F32 MIN_ROTATION_RADIUS_FRACTION = 0.2f;
const LLVector3 pick_pos = gAgent.getPosAgentFromGlobal(mDragPick.mPosGlobal);
const LLVector3 rotation_center = gAgent.getFrameAgent().getOrigin();
@ -1740,7 +1703,8 @@ void LLToolPie::steerCameraWithMouse(S32 x, S32 y)
LLVector3 pick_offset = pick_pos - rotation_center;
F32 up_distance = pick_offset * rotation_up_axis;
LLVector3 object_rotation_center = rotation_center + rotation_up_axis * up_distance;
F32 pick_distance_from_rotation_center = llclamp(dist_vec(pick_pos, object_rotation_center), MIN_ROTATION_RADIUS, F32_MAX);
F32 min_rotation_radius = MIN_ROTATION_RADIUS_FRACTION * dist_vec(rotation_center, LLViewerCamera::instance().getOrigin());;
F32 pick_distance_from_rotation_center = llclamp(dist_vec(pick_pos, object_rotation_center), min_rotation_radius, F32_MAX);
LLVector3 screen_rotation_up_axis = rotation_up_axis - projected_vec(rotation_up_axis, LLViewerCamera::instance().getAtAxis());
screen_rotation_up_axis.normalize();
@ -1760,25 +1724,36 @@ void LLToolPie::steerCameraWithMouse(S32 x, S32 y)
LLVector3 rotation_fwd_axis = LLViewerCamera::instance().getAtAxis() - projected_vec(LLViewerCamera::instance().getAtAxis(), rotation_up_axis);
rotation_fwd_axis.normalize();
F64 pick_dist = dist_vec(pick_pos, adjusted_camera_pos);
LLVector3 mouse_on_sphere = intersect_ray_with_sphere(adjusted_camera_pos + (mouse_ray * pick_dist * 1.1f),
-1.f * mouse_ray,
object_rotation_center,
pick_distance_from_rotation_center);
LLVector3 old_mouse_on_sphere = intersect_ray_with_sphere(adjusted_camera_pos + (old_mouse_ray * pick_dist * 1.1f),
-1.f * old_mouse_ray,
object_rotation_center,
pick_distance_from_rotation_center);
LLVector3 mouse_on_sphere;
bool mouse_hit_sphere = intersect_ray_with_sphere(adjusted_camera_pos + (mouse_ray * pick_dist * 1.1f),
-1.f * mouse_ray,
object_rotation_center,
pick_distance_from_rotation_center,
mouse_on_sphere);
LLVector3 rotation_furthest_pt = object_rotation_center + pick_distance_from_rotation_center * rotation_fwd_axis;
F32 mouse_lateral_distance = llclamp(((mouse_on_sphere - rotation_furthest_pt) * screen_rotation_left_axis) / pick_distance_from_rotation_center, -1.f, 1.f);
F32 old_mouse_lateral_distance = llclamp(((old_mouse_on_sphere - rotation_furthest_pt) * screen_rotation_left_axis) / pick_distance_from_rotation_center, -1.f, 1.f);
LLVector3 old_mouse_on_sphere;
intersect_ray_with_sphere(adjusted_camera_pos + (old_mouse_ray * pick_dist * 1.1f),
-1.f * old_mouse_ray,
object_rotation_center,
pick_distance_from_rotation_center,
old_mouse_on_sphere);
F32 yaw_angle = -1.f * asinf(mouse_lateral_distance);
F32 old_yaw_angle = -1.f * asinf(old_mouse_lateral_distance);
if (mouse_hit_sphere)
{
// apply delta
gAgent.yaw(yaw_angle - old_yaw_angle);
mMouseSteerX = x;
mMouseSteerY = y;
LLVector3 rotation_furthest_pt = object_rotation_center + pick_distance_from_rotation_center * rotation_fwd_axis;
F32 mouse_lateral_distance = llclamp(((mouse_on_sphere - rotation_furthest_pt) * screen_rotation_left_axis) / pick_distance_from_rotation_center, -1.f, 1.f);
F32 old_mouse_lateral_distance = llclamp(((old_mouse_on_sphere - rotation_furthest_pt) * screen_rotation_left_axis) / pick_distance_from_rotation_center, -1.f, 1.f);
F32 yaw_angle = -1.f * asinf(mouse_lateral_distance);
F32 old_yaw_angle = -1.f * asinf(old_mouse_lateral_distance);
F32 delta_angle = yaw_angle - old_yaw_angle;
if (mClockwise) delta_angle *= -1.f;
gAgent.yaw(delta_angle);
mMouseSteerX = x;
mMouseSteerY = y;
}
}

View File

@ -92,13 +92,13 @@ private:
void startCameraSteering();
private:
BOOL mMouseButtonDown;
BOOL mMouseOutsideSlop; // for this drag, has mouse moved outside slop region
bool mMouseButtonDown;
bool mMouseOutsideSlop; // for this drag, has mouse moved outside slop region
S32 mMouseDownX;
S32 mMouseDownY;
S32 mMouseSteerX;
S32 mMouseSteerY;
F32 mLastYaw;
bool mClockwise;
LLUUID mMediaMouseCaptureID;
LLPickInfo mPick;
LLPickInfo mHoverPick;