diff options
author | Adam Moss <moss@lindenlab.com> | 2008-11-12 20:28:24 +0000 |
---|---|---|
committer | Adam Moss <moss@lindenlab.com> | 2008-11-12 20:28:24 +0000 |
commit | a879e13055f0bb759ee12e708184e95d8bd9be30 (patch) | |
tree | d659c3f71dea7a4f213e9d855f331dc5af56c63a /indra/newview | |
parent | f89f19990cbb9f3f2e7473ac6c159098bdfabec7 (diff) |
svn merge -c102054
svn+ssh://svn.lindenlab.com/svn/linden/branches/moss/morejoy-2-r102015
QAR-1016 joystick+spacenav improvements MERGE
Diffstat (limited to 'indra/newview')
-rw-r--r-- | indra/newview/app_settings/settings.xml | 25 | ||||
-rw-r--r-- | indra/newview/linux_tools/client-readme-joystick.txt | 78 | ||||
-rw-r--r-- | indra/newview/linux_tools/client-readme.txt | 8 | ||||
-rw-r--r-- | indra/newview/llfloaterjoystick.cpp | 67 | ||||
-rw-r--r-- | indra/newview/llfloaterjoystick.h | 13 | ||||
-rw-r--r-- | indra/newview/lloverlaybar.cpp | 18 | ||||
-rw-r--r-- | indra/newview/lloverlaybar.h | 1 | ||||
-rw-r--r-- | indra/newview/llviewerjoystick.cpp | 283 | ||||
-rw-r--r-- | indra/newview/llviewerjoystick.h | 2 | ||||
-rw-r--r-- | indra/newview/llviewermenu.cpp | 11 | ||||
-rwxr-xr-x | indra/newview/viewer_manifest.py | 1 |
11 files changed, 391 insertions, 116 deletions
diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 4d4ce6c326..b01fbbec4f 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -2221,7 +2221,7 @@ <key>Type</key> <string>Boolean</string> <key>Value</key> - <real>1.0</real> + <integer>1</integer> </map> <key>Disregard96DefaultDrawDistance</key> <map> @@ -2232,7 +2232,7 @@ <key>Type</key> <string>Boolean</string> <key>Value</key> - <real>1.0</real> + <integer>1</integer> </map> <key>DoubleClickAutoPilot</key> <map> @@ -4007,13 +4007,13 @@ <key>JoystickAvatarEnabled</key> <map> <key>Comment</key> - <string>Enables the Joystick to control Avatar movmement.</string> + <string>Enables the Joystick to control Avatar movement.</string> <key>Persist</key> <integer>1</integer> <key>Type</key> <string>Boolean</string> <key>Value</key> - <string>1</string> + <integer>1</integer> </map> <key>JoystickAxis0</key> <map> @@ -4101,7 +4101,7 @@ <key>Type</key> <string>Boolean</string> <key>Value</key> - <string>1</string> + <integer>0</integer> </map> <key>JoystickEnabled</key> <map> @@ -4119,11 +4119,11 @@ <key>Comment</key> <string>Enables the Joystick to control the flycam.</string> <key>Persist</key> - <integer>1</integer> + <integer>0</integer> <key>Type</key> <string>Boolean</string> <key>Value</key> - <string>1</string> + <integer>1</integer> </map> <key>JoystickInitialized</key> <map> @@ -4136,6 +4136,17 @@ <key>Value</key> <string /> </map> + <key>JoystickRunThreshold</key> + <map> + <key>Comment</key> + <string>Input threshold to initiate running</string> + <key>Persist</key> + <integer>1</integer> + <key>Type</key> + <string>F32</string> + <key>Value</key> + <real>0.25</real> + </map> <key>KeepAspectForSnapshot</key> <map> <key>Comment</key> diff --git a/indra/newview/linux_tools/client-readme-joystick.txt b/indra/newview/linux_tools/client-readme-joystick.txt new file mode 100644 index 0000000000..997a8b08eb --- /dev/null +++ b/indra/newview/linux_tools/client-readme-joystick.txt @@ -0,0 +1,78 @@ +Second Life - Joystick & SpaceNavigator Support README +-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-= + +WHAT IS IT? +-=-=-=-=-=- + +This feature allows the use of a joystick or other supported multi-axis +device for controlling your avatar and camera. + +REQUIREMENTS +-=-=-=-=-=-= + +* A joystick or other generic multi-axis input device supported by your chosen + version of Linux + +- OR - + +* A SpaceNavigator device (additional configuration may be required, see below) + +Success has been reported on the following systems so far: +* Ubuntu 7.04 (Feisty) with a generic USB joystick +* Ubuntu 7.04 (Feisty) with a USB 3DConnexion SpaceNavigator +* Ubuntu 6.06 (Dapper) with a generic USB joystick +* Ubuntu 6.06 (Dapper) with a USB 3DConnexion SpaceNavigator + +CONFIGURATION +-=-=-=-=-=-=- + +SPACE NAVIGATOR: *Important* - do not install the Linux SpaceNavigator +drivers from the disk included with the device - these are problematic. +Some distributions of Linux (such as Ubuntu, Gentoo and Mandriva) will +need some system configuration to make the SpaceNavigator usable by +applications such as the Second Life Viewer, as follows: + +* Mandriva Linux Configuration: + You need to add two new files to your system. This only needs to be + done once. These files are available at the 'SpaceNavigator support with + udev and Linux input framework' section of + <http://www.aaue.dk/~janoc/index.php?n=Personal.Downloads> + +* Ubuntu or Gentoo Linux Configuration: + For a quick start, you can simply paste the following line into a terminal + before plugging in your SpaceNavigator - this only needs to be done once: + sudo bash -c 'echo KERNEL==\"event[0-9]*\", SYSFS{idVendor}==\"046d\", SYSFS{idProduct}==\"c626\", SYMLINK+=\"input/spacenavigator\", GROUP=\"plugdev\", MODE=\"664\" >> /etc/udev/rules.d/91-spacenavigator.rules' + +For more comprehensive Linux SpaceNavigator configuration information please +see the section 'Installing SpaceNavigator without the official driver' here: +<http://www.aaue.dk/~janoc/index.php?n=Personal.3DConnexionSpaceNavigatorSupport> + +JOYSTICKS: These should be automatically detected and configured on all +modern distributions of Linux. + +ALL: Your joystick or SpaceNavigator should be plugged-in before you start the +Second Life Viewer, so that it may be detected. If you have multiple input +devices attached, only the first detected SpaceNavigator or joystick device +will be available. + +Once your system recognises your joystick or SpaceNavigator correctly, you +can go into the Second Life Viewer's Preferences dialog, click the 'Input & +Camera' tab, and click the 'Joystick Setup' button. From here you may enable +and disable joystick support and change some configuration settings such as +sensitivity. SpaceNavigator users are recommended to click the +'SpaceNavigator Defaults' button. + +KNOWN PROBLEMS +-=-=-=-=-=-=-= + +* If your chosen version of Linux treats your joystick/SpaceNavigator as +if it were a mouse when you plug it in (i.e. it is automatically used to control +your desktop cursor), then the SL Viewer may detect this device *but* will be +unable to use it properly. + +FURTHER PROBLEMS? +-=-=-=-=-=-=-=-=- + +Please report further issues to the public Second Life issue-tracker +at <http://jira.secondlife.com/> (please note, however, that this is not +a support forum). diff --git a/indra/newview/linux_tools/client-readme.txt b/indra/newview/linux_tools/client-readme.txt index 179cb9e0b7..c4e193bd9b 100644 --- a/indra/newview/linux_tools/client-readme.txt +++ b/indra/newview/linux_tools/client-readme.txt @@ -112,10 +112,14 @@ the Beta release of the Linux client. The client prints a lot of diagnostic information to the console it was run from. Most of this is also replicated in ~/.secondlife/logs/SecondLife.log -- this is helpful to read when troubleshooting, especially 'WARNING' lines. +- this is helpful to read when troubleshooting, especially 'WARNING' and +'ERROR' lines. VOICE PROBLEMS? See the separate README-linux-voice.txt file for Voice -troubleshooting information. + troubleshooting information. + +SPACENAVIGATOR OR JOYSTICK PROBLEMS? See the separate + README-linux-joystick.txt file for configuration information. PROBLEM 1:- Second Life fails to start up, with a warning on the console like: 'Error creating window.' or diff --git a/indra/newview/llfloaterjoystick.cpp b/indra/newview/llfloaterjoystick.cpp index 9c3463010e..b9ffe79151 100644 --- a/indra/newview/llfloaterjoystick.cpp +++ b/indra/newview/llfloaterjoystick.cpp @@ -44,6 +44,7 @@ #include "llviewercontrol.h" #include "llappviewer.h" #include "llviewerjoystick.h" +#include "llcheckboxctrl.h" LLFloaterJoystick::LLFloaterJoystick(const LLSD& data) : LLFloater("floater_joystick") @@ -114,7 +115,15 @@ BOOL LLFloaterJoystick::postBuild() addChild(mAxisStatsView); + mCheckJoystickEnabled = getChild<LLCheckBoxCtrl>("enable_joystick"); + childSetCommitCallback("enable_joystick",onCommitJoystickEnabled,this); + mCheckFlycamEnabled = getChild<LLCheckBoxCtrl>("JoystickFlycamEnabled"); + childSetCommitCallback("JoystickFlycamEnabled",onCommitJoystickEnabled,this); + childSetAction("SpaceNavigatorDefaults", onClickRestoreSNDefaults, this); + childSetAction("cancel_btn", onClickCancel, this); + childSetAction("ok_btn", onClickOK, this); + refresh(); return TRUE; } @@ -133,6 +142,8 @@ void LLFloaterJoystick::refresh() { LLFloater::refresh(); + mJoystickEnabled = gSavedSettings.getBOOL("JoystickEnabled"); + mJoystickAxis[0] = gSavedSettings.getS32("JoystickAxis0"); mJoystickAxis[1] = gSavedSettings.getS32("JoystickAxis1"); mJoystickAxis[2] = gSavedSettings.getS32("JoystickAxis2"); @@ -145,6 +156,10 @@ void LLFloaterJoystick::refresh() mAutoLeveling = gSavedSettings.getBOOL("AutoLeveling"); mZoomDirect = gSavedSettings.getBOOL("ZoomDirect"); + mAvatarEnabled = gSavedSettings.getBOOL("JoystickAvatarEnabled"); + mBuildEnabled = gSavedSettings.getBOOL("JoystickBuildEnabled"); + mFlycamEnabled = gSavedSettings.getBOOL("JoystickFlycamEnabled"); + mAvatarAxisScale[0] = gSavedSettings.getF32("AvatarAxisScale0"); mAvatarAxisScale[1] = gSavedSettings.getF32("AvatarAxisScale1"); mAvatarAxisScale[2] = gSavedSettings.getF32("AvatarAxisScale2"); @@ -196,9 +211,7 @@ void LLFloaterJoystick::refresh() void LLFloaterJoystick::cancel() { - llinfos << "reading from gSavedSettings->Cursor3D=" - << gSavedSettings.getBOOL("Cursor3D") << "; m3DCursor=" - << m3DCursor << llendl; + gSavedSettings.setBOOL("JoystickEnabled", mJoystickEnabled); gSavedSettings.setS32("JoystickAxis0", mJoystickAxis[0]); gSavedSettings.setS32("JoystickAxis1", mJoystickAxis[1]); @@ -212,6 +225,10 @@ void LLFloaterJoystick::cancel() gSavedSettings.setBOOL("AutoLeveling", mAutoLeveling); gSavedSettings.setBOOL("ZoomDirect", mZoomDirect ); + gSavedSettings.setBOOL("JoystickAvatarEnabled", mAvatarEnabled); + gSavedSettings.setBOOL("JoystickBuildEnabled", mBuildEnabled); + gSavedSettings.setBOOL("JoystickFlycamEnabled", mFlycamEnabled); + gSavedSettings.setF32("AvatarAxisScale0", mAvatarAxisScale[0]); gSavedSettings.setF32("AvatarAxisScale1", mAvatarAxisScale[1]); gSavedSettings.setF32("AvatarAxisScale2", mAvatarAxisScale[2]); @@ -261,11 +278,55 @@ void LLFloaterJoystick::cancel() gSavedSettings.setF32("FlycamFeathering", mFlycamFeathering); } +void LLFloaterJoystick::onCommitJoystickEnabled(LLUICtrl*, void *joy_panel) +{ + LLFloaterJoystick* self = (LLFloaterJoystick*)joy_panel; + BOOL joystick_enabled = self->mCheckJoystickEnabled->get(); + BOOL flycam_enabled = self->mCheckFlycamEnabled->get(); + + if (!joystick_enabled || !flycam_enabled) + { + // Turn off flycam + LLViewerJoystick* joystick(LLViewerJoystick::getInstance()); + if (joystick->getOverrideCamera()) + { + joystick->toggleFlycam(); + } + } +} + void LLFloaterJoystick::onClickRestoreSNDefaults(void *joy_panel) { setSNDefaults(); } +void LLFloaterJoystick::onClickCancel(void *joy_panel) +{ + if (joy_panel) + { + LLFloaterJoystick* self = (LLFloaterJoystick*)joy_panel; + + if (self) + { + self->cancel(); + self->close(); + } + } +} + +void LLFloaterJoystick::onClickOK(void *joy_panel) +{ + if (joy_panel) + { + LLFloaterJoystick* self = (LLFloaterJoystick*)joy_panel; + + if (self) + { + self->close(); + } + } +} + void LLFloaterJoystick::setSNDefaults() { LLViewerJoystick::getInstance()->setSNDefaults(); diff --git a/indra/newview/llfloaterjoystick.h b/indra/newview/llfloaterjoystick.h index 6dc40704f0..118920ee83 100644 --- a/indra/newview/llfloaterjoystick.h +++ b/indra/newview/llfloaterjoystick.h @@ -35,6 +35,8 @@ #include "llfloater.h" #include "llstatview.h" +class LLCheckBoxCtrl; + class LLFloaterJoystick : public LLFloater, public LLFloaterSingleton<LLFloaterJoystick > { public: @@ -49,16 +51,23 @@ public: static void setSNDefaults(); private: + static void onCommitJoystickEnabled(LLUICtrl*, void*); static void onClickRestoreSNDefaults(void*); + static void onClickCancel(void*); + static void onClickOK(void*); private: // Device prefs + bool mJoystickEnabled; S32 mJoystickAxis[7]; bool m3DCursor; bool mAutoLeveling; bool mZoomDirect; // Modes prefs + bool mAvatarEnabled; + bool mBuildEnabled; + bool mFlycamEnabled; F32 mAvatarAxisScale[6]; F32 mBuildAxisScale[6]; F32 mFlycamAxisScale[7]; @@ -69,6 +78,10 @@ private: F32 mBuildFeathering; F32 mFlycamFeathering; + // Controls that can disable the flycam + LLCheckBoxCtrl *mCheckJoystickEnabled; + LLCheckBoxCtrl *mCheckFlycamEnabled; + // stats view LLStatView* mAxisStatsView; LLStat* mAxisStats[6]; diff --git a/indra/newview/lloverlaybar.cpp b/indra/newview/lloverlaybar.cpp index 7162c2e925..f311732e46 100644 --- a/indra/newview/lloverlaybar.cpp +++ b/indra/newview/lloverlaybar.cpp @@ -50,6 +50,7 @@ #include "llui.h" #include "llviewercontrol.h" #include "llviewerimagelist.h" +#include "llviewerjoystick.h" #include "llviewermedia.h" #include "llviewermenu.h" // handle_reset_view() #include "llviewermedia.h" @@ -122,6 +123,7 @@ BOOL LLOverlayBar::postBuild() childSetAction("Set Not Busy",onClickSetNotBusy,this); childSetAction("Mouselook",onClickMouselook,this); childSetAction("Stand Up",onClickStandUp,this); + childSetAction("Flycam",onClickFlycam,this); childSetVisible("chat_bar", gSavedSettings.getBOOL("ChatVisible")); setFocusRoot(TRUE); @@ -209,6 +211,16 @@ void LLOverlayBar::refresh() buttons_changed = TRUE; } + BOOL flycam = LLViewerJoystick::getInstance()->getOverrideCamera(); + button = getChild<LLButton>("Flycam"); + if (button && button->getVisible() != flycam) + { + button->setVisible(flycam); + sendChildToFront(button); + moveChildToBackOfTabGroup(button); + buttons_changed = TRUE; + } + BOOL mouselook_grabbed; mouselook_grabbed = gAgent.isControlGrabbed(CONTROL_ML_LBUTTON_DOWN_INDEX) || gAgent.isControlGrabbed(CONTROL_ML_LBUTTON_UP_INDEX); @@ -284,6 +296,12 @@ void LLOverlayBar::onClickSetNotBusy(void*) // static +void LLOverlayBar::onClickFlycam(void*) +{ + LLViewerJoystick::getInstance()->toggleFlycam(); +} + +// static void LLOverlayBar::onClickResetView(void* data) { handle_reset_view(); diff --git a/indra/newview/lloverlaybar.h b/indra/newview/lloverlaybar.h index 581effa56b..2f74a02310 100644 --- a/indra/newview/lloverlaybar.h +++ b/indra/newview/lloverlaybar.h @@ -71,6 +71,7 @@ public: static void onClickMouselook(void* data); static void onClickStandUp(void* data); static void onClickResetView(void* data); + static void onClickFlycam(void* data); //static media helper functions static void toggleMediaPlay(void*); diff --git a/indra/newview/llviewerjoystick.cpp b/indra/newview/llviewerjoystick.cpp index 899ad2c0d6..ff5abb447d 100644 --- a/indra/newview/llviewerjoystick.cpp +++ b/indra/newview/llviewerjoystick.cpp @@ -58,12 +58,15 @@ // flycam translations in build mode should be reduced const F32 BUILDMODE_FLYCAM_T_SCALE = 3.f; +// minimum time after setting away state before coming back +const F32 MIN_AFK_TIME = 2.f; + F32 LLViewerJoystick::sLastDelta[] = {0,0,0,0,0,0,0}; F32 LLViewerJoystick::sDelta[] = {0,0,0,0,0,0,0}; // These constants specify the maximum absolute value coming in from the device. // HACK ALERT! the value of MAX_JOYSTICK_INPUT_VALUE is not arbitrary as it -// should be. It has to be equal to 3000 because the SpaceNavigator on Windows +// should be. It has to be equal to 3000 because the SpaceNavigator on Windows // refuses to respond to the DirectInput SetProperty call; it always returns // values in the [-3000, 3000] range. #define MAX_SPACENAVIGATOR_INPUT 3000.0f @@ -147,7 +150,8 @@ LLViewerJoystick::LLViewerJoystick() mNdofDev(NULL), mResetFlag(false), mCameraUpdated(true), - mOverrideCamera(false) + mOverrideCamera(false), + mJoystickRun(0) { for (int i = 0; i < 6; i++) { @@ -322,6 +326,40 @@ U32 LLViewerJoystick::getJoystickButton(U32 button) const } // ----------------------------------------------------------------------------- +void LLViewerJoystick::handleRun(F32 inc) +{ + // Decide whether to walk or run by applying a threshold, with slight + // hysteresis to avoid oscillating between the two with input spikes. + // Analog speed control would be better, but not likely any time soon. + if (inc > gSavedSettings.getF32("JoystickRunThreshold")) + { + if (1 == mJoystickRun) + { + ++mJoystickRun; + gAgent.setRunning(); + gAgent.sendWalkRun(gAgent.getRunning()); + } + else if (0 == mJoystickRun) + { + // hysteresis - respond NEXT frame + ++mJoystickRun; + } + } + else + { + if (mJoystickRun > 0) + { + --mJoystickRun; + if (0 == mJoystickRun) + { + gAgent.clearRunning(); + gAgent.sendWalkRun(gAgent.getRunning()); + } + } + } +} + +// ----------------------------------------------------------------------------- void LLViewerJoystick::agentJump() { gAgent.moveUp(1); @@ -330,11 +368,11 @@ void LLViewerJoystick::agentJump() // ----------------------------------------------------------------------------- void LLViewerJoystick::agentSlide(F32 inc) { - if (inc < 0) + if (inc < 0.f) { gAgent.moveLeft(1); } - else if (inc > 0) + else if (inc > 0.f) { gAgent.moveLeft(-1); } @@ -343,11 +381,11 @@ void LLViewerJoystick::agentSlide(F32 inc) // ----------------------------------------------------------------------------- void LLViewerJoystick::agentPush(F32 inc) { - if (inc < 0) // forward + if (inc < 0.f) // forward { gAgent.moveAt(1, false); } - else if (inc > 0) // backward + else if (inc > 0.f) // backward { gAgent.moveAt(-1, false); } @@ -356,18 +394,18 @@ void LLViewerJoystick::agentPush(F32 inc) // ----------------------------------------------------------------------------- void LLViewerJoystick::agentFly(F32 inc) { - if (inc < 0) + if (inc < 0.f) { - if (gAgent.getFlying()) - { - gAgent.moveUp(1); - } - else + if (! (gAgent.getFlying() || + !gAgent.canFly() || + gAgent.upGrabbed() || + !gSavedSettings.getBOOL("AutomaticFly")) ) { gAgent.setFlying(true); } + gAgent.moveUp(1); } - else if (inc > 0) + else if (inc > 0.f) { // crouch gAgent.moveUp(-1); @@ -492,6 +530,12 @@ void LLViewerJoystick::moveObjects(bool reset) if (!is_zero) { + // Clear AFK state if moved beyond the deadzone + if (gAwayTimer.getElapsedTimeF32() > MIN_AFK_TIME) + { + gAgent.clearAFK(); + } + if (sDelta[0] || sDelta[1] || sDelta[2]) { upd_type |= UPD_POSITION; @@ -549,11 +593,13 @@ void LLViewerJoystick::moveAvatar(bool reset) return; } + bool is_zero = true; + if (mBtn[1] == 1) - { + { agentJump(); - return; - } + is_zero = false; + } F32 axis_scale[] = { @@ -626,16 +672,29 @@ void LLViewerJoystick::moveAvatar(bool reset) dom_mov = val; } } + + is_zero = is_zero && (cur_delta[i] == 0.f); + } + + if (!is_zero) + { + // Clear AFK state if moved beyond the deadzone + if (gAwayTimer.getElapsedTimeF32() > MIN_AFK_TIME) + { + gAgent.clearAFK(); + } + + setCameraNeedsUpdate(true); } // forward|backward movements overrule the real dominant movement if - // they're bigger than its 20%. This is what you want cos moving forward + // they're bigger than its 20%. This is what you want 'cos moving forward // is what you do most. We also added a special (even more lenient) case - // for RX|RY to allow walking while pitching n' turning + // for RX|RY to allow walking while pitching and turning if (fabs(cur_delta[Z_I]) > .2f * dom_mov - || ((dom_axis == RX_I || dom_axis == RY_I) - && fabs(cur_delta[Z_I]) > .05f * dom_mov)) - { + || ((dom_axis == RX_I || dom_axis == RY_I) + && fabs(cur_delta[Z_I]) > .05f * dom_mov)) + { dom_axis = Z_I; } @@ -653,68 +712,67 @@ void LLViewerJoystick::moveAvatar(bool reset) sDelta[RX_I] += (cur_delta[RX_I] - sDelta[RX_I]) * time * feather; sDelta[RY_I] += (cur_delta[RY_I] - sDelta[RY_I]) * time * feather; - switch (dom_axis) - { - case X_I: // move sideways - agentSlide(sDelta[X_I]); - break; - - case Z_I: // forward/back - { - agentPush(sDelta[Z_I]); - - if (fabs(sDelta[Y_I]) > .1f) - { - agentFly(sDelta[Y_I]); - } + llinfos << sDelta[Z_I] << ", " << sDelta[X_I] << llendl; + handleRun(fsqrtf(sDelta[Z_I]*sDelta[Z_I] + sDelta[X_I]*sDelta[X_I])); + + // Allow forward/backward movement some priority + if (dom_axis == Z_I) + { + agentPush(sDelta[Z_I]); // forward/back - // too many rotations during walking can be confusing, so apply - // the deadzones one more time (quick & dirty), at 50%|30% power - F32 eff_rx = .3f * dead_zone[RX_I]; - F32 eff_ry = .3f * dead_zone[RY_I]; + if (fabs(sDelta[X_I]) > .1f) + { + agentSlide(sDelta[X_I]); // move sideways + } - if (sDelta[RX_I] > 0) - { - eff_rx = llmax(sDelta[RX_I] - eff_rx, 0.f); - } - else - { - eff_rx = llmin(sDelta[RX_I] + eff_rx, 0.f); - } + if (fabs(sDelta[Y_I]) > .1f) + { + agentFly(sDelta[Y_I]); // up/down & crouch + } + + // too many rotations during walking can be confusing, so apply + // the deadzones one more time (quick & dirty), at 50%|30% power + F32 eff_rx = .3f * dead_zone[RX_I]; + F32 eff_ry = .3f * dead_zone[RY_I]; + + if (sDelta[RX_I] > 0) + { + eff_rx = llmax(sDelta[RX_I] - eff_rx, 0.f); + } + else + { + eff_rx = llmin(sDelta[RX_I] + eff_rx, 0.f); + } - if (sDelta[RY_I] > 0) + if (sDelta[RY_I] > 0) + { + eff_ry = llmax(sDelta[RY_I] - eff_ry, 0.f); + } + else + { + eff_ry = llmin(sDelta[RY_I] + eff_ry, 0.f); + } + + + if (fabs(eff_rx) > 0.f || fabs(eff_ry) > 0.f) + { + if (gAgent.getFlying()) { - eff_ry = llmax(sDelta[RY_I] - eff_ry, 0.f); + agentRotate(eff_rx, eff_ry); } else { - eff_ry = llmin(sDelta[RY_I] + eff_ry, 0.f); - } - - - if (fabs(eff_rx) > 0.f || fabs(eff_ry) > 0.f) - { - if (gAgent.getFlying()) - { - agentRotate(eff_rx, eff_ry); - } - else - { - agentRotate(eff_rx, 2.f * eff_ry); - } + agentRotate(eff_rx, 2.f * eff_ry); } - break; - } - case Y_I: // up/crouch - agentFly(sDelta[Y_I]); - break; - - case RX_I: // pitch - case RY_I: // turn - agentRotate(sDelta[RX_I], sDelta[RY_I]); - break; - // case RZ_I: roll is unused in avatar mode - }// switch + } + } + else + { + agentSlide(sDelta[X_I]); // move sideways + agentFly(sDelta[Y_I]); // up/down & crouch + agentPush(sDelta[Z_I]); // forward/back + agentRotate(sDelta[RX_I], sDelta[RY_I]); // pitch & turn + } } // ----------------------------------------------------------------------------- @@ -777,7 +835,7 @@ void LLViewerJoystick::moveFlycam(bool reset) F32 time = gFrameIntervalSeconds; - // avoid making ridicously big movements if there's a big drop in fps + // avoid making ridiculously big movements if there's a big drop in fps if (time > .2f) { time = .2f; @@ -786,6 +844,7 @@ void LLViewerJoystick::moveFlycam(bool reset) F32 cur_delta[7]; F32 feather = gSavedSettings.getF32("FlycamFeathering"); bool absolute = gSavedSettings.getBOOL("Cursor3D"); + bool is_zero = true; for (U32 i = 0; i < 7; i++) { @@ -827,6 +886,15 @@ void LLViewerJoystick::moveFlycam(bool reset) } sDelta[i] = sDelta[i] + (cur_delta[i]-sDelta[i])*time*feather; + + is_zero = is_zero && (cur_delta[i] == 0.f); + + } + + // Clear AFK state if moved beyond the deadzone + if (!is_zero && gAwayTimer.getElapsedTimeF32() > MIN_AFK_TIME) + { + gAgent.clearAFK(); } sFlycamPosition += LLVector3(sDelta) * sFlycamRotation; @@ -875,13 +943,20 @@ bool LLViewerJoystick::toggleFlycam() { if (!gSavedSettings.getBOOL("JoystickEnabled") || !gSavedSettings.getBOOL("JoystickFlycamEnabled")) { + mOverrideCamera = false; return false; } + if (!mOverrideCamera) { gAgent.changeCameraToDefault(); } + if (gAwayTimer.getElapsedTimeF32() > MIN_AFK_TIME) + { + gAgent.clearAFK(); + } + mOverrideCamera = !mOverrideCamera; if (mOverrideCamera) { @@ -931,7 +1006,7 @@ void LLViewerJoystick::scanJoystick() toggle_flycam = 0; } - if (!mOverrideCamera && !LLToolMgr::getInstance()->inBuildMode()) + if (!mOverrideCamera && !(LLToolMgr::getInstance()->inBuildMode() && gSavedSettings.getBOOL("JoystickBuildEnabled"))) { moveAvatar(); } @@ -966,10 +1041,15 @@ bool LLViewerJoystick::isLikeSpaceNavigator() const // ----------------------------------------------------------------------------- void LLViewerJoystick::setSNDefaults() { -#if LL_DARWIN -#define kPlatformScale 20.f +#if LL_DARWIN || LL_LINUX + const float platformScale = 20.f; + const float platformScaleAvXZ = 1.f; + // The SpaceNavigator doesn't act as a 3D cursor on OS X / Linux. + const bool is_3d_cursor = false; #else -#define kPlatformScale 1.f + const float platformScale = 1.f; + const float platformScaleAvXZ = 2.f; + const bool is_3d_cursor = true; #endif //gViewerWindow->alertXml("CacheWillClear"); @@ -983,34 +1063,29 @@ void LLViewerJoystick::setSNDefaults() gSavedSettings.setS32("JoystickAxis5", 5); // yaw gSavedSettings.setS32("JoystickAxis6", -1); -#if LL_DARWIN - // The SpaceNavigator doesn't act as a 3D cursor on OS X. - gSavedSettings.setBOOL("Cursor3D", false); -#else - gSavedSettings.setBOOL("Cursor3D", true); -#endif + gSavedSettings.setBOOL("Cursor3D", is_3d_cursor); gSavedSettings.setBOOL("AutoLeveling", true); gSavedSettings.setBOOL("ZoomDirect", false); - gSavedSettings.setF32("AvatarAxisScale0", 1.f); - gSavedSettings.setF32("AvatarAxisScale1", 1.f); + gSavedSettings.setF32("AvatarAxisScale0", 1.f * platformScaleAvXZ); + gSavedSettings.setF32("AvatarAxisScale1", 1.f * platformScaleAvXZ); gSavedSettings.setF32("AvatarAxisScale2", 1.f); - gSavedSettings.setF32("AvatarAxisScale4", .1f * kPlatformScale); - gSavedSettings.setF32("AvatarAxisScale5", .1f * kPlatformScale); - gSavedSettings.setF32("AvatarAxisScale3", 0.f * kPlatformScale); - gSavedSettings.setF32("BuildAxisScale1", .3f * kPlatformScale); - gSavedSettings.setF32("BuildAxisScale2", .3f * kPlatformScale); - gSavedSettings.setF32("BuildAxisScale0", .3f * kPlatformScale); - gSavedSettings.setF32("BuildAxisScale4", .3f * kPlatformScale); - gSavedSettings.setF32("BuildAxisScale5", .3f * kPlatformScale); - gSavedSettings.setF32("BuildAxisScale3", .3f * kPlatformScale); - gSavedSettings.setF32("FlycamAxisScale1", 2.f * kPlatformScale); - gSavedSettings.setF32("FlycamAxisScale2", 2.f * kPlatformScale); - gSavedSettings.setF32("FlycamAxisScale0", 2.1f * kPlatformScale); - gSavedSettings.setF32("FlycamAxisScale4", .1f * kPlatformScale); - gSavedSettings.setF32("FlycamAxisScale5", .15f * kPlatformScale); - gSavedSettings.setF32("FlycamAxisScale3", 0.f * kPlatformScale); - gSavedSettings.setF32("FlycamAxisScale6", 0.f * kPlatformScale); + gSavedSettings.setF32("AvatarAxisScale4", .1f * platformScale); + gSavedSettings.setF32("AvatarAxisScale5", .1f * platformScale); + gSavedSettings.setF32("AvatarAxisScale3", 0.f * platformScale); + gSavedSettings.setF32("BuildAxisScale1", .3f * platformScale); + gSavedSettings.setF32("BuildAxisScale2", .3f * platformScale); + gSavedSettings.setF32("BuildAxisScale0", .3f * platformScale); + gSavedSettings.setF32("BuildAxisScale4", .3f * platformScale); + gSavedSettings.setF32("BuildAxisScale5", .3f * platformScale); + gSavedSettings.setF32("BuildAxisScale3", .3f * platformScale); + gSavedSettings.setF32("FlycamAxisScale1", 2.f * platformScale); + gSavedSettings.setF32("FlycamAxisScale2", 2.f * platformScale); + gSavedSettings.setF32("FlycamAxisScale0", 2.1f * platformScale); + gSavedSettings.setF32("FlycamAxisScale4", .1f * platformScale); + gSavedSettings.setF32("FlycamAxisScale5", .15f * platformScale); + gSavedSettings.setF32("FlycamAxisScale3", 0.f * platformScale); + gSavedSettings.setF32("FlycamAxisScale6", 0.f * platformScale); gSavedSettings.setF32("AvatarAxisDeadZone0", .1f); gSavedSettings.setF32("AvatarAxisDeadZone1", .1f); diff --git a/indra/newview/llviewerjoystick.h b/indra/newview/llviewerjoystick.h index c4dd8cfc5a..fbfcef0173 100644 --- a/indra/newview/llviewerjoystick.h +++ b/indra/newview/llviewerjoystick.h @@ -76,6 +76,7 @@ public: protected: void updateEnabled(bool autoenable); void terminate(); + void handleRun(F32 inc); void agentSlide(F32 inc); void agentPush(F32 inc); void agentFly(F32 inc); @@ -96,6 +97,7 @@ private: F32 mPerfScale; bool mCameraUpdated; bool mOverrideCamera; + U32 mJoystickRun; static F32 sLastDelta[7]; static F32 sDelta[7]; diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 4bf5a2d4ea..645d68a13a 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -4501,6 +4501,16 @@ void handle_force_delete(void*) LLSelectMgr::getInstance()->selectForceDelete(); } +class LLViewEnableJoystickFlycam : public view_listener_t +{ + bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) + { + bool new_value = (gSavedSettings.getBOOL("JoystickEnabled") && gSavedSettings.getBOOL("JoystickFlycamEnabled")); + gMenuHolder->findControl(userdata["control"].asString())->setValue(new_value); + return true; + } +}; + class LLViewEnableLastChatter : public view_listener_t { bool handleEvent(LLPointer<LLEvent> event, const LLSD& userdata) @@ -7447,6 +7457,7 @@ void initialize_menus() addMenu(new LLViewDefaultUISize(), "View.DefaultUISize"); addMenu(new LLViewEnableMouselook(), "View.EnableMouselook"); + addMenu(new LLViewEnableJoystickFlycam(), "View.EnableJoystickFlycam"); addMenu(new LLViewEnableLastChatter(), "View.EnableLastChatter"); addMenu(new LLViewCheckBuildMode(), "View.CheckBuildMode"); diff --git a/indra/newview/viewer_manifest.py b/indra/newview/viewer_manifest.py index 875b3ccbf7..317cb6f5fc 100755 --- a/indra/newview/viewer_manifest.py +++ b/indra/newview/viewer_manifest.py @@ -542,6 +542,7 @@ class LinuxManifest(ViewerManifest): if self.prefix("linux_tools", dst=""): self.path("client-readme.txt","README-linux.txt") self.path("client-readme-voice.txt","README-linux-voice.txt") + self.path("client-readme-joystick.txt","README-linux-joystick.txt") self.path("wrapper.sh","secondlife") self.path("handle_secondlifeprotocol.sh") self.path("register_secondlifeprotocol.sh") |