From 31e175232a2d2020070ff87900204fa9a509ca67 Mon Sep 17 00:00:00 2001 From: Jonathan Bosson Date: Thu, 6 Apr 2017 15:16:25 -0600 Subject: [PATCH] the point on the surface of a body can now be described in spherical coordinates --- modules/touch/include/TouchInteraction.h | 7 +++- modules/touch/src/TouchInteraction.cpp | 49 ++++++++++-------------- 2 files changed, 26 insertions(+), 30 deletions(-) diff --git a/modules/touch/include/TouchInteraction.h b/modules/touch/include/TouchInteraction.h index d493fbe99e..9e24216e73 100644 --- a/modules/touch/include/TouchInteraction.h +++ b/modules/touch/include/TouchInteraction.h @@ -74,6 +74,11 @@ struct InteractionType { bool roll; bool pick; }; +struct SelectedBody { + int id; + SceneGraphNode* node; + glm::dvec2 coordinates; +}; using Point = std::pair; @@ -120,7 +125,7 @@ class TouchInteraction : public properties::PropertyOwner bool _directTouchMode; double _projectionScaleFactor; double _currentRadius; - std::vector> _selected; + std::vector _selected; InteractionType _action; glm::dvec3 _centroid; diff --git a/modules/touch/src/TouchInteraction.cpp b/modules/touch/src/TouchInteraction.cpp index 8e876a32a0..a7844ee19e 100644 --- a/modules/touch/src/TouchInteraction.cpp +++ b/modules/touch/src/TouchInteraction.cpp @@ -43,6 +43,7 @@ #include #endif +#include #include namespace { @@ -106,7 +107,7 @@ void TouchInteraction::trace(const std::vector& list) { double aspectRatio = res.x/res.y; glm::dquat camToWorldSpace = _camera->rotationQuaternion(); glm::dvec3 camPos = _camera->positionVec3(); - std::vector> newSelected; + std::vector newSelected; for (const TuioCursor& c : list) { double xCo = 2 * (c.getX() - 0.5) * aspectRatio; double yCo = -2 * (c.getY() - 0.5); // normalized -1 to 1 coordinates on screen @@ -118,45 +119,35 @@ void TouchInteraction::trace(const std::vector& list) { int id = c.getSessionID(); double dist = length(glm::cross(cursorInWorldSpace, camToSelectable)) / glm::length(cursorInWorldSpace) - boundingSphere; if (dist <= 0.0) { - auto found = find_if(newSelected.begin(), newSelected.end(), [id](std::pair p) { return p.first == id; }); - if (found != newSelected.end()) { - double oldNodeDist = glm::length(found->second->worldPosition() - camPos); - if (glm::length(camToSelectable) < oldNodeDist) { // new node is closer, remove added node and add the new one instead - newSelected.pop_back(); - newSelected.push_back(std::make_pair(id, node)); - } - } - else - newSelected.push_back(std::make_pair(id, node)); - // finds intersection point between boundingsphere and line in world coordinates, assumes line direction is normalized double d = glm::dot(raytrace, camToSelectable); double root = boundingSphere * boundingSphere - glm::dot(camToSelectable, camToSelectable) + d * d; if (root > 0) // two intersection points (take the closest one) d -= sqrt(root); glm::dvec3 intersectionPoint = camPos + d * raytrace; - //double d2 = d + sqrt(root); - //glm::dvec3 intersectionPoint2 = camPos + d2 * raytrace; - //std::cout << root << ", " << glm::to_string(intersectionPoint) /*<< ", " << glm::to_string(intersectionPoint2)*/ << "\n"; - - std::cout << glm::to_string(raytrace) << "\n"; - - - glm::dvec3 modelVector = node->rotationMatrix() * glm::dvec3(1.0, 0.0, 0.0); - // assume raytrace is constant -#ifdef OPENSPACE_MODULE_GLOBEBROWSING_ENABLED - // in this case raytrace dir in world space differs as we follow the focus nodes rotation with the camera -#endif - - // f(theta, phi, v) = matrix * modelVector = surfacepointinmodelview + glm::dvec3 pointInModelView = glm::inverse(node->rotationMatrix()) * (intersectionPoint - node->worldPosition()); + double theta = atan(pointInModelView.y / pointInModelView.x); + double phi = atan(glm::length(glm::dvec2(pointInModelView.x, pointInModelView.y)) / pointInModelView.z); // spherical coordinates for point on surface + // Add id, node and surface coordinates to the selected list + auto found = find_if(newSelected.begin(), newSelected.end(), [id](SelectedBody s) { return s.id == id; }); + if (found != newSelected.end()) { + double oldNodeDist = glm::length(found->node->worldPosition() - camPos); + if (glm::length(camToSelectable) < oldNodeDist) { // new node is closer, remove added node and add the new one instead + newSelected.pop_back(); + newSelected.push_back({ id, node, glm::dvec2(theta, phi) }); + } + } + else { + newSelected.push_back({ id, node, glm::dvec2(theta, phi) }); + } } } } //debugging for (auto it : newSelected) - std::cout << it.second->name() << " hit with cursor " << it.first << ". World Pos: " << glm::to_string(it.second->worldPosition()) << "\n"; + std::cout << it.node->name() << " hit with cursor " << it.id << ". Surface Coordinates: " << glm::to_string(it.coordinates) << "\n"; /*std::cout << "Dist: " << dist << ", Ray: " << glm::to_string(glm::normalize(cursorInWorldSpace)) << "\nview: " << glm::to_string(_camera->viewDirectionWorldSpace()) << "\ntoFocus: " << glm::to_string(glm::normalize(camToCenter)) << "\n\n";*/ @@ -273,8 +264,8 @@ void TouchInteraction::accelerate(const std::vector& list, const std _vel.localRoll += -rollFactor * _sensitivity.localRoll; } if (_action.pick) { // pick something in the scene as focus node - if (_selected.size() == 1 && _selected.at(0).second != _focusNode) { - _focusNode = _selected.at(0).second; // rotate camera to look at new focus + if (_selected.size() == 1 && _selected.at(0).node != _focusNode) { + _focusNode = _selected.at(0).node; // rotate camera to look at new focus OsEng.interactionHandler().setFocusNode(_focusNode); // cant do setFocusNode since TouchInteraction is not subclass of InteractionMode glm::dvec3 camToFocus = glm::normalize(_focusNode->worldPosition() - _camera->positionVec3()); double angleX = glm::orientedAngle(_camera->viewDirectionWorldSpace(), camToFocus, glm::normalize(_camera->rotationQuaternion() * _camera->lookUpVectorWorldSpace()));