summaryrefslogtreecommitdiff
path: root/indra/newview
diff options
context:
space:
mode:
Diffstat (limited to 'indra/newview')
-rw-r--r--indra/newview/app_settings/settings.xml25
-rw-r--r--indra/newview/linux_tools/client-readme-joystick.txt78
-rw-r--r--indra/newview/linux_tools/client-readme.txt8
-rw-r--r--indra/newview/llfloaterjoystick.cpp67
-rw-r--r--indra/newview/llfloaterjoystick.h13
-rw-r--r--indra/newview/lloverlaybar.cpp18
-rw-r--r--indra/newview/lloverlaybar.h1
-rw-r--r--indra/newview/llviewerjoystick.cpp283
-rw-r--r--indra/newview/llviewerjoystick.h2
-rw-r--r--indra/newview/llviewermenu.cpp11
-rwxr-xr-xindra/newview/viewer_manifest.py1
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")