Merge branch 'master' of github.com:OpenSpace/OpenSpace into feature/data-management

This commit is contained in:
Emil Axelsson
2017-11-05 20:04:47 +01:00
16 changed files with 6260 additions and 12 deletions
+2
View File
@@ -176,6 +176,7 @@ private:
properties::FloatProperty _slerpTime;
properties::IVec2Property _guiButton;
properties::Vec4Property _friction;
properties::FloatProperty _pickingRadiusMinimum;
// Class variables
VelocityStates _vel;
@@ -194,6 +195,7 @@ private:
bool _lmSuccess;
bool _guiON;
std::vector<SelectedBody> _selected;
SceneGraphNode* _pickingSelected;
LMstat _lmstat;
glm::dquat _toSlerp;
glm::dvec3 _centroid;
+81 -5
View File
@@ -172,6 +172,12 @@ TouchInteraction::TouchInteraction()
glm::vec4(0.f),
glm::vec4(0.2f)
)
, _pickingRadiusMinimum(
{ "Picking Radius", "Minimum radius for picking in NDC coordinates", "" },
0.1f,
0.f,
1.f
)
, _vel{ glm::dvec2(0.0), 0.0, 0.0, glm::dvec2(0.0) }
, _sensitivity{ glm::dvec2(0.08, 0.045), 4.0, 2.75, glm::dvec2(0.08, 0.045) }
, _centroid(glm::dvec3(0.0))
@@ -203,6 +209,7 @@ TouchInteraction::TouchInteraction()
addProperty(_slerpTime);
addProperty(_guiButton);
addProperty(_friction);
addProperty(_pickingRadiusMinimum);
_origin.onChange([this]() {
SceneGraphNode* node = sceneGraphNode(_origin.value());
@@ -476,6 +483,15 @@ void TouchInteraction::findSelectedNode(const std::vector<TuioCursor>& list) {
glm::dquat camToWorldSpace = _camera->rotationQuaternion();
glm::dvec3 camPos = _camera->positionVec3();
std::vector<SelectedBody> newSelected;
struct PickingInfo {
SceneGraphNode* node;
double pickingDistanceNDC;
double pickingDistanceWorld;
};
std::vector<PickingInfo> pickingInfo;
for (const TuioCursor& c : list) {
double xCo = 2 * (c.getX() - 0.5);
double yCo = -2 * (c.getY() - 0.5); // normalized -1 to 1 coordinates on screen
@@ -484,7 +500,8 @@ void TouchInteraction::findSelectedNode(const std::vector<TuioCursor>& list) {
glm::dvec3 raytrace = glm::normalize(cursorInWorldSpace);
int id = c.getSessionID();
for (SceneGraphNode* node : selectableNodes) {
for (SceneGraphNode* node : selectableNodes) {
double boundingSphere = node->boundingSphere();
glm::dvec3 camToSelectable = node->worldPosition() - camPos;
double dist = length(glm::cross(cursorInWorldSpace, camToSelectable)) / glm::length(cursorInWorldSpace) - boundingSphere;
@@ -492,8 +509,9 @@ void TouchInteraction::findSelectedNode(const std::vector<TuioCursor>& list) {
// finds intersection closest 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)
if (root > 0) { // two intersection points (take the closest one)
d -= sqrt(root);
}
glm::dvec3 intersectionPoint = camPos + d * raytrace;
glm::dvec3 pointInModelView = glm::inverse(node->rotationMatrix()) * (intersectionPoint - node->worldPosition());
@@ -510,9 +528,65 @@ void TouchInteraction::findSelectedNode(const std::vector<TuioCursor>& list) {
newSelected.push_back({ id, node, pointInModelView });
}
}
// Compute locations in view space to perform the picking
glm::dvec4 clip = glm::dmat4(_camera->projectionMatrix()) * _camera->combinedViewMatrix() * glm::vec4(node->worldPosition(), 1.0);
glm::dvec2 ndc = clip / clip.w;
// If the object is not in the screen, we dont want to consider it at all
if (ndc.x >= -1.0 && ndc.x <= 1.0 && ndc.y >= -1.0 && ndc.y <= 1.0) {
glm::dvec2 cursor = { xCo, yCo };
double ndcDist = glm::length(ndc - cursor);
// We either want to select the object if it's bounding sphere as been touched
// (checked by the first part of this loop above) or if the touch point is
// within a minimum distance of the center
if (dist <= 0.0 || (ndcDist <= _pickingRadiusMinimum)) {
// If the user touched the planet directly, this is definitely the one they are
// interested in => minimum distance
if (dist <= 0.0) {
LINFOC(node->name(), "Picking candidate based on direct touch");
pickingInfo.push_back({
node,
-std::numeric_limits<double>::max(),
-std::numeric_limits<double>::max()
});
}
else {
// The node was considered due to minimum picking distance radius
LINFOC(node->name(), "Picking candidate based on proximity");
pickingInfo.push_back({
node,
ndcDist,
dist
});
}
}
}
}
}
_selected = newSelected;
// After we are done with all of the nodes, we can sort the picking list and pick the
// one that fits best (= is closest or was touched directly)
std::sort(
pickingInfo.begin(),
pickingInfo.end(),
[](const PickingInfo& lhs, const PickingInfo& rhs) {
return lhs.pickingDistanceWorld < rhs.pickingDistanceWorld;
}
);
// If an item has been picked, it's in the first position of the vector now
if (!pickingInfo.empty()) {
_pickingSelected = pickingInfo.begin()->node;
LINFOC("Picking", "Picked node: " + _pickingSelected->name());
}
LINFOC("Picking", "============");
_selected = std::move(newSelected);
}
// Interprets the input gesture to a specific interaction
@@ -634,8 +708,8 @@ void TouchInteraction::computeVelocities(const std::vector<TuioCursor>& list, co
break;
}
case PICK: { // pick something in the scene as focus node
if (_selected.size() == 1 && _selected.at(0).node) {
setFocusNode(_selected.at(0).node);
if (_pickingSelected) {
setFocusNode(_pickingSelected);
OsEng.navigationHandler().setFocusNode(_focusNode); // cant do setFocusNode() since TouchInteraction is not subclass of InteractionMode
// rotate camera to look at new focus, using slerp quat
@@ -771,6 +845,7 @@ void TouchInteraction::unitTest() {
// clear everything
_selected.clear();
_pickingSelected = nullptr;
_vel.orbit = glm::dvec2(0.0, 0.0);
_vel.zoom = 0.0;
_vel.roll = 0.0;
@@ -838,6 +913,7 @@ void TouchInteraction::resetAfterInput() {
_lastVel.roll = 0.0;
_lastVel.pan = glm::dvec2(0.0, 0.0);
_selected.clear();
_pickingSelected = nullptr;
}
// Reset all property values to default