This repository has been archived on 2019-09-17. You can view files and clone it, but cannot push or open issues or pull requests.
Files
research-project/src/fmri/camera.cpp

135 lines
2.6 KiB
C++

#include <GL/freeglut.h>
#include <cmath>
#include <sstream>
#include <iostream>
#include "camera.hpp"
#include "utils.hpp"
using namespace fmri;
using namespace std;
static Camera& camera = Camera::instance();
static void handleMouseMove(int x, int y)
{
const float width = glutGet(GLUT_WINDOW_WIDTH) / 2;
const float height = glutGet(GLUT_WINDOW_HEIGHT) / 2;
camera.angle[0] = (x - width) / width * 180;
camera.angle[1] = (y - height) / height * 90;
glutPostRedisplay();
}
static float getFPS()
{
static int frames = 0;
static float fps = 0;
static auto timeBase = glutGet(GLUT_ELAPSED_TIME);
++frames;
const auto time = glutGet(GLUT_ELAPSED_TIME);
if (time - timeBase > 2000) {
fps = frames * 1000.0f / (time - timeBase);
frames = 0;
timeBase = time;
}
return fps;
}
static void move(unsigned char key)
{
float speed = 0.5;
float dir[3];
const auto yaw = deg2rad(camera.angle[0]);
const auto pitch = deg2rad(camera.angle[1]);
if (key == 'w' || key == 's') {
dir[0] = sin(yaw) * cos(pitch);
dir[1] = -sin(pitch);
dir[2] = -cos(yaw) * cos(pitch);
} else {
dir[0] = -cos(yaw);
dir[1] = 0;
dir[2] = -sin(yaw);
}
if (key == 's' || key == 'd') {
speed *= -1;
}
for (auto i = 0; i < 3; ++i) {
camera.pos[i] += speed * dir[i];
}
}
static void handleKeys(unsigned char key, int, int)
{
switch (key) {
case 'w':
case 'a':
case 's':
case 'd':
move(key);
break;
case 'q':
// Utility quit function.
glutLeaveMainLoop();
break;
case 'h':
camera.reset();
break;
default:
// Do nothing.
break;
}
glutPostRedisplay();
}
std::string Camera::infoLine()
{
stringstream buffer;
buffer << "Pos(x,y,z) = (" << pos[0] << ", " << pos[1] << ", " << pos[2] << ")\n";
buffer << "Angle(p,y) = (" << angle[0] << ", " << angle[1] << ")\n";
buffer << "FPS = " << getFPS() << "\n";
return buffer.str();
}
void Camera::reset()
{
pos[0] = 0;
pos[1] = 0;
pos[2] = 3;
angle[0] = 0;
angle[1] = 0;
}
void Camera::configureRenderingContext()
{
glLoadIdentity();
glRotatef(angle[1], 1, 0, 0);
glRotatef(angle[0], 0, 1, 0);
glTranslatef(-pos[0], -pos[1], -pos[2]);
}
Camera &Camera::instance()
{
static Camera camera;
return camera;
}
void Camera::registerControls()
{
reset();
glutPassiveMotionFunc(handleMouseMove);
glutKeyboardFunc(handleKeys);
}