svn merge -c102054

svn+ssh://svn.lindenlab.com/svn/linden/branches/moss/morejoy-2-r102015

QAR-1016 joystick+spacenav improvements MERGE
master
Adam Moss 2008-11-12 20:28:24 +00:00
parent f89f19990c
commit a879e13055
14 changed files with 406 additions and 122 deletions

View File

@ -13,9 +13,18 @@ Able Whitman
Adam Marker
VWR-2755
Aimee Trescothick
VWR-3336
VWR-3336
VWR-3903
VWR-4083
VWR-6348
VWR-6358
VWR-6360
VWR-6550
VWR-6583
VWR-6482
VWR-7383
VWR-8341
VWR-8482
VWR-9255
Alejandro Rosenthal
VWR-1184

View File

@ -3,12 +3,12 @@ include(Prebuilt)
use_prebuilt_binary(ndofdev)
if (WINDOWS OR DARWIN)
if (WINDOWS OR DARWIN OR LINUX)
add_definitions(-DLIB_NDOF=1)
endif (WINDOWS OR DARWIN)
endif (WINDOWS OR DARWIN OR LINUX)
if (WINDOWS)
set(NDOF_LIBRARY libndofdev)
elseif (DARWIN)
elseif (DARWIN OR LINUX)
set(NDOF_LIBRARY ndofdev)
endif (WINDOWS)

View File

@ -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>

View File

@ -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).

View File

@ -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

View File

@ -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();

View File

@ -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];

View File

@ -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);
@ -283,6 +295,12 @@ void LLOverlayBar::onClickSetNotBusy(void*)
}
// static
void LLOverlayBar::onClickFlycam(void*)
{
LLViewerJoystick::getInstance()->toggleFlycam();
}
// static
void LLOverlayBar::onClickResetView(void* data)
{

View File

@ -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*);

View File

@ -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++)
{
@ -321,6 +325,40 @@ U32 LLViewerJoystick::getJoystickButton(U32 button) const
return 0;
}
// -----------------------------------------------------------------------------
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()
{
@ -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
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
if (fabs(sDelta[X_I]) > .1f)
{
agentPush(sDelta[Z_I]);
if (fabs(sDelta[Y_I]) > .1f)
{
agentFly(sDelta[Y_I]);
}
agentSlide(sDelta[X_I]); // move sideways
}
// 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 (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);
agentRotate(eff_rx, 2.f * eff_ry);
}
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);
}
}
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);

View File

@ -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];

View File

@ -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");

View File

@ -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")

View File

@ -1124,9 +1124,9 @@ anguage Infrstructure (CLI) international standard</string>
<key>linux</key>
<map>
<key>md5sum</key>
<string>489612b246b2f4b2f239611d786c79de</string>
<string>9469c3732a33a154fa0a2807b9f36ccc</string>
<key>url</key>
<uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/ndofdev-linux-20080618.tar.bz2</uri>
<uri>http://s3.amazonaws.com/viewer-source-downloads/install_pkgs/ndofdev-linux-0.2-20080828.tar.bz2</uri>
</map>
<key>linux32</key>
<map>