mirror of
https://github.com/overte-org/overte.git
synced 2025-08-08 14:37:46 +02:00
dynamically load sixense lib on OS X to make avoiding hid_init crash easier
This commit is contained in:
parent
a701bcea7b
commit
f7a17b7dec
8 changed files with 276 additions and 162 deletions
|
@ -137,8 +137,9 @@ foreach(EXTERNAL ${OPTIONAL_EXTERNALS})
|
|||
set(${${EXTERNAL}_UPPERCASE}_LIBRARIES ${${${EXTERNAL}_UPPERCASE}_LIBRARY})
|
||||
endif ()
|
||||
|
||||
if (NOT APPLE OR NOT ${${EXTERNAL}_UPPERCASE} MATCHES "SIXENSE")
|
||||
target_link_libraries(${TARGET_NAME} ${${${EXTERNAL}_UPPERCASE}_LIBRARIES})
|
||||
|
||||
endif ()
|
||||
endif ()
|
||||
endforeach()
|
||||
|
||||
|
|
|
@ -182,7 +182,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) :
|
|||
_lastNackTime(usecTimestampNow()),
|
||||
_lastSendDownstreamAudioStats(usecTimestampNow())
|
||||
{
|
||||
|
||||
// read the ApplicationInfo.ini file for Name/Version/Domain information
|
||||
QSettings applicationInfo(Application::resourcesPath() + "info/ApplicationInfo.ini", QSettings::IniFormat);
|
||||
|
||||
|
@ -381,12 +380,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer &startup_time) :
|
|||
_particleEditSender.setPacketsPerSecond(3000); // super high!!
|
||||
_entityEditSender.setPacketsPerSecond(3000); // super high!!
|
||||
|
||||
// Set the sixense filtering
|
||||
_sixenseManager.setFilter(Menu::getInstance()->isOptionChecked(MenuOption::FilterSixense));
|
||||
|
||||
// Set hand controller velocity filtering
|
||||
_sixenseManager.setLowVelocityFilter(Menu::getInstance()->isOptionChecked(MenuOption::LowVelocityFilter));
|
||||
|
||||
checkVersion();
|
||||
|
||||
_overlays.init(_glWidget); // do this before scripts load
|
||||
|
@ -1484,7 +1477,7 @@ void Application::setRenderVoxels(bool voxelRender) {
|
|||
}
|
||||
|
||||
void Application::setLowVelocityFilter(bool lowVelocityFilter) {
|
||||
getSixenseManager()->setLowVelocityFilter(lowVelocityFilter);
|
||||
SixenseManager::getInstance().setLowVelocityFilter(lowVelocityFilter);
|
||||
}
|
||||
|
||||
void Application::doKillLocalVoxels() {
|
||||
|
@ -1799,6 +1792,17 @@ void Application::init() {
|
|||
|
||||
qDebug("Loaded settings");
|
||||
|
||||
#ifdef __APPLE__
|
||||
if (Menu::getInstance()->isOptionChecked(MenuOption::SixenseEnabled)) {
|
||||
// on OS X we only setup sixense if the user wants it on - this allows running without the hid_init crash
|
||||
// if hydra support is temporarily not required
|
||||
Menu::getInstance()->toggleSixense(true);
|
||||
}
|
||||
#else
|
||||
// setup sixense
|
||||
Menu::getInstance()->toggleSixense(true);
|
||||
#endif
|
||||
|
||||
// initialize our face trackers after loading the menu settings
|
||||
_faceshift.init();
|
||||
_faceplus.init();
|
||||
|
@ -2174,7 +2178,7 @@ void Application::update(float deltaTime) {
|
|||
DeviceTracker::updateAll();
|
||||
updateFaceshift();
|
||||
updateVisage();
|
||||
_sixenseManager.update(deltaTime);
|
||||
SixenseManager::getInstance().update(deltaTime);
|
||||
JoystickScriptingInterface::getInstance().update();
|
||||
_prioVR.update(deltaTime);
|
||||
|
||||
|
|
|
@ -219,7 +219,6 @@ public:
|
|||
DdeFaceTracker* getDDE() { return &_dde; }
|
||||
CaraFaceTracker* getCara() { return &_cara; }
|
||||
FaceTracker* getActiveFaceTracker();
|
||||
SixenseManager* getSixenseManager() { return &_sixenseManager; }
|
||||
PrioVR* getPrioVR() { return &_prioVR; }
|
||||
BandwidthMeter* getBandwidthMeter() { return &_bandwidthMeter; }
|
||||
QUndoStack* getUndoStack() { return &_undoStack; }
|
||||
|
@ -510,7 +509,6 @@ private:
|
|||
CaraFaceTracker _cara;
|
||||
DdeFaceTracker _dde;
|
||||
|
||||
SixenseManager _sixenseManager;
|
||||
PrioVR _prioVR;
|
||||
|
||||
Camera _myCamera; // My view onto the world
|
||||
|
|
|
@ -431,11 +431,18 @@ Menu::Menu() :
|
|||
addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::ShowIKConstraints, 0, false);
|
||||
|
||||
QMenu* sixenseOptionsMenu = handOptionsMenu->addMenu("Sixense");
|
||||
#ifdef __APPLE__
|
||||
addCheckableActionToQMenuAndActionHash(sixenseOptionsMenu,
|
||||
MenuOption::SixenseEnabled,
|
||||
0, true,
|
||||
this,
|
||||
SLOT(toggleSixense(bool)));
|
||||
#endif
|
||||
addCheckableActionToQMenuAndActionHash(sixenseOptionsMenu,
|
||||
MenuOption::FilterSixense,
|
||||
0,
|
||||
true,
|
||||
appInstance->getSixenseManager(),
|
||||
&SixenseManager::getInstance(),
|
||||
SLOT(setFilter(bool)));
|
||||
addCheckableActionToQMenuAndActionHash(sixenseOptionsMenu,
|
||||
MenuOption::LowVelocityFilter,
|
||||
|
@ -1134,6 +1141,18 @@ void Menu::editAnimations() {
|
|||
}
|
||||
}
|
||||
|
||||
void Menu::toggleSixense(bool shouldEnable) {
|
||||
SixenseManager& sixenseManager = SixenseManager::getInstance();
|
||||
|
||||
if (shouldEnable && !sixenseManager.isInitialized()) {
|
||||
sixenseManager.initialize();
|
||||
sixenseManager.setFilter(isOptionChecked(MenuOption::FilterSixense));
|
||||
sixenseManager.setLowVelocityFilter(isOptionChecked(MenuOption::LowVelocityFilter));
|
||||
}
|
||||
|
||||
sixenseManager.setIsEnabled(shouldEnable);
|
||||
}
|
||||
|
||||
void Menu::changePrivateKey() {
|
||||
// setup the dialog
|
||||
QInputDialog privateKeyDialog(Application::getInstance()->getWindow());
|
||||
|
|
|
@ -186,6 +186,7 @@ public slots:
|
|||
void pasteToVoxel();
|
||||
|
||||
void toggleLoginMenuItem();
|
||||
void toggleSixense(bool shouldEnable);
|
||||
|
||||
QMenu* addMenu(const QString& menuName);
|
||||
void removeMenu(const QString& menuName);
|
||||
|
@ -448,6 +449,7 @@ namespace MenuOption {
|
|||
const QString ShowBordersVoxelNodes = "Show Voxel Nodes";
|
||||
const QString ShowIKConstraints = "Show IK Constraints";
|
||||
const QString SimpleShadows = "Simple";
|
||||
const QString SixenseEnabled = "Enable Hydra Support";
|
||||
const QString SixenseMouseInput = "Enable Sixense Mouse Input";
|
||||
const QString SixenseLasers = "Enable Sixense UI Lasers";
|
||||
const QString StandOnNearbyFloors = "Stand on nearby floors";
|
||||
|
|
|
@ -30,23 +30,28 @@ const int CALIBRATION_STATE_COMPLETE = 4;
|
|||
const float NECK_X = 0.25f; // meters
|
||||
const float NECK_Y = 0.3f; // meters
|
||||
const float NECK_Z = 0.3f; // meters
|
||||
|
||||
#ifdef __APPLE__
|
||||
typedef int (*SixenseBaseFunction)();
|
||||
typedef int (*SixenseTakeIntFunction)(int);
|
||||
typedef int (*SixenseTakeIntAndSixenseControllerData)(int, sixenseControllerData*);
|
||||
#endif
|
||||
|
||||
SixenseManager::SixenseManager() {
|
||||
#ifdef HAVE_SIXENSE
|
||||
_lastMovement = 0;
|
||||
_amountMoved = glm::vec3(0.0f);
|
||||
_lowVelocityFilter = false;
|
||||
|
||||
_calibrationState = CALIBRATION_STATE_IDLE;
|
||||
// By default we assume the _neckBase (in orb frame) is as high above the orb
|
||||
// as the "torso" is below it.
|
||||
_neckBase = glm::vec3(NECK_X, -NECK_Y, NECK_Z);
|
||||
|
||||
sixenseInit();
|
||||
|
||||
#endif
|
||||
_hydrasConnected = false;
|
||||
|
||||
SixenseManager& SixenseManager::getInstance() {
|
||||
static SixenseManager sharedInstance;
|
||||
return sharedInstance;
|
||||
}
|
||||
|
||||
SixenseManager::SixenseManager() :
|
||||
#ifdef __APPLE__
|
||||
_sixenseLibrary(NULL),
|
||||
#endif
|
||||
_isInitialized(false),
|
||||
_isEnabled(true),
|
||||
_hydrasConnected(false)
|
||||
{
|
||||
_triggerPressed[0] = false;
|
||||
_bumperPressed[0] = false;
|
||||
_oldX[0] = -1;
|
||||
|
@ -58,23 +63,71 @@ SixenseManager::SixenseManager() {
|
|||
}
|
||||
|
||||
SixenseManager::~SixenseManager() {
|
||||
#ifdef HAVE_SIXENSE
|
||||
|
||||
if (_isInitialized) {
|
||||
#ifdef __APPLE__
|
||||
SixenseBaseFunction sixenseExit = (SixenseBaseFunction) _sixenseLibrary->resolve("sixenseExit");
|
||||
#endif
|
||||
|
||||
sixenseExit();
|
||||
}
|
||||
|
||||
#ifdef __APPLE__
|
||||
delete _sixenseLibrary;
|
||||
#endif
|
||||
}
|
||||
|
||||
void SixenseManager::initialize() {
|
||||
#ifdef HAVE_SIXENSE
|
||||
|
||||
if (!_isInitialized) {
|
||||
_lastMovement = 0;
|
||||
_amountMoved = glm::vec3(0.0f);
|
||||
_lowVelocityFilter = false;
|
||||
|
||||
_calibrationState = CALIBRATION_STATE_IDLE;
|
||||
// By default we assume the _neckBase (in orb frame) is as high above the orb
|
||||
// as the "torso" is below it.
|
||||
_neckBase = glm::vec3(NECK_X, -NECK_Y, NECK_Z);
|
||||
|
||||
#ifdef __APPLE__
|
||||
|
||||
if (!_sixenseLibrary) {
|
||||
_sixenseLibrary = new QLibrary("libsixense_x64.dylib");
|
||||
}
|
||||
|
||||
SixenseBaseFunction sixenseInit = (SixenseBaseFunction) _sixenseLibrary->resolve("sixenseInit");
|
||||
#endif
|
||||
|
||||
sixenseInit();
|
||||
|
||||
_isInitialized = true;
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
void SixenseManager::setFilter(bool filter) {
|
||||
#ifdef HAVE_SIXENSE
|
||||
|
||||
if (_isInitialized) {
|
||||
#ifdef __APPLE__
|
||||
SixenseTakeIntFunction sixenseSetFilterEnabled = (SixenseTakeIntFunction) _sixenseLibrary->resolve("sixenseSetFilterEnabled");
|
||||
#endif
|
||||
|
||||
if (filter) {
|
||||
sixenseSetFilterEnabled(1);
|
||||
} else {
|
||||
sixenseSetFilterEnabled(0);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
||||
void SixenseManager::update(float deltaTime) {
|
||||
#ifdef HAVE_SIXENSE
|
||||
if (_isInitialized && _isEnabled) {
|
||||
// if the controllers haven't been moved in a while, disable
|
||||
const unsigned int MOVEMENT_DISABLE_SECONDS = 3;
|
||||
if (usecTimestampNow() - _lastMovement > (MOVEMENT_DISABLE_SECONDS * USECS_PER_SECOND)) {
|
||||
|
@ -85,6 +138,11 @@ void SixenseManager::update(float deltaTime) {
|
|||
_lastMovement = usecTimestampNow();
|
||||
}
|
||||
|
||||
#ifdef __APPLE__
|
||||
SixenseBaseFunction sixenseGetNumActiveControllers =
|
||||
(SixenseBaseFunction) _sixenseLibrary->resolve("sixenseGetNumActiveControllers");
|
||||
#endif
|
||||
|
||||
if (sixenseGetNumActiveControllers() == 0) {
|
||||
_hydrasConnected = false;
|
||||
return;
|
||||
|
@ -98,11 +156,24 @@ void SixenseManager::update(float deltaTime) {
|
|||
MyAvatar* avatar = Application::getInstance()->getAvatar();
|
||||
Hand* hand = avatar->getHand();
|
||||
|
||||
#ifdef __APPLE__
|
||||
SixenseBaseFunction sixenseGetMaxControllers =
|
||||
(SixenseBaseFunction) _sixenseLibrary->resolve("sixenseGetMaxControllers");
|
||||
#endif
|
||||
|
||||
int maxControllers = sixenseGetMaxControllers();
|
||||
|
||||
// we only support two controllers
|
||||
sixenseControllerData controllers[2];
|
||||
|
||||
#ifdef __APPLE__
|
||||
SixenseTakeIntFunction sixenseIsControllerEnabled =
|
||||
(SixenseTakeIntFunction) _sixenseLibrary->resolve("sixenseIsControllerEnabled");
|
||||
|
||||
SixenseTakeIntAndSixenseControllerData sixenseGetNewestData =
|
||||
(SixenseTakeIntAndSixenseControllerData) _sixenseLibrary->resolve("sixenseGetNewestData");
|
||||
#endif
|
||||
|
||||
int numActiveControllers = 0;
|
||||
for (int i = 0; i < maxControllers && numActiveControllers < 2; i++) {
|
||||
if (!sixenseIsControllerEnabled(i)) {
|
||||
|
@ -208,6 +279,8 @@ void SixenseManager::update(float deltaTime) {
|
|||
if (numActiveControllers == 2) {
|
||||
updateCalibration(controllers);
|
||||
}
|
||||
|
||||
}
|
||||
#endif // HAVE_SIXENSE
|
||||
}
|
||||
|
||||
|
|
|
@ -18,6 +18,11 @@
|
|||
#include <glm/glm.hpp>
|
||||
#include <glm/gtc/quaternion.hpp>
|
||||
#include "sixense.h"
|
||||
|
||||
#ifdef __APPLE__
|
||||
#include <qlibrary.h>
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
const unsigned int BUTTON_0 = 1U << 0; // the skinny button between 1 and 2
|
||||
|
@ -38,9 +43,12 @@ const bool DEFAULT_INVERT_SIXENSE_MOUSE_BUTTONS = false;
|
|||
class SixenseManager : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
static SixenseManager& getInstance();
|
||||
|
||||
SixenseManager();
|
||||
~SixenseManager();
|
||||
void initialize();
|
||||
bool isInitialized() const { return _isInitialized; }
|
||||
|
||||
void setIsEnabled(bool isEnabled) { _isEnabled = isEnabled; }
|
||||
|
||||
void update(float deltaTime);
|
||||
float getCursorPixelRangeMult() const;
|
||||
|
@ -51,6 +59,9 @@ public slots:
|
|||
void setLowVelocityFilter(bool lowVelocityFilter) { _lowVelocityFilter = lowVelocityFilter; };
|
||||
|
||||
private:
|
||||
SixenseManager();
|
||||
~SixenseManager();
|
||||
|
||||
#ifdef HAVE_SIXENSE
|
||||
void updateCalibration(const sixenseControllerData* controllers);
|
||||
void emulateMouse(PalmData* palm, int index);
|
||||
|
@ -72,7 +83,13 @@ private:
|
|||
glm::vec3 _reachForward;
|
||||
float _lastDistance;
|
||||
|
||||
#ifdef __APPLE__
|
||||
QLibrary* _sixenseLibrary;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
bool _isInitialized;
|
||||
bool _isEnabled;
|
||||
bool _hydrasConnected;
|
||||
quint64 _lastMovement;
|
||||
glm::vec3 _amountMoved;
|
||||
|
|
|
@ -671,7 +671,7 @@ void ApplicationOverlay::renderControllerPointers() {
|
|||
float yAngle = 0.5f - ((atan2(direction.z, direction.y) + M_PI_2));
|
||||
|
||||
// Get the pixel range over which the xAngle and yAngle are scaled
|
||||
float cursorRange = glWidget->width() * application->getSixenseManager()->getCursorPixelRangeMult();
|
||||
float cursorRange = glWidget->width() * SixenseManager::getInstance().getCursorPixelRangeMult();
|
||||
|
||||
mouseX = (glWidget->width() / 2.0f + cursorRange * xAngle);
|
||||
mouseY = (glWidget->height() / 2.0f + cursorRange * yAngle);
|
||||
|
|
Loading…
Reference in a new issue