The Razer Hydra provides a controller for each hand that may report its absolute position and rotation, along with a series of standard gamepad controls. Torque 3D has preliminary support for this new input device. This page describes how to set up and use the Razer Hydra controller with Torque 3D. You may also want to check out the following related pages:
Setting Up Your Project for the Razer Hydra Controller
Before you can make use of the Razer Hydra controller in Torque 3D you will need to download the Sixense SDK from their [web site](http://sixense.com/developers) and extract it to a convenient directory.
Configure Your project.conf
With the Sixense SDK in place, you will need to modify your project's buildFiles/config/project.conf file in a text editor. The first step is to let Torque 3D's Project Generator know where the Sixense SDK is located. The easiest way to do this is to add the $RAZERHYDRA_SDK_PATH global variable to the top of your project.conf file. For example:
$RAZERHYDRA_SDK_PATH = "C:\Users\dwyand_2\Downloads\RazerHydra\SixenseSDK_062612";
You may also create a Windows environmental variable named TORQUE_RAZERHYDRA_PATH that also provides an absolute path to the Sixense SDK. Going this route doesn't store the path within the project.conf file, which may be required if multiple developers are working on the same project.
The second addition to your project.conf file is a reference to the Torque 3D's Project Generator module for the Razer Hydra. Add the following between the Torque3D::beginConfig() and Torque3D::endConfig() lines:
// Include Razer Hydra module
includeModule( 'razerHydra' );
With these changes in place you may run your project's generateProjects.bat file to rebuild the various Visual Studio files.
Example project.conf
Here is a complete example of a project.conf file with all of the required changes:
Required DLLs
Before you may run your freshly compiled game you will need to include the appropriate Sixense DLLs with your game's executable. These files are located in the SixenseSDK_062612/bin/win32 directory. Specifically you should copy the sixense.dll (the release library) and sixensed.dll (the debug library) into the same directory as your game's executable. It appears that the debug version of the Sixense DLL also requires DeviceDLL.dll that is located in the SixenseSDK_062612\samples\win32\sixense_simple3d directory. You should also copy this file to your game's executable directory.
When it comes time to release your game you only need to include the sixense.dll library.
Using the Razer Hydra Controller Input Events
The new Torque 3D Razer Hydra input device provides a number of input events that may be used with Torque 3D's action map system. There are a number of different ways to use the Razer Hydra input device, which are set up using global TorqueScript variables.
Action Map Device Type
When binding a TorqueScript function to a Razer Hydra input event using Torque 3D's action map system, the device name to use is {{razerhydra{{. As only one Razer Hydra may be used on a computer at a time, there is no need to append a device instance number to the end of the device name. The following is an example of setting up a proper action map binding:
Processing Input Events When Docked
The $RazerHydra::ProcessWhenDocked global TorqueScript variable determines if input events are generated by the Razer Hydra when a controller is docked. A controller is considered docked when it is placed in the Razer Hydra base station. When $RazerHydra::ProcessWhenDocked is false (the default) then no events will be generated by the controller. When this global variable is set to true then all input events will continue to be generated by a docked controller. Please note that a controller's position and rotation values may be warped when it is placed near or on the base station.
Standard Gamepad Input Events
The Razer Hydra provides a full compliment of gamepad buttons and sticks spread across two hand held controllers. Torque 3D provides complete access to all of these input events which behave as you would expect from a Xbox 360 compatible gamepad. The following action map input events are available:
Left Controller
- rh_thumbx0 - thumb stick x-axis motion in the range of -1.0 to 1.0
- rh_thumby0 - thumb stick y-axis motion in the range of -1.0 to 1.0
- rh_trigger0 - trigger motion (sometimes referred to as z-axis motion) in the range of 0.0 to 1.0
- rh_shoulder0 - shoulder (or bumper) button
- rh_thumb0 - thumb stick used as a button
- rh_start0 - start button
- rh_1button0 - 1 button
- rh_2button0 - 2 button
- rh_3button0 - 3 button
- rh_4button0 - 4 button
Right Controller
- rh_thumbx1 - thumb stick x-axis motion in the range of -1.0 to 1.0
- rh_thumby1 - thumb stick y-axis motion in the range of -1.0 to 1.0
- rh_trigger1 - trigger motion (sometimes referred to as z-axis motion) in the range of 0.0 to 1.0
- rh_shoulder1 - shoulder (or bumper) button
- rh_thumb1 - thumb stick used as a button
- rh_start1 - start button
- rh_1button1 - 1 button
- rh_2button1 - 2 button
- rh_3button1 - 3 button
- rh_4button1 - 4 button
As with a standard gamepad, each of the thumb stick motions (and even the trigger although it is not usually used this way) are of the *AXIS* type. This means that additional modifiers may be placed on their inputs, such as defining a dead zone. For example, here is how you could set up the right controller's thumb stick to be used to rotate the player with a slight dead zone around the stick's neutral position:
Controller Absolute Position and Rotation Events
The unique feature of the Razer Hydra is being able to detect each the left and right controller's absolute position and rotation in space. When it comes to generating position input events, there are two options available. The first option is to receive each x, y and z axis update as separate events given as rh_posx, rh_posy and rh_posz. You activate this option by setting the global TorqueScript variable $RazerHydra::SeparatePositionEvents to true, which is the default setting. This is similar to how a thumb stick generates separate events for both the x and y axis.
The second option is to receive only a single position event rh_pos that includes each axis as a separate parameter. You activate this mode by setting the global TorqueScript variable $RazerHydra::CombinedPositionEvents to true. The primary advantage of this mode is you generally produce much less input events for Torque 3D to process.
The following action map input events are available (all positions are in millimeters and all rotations are in angled axis format):
Left Controller
- rh_posx0 - absolute x axis position
- rh_posy0 - absolute y axis position
- rh_posz0 - absolute z axis position
- rh_pos0 - absolute position provided as 3 parameters
- rh_rot0 - absolute rotation
Right Controller
- rh_posx1 - absolute x axis position
- rh_posy1 - absolute y axis position
- rh_posz1 - absolute z axis position
- rh_pos1 - absolute position provided as 3 parameters
- rh_rot1 - absolute rotation
Using Position and Rotation Input Events
You bind Razer Hydra position and rotation events to an action map just like any other input event. Here is an example of making use of the position (the single event version) and rotation events generated by the right controller (place it in {{scripts/client/default.bind.cs{{):
Controller as Thumb Stick Input Events
Torque 3D allows a Razer Hydra controller to be used like a gamepad thumb stick. Imagine that a thumb stick is coming out of the top of the controller and you move it by tilting the controller.
To activate these thumb stick input events we set the $RazerHydra::RotationAsAxisEvents global TorqueScript variable to true. With that variable set the following action map input events are available:
Left Controller
- rh_rotaxisx0 - thumb stick like x-axis motion in the range of -1.0 to 1.0
- rh_rotaxisy0 - thumb stick like y-axis motion in the range of -1.0 to 1.0
Right Controller
- rh_rotaxisx1 - thumb stick like x-axis motion in the range of -1.0 to 1.0
- rh_rotaxisy1 - thumb stick like y-axis motion in the range of -1.0 to 1.0
Internally, these x and y axis values are normalized to ensure the length of their vector is never more than 1, just like a real thumb stick.
In order to calculate the -1.0 to 1.0 range, the tilt of the controller with respect to a vector pointing straight up (technically this vector is normal to the plane of the Razer Hydra's base unit) is used. When this controller to up vector angle reaches the $RazerHydra::MaximumAxisAngle global script variable value (the default is 25 degrees) then the virtual thumb stick is considered all the way over. Adjusting $RazerHydra::MaximumAxisAngle for your application determines how far over the user must tilt their controller for a 100% value.
Whole Frame Input Events
There may be a time when the provided Razer Hydra input events don't quite fit your needs. In these cases you may make use of the Razer Hydra whole frame input event that is available in Torque 3D. To activate this input event you set the $RazerHydra::GenerateWholeFrameEvents global TorqueScript variable to true. When active, you may then receive the rh_frame input event.
The rh_frame event is unique in that it provides a single value that is a SimObject ID to a RazerHydraFrame class instance. You may then use this ID to call the instance's methods and retrieve the frame's data.
Each RazerHydraFrame class instance is automatically stored within the RazerHydraFrameGroup SimGroup. A maximum number of RazerHydraFrame objects are kept at any time as determined by the $RazerHydra::MaximumFramesStored global TorqueScript variable (the default is 30). When a new RazerHydraFrame object is required, the oldest is removed from the RazerHydraFrameGroup and recycled.
The RazerHydraFrame instances are stored newest to oldest, with the newest at index 0 within the group. When you receive a rh_frame event you may safely assume that the frame ID given in the frame's parameter is the first frame in the RazerHydraFrameGroup. To manually retrieve the newest frame and the frame that came just before it (perhaps to perform a delta calculation between the two) you may use the following:
This may be done at any time that your application is running so long as you are collecting whole frames as set with the $RazerHydra::GenerateWholeFrameEvents global variable.
Using Whole Frame Input Events
You bind the Razer Hydra input events to an action map just like any other input event. Specifically, you tie the events to the razerhydra device with the action map bind() method. For example, the following TorqueScript code (placed in scripts/client/default.bind.cs) performs an action against each frame received by the input event:
The 'RazerHydraFrame' class has a large number of methods available for working with a frame's controller data. Please see the bottom of the source code file platform/input/razerHydra/razerHydraFrame.cpp for a complete list of the available methods.
Miscellaneous Input Events
The rh_docked0 and rh_docked1 (for left and right) input events are generated whenever a controller's docked status changes. A controller is docked when it is sitting in the Razer Hydra base station. This event can be useful for changing the application's state, such as pausing when nothing is being tracked by the Razer Hydra controller.
The rh_docked0 and rh_docked1 input events provides a single parameter that has a value of 1 when a controller is docked, and 0 when a controller has been picked up by the user. Here is an example of using this event:
We may also check a controller's docked status at any time with the following TorqueScript function:
where the *controller* parameter is or 1 for the left or right controller. This function returns true if the requested controller is currently docked. As the rh_docked0 and rh_docked1 input events are only generated when a controller's docked status changes, the isRazerHydraControllerDocked() function is useful when your application first starts up to detect a controller's current state.
Order of Input Events
The following is the order in which Razer Hydra input events may be received by the application:
For each controller, starting with the left one
- The rh_docked event. If a controller is docked and $RazerHydra::ProcessWhenDocked is set to false then the following controller events will be skipped.
- If $RazerHydra::SeparatePositionEvents is true then all individual controller position events.
- If $RazerHydra::CombinedPositionEvents is true then the combined controller position event.
- The controller's rotation event.
- All standard gamepad input events.
- If $RazerHydra::RotationAsAxisEvents is true then the controller as thumb stick input events, but only if these values have changed this frame compared to the previous frame. This is the same behavior as with gamepad thumb sticks. When a controller is docked one last input event of this type is sent out with a value of {{0.0{{. This returns the virtual thumb stick to a neutral position.
Following the controllers being processed
- If $RazerHydra::GenerateWholeFrameEvents is true then the rh_frame event.