123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462 |
- /**
- * @file lltoolfocus.cpp
- * @brief A tool to set the build focus point.
- *
- * $LicenseInfo:firstyear=2001&license=viewergpl$
- *
- * Copyright (c) 2001-2009, Linden Research, Inc.
- *
- * Second Life Viewer Source Code
- * The source code in this file ("Source Code") is provided by Linden Lab
- * to you under the terms of the GNU General Public License, version 2.0
- * ("GPL"), unless you have obtained a separate licensing agreement
- * ("Other License"), formally executed by you and Linden Lab. Terms of
- * the GPL can be found in doc/GPL-license.txt in this distribution, or
- * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
- *
- * There are special exceptions to the terms and conditions of the GPL as
- * it is applied to this Source Code. View the full text of the exception
- * in the file doc/FLOSS-exception.txt in this software distribution, or
- * online at
- * http://secondlifegrid.net/programs/open_source/licensing/flossexception
- *
- * By copying, modifying or distributing this software, you acknowledge
- * that you have read and understood your obligations described above,
- * and agree to abide by those obligations.
- *
- * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
- * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
- * COMPLETENESS OR PERFORMANCE.
- * $/LicenseInfo$
- */
- #include "llviewerprecompiledheaders.h"
- #include "lltoolfocus.h"
- #include "llagent.h"
- #include "lldrawable.h"
- #include "llhoverview.h"
- #include "llhudmanager.h"
- #include "llfloatertools.h"
- #include "llmorphview.h"
- #include "llpipeline.h" // For LLPipeline::sFreezeTime
- //MK
- #include "mkrlinterface.h"
- //mk
- #include "llselectmgr.h"
- #include "llstatusbar.h"
- #include "lltoolmgr.h"
- #include "llviewercamera.h"
- #include "llviewercontrol.h"
- #include "llviewerobject.h"
- #include "llviewerwindow.h"
- #include "llvoavatarself.h"
- // Globals
- bool gCameraBtnZoom = true;
- bool gCameraBtnOrbit = false;
- bool gCameraBtnPan = false;
- constexpr S32 SLOP_RANGE = 4;
- LLToolFocus gToolFocus;
- LLToolFocus::LLToolFocus()
- : LLTool("Focus"),
- mAccumX(0),
- mAccumY(0),
- mMouseDownX(0),
- mMouseDownY(0),
- mOutsideSlopX(false),
- mOutsideSlopY(false),
- mValidClickPoint(false),
- mMouseSteering(false),
- mMouseUpX(0),
- mMouseUpY(0),
- mMouseUpMask(MASK_NONE)
- {
- }
- //virtual
- void LLToolFocus::handleSelect()
- {
- if (gFloaterToolsp)
- {
- gFloaterToolsp->setStatusText("camera");
- }
- }
- //virtual
- void LLToolFocus::handleDeselect()
- {
- }
- bool LLToolFocus::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 = mAccumY = 0;
- mOutsideSlopX = mOutsideSlopY = mValidClickPoint = false;
- // If mouse capture gets ripped away, claim we moused up at the point we
- // clicked down. JC
- mMouseUpX = x;
- mMouseUpY = y;
- mMouseUpMask = mask;
- gViewerWindowp->hideCursor();
- gViewerWindowp->pickAsync(x, y, mask, pickCallback);
- // Do not steal focus from UI
- return false;
- }
- //static
- void LLToolFocus::pickCallback(const LLPickInfo& pick_info)
- {
- LLToolFocus* self = &gToolFocus;
- if (!self->hasMouseCapture())
- {
- return;
- }
- self->mMouseDownX = pick_info.mMousePt.mX;
- self->mMouseDownY = pick_info.mMousePt.mY;
- gViewerWindowp->moveCursorToCenter();
- // Potentially recenter if click outside rectangle
- LLViewerObject* hit_obj = pick_info.getObject();
- // Check for hit the sky, or some other invalid point
- if (!hit_obj && pick_info.mPosGlobal.isExactlyZero())
- {
- self->mValidClickPoint = false;
- return;
- }
- // check for hud attachments
- if (hit_obj && hit_obj->isHUDAttachment())
- {
- LLObjectSelectionHandle selection = gSelectMgr.getSelection();
- if (!selection->getObjectCount() ||
- selection->getSelectType() != SELECT_TYPE_HUD)
- {
- self->mValidClickPoint = false;
- return;
- }
- }
- if (gAgent.getCameraMode() == CAMERA_MODE_CUSTOMIZE_AVATAR)
- {
- bool good_customize_avatar_hit = false;
- if (hit_obj)
- {
- if (hit_obj == gAgentAvatarp)
- {
- // 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)
- {
- self->mValidClickPoint = false;
- return;
- }
- if (gMorphViewp)
- {
- gMorphViewp->setCameraDrivenByKeys(false);
- }
- }
- // RN: check to see if this is mouse-driving as opposed to ALT-zoom or
- // Focus tool
- else if (pick_info.mKeyMask & MASK_ALT ||
- gToolMgr.getCurrentTool()->getName() == "Focus")
- {
- //MK
- if (gRLenabled &&
- (gRLInterface.contains("camunlock") ||
- gRLInterface.contains("setcam_unlock")))
- {
- if (!(pick_info.mKeyMask & MASK_ALT) &&
- gAgent.cameraThirdPerson() &&
- gViewerWindowp->getLeftMouseDown() &&
- !LLPipeline::sFreezeTime &&
- (hit_obj == gAgentAvatarp ||
- (hit_obj && hit_obj->isAttachment() &&
- LLVOAvatar::findAvatarFromAttachment(hit_obj)->isSelf())))
- {
- // Do nothing, we are steering with the mouse... but the
- // condition is so complex it is better to check for its
- // negative.
- }
- else
- {
- self->mValidClickPoint = false;
- return;
- }
- }
- //mk
- LLViewerObject* hit_obj = pick_info.getObject();
- if (hit_obj)
- {
- // ...clicked on a world object, so focus at its position
- if (!hit_obj->isHUDAttachment())
- {
- gAgent.setFocusOnAvatar(false);
- gAgent.setFocusGlobal(pick_info);
- }
- }
- else if (!pick_info.mPosGlobal.isExactlyZero())
- {
- // Hit the ground
- gAgent.setFocusOnAvatar(false);
- gAgent.setFocusGlobal(pick_info);
- }
- if (!(pick_info.mKeyMask & MASK_ALT) && gAgent.cameraThirdPerson() &&
- gViewerWindowp->getLeftMouseDown() && !LLPipeline::sFreezeTime &&
- (hit_obj == gAgentAvatarp ||
- (hit_obj && hit_obj->isAttachment() &&
- LLVOAvatar::findAvatarFromAttachment(hit_obj)->isSelf())))
- {
- self->mMouseSteering = true;
- }
- }
- self->mValidClickPoint = true;
- if (CAMERA_MODE_CUSTOMIZE_AVATAR == gAgent.getCameraMode())
- {
- gAgent.setFocusOnAvatar(false, false);
- LLVector3d cam_pos = gAgent.getCameraPositionGlobal();
- cam_pos -= LLVector3d(gViewerCamera.getLeftAxis() *
- gAgent.calcCustomizeAvatarUIOffset(cam_pos));
- gAgent.setCameraPosAndFocusGlobal(cam_pos, pick_info.mPosGlobal,
- pick_info.mObjectID);
- }
- }
- // "Let go" of the mouse, for example on mouse up or when we loose mouse
- // capture. This ensures that cursor becomes visible if a modal dialog pops up
- // during Alt-Zoom. JC
- void LLToolFocus::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);
- gViewerWindowp->showCursor();
- gToolMgr.clearTransientTool();
- mMouseSteering = false;
- mValidClickPoint = false;
- mOutsideSlopX = false;
- mOutsideSlopY = false;
- }
- bool LLToolFocus::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;
- focus_pos = gAgent.getPosAgentFromGlobal(gAgent.getFocusGlobal());
- bool success = gViewerCamera.projectPosAgentToScreen(focus_pos,
- mouse_pos);
- if (success)
- {
- LLUI::setCursorPositionScreen(mouse_pos.mX, mouse_pos.mY);
- }
- }
- else if (mMouseSteering)
- {
- LLUI::setCursorPositionScreen(mMouseDownX, mMouseDownY);
- }
- else
- {
- gViewerWindowp->moveCursorToCenter();
- }
- }
- else
- {
- // not a valid zoomable object
- LLUI::setCursorPositionScreen(mMouseDownX, mMouseDownY);
- }
- // calls releaseMouse() internally
- setMouseCapture(false);
- }
- else
- {
- releaseMouse();
- }
- return true;
- }
- bool LLToolFocus::handleHover(S32 x, S32 y, MASK mask)
- {
- S32 dx = gViewerWindowp->getCurrentMouseDX();
- S32 dy = gViewerWindowp->getCurrentMouseDY();
- if (hasMouseCapture() && mValidClickPoint)
- {
- mAccumX += abs(dx);
- mAccumY += abs(dy);
- if (mAccumX >= SLOP_RANGE)
- {
- mOutsideSlopX = true;
- }
- if (mAccumY >= SLOP_RANGE)
- {
- mOutsideSlopY = true;
- }
- }
- if (mOutsideSlopX || mOutsideSlopY)
- {
- if (!mValidClickPoint)
- {
- LL_DEBUGS("UserInput") << "hover handled by LLToolFocus [invalid point]"
- << LL_ENDL;
- gViewerWindowp->setCursor(UI_CURSOR_NO);
- gViewerWindowp->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 /
- gViewerWindowp->getWindowWidth();
- if (dx != 0)
- {
- gAgent.cameraOrbitAround(-dx * radians_per_pixel);
- }
- if (dy != 0)
- {
- gAgent.cameraOrbitOver(-dy * radians_per_pixel);
- }
- gViewerWindowp->moveCursorToCenter();
- }
- LL_DEBUGS("UserInput") << "hover handled by LLToolFocus [active]"
- << LL_ENDL;
- }
- 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.normalize();
- // Fudge factor for pan
- F32 meters_per_pixel = 3.f * dist / gViewerWindowp->getWindowWidth();
- if (dx != 0)
- {
- gAgent.cameraPanLeft(dx * meters_per_pixel);
- }
- if (dy != 0)
- {
- gAgent.cameraPanUp(-dy * meters_per_pixel);
- }
- gViewerWindowp->moveCursorToCenter();
- }
- LL_DEBUGS("UserInput") << "hover handled by LLToolPan" << LL_ENDL;
- }
- else if (gCameraBtnZoom)
- {
- // Zoom tool
- if (hasMouseCapture())
- {
- const F32 radians_per_pixel = 360.f * DEG_TO_RAD /
- gViewerWindowp->getWindowWidth();
- if (dx != 0)
- {
- gAgent.cameraOrbitAround(-dx * radians_per_pixel);
- }
- constexpr F32 IN_FACTOR = 0.99f;
- if (dy != 0 && mOutsideSlopY)
- {
- if (mMouseSteering)
- {
- gAgent.cameraOrbitOver(-dy * radians_per_pixel);
- }
- else
- {
- gAgent.cameraZoomIn(powf(IN_FACTOR, dy));
- }
- }
- gViewerWindowp->moveCursorToCenter();
- }
- LL_DEBUGS("UserInput") << "hover handled by LLToolZoom" << LL_ENDL;
- }
- }
- if (gCameraBtnOrbit || mask == MASK_ORBIT ||
- mask == (MASK_ALT | MASK_ORBIT))
- {
- gViewerWindowp->setCursor(UI_CURSOR_TOOLCAMERA);
- }
- else if (gCameraBtnPan || mask == MASK_PAN ||
- mask == (MASK_PAN | MASK_ALT))
- {
- gViewerWindowp->setCursor(UI_CURSOR_TOOLPAN);
- }
- else
- {
- gViewerWindowp->setCursor(UI_CURSOR_TOOLZOOMIN);
- }
- return true;
- }
- void LLToolFocus::onMouseCaptureLost()
- {
- releaseMouse();
- }
|