More trackball/camera work

This commit is contained in:
Hans-Christian Helltegen
2014-04-28 16:02:27 -04:00
parent ed93372c8b
commit a80c5d45d4
4 changed files with 92 additions and 21 deletions
@@ -59,13 +59,18 @@ public:
private:
glm::vec3 mapToTrackball(glm::vec2 mousePos);
void trackballRotate(int x, int y);
Camera *camera_;
Camera* camera_;
bool enabled_;
SceneGraphNode *node_;
double dt_;
glm::vec3 _lastTrackballPos;
bool _leftMouseButtonDown, _isMouseBeingPressedAndHeld;
// used for calling when updating and deallocation
std::vector<ExternalControl*> controllers_;
+76 -14
View File
@@ -7,6 +7,8 @@
#include <openspace/interaction/externalcontrol/joystickexternalcontrol.h>
#include <openspace/query/query.h>
#include <openspace/engine/openspaceengine.h>
#include <openspace/util/psc.h>
#include <glm/gtx/vector_angle.hpp>
// std includes
#include <cassert>
@@ -22,11 +24,13 @@ InteractionHandler::InteractionHandler() {
enabled_ = true;
node_ = nullptr;
dt_ = 0.0;
_lastTrackballPos = glm::vec3(0.5);
_leftMouseButtonDown = false;
_isMouseBeingPressedAndHeld = false;
}
InteractionHandler::~InteractionHandler() {
for (size_t i = 0; i < controllers_.size(); ++i)
{
for (size_t i = 0; i < controllers_.size(); ++i) {
delete controllers_[i];
}
}
@@ -228,16 +232,70 @@ double InteractionHandler::getDt() {
return dt_;
}
// Implementation of Holroyd's Trackball
glm::vec3 InteractionHandler::mapToTrackball(glm::vec2 mousePos) {
glm::vec3 out = glm::vec3(mousePos.x, mousePos.y, 0);
const float RADIUS = 0.5; // Sphere radius
if (out.x*out.x + out.y*out.y <= RADIUS*RADIUS/2.0)
out.z = sqrt(RADIUS*RADIUS - (out.x*out.x + out.y*out.y));
else
out.z = (RADIUS*RADIUS/2.0)/sqrt(out.x*out.x + out.y*out.y);
glm::vec3 out = glm::vec3(mousePos.x-0.5, -1.0*(mousePos.y-0.5), 0);
return out;
// Mapping according to Holroyds trackball
// Piece-wise sphere + hyperbolic sheet
if (out.x*out.x + out.y*out.y <= RADIUS*RADIUS/2.0) {
//Spherical Region
out.z = RADIUS*RADIUS - (out.x*out.x + out.y*out.y);
out.z = out.z > 0.0 ? sqrtf(out.z) : 0.0;
} else { //Hyperbolic Region - for smooth z values
out.z = (RADIUS*RADIUS)/(2.0*sqrt(out.x*out.x + out.y*out.y));
}
return glm::normalize(out);
}
void InteractionHandler::trackballRotate(int x, int y) {
// Normalize mouse coordinates to [0,1]
float width = sgct::Engine::instance()->getActiveXResolution();
float height = sgct::Engine::instance()->getActiveYResolution();
glm::vec2 mousePos = glm::vec2((float)x/width, (float)y/height);
glm::vec3 curTrackballPos = mapToTrackball(mousePos);
// LDEBUG(mousePos.x << ", " << mousePos.y << " = " << curTrackballPos.x << ", " << curTrackballPos.y << ", " << curTrackballPos.z);
// Disable movement on the first click for extra smoothness
if (!_isMouseBeingPressedAndHeld) {
_lastTrackballPos = curTrackballPos;
_isMouseBeingPressedAndHeld = true;
}
if (curTrackballPos != _lastTrackballPos) {
// calculate rotation angle (in radians), rotation axis and quaternion
float rotationAngle = glm::angle(curTrackballPos, _lastTrackballPos);
glm::vec3 rotationAxis = glm::cross(_lastTrackballPos, curTrackballPos);
rotationAxis = glm::normalize(rotationAxis);
glm::quat quaternion = glm::angleAxis(rotationAngle, rotationAxis);
// -----------------------------------------------------------------
// orbit(quaternion);
// camera_->setRotation(quaternion);
// camera_->compileViewRotationMatrix();
psc nodePos = node_->getWorldPosition();
psc camPos = camera_->getPosition();
glm::mat4 transMatrix = glm::translate(glm::mat4(1.0), nodePos.getVec3f()-camPos.getVec3f());
glm::mat4 transBackMatrix = glm::translate(glm::mat4(1.0), camPos.getVec3f()-nodePos.getVec3f());
glm::vec4 translated = transMatrix*glm::vec4(camPos.getVec3f(), 1.0);
glm::vec4 postRot = glm::rotate(quaternion, translated);
glm::vec4 newCamPos = transBackMatrix*glm::vec4(postRot.x, postRot.y, postRot.z, 1.0);
camera_->setPosition(psc::CreatePSC(newCamPos.x, newCamPos.y, newCamPos.z));
camera_->rotate(glm::inverse(quaternion));
camera_->compileViewRotationMatrix();
// node_->calculateBoundingSphere();
// glm::vec3 camPos = *sgct::Engine::instance()->getUserPtr()->getPosPtr();
// sgct::Engine::instance()->getUserPtr()->setOrientation(quaternion.w, quaternion.x, quaternion.y, quaternion.z);
// sgct::Engine::instance()->getUserPtr()->setPos(glm::rotate(quaternion, camPos));
_lastTrackballPos = curTrackballPos;
}
}
void InteractionHandler::keyboardCallback(int key, int action) {
@@ -324,14 +382,18 @@ void InteractionHandler::mouseButtonCallback(int key, int action) {
//if(mouseControl_ != nullptr) {
// mouseControl_->mouseButtonCallback(key,action);
//}
if (key == GLFW_MOUSE_BUTTON_LEFT && action == GLFW_PRESS)
_leftMouseButtonDown = true;
else if (key == GLFW_MOUSE_BUTTON_LEFT && action == GLFW_RELEASE) {
_leftMouseButtonDown = false;
_isMouseBeingPressedAndHeld = false;
}
}
void InteractionHandler::mousePositionCallback(int x, int y) {
float width = sgct::Engine::instance()->getActiveXResolution();
float height = sgct::Engine::instance()->getActiveYResolution();
glm::vec2 mousePos = glm::vec2(((float)x/width)-0.5, ((float)y/height)-0.5);
glm::vec3 trackballPos = mapToTrackball(mousePos);
LDEBUG(mousePos.x << ", " << mousePos.y << " = " << trackballPos.x << ", " << trackballPos.y << ", " << trackballPos.z);
if (_leftMouseButtonDown)
trackballRotate(x,y);
//if(mouseControl_ != nullptr) {
// mouseControl_->mousePosCallback(x,y);
//}
+3 -3
View File
@@ -115,8 +115,8 @@ void RenderablePlanet::render(const Camera *camera, const psc &thisPosition) {
// scale the planet to appropriate size since the planet is a unit sphere
glm::mat4 transform = glm::mat4(1);
transform = glm::rotate(transform, 4.1f*static_cast<float>(sgct::Engine::instance()->getTime()), glm::vec3(0.0f, 1.0f, 0.0f));
// transform = glm::rotate(transform, 4.1f*static_cast<float>(sgct::Engine::instance()->getTime()), glm::vec3(0.0f, 1.0f, 0.0f));
// setup the data to the shader
programObject_->setUniform("ViewProjection", camera->getViewProjectionMatrix());
programObject_->setUniform("ModelTransform", transform);
@@ -142,4 +142,4 @@ void RenderablePlanet::update() {
}
} // namespace openspace
} // namespace openspace
+7 -3
View File
@@ -281,7 +281,6 @@ bool RenderableVolumeExpert::initialize() {
local_y /= 2;
}
_ws = new ghoul::opencl::CLWorkSize({dimensions[0],dimensions[1]}, {local_x,local_y});
return true;
}
@@ -299,10 +298,15 @@ void RenderableVolumeExpert::render(const Camera *camera, const psc &thisPositio
float speed = 50.0f;
float time = sgct::Engine::getTime();
glm::mat4 transform = camera->getViewProjectionMatrix();
glm::mat4 camTransform = camera->getViewRotationMatrix();
psc camPos = camera->getPosition();
double factor = pow(10.0,thisPosition[3]);
transform = glm::translate(transform, glm::vec3(thisPosition[0]*factor, thisPosition[1]*factor, thisPosition[2]*factor));
transform = glm::rotate(transform, time*speed, glm::vec3(0.0f, 1.0f, 0.0f));
transform = transform*camTransform;
// transform = glm::rotate(transform, speed*camera->getRotationAngle(), camera->getRotationAxis());
// transform = glm::rotate(transform, time*speed, glm::vec3(0.0f, 1.0f, 0.0f));
_colorBoxRenderer->render(transform);
@@ -330,7 +334,7 @@ void RenderableVolumeExpert::render(const Camera *camera, const psc &thisPositio
_quadProgram->activate();
glActiveTexture(GL_TEXTURE0);
_output->bind();
glClearColor(0.0f, 0.0f, 0.0f, 0);
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBindVertexArray(_screenQuad);
glDrawArrays(GL_TRIANGLES, 0, 6);