Razer Hydra integration

This commit is contained in:
DavidWyand-GG 2013-02-12 15:49:37 -05:00
parent 965336d54d
commit 0b4c3f1e42
12 changed files with 2195 additions and 0 deletions

View file

@ -0,0 +1,35 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#ifndef _RAZERHYDRACONSTANTS_H_
#define _RAZERHYDRACONSTANTS_H_
namespace RazerHydraConstants
{
enum Constants {
DefaultHydraBase = 0,
HydraActiveCheckFreq = 1000,
MaxControllers = 2,
};
}
#endif // _RAZERHYDRACONSTANTS_H_

View file

@ -0,0 +1,192 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#include "platform/input/razerHydra/razerHydraData.h"
#include "platform/input/razerHydra/razerHydraUtil.h"
RazerHyrdaControllerData::RazerHyrdaControllerData()
{
reset();
}
void RazerHyrdaControllerData::reset()
{
mDataSet = false;
mShoulder = false;
mThumb = false;
mStart = false;
mButton1 = false;
mButton2 = false;
mButton3 = false;
mButton4 = false;
mIsDocked = false;
}
void RazerHyrdaControllerData::setData(const sixenseControllerData& data, const F32& maxAxisRadius)
{
// Controller position
RazerHydraUtil::convertPosition(data.pos, mRawPos[0], mRawPos[1], mRawPos[2]);
mPos[0] = (S32)mFloor(mRawPos[0]);
mPos[1] = (S32)mFloor(mRawPos[1]);
mPos[2] = (S32)mFloor(mRawPos[2]);
mPosPoint.set(mPos[0], mPos[1], mPos[2]);
// Controller rotation
RazerHydraUtil::convertRotation(data.rot_mat, mRot);
mRotQuat.set(mRot);
// Controller rotation as axis, but only if not docked
if(!data.is_docked)
{
RazerHydraUtil::calculateAxisRotation(mRot, maxAxisRadius, mRotAxis);
}
else
{
mRotAxis.x = 0.0f;
mRotAxis.y = 0.0f;
}
// Thumb stick
mThumbStick[0] = data.joystick_x;
mThumbStick[1] = data.joystick_y;
// Trigger
mTrigger = data.trigger;
//Buttons
mShoulder = data.buttons & SIXENSE_BUTTON_BUMPER;
mThumb = data.buttons & SIXENSE_BUTTON_JOYSTICK;
mStart = data.buttons & SIXENSE_BUTTON_START;
mButton1 = data.buttons & SIXENSE_BUTTON_1;
mButton2 = data.buttons & SIXENSE_BUTTON_2;
mButton3 = data.buttons & SIXENSE_BUTTON_3;
mButton4 = data.buttons & SIXENSE_BUTTON_4;
// Other data
mIsDocked = data.is_docked;
// Store the current sequence number
mSequenceNum = data.sequence_number;
mDataSet = true;
}
U32 RazerHyrdaControllerData::compare(RazerHyrdaControllerData* other)
{
S32 result = DIFF_NONE;
// Check position
if(mDataSet)
{
if(mPos[0] != other->mPos[0])
result |= DIFF_POSX;
if(mPos[1] != other->mPos[1])
result |= DIFF_POSY;
if(mPos[2] != other->mPos[2])
result |= DIFF_POSZ;
}
else
{
result |= DIFF_POS;
}
// Check rotation
if(mRotQuat != other->mRotQuat || !mDataSet)
{
result |= DIFF_ROT;
}
// Check rotation as axis
if(mRotAxis.x != other->mRotAxis.x || !mDataSet)
{
result |= DIFF_ROTAXISX;
}
if(mRotAxis.y != other->mRotAxis.y || !mDataSet)
{
result |= DIFF_ROTAXISY;
}
// Check thumb stick
if(mThumbStick[0] != other->mThumbStick[0] || !mDataSet)
{
result |= DIFF_AXISX;
}
if(mThumbStick[1] != other->mThumbStick[1] || !mDataSet)
{
result |= DIFF_AXISY;
}
// Check trigger
if(mTrigger != other->mTrigger || !mDataSet)
{
result |= DIFF_TRIGGER;
}
// Check buttons
if(mShoulder != other->mShoulder)
{
result |= DIFF_BUTTON_SHOULDER;
}
if(mThumb != other->mThumb)
{
result |= DIFF_BUTTON_THUMB;
}
if(mStart != other->mStart)
{
result |= DIFF_BUTTON_START;
}
if(mButton1 != other->mButton1)
{
result |= DIFF_BUTTON1;
}
if(mButton2 != other->mButton2)
{
result |= DIFF_BUTTON2;
}
if(mButton3 != other->mButton3)
{
result |= DIFF_BUTTON3;
}
if(mButton4 != other->mButton4)
{
result |= DIFF_BUTTON4;
}
return result;
}
U32 RazerHyrdaControllerData::compareMeta(RazerHyrdaControllerData* other)
{
S32 result = DIFF_NONE;
if(mIsDocked != other->mIsDocked || !mDataSet)
{
result |= METADIFF_DOCKED;
}
return result;
}

View file

@ -0,0 +1,111 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#ifndef _RAZERHYDRADATA_H_
#define _RAZERHYDRADATA_H_
#include "console/consoleTypes.h"
#include "math/mMathFn.h"
#include "math/mMatrix.h"
#include "math/mQuat.h"
#include "sixense.h"
struct RazerHyrdaControllerData
{
enum DataDifferences {
DIFF_NONE = 0,
DIFF_POSX = (1<<0),
DIFF_POSY = (1<<1),
DIFF_POSZ = (1<<2),
DIFF_ROT = (1<<3),
DIFF_ROTAXISX = (1<<4),
DIFF_ROTAXISY = (1<<5),
DIFF_AXISX = (1<<6),
DIFF_AXISY = (1<<7),
DIFF_TRIGGER = (1<<8),
DIFF_BUTTON1 = (1<<9),
DIFF_BUTTON2 = (1<<10),
DIFF_BUTTON3 = (1<<11),
DIFF_BUTTON4 = (1<<12),
DIFF_BUTTON_START = (1<<13),
DIFF_BUTTON_SHOULDER = (1<<14),
DIFF_BUTTON_THUMB = (1<<15),
DIFF_POS = (DIFF_POSX | DIFF_POSY | DIFF_POSZ),
DIFF_AXIS = (DIFF_AXISX | DIFF_AXISY),
DIFF_ROTAXIS = (DIFF_ROTAXISX | DIFF_ROTAXISY),
};
enum MetaDataDifferences {
METADIFF_NONE = 0,
METADIFF_DOCKED = (1<<0),
};
bool mDataSet;
// Position
F32 mRawPos[3];
S32 mPos[3];
Point3F mPosPoint;
// Rotation
MatrixF mRot;
QuatF mRotQuat;
// Controller rotation as axis x, y
Point2F mRotAxis;
// Thumb stick x, y and trigger
F32 mThumbStick[2];
F32 mTrigger;
// Buttons
bool mShoulder;
bool mThumb;
bool mStart;
bool mButton1;
bool mButton2;
bool mButton3;
bool mButton4;
// Other data
bool mIsDocked;
// Sequence number from sixense
U32 mSequenceNum;
RazerHyrdaControllerData();
/// Reset controller data
void reset();
/// Set position based on sixense controller data
void setData(const sixenseControllerData& data, const F32& maxAxisRadius);
/// Compare this data and given and return differences
U32 compare(RazerHyrdaControllerData* other);
/// Compare meta data between this and given and return differences
U32 compareMeta(RazerHyrdaControllerData* other);
};
#endif // _RAZERHYDRADATA_H_

View file

