From 394985ef4538b8c3c3f968cb4bc66cde02035eea Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Wed, 14 May 2014 11:52:01 -0700 Subject: [PATCH 01/14] Switched to Halo gun in gun.js, work in progress on hydraMove to add flying --- examples/gun.js | 5 +-- examples/hydraMove.js | 98 ++++++++++++++++++++++++------------------- 2 files changed, 56 insertions(+), 47 deletions(-) diff --git a/examples/gun.js b/examples/gun.js index e404ae1d4d..a5c0ee83e0 100644 --- a/examples/gun.js +++ b/examples/gun.js @@ -39,7 +39,7 @@ var impactSound = new Sound("https://s3-us-west-1.amazonaws.com/highfidelity-pub var targetHitSound = new Sound("http://highfidelity-public.s3-us-west-1.amazonaws.com/sounds/Space%20Invaders/hit.raw"); var targetLaunchSound = new Sound("http://highfidelity-public.s3-us-west-1.amazonaws.com/sounds/Space%20Invaders/shoot.raw"); -var gunModel = "http://highfidelity-public.s3-us-west-1.amazonaws.com/models/attachments/Raygun2.fst"; +var gunModel = "http://public.highfidelity.io/models/attachments/HaloGun.fst"; var audioOptions = new AudioInjectionOptions(); audioOptions.volume = 0.9; @@ -199,7 +199,7 @@ function playLoadSound() { Audio.playSound(loadSound, audioOptions); } -MyAvatar.attach(gunModel, "RightHand", {x: -0.02, y: -.14, z: 0.07}, Quat.fromPitchYawRollDegrees(-70, -151, 72), 0.20); +//MyAvatar.attach(gunModel, "RightHand", {x: -0.02, y: -.14, z: 0.07}, Quat.fromPitchYawRollDegrees(-70, -151, 72), 0.20); MyAvatar.attach(gunModel, "LeftHand", {x: -0.02, y: -.14, z: 0.07}, Quat.fromPitchYawRollDegrees(-70, -151, 72), 0.20); // Give a bit of time to load before playing sound @@ -320,7 +320,6 @@ function scriptEnding() { Overlays.deleteOverlay(reticle); Overlays.deleteOverlay(text); MyAvatar.detachOne(gunModel); - MyAvatar.detachOne(gunModel); } Particles.particleCollisionWithVoxel.connect(particleCollisionWithVoxel); diff --git a/examples/hydraMove.js b/examples/hydraMove.js index ad0eeddfca..638e5fe226 100644 --- a/examples/hydraMove.js +++ b/examples/hydraMove.js @@ -50,6 +50,13 @@ var LEFT_BUTTON_4 = 4; var RIGHT_PALM = 2; var RIGHT_BUTTON_4 = 10; + +function printVector(text, v, decimals) { + print(text + " " + v.x.toFixed(decimals) + ", " + v.y.toFixed(decimals) + ", " + v.z.toFixed(decimals)); +} + +var debug = true; + // Used by handleGrabBehavior() for managing the grab position changes function getAndResetGrabDelta() { var HAND_GRAB_SCALE_DISTANCE = 2.0; @@ -60,24 +67,12 @@ function getAndResetGrabDelta() { return result; } -// Used by handleGrabBehavior() for managing the grab velocity feature -function getAndResetGrabDeltaVelocity() { - var HAND_GRAB_SCALE_VELOCITY = 50.0; - var delta = Vec3.multiply(grabDeltaVelocity, (MyAvatar.scale * HAND_GRAB_SCALE_VELOCITY)); - grabDeltaVelocity = { x: 0, y: 0, z: 0}; - var avatarRotation = MyAvatar.orientation; - var result = Quat.multiply(avatarRotation, Vec3.multiply(delta, -1)); - return result; -} - -// Used by handleGrabBehavior() for managing the grab rotation feature -function getAndResetGrabRotation() { +function getGrabRotation() { var quatDiff = Quat.multiply(grabCurrentRotation, Quat.inverse(grabStartRotation)); - grabStartRotation = grabCurrentRotation; return quatDiff; } -// handles all the grab related behavior: position (crawl), velocity (flick), and rotate (twist) +// When move button is pressed, process results function handleGrabBehavior(deltaTime) { // check for and handle grab behaviors grabbingWithRightHand = Controller.isButtonPressed(RIGHT_BUTTON_4); @@ -88,9 +83,12 @@ function handleGrabBehavior(deltaTime) { if (grabbingWithRightHand && !wasGrabbingWithRightHand) { // Just starting grab, capture starting rotation grabStartRotation = Controller.getSpatialControlRawRotation(RIGHT_PALM); + grabStartPosition = Controller.getSpatialControlPosition(RIGHT_PALM); + if (debug) printVector("start position", grabStartPosition, 3); } if (grabbingWithRightHand) { - grabDelta = Vec3.sum(grabDelta, Vec3.multiply(Controller.getSpatialControlVelocity(RIGHT_PALM), deltaTime)); + //grabDelta = Vec3.sum(grabDelta, Vec3.multiply(Controller.getSpatialControlVelocity(RIGHT_PALM), deltaTime)); + grabDelta = Vec3.subtract(Controller.getSpatialControlPosition(RIGHT_PALM), grabStartPosition); grabCurrentRotation = Controller.getSpatialControlRawRotation(RIGHT_PALM); } if (!grabbingWithRightHand && wasGrabbingWithRightHand) { @@ -102,10 +100,13 @@ function handleGrabBehavior(deltaTime) { if (grabbingWithLeftHand && !wasGrabbingWithLeftHand) { // Just starting grab, capture starting rotation grabStartRotation = Controller.getSpatialControlRawRotation(LEFT_PALM); + grabStartPosition = Controller.getSpatialControlPosition(LEFT_PALM); + if (debug) printVector("start position", grabStartPosition, 3); } if (grabbingWithLeftHand) { - grabDelta = Vec3.sum(grabDelta, Vec3.multiply(Controller.getSpatialControlVelocity(LEFT_PALM), deltaTime)); + //grabDelta = Vec3.sum(grabDelta, Vec3.multiply(Controller.getSpatialControlVelocity(LEFT_PALM), deltaTime)); + grabDelta = Vec3.subtract(Controller.getSpatialControlPosition(LEFT_PALM), grabStartPosition); grabCurrentRotation = Controller.getSpatialControlRawRotation(LEFT_PALM); } if (!grabbingWithLeftHand && wasGrabbingWithLeftHand) { @@ -119,44 +120,53 @@ function handleGrabBehavior(deltaTime) { if (grabbing) { - // move position - var moveFromGrab = getAndResetGrabDelta(); - if (Vec3.length(moveFromGrab) > EPSILON) { - MyAvatar.position = Vec3.sum(MyAvatar.position, moveFromGrab); - velocity = { x: 0, y: 0, z: 0}; - } - - // add some rotation... - var deltaRotation = getAndResetGrabRotation(); - var GRAB_CONTROLLER_TURN_SCALING = 0.5; - var euler = Vec3.multiply(Quat.safeEulerAngles(deltaRotation), GRAB_CONTROLLER_TURN_SCALING); + var headOrientation = MyAvatar.headOrientation; + var front = Quat.getFront(headOrientation); + var right = Quat.getRight(headOrientation); + var up = Quat.getUp(headOrientation); - // Adjust body yaw by yaw from controller - var orientation = Quat.multiply(Quat.angleAxis(-euler.y, {x:0, y: 1, z:0}), MyAvatar.orientation); + //grabDelta = Quat.multiply(headOrientation, grabDelta); + //grabDelta = Quat.multiply(Camera.getOrientation(), grabDelta); + grabDelta = Vec3.multiplyQbyV(MyAvatar.orientation, Vec3.multiply(grabDelta, -1)); + + if (debug) { + printVector("grabDelta: ", grabDelta, 3); + } + + var THRUST_GRAB_SCALING = 0.0; + + var thrustFront = Vec3.multiply(front, MyAvatar.scale * grabDelta.z * THRUST_GRAB_SCALING * deltaTime); + MyAvatar.addThrust(thrustFront); + var thrustRight = Vec3.multiply(right, MyAvatar.scale * grabDelta.x * THRUST_GRAB_SCALING * deltaTime); + MyAvatar.addThrust(thrustRight); + var thrustUp = Vec3.multiply(up, MyAvatar.scale * grabDelta.y * THRUST_GRAB_SCALING * deltaTime); + MyAvatar.addThrust(thrustUp); + + + // add some rotation... + var deltaRotation = getGrabRotation(); + var GRAB_CONTROLLER_PITCH_SCALING = 2.5; + var GRAB_CONTROLLER_YAW_SCALING = 2.5; + var GRAB_CONTROLLER_ROLL_SCALING = 2.5; + var euler = Quat.safeEulerAngles(deltaRotation); + + // Adjust body yaw by roll from controller + var orientation = Quat.multiply(Quat.angleAxis(((euler.y * GRAB_CONTROLLER_YAW_SCALING) + + (euler.z * GRAB_CONTROLLER_ROLL_SCALING)) * deltaTime, {x:0, y: 1, z:0}), MyAvatar.orientation); MyAvatar.orientation = orientation; // Adjust head pitch from controller - MyAvatar.headPitch = MyAvatar.headPitch - euler.x; + MyAvatar.headPitch = MyAvatar.headPitch + (euler.x * GRAB_CONTROLLER_PITCH_SCALING * deltaTime); + + // Add some camera roll proportional to the rate of turn (so it feels like an airplane or roller coaster) + } - // add some velocity... - if (stoppedGrabbing) { - velocity = Vec3.sum(velocity, getAndResetGrabDeltaVelocity()); - } - - // handle residual velocity - if(Vec3.length(velocity) > EPSILON) { - MyAvatar.position = Vec3.sum(MyAvatar.position, Vec3.multiply(velocity, deltaTime)); - // damp velocity - velocity = Vec3.multiply(velocity, damping); - } - - wasGrabbingWithRightHand = grabbingWithRightHand; wasGrabbingWithLeftHand = grabbingWithLeftHand; } -// Main update function that handles flying and grabbing behaviort +// Update for joysticks and move button function flyWithHydra(deltaTime) { var thrustJoystickPosition = Controller.getJoystickPosition(THRUST_CONTROLLER); From 6dd08ca1bf0cb98ffa52dad5c7b28352ce2aaaa0 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Thu, 15 May 2014 17:09:28 -0700 Subject: [PATCH 02/14] Working on joystick support using SDL. --- interface/CMakeLists.txt | 8 +++ interface/src/Application.h | 3 ++ interface/src/devices/JoystickManager.cpp | 63 +++++++++++++++++++++++ interface/src/devices/JoystickManager.h | 52 +++++++++++++++++++ 4 files changed, 126 insertions(+) create mode 100644 interface/src/devices/JoystickManager.cpp create mode 100644 interface/src/devices/JoystickManager.h diff --git a/interface/CMakeLists.txt b/interface/CMakeLists.txt index 96c212add6..3cbeff7801 100644 --- a/interface/CMakeLists.txt +++ b/interface/CMakeLists.txt @@ -136,6 +136,7 @@ find_package(Faceplus) find_package(Faceshift) find_package(LibOVR) find_package(PrioVR) +find_package(SDL) find_package(Sixense) find_package(Visage) find_package(ZLIB) @@ -193,6 +194,13 @@ if (PRIOVR_FOUND AND NOT DISABLE_PRIOVR) target_link_libraries(${TARGET_NAME} "${PRIOVR_LIBRARIES}") endif (PRIOVR_FOUND AND NOT DISABLE_PRIOVR) +# and with SDL for joysticks +if (SDL_FOUND AND NOT DISABLE_SDL) + add_definitions(-DHAVE_SDL) + include_directories(SYSTEM "${SDL_INCLUDE_DIR}") + target_link_libraries(${TARGET_NAME} "${SDL_LIBRARY}") +endif (SDL_FOUND AND NOT DISABLE_SDL) + # and with qxmpp for chat if (QXMPP_FOUND AND NOT DISABLE_QXMPP) add_definitions(-DHAVE_QXMPP -DQXMPP_STATIC) diff --git a/interface/src/Application.h b/interface/src/Application.h index 33ec9ca856..b9b73ac86a 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -58,6 +58,7 @@ #include "avatar/MyAvatar.h" #include "devices/Faceplus.h" #include "devices/Faceshift.h" +#include "devices/JoystickManager.h" #include "devices/PrioVR.h" #include "devices/SixenseManager.h" #include "devices/Visage.h" @@ -196,6 +197,7 @@ public: FaceTracker* getActiveFaceTracker(); SixenseManager* getSixenseManager() { return &_sixenseManager; } PrioVR* getPrioVR() { return &_prioVR; } + JoystickManager* getJoystickManager() { return &_joystickManager; } BandwidthMeter* getBandwidthMeter() { return &_bandwidthMeter; } QUndoStack* getUndoStack() { return &_undoStack; } @@ -449,6 +451,7 @@ private: SixenseManager _sixenseManager; PrioVR _prioVR; + JoystickManager _joystickManager; Camera _myCamera; // My view onto the world Camera _viewFrustumOffsetCamera; // The camera we use to sometimes show the view frustum from an offset mode diff --git a/interface/src/devices/JoystickManager.cpp b/interface/src/devices/JoystickManager.cpp new file mode 100644 index 0000000000..77e53f3dcc --- /dev/null +++ b/interface/src/devices/JoystickManager.cpp @@ -0,0 +1,63 @@ +// +// JoystickManager.cpp +// interface/src/devices +// +// Created by Andrzej Kapolka on 5/15/14. +// Copyright 2014 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include + +#include + +#include + +#include "JoystickManager.h" + +using namespace std; + +JoystickManager::JoystickManager() { +#ifdef HAVE_SDL + SDL_Init(SDL_INIT_JOYSTICK); + int joystickCount = SDL_NumJoysticks(); + for (int i = 0; i < joystickCount; i++) { + SDL_Joystick* joystick = SDL_JoystickOpen(i); + if (joystick) { + JoystickState state = { SDL_JoystickName(i), QVector(SDL_JoystickNumAxes(joystick)), + QVector(SDL_JoystickNumButtons(joystick)) }; + qDebug() << state.name << state.axes.size() << state.buttons.size(); + _joystickStates.append(state); + _joysticks.append(joystick); + } + } +#endif +} + +JoystickManager::~JoystickManager() { +#ifdef HAVE_SDL + foreach (SDL_Joystick* joystick, _joysticks) { + SDL_JoystickClose(joystick); + } + SDL_Quit(); +#endif +} + +void JoystickManager::update() { +#ifdef HAVE_SDL + SDL_JoystickUpdate(); + + for (int i = 0; i < _joystickStates.size(); i++) { + SDL_Joystick* joystick = _joysticks.at(i); + JoystickState& state = _joystickStates[i]; + for (int j = 0; j < state.axes.size(); j++) { + state.axes[j] = glm::round(SDL_JoystickGetAxis(joystick, j) + 0.5f) / numeric_limits::max(); + } + for (int j = 0; j < state.buttons.size(); j++) { + state.buttons[j] = SDL_JoystickGetButton(joystick, j); + } + } +#endif +} diff --git a/interface/src/devices/JoystickManager.h b/interface/src/devices/JoystickManager.h new file mode 100644 index 0000000000..61cc2b2571 --- /dev/null +++ b/interface/src/devices/JoystickManager.h @@ -0,0 +1,52 @@ +// +// JoystickManager.h +// interface/src/devices +// +// Created by Andrzej Kapolka on 5/15/14. +// Copyright 2014 High Fidelity, Inc. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_JoystickManager_h +#define hifi_JoystickManager_h + +#include +#include + +#ifdef HAVE_SDL +#include +#endif + +class JoystickState; + +/// Handles joystick input through SDL. +class JoystickManager : public QObject { + Q_OBJECT + +public: + + JoystickManager(); + virtual ~JoystickManager(); + + const QVector& getJoystickStates() const { return _joystickStates; } + + void update(); + +private: + QVector _joystickStates; + +#ifdef HAVE_SDL + QVector _joysticks; +#endif +}; + +class JoystickState { +public: + QString name; + QVector axes; + QVector buttons; +}; + +#endif // hifi_JoystickManager_h From 946e2b574308013375c83aacda0a2a0cde795d62 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Thu, 15 May 2014 17:15:25 -0700 Subject: [PATCH 03/14] Avoid unused variable warnings in Xcode. --- interface/src/devices/PrioVR.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/devices/PrioVR.cpp b/interface/src/devices/PrioVR.cpp index 28564f6f2e..e6e948422e 100644 --- a/interface/src/devices/PrioVR.cpp +++ b/interface/src/devices/PrioVR.cpp @@ -17,6 +17,7 @@ #include "PrioVR.h" #include "ui/TextRenderer.h" +#ifdef HAVE_PRIOVR const unsigned int SERIAL_LIST[] = { 0x00000001, 0x00000000, 0x00000008, 0x00000009, 0x0000000A, 0x0000000C, 0x0000000D, 0x0000000E, 0x00000004, 0x00000005, 0x00000010, 0x00000011 }; const unsigned char AXIS_LIST[] = { 9, 43, 37, 37, 37, 13, 13, 13, 52, 52, 28, 28 }; @@ -25,7 +26,6 @@ const int LIST_LENGTH = sizeof(SERIAL_LIST) / sizeof(SERIAL_LIST[0]); const char* JOINT_NAMES[] = { "Neck", "Spine", "LeftArm", "LeftForeArm", "LeftHand", "RightArm", "RightForeArm", "RightHand", "LeftUpLeg", "LeftLeg", "RightUpLeg", "RightLeg" }; -#ifdef HAVE_PRIOVR static int indexOfHumanIKJoint(const char* jointName) { for (int i = 0;; i++) { QByteArray humanIKJoint = HUMANIK_JOINTS[i]; From a544489f3020e21529872aeb1c20291de5a8b71a Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Thu, 15 May 2014 17:44:35 -0700 Subject: [PATCH 04/14] First cut at adding external joysticks to the mix. --- interface/src/devices/JoystickManager.cpp | 1 - interface/src/devices/JoystickManager.h | 1 + .../ControllerScriptingInterface.cpp | 25 +++++++++++++++++-- 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/interface/src/devices/JoystickManager.cpp b/interface/src/devices/JoystickManager.cpp index 77e53f3dcc..da3c1834af 100644 --- a/interface/src/devices/JoystickManager.cpp +++ b/interface/src/devices/JoystickManager.cpp @@ -28,7 +28,6 @@ JoystickManager::JoystickManager() { if (joystick) { JoystickState state = { SDL_JoystickName(i), QVector(SDL_JoystickNumAxes(joystick)), QVector(SDL_JoystickNumButtons(joystick)) }; - qDebug() << state.name << state.axes.size() << state.buttons.size(); _joystickStates.append(state); _joysticks.append(joystick); } diff --git a/interface/src/devices/JoystickManager.h b/interface/src/devices/JoystickManager.h index 61cc2b2571..53a255e129 100644 --- a/interface/src/devices/JoystickManager.h +++ b/interface/src/devices/JoystickManager.h @@ -17,6 +17,7 @@ #ifdef HAVE_SDL #include +#undef main #endif class JoystickState; diff --git a/interface/src/scripting/ControllerScriptingInterface.cpp b/interface/src/scripting/ControllerScriptingInterface.cpp index 58a08066d6..929be1df5e 100644 --- a/interface/src/scripting/ControllerScriptingInterface.cpp +++ b/interface/src/scripting/ControllerScriptingInterface.cpp @@ -88,10 +88,24 @@ glm::vec2 ControllerScriptingInterface::getPrimaryJoystickPosition() const { } int ControllerScriptingInterface::getNumberOfButtons() const { - return getNumberOfActivePalms() * NUMBER_OF_BUTTONS_PER_PALM; + int buttonCount = 0; + foreach (const JoystickState& state, Application::getInstance()->getJoystickManager()->getJoystickStates()) { + buttonCount += state.buttons.size(); + } + return buttonCount + getNumberOfActivePalms() * NUMBER_OF_BUTTONS_PER_PALM; } bool ControllerScriptingInterface::isButtonPressed(int buttonIndex) const { + int managedButtonIndex = buttonIndex - getNumberOfActivePalms() * NUMBER_OF_BUTTONS_PER_PALM; + if (managedButtonIndex >= 0) { + foreach (const JoystickState& state, Application::getInstance()->getJoystickManager()->getJoystickStates()) { + if (managedButtonIndex < state.buttons.size()) { + return state.buttons.at(managedButtonIndex); + } + managedButtonIndex -= state.buttons.size(); + } + return false; + } int palmIndex = buttonIndex / NUMBER_OF_BUTTONS_PER_PALM; int buttonOnPalm = buttonIndex % NUMBER_OF_BUTTONS_PER_PALM; const PalmData* palmData = getActivePalm(palmIndex); @@ -129,11 +143,18 @@ float ControllerScriptingInterface::getTriggerValue(int triggerIndex) const { } int ControllerScriptingInterface::getNumberOfJoysticks() const { - return getNumberOfActivePalms() * NUMBER_OF_JOYSTICKS_PER_PALM; + return getNumberOfActivePalms() * NUMBER_OF_JOYSTICKS_PER_PALM + + Application::getInstance()->getJoystickManager()->getJoystickStates().size(); } glm::vec2 ControllerScriptingInterface::getJoystickPosition(int joystickIndex) const { // we know there's one joystick per palm, so the joystickIndex is the palm Index + int managedJoystickIndex = joystickIndex - getNumberOfActivePalms(); + if (managedJoystickIndex >= 0) { + const JoystickState& state = Application::getInstance()->getJoystickManager()->getJoystickStates().at( + managedJoystickIndex); + return glm::vec2(state.axes.size() > 0 ? state.axes.at(0) : 0.0f, state.axes.size() > 1 ? state.axes.at(1) : 0.0f); + } int palmIndex = joystickIndex; const PalmData* palmData = getActivePalm(palmIndex); if (palmData) { From e41500652606212d0bf865706ff754eb60ff2cbc Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Thu, 15 May 2014 18:22:57 -0700 Subject: [PATCH 05/14] Fixed index of out bounds error, issue with head not being tracked in PrioVR. --- interface/src/scripting/ControllerScriptingInterface.cpp | 3 ++- libraries/fbx/src/FBXReader.cpp | 1 + 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/interface/src/scripting/ControllerScriptingInterface.cpp b/interface/src/scripting/ControllerScriptingInterface.cpp index 929be1df5e..df97af1a16 100644 --- a/interface/src/scripting/ControllerScriptingInterface.cpp +++ b/interface/src/scripting/ControllerScriptingInterface.cpp @@ -150,7 +150,8 @@ int ControllerScriptingInterface::getNumberOfJoysticks() const { glm::vec2 ControllerScriptingInterface::getJoystickPosition(int joystickIndex) const { // we know there's one joystick per palm, so the joystickIndex is the palm Index int managedJoystickIndex = joystickIndex - getNumberOfActivePalms(); - if (managedJoystickIndex >= 0) { + if (managedJoystickIndex >= 0 && managedJoystickIndex < + Application::getInstance()->getJoystickManager()->getJoystickStates().size()) { const JoystickState& state = Application::getInstance()->getJoystickManager()->getJoystickStates().at( managedJoystickIndex); return glm::vec2(state.axes.size() > 0 ? state.axes.at(0) : 0.0f, state.axes.size() > 1 ? state.axes.at(1) : 0.0f); diff --git a/libraries/fbx/src/FBXReader.cpp b/libraries/fbx/src/FBXReader.cpp index 264f58f0d4..44ef3f3aab 100644 --- a/libraries/fbx/src/FBXReader.cpp +++ b/libraries/fbx/src/FBXReader.cpp @@ -585,6 +585,7 @@ const char* HUMANIK_JOINTS[] = { "LeftArm", "LeftForeArm", "LeftHand", + "Neck", "Spine", "Hips", "RightUpLeg", From c29708f22c3a8f2484a486b6d6abcc6884b03ac9 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Thu, 15 May 2014 19:18:19 -0700 Subject: [PATCH 06/14] Basic joystick integration. --- interface/src/Application.cpp | 1 + interface/src/devices/JoystickManager.cpp | 4 +- interface/src/devices/PrioVR.cpp | 3 ++ interface/src/devices/PrioVR.h | 3 ++ .../ControllerScriptingInterface.cpp | 40 ++++++++++++++----- 5 files changed, 39 insertions(+), 12 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 91e95bb4e3..85fb77908a 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1990,6 +1990,7 @@ void Application::update(float deltaTime) { _myAvatar->updateLookAtTargetAvatar(); updateMyAvatarLookAtPosition(); _sixenseManager.update(deltaTime); + _joystickManager.update(); _prioVR.update(); updateMyAvatar(deltaTime); // Sample hardware, update view frustum if needed, and send avatar data to mixer/nodes updateThreads(deltaTime); // If running non-threaded, then give the threads some time to process... diff --git a/interface/src/devices/JoystickManager.cpp b/interface/src/devices/JoystickManager.cpp index da3c1834af..005505441c 100644 --- a/interface/src/devices/JoystickManager.cpp +++ b/interface/src/devices/JoystickManager.cpp @@ -52,7 +52,9 @@ void JoystickManager::update() { SDL_Joystick* joystick = _joysticks.at(i); JoystickState& state = _joystickStates[i]; for (int j = 0; j < state.axes.size(); j++) { - state.axes[j] = glm::round(SDL_JoystickGetAxis(joystick, j) + 0.5f) / numeric_limits::max(); + float value = glm::round(SDL_JoystickGetAxis(joystick, j) + 0.5f) / numeric_limits::max(); + const float DEAD_ZONE = 0.1f; + state.axes[j] = glm::abs(value) < DEAD_ZONE ? 0.0f : value; } for (int j = 0; j < state.buttons.size(); j++) { state.buttons[j] = SDL_JoystickGetButton(joystick, j); diff --git a/interface/src/devices/PrioVR.cpp b/interface/src/devices/PrioVR.cpp index e6e948422e..c97d35b9d2 100644 --- a/interface/src/devices/PrioVR.cpp +++ b/interface/src/devices/PrioVR.cpp @@ -9,6 +9,7 @@ // See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html // +#include #include #include @@ -52,6 +53,8 @@ PrioVR::PrioVR() { for (int i = 0; i < LIST_LENGTH; i++) { _humanIKJointIndices.append(jointsDiscovered[i] ? indexOfHumanIKJoint(JOINT_NAMES[i]) : -1); } + const int INITIAL_RESET_DELAY = 5000; + QTimer::singleShot(INITIAL_RESET_DELAY, this, SLOT(reset())); #endif } diff --git a/interface/src/devices/PrioVR.h b/interface/src/devices/PrioVR.h index 8f01574356..59352d2ac4 100644 --- a/interface/src/devices/PrioVR.h +++ b/interface/src/devices/PrioVR.h @@ -44,6 +44,9 @@ public: const QVector& getJointRotations() const { return _jointRotations; } void update(); + +public slots: + void reset(); private slots: diff --git a/interface/src/scripting/ControllerScriptingInterface.cpp b/interface/src/scripting/ControllerScriptingInterface.cpp index df97af1a16..b5619191fa 100644 --- a/interface/src/scripting/ControllerScriptingInterface.cpp +++ b/interface/src/scripting/ControllerScriptingInterface.cpp @@ -90,19 +90,20 @@ glm::vec2 ControllerScriptingInterface::getPrimaryJoystickPosition() const { int ControllerScriptingInterface::getNumberOfButtons() const { int buttonCount = 0; foreach (const JoystickState& state, Application::getInstance()->getJoystickManager()->getJoystickStates()) { - buttonCount += state.buttons.size(); + buttonCount += state.buttons.size() / 2; } return buttonCount + getNumberOfActivePalms() * NUMBER_OF_BUTTONS_PER_PALM; } bool ControllerScriptingInterface::isButtonPressed(int buttonIndex) const { + // as a temporary hack, we consider every other button a trigger int managedButtonIndex = buttonIndex - getNumberOfActivePalms() * NUMBER_OF_BUTTONS_PER_PALM; if (managedButtonIndex >= 0) { foreach (const JoystickState& state, Application::getInstance()->getJoystickManager()->getJoystickStates()) { - if (managedButtonIndex < state.buttons.size()) { - return state.buttons.at(managedButtonIndex); + if (managedButtonIndex * 2 + 1 < state.buttons.size()) { + return state.buttons.at(managedButtonIndex * 2 + 1); } - managedButtonIndex -= state.buttons.size(); + managedButtonIndex -= state.buttons.size() / 2; } return false; } @@ -129,10 +130,24 @@ bool ControllerScriptingInterface::isButtonPressed(int buttonIndex) const { } int ControllerScriptingInterface::getNumberOfTriggers() const { - return getNumberOfActivePalms() * NUMBER_OF_TRIGGERS_PER_PALM; + int buttonCount = 0; + foreach (const JoystickState& state, Application::getInstance()->getJoystickManager()->getJoystickStates()) { + buttonCount += state.buttons.size() / 2; + } + return buttonCount + getNumberOfActivePalms() * NUMBER_OF_TRIGGERS_PER_PALM; } float ControllerScriptingInterface::getTriggerValue(int triggerIndex) const { + int managedButtonIndex = triggerIndex - getNumberOfActivePalms() * NUMBER_OF_TRIGGERS_PER_PALM; + if (managedButtonIndex >= 0) { + foreach (const JoystickState& state, Application::getInstance()->getJoystickManager()->getJoystickStates()) { + if (managedButtonIndex * 2 < state.buttons.size()) { + return state.buttons.at(managedButtonIndex * 2) ? 1.0f : 0.0f; + } + managedButtonIndex -= state.buttons.size() / 2; + } + return false; + } // we know there's one trigger per palm, so the triggerIndex is the palm Index int palmIndex = triggerIndex; const PalmData* palmData = getActivePalm(palmIndex); @@ -149,12 +164,15 @@ int ControllerScriptingInterface::getNumberOfJoysticks() const { glm::vec2 ControllerScriptingInterface::getJoystickPosition(int joystickIndex) const { // we know there's one joystick per palm, so the joystickIndex is the palm Index - int managedJoystickIndex = joystickIndex - getNumberOfActivePalms(); - if (managedJoystickIndex >= 0 && managedJoystickIndex < - Application::getInstance()->getJoystickManager()->getJoystickStates().size()) { - const JoystickState& state = Application::getInstance()->getJoystickManager()->getJoystickStates().at( - managedJoystickIndex); - return glm::vec2(state.axes.size() > 0 ? state.axes.at(0) : 0.0f, state.axes.size() > 1 ? state.axes.at(1) : 0.0f); + int managedAxisIndex = (joystickIndex - getNumberOfActivePalms()) * 2; + if (managedAxisIndex >= 0) { + foreach (const JoystickState& state, Application::getInstance()->getJoystickManager()->getJoystickStates()) { + if (managedAxisIndex + 1 < state.axes.size()) { + return glm::vec2(state.axes.at(managedAxisIndex), -state.axes.at(managedAxisIndex + 1)); + } + managedAxisIndex -= state.axes.size(); + } + return glm::vec2(); } int palmIndex = joystickIndex; const PalmData* palmData = getActivePalm(palmIndex); From 85b94ff71cf6681a4704f85b10bdd723dfb9ec89 Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Fri, 16 May 2014 09:20:15 -0700 Subject: [PATCH 07/14] added dead zone to pitch in hydra move, animated models show up where you are --- examples/animatedModelExample.js | 10 +++++----- examples/hydraMove.js | 24 ++++++++++++++++-------- 2 files changed, 21 insertions(+), 13 deletions(-) diff --git a/examples/animatedModelExample.js b/examples/animatedModelExample.js index 5199eb419f..3fb4ae8bd4 100644 --- a/examples/animatedModelExample.js +++ b/examples/animatedModelExample.js @@ -21,9 +21,9 @@ var roll = 0.0; var rotation = Quat.fromPitchYawRollDegrees(pitch, yaw, roll) var originalProperties = { - position: { x: 10, - y: 0, - z: 0 }, + position: { x: MyAvatar.position.x, + y: MyAvatar.position.y, + z: MyAvatar.position.z }, radius : 1, @@ -58,9 +58,9 @@ function moveModel(deltaTime) { if (animationFPS == 30) { animationFPS = 10; } else if (animationFPS == 10) { - animationFPS = 60; + animationFPS = 10; } else if (animationFPS == 60) { - animationFPS = 30; + animationFPS = 10; } print("animationFPS=" + animationFPS); isPlaying = true; diff --git a/examples/hydraMove.js b/examples/hydraMove.js index 638e5fe226..3a11fa0b5e 100644 --- a/examples/hydraMove.js +++ b/examples/hydraMove.js @@ -145,20 +145,28 @@ function handleGrabBehavior(deltaTime) { // add some rotation... var deltaRotation = getGrabRotation(); - var GRAB_CONTROLLER_PITCH_SCALING = 2.5; - var GRAB_CONTROLLER_YAW_SCALING = 2.5; - var GRAB_CONTROLLER_ROLL_SCALING = 2.5; + var PITCH_SCALING = 2.0; + var PITCH_DEAD_ZONE = 2.0; + var YAW_SCALING = 2.0; + var ROLL_SCALING = 2.0; + var euler = Quat.safeEulerAngles(deltaRotation); + print("dx: " + euler.x); + // Adjust body yaw by roll from controller - var orientation = Quat.multiply(Quat.angleAxis(((euler.y * GRAB_CONTROLLER_YAW_SCALING) + - (euler.z * GRAB_CONTROLLER_ROLL_SCALING)) * deltaTime, {x:0, y: 1, z:0}), MyAvatar.orientation); + var orientation = Quat.multiply(Quat.angleAxis(((euler.y * YAW_SCALING) + + (euler.z * ROLL_SCALING)) * deltaTime, {x:0, y: 1, z:0}), MyAvatar.orientation); MyAvatar.orientation = orientation; // Adjust head pitch from controller - MyAvatar.headPitch = MyAvatar.headPitch + (euler.x * GRAB_CONTROLLER_PITCH_SCALING * deltaTime); - - // Add some camera roll proportional to the rate of turn (so it feels like an airplane or roller coaster) + var pitch = 0.0; + if (Math.abs(euler.x) > PITCH_DEAD_ZONE) { + pitch = (euler.x < 0.0) ? (euler.x + PITCH_DEAD_ZONE) : (euler.x - PITCH_DEAD_ZONE); + } + MyAvatar.headPitch = MyAvatar.headPitch + (pitch * PITCH_SCALING * deltaTime); + + // TODO: Add some camera roll proportional to the rate of turn (so it feels like an airplane or roller coaster) } From 25f1e180f504c87c3a1ef704d30b24f8eb82fa51 Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Fri, 16 May 2014 09:34:54 -0700 Subject: [PATCH 08/14] revert test change --- examples/animatedModelExample.js | 4 ++-- examples/bot.js | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/examples/animatedModelExample.js b/examples/animatedModelExample.js index 3fb4ae8bd4..70e40140eb 100644 --- a/examples/animatedModelExample.js +++ b/examples/animatedModelExample.js @@ -56,11 +56,11 @@ function moveModel(deltaTime) { if (count % adjustFPSEveryWhile == 0) { if (animationFPS == 30) { - animationFPS = 10; + animationFPS = 30; } else if (animationFPS == 10) { animationFPS = 10; } else if (animationFPS == 60) { - animationFPS = 10; + animationFPS = 60; } print("animationFPS=" + animationFPS); isPlaying = true; diff --git a/examples/bot.js b/examples/bot.js index f7a0429c53..e42d234abf 100644 --- a/examples/bot.js +++ b/examples/bot.js @@ -25,7 +25,7 @@ function printVector(string, vector) { } var CHANCE_OF_MOVING = 0.005; -var CHANCE_OF_SOUND = 0.000; +var CHANCE_OF_SOUND = 0.005; var CHANCE_OF_HEAD_TURNING = 0.05; var CHANCE_OF_BIG_MOVE = 0.1; var CHANCE_OF_WAVING = 0.009; @@ -41,11 +41,11 @@ var isWaving = false; var waveFrequency = 0.0; var waveAmplitude = 0.0; -var X_MIN = 20.0; -var X_MAX = 25.0; -var Z_MIN = 20.0; -var Z_MAX = 25.0; -var Y_PELVIS = 2.5; +var X_MIN = 5.0; +var X_MAX = 15.0; +var Z_MIN = 5.0; +var Z_MAX = 15.0; +var Y_PELVIS = 1.0; var SPINE_JOINT_NUMBER = 13; var SHOULDER_JOINT_NUMBER = 17; var ELBOW_JOINT_NUMBER = 18; From 4532c934199b7a0292c4a58ef18cb5dba952c60b Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Fri, 16 May 2014 09:36:55 -0700 Subject: [PATCH 09/14] debug off --- examples/hydraMove.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/examples/hydraMove.js b/examples/hydraMove.js index 3a11fa0b5e..9465bd9447 100644 --- a/examples/hydraMove.js +++ b/examples/hydraMove.js @@ -55,7 +55,7 @@ function printVector(text, v, decimals) { print(text + " " + v.x.toFixed(decimals) + ", " + v.y.toFixed(decimals) + ", " + v.z.toFixed(decimals)); } -var debug = true; +var debug = false; // Used by handleGrabBehavior() for managing the grab position changes function getAndResetGrabDelta() { @@ -151,8 +151,6 @@ function handleGrabBehavior(deltaTime) { var ROLL_SCALING = 2.0; var euler = Quat.safeEulerAngles(deltaRotation); - - print("dx: " + euler.x); // Adjust body yaw by roll from controller var orientation = Quat.multiply(Quat.angleAxis(((euler.y * YAW_SCALING) + From 5dcd942e8e562872ed949d074951a7d7a890caa5 Mon Sep 17 00:00:00 2001 From: Philip Rosedale Date: Fri, 16 May 2014 09:44:03 -0700 Subject: [PATCH 10/14] removed dead code --- examples/hydraMove.js | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/examples/hydraMove.js b/examples/hydraMove.js index 9465bd9447..ff71316886 100644 --- a/examples/hydraMove.js +++ b/examples/hydraMove.js @@ -87,7 +87,6 @@ function handleGrabBehavior(deltaTime) { if (debug) printVector("start position", grabStartPosition, 3); } if (grabbingWithRightHand) { - //grabDelta = Vec3.sum(grabDelta, Vec3.multiply(Controller.getSpatialControlVelocity(RIGHT_PALM), deltaTime)); grabDelta = Vec3.subtract(Controller.getSpatialControlPosition(RIGHT_PALM), grabStartPosition); grabCurrentRotation = Controller.getSpatialControlRawRotation(RIGHT_PALM); } @@ -105,7 +104,6 @@ function handleGrabBehavior(deltaTime) { } if (grabbingWithLeftHand) { - //grabDelta = Vec3.sum(grabDelta, Vec3.multiply(Controller.getSpatialControlVelocity(LEFT_PALM), deltaTime)); grabDelta = Vec3.subtract(Controller.getSpatialControlPosition(LEFT_PALM), grabStartPosition); grabCurrentRotation = Controller.getSpatialControlRawRotation(LEFT_PALM); } @@ -125,9 +123,7 @@ function handleGrabBehavior(deltaTime) { var right = Quat.getRight(headOrientation); var up = Quat.getUp(headOrientation); - //grabDelta = Quat.multiply(headOrientation, grabDelta); - //grabDelta = Quat.multiply(Camera.getOrientation(), grabDelta); - grabDelta = Vec3.multiplyQbyV(MyAvatar.orientation, Vec3.multiply(grabDelta, -1)); + grabDelta = Vec3.multiplyQbyV(MyAvatar.orientation, Vec3.multiply(grabDelta, -1)); if (debug) { printVector("grabDelta: ", grabDelta, 3); From 20eadab9700adb05a3ceb46909d8b59ffcf0500b Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Fri, 16 May 2014 11:18:21 -0700 Subject: [PATCH 11/14] Lock joystick states for thread safety. --- interface/src/devices/JoystickManager.cpp | 6 ++++++ interface/src/devices/JoystickManager.h | 4 +++- 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/interface/src/devices/JoystickManager.cpp b/interface/src/devices/JoystickManager.cpp index da3c1834af..6b8fd9563f 100644 --- a/interface/src/devices/JoystickManager.cpp +++ b/interface/src/devices/JoystickManager.cpp @@ -44,10 +44,16 @@ JoystickManager::~JoystickManager() { #endif } +QVector JoystickManager::getJoystickStates() { + QMutexLocker locker(&_joystickMutex); + return _joystickStates; +} + void JoystickManager::update() { #ifdef HAVE_SDL SDL_JoystickUpdate(); + QMutexLocker locker(&_joystickMutex); for (int i = 0; i < _joystickStates.size(); i++) { SDL_Joystick* joystick = _joysticks.at(i); JoystickState& state = _joystickStates[i]; diff --git a/interface/src/devices/JoystickManager.h b/interface/src/devices/JoystickManager.h index 53a255e129..1979cf0205 100644 --- a/interface/src/devices/JoystickManager.h +++ b/interface/src/devices/JoystickManager.h @@ -12,6 +12,7 @@ #ifndef hifi_JoystickManager_h #define hifi_JoystickManager_h +#include #include #include @@ -31,12 +32,13 @@ public: JoystickManager(); virtual ~JoystickManager(); - const QVector& getJoystickStates() const { return _joystickStates; } + QVector getJoystickStates(); void update(); private: QVector _joystickStates; + QMutex _joystickMutex; #ifdef HAVE_SDL QVector _joysticks; From c42368594d7035f33327cb8a54884e8e40eea060 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Fri, 16 May 2014 11:24:45 -0700 Subject: [PATCH 12/14] Scratch that; going to shoehorn joystick data into palms. --- interface/src/devices/JoystickManager.cpp | 6 ----- interface/src/devices/JoystickManager.h | 4 +-- .../ControllerScriptingInterface.cpp | 26 ++----------------- 3 files changed, 3 insertions(+), 33 deletions(-) diff --git a/interface/src/devices/JoystickManager.cpp b/interface/src/devices/JoystickManager.cpp index 6b8fd9563f..da3c1834af 100644 --- a/interface/src/devices/JoystickManager.cpp +++ b/interface/src/devices/JoystickManager.cpp @@ -44,16 +44,10 @@ JoystickManager::~JoystickManager() { #endif } -QVector JoystickManager::getJoystickStates() { - QMutexLocker locker(&_joystickMutex); - return _joystickStates; -} - void JoystickManager::update() { #ifdef HAVE_SDL SDL_JoystickUpdate(); - QMutexLocker locker(&_joystickMutex); for (int i = 0; i < _joystickStates.size(); i++) { SDL_Joystick* joystick = _joysticks.at(i); JoystickState& state = _joystickStates[i]; diff --git a/interface/src/devices/JoystickManager.h b/interface/src/devices/JoystickManager.h index 1979cf0205..53a255e129 100644 --- a/interface/src/devices/JoystickManager.h +++ b/interface/src/devices/JoystickManager.h @@ -12,7 +12,6 @@ #ifndef hifi_JoystickManager_h #define hifi_JoystickManager_h -#include #include #include @@ -32,13 +31,12 @@ public: JoystickManager(); virtual ~JoystickManager(); - QVector getJoystickStates(); + const QVector& getJoystickStates() const { return _joystickStates; } void update(); private: QVector _joystickStates; - QMutex _joystickMutex; #ifdef HAVE_SDL QVector _joysticks; diff --git a/interface/src/scripting/ControllerScriptingInterface.cpp b/interface/src/scripting/ControllerScriptingInterface.cpp index 929be1df5e..286d55081d 100644 --- a/interface/src/scripting/ControllerScriptingInterface.cpp +++ b/interface/src/scripting/ControllerScriptingInterface.cpp @@ -74,7 +74,6 @@ bool ControllerScriptingInterface::isPrimaryButtonPressed() const { return true; } } - return false; } @@ -88,24 +87,10 @@ glm::vec2 ControllerScriptingInterface::getPrimaryJoystickPosition() const { } int ControllerScriptingInterface::getNumberOfButtons() const { - int buttonCount = 0; - foreach (const JoystickState& state, Application::getInstance()->getJoystickManager()->getJoystickStates()) { - buttonCount += state.buttons.size(); - } - return buttonCount + getNumberOfActivePalms() * NUMBER_OF_BUTTONS_PER_PALM; + return getNumberOfActivePalms() * NUMBER_OF_BUTTONS_PER_PALM; } bool ControllerScriptingInterface::isButtonPressed(int buttonIndex) const { - int managedButtonIndex = buttonIndex - getNumberOfActivePalms() * NUMBER_OF_BUTTONS_PER_PALM; - if (managedButtonIndex >= 0) { - foreach (const JoystickState& state, Application::getInstance()->getJoystickManager()->getJoystickStates()) { - if (managedButtonIndex < state.buttons.size()) { - return state.buttons.at(managedButtonIndex); - } - managedButtonIndex -= state.buttons.size(); - } - return false; - } int palmIndex = buttonIndex / NUMBER_OF_BUTTONS_PER_PALM; int buttonOnPalm = buttonIndex % NUMBER_OF_BUTTONS_PER_PALM; const PalmData* palmData = getActivePalm(palmIndex); @@ -143,18 +128,11 @@ float ControllerScriptingInterface::getTriggerValue(int triggerIndex) const { } int ControllerScriptingInterface::getNumberOfJoysticks() const { - return getNumberOfActivePalms() * NUMBER_OF_JOYSTICKS_PER_PALM + - Application::getInstance()->getJoystickManager()->getJoystickStates().size(); + return getNumberOfActivePalms() * NUMBER_OF_JOYSTICKS_PER_PALM; } glm::vec2 ControllerScriptingInterface::getJoystickPosition(int joystickIndex) const { // we know there's one joystick per palm, so the joystickIndex is the palm Index - int managedJoystickIndex = joystickIndex - getNumberOfActivePalms(); - if (managedJoystickIndex >= 0) { - const JoystickState& state = Application::getInstance()->getJoystickManager()->getJoystickStates().at( - managedJoystickIndex); - return glm::vec2(state.axes.size() > 0 ? state.axes.at(0) : 0.0f, state.axes.size() > 1 ? state.axes.at(1) : 0.0f); - } int palmIndex = joystickIndex; const PalmData* palmData = getActivePalm(palmIndex); if (palmData) { From a7234fd8d33e72dba01eb5c9485f408138994a4e Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Fri, 16 May 2014 12:10:21 -0700 Subject: [PATCH 13/14] Stuff the joystick and position bits into the palms. --- interface/src/Application.cpp | 2 +- interface/src/devices/PrioVR.cpp | 87 ++++++++++++++++++- interface/src/devices/PrioVR.h | 2 +- .../ControllerScriptingInterface.cpp | 1 + 4 files changed, 89 insertions(+), 3 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 91e95bb4e3..9f391aa36b 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1990,7 +1990,7 @@ void Application::update(float deltaTime) { _myAvatar->updateLookAtTargetAvatar(); updateMyAvatarLookAtPosition(); _sixenseManager.update(deltaTime); - _prioVR.update(); + _prioVR.update(deltaTime); updateMyAvatar(deltaTime); // Sample hardware, update view frustum if needed, and send avatar data to mixer/nodes updateThreads(deltaTime); // If running non-threaded, then give the threads some time to process... _avatarManager.updateOtherAvatars(deltaTime); //loop through all the other avatars and simulate them... diff --git a/interface/src/devices/PrioVR.cpp b/interface/src/devices/PrioVR.cpp index e6e948422e..dcc3d314f3 100644 --- a/interface/src/devices/PrioVR.cpp +++ b/interface/src/devices/PrioVR.cpp @@ -37,6 +37,87 @@ static int indexOfHumanIKJoint(const char* jointName) { } } } + +static void setPalm(float deltaTime, int index) { + MyAvatar* avatar = Application::getInstance()->getAvatar(); + Hand* hand = avatar->getHand(); + PalmData* palm; + bool foundHand = false; + for (size_t j = 0; j < hand->getNumPalms(); j++) { + if (hand->getPalms()[j].getSixenseID() == index) { + palm = &(hand->getPalms()[j]); + foundHand = true; + } + } + if (!foundHand) { + PalmData newPalm(hand); + hand->getPalms().push_back(newPalm); + palm = &(hand->getPalms()[hand->getNumPalms() - 1]); + palm->setSixenseID(index); + } + + palm->setActive(true); + + // Read controller buttons and joystick into the hand + if (!Application::getInstance()->getJoystickManager()->getJoystickStates().isEmpty()) { + const JoystickState& state = Application::getInstance()->getJoystickManager()->getJoystickStates().at(0); + if (state.axes.size() >= 4 && state.buttons.size() >= 4) { + if (index == 0) { + palm->setControllerButtons(state.buttons.at(1) ? BUTTON_FWD : 0); + palm->setTrigger(state.buttons.at(0) ? 1.0f : 0.0f); + palm->setJoystick(state.axes.at(0), -state.axes.at(1)); + + } else { + palm->setControllerButtons(state.buttons.at(3) ? BUTTON_FWD : 0); + palm->setTrigger(state.buttons.at(2) ? 1.0f : 0.0f); + palm->setJoystick(state.axes.at(2), -state.axes.at(3)); + } + } + } + + glm::vec3 position; + glm::quat rotation; + + Model* skeletonModel = &Application::getInstance()->getAvatar()->getSkeletonModel(); + int jointIndex; + glm::quat inverseRotation = glm::inverse(skeletonModel->getRotation()); + if (index == 0) { + jointIndex = skeletonModel->getLeftHandJointIndex(); + skeletonModel->getJointRotation(jointIndex, rotation, true); + rotation = inverseRotation * rotation * glm::quat(glm::vec3(0.0f, -PI_OVER_TWO, 0.0f)); + + } else { + jointIndex = skeletonModel->getRightHandJointIndex(); + skeletonModel->getJointRotation(jointIndex, rotation, true); + rotation = inverseRotation * rotation * glm::quat(glm::vec3(0.0f, PI_OVER_TWO, 0.0f)); + } + skeletonModel->getJointPosition(jointIndex, position); + position = inverseRotation * (position - skeletonModel->getTranslation()); + + palm->setRawRotation(rotation); + + // Compute current velocity from position change + glm::vec3 rawVelocity; + if (deltaTime > 0.f) { + rawVelocity = (position - palm->getRawPosition()) / deltaTime; + } else { + rawVelocity = glm::vec3(0.0f); + } + palm->setRawVelocity(rawVelocity); + palm->setRawPosition(position); + + // 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.f) { + palm->setTipVelocity((newTipPosition - oldTipPosition) / deltaTime); + } else { + palm->setTipVelocity(glm::vec3(0.f)); + } + palm->setTipPosition(newTipPosition); +} #endif PrioVR::PrioVR() { @@ -78,7 +159,7 @@ glm::quat PrioVR::getTorsoRotation() const { return _jointRotations.size() > TORSO_ROTATION_INDEX ? _jointRotations.at(TORSO_ROTATION_INDEX) : glm::quat(); } -void PrioVR::update() { +void PrioVR::update(float deltaTime) { #ifdef HAVE_PRIOVR if (!_skeletalDevice) { return; @@ -96,6 +177,10 @@ void PrioVR::update() { _lastJointRotations[i] = _jointRotations.at(i); _jointRotations[i] = safeMix(lastRotation, _jointRotations.at(i), 0.5f); } + + // convert the joysticks into palm data + setPalm(deltaTime, 0); + setPalm(deltaTime, 1); #endif } diff --git a/interface/src/devices/PrioVR.h b/interface/src/devices/PrioVR.h index 8f01574356..bb563bf807 100644 --- a/interface/src/devices/PrioVR.h +++ b/interface/src/devices/PrioVR.h @@ -43,7 +43,7 @@ public: const QVector& getHumanIKJointIndices() const { return _humanIKJointIndices; } const QVector& getJointRotations() const { return _jointRotations; } - void update(); + void update(float deltaTime); void reset(); private slots: diff --git a/interface/src/scripting/ControllerScriptingInterface.cpp b/interface/src/scripting/ControllerScriptingInterface.cpp index 286d55081d..34c1cc2f1c 100644 --- a/interface/src/scripting/ControllerScriptingInterface.cpp +++ b/interface/src/scripting/ControllerScriptingInterface.cpp @@ -74,6 +74,7 @@ bool ControllerScriptingInterface::isPrimaryButtonPressed() const { return true; } } + return false; } From 956c5d2eb67310d7b0c822a4cca74780e610d2c9 Mon Sep 17 00:00:00 2001 From: Andrzej Kapolka Date: Fri, 16 May 2014 14:24:49 -0700 Subject: [PATCH 14/14] More joystick fixes. --- interface/src/Application.cpp | 1 + interface/src/devices/PrioVR.cpp | 18 ++++++++---------- 2 files changed, 9 insertions(+), 10 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 9f391aa36b..fc23a50f7b 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -1990,6 +1990,7 @@ void Application::update(float deltaTime) { _myAvatar->updateLookAtTargetAvatar(); updateMyAvatarLookAtPosition(); _sixenseManager.update(deltaTime); + _joystickManager.update(); _prioVR.update(deltaTime); updateMyAvatar(deltaTime); // Sample hardware, update view frustum if needed, and send avatar data to mixer/nodes updateThreads(deltaTime); // If running non-threaded, then give the threads some time to process... diff --git a/interface/src/devices/PrioVR.cpp b/interface/src/devices/PrioVR.cpp index f38a2964b4..deba4f82a5 100644 --- a/interface/src/devices/PrioVR.cpp +++ b/interface/src/devices/PrioVR.cpp @@ -63,7 +63,7 @@ static void setPalm(float deltaTime, int index) { if (!Application::getInstance()->getJoystickManager()->getJoystickStates().isEmpty()) { const JoystickState& state = Application::getInstance()->getJoystickManager()->getJoystickStates().at(0); if (state.axes.size() >= 4 && state.buttons.size() >= 4) { - if (index == 0) { + if (index == SIXENSE_CONTROLLER_ID_LEFT_HAND) { palm->setControllerButtons(state.buttons.at(1) ? BUTTON_FWD : 0); palm->setTrigger(state.buttons.at(0) ? 1.0f : 0.0f); palm->setJoystick(state.axes.at(0), -state.axes.at(1)); @@ -71,7 +71,7 @@ static void setPalm(float deltaTime, int index) { } else { palm->setControllerButtons(state.buttons.at(3) ? BUTTON_FWD : 0); palm->setTrigger(state.buttons.at(2) ? 1.0f : 0.0f); - palm->setJoystick(state.axes.at(2), -state.axes.at(3)); + palm->setJoystick(state.axes.at(2), -state.axes.at(3)); } } } @@ -81,16 +81,16 @@ static void setPalm(float deltaTime, int index) { Model* skeletonModel = &Application::getInstance()->getAvatar()->getSkeletonModel(); int jointIndex; - glm::quat inverseRotation = glm::inverse(skeletonModel->getRotation()); - if (index == 0) { + glm::quat inverseRotation = glm::inverse(Application::getInstance()->getAvatar()->getOrientation()); + if (index == SIXENSE_CONTROLLER_ID_LEFT_HAND) { jointIndex = skeletonModel->getLeftHandJointIndex(); skeletonModel->getJointRotation(jointIndex, rotation, true); - rotation = inverseRotation * rotation * glm::quat(glm::vec3(0.0f, -PI_OVER_TWO, 0.0f)); + rotation = inverseRotation * rotation * glm::quat(glm::vec3(0.0f, PI_OVER_TWO, 0.0f)); } else { jointIndex = skeletonModel->getRightHandJointIndex(); skeletonModel->getJointRotation(jointIndex, rotation, true); - rotation = inverseRotation * rotation * glm::quat(glm::vec3(0.0f, PI_OVER_TWO, 0.0f)); + rotation = inverseRotation * rotation * glm::quat(glm::vec3(0.0f, -PI_OVER_TWO, 0.0f)); } skeletonModel->getJointPosition(jointIndex, position); position = inverseRotation * (position - skeletonModel->getTranslation()); @@ -134,8 +134,6 @@ PrioVR::PrioVR() { for (int i = 0; i < LIST_LENGTH; i++) { _humanIKJointIndices.append(jointsDiscovered[i] ? indexOfHumanIKJoint(JOINT_NAMES[i]) : -1); } - const int INITIAL_RESET_DELAY = 5000; - QTimer::singleShot(INITIAL_RESET_DELAY, this, SLOT(reset())); #endif } @@ -182,8 +180,8 @@ void PrioVR::update(float deltaTime) { } // convert the joysticks into palm data - setPalm(deltaTime, 0); - setPalm(deltaTime, 1); + setPalm(deltaTime, SIXENSE_CONTROLLER_ID_LEFT_HAND); + setPalm(deltaTime, SIXENSE_CONTROLLER_ID_RIGHT_HAND); #endif }