Compare commits

..

2 commits

Author SHA1 Message Date
8051f4203f Allow the camera to follow the ball
But when the ground is not textured, this looks just as if the ball was
not moving… :(
2018-02-14 13:23:27 +01:00
baaa5e4057 Control pause and speed with keyboard
Keys: space for toggle pause, < and > for speed control, 0 to reset
speed
2018-02-14 13:22:31 +01:00
5 changed files with 77 additions and 6 deletions

View file

@ -52,8 +52,10 @@ int main(int argc, char** argv) {
ground_mesh.get_mesh()->set_color(Color(0.13, 0.82, 0.21)); ground_mesh.get_mesh()->set_color(Color(0.13, 0.82, 0.21));
render.add_mesh(ground_mesh.get_mesh()); render.add_mesh(ground_mesh.get_mesh());
} }
//render.follow_implicit_position(ball.get_surface());
render.set_idle_func(periodic_update); render.set_idle_func(periodic_update);
render.add_kb_handler(periodic_kb_handler);
init_periodic_static(&ball); init_periodic_static(&ball);
render.run(); render.run();

View file

@ -8,6 +8,9 @@ static Ball* _ball = nullptr;
static std::chrono::time_point<std::chrono::steady_clock> static std::chrono::time_point<std::chrono::steady_clock>
_last_time, _init_clocks; _last_time, _init_clocks;
static bool is_paused = false;
static double speed_factor = 1.;
void init_periodic_static(Ball* ball) { void init_periodic_static(Ball* ball) {
_last_time = std::chrono::steady_clock::now(); _last_time = std::chrono::steady_clock::now();
_init_clocks = std::chrono::steady_clock::now(); _init_clocks = std::chrono::steady_clock::now();
@ -23,9 +26,32 @@ double ellapsed_double(
} }
void periodic_update() { void periodic_update() {
if(is_paused)
return;
printf("%lf\n", speed_factor);
auto now = std::chrono::steady_clock::now(); auto now = std::chrono::steady_clock::now();
_ball->update_pos(ellapsed_double(_last_time, now)); _ball->update_pos(speed_factor * ellapsed_double(_last_time, now));
_last_time = now; _last_time = now;
glutPostRedisplay(); glutPostRedisplay();
} }
void periodic_kb_handler(unsigned char key, int, int) {
if(key == ' ') {
if(is_paused)
_last_time = std::chrono::steady_clock::now();
is_paused = !is_paused;
}
else if(key == '<') {
speed_factor -= .1;
if(speed_factor <= 0.05)
speed_factor = .1;
}
else if(key == '>') {
speed_factor += .1;
}
else if(key == '0') {
speed_factor = 1.;
}
}

View file

@ -4,3 +4,5 @@
void init_periodic_static(Ball* ball); void init_periodic_static(Ball* ball);
void periodic_update(); void periodic_update();
void periodic_kb_handler(unsigned char key, int, int);

View file

@ -12,7 +12,7 @@ GlutRender& GlutRender::get_instance() {
return instance; return instance;
} }
GlutRender::GlutRender() { GlutRender::GlutRender() : followed_implicit(nullptr) {
std::default_random_engine rand_engine(time(NULL)); std::default_random_engine rand_engine(time(NULL));
std::uniform_real_distribution<double> distribution; std::uniform_real_distribution<double> distribution;
rand_color = std::bind(distribution, rand_engine); rand_color = std::bind(distribution, rand_engine);
@ -29,6 +29,7 @@ void GlutRender::init(int* argc, char** argv,
// ==== Callbacks ==== // ==== Callbacks ====
glutDisplayFunc(display_handle); glutDisplayFunc(display_handle);
glutReshapeFunc(reshape_handle); glutReshapeFunc(reshape_handle);
glutKeyboardFunc(kb_evt_handle);
// ==== Lighting ==== // ==== Lighting ====
GLfloat light0_pos[] = {30., 35., 20., 0.}; GLfloat light0_pos[] = {30., 35., 20., 0.};
@ -92,6 +93,14 @@ void GlutRender::set_idle_func(void (*func)(void)) {
glutIdleFunc(func); glutIdleFunc(func);
} }
void GlutRender::add_kb_handler(GlutRender::kb_handler_t handler) {
kb_handlers.push_back(handler);
}
void GlutRender::follow_implicit_position(const ImplicitSurface* surf) {
followed_implicit = surf;
}
void GlutRender::reshape(int wid, int hei) { void GlutRender::reshape(int wid, int hei) {
if (hei == 0) if (hei == 0)
hei = 1; hei = 1;
@ -182,10 +191,19 @@ void GlutRender::display() {
// Camera position and orientation // Camera position and orientation
glLoadIdentity(); glLoadIdentity();
//glTranslatef(1., 2., -10.);
gluLookAt(0, 2.5, -10, Point look_from(0, 2.5, -10);
if(followed_implicit != nullptr) {
const Point& look_at = followed_implicit->getCenter();
gluLookAt(look_from.x, look_from.y, look_from.z,
look_at.x, look_from.y, look_at.z,
0, 1, 0);
}
else {
gluLookAt(look_from.x, look_from.y, look_from.z,
0, 2.5, 0, 0, 2.5, 0,
0, 1, 0); 0, 1, 0);
}
for(Mesh* mesh: meshes) { for(Mesh* mesh: meshes) {
display_mesh(*mesh); display_mesh(*mesh);
@ -202,9 +220,18 @@ void GlutRender::display() {
glutSwapBuffers(); glutSwapBuffers();
} }
void GlutRender::on_kb_evt(unsigned char key, int x, int y) {
for(auto& handler: kb_handlers) {
handler(key, x, y);
}
}
void GlutRender::reshape_handle(int wid, int hei) { void GlutRender::reshape_handle(int wid, int hei) {
get_instance().reshape(wid, hei); get_instance().reshape(wid, hei);
} }
void GlutRender::display_handle() { void GlutRender::display_handle() {
get_instance().display(); get_instance().display();
} }
void GlutRender::kb_evt_handle(unsigned char key, int x, int y) {
get_instance().on_kb_evt(key, x, y);
}

View file

@ -5,9 +5,12 @@
#include "../Mesh.hpp" #include "../Mesh.hpp"
#include "../Implicit.hpp" #include "../Implicit.hpp"
#include <set> #include <set>
#include <functional>
class GlutRender { class GlutRender {
public: public:
typedef std::function<void(unsigned char, int, int)> kb_handler_t;
static GlutRender& get_instance(); static GlutRender& get_instance();
GlutRender(GlutRender const&) = delete; GlutRender(GlutRender const&) = delete;
@ -25,6 +28,10 @@ class GlutRender {
void set_idle_func(void (*func)(void)); void set_idle_func(void (*func)(void));
void add_kb_handler(kb_handler_t handler);
void follow_implicit_position(const ImplicitSurface* surf);
private: private:
struct SurfaceDetails { struct SurfaceDetails {
SurfaceDetails(ImplicitSurface* surf, const Cuboid& box, SurfaceDetails(ImplicitSurface* surf, const Cuboid& box,
@ -49,13 +56,20 @@ class GlutRender {
protected: protected:
void reshape(int wid, int hei); void reshape(int wid, int hei);
void display(); void display();
void on_kb_evt(unsigned char key, int x, int y);
static void reshape_handle(int wid, int hei); static void reshape_handle(int wid, int hei);
static void display_handle(); static void display_handle();
static void kb_evt_handle(unsigned char key, int x, int y);
private: //attr private: //attr
std::function<double()> rand_color; std::function<double()> rand_color;
std::set<Mesh*> meshes; std::set<Mesh*> meshes;
std::set<SurfaceDetails> surfaces; std::set<SurfaceDetails> surfaces;
std::vector<kb_handler_t> kb_handlers;
const ImplicitSurface* followed_implicit;
}; };