Compare commits
No commits in common. "master" and "better_bouncing" have entirely different histories.
master
...
better_bou
11
Ball.cpp
11
Ball.cpp
|
@ -63,18 +63,12 @@ void Ball::_compute_U_n() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void Ball::_compute_v_x(Point normal) {
|
void Ball::_compute_v_x(Point normal) {
|
||||||
double factor = 0;
|
double factor = normal.x / (4*(normal.x + normal.z));
|
||||||
if (normal.x + normal.z != 0) {
|
|
||||||
factor = normal.x / (4*(normal.x + normal.z));
|
|
||||||
}
|
|
||||||
v_x *= (0.5 + factor);
|
v_x *= (0.5 + factor);
|
||||||
}
|
}
|
||||||
|
|
||||||
void Ball::_compute_v_z(Point normal) {
|
void Ball::_compute_v_z(Point normal) {
|
||||||
double factor = 0;
|
double factor = normal.z / (4*(normal.x + normal.z));
|
||||||
if (normal.x + normal.z != 0) {
|
|
||||||
factor = normal.z / (4*(normal.x + normal.z));
|
|
||||||
}
|
|
||||||
v_z *= (0.5 + factor);
|
v_z *= (0.5 + factor);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,6 +82,7 @@ void Ball::_compute_parameters() {
|
||||||
_compute_v_x(normal);
|
_compute_v_x(normal);
|
||||||
_compute_v_z(normal);
|
_compute_v_z(normal);
|
||||||
min_height = fmin(radius, min_height + 0.2 * (radius - min_height));
|
min_height = fmin(radius, min_height + 0.2 * (radius - min_height));
|
||||||
|
std::cout << "U:" << U << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
void Ball::update_pos(double dt) {
|
void Ball::update_pos(double dt) {
|
||||||
|
|
|
@ -1,45 +0,0 @@
|
||||||
#include "GroundFlatMesh.hpp"
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
const int GroundFlatMesh::MIN_I = -40;
|
|
||||||
const int GroundFlatMesh::MAX_I = 100;
|
|
||||||
const int GroundFlatMesh::MIN_J = -40;
|
|
||||||
const int GroundFlatMesh::MAX_J = 100;
|
|
||||||
|
|
||||||
GroundFlatMesh::GroundFlatMesh(const Point& center, double decay_speed)
|
|
||||||
: center(center), decay_speed(decay_speed)
|
|
||||||
{
|
|
||||||
std::vector<std::vector<size_t> > vertice_at(MAX_I - MIN_I + 1,
|
|
||||||
std::vector<size_t>(MAX_J - MIN_J + 1));
|
|
||||||
|
|
||||||
for(int i=MIN_I; i < MAX_I + 1; ++i) {
|
|
||||||
for(int j=MIN_J; j < MAX_J + 1; ++j) {
|
|
||||||
vertice_at[i - MIN_I][j - MIN_J] =
|
|
||||||
output.add_vertice(
|
|
||||||
tile_position(i, j),
|
|
||||||
Point(0., 1., 0.));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for(int i=MIN_I; i < MAX_I; ++i) {
|
|
||||||
for(int j=MIN_J; j < MAX_J; ++j) {
|
|
||||||
output.add_face(Face(
|
|
||||||
vertice_at[i - MIN_I][j - MIN_J],
|
|
||||||
vertice_at[i - MIN_I][j + 1 - MIN_J],
|
|
||||||
vertice_at[i + 1 - MIN_I][j + 1 - MIN_J]));
|
|
||||||
output.add_face(Face(
|
|
||||||
vertice_at[i - MIN_I][j - MIN_J],
|
|
||||||
vertice_at[i + 1 - MIN_I][j + 1 - MIN_J],
|
|
||||||
vertice_at[i + 1- MIN_I][j - MIN_J]));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
double GroundFlatMesh::ith_dist(int i) const {
|
|
||||||
return ((i < 0) ? -1 : 1) * decay_speed * i * i;
|
|
||||||
}
|
|
||||||
|
|
||||||
Point GroundFlatMesh::tile_position(int i, int j) const {
|
|
||||||
return Point(ith_dist(i), 0., ith_dist(j));
|
|
||||||
}
|
|
|
@ -1,20 +0,0 @@
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include "Mesh.hpp"
|
|
||||||
|
|
||||||
class GroundFlatMesh {
|
|
||||||
public:
|
|
||||||
GroundFlatMesh(const Point& center, double decay_speed);
|
|
||||||
|
|
||||||
Mesh* get_mesh() { return &output; }
|
|
||||||
|
|
||||||
private: //meth
|
|
||||||
double ith_dist(int i) const;
|
|
||||||
Point tile_position(int i, int j) const;
|
|
||||||
|
|
||||||
private:
|
|
||||||
static const int MIN_I, MAX_I, MIN_J, MAX_J;
|
|
||||||
Mesh output;
|
|
||||||
const Point& center;
|
|
||||||
double decay_speed;
|
|
||||||
};
|
|
|
@ -8,16 +8,11 @@ class ImplicitSurface {
|
||||||
double operator()(const Point& pt) const;
|
double operator()(const Point& pt) const;
|
||||||
Point getCenter() const { return center;}
|
Point getCenter() const { return center;}
|
||||||
|
|
||||||
const Color& get_color() const { return color; }
|
|
||||||
void set_color(const Color& _color) { color = _color; }
|
|
||||||
|
|
||||||
virtual Point location_hint() const = 0;
|
virtual Point location_hint() const = 0;
|
||||||
|
|
||||||
/// Compute the normal vector to the isosurface at `pt`
|
/// Compute the normal vector to the isosurface at `pt`
|
||||||
Point normal_at(const Point& pt) const;
|
Point normal_at(const Point& pt) const;
|
||||||
protected:
|
protected:
|
||||||
Point center;
|
Point center;
|
||||||
Color color;
|
|
||||||
|
|
||||||
ImplicitSurface(Point _center) : center(_center) {}
|
ImplicitSurface(Point _center) : center(_center) {}
|
||||||
};
|
};
|
||||||
|
|
1
Makefile
1
Makefile
|
@ -19,7 +19,6 @@ OBJS=Implicit.o \
|
||||||
MarchingCubes.o \
|
MarchingCubes.o \
|
||||||
_gen/marching_cubes_data.o \
|
_gen/marching_cubes_data.o \
|
||||||
periodic_updates.o \
|
periodic_updates.o \
|
||||||
GroundFlatMesh.o \
|
|
||||||
tests/TestImplicitSphere.o \
|
tests/TestImplicitSphere.o \
|
||||||
render/GlutRender.o
|
render/GlutRender.o
|
||||||
|
|
||||||
|
|
|
@ -24,8 +24,6 @@ MarchingCubes& MarchingCubes::add_hint(const Point& hint) {
|
||||||
Mesh MarchingCubes::operator()() {
|
Mesh MarchingCubes::operator()() {
|
||||||
Mesh output;
|
Mesh output;
|
||||||
|
|
||||||
output.set_color(surface.get_color());
|
|
||||||
|
|
||||||
perf_counter = 0;
|
perf_counter = 0;
|
||||||
|
|
||||||
if(hints.empty())
|
if(hints.empty())
|
||||||
|
@ -33,9 +31,7 @@ Mesh MarchingCubes::operator()() {
|
||||||
else
|
else
|
||||||
with_hints(output);
|
with_hints(output);
|
||||||
|
|
||||||
#ifdef MC_SHOW_PERF
|
printf("Explored cubes: %ld\n", perf_counter);
|
||||||
fprintf(stderr, "Explored cubes: %ld\n", perf_counter);
|
|
||||||
#endif // MC_SHOW_PERF
|
|
||||||
|
|
||||||
output.translate(surface.getCenter());
|
output.translate(surface.getCenter());
|
||||||
|
|
||||||
|
|
4
Mesh.hpp
4
Mesh.hpp
|
@ -41,9 +41,6 @@ class Mesh {
|
||||||
/// Gets the various faces
|
/// Gets the various faces
|
||||||
const std::vector<Face>& get_faces() const;
|
const std::vector<Face>& get_faces() const;
|
||||||
|
|
||||||
const Color& get_color() const { return color; }
|
|
||||||
void set_color(const Color& _color) { color = _color; }
|
|
||||||
|
|
||||||
private: //struct
|
private: //struct
|
||||||
struct NormalVect {
|
struct NormalVect {
|
||||||
NormalVect(const Point& vect, bool manual=false)
|
NormalVect(const Point& vect, bool manual=false)
|
||||||
|
@ -66,5 +63,4 @@ class Mesh {
|
||||||
std::vector<std::vector<size_t> > faces_with_vert;
|
std::vector<std::vector<size_t> > faces_with_vert;
|
||||||
|
|
||||||
Point center;
|
Point center;
|
||||||
Color color;
|
|
||||||
};
|
};
|
||||||
|
|
40
README.md
40
README.md
|
@ -1,40 +1,4 @@
|
||||||
# mpri-graphics-project
|
# mpri-graphics-project
|
||||||
|
|
||||||
|
Un repo pour le projet de graphics du MPRI. On va faire rebondir des trucs. Ça
|
||||||
A repository for the MPRI's Computer Graphics and Visualization course project.
|
va être distrayant. On va vraiment s'amuser. Et valider un cours. Peut-être.
|
||||||
A jelly-like ball bounces around.
|
|
||||||
|
|
||||||
[Course page](https://wikimpri.dptinfo.ens-cachan.fr/doku.php?id=cours:c-2-39)
|
|
||||||
|
|
|
||||||
[Slides](https://tobast.fr/m2/graphics/jelly.pdf)
|
|
||||||
|
|
||||||
## Compiling
|
|
||||||
|
|
||||||
The basic compilation is achieved by a simple `make`.
|
|
||||||
|
|
||||||
You can add additional compilation flags with `ADD_FLAGS="..." make`.
|
|
||||||
|
|
||||||
The produced binary is `./bounce.bin`
|
|
||||||
|
|
||||||
## Compilation flags
|
|
||||||
|
|
||||||
* `-DDEBUG_DISPLAY_WIREFRAME`: display the wireframe of meshes
|
|
||||||
* `-DDEBUG_DISPLAY_NORMAL`: display the computed normal vectors for each
|
|
||||||
vertice
|
|
||||||
* `-DMC_SHOW_PERF`: display Marching Cubes performance stats
|
|
||||||
|
|
||||||
## Run flags
|
|
||||||
|
|
||||||
* `-perlin`: replace flat ground by perlin noise
|
|
||||||
* `-qwerty`, `-azerty`: change the used keymap
|
|
||||||
|
|
||||||
For instance, `./bounce.bin -perlin -qwerty` will use perlin floor and a qwerty
|
|
||||||
keymap.
|
|
||||||
|
|
||||||
## In-app commands
|
|
||||||
|
|
||||||
* space: play/pause
|
|
||||||
* <, >: slow down/speed up animation
|
|
||||||
* 0: reset to default speed
|
|
||||||
* w, a, s, d (z, q, s, d in azerty): move camera
|
|
||||||
* q, e (a, e in azerty): rotate camera around y axis
|
|
||||||
|
|
|
@ -152,20 +152,6 @@ class Cuboid {
|
||||||
Point lowBound, highBound;
|
Point lowBound, highBound;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Color {
|
|
||||||
Color() : r(0), g(0), b(0) {}
|
|
||||||
Color(double r, double g, double b) : r(r), g(g), b(b) {}
|
|
||||||
double r, g, b;
|
|
||||||
double operator[](int i) const {
|
|
||||||
switch(i % 3) {
|
|
||||||
case 0: return r;
|
|
||||||
case 1: return g;
|
|
||||||
case 2: return b;
|
|
||||||
}
|
|
||||||
return 0; // won't happen
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
namespace std {
|
namespace std {
|
||||||
template<> struct hash<Face>
|
template<> struct hash<Face>
|
||||||
{
|
{
|
||||||
|
|
|
@ -2,66 +2,31 @@
|
||||||
* bouncing implicit-surface defined sphere.
|
* bouncing implicit-surface defined sphere.
|
||||||
**/
|
**/
|
||||||
|
|
||||||
#include <cstring>
|
|
||||||
|
|
||||||
#include "render/GlutRender.hpp"
|
#include "render/GlutRender.hpp"
|
||||||
#include "Ball.hpp"
|
#include "Ball.hpp"
|
||||||
#include "FlatGround.hpp"
|
#include "FlatGround.hpp"
|
||||||
#include "MarchingCubes.hpp"
|
#include "MarchingCubes.hpp"
|
||||||
#include "GroundFlatMesh.hpp"
|
|
||||||
|
|
||||||
#include "periodic_updates.hpp"
|
#include "periodic_updates.hpp"
|
||||||
|
|
||||||
int main(int argc, char** argv) {
|
int main(int argc, char** argv) {
|
||||||
bool perlin = false;
|
|
||||||
for(int pos=1; pos < argc; ++pos) {
|
|
||||||
if(strcmp(argv[pos], "-perlin") == 0)
|
|
||||||
perlin = true;
|
|
||||||
if(strcmp(argv[pos], "-azerty") == 0)
|
|
||||||
set_key_mapping(KeyMappings::azerty());
|
|
||||||
if(strcmp(argv[pos], "-qwerty") == 0)
|
|
||||||
set_key_mapping(KeyMappings::qwerty());
|
|
||||||
}
|
|
||||||
|
|
||||||
// Last minute switch, this code is ugly, please close your eyes until
|
|
||||||
// stated otherwise.
|
|
||||||
PerlinGround perlin_ground;
|
|
||||||
FlatGround flat_ground;
|
|
||||||
GroundFlatMesh ground_mesh(Point(0., 0., 0.), 0.05);
|
|
||||||
Ground* ball_ground = nullptr;
|
|
||||||
if(perlin)
|
|
||||||
ball_ground = &perlin_ground;
|
|
||||||
else
|
|
||||||
ball_ground = &flat_ground;
|
|
||||||
// You can open your eyes, now.
|
|
||||||
|
|
||||||
|
PerlinGround* flat = new PerlinGround();
|
||||||
GlutRender& render = GlutRender::get_instance();
|
GlutRender& render = GlutRender::get_instance();
|
||||||
render.init(&argc, argv, 640, 480, "Bouncing stuff");
|
render.init(&argc, argv, 640, 480, "Bouncing stuff");
|
||||||
|
|
||||||
Ball ball(Point(0, 5, 0), ball_ground, 0.55, -.5, -.7, 1, 1);
|
Ball ball(Point(0, 5, 0), flat, 0.75, -0.5, -0.7, 1, 1);
|
||||||
ball.get_surface()->set_color(Color(1., 0., 0.));
|
|
||||||
|
|
||||||
Cuboid bbox = ball.get_surface()->max_bounding_box();
|
Cuboid bbox = ball.get_surface()->max_bounding_box();
|
||||||
Cuboid bbox_2(Point(-20, -3, -20), Point(20,3,20));
|
Cuboid bbox_2(Point(-2, -1, -2), Point(2,1,2));
|
||||||
printf("%.2lf %.2lf %.2lf | %.2lf %.2lf %.2lf\n",
|
printf("%.2lf %.2lf %.2lf | %.2lf %.2lf %.2lf\n",
|
||||||
bbox.low(0), bbox.low(1), bbox.low(2),
|
bbox.low(0), bbox.low(1), bbox.low(2),
|
||||||
bbox.high(0), bbox.high(1), bbox.high(2));
|
bbox.high(0), bbox.high(1), bbox.high(2));
|
||||||
render.add_surface(ball.get_surface(), bbox);
|
render.add_surface(ball.get_surface(), bbox);
|
||||||
|
render.add_surface(flat->get_surface(), bbox_2);
|
||||||
if(perlin) {
|
|
||||||
perlin_ground.get_surface()->set_color(Color(0.13, 0.82, 0.21));
|
|
||||||
render.add_surface(perlin_ground.get_surface(), bbox_2, false, 0.50);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
ground_mesh.get_mesh()->set_color(Color(0.13, 0.82, 0.21));
|
|
||||||
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);
|
||||||
render.add_kb_up_handler(periodic_kb_up_handler);
|
|
||||||
init_periodic_static(&ball, &render);
|
|
||||||
render.run();
|
render.run();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -1,66 +1,17 @@
|
||||||
#include "periodic_updates.hpp"
|
#include "periodic_updates.hpp"
|
||||||
|
|
||||||
#include <ctime>
|
#include <ctime>
|
||||||
#include <cmath>
|
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <GL/glut.h>
|
#include <GL/glut.h>
|
||||||
|
|
||||||
struct Movement {
|
|
||||||
Movement() :
|
|
||||||
fwd(false),
|
|
||||||
bck(false),
|
|
||||||
left(false),
|
|
||||||
right(false),
|
|
||||||
turn_l(false),
|
|
||||||
turn_r(false),
|
|
||||||
sight_angle(3.14159)
|
|
||||||
{}
|
|
||||||
|
|
||||||
bool
|
|
||||||
fwd,
|
|
||||||
bck,
|
|
||||||
left,
|
|
||||||
right,
|
|
||||||
turn_l,
|
|
||||||
turn_r;
|
|
||||||
|
|
||||||
double sight_angle;
|
|
||||||
|
|
||||||
void tick() {
|
|
||||||
sight_angle += (turn_l - turn_r) * .05;
|
|
||||||
}
|
|
||||||
|
|
||||||
Point movement() {
|
|
||||||
Point front_dir = Point(-sin(sight_angle), 0, -cos(sight_angle)),
|
|
||||||
left_dir = Point(-cos(sight_angle), 0, sin(sight_angle));
|
|
||||||
return (fwd - bck) * front_dir
|
|
||||||
+ (left - right) * left_dir;
|
|
||||||
}
|
|
||||||
Point sight() {
|
|
||||||
return Point(-sin(sight_angle), 0., -cos(sight_angle));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
static Ball* _ball = nullptr;
|
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;
|
void init_periodic_static(Ball* ball) {
|
||||||
static double speed_factor = 1.;
|
|
||||||
static KeyMappings _keymap = KeyMappings::qwerty();
|
|
||||||
static Movement _movement;
|
|
||||||
static Point _position(0., 2.5, -10.);
|
|
||||||
static GlutRender* _render = nullptr;
|
|
||||||
|
|
||||||
void init_periodic_static(Ball* ball, GlutRender* render) {
|
|
||||||
_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();
|
||||||
_ball = ball;
|
_ball = ball;
|
||||||
_render = render;
|
|
||||||
}
|
|
||||||
|
|
||||||
void set_key_mapping(const KeyMappings& mapping) {
|
|
||||||
_keymap = mapping;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
double ellapsed_double(
|
double ellapsed_double(
|
||||||
|
@ -73,52 +24,8 @@ double ellapsed_double(
|
||||||
|
|
||||||
void periodic_update() {
|
void periodic_update() {
|
||||||
auto now = std::chrono::steady_clock::now();
|
auto now = std::chrono::steady_clock::now();
|
||||||
|
_ball->update_pos(ellapsed_double(_last_time, now));
|
||||||
if(!is_paused)
|
|
||||||
_ball->update_pos(speed_factor * ellapsed_double(_last_time, now));
|
|
||||||
|
|
||||||
_movement.tick();
|
|
||||||
_position += _movement.movement();
|
|
||||||
Point look_at = _position + _movement.sight();
|
|
||||||
|
|
||||||
_render->set_camera(_position, look_at);
|
|
||||||
|
|
||||||
_last_time = now;
|
_last_time = now;
|
||||||
glutPostRedisplay();
|
glutPostRedisplay();
|
||||||
}
|
}
|
||||||
|
|
||||||
void mvt_keys_update(bool up, unsigned key) {
|
|
||||||
if(key == _keymap.mv_fwd)
|
|
||||||
_movement.fwd = !up;
|
|
||||||
else if(key == _keymap.mv_bck)
|
|
||||||
_movement.bck = !up;
|
|
||||||
else if(key == _keymap.mv_left)
|
|
||||||
_movement.left = !up;
|
|
||||||
else if(key == _keymap.mv_right)
|
|
||||||
_movement.right = !up;
|
|
||||||
else if(key == _keymap.turn_left)
|
|
||||||
_movement.turn_l = !up;
|
|
||||||
else if(key == _keymap.turn_right)
|
|
||||||
_movement.turn_r = !up;
|
|
||||||
}
|
|
||||||
|
|
||||||
void periodic_kb_handler(unsigned char key, int, int) {
|
|
||||||
if(key == ' ')
|
|
||||||
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.;
|
|
||||||
}
|
|
||||||
mvt_keys_update(false, key);
|
|
||||||
}
|
|
||||||
|
|
||||||
void periodic_kb_up_handler(unsigned char key, int, int) {
|
|
||||||
mvt_keys_update(true, key);
|
|
||||||
}
|
|
||||||
|
|
|
@ -1,45 +1,6 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include "Ball.hpp"
|
#include "Ball.hpp"
|
||||||
#include "render/GlutRender.hpp"
|
|
||||||
|
|
||||||
struct KeyMappings {
|
void init_periodic_static(Ball* ball);
|
||||||
static KeyMappings qwerty() {
|
|
||||||
return KeyMappings('w', 's', 'a', 'd', 'q', 'e');
|
|
||||||
}
|
|
||||||
static KeyMappings azerty() {
|
|
||||||
return KeyMappings('z', 's', 'q', 'd', 'a', 'e');
|
|
||||||
}
|
|
||||||
|
|
||||||
KeyMappings(
|
|
||||||
unsigned char mv_fwd,
|
|
||||||
unsigned char mv_bck,
|
|
||||||
unsigned char mv_left,
|
|
||||||
unsigned char mv_right,
|
|
||||||
unsigned char turn_left,
|
|
||||||
unsigned char turn_right)
|
|
||||||
:
|
|
||||||
mv_fwd(mv_fwd),
|
|
||||||
mv_bck(mv_bck),
|
|
||||||
mv_left(mv_left),
|
|
||||||
mv_right(mv_right),
|
|
||||||
turn_left(turn_left),
|
|
||||||
turn_right(turn_right)
|
|
||||||
{}
|
|
||||||
|
|
||||||
|
|
||||||
unsigned char
|
|
||||||
mv_fwd,
|
|
||||||
mv_bck,
|
|
||||||
mv_left,
|
|
||||||
mv_right,
|
|
||||||
turn_left,
|
|
||||||
turn_right;
|
|
||||||
};
|
|
||||||
|
|
||||||
void init_periodic_static(Ball* ball, GlutRender* render);
|
|
||||||
void set_key_mapping(const KeyMappings& mapping);
|
|
||||||
void periodic_update();
|
void periodic_update();
|
||||||
|
|
||||||
void periodic_kb_handler(unsigned char key, int, int);
|
|
||||||
void periodic_kb_up_handler(unsigned char key, int, int);
|
|
||||||
|
|
|
@ -12,18 +12,7 @@ GlutRender& GlutRender::get_instance() {
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
Mesh GlutRender::SurfaceDetails::render() const {
|
GlutRender::GlutRender() {
|
||||||
return MarchingCubes(*surface, box,
|
|
||||||
resolution)
|
|
||||||
.add_hint(surface->location_hint())
|
|
||||||
();
|
|
||||||
}
|
|
||||||
|
|
||||||
GlutRender::GlutRender()
|
|
||||||
: followed_implicit(nullptr),
|
|
||||||
camera_position(0., 2.5, -10.),
|
|
||||||
camera_sight(0, 2.5, 0)
|
|
||||||
{
|
|
||||||
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);
|
||||||
|
@ -40,14 +29,12 @@ 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);
|
|
||||||
glutKeyboardUpFunc(kb_evt_up_handle);
|
|
||||||
|
|
||||||
// ==== Lighting ====
|
// ==== Lighting ====
|
||||||
GLfloat light0_pos[] = {30., 35., 20., 0.};
|
GLfloat light0_pos[] = {10., 15., 10.};
|
||||||
GLfloat light0_ambient[] = {0., 0., 0., 1.};
|
GLfloat light0_ambient[] = {0., 0., 0., 1.};
|
||||||
GLfloat light0_diffuse[] = {1., 1., .85, 1.};
|
GLfloat light0_diffuse[] = {1., 1., .65, 1.};
|
||||||
GLfloat light0_specular[] = {5., 5., .43, 1.};
|
GLfloat light0_specular[] = {5., 5., .33, 1.};
|
||||||
glLightfv(GL_LIGHT0, GL_POSITION, light0_pos);
|
glLightfv(GL_LIGHT0, GL_POSITION, light0_pos);
|
||||||
glLightfv(GL_LIGHT0, GL_AMBIENT, light0_ambient);
|
glLightfv(GL_LIGHT0, GL_AMBIENT, light0_ambient);
|
||||||
glLightfv(GL_LIGHT0, GL_DIFFUSE, light0_diffuse);
|
glLightfv(GL_LIGHT0, GL_DIFFUSE, light0_diffuse);
|
||||||
|
@ -60,16 +47,15 @@ void GlutRender::init(int* argc, char** argv,
|
||||||
glEnable(GL_LIGHT0);
|
glEnable(GL_LIGHT0);
|
||||||
glShadeModel(GL_SMOOTH); // Enable smooth shading
|
glShadeModel(GL_SMOOTH); // Enable smooth shading
|
||||||
|
|
||||||
glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
|
|
||||||
GLfloat material_specular[] = {1., 1., 1., 1.};
|
GLfloat material_specular[] = {1., 1., 1., 1.};
|
||||||
GLfloat material_emission[] = {0., 0., 0., 1.};
|
GLfloat material_emission[] = {0., 0., 0., 1.};
|
||||||
|
glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE);
|
||||||
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, material_specular);
|
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, material_specular);
|
||||||
glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, material_emission);
|
glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, material_emission);
|
||||||
glEnable(GL_COLOR_MATERIAL);
|
glEnable(GL_COLOR_MATERIAL);
|
||||||
|
|
||||||
// ==== Misc ====
|
// ==== Misc ====
|
||||||
//glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Background color
|
glClearColor(0.0f, 0.0f, 0.0f, 1.0f); // Background color
|
||||||
glClearColor(0.15f, 0.08f, 0.5f, 1.0f); // Background color
|
|
||||||
glClearDepth(1.0f); // Set background depth to farthest
|
glClearDepth(1.0f); // Set background depth to farthest
|
||||||
glEnable(GL_DEPTH_TEST);
|
glEnable(GL_DEPTH_TEST);
|
||||||
glDepthFunc(GL_LEQUAL);
|
glDepthFunc(GL_LEQUAL);
|
||||||
|
@ -87,19 +73,12 @@ void GlutRender::remove_mesh(Mesh* mesh) {
|
||||||
meshes.erase(mesh);
|
meshes.erase(mesh);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GlutRender::add_surface(ImplicitSurface* surf, const Cuboid& box,
|
void GlutRender::add_surface(ImplicitSurface* surf, const Cuboid& box) {
|
||||||
bool always_render, double resolution)
|
surfaces.insert(SurfaceDetails(surf, box));
|
||||||
{
|
|
||||||
surfaces.push_back(SurfaceDetails(surf, box, resolution, always_render));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GlutRender::remove_surface(ImplicitSurface* surf) {
|
void GlutRender::remove_surface(ImplicitSurface* surf) {
|
||||||
for(auto it=surfaces.begin(); it != surfaces.end(); ++it) {
|
surfaces.erase(SurfaceDetails(surf, Cuboid::empty()));
|
||||||
if(*it == SurfaceDetails(surf, Cuboid::empty(), 0.1, true)) {
|
|
||||||
surfaces.erase(it);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void GlutRender::run() {
|
void GlutRender::run() {
|
||||||
|
@ -110,23 +89,6 @@ 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::add_kb_up_handler(GlutRender::kb_handler_t handler) {
|
|
||||||
kb_up_handlers.push_back(handler);
|
|
||||||
}
|
|
||||||
|
|
||||||
void GlutRender::follow_implicit_position(const ImplicitSurface* surf) {
|
|
||||||
followed_implicit = surf;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GlutRender::set_camera(const Point& location, const Point& sight) {
|
|
||||||
camera_position = location;
|
|
||||||
camera_sight = sight;
|
|
||||||
}
|
|
||||||
|
|
||||||
void GlutRender::reshape(int wid, int hei) {
|
void GlutRender::reshape(int wid, int hei) {
|
||||||
if (hei == 0)
|
if (hei == 0)
|
||||||
hei = 1;
|
hei = 1;
|
||||||
|
@ -187,15 +149,8 @@ void GlutRender::display_mesh(Mesh& mesh) const {
|
||||||
#endif // DEBUG_DISPLAY_WIREFRAME
|
#endif // DEBUG_DISPLAY_WIREFRAME
|
||||||
|
|
||||||
|
|
||||||
const Color& color = mesh.get_color();
|
|
||||||
GLfloat material_specular[] = {
|
|
||||||
(float)color[0],
|
|
||||||
(float)color[1],
|
|
||||||
(float)color[2],
|
|
||||||
1.};
|
|
||||||
glBegin(GL_TRIANGLES);
|
glBegin(GL_TRIANGLES);
|
||||||
glColor3f(color[0], color[1], color[2]);
|
glColor3f(1., 1., 1.);
|
||||||
glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, material_specular);
|
|
||||||
for(const Face& face: mesh.get_faces()) {
|
for(const Face& face: mesh.get_faces()) {
|
||||||
Point p0 = face.pt(0, points) + mesh_center,
|
Point p0 = face.pt(0, points) + mesh_center,
|
||||||
p1 = face.pt(1, points) + mesh_center,
|
p1 = face.pt(1, points) + mesh_center,
|
||||||
|
@ -217,54 +172,28 @@ void GlutRender::display() {
|
||||||
|
|
||||||
// Camera position and orientation
|
// Camera position and orientation
|
||||||
glLoadIdentity();
|
glLoadIdentity();
|
||||||
|
//glTranslatef(1., 2., -10.);
|
||||||
if(followed_implicit != nullptr) {
|
gluLookAt(0, 2.5, -10,
|
||||||
const Point& look_at = followed_implicit->getCenter();
|
0, 2.5, 0,
|
||||||
gluLookAt(camera_position.x, camera_position.y, camera_position.z,
|
|
||||||
look_at.x, camera_position.y, look_at.z,
|
|
||||||
0, 1, 0);
|
0, 1, 0);
|
||||||
}
|
|
||||||
else {
|
|
||||||
gluLookAt(camera_position.x, camera_position.y, camera_position.z,
|
|
||||||
camera_sight.x, camera_position.y, camera_sight.z,
|
|
||||||
0, 1, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
for(Mesh* mesh: meshes) {
|
for(Mesh* mesh: meshes) {
|
||||||
display_mesh(*mesh);
|
display_mesh(*mesh);
|
||||||
}
|
}
|
||||||
|
|
||||||
for(SurfaceDetails& surface: surfaces) {
|
for(const SurfaceDetails& surface: surfaces) {
|
||||||
if(!surface.always_render) {
|
Mesh mesh = MarchingCubes(*surface.surface, surface.box)
|
||||||
if(surface.prerender == nullptr)
|
.add_hint(surface.surface->location_hint())
|
||||||
surface.self_render();
|
();
|
||||||
display_mesh(*surface.prerender);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
Mesh mesh = surface.render();
|
|
||||||
display_mesh(mesh);
|
display_mesh(mesh);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
glutSwapBuffers();
|
glutSwapBuffers();
|
||||||
}
|
}
|
||||||
|
|
||||||
void GlutRender::on_kb_evt(bool up, unsigned char key, int x, int y) {
|
|
||||||
std::vector<kb_handler_t>& handlers = up? kb_up_handlers : kb_handlers;
|
|
||||||
for(auto& handler: 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(false, key, x, y);
|
|
||||||
}
|
|
||||||
void GlutRender::kb_evt_up_handle(unsigned char key, int x, int y) {
|
|
||||||
get_instance().on_kb_evt(true, key, x, y);
|
|
||||||
}
|
|
||||||
|
|
|
@ -5,13 +5,9 @@
|
||||||
#include "../Mesh.hpp"
|
#include "../Mesh.hpp"
|
||||||
#include "../Implicit.hpp"
|
#include "../Implicit.hpp"
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <vector>
|
|
||||||
#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;
|
||||||
|
@ -22,46 +18,22 @@ class GlutRender {
|
||||||
void cleanup();
|
void cleanup();
|
||||||
void add_mesh(Mesh* mesh);
|
void add_mesh(Mesh* mesh);
|
||||||
void remove_mesh(Mesh* mesh);
|
void remove_mesh(Mesh* mesh);
|
||||||
void add_surface(ImplicitSurface* surf, const Cuboid& box,
|
void add_surface(ImplicitSurface* surf, const Cuboid& box);
|
||||||
bool always_render=true, double resolution=0.1);
|
|
||||||
void remove_surface(ImplicitSurface* surf);
|
void remove_surface(ImplicitSurface* surf);
|
||||||
void run();
|
void run();
|
||||||
|
|
||||||
void set_idle_func(void (*func)(void));
|
void set_idle_func(void (*func)(void));
|
||||||
|
|
||||||
void add_kb_handler(kb_handler_t handler);
|
|
||||||
void add_kb_up_handler(kb_handler_t handler);
|
|
||||||
|
|
||||||
void follow_implicit_position(const ImplicitSurface* surf);
|
|
||||||
|
|
||||||
void set_camera(const Point& location, const Point& sight);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
struct SurfaceDetails {
|
struct SurfaceDetails {
|
||||||
SurfaceDetails(ImplicitSurface* surf, const Cuboid& box,
|
SurfaceDetails(ImplicitSurface* surf, const Cuboid& box):
|
||||||
double resolution,
|
surface(surf), box(box) {}
|
||||||
bool always_render):
|
|
||||||
surface(surf), box(box), resolution(resolution),
|
|
||||||
always_render(always_render), prerender(nullptr)
|
|
||||||
{}
|
|
||||||
~SurfaceDetails() {
|
|
||||||
if(prerender != nullptr)
|
|
||||||
delete prerender;
|
|
||||||
}
|
|
||||||
|
|
||||||
ImplicitSurface* surface;
|
ImplicitSurface* surface;
|
||||||
Cuboid box;
|
Cuboid box;
|
||||||
double resolution;
|
|
||||||
|
|
||||||
bool always_render;
|
bool operator<(const SurfaceDetails& oth) const {
|
||||||
Mesh* prerender;
|
return surface < oth.surface;
|
||||||
|
|
||||||
bool operator==(const SurfaceDetails& oth) const {
|
|
||||||
return surface == oth.surface;
|
|
||||||
}
|
|
||||||
Mesh render() const;
|
|
||||||
void self_render() {
|
|
||||||
prerender = new Mesh(render());
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -74,24 +46,13 @@ class GlutRender {
|
||||||
protected:
|
protected:
|
||||||
void reshape(int wid, int hei);
|
void reshape(int wid, int hei);
|
||||||
void display();
|
void display();
|
||||||
void on_kb_evt(bool up, 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);
|
|
||||||
static void kb_evt_up_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::vector<SurfaceDetails> surfaces;
|
std::set<SurfaceDetails> surfaces;
|
||||||
|
|
||||||
std::vector<kb_handler_t> kb_handlers;
|
|
||||||
std::vector<kb_handler_t> kb_up_handlers;
|
|
||||||
|
|
||||||
const ImplicitSurface* followed_implicit;
|
|
||||||
|
|
||||||
Point camera_position, camera_sight;
|
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue