diff --git a/interface/resources/qml/hifi/tablet/NewModelDialog.qml b/interface/resources/qml/hifi/tablet/NewModelDialog.qml index 2fa48cac07..5dbb733872 100644 --- a/interface/resources/qml/hifi/tablet/NewModelDialog.qml +++ b/interface/resources/qml/hifi/tablet/NewModelDialog.qml @@ -22,15 +22,20 @@ Rectangle { color: hifi.colors.baseGray; property var eventBridge; signal sendToScript(var message); + property bool keyboardEnabled: false + property bool punctuationMode: false + property bool keyboardRasied: false - Column { + Item { id: column1 anchors.rightMargin: 10 anchors.leftMargin: 10 anchors.bottomMargin: 10 anchors.topMargin: 10 - anchors.fill: parent - spacing: 5 + anchors.top: parent.top + anchors.left: parent.left + anchors.right: parent.right + anchors.bottom: keyboard.top Text { id: text1 @@ -43,17 +48,42 @@ Rectangle { id: modelURL height: 20 text: qsTr("") + color: "white" + anchors.top: text1.bottom + anchors.topMargin: 5 anchors.left: parent.left anchors.leftMargin: 0 anchors.right: parent.right anchors.rightMargin: 0 font.pixelSize: 12 + + onAccepted: { + newModelDialog.keyboardEnabled = false; + } + + MouseArea { + anchors.fill: parent + onClicked: { + newModelDialog.keyboardEnabled = HMD.active + parent.focus = true; + parent.forceActiveFocus() + } + } + } + + Rectangle { + id: textInputBox + color: "white" + anchors.fill: modelURL + opacity: 0.1 } Row { id: row1 height: 400 spacing: 30 + anchors.top: modelURL.top + anchors.topMargin: 25 anchors.left: parent.left anchors.leftMargin: 0 anchors.right: parent.right @@ -155,4 +185,15 @@ Rectangle { } } } + + Keyboard { + id: keyboard + raised: parent.keyboardEnabled + numeric: parent.punctuationMode + anchors { + bottom: parent.bottom + left: parent.left + right: parent.right + } + } } diff --git a/plugins/oculus/src/OculusControllerManager.cpp b/plugins/oculus/src/OculusControllerManager.cpp index 87c52de3e7..6445c3c891 100644 --- a/plugins/oculus/src/OculusControllerManager.cpp +++ b/plugins/oculus/src/OculusControllerManager.cpp @@ -33,6 +33,8 @@ static const char* MENU_PATH = "Avatar" ">" "Oculus Touch Controllers"; const char* OculusControllerManager::NAME = "Oculus"; +const quint64 LOST_TRACKING_DELAY = 3000000; + bool OculusControllerManager::isSupported() const { return oculusAvailable(); } @@ -207,9 +209,7 @@ void OculusControllerManager::RemoteDevice::focusOutEvent() { } void OculusControllerManager::TouchDevice::update(float deltaTime, const controller::InputCalibrationData& inputCalibrationData) { - _poseStateMap.clear(); _buttonPressedMap.clear(); - ovrSessionStatus status; if (!OVR_SUCCESS(ovr_GetSessionStatus(_parent._session, &status)) || (ovrFalse == status.HmdMounted)) { // if the HMD isn't on someone's head, don't take input from the controllers @@ -217,15 +217,33 @@ void OculusControllerManager::TouchDevice::update(float deltaTime, const control } int numTrackedControllers = 0; + quint64 currentTime = usecTimestampNow(); static const auto REQUIRED_HAND_STATUS = ovrStatus_OrientationTracked | ovrStatus_PositionTracked; auto tracking = ovr_GetTrackingState(_parent._session, 0, false); ovr_for_each_hand([&](ovrHandType hand) { ++numTrackedControllers; + int controller = (hand == ovrHand_Left ? controller::LEFT_HAND : controller::RIGHT_HAND); if (REQUIRED_HAND_STATUS == (tracking.HandStatusFlags[hand] & REQUIRED_HAND_STATUS)) { + _poseStateMap.erase(controller); handlePose(deltaTime, inputCalibrationData, hand, tracking.HandPoses[hand]); - } else { - _poseStateMap[hand == ovrHand_Left ? controller::LEFT_HAND : controller::RIGHT_HAND].valid = false; + _lostTracking[controller] = false; + _lastControllerPose[controller] = tracking.HandPoses[hand]; + return; } + + if (_lostTracking[controller]) { + if (currentTime > _regainTrackingDeadline[controller]) { + _poseStateMap.erase(controller); + _poseStateMap[controller].valid = false; + return; + } + + } else { + quint64 deadlineToRegainTracking = currentTime + LOST_TRACKING_DELAY; + _regainTrackingDeadline[controller] = deadlineToRegainTracking; + _lostTracking[controller] = true; + } + handleRotationForUntrackedHand(inputCalibrationData, hand, tracking.HandPoses[hand]); }); using namespace controller; // Axes @@ -251,7 +269,7 @@ void OculusControllerManager::TouchDevice::update(float deltaTime, const control if (inputState.Touches & pair.first) { _buttonPressedMap.insert(pair.second); } - } + } // Haptics { @@ -286,6 +304,16 @@ void OculusControllerManager::TouchDevice::handlePose(float deltaTime, } +void OculusControllerManager::TouchDevice::handleRotationForUntrackedHand(const controller::InputCalibrationData& inputCalibrationData, + ovrHandType hand, const ovrPoseStatef& handPose) { + auto poseId = (hand == ovrHand_Left ? controller::LEFT_HAND : controller::RIGHT_HAND); + auto& pose = _poseStateMap[poseId]; + auto lastHandPose = _lastControllerPose[poseId]; + pose = ovrControllerRotationToHandRotation(hand, handPose, lastHandPose); + glm::mat4 controllerToAvatar = glm::inverse(inputCalibrationData.avatarMat) * inputCalibrationData.sensorToWorldMat; + pose = pose.transform(controllerToAvatar); +} + bool OculusControllerManager::TouchDevice::triggerHapticPulse(float strength, float duration, controller::Hand hand) { Locker locker(_lock); bool toReturn = true; diff --git a/plugins/oculus/src/OculusControllerManager.h b/plugins/oculus/src/OculusControllerManager.h index 23ef52ab64..11d699ca8e 100644 --- a/plugins/oculus/src/OculusControllerManager.h +++ b/plugins/oculus/src/OculusControllerManager.h @@ -11,6 +11,7 @@ #include #include +#include #include @@ -75,6 +76,7 @@ private: private: void stopHapticPulse(bool leftHand); void handlePose(float deltaTime, const controller::InputCalibrationData& inputCalibrationData, ovrHandType hand, const ovrPoseStatef& handPose); + void handleRotationForUntrackedHand(const controller::InputCalibrationData& inputCalibrationData, ovrHandType hand, const ovrPoseStatef& handPose); int _trackedControllers { 0 }; // perform an action when the TouchDevice mutex is acquired. @@ -87,6 +89,9 @@ private: float _rightHapticDuration { 0.0f }; float _rightHapticStrength { 0.0f }; mutable std::recursive_mutex _lock; + std::map _lostTracking; + std::map _regainTrackingDeadline; + std::map _lastControllerPose; friend class OculusControllerManager; }; diff --git a/plugins/oculus/src/OculusHelpers.cpp b/plugins/oculus/src/OculusHelpers.cpp index 767d191c03..18844a1995 100644 --- a/plugins/oculus/src/OculusHelpers.cpp +++ b/plugins/oculus/src/OculusHelpers.cpp @@ -267,3 +267,37 @@ controller::Pose ovrControllerPoseToHandPose( pose.valid = true; return pose; } + +controller::Pose ovrControllerRotationToHandRotation(ovrHandType hand, const ovrPoseStatef& handPose, + const ovrPoseStatef& lastHandPose) { + static const glm::quat yFlip = glm::angleAxis(PI, Vectors::UNIT_Y); + static const glm::quat quarterX = glm::angleAxis(PI_OVER_TWO, Vectors::UNIT_X); + static const glm::quat touchToHand = yFlip * quarterX; + + static const glm::quat leftQuarterZ = glm::angleAxis(-PI_OVER_TWO, Vectors::UNIT_Z); + static const glm::quat rightQuarterZ = glm::angleAxis(PI_OVER_TWO, Vectors::UNIT_Z); + + static const glm::quat leftRotationOffset = glm::inverse(leftQuarterZ) * touchToHand; + static const glm::quat rightRotationOffset = glm::inverse(rightQuarterZ) * touchToHand; + + static const float CONTROLLER_LENGTH_OFFSET = 0.0762f; // three inches + static const glm::vec3 CONTROLLER_OFFSET = glm::vec3(CONTROLLER_LENGTH_OFFSET / 2.0f, + -CONTROLLER_LENGTH_OFFSET / 2.0f, + CONTROLLER_LENGTH_OFFSET * 1.5f); + static const glm::vec3 leftTranslationOffset = glm::vec3(-1.0f, 1.0f, 1.0f) * CONTROLLER_OFFSET; + static const glm::vec3 rightTranslationOffset = CONTROLLER_OFFSET; + + auto translationOffset = (hand == ovrHand_Left ? leftTranslationOffset : rightTranslationOffset); + auto rotationOffset = (hand == ovrHand_Left ? leftRotationOffset : rightRotationOffset); + + glm::quat rotation = toGlm(handPose.ThePose.Orientation); + + controller::Pose pose; + pose.translation = toGlm(lastHandPose.ThePose.Position); + pose.translation += rotation * translationOffset; + pose.rotation = rotation * rotationOffset; + pose.angularVelocity = toGlm(lastHandPose.AngularVelocity); + pose.velocity = toGlm(lastHandPose.LinearVelocity); + pose.valid = true; + return pose; +} diff --git a/plugins/oculus/src/OculusHelpers.h b/plugins/oculus/src/OculusHelpers.h index 50ba355b0c..5743f8576b 100644 --- a/plugins/oculus/src/OculusHelpers.h +++ b/plugins/oculus/src/OculusHelpers.h @@ -118,3 +118,6 @@ inline ovrPosef ovrPoseFromGlm(const glm::mat4 & m) { controller::Pose ovrControllerPoseToHandPose( ovrHandType hand, const ovrPoseStatef& handPose); + +controller::Pose ovrControllerRotationToHandRotation(ovrHandType hand, + const ovrPoseStatef& handPose, const ovrPoseStatef& lastHandPose);