From c2cd75a61ca1e935b5083a1e8e42649d1aae36af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Oudin?= Date: Mon, 12 Feb 2018 13:54:39 +0100 Subject: [PATCH 01/10] Add movement on y-axis --- Ball.cpp | 11 +++++++++-- Ball.hpp | 4 ++-- main_ball.cpp | 2 +- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/Ball.cpp b/Ball.cpp index 82338a4..390fa56 100644 --- a/Ball.cpp +++ b/Ball.cpp @@ -2,7 +2,7 @@ #include #include -Ball::Ball(Point& _center, double _min_height, double _v_x, double _p, double _q) : +Ball::Ball(Point& _center, double _min_height, double _v_x, double _v_y, double _p, double _q) : Center(_center), surface(_center, _p, _q), init_h(_center.z), @@ -13,13 +13,15 @@ Ball::Ball(Point& _center, double _min_height, double _v_x, double _p, double _q B(0), U(sqrt(2 * G_CTE * _center.z)), T(sqrt(2.0 * _center.z / G_CTE)), - v_x(_v_x) + v_x(_v_x), + v_y(_v_y) { } void Ball::_compute_pos(double dt) { Center.z = fmax(0.0, A + B * crt_time - (G_CTE / 2) * crt_time * crt_time + min_height); Center.x += dt * v_x; + Center.y += dt * v_y; surface.update_center_pos(Center); } @@ -43,6 +45,10 @@ void Ball::_compute_v_x() { v_x *= 0.5; } +void Ball::_compute_v_y() { + v_y *= 0.5; +} + void Ball::update_pos(double dt) { crt_time += dt; if (crt_time >= T) { @@ -52,6 +58,7 @@ void Ball::update_pos(double dt) { _compute_B_n(); _compute_T_n(); _compute_v_x(); + _compute_v_y(); std::cout << "New bounce :"; std::cout << "U:" << U << ":"; std::cout << "A:" << A << ":"; diff --git a/Ball.hpp b/Ball.hpp index 0ab1a86..4ddad91 100644 --- a/Ball.hpp +++ b/Ball.hpp @@ -24,7 +24,7 @@ class Ball { size_t bounce_number; double crt_time; double A, B, U, T; // Coefficients for the physical model. - double v_x; + double v_x, v_y; void _compute_pos(double dt); void _compute_v_x(); void _compute_A_n(); @@ -32,7 +32,7 @@ class Ball { void _compute_U_n(); void _compute_T_n(); public: - Ball(Point& _center, double _min_height, double _v_x, double p, double q); + Ball(Point& _center, double _min_height, double _v_x, double _v_y, double p, double q); void update_pos(double dt); Point getCenter() const {return Center;} double accessT() const { return T;} diff --git a/main_ball.cpp b/main_ball.cpp index 00fb7c4..aa3ab02 100644 --- a/main_ball.cpp +++ b/main_ball.cpp @@ -11,7 +11,7 @@ using namespace std; int main(int argc, char** argv) { int i; Point center(0,0,10); - Ball ball(center, 0, 0.25, 1, 1); + Ball ball(center, 0, 0.25, 0, 1, 1); for(i=0; i< 10000; i++) { ball.update_pos(0.001); cout << ball << "\n"; From 1be55612d441a155c4dc470707b25bc3ea1980be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Oudin?= Date: Mon, 12 Feb 2018 14:14:50 +0100 Subject: [PATCH 02/10] Missing function in header file --- Ball.hpp | 1 + 1 file changed, 1 insertion(+) diff --git a/Ball.hpp b/Ball.hpp index 4ddad91..a9ed49f 100644 --- a/Ball.hpp +++ b/Ball.hpp @@ -27,6 +27,7 @@ class Ball { double v_x, v_y; void _compute_pos(double dt); void _compute_v_x(); + void _compute_v_y(); void _compute_A_n(); void _compute_B_n(); void _compute_U_n(); From 61f50c2861aa04e46e0a22dd572b14b451f80721 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Oudin?= Date: Mon, 12 Feb 2018 14:15:30 +0100 Subject: [PATCH 03/10] Move operator in .cpp file --- spheroid.cpp | 7 +++++++ spheroid.hpp | 6 +----- 2 files changed, 8 insertions(+), 5 deletions(-) diff --git a/spheroid.cpp b/spheroid.cpp index ef9f381..2c0a60b 100644 --- a/spheroid.cpp +++ b/spheroid.cpp @@ -51,3 +51,10 @@ void Spheroid::check_vertical_plan_collision(double& abscissa) { } } } + + +double Spheroid::operator() (double _x, double _y, double _z) const { + return (pow(_x - center.x, 2) / pow(q, 2) + + pow(_y - center.y, 2) / pow(q, 2) + + pow(_z - center.z, 2) / pow(p, 2) -1); + } diff --git a/spheroid.hpp b/spheroid.hpp index 66b2aec..ca74894 100644 --- a/spheroid.hpp +++ b/spheroid.hpp @@ -19,11 +19,7 @@ class Spheroid : public ImplicitSurface { void set_stiffness(size_t _stiffness); void check_horizontal_plan_collision(double& height); void check_vertical_plan_collision(double& abscissa); - double operator() (double _x, double _y, double _z) const { - return (pow(_x - center.x, 2) / pow(q, 2) - + pow(_y - center.y, 2) / pow(q, 2) - + pow(_z - center.z, 2) / pow(p, 2) -1); - } + double operator() (double _x, double _y, double _z) const; private: /** * p corresponds to the half-height of the ball, From 1ee6875b5a945afc4a89fa972ac352efc0d93626 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Oudin?= Date: Mon, 12 Feb 2018 14:31:08 +0100 Subject: [PATCH 04/10] Bounding box for spheroid, based on initial values. --- Ball.cpp | 2 +- spheroid.cpp | 15 ++++++++++----- spheroid.hpp | 7 +++---- 3 files changed, 14 insertions(+), 10 deletions(-) diff --git a/Ball.cpp b/Ball.cpp index 82338a4..f5b8933 100644 --- a/Ball.cpp +++ b/Ball.cpp @@ -4,7 +4,7 @@ Ball::Ball(Point& _center, double _min_height, double _v_x, double _p, double _q) : Center(_center), - surface(_center, _p, _q), + surface(_center, min_height, _p, _q), init_h(_center.z), min_height(_min_height), bounce_number(0.0), diff --git a/spheroid.cpp b/spheroid.cpp index ef9f381..7fb8673 100644 --- a/spheroid.cpp +++ b/spheroid.cpp @@ -4,8 +4,8 @@ #include "spheroid.hpp" -Spheroid::Spheroid(Point& _center, size_t _p, size_t _q) : - ImplicitSurface(_center), init_p(_p), p(_p), q(_q), stiffness(0) { +Spheroid::Spheroid(Point& _center, double _min_p, size_t _p, size_t _q) : + ImplicitSurface(_center), min_p(_min_p), init_p(_p), p(_p), q(_q) { _compute_volume(); } @@ -13,9 +13,6 @@ void Spheroid::_compute_volume() { V = (4/3) * PI * p * q * q; } -void Spheroid::set_stiffness(size_t _stiffness) { - stiffness = _stiffness; -} void Spheroid::update_radius() { @@ -51,3 +48,11 @@ void Spheroid::check_vertical_plan_collision(double& abscissa) { } } } + +Cuboid Spheroid::max_bounding_box() const { + double max_radius = sqrt((3/4) * V / PI / min_p); + double max_height = init_p; + Point _bd1(max_radius, max_radius, max_height); + Point _bd2(-max_radius, -max_radius, -max_height); + return Cuboid(_bd1, _bd2); +} diff --git a/spheroid.hpp b/spheroid.hpp index 66b2aec..eb0128d 100644 --- a/spheroid.hpp +++ b/spheroid.hpp @@ -12,13 +12,13 @@ const double PI = 3.141592653589793; class Spheroid : public ImplicitSurface { public: - Spheroid(Point& _center, size_t _p, size_t _q); + Spheroid(Point& _center, double _min_p, size_t _p, size_t _q); void update_center_pos(Point& _center); void update_radius(); void update_height(); - void set_stiffness(size_t _stiffness); void check_horizontal_plan_collision(double& height); void check_vertical_plan_collision(double& abscissa); + Cuboid max_bounding_box() const; double operator() (double _x, double _y, double _z) const { return (pow(_x - center.x, 2) / pow(q, 2) + pow(_y - center.y, 2) / pow(q, 2) @@ -31,8 +31,7 @@ class Spheroid : public ImplicitSurface { * V is the volume. Extremely useful to have a constant volume in the * ball **/ - double init_p, p, q; - size_t stiffness; + double min_p, init_p, p, q; double V; void _compute_volume(); }; From 7b14f2e5f1f74e71caa18755be4c791735136760 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Oudin?= Date: Mon, 12 Feb 2018 17:40:00 +0100 Subject: [PATCH 05/10] Generation of perlin noise structures --- PerlinNoise.cpp | 123 ++++++++++++++++++++++++++++++++++++++++++++++++ PerlinNoise.hpp | 23 +++++++++ 2 files changed, 146 insertions(+) create mode 100644 PerlinNoise.cpp create mode 100644 PerlinNoise.hpp diff --git a/PerlinNoise.cpp b/PerlinNoise.cpp new file mode 100644 index 0000000..af46b57 --- /dev/null +++ b/PerlinNoise.cpp @@ -0,0 +1,123 @@ +#include "PerlinNoise.hpp" + +Point vector_product(Point u, Point v) { + Point u_v(0,0,0); + u_v.x = u.y* v.z - u.z * v.y; + u_v.y = u.z* v.x - u.x * v.z; + u_v.z = u.x* v.y - u.y * v.x; + return u_v; +} + +PerlinNoise::PerlinNoise() : ImplicitSurface(Point(0,0,0)) { + // permutation vector (source : http://mrl.nyu.edu/~perlin/noise/) + p = { + 151,160,137,91,90,15,131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142, + 8,99,37,240,21,10,23,190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117, + 35,11,32,57,177,33,88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71, + 134,139,48,27,166,77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41, + 55,46,245,40,244,102,143,54, 65,25,63,161,1,216,80,73,209,76,132,187,208, 89, + 18,169,200,196,135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226, + 250,124,123,5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182, + 189,28,42,223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, + 43,172,9,129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246, + 97,228,251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239, + 107,49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254, + 138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180 }; + // Duplication of the permutation vector. + p.insert(p.end(), p.begin(), p.end()); +} + +PerlinNoise::PerlinNoise(unsigned int seed) : ImplicitSurface(Point(0,0,0)) { + p.resize(256); + + // Fill p with values from 0 to 255 + std::iota(p.begin(), p.end(), 0); + + // Initialize a random engine with seed + std::default_random_engine engine(seed); + + // Shuffle using the above random engine + std::shuffle(p.begin(), p.end(), engine); + + // Duplicate the permutation vector + p.insert(p.end(), p.begin(), p.end()); +} + +double PerlinNoise::operator() (double x, double y, double z) const { + return z - noise(x, y, 0); +} + +double PerlinNoise::noise(double _x, double _y, double _z) const { + int X = (int) floor(_x) & 255; + int Y = (int) floor(_y) & 255; + int Z = (int) floor(_z) & 255; + + _x -= floor(_x); + _y -= floor(_y); + _z -= floor(_z); + + double u = fade(_x); + double v = fade(_y); + double w = fade(_z); + + int A = p[X] + Y; + int AA = p[A] + Z; + int AB = p[A + 1] + Z; + int B = p[X + 1] + Y; + int BA = p[B] + Z; + int BB = p[B + 1] + Z; + + double res = lerp( + w, + lerp( + v, + lerp(u, grad(p[AA], _x, _y, _z), grad(p[BA], _x-1, _y, _z)), + lerp(u, grad(p[AB], _x, _y-1, _z), grad(p[BB], _x-1, _y-1, _z)) + ), + lerp( + v, + lerp( + u, + grad(p[AA+1], _x, _y, _z-1), + grad(p[BA+1], _x-1, _y, _z-1) + ), + lerp( + u, + grad(p[AB+1], _x, _y-1, _z-1), + grad(p[BB+1], _x-1, _y-1, _z-1) + ) + ) + ); + return (res + 1.0)/2.0; +} + +double PerlinNoise::noise(double _x, double _y) const { + return noise(_x, _y, 0); +} + +double PerlinNoise::fade(double t) const { + return t * t * t * (t * (t * 6 - 15) + 10); +} + +double PerlinNoise::lerp(double t, double a, double b) const { + return a + t * (b-a); +} + +double PerlinNoise::grad(int hash, double x, double y, double z) const { + int h = hash & 15; + // Convert lower 4 bits of hash into 12 gradient directions + double u = h < 8 ? x : y, + v = h < 4 ? y : h == 12 || h == 14 ? x : z; + return ((h & 1) == 0 ? u : -u) + ((h & 2) == 0 ? v : -v); +} + +Point PerlinNoise::normal_vector(double x, double y) { + double n_x_y = noise(x, y, 0); + double n_dx_y = noise(x + 0.01, y, 0); + double n_x_dy = noise(x, y + 0.01, 0); + Point product = vector_product( + Point(0.01, 0, n_dx_y - n_x_y), + Point(0, 0.01, (n_x_dy - n_x_y)) + ); + return product; +} diff --git a/PerlinNoise.hpp b/PerlinNoise.hpp new file mode 100644 index 0000000..e013e9e --- /dev/null +++ b/PerlinNoise.hpp @@ -0,0 +1,23 @@ +/** + * Perlin Noise implementation for the ground (header file) + **/ +#include "Implicit.hpp" +#include +#include +#include +#include + +class PerlinNoise : public ImplicitSurface { + std::vector p; + public: + PerlinNoise(); + PerlinNoise(unsigned int seed); + double operator() (double _x, double _y, double _z) const; + double noise(double x, double y) const; + Point normal_vector(double x, double y); + private: + double noise(double x, double y, double z) const; + double fade(double t) const; + double lerp(double t, double a, double b) const; + double grad(int hash, double x, double y, double z) const; +}; From 588ff14b339ca52d76b8c2b62602ba82f97a2017 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Oudin?= Date: Mon, 12 Feb 2018 17:40:21 +0100 Subject: [PATCH 06/10] Update makefile for Perlin Noise --- Makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/Makefile b/Makefile index c816215..aff6c53 100644 --- a/Makefile +++ b/Makefile @@ -11,6 +11,7 @@ OBJS=Implicit.o \ Mesh.o \ spheroid.o \ Ball.o \ + PerlinNoise.o \ util/ObjParser.o \ MarchingCubes.o \ _gen/marching_cubes_data.o \ From 0987290111cb3b9ab4ea239b027e706ef28f9499 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Oudin?= Date: Mon, 12 Feb 2018 17:40:50 +0100 Subject: [PATCH 07/10] Handling of perlin noise surfaces --- spheroid.cpp | 11 ++++++++++- spheroid.hpp | 4 ++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/spheroid.cpp b/spheroid.cpp index 2c0a60b..af24061 100644 --- a/spheroid.cpp +++ b/spheroid.cpp @@ -5,7 +5,7 @@ #include "spheroid.hpp" Spheroid::Spheroid(Point& _center, size_t _p, size_t _q) : - ImplicitSurface(_center), init_p(_p), p(_p), q(_q), stiffness(0) { + ImplicitSurface(_center), normal_vector(Point(0,0,1)), init_p(_p), p(_p), q(_q), stiffness(0) { _compute_volume(); } @@ -52,6 +52,15 @@ void Spheroid::check_vertical_plan_collision(double& abscissa) { } } +void Spheroid::check_perlin_collision(PerlinNoise perlin) { + double height = perlin.noise(center.x, center.y); + if ((center.z - p) <= height) { + p = fmin(init_p, center.z- height ); + normal_vector = perlin.normal_vector(center.x, center.y); + update_radius(); + } +} + double Spheroid::operator() (double _x, double _y, double _z) const { return (pow(_x - center.x, 2) / pow(q, 2) diff --git a/spheroid.hpp b/spheroid.hpp index ca74894..df84664 100644 --- a/spheroid.hpp +++ b/spheroid.hpp @@ -7,6 +7,7 @@ #include #include "Implicit.hpp" #include "common_structures.hpp" +#include "PerlinNoise.hpp" const double PI = 3.141592653589793; @@ -19,6 +20,8 @@ class Spheroid : public ImplicitSurface { void set_stiffness(size_t _stiffness); void check_horizontal_plan_collision(double& height); void check_vertical_plan_collision(double& abscissa); + void check_perlin_collision(PerlinNoise perlin); + Point getNormalVector() const { return normal_vector;} double operator() (double _x, double _y, double _z) const; private: /** @@ -27,6 +30,7 @@ class Spheroid : public ImplicitSurface { * V is the volume. Extremely useful to have a constant volume in the * ball **/ + Point normal_vector; double init_p, p, q; size_t stiffness; double V; From f2f6e9cb76a5ed9e4ae9416eeace336aeac74be4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Oudin?= Date: Mon, 12 Feb 2018 17:41:12 +0100 Subject: [PATCH 08/10] Handling of bounces for perlin noise surfaces --- Ball.cpp | 15 +++++++++------ Ball.hpp | 4 ++-- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/Ball.cpp b/Ball.cpp index 390fa56..0201912 100644 --- a/Ball.cpp +++ b/Ball.cpp @@ -41,24 +41,27 @@ void Ball::_compute_U_n() { U *= 0.5; } -void Ball::_compute_v_x() { - v_x *= 0.5; +void Ball::_compute_v_x(Point normal) { + double factor = normal.x / (4*(normal.x + normal.y)); + v_x *= (0.5 + factor); } -void Ball::_compute_v_y() { - v_y *= 0.5; +void Ball::_compute_v_y(Point normal) { + double factor = normal.x / (4*(normal.x + normal.y)); + v_y *= (0.5 + factor); } void Ball::update_pos(double dt) { crt_time += dt; if (crt_time >= T) { + Point normal = surface.getNormalVector(); bounce_number += 1; _compute_U_n(); _compute_A_n(); _compute_B_n(); _compute_T_n(); - _compute_v_x(); - _compute_v_y(); + _compute_v_x(normal); + _compute_v_y(normal); std::cout << "New bounce :"; std::cout << "U:" << U << ":"; std::cout << "A:" << A << ":"; diff --git a/Ball.hpp b/Ball.hpp index a9ed49f..9f2d90e 100644 --- a/Ball.hpp +++ b/Ball.hpp @@ -26,8 +26,8 @@ class Ball { double A, B, U, T; // Coefficients for the physical model. double v_x, v_y; void _compute_pos(double dt); - void _compute_v_x(); - void _compute_v_y(); + void _compute_v_x(Point normal); + void _compute_v_y(Point normal); void _compute_A_n(); void _compute_B_n(); void _compute_U_n(); From 26cac772d7746178a8ae3348e0d9695af0660df5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Oudin?= Date: Mon, 12 Feb 2018 18:18:28 +0100 Subject: [PATCH 09/10] Y axis is vertical for OpenGL --- Ball.cpp | 12 ++++++------ main_ball.cpp | 2 +- spheroid.cpp | 4 ++-- 3 files changed, 9 insertions(+), 9 deletions(-) diff --git a/Ball.cpp b/Ball.cpp index f5b8933..1e24fdc 100644 --- a/Ball.cpp +++ b/Ball.cpp @@ -5,20 +5,20 @@ Ball::Ball(Point& _center, double _min_height, double _v_x, double _p, double _q) : Center(_center), surface(_center, min_height, _p, _q), - init_h(_center.z), + init_h(_center.y), min_height(_min_height), bounce_number(0.0), crt_time(0), - A(_center.z), + A(_center.y), B(0), - U(sqrt(2 * G_CTE * _center.z)), - T(sqrt(2.0 * _center.z / G_CTE)), + U(sqrt(2 * G_CTE * _center.y)), + T(sqrt(2.0 * _center.y / G_CTE)), v_x(_v_x) { } void Ball::_compute_pos(double dt) { - Center.z = fmax(0.0, A + B * crt_time - (G_CTE / 2) * crt_time * crt_time + min_height); + Center.y = fmax(0.0, A + B * crt_time - (G_CTE / 2) * crt_time * crt_time + min_height); Center.x += dt * v_x; surface.update_center_pos(Center); } @@ -66,7 +66,7 @@ std::ostream& operator<< (std::ostream &out, Ball const& data) { out << "t:" << data.access_crt_time() << ":"; out << "T:" << data.accessT() << ":"; out << center.x << ':'; - out << center.y << ':'; out << center.z << ':'; + out << center.y << ':'; return out; } diff --git a/main_ball.cpp b/main_ball.cpp index 00fb7c4..14e6f58 100644 --- a/main_ball.cpp +++ b/main_ball.cpp @@ -10,7 +10,7 @@ using namespace std; int main(int argc, char** argv) { int i; - Point center(0,0,10); + Point center(0,10,0); Ball ball(center, 0, 0.25, 1, 1); for(i=0; i< 10000; i++) { ball.update_pos(0.001); diff --git a/spheroid.cpp b/spheroid.cpp index 7fb8673..1e5be43 100644 --- a/spheroid.cpp +++ b/spheroid.cpp @@ -29,8 +29,8 @@ void Spheroid::update_center_pos(Point& _center) { } void Spheroid::check_horizontal_plan_collision(double& height) { - if ((center.z - p) <= height) { - p = fmin(init_p, center.z-height); + if ((center.y - p) <= height) { + p = fmin(init_p, center.y-height); update_radius(); } } From 286173425846d720b91dc5ca466d29e13bc7d804 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9mi=20Oudin?= Date: Mon, 12 Feb 2018 18:36:59 +0100 Subject: [PATCH 10/10] Implicit surface operator should be centered in 0. --- spheroid.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/spheroid.cpp b/spheroid.cpp index d55f451..b6cb9f6 100644 --- a/spheroid.cpp +++ b/spheroid.cpp @@ -68,7 +68,7 @@ void Spheroid::check_perlin_collision(PerlinNoise perlin) { double Spheroid::operator() (double _x, double _y, double _z) const { - return (pow(_x - center.x, 2) / pow(q, 2) - + pow(_y - center.y, 2) / pow(q, 2) - + pow(_z - center.z, 2) / pow(p, 2) -1); + return (pow(_x, 2) / pow(q, 2) + + pow(_y, 2) / pow(q, 2) + + pow(_z, 2) / pow(p, 2) -1); }