From 1c5d2516e0d926c8bd0bc2faad0f8ccaa2725339 Mon Sep 17 00:00:00 2001 From: Richard Linden Date: Fri, 11 Mar 2011 00:21:22 -0800 Subject: 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 --- indra/newview/lltoolpie.cpp | 125 ++++++++++++++++++-------------------------- 1 file changed, 50 insertions(+), 75 deletions(-) (limited to 'indra/newview/lltoolpie.cpp') diff --git a/indra/newview/lltoolpie.cpp b/indra/newview/lltoolpie.cpp index e539174a4b..c52111ab54 100644 --- a/indra/newview/lltoolpie.cpp +++ b/indra/newview/lltoolpie.cpp @@ -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 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); - - // apply delta - gAgent.yaw(yaw_angle - old_yaw_angle); - mMouseSteerX = x; - mMouseSteerY = y; + + 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 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); + + if (mouse_hit_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); + + 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; + } } \ No newline at end of file -- cgit v1.2.3