@ -0,0 +1,701 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#include "platform/input/razerHydra/razerHydraDevice.h"
#include "platform/input/razerHydra/razerHydraData.h"
#include "platform/input/razerHydra/razerHydraConstants.h"
#include "platform/input/razerHydra/razerHydraFrameStore.h"
#include "platform/platformInput.h"
#include "core/module.h"
#include "console/engineAPI.h"
#include "math/mAngAxis.h"
#include "math/mTransform.h"
MODULE_BEGIN( RazerHydraDevice )
MODULE_INIT_AFTER( InputEventManager )
MODULE_SHUTDOWN_BEFORE( InputEventManager )
MODULE_INIT
{
RazerHydraDevice::staticInit();
ManagedSingleton< RazerHydraDevice >::createSingleton();
if(RazerHydraDevice::smEnableDevice)
{
RAZERHYDRADEV->enable();
}
// Register the device with the Input Event Manager
INPUTMGR->registerDevice(RAZERHYDRADEV);
}
MODULE_SHUTDOWN
{
INPUTMGR->unregisterDevice(RAZERHYDRADEV);
ManagedSingleton< RazerHydraDevice >::deleteSingleton();
}
MODULE_END;
bool RazerHydraDevice::smEnableDevice = true;
bool RazerHydraDevice::smProcessWhenDocked = false;
bool RazerHydraDevice::smSeparatePositionEvents = true;
bool RazerHydraDevice::smCombinedPositionEvents = false;
bool RazerHydraDevice::smRotationAsAxisEvents = false;
F32 RazerHydraDevice::smMaximumAxisAngle = 25.0;
bool RazerHydraDevice::smGenerateWholeFrameEvents = false;
U32 RazerHydraDevice::RH_DOCKED[RazerHydraConstants::MaxControllers] = {0};
U32 RazerHydraDevice::RH_POSX[RazerHydraConstants::MaxControllers] = {0};
U32 RazerHydraDevice::RH_POSY[RazerHydraConstants::MaxControllers] = {0};
U32 RazerHydraDevice::RH_POSZ[RazerHydraConstants::MaxControllers] = {0};
U32 RazerHydraDevice::RH_POS[RazerHydraConstants::MaxControllers] = {0};
U32 RazerHydraDevice::RH_ROT[RazerHydraConstants::MaxControllers] = {0};
U32 RazerHydraDevice::RH_ROTAXISX[RazerHydraConstants::MaxControllers] = {0};
U32 RazerHydraDevice::RH_ROTAXISY[RazerHydraConstants::MaxControllers] = {0};
U32 RazerHydraDevice::RH_THUMBX[RazerHydraConstants::MaxControllers] = {0};
U32 RazerHydraDevice::RH_THUMBY[RazerHydraConstants::MaxControllers] = {0};
U32 RazerHydraDevice::RH_TRIGGER[RazerHydraConstants::MaxControllers] = {0};
U32 RazerHydraDevice::RH_SHOULDER[RazerHydraConstants::MaxControllers] = {0};
U32 RazerHydraDevice::RH_THUMB[RazerHydraConstants::MaxControllers] = {0};
U32 RazerHydraDevice::RH_START[RazerHydraConstants::MaxControllers] = {0};
U32 RazerHydraDevice::RH_1[RazerHydraConstants::MaxControllers] = {0};
U32 RazerHydraDevice::RH_2[RazerHydraConstants::MaxControllers] = {0};
U32 RazerHydraDevice::RH_3[RazerHydraConstants::MaxControllers] = {0};
U32 RazerHydraDevice::RH_4[RazerHydraConstants::MaxControllers] = {0};
U32 RazerHydraDevice::RH_FRAME = 0;
RazerHydraDevice::RazerHydraDevice()
{
// From IInputDevice
dStrcpy(mName, "razerhydra");
mDeviceType = INPUTMGR->getNextDeviceType();
//
mRazerHydraLib = NULL;
mEnabled = false;
mActive = false;
mNumberActiveControllers = 0;
mLastActiveCheck = 0;
for(U32 i=0; i<RazerHydraConstants::MaxControllers; ++i)
{
for(U32 j=0; j<2; ++j)
{
mDataBuffer[i][j] = new RazerHyrdaControllerData();
}
mPrevData[i] = mDataBuffer[i][0];
}
buildCodeTable();
}
RazerHydraDevice::~RazerHydraDevice()
{
mRazerHydraLib = NULL;
// Delete the controller data buffers
for(U32 i=0; i<RazerHydraConstants::MaxControllers; ++i)
{
for(U32 j=0; j<2; ++j)
{
delete mDataBuffer[i][j];
mDataBuffer[i][j] = NULL;
mPrevData[i] = NULL;
}
}
}
void RazerHydraDevice::staticInit()
{
Con::addVariable("pref::RazerHydra::EnableDevice", TypeBool, &smEnableDevice,
"@brief If true, the Razer Hydra device will be enabled, if present.\n\n"
"@ingroup Game");
Con::addVariable("RazerHydra::ProcessWhenDocked", TypeBool, &smProcessWhenDocked,
"@brief If true, events will still be sent when a controller is docked.\n\n"
"@ingroup Game");
Con::addVariable("RazerHydra::SeparatePositionEvents", TypeBool, &smSeparatePositionEvents,
"@brief If true, separate position events will be sent for each component.\n\n"
"@ingroup Game");
Con::addVariable("RazerHydra::CombinedPositionEvents", TypeBool, &smCombinedPositionEvents,
"@brief If true, one position event will be sent that includes one component per argument.\n\n"
"@ingroup Game");
Con::addVariable("RazerHydra::RotationAsAxisEvents", TypeBool, &smRotationAsAxisEvents,
"@brief If true, broadcast controller rotation as axis events.\n\n"
"@ingroup Game");
Con::addVariable("RazerHydra::MaximumAxisAngle", TypeF32, &smMaximumAxisAngle,
"@brief The maximum controller angle when used as an axis event as measured from a vector pointing straight up (in degrees).\n\n"
"Shoud range from 0 to 90 degrees.\n\n"
"@ingroup Game");
Con::addVariable("RazerHydra::GenerateWholeFrameEvents", TypeBool, &smGenerateWholeFrameEvents,
"@brief Indicates that a whole frame event should be generated and frames should be buffered.\n\n"
"@ingroup Game");
}
void RazerHydraDevice::buildCodeTable()
{
// Obtain all of the device codes
for(U32 i=0; i<RazerHydraConstants::MaxControllers; ++i)
{
RH_DOCKED[i] = INPUTMGR->getNextDeviceCode();
RH_POSX[i] = INPUTMGR->getNextDeviceCode();
RH_POSY[i] = INPUTMGR->getNextDeviceCode();
RH_POSZ[i] = INPUTMGR->getNextDeviceCode();
RH_POS[i] = INPUTMGR->getNextDeviceCode();
RH_ROT[i] = INPUTMGR->getNextDeviceCode();
RH_ROTAXISX[i] = INPUTMGR->getNextDeviceCode();
RH_ROTAXISY[i] = INPUTMGR->getNextDeviceCode();
RH_THUMBX[i] = INPUTMGR->getNextDeviceCode();
RH_THUMBY[i] = INPUTMGR->getNextDeviceCode();
RH_TRIGGER[i] = INPUTMGR->getNextDeviceCode();
RH_SHOULDER[i] = INPUTMGR->getNextDeviceCode();
RH_THUMB[i] = INPUTMGR->getNextDeviceCode();
RH_START[i] = INPUTMGR->getNextDeviceCode();
RH_1[i] = INPUTMGR->getNextDeviceCode();
RH_2[i] = INPUTMGR->getNextDeviceCode();
RH_3[i] = INPUTMGR->getNextDeviceCode();
RH_4[i] = INPUTMGR->getNextDeviceCode();
}
RH_FRAME = INPUTMGR->getNextDeviceCode();
// Build out the virtual map
char buffer[64];
for(U32 i=0; i<RazerHydraConstants::MaxControllers; ++i)
{
dSprintf(buffer, 64, "rh_docked%d", i);
INPUTMGR->addVirtualMap( buffer, SI_BUTTON, RH_DOCKED[i] );
dSprintf(buffer, 64, "rh_posx%d", i);
INPUTMGR->addVirtualMap( buffer, SI_FLOAT, RH_POSX[i] );
dSprintf(buffer, 64, "rh_posy%d", i);
INPUTMGR->addVirtualMap( buffer, SI_FLOAT, RH_POSY[i] );
dSprintf(buffer, 64, "rh_posz%d", i);
INPUTMGR->addVirtualMap( buffer, SI_FLOAT, RH_POSZ[i] );
dSprintf(buffer, 64, "rh_pos%d", i);
INPUTMGR->addVirtualMap( buffer, SI_POS, RH_POS[i] );
dSprintf(buffer, 64, "rh_rot%d", i);
INPUTMGR->addVirtualMap( buffer, SI_ROT, RH_ROT[i] );
dSprintf(buffer, 64, "rh_rotaxisx%d", i);
INPUTMGR->addVirtualMap( buffer, SI_AXIS, RH_ROTAXISX[i] );
dSprintf(buffer, 64, "rh_rotaxisy%d", i);
INPUTMGR->addVirtualMap( buffer, SI_AXIS, RH_ROTAXISY[i] );
dSprintf(buffer, 64, "rh_thumbx%d", i);
INPUTMGR->addVirtualMap( buffer, SI_AXIS, RH_THUMBX[i] );
dSprintf(buffer, 64, "rh_thumby%d", i);
INPUTMGR->addVirtualMap( buffer, SI_AXIS, RH_THUMBY[i] );
dSprintf(buffer, 64, "rh_trigger%d", i);
INPUTMGR->addVirtualMap( buffer, SI_AXIS, RH_TRIGGER[i] );
dSprintf(buffer, 64, "rh_shoulder%d", i);
INPUTMGR->addVirtualMap( buffer, SI_BUTTON, RH_SHOULDER[i] );
dSprintf(buffer, 64, "rh_thumb%d", i);
INPUTMGR->addVirtualMap( buffer, SI_BUTTON, RH_THUMB[i] );
dSprintf(buffer, 64, "rh_start%d", i);
INPUTMGR->addVirtualMap( buffer, SI_BUTTON, RH_START[i] );
dSprintf(buffer, 64, "rh_1button%d", i);
INPUTMGR->addVirtualMap( buffer, SI_BUTTON, RH_1[i] );
dSprintf(buffer, 64, "rh_2button%d", i);
INPUTMGR->addVirtualMap( buffer, SI_BUTTON, RH_2[i] );
dSprintf(buffer, 64, "rh_3button%d", i);
INPUTMGR->addVirtualMap( buffer, SI_BUTTON, RH_3[i] );
dSprintf(buffer, 64, "rh_4button%d", i);
INPUTMGR->addVirtualMap( buffer, SI_BUTTON, RH_4[i] );
}
AddInputVirtualMap( rh_frame, SI_INT, RH_FRAME );
}
bool RazerHydraDevice::enable()
{
// Start off with disabling the device if it is already enabled
disable();
// Dynamically load the Razer Hydra library and set up function pointers
#ifdef LOG_INPUT
Input::log( "Enabling Razer Hydra...\n" );
#endif
const char* dllName;
#ifdef TORQUE_OS_WIN32
#ifdef TORQUE_DEBUG
dllName = "sixensed.dll";
#else
dllName = "sixense.dll";
#endif
#else
#ifdef LOG_INPUT
Input::log( "...platform not supported for Razer Hydra\n" );
#endif
return;
#endif
mRazerHydraLib = OsLoadLibrary( dllName );
if(mRazerHydraLib)
{
#ifdef LOG_INPUT
Input::log( "Razer Hydra library loaded.\n" );
#endif
Con::printf("Razer Hydra Init:");
// Obtain library function pointers
mfnSixenseInit = (FN_SixenseInit) mRazerHydraLib->bind( "sixenseInit" );
mfnSixenseExit = (FN_SixenseExit) mRazerHydraLib->bind( "sixenseExit" );
mfnSixenseGetMaxBases = (FN_SixenseGetMaxBases) mRazerHydraLib->bind( "sixenseGetMaxBases" );
mfnSixenseSetActiveBase = (FN_SixenseSetActiveBase) mRazerHydraLib->bind( "sixenseSetActiveBase" );
mfnSixenseIsBaseConnected = (FN_SixenseIsBaseConnected) mRazerHydraLib->bind( "sixenseIsBaseConnected" );
mfnSixenseGetMaxControllers = (FN_SixenseGetMaxControllers) mRazerHydraLib->bind( "sixenseGetMaxControllers" );
mfnSixenseIsControllerEnabled = (FN_SixenseIsControllerEnabled) mRazerHydraLib->bind( "sixenseIsControllerEnabled" );
mfnSixenseGetNumActiveControllers = (FN_SixenseGetNumActiveControllers) mRazerHydraLib->bind( "sixenseGetNumActiveControllers" );
mfnSixenseGetHistorySize = (FN_SixenseGetHistorySize) mRazerHydraLib->bind( "sixenseGetHistorySize" );
mfnSixenseGetData = (FN_SixenseGetData) mRazerHydraLib->bind( "sixenseGetData" );
mfnSixenseGetAllData = (FN_SixenseGetAllData) mRazerHydraLib->bind( "sixenseGetAllData" );
mfnSixenseGetNewestData = (FN_SixenseGetNewestData) mRazerHydraLib->bind( "sixenseGetNewestData" );
mfnSixenseGetAllNewestData = (FN_SixenseGetAllNewestData) mRazerHydraLib->bind( "sixenseGetAllNewestData" );
mfnSixenseSetHemisphereTrackingMode = (FN_SixenseSetHemisphereTrackingMode) mRazerHydraLib->bind( "sixenseSetHemisphereTrackingMode" );
mfnSixenseGetHemisphereTrackingMode = (FN_SixenseGetHemisphereTrackingMode) mRazerHydraLib->bind( "sixenseGetHemisphereTrackingMode" );
mfnSixenseAutoEnableHemisphereTracking = (FN_SixenseAutoEnableHemisphereTracking) mRazerHydraLib->bind( "sixenseAutoEnableHemisphereTracking" );
mfnSixenseSetHighPriorityBindingEnabled = (FN_SixenseSetHighPriorityBindingEnabled) mRazerHydraLib->bind( "sixenseSetHighPriorityBindingEnabled" );
mfnSixenseGetHighPriorityBindingEnabled = (FN_SixenseGetHighPriorityBindingEnabled) mRazerHydraLib->bind( "sixenseGetHighPriorityBindingEnabled" );
mfnSixenseTriggerVibration = (FN_SixenseTriggerVibration) mRazerHydraLib->bind( "sixenseTriggerVibration" );
mfnSixenseSetFilterEnabled = (FN_SixenseSetFilterEnabled) mRazerHydraLib->bind( "sixenseSetFilterEnabled" );
mfnSixenseGetFilterEnabled = (FN_SixenseGetFilterEnabled) mRazerHydraLib->bind( "sixenseGetFilterEnabled" );
mfnSixenseSetFilterParams = (FN_SixenseSetFilterParams) mRazerHydraLib->bind( "sixenseSetFilterParams" );
mfnSixenseGetFilterParams = (FN_SixenseGetFilterParams) mRazerHydraLib->bind( "sixenseGetFilterParams" );
mfnSixenseSetBaseColor = (FN_SixenseSetBaseColor) mRazerHydraLib->bind( "sixenseSetBaseColor" );
mfnSixenseGetBaseColor = (FN_SixenseGetBaseColor) mRazerHydraLib->bind( "sixenseGetBaseColor" );
// Init the sixense library
S32 result = mfnSixenseInit();
if(result == SIXENSE_FAILURE)
{
// Problem with starting the library
Con::printf(" Sixense library startup failure");
mRazerHydraLib = NULL;
mEnabled = false;
mActive = false;
return false;
}
// Retrieve some information about the Hydra
mMaximumBases = mfnSixenseGetMaxBases();
Con::printf(" Max bases: %d", mMaximumBases);
mMaximumControllers = mfnSixenseGetMaxControllers();
Con::printf(" Max controllers: %d", mMaximumControllers);
mEnabled = true;
if(checkControllers())
{
Con::printf(" Active controllers: %d", mNumberActiveControllers);
mActive = true;
}
else
{
Con::printf(" Controllers not yet found. Starting to poll.");
mLastActiveCheck = Platform::getRealMilliseconds();
mActive = false;
}
Con::printf("");
return true;
}
else
{
#ifdef LOG_INPUT
Input::log( "Razer Hydra library was not found.\n" );
#endif
Con::errorf("Razer Hydra library was not found.");
mEnabled = false;
mActive = false;
}
return false;
}
void RazerHydraDevice::disable()
{
if(mRazerHydraLib)
{
// Shutdown the sixense library
mfnSixenseExit();
mRazerHydraLib = NULL;
}
mEnabled = false;
}
bool RazerHydraDevice::process()
{
if(!mEnabled)
return false;
//Con::printf("RazerHydraDevice::process()");
if(!mActive)
{
// Only perform a check on a periodic basis
S32 time = Platform::getRealMilliseconds();
if((time - mLastActiveCheck) < RazerHydraConstants::HydraActiveCheckFreq)
return false;
mLastActiveCheck = time;
if(checkControllers())
{
Con::printf("Razer Hydra now has %d active controllers", mNumberActiveControllers);
mActive = true;
}
else
{
return false;
}
}
else if(!checkControllers())
{
// We no longer have active controllers
Con::printf("Razer Hydra now has NO active controllers");
mLastActiveCheck = Platform::getRealMilliseconds();
mActive = false;
return false;
}
//Build the maximum axis angle to be passed into the RazerHyrdaControllerData::setData()
F32 maxAxisRadius = mSin(mDegToRad(smMaximumAxisAngle));
// Get the controller data
mfnSixenseSetActiveBase(RazerHydraConstants::DefaultHydraBase);
sixenseAllControllerData acd;
mfnSixenseGetAllNewestData(&acd);
// Store the current data from each controller and compare with previous data
U32 diff[RazerHydraConstants::MaxControllers];
U32 metaDiff[RazerHydraConstants::MaxControllers];
RazerHyrdaControllerData* currentBuffer[RazerHydraConstants::MaxControllers];
for(U32 i=0; i<RazerHydraConstants::MaxControllers; ++i)
{
currentBuffer[i] = (mPrevData[i] == mDataBuffer[i][0]) ? mDataBuffer[i][1] : mDataBuffer[i][0];
currentBuffer[i]->setData(acd.controllers[i], maxAxisRadius);
diff[i] = mPrevData[i]->compare(currentBuffer[i]);
metaDiff[i] = mPrevData[i]->compareMeta(currentBuffer[i]);
}
// Update the previous data pointers. We do this here in case someone calls our
// console functions during one of the input events below.
mPrevData[0] = currentBuffer[0];
mPrevData[1] = currentBuffer[1];
// Process each controller's meta data.
for(U32 i=0; i<RazerHydraConstants::MaxControllers; ++i)
{
// Docked
if(metaDiff[i] != RazerHyrdaControllerData::METADIFF_NONE)
{
INPUTMGR->buildInputEvent(mDeviceType, RazerHydraConstants::DefaultHydraBase, SI_BUTTON, RH_DOCKED[i], currentBuffer[i]->mIsDocked ? SI_MAKE : SI_BREAK, currentBuffer[i]->mIsDocked ? 1.0f : 0.0f);
}
// Position, rotation and buttons
if(diff[i] != RazerHyrdaControllerData::DIFF_NONE && (!currentBuffer[i]->mIsDocked || smProcessWhenDocked && currentBuffer[i]->mIsDocked))
{
// Position
if(smSeparatePositionEvents)
{
if(diff[i] & RazerHyrdaControllerData::DIFF_POSX)
INPUTMGR->buildInputEvent(mDeviceType, RazerHydraConstants::DefaultHydraBase, SI_FLOAT, RH_POSX[i], SI_MOVE, currentBuffer[i]->mPos[0]);
if(diff[i] & RazerHyrdaControllerData::DIFF_POSY)
INPUTMGR->buildInputEvent(mDeviceType, RazerHydraConstants::DefaultHydraBase, SI_FLOAT, RH_POSY[i], SI_MOVE, currentBuffer[i]->mPos[1]);
if(diff[i] & RazerHyrdaControllerData::DIFF_POSZ)
INPUTMGR->buildInputEvent(mDeviceType, RazerHydraConstants::DefaultHydraBase, SI_FLOAT, RH_POSZ[i], SI_MOVE, currentBuffer[i]->mPos[2]);
}
if(smCombinedPositionEvents)
{
if(diff[i] & RazerHyrdaControllerData::DIFF_POSX || diff[i] & RazerHyrdaControllerData::DIFF_POSY || diff[i] & RazerHyrdaControllerData::DIFF_POSZ)
{
INPUTMGR->buildInputEvent(mDeviceType, RazerHydraConstants::DefaultHydraBase, SI_POS, RH_POS[i], SI_MOVE, currentBuffer[i]->mPosPoint);
}
}
// Rotation
if(diff[i] & RazerHyrdaControllerData::DIFF_ROT)
INPUTMGR->buildInputEvent(mDeviceType, RazerHydraConstants::DefaultHydraBase, SI_ROT, RH_ROT[i], SI_MOVE, currentBuffer[i]->mRotQuat);
// Thumb stick
if(diff[i] & RazerHyrdaControllerData::DIFF_AXISX)
INPUTMGR->buildInputEvent(mDeviceType, RazerHydraConstants::DefaultHydraBase, SI_AXIS, RH_THUMBX[i], SI_MOVE, currentBuffer[i]->mThumbStick[0]);
if(diff[i] & RazerHyrdaControllerData::DIFF_AXISY)
INPUTMGR->buildInputEvent(mDeviceType, RazerHydraConstants::DefaultHydraBase, SI_AXIS, RH_THUMBY[i], SI_MOVE, currentBuffer[i]->mThumbStick[1]);
// Trigger
if(diff[i] & RazerHyrdaControllerData::DIFF_TRIGGER)
INPUTMGR->buildInputEvent(mDeviceType, RazerHydraConstants::DefaultHydraBase, SI_AXIS, RH_TRIGGER[i], SI_MOVE, currentBuffer[i]->mTrigger);
// Shoulder button
if(diff[i] & RazerHyrdaControllerData::DIFF_BUTTON_SHOULDER)
INPUTMGR->buildInputEvent(mDeviceType, RazerHydraConstants::DefaultHydraBase, SI_BUTTON, RH_SHOULDER[i], currentBuffer[i]->mShoulder ? SI_MAKE : SI_BREAK, currentBuffer[i]->mShoulder ? 1.0f : 0.0f);
// Thumb button
if(diff[i] & RazerHyrdaControllerData::DIFF_BUTTON_THUMB)
INPUTMGR->buildInputEvent(mDeviceType, RazerHydraConstants::DefaultHydraBase, SI_BUTTON, RH_THUMB[i], currentBuffer[i]->mThumb ? SI_MAKE : SI_BREAK, currentBuffer[i]->mThumb ? 1.0f : 0.0f);
// Start button
if(diff[i] & RazerHyrdaControllerData::DIFF_BUTTON_START)
INPUTMGR->buildInputEvent(mDeviceType, RazerHydraConstants::DefaultHydraBase, SI_BUTTON, RH_START[i], currentBuffer[i]->mStart ? SI_MAKE : SI_BREAK, currentBuffer[i]->mStart ? 1.0f : 0.0f);
// Button 1
if(diff[i] & RazerHyrdaControllerData::DIFF_BUTTON1)
INPUTMGR->buildInputEvent(mDeviceType, RazerHydraConstants::DefaultHydraBase, SI_BUTTON, RH_1[i], currentBuffer[i]->mButton1 ? SI_MAKE : SI_BREAK, currentBuffer[i]->mButton1 ? 1.0f : 0.0f);
// Button 2
if(diff[i] & RazerHyrdaControllerData::DIFF_BUTTON2)
INPUTMGR->buildInputEvent(mDeviceType, RazerHydraConstants::DefaultHydraBase, SI_BUTTON, RH_2[i], currentBuffer[i]->mButton2 ? SI_MAKE : SI_BREAK, currentBuffer[i]->mButton2 ? 1.0f : 0.0f);
// Button 3
if(diff[i] & RazerHyrdaControllerData::DIFF_BUTTON3)
INPUTMGR->buildInputEvent(mDeviceType, RazerHydraConstants::DefaultHydraBase, SI_BUTTON, RH_3[i], currentBuffer[i]->mButton3 ? SI_MAKE : SI_BREAK, currentBuffer[i]->mButton3 ? 1.0f : 0.0f);
// Button 4
if(diff[i] & RazerHyrdaControllerData::DIFF_BUTTON4)
INPUTMGR->buildInputEvent(mDeviceType, RazerHydraConstants::DefaultHydraBase, SI_BUTTON, RH_4[i], currentBuffer[i]->mButton4 ? SI_MAKE : SI_BREAK, currentBuffer[i]->mButton4 ? 1.0f : 0.0f);
}
// Left rotation as axis. Done here as we still need to send events even when docked.
if(smRotationAsAxisEvents && diff[i] & RazerHyrdaControllerData::DIFF_ROTAXIS)
{
if(diff[i] & RazerHyrdaControllerData::DIFF_ROTAXISX)
INPUTMGR->buildInputEvent(mDeviceType, RazerHydraConstants::DefaultHydraBase, SI_AXIS, RH_ROTAXISX[i], SI_MOVE, currentBuffer[i]->mRotAxis.x);
if(diff[i] & RazerHyrdaControllerData::DIFF_ROTAXISY)
INPUTMGR->buildInputEvent(mDeviceType, RazerHydraConstants::DefaultHydraBase, SI_AXIS, RH_ROTAXISY[i], SI_MOVE, currentBuffer[i]->mRotAxis.y);
}
}
// Send out whole frame event, but only if the special frame group is defined
if(smGenerateWholeFrameEvents && RazerHydraFrameStore::isFrameGroupDefined())
{
S32 id = RAZERHYDRAFS->generateNewFrame(acd, maxAxisRadius);
if(id != 0)
{
INPUTMGR->buildInputEvent(mDeviceType, RazerHydraConstants::DefaultHydraBase, SI_INT, RH_FRAME, SI_VALUE, id);
}
}
return true;
}
bool RazerHydraDevice::checkControllers()
{
if(!mEnabled)
return false;
bool hasBase = (mfnSixenseIsBaseConnected(RazerHydraConstants::DefaultHydraBase) == 1);
if(!hasBase)
{
mNumberActiveControllers = 0;
return false;
}
mfnSixenseSetActiveBase(RazerHydraConstants::DefaultHydraBase);
mNumberActiveControllers = mfnSixenseGetNumActiveControllers();
if(mNumberActiveControllers < 1)
return false;
return true;
}
bool RazerHydraDevice::isControllerDocked(U32 controller)
{
if(!mEnabled || !mActive)
return true;
if(controller >= RazerHydraConstants::MaxControllers)
return true;
// Results are based on the last retrieved data from the device
return mPrevData[controller]->mIsDocked || !mPrevData[controller]->mDataSet;
}
const Point3F& RazerHydraDevice::getControllerPosition(U32 controller)
{
if(!mEnabled || !mActive)
return Point3F::Zero;
if(controller >= RazerHydraConstants::MaxControllers)
return Point3F::Zero;
// Results are based on the last retrieved data from the device
return mPrevData[controller]->mPosPoint;
}
const QuatF& RazerHydraDevice::getControllerRotation(U32 controller)
{
if(!mEnabled || !mActive)
return QuatF::Identity;
if(controller >= RazerHydraConstants::MaxControllers)
return QuatF::Identity;
// Results are based on the last retrieved data from the device
return mPrevData[controller]->mRotQuat;
}
//-----------------------------------------------------------------------------
DefineEngineFunction(isRazerHydraActive, bool, (),,
"@brief Used to determine if the Razer Hydra input device active\n\n"
"The Razer Hydra input device is considered active when the support library has been "
"loaded and the controller has been found.\n\n"
"@return True if the Razer Hydra input device is active.\n"
"@ingroup Game")
{
if(!ManagedSingleton<RazerHydraDevice>::instanceOrNull())
{
return false;
}
return RAZERHYDRADEV->isActive();
}
DefineEngineFunction(isRazerHydraControllerDocked, bool, (S32 controller),,
"@brief Used to determine if the given Razer Hydra controller is docked\n\n"
"@param controller Controller number to check.\n"
"@return True if the given Razer Hydra controller is docked. Also returns true if "
"the input device is not found or active.\n"
"@ingroup Game")
{
if(!ManagedSingleton<RazerHydraDevice>::instanceOrNull())
{
return true;
}
return RAZERHYDRADEV->isControllerDocked(controller);
}
DefineEngineFunction(getRazerHydraControllerPos, Point3F, (S32 controller),,
"@brief Get the given Razer Hydra controller's last position\n\n"
"@param controller Controller number to check.\n"
"@return A Point3F containing the last known position.\n"
"@ingroup Game")
{
if(!ManagedSingleton<RazerHydraDevice>::instanceOrNull())
{
return Point3F::Zero;
}
return RAZERHYDRADEV->getControllerPosition(controller);
}
DefineEngineFunction(getRazerHydraControllerRot, AngAxisF, (S32 controller),,
"@brief Get the given Razer Hydra controller's last rotation\n\n"
"@param controller Controller number to check.\n"
"@return A AngAxisF containing the last known rotation.\n"
"@ingroup Game")
{
AngAxisF aa(Point3F(0, 0, 1), 0);
if(!ManagedSingleton<RazerHydraDevice>::instanceOrNull())
{
return aa;
}
const QuatF& qa = RAZERHYDRADEV->getControllerRotation(controller);
aa.set(qa);
aa.axis.normalize();
return aa;
}
DefineEngineFunction(getRazerHydraControllerTransform, TransformF, (S32 controller),,
"@brief Get the given Razer Hydra controller's last transform\n\n"
"@param controller Controller number to check.\n"
"@return A TransformF containing the last known transform.\n"
"@ingroup Game")
{
TransformF trans;
if(!ManagedSingleton<RazerHydraDevice>::instanceOrNull())
{
return trans;
}
const Point3F& pos = RAZERHYDRADEV->getControllerPosition(controller);
const QuatF& qa = RAZERHYDRADEV->getControllerRotation(controller);
AngAxisF aa(qa);
aa.axis.normalize();
trans.set(pos, aa);
return trans;
}

