cleaning up plugin architecture, fixed hand controllers

This commit is contained in:
Anthony J. Thibault 2015-07-17 17:19:49 -07:00
parent 5fe4d06562
commit 01c740f415
20 changed files with 197 additions and 270 deletions

View file

@ -76,7 +76,6 @@
#include <InfoView.h>
#include <input-plugins/InputPlugin.h>
#include <input-plugins/Joystick.h> // this should probably be removed
#include <input-plugins/SixenseManager.h> // this definitely should be removed
#include <LogHandler.h>
#include <MainWindow.h>
#include <MessageDialog.h>
@ -2130,7 +2129,7 @@ void Application::setEnableVRMode(bool enableVRMode) {
#endif
void Application::setLowVelocityFilter(bool lowVelocityFilter) {
SixenseManager::getInstance().setLowVelocityFilter(lowVelocityFilter);
InputDevice::setLowVelocityFilter(lowVelocityFilter);
}
bool Application::mouseOnScreen() const {
@ -2364,18 +2363,7 @@ void Application::init() {
DependencyManager::get<AddressManager>()->loadSettings(addressLookupString);
qCDebug(interfaceapp) << "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
SixenseManager::getInstance().toggleSixense(true);
}
#else
// setup sixense
SixenseManager::getInstance().toggleSixense(true);
#endif
Leapmotion::init();
RealSense::init();
@ -2683,12 +2671,17 @@ void Application::update(float deltaTime) {
userInputMapper->setSensorToWorldMat(_myAvatar->getSensorToWorldMatrix());
userInputMapper->update(deltaTime);
// This needs to go after userInputMapper->update() because of the keyboard
bool jointsCaptured = false;
auto inputPlugins = getInputPlugins();
foreach(auto inputPlugin, inputPlugins) {
QString name = inputPlugin->getName();
QAction* action = Menu::getInstance()->getActionForOption(name);
if (action->isChecked()) {
inputPlugin->pluginUpdate(deltaTime); // add flag to prevent multiple devices from modifying joints
inputPlugin->pluginUpdate(deltaTime, jointsCaptured);
if (inputPlugin->isJointController()) {
jointsCaptured = true;
}
}
}
@ -2716,8 +2709,8 @@ void Application::update(float deltaTime) {
UserInputMapper::PoseValue leftHand = userInputMapper->getPoseState(UserInputMapper::LEFT_HAND);
UserInputMapper::PoseValue rightHand = userInputMapper->getPoseState(UserInputMapper::RIGHT_HAND);
Hand* hand = DependencyManager::get<AvatarManager>()->getMyAvatar()->getHand();
setPalmData(hand, leftHand, LEFT_HAND_INDEX);
setPalmData(hand, rightHand, RIGHT_HAND_INDEX);
setPalmData(hand, leftHand, deltaTime, LEFT_HAND_INDEX);
setPalmData(hand, rightHand, deltaTime, RIGHT_HAND_INDEX);
if (Menu::getInstance()->isOptionChecked(MenuOption::HandMouseInput)) {
emulateMouse(hand, userInputMapper->getActionState(UserInputMapper::LEFT_HAND_CLICK),
userInputMapper->getActionState(UserInputMapper::SHIFT), LEFT_HAND_INDEX);
@ -2869,7 +2862,7 @@ void Application::update(float deltaTime) {
_myAvatar->updateSensorToWorldMatrix();
}
void Application::setPalmData(Hand* hand, UserInputMapper::PoseValue pose, int index) {
void Application::setPalmData(Hand* hand, UserInputMapper::PoseValue pose, float deltaTime, int index) {
PalmData* palm;
bool foundHand = false;
for (size_t j = 0; j < hand->getNumPalms(); j++) {
@ -2887,12 +2880,54 @@ void Application::setPalmData(Hand* hand, UserInputMapper::PoseValue pose, int i
}
palm->setActive(pose.isValid());
glm::vec3 position = pose.getTranslation();
glm::quat rotation = pose.getRotation();
// TODO: velocity and tip position information should be converted to model space
// Compute current velocity from position change
glm::vec3 rawVelocity;
if (deltaTime > 0.0f) {
rawVelocity = (position - palm->getRawPosition()) / deltaTime;
} else {
rawVelocity = glm::vec3(0.0f);
}
palm->setRawVelocity(rawVelocity); // meters/sec
// TODO: velocity filters, tip velocities, etc.
// see SixenseManager
// Angular Velocity of Palm
glm::quat deltaRotation = rotation * glm::inverse(palm->getRawRotation());
glm::vec3 angularVelocity(0.0f);
float rotationAngle = glm::angle(deltaRotation);
if ((rotationAngle > EPSILON) && (deltaTime > 0.0f)) {
angularVelocity = glm::normalize(glm::axis(deltaRotation));
angularVelocity *= (rotationAngle / deltaTime);
palm->setRawAngularVelocity(angularVelocity);
} else {
palm->setRawAngularVelocity(glm::vec3(0.0f));
}
if (InputDevice::getLowVelocityFilter()) {
// Use a velocity sensitive filter to damp small motions and preserve large ones with
// no latency.
float velocityFilter = glm::clamp(1.0f - glm::length(rawVelocity), 0.0f, 1.0f);
position = palm->getRawPosition() * velocityFilter + position * (1.0f - velocityFilter);
rotation = safeMix(palm->getRawRotation(), rotation, 1.0f - velocityFilter);
}
// Store the one fingertip in the palm structure so we can track velocity
const float FINGER_LENGTH = 0.3f; // meters
const glm::vec3 FINGER_VECTOR(0.0f, 0.0f, FINGER_LENGTH);
const glm::vec3 newTipPosition = position + rotation * FINGER_VECTOR;
glm::vec3 oldTipPosition = palm->getTipRawPosition();
if (deltaTime > 0.0f) {
palm->setTipVelocity((newTipPosition - oldTipPosition) / deltaTime);
} else {
palm->setTipVelocity(glm::vec3(0.0f));
}
palm->setTipPosition(newTipPosition);
// transform from sensor space, to world space, to avatar model space.
glm::mat4 poseMat = createMatFromQuatAndPos(pose.getRotation(), pose.getTranslation());
glm::mat4 poseMat = createMatFromQuatAndPos(rotation, position);
glm::mat4 sensorToWorldMat = _myAvatar->getSensorToWorldMatrix();
glm::mat4 modelMat = createMatFromQuatAndPos(_myAvatar->getOrientation(), _myAvatar->getPosition());
glm::mat4 objectPose = glm::inverse(modelMat) * sensorToWorldMat * poseMat;

View file

@ -475,7 +475,7 @@ private:
void update(float deltaTime);
void setPalmData(Hand* hand, UserInputMapper::PoseValue pose, int index);
void setPalmData(Hand* hand, UserInputMapper::PoseValue pose, float deltaTime, int index);
void emulateMouse(Hand* hand, float click, float shift, int index);
// Various helper functions called during update()

View file

@ -7,6 +7,8 @@
//
#pragma once
#include <plugins/PluginContainer.h>
class InputPlugin;
#include <QVector>

View file

@ -464,26 +464,17 @@ Menu::Menu() {
addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::DisplayHandTargets, 0, false);
addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::HandMouseInput, 0, true);
addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::HandLasers, 0, false);
addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::LowVelocityFilter, 0, true,
qApp, SLOT(setLowVelocityFilter(bool)));
addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::ShowIKConstraints, 0, false);
MenuWrapper* sixenseOptionsMenu = handOptionsMenu->addMenu("Sixense");
addCheckableActionToQMenuAndActionHash(sixenseOptionsMenu,
MenuOption::SixenseEnabled,
0, false,
&SixenseManager::getInstance(),
SLOT(toggleSixense(bool)));
addCheckableActionToQMenuAndActionHash(sixenseOptionsMenu,
MenuOption::FilterSixense,
0,
true,
&SixenseManager::getInstance(),
SLOT(setFilter(bool)));
addCheckableActionToQMenuAndActionHash(sixenseOptionsMenu,
MenuOption::LowVelocityFilter,
0,
true,
qApp,
SLOT(setLowVelocityFilter(bool)));
MenuWrapper* leapOptionsMenu = handOptionsMenu->addMenu("Leap Motion");
addCheckableActionToQMenuAndActionHash(leapOptionsMenu, MenuOption::LeapMotionOnHMD, 0, false);

View file

@ -181,8 +181,9 @@ void PreferencesDialog::loadPreferences() {
ui.oculusUIAngularSizeSpin->setValue(qApp->getApplicationCompositor().getHmdUIAngularSize());
#endif
SixenseManager& sixense = SixenseManager::getInstance();
ui.sixenseReticleMoveSpeedSpin->setValue(InputDevice::getReticleMoveSpeed());
SixenseManager& sixense = SixenseManager::getInstance();
ui.invertSixenseButtonsCheckBox->setChecked(sixense.getInvertButtons());
// LOD items

View file

@ -7,6 +7,8 @@
//
#include "InputDevice.h"
bool InputDevice::_lowVelocityFilter = false;
const float DEFAULT_HAND_RETICLE_MOVE_SPEED = 37.5f;
float InputDevice::reticleMoveSpeed = DEFAULT_HAND_RETICLE_MOVE_SPEED;

View file

@ -34,7 +34,7 @@ public:
// Update call MUST be called once per simulation loop
// It takes care of updating the action states and deltas
virtual void update(float deltaTime) = 0;
virtual void update(float deltaTime, bool jointsCaptured) = 0;
virtual void focusOutEvent() = 0;
@ -44,6 +44,11 @@ public:
static float getReticleMoveSpeed() { return reticleMoveSpeed; }
static void setReticleMoveSpeed(float sixenseReticleMoveSpeed) { reticleMoveSpeed = sixenseReticleMoveSpeed; }
static bool getLowVelocityFilter() { return _lowVelocityFilter; };
public slots:
static void setLowVelocityFilter(bool newLowVelocityFilter) { _lowVelocityFilter = newLowVelocityFilter; };
protected:
int _deviceID = 0;
@ -53,6 +58,8 @@ protected:
AxisStateMap _axisStateMap;
PoseStateMap _poseStateMap;
static bool _lowVelocityFilter;
private:
static float reticleMoveSpeed;
};

View file

@ -15,6 +15,6 @@ public:
virtual void pluginFocusOutEvent() = 0;
virtual void pluginUpdate(float deltaTime) = 0;
virtual void pluginUpdate(float deltaTime, bool jointsCaptured) = 0;
};

View file

@ -41,7 +41,7 @@ void Joystick::closeJoystick() {
#endif
}
void Joystick::update(float deltaTime) {
void Joystick::update(float deltaTime, bool jointsCaptured) {
for (auto axisState : _axisStateMap) {
if (fabsf(axisState.second) < CONTROLLER_THRESHOLD) {
_axisStateMap[axisState.first] = 0.0f;

View file

@ -49,7 +49,7 @@ public:
// Device functions
virtual void registerToUserInputMapper(UserInputMapper& mapper) override;
virtual void assignDefaultInputMapping(UserInputMapper& mapper) override;
virtual void update(float deltaTime) override;
virtual void update(float deltaTime, bool jointsCaptured) override;
virtual void focusOutEvent() override;
Joystick() : InputDevice("Joystick") {}

View file

@ -13,7 +13,7 @@
const QString KeyboardMouseDevice::NAME = "Keyboard/Mouse";
void KeyboardMouseDevice::update(float deltaTime) {
void KeyboardMouseDevice::update(float deltaTime, bool jointsCaptured) {
_axisStateMap.clear();
// For touch event, we need to check that the last event is not too long ago

View file

@ -65,12 +65,12 @@ public:
virtual void deactivate() override {};
virtual void pluginFocusOutEvent() override { focusOutEvent(); }
virtual void pluginUpdate(float deltaTime) override { update(deltaTime); }
virtual void pluginUpdate(float deltaTime, bool jointsCaptured) override { update(deltaTime, jointsCaptured); }
// Device functions
virtual void registerToUserInputMapper(UserInputMapper& mapper) override;
virtual void assignDefaultInputMapping(UserInputMapper& mapper) override;
virtual void update(float deltaTime) override;
virtual void update(float deltaTime, bool jointsCaptured) override;
virtual void focusOutEvent() override;
void keyPressEvent(QKeyEvent* event);

View file

@ -89,12 +89,12 @@ void SDL2Manager::pluginFocusOutEvent() {
#endif
}
void SDL2Manager::pluginUpdate(float deltaTime) {
void SDL2Manager::pluginUpdate(float deltaTime, bool jointsCaptured) {
#ifdef HAVE_SDL2
if (_isInitialized) {
auto userInputMapper = DependencyManager::get<UserInputMapper>();
for (auto joystick : _openJoysticks) {
joystick->update(deltaTime);
joystick->update(deltaTime, jointsCaptured);
}
PerformanceTimer perfTimer("SDL2Manager::update");

View file

@ -38,7 +38,7 @@ public:
virtual void deactivate() override {};
virtual void pluginFocusOutEvent() override;
virtual void pluginUpdate(float deltaTime) override;
virtual void pluginUpdate(float deltaTime, bool jointsCaptured) override;
signals:
void joystickAdded(Joystick* joystick);

View file

@ -61,8 +61,6 @@ SixenseManager::SixenseManager() :
#if defined(HAVE_SIXENSE) && defined(__APPLE__)
_sixenseLibrary(NULL),
#endif
_isInitialized(false),
_isEnabled(true),
_hydrasConnected(false)
{
@ -76,59 +74,50 @@ bool SixenseManager::isSupported() const {
#endif
}
void SixenseManager::init() {
void SixenseManager::activate(PluginContainer* container) {
#ifdef HAVE_SIXENSE
if (!_isInitialized) {
_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);
_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) {
if (!_sixenseLibrary) {
#ifdef SIXENSE_LIB_FILENAME
_sixenseLibrary = new QLibrary(SIXENSE_LIB_FILENAME);
_sixenseLibrary = new QLibrary(SIXENSE_LIB_FILENAME);
#else
const QString SIXENSE_LIBRARY_NAME = "libsixense_x64";
QString frameworkSixenseLibrary = QCoreApplication::applicationDirPath() + "/../Frameworks/"
+ SIXENSE_LIBRARY_NAME;
const QString SIXENSE_LIBRARY_NAME = "libsixense_x64";
QString frameworkSixenseLibrary = QCoreApplication::applicationDirPath() + "/../Frameworks/"
+ SIXENSE_LIBRARY_NAME;
_sixenseLibrary = new QLibrary(frameworkSixenseLibrary);
_sixenseLibrary = new QLibrary(frameworkSixenseLibrary);
#endif
}
if (_sixenseLibrary->load()){
qCDebug(interfaceapp) << "Loaded sixense library for hydra support -" << _sixenseLibrary->fileName();
} else {
qCDebug(interfaceapp) << "Sixense library at" << _sixenseLibrary->fileName() << "failed to load."
<< "Continuing without hydra support.";
return;
}
SixenseBaseFunction sixenseInit = (SixenseBaseFunction) _sixenseLibrary->resolve("sixenseInit");
#endif
sixenseInit();
_isInitialized = true;
}
if (_sixenseLibrary->load()){
qCDebug(interfaceapp) << "Loaded sixense library for hydra support -" << _sixenseLibrary->fileName();
} else {
qCDebug(interfaceapp) << "Sixense library at" << _sixenseLibrary->fileName() << "failed to load."
<< "Continuing without hydra support.";
return;
}
SixenseBaseFunction sixenseInit = (SixenseBaseFunction) _sixenseLibrary->resolve("sixenseInit");
#endif
sixenseInit();
#endif
}
void SixenseManager::deinit() {
#ifdef HAVE_SIXENSE_
if (_isInitialized) {
#ifdef __APPLE__
SixenseBaseFunction sixenseExit = (SixenseBaseFunction)_sixenseLibrary->resolve("sixenseExit");
SixenseBaseFunction sixenseExit = (SixenseBaseFunction)_sixenseLibrary->resolve("sixenseExit");
#endif
sixenseExit();
}
sixenseExit();
#ifdef __APPLE__
delete _sixenseLibrary;
@ -139,141 +128,101 @@ void SixenseManager::deinit() {
void SixenseManager::setFilter(bool filter) {
#ifdef HAVE_SIXENSE
if (_isInitialized) {
#ifdef __APPLE__
SixenseTakeIntFunction sixenseSetFilterEnabled = (SixenseTakeIntFunction) _sixenseLibrary->resolve("sixenseSetFilterEnabled");
SixenseTakeIntFunction sixenseSetFilterEnabled = (SixenseTakeIntFunction) _sixenseLibrary->resolve("sixenseSetFilterEnabled");
#endif
if (filter) {
sixenseSetFilterEnabled(1);
} else {
sixenseSetFilterEnabled(0);
}
}
int newFilter = filter ? 1 : 0;
sixenseSetFilterEnabled(newFilter);
#endif
}
void SixenseManager::update(float deltaTime) {
void SixenseManager::update(float deltaTime, bool jointsCaptured) {
#ifdef HAVE_SIXENSE
//Hand* hand = DependencyManager::get<AvatarManager>()->getMyAvatar()->getHand();
if (_isInitialized && _isEnabled) {
_buttonPressedMap.clear();
_buttonPressedMap.clear();
#ifdef __APPLE__
SixenseBaseFunction sixenseGetNumActiveControllers =
(SixenseBaseFunction) _sixenseLibrary->resolve("sixenseGetNumActiveControllers");
SixenseBaseFunction sixenseGetNumActiveControllers =
(SixenseBaseFunction) _sixenseLibrary->resolve("sixenseGetNumActiveControllers");
#endif
auto userInputMapper = DependencyManager::get<UserInputMapper>();
auto userInputMapper = DependencyManager::get<UserInputMapper>();
if (sixenseGetNumActiveControllers() == 0) {
_hydrasConnected = false;
if (_deviceID != 0) {
userInputMapper->removeDevice(_deviceID);
_deviceID = 0;
if (sixenseGetNumActiveControllers() == 0) {
_hydrasConnected = false;
if (_deviceID != 0) {
userInputMapper->removeDevice(_deviceID);
_deviceID = 0;
_poseStateMap.clear();
}
return;
}
PerformanceTimer perfTimer("sixense");
if (!_hydrasConnected) {
_hydrasConnected = true;
registerToUserInputMapper(*userInputMapper);
assignDefaultInputMapping(*userInputMapper);
UserActivityLogger::getInstance().connectedDevice("spatial_controller", "hydra");
}
#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)) {
continue;
}
sixenseControllerData* data = controllers + numActiveControllers;
++numActiveControllers;
sixenseGetNewestData(i, data);
// NOTE: Sixense API returns pos data in millimeters but we IMMEDIATELY convert to meters.
glm::vec3 position(data->pos[0], data->pos[1], data->pos[2]);
position *= METERS_PER_MILLIMETER;
// Check to see if this hand/controller is on the base
const float CONTROLLER_AT_BASE_DISTANCE = 0.075f;
if (glm::length(position) >= CONTROLLER_AT_BASE_DISTANCE) {
handleButtonEvent(data->buttons, numActiveControllers - 1);
handleAxisEvent(data->joystick_x, data->joystick_y, data->trigger, numActiveControllers - 1);
// Rotation of Palm
glm::quat rotation(data->rot_quat[3], -data->rot_quat[0], data->rot_quat[1], -data->rot_quat[2]);
rotation = glm::angleAxis(PI, glm::vec3(0.0f, 1.0f, 0.0f)) * _orbRotation * rotation;
if (!jointsCaptured) {
handlePoseEvent(position, rotation, numActiveControllers - 1);
} else {
_poseStateMap.clear();
}
return;
} else {
_poseStateMap[(numActiveControllers - 1) == 0 ? LEFT_HAND : RIGHT_HAND] = UserInputMapper::PoseValue();
}
PerformanceTimer perfTimer("sixense");
if (!_hydrasConnected) {
_hydrasConnected = true;
registerToUserInputMapper(*userInputMapper);
getInstance().assignDefaultInputMapping(*userInputMapper);
UserActivityLogger::getInstance().connectedDevice("spatial_controller", "hydra");
}
#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 numControllersAtBase = 0;
int numActiveControllers = 0;
for (int i = 0; i < maxControllers && numActiveControllers < 2; i++) {
if (!sixenseIsControllerEnabled(i)) {
continue;
}
sixenseControllerData* data = controllers + numActiveControllers;
++numActiveControllers;
sixenseGetNewestData(i, data);
// Set palm position and normal based on Hydra position/orientation
// // Either find a palm matching the sixense controller, or make a new one
// PalmData* palm;
// bool foundHand = false;
// for (size_t j = 0; j < hand->getNumPalms(); j++) {
// if (hand->getPalms()[j].getSixenseID() == data->controller_index) {
// palm = &(hand->getPalms()[j]);
// _prevPalms[numActiveControllers - 1] = palm;
// foundHand = true;
// }
// }
// if (!foundHand) {
// PalmData newPalm(hand);
// hand->getPalms().push_back(newPalm);
// palm = &(hand->getPalms()[hand->getNumPalms() - 1]);
// palm->setSixenseID(data->controller_index);
// _prevPalms[numActiveControllers - 1] = palm;
// qCDebug(interfaceapp, "Found new Sixense controller, ID %i", data->controller_index);
// }
// NOTE: Sixense API returns pos data in millimeters but we IMMEDIATELY convert to meters.
glm::vec3 position(data->pos[0], data->pos[1], data->pos[2]);
position *= METERS_PER_MILLIMETER;
// Check to see if this hand/controller is on the base
const float CONTROLLER_AT_BASE_DISTANCE = 0.075f;
if (glm::length(position) >= CONTROLLER_AT_BASE_DISTANCE) {
handleButtonEvent(data->buttons, numActiveControllers - 1);
handleAxisEvent(data->joystick_x, data->joystick_y, data->trigger, numActiveControllers - 1);
// Rotation of Palm
glm::quat rotation(data->rot_quat[3], -data->rot_quat[0], data->rot_quat[1], -data->rot_quat[2]);
rotation = glm::angleAxis(PI, glm::vec3(0.0f, 1.0f, 0.0f)) * _orbRotation * rotation;
handlePoseEvent(position, rotation, numActiveControllers - 1);
}
// // Disable the hands (and return to default pose) if both controllers are at base station
// if (foundHand) {
// palm->setActive(!_controllersAtBase);
// } else {
// palm->setActive(false); // if this isn't a Sixsense ID palm, always make it inactive
// }
// // Read controller buttons and joystick into the hand
// palm->setControllerButtons(data->buttons);
// palm->setTrigger(data->trigger);
// palm->setJoystick(data->joystick_x, data->joystick_y);
}
//handleButtonEvent(data->buttons, numActiveControllers - 1);
//handleAxisEvent(data->joystick_x, data->joystick_y, data->trigger, numActiveControllers - 1);
// // Emulate the mouse so we can use scripts
// if (Menu::getInstance()->isOptionChecked(MenuOption::HandMouseInput) && !_controllersAtBase) {
// emulateMouse(palm, numActiveControllers - 1);
// }
}
if (numActiveControllers == 2) {
updateCalibration(controllers);
}
if (numActiveControllers == 2) {
updateCalibration(controllers);
}
for (auto axisState : _axisStateMap) {
@ -284,15 +233,6 @@ void SixenseManager::update(float deltaTime) {
#endif // HAVE_SIXENSE
}
void SixenseManager::toggleSixense(bool shouldEnable) {
if (shouldEnable && !isInitialized()) {
init();
//setFilter(Menu::getInstance()->isOptionChecked(MenuOption::FilterSixense));
//setLowVelocityFilter(Menu::getInstance()->isOptionChecked(MenuOption::LowVelocityFilter));
}
setIsEnabled(shouldEnable);
}
#ifdef HAVE_SIXENSE
// the calibration sequence is:
@ -483,56 +423,10 @@ void SixenseManager::handlePoseEvent(glm::vec3 position, glm::quat rotation, int
neck.y = 0.0f;
position = _orbRotation * (position - neck);
// // Compute current velocity from position change
// glm::vec3 rawVelocity;
// if (deltaTime > 0.0f) {
// rawVelocity = (position - palm->getRawPosition()) / deltaTime;
// } else {
// rawVelocity = glm::vec3(0.0f);
// }
// palm->setRawVelocity(rawVelocity); // meters/sec
// adjustment for hydra controllers fit into hands
float sign = (index == 0) ? -1.0f : 1.0f;
rotation *= glm::angleAxis(sign * PI/4.0f, glm::vec3(0.0f, 0.0f, 1.0f));
// // Angular Velocity of Palm
// glm::quat deltaRotation = rotation * glm::inverse(palm->getRawRotation());
// glm::vec3 angularVelocity(0.0f);
// float rotationAngle = glm::angle(deltaRotation);
// if ((rotationAngle > EPSILON) && (deltaTime > 0.0f)) {
// angularVelocity = glm::normalize(glm::axis(deltaRotation));
// angularVelocity *= (rotationAngle / deltaTime);
// palm->setRawAngularVelocity(angularVelocity);
// } else {
// palm->setRawAngularVelocity(glm::vec3(0.0f));
// }
// if (_lowVelocityFilter) {
// // Use a velocity sensitive filter to damp small motions and preserve large ones with
// // no latency.
// float velocityFilter = glm::clamp(1.0f - glm::length(rawVelocity), 0.0f, 1.0f);
// position = palm->getRawPosition() * velocityFilter + position * (1.0f - velocityFilter);
// rotation = safeMix(palm->getRawRotation(), rotation, 1.0f - velocityFilter);
// palm->setRawPosition(position);
// palm->setRawRotation(rotation);
// } else {
// palm->setRawPosition(position);
// palm->setRawRotation(rotation);
// }
// // Store the one fingertip in the palm structure so we can track velocity
// const float FINGER_LENGTH = 0.3f; // meters
// const glm::vec3 FINGER_VECTOR(0.0f, 0.0f, FINGER_LENGTH);
// const glm::vec3 newTipPosition = position + rotation * FINGER_VECTOR;
// glm::vec3 oldTipPosition = palm->getTipRawPosition();
// if (deltaTime > 0.0f) {
// palm->setTipVelocity((newTipPosition - oldTipPosition) / deltaTime);
// } else {
// palm->setTipVelocity(glm::vec3(0.0f));
// }
// palm->setTipPosition(newTipPosition);
_poseStateMap[makeInput(JointChannel(index)).getChannel()] = UserInputMapper::PoseValue(position, rotation);
#endif // HAVE_SIXENSE
}

View file

@ -62,24 +62,19 @@ public:
virtual bool isJointController() const override { return true; }
const QString& getName() const { return NAME; }
virtual void init() override;
virtual void deinit() override;
virtual void activate(PluginContainer * container) override {};
virtual void deactivate() override { _poseStateMap.clear(); };
virtual void activate(PluginContainer * container) override;
virtual void deactivate() override { _poseStateMap.clear(); }
virtual void pluginFocusOutEvent() override { focusOutEvent(); }
virtual void pluginUpdate(float deltaTime) override { update(deltaTime); }
virtual void pluginUpdate(float deltaTime, bool jointsCaptured) override { update(deltaTime, jointsCaptured); }
// Device functions
virtual void registerToUserInputMapper(UserInputMapper& mapper) override;
virtual void assignDefaultInputMapping(UserInputMapper& mapper) override;
virtual void update(float deltaTime) override;
virtual void update(float deltaTime, bool jointsCaptured) override;
virtual void focusOutEvent() override;
bool isInitialized() const { return _isInitialized; }
void setIsEnabled(bool isEnabled) { _isEnabled = isEnabled; }
bool getInvertButtons() const { return _invertButtons; }
void setInvertButtons(bool invertSixenseButtons) { _invertButtons = invertSixenseButtons; }
@ -88,9 +83,7 @@ public:
UserInputMapper::Input makeInput(JointChannel joint);
public slots:
void toggleSixense(bool shouldEnable);
void setFilter(bool filter);
void setLowVelocityFilter(bool lowVelocityFilter) { _lowVelocityFilter = lowVelocityFilter; };
private:
void handleButtonEvent(unsigned int buttons, int index);
@ -122,11 +115,7 @@ private:
#endif
#endif
bool _isInitialized;
bool _isEnabled;
bool _hydrasConnected;
bool _lowVelocityFilter;
bool _invertButtons = DEFAULT_INVERT_SIXENSE_MOUSE_BUTTONS;

View file

@ -192,7 +192,9 @@ void UserInputMapper::update(float deltaTime) {
break;
}
case ChannelType::POSE: {
_poseStates[channelInput.first] = deviceProxy->getPose(inputID, currentTimestamp);
if (!_poseStates[channelInput.first].isValid()) {
_poseStates[channelInput.first] = deviceProxy->getPose(inputID, currentTimestamp);
}
break;
}
default: {

View file

@ -186,7 +186,8 @@ void ViveControllerManager::renderHand(UserInputMapper::PoseValue pose, gpu::Bat
batch.drawIndexed(gpu::TRIANGLES, mesh->getNumIndices(), 0);
}
void ViveControllerManager::update(float deltaTime) {
void ViveControllerManager::update(float deltaTime, bool jointsCaptured) {
_poseStateMap.clear();
// TODO: This shouldn't be necessary
if (!_hmd) {
return;
@ -216,8 +217,10 @@ void ViveControllerManager::update(float deltaTime) {
numTrackedControllers++;
const mat4& mat = _trackedDevicePoseMat4[device];
handlePoseEvent(mat, numTrackedControllers - 1);
if (!jointsCaptured) {
handlePoseEvent(mat, numTrackedControllers - 1);
}
// handle inputs
vr::VRControllerState_t controllerState = vr::VRControllerState_t();

View file

@ -59,12 +59,12 @@ public:
virtual void deactivate() override;
virtual void pluginFocusOutEvent() override { focusOutEvent(); }
virtual void pluginUpdate(float deltaTime) override { update(deltaTime); }
virtual void pluginUpdate(float deltaTime, bool jointsCaptured) override { update(deltaTime, jointsCaptured); }
// Device functions
virtual void registerToUserInputMapper(UserInputMapper& mapper) override;
virtual void assignDefaultInputMapping(UserInputMapper& mapper) override;
virtual void update(float deltaTime) override;
virtual void update(float deltaTime, bool jointsCaptured) override;
virtual void focusOutEvent() override;
void updateRendering(RenderArgs* args, render::ScenePointer scene, render::PendingChanges pendingChanges);

View file

@ -1,6 +1,7 @@
#pragma once
#include <QString>
#include <functional>
class GlWindow;