From 2e3cd2e5997f5909bd687ef1f0477bacd91499ea Mon Sep 17 00:00:00 2001 From: Jonathan Bosson Date: Thu, 16 Mar 2017 13:40:29 -0600 Subject: [PATCH] Touch interaction works decently on globebrowsing and newhorizon scenes. Pause globebrowsing to freeze focus nodes orbit --- .../interaction/interactionhandler.h | 1 + modules/touch/include/TouchInteraction.h | 4 +- modules/touch/src/TouchInteraction.cpp | 178 ++++++++++-------- openspace.cfg | 2 +- src/interaction/interactionhandler.cpp | 4 + src/interaction/interactionmode.cpp | 15 +- 6 files changed, 121 insertions(+), 83 deletions(-) diff --git a/include/openspace/interaction/interactionhandler.h b/include/openspace/interaction/interactionhandler.h index 34c398186c..7583cc0112 100644 --- a/include/openspace/interaction/interactionhandler.h +++ b/include/openspace/interaction/interactionhandler.h @@ -97,6 +97,7 @@ public: ghoul::Dictionary getCameraStateDictionary(); SceneGraphNode* const focusNode() const; Camera* const camera() const; + std::shared_ptr interactionmode(); const InputState& inputState() const; /** diff --git a/modules/touch/include/TouchInteraction.h b/modules/touch/include/TouchInteraction.h index e6652c7438..ef586ea320 100644 --- a/modules/touch/include/TouchInteraction.h +++ b/modules/touch/include/TouchInteraction.h @@ -95,7 +95,9 @@ class TouchInteraction : public properties::PropertyOwner private: Camera* _camera; - SceneGraphNode* _focusNode; + SceneGraphNode* _focusNode = nullptr; + properties::StringProperty _origin; + globebrowsing::RenderableGlobe* _globe; glm::dvec3 _previousFocusNodePosition; glm::dquat _previousFocusNodeRotation; diff --git a/modules/touch/src/TouchInteraction.cpp b/modules/touch/src/TouchInteraction.cpp index 99e67ddf50..88b07dfcc5 100644 --- a/modules/touch/src/TouchInteraction.cpp +++ b/modules/touch/src/TouchInteraction.cpp @@ -25,6 +25,7 @@ #include +#include #include #include #include @@ -52,13 +53,23 @@ using namespace TUIO; using namespace openspace; TouchInteraction::TouchInteraction() - : _focusNode{ OsEng.interactionHandler().focusNode() }, _camera{ OsEng.interactionHandler().camera() }, + : properties::PropertyOwner("TouchInteraction"), + _origin("origin", "Origin", ""), _camera{ OsEng.interactionHandler().camera() }, _baseSensitivity{ 0.1 }, _baseFriction{ 0.02 }, _vel{ 0.0, glm::dvec2(0.0), glm::dvec2(0.0), 0.0, 0.0 }, _friction{ _baseFriction, _baseFriction/2.0, _baseFriction, _baseFriction, _baseFriction }, - _sensitivity{ 2.0, 0.1, 0.1, 0.1, 0.3 }, - _previousFocusNodePosition{ glm::dvec3(0.0) }, _minHeightFromSurface{ 6.6 * 1000000.0 } - {} + _sensitivity{ 2.0, 0.1, 0.1, 0.1, 0.3 }, _minHeightFromSurface{ 6.6 * 1000000.0 } +{ + _origin.onChange([this]() { + SceneGraphNode* node = sceneGraphNode(_origin.value()); + if (!node) { + LWARNING("Could not find a node in scenegraph called '" << _origin.value() << "'"); + return; + } + setFocusNode(node); + }); + +} TouchInteraction::~TouchInteraction() { } @@ -140,88 +151,96 @@ int TouchInteraction::interpret(const std::vector& list, const std:: void TouchInteraction::step(double dt) { using namespace glm; - // Create variables from current state - _focusNode = OsEng.interactionHandler().focusNode(); - dvec3 camPos = _camera->positionVec3(); - dvec3 centerPos = _focusNode->worldPosition(); - if (length(_previousFocusNodePosition) == 0) // ugly check to not make startup freak out + if (_focusNode) { + // Create variables from current state + dvec3 camPos = _camera->positionVec3(); + + // Follow the focus node + dquat totRot = _camera->rotationQuaternion(); + dvec3 centerPos = _focusNode->worldPosition(); + dvec3 focusNodeDiff = centerPos - _previousFocusNodePosition; _previousFocusNodePosition = centerPos; + camPos += focusNodeDiff; - // Follow the focus node - dvec3 focusNodeDiff = centerPos - _previousFocusNodePosition; - _previousFocusNodePosition = centerPos; - camPos += focusNodeDiff; + dvec3 directionToCenter = normalize(centerPos - camPos); + dvec3 centerToCamera = camPos - centerPos; + dvec3 lookUp = _camera->lookUpVectorWorldSpace(); + dvec3 camDirection = _camera->viewDirectionWorldSpace(); - dvec3 directionToCenter = normalize(centerPos - camPos); - dvec3 centerToCamera = camPos - centerPos; - dvec3 lookUp = _camera->lookUpVectorWorldSpace(); - dvec3 camDirection = _camera->viewDirectionWorldSpace(); - - // Make a representation of the rotation quaternion with local and global rotations - dmat4 lookAtMat = lookAt( - dvec3(0, 0, 0), - directionToCenter, - normalize(camDirection + lookUp)); // To avoid problem with lookup in up direction - dquat globalCamRot = normalize(quat_cast(inverse(lookAtMat))); - dquat localCamRot = inverse(globalCamRot) * _camera->rotationQuaternion(); - - - double boundingSphere = _focusNode->boundingSphere().lengthf(); - double minHeightAboveBoundingSphere = 1; - dvec3 centerToBoundingSphere; - - { // Roll - dquat camRollRot = angleAxis(_vel.localRoll*dt, dvec3(0.0, 0.0, 1.0)); - localCamRot = localCamRot * camRollRot; - } - { // Panning (local rotation) - dvec3 eulerAngles(-_vel.localRot.y*dt, -_vel.localRot.x*dt, 0); - dquat rotationDiff = dquat(eulerAngles); - localCamRot = localCamRot * rotationDiff; - } - { // Orbit (global rotation) - dvec3 eulerAngles(_vel.globalRot.y*dt, _vel.globalRot.x*dt, 0); - dquat rotationDiffCamSpace = dquat(eulerAngles); - - dquat rotationDiffWorldSpace = globalCamRot * rotationDiffCamSpace * inverse(globalCamRot); - dvec3 rotationDiffVec3 = centerToCamera * rotationDiffWorldSpace - centerToCamera; - camPos += rotationDiffVec3; - - directionToCenter = normalize(-(camPos - centerPos)); - dvec3 lookUpWhenFacingCenter = globalCamRot * dvec3(_camera->lookUpVectorCameraSpace()); + // Make a representation of the rotation quaternion with local and global rotations dmat4 lookAtMat = lookAt( dvec3(0, 0, 0), directionToCenter, - lookUpWhenFacingCenter); - globalCamRot = normalize(quat_cast(inverse(lookAtMat))); - } - { // Zooming - centerToBoundingSphere = -directionToCenter * boundingSphere; - dvec3 centerToCamera = camPos - centerPos; - if (length(_vel.zoom*dt) < length(centerToCamera - centerToBoundingSphere) && length(centerToCamera + directionToCenter*_vel.zoom*dt) > length(centerToBoundingSphere)) // should get boundingsphere from focusnode - camPos += directionToCenter*_vel.zoom*dt; - else - _vel.zoom = 0.0; - } - { // Roll around sphere normal - dquat camRollRot = angleAxis(_vel.globalRoll*dt, -directionToCenter); - globalCamRot = camRollRot * globalCamRot; - } - { // Push up to surface - dvec3 sphereSurfaceToCamera = camPos - (centerPos + centerToBoundingSphere); - double distFromSphereSurfaceToCamera = length(sphereSurfaceToCamera); - camPos += -directionToCenter * max(minHeightAboveBoundingSphere - distFromSphereSurfaceToCamera, 0.0); - } + normalize(camDirection + lookUp)); // To avoid problem with lookup in up direction + dquat globalCamRot = normalize(quat_cast(inverse(lookAtMat))); + dquat localCamRot = inverse(globalCamRot) * totRot; - double dist = length(camPos - (centerPos + centerToBoundingSphere)); - configSensitivities(dist); - decelerate(); - // Update the camera state - _camera->setPositionVec3(camPos); - _camera->setRotation(globalCamRot * localCamRot); + double boundingSphere = _focusNode->boundingSphere().lengthf(); + double minHeightAboveBoundingSphere = 1; + dvec3 centerToBoundingSphere; - + { // Roll + dquat camRollRot = angleAxis(_vel.localRoll*dt, dvec3(0.0, 0.0, 1.0)); + localCamRot = localCamRot * camRollRot; + } + { // Panning (local rotation) + dvec3 eulerAngles(-_vel.localRot.y*dt, -_vel.localRot.x*dt, 0); + dquat rotationDiff = dquat(eulerAngles); + localCamRot = localCamRot * rotationDiff; + } + { // Orbit (global rotation) + dvec3 eulerAngles(_vel.globalRot.y*dt, _vel.globalRot.x*dt, 0); + dquat rotationDiffCamSpace = dquat(eulerAngles); + + dquat rotationDiffWorldSpace = globalCamRot * rotationDiffCamSpace * inverse(globalCamRot); + dvec3 rotationDiffVec3 = centerToCamera * rotationDiffWorldSpace - centerToCamera; + camPos += rotationDiffVec3; + + dvec3 centerToCamera = camPos - centerPos; + directionToCenter = normalize(-centerToCamera); + dvec3 lookUpWhenFacingCenter = globalCamRot * dvec3(_camera->lookUpVectorCameraSpace()); + dmat4 lookAtMat = lookAt( + dvec3(0, 0, 0), + directionToCenter, + lookUpWhenFacingCenter); + globalCamRot = normalize(quat_cast(inverse(lookAtMat))); + } + { // Zooming + centerToBoundingSphere = -directionToCenter * boundingSphere; + dvec3 centerToCamera = camPos - centerPos; + if (length(_vel.zoom*dt) < length(centerToCamera - centerToBoundingSphere) && length(centerToCamera + directionToCenter*_vel.zoom*dt) > length(centerToBoundingSphere)) // should get boundingsphere from focusnode + camPos += directionToCenter*_vel.zoom*dt; + else + _vel.zoom = 0.0; + } + { // Roll around sphere normal + dquat camRollRot = angleAxis(_vel.globalRoll*dt, -directionToCenter); + globalCamRot = camRollRot * globalCamRot; + } + { // Push up to surface + dvec3 sphereSurfaceToCamera = camPos - (centerPos + centerToBoundingSphere); + double distFromSphereSurfaceToCamera = length(sphereSurfaceToCamera); + camPos += -directionToCenter * max(minHeightAboveBoundingSphere - distFromSphereSurfaceToCamera, 0.0); + } + + std::shared_ptr gbim = + std::dynamic_pointer_cast (OsEng.interactionHandler().interactionmode()); + if (gbim) { + double dist = length(camPos - (centerPos + centerToBoundingSphere)); + configSensitivities(dist); + } + decelerate(); + + // Update the camera state + _camera->setPositionVec3(camPos); + _camera->setRotation(globalCamRot * localCamRot); + } + else { + setFocusNode(OsEng.interactionHandler().focusNode()); + std::cout << "focus node set\n"; + } + } @@ -274,6 +293,11 @@ void TouchInteraction::setCamera(Camera* camera) { } void TouchInteraction::setFocusNode(SceneGraphNode* focusNode) { _focusNode = focusNode; + + if (_focusNode != nullptr) { + _previousFocusNodePosition = _focusNode->worldPosition(); + _previousFocusNodeRotation = glm::quat_cast(_focusNode->worldRotationMatrix()); + } } void TouchInteraction::setFriction(double friction) { _baseFriction = std::max(friction, 0.0); diff --git a/openspace.cfg b/openspace.cfg index 050d9758c7..87382f4356 100644 --- a/openspace.cfg +++ b/openspace.cfg @@ -23,7 +23,7 @@ return { -- Sets the scene that is to be loaded by OpenSpace. A scene file is a description -- of all entities that will be visible during an instance of OpenSpace - Scene = "${SCENE}/globebrowsing.scene", + Scene = "${SCENE}/newhorizons.scene", -- Scene = "${SCENE}/globebrowsing.scene", -- Scene = "${SCENE}/rosetta.scene", -- Scene = "${SCENE}/dawn.scene", diff --git a/src/interaction/interactionhandler.cpp b/src/interaction/interactionhandler.cpp index 2b0dcaeff9..a9bdbf06df 100644 --- a/src/interaction/interactionhandler.cpp +++ b/src/interaction/interactionhandler.cpp @@ -268,6 +268,10 @@ Camera* const InteractionHandler::camera() const { return _camera; } +std::shared_ptr InteractionHandler::interactionmode() { + return _currentInteractionMode; +} + const InputState& InteractionHandler::inputState() const { return *_inputState; } diff --git a/src/interaction/interactionmode.cpp b/src/interaction/interactionmode.cpp index 539416890e..cf5787cb8b 100644 --- a/src/interaction/interactionmode.cpp +++ b/src/interaction/interactionmode.cpp @@ -481,8 +481,8 @@ void OrbitalInteractionMode::updateCameraStateFromMouseStates(Camera& camera, do } // Update the camera state - camera.setPositionVec3(camPos); - camera.setRotation(globalCameraRotation * localCameraRotation); + //camera.setPositionVec3(camPos); + //camera.setRotation(globalCameraRotation * localCameraRotation); } } @@ -681,8 +681,15 @@ void GlobeBrowsingInteractionMode::updateCameraStateFromMouseStates(Camera& came } // Update the camera state - camera.setPositionVec3(camPos); - camera.setRotation(globalCameraRotation * localCameraRotation); + //camera.setPositionVec3(camPos); + //camera.setRotation(globalCameraRotation * localCameraRotation); + + std::cout << "gRot: " << "(" << _mouseStates->synchedGlobalRotationMouseVelocity().x << "," << _mouseStates->synchedGlobalRotationMouseVelocity().y << ")" + << ", lRot: " << "(" << _mouseStates->synchedLocalRotationMouseVelocity().x << "," << _mouseStates->synchedLocalRotationMouseVelocity().y << ")" + << ", Zoom: " << "(" << _mouseStates->synchedTruckMovementMouseVelocity().x << "," << _mouseStates->synchedTruckMovementMouseVelocity().y << ")" + << ", gRoll: " << "(" << _mouseStates->synchedGlobalRollMouseVelocity().x << "," << _mouseStates->synchedGlobalRollMouseVelocity().y << ")" + << ", lRoll: " << "(" << _mouseStates->synchedLocalRollMouseVelocity().x << "," << _mouseStates->synchedLocalRollMouseVelocity().y << ")" + << "\n"; } #endif // OPENSPACE_MODULE_GLOBEBROWSING_ENABLED }