View file

@ -0,0 +1,225 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#ifndef _RAZERHYDRADEVICE_H_
#define _RAZERHYDRADEVICE_H_
#include "platform/input/razerHydra/razerHydraConstants.h"
#include "platform/platformDlibrary.h"
#include "platform/input/IInputDevice.h"
#include "platform/input/event.h"
#include "core/util/tSingleton.h"
#include "math/mQuat.h"
#include "sixense.h"
#define HYDRA_ACTIVE_CHECK_FREQ 1000
#define FN_HYDRA __cdecl
// Library function typedefs
typedef int (FN_HYDRA* FN_SixenseInit)();
typedef int (FN_HYDRA* FN_SixenseExit)();
typedef int (FN_HYDRA* FN_SixenseGetMaxBases)();
typedef int (FN_HYDRA* FN_SixenseSetActiveBase)(int base_num);
typedef int (FN_HYDRA* FN_SixenseIsBaseConnected)(int base_num);
typedef int (FN_HYDRA* FN_SixenseGetMaxControllers)();
typedef int (FN_HYDRA* FN_SixenseIsControllerEnabled)(int which);
typedef int (FN_HYDRA* FN_SixenseGetNumActiveControllers)();
typedef int (FN_HYDRA* FN_SixenseGetHistorySize)();
typedef int (FN_HYDRA* FN_SixenseGetData)(int which, int index_back, sixenseControllerData *);
typedef int (FN_HYDRA* FN_SixenseGetAllData)(int index_back, sixenseAllControllerData *);
typedef int (FN_HYDRA* FN_SixenseGetNewestData)(int which, sixenseControllerData *);
typedef int (FN_HYDRA* FN_SixenseGetAllNewestData)(sixenseAllControllerData *);
typedef int (FN_HYDRA* FN_SixenseSetHemisphereTrackingMode)(int which_controller, int state);
typedef int (FN_HYDRA* FN_SixenseGetHemisphereTrackingMode)(int which_controller, int *state);
typedef int (FN_HYDRA* FN_SixenseAutoEnableHemisphereTracking)(int which_controller);
typedef int (FN_HYDRA* FN_SixenseSetHighPriorityBindingEnabled)(int on_or_off);
typedef int (FN_HYDRA* FN_SixenseGetHighPriorityBindingEnabled)(int *on_or_off);
typedef int (FN_HYDRA* FN_SixenseTriggerVibration)(int controller_id, int duration_100ms, int pattern_id);
typedef int (FN_HYDRA* FN_SixenseSetFilterEnabled)(int on_or_off);
typedef int (FN_HYDRA* FN_SixenseGetFilterEnabled)(int *on_or_off);
typedef int (FN_HYDRA* FN_SixenseSetFilterParams)(float near_range, float near_val, float far_range, float far_val);
typedef int (FN_HYDRA* FN_SixenseGetFilterParams)(float *near_range, float *near_val, float *far_range, float *far_val);
typedef int (FN_HYDRA* FN_SixenseSetBaseColor)(unsigned char red, unsigned char green, unsigned char blue);
typedef int (FN_HYDRA* FN_SixenseGetBaseColor)(unsigned char *red, unsigned char *green, unsigned char *blue);
struct RazerHyrdaControllerData;
class RazerHydraDevice : public IInputDevice
{
public:
static bool smEnableDevice;
// Should events be sent when a controller is docked
static bool smProcessWhenDocked;
// The type of position events to broadcast
static bool smSeparatePositionEvents;
static bool smCombinedPositionEvents;
// Broadcast controller rotation as axis
static bool smRotationAsAxisEvents;
// The maximum controller angle when used as an axis event
// as measured from a vector pointing straight up (in degrees)
static F32 smMaximumAxisAngle;
// Indicates that a whole frame event should be generated and frames
// should be buffered.
static bool smGenerateWholeFrameEvents;
// Controller Action Codes
static U32 RH_DOCKED[RazerHydraConstants::MaxControllers]; // SI_BUTTON
static U32 RH_POSX[RazerHydraConstants::MaxControllers]; // SI_FLOAT
static U32 RH_POSY[RazerHydraConstants::MaxControllers];
static U32 RH_POSZ[RazerHydraConstants::MaxControllers];
static U32 RH_POS[RazerHydraConstants::MaxControllers]; // SI_POS
static U32 RH_ROT[RazerHydraConstants::MaxControllers]; // SI_ROT
static U32 RH_ROTAXISX[RazerHydraConstants::MaxControllers]; // SI_AXIS
static U32 RH_ROTAXISY[RazerHydraConstants::MaxControllers];
static U32 RH_THUMBX[RazerHydraConstants::MaxControllers]; // SI_AXIS
static U32 RH_THUMBY[RazerHydraConstants::MaxControllers];
static U32 RH_TRIGGER[RazerHydraConstants::MaxControllers]; // SI_AXIS
static U32 RH_SHOULDER[RazerHydraConstants::MaxControllers]; // SI_BUTTON
static U32 RH_THUMB[RazerHydraConstants::MaxControllers]; // SI_BUTTON
static U32 RH_START[RazerHydraConstants::MaxControllers]; // SI_BUTTON
static U32 RH_1[RazerHydraConstants::MaxControllers]; // SI_BUTTON
static U32 RH_2[RazerHydraConstants::MaxControllers]; // SI_BUTTON
static U32 RH_3[RazerHydraConstants::MaxControllers]; // SI_BUTTON
static U32 RH_4[RazerHydraConstants::MaxControllers]; // SI_BUTTON
// Whole frame
static U32 RH_FRAME; // SI_INT
public:
RazerHydraDevice();
~RazerHydraDevice();
static void staticInit();
bool enable();
void disable();
bool process();
bool isActive() { return mActive; }
bool isControllerDocked(U32 controller);
const Point3F& getControllerPosition(U32 controller);
const QuatF& getControllerRotation(U32 controller);
protected:
DLibraryRef mRazerHydraLib;
FN_SixenseInit mfnSixenseInit;
FN_SixenseExit mfnSixenseExit;
FN_SixenseGetMaxBases mfnSixenseGetMaxBases;
FN_SixenseSetActiveBase mfnSixenseSetActiveBase;
FN_SixenseIsBaseConnected mfnSixenseIsBaseConnected;
FN_SixenseGetMaxControllers mfnSixenseGetMaxControllers;
FN_SixenseIsControllerEnabled mfnSixenseIsControllerEnabled;
FN_SixenseGetNumActiveControllers mfnSixenseGetNumActiveControllers;
FN_SixenseGetHistorySize mfnSixenseGetHistorySize;
FN_SixenseGetData mfnSixenseGetData;
FN_SixenseGetAllData mfnSixenseGetAllData;
FN_SixenseGetNewestData mfnSixenseGetNewestData;
FN_SixenseGetAllNewestData mfnSixenseGetAllNewestData;
FN_SixenseSetHemisphereTrackingMode mfnSixenseSetHemisphereTrackingMode;
FN_SixenseGetHemisphereTrackingMode mfnSixenseGetHemisphereTrackingMode;
FN_SixenseAutoEnableHemisphereTracking mfnSixenseAutoEnableHemisphereTracking;
FN_SixenseSetHighPriorityBindingEnabled mfnSixenseSetHighPriorityBindingEnabled;
FN_SixenseGetHighPriorityBindingEnabled mfnSixenseGetHighPriorityBindingEnabled;
FN_SixenseTriggerVibration mfnSixenseTriggerVibration;
FN_SixenseSetFilterEnabled mfnSixenseSetFilterEnabled;
FN_SixenseGetFilterEnabled mfnSixenseGetFilterEnabled;
FN_SixenseSetFilterParams mfnSixenseSetFilterParams;
FN_SixenseGetFilterParams mfnSixenseGetFilterParams;
FN_SixenseSetBaseColor mfnSixenseSetBaseColor;
FN_SixenseGetBaseColor mfnSixenseGetBaseColor;
S32 mMaximumBases;
S32 mMaximumControllers;
S32 mNumberActiveControllers;
/// Is the Razer Hydra active (enabled means the library is loaded)
bool mActive;
/// When was the last check for an active Hydra
S32 mLastActiveCheck;
/// Buffers to store data for the controllers
RazerHyrdaControllerData* mDataBuffer[RazerHydraConstants::MaxControllers][2];
/// Points to the buffers that holds the previously collected data
/// for each controller
RazerHyrdaControllerData* mPrevData[RazerHydraConstants::MaxControllers];
protected:
/// Build out the codes used for controller actions with the
/// Input Event Manager
void buildCodeTable();
/// Checks if there are active controllers
bool checkControllers();
public:
// For ManagedSingleton.
static const char* getSingletonName() { return "RazerHydraDevice"; }
};
/// Returns the RazerHydraDevice singleton.
#define RAZERHYDRADEV ManagedSingleton<RazerHydraDevice>::instance()
#endif // _RAZERHYDRADEVICE_H_

