diff options
author | James Cook <james@lindenlab.com> | 2007-01-02 08:33:20 +0000 |
---|---|---|
committer | James Cook <james@lindenlab.com> | 2007-01-02 08:33:20 +0000 |
commit | 420b91db29485df39fd6e724e782c449158811cb (patch) | |
tree | b471a94563af914d3ed3edd3e856d21cb1b69945 /indra/newview/lltoolfocus.cpp |
Print done when done.
Diffstat (limited to 'indra/newview/lltoolfocus.cpp')
-rw-r--r-- | indra/newview/lltoolfocus.cpp | 442 |
1 files changed, 442 insertions, 0 deletions
diff --git a/indra/newview/lltoolfocus.cpp b/indra/newview/lltoolfocus.cpp new file mode 100644 index 0000000000..627a49a6cc --- /dev/null +++ b/indra/newview/lltoolfocus.cpp @@ -0,0 +1,442 @@ +/** + * @file lltoolfocus.cpp + * @brief A tool to set the build focus point. + * + * Copyright (c) 2001-$CurrentYear$, Linden Research, Inc. + * $License$ + */ + +#include "llviewerprecompiledheaders.h" + +// File includes +#include "lltoolfocus.h" + +// Library includes +#include "v3math.h" +#include "llfontgl.h" +#include "llui.h" + +// Viewer includes +#include "llagent.h" +#include "llbutton.h" +#include "llviewercontrol.h" +#include "lldrawable.h" +#include "llhoverview.h" +#include "llhudmanager.h" +#include "llfloatertools.h" +#include "llselectmgr.h" +#include "llstatusbar.h" +#include "lltoolmgr.h" +#include "lltoolselect.h" +#include "llviewborder.h" +#include "llviewercamera.h" +#include "llviewerobject.h" +#include "llviewerwindow.h" +#include "viewer.h" +#include "llvoavatar.h" +#include "llmorphview.h" + +// Globals +LLToolCamera *gToolCamera = NULL; +BOOL gCameraBtnOrbit = FALSE; +BOOL gCameraBtnPan = FALSE; +const S32 SLOP_RANGE = 4; +const F32 FOCUS_OFFSET_FACTOR = 1.f; + +extern void handle_first_tool(void*); + + +// +// Camera - shared functionality +// + +LLToolCamera::LLToolCamera() +: LLTool("Camera"), + mAccumX(0), + mAccumY(0), + mMouseDownX(0), + mMouseDownY(0), + mOutsideSlopX(FALSE), + mOutsideSlopY(FALSE), + mValidClickPoint(FALSE), + mMouseSteering(FALSE), + mMouseUpX(0), + mMouseUpY(0), + mMouseUpMask(MASK_NONE) +{ } + + +LLToolCamera::~LLToolCamera() +{ } + +// virtual +void LLToolCamera::handleSelect() +{ + gFloaterTools->setStatusText("Click and drag to change view"); +} + +// virtual +void LLToolCamera::handleDeselect() +{ + gFloaterTools->setStatusText(""); +// gAgent.setLookingAtAvatar(FALSE); +} + +BOOL LLToolCamera::handleMouseDown(S32 x, S32 y, MASK mask) +{ + // Ensure a mouseup + setMouseCapture(TRUE); + + // call the base class to propogate info to sim + LLTool::handleMouseDown(x, y, mask); + + mAccumX = 0; + mAccumY = 0; + + mOutsideSlopX = FALSE; + mOutsideSlopY = FALSE; + + mValidClickPoint = FALSE; + + // If mouse capture gets ripped away, claim we moused up + // at the point we moused down. JC + mMouseUpX = x; + mMouseUpY = y; + mMouseUpMask = mask; + + gViewerWindow->hideCursor(); + + gViewerWindow->hitObjectOrLandGlobalAsync(x, y, mask, pickCallback); + // don't steal focus from UI + return FALSE; +} + +void LLToolCamera::pickCallback(S32 x, S32 y, MASK mask) +{ + if (!gToolCamera->hasMouseCapture()) + { + return; + } + + gToolCamera->mMouseDownX = x; + gToolCamera->mMouseDownY = y; + + gViewerWindow->moveCursorToCenter(); + + // Potentially recenter if click outside rectangle + LLViewerObject* hit_obj = gViewerWindow->lastObjectHit(); + + // Check for hit the sky, or some other invalid point + if (!hit_obj && gLastHitPosGlobal.isExactlyZero()) + { + gToolCamera->mValidClickPoint = FALSE; + return; + } + + // check for hud attachments + if (hit_obj && hit_obj->isHUDAttachment()) + { + if (!gSelectMgr->getObjectCount() || gSelectMgr->getSelectType() != SELECT_TYPE_HUD) + { + gToolCamera->mValidClickPoint = FALSE; + return; + } + } + + if( CAMERA_MODE_CUSTOMIZE_AVATAR == gAgent.getCameraMode() ) + { + BOOL good_customize_avatar_hit = FALSE; + if( hit_obj ) + { + LLVOAvatar* avatar = gAgent.getAvatarObject(); + if( hit_obj == avatar) + { + // It's you + good_customize_avatar_hit = TRUE; + } + else + if( hit_obj->isAttachment() && hit_obj->permYouOwner() ) + { + // It's an attachment that you're wearing + good_customize_avatar_hit = TRUE; + } + } + + if( !good_customize_avatar_hit ) + { + gToolCamera->mValidClickPoint = FALSE; + return; + } + + if( gMorphView ) + { + gMorphView->setCameraDrivenByKeys( FALSE ); + } + } + //RN: check to see if this is mouse-driving as opposed to ALT-zoom or Focus tool + else if (mask & MASK_ALT || + (gToolMgr->getCurrentTool(mask)->getName() == "Camera")) + { + LLViewerObject* hit_obj = gViewerWindow->lastObjectHit(); + if (hit_obj) + { + // ...clicked on a world object, so focus at its position + // Use "gLastHitPosGlobal" because it's correct for avatar heads, + // not pelvis. + if (!hit_obj->isHUDAttachment()) + { + gAgent.setFocusOnAvatar(FALSE, ANIMATE); + gAgent.setFocusGlobal( gLastHitObjectOffset + gLastHitPosGlobal, gLastHitObjectID); + } + } + else if (!gLastHitPosGlobal.isExactlyZero()) + { + // Hit the ground + gAgent.setFocusOnAvatar(FALSE, ANIMATE); + gAgent.setFocusGlobal( gLastHitPosGlobal, gLastHitObjectID); + } + + if (!(mask & MASK_ALT) && + gAgent.cameraThirdPerson() && + gViewerWindow->getLeftMouseDown() && + !gSavedSettings.getBOOL("FreezeTime") && + (hit_obj == gAgent.getAvatarObject() || + (hit_obj && hit_obj->isAttachment() && LLVOAvatar::findAvatarFromAttachment(hit_obj)->mIsSelf))) + { + gToolCamera->mMouseSteering = TRUE; + } + + } + + gToolCamera->mValidClickPoint = TRUE; + + if( CAMERA_MODE_CUSTOMIZE_AVATAR == gAgent.getCameraMode() ) + { + gAgent.setFocusOnAvatar(FALSE, FALSE); + + LLVector3d cam_pos = gAgent.getCameraPositionGlobal(); + cam_pos -= LLVector3d(gCamera->getLeftAxis() * gAgent.calcCustomizeAvatarUIOffset( cam_pos )); + + gAgent.setCameraPosAndFocusGlobal( cam_pos, gLastHitObjectOffset + gLastHitPosGlobal, gLastHitObjectID); + } +} + + +// "Let go" of the mouse, for example on mouse up or when +// we lose mouse capture. This ensures that cursor becomes visible +// if a modal dialog pops up during Alt-Zoom. JC +void LLToolCamera::releaseMouse() +{ + // Need to tell the sim that the mouse button is up, since this + // tool is no longer working and cursor is visible (despite actual + // mouse button status). + LLTool::handleMouseUp(mMouseUpX, mMouseUpY, mMouseUpMask); + + gViewerWindow->showCursor(); + + gToolMgr->clearTransientTool(); + + mMouseSteering = FALSE; + mValidClickPoint = FALSE; + mOutsideSlopX = FALSE; + mOutsideSlopY = FALSE; +} + + +BOOL LLToolCamera::handleMouseUp(S32 x, S32 y, MASK mask) +{ + // Claim that we're mousing up somewhere + mMouseUpX = x; + mMouseUpY = y; + mMouseUpMask = mask; + + if (hasMouseCapture()) + { + if (mValidClickPoint) + { + if( CAMERA_MODE_CUSTOMIZE_AVATAR == gAgent.getCameraMode() ) + { + LLCoordGL mouse_pos; + LLVector3 focus_pos = gAgent.getPosAgentFromGlobal(gAgent.getFocusGlobal()); + gCamera->projectPosAgentToScreen(focus_pos, mouse_pos); + + LLUI::setCursorPositionScreen(mouse_pos.mX, mouse_pos.mY); + } + else if (mMouseSteering) + { + LLUI::setCursorPositionScreen(mMouseDownX, mMouseDownY); + } + else + { + gViewerWindow->moveCursorToCenter(); + } + } + else + { + // not a valid zoomable object + LLUI::setCursorPositionScreen(mMouseDownX, mMouseDownY); + } + + // calls releaseMouse() internally + setMouseCapture(FALSE); + } + else + { + releaseMouse(); + } + + return TRUE; +} + + +BOOL LLToolCamera::handleHover(S32 x, S32 y, MASK mask) +{ + S32 dx = gViewerWindow->getCurrentMouseDX(); + S32 dy = gViewerWindow->getCurrentMouseDY(); + + BOOL moved_outside_slop = FALSE; + + if (hasMouseCapture() && mValidClickPoint) + { + mAccumX += llabs(dx); + mAccumY += llabs(dy); + + if (mAccumX >= SLOP_RANGE) + { + if (!mOutsideSlopX) + { + moved_outside_slop = TRUE; + } + mOutsideSlopX = TRUE; + } + + if (mAccumY >= SLOP_RANGE) + { + if (!mOutsideSlopY) + { + moved_outside_slop = TRUE; + } + mOutsideSlopY = TRUE; + } + } + + if (mOutsideSlopX || mOutsideSlopY) + { + if (!mValidClickPoint) + { + lldebugst(LLERR_USER_INPUT) << "hover handled by LLToolFocus [invalid point]" << llendl; + gViewerWindow->setCursor(UI_CURSOR_NO); + gViewerWindow->showCursor(); + return TRUE; + } + + if (gCameraBtnOrbit || + mask == MASK_ORBIT || + mask == (MASK_ALT | MASK_ORBIT)) + { + // Orbit tool + if (hasMouseCapture()) + { + const F32 RADIANS_PER_PIXEL = 360.f * DEG_TO_RAD / gViewerWindow->getWindowWidth(); + + if (dx != 0) + { + gAgent.cameraOrbitAround( -dx * RADIANS_PER_PIXEL ); + } + + if (dy != 0) + { + gAgent.cameraOrbitOver( -dy * RADIANS_PER_PIXEL ); + } + + gViewerWindow->moveCursorToCenter(); + } + lldebugst(LLERR_USER_INPUT) << "hover handled by LLToolFocus [active]" << llendl; + } + else if ( gCameraBtnPan || + mask == MASK_PAN || + mask == (MASK_PAN | MASK_ALT) ) + { + // Pan tool + if (hasMouseCapture()) + { + LLVector3d camera_to_focus = gAgent.getCameraPositionGlobal(); + camera_to_focus -= gAgent.getFocusGlobal(); + F32 dist = (F32) camera_to_focus.normVec(); + + // Fudge factor for pan + F32 meters_per_pixel = 3.f * dist / gViewerWindow->getWindowWidth(); + + if (dx != 0) + { + gAgent.cameraPanLeft( dx * meters_per_pixel ); + } + + if (dy != 0) + { + gAgent.cameraPanUp( -dy * meters_per_pixel ); + } + + gViewerWindow->moveCursorToCenter(); + } + lldebugst(LLERR_USER_INPUT) << "hover handled by LLToolPan" << llendl; + } + else + { + // Zoom tool + if (hasMouseCapture()) + { + + const F32 RADIANS_PER_PIXEL = 360.f * DEG_TO_RAD / gViewerWindow->getWindowWidth(); + + if (dx != 0) + { + gAgent.cameraOrbitAround( -dx * RADIANS_PER_PIXEL ); + } + + const F32 IN_FACTOR = 0.99f; + + if (dy != 0 && mOutsideSlopY ) + { + if (mMouseSteering) + { + gAgent.cameraOrbitOver( -dy * RADIANS_PER_PIXEL ); + } + else + { + gAgent.cameraZoomIn( pow( IN_FACTOR, dy ) ); + } + } + + gViewerWindow->moveCursorToCenter(); + } + + lldebugst(LLERR_USER_INPUT) << "hover handled by LLToolZoom" << llendl; + } + } + + if (gCameraBtnOrbit || + mask == MASK_ORBIT || + mask == (MASK_ALT | MASK_ORBIT)) + { + gViewerWindow->setCursor(UI_CURSOR_TOOLCAMERA); + } + else if ( gCameraBtnPan || + mask == MASK_PAN || + mask == (MASK_PAN | MASK_ALT) ) + { + gViewerWindow->setCursor(UI_CURSOR_TOOLPAN); + } + else + { + gViewerWindow->setCursor(UI_CURSOR_TOOLZOOMIN); + } + + return TRUE; +} + + +void LLToolCamera::onMouseCaptureLost() +{ + releaseMouse(); +} |