From 652ce5501f16699211541fe19a80572dd2f3a1c5 Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Thu, 10 Dec 2015 13:36:18 -0800 Subject: [PATCH 01/11] Expose Avatar default pose to JavaScript New JavaScript API to get the avatar's default pose. MyAvatar.getDefaultJointRotation(index); MyAvatar.getDefaultJointTranslation(index); See `examples/tPose.js` for example usage --- examples/tPose.js | 84 ++++++++++++++++++++++++++++ interface/src/avatar/Avatar.cpp | 12 ++++ interface/src/avatar/Avatar.h | 4 ++ interface/src/avatar/MyAvatar.cpp | 6 +- libraries/animation/src/Rig.cpp | 21 +++++++ libraries/animation/src/Rig.h | 4 ++ libraries/render-utils/src/Model.cpp | 16 ++++-- libraries/render-utils/src/Model.h | 7 ++- 8 files changed, 147 insertions(+), 7 deletions(-) create mode 100644 examples/tPose.js diff --git a/examples/tPose.js b/examples/tPose.js new file mode 100644 index 0000000000..e6ead08420 --- /dev/null +++ b/examples/tPose.js @@ -0,0 +1,84 @@ +// +// tPose.js +// examples +// +// Created by Anthony Thibault on 11/9/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 +// +// Example of how to put the avatar into it's default tpose. +// + +// TODO: CHANGE +var buttonImageUrl = "https://s3.amazonaws.com/hifi-public/images/tools/tpose.svg"; +var windowDimensions = Controller.getViewportDimensions(); + +var buttonWidth = 37; +var buttonHeight = 46; +var buttonPadding = 10; + +var buttonPositionX = windowDimensions.x - buttonPadding - buttonWidth; +var buttonPositionY = (windowDimensions.y - buttonHeight) / 2 - (buttonHeight + buttonPadding); + +var tPoseEnterImageOverlay = { + x: buttonPositionX, + y: buttonPositionY, + width: buttonWidth, + height: buttonHeight, + subImage: { x: 0, y: buttonHeight, width: buttonWidth, height: buttonHeight }, + imageURL: buttonImageUrl, + visible: true, + alpha: 1.0 +}; + +var tPoseExitImageOverlay = { + x: buttonPositionX, + y: buttonPositionY, + width: buttonWidth, + height: buttonHeight, + subImage: { x: buttonWidth, y: buttonHeight, width: buttonWidth, height: buttonHeight }, + imageURL: buttonImageUrl, + visible: false, + alpha: 1.0 +}; + +var tPoseEnterButton = Overlays.addOverlay("image", tPoseEnterImageOverlay); +var tPoseExitButton = Overlays.addOverlay("image", tPoseExitImageOverlay); +var tPose = false; + +function enterDefaultPose() { + tPose = true; + var i, l = MyAvatar.getJointNames().length; + var rot, trans; + for (i = 0; i < l; i++) { + rot = MyAvatar.getDefaultJointRotation(i); + trans = MyAvatar.getDefaultJointTranslation(i); + MyAvatar.setJointData(i, rot, trans); + } + Overlays.editOverlay(tPoseEnterButton, { visible: false }); + Overlays.editOverlay(tPoseExitButton, { visible: true }); +} + +function exitDefaultPose() { + tPose = false; + MyAvatar.clearJointsData(); + Overlays.editOverlay(tPoseEnterButton, { visible: true }); + Overlays.editOverlay(tPoseExitButton, { visible: false }); +} + +Controller.mousePressEvent.connect(function (event) { + var clickedOverlay = Overlays.getOverlayAtPoint({ x: event.x, y: event.y }); + if (clickedOverlay == tPoseEnterButton) { + enterDefaultPose(); + } else if (clickedOverlay == tPoseExitButton) { + exitDefaultPose(); + } +}); + +Script.scriptEnding.connect(function() { + Overlays.deleteOverlay(tPoseEnterButton); + Overlays.deleteOverlay(tPoseExitButton); +}); + diff --git a/interface/src/avatar/Avatar.cpp b/interface/src/avatar/Avatar.cpp index e2b92cc06f..8f8746dc27 100644 --- a/interface/src/avatar/Avatar.cpp +++ b/interface/src/avatar/Avatar.cpp @@ -869,6 +869,18 @@ glm::vec3 Avatar::getJointTranslation(int index) const { return translation; } +glm::quat Avatar::getDefaultJointRotation(int index) const { + glm::quat rotation; + _skeletonModel.getRelativeDefaultJointRotation(index, rotation); + return rotation; +} + +glm::vec3 Avatar::getDefaultJointTranslation(int index) const { + glm::vec3 translation; + _skeletonModel.getRelativeDefaultJointTranslation(index, translation); + return translation; +} + glm::quat Avatar::getAbsoluteJointRotationInObjectFrame(int index) const { glm::quat rotation; _skeletonModel.getAbsoluteJointRotationInRigFrame(index, rotation); diff --git a/interface/src/avatar/Avatar.h b/interface/src/avatar/Avatar.h index 99a4fc52a9..b161b46634 100644 --- a/interface/src/avatar/Avatar.h +++ b/interface/src/avatar/Avatar.h @@ -105,6 +105,10 @@ public: virtual QVector getJointRotations() const; virtual glm::quat getJointRotation(int index) const; virtual glm::vec3 getJointTranslation(int index) const; + + Q_INVOKABLE virtual glm::quat getDefaultJointRotation(int index) const; + Q_INVOKABLE virtual glm::vec3 getDefaultJointTranslation(int index) const; + virtual int getJointIndex(const QString& name) const; virtual QStringList getJointNames() const; diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 34821e6737..7cb6d37184 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -971,7 +971,11 @@ void MyAvatar::clearJointData(int index) { } void MyAvatar::clearJointsData() { - //clearJointAnimationPriorities(); + if (QThread::currentThread() != thread()) { + QMetaObject::invokeMethod(this, "clearJointsData"); + return; + } + _rig->clearJointStates(); } void MyAvatar::setFaceModelURL(const QUrl& faceModelURL) { diff --git a/libraries/animation/src/Rig.cpp b/libraries/animation/src/Rig.cpp index a80ef5d2eb..cd34303753 100644 --- a/libraries/animation/src/Rig.cpp +++ b/libraries/animation/src/Rig.cpp @@ -283,12 +283,14 @@ bool Rig::getJointStateTranslation(int index, glm::vec3& translation) const { void Rig::clearJointState(int index) { if (isIndexValid(index)) { _internalPoseSet._overrideFlags[index] = false; + _internalPoseSet._overridePoses[index] = _animSkeleton->getRelativeDefaultPose(index); } } void Rig::clearJointStates() { _internalPoseSet._overrideFlags.clear(); _internalPoseSet._overrideFlags.resize(_animSkeleton->getNumJoints()); + _internalPoseSet._overridePoses = _animSkeleton->getRelativeDefaultPoses(); } void Rig::clearJointAnimationPriority(int index) { @@ -464,6 +466,25 @@ const AnimPoseVec& Rig::getAbsoluteDefaultPoses() const { return _absoluteDefaultPoses; } + +bool Rig::getRelativeDefaultJointRotation(int index, glm::quat& rotationOut) const { + if (_animSkeleton && index >= 0 && index < _animSkeleton->getNumJoints()) { + rotationOut = _animSkeleton->getRelativeDefaultPose(index).rot; + return true; + } else { + return false; + } +} + +bool Rig::getRelativeDefaultJointTranslation(int index, glm::vec3& translationOut) const { + if (_animSkeleton && index >= 0 && index < _animSkeleton->getNumJoints()) { + translationOut = _animSkeleton->getRelativeDefaultPose(index).trans; + return true; + } else { + return false; + } +} + // animation reference speeds. static const std::vector FORWARD_SPEEDS = { 0.4f, 1.4f, 4.5f }; // m/s static const std::vector BACKWARD_SPEEDS = { 0.6f, 1.45f }; // m/s diff --git a/libraries/animation/src/Rig.h b/libraries/animation/src/Rig.h index e3ec5d18cf..9faf93e40b 100644 --- a/libraries/animation/src/Rig.h +++ b/libraries/animation/src/Rig.h @@ -200,6 +200,10 @@ public: // rig space const AnimPoseVec& getAbsoluteDefaultPoses() const; + // geometry space + bool getRelativeDefaultJointRotation(int index, glm::quat& rotationOut) const; + bool getRelativeDefaultJointTranslation(int index, glm::vec3& translationOut) const; + void copyJointsIntoJointData(QVector& jointDataVec) const; void copyJointsFromJointData(const QVector& jointDataVec); diff --git a/libraries/render-utils/src/Model.cpp b/libraries/render-utils/src/Model.cpp index b367d299e5..3a26a15855 100644 --- a/libraries/render-utils/src/Model.cpp +++ b/libraries/render-utils/src/Model.cpp @@ -766,12 +766,20 @@ bool Model::getJointTranslation(int jointIndex, glm::vec3& translation) const { return _rig->getJointTranslation(jointIndex, translation); } -bool Model::getAbsoluteJointRotationInRigFrame(int jointIndex, glm::quat& rotation) const { - return _rig->getAbsoluteJointRotationInRigFrame(jointIndex, rotation); +bool Model::getAbsoluteJointRotationInRigFrame(int jointIndex, glm::quat& rotationOut) const { + return _rig->getAbsoluteJointRotationInRigFrame(jointIndex, rotationOut); } -bool Model::getAbsoluteJointTranslationInRigFrame(int jointIndex, glm::vec3& translation) const { - return _rig->getAbsoluteJointTranslationInRigFrame(jointIndex, translation); +bool Model::getAbsoluteJointTranslationInRigFrame(int jointIndex, glm::vec3& translationOut) const { + return _rig->getAbsoluteJointTranslationInRigFrame(jointIndex, translationOut); +} + +bool Model::getRelativeDefaultJointRotation(int jointIndex, glm::quat& rotationOut) const { + return _rig->getRelativeDefaultJointRotation(jointIndex, rotationOut); +} + +bool Model::getRelativeDefaultJointTranslation(int jointIndex, glm::vec3& translationOut) const { + return _rig->getRelativeDefaultJointTranslation(jointIndex, translationOut); } bool Model::getJointCombinedRotation(int jointIndex, glm::quat& rotation) const { diff --git a/libraries/render-utils/src/Model.h b/libraries/render-utils/src/Model.h index d77cf830bd..001ae61c92 100644 --- a/libraries/render-utils/src/Model.h +++ b/libraries/render-utils/src/Model.h @@ -167,8 +167,11 @@ public: bool getJointTranslation(int jointIndex, glm::vec3& translation) const; // model frame - bool getAbsoluteJointRotationInRigFrame(int jointIndex, glm::quat& rotation) const; - bool getAbsoluteJointTranslationInRigFrame(int jointIndex, glm::vec3& translation) const; + bool getAbsoluteJointRotationInRigFrame(int jointIndex, glm::quat& rotationOut) const; + bool getAbsoluteJointTranslationInRigFrame(int jointIndex, glm::vec3& translationOut) const; + + bool getRelativeDefaultJointRotation(int jointIndex, glm::quat& rotationOut) const; + bool getRelativeDefaultJointTranslation(int jointIndex, glm::vec3& translationOut) const; /// Returns the index of the parent of the indexed joint, or -1 if not found. int getParentJointIndex(int jointIndex) const; From 020836f536aa01260b853686bc1828cd78d26f6f Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Thu, 10 Dec 2015 14:00:22 -0800 Subject: [PATCH 02/11] Fixed date on tPose.js --- examples/tPose.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/examples/tPose.js b/examples/tPose.js index e6ead08420..cbdd223954 100644 --- a/examples/tPose.js +++ b/examples/tPose.js @@ -2,7 +2,7 @@ // tPose.js // examples // -// Created by Anthony Thibault on 11/9/2015 +// Created by Anthony Thibault on 12/10/2015 // Copyright 2015 High Fidelity, Inc. // // Distributed under the Apache License, Version 2.0. From 617fda783242cf3592090b3b4403aab00d9b6059 Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Mon, 14 Dec 2015 17:07:53 -0800 Subject: [PATCH 03/11] ModelEntityItem: fix for incorrect joint mapping This could happen when switching the animation url between fbx files with different joint mappings. Only the first one would take effect. This should fix the issue in the demo domain, with the contorted doll model. --- libraries/entities/src/ModelEntityItem.cpp | 3 ++- libraries/entities/src/ModelEntityItem.h | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/libraries/entities/src/ModelEntityItem.cpp b/libraries/entities/src/ModelEntityItem.cpp index d96814ff04..352ab4d701 100644 --- a/libraries/entities/src/ModelEntityItem.cpp +++ b/libraries/entities/src/ModelEntityItem.cpp @@ -194,7 +194,7 @@ AnimationPointer ModelEntityItem::getAnimation(const QString& url) { void ModelEntityItem::mapJoints(const QStringList& modelJointNames) { // if we don't have animation, or we're already joint mapped then bail early - if (!hasAnimation() || _jointMappingCompleted) { + if (!hasAnimation() || jointsMapped()) { return; } @@ -208,6 +208,7 @@ void ModelEntityItem::mapJoints(const QStringList& modelJointNames) { _jointMapping[i] = animationJointNames.indexOf(modelJointNames[i]); } _jointMappingCompleted = true; + _jointMappingURL = _animationProperties.getURL(); } } } diff --git a/libraries/entities/src/ModelEntityItem.h b/libraries/entities/src/ModelEntityItem.h index ac70c73654..b08fed5970 100644 --- a/libraries/entities/src/ModelEntityItem.h +++ b/libraries/entities/src/ModelEntityItem.h @@ -104,7 +104,7 @@ public: void mapJoints(const QStringList& modelJointNames); void getAnimationFrame(bool& newFrame, QVector& rotationsResult, QVector& translationsResult); - bool jointsMapped() const { return _jointMappingCompleted; } + bool jointsMapped() const { return _jointMappingURL == getAnimationURL() && _jointMappingCompleted; } bool getAnimationIsPlaying() const { return _animationLoop.getRunning(); } float getAnimationCurrentFrame() const { return _animationLoop.getCurrentFrame(); } @@ -146,6 +146,7 @@ protected: // used on client side bool _jointMappingCompleted; QVector _jointMapping; + QString _jointMappingURL; static AnimationPointer getAnimation(const QString& url); static QMap _loadedAnimations; From 51ff8f096e7e6d2a27a6d1610a92c40008aca636 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Tue, 15 Dec 2015 08:43:04 -0800 Subject: [PATCH 04/11] correct input plugin load path on linux --- cmake/macros/SetupHifiPlugin.cmake | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/cmake/macros/SetupHifiPlugin.cmake b/cmake/macros/SetupHifiPlugin.cmake index 0ee94c7816..b9fc4490d7 100644 --- a/cmake/macros/SetupHifiPlugin.cmake +++ b/cmake/macros/SetupHifiPlugin.cmake @@ -10,24 +10,30 @@ macro(SETUP_HIFI_PLUGIN) setup_hifi_library(${ARGV}) add_dependencies(interface ${TARGET_NAME}) set_target_properties(${TARGET_NAME} PROPERTIES FOLDER "Plugins") - - if (APPLE) + + if (APPLE) set(PLUGIN_PATH "interface.app/Contents/MacOS/plugins") else() set(PLUGIN_PATH "plugins") endif() - + + IF(${CMAKE_SYSTEM_NAME} MATCHES "Linux") + set(PLUGIN_FULL_PATH "${CMAKE_BINARY_DIR}/interface/${PLUGIN_PATH}/") + else() + set(PLUGIN_FULL_PATH "${CMAKE_BINARY_DIR}/interface/$/${PLUGIN_PATH}/") + endif() + # create the destination for the plugin binaries add_custom_command( TARGET ${TARGET_NAME} POST_BUILD COMMAND "${CMAKE_COMMAND}" -E make_directory - "${CMAKE_BINARY_DIR}/interface/$/${PLUGIN_PATH}/" + ${PLUGIN_FULL_PATH} ) - + add_custom_command(TARGET ${DIR} POST_BUILD COMMAND "${CMAKE_COMMAND}" -E copy "$" - "${CMAKE_BINARY_DIR}/interface/$/${PLUGIN_PATH}/" + ${PLUGIN_FULL_PATH} ) -endmacro() \ No newline at end of file +endmacro() From 541af3679411cb25a6d753b91fc1a3371968d4e6 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Wed, 16 Dec 2015 09:12:07 +1300 Subject: [PATCH 05/11] Fix signal connection to ScriptEngine::finished --- interface/src/Application.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 2aa1a5ee96..a2a2ff6332 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -4107,7 +4107,7 @@ void Application::registerScriptEngineWithApplicationServices(ScriptEngine* scri ClipboardScriptingInterface* clipboardScriptable = new ClipboardScriptingInterface(); scriptEngine->registerGlobalObject("Clipboard", clipboardScriptable); - connect(scriptEngine, SIGNAL(finished(const QString&)), clipboardScriptable, SLOT(deleteLater())); + connect(scriptEngine, &ScriptEngine::finished, clipboardScriptable, &ClipboardScriptingInterface::deleteLater); connect(scriptEngine, &ScriptEngine::finished, this, &Application::scriptFinished, Qt::DirectConnection); From 3dcdfbc0f13f2d0a41c71283dcee84e163db2087 Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Tue, 15 Dec 2015 13:07:47 -0800 Subject: [PATCH 06/11] first cut at simulating mouse/reticle behavior with input contorllers --- examples/controllers/reticleTests.js | 39 ++++ .../resources/controllers/keyboardMouse.json | 3 +- interface/resources/controllers/standard.json | 3 +- interface/src/Application.cpp | 186 ++++-------------- interface/src/Application.h | 17 +- interface/src/Menu.cpp | 1 - interface/src/Menu.h | 1 - interface/src/ui/ApplicationCompositor.cpp | 161 +-------------- interface/src/ui/ApplicationCompositor.h | 8 - .../controllers/src/controllers/Actions.cpp | 8 + .../controllers/src/controllers/Actions.h | 13 +- .../src/controllers/UserInputMapper.cpp | 33 +--- .../src/input-plugins/KeyboardMouseDevice.cpp | 3 + 13 files changed, 123 insertions(+), 353 deletions(-) create mode 100644 examples/controllers/reticleTests.js diff --git a/examples/controllers/reticleTests.js b/examples/controllers/reticleTests.js new file mode 100644 index 0000000000..4c805c8b1c --- /dev/null +++ b/examples/controllers/reticleTests.js @@ -0,0 +1,39 @@ +// +// reticleTest.js +// examples/controllers +// +// Created by Brad Hefta-Gaub on 2015/12/15 +// 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 +// + +var mappingJSON = { + "name": "com.highfidelity.testing.reticleWithJoystick", + "channels": [ + { "from": "Standard.RT", "to": "Actions.ReticleClick", "filters": "constrainToInteger" }, + + { "from": "Standard.RX", "to": "Actions.ReticleX", + "filters": + [ + { "type": "pulse", "interval": 0.05 }, + { "type": "scale", "scale": 20 } + ] + }, + { "from": "Standard.RY", "to": "Actions.ReticleY", + "filters": + [ + { "type": "pulse", "interval": 0.05 }, + { "type": "scale", "scale": 20 } + ] + }, + ] +}; + +mapping = Controller.parseMapping(JSON.stringify(mappingJSON)); +mapping.enable(); + +Script.scriptEnding.connect(function(){ + mapping.disable(); +}); diff --git a/interface/resources/controllers/keyboardMouse.json b/interface/resources/controllers/keyboardMouse.json index 4a68ca0d20..5d7930a59b 100644 --- a/interface/resources/controllers/keyboardMouse.json +++ b/interface/resources/controllers/keyboardMouse.json @@ -11,7 +11,7 @@ { "from": "Keyboard.S", "when": "Keyboard.Shift", "to": "Actions.PITCH_DOWN" }, { "from": "Keyboard.W", "when": "Keyboard.Shift", "to": "Actions.PITCH_UP" }, - + { "comment" : "Mouse turn need to be small continuous increments", "from": { "makeAxis" : [ [ "Keyboard.MouseMoveLeft" ], @@ -75,7 +75,6 @@ { "from": "Keyboard.S", "to": "Actions.LONGITUDINAL_BACKWARD" }, { "from": "Keyboard.C", "to": "Actions.VERTICAL_DOWN" }, { "from": "Keyboard.E", "to": "Actions.VERTICAL_UP" }, - { "from": "Keyboard.Left", "when": "Keyboard.RightMouseButton", "to": "Actions.LATERAL_LEFT" }, { "from": "Keyboard.Right", "when": "Keyboard.RightMouseButton", "to": "Actions.LATERAL_RIGHT" }, { "from": "Keyboard.Left", "when": "Keyboard.Shift", "to": "Actions.LATERAL_LEFT" }, diff --git a/interface/resources/controllers/standard.json b/interface/resources/controllers/standard.json index d4988fc00d..6a8fc0d803 100644 --- a/interface/resources/controllers/standard.json +++ b/interface/resources/controllers/standard.json @@ -13,8 +13,8 @@ { "type": "scale", "scale": 22.5 } ] }, - { "from": "Standard.RX", "to": "Actions.Yaw" }, + { "from": "Standard.RX", "to": "Actions.Yaw" }, { "from": "Standard.RY", "when": "Application.Grounded", "to": "Actions.Up", @@ -24,6 +24,7 @@ "invert" ] }, + { "from": "Standard.RY", "to": "Actions.Up", "filters": "invert"}, { "from": [ "Standard.DU", "Standard.DL", "Standard.DR", "Standard.DD" ], "to": "Standard.LeftPrimaryThumb" }, diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 4494203a49..7294350d44 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -382,7 +382,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) : _scaleMirror(1.0f), _rotateMirror(0.0f), _raiseMirror(0.0f), - _lastMouseMoveWasSimulated(false), _enableProcessOctreeThread(true), _runningScriptsWidget(NULL), _runningScriptsWidgetWasVisible(false), @@ -664,6 +663,21 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) : // Setup the userInputMapper with the actions auto userInputMapper = DependencyManager::get(); connect(userInputMapper.data(), &UserInputMapper::actionEvent, [this](int action, float state) { + if (action == controller::toInt(controller::Action::RETICLE_CLICK)) { + auto globalPos = getReticlePosition(); + auto localPos = _glWidget->mapFromGlobal(globalPos); + if (state) { + QMouseEvent mousePress(QEvent::MouseButtonPress, localPos, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier); + sendEvent(_glWidget, &mousePress); + _reticleClickPressed = true; + } else { + QMouseEvent mouseRelease(QEvent::MouseButtonRelease, localPos, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier); + sendEvent(_glWidget, &mouseRelease); + _reticleClickPressed = false; + } + return; // nothing else to do + } + if (state) { if (action == controller::toInt(controller::Action::TOGGLE_MUTE)) { DependencyManager::get()->toggleMute(); @@ -671,6 +685,14 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) : cycleCamera(); } else if (action == controller::toInt(controller::Action::CONTEXT_MENU)) { VrMenu::toggle(); // show context menu even on non-stereo displays + } else if (action == controller::toInt(controller::Action::RETICLE_X)) { + auto reticlePos = getReticlePosition(); + reticlePos.setX(reticlePos.x() + state); + setReticlePosition(reticlePos); + } else if (action == controller::toInt(controller::Action::RETICLE_Y)) { + auto reticlePos = getReticlePosition(); + reticlePos.setY(reticlePos.y() + state); + setReticlePosition(reticlePos); } } }); @@ -692,8 +714,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) : // Setup the keyboardMouseDevice and the user input mapper with the default bindings userInputMapper->registerDevice(_keyboardMouseDevice->getInputDevice()); - - userInputMapper->loadDefaultMapping(userInputMapper->getStandardDeviceID()); // check first run... @@ -745,15 +765,6 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) : setActiveEyeTracker(); #endif - _oldHandMouseX[0] = -1; - _oldHandMouseY[0] = -1; - _oldHandMouseX[1] = -1; - _oldHandMouseY[1] = -1; - _oldHandLeftClick[0] = false; - _oldHandRightClick[0] = false; - _oldHandLeftClick[1] = false; - _oldHandRightClick[1] = false; - auto applicationUpdater = DependencyManager::get(); connect(applicationUpdater.data(), &AutoUpdater::newVersionIsAvailable, dialogsManager.data(), &DialogsManager::showUpdateDialog); applicationUpdater->checkForUpdate(); @@ -1940,8 +1951,6 @@ void Application::focusOutEvent(QFocusEvent* event) { void Application::mouseMoveEvent(QMouseEvent* event, unsigned int deviceID) { PROFILE_RANGE(__FUNCTION__); - // Used by application overlay to determine how to draw cursor(s) - _lastMouseMoveWasSimulated = deviceID > 0; if (_aboutToQuit) { return; @@ -1969,11 +1978,20 @@ void Application::mouseMoveEvent(QMouseEvent* event, unsigned int deviceID) { auto offscreenUi = DependencyManager::get(); QPointF transformedPos = offscreenUi->mapToVirtualScreen(event->localPos(), _glWidget); + auto button = event->button(); + auto buttons = event->buttons(); + // Determine if the ReticleClick Action is 1 and if so, fake include the LeftMouseButton + if (_reticleClickPressed) { + if (button == Qt::NoButton) { + button = Qt::LeftButton; + } + buttons |= Qt::LeftButton; + } + QMouseEvent mappedEvent(event->type(), transformedPos, - event->screenPos(), event->button(), - event->buttons(), event->modifiers()); - + event->screenPos(), button, + buttons, event->modifiers()); getEntities()->mouseMoveEvent(&mappedEvent, deviceID); _controllerScriptingInterface->emitMouseMoveEvent(&mappedEvent, deviceID); // send events to any registered scripts @@ -2877,13 +2895,6 @@ void Application::update(float deltaTime) { 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)); - if (Menu::getInstance()->isOptionChecked(MenuOption::EnableHandMouseInput)) { - emulateMouse(hand, userInputMapper->getActionState(controller::Action::LEFT_HAND_CLICK), - userInputMapper->getActionState(controller::Action::SHIFT), HandData::LeftHand); - emulateMouse(hand, userInputMapper->getActionState(controller::Action::RIGHT_HAND_CLICK), - userInputMapper->getActionState(controller::Action::SHIFT), HandData::RightHand); - } - updateThreads(deltaTime); // If running non-threaded, then give the threads some time to process... updateDialogs(deltaTime); // update various stats dialogs if present @@ -4742,6 +4753,14 @@ bool Application::isThrottleRendering() const { return getActiveDisplayPlugin()->isThrottled(); } +QPoint Application::getReticlePosition() const { + return QCursor::pos(); +} + +void Application::setReticlePosition(QPoint position) { + QCursor::setPos(position); +} + ivec2 Application::getTrueMouse() const { return toGlm(_glWidget->mapFromGlobal(QCursor::pos())); } @@ -5062,125 +5081,6 @@ void Application::setPalmData(Hand* hand, const controller::Pose& pose, float de }); } -void Application::emulateMouse(Hand* hand, float click, float shift, HandData::Hand whichHand) { - auto palms = hand->getCopyOfPalms(); - - // Locate the palm, if it exists and is active - PalmData* palm; - bool foundHand = false; - for (size_t j = 0; j < palms.size(); j++) { - if (palms[j].whichHand() == whichHand) { - palm = &(palms[j]); - foundHand = true; - break; - } - } - if (!foundHand || !palm->isActive()) { - return; - } - - // Process the mouse events - QPoint pos; - - - // FIXME - this mouse emulation stuff needs to be reworked for new controller input plugins - unsigned int deviceID = whichHand == HandData::LeftHand ? CONTROLLER_0_EVENT : CONTROLLER_1_EVENT; - int index = (int)whichHand; // FIXME - hack attack - - if (isHMDMode()) { - pos = getApplicationCompositor().getPalmClickLocation(palm); - } else { - // Get directon relative to avatar orientation - glm::vec3 direction = glm::inverse(getMyAvatar()->getOrientation()) * palm->getFingerDirection(); - - // Get the angles, scaled between (-0.5,0.5) - float xAngle = (atan2f(direction.z, direction.x) + (float)M_PI_2); - float yAngle = 0.5f - ((atan2f(direction.z, direction.y) + (float)M_PI_2)); - auto canvasSize = getCanvasSize(); - // Get the pixel range over which the xAngle and yAngle are scaled - float cursorRange = canvasSize.x * controller::InputDevice::getCursorPixelRangeMult(); - - pos.setX(canvasSize.x / 2.0f + cursorRange * xAngle); - pos.setY(canvasSize.y / 2.0f + cursorRange * yAngle); - - } - - //If we are off screen then we should stop processing, and if a trigger or bumper is pressed, - //we should unpress them. - if (pos.x() == INT_MAX) { - if (_oldHandLeftClick[index]) { - QMouseEvent mouseEvent(QEvent::MouseButtonRelease, pos, Qt::LeftButton, Qt::LeftButton, 0); - - mouseReleaseEvent(&mouseEvent, deviceID); - - _oldHandLeftClick[index] = false; - } - if (_oldHandRightClick[index]) { - QMouseEvent mouseEvent(QEvent::MouseButtonRelease, pos, Qt::RightButton, Qt::RightButton, 0); - - mouseReleaseEvent(&mouseEvent, deviceID); - - _oldHandRightClick[index] = false; - } - return; - } - - //If position has changed, emit a mouse move to the application - if (pos.x() != _oldHandMouseX[index] || pos.y() != _oldHandMouseY[index]) { - QMouseEvent mouseEvent(QEvent::MouseMove, pos, Qt::NoButton, Qt::NoButton, 0); - - // Only send the mouse event if the opposite left button isnt held down. - // Is this check necessary? - if (!_oldHandLeftClick[(int)(!index)]) { - mouseMoveEvent(&mouseEvent, deviceID); - } - } - _oldHandMouseX[index] = pos.x(); - _oldHandMouseY[index] = pos.y(); - - //We need separate coordinates for clicks, since we need to check if - //a magnification window was clicked on - int clickX = pos.x(); - int clickY = pos.y(); - //Set pos to the new click location, which may be the same if no magnification window is open - pos.setX(clickX); - pos.setY(clickY); - - // Right click - if (shift == 1.0f && click == 1.0f) { - if (!_oldHandRightClick[index]) { - _oldHandRightClick[index] = true; - - QMouseEvent mouseEvent(QEvent::MouseButtonPress, pos, Qt::RightButton, Qt::RightButton, 0); - - mousePressEvent(&mouseEvent, deviceID); - } - } else if (_oldHandRightClick[index]) { - QMouseEvent mouseEvent(QEvent::MouseButtonRelease, pos, Qt::RightButton, Qt::RightButton, 0); - - mouseReleaseEvent(&mouseEvent, deviceID); - - _oldHandRightClick[index] = false; - } - - // Left click - if (shift != 1.0f && click == 1.0f) { - if (!_oldHandLeftClick[index]) { - _oldHandLeftClick[index] = true; - - QMouseEvent mouseEvent(QEvent::MouseButtonPress, pos, Qt::LeftButton, Qt::LeftButton, 0); - - mousePressEvent(&mouseEvent, deviceID); - } - } else if (_oldHandLeftClick[index]) { - QMouseEvent mouseEvent(QEvent::MouseButtonRelease, pos, Qt::LeftButton, Qt::LeftButton, 0); - - mouseReleaseEvent(&mouseEvent, deviceID); - - _oldHandLeftClick[index] = false; - } -} - void Application::crashApplication() { qCDebug(interfaceapp) << "Intentionally crashed Interface"; QObject* object = nullptr; diff --git a/interface/src/Application.h b/interface/src/Application.h index e0f86d97bd..6c9dd1db47 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -143,9 +143,11 @@ public: EntityTreeRenderer* getEntityClipboardRenderer() { return &_entityClipboardRenderer; } EntityEditPacketSender* getEntityEditPacketSender() { return &_entityEditSender; } + QPoint getReticlePosition() const; + void setReticlePosition(QPoint position); + ivec2 getMouse() const; ivec2 getTrueMouse() const; - bool getLastMouseMoveWasSimulated() const { return _lastMouseMoveWasSimulated; } FaceTracker* getActiveFaceTracker(); FaceTracker* getSelectedFaceTracker(); @@ -361,7 +363,6 @@ private: void update(float deltaTime); void setPalmData(Hand* hand, const controller::Pose& pose, float deltaTime, HandData::Hand whichHand, float triggerValue); - void emulateMouse(Hand* hand, float click, float shift, HandData::Hand whichHand); // Various helper functions called during update() void updateLOD(); @@ -476,8 +477,6 @@ private: Environment _environment; - bool _lastMouseMoveWasSimulated; - QSet _keysPressed; bool _enableProcessOctreeThread; @@ -537,14 +536,6 @@ private: ApplicationCompositor _compositor; OverlayConductor _overlayConductor; - - // FIXME - Hand Controller to mouse emulation helpers. This is crufty and should be moved - // into the input plugins or something. - int _oldHandMouseX[(int)HandData::NUMBER_OF_HANDS]; - int _oldHandMouseY[(int)HandData::NUMBER_OF_HANDS]; - bool _oldHandLeftClick[(int)HandData::NUMBER_OF_HANDS]; - bool _oldHandRightClick[(int)HandData::NUMBER_OF_HANDS]; - DialogsManagerScriptingInterface* _dialogsManagerScriptingInterface = new DialogsManagerScriptingInterface(); EntityItemID _keyboardFocusedItem; @@ -559,6 +550,8 @@ private: bool _inPaint = false; bool _isGLInitialized { false }; bool _physicsEnabled { false }; + + bool _reticleClickPressed { false }; }; #endif // hifi_Application_h diff --git a/interface/src/Menu.cpp b/interface/src/Menu.cpp index b965607b39..ae22869273 100644 --- a/interface/src/Menu.cpp +++ b/interface/src/Menu.cpp @@ -477,7 +477,6 @@ Menu::Menu() { MenuWrapper* handOptionsMenu = developerMenu->addMenu("Hands"); addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::DisplayHandTargets, 0, false); - addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::EnableHandMouseInput, 0, false); addCheckableActionToQMenuAndActionHash(handOptionsMenu, MenuOption::LowVelocityFilter, 0, true, qApp, SLOT(setLowVelocityFilter(bool))); diff --git a/interface/src/Menu.h b/interface/src/Menu.h index 13618d1808..55266cf062 100644 --- a/interface/src/Menu.h +++ b/interface/src/Menu.h @@ -219,7 +219,6 @@ namespace MenuOption { const QString FrameTimer = "Show Timer"; const QString FullscreenMirror = "Fullscreen Mirror"; const QString GlowWhenSpeaking = "Glow When Speaking"; - const QString EnableHandMouseInput = "Enable Hand Controller Mouse Input"; const QString IncreaseAvatarSize = "Increase Avatar Size"; const QString IndependentMode = "Independent Mode"; const QString InputMenu = "Avatar>Input Devices"; diff --git a/interface/src/ui/ApplicationCompositor.cpp b/interface/src/ui/ApplicationCompositor.cpp index f4dbdd3bc0..99285c6558 100644 --- a/interface/src/ui/ApplicationCompositor.cpp +++ b/interface/src/ui/ApplicationCompositor.cpp @@ -115,10 +115,6 @@ bool raySphereIntersect(const glm::vec3 &dir, const glm::vec3 &origin, float r, ApplicationCompositor::ApplicationCompositor() : _alphaPropertyAnimation(new QPropertyAnimation(this, "alpha")) { - memset(_reticleActive, 0, sizeof(_reticleActive)); - memset(_magActive, 0, sizeof(_reticleActive)); - memset(_magSizeMult, 0, sizeof(_magSizeMult)); - auto geometryCache = DependencyManager::get(); _reticleQuad = geometryCache->allocateID(); @@ -219,9 +215,6 @@ void ApplicationCompositor::displayOverlayTexture(RenderArgs* renderArgs) { batch.setResourceTexture(0, overlayFramebuffer->getRenderBuffer(0)); geometryCache->renderUnitQuad(batch, vec4(vec3(1), _alpha)); - // Doesn't actually render - renderPointers(batch); - //draw the mouse pointer // Get the mouse coordinates and convert to NDC [-1, 1] vec2 canvasSize = qApp->getCanvasSize(); @@ -306,8 +299,7 @@ void ApplicationCompositor::displayOverlayTextureHmd(RenderArgs* renderArgs, int } #endif - // Doesn't actually render - renderPointers(batch); + vec3 reticleScale = vec3(Cursor::Manager::instance().getScale() * reticleSize); bindCursorTexture(batch); @@ -316,34 +308,13 @@ void ApplicationCompositor::displayOverlayTextureHmd(RenderArgs* renderArgs, int glm::mat4 overlayXfm; _modelTransform.getMatrix(overlayXfm); - // Only render the hand pointers if the EnableHandMouseInput is enabled - if (Menu::getInstance()->isOptionChecked(MenuOption::EnableHandMouseInput)) { - MyAvatar* myAvatar = DependencyManager::get()->getMyAvatar(); - auto palms = myAvatar->getHand()->getCopyOfPalms(); - for (const auto& palm : palms) { - if (palm.isActive()) { - glm::vec2 polar = getPolarCoordinates(palm); - // Convert to quaternion - mat4 pointerXfm = glm::mat4_cast(quat(vec3(polar.y, -polar.x, 0.0f))) * glm::translate(mat4(), vec3(0, 0, -1)); - mat4 reticleXfm = overlayXfm * pointerXfm; - reticleXfm = glm::scale(reticleXfm, reticleScale); - batch.setModelTransform(reticleXfm); - // Render reticle at location - geometryCache->renderUnitQuad(batch, glm::vec4(1), _reticleQuad); - } - } - } - //Mouse Pointer - if (_reticleActive[MOUSE]) { - glm::vec2 projection = screenToSpherical(glm::vec2(_reticlePosition[MOUSE].x(), - _reticlePosition[MOUSE].y())); - mat4 pointerXfm = glm::mat4_cast(quat(vec3(-projection.y, projection.x, 0.0f))) * glm::translate(mat4(), vec3(0, 0, -1)); - mat4 reticleXfm = overlayXfm * pointerXfm; - reticleXfm = glm::scale(reticleXfm, reticleScale); - batch.setModelTransform(reticleXfm); - geometryCache->renderUnitQuad(batch, glm::vec4(1), _reticleQuad); - } + glm::vec2 projection = screenToSpherical(qApp->getTrueMouse()); + mat4 pointerXfm = glm::mat4_cast(quat(vec3(-projection.y, projection.x, 0.0f))) * glm::translate(mat4(), vec3(0, 0, -1)); + mat4 reticleXfm = overlayXfm * pointerXfm; + reticleXfm = glm::scale(reticleXfm, reticleScale); + batch.setModelTransform(reticleXfm); + geometryCache->renderUnitQuad(batch, glm::vec4(1), _reticleQuad); }); } @@ -423,124 +394,6 @@ bool ApplicationCompositor::calculateRayUICollisionPoint(const glm::vec3& positi return false; } -//Renders optional pointers -void ApplicationCompositor::renderPointers(gpu::Batch& batch) { - if (qApp->isHMDMode() && !qApp->getLastMouseMoveWasSimulated()) { - //If we are in oculus, render reticle later - auto trueMouse = qApp->getTrueMouse(); - trueMouse /= qApp->getCanvasSize(); - QPoint position = QPoint(qApp->getTrueMouse().x, qApp->getTrueMouse().y); - _reticlePosition[MOUSE] = position; - _reticleActive[MOUSE] = true; - _magActive[MOUSE] = _magnifier; - _reticleActive[LEFT_CONTROLLER] = false; - _reticleActive[RIGHT_CONTROLLER] = false; - } else if (qApp->getLastMouseMoveWasSimulated() - && Menu::getInstance()->isOptionChecked(MenuOption::EnableHandMouseInput)) { - //only render controller pointer if we aren't already rendering a mouse pointer - _reticleActive[MOUSE] = false; - _magActive[MOUSE] = false; - renderControllerPointers(batch); - } -} - - -// FIXME - this is old code that likely needs to be removed and/or reworked to support the new input control model -void ApplicationCompositor::renderControllerPointers(gpu::Batch& batch) { - MyAvatar* myAvatar = DependencyManager::get()->getMyAvatar(); - - //Static variables used for storing controller state - static quint64 pressedTime[NUMBER_OF_RETICLES] = { 0ULL, 0ULL, 0ULL }; - static bool isPressed[NUMBER_OF_RETICLES] = { false, false, false }; - static bool stateWhenPressed[NUMBER_OF_RETICLES] = { false, false, false }; - - const HandData* handData = DependencyManager::get()->getMyAvatar()->getHandData(); - auto palms = handData->getCopyOfPalms(); - - for (unsigned int palmIndex = 2; palmIndex < 4; palmIndex++) { - const int index = palmIndex - 1; - - const PalmData* palmData = NULL; - - if (palmIndex >= palms.size()) { - return; - } - - if (palms[palmIndex].isActive()) { - palmData = &palms[palmIndex]; - } else { - continue; - } - - if (isPressed[index]) { - isPressed[index] = false; - //If the button was only pressed for < 250 ms - //then disable it. - - const int MAX_BUTTON_PRESS_TIME = 250 * MSECS_TO_USECS; - if (usecTimestampNow() < pressedTime[index] + MAX_BUTTON_PRESS_TIME) { - _magActive[index] = !stateWhenPressed[index]; - } - } - - //if we have the oculus, we should make the cursor smaller since it will be - //magnified - if (qApp->isHMDMode()) { - - QPoint point = getPalmClickLocation(palmData); - - _reticlePosition[index] = point; - - //When button 2 is pressed we drag the mag window - if (isPressed[index]) { - _magActive[index] = true; - } - - // If oculus is enabled, we draw the crosshairs later - continue; - } - - auto canvasSize = qApp->getCanvasSize(); - int mouseX, mouseY; - - // Get directon relative to avatar orientation - glm::vec3 direction = glm::inverse(myAvatar->getOrientation()) * palmData->getFingerDirection(); - - // Get the angles, scaled between (-0.5,0.5) - float xAngle = (atan2f(direction.z, direction.x) + PI_OVER_TWO); - float yAngle = 0.5f - ((atan2f(direction.z, direction.y) + (float)PI_OVER_TWO)); - - // Get the pixel range over which the xAngle and yAngle are scaled - float cursorRange = canvasSize.x * controller::InputDevice::getCursorPixelRangeMult(); - - mouseX = (canvasSize.x / 2.0f + cursorRange * xAngle); - mouseY = (canvasSize.y / 2.0f + cursorRange * yAngle); - - //If the cursor is out of the screen then don't render it - if (mouseX < 0 || mouseX >= (int)canvasSize.x || mouseY < 0 || mouseY >= (int)canvasSize.y) { - _reticleActive[index] = false; - continue; - } - _reticleActive[index] = true; - - - const float reticleSize = 40.0f; - - mouseX -= reticleSize / 2.0f; - mouseY += reticleSize / 2.0f; - - - glm::vec2 topLeft(mouseX, mouseY); - glm::vec2 bottomRight(mouseX + reticleSize, mouseY - reticleSize); - glm::vec2 texCoordTopLeft(0.0f, 0.0f); - glm::vec2 texCoordBottomRight(1.0f, 1.0f); - - DependencyManager::get()->renderQuad(batch, topLeft, bottomRight, texCoordTopLeft, texCoordBottomRight, - glm::vec4(RETICLE_COLOR[0], RETICLE_COLOR[1], RETICLE_COLOR[2], 1.0f)); - - } -} - void ApplicationCompositor::buildHemiVertices( const float fov, const float aspectRatio, const int slices, const int stacks) { static float textureFOV = 0.0f, textureAspectRatio = 1.0f; diff --git a/interface/src/ui/ApplicationCompositor.h b/interface/src/ui/ApplicationCompositor.h index 704d53dcfa..5f023adaef 100644 --- a/interface/src/ui/ApplicationCompositor.h +++ b/interface/src/ui/ApplicationCompositor.h @@ -92,9 +92,6 @@ private: void drawSphereSection(gpu::Batch& batch); void updateTooltips(); - void renderPointers(gpu::Batch& batch); - void renderControllerPointers(gpu::Batch& batch); - vec2 getPolarCoordinates(const PalmData& palm) const; // Support for hovering and tooltips @@ -109,11 +106,6 @@ private: float _textureAspectRatio{ 1.0f }; int _hemiVerticesID{ GeometryCache::UNKNOWN_ID }; - enum Reticles { MOUSE, LEFT_CONTROLLER, RIGHT_CONTROLLER, NUMBER_OF_RETICLES }; - bool _reticleActive[NUMBER_OF_RETICLES]; - QPoint _reticlePosition[NUMBER_OF_RETICLES]; - bool _magActive[NUMBER_OF_RETICLES]; - float _magSizeMult[NUMBER_OF_RETICLES]; bool _magnifier{ true }; float _alpha{ 1.0f }; diff --git a/libraries/controllers/src/controllers/Actions.cpp b/libraries/controllers/src/controllers/Actions.cpp index 701aea79c5..0bda52b237 100644 --- a/libraries/controllers/src/controllers/Actions.cpp +++ b/libraries/controllers/src/controllers/Actions.cpp @@ -62,6 +62,14 @@ namespace controller { makeButtonPair(Action::TOGGLE_MUTE, "ToggleMute"), makeButtonPair(Action::CYCLE_CAMERA, "CycleCamera"), + makeAxisPair(Action::RETICLE_CLICK, "ReticleClick"), + makeAxisPair(Action::RETICLE_X, "ReticleX"), + makeAxisPair(Action::RETICLE_Y, "ReticleY"), + makeAxisPair(Action::RETICLE_LEFT, "ReticleLeft"), + makeAxisPair(Action::RETICLE_RIGHT, "ReticleRight"), + makeAxisPair(Action::RETICLE_UP, "ReticleUp"), + makeAxisPair(Action::RETICLE_DOWN, "ReticleDown"), + // Aliases and bisected versions makeAxisPair(Action::LONGITUDINAL_BACKWARD, "Backward"), makeAxisPair(Action::LONGITUDINAL_FORWARD, "Forward"), diff --git a/libraries/controllers/src/controllers/Actions.h b/libraries/controllers/src/controllers/Actions.h index d5ad44c720..c8fabdd87b 100644 --- a/libraries/controllers/src/controllers/Actions.h +++ b/libraries/controllers/src/controllers/Actions.h @@ -55,6 +55,17 @@ enum class Action { SHIFT, + // Pointer/Reticle control + RETICLE_CLICK, + RETICLE_X, + RETICLE_Y, + + // Biseced aliases for RETICLE_X/RETICLE_Y + RETICLE_LEFT, + RETICLE_RIGHT, + RETICLE_UP, + RETICLE_DOWN, + // Biseced aliases for TRANSLATE_Z LONGITUDINAL_BACKWARD, LONGITUDINAL_FORWARD, @@ -78,7 +89,7 @@ enum class Action { // Biseced aliases for TRANSLATE_CAMERA_Z BOOM_IN, BOOM_OUT, - + NUM_ACTIONS, }; diff --git a/libraries/controllers/src/controllers/UserInputMapper.cpp b/libraries/controllers/src/controllers/UserInputMapper.cpp index fae7a2aaa8..9251a663ba 100755 --- a/libraries/controllers/src/controllers/UserInputMapper.cpp +++ b/libraries/controllers/src/controllers/UserInputMapper.cpp @@ -255,6 +255,9 @@ void UserInputMapper::update(float deltaTime) { fixBisectedAxis(_actionStates[toInt(Action::ROTATE_Y)], _actionStates[toInt(Action::YAW_LEFT)], _actionStates[toInt(Action::YAW_RIGHT)]); fixBisectedAxis(_actionStates[toInt(Action::ROTATE_X)], _actionStates[toInt(Action::PITCH_UP)], _actionStates[toInt(Action::PITCH_DOWN)]); + fixBisectedAxis(_actionStates[toInt(Action::RETICLE_X)], _actionStates[toInt(Action::RETICLE_LEFT)], _actionStates[toInt(Action::RETICLE_RIGHT)]); + fixBisectedAxis(_actionStates[toInt(Action::RETICLE_Y)], _actionStates[toInt(Action::RETICLE_UP)], _actionStates[toInt(Action::RETICLE_DOWN)]); + static const float EPSILON = 0.01f; for (auto i = 0; i < toInt(Action::NUM_ACTIONS); i++) { _actionStates[i] *= _actionScales[i]; @@ -319,42 +322,12 @@ QVector UserInputMapper::getActionNames() const { } return result; } -/* -void UserInputMapper::assignDefaulActionScales() { - _actionScales[toInt(Action::LONGITUDINAL_BACKWARD)] = 1.0f; // 1m per unit - _actionScales[toInt(Action::LONGITUDINAL_FORWARD)] = 1.0f; // 1m per unit - _actionScales[toInt(Action::LATERAL_LEFT)] = 1.0f; // 1m per unit - _actionScales[toInt(Action::LATERAL_RIGHT)] = 1.0f; // 1m per unit - _actionScales[toInt(Action::VERTICAL_DOWN)] = 1.0f; // 1m per unit - _actionScales[toInt(Action::VERTICAL_UP)] = 1.0f; // 1m per unit - _actionScales[toInt(Action::YAW_LEFT)] = 1.0f; // 1 degree per unit - _actionScales[toInt(Action::YAW_RIGHT)] = 1.0f; // 1 degree per unit - _actionScales[toInt(Action::PITCH_DOWN)] = 1.0f; // 1 degree per unit - _actionScales[toInt(Action::PITCH_UP)] = 1.0f; // 1 degree per unit - _actionScales[toInt(Action::BOOM_IN)] = 0.5f; // .5m per unit - _actionScales[toInt(Action::BOOM_OUT)] = 0.5f; // .5m per unit - _actionScales[toInt(Action::LEFT_HAND)] = 1.0f; // default - _actionScales[toInt(Action::RIGHT_HAND)] = 1.0f; // default - _actionScales[toInt(Action::LEFT_HAND_CLICK)] = 1.0f; // on - _actionScales[toInt(Action::RIGHT_HAND_CLICK)] = 1.0f; // on - _actionScales[toInt(Action::SHIFT)] = 1.0f; // on - _actionScales[toInt(Action::ACTION1)] = 1.0f; // default - _actionScales[toInt(Action::ACTION2)] = 1.0f; // default - _actionScales[toInt(Action::TRANSLATE_X)] = 1.0f; // default - _actionScales[toInt(Action::TRANSLATE_Y)] = 1.0f; // default - _actionScales[toInt(Action::TRANSLATE_Z)] = 1.0f; // default - _actionScales[toInt(Action::ROLL)] = 1.0f; // default - _actionScales[toInt(Action::PITCH)] = 1.0f; // default - _actionScales[toInt(Action::YAW)] = 1.0f; // default -} -*/ static int actionMetaTypeId = qRegisterMetaType(); static int inputMetaTypeId = qRegisterMetaType(); static int inputPairMetaTypeId = qRegisterMetaType(); static int poseMetaTypeId = qRegisterMetaType("Pose"); - QScriptValue inputToScriptValue(QScriptEngine* engine, const Input& input); void inputFromScriptValue(const QScriptValue& object, Input& input); QScriptValue actionToScriptValue(QScriptEngine* engine, const Action& action); diff --git a/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.cpp b/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.cpp index 9a9514db1b..1d7fbbec67 100755 --- a/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.cpp +++ b/libraries/input-plugins/src/input-plugins/KeyboardMouseDevice.cpp @@ -99,6 +99,9 @@ void KeyboardMouseDevice::mouseMoveEvent(QMouseEvent* event, unsigned int device _inputDevice->_axisStateMap[MOUSE_AXIS_Y_POS] = (currentMove.y() < 0 ? -currentMove.y() : 0.0f); _inputDevice->_axisStateMap[MOUSE_AXIS_Y_NEG] = (currentMove.y() > 0 ? currentMove.y() : 0.0f); + // FIXME - this has the characteristic that it will show large jumps when you move the cursor + // outside of the application window, because we don't get MouseEvents when the cursor is outside + // of the application window. _lastCursor = currentPos; _mouseMoved = true; From 6420a43858fa57095a498771d93ba47c0804c880 Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Tue, 15 Dec 2015 15:35:17 -0800 Subject: [PATCH 07/11] fix type --- libraries/controllers/src/controllers/Actions.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/libraries/controllers/src/controllers/Actions.h b/libraries/controllers/src/controllers/Actions.h index c8fabdd87b..56dd9660d9 100644 --- a/libraries/controllers/src/controllers/Actions.h +++ b/libraries/controllers/src/controllers/Actions.h @@ -60,33 +60,33 @@ enum class Action { RETICLE_X, RETICLE_Y, - // Biseced aliases for RETICLE_X/RETICLE_Y + // Bisected aliases for RETICLE_X/RETICLE_Y RETICLE_LEFT, RETICLE_RIGHT, RETICLE_UP, RETICLE_DOWN, - // Biseced aliases for TRANSLATE_Z + // Bisected aliases for TRANSLATE_Z LONGITUDINAL_BACKWARD, LONGITUDINAL_FORWARD, - // Biseced aliases for TRANSLATE_X + // Bisected aliases for TRANSLATE_X LATERAL_LEFT, LATERAL_RIGHT, - // Biseced aliases for TRANSLATE_Y + // Bisected aliases for TRANSLATE_Y VERTICAL_DOWN, VERTICAL_UP, - // Biseced aliases for ROTATE_Y + // Bisected aliases for ROTATE_Y YAW_LEFT, YAW_RIGHT, - // Biseced aliases for ROTATE_X + // Bisected aliases for ROTATE_X PITCH_DOWN, PITCH_UP, - // Biseced aliases for TRANSLATE_CAMERA_Z + // Bisected aliases for TRANSLATE_CAMERA_Z BOOM_IN, BOOM_OUT, From aa53900fa3a3b38809d8eee70d30b8172e4436f7 Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Tue, 15 Dec 2015 15:40:50 -0800 Subject: [PATCH 08/11] CR feedback --- interface/src/Application.cpp | 22 +++++++--------------- interface/src/Application.h | 3 --- 2 files changed, 7 insertions(+), 18 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 7294350d44..8ec5506f21 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -664,7 +664,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) : auto userInputMapper = DependencyManager::get(); connect(userInputMapper.data(), &UserInputMapper::actionEvent, [this](int action, float state) { if (action == controller::toInt(controller::Action::RETICLE_CLICK)) { - auto globalPos = getReticlePosition(); + auto globalPos = QCursor::pos(); auto localPos = _glWidget->mapFromGlobal(globalPos); if (state) { QMouseEvent mousePress(QEvent::MouseButtonPress, localPos, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier); @@ -686,13 +686,13 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) : } else if (action == controller::toInt(controller::Action::CONTEXT_MENU)) { VrMenu::toggle(); // show context menu even on non-stereo displays } else if (action == controller::toInt(controller::Action::RETICLE_X)) { - auto reticlePos = getReticlePosition(); - reticlePos.setX(reticlePos.x() + state); - setReticlePosition(reticlePos); + auto globalPos = QCursor::pos(); + globalPos.setX(globalPos.x() + state); + QCursor::setPos(globalPos); } else if (action == controller::toInt(controller::Action::RETICLE_Y)) { - auto reticlePos = getReticlePosition(); - reticlePos.setY(reticlePos.y() + state); - setReticlePosition(reticlePos); + auto globalPos = QCursor::pos(); + globalPos.setY(globalPos.y() + state); + QCursor::setPos(globalPos); } } }); @@ -4753,14 +4753,6 @@ bool Application::isThrottleRendering() const { return getActiveDisplayPlugin()->isThrottled(); } -QPoint Application::getReticlePosition() const { - return QCursor::pos(); -} - -void Application::setReticlePosition(QPoint position) { - QCursor::setPos(position); -} - ivec2 Application::getTrueMouse() const { return toGlm(_glWidget->mapFromGlobal(QCursor::pos())); } diff --git a/interface/src/Application.h b/interface/src/Application.h index 6c9dd1db47..a665e925a9 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -143,9 +143,6 @@ public: EntityTreeRenderer* getEntityClipboardRenderer() { return &_entityClipboardRenderer; } EntityEditPacketSender* getEntityEditPacketSender() { return &_entityEditSender; } - QPoint getReticlePosition() const; - void setReticlePosition(QPoint position); - ivec2 getMouse() const; ivec2 getTrueMouse() const; From 13c83bb262ca5f788d2ad80d754b49cafd657308 Mon Sep 17 00:00:00 2001 From: Stephen Birarda Date: Tue, 15 Dec 2015 17:23:29 -0800 Subject: [PATCH 09/11] update link to bat script in createBatButton.js --- examples/baseball/createBatButton.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/examples/baseball/createBatButton.js b/examples/baseball/createBatButton.js index 75f3dee26e..684e579ee7 100644 --- a/examples/baseball/createBatButton.js +++ b/examples/baseball/createBatButton.js @@ -46,7 +46,7 @@ var BAT_MODEL = "atp:c47deaae09cca927f6bc9cca0e8bbe77fc618f8c3f2b49899406a63a59f885cb.fbx"; var BAT_COLLISION_HULL = "atp:9eafceb7510c41d50661130090de7e0632aa4da236ebda84a0059a4be2130e0c.obj"; - var SCRIPT_URL = "http://rawgit.com/birarda/hifi/baseball/examples/baseball/bat.js" + var SCRIPT_RELATIVE_PATH = "bat.js" var batUserData = { grabbableKey: { @@ -70,7 +70,7 @@ velocity: { x: 0, y: 0.05, z: 0}, // workaround for gravity not taking effect on add gravity: { x: 0, y: -9.81, z: 0}, rotation: Quat.fromPitchYawRollDegrees(0.0, 0.0, -90.0), - script: SCRIPT_URL, + script: Script.resolvePath(SCRIPT_RELATIVE_PATH), userData: JSON.stringify(batUserData) }); }; From 76da3a14acda6f57d88d717adcb4c95ded57dc1e Mon Sep 17 00:00:00 2001 From: Brad Hefta-Gaub Date: Tue, 15 Dec 2015 17:58:07 -0800 Subject: [PATCH 10/11] fix bug in simulated left click - make qml menus work --- interface/src/Application.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index 8ec5506f21..2286c73d6e 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -671,7 +671,7 @@ Application::Application(int& argc, char** argv, QElapsedTimer& startupTimer) : sendEvent(_glWidget, &mousePress); _reticleClickPressed = true; } else { - QMouseEvent mouseRelease(QEvent::MouseButtonRelease, localPos, Qt::LeftButton, Qt::LeftButton, Qt::NoModifier); + QMouseEvent mouseRelease(QEvent::MouseButtonRelease, localPos, Qt::LeftButton, Qt::NoButton, Qt::NoModifier); sendEvent(_glWidget, &mouseRelease); _reticleClickPressed = false; } From 3280894e29c77e778fc9efd85a1917b3fdabc0e3 Mon Sep 17 00:00:00 2001 From: Zach Pomerantz Date: Tue, 15 Dec 2015 19:26:39 -0800 Subject: [PATCH 11/11] Load texture by convention with .obj --- libraries/fbx/src/OBJReader.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libraries/fbx/src/OBJReader.cpp b/libraries/fbx/src/OBJReader.cpp index 835bb1a9b6..11164afbbb 100644 --- a/libraries/fbx/src/OBJReader.cpp +++ b/libraries/fbx/src/OBJReader.cpp @@ -217,7 +217,6 @@ void OBJReader::parseMaterialLibrary(QIODevice* device) { materials[matName] = currentMaterial; matName = tokenizer.getDatum(); currentMaterial = materials[matName]; - currentMaterial.diffuseTextureFilename = "test"; #ifdef WANT_DEBUG qCDebug(modelformat) << "OBJ Reader Starting new material definition " << matName; #endif @@ -461,6 +460,9 @@ FBXGeometry* OBJReader::readOBJ(QByteArray& model, const QVariantHash& mapping, } if (!textName.isEmpty()) { + #ifdef WANT_DEBUG + qCDebug(modelformat) << "OBJ Reader found a default texture: " << textName; + #endif preDefinedMaterial.diffuseTextureFilename = textName; } materials[SMART_DEFAULT_MATERIAL_NAME] = preDefinedMaterial; @@ -553,9 +555,7 @@ FBXGeometry* OBJReader::readOBJ(QByteArray& model, const QVariantHash& mapping, model::MaterialPointer modelMaterial = fbxMaterial._material; if (!objMaterial.diffuseTextureFilename.isEmpty()) { - FBXTexture texture; - QUrl url = _url.resolved(QUrl(objMaterial.diffuseTextureFilename)); - // TODO -- something to get textures working again + fbxMaterial.diffuseTexture.filename = objMaterial.diffuseTextureFilename; } modelMaterial->setEmissive(fbxMaterial.emissiveColor);