---------------------------------------
An RFC is a Request for Comments. It is patterned loosely after these.
Status of This Memo
---------------------------------------
This memo defines an Experimental Interface for use within LSL. Discussion and suggestions for improvement are requested.
Abstract
---------------------------------------
Joystick support has been suggested in the past, but has received a reception that could be considered lukewarm at best. However, now that Second Life has vehicle support, it is becoming increasingly obvious that relying on a few trappable keys is a clunky and onerous way to control a vehicle, outside a very narrow range of parameters. This is particularly true of ground vehicles, which practically have to be optimized differently for each coursre they run on in order to yield the best results. This can be overcome to a certain degree with clever scripting, but even the most intelligently-planned keyboard control scheme would be hard-pressed to compete with even a mediocre joystick control scheme.
This is a first draft of constants, functions, and an event that we would like to propose. Joystick inputs would be accessed with a joystick() event, with buttons and axes passed in a manner that is (somewhat) consistent with the control() event. There would also be a facility to map joystick axes directly to the linear and angular motors, which should make it exceptionally easy to adapt vehicle scripts to use joysticks.
We are working under the assumption that the joystick inputs would be reported to the LSL VM on the same schedule as the keyboard.
To Be Addressed
---------------------------------------
This early draft does not address D-pad joysticks. It is suggested that, provisionally, the viewer provide an option to map the D-pad to the cursor (arrow) keys. It will also be necessary to add joystick-related constants for llTakeControls() et. al.
Interface Specifics
---------------------------------------
// Constants concerning axes and buttons
JOY_NUM_AXES
JOY_NUM_BUTTONS
JOY_AXIS_MIN
JOY_AXIS_MAX
JOY_AXIS_X
JOY_AXIS_Y
JOY_AXIS_Z // throttle
JOY_AXIS_U // rudder
JOY_AXIS_V // rare
JOY_AXIS_W // not even sure if W exists
JOY_AXIS_ALL // for setting params on all axes
// Hat control and buttons
// Among other things, these are bitmapped in the levels
// and edges parameters in the joystick() event
JOY_HAT_UP
JOY_HAT_DOWN
JOY_HAT_LEFT
JOY_HAT_RIGHT
JOY_BUTTON_1
...
JOY_BUTTON_9
// Constants concerning particular hardware
JOY_VENDOR_ID
JOY_PRODUCT_ID
// Constants concerning axis input smoothing and scaling
JOY_AXIS_SMOOTHING // Average last few inputs against current
JOY_AXIS_SMOOTHING_FACTOR // Same idea as mouse accel
JOY_AXIS_ACCEL_FACTOR // How fast to accelerate across an axis
JOY_AXIS_ACCEL_THRESHOLD // Do not apply acceleration below this speed
JOY_AXIS_NOSCALE // Just return raw axis numbers
JOY_AXIS_SIGNED_100 // Returns range -100 to 99
JOY_AXIS_UNSIGNED_100 // Returns range 0 to 99
// Many joysticks return spurious inputs when the control stick
// is "centered." This sets up a deadzone, such that when the
// joystick is within param / 2 mickeys (or whatever) of
// dead center, the joystick API will say that the stick is at
// dead center.
JOY_AXIS_DEADZONE
// Constants concerning joystick-to-motor mapping.
// Note that multiple axes can be mapped to a singular
// motor. For example, an airplane would map X and Y to the
// angular motor.
JOY_MAP_AXIS_TO_LINEAR_MOTOR
JOY_MAP_AXIS_TO_ANGULAR_MOTOR
JOY_UNMAP_AXIS_TO_LINEAR_MOTOR
JOY_UNMAP_AXIS_TO_ANGULAR_MOTOR
JOY_LINEAR_MAP_FACTOR
JOY_ANGULAR_MAP_FACTOR
// Constants concerning "force feedback" and the like
JOY_HAS_OSCILLATOR
// Reads a single joystick parameter; param = 0 if unneeded
float llGetJoystickParam(paramType, param)
// Sets a single joystick parameter, such as smoothing
// Returns TRUE or FALSE
integer llSetJoystickParam(paramType, param)
// Returns (list)[x, y, throttle, rudder, u, v, w, hatX, hatY]
// i.e. [22.3, -14.57, 78, -12, 0, 0, 0, 1, -1]
list llGetJoystickAxes()
// Returns (rot)<x, y, throttle, rudder>
rotation llGetJoystickControlAxes()
// Returns (rot)<u, v, hatX, hatY>
rotation llGetJoystickAuxAxes()
// Turn on the oscillator (force feedback etc.)
// TRUE if hardware supports this, FALSE if not
integer llActivateJoystickOscillator(integer seconds)
// Joystick event, fired whenever joystick data is returned from the viewer
joystick(key name, integer levels, integer edges, list axes, rotation control, rotation aux)
Example Code
---------------------------------------
// Joystick event
joystick(key name, integer levels, integer edges, list axes, rotation control, rotation aux) {
// X-axis turns vehicle
llSetVehicleVectorParam(
VEHICLE_ANGULAR_MOTOR_DIRECTION,
<ROTATION_RATE * control.x, 0, ROTATION_RATE/2.0>
;// Z-axis controls throttle
llSetVehicleVectorParam(
VEHICLE_LINEAR_MOTOR_DIRECTION, <FWD_THRUST * control.z,0,0>
;// Button 1 controls
if((edge & JOY_BUTTON_1) && (level & JOY_BUTTON_1))
jump();
}
// Using joystick-to-motor mapping (instead of/in addition to joystick() event)
// Set useful joystick axis maps for steering and throttle axes
llSetJoystickParam(JOY_AXIS_SIGNED_100, JOY_AXIS_X);
llSetJoystickParam(JOY_AXIS_UNSIGNED_100, JOY_AXIS_Z);
// Set a deadzone 20 units wide for the X-axis
// (axis in range -10 to +9 will return 0)
llSetJoystickParam(JOY_AXIS_DEADZONE, 20);
// Turn on mapping
llSetJoystickParam(JOY_MAP_AXIS_TO_LINEAR_MOTOR, JOY_AXIS_Z);
llSetJoystickParam(JOY_MAP_AXIS_TO_ANGULAR_MOTOR, JOY_AXIS_X);
// Set mapping factors
llSetJoystickParam(JOY_LINEAR_MAP_FACTOR, 2);
llSetJoystickParam(JOY_ANGULAR_MAP_FACTOR, 1);
// When you are done, unmap the axes with
// JOY_UNMAP_AXIS_TO_LINEAR_MOTOR and
// JOY_UNMAP_AXIS_TO_ANGULAR_MOTOR
Revision History
---------------------------------------
11/11/2003 03:24
Original created by Huns Valen

