From f4d4fb2ad0927ebb8545bac1abd1b74918a006f5 Mon Sep 17 00:00:00 2001 From: maxim_productengine Date: Fri, 22 Nov 2019 14:34:20 +0200 Subject: [PATCH] SL-12288 Enhancement for Rotate and Track camera controls --- indra/newview/llagentcamera.cpp | 58 ++++++++++- indra/newview/llagentcamera.h | 13 ++- indra/newview/lljoystickbutton.cpp | 95 ++++++++++++++---- indra/newview/lljoystickbutton.h | 9 +- .../textures/bottomtray/Cam_Rotate_Center.png | Bin 0 -> 10689 bytes .../bottomtray/Cam_Tracking_Center.png | Bin 0 -> 1714 bytes .../skins/default/textures/textures.xml | 2 + 7 files changed, 155 insertions(+), 22 deletions(-) create mode 100644 indra/newview/skins/default/textures/bottomtray/Cam_Rotate_Center.png create mode 100644 indra/newview/skins/default/textures/bottomtray/Cam_Tracking_Center.png diff --git a/indra/newview/llagentcamera.cpp b/indra/newview/llagentcamera.cpp index e5fba7f28f..67b117657f 100644 --- a/indra/newview/llagentcamera.cpp +++ b/indra/newview/llagentcamera.cpp @@ -184,6 +184,9 @@ LLAgentCamera::LLAgentCamera() : clearGeneralKeys(); clearOrbitKeys(); clearPanKeys(); + + resetPanDiff(); + resetOrbitDiff(); } // Requires gSavedSettings to be initialized. @@ -343,7 +346,8 @@ void LLAgentCamera::resetView(BOOL reset_camera, BOOL change_camera) mCameraFOVZoomFactor = 0.f; } - + resetPanDiff(); + resetOrbitDiff(); mHUDTargetZoom = 1.f; } @@ -822,6 +826,7 @@ void LLAgentCamera::cameraOrbitAround(const F32 radians) } else { + mOrbitAroundRadians += radians; mCameraFocusOffsetTarget.rotVec(radians, 0.f, 0.f, 1.f); cameraZoomIn(1.f); @@ -853,12 +858,34 @@ void LLAgentCamera::cameraOrbitOver(const F32 angle) LLVector3d left_axis; left_axis.setVec(LLViewerCamera::getInstance()->getLeftAxis()); F32 new_angle = llclamp(angle_from_up - angle, 1.f * DEG_TO_RAD, 179.f * DEG_TO_RAD); + mOrbitOverAngle += angle_from_up - new_angle; mCameraFocusOffsetTarget.rotVec(angle_from_up - new_angle, left_axis); cameraZoomIn(1.f); } } +void LLAgentCamera::resetCameraOrbit() +{ + LLVector3 camera_offset_unit(mCameraFocusOffsetTarget); + camera_offset_unit.normalize(); + + LLVector3d left_axis; + left_axis.setVec(LLViewerCamera::getInstance()->getLeftAxis()); + mCameraFocusOffsetTarget.rotVec(-mOrbitOverAngle, left_axis); + + mCameraFocusOffsetTarget.rotVec(-mOrbitAroundRadians, 0.f, 0.f, 1.f); + + cameraZoomIn(1.f); + resetOrbitDiff(); +} + +void LLAgentCamera::resetOrbitDiff() +{ + mOrbitAroundRadians = 0; + mOrbitOverAngle = 0; +} + //----------------------------------------------------------------------------- // cameraZoomIn() //----------------------------------------------------------------------------- @@ -997,6 +1024,8 @@ void LLAgentCamera::cameraPanIn(F32 meters) LLVector3d at_axis; at_axis.setVec(LLViewerCamera::getInstance()->getAtAxis()); + mPanFocusDiff += meters * at_axis; + mFocusTargetGlobal += meters * at_axis; mFocusGlobal = mFocusTargetGlobal; // don't enforce zoom constraints as this is the only way for users to get past them easily @@ -1013,6 +1042,8 @@ void LLAgentCamera::cameraPanLeft(F32 meters) LLVector3d left_axis; left_axis.setVec(LLViewerCamera::getInstance()->getLeftAxis()); + mPanFocusDiff += meters * left_axis; + mFocusTargetGlobal += meters * left_axis; mFocusGlobal = mFocusTargetGlobal; @@ -1033,6 +1064,8 @@ void LLAgentCamera::cameraPanUp(F32 meters) LLVector3d up_axis; up_axis.setVec(LLViewerCamera::getInstance()->getUpAxis()); + mPanFocusDiff += meters * up_axis; + mFocusTargetGlobal += meters * up_axis; mFocusGlobal = mFocusTargetGlobal; @@ -1045,6 +1078,26 @@ void LLAgentCamera::cameraPanUp(F32 meters) mCameraSmoothingLastPositionGlobal = calcCameraPositionTargetGlobal(); } +void LLAgentCamera::resetCameraPan() +{ + mFocusTargetGlobal -= mPanFocusDiff; + + mFocusGlobal = mFocusTargetGlobal; + mCameraSmoothingStop = true; + + cameraZoomIn(1.f); + updateFocusOffset(); + + mCameraSmoothingLastPositionGlobal = calcCameraPositionTargetGlobal(); + + resetPanDiff(); +} + +void LLAgentCamera::resetPanDiff() +{ + mPanFocusDiff.clear(); +} + //----------------------------------------------------------------------------- // updateLookAt() //----------------------------------------------------------------------------- @@ -2330,6 +2383,9 @@ void LLAgentCamera::switchCameraPreset(ECameraPreset preset) mCameraPreset = preset; + resetPanDiff(); + resetOrbitDiff(); + gSavedSettings.setU32("CameraPreset", mCameraPreset); } diff --git a/indra/newview/llagentcamera.h b/indra/newview/llagentcamera.h index 8a922bf678..0608507d1a 100644 --- a/indra/newview/llagentcamera.h +++ b/indra/newview/llagentcamera.h @@ -262,7 +262,8 @@ public: void cameraOrbitAround(const F32 radians); // Rotate camera CCW radians about build focus point void cameraOrbitOver(const F32 radians); // Rotate camera forward radians over build focus point void cameraOrbitIn(const F32 meters); // Move camera in toward build focus point - + void resetCameraOrbit(); + void resetOrbitDiff(); //-------------------------------------------------------------------- // Zoom //-------------------------------------------------------------------- @@ -279,8 +280,9 @@ public: public: void cameraPanIn(const F32 meters); void cameraPanLeft(const F32 meters); - void cameraPanUp(const F32 meters); - + void cameraPanUp(const F32 meters); + void resetCameraPan(); + void resetPanDiff(); //-------------------------------------------------------------------- // View //-------------------------------------------------------------------- @@ -367,6 +369,9 @@ private: F32 mOrbitInKey; F32 mOrbitOutKey; + F32 mOrbitAroundRadians; + F32 mOrbitOverAngle; + //-------------------------------------------------------------------- // Pan //-------------------------------------------------------------------- @@ -394,6 +399,8 @@ private: F32 mPanInKey; F32 mPanOutKey; + LLVector3d mPanFocusDiff; + /** Keys ** ** *******************************************************************************/ diff --git a/indra/newview/lljoystickbutton.cpp b/indra/newview/lljoystickbutton.cpp index 59e14e6cc0..eb4e4f4100 100644 --- a/indra/newview/lljoystickbutton.cpp +++ b/indra/newview/lljoystickbutton.cpp @@ -37,6 +37,7 @@ #include "llui.h" #include "llagent.h" #include "llagentcamera.h" +#include "llviewercamera.h" #include "llviewertexture.h" #include "llviewertexturelist.h" #include "llviewerwindow.h" @@ -54,6 +55,8 @@ static LLDefaultChildRegistry::Register r5("joystick_trac const F32 NUDGE_TIME = 0.25f; // in seconds const F32 ORBIT_NUDGE_RATE = 0.05f; // fraction of normal speed +const S32 CENTER_DOT_RADIUS = 7; + // // Public Methods // @@ -138,9 +141,25 @@ bool LLJoystick::pointInCircle(S32 x, S32 y) const //center is x and y coordinates of center of joystick circle, and also its radius int center = this->getLocalRect().getHeight()/2; bool in_circle = (x - center) * (x - center) + (y - center) * (y - center) <= center * center; + return in_circle; } +bool LLJoystick::pointInCenterDot(S32 x, S32 y, S32 radius) const +{ + if (this->getLocalRect().getHeight() != this->getLocalRect().getWidth()) + { + LL_WARNS() << "Joystick shape is not square" << LL_ENDL; + return true; + } + + S32 center = this->getLocalRect().getHeight() / 2; + + bool in_center_circle = (x - center) * (x - center) + (y - center) * (y - center) <= radius * radius; + + return in_center_circle; +} + BOOL LLJoystick::handleMouseDown(S32 x, S32 y, MASK mask) { //LL_INFOS() << "joystick mouse down " << x << ", " << y << LL_ENDL; @@ -403,8 +422,11 @@ LLJoystickCameraRotate::LLJoystickCameraRotate(const LLJoystickCameraRotate::Par mInLeft( FALSE ), mInTop( FALSE ), mInRight( FALSE ), - mInBottom( FALSE ) -{ } + mInBottom( FALSE ), + mInCenter( FALSE ) +{ + mCenterImageName = "Cam_Rotate_Center"; +} void LLJoystickCameraRotate::updateSlop() @@ -434,7 +456,16 @@ BOOL LLJoystickCameraRotate::handleMouseDown(S32 x, S32 y, MASK mask) S32 dx = x - horiz_center; S32 dy = y - vert_center; - if (dy > dx && dy > -dx) + if (pointInCenterDot(x, y, CENTER_DOT_RADIUS)) + { + mInitialOffset.mX = 0; + mInitialOffset.mY = 0; + mInitialQuadrant = JQ_ORIGIN; + mInCenter = TRUE; + + resetJoystickCamera(); + } + else if (dy > dx && dy > -dx) { // top mInitialOffset.mX = 0; @@ -469,9 +500,20 @@ BOOL LLJoystickCameraRotate::handleMouseDown(S32 x, S32 y, MASK mask) BOOL LLJoystickCameraRotate::handleMouseUp(S32 x, S32 y, MASK mask) { gAgent.setMovementLocked(FALSE); + mInCenter = FALSE; return LLJoystick::handleMouseUp(x, y, mask); } +BOOL LLJoystickCameraRotate::handleHover(S32 x, S32 y, MASK mask) +{ + if (!pointInCenterDot(x, y, CENTER_DOT_RADIUS)) + { + mInCenter = FALSE; + } + + return LLJoystick::handleHover(x, y, mask); +} + void LLJoystickCameraRotate::onHeldDown() { updateSlop(); @@ -504,6 +546,11 @@ void LLJoystickCameraRotate::onHeldDown() } } +void LLJoystickCameraRotate::resetJoystickCamera() +{ + gAgentCamera.resetCameraOrbit(); +} + F32 LLJoystickCameraRotate::getOrbitRate() { F32 time = getElapsedHeldDownTime(); @@ -536,24 +583,31 @@ void LLJoystickCameraRotate::draw() getImageUnselected()->draw( 0, 0 ); LLPointer image = getImageSelected(); - if( mInTop ) + if (mInCenter) { - drawRotatedImage( getImageSelected(), 0 ); + drawRotatedImage(LLUI::getUIImage(mCenterImageName), 0); } - - if( mInRight ) + else { - drawRotatedImage( getImageSelected(), 1 ); - } + if (mInTop) + { + drawRotatedImage(getImageSelected(), 0); + } - if( mInBottom ) - { - drawRotatedImage( getImageSelected(), 2 ); - } + if (mInRight) + { + drawRotatedImage(getImageSelected(), 1); + } - if( mInLeft ) - { - drawRotatedImage( getImageSelected(), 3 ); + if (mInBottom) + { + drawRotatedImage(getImageSelected(), 2); + } + + if (mInLeft) + { + drawRotatedImage(getImageSelected(), 3); + } } } @@ -613,7 +667,9 @@ LLJoystickCameraTrack::Params::Params() LLJoystickCameraTrack::LLJoystickCameraTrack(const LLJoystickCameraTrack::Params& p) : LLJoystickCameraRotate(p) -{} +{ + mCenterImageName = "Cam_Tracking_Center"; +} void LLJoystickCameraTrack::onHeldDown() @@ -646,3 +702,8 @@ void LLJoystickCameraTrack::onHeldDown() gAgentCamera.setPanDownKey(getOrbitRate()); } } + +void LLJoystickCameraTrack::resetJoystickCamera() +{ + gAgentCamera.resetCameraPan(); +} diff --git a/indra/newview/lljoystickbutton.h b/indra/newview/lljoystickbutton.h index 4e6c774cad..3e29215f61 100644 --- a/indra/newview/lljoystickbutton.h +++ b/indra/newview/lljoystickbutton.h @@ -79,7 +79,8 @@ public: * Image containing circle is square and this square has adherent points with joystick * circle. Make sure to change method according to shape other than square. */ - bool pointInCircle(S32 x, S32 y) const; + bool pointInCircle(S32 x, S32 y) const; + bool pointInCenterDot(S32 x, S32 y, S32 radius) const; static std::string nameFromQuadrant(const EJoystickQuadrant quadrant); static EJoystickQuadrant quadrantFromName(const std::string& name); @@ -147,7 +148,9 @@ public: virtual BOOL handleMouseDown(S32 x, S32 y, MASK mask); virtual BOOL handleMouseUp(S32 x, S32 y, MASK mask); + virtual BOOL handleHover(S32 x, S32 y, MASK mask); virtual void onHeldDown(); + virtual void resetJoystickCamera(); virtual void draw(); protected: @@ -160,6 +163,9 @@ protected: BOOL mInTop; BOOL mInRight; BOOL mInBottom; + BOOL mInCenter; + + std::string mCenterImageName; }; @@ -176,6 +182,7 @@ public: LLJoystickCameraTrack(const LLJoystickCameraTrack::Params&); virtual void onHeldDown(); + virtual void resetJoystickCamera(); }; #endif // LL_LLJOYSTICKBUTTON_H diff --git a/indra/newview/skins/default/textures/bottomtray/Cam_Rotate_Center.png b/indra/newview/skins/default/textures/bottomtray/Cam_Rotate_Center.png new file mode 100644 index 0000000000000000000000000000000000000000..ffc3c85ea2a96cb82eeb487625eac03bb1c90aa2 GIT binary patch literal 10689 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 literal 0 HcmV?d00001 diff --git a/indra/newview/skins/default/textures/bottomtray/Cam_Tracking_Center.png b/indra/newview/skins/default/textures/bottomtray/Cam_Tracking_Center.png new file mode 100644 index 0000000000000000000000000000000000000000..2812d614e6abc12f8f3ec1bcbad8f2f445e6f3e2 GIT binary patch literal 1714 zcmV;j22J^iP) zaB^>EX>4U6ba`-PAZ2)IW&i+q+U=KHjwLA$hTmDmECFMDVL99^%?^6`^Fv1EwYsFL zo|l&Lpc6p=VZfiU9clmd-$?(#uW-w$in%t`j9+cFm5z$%m*2~sa=q94tNZDrkL~HT zqo9d#=a)x)+Nq;m-d?c!w2zPN$>t-+A3;yY4}pAUE~q@?{1L?ErJbJV)SmZxeYc(G zAG6$U882O*pQ}L`OCXO+Dw~Nju6Gv33b=8{m2fRg<+K#k1*M<X8zE@@oEHLbr;Jc_RH>iRcK1nv#B3jxit)g zIxFAT6vglt)a{mr;@IK@u?3m~WhQD=pzWYai#i4Ed!ID1#9DSS+)J6z`)PBw(#pJ0 z>M0b(fM+FkFqxpnXfCg7p*wH8^G$Nhya*!;LD-@ArKF!V{z-Wi6md+KDEq6fu! z8p}B3&K08ogyPYuT>ajX-q}rl2bMulu9_Vi?0LM17(#Eh#g{W#mfQSV$>bDMkc6I{0*~yl^c81W2STN&z;^3OHWQ+<3?6jxADNn&DaiLRi^= z1_ubRY8BXzRfi3AoSvFQM8(9VNmtgYqN=9HM|ESXCZ=ZQ)~q{wb#Zlb_vXEo#&BWM zv{`E2TI(H?c8KnHyJJM}qYNH($k1WKM;m>@d}f_8b=vgVW?yCT!tr0aEG=Jc^-UY5 zwCk3w+qUnvd%)I$qlScrg-472O6{Tgks5s>_iJkOP&>rx9cORU&}{ZY1RZxGhZ%^K zN+52B01UbuX4$FMa>yNKxfL7=DWFDj;4C`CK(KBq67zNTwY&Z7XG>d|u9hGo zv?I0%yy!kbyqX3g88Ard;kqY5fveQkHe0K+S8O%6iDcL`v+pcA7Qx+Pz)*l2xla$u z;ntVU+LGquwIO^WWK;xv#31CMyXL~fd0NpS@SvGk+gcPnwPP8v1W5$awHWn?N*+86 z0Rl8cCz9?KqgSBsP=C}JaQc^7h7}BrQy(ycIX9qd@ww(kx}WA_bgTX|^G?4QFc$Ns ztLQnEV=sq+uG#_UAy^3nT|h7$gv+j}uS-z-YEv&k3h05FD55J;S|JdHJ!3FPQ3iTP zhD&<`RpN%=ji@^jgC|rvPeP6`?YkaQ7gJq4_?pv0$`K4F11K<=(VRhPz@m{!<4d9L z>cvK*iTvF06*vsB9a|&AwltqD29|wo3P%a2O-~d(2kONB^&kX@GX!bLWjI961`oq* zJs*ahm*e{gnNIPMKb@$Q|LkaexqlVJHO_HDW(CU}4X3GH7SVW&FdKo~pmedmGm-&R zu=B`i90l}zeNJOLA3k!O&2>L;Rq$IlQ(X;S>iDYe*C2L%v_%57yC;@o8?b<~OuTV8$ngcVk$%0iht?a0000000000004@~*cSBMY@1oChvc#-OFVb!kGpzP zEA9tR`|ay|I$I@KCaKEjKFO&ay2HzQ^QgG*OIv>`?5n;Vy8T$nn~vr8ER$CK607FZ z+3LC3Hi|2*ds>!vM3*J2xU0+J#p*!4|y1pH{!&olDF2J5#0000000000004jF4eiTM6!4%6p#T5?07*qo IM6N<$f~LqfN&o-= literal 0 HcmV?d00001 diff --git a/indra/newview/skins/default/textures/textures.xml b/indra/newview/skins/default/textures/textures.xml index b086f7dfa8..2a4171f11b 100644 --- a/indra/newview/skins/default/textures/textures.xml +++ b/indra/newview/skins/default/textures/textures.xml @@ -113,8 +113,10 @@ with the same filename but different name + +