View file

@ -0,0 +1,337 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#include "platform/input/razerHydra/razerHydraFrame.h"
#include "platform/input/razerHydra/razerHydraUtil.h"
#include "console/engineAPI.h"
#include "math/mAngAxis.h"
#include "math/mTransform.h"
U32 RazerHydraFrame::smNextInternalFrameId = 0;
IMPLEMENT_CONOBJECT(RazerHydraFrame);
RazerHydraFrame::RazerHydraFrame()
{
clear();
}
RazerHydraFrame::~RazerHydraFrame()
{
clear();
for(U32 i=0; i<RazerHydraConstants::MaxControllers; ++i)
{
mControllerData[i].mEnabled = false;
}
}
void RazerHydraFrame::initPersistFields()
{
Parent::initPersistFields();
}
bool RazerHydraFrame::onAdd()
{
if (!Parent::onAdd())
return false;
return true;
}
void RazerHydraFrame::onRemove()
{
Parent::onRemove();
}
void RazerHydraFrame::clear()
{
mFrameValid = false;
}
void RazerHydraFrame::copyFromFrame(const sixenseAllControllerData& frame, const F32& maxAxisRadius)
{
clear();
// Calling this method automatically makes this a valid frame
mFrameValid = true;
mFrameInternalId = smNextInternalFrameId;
++smNextInternalFrameId;
mFrameSimTime = Sim::getCurrentTime();
mFrameRealTime = Platform::getRealMilliseconds();
// Process the controllers
for(U32 i=0; i<RazerHydraConstants::MaxControllers; ++i)
{
const sixenseControllerData& controller = frame.controllers[i];
ControllerData& data = mControllerData[i];
// General controller data
data.mEnabled = controller.enabled;
data.mIsDocked = controller.is_docked;
data.mSequenceNum = controller.sequence_number;
// Controller position
RazerHydraUtil::convertPosition(controller.pos, data.mRawPos);
data.mPos.x = (S32)mFloor(data.mRawPos.x);
data.mPos.y = (S32)mFloor(data.mRawPos.y);
data.mPos.z = (S32)mFloor(data.mRawPos.z);
// Controller rotation
RazerHydraUtil::convertRotation(controller.rot_mat, data.mRot);
data.mRotQuat.set(data.mRot);
// Controller as axis rotation
RazerHydraUtil::calculateAxisRotation(data.mRot, maxAxisRadius, data.mRotAxis);
// Controller thumb stick
data.mThumbStick.x = controller.joystick_x;
data.mThumbStick.y = controller.joystick_y;
// Trigger
data.mTrigger = controller.trigger;
// Controller buttons
data.mShoulder = controller.buttons & SIXENSE_BUTTON_BUMPER;
data.mThumb = controller.buttons & SIXENSE_BUTTON_JOYSTICK;
data.mStart = controller.buttons & SIXENSE_BUTTON_START;
data.mButton1 = controller.buttons & SIXENSE_BUTTON_1;
data.mButton2 = controller.buttons & SIXENSE_BUTTON_2;
data.mButton3 = controller.buttons & SIXENSE_BUTTON_3;
data.mButton4 = controller.buttons & SIXENSE_BUTTON_4;
}
}
//-----------------------------------------------------------------------------
DefineEngineMethod( RazerHydraFrame, isFrameValid, bool, ( ),,
"@brief Checks if this frame is valid.\n\n"
"@return True if the frame is valid.\n\n")
{
return object->isFrameValid();
}
DefineEngineMethod( RazerHydraFrame, getFrameInternalId, S32, ( ),,
"@brief Provides the internal ID for this frame.\n\n"
"@return Internal ID of this frame.\n\n")
{
return object->getFrameInternalId();
}
DefineEngineMethod( RazerHydraFrame, getFrameSimTime, S32, ( ),,
"@brief Get the sim time that this frame was generated.\n\n"
"@return Sim time of this frame in milliseconds.\n\n")
{
return object->getFrameSimTime();
}
DefineEngineMethod( RazerHydraFrame, getFrameRealTime, S32, ( ),,
"@brief Get the real time that this frame was generated.\n\n"
"@return Real time of this frame in milliseconds.\n\n")
{
return object->getFrameRealTime();
}
DefineEngineMethod( RazerHydraFrame, getControllerCount, S32, ( ),,
"@brief Get the number of controllers defined in this frame.\n\n"
"@return The number of defined controllers.\n\n")
{
return RazerHydraConstants::MaxControllers;
}
DefineEngineMethod( RazerHydraFrame, getControllerEnabled, bool, ( S32 index ),,
"@brief Get the enabled state of the controller.\n\n"
"@param index The controller index to check.\n"
"@return True if the requested controller is enabled.\n\n")
{
return object->getEnabled(index);
}
DefineEngineMethod( RazerHydraFrame, getControllerDocked, bool, ( S32 index ),,
"@brief Get the docked state of the controller.\n\n"
"@param index The controller index to check.\n"
"@return True if the requested controller is docked.\n\n")
{
return object->getDocked(index);
}
DefineEngineMethod( RazerHydraFrame, getControllerSequenceNum, S32, ( S32 index ),,
"@brief Get the controller sequence number.\n\n"
"@param index The controller index to check.\n"
"@return The sequence number of the requested controller.\n\n")
{
return object->getSequenceNum(index);
}
DefineEngineMethod( RazerHydraFrame, getControllerRawPos, Point3F, ( S32 index ),,
"@brief Get the raw position of the requested controller.\n\n"
"The raw position is the controller's floating point position converted to "
"Torque 3D coordinates (in millimeters).\n"
"@param index The controller index to check.\n"
"@return Raw position of the requested controller (in millimeters).\n\n")
{
return object->getRawPos(index);
}
DefineEngineMethod( RazerHydraFrame, getControllerPos, Point3I, ( S32 index ),,
"@brief Get the position of the requested controller.\n\n"
"The position is the controller's integer position converted to "
"Torque 3D coordinates (in millimeters).\n"
"@param index The controller index to check.\n"
"@return Integer position of the requested controller (in millimeters).\n\n")
{
return object->getPos(index);
}
DefineEngineMethod( RazerHydraFrame, getControllerRot, AngAxisF, ( S32 index ),,
"@brief Get the rotation of the requested controller.\n\n"
"The Razer Hydra controller rotation as converted into the Torque 3D"
"coordinate system.\n"
"@param index The controller index to check.\n"
"@return Rotation of the requested controller.\n\n")
{
AngAxisF aa(object->getRot(index));
return aa;
}
DefineEngineMethod( RazerHydraFrame, getControllerRawTransform, TransformF, ( S32 index ),,
"@brief Get the raw transform of the requested controller.\n\n"
"@param index The controller index to check.\n"
"@return The raw position and rotation of the requested controller (in Torque 3D coordinates).\n\n")
{
const Point3F& pos = object->getRawPos(index);
const QuatF& qa = object->getRotQuat(index);
AngAxisF aa(qa);
aa.axis.normalize();
TransformF trans(pos, aa);
return trans;
}
DefineEngineMethod( RazerHydraFrame, getControllerTransform, TransformF, ( S32 index ),,
"@brief Get the transform of the requested controller.\n\n"
"@param index The controller index to check.\n"
"@return The position and rotation of the requested controller (in Torque 3D coordinates).\n\n")
{
const Point3I& pos = object->getPos(index);
const QuatF& qa = object->getRotQuat(index);
AngAxisF aa(qa);
aa.axis.normalize();
TransformF trans;
trans.mPosition = Point3F(pos.x, pos.y, pos.z);
trans.mOrientation = aa;
return trans;
}
DefineEngineMethod( RazerHydraFrame, getControllerRotAxis, Point2F, ( S32 index ),,
"@brief Get the axis rotation of the requested controller.\n\n"
"This is the axis rotation of the controller as if the controller were a gamepad thumb stick. "
"Imagine a stick coming out the top of the controller and tilting the controller front, back, "
"left and right controls that stick. The values returned along the x and y stick "
"axis are normalized from -1.0 to 1.0 with the maximum controller tilt angle for these "
"values as defined by $RazerHydra::MaximumAxisAngle.\n"
"@param index The controller index to check.\n"
"@return Axis rotation of the requested controller.\n\n"
"@see RazerHydra::MaximumAxisAngle\n")
{
return object->getRotAxis(index);
}
DefineEngineMethod( RazerHydraFrame, getControllerThumbStick, Point2F, ( S32 index ),,
"@brief Get the thumb stick values of the requested controller.\n\n"
"The thumb stick values are in the range of -1.0..1.0\n"
"@param index The controller index to check.\n"
"@return Thumb stick values of the requested controller.\n\n")
{
return object->getThumbStick(index);
}
DefineEngineMethod( RazerHydraFrame, getControllerTrigger, F32, ( S32 index ),,
"@brief Get the trigger value for the requested controller.\n\n"
"The trigger value is in the range of -1.0..1.0\n"
"@param index The controller index to check.\n"
"@return Trigger value of the requested controller.\n\n")
{
return object->getTrigger(index);
}
DefineEngineMethod( RazerHydraFrame, getControllerShoulderButton, bool, ( S32 index ),,
"@brief Get the shoulder button state for the requested controller.\n\n"
"@param index The controller index to check.\n"
"@return Shoulder button state requested controller as true or false.\n\n")
{
return object->getShoulder(index);
}
DefineEngineMethod( RazerHydraFrame, getControllerThumbButton, bool, ( S32 index ),,
"@brief Get the thumb button state for the requested controller.\n\n"
"@param index The controller index to check.\n"
"@return Thumb button state requested controller as true or false.\n\n")
{
return object->getThumb(index);
}
DefineEngineMethod( RazerHydraFrame, getControllerStartButton, bool, ( S32 index ),,
"@brief Get the start button state for the requested controller.\n\n"
"@param index The controller index to check.\n"
"@return Start button state requested controller as true or false.\n\n")
{
return object->getStart(index);
}
DefineEngineMethod( RazerHydraFrame, getControllerButton1, bool, ( S32 index ),,
"@brief Get the button 1 state for the requested controller.\n\n"
"@param index The controller index to check.\n"
"@return Button 1 state requested controller as true or false.\n\n")
{
return object->getButton1(index);
}
DefineEngineMethod( RazerHydraFrame, getControllerButton2, bool, ( S32 index ),,
"@brief Get the button 2 state for the requested controller.\n\n"
"@param index The controller index to check.\n"
"@return Button 2 state requested controller as true or false.\n\n")
{
return object->getButton2(index);
}
DefineEngineMethod( RazerHydraFrame, getControllerButton3, bool, ( S32 index ),,
"@brief Get the button 3 state for the requested controller.\n\n"
"@param index The controller index to check.\n"
"@return Button 3 state requested controller as true or false.\n\n")
{
return object->getButton3(index);
}
DefineEngineMethod( RazerHydraFrame, getControllerButton4, bool, ( S32 index ),,
"@brief Get the button 4 state for the requested controller.\n\n"
"@param index The controller index to check.\n"
"@return Button 4 state requested controller as true or false.\n\n")
{
return object->getButton4(index);
}

