Files

204 lines
5.8 KiB
C++
Raw Permalink Normal View History

#define GLM_ENABLE_EXPERIMENTAL
#include "../../../headers/GL_STUFF/SCENE/Camera.hpp"
/* REPLACED
#include <GL/freeglut.h>
*/
extern "C" {
#include <glut.h>
}
#include <glm/gtc/matrix_transform.hpp>
#include <string>
#include <iostream>
#include <glm/gtx/transform.hpp>
#include <glm/gtx/norm.hpp>
/* don't know how it worked before */
#include <glm/gtx/quaternion.hpp>
/* aarch64-linux-gnu/include/math.h already defines it */
#ifndef M_PI
#define M_PI 3.14159265358979323846264338327950288
#endif
using namespace glm;
Camera::Camera() {
this->cameraPos = vec3();
this->cameraFront = vec3(0.0f, 0.0f, -1.0f);
this->cameraUp = vec3(0.0f, 1.0f, 0.0f);
}
Camera::Camera(vec3 position, vec3 front, vec3 up) {
if (! glm::length(front))
throw std::invalid_argument("Camera : front vector has no length");
if (! glm::length(up))
throw std::invalid_argument("Camera : up vector has no length");
this->cameraPos = position;
this->cameraFront = front;
this->cameraUp = up;
}
glm::mat4 Camera::getViewMat() {
return lookAt(cameraPos, cameraPos + cameraFront, cameraUp);
}
glm::vec3 Camera::getPosition() {
return cameraPos;
}
void Camera::setPosition(glm::vec3 pos) {
cameraPos = pos;
}
void Camera::alignTo(glm::vec3 direction) {
glm::vec3 localZ;
direction = glm::normalize(direction);
localZ = cameraFront;
glm::quat a = glm::rotation(localZ, direction);
cameraFront = glm::toMat4(a) * glm::vec4(cameraFront, 0.0f);
cameraUp = glm::toMat4(a) * glm::vec4(cameraUp, 0.0f); //temp
// ++++++++++++++++++++++++++ //
glm::vec3 right = glm::normalize(cross(cameraFront, cameraUp));
right.y = 0;
glm::vec3 stabilizedR = glm::normalize(right);
cameraUp = glm::cross(stabilizedR, cameraFront);
}
CameraController::CameraController(Camera *cam) {
lastX = 0;
lastY = 0;
windowHeight = 0;
windowWidth = 0;
windowTop = 0;
windowLeft = 0;
this->camera = cam;
}
Camera* CameraController::getCamera() {
return camera;
}
void CameraController::setWindowData(int left, int width, int top, int height) {
windowLeft = left;
windowWidth = width;
windowTop = top;
windowHeight = height;
lastX = left + width / 2;
lastY = top + height / 2;
}
void CameraController::mouseMotion(int cursorX, int cursorY) {
//return;
float alfa = 0.05; //serve ridimensionare l'offset tra due posizioni successive del mouse
//il mouse è appena entrato nella finestra
if (mouseUnlocked)
{
lastX = windowLeft + windowWidth / 2;
lastY = windowTop + windowHeight / 2;
mouseUnlocked = false;
}
//di quanto ci siamo mossi
float xoffset = (cursorX - lastX);
float yoffset = (lastY - cursorY);
glutWarpPointer(windowLeft + windowWidth / 2, windowTop + windowHeight / 2);
lastX = windowLeft + windowWidth / 2;
lastY = windowTop + windowHeight / 2;
xoffset *= alfa;
yoffset *= alfa;
PHI += yoffset;
THETA += xoffset;
//if (PHI >= 179.0)
// PHI = 179;
vec3 direction;
direction.x = cos(radians(PHI)) * cos(radians(THETA));
direction.y = sin(radians(PHI));
direction.z = cos(radians(PHI)) * sin(radians(THETA));
getCamera()->cameraFront = normalize(direction);
}
void CameraController::keyPress(unsigned char key) {
Camera *c = getCamera();
vec3 dir;
switch (key)
{
case 'a':
//Calcolo la direzione perpendicolare alla direzione della camera e l'alto della camera
dir = normalize(cross(getCamera()->cameraFront, getCamera()->cameraUp));
//Mi sposto a sinistra lungo la direzione perpendicolare alla direzione della camera e l'alto della camera
c->cameraPos = c->cameraPos - dir * cameraSpeed;
break;
case 'A':
//Calcolo la direzione perpendicolare alla direzione della camera e l'alto della camera
dir = normalize(cross(c->cameraFront, c->cameraUp));
//Mi sposto a sinistra lungo la direzione perpendicolare alla direzione della camera e l'alto della camera
c->cameraPos = c->cameraPos - dir * (cameraSpeed * 10);
break;
case 'd':
//Calcolo la irezione perpendicolare alla direzione della camera e l'alto della camera
dir = normalize(cross(c->cameraFront, c->cameraUp));//Mi sposto a destra lungo la direzione perpendicolare alla direzione della camera e l'alto della camera
c->cameraPos = c->cameraPos + dir * cameraSpeed;
break;
case 'D':
//Calcolo la irezione perpendicolare alla direzione della camera e l'alto della camera
dir = normalize(cross(c->cameraFront, c->cameraUp));//Mi sposto a destra lungo la direzione perpendicolare alla direzione della camera e l'alto della camera
c->cameraPos = c->cameraPos + dir * (cameraSpeed * 10);
break;
case 's':
//Mi sposto indietro lungo la direzione della camera
c->cameraPos = c->cameraPos - cameraSpeed * c->cameraFront;
break;
case 'S':
//Mi sposto indietro lungo la direzione della camera
c->cameraPos = c->cameraPos - (cameraSpeed * 10) * c->cameraFront;
break;
case 'w':
//Mi sposto avanti lungo la direzione perpendicolare alla direzione della camera e l'alto della camera
c->cameraPos = c->cameraPos + cameraSpeed * c->cameraFront;
break;
case 'W':
//Mi sposto avanti lungo la direzione perpendicolare alla direzione della camera e l'alto della camera
c->cameraPos = c->cameraPos + (cameraSpeed * 10) * c->cameraFront;
break;
case 'r':
//Mi sposto avanti lungo la direzione perpendicolare alla direzione della camera e l'alto della camera
c->cameraPos = c->cameraPos + cameraSpeed * c->cameraUp;
break;
case 'R':
//Mi sposto avanti lungo la direzione perpendicolare alla direzione della camera e l'alto della camera
c->cameraPos = c->cameraPos + (cameraSpeed * 10) * c->cameraUp;
break;
case 'f':
//Mi sposto avanti lungo la direzione perpendicolare alla direzione della camera e l'alto della camera
c->cameraPos = c->cameraPos - cameraSpeed * c->cameraUp;
break;
case 'F':
//Mi sposto avanti lungo la direzione perpendicolare alla direzione della camera e l'alto della camera
c->cameraPos = c->cameraPos - (cameraSpeed * 10) * c->cameraUp;
break;
default:
break;
}
}