diff --git a/Engine/source/platform/input/razerHydra/razerHydraConstants.h b/Engine/source/platform/input/razerHydra/razerHydraConstants.h new file mode 100644 index 0000000000..59f778bfcb --- /dev/null +++ b/Engine/source/platform/input/razerHydra/razerHydraConstants.h @@ -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_ diff --git a/Engine/source/platform/input/razerHydra/razerHydraData.cpp b/Engine/source/platform/input/razerHydra/razerHydraData.cpp new file mode 100644 index 0000000000..d80cffb157 --- /dev/null +++ b/Engine/source/platform/input/razerHydra/razerHydraData.cpp @@ -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; +} diff --git a/Engine/source/platform/input/razerHydra/razerHydraData.h b/Engine/source/platform/input/razerHydra/razerHydraData.h new file mode 100644 index 0000000000..21c6204f98 --- /dev/null +++ b/Engine/source/platform/input/razerHydra/razerHydraData.h @@ -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_ diff --git a/Engine/source/platform/input/razerHydra/razerHydraDevice.cpp b/Engine/source/platform/input/razerHydra/razerHydraDevice.cpp new file mode 100644 index 0000000000..89dd771f39 --- /dev/null +++ b/Engine/source/platform/input/razerHydra/razerHydraDevice.cpp @@ -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; igetNextDeviceCode(); + + 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; iaddVirtualMap( 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; isetData(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; ibuildInputEvent(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::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::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::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::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::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; +} diff --git a/Engine/source/platform/input/razerHydra/razerHydraDevice.h b/Engine/source/platform/input/razerHydra/razerHydraDevice.h new file mode 100644 index 0000000000..23c15bcb90 --- /dev/null +++ b/Engine/source/platform/input/razerHydra/razerHydraDevice.h @@ -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::instance() + +#endif // _RAZERHYDRADEVICE_H_ diff --git a/Engine/source/platform/input/razerHydra/razerHydraFrame.cpp b/Engine/source/platform/input/razerHydra/razerHydraFrame.cpp new file mode 100644 index 0000000000..a36a33f019 --- /dev/null +++ b/Engine/source/platform/input/razerHydra/razerHydraFrame.cpp @@ -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; iisFrameValid(); +} + +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); +} diff --git a/Engine/source/platform/input/razerHydra/razerHydraFrame.h b/Engine/source/platform/input/razerHydra/razerHydraFrame.h new file mode 100644 index 0000000000..a66143bd5e --- /dev/null +++ b/Engine/source/platform/input/razerHydra/razerHydraFrame.h @@ -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_ diff --git a/Engine/source/platform/input/razerHydra/razerHydraFrameStore.cpp b/Engine/source/platform/input/razerHydra/razerHydraFrameStore.cpp new file mode 100644 index 0000000000..4fc77acd5e --- /dev/null +++ b/Engine/source/platform/input/razerHydra/razerHydraFrameStore.cpp @@ -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(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; +} diff --git a/Engine/source/platform/input/razerHydra/razerHydraFrameStore.h b/Engine/source/platform/input/razerHydra/razerHydraFrameStore.h new file mode 100644 index 0000000000..da780c9f16 --- /dev/null +++ b/Engine/source/platform/input/razerHydra/razerHydraFrameStore.h @@ -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::instance() + +#endif // _RAZERHYDRAFRAMESTORE_H_ diff --git a/Engine/source/platform/input/razerHydra/razerHydraUtil.cpp b/Engine/source/platform/input/razerHydra/razerHydraUtil.cpp new file mode 100644 index 0000000000..15e5ec8c02 --- /dev/null +++ b/Engine/source/platform/input/razerHydra/razerHydraUtil.cpp @@ -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; +} + +} diff --git a/Engine/source/platform/input/razerHydra/razerHydraUtil.h b/Engine/source/platform/input/razerHydra/razerHydraUtil.h new file mode 100644 index 0000000000..54e1487f1e --- /dev/null +++ b/Engine/source/platform/input/razerHydra/razerHydraUtil.h @@ -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_ diff --git a/Tools/projectGenerator/modules/razerHydra.inc b/Tools/projectGenerator/modules/razerHydra.inc new file mode 100644 index 0000000000..e24a220be3 --- /dev/null +++ b/Tools/projectGenerator/modules/razerHydra.inc @@ -0,0 +1,75 @@ +