View file

@ -0,0 +1,218 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#ifndef _RAZERHYDRAFRAME_H_
#define _RAZERHYDRAFRAME_H_
#include "platform/input/razerHydra/razerHydraConstants.h"
#include "console/simObject.h"
#include "math/mPoint3.h"
#include "math/mMatrix.h"
#include "math/mQuat.h"
#include "sixense.h"
class RazerHydraFrame : public SimObject
{
typedef SimObject Parent;
protected:
struct ControllerData
{
// Position
Point3F mRawPos;
Point3I mPos;
// Rotation
MatrixF mRot;
QuatF mRotQuat;
// Controller rotation as axis x, y
Point2F mRotAxis;
// Thumb stick x, y and trigger
Point2F mThumbStick;
F32 mTrigger;
// Buttons
bool mShoulder;
bool mThumb;
bool mStart;
bool mButton1;
bool mButton2;
bool mButton3;
bool mButton4;
// Other data
U8 mSequenceNum;
bool mEnabled;
bool mIsDocked;
};
static U32 smNextInternalFrameId;
// Sixense Frame
bool mFrameValid;
// Torque 3D frame information
U32 mFrameInternalId;
S32 mFrameSimTime;
S32 mFrameRealTime;
// Controller data for the frame
ControllerData mControllerData[RazerHydraConstants::MaxControllers];
public:
RazerHydraFrame();
virtual ~RazerHydraFrame();
static void initPersistFields();
virtual bool onAdd();
virtual void onRemove();
void clear();
/// Copy a Leap Frame into our data structures
void copyFromFrame(const sixenseAllControllerData& frame, const F32& maxAxisRadius);
// Frame
bool isFrameValid() const { return mFrameValid; }
U32 getFrameInternalId() const { return mFrameInternalId; }
S32 getFrameSimTime() const { return mFrameSimTime; }
S32 getFrameRealTime() const { return mFrameRealTime; }
// Controller
const Point3F& getRawPos(U32 index) const;
const Point3I& getPos(U32 index) const;
const MatrixF& getRot(U32 index) const;
const QuatF& getRotQuat(U32 index) const;
const Point2F& getRotAxis(U32 index) const;
// Controller variable controls
const Point2F& getThumbStick(U32 Index) const;
F32 getTrigger(U32 index) const;
// Controller buttons
bool getShoulder(U32 index) const;
bool getThumb(U32 index) const;
bool getStart(U32 index) const;
bool getButton1(U32 index) const;
bool getButton2(U32 index) const;
bool getButton3(U32 index) const;
bool getButton4(U32 index) const;
// Controller other
bool getEnabled(U32 index) const;
bool getDocked(U32 index) const;
S32 getSequenceNum(U32 index) const;
DECLARE_CONOBJECT(RazerHydraFrame);
};
//-----------------------------------------------------------------------------
inline const Point3F& RazerHydraFrame::getRawPos(U32 index) const
{
return (index >= RazerHydraConstants::MaxControllers) ? Point3F::Zero : mControllerData[index].mRawPos;
}
inline const Point3I& RazerHydraFrame::getPos(U32 index) const
{
return (index >= RazerHydraConstants::MaxControllers) ? Point3I::Zero : mControllerData[index].mPos;
}
inline const MatrixF& RazerHydraFrame::getRot(U32 index) const
{
return (index >= RazerHydraConstants::MaxControllers) ? MatrixF::Identity : mControllerData[index].mRot;
}
inline const QuatF& RazerHydraFrame::getRotQuat(U32 index) const
{
return (index >= RazerHydraConstants::MaxControllers) ? QuatF::Identity : mControllerData[index].mRotQuat;
}
inline const Point2F& RazerHydraFrame::getRotAxis(U32 index) const
{
return (index >= RazerHydraConstants::MaxControllers) ? Point2F::Zero : mControllerData[index].mRotAxis;
}
inline const Point2F& RazerHydraFrame::getThumbStick(U32 index) const
{
return (index >= RazerHydraConstants::MaxControllers) ? Point2F::Zero : mControllerData[index].mThumbStick;
}
inline F32 RazerHydraFrame::getTrigger(U32 index) const
{
return (index >= RazerHydraConstants::MaxControllers) ? 0.0f : mControllerData[index].mTrigger;
}
inline bool RazerHydraFrame::getShoulder(U32 index) const
{
return (index >= RazerHydraConstants::MaxControllers) ? false : mControllerData[index].mShoulder;
}
inline bool RazerHydraFrame::getThumb(U32 index) const
{
return (index >= RazerHydraConstants::MaxControllers) ? false : mControllerData[index].mThumb;
}
inline bool RazerHydraFrame::getStart(U32 index) const
{
return (index >= RazerHydraConstants::MaxControllers) ? false : mControllerData[index].mStart;
}
inline bool RazerHydraFrame::getButton1(U32 index) const
{
return (index >= RazerHydraConstants::MaxControllers) ? false : mControllerData[index].mButton1;
}
inline bool RazerHydraFrame::getButton2(U32 index) const
{
return (index >= RazerHydraConstants::MaxControllers) ? false : mControllerData[index].mButton2;
}
inline bool RazerHydraFrame::getButton3(U32 index) const
{
return (index >= RazerHydraConstants::MaxControllers) ? false : mControllerData[index].mButton3;
}
inline bool RazerHydraFrame::getButton4(U32 index) const
{
return (index >= RazerHydraConstants::MaxControllers) ? false : mControllerData[index].mButton4;
}
inline bool RazerHydraFrame::getEnabled(U32 index) const
{
return (index >= RazerHydraConstants::MaxControllers) ? false : mControllerData[index].mEnabled;
}
inline bool RazerHydraFrame::getDocked(U32 index) const
{
return (index >= RazerHydraConstants::MaxControllers) ? false : mControllerData[index].mIsDocked;
}
inline S32 RazerHydraFrame::getSequenceNum(U32 index) const
{
return (index >= RazerHydraConstants::MaxControllers) ? -1 : mControllerData[index].mSequenceNum;
}
#endif // _RAZERHYDRAFRAME_H_

View file

@ -0,0 +1,104 @@
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#include "platform/input/razerHydra/razerHydraFrameStore.h"
#include "platform/input/razerHydra/razerHydraFrame.h"
#include "core/module.h"
#include "console/simSet.h"
#include "console/consoleTypes.h"
MODULE_BEGIN( RazerHydraFrameStore )
MODULE_INIT_AFTER( RazerHydraDevice )
MODULE_INIT_AFTER( Sim )
MODULE_SHUTDOWN_BEFORE( Sim )
MODULE_SHUTDOWN_BEFORE( RazerHydraDevice )
MODULE_INIT
{
RazerHydraFrameStore::staticInit();
ManagedSingleton< RazerHydraFrameStore >::createSingleton();
}
MODULE_SHUTDOWN
{
ManagedSingleton< RazerHydraFrameStore >::deleteSingleton();
}
MODULE_END;
S32 RazerHydraFrameStore::smMaximumFramesStored = 30;
SimGroup* RazerHydraFrameStore::smFrameGroup = NULL;
RazerHydraFrameStore::RazerHydraFrameStore()
{
// Set up the SimGroup to store our frames
smFrameGroup = new SimGroup();
smFrameGroup->registerObject("RazerHydraFrameGroup");
smFrameGroup->setNameChangeAllowed(false);
Sim::getRootGroup()->addObject(smFrameGroup);
}
RazerHydraFrameStore::~RazerHydraFrameStore()
{
if(smFrameGroup)
{
smFrameGroup->deleteObject();
smFrameGroup = NULL;
}
}
void RazerHydraFrameStore::staticInit()
{
Con::addVariable("RazerHydra::MaximumFramesStored", TypeS32, &smMaximumFramesStored,
"@brief The maximum number of frames to keep when $RazerHydra::GenerateWholeFrameEvents is true.\n\n"
"@ingroup Game");
}
S32 RazerHydraFrameStore::generateNewFrame(const sixenseAllControllerData& frame, const F32& maxAxisRadius)
{
// Make sure our group has been created
if(!smFrameGroup)
return 0;
// Either create a new frame object or pull one off the end
S32 frameID = 0;
if(smFrameGroup->size() >= smMaximumFramesStored)
{
// Make the last frame the first and update
RazerHydraFrame* frameObj = static_cast<RazerHydraFrame*>(smFrameGroup->last());
smFrameGroup->bringObjectToFront(frameObj);
frameObj->copyFromFrame(frame, maxAxisRadius);
frameID = frameObj->getId();
}
else
{
// Create a new frame and add it to the front of the list
RazerHydraFrame* frameObj = new RazerHydraFrame();
frameObj->registerObject();
smFrameGroup->addObject(frameObj);
smFrameGroup->bringObjectToFront(frameObj);
frameObj->copyFromFrame(frame, maxAxisRadius);
frameID = frameObj->getId();
}
return frameID;
}

