From bbe507ec0504fda0f67a084079692649aedc2e51 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Fri, 11 Mar 2016 09:53:10 +1300 Subject: [PATCH 01/20] Add file headers and update Qt versions in VR menu QML files --- .../resources/qml/menus/MenuMouseHandler.qml | 10 ++++++++++ interface/resources/qml/menus/VrMenuItem.qml | 16 +++++++++++++--- interface/resources/qml/menus/VrMenuView.qml | 17 +++++++++++++---- 3 files changed, 36 insertions(+), 7 deletions(-) diff --git a/interface/resources/qml/menus/MenuMouseHandler.qml b/interface/resources/qml/menus/MenuMouseHandler.qml index 6f507dd445..d99b7f7828 100644 --- a/interface/resources/qml/menus/MenuMouseHandler.qml +++ b/interface/resources/qml/menus/MenuMouseHandler.qml @@ -1,3 +1,13 @@ +// +// MessageDialog.qml +// +// Created by Bradley Austin Davis on 18 Jan 2016 +// Copyright 2016 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 +// + import QtQuick 2.5 import QtQuick.Controls 1.4 diff --git a/interface/resources/qml/menus/VrMenuItem.qml b/interface/resources/qml/menus/VrMenuItem.qml index c23a54a2c7..955ab86167 100644 --- a/interface/resources/qml/menus/VrMenuItem.qml +++ b/interface/resources/qml/menus/VrMenuItem.qml @@ -1,6 +1,16 @@ -import QtQuick 2.4 -import QtQuick.Controls 1.3 -import QtQuick.Controls.Styles 1.3 +// +// VrMenuItem.qml +// +// Created by Bradley Austin Davis on 29 Apr 2015 +// Copyright 2015 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 +// + +import QtQuick 2.5 +import QtQuick.Controls 1.4 +import QtQuick.Controls.Styles 1.4 import "../controls" import "../styles" diff --git a/interface/resources/qml/menus/VrMenuView.qml b/interface/resources/qml/menus/VrMenuView.qml index bbb9bd706e..8b0673229c 100644 --- a/interface/resources/qml/menus/VrMenuView.qml +++ b/interface/resources/qml/menus/VrMenuView.qml @@ -1,10 +1,19 @@ -import QtQuick 2.4 -import QtQuick.Controls 1.3 -import QtQuick.Controls.Styles 1.3 +// +// VrMenuView.qml +// +// Created by Bradley Austin Davis on 18 Jan 2016 +// Copyright 2016 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 +// + +import QtQuick 2.5 +import QtQuick.Controls 1.4 +import QtQuick.Controls.Styles 1.4 import "../styles" - FocusScope { id: root implicitHeight: border.height From 2b45971f8cfea55ffd894a5479b3a52904a6e755 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Fri, 11 Mar 2016 11:42:49 +1300 Subject: [PATCH 02/20] Style HMD menu backgrounds --- .../resources/qml/menus/MenuMouseHandler.qml | 4 ++-- interface/resources/qml/menus/VrMenuView.qml | 23 +++++++++++-------- .../qml/styles-uit/HifiConstants.qml | 2 ++ 3 files changed, 17 insertions(+), 12 deletions(-) diff --git a/interface/resources/qml/menus/MenuMouseHandler.qml b/interface/resources/qml/menus/MenuMouseHandler.qml index d99b7f7828..9ba158cb28 100644 --- a/interface/resources/qml/menus/MenuMouseHandler.qml +++ b/interface/resources/qml/menus/MenuMouseHandler.qml @@ -104,8 +104,8 @@ Item { function buildMenu(items, targetPosition) { var model = toModel(items); - // Menu's must be childed to desktop for Z-ordering - var newMenu = menuViewMaker.createObject(desktop, { model: model, z: topMenu ? topMenu.z + 1 : desktop.zLevels.menu }); + // Menus must be childed to desktop for Z-ordering + var newMenu = menuViewMaker.createObject(desktop, { model: model, z: topMenu ? topMenu.z + 1 : desktop.zLevels.menu, isSubMenu: topMenu !== null }); if (targetPosition) { newMenu.x = targetPosition.x newMenu.y = targetPosition.y - newMenu.height / 3 * 1 diff --git a/interface/resources/qml/menus/VrMenuView.qml b/interface/resources/qml/menus/VrMenuView.qml index 8b0673229c..8778bc4bd1 100644 --- a/interface/resources/qml/menus/VrMenuView.qml +++ b/interface/resources/qml/menus/VrMenuView.qml @@ -12,33 +12,35 @@ import QtQuick 2.5 import QtQuick.Controls 1.4 import QtQuick.Controls.Styles 1.4 -import "../styles" +import "../styles-uit" FocusScope { id: root - implicitHeight: border.height - implicitWidth: border.width + implicitHeight: background.height + implicitWidth: background.width property alias currentItem: listView.currentItem property alias model: listView.model + property bool isSubMenu: false signal selected(var item) + HifiConstants { id: hifi } - Border { - id: border + Rectangle { + id: background anchors.fill: listView - anchors.margins: -8 - border.color: hifi.colors.hifiBlue - color: hifi.colors.window - // color: "#7f7f7f7f" + radius: hifi.dimensions.borderRadius + border.width: hifi.dimensions.borderWidth + border.color: hifi.colors.lightGrayText80 + color: isSubMenu ? hifi.colors.faintGray : hifi.colors.faintGray80 } ListView { id: listView x: 8; y: 8 - HifiConstants { id: hifi } width: 128 height: count * 32 + topMargin: hifi.dimensions.menuPadding onEnabledChanged: recalcSize(); onVisibleChanged: recalcSize(); onCountChanged: recalcSize(); @@ -84,6 +86,7 @@ FocusScope { newHeight += currentItem.implicitHeight } } + newHeight += 2 * hifi.dimensions.menuPadding; // White space at top and bottom. if (maxWidth > width) { width = maxWidth; } diff --git a/interface/resources/qml/styles-uit/HifiConstants.qml b/interface/resources/qml/styles-uit/HifiConstants.qml index eb4c84b5b8..4f06b676e6 100644 --- a/interface/resources/qml/styles-uit/HifiConstants.qml +++ b/interface/resources/qml/styles-uit/HifiConstants.qml @@ -70,6 +70,7 @@ Item { readonly property color baseGrayHighlight40: "#66575757" readonly property color baseGrayHighlight15: "#26575757" readonly property color lightGrayText80: "#ccafafaf" + readonly property color faintGray80: "#cce3e3e3" readonly property color faintGray50: "#80e3e3e3" // Other colors @@ -135,6 +136,7 @@ Item { readonly property real modalDialogTitleHeight: 40 readonly property real controlLineHeight: 29 // Height of spinbox control on 1920 x 1080 monitor readonly property real controlInterlineHeight: 22 // 75% of controlLineHeight + readonly property real menuPadding: 12 } Item { From fb0f97264c29f5f9af8b96cb92e9abab1865430d Mon Sep 17 00:00:00 2001 From: David Rowe Date: Fri, 11 Mar 2016 15:24:35 +1300 Subject: [PATCH 03/20] Style HMD menu items --- interface/resources/qml/menus/VrMenuItem.qml | 55 ++++++++++++------- interface/resources/qml/menus/VrMenuView.qml | 14 +++-- .../qml/styles-uit/HifiConstants.qml | 5 +- 3 files changed, 48 insertions(+), 26 deletions(-) diff --git a/interface/resources/qml/menus/VrMenuItem.qml b/interface/resources/qml/menus/VrMenuItem.qml index 955ab86167..f2c077a59e 100644 --- a/interface/resources/qml/menus/VrMenuItem.qml +++ b/interface/resources/qml/menus/VrMenuItem.qml @@ -12,8 +12,8 @@ import QtQuick 2.5 import QtQuick.Controls 1.4 import QtQuick.Controls.Styles 1.4 -import "../controls" -import "../styles" +import "../controls-uit" +import "../styles-uit" Item { id: root @@ -21,24 +21,28 @@ Item { property alias text: label.text property var source - implicitHeight: source.visible ? label.implicitHeight * 1.5 : 0 - implicitWidth: label.width + label.height * 2.5 + implicitHeight: source.visible ? 2 * label.implicitHeight : 0 + implicitWidth: 2 * hifi.dimensions.menuPadding.x + check.width + label.width + tail.width visible: source.visible width: parent.width FontAwesome { clip: true id: check - verticalAlignment: Text.AlignVCenter - horizontalAlignment: Text.AlignHCenter - anchors.verticalCenter: parent.verticalCenter + verticalAlignment: Text.AlignVCenter + anchors { + verticalCenter: parent.verticalCenter + left: parent.left + leftMargin: hifi.dimensions.menuPadding.x + } + width: 1.5 * hifi.dimensions.menuPadding.x color: label.color text: checkText() size: label.height visible: source.visible font.pixelSize: size function checkText() { - if (!source || source.type != 1 || !source.checkable) { + if (!source || source.type !== 1 || !source.checkable) { return "" } // FIXME this works for native QML menus but I don't think it will @@ -50,25 +54,36 @@ Item { } } - Text { + RalewaySemiBold { id: label + size: hifi.fontSizes.rootMenu + font.capitalization: Font.AllUppercase anchors.left: check.right - anchors.leftMargin: 4 anchors.verticalCenter: parent.verticalCenter verticalAlignment: Text.AlignVCenter - color: source.enabled ? hifi.colors.text : hifi.colors.disabledText + color: source.enabled ? hifi.colors.baseGrayShadow : hifi.colors.baseGrayShadow50 enabled: source.visible && (source.type !== 0 ? source.enabled : false) visible: source.visible } - FontAwesome { - id: tag - x: root.parent.width - width - size: label.height - width: implicitWidth - visible: source.visible && (source.type == 2) - text: "\uF0DA" - anchors.verticalCenter: parent.verticalCenter - color: label.color + Item { + // Space for shortcut key or disclosure icon. + id: tail + width: 4 * hifi.dimensions.menuPadding.x + anchors { + verticalCenter: parent.verticalCenter + right: parent.right + rightMargin: hifi.dimensions.menuPadding.x + } + + HiFiGlyphs { + text: hifi.glyphs.disclosureExpand + color: source.enabled ? hifi.colors.baseGrayShadow : hifi.colors.baseGrayShadow25 + size: 2 * hifi.fontSizes.rootMenuDisclosure + anchors.verticalCenter: parent.verticalCenter + anchors.right: parent.right + horizontalAlignment: Text.AlignRight + visible: source.visible && (source.type === 2) + } } } diff --git a/interface/resources/qml/menus/VrMenuView.qml b/interface/resources/qml/menus/VrMenuView.qml index 8778bc4bd1..d8cc0e6667 100644 --- a/interface/resources/qml/menus/VrMenuView.qml +++ b/interface/resources/qml/menus/VrMenuView.qml @@ -40,16 +40,20 @@ FocusScope { x: 8; y: 8 width: 128 height: count * 32 - topMargin: hifi.dimensions.menuPadding + topMargin: hifi.dimensions.menuPadding.y onEnabledChanged: recalcSize(); onVisibleChanged: recalcSize(); onCountChanged: recalcSize(); focus: true highlight: Rectangle { - width: listView.currentItem ? listView.currentItem.width : 0 - height: listView.currentItem ? listView.currentItem.height : 0 - color: "lightsteelblue"; radius: 3 + anchors { + left: parent ? parent.left : undefined + right: parent ? parent.right : undefined + leftMargin: hifi.dimensions.borderWidth + rightMargin: hifi.dimensions.borderWidth + } + color: hifi.colors.white } delegate: VrMenuItem { @@ -86,7 +90,7 @@ FocusScope { newHeight += currentItem.implicitHeight } } - newHeight += 2 * hifi.dimensions.menuPadding; // White space at top and bottom. + newHeight += 2 * hifi.dimensions.menuPadding.y; // White space at top and bottom. if (maxWidth > width) { width = maxWidth; } diff --git a/interface/resources/qml/styles-uit/HifiConstants.qml b/interface/resources/qml/styles-uit/HifiConstants.qml index 4f06b676e6..3b6eb2d9fc 100644 --- a/interface/resources/qml/styles-uit/HifiConstants.qml +++ b/interface/resources/qml/styles-uit/HifiConstants.qml @@ -67,6 +67,8 @@ Item { readonly property color darkGray30: "#4d121212" readonly property color darkGray0: "#00121212" readonly property color baseGrayShadow60: "#99252525" + readonly property color baseGrayShadow50: "#80252525" + readonly property color baseGrayShadow25: "#40252525" readonly property color baseGrayHighlight40: "#66575757" readonly property color baseGrayHighlight15: "#26575757" readonly property color lightGrayText80: "#ccafafaf" @@ -136,7 +138,7 @@ Item { readonly property real modalDialogTitleHeight: 40 readonly property real controlLineHeight: 29 // Height of spinbox control on 1920 x 1080 monitor readonly property real controlInterlineHeight: 22 // 75% of controlLineHeight - readonly property real menuPadding: 12 + readonly property vector2d menuPadding: Qt.vector2d(12, 12) } Item { @@ -154,6 +156,7 @@ Item { readonly property real logs: dimensions.largeScreen ? 16 : 12 readonly property real code: dimensions.largeScreen ? 16 : 12 readonly property real rootMenu: dimensions.largeScreen ? 15 : 11 + readonly property real rootMenuDisclosure: dimensions.largeScreen ? 20 : 16 readonly property real menuItem: dimensions.largeScreen ? 15 : 11 readonly property real shortcutText: dimensions.largeScreen ? 13 : 9 readonly property real carat: dimensions.largeScreen ? 38 : 30 From e175c1975464fe3a22fbf46b5509ca7ecc42f0d2 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Fri, 11 Mar 2016 15:51:27 +1300 Subject: [PATCH 04/20] Style checkbox for menu items --- interface/resources/qml/menus/VrMenuItem.qml | 28 ++++++++----------- .../qml/styles-uit/HifiConstants.qml | 2 +- 2 files changed, 12 insertions(+), 18 deletions(-) diff --git a/interface/resources/qml/menus/VrMenuItem.qml b/interface/resources/qml/menus/VrMenuItem.qml index f2c077a59e..636728c890 100644 --- a/interface/resources/qml/menus/VrMenuItem.qml +++ b/interface/resources/qml/menus/VrMenuItem.qml @@ -26,31 +26,25 @@ Item { visible: source.visible width: parent.width - FontAwesome { - clip: true + CheckBox { id: check - verticalAlignment: Text.AlignVCenter + // FIXME: Shouild use radio buttons if source.exclusiveGroup. anchors { - verticalCenter: parent.verticalCenter left: parent.left leftMargin: hifi.dimensions.menuPadding.x + top: label.top + topMargin: 0 } - width: 1.5 * hifi.dimensions.menuPadding.x - color: label.color - text: checkText() - size: label.height - visible: source.visible - font.pixelSize: size - function checkText() { + width: 20 + visible: source.visible && source.type === 1 && source.checkable + checked: setChecked() + function setChecked() { if (!source || source.type !== 1 || !source.checkable) { - return "" + return false; } // FIXME this works for native QML menus but I don't think it will // for proxied QML menus - if (source.exclusiveGroup) { - return source.checked ? "\uF05D" : "\uF10C" - } - return source.checked ? "\uF046" : "\uF096" + return source.checked; } } @@ -69,7 +63,7 @@ Item { Item { // Space for shortcut key or disclosure icon. id: tail - width: 4 * hifi.dimensions.menuPadding.x + width: 48 anchors { verticalCenter: parent.verticalCenter right: parent.right diff --git a/interface/resources/qml/styles-uit/HifiConstants.qml b/interface/resources/qml/styles-uit/HifiConstants.qml index 3b6eb2d9fc..718c1e32cb 100644 --- a/interface/resources/qml/styles-uit/HifiConstants.qml +++ b/interface/resources/qml/styles-uit/HifiConstants.qml @@ -138,7 +138,7 @@ Item { readonly property real modalDialogTitleHeight: 40 readonly property real controlLineHeight: 29 // Height of spinbox control on 1920 x 1080 monitor readonly property real controlInterlineHeight: 22 // 75% of controlLineHeight - readonly property vector2d menuPadding: Qt.vector2d(12, 12) + readonly property vector2d menuPadding: Qt.vector2d(14, 12) } Item { From 807d31743c5b6786306d2e43c52654e0b587ed96 Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Thu, 10 Mar 2016 19:33:31 -0800 Subject: [PATCH 05/20] Removed Hand, HandData & PalmData Instead, we just store two controller::Poses in MyAvatar. Existing behavior and scripting APIs have been preserved. The hand controller debug drawing is slightly different, but still works. --- interface/src/Application.cpp | 52 +----- interface/src/Application.h | 4 +- interface/src/Menu.cpp | 3 +- interface/src/avatar/Avatar.cpp | 12 -- interface/src/avatar/Avatar.h | 3 +- interface/src/avatar/AvatarActionHold.cpp | 79 ++++---- interface/src/avatar/Hand.cpp | 101 ---------- interface/src/avatar/Hand.h | 36 ---- interface/src/avatar/MyAvatar.cpp | 110 +++++++---- interface/src/avatar/MyAvatar.h | 9 + interface/src/avatar/SkeletonModel.cpp | 28 +-- interface/src/avatar/SkeletonModel.h | 1 - .../ControllerScriptingInterface.cpp | 1 - libraries/avatars/src/AvatarData.cpp | 7 - libraries/avatars/src/AvatarData.h | 4 +- libraries/avatars/src/HandData.cpp | 110 ----------- libraries/avatars/src/HandData.h | 174 ------------------ 17 files changed, 149 insertions(+), 585 deletions(-) delete mode 100644 interface/src/avatar/Hand.cpp delete mode 100644 interface/src/avatar/Hand.h delete mode 100644 libraries/avatars/src/HandData.cpp delete mode 100644 libraries/avatars/src/HandData.h diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 4ae63f817a..728691a0e1 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3216,11 +3216,10 @@ void Application::update(float deltaTime) { myAvatar->setDriveKeys(ZOOM, userInputMapper->getActionState(controller::Action::TRANSLATE_CAMERA_Z)); } - controller::Pose leftHand = userInputMapper->getPoseState(controller::Action::LEFT_HAND); - controller::Pose rightHand = userInputMapper->getPoseState(controller::Action::RIGHT_HAND); - Hand* hand = DependencyManager::get()->getMyAvatar()->getHand(); - setPalmData(hand, leftHand, deltaTime, HandData::LeftHand, userInputMapper->getActionState(controller::Action::LEFT_HAND_CLICK)); - setPalmData(hand, rightHand, deltaTime, HandData::RightHand, userInputMapper->getActionState(controller::Action::RIGHT_HAND_CLICK)); + controller::Pose leftHandPose = userInputMapper->getPoseState(controller::Action::LEFT_HAND); + controller::Pose rightHandPose = userInputMapper->getPoseState(controller::Action::RIGHT_HAND); + myAvatar->setHandControllerPoses(leftHandPose, rightHandPose); + updateThreads(deltaTime); // If running non-threaded, then give the threads some time to process... updateDialogs(deltaTime); // update various stats dialogs if present @@ -4979,49 +4978,6 @@ mat4 Application::getHMDSensorPose() const { return mat4(); } -void Application::setPalmData(Hand* hand, const controller::Pose& pose, float deltaTime, HandData::Hand whichHand, float triggerValue) { - - // NOTE: the Hand::modifyPalm() will allow the lambda to modify the palm data while ensuring some other user isn't - // reading or writing to the Palms. This is definitely not the best way of handling this, and I'd like to see more - // of this palm manipulation in the Hand class itself. But unfortunately the Hand and Palm don't knbow about - // controller::Pose. More work is needed to clean this up. - hand->modifyPalm(whichHand, [&](PalmData& palm) { - palm.setActive(pose.isValid()); - - // controller pose is in Avatar frame. - glm::vec3 position = pose.getTranslation(); - glm::quat rotation = pose.getRotation(); - glm::vec3 rawVelocity = pose.getVelocity(); - glm::vec3 angularVelocity = pose.getAngularVelocity(); - - palm.setRawVelocity(rawVelocity); - palm.setRawAngularVelocity(angularVelocity); - - if (controller::InputDevice::getLowVelocityFilter()) { - // Use a velocity sensitive filter to damp small motions and preserve large ones with - // no latency. - float velocityFilter = glm::clamp(1.0f - glm::length(rawVelocity), 0.0f, 1.0f); - position = palm.getRawPosition() * velocityFilter + position * (1.0f - velocityFilter); - rotation = safeMix(palm.getRawRotation(), rotation, 1.0f - velocityFilter); - } - palm.setRawPosition(position); - palm.setRawRotation(rotation); - - // Store the one fingertip in the palm structure so we can track velocity - const float FINGER_LENGTH = 0.3f; // meters - const glm::vec3 FINGER_VECTOR(0.0f, FINGER_LENGTH, 0.0f); - const glm::vec3 newTipPosition = position + rotation * FINGER_VECTOR; - glm::vec3 oldTipPosition = palm.getTipRawPosition(); - if (deltaTime > 0.0f) { - palm.setTipVelocity((newTipPosition - oldTipPosition) / deltaTime); - } else { - palm.setTipVelocity(glm::vec3(0.0f)); - } - palm.setTipPosition(newTipPosition); - palm.setTrigger(triggerValue); // FIXME - we want to get rid of this idea of PalmData having a trigger - }); -} - void Application::crashApplication() { qCDebug(interfaceapp) << "Intentionally crashed Interface"; QObject* object = nullptr; diff --git a/interface/src/Application.h b/interface/src/Application.h index c93b7431f3..14b90877df 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -299,7 +299,7 @@ private slots: void loadSettings(); void saveSettings(); - + bool acceptSnapshot(const QString& urlString); bool askToSetAvatarUrl(const QString& url); bool askToLoadScript(const QString& scriptFilenameOrURL); @@ -327,8 +327,6 @@ private: void update(float deltaTime); - void setPalmData(Hand* hand, const controller::Pose& pose, float deltaTime, HandData::Hand whichHand, float triggerValue); - // Various helper functions called during update() void updateLOD(); void updateThreads(float deltaTime); diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index 15fae25646..ab1b7238df 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -479,7 +479,8 @@ Menu::Menu() { // Developer > Hands >>> MenuWrapper* handOptionsMenu = developerMenu->addMenu("Hands"); - addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::DisplayHandTargets, 0, false); + addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::DisplayHandTargets, 0, false, + avatar, SLOT(setEnableDebugDrawHandControllers(bool))); addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::LowVelocityFilter, 0, true, qApp, SLOT(setLowVelocityFilter(bool))); diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index 292e4c637e..ca242a2ca2 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -35,7 +35,6 @@ #include "Avatar.h" #include "AvatarManager.h" #include "AvatarMotionState.h" -#include "Hand.h" #include "Head.h" #include "Menu.h" #include "Physics.h" @@ -101,7 +100,6 @@ Avatar::Avatar(RigPointer rig) : // give the pointer to our head to inherited _headData variable from AvatarData _headData = static_cast(new Head(this)); - _handData = static_cast(new Hand(this)); } Avatar::~Avatar() { @@ -190,11 +188,6 @@ void Avatar::simulate(float deltaTime) { float boundingRadius = getBoundingRadius(); bool inView = qApp->getViewFrustum()->sphereIntersectsFrustum(getPosition(), boundingRadius); - { - PerformanceTimer perfTimer("hand"); - getHand()->simulate(deltaTime, false); - } - if (_shouldAnimate && !_shouldSkipRender && inView) { { PerformanceTimer perfTimer("skeleton"); @@ -578,11 +571,6 @@ void Avatar::renderBody(RenderArgs* renderArgs, ViewFrustum* renderFrustum, floa if (_skeletonModel.isRenderable() && getHead()->getFaceModel().isRenderable()) { getHead()->render(renderArgs, 1.0f, renderFrustum); } - - if (renderArgs->_renderMode != RenderArgs::SHADOW_RENDER_MODE && - Menu::getInstance()->isOptionChecked(MenuOption::DisplayHandTargets)) { - getHand()->renderHandTargets(renderArgs, false); - } } getHead()->renderLookAts(renderArgs); } diff --git a/interface/src/avatar/Avatar.h b/interface/src/avatar/Avatar.h index f9e21febd5..7020de377f 100644 --- a/interface/src/avatar/Avatar.h +++ b/interface/src/avatar/Avatar.h @@ -22,7 +22,6 @@ #include -#include "Hand.h" #include "Head.h" #include "SkeletonModel.h" #include "world.h" @@ -91,7 +90,7 @@ public: float getUniformScale() const { return getScale().y; } const Head* getHead() const { return static_cast(_headData); } Head* getHead() { return static_cast(_headData); } - Hand* getHand() { return static_cast(_handData); } + glm::quat getWorldAlignedOrientation() const; AABox getBounds() const; diff --git a/interface/src/avatar/AvatarActionHold.cpp b/interface/src/avatar/AvatarActionHold.cpp index b62cae1d58..0ce0b5a190 100644 --- a/interface/src/avatar/AvatarActionHold.cpp +++ b/interface/src/avatar/AvatarActionHold.cpp @@ -104,48 +104,57 @@ std::shared_ptr AvatarActionHold::getTarget(float deltaTimeStep, glm::qu withReadLock([&]{ bool isRightHand = (_hand == "right"); + glm::vec3 palmPosition; glm::quat palmRotation; - PalmData palmData = holdingAvatar->getHand()->getCopyOfPalmData(isRightHand ? HandData::RightHand : HandData::LeftHand); - - if (palmData.isValid()) { - // TODO: adjust according to _relativePosition and _relativeRotation? - linearVelocity = palmData.getVelocity(); - angularVelocity = palmData.getAngularVelocity(); - } - - if (_ignoreIK && holdingAvatar->isMyAvatar() && palmData.isValid()) { - // We cannot ignore other avatars IK and this is not the point of this option - // This is meant to make the grabbing behavior more reactive. - palmPosition = palmData.getPosition(); - palmRotation = palmData.getRotation(); - } else if (holdingAvatar->isMyAvatar()) { - glm::vec3 avatarRigidBodyPosition; - glm::quat avatarRigidBodyRotation; - getAvatarRigidBodyLocation(avatarRigidBodyPosition, avatarRigidBodyRotation); - - // the offset and rotation between the avatar's rigid body and the palm were determined earlier - // in prepareForPhysicsSimulation. At this point, the avatar's rigid body has been moved by bullet - // and the data in the Avatar class is stale. This means that the result of get*PalmPosition will - // be stale. Instead, determine the current palm position with the current avatar's rigid body - // location and the saved offsets. - - // this line is more correct but breaks for the current way avatar data is updated. - // palmPosition = avatarRigidBodyPosition + avatarRigidBodyRotation * _palmOffsetFromRigidBody; - // instead, use this for now: - palmPosition = avatarRigidBodyPosition + _palmOffsetFromRigidBody; - - // the item jitters the least by getting the rotation based on the opinion of Avatar.h rather - // than that of the rigid body. leaving this next line here for future reference: - // palmRotation = avatarRigidBodyRotation * _palmRotationFromRigidBody; + if (holdingAvatar->isMyAvatar()) { + // fetch the hand controller pose + controller::Pose pose; if (isRightHand) { - palmRotation = holdingAvatar->getRightPalmRotation(); + pose = avatarManager->getMyAvatar()->getRightHandControllerPose(); } else { - palmRotation = holdingAvatar->getLeftPalmRotation(); + pose = avatarManager->getMyAvatar()->getLeftHandControllerPose(); } - } else { + + if (pose.isValid()) { + linearVelocity = pose.getVelocity(); + angularVelocity = pose.getAngularVelocity(); + } + + if (_ignoreIK && pose.isValid()) { + // We cannot ignore other avatars IK and this is not the point of this option + // This is meant to make the grabbing behavior more reactive. + palmPosition = pose.getTranslation(); + palmRotation = pose.getRotation(); + } else { + glm::vec3 avatarRigidBodyPosition; + glm::quat avatarRigidBodyRotation; + getAvatarRigidBodyLocation(avatarRigidBodyPosition, avatarRigidBodyRotation); + + // the offset and rotation between the avatar's rigid body and the palm were determined earlier + // in prepareForPhysicsSimulation. At this point, the avatar's rigid body has been moved by bullet + // and the data in the Avatar class is stale. This means that the result of get*PalmPosition will + // be stale. Instead, determine the current palm position with the current avatar's rigid body + // location and the saved offsets. + + // this line is more correct but breaks for the current way avatar data is updated. + // palmPosition = avatarRigidBodyPosition + avatarRigidBodyRotation * _palmOffsetFromRigidBody; + // instead, use this for now: + palmPosition = avatarRigidBodyPosition + _palmOffsetFromRigidBody; + + // the item jitters the least by getting the rotation based on the opinion of Avatar.h rather + // than that of the rigid body. leaving this next line here for future reference: + // palmRotation = avatarRigidBodyRotation * _palmRotationFromRigidBody; + + if (isRightHand) { + palmRotation = holdingAvatar->getRightPalmRotation(); + } else { + palmRotation = holdingAvatar->getLeftPalmRotation(); + } + } + } else { // regular avatar if (isRightHand) { palmPosition = holdingAvatar->getRightPalmPosition(); palmRotation = holdingAvatar->getRightPalmRotation(); diff --git a/interface/src/avatar/Hand.cpp b/interface/src/avatar/Hand.cpp deleted file mode 100644 index 5371fe5736..0000000000 --- a/interface/src/avatar/Hand.cpp +++ /dev/null @@ -1,101 +0,0 @@ -// -// Hand.cpp -// interface/src/avatar -// -// Copyright 2013 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 "Hand.h" - -#include - -#include -#include - -#include "Avatar.h" -#include "AvatarManager.h" -#include "MyAvatar.h" -#include "Util.h" -#include "world.h" - -using namespace std; - -Hand::Hand(Avatar* owningAvatar) : - HandData((AvatarData*)owningAvatar), - _owningAvatar(owningAvatar) -{ -} - -void Hand::simulate(float deltaTime, bool isMine) { - // nothing to do here -} - -void Hand::renderHandTargets(RenderArgs* renderArgs, bool isMine) { - float avatarScale = 1.0f; - if (_owningAvatar) { - avatarScale = _owningAvatar->getUniformScale(); - } - - const float alpha = 1.0f; - const glm::vec3 redColor(1.0f, 0.0f, 0.0f); // Color the hand targets red to be different than skin - const glm::vec3 greenColor(0.0f, 1.0f, 0.0f); // Color the hand targets red to be different than skin - const glm::vec3 blueColor(0.0f, 0.0f, 1.0f); // Color the hand targets red to be different than skin - const glm::vec3 grayColor(0.5f); - const float SPHERE_RADIUS = 0.03f * avatarScale; - - auto palms = getCopyOfPalms(); - - gpu::Batch& batch = *renderArgs->_batch; - if (isMine) { - for (const auto& palm : palms) { - if (!palm.isActive()) { - continue; - } - // draw a gray sphere at the target position of the "Hand" joint - glm::vec3 position = palm.getPosition(); - Transform transform = Transform(); - transform.setTranslation(position); - transform.setRotation(palm.getRotation()); - transform.postScale(SPHERE_RADIUS); - batch.setModelTransform(transform); - DependencyManager::get()->renderSolidSphereInstance(batch, grayColor); - - // draw a green sphere at the old "finger tip" - transform = Transform(); - position = palm.getTipPosition(); - transform.setTranslation(position); - transform.setRotation(palm.getRotation()); - transform.postScale(SPHERE_RADIUS); - batch.setModelTransform(transform); - DependencyManager::get()->renderSolidSphereInstance(batch, greenColor); - } - } - - const float AXIS_RADIUS = 0.1f * SPHERE_RADIUS; - const float AXIS_LENGTH = 10.0f * SPHERE_RADIUS; - - // Draw the coordinate frames of the hand targets - for (const auto& palm : palms) { - if (palm.isActive()) { - glm::vec3 root = palm.getPosition(); - - const glm::vec3 yAxis(0.0f, 1.0f, 0.0f); - glm::quat palmRotation = palm.getRotation(); - Transform transform = Transform(); - transform.setTranslation(glm::vec3()); - batch.setModelTransform(transform); - glm::vec3 tip = root + palmRotation * glm::vec3(AXIS_LENGTH, 0.0f, 0.0f); - Avatar::renderJointConnectingCone(batch, root, tip, AXIS_RADIUS, AXIS_RADIUS, glm::vec4(redColor.r, redColor.g, redColor.b, alpha)); - - tip = root + palmRotation * glm::vec3(0.0f, AXIS_LENGTH, 0.0f); - Avatar::renderJointConnectingCone(batch, root, tip, AXIS_RADIUS, AXIS_RADIUS, glm::vec4(greenColor.r, greenColor.g, greenColor.b, alpha)); - - tip = root + palmRotation * glm::vec3(0.0f, 0.0f, AXIS_LENGTH); - Avatar::renderJointConnectingCone(batch, root, tip, AXIS_RADIUS, AXIS_RADIUS, glm::vec4(blueColor.r, blueColor.g, blueColor.b, alpha)); - } - } -} - diff --git a/interface/src/avatar/Hand.h b/interface/src/avatar/Hand.h deleted file mode 100644 index 2ece3e9f9e..0000000000 --- a/interface/src/avatar/Hand.h +++ /dev/null @@ -1,36 +0,0 @@ -// -// Hand.h -// interface/src/avatar -// -// Copyright 2013 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_Hand_h -#define hifi_Hand_h - -#include - -class Avatar; -class RenderArgs; - -class Hand : public HandData { -public: - Hand(Avatar* owningAvatar); - - void simulate(float deltaTime, bool isMine); - void renderHandTargets(RenderArgs* renderArgs, bool isMine); - -private: - // disallow copies of the Hand, copy of owning Avatar is disallowed too - Hand(const Hand&); - Hand& operator= (const Hand&); - - int _controllerButtons; /// Button states read from hand-held controllers - - Avatar* _owningAvatar; -}; - -#endif // hifi_Hand_h diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 26e0ce56dd..016e2a464c 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -341,12 +341,6 @@ void MyAvatar::simulate(float deltaTime) { updatePosition(deltaTime); } - { - PerformanceTimer perfTimer("hand"); - // update avatar skeleton and simulate hand and head - getHand()->simulate(deltaTime, true); - } - { PerformanceTimer perfTimer("skeleton"); _skeletonModel.simulate(deltaTime); @@ -520,47 +514,49 @@ void MyAvatar::updateFromTrackers(float deltaTime) { glm::vec3 MyAvatar::getLeftHandPosition() const { - auto palmData = getHandData()->getCopyOfPalmData(HandData::LeftHand); - return palmData.isValid() ? palmData.getPosition() : glm::vec3(0.0f); + auto pose = getLeftHandControllerPose(); + return pose.isValid() ? pose.getTranslation() : glm::vec3(0.0f); } glm::vec3 MyAvatar::getRightHandPosition() const { - auto palmData = getHandData()->getCopyOfPalmData(HandData::RightHand); - return palmData.isValid() ? palmData.getPosition() : glm::vec3(0.0f); + auto pose = getRightHandControllerPose(); + return pose.isValid() ? pose.getTranslation() : glm::vec3(0.0f); } glm::vec3 MyAvatar::getLeftHandTipPosition() const { - auto palmData = getHandData()->getCopyOfPalmData(HandData::LeftHand); - return palmData.isValid() ? palmData.getTipPosition() : glm::vec3(0.0f); + const float TIP_LENGTH = 0.3f; + auto pose = getLeftHandControllerPose(); + return pose.isValid() ? pose.getTranslation() * pose.getRotation() + glm::vec3(0.0f, TIP_LENGTH, 0.0f) : glm::vec3(0.0f); } glm::vec3 MyAvatar::getRightHandTipPosition() const { - auto palmData = getHandData()->getCopyOfPalmData(HandData::RightHand); - return palmData.isValid() ? palmData.getTipPosition() : glm::vec3(0.0f); + const float TIP_LENGTH = 0.3f; + auto pose = getRightHandControllerPose(); + return pose.isValid() ? pose.getTranslation() * pose.getRotation() + glm::vec3(0.0f, TIP_LENGTH, 0.0f) : glm::vec3(0.0f); } controller::Pose MyAvatar::getLeftHandPose() const { - auto palmData = getHandData()->getCopyOfPalmData(HandData::LeftHand); - return palmData.isValid() ? controller::Pose(palmData.getPosition(), palmData.getRotation(), - palmData.getVelocity(), palmData.getRawAngularVelocity()) : controller::Pose(); + return getLeftHandControllerPose(); } controller::Pose MyAvatar::getRightHandPose() const { - auto palmData = getHandData()->getCopyOfPalmData(HandData::RightHand); - return palmData.isValid() ? controller::Pose(palmData.getPosition(), palmData.getRotation(), - palmData.getVelocity(), palmData.getRawAngularVelocity()) : controller::Pose(); + return getRightHandControllerPose(); } controller::Pose MyAvatar::getLeftHandTipPose() const { - auto palmData = getHandData()->getCopyOfPalmData(HandData::LeftHand); - return palmData.isValid() ? controller::Pose(palmData.getTipPosition(), palmData.getRotation(), - palmData.getTipVelocity(), palmData.getRawAngularVelocity()) : controller::Pose(); + auto pose = getLeftHandControllerPose(); + glm::vec3 tipTrans = getLeftHandTipPosition(); + pose.velocity += glm::cross(pose.getAngularVelocity(), pose.getTranslation() - tipTrans); + pose.translation = tipTrans; + return pose; } controller::Pose MyAvatar::getRightHandTipPose() const { - auto palmData = getHandData()->getCopyOfPalmData(HandData::RightHand); - return palmData.isValid() ? controller::Pose(palmData.getTipPosition(), palmData.getRotation(), - palmData.getTipVelocity(), palmData.getRawAngularVelocity()) : controller::Pose(); + auto pose = getRightHandControllerPose(); + glm::vec3 tipTrans = getRightHandTipPosition(); + pose.velocity += glm::cross(pose.getAngularVelocity(), pose.getTranslation() - tipTrans); + pose.translation = tipTrans; + return pose; } // virtual @@ -698,6 +694,14 @@ void MyAvatar::setEnableDebugDrawPosition(bool isEnabled) { } } +void MyAvatar::setEnableDebugDrawHandControllers(bool isEnabled) { + _enableDebugDrawHandControllers = isEnabled; + if (!isEnabled) { + DebugDraw::getInstance().removeMyAvatarMarker("leftHandController"); + DebugDraw::getInstance().removeMyAvatarMarker("rightHandController"); + } +} + void MyAvatar::setEnableMeshVisible(bool isEnabled) { render::ScenePointer scene = qApp->getMain3DScene(); _skeletonModel.setVisibleInScene(isEnabled, scene); @@ -1080,6 +1084,38 @@ void MyAvatar::rebuildCollisionShape() { _characterController.setLocalBoundingBox(corner, diagonal); } +static controller::Pose applyLowVelocityFilter(const controller::Pose& oldPose, const controller::Pose& newPose) { + controller::Pose finalPose = newPose; + if (newPose.isValid()) { + // Use a velocity sensitive filter to damp small motions and preserve large ones with + // no latency. + float velocityFilter = glm::clamp(1.0f - glm::length(oldPose.getVelocity()), 0.0f, 1.0f); + finalPose.translation = oldPose.getTranslation() * velocityFilter + newPose.getTranslation() * (1.0f - velocityFilter); + finalPose.rotation = safeMix(oldPose.getRotation(), newPose.getRotation(), 1.0f - velocityFilter); + } + return finalPose; +} + +void MyAvatar::setHandControllerPoses(const controller::Pose& left, const controller::Pose& right) { + if (controller::InputDevice::getLowVelocityFilter()) { + auto oldLeftPose = getLeftHandControllerPose(); + auto oldRightPose = getRightHandControllerPose(); + _leftHandControllerPoseCache.set(applyLowVelocityFilter(oldLeftPose, left)); + _rightHandControllerPoseCache.set(applyLowVelocityFilter(oldRightPose, right)); + } else { + _leftHandControllerPoseCache.set(left); + _rightHandControllerPoseCache.set(right); + } +} + +controller::Pose MyAvatar::getLeftHandControllerPose() const { + return _leftHandControllerPoseCache.get(); +} + +controller::Pose MyAvatar::getRightHandControllerPose() const { + return _rightHandControllerPoseCache.get(); +} + void MyAvatar::prepareForPhysicsSimulation() { relayDriveKeysToCharacterController(); @@ -1215,11 +1251,6 @@ void MyAvatar::renderBody(RenderArgs* renderArgs, ViewFrustum* renderFrustum, fl } else { getHead()->renderLookAts(renderArgs); } - - if (renderArgs->_renderMode != RenderArgs::SHADOW_RENDER_MODE && - Menu::getInstance()->isOptionChecked(MenuOption::DisplayHandTargets)) { - getHand()->renderHandTargets(renderArgs, true); - } } void MyAvatar::setVisibleInSceneIfReady(Model* model, render::ScenePointer scene, bool visible) { @@ -1328,6 +1359,23 @@ void MyAvatar::preRender(RenderArgs* renderArgs) { } } + if (_enableDebugDrawHandControllers) { + auto leftHandPose = getLeftHandControllerPose(); + auto rightHandPose = getRightHandControllerPose(); + + if (leftHandPose.isValid()) { + DebugDraw::getInstance().addMyAvatarMarker("leftHandController", leftHandPose.getRotation(), leftHandPose.getTranslation(), glm::vec4(1)); + } else { + DebugDraw::getInstance().removeMyAvatarMarker("leftHandController"); + } + + if (rightHandPose.isValid()) { + DebugDraw::getInstance().addMyAvatarMarker("rightHandController", rightHandPose.getRotation(), rightHandPose.getTranslation(), glm::vec4(1)); + } else { + DebugDraw::getInstance().removeMyAvatarMarker("rightHandController"); + } + } + DebugDraw::getInstance().updateMyAvatarPos(getPosition()); DebugDraw::getInstance().updateMyAvatarRot(getOrientation()); diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index fd5c2920a9..0092280762 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -249,6 +249,10 @@ public: virtual void rebuildCollisionShape() override; + void setHandControllerPoses(const controller::Pose& left, const controller::Pose& right); + controller::Pose MyAvatar::getLeftHandControllerPose() const; + controller::Pose MyAvatar::getRightHandControllerPose() const; + public slots: void increaseSize(); void decreaseSize(); @@ -271,6 +275,7 @@ public slots: void setEnableDebugDrawDefaultPose(bool isEnabled); void setEnableDebugDrawAnimPose(bool isEnabled); void setEnableDebugDrawPosition(bool isEnabled); + void setEnableDebugDrawHandControllers(bool isEnabled); bool getEnableMeshVisible() const { return _skeletonModel.isVisible(); } void setEnableMeshVisible(bool isEnabled); void setUseAnimPreAndPostRotations(bool isEnabled); @@ -434,6 +439,7 @@ private: bool _enableDebugDrawDefaultPose { false }; bool _enableDebugDrawAnimPose { false }; + bool _enableDebugDrawHandControllers { false }; AudioListenerMode _audioListenerMode; glm::vec3 _customListenPosition; @@ -444,6 +450,9 @@ private: bool _hoverReferenceCameraFacingIsCaptured { false }; glm::vec3 _hoverReferenceCameraFacing { 0.0f, 0.0f, -1.0f }; // hmd sensor space + ThreadSafeValueCache _leftHandControllerPoseCache { controller::Pose() }; + ThreadSafeValueCache _rightHandControllerPoseCache { controller::Pose() }; + float AVATAR_MOVEMENT_ENERGY_CONSTANT { 0.001f }; float AUDIO_ENERGY_CONSTANT { 0.000001f }; float MAX_AVATAR_MOVEMENT_PER_FRAME { 30.0f }; diff --git a/interface/src/avatar/SkeletonModel.cpp b/interface/src/avatar/SkeletonModel.cpp index 711ed17231..d659d79dd9 100644 --- a/interface/src/avatar/SkeletonModel.cpp +++ b/interface/src/avatar/SkeletonModel.cpp @@ -16,7 +16,6 @@ #include "Application.h" #include "Avatar.h" -#include "Hand.h" #include "Menu.h" #include "SkeletonModel.h" #include "Util.h" @@ -127,20 +126,20 @@ void SkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) { Rig::HandParameters handParams; - auto leftPalm = myAvatar->getHand()->getCopyOfPalmData(HandData::LeftHand); - if (leftPalm.isValid() && leftPalm.isActive()) { + auto leftPose = myAvatar->getLeftHandControllerPose(); + if (leftPose.isValid()) { handParams.isLeftEnabled = true; - handParams.leftPosition = Quaternions::Y_180 * leftPalm.getRawPosition(); - handParams.leftOrientation = Quaternions::Y_180 * leftPalm.getRawRotation(); + handParams.leftPosition = Quaternions::Y_180 * leftPose.getTranslation(); + handParams.leftOrientation = Quaternions::Y_180 * leftPose.getRotation(); } else { handParams.isLeftEnabled = false; } - auto rightPalm = myAvatar->getHand()->getCopyOfPalmData(HandData::RightHand); - if (rightPalm.isValid() && rightPalm.isActive()) { + auto rightPose = myAvatar->getRightHandControllerPose(); + if (rightPose.isValid()) { handParams.isRightEnabled = true; - handParams.rightPosition = Quaternions::Y_180 * rightPalm.getRawPosition(); - handParams.rightOrientation = Quaternions::Y_180 * rightPalm.getRawRotation(); + handParams.rightPosition = Quaternions::Y_180 * rightPose.getTranslation(); + handParams.rightOrientation = Quaternions::Y_180 * rightPose.getRotation(); } else { handParams.isRightEnabled = false; } @@ -247,17 +246,6 @@ bool operator<(const IndexValue& firstIndex, const IndexValue& secondIndex) { return firstIndex.value < secondIndex.value; } -void SkeletonModel::applyPalmData(int jointIndex, const PalmData& palm) { - if (jointIndex == -1 || jointIndex >= _rig->getJointStateCount()) { - return; - } - const FBXGeometry& geometry = _geometry->getFBXGeometry(); - int parentJointIndex = geometry.joints.at(jointIndex).parentIndex; - if (parentJointIndex == -1) { - return; - } -} - bool SkeletonModel::getLeftGrabPosition(glm::vec3& position) const { int knuckleIndex = _rig->indexOfJoint("LeftHandMiddle1"); int handIndex = _rig->indexOfJoint("LeftHand"); diff --git a/interface/src/avatar/SkeletonModel.h b/interface/src/avatar/SkeletonModel.h index b57d54020d..6c6a7472f7 100644 --- a/interface/src/avatar/SkeletonModel.h +++ b/interface/src/avatar/SkeletonModel.h @@ -111,7 +111,6 @@ protected: void computeBoundingShape(); - void applyPalmData(int jointIndex, const PalmData& palm); private: bool getEyeModelPositions(glm::vec3& firstEyePosition, glm::vec3& secondEyePosition) const; diff --git a/interface/src/scripting/ControllerScriptingInterface.cpp b/interface/src/scripting/ControllerScriptingInterface.cpp index 9ca1e2c6c6..f6e5b6364f 100644 --- a/interface/src/scripting/ControllerScriptingInterface.cpp +++ b/interface/src/scripting/ControllerScriptingInterface.cpp @@ -13,7 +13,6 @@ #include #include -#include #include #include diff --git a/libraries/avatars/src/AvatarData.cpp b/libraries/avatars/src/AvatarData.cpp index d14df7b05a..067ab0603b 100644 --- a/libraries/avatars/src/AvatarData.cpp +++ b/libraries/avatars/src/AvatarData.cpp @@ -57,7 +57,6 @@ AvatarData::AvatarData() : _hasNewJointRotations(true), _hasNewJointTranslations(true), _headData(NULL), - _handData(NULL), _faceModelURL("http://invalid.com"), _displayNameTargetAlpha(1.0f), _displayNameAlpha(1.0f), @@ -74,7 +73,6 @@ AvatarData::AvatarData() : AvatarData::~AvatarData() { delete _headData; - delete _handData; } // We cannot have a file-level variable (const or otherwise) in the header if it uses PathUtils, because that references Application, which will not yet initialized. @@ -418,11 +416,6 @@ int AvatarData::parseDataFromBuffer(const QByteArray& buffer) { _headData = new HeadData(this); } - // lazily allocate memory for HandData in case we're not an Avatar instance - if (!_handData) { - _handData = new HandData(this); - } - const unsigned char* startPosition = reinterpret_cast(buffer.data()); const unsigned char* sourceBuffer = startPosition; quint64 now = usecTimestampNow(); diff --git a/libraries/avatars/src/AvatarData.h b/libraries/avatars/src/AvatarData.h index cf6cf80162..6ffcaed0da 100644 --- a/libraries/avatars/src/AvatarData.h +++ b/libraries/avatars/src/AvatarData.h @@ -52,9 +52,9 @@ typedef unsigned long long quint64; #include #include #include +#include #include "AABox.h" -#include "HandData.h" #include "HeadData.h" #include "PathUtils.h" @@ -290,7 +290,6 @@ public: KeyState keyState() const { return _keyState; } const HeadData* getHeadData() const { return _headData; } - const HandData* getHandData() const { return _handData; } bool hasIdentityChangedAfterParsing(const QByteArray& data); QByteArray identityByteArray(); @@ -383,7 +382,6 @@ protected: bool _hasNewJointTranslations; // set in AvatarData, cleared in Avatar HeadData* _headData; - HandData* _handData; QUrl _faceModelURL; // These need to be empty so that on first time setting them they will not short circuit QUrl _skeletonModelURL; // These need to be empty so that on first time setting them they will not short circuit diff --git a/libraries/avatars/src/HandData.cpp b/libraries/avatars/src/HandData.cpp deleted file mode 100644 index 7ba23b01ad..0000000000 --- a/libraries/avatars/src/HandData.cpp +++ /dev/null @@ -1,110 +0,0 @@ -// -// HandData.cpp -// libraries/avatars/src -// -// Created by Stephen Birarda on 5/20/13. -// Copyright 2013 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 "AvatarData.h" -#include "HandData.h" - - -HandData::HandData(AvatarData* owningAvatar) : - _owningAvatarData(owningAvatar) -{ - addNewPalm(LeftHand); - addNewPalm(RightHand); -} - -glm::vec3 HandData::worldToLocalVector(const glm::vec3& worldVector) const { - return glm::inverse(getBaseOrientation()) * worldVector / getBaseScale(); -} - -PalmData& HandData::addNewPalm(Hand whichHand) { - QWriteLocker locker(&_palmsLock); - _palms.push_back(PalmData(this, whichHand)); - return _palms.back(); -} - -PalmData HandData::getCopyOfPalmData(Hand hand) const { - QReadLocker locker(&_palmsLock); - - // the palms are not necessarily added in left-right order, - // so we have to search for the correct hand - for (const auto& palm : _palms) { - if (palm.whichHand() == hand && palm.isActive()) { - return palm; - } - } - return PalmData(); // invalid hand -} - -PalmData::PalmData(HandData* owningHandData, HandData::Hand hand) : -_rawRotation(0.0f, 0.0f, 0.0f, 1.0f), -_rawPosition(0.0f), -_rawVelocity(0.0f), -_rawAngularVelocity(0.0f), -_totalPenetration(0.0f), -_isActive(false), -_numFramesWithoutData(0), -_owningHandData(owningHandData), -_hand(hand) { -} - -void PalmData::addToPosition(const glm::vec3& delta) { - _rawPosition += _owningHandData->worldToLocalVector(delta); -} - -bool HandData::findSpherePenetration(const glm::vec3& penetratorCenter, float penetratorRadius, glm::vec3& penetration, - const PalmData*& collidingPalm) const { - QReadLocker locker(&_palmsLock); - - for (const auto& palm : _palms) { - if (!palm.isActive()) { - continue; - } - glm::vec3 palmPosition = palm.getPosition(); - const float PALM_RADIUS = 0.05f; // in world (not voxel) coordinates - if (findSphereSpherePenetration(penetratorCenter, penetratorRadius, palmPosition, PALM_RADIUS, penetration)) { - collidingPalm = &palm; - return true; - } - } - return false; -} - -glm::quat HandData::getBaseOrientation() const { - return _owningAvatarData->getOrientation(); -} - -glm::vec3 HandData::getBasePosition() const { - return _owningAvatarData->getPosition(); -} - -float HandData::getBaseScale() const { - return _owningAvatarData->getTargetScale(); -} - -glm::vec3 PalmData::getFingerDirection() const { - // finger points along yAxis in hand-frame - const glm::vec3 LOCAL_FINGER_DIRECTION(0.0f, 1.0f, 0.0f); - return glm::normalize(_owningHandData->localToWorldDirection(_rawRotation * LOCAL_FINGER_DIRECTION)); -} - -glm::vec3 PalmData::getNormal() const { - // palm normal points along zAxis in hand-frame - const glm::vec3 LOCAL_PALM_DIRECTION(0.0f, 0.0f, 1.0f); - return glm::normalize(_owningHandData->localToWorldDirection(_rawRotation * LOCAL_PALM_DIRECTION)); -} - - - diff --git a/libraries/avatars/src/HandData.h b/libraries/avatars/src/HandData.h deleted file mode 100644 index 63af43e399..0000000000 --- a/libraries/avatars/src/HandData.h +++ /dev/null @@ -1,174 +0,0 @@ -// -// HandData.h -// libraries/avatars/src -// -// Created by Eric Johnston on 6/26/13. -// Copyright 2013 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_HandData_h -#define hifi_HandData_h - -#include -#include -#include - -#include -#include - -#include - -#include -#include - -class AvatarData; -class PalmData; - -class HandData { -public: - enum Hand { - LeftHand, - RightHand, - UnknownHand, - NUMBER_OF_HANDS - }; - - HandData(AvatarData* owningAvatar); - virtual ~HandData() {} - - // position conversion - glm::vec3 localToWorldPosition(const glm::vec3& localPosition) { - return getBasePosition() + getBaseOrientation() * localPosition * getBaseScale(); - } - - glm::vec3 localToWorldDirection(const glm::vec3& localVector) { - return getBaseOrientation() * localVector * getBaseScale(); - } - - glm::vec3 worldToLocalVector(const glm::vec3& worldVector) const; - - PalmData getCopyOfPalmData(Hand hand) const; - - std::vector getCopyOfPalms() const { QReadLocker locker(&_palmsLock); return _palms; } - - /// Checks for penetration between the described sphere and the hand. - /// \param penetratorCenter the center of the penetration test sphere - /// \param penetratorRadius the radius of the penetration test sphere - /// \param penetration[out] the vector in which to store the penetration - /// \param collidingPalm[out] a const PalmData* to the palm that was collided with - /// \return whether or not the sphere penetrated - bool findSpherePenetration(const glm::vec3& penetratorCenter, float penetratorRadius, glm::vec3& penetration, - const PalmData*& collidingPalm) const; - - glm::quat getBaseOrientation() const; - - /// Allows a lamda function write access to the specific palm for this Hand, this might - /// modify the _palms vector - template void modifyPalm(Hand whichHand, PalmModifierFunction callback); - - friend class AvatarData; -protected: - AvatarData* _owningAvatarData; - std::vector _palms; - mutable QReadWriteLock _palmsLock{ QReadWriteLock::Recursive }; - - glm::vec3 getBasePosition() const; - float getBaseScale() const; - - PalmData& addNewPalm(Hand whichHand); - PalmData& getPalmData(Hand hand); - -private: - // privatize copy ctor and assignment operator so copies of this object cannot be made - HandData(const HandData&); - HandData& operator= (const HandData&); -}; - - -class PalmData { -public: - PalmData(HandData* owningHandData = nullptr, HandData::Hand hand = HandData::UnknownHand); - glm::vec3 getPosition() const { return _owningHandData->localToWorldPosition(_rawPosition); } - glm::vec3 getVelocity() const { return _owningHandData->localToWorldDirection(_rawVelocity); } - glm::vec3 getAngularVelocity() const { return _owningHandData->localToWorldDirection(_rawAngularVelocity); } - - const glm::vec3& getRawPosition() const { return _rawPosition; } - bool isActive() const { return _isActive; } - bool isValid() const { return _owningHandData; } - - void setActive(bool active) { _isActive = active; } - - HandData::Hand whichHand() const { return _hand; } - void setHand(HandData::Hand hand) { _hand = hand; } - - void setRawRotation(const glm::quat& rawRotation) { _rawRotation = rawRotation; }; - glm::quat getRawRotation() const { return _rawRotation; } - glm::quat getRotation() const { return _owningHandData->getBaseOrientation() * _rawRotation; } - void setRawPosition(const glm::vec3& pos) { _rawPosition = pos; } - void setRawVelocity(const glm::vec3& velocity) { _rawVelocity = velocity; } - const glm::vec3& getRawVelocity() const { return _rawVelocity; } - - void setRawAngularVelocity(const glm::vec3& angularVelocity) { _rawAngularVelocity = angularVelocity; } - const glm::vec3& getRawAngularVelocity() const { return _rawAngularVelocity; } - - void addToPosition(const glm::vec3& delta); - - void addToPenetration(const glm::vec3& penetration) { _totalPenetration += penetration; } - void resolvePenetrations() { addToPosition(-_totalPenetration); _totalPenetration = glm::vec3(0.0f); } - - void setTipPosition(const glm::vec3& position) { _tipPosition = position; } - const glm::vec3 getTipPosition() const { return _owningHandData->localToWorldPosition(_tipPosition); } - const glm::vec3& getTipRawPosition() const { return _tipPosition; } - - void setTipVelocity(const glm::vec3& velocity) { _tipVelocity = velocity; } - const glm::vec3 getTipVelocity() const { return _owningHandData->localToWorldDirection(_tipVelocity); } - const glm::vec3& getTipRawVelocity() const { return _tipVelocity; } - - void incrementFramesWithoutData() { _numFramesWithoutData++; } - void resetFramesWithoutData() { _numFramesWithoutData = 0; } - int getFramesWithoutData() const { return _numFramesWithoutData; } - - // FIXME - these are used in SkeletonModel::updateRig() the skeleton/rig should probably get this information - // from an action and/or the UserInputMapper instead of piping it through here. - void setTrigger(float trigger) { _trigger = trigger; } - float getTrigger() const { return _trigger; } - - // return world-frame: - glm::vec3 getFingerDirection() const; - glm::vec3 getNormal() const; - -private: - // unless marked otherwise, these are all in the model-frame - glm::quat _rawRotation; - glm::vec3 _rawPosition; - glm::vec3 _rawVelocity; - glm::vec3 _rawAngularVelocity; - glm::quat _rawDeltaRotation; - glm::quat _lastRotation; - - glm::vec3 _tipPosition; - glm::vec3 _tipVelocity; - glm::vec3 _totalPenetration; /// accumulator for per-frame penetrations - - float _trigger; - - bool _isActive; /// This has current valid data - int _numFramesWithoutData; /// after too many frames without data, this tracked object assumed lost. - HandData* _owningHandData; - HandData::Hand _hand; -}; - -template void HandData::modifyPalm(Hand whichHand, PalmModifierFunction callback) { - QReadLocker locker(&_palmsLock); - for (auto& palm : _palms) { - if (palm.whichHand() == whichHand && palm.isValid()) { - callback(palm); - return; - } - } -} - -#endif // hifi_HandData_h From ab19d3e5a2a4ec261377c42a53efa768a803b386 Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Thu, 10 Mar 2016 20:44:35 -0800 Subject: [PATCH 06/20] Moved animation after physics, hand poses are in world frame. There are still some debug hacks enabled so I can test in the vive room. --- interface/src/Application.cpp | 7 +- interface/src/avatar/AvatarActionHold.cpp | 4 +- interface/src/avatar/MyAvatar.cpp | 68 ++++++++++++-------- interface/src/avatar/MyAvatar.h | 13 ++-- interface/src/avatar/SkeletonModel.cpp | 4 +- libraries/render-utils/src/AnimDebugDraw.cpp | 7 +- plugins/hifiSixense/src/SixenseManager.cpp | 6 ++ 7 files changed, 68 insertions(+), 41 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 728691a0e1..42430b3a4c 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3218,13 +3218,12 @@ void Application::update(float deltaTime) { controller::Pose leftHandPose = userInputMapper->getPoseState(controller::Action::LEFT_HAND); controller::Pose rightHandPose = userInputMapper->getPoseState(controller::Action::RIGHT_HAND); - myAvatar->setHandControllerPoses(leftHandPose, rightHandPose); + auto myAvatarMatrix = createMatFromQuatAndPos(myAvatar->getOrientation(), myAvatar->getPosition()); + myAvatar->setHandControllerPosesInWorldFrame(leftHandPose.transform(myAvatarMatrix), rightHandPose.transform(myAvatarMatrix)); updateThreads(deltaTime); // If running non-threaded, then give the threads some time to process... updateDialogs(deltaTime); // update various stats dialogs if present - _avatarUpdate->synchronousProcess(); - if (_physicsEnabled) { PerformanceTimer perfTimer("physics"); AvatarManager* avatarManager = DependencyManager::get().data(); @@ -3296,6 +3295,8 @@ void Application::update(float deltaTime) { } } + _avatarUpdate->synchronousProcess(); + { PerformanceTimer perfTimer("overlays"); _overlays.update(deltaTime); diff --git a/interface/src/avatar/AvatarActionHold.cpp b/interface/src/avatar/AvatarActionHold.cpp index 0ce0b5a190..5087f7955d 100644 --- a/interface/src/avatar/AvatarActionHold.cpp +++ b/interface/src/avatar/AvatarActionHold.cpp @@ -113,9 +113,9 @@ std::shared_ptr AvatarActionHold::getTarget(float deltaTimeStep, glm::qu // fetch the hand controller pose controller::Pose pose; if (isRightHand) { - pose = avatarManager->getMyAvatar()->getRightHandControllerPose(); + pose = avatarManager->getMyAvatar()->getRightHandControllerPoseInWorldFrame(); } else { - pose = avatarManager->getMyAvatar()->getLeftHandControllerPose(); + pose = avatarManager->getMyAvatar()->getLeftHandControllerPoseInWorldFrame(); } if (pose.isValid()) { diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 016e2a464c..c018a76168 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -512,39 +512,38 @@ void MyAvatar::updateFromTrackers(float deltaTime) { -MAX_LEAN, MAX_LEAN)); } - glm::vec3 MyAvatar::getLeftHandPosition() const { - auto pose = getLeftHandControllerPose(); + auto pose = getLeftHandControllerPoseInAvatarFrame(); return pose.isValid() ? pose.getTranslation() : glm::vec3(0.0f); } glm::vec3 MyAvatar::getRightHandPosition() const { - auto pose = getRightHandControllerPose(); + auto pose = getRightHandControllerPoseInAvatarFrame(); return pose.isValid() ? pose.getTranslation() : glm::vec3(0.0f); } glm::vec3 MyAvatar::getLeftHandTipPosition() const { const float TIP_LENGTH = 0.3f; - auto pose = getLeftHandControllerPose(); + auto pose = getLeftHandControllerPoseInAvatarFrame(); return pose.isValid() ? pose.getTranslation() * pose.getRotation() + glm::vec3(0.0f, TIP_LENGTH, 0.0f) : glm::vec3(0.0f); } glm::vec3 MyAvatar::getRightHandTipPosition() const { const float TIP_LENGTH = 0.3f; - auto pose = getRightHandControllerPose(); + auto pose = getRightHandControllerPoseInAvatarFrame(); return pose.isValid() ? pose.getTranslation() * pose.getRotation() + glm::vec3(0.0f, TIP_LENGTH, 0.0f) : glm::vec3(0.0f); } controller::Pose MyAvatar::getLeftHandPose() const { - return getLeftHandControllerPose(); + return getLeftHandControllerPoseInAvatarFrame(); } controller::Pose MyAvatar::getRightHandPose() const { - return getRightHandControllerPose(); + return getRightHandControllerPoseInAvatarFrame(); } controller::Pose MyAvatar::getLeftHandTipPose() const { - auto pose = getLeftHandControllerPose(); + auto pose = getLeftHandControllerPoseInAvatarFrame(); glm::vec3 tipTrans = getLeftHandTipPosition(); pose.velocity += glm::cross(pose.getAngularVelocity(), pose.getTranslation() - tipTrans); pose.translation = tipTrans; @@ -552,7 +551,7 @@ controller::Pose MyAvatar::getLeftHandTipPose() const { } controller::Pose MyAvatar::getRightHandTipPose() const { - auto pose = getRightHandControllerPose(); + auto pose = getRightHandControllerPoseInAvatarFrame(); glm::vec3 tipTrans = getRightHandTipPosition(); pose.velocity += glm::cross(pose.getAngularVelocity(), pose.getTranslation() - tipTrans); pose.translation = tipTrans; @@ -697,8 +696,8 @@ void MyAvatar::setEnableDebugDrawPosition(bool isEnabled) { void MyAvatar::setEnableDebugDrawHandControllers(bool isEnabled) { _enableDebugDrawHandControllers = isEnabled; if (!isEnabled) { - DebugDraw::getInstance().removeMyAvatarMarker("leftHandController"); - DebugDraw::getInstance().removeMyAvatarMarker("rightHandController"); + DebugDraw::getInstance().removeMarker("leftHandController"); + DebugDraw::getInstance().removeMarker("rightHandController"); } } @@ -1096,24 +1095,34 @@ static controller::Pose applyLowVelocityFilter(const controller::Pose& oldPose, return finalPose; } -void MyAvatar::setHandControllerPoses(const controller::Pose& left, const controller::Pose& right) { +void MyAvatar::setHandControllerPosesInWorldFrame(const controller::Pose& left, const controller::Pose& right) { if (controller::InputDevice::getLowVelocityFilter()) { - auto oldLeftPose = getLeftHandControllerPose(); - auto oldRightPose = getRightHandControllerPose(); - _leftHandControllerPoseCache.set(applyLowVelocityFilter(oldLeftPose, left)); - _rightHandControllerPoseCache.set(applyLowVelocityFilter(oldRightPose, right)); + auto oldLeftPose = getLeftHandControllerPoseInWorldFrame(); + auto oldRightPose = getRightHandControllerPoseInWorldFrame(); + _leftHandControllerPoseInWorldFrameCache.set(applyLowVelocityFilter(oldLeftPose, left)); + _rightHandControllerPoseInWorldFrameCache.set(applyLowVelocityFilter(oldRightPose, right)); } else { - _leftHandControllerPoseCache.set(left); - _rightHandControllerPoseCache.set(right); + _leftHandControllerPoseInWorldFrameCache.set(left); + _rightHandControllerPoseInWorldFrameCache.set(right); } } -controller::Pose MyAvatar::getLeftHandControllerPose() const { - return _leftHandControllerPoseCache.get(); +controller::Pose MyAvatar::getLeftHandControllerPoseInWorldFrame() const { + return _leftHandControllerPoseInWorldFrameCache.get(); } -controller::Pose MyAvatar::getRightHandControllerPose() const { - return _rightHandControllerPoseCache.get(); +controller::Pose MyAvatar::getRightHandControllerPoseInWorldFrame() const { + return _rightHandControllerPoseInWorldFrameCache.get(); +} + +controller::Pose MyAvatar::getLeftHandControllerPoseInAvatarFrame() const { + glm::mat4 invAvatarMatrix = glm::inverse(createMatFromQuatAndPos(getOrientation(), getPosition())); + return getLeftHandControllerPoseInWorldFrame().transform(invAvatarMatrix); +} + +controller::Pose MyAvatar::getRightHandControllerPoseInAvatarFrame() const { + glm::mat4 invAvatarMatrix = glm::inverse(createMatFromQuatAndPos(getOrientation(), getPosition())); + return getRightHandControllerPoseInWorldFrame().transform(invAvatarMatrix); } void MyAvatar::prepareForPhysicsSimulation() { @@ -1360,20 +1369,23 @@ void MyAvatar::preRender(RenderArgs* renderArgs) { } if (_enableDebugDrawHandControllers) { - auto leftHandPose = getLeftHandControllerPose(); - auto rightHandPose = getRightHandControllerPose(); + auto leftHandPose = getLeftHandControllerPoseInWorldFrame(); + auto rightHandPose = getRightHandControllerPoseInWorldFrame(); if (leftHandPose.isValid()) { - DebugDraw::getInstance().addMyAvatarMarker("leftHandController", leftHandPose.getRotation(), leftHandPose.getTranslation(), glm::vec4(1)); + DebugDraw::getInstance().addMarker("leftHandController", leftHandPose.getRotation(), leftHandPose.getTranslation(), glm::vec4(1)); } else { - DebugDraw::getInstance().removeMyAvatarMarker("leftHandController"); + DebugDraw::getInstance().removeMarker("leftHandController"); } if (rightHandPose.isValid()) { - DebugDraw::getInstance().addMyAvatarMarker("rightHandController", rightHandPose.getRotation(), rightHandPose.getTranslation(), glm::vec4(1)); + DebugDraw::getInstance().addMarker("rightHandController", rightHandPose.getRotation(), rightHandPose.getTranslation(), glm::vec4(1)); } else { - DebugDraw::getInstance().removeMyAvatarMarker("rightHandController"); + DebugDraw::getInstance().removeMarker("rightHandController"); } + + // AJT: REMOVE + DebugDraw::getInstance().addMyAvatarMarker("REFERENCE", glm::quat(), glm::vec3(0.0f, 0.7f, -0.5f), glm::vec4(1)); } DebugDraw::getInstance().updateMyAvatarPos(getPosition()); diff --git a/interface/src/avatar/MyAvatar.h b/interface/src/avatar/MyAvatar.h index 0092280762..2301e37a5b 100644 --- a/interface/src/avatar/MyAvatar.h +++ b/interface/src/avatar/MyAvatar.h @@ -249,9 +249,11 @@ public: virtual void rebuildCollisionShape() override; - void setHandControllerPoses(const controller::Pose& left, const controller::Pose& right); - controller::Pose MyAvatar::getLeftHandControllerPose() const; - controller::Pose MyAvatar::getRightHandControllerPose() const; + void setHandControllerPosesInWorldFrame(const controller::Pose& left, const controller::Pose& right); + controller::Pose getLeftHandControllerPoseInWorldFrame() const; + controller::Pose getRightHandControllerPoseInWorldFrame() const; + controller::Pose getLeftHandControllerPoseInAvatarFrame() const; + controller::Pose getRightHandControllerPoseInAvatarFrame() const; public slots: void increaseSize(); @@ -450,8 +452,9 @@ private: bool _hoverReferenceCameraFacingIsCaptured { false }; glm::vec3 _hoverReferenceCameraFacing { 0.0f, 0.0f, -1.0f }; // hmd sensor space - ThreadSafeValueCache _leftHandControllerPoseCache { controller::Pose() }; - ThreadSafeValueCache _rightHandControllerPoseCache { controller::Pose() }; + // These are stored in WORLD frame + ThreadSafeValueCache _leftHandControllerPoseInWorldFrameCache { controller::Pose() }; + ThreadSafeValueCache _rightHandControllerPoseInWorldFrameCache { controller::Pose() }; float AVATAR_MOVEMENT_ENERGY_CONSTANT { 0.001f }; float AUDIO_ENERGY_CONSTANT { 0.000001f }; diff --git a/interface/src/avatar/SkeletonModel.cpp b/interface/src/avatar/SkeletonModel.cpp index d659d79dd9..46a091cf35 100644 --- a/interface/src/avatar/SkeletonModel.cpp +++ b/interface/src/avatar/SkeletonModel.cpp @@ -126,7 +126,7 @@ void SkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) { Rig::HandParameters handParams; - auto leftPose = myAvatar->getLeftHandControllerPose(); + auto leftPose = myAvatar->getLeftHandControllerPoseInAvatarFrame(); if (leftPose.isValid()) { handParams.isLeftEnabled = true; handParams.leftPosition = Quaternions::Y_180 * leftPose.getTranslation(); @@ -135,7 +135,7 @@ void SkeletonModel::updateRig(float deltaTime, glm::mat4 parentTransform) { handParams.isLeftEnabled = false; } - auto rightPose = myAvatar->getRightHandControllerPose(); + auto rightPose = myAvatar->getRightHandControllerPoseInAvatarFrame(); if (rightPose.isValid()) { handParams.isRightEnabled = true; handParams.rightPosition = Quaternions::Y_180 * rightPose.getTranslation(); diff --git a/libraries/render-utils/src/AnimDebugDraw.cpp b/libraries/render-utils/src/AnimDebugDraw.cpp index c9abf71fad..44bf533739 100644 --- a/libraries/render-utils/src/AnimDebugDraw.cpp +++ b/libraries/render-utils/src/AnimDebugDraw.cpp @@ -392,13 +392,18 @@ void AnimDebugDraw::update() { assert(numVerts == (v - verts)); + // This render item bound shit is broken. + // Fuck that, use the big ass bound instead. + /* render::Item::Bound theBound; for (int i = 0; i < numVerts; i++) { theBound += verts[i].pos; } + */ data._isVisible = (numVerts > 0); - data._bound = theBound; + + //data._bound = theBound; data._indexBuffer->resize(sizeof(uint16_t) * numVerts); uint16_t* indices = (uint16_t*)data._indexBuffer->editData(); for (int i = 0; i < numVerts; i++) { diff --git a/plugins/hifiSixense/src/SixenseManager.cpp b/plugins/hifiSixense/src/SixenseManager.cpp index 9fdce3add4..67192edebd 100644 --- a/plugins/hifiSixense/src/SixenseManager.cpp +++ b/plugins/hifiSixense/src/SixenseManager.cpp @@ -481,6 +481,12 @@ void SixenseManager::InputDevice::handlePoseEvent(float deltaTime, const control // transform pose into avatar frame. auto nextPose = controller::Pose(pos, rot, velocity, angularVelocity).transform(controllerToAvatar); + if (!left) { + // AJT: HACK TO DEBUG IK + nextPose.translation = glm::vec3(0.25f, 0.7f, -0.5f); + nextPose.rotation = glm::quat(); + } + if (prevPose.isValid() && (deltaTime > std::numeric_limits::epsilon())) { nextPose.velocity = (nextPose.getTranslation() - prevPose.getTranslation()) / deltaTime; From 7ae9006b30f331f99bd68f553e47cb7b5ffdef77 Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Thu, 10 Mar 2016 22:42:53 -0800 Subject: [PATCH 07/20] add current version to console menu --- server-console/src/main.js | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/server-console/src/main.js b/server-console/src/main.js index e05106aa6f..fedd934029 100644 --- a/server-console/src/main.js +++ b/server-console/src/main.js @@ -532,10 +532,13 @@ function buildMenuArray(serverState) { { type: 'separator' }, - { + { label: 'Quit', accelerator: 'Command+Q', click: function() { shutdown(); } + }, + { + label: 'Current Version: '+buildInfo.buildIdentifier } ]; @@ -776,6 +779,7 @@ app.on('ready', function() { } catch (e) { } + if (currentVersion !== null) { const CHECK_FOR_UPDATES_INTERVAL_SECONDS = 60 * 30; var hasShownUpdateNotification = false; From 5eeb4ca594aae5de25b81f1e90987a059c9d7399 Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Fri, 11 Mar 2016 09:28:25 -0800 Subject: [PATCH 08/20] Fix one frame lag controller lag/jitter Move userInputMapper->update() after inputPlugin->pluginUpdate(). --- interface/src/Application.cpp | 3 ++- interface/src/avatar/MyAvatar.cpp | 3 --- libraries/shared/src/GLMHelpers.cpp | 8 ++++++++ libraries/shared/src/GLMHelpers.h | 2 ++ plugins/hifiSixense/src/SixenseManager.cpp | 6 ------ 5 files changed, 12 insertions(+), 10 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 42430b3a4c..2e4cb1db0f 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3179,7 +3179,6 @@ void Application::update(float deltaTime) { auto myAvatar = getMyAvatar(); auto userInputMapper = DependencyManager::get(); - userInputMapper->update(deltaTime); controller::InputCalibrationData calibrationData = { myAvatar->getSensorToWorldMatrix(), @@ -3197,6 +3196,8 @@ void Application::update(float deltaTime) { } } + userInputMapper->update(deltaTime); + _controllerScriptingInterface->updateInputControllers(); // Transfer the user inputs to the driveKeys diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index c018a76168..8be8b601a4 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -1383,9 +1383,6 @@ void MyAvatar::preRender(RenderArgs* renderArgs) { } else { DebugDraw::getInstance().removeMarker("rightHandController"); } - - // AJT: REMOVE - DebugDraw::getInstance().addMyAvatarMarker("REFERENCE", glm::quat(), glm::vec3(0.0f, 0.7f, -0.5f), glm::vec4(1)); } DebugDraw::getInstance().updateMyAvatarPos(getPosition()); diff --git a/libraries/shared/src/GLMHelpers.cpp b/libraries/shared/src/GLMHelpers.cpp index b2294f9ef3..d21d88d212 100644 --- a/libraries/shared/src/GLMHelpers.cpp +++ b/libraries/shared/src/GLMHelpers.cpp @@ -471,3 +471,11 @@ bool isNaN(glm::quat value) { return isNaN(value.w) || isNaN(value.x) || isNaN(value.y) || isNaN(value.z); } +glm::mat4 orthoInverse(const glm::mat4& m) { + glm::mat4 r = m; + r[3] = glm::vec4(0.0f, 0.0f, 0.0f, 1.0f); + r = glm::transpose(r); + r[3] = -(r * m[3]); + r[3][3] = 1.0f; + return r; +} diff --git a/libraries/shared/src/GLMHelpers.h b/libraries/shared/src/GLMHelpers.h index 4a37d68240..469ca1fc81 100644 --- a/libraries/shared/src/GLMHelpers.h +++ b/libraries/shared/src/GLMHelpers.h @@ -232,4 +232,6 @@ glm::vec2 getFacingDir2D(const glm::mat4& m); bool isNaN(glm::vec3 value); bool isNaN(glm::quat value); +glm::mat4 orthoInverse(const glm::mat4& m); + #endif // hifi_GLMHelpers_h diff --git a/plugins/hifiSixense/src/SixenseManager.cpp b/plugins/hifiSixense/src/SixenseManager.cpp index 67192edebd..9fdce3add4 100644 --- a/plugins/hifiSixense/src/SixenseManager.cpp +++ b/plugins/hifiSixense/src/SixenseManager.cpp @@ -481,12 +481,6 @@ void SixenseManager::InputDevice::handlePoseEvent(float deltaTime, const control // transform pose into avatar frame. auto nextPose = controller::Pose(pos, rot, velocity, angularVelocity).transform(controllerToAvatar); - if (!left) { - // AJT: HACK TO DEBUG IK - nextPose.translation = glm::vec3(0.25f, 0.7f, -0.5f); - nextPose.rotation = glm::quat(); - } - if (prevPose.isValid() && (deltaTime > std::numeric_limits::epsilon())) { nextPose.velocity = (nextPose.getTranslation() - prevPose.getTranslation()) / deltaTime; From 082bb8c4b8d773add9c0fbacb4668c762cf24fa2 Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Fri, 11 Mar 2016 12:49:42 -0800 Subject: [PATCH 09/20] auto-show reticle on mouse click --- examples/depthReticle.js | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/examples/depthReticle.js b/examples/depthReticle.js index 14215bff3d..52392b2466 100644 --- a/examples/depthReticle.js +++ b/examples/depthReticle.js @@ -21,7 +21,7 @@ var MINIMUM_DEPTH_ADJUST = 0.01; var NON_LINEAR_DIVISOR = 2; var MINIMUM_SEEK_DISTANCE = 0.01; -var lastMouseMove = Date.now(); +var lastMouseMoveOrClick = Date.now(); var lastMouseX = Reticle.position.x; var lastMouseY = Reticle.position.y; var HIDE_STATIC_MOUSE_AFTER = 3000; // 3 seconds @@ -32,6 +32,14 @@ var WEIGHTING = 1/20; // simple moving average over last 20 samples var ONE_MINUS_WEIGHTING = 1 - WEIGHTING; var AVERAGE_MOUSE_VELOCITY_FOR_SEEK_TO = 50; +function showReticleOnMouseClick() { + Reticle.visible = true; + lastMouseMoveOrClick = Date.now(); // move or click +} + +Controller.mousePressEvent.connect(showReticleOnMouseClick); +Controller.mouseDoublePressEvent.connect(showReticleOnMouseClick); + Controller.mouseMoveEvent.connect(function(mouseEvent) { var now = Date.now(); @@ -47,7 +55,7 @@ Controller.mouseMoveEvent.connect(function(mouseEvent) { if (HMD.active && !shouldSeekToLookAt && Reticle.allowMouseCapture) { var dx = Reticle.position.x - lastMouseX; var dy = Reticle.position.y - lastMouseY; - var dt = Math.max(1, (now - lastMouseMove)); // mSecs since last mouse move + var dt = Math.max(1, (now - lastMouseMoveOrClick)); // mSecs since last mouse move var mouseMoveDistance = Math.sqrt((dx*dx) + (dy*dy)); var mouseVelocity = mouseMoveDistance / dt; averageMouseVelocity = (ONE_MINUS_WEIGHTING * averageMouseVelocity) + (WEIGHTING * mouseVelocity); @@ -56,7 +64,7 @@ Controller.mouseMoveEvent.connect(function(mouseEvent) { } } } - lastMouseMove = now; + lastMouseMoveOrClick = now; lastMouseX = mouseEvent.x; lastMouseY = mouseEvent.y; }); @@ -94,7 +102,7 @@ function autoHideReticle() { // system overlay (like a window), then hide the reticle if (Reticle.visible && !Reticle.pointingAtSystemOverlay) { var now = Date.now(); - var timeSinceLastMouseMove = now - lastMouseMove; + var timeSinceLastMouseMove = now - lastMouseMoveOrClick; if (timeSinceLastMouseMove > HIDE_STATIC_MOUSE_AFTER) { Reticle.visible = false; } From 0ce004c8a7db7d555755544b1cd7ab824cbf990f Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Fri, 11 Mar 2016 13:35:27 -0800 Subject: [PATCH 10/20] Removed passive-aggressive comment, (it was a late night) --- libraries/render-utils/src/AnimDebugDraw.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/libraries/render-utils/src/AnimDebugDraw.cpp b/libraries/render-utils/src/AnimDebugDraw.cpp index 44bf533739..a0f7d7eca1 100644 --- a/libraries/render-utils/src/AnimDebugDraw.cpp +++ b/libraries/render-utils/src/AnimDebugDraw.cpp @@ -392,18 +392,20 @@ void AnimDebugDraw::update() { assert(numVerts == (v - verts)); - // This render item bound shit is broken. - // Fuck that, use the big ass bound instead. + // The RenderItem culling is not working correctly + // Workaround this issue by using the default constructed + // item._bound which is a 16 km cube. /* render::Item::Bound theBound; for (int i = 0; i < numVerts; i++) { theBound += verts[i].pos; } + data._bound = theBound; */ data._isVisible = (numVerts > 0); - //data._bound = theBound; + data._indexBuffer->resize(sizeof(uint16_t) * numVerts); uint16_t* indices = (uint16_t*)data._indexBuffer->editData(); for (int i = 0; i < numVerts; i++) { From fce83697087d657c3b76ec35f09150dbbb57d7f3 Mon Sep 17 00:00:00 2001 From: howard-stearns Date: Fri, 11 Mar 2016 14:23:47 -0800 Subject: [PATCH 11/20] Remove logging that implies a problem that isn't there. --- libraries/script-engine/src/ScriptCache.cpp | 3 --- 1 file changed, 3 deletions(-) diff --git a/libraries/script-engine/src/ScriptCache.cpp b/libraries/script-engine/src/ScriptCache.cpp index ae422313aa..3ebd3d53ce 100644 --- a/libraries/script-engine/src/ScriptCache.cpp +++ b/libraries/script-engine/src/ScriptCache.cpp @@ -115,9 +115,6 @@ void ScriptCache::getScriptContents(const QString& scriptOrURL, contentAvailable auto scriptContent = _scriptCache[url]; lock.unlock(); qCDebug(scriptengine) << "Found script in cache:" << url.toString(); - #if 1 // def THREAD_DEBUGGING - qCDebug(scriptengine) << "ScriptCache::getScriptContents() about to call contentAvailable() on thread [" << QThread::currentThread() << "] expected thread [" << thread() << "]"; - #endif contentAvailable(url.toString(), scriptContent, true, true); } else { bool alreadyWaiting = _contentCallbacks.contains(url); From 973022f0e104ab1430e4958205b5377db3bf7d7c Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Fri, 11 Mar 2016 14:51:36 -0800 Subject: [PATCH 12/20] version attempts --- server-console/src/main.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/server-console/src/main.js b/server-console/src/main.js index fedd934029..c9e33e2ce4 100644 --- a/server-console/src/main.js +++ b/server-console/src/main.js @@ -538,7 +538,11 @@ function buildMenuArray(serverState) { click: function() { shutdown(); } }, { - label: 'Current Version: '+buildInfo.buildIdentifier + type: 'separator' + }, + { + label: 'Current Version: '+buildInfo.buildIdentifier, + enabled: false } ]; @@ -776,6 +780,7 @@ app.on('ready', function() { var currentVersion = null; try { currentVersion = parseInt(buildInfo.buildIdentifier); + console.log('CURRENT VERSION:: ',currentVersion) } catch (e) { } From ecf67282d5b43ae43473e9b6736625867c5badfe Mon Sep 17 00:00:00 2001 From: David Rowe Date: Sat, 12 Mar 2016 12:29:52 +1300 Subject: [PATCH 13/20] Add separators to HMD menus --- interface/resources/qml/menus/VrMenuItem.qml | 22 ++++++++++++++++++- .../qml/styles-uit/HifiConstants.qml | 1 + libraries/ui/src/VrMenu.cpp | 14 ++++++++++++ libraries/ui/src/VrMenu.h | 1 + libraries/ui/src/ui/Menu.cpp | 6 ++++- 5 files changed, 42 insertions(+), 2 deletions(-) diff --git a/interface/resources/qml/menus/VrMenuItem.qml b/interface/resources/qml/menus/VrMenuItem.qml index 636728c890..5854a75ef5 100644 --- a/interface/resources/qml/menus/VrMenuItem.qml +++ b/interface/resources/qml/menus/VrMenuItem.qml @@ -28,7 +28,7 @@ Item { CheckBox { id: check - // FIXME: Shouild use radio buttons if source.exclusiveGroup. + // FIXME: Should use radio buttons if source.exclusiveGroup. anchors { left: parent.left leftMargin: hifi.dimensions.menuPadding.x @@ -60,6 +60,26 @@ Item { visible: source.visible } + Item { + id: separator + anchors { + fill: parent + leftMargin: hifi.dimensions.menuPadding.x + check.width + rightMargin: hifi.dimensions.menuPadding.x + tail.width + } + visible: source.type === MenuItemType.Separator + + Rectangle { + anchors { + left: parent.left + right: parent.right + verticalCenter: parent.verticalCenter + } + height: 1 + color: hifi.colors.lightGray50 + } + } + Item { // Space for shortcut key or disclosure icon. id: tail diff --git a/interface/resources/qml/styles-uit/HifiConstants.qml b/interface/resources/qml/styles-uit/HifiConstants.qml index 718c1e32cb..2a1053c2b6 100644 --- a/interface/resources/qml/styles-uit/HifiConstants.qml +++ b/interface/resources/qml/styles-uit/HifiConstants.qml @@ -71,6 +71,7 @@ Item { readonly property color baseGrayShadow25: "#40252525" readonly property color baseGrayHighlight40: "#66575757" readonly property color baseGrayHighlight15: "#26575757" + readonly property color lightGray50: "#806a6a6a" readonly property color lightGrayText80: "#ccafafaf" readonly property color faintGray80: "#cce3e3e3" readonly property color faintGray50: "#80e3e3e3" diff --git a/libraries/ui/src/VrMenu.cpp b/libraries/ui/src/VrMenu.cpp index 76acf5d18a..41768a5349 100644 --- a/libraries/ui/src/VrMenu.cpp +++ b/libraries/ui/src/VrMenu.cpp @@ -190,6 +190,20 @@ void VrMenu::addAction(QMenu* menu, QAction* action) { bindActionToQmlAction(result, action); } +void VrMenu::addSeparator(QMenu* menu) { + Q_ASSERT(MenuUserData::forObject(menu)); + MenuUserData* userData = MenuUserData::forObject(menu); + if (!userData) { + return; + } + QObject* menuQml = findMenuObject(userData->uuid.toString()); + Q_ASSERT(menuQml); + + bool invokeResult = QMetaObject::invokeMethod(menuQml, "addSeparator", Qt::DirectConnection); + Q_ASSERT(invokeResult); + Q_UNUSED(invokeResult); // FIXME - apparently we haven't upgraded the Qt on our unix Jenkins environments to 5.5.x +} + void VrMenu::insertAction(QAction* before, QAction* action) { QObject* beforeQml{ nullptr }; { diff --git a/libraries/ui/src/VrMenu.h b/libraries/ui/src/VrMenu.h index b092b63566..d03887821f 100644 --- a/libraries/ui/src/VrMenu.h +++ b/libraries/ui/src/VrMenu.h @@ -28,6 +28,7 @@ public: VrMenu(QObject* parent = nullptr); void addMenu(QMenu* menu); void addAction(QMenu* parent, QAction* action); + void addSeparator(QMenu* parent); void insertAction(QAction* before, QAction* action); void removeAction(QAction* action); diff --git a/libraries/ui/src/ui/Menu.cpp b/libraries/ui/src/ui/Menu.cpp index 1b70213876..a5d801869d 100644 --- a/libraries/ui/src/ui/Menu.cpp +++ b/libraries/ui/src/ui/Menu.cpp @@ -511,7 +511,11 @@ void MenuWrapper::setEnabled(bool enabled) { } QAction* MenuWrapper::addSeparator() { - return _realMenu->addSeparator(); + QAction* action = _realMenu->addSeparator(); + VrMenu::executeOrQueue([=](VrMenu* vrMenu) { + vrMenu->addSeparator(_realMenu); + }); + return action; } void MenuWrapper::addAction(QAction* action) { From 9da64e540dd7485b8fdcdd64e2f5a27e040030e2 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Sat, 12 Mar 2016 12:53:16 +1300 Subject: [PATCH 14/20] Add shortcut keys to HMD menu --- interface/resources/qml/menus/VrMenuItem.qml | 14 ++++++++++++-- libraries/ui/src/VrMenu.cpp | 1 + 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/interface/resources/qml/menus/VrMenuItem.qml b/interface/resources/qml/menus/VrMenuItem.qml index 5854a75ef5..0b18811ccf 100644 --- a/interface/resources/qml/menus/VrMenuItem.qml +++ b/interface/resources/qml/menus/VrMenuItem.qml @@ -81,15 +81,25 @@ Item { } Item { - // Space for shortcut key or disclosure icon. id: tail - width: 48 + width: 48 + (shortcut.visible ? shortcut.width : 0) anchors { verticalCenter: parent.verticalCenter right: parent.right rightMargin: hifi.dimensions.menuPadding.x } + RalewayLight { + id: shortcut + text: source.shortcut ? source.shortcut : "" + size: hifi.fontSizes.shortcutText + color: hifi.colors.baseGrayShadow + anchors.verticalCenter: parent.verticalCenter + anchors.right: parent.right + anchors.rightMargin: 15 + visible: source.visible && text != "" + } + HiFiGlyphs { text: hifi.glyphs.disclosureExpand color: source.enabled ? hifi.colors.baseGrayShadow : hifi.colors.baseGrayShadow25 diff --git a/libraries/ui/src/VrMenu.cpp b/libraries/ui/src/VrMenu.cpp index 41768a5349..5acf81c319 100644 --- a/libraries/ui/src/VrMenu.cpp +++ b/libraries/ui/src/VrMenu.cpp @@ -104,6 +104,7 @@ void updateQmlItemFromAction(QObject* target, QAction* source) { target->setProperty("checkable", source->isCheckable()); target->setProperty("enabled", source->isEnabled()); target->setProperty("text", source->text()); + target->setProperty("shortcut", source->shortcut().toString()); target->setProperty("checked", source->isChecked()); target->setProperty("visible", source->isVisible()); } From 3bf1afb80ba22e2f36f72f18568e3c0d46182100 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Sat, 12 Mar 2016 12:56:38 +1300 Subject: [PATCH 15/20] HMD submenus not allcaps --- interface/resources/qml/menus/VrMenuItem.qml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/resources/qml/menus/VrMenuItem.qml b/interface/resources/qml/menus/VrMenuItem.qml index 0b18811ccf..38d2b57c03 100644 --- a/interface/resources/qml/menus/VrMenuItem.qml +++ b/interface/resources/qml/menus/VrMenuItem.qml @@ -51,7 +51,7 @@ Item { RalewaySemiBold { id: label size: hifi.fontSizes.rootMenu - font.capitalization: Font.AllUppercase + font.capitalization: isSubMenu ? Font.MixedCase : Font.AllUppercase anchors.left: check.right anchors.verticalCenter: parent.verticalCenter verticalAlignment: Text.AlignVCenter From 3deb30d699488f1ed7860f3d435d9bfdc7131b0a Mon Sep 17 00:00:00 2001 From: David Rowe Date: Sat, 12 Mar 2016 13:06:29 +1300 Subject: [PATCH 16/20] Remove no longer need font type --- .../resources/qml/styles-uit/FontAwesome.qml | 26 ------------------- 1 file changed, 26 deletions(-) delete mode 100644 interface/resources/qml/styles-uit/FontAwesome.qml diff --git a/interface/resources/qml/styles-uit/FontAwesome.qml b/interface/resources/qml/styles-uit/FontAwesome.qml deleted file mode 100644 index 5c03ef09b2..0000000000 --- a/interface/resources/qml/styles-uit/FontAwesome.qml +++ /dev/null @@ -1,26 +0,0 @@ -// -// FontAwesome.qml -// -// Created by Bradley Austin Davis on 24 Apr 2015 -// Copyright 2015 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 -// - -import QtQuick 2.5 -import QtQuick.Controls 1.4 -import QtQuick.Controls.Styles 1.4 - -Text { - id: root - FontLoader { id: iconFont; source: "../../fonts/fontawesome-webfont.ttf"; } - property int size: 32 - width: size - height: size - font.pixelSize: size - verticalAlignment: Text.AlignVCenter - horizontalAlignment: Text.AlignLeft - font.family: iconFont.name -} - From 23fd2e93b523a370dca7605eaa9bf9f93ecf8584 Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Fri, 11 Mar 2016 16:26:14 -0800 Subject: [PATCH 17/20] add version number --- server-console/src/main.js | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/server-console/src/main.js b/server-console/src/main.js index c9e33e2ce4..667094710d 100644 --- a/server-console/src/main.js +++ b/server-console/src/main.js @@ -493,6 +493,10 @@ function buildMenuArray(serverState) { label: 'Server - Stopped', enabled: false }, + { + label: 'Version - '+buildInfo.buildIdentifier, + enabled: false + }, { type: 'separator' }, @@ -536,14 +540,7 @@ function buildMenuArray(serverState) { label: 'Quit', accelerator: 'Command+Q', click: function() { shutdown(); } - }, - { - type: 'separator' - }, - { - label: 'Current Version: '+buildInfo.buildIdentifier, - enabled: false - } + } ]; var foundStackManagerContent = isStackManagerContentPresent(); From 42e3d0bdadc40c96e8e9a1aee915d7869dc120ca Mon Sep 17 00:00:00 2001 From: "James B. Pollack" Date: Fri, 11 Mar 2016 16:57:50 -0800 Subject: [PATCH 18/20] remove logging --- server-console/src/main.js | 165 ++++++++++++++++++++----------------- 1 file changed, 88 insertions(+), 77 deletions(-) diff --git a/server-console/src/main.js b/server-console/src/main.js index 667094710d..15dbf698bc 100644 --- a/server-console/src/main.js +++ b/server-console/src/main.js @@ -1,7 +1,7 @@ 'use strict'; const electron = require('electron'); -const app = electron.app; // Module to control application life. +const app = electron.app; // Module to control application life. const BrowserWindow = electron.BrowserWindow; const nativeImage = electron.nativeImage; @@ -57,7 +57,10 @@ function getBuildInfo() { } } - const DEFAULT_BUILD_INFO = { releaseType: "", buildIdentifier: "dev" }; + const DEFAULT_BUILD_INFO = { + releaseType: "", + buildIdentifier: "dev" + }; var buildInfo = DEFAULT_BUILD_INFO; if (buildInfoPath) { @@ -104,6 +107,7 @@ const ipcMain = electron.ipcMain; var isShuttingDown = false; + function shutdown() { if (!isShuttingDown) { // if the home server is running, show a prompt before quit to ask if the user is sure @@ -283,8 +287,7 @@ function openFileBrowser(path) { // NOTE: this looks like it does nothing, but it's very important. // Without it the default behaviour is to quit the app once all windows closed // which is absolutely not what we want for a taskbar application. -app.on('window-all-closed', function() { -}); +app.on('window-all-closed', function() {}); function startInterface(url) { var argArray = []; @@ -320,7 +323,11 @@ LogWindow.prototype = { return; } // Create the browser window. - this.window = new BrowserWindow({ width: 700, height: 500, icon: appIcon }); + this.window = new BrowserWindow({ + width: 700, + height: 500, + icon: appIcon + }); this.window.loadURL('file://' + __dirname + '/log.html'); if (!debug) { @@ -367,7 +374,7 @@ function isStackManagerContentPresent() { if (stats.isFile()) { console.log("Stack Manager entities file discovered at " + modelsPath) - // we found a content file + // we found a content file return true; } } catch (e) { @@ -481,74 +488,72 @@ function buildMenuArray(serverState) { var menuArray = null; if (isShuttingDown) { - menuArray = [ - { - label: "Shutting down...", - enabled: false - } - ]; + menuArray = [{ + label: "Shutting down...", + enabled: false + }]; } else { - menuArray = [ - { - label: 'Server - Stopped', - enabled: false + menuArray = [{ + label: 'Server - Stopped', + enabled: false + }, { + label: 'Version - ' + buildInfo.buildIdentifier, + enabled: false + }, { + type: 'separator' + }, { + label: 'Go Home', + click: goHomeClicked, + enabled: false + }, { + type: 'separator' + }, { + label: 'Start Server', + click: function() { + homeServer.restart(); + } + }, { + label: 'Stop Server', + visible: false, + click: function() { + homeServer.stop(); + } + }, { + label: 'Settings', + click: function() { + shell.openExternal('http://localhost:40100/settings'); }, - { - label: 'Version - '+buildInfo.buildIdentifier, - enabled: false - }, - { - type: 'separator' - }, - { - label: 'Go Home', - click: goHomeClicked, - enabled: false - }, - { - type: 'separator' - }, - { - label: 'Start Server', - click: function() { homeServer.restart(); } - }, - { - label: 'Stop Server', - visible: false, - click: function() { homeServer.stop(); } - }, - { - label: 'Settings', - click: function() { shell.openExternal('http://localhost:40100/settings'); }, - enabled: false - }, - { - label: 'View Logs', - click: function() { logWindow.open(); } - }, - { - type: 'separator' - }, - { - label: 'Share', - click: function() { shell.openExternal('http://localhost:40100/settings/?action=share') } - }, - { - type: 'separator' - }, - { - label: 'Quit', - accelerator: 'Command+Q', - click: function() { shutdown(); } - } - ]; + enabled: false + }, { + label: 'View Logs', + click: function() { + logWindow.open(); + } + }, { + type: 'separator' + }, { + label: 'Share', + click: function() { + shell.openExternal('http://localhost:40100/settings/?action=share') + } + }, { + type: 'separator' + }, { + label: 'Quit', + accelerator: 'Command+Q', + click: function() { + shutdown(); + } + }]; var foundStackManagerContent = isStackManagerContentPresent(); if (foundStackManagerContent) { // add a separator and the stack manager content migration option menuArray.splice(menuArray.length - 1, 0, { label: 'Migrate Stack Manager Content', - click: function() { promptToMigrateContent(); } + click: function() { + promptToMigrateContent(); + } }, { type: 'separator' }); @@ -647,9 +652,13 @@ function maybeInstallDefaultContentSet(onComplete) { electron.ipcMain.on('ready', function() { console.log("got ready"); + function sendStateUpdate(state, args) { // console.log(state, window, args); - window.webContents.send('update', { state: state, args: args }); + window.webContents.send('update', { + state: state, + args: args + }); } var aborted = false; @@ -673,7 +682,9 @@ function maybeInstallDefaultContentSet(onComplete) { } else { sendStateUpdate('installing'); } - }), { throttle: 250 }).on('progress', function(state) { + }), { + throttle: 250 + }).on('progress', function(state) { if (!aborted) { // Update progress popup sendStateUpdate('downloading', state); @@ -687,7 +698,7 @@ function maybeInstallDefaultContentSet(onComplete) { console.log("Done", arguments); sendStateUpdate('complete'); }); - unzipper.on('error', function (err) { + unzipper.on('error', function(err) { console.log("aborting"); aborted = true; req.abort(); @@ -777,10 +788,7 @@ app.on('ready', function() { var currentVersion = null; try { currentVersion = parseInt(buildInfo.buildIdentifier); - console.log('CURRENT VERSION:: ',currentVersion) - } catch (e) { - } - + } catch (e) {} if (currentVersion !== null) { const CHECK_FOR_UPDATES_INTERVAL_SECONDS = 60 * 30; @@ -810,8 +818,9 @@ app.on('ready', function() { if (dsPath && acPath) { domainServer = new Process('domain-server', dsPath, ["--get-temp-name"], logPath); acMonitor = new ACMonitorProcess('ac-monitor', acPath, ['-n6', - '--log-directory', logPath, - '--http-status-port', httpStatusPort], httpStatusPort, logPath); + '--log-directory', logPath, + '--http-status-port', httpStatusPort + ], httpStatusPort, logPath); homeServer = new ProcessGroup('home', [domainServer, acMonitor]); logWindow = new LogWindow(acMonitor, domainServer); @@ -820,10 +829,12 @@ app.on('ready', function() { }; // handle process updates - homeServer.on('state-update', function(processGroup) { updateTrayMenu(processGroup.state); }); + homeServer.on('state-update', function(processGroup) { + updateTrayMenu(processGroup.state); + }); // start the home server homeServer.start(); } }); -}); +}); \ No newline at end of file From 9fb897476e21b02c3b65d9ccefdc256ea0c809c4 Mon Sep 17 00:00:00 2001 From: Anthony Thibault Date: Fri, 11 Mar 2016 17:29:18 -0800 Subject: [PATCH 19/20] Application: fix for mouse control in third-person camera Process the keyboard & mouse input plugin after the userInputMapper()->update(). --- interface/src/Application.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 9bd4b00246..ce8f4e48d9 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3186,9 +3186,12 @@ void Application::update(float deltaTime) { myAvatar->getHMDSensorMatrix() }; + InputPluginPointer keyboardMousePlugin; bool jointsCaptured = false; for (auto inputPlugin : PluginManager::getInstance()->getInputPlugins()) { - if (inputPlugin->isActive()) { + if (inputPlugin->getName() == KeyboardMouseDevice::NAME) { + keyboardMousePlugin = inputPlugin; + } else if (inputPlugin->isActive()) { inputPlugin->pluginUpdate(deltaTime, calibrationData, jointsCaptured); if (inputPlugin->isJointController()) { jointsCaptured = true; @@ -3198,6 +3201,10 @@ void Application::update(float deltaTime) { userInputMapper->update(deltaTime); + if (keyboardMousePlugin && keyboardMousePlugin->isActive()) { + keyboardMousePlugin->pluginUpdate(deltaTime, calibrationData, jointsCaptured); + } + _controllerScriptingInterface->updateInputControllers(); // Transfer the user inputs to the driveKeys From 90f5dd50a52d12f96f537292d39a6d2fd54a0895 Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Sat, 12 Mar 2016 08:38:41 -0800 Subject: [PATCH 20/20] Revert "Show Server Console Version" --- server-console/src/main.js | 157 +++++++++++++++++-------------------- 1 file changed, 70 insertions(+), 87 deletions(-) diff --git a/server-console/src/main.js b/server-console/src/main.js index 15dbf698bc..e05106aa6f 100644 --- a/server-console/src/main.js +++ b/server-console/src/main.js @@ -1,7 +1,7 @@ 'use strict'; const electron = require('electron'); -const app = electron.app; // Module to control application life. +const app = electron.app; // Module to control application life. const BrowserWindow = electron.BrowserWindow; const nativeImage = electron.nativeImage; @@ -57,10 +57,7 @@ function getBuildInfo() { } } - const DEFAULT_BUILD_INFO = { - releaseType: "", - buildIdentifier: "dev" - }; + const DEFAULT_BUILD_INFO = { releaseType: "", buildIdentifier: "dev" }; var buildInfo = DEFAULT_BUILD_INFO; if (buildInfoPath) { @@ -107,7 +104,6 @@ const ipcMain = electron.ipcMain; var isShuttingDown = false; - function shutdown() { if (!isShuttingDown) { // if the home server is running, show a prompt before quit to ask if the user is sure @@ -287,7 +283,8 @@ function openFileBrowser(path) { // NOTE: this looks like it does nothing, but it's very important. // Without it the default behaviour is to quit the app once all windows closed // which is absolutely not what we want for a taskbar application. -app.on('window-all-closed', function() {}); +app.on('window-all-closed', function() { +}); function startInterface(url) { var argArray = []; @@ -323,11 +320,7 @@ LogWindow.prototype = { return; } // Create the browser window. - this.window = new BrowserWindow({ - width: 700, - height: 500, - icon: appIcon - }); + this.window = new BrowserWindow({ width: 700, height: 500, icon: appIcon }); this.window.loadURL('file://' + __dirname + '/log.html'); if (!debug) { @@ -374,7 +367,7 @@ function isStackManagerContentPresent() { if (stats.isFile()) { console.log("Stack Manager entities file discovered at " + modelsPath) - // we found a content file + // we found a content file return true; } } catch (e) { @@ -488,72 +481,70 @@ function buildMenuArray(serverState) { var menuArray = null; if (isShuttingDown) { - menuArray = [{ - label: "Shutting down...", - enabled: false - }]; + menuArray = [ + { + label: "Shutting down...", + enabled: false + } + ]; } else { - menuArray = [{ - label: 'Server - Stopped', - enabled: false - }, { - label: 'Version - ' + buildInfo.buildIdentifier, - enabled: false - }, { - type: 'separator' - }, { - label: 'Go Home', - click: goHomeClicked, - enabled: false - }, { - type: 'separator' - }, { - label: 'Start Server', - click: function() { - homeServer.restart(); - } - }, { - label: 'Stop Server', - visible: false, - click: function() { - homeServer.stop(); - } - }, { - label: 'Settings', - click: function() { - shell.openExternal('http://localhost:40100/settings'); + menuArray = [ + { + label: 'Server - Stopped', + enabled: false }, - enabled: false - }, { - label: 'View Logs', - click: function() { - logWindow.open(); + { + type: 'separator' + }, + { + label: 'Go Home', + click: goHomeClicked, + enabled: false + }, + { + type: 'separator' + }, + { + label: 'Start Server', + click: function() { homeServer.restart(); } + }, + { + label: 'Stop Server', + visible: false, + click: function() { homeServer.stop(); } + }, + { + label: 'Settings', + click: function() { shell.openExternal('http://localhost:40100/settings'); }, + enabled: false + }, + { + label: 'View Logs', + click: function() { logWindow.open(); } + }, + { + type: 'separator' + }, + { + label: 'Share', + click: function() { shell.openExternal('http://localhost:40100/settings/?action=share') } + }, + { + type: 'separator' + }, + { + label: 'Quit', + accelerator: 'Command+Q', + click: function() { shutdown(); } } - }, { - type: 'separator' - }, { - label: 'Share', - click: function() { - shell.openExternal('http://localhost:40100/settings/?action=share') - } - }, { - type: 'separator' - }, { - label: 'Quit', - accelerator: 'Command+Q', - click: function() { - shutdown(); - } - }]; + ]; var foundStackManagerContent = isStackManagerContentPresent(); if (foundStackManagerContent) { // add a separator and the stack manager content migration option menuArray.splice(menuArray.length - 1, 0, { label: 'Migrate Stack Manager Content', - click: function() { - promptToMigrateContent(); - } + click: function() { promptToMigrateContent(); } }, { type: 'separator' }); @@ -652,13 +643,9 @@ function maybeInstallDefaultContentSet(onComplete) { electron.ipcMain.on('ready', function() { console.log("got ready"); - function sendStateUpdate(state, args) { // console.log(state, window, args); - window.webContents.send('update', { - state: state, - args: args - }); + window.webContents.send('update', { state: state, args: args }); } var aborted = false; @@ -682,9 +669,7 @@ function maybeInstallDefaultContentSet(onComplete) { } else { sendStateUpdate('installing'); } - }), { - throttle: 250 - }).on('progress', function(state) { + }), { throttle: 250 }).on('progress', function(state) { if (!aborted) { // Update progress popup sendStateUpdate('downloading', state); @@ -698,7 +683,7 @@ function maybeInstallDefaultContentSet(onComplete) { console.log("Done", arguments); sendStateUpdate('complete'); }); - unzipper.on('error', function(err) { + unzipper.on('error', function (err) { console.log("aborting"); aborted = true; req.abort(); @@ -788,7 +773,8 @@ app.on('ready', function() { var currentVersion = null; try { currentVersion = parseInt(buildInfo.buildIdentifier); - } catch (e) {} + } catch (e) { + } if (currentVersion !== null) { const CHECK_FOR_UPDATES_INTERVAL_SECONDS = 60 * 30; @@ -818,9 +804,8 @@ app.on('ready', function() { if (dsPath && acPath) { domainServer = new Process('domain-server', dsPath, ["--get-temp-name"], logPath); acMonitor = new ACMonitorProcess('ac-monitor', acPath, ['-n6', - '--log-directory', logPath, - '--http-status-port', httpStatusPort - ], httpStatusPort, logPath); + '--log-directory', logPath, + '--http-status-port', httpStatusPort], httpStatusPort, logPath); homeServer = new ProcessGroup('home', [domainServer, acMonitor]); logWindow = new LogWindow(acMonitor, domainServer); @@ -829,12 +814,10 @@ app.on('ready', function() { }; // handle process updates - homeServer.on('state-update', function(processGroup) { - updateTrayMenu(processGroup.state); - }); + homeServer.on('state-update', function(processGroup) { updateTrayMenu(processGroup.state); }); // start the home server homeServer.start(); } }); -}); \ No newline at end of file +});