From 8538c700b5dfc16a0582aa5c0d33a5585887a722 Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Thu, 25 May 2017 21:41:41 +0100 Subject: [PATCH 1/7] saving head work --- interface/resources/controllers/vive.json | 22 ++++---- plugins/openvr/src/ViveControllerManager.cpp | 53 ++++++++++++++++++-- plugins/openvr/src/ViveControllerManager.h | 26 +++++----- 3 files changed, 70 insertions(+), 31 deletions(-) diff --git a/interface/resources/controllers/vive.json b/interface/resources/controllers/vive.json index 591b6f515e..984f9c65fb 100644 --- a/interface/resources/controllers/vive.json +++ b/interface/resources/controllers/vive.json @@ -34,36 +34,32 @@ { "from": "Vive.RSCenter", "to": "Standard.RightPrimaryThumb" }, { "from": "Vive.RightApplicationMenu", "to": "Standard.RightSecondaryThumb" }, - { "from": "Vive.LeftHand", "to": "Standard.LeftHand", "when": [ "Application.InHMD" ] }, - { "from": "Vive.RightHand", "to": "Standard.RightHand", "when": [ "Application.InHMD" ] }, + { "from": "Vive.LeftHand", "to": "Standard.LeftHand" }, + { "from": "Vive.RightHand", "to": "Standard.RightHand" }, { "from": "Vive.LeftFoot", "to" : "Standard.LeftFoot", - "filters" : [{"type" : "lowVelocity", "rotation" : 1.0, "translation": 1.0}], - "when": [ "Application.InHMD"] + "filters" : [{"type" : "lowVelocity", "rotation" : 1.0, "translation": 1.0}] }, { "from": "Vive.RightFoot", "to" : "Standard.RightFoot", - "filters" : [{"type" : "lowVelocity", "rotation" : 1.0, "translation": 1.0}], - "when": [ "Application.InHMD"] + "filters" : [{"type" : "lowVelocity", "rotation" : 1.0, "translation": 1.0}] }, { "from": "Vive.Hips", "to" : "Standard.Hips", - "filters" : [{"type" : "lowVelocity", "rotation" : 0.01, "translation": 0.01}], - "when": [ "Application.InHMD"] + "filters" : [{"type" : "lowVelocity", "rotation" : 0.01, "translation": 0.01}] }, { "from": "Vive.Spine2", "to" : "Standard.Spine2", - "filters" : [{"type" : "lowVelocity", "rotation" : 0.01, "translation": 0.01}], - "when": [ "Application.InHMD"] + "filters" : [{"type" : "lowVelocity", "rotation" : 0.01, "translation": 0.01}] }, - { "from": "Vive.Head", "to" : "Standard.Head", "when" : [ "Application.InHMD"] }, + { "from": "Vive.Head", "to" : "Standard.Head"}, - { "from": "Vive.RightArm", "to" : "Standard.RightArm", "when" : [ "Application.InHMD"] }, - { "from": "Vive.LeftArm", "to" : "Standard.LeftArm", "when" : [ "Application.InHMD"] } + { "from": "Vive.RightArm", "to" : "Standard.RightArm"}, + { "from": "Vive.LeftArm", "to" : "Standard.LeftArm"} ] } diff --git a/plugins/openvr/src/ViveControllerManager.cpp b/plugins/openvr/src/ViveControllerManager.cpp index 016b2a1c55..a9bc066dc2 100644 --- a/plugins/openvr/src/ViveControllerManager.cpp +++ b/plugins/openvr/src/ViveControllerManager.cpp @@ -51,8 +51,7 @@ static const int MIN_PUCK_COUNT = 2; static const int MIN_FEET_AND_HIPS = 3; static const int MIN_FEET_HIPS_CHEST = 4; static const int MIN_FEET_HIPS_SHOULDERS = 5; -static const int MIN_FEET_HIPS_CHEST_AND_HANDS = 6; -static const int MIN_FEET_HIPS_SHOULDERS_AND_HANDS = 7; +static const int MIN_FEET_HIPS_CHEST_HEAD = 5; static const int FIRST_FOOT = 0; static const int SECOND_FOOT = 1; static const int HIP = 2; @@ -177,6 +176,7 @@ ViveControllerManager::InputDevice::InputDevice(vr::IVRSystem*& system) : contro _configStringMap[Config::FeetAndHips] = QString("FeetAndHips"); _configStringMap[Config::FeetHipsAndChest] = QString("FeetHipsAndChest"); _configStringMap[Config::FeetHipsAndShoulders] = QString("FeetHipsAndShoulders"); + _configStringMap[Config::FeetHipsChestAndHead] = QString("FeetHipsChestAndHead"); if (openVrSupported()) { createPreferences(); @@ -351,12 +351,18 @@ void ViveControllerManager::InputDevice::calibrate(const controller::InputCalibr calibrateFeet(defaultToReferenceMat, inputCalibration); calibrateHips(defaultToReferenceMat, inputCalibration); calibrateChest(defaultToReferenceMat, inputCalibration); - } else if (_config == Config::FeetHipsAndShoulders && puckCount >= MIN_FEET_HIPS_SHOULDERS){ + } else if (_config == Config::FeetHipsAndShoulders && puckCount >= MIN_FEET_HIPS_SHOULDERS) { calibrateFeet(defaultToReferenceMat, inputCalibration); calibrateHips(defaultToReferenceMat, inputCalibration); int firstShoulderIndex = 3; int secondShoulderIndex = 4; calibrateShoulders(defaultToReferenceMat, inputCalibration, firstShoulderIndex, secondShoulderIndex); + } else if (_config == Config::FeetHipsChestAndHead && puckCount == MIN_FEET_HIPS_CHEST_HEAD) { + glm::mat4 headPuckDefaultToReferenceMat = recalculateDefaultToReferenceForHeadPuck(inputCalibration); + calibrateFeet(headPuckDefaultToReferenceMat, inputCalibration); + calibrateHips(headPuckDefaultToReferenceMat, inputCalibration); + calibrateChest(headPuckDefaultToReferenceMat, inputCalibration); + calibrateHead(headPuckDefaultToReferenceMat, inputCalibration); } else { qDebug() << "Puck Calibration: " << configToString(_config) << " Config Failed: Could not meet the minimal # of pucks"; uncalibrate(); @@ -371,6 +377,7 @@ void ViveControllerManager::InputDevice::uncalibrate() { _pucksOffset.clear(); _jointToPuckMap.clear(); _calibrated = false; + _overrideHead = false; } void ViveControllerManager::InputDevice::updateCalibratedLimbs() { @@ -380,6 +387,10 @@ void ViveControllerManager::InputDevice::updateCalibratedLimbs() { _poseStateMap[controller::SPINE2] = addOffsetToPuckPose(controller::SPINE2); _poseStateMap[controller::RIGHT_ARM] = addOffsetToPuckPose(controller::RIGHT_ARM); _poseStateMap[controller::LEFT_ARM] = addOffsetToPuckPose(controller::LEFT_ARM); + + if (_overrideHead) { + _poseStateMap[controller::HEAD] = addOffsetToPuckPose(controller::HEAD); + } } controller::Pose ViveControllerManager::InputDevice::addOffsetToPuckPose(int joint) const { @@ -445,6 +456,27 @@ void ViveControllerManager::InputDevice::handleHandController(float deltaTime, u } } +glm::mat4 ViveControllerManager::InputDevice::recalculateDefaultToReferenceForHeadPuck(const controller::InputCalibrationData& inputCalibration) { + size_t headPuckIndex = _validTrackedObjects.size() - 1; + controller::Pose headPuckPose = _validTrackedObjects[headPuckIndex].second; + + // make the head puck rotation to match the default head rotation + glm::quat headPuckRotation = cancelOutRollAndPitch(headPuckPose.getRotation()); + glm::quat defaultHeadRotation = glmExtractRotation(inputCalibration.defaultHeadMat); + glm::quat defaultRotationOffset = glm::inverse(headPuckRotation) * defaultHeadRotation; + glm::quat finalHeadPuckRotation = defaultRotationOffset * headPuckRotation; + glm::vec3 headPuckTranslation = headPuckPose.getTranslation(); + glm::mat4 headPuckMat = createMatFromQuatAndPos(finalHeadPuckRotation, headPuckTranslation); + + // calculate the offset from the centerOfEye to defaultHeadMat + glm::mat4 defaultHeadOffset = glm::inverse(inputCalibration.defaultCenterEyeMat) * inputCalibration.defaultHeadMat; + + glm::mat4 currentHead = headPuckMat * defaultHeadOffset; + + // calculate the defaultToRefrenceXform + return currentHead * glm::inverse(inputCalibration.defaultHeadMat); +} + void ViveControllerManager::InputDevice::partitionTouchpad(int sButton, int xAxis, int yAxis, int centerPseudoButton, int xPseudoButton, int yPseudoButton) { // Populate the L/RS_CENTER/OUTER pseudo buttons, corresponding to a partition of the L/RS space based on the X/Y values. const float CENTER_DEADBAND = 0.6f; @@ -664,7 +696,16 @@ void ViveControllerManager::InputDevice::calibrateShoulders(glm::mat4& defaultTo } void ViveControllerManager::InputDevice::calibrateHead(glm::mat4& defaultToReferenceMat, const controller::InputCalibrationData& inputCalibration) { - int headIndex = _validTrackedObjects.size() - 1; + size_t headIndex = _validTrackedObjects.size() - 1; + const PuckPosePair& head = _validTrackedObjects[headIndex]; + + // assume the person is wearing the head puck on his/her forehead + glm::mat4 defaultHeadOffset = glm::inverse(inputCalibration.defaultCenterEyeMat) * inputCalibration.defaultHeadMat; + controller::Pose newHead = head.second.postTransform(defaultHeadOffset); + + _jointToPuckMap[controller::HEAD] = head.first; + _pucksOffset[head.first] = computeOffset(defaultToReferenceMat, inputCalibration.defaultHeadMat, newHead); + _overrideHead = true; } @@ -701,6 +742,8 @@ void ViveControllerManager::InputDevice::setConfigFromString(const QString& valu _preferedConfig = Config::FeetHipsAndChest; } else if (value == "FeetHipsAndShoulders") { _preferedConfig = Config::FeetHipsAndShoulders; + } else if (value == "FeetHipsChestAndHead") { + _preferedConfig = Config::FeetHipsChestAndHead; } } @@ -713,7 +756,7 @@ void ViveControllerManager::InputDevice::createPreferences() { auto getter = [this]()->QString { return _configStringMap[_preferedConfig]; }; auto setter = [this](const QString& value) { setConfigFromString(value); saveSettings(); }; auto preference = new ComboBoxPreference(VIVE_PUCKS_CONFIG, "Configuration", getter, setter); - QStringList list = (QStringList() << "Auto" << "Feet" << "FeetAndHips" << "FeetHipsAndChest" << "FeetHipsAndShoulders"); + QStringList list = (QStringList() << "Feet" << "FeetAndHips" << "FeetHipsAndChest" << "FeetHipsAndShoulders" << "FeetHipsChestAndHead"); preference->setItems(list); preferences->addPreference(preference); diff --git a/plugins/openvr/src/ViveControllerManager.h b/plugins/openvr/src/ViveControllerManager.h index bc9558beaa..f3b87ea3a0 100644 --- a/plugins/openvr/src/ViveControllerManager.h +++ b/plugins/openvr/src/ViveControllerManager.h @@ -67,6 +67,7 @@ private: void calibrate(const controller::InputCalibrationData& inputCalibration); void uncalibrate(); controller::Pose addOffsetToPuckPose(int joint) const; + glm::mat4 recalculateDefaultToReferenceForHeadPuck(const controller::InputCalibrationData& inputCalibration); void updateCalibratedLimbs(); bool checkForCalibrationEvent(); void handleHandController(float deltaTime, uint32_t deviceIndex, const controller::InputCalibrationData& inputCalibrationData, bool isLeftHand); @@ -80,6 +81,17 @@ private: const vec3& angularVelocity); void partitionTouchpad(int sButton, int xAxis, int yAxis, int centerPsuedoButton, int xPseudoButton, int yPseudoButton); void printDeviceTrackingResultChange(uint32_t deviceIndex); + void setConfigFromString(const QString& value); + void loadSettings(); + void saveSettings() const; + void calibrateFeet(glm::mat4& defaultToReferenceMat, const controller::InputCalibrationData& inputCalibration); + void calibrateHips(glm::mat4& defaultToReferenceMat, const controller::InputCalibrationData& inputCalibration); + void calibrateChest(glm::mat4& defaultToReferenceMat, const controller::InputCalibrationData& inputCalibration); + + void calibrateShoulders(glm::mat4& defaultToReferenceMat, const controller::InputCalibrationData& inputCalibration, + int firstShoulderIndex, int secondShoulderIndex); + + void calibrateHead(glm::mat4& defaultToReferenceMat, const controller::InputCalibrationData& inputCalibration); class FilteredStick { public: @@ -106,9 +118,7 @@ private: }; enum class Config { Auto, - Head, Feet, - Shoulders, FeetAndHips, FeetHipsAndChest, FeetHipsAndShoulders, @@ -139,21 +149,11 @@ private: bool _triggersPressedHandled { false }; bool _calibrated { false }; bool _timeTilCalibrationSet { false }; - bool overrideHands { false }; + bool _overrideHead { false }; mutable std::recursive_mutex _lock; QString configToString(Config config); - void setConfigFromString(const QString& value); - void loadSettings(); - void saveSettings() const; - void calibrateFeet(glm::mat4& defaultToReferenceMat, const controller::InputCalibrationData& inputCalibration); - void calibrateHips(glm::mat4& defaultToReferenceMat, const controller::InputCalibrationData& inputCalibration); - void calibrateChest(glm::mat4& defaultToReferenceMat, const controller::InputCalibrationData& inputCalibration); - void calibrateShoulders(glm::mat4& defaultToReferenceMat, const controller::InputCalibrationData& inputCalibration, - int firstShoulderIndex, int secondShoulderIndex); - - void calibrateHead(glm::mat4& defaultToReferenceMat, const controller::InputCalibrationData& inputCalibration); friend class ViveControllerManager; }; From 4c4811dca82ea881bdf19d07dd581d179b807194 Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Tue, 30 May 2017 22:52:39 +0100 Subject: [PATCH 2/7] finished the head puck --- libraries/shared/src/GLMHelpers.h | 3 +- plugins/openvr/src/ViveControllerManager.cpp | 78 +++++++++++++++++--- plugins/openvr/src/ViveControllerManager.h | 1 + 3 files changed, 70 insertions(+), 12 deletions(-) diff --git a/libraries/shared/src/GLMHelpers.h b/libraries/shared/src/GLMHelpers.h index 5574007b9b..ef92552d1f 100644 --- a/libraries/shared/src/GLMHelpers.h +++ b/libraries/shared/src/GLMHelpers.h @@ -147,8 +147,7 @@ bool isPointBehindTrianglesPlane(glm::vec3 point, glm::vec3 p0, glm::vec3 p1, gl glm::vec3 extractTranslation(const glm::mat4& matrix); -void setTranslation(glm::mat4& matrix, cons - t glm::vec3& translation); +void setTranslation(glm::mat4& matrix, const glm::vec3& translation); glm::quat extractRotation(const glm::mat4& matrix, bool assumeOrthogonal = false); glm::quat glmExtractRotation(const glm::mat4& matrix); diff --git a/plugins/openvr/src/ViveControllerManager.cpp b/plugins/openvr/src/ViveControllerManager.cpp index 0f0cc5860e..82457928a2 100644 --- a/plugins/openvr/src/ViveControllerManager.cpp +++ b/plugins/openvr/src/ViveControllerManager.cpp @@ -82,6 +82,28 @@ static bool sortPucksXPosition(PuckPosePair firstPuck, PuckPosePair secondPuck) return (firstPuck.second.translation.x < secondPuck.second.translation.x); } +static bool comparePosePositions(const controller::Pose& poseA, const controller::Pose& poseB, glm::vec3 axis, glm::vec3 axisOrigin) { + glm::vec3 poseAPosition = poseA.getTranslation(); + glm::vec3 poseBPosition = poseB.getTranslation(); + + glm::vec3 poseAFinalPosition = poseAPosition - axisOrigin; + glm::vec3 poseBFinalPosition = poseBPosition - axisOrigin; + + float poseADistance = glm::dot(poseAFinalPosition, axis); + float poseBDistance = glm::dot(poseBFinalPosition, axis); + return (poseADistance > poseBDistance); +} + +static glm::vec3 getHeadXAxis(glm::mat4 defaultToReferenceMat, glm::mat4 defaultHead) { + glm::mat4 finalHead = defaultToReferenceMat * defaultHead; + return glmExtractRotation(finalHead) * Vectors::UNIT_X; +} + +static glm::vec3 getHeadPosition(glm::mat4 defaultToReferenceMat, glm::mat4 defaultHead) { + glm::mat4 finalHead = defaultToReferenceMat * defaultHead; + return extractTranslation(finalHead); +} + static QString deviceTrackingResultToString(vr::ETrackingResult trackingResult) { QString result; auto iterator = TRACKING_RESULT_TO_STRING.find(trackingResult); @@ -361,12 +383,16 @@ void ViveControllerManager::InputDevice::calibrate(const controller::InputCalibr calibrateShoulders(defaultToReferenceMat, inputCalibration, firstShoulderIndex, secondShoulderIndex); } else if (_config == Config::FeetHipsAndHead && puckCount == MIN_FEET_HIPS_HEAD) { glm::mat4 headPuckDefaultToReferenceMat = recalculateDefaultToReferenceForHeadPuck(inputCalibration); - calibrateFeet(headPuckDefaultToReferenceMat, inputCalibration); + glm::vec3 headXAxis = getHeadXAxis(headPuckDefaultToReferenceMat, inputCalibration.defaultHeadMat); + glm::vec3 headPosition = getHeadPosition(headPuckDefaultToReferenceMat, inputCalibration.defaultHeadMat); + calibrateFeet(headPuckDefaultToReferenceMat, inputCalibration, headXAxis, headPosition); calibrateHips(headPuckDefaultToReferenceMat, inputCalibration); calibrateHead(headPuckDefaultToReferenceMat, inputCalibration); } else if (_config == Config::FeetHipsChestAndHead && puckCount == MIN_FEET_HIPS_CHEST_HEAD) { glm::mat4 headPuckDefaultToReferenceMat = recalculateDefaultToReferenceForHeadPuck(inputCalibration); - calibrateFeet(headPuckDefaultToReferenceMat, inputCalibration); + glm::vec3 headXAxis = getHeadXAxis(headPuckDefaultToReferenceMat, inputCalibration.defaultHeadMat); + glm::vec3 headPosition = getHeadPosition(headPuckDefaultToReferenceMat, inputCalibration.defaultHeadMat); + calibrateFeet(headPuckDefaultToReferenceMat, inputCalibration, headXAxis, headPosition); calibrateHips(headPuckDefaultToReferenceMat, inputCalibration); calibrateChest(headPuckDefaultToReferenceMat, inputCalibration); calibrateHead(headPuckDefaultToReferenceMat, inputCalibration); @@ -468,17 +494,29 @@ glm::mat4 ViveControllerManager::InputDevice::recalculateDefaultToReferenceForHe glm::mat4 sensorToAvatarMat = glm::inverse(inputCalibration.avatarMat) * inputCalibration.sensorToWorldMat; size_t headPuckIndex = _validTrackedObjects.size() - 1; controller::Pose headPuckPose = _validTrackedObjects[headPuckIndex].second; - glm::mat4 headPuckSensorMat = avatarToSensorMat * createMatFromQuatAndPos(headPuckPose.getRotation(), headPuckPose.getTranslation()); - glm::vec3 headPuckTranslation = extractTranslation(headPuckSensorMat); - glm::vec3 headPuckYRotation = glmExtractRotation(headPuckSensorMat) * glm::vec3(0.0f, 1.0f, 0.0f); + glm::mat4 headPuckAvatarMat = createMatFromQuatAndPos(headPuckPose.getRotation(), headPuckPose.getTranslation()) * Matrices::Y_180; + glm::vec3 headPuckTranslation = extractTranslation(headPuckAvatarMat); + glm::vec3 headPuckZAxis = cancelOutRollAndPitch(glmExtractRotation(headPuckAvatarMat)) * glm::vec3(0.0f, 0.0f, 1.0f); glm::vec3 worldUp = glm::vec3(0.0f, 1.0f, 0.0f); - glm::vec3 desiredY = glm::vec3(0.0f, 1.0f, 0.0f); - glm::vec3 xPrime = glm::normalize(glm::cross(worldUp, headPuckYRotation)); - glm::vec3 zPrime = glm::normalize(glm::cross(xPrime, desiredY)); + glm::vec3 yPrime = glm::vec3(0.0f, 1.0f, 0.0f); + glm::vec3 xPrime = glm::normalize(glm::cross(worldUp, headPuckZAxis)); + glm::vec3 zPrime = glm::normalize(glm::cross(xPrime, yPrime)); + glm::mat4 newHeadPuck = glm::mat4(glm::vec4(xPrime, 0.0f), glm::vec4(yPrime, 0.0f), + glm::vec4(zPrime, 0.0f), glm::vec4(headPuckTranslation, 1.0f)); - glm::mat4 - return glm::mat4(); + glm::mat4 headPuckOffset = glm::mat4(glm::vec4(1.0f, 0.0f, 0.0f, 0.0f), glm::vec4(0.0f, 1.0f, 0.0f, 0.0f), + glm::vec4(0.0f, 0.0f, 1.0f, 0.0f), glm::vec4(0.0f, -0.005f, 0.0f, 1.0f)); + + glm::mat4 finalHeadPuck = newHeadPuck * headPuckOffset; + + glm::mat4 defaultHeadOffset = glm::inverse(inputCalibration.defaultCenterEyeMat) * inputCalibration.defaultHeadMat; + + glm::mat4 currentHead = finalHeadPuck * defaultHeadOffset; + + // calculate the defaultToRefrenceXform + glm::mat4 defaultToReferenceMat = currentHead * glm::inverse(inputCalibration.defaultHeadMat); + return defaultToReferenceMat; } void ViveControllerManager::InputDevice::partitionTouchpad(int sButton, int xAxis, int yAxis, int centerPseudoButton, int xPseudoButton, int yPseudoButton) { @@ -668,6 +706,26 @@ void ViveControllerManager::InputDevice::calibrateFeet(glm::mat4& defaultToRefer } } + +void ViveControllerManager::InputDevice::calibrateFeet(glm::mat4& defaultToReferenceMat, const controller::InputCalibrationData& inputCalibration, glm::vec3 headXAxis, glm::vec3 headPosition) { + auto& firstFoot = _validTrackedObjects[FIRST_FOOT]; + auto& secondFoot = _validTrackedObjects[SECOND_FOOT]; + controller::Pose& firstFootPose = firstFoot.second; + controller::Pose& secondFootPose = secondFoot.second; + + if (comparePosePositions(firstFootPose, secondFootPose, headXAxis, headPosition)) { + _jointToPuckMap[controller::LEFT_FOOT] = firstFoot.first; + _pucksOffset[firstFoot.first] = computeOffset(defaultToReferenceMat, inputCalibration.defaultLeftFoot, firstFootPose); + _jointToPuckMap[controller::RIGHT_FOOT] = secondFoot.first; + _pucksOffset[secondFoot.first] = computeOffset(defaultToReferenceMat, inputCalibration.defaultRightFoot, secondFootPose); + } else { + _jointToPuckMap[controller::LEFT_FOOT] = secondFoot.first; + _pucksOffset[secondFoot.first] = computeOffset(defaultToReferenceMat, inputCalibration.defaultLeftFoot, secondFootPose); + _jointToPuckMap[controller::RIGHT_FOOT] = firstFoot.first; + _pucksOffset[firstFoot.first] = computeOffset(defaultToReferenceMat, inputCalibration.defaultRightFoot, firstFootPose); + } +} + void ViveControllerManager::InputDevice::calibrateHips(glm::mat4& defaultToReferenceMat, const controller::InputCalibrationData& inputCalibration) { _jointToPuckMap[controller::HIPS] = _validTrackedObjects[HIP].first; _pucksOffset[_validTrackedObjects[HIP].first] = computeOffset(defaultToReferenceMat, inputCalibration.defaultHips, _validTrackedObjects[HIP].second); diff --git a/plugins/openvr/src/ViveControllerManager.h b/plugins/openvr/src/ViveControllerManager.h index 545af1b00b..c32579b0d8 100644 --- a/plugins/openvr/src/ViveControllerManager.h +++ b/plugins/openvr/src/ViveControllerManager.h @@ -85,6 +85,7 @@ private: void loadSettings(); void saveSettings() const; void calibrateFeet(glm::mat4& defaultToReferenceMat, const controller::InputCalibrationData& inputCalibration); + void calibrateFeet(glm::mat4& defaultToReferenceMat, const controller::InputCalibrationData& inputCalibration, glm::vec3 headXAxis, glm::vec3 headPosition); void calibrateHips(glm::mat4& defaultToReferenceMat, const controller::InputCalibrationData& inputCalibration); void calibrateChest(glm::mat4& defaultToReferenceMat, const controller::InputCalibrationData& inputCalibration); From 9c787eb784326adc4f650dc113fe03bf400a445b Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Tue, 30 May 2017 22:59:12 +0100 Subject: [PATCH 3/7] removed commented code --- scripts/defaultScripts.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/defaultScripts.js b/scripts/defaultScripts.js index db0b705f8e..81ce72d901 100644 --- a/scripts/defaultScripts.js +++ b/scripts/defaultScripts.js @@ -13,7 +13,7 @@ var DEFAULT_SCRIPTS_COMBINED = [ "system/progress.js", - //"system/away.js", + "system/away.js", "system/audio.js", "system/hmd.js", "system/menu.js", From b3401d97629a6544358b2c908ff43349268f091e Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Tue, 30 May 2017 23:55:45 +0100 Subject: [PATCH 4/7] making some final changes --- interface/resources/controllers/vive.json | 22 ++++++++++++-------- plugins/openvr/src/ViveControllerManager.cpp | 2 +- 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/interface/resources/controllers/vive.json b/interface/resources/controllers/vive.json index 984f9c65fb..a0e9bd30d4 100644 --- a/interface/resources/controllers/vive.json +++ b/interface/resources/controllers/vive.json @@ -34,32 +34,36 @@ { "from": "Vive.RSCenter", "to": "Standard.RightPrimaryThumb" }, { "from": "Vive.RightApplicationMenu", "to": "Standard.RightSecondaryThumb" }, - { "from": "Vive.LeftHand", "to": "Standard.LeftHand" }, - { "from": "Vive.RightHand", "to": "Standard.RightHand" }, + { "from": "Vive.LeftHand", "to": "Standard.LeftHand", "when": [ "Application.InHMD" ] }, + { "from": "Vive.RightHand", "to": "Standard.RightHand", "when": [ "Application.InHMD" ] }, { "from": "Vive.LeftFoot", "to" : "Standard.LeftFoot", - "filters" : [{"type" : "lowVelocity", "rotation" : 1.0, "translation": 1.0}] + "filters" : [{"type" : "lowVelocity", "rotation" : 1.0, "translation": 1.0}], + "when": [ "Application.InHMD" ] }, { "from": "Vive.RightFoot", "to" : "Standard.RightFoot", - "filters" : [{"type" : "lowVelocity", "rotation" : 1.0, "translation": 1.0}] + "filters" : [{"type" : "lowVelocity", "rotation" : 1.0, "translation": 1.0}], + "when": [ "Application.InHMD" ] }, { "from": "Vive.Hips", "to" : "Standard.Hips", - "filters" : [{"type" : "lowVelocity", "rotation" : 0.01, "translation": 0.01}] + "filters" : [{"type" : "lowVelocity", "rotation" : 0.01, "translation": 0.01}], + "when": [ "Application.InHMD" ] }, { "from": "Vive.Spine2", "to" : "Standard.Spine2", - "filters" : [{"type" : "lowVelocity", "rotation" : 0.01, "translation": 0.01}] + "filters" : [{"type" : "lowVelocity", "rotation" : 0.01, "translation": 0.01}], + "when": [ "Application.InHMD" ] }, - { "from": "Vive.Head", "to" : "Standard.Head"}, + { "from": "Vive.Head", "to" : "Standard.Head", "when": [ "Application.InHMD" ] }, - { "from": "Vive.RightArm", "to" : "Standard.RightArm"}, - { "from": "Vive.LeftArm", "to" : "Standard.LeftArm"} + { "from": "Vive.RightArm", "to" : "Standard.RightArm", "when": [ "Application.InHMD" ] }, + { "from": "Vive.LeftArm", "to" : "Standard.LeftArm", "when": [ "Application.InHMD" ] } ] } diff --git a/plugins/openvr/src/ViveControllerManager.cpp b/plugins/openvr/src/ViveControllerManager.cpp index 82457928a2..6edcbcb3fa 100644 --- a/plugins/openvr/src/ViveControllerManager.cpp +++ b/plugins/openvr/src/ViveControllerManager.cpp @@ -506,7 +506,7 @@ glm::mat4 ViveControllerManager::InputDevice::recalculateDefaultToReferenceForHe glm::vec4(zPrime, 0.0f), glm::vec4(headPuckTranslation, 1.0f)); glm::mat4 headPuckOffset = glm::mat4(glm::vec4(1.0f, 0.0f, 0.0f, 0.0f), glm::vec4(0.0f, 1.0f, 0.0f, 0.0f), - glm::vec4(0.0f, 0.0f, 1.0f, 0.0f), glm::vec4(0.0f, -0.005f, 0.0f, 1.0f)); + glm::vec4(0.0f, 0.0f, 1.0f, 0.0f), glm::vec4(0.0f, -0.0254f, -0.152f, 1.0f)); glm::mat4 finalHeadPuck = newHeadPuck * headPuckOffset; From 41869430f7dab1dc1eefb6a5788926c19f811305 Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Wed, 31 May 2017 01:29:32 +0100 Subject: [PATCH 5/7] made some changes that were requested --- plugins/openvr/src/ViveControllerManager.cpp | 33 +++++++++++--------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/plugins/openvr/src/ViveControllerManager.cpp b/plugins/openvr/src/ViveControllerManager.cpp index 6edcbcb3fa..e08929cf08 100644 --- a/plugins/openvr/src/ViveControllerManager.cpp +++ b/plugins/openvr/src/ViveControllerManager.cpp @@ -57,6 +57,8 @@ static const int FIRST_FOOT = 0; static const int SECOND_FOOT = 1; static const int HIP = 2; static const int CHEST = 3; +static const float HEAD_PUCK_Y_OFFSET = -0.0254f; +static const float HEAD_PUCK_Z_OFFSET = -0.152f; const char* ViveControllerManager::NAME { "OpenVR" }; @@ -82,24 +84,24 @@ static bool sortPucksXPosition(PuckPosePair firstPuck, PuckPosePair secondPuck) return (firstPuck.second.translation.x < secondPuck.second.translation.x); } -static bool comparePosePositions(const controller::Pose& poseA, const controller::Pose& poseB, glm::vec3 axis, glm::vec3 axisOrigin) { +static bool determineFeetOrdering(const controller::Pose& poseA, const controller::Pose& poseB, glm::vec3 axis, glm::vec3 axisOrigin) { glm::vec3 poseAPosition = poseA.getTranslation(); glm::vec3 poseBPosition = poseB.getTranslation(); - glm::vec3 poseAFinalPosition = poseAPosition - axisOrigin; - glm::vec3 poseBFinalPosition = poseBPosition - axisOrigin; + glm::vec3 poseAVector = poseAPosition - axisOrigin; + glm::vec3 poseBVector = poseBPosition - axisOrigin; - float poseADistance = glm::dot(poseAFinalPosition, axis); - float poseBDistance = glm::dot(poseBFinalPosition, axis); - return (poseADistance > poseBDistance); + float poseAProjection = glm::dot(poseAVector, axis); + float poseBProjection = glm::dot(poseBVector, axis); + return (poseAProjection > poseBProjection); } -static glm::vec3 getHeadXAxis(glm::mat4 defaultToReferenceMat, glm::mat4 defaultHead) { +static glm::vec3 getReferenceHeadXAxis(glm::mat4 defaultToReferenceMat, glm::mat4 defaultHead) { glm::mat4 finalHead = defaultToReferenceMat * defaultHead; return glmExtractRotation(finalHead) * Vectors::UNIT_X; } -static glm::vec3 getHeadPosition(glm::mat4 defaultToReferenceMat, glm::mat4 defaultHead) { +static glm::vec3 getReferenceHeadPosition(glm::mat4 defaultToReferenceMat, glm::mat4 defaultHead) { glm::mat4 finalHead = defaultToReferenceMat * defaultHead; return extractTranslation(finalHead); } @@ -383,19 +385,21 @@ void ViveControllerManager::InputDevice::calibrate(const controller::InputCalibr calibrateShoulders(defaultToReferenceMat, inputCalibration, firstShoulderIndex, secondShoulderIndex); } else if (_config == Config::FeetHipsAndHead && puckCount == MIN_FEET_HIPS_HEAD) { glm::mat4 headPuckDefaultToReferenceMat = recalculateDefaultToReferenceForHeadPuck(inputCalibration); - glm::vec3 headXAxis = getHeadXAxis(headPuckDefaultToReferenceMat, inputCalibration.defaultHeadMat); - glm::vec3 headPosition = getHeadPosition(headPuckDefaultToReferenceMat, inputCalibration.defaultHeadMat); + glm::vec3 headXAxis = getReferenceHeadXAxis(headPuckDefaultToReferenceMat, inputCalibration.defaultHeadMat); + glm::vec3 headPosition = getReferenceHeadPosition(headPuckDefaultToReferenceMat, inputCalibration.defaultHeadMat); calibrateFeet(headPuckDefaultToReferenceMat, inputCalibration, headXAxis, headPosition); calibrateHips(headPuckDefaultToReferenceMat, inputCalibration); calibrateHead(headPuckDefaultToReferenceMat, inputCalibration); + _overrideHead = true; } else if (_config == Config::FeetHipsChestAndHead && puckCount == MIN_FEET_HIPS_CHEST_HEAD) { glm::mat4 headPuckDefaultToReferenceMat = recalculateDefaultToReferenceForHeadPuck(inputCalibration); - glm::vec3 headXAxis = getHeadXAxis(headPuckDefaultToReferenceMat, inputCalibration.defaultHeadMat); - glm::vec3 headPosition = getHeadPosition(headPuckDefaultToReferenceMat, inputCalibration.defaultHeadMat); + glm::vec3 headXAxis = getReferenceHeadXAxis(headPuckDefaultToReferenceMat, inputCalibration.defaultHeadMat); + glm::vec3 headPosition = getReferenceHeadPosition(headPuckDefaultToReferenceMat, inputCalibration.defaultHeadMat); calibrateFeet(headPuckDefaultToReferenceMat, inputCalibration, headXAxis, headPosition); calibrateHips(headPuckDefaultToReferenceMat, inputCalibration); calibrateChest(headPuckDefaultToReferenceMat, inputCalibration); calibrateHead(headPuckDefaultToReferenceMat, inputCalibration); + _overrideHead = true; } else { qDebug() << "Puck Calibration: " << configToString(_config) << " Config Failed: Could not meet the minimal # of pucks"; uncalibrate(); @@ -506,7 +510,7 @@ glm::mat4 ViveControllerManager::InputDevice::recalculateDefaultToReferenceForHe glm::vec4(zPrime, 0.0f), glm::vec4(headPuckTranslation, 1.0f)); glm::mat4 headPuckOffset = glm::mat4(glm::vec4(1.0f, 0.0f, 0.0f, 0.0f), glm::vec4(0.0f, 1.0f, 0.0f, 0.0f), - glm::vec4(0.0f, 0.0f, 1.0f, 0.0f), glm::vec4(0.0f, -0.0254f, -0.152f, 1.0f)); + glm::vec4(0.0f, 0.0f, 1.0f, 0.0f), glm::vec4(0.0f, HEAD_PUCK_Y_OFFSET, HEAD_PUCK_Z_OFFSET, 1.0f)); glm::mat4 finalHeadPuck = newHeadPuck * headPuckOffset; @@ -713,7 +717,7 @@ void ViveControllerManager::InputDevice::calibrateFeet(glm::mat4& defaultToRefer controller::Pose& firstFootPose = firstFoot.second; controller::Pose& secondFootPose = secondFoot.second; - if (comparePosePositions(firstFootPose, secondFootPose, headXAxis, headPosition)) { + if (determineFeetOrdering(firstFootPose, secondFootPose, headXAxis, headPosition)) { _jointToPuckMap[controller::LEFT_FOOT] = firstFoot.first; _pucksOffset[firstFoot.first] = computeOffset(defaultToReferenceMat, inputCalibration.defaultLeftFoot, firstFootPose); _jointToPuckMap[controller::RIGHT_FOOT] = secondFoot.first; @@ -766,7 +770,6 @@ void ViveControllerManager::InputDevice::calibrateHead(glm::mat4& defaultToRefer _jointToPuckMap[controller::HEAD] = head.first; _pucksOffset[head.first] = computeOffset(defaultToReferenceMat, inputCalibration.defaultHeadMat, newHead); - _overrideHead = true; } From f4328af66f6d2535707a5bef5f86b438defe2761 Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Wed, 31 May 2017 17:12:27 +0100 Subject: [PATCH 6/7] made final requested changes --- plugins/openvr/src/ViveControllerManager.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/plugins/openvr/src/ViveControllerManager.cpp b/plugins/openvr/src/ViveControllerManager.cpp index e08929cf08..8ddf458210 100644 --- a/plugins/openvr/src/ViveControllerManager.cpp +++ b/plugins/openvr/src/ViveControllerManager.cpp @@ -503,6 +503,13 @@ glm::mat4 ViveControllerManager::InputDevice::recalculateDefaultToReferenceForHe glm::vec3 headPuckZAxis = cancelOutRollAndPitch(glmExtractRotation(headPuckAvatarMat)) * glm::vec3(0.0f, 0.0f, 1.0f); glm::vec3 worldUp = glm::vec3(0.0f, 1.0f, 0.0f); + // check that the head puck z axis is not parrallel to the world up + const float EPSILON = 1.0e-4f; + glm::vec3 zAxis = glmExtractRotation(headPuckAvatarMat) * glm::vec3(0.0f, 0.0f, 1.0f); + if (fabsf(fabsf(glm::dot(glm::normalize(worldUp), glm::normalize(zAxis))) - 1.0f) < EPSILON) { + headPuckZAxis = glm::vec3(1.0f, 0.0f, 0.0f); + } + glm::vec3 yPrime = glm::vec3(0.0f, 1.0f, 0.0f); glm::vec3 xPrime = glm::normalize(glm::cross(worldUp, headPuckZAxis)); glm::vec3 zPrime = glm::normalize(glm::cross(xPrime, yPrime)); From 7fcdc6124450e988df0a8900a9843edeb33816a0 Mon Sep 17 00:00:00 2001 From: Dante Ruiz Date: Wed, 31 May 2017 18:20:35 +0100 Subject: [PATCH 7/7] add head puck offset preference --- plugins/openvr/src/ViveControllerManager.cpp | 36 ++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/plugins/openvr/src/ViveControllerManager.cpp b/plugins/openvr/src/ViveControllerManager.cpp index 8ddf458210..5583ec6351 100644 --- a/plugins/openvr/src/ViveControllerManager.cpp +++ b/plugins/openvr/src/ViveControllerManager.cpp @@ -57,8 +57,8 @@ static const int FIRST_FOOT = 0; static const int SECOND_FOOT = 1; static const int HIP = 2; static const int CHEST = 3; -static const float HEAD_PUCK_Y_OFFSET = -0.0254f; -static const float HEAD_PUCK_Z_OFFSET = -0.152f; +static float HEAD_PUCK_Y_OFFSET = -0.0254f; +static float HEAD_PUCK_Z_OFFSET = -0.152f; const char* ViveControllerManager::NAME { "OpenVR" }; @@ -825,6 +825,38 @@ void ViveControllerManager::InputDevice::createPreferences() { auto preferences = DependencyManager::get(); static const QString VIVE_PUCKS_CONFIG = "Vive Pucks Configuration"; + { + static const float MIN_VALUE = -3.0f; + static const float MAX_VALUE = 3.0f; + static const float STEP = 0.01f; + + auto getter = [this]()->float { return HEAD_PUCK_Y_OFFSET; }; + auto setter = [this](const float& value) { HEAD_PUCK_Y_OFFSET = value; }; + + auto preference = new SpinnerPreference(VIVE_PUCKS_CONFIG, "HeadPuckYOffset", getter, setter); + preference->setMin(MIN_VALUE); + preference->setMax(MAX_VALUE); + preference->setDecimals(3); + preference->setStep(STEP); + preferences->addPreference(preference); + } + + { + static const float MIN_VALUE = -3.0f; + static const float MAX_VALUE = 3.0f; + static const float STEP = 0.01f; + + auto getter = [this]()->float { return HEAD_PUCK_Z_OFFSET; }; + auto setter = [this](const float& value) { HEAD_PUCK_Z_OFFSET = value; }; + + auto preference = new SpinnerPreference(VIVE_PUCKS_CONFIG, "HeadPuckXOffset", getter, setter); + preference->setMin(MIN_VALUE); + preference->setMax(MAX_VALUE); + preference->setStep(STEP); + preference->setDecimals(3); + preferences->addPreference(preference); + } + { auto getter = [this]()->QString { return _configStringMap[_preferedConfig]; }; auto setter = [this](const QString& value) { setConfigFromString(value); saveSettings(); };