View file

@ -0,0 +1,58 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#ifndef _RAZERHYDRAFRAMESTORE_H_
#define _RAZERHYDRAFRAMESTORE_H_
#include "platform/types.h"
#include "sixense.h"
class SimGroup;
class RazerHydraFrameStore
{
public:
// The maximum number of frames to keep
static S32 smMaximumFramesStored;
static SimGroup* smFrameGroup;
public:
RazerHydraFrameStore();
virtual ~RazerHydraFrameStore();
static void staticInit();
static bool isFrameGroupDefined() { return smFrameGroup != NULL; }
static SimGroup* getFrameGroup() { return smFrameGroup; }
S32 generateNewFrame(const sixenseAllControllerData& frame, const F32& maxAxisRadius);
public:
// For ManagedSingleton.
static const char* getSingletonName() { return "RazerHydraFrameStore"; }
};
/// Returns the LeapMotionFrameStore singleton.
#define RAZERHYDRAFS ManagedSingleton<RazerHydraFrameStore>::instance()
#endif // _RAZERHYDRAFRAMESTORE_H_

View file

@ -0,0 +1,95 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#include "platform/input/razerHydra/razerHydraUtil.h"
namespace RazerHydraUtil
{
enum Components
{
X = 0,
Y = 1,
Z = 2,
};
void convertPosition(const F32 inPosition[3], F32& x, F32& y, F32& z)
{
// Convert to Torque coordinates. The conversion is:
//
// Motion Torque
// x y z --> x -z y
x = inPosition[X]; // x = x
y = -inPosition[Z]; // y = -z
z = inPosition[Y]; // z = y;
}
void convertPosition(const F32 inPosition[3], Point3F& outPosition)
{
// Convert to Torque coordinates. The conversion is:
//
// Motion Torque
// x y z --> x -z y
outPosition.x = inPosition[X]; // x = x
outPosition.y = -inPosition[Z]; // y = -z
outPosition.z = inPosition[Y]; // z = y;
}
void convertRotation(const F32 inRotMat[3][3], MatrixF& outRotation)
{
// Set rotation. We need to convert from sixense coordinates to
// Torque coordinates. The conversion is:
//
// Sixense Torque
// a b c a b c a -c b
// d e f --> -g -h -i --> -g i -h
// g h i d e f d -f e
outRotation.setColumn(0, Point4F( inRotMat[0][0], -inRotMat[0][2], inRotMat[0][1], 0.0f));
outRotation.setColumn(1, Point4F(-inRotMat[2][0], inRotMat[2][2], -inRotMat[2][1], 0.0f));
outRotation.setColumn(2, Point4F( inRotMat[1][0], -inRotMat[1][2], inRotMat[1][1], 0.0f));
outRotation.setPosition(Point3F::Zero);
}
void calculateAxisRotation(const MatrixF& inRotation, const F32& maxAxisRadius, Point2F& outRotation)
{
const VectorF& controllerUp = inRotation.getUpVector();
Point2F axis(0,0);
axis.x = controllerUp.x;
axis.y = controllerUp.y;
// Limit the axis angle to that given to us
if(axis.len() > maxAxisRadius)
{
axis.normalize(maxAxisRadius);
}
// Renormalize to the range of 0..1
if(maxAxisRadius != 0.0f)
{
axis /= maxAxisRadius;
}
outRotation.x = axis.x;
outRotation.y = axis.y;
}
}

View file

@ -0,0 +1,44 @@
//-----------------------------------------------------------------------------
// Copyright (c) 2012 GarageGames, LLC
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.
//-----------------------------------------------------------------------------
#ifndef _RAZERHYDRAUTIL_H_
#define _RAZERHYDRAUTIL_H_
#include "math/mPoint3.h"
#include "math/mMatrix.h"
namespace RazerHydraUtil
{
/// Convert from a Razer Hydra controller position to a Torque 3D position
void convertPosition(const F32 inPosition[3], F32& x, F32& y, F32& z);
/// Convert from a Razer Hydra controller position to a Torque 3D Point3F
void convertPosition(const F32 inPosition[3], Point3F& outPosition);
/// Convert a Razer Hydra controller's rotation to a Torque 3D matrix
void convertRotation(const F32 inRotMat[3][3], MatrixF& outRotation);
/// Calcualte a controller's rotation as if it were a thumb stick axis
void calculateAxisRotation(const MatrixF& inRotation, const F32& maxAxisRadius, Point2F& outRotation);
}
#endif // _RAZERHYDRAUTIL_H_