Compare commits
2 commits
3d0f723016
...
24d21d77cb
Author | SHA1 | Date | |
---|---|---|---|
24d21d77cb | |||
ffaa4ed7c8 |
4 changed files with 77 additions and 16 deletions
30
README.md
30
README.md
|
@ -8,3 +8,33 @@ A jelly-like ball bounces around.
|
|||
|
|
||||
[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
|
||||
|
|
|
@ -50,7 +50,7 @@ int main(int argc, char** argv) {
|
|||
|
||||
if(perlin) {
|
||||
perlin_ground.get_surface()->set_color(Color(0.13, 0.82, 0.21));
|
||||
render.add_surface(perlin_ground.get_surface(), bbox_2, 1.2);
|
||||
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));
|
||||
|
|
|
@ -12,6 +12,13 @@ GlutRender& GlutRender::get_instance() {
|
|||
return instance;
|
||||
}
|
||||
|
||||
Mesh GlutRender::SurfaceDetails::render() const {
|
||||
return MarchingCubes(*surface, box,
|
||||
resolution)
|
||||
.add_hint(surface->location_hint())
|
||||
();
|
||||
}
|
||||
|
||||
GlutRender::GlutRender()
|
||||
: followed_implicit(nullptr),
|
||||
camera_position(0., 2.5, -10.),
|
||||
|
@ -81,13 +88,18 @@ void GlutRender::remove_mesh(Mesh* mesh) {
|
|||
}
|
||||
|
||||
void GlutRender::add_surface(ImplicitSurface* surf, const Cuboid& box,
|
||||
double resolution)
|
||||
bool always_render, double resolution)
|
||||
{
|
||||
surfaces.insert(SurfaceDetails(surf, box, resolution));
|
||||
surfaces.push_back(SurfaceDetails(surf, box, resolution, always_render));
|
||||
}
|
||||
|
||||
void GlutRender::remove_surface(ImplicitSurface* surf) {
|
||||
surfaces.erase(SurfaceDetails(surf, Cuboid::empty(), 0.1));
|
||||
for(auto it=surfaces.begin(); it != surfaces.end(); ++it) {
|
||||
if(*it == SurfaceDetails(surf, Cuboid::empty(), 0.1, true)) {
|
||||
surfaces.erase(it);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GlutRender::run() {
|
||||
|
@ -222,12 +234,16 @@ void GlutRender::display() {
|
|||
display_mesh(*mesh);
|
||||
}
|
||||
|
||||
for(const SurfaceDetails& surface: surfaces) {
|
||||
Mesh mesh = MarchingCubes(*surface.surface, surface.box,
|
||||
surface.resolution)
|
||||
.add_hint(surface.surface->location_hint())
|
||||
();
|
||||
display_mesh(mesh);
|
||||
for(SurfaceDetails& surface: surfaces) {
|
||||
if(!surface.always_render) {
|
||||
if(surface.prerender == nullptr)
|
||||
surface.self_render();
|
||||
display_mesh(*surface.prerender);
|
||||
}
|
||||
else {
|
||||
Mesh mesh = surface.render();
|
||||
display_mesh(mesh);
|
||||
}
|
||||
}
|
||||
|
||||
glutSwapBuffers();
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include "../Mesh.hpp"
|
||||
#include "../Implicit.hpp"
|
||||
#include <set>
|
||||
#include <vector>
|
||||
#include <functional>
|
||||
|
||||
class GlutRender {
|
||||
|
@ -22,7 +23,7 @@ class GlutRender {
|
|||
void add_mesh(Mesh* mesh);
|
||||
void remove_mesh(Mesh* mesh);
|
||||
void add_surface(ImplicitSurface* surf, const Cuboid& box,
|
||||
double resolution=0.1);
|
||||
bool always_render=true, double resolution=0.1);
|
||||
void remove_surface(ImplicitSurface* surf);
|
||||
void run();
|
||||
|
||||
|
@ -38,15 +39,29 @@ class GlutRender {
|
|||
private:
|
||||
struct SurfaceDetails {
|
||||
SurfaceDetails(ImplicitSurface* surf, const Cuboid& box,
|
||||
double resolution):
|
||||
surface(surf), box(box), resolution(resolution) {}
|
||||
double resolution,
|
||||
bool always_render):
|
||||
surface(surf), box(box), resolution(resolution),
|
||||
always_render(always_render), prerender(nullptr)
|
||||
{}
|
||||
~SurfaceDetails() {
|
||||
if(prerender != nullptr)
|
||||
delete prerender;
|
||||
}
|
||||
|
||||
ImplicitSurface* surface;
|
||||
Cuboid box;
|
||||
double resolution;
|
||||
|
||||
bool operator<(const SurfaceDetails& oth) const {
|
||||
return surface < oth.surface;
|
||||
bool always_render;
|
||||
Mesh* prerender;
|
||||
|
||||
bool operator==(const SurfaceDetails& oth) const {
|
||||
return surface == oth.surface;
|
||||
}
|
||||
Mesh render() const;
|
||||
void self_render() {
|
||||
prerender = new Mesh(render());
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -71,7 +86,7 @@ class GlutRender {
|
|||
std::function<double()> rand_color;
|
||||
|
||||
std::set<Mesh*> meshes;
|
||||
std::set<SurfaceDetails> surfaces;
|
||||
std::vector<SurfaceDetails> surfaces;
|
||||
|
||||
std::vector<kb_handler_t> kb_handlers;
|
||||
std::vector<kb_handler_t> kb_up_handlers;
|
||||
|
|
Loading…
Reference in a new issue