zooming now uses velocity to move the camera, rotation works with one touch input although currently with a direct new position

This commit is contained in:
Jonathan Bosson
2017-03-09 14:43:18 -07:00
parent cc269d6aff
commit fc2a9b03d2
4 changed files with 93 additions and 80 deletions
+77 -31
View File
@@ -42,6 +42,7 @@
#include <modules/globebrowsing/geometry/geodetic2.h>
#endif
#include <glm/ext.hpp>
namespace {
const std::string _loggerCat = "TouchInteraction";
@@ -51,48 +52,94 @@ using namespace TUIO;
using namespace openspace;
TouchInteraction::TouchInteraction()
: _dt{ 0.0 }, _sensitivity{ 1.0 }, _friction{ 0.8 }, _focusNode{ nullptr },
: _sensitivity{ 1.0 }, _friction{ 0.98 }, _focusNode{ OsEng.interactionHandler().focusNode() },
_camera{ OsEng.interactionHandler().camera() },
_globalCameraRotation{ glm::dquat(0.0, 0.0, 0.0, 0.0) }, _localCameraRotation{ glm::dquat(0.0, 0.0, 0.0, 0.0) },
_cameraPosition{ OsEng.interactionHandler().camera()->positionVec3() }, // initialise local/global rotations?
_velocityPos { glm::dvec3(0.0) }, _velocityRot{ glm::dvec3(0.0) }, _centroid{ glm::dvec3(0.0) }
_velocityPos{ glm::dvec3(0.0) }, _velocityRot{ glm::dvec3(0.0) }, _centroid{ glm::dvec3(0.0) },
_previousFocusNodePosition{ glm::dvec3(0.0) }
{}
TouchInteraction::~TouchInteraction() { }
void TouchInteraction::update(const std::vector<TUIO::TuioCursor>& list, std::vector<Point>& lastProcessed) {
void TouchInteraction::update(const std::vector<TuioCursor>& list, std::vector<Point>& lastProcessed) {
using namespace glm;
// Create variables from current state
_focusNode = OsEng.interactionHandler().focusNode();
_cameraPosition = _camera->positionVec3();
dvec3 centerPos = _focusNode->worldPosition();
if (length(_previousFocusNodePosition) == 0) // ugly check to not make startup freak out
_previousFocusNodePosition = centerPos;
double distance;
double lastDistance;
double zoomFactor;
glm::dvec3 focusDir;
TuioCursor cursor = list.at(0);
// Follow the focus node
dvec3 focusNodeDiff = centerPos - _previousFocusNodePosition;
_previousFocusNodePosition = centerPos;
_cameraPosition += focusNodeDiff;
dquat totalRotation = _camera->rotationQuaternion();
dvec3 directionToCenter = normalize(centerPos - _cameraPosition);
dvec3 centerToCamera = _cameraPosition - centerPos;
dvec3 lookUp = _camera->lookUpVectorWorldSpace();
dvec3 camDirection = _camera->viewDirectionWorldSpace();
// Create the internal representation of the local and global camera rotations
dmat4 lookAtMat = lookAt(
dvec3(0, 0, 0),
directionToCenter,
normalize(camDirection + lookUp)); // To avoid problem with lookup in up direction
_globalCameraRotation = normalize(quat_cast(inverse(lookAtMat)));
_localCameraRotation = inverse(_globalCameraRotation) * totalRotation;
_interactionMode = interpret(list);
switch (_interactionMode) {
case ROT:
// add rotation velocity
break;
case PINCH:
// add zooming velocity
focusDir = glm::normalize(_camera->focusPositionVec3() - _cameraPosition);
case ROT: { // add rotation velocity
// Do global rotation
dvec2 rotationVelocity = dvec2(cursor.getXSpeed()*0.1, cursor.getYSpeed()*0.1);
dvec3 eulerAngles(rotationVelocity.y, rotationVelocity.x, 0);
dquat rotationDiffCamSpace = dquat(eulerAngles);
dquat newRotationCamspace = _globalCameraRotation * rotationDiffCamSpace;
dquat rotationDiffWorldSpace = newRotationCamspace * inverse(_globalCameraRotation);
_rotationDiff = centerToCamera * rotationDiffWorldSpace - centerToCamera; // _velocityPos += rotationDiffVec3
_cameraPosition += _rotationDiff;
centerToCamera = _cameraPosition - centerPos;
directionToCenter = normalize(-centerToCamera);
dvec3 lookUpWhenFacingCenter = _globalCameraRotation * dvec3(_camera->lookUpVectorCameraSpace());
dmat4 lookAtMat = lookAt(
dvec3(0, 0, 0),
directionToCenter,
lookUpWhenFacingCenter);
_globalCameraRotation = normalize(quat_cast(inverse(lookAtMat)));
_camera->setPositionVec3(_cameraPosition);
_camera->setRotation(_globalCameraRotation * _localCameraRotation);
break;
}
case PINCH: { // add zooming velocity
_centroid.x = std::accumulate(list.begin(), list.end(), 0.0f, [](double x, const TuioCursor& c) { return x + c.getX(); }) / list.size();
_centroid.y = std::accumulate(list.begin(), list.end(), 0.0f, [](double y, const TuioCursor& c) { return y + c.getY(); }) / list.size();
distance = std::accumulate(list.begin(), list.end(), 0.0, [&](double d, const TuioCursor& c) {
double distance = std::accumulate(list.begin(), list.end(), 0.0, [&](double d, const TuioCursor& c) {
return d + sqrt(pow(c.getX() - _centroid.x, 2) + pow(c.getY() - _centroid.y, 2));
});
lastDistance = std::accumulate(lastProcessed.begin(), lastProcessed.end(), 0.0f, [&](float d, const Point& p) {
double lastDistance = std::accumulate(lastProcessed.begin(), lastProcessed.end(), 0.0f, [&](float d, const Point& p) {
return d + sqrt(pow(p.second.getX() - _centroid.x, 2) + pow(p.second.getY() - _centroid.y, 2));
});
zoomFactor = distance - lastDistance; // should be dependant on screen size, distance from focusNode
double zoomFactor = distance - lastDistance; // should be dependant on screen size, distance from focusNode
zoomFactor *= glm::distance(_cameraPosition, _camera->focusPositionVec3());
_velocityPos += focusDir*zoomFactor;
// gets really crazy if you set a velocity when we're far away, limit zooming to not go into globe
_velocityPos += directionToCenter*zoomFactor;
break;
case PAN:
// add local rotation velocity
}
case PAN: { // add local rotation velocity
break;
}
default:
LINFO("Couldn't interpret input" << "\n");
}
@@ -107,19 +154,18 @@ int TouchInteraction::interpret(const std::vector<TuioCursor>& list) {
return PINCH;
}
void TouchInteraction::performStep(double dt) {
if (dt != _dt) {
_cameraPosition += _velocityPos * (dt - _dt);
_velocityPos *= _friction;
if (glm::length(_velocityPos) < 100) // max of zero to have a shut off range
_velocityPos = glm::dvec3(0.0);
void TouchInteraction::step(double dt) {
_cameraPosition = _camera->positionVec3();
_cameraPosition += _velocityPos * dt;
_velocityPos *= _friction;
_dt = dt;
// Update the camera state
_camera->setPositionVec3(_cameraPosition);
//_camera->setRotation(_globalCameraRotation * _localCameraRotation);
}
// Update the camera state
_camera->setPositionVec3(_cameraPosition);
//_camera->setRotation(_globalCameraRotation * _localCameraRotation); // need to initialize these camerarotations
}