diff --git a/projet-code/scenes_inf443/base/src/ball.cpp b/projet-code/scenes_inf443/base/src/ball.cpp index 7a32f47a14d6d24b5c201a2fac0bd80585c1db76..644d8b834ed978bd57a0681aaf97a0d274310187 100644 --- a/projet-code/scenes_inf443/base/src/ball.cpp +++ b/projet-code/scenes_inf443/base/src/ball.cpp @@ -1,5 +1,6 @@ #include "ball.hpp" #include "terrain.hpp" +#include "settings.hpp" void ball::initialize(int n) { @@ -38,10 +39,10 @@ void ball::add_ball(vec3 new_pos, vec3 new_dir) { } -void ball::simulate(float dt, float terrain_length) { +void ball::simulate(float dt) { for (int i = 0; i < N; i++) { - if (pos[i][2] < -1 || cgp::abs(pos[i][0]) > terrain_length / 2 || cgp::abs(pos[i][1]) > terrain_length / 2) { - pos[i] = { 0,0, evaluate_terrain_height(0,0, terrain_length) }; + if (pos[i][2] < -1 || cgp::abs(pos[i][0]) > terrain_length() / 2 || cgp::abs(pos[i][1]) > terrain_length() / 2) { + pos[i] = { 0,0, evaluate_terrain_height(0,0) }; v[i] = { 3 * rand_interval(), 3 * rand_interval(), 4 + i }; } else { @@ -49,8 +50,8 @@ void ball::simulate(float dt, float terrain_length) { v[i][2] -= 10 * dt; } - if (pos[i][2] < evaluate_terrain_height(pos[i][0], pos[i][1], terrain_length)) { - vec3 normal = normalize(terrain_orientation(pos[i][0], pos[i][1], terrain_length)); + if (pos[i][2] < evaluate_terrain_height(pos[i][0], pos[i][1])) { + vec3 normal = normalize(terrain_orientation(pos[i][0], pos[i][1])); vec3 temp = v[i] - dot(v[i], normal) * normal; @@ -64,11 +65,11 @@ void ball::simulate(float dt, float terrain_length) { } } -vec3 terrain_orientation(float x, float y, float terrain_length) { - float z = evaluate_terrain_height(x, y, terrain_length); +vec3 terrain_orientation(float x, float y) { + float z = evaluate_terrain_height(x, y); float step = 0.1f; - vec3 u = { step, 0, evaluate_terrain_height(x + step,y, terrain_length) - z }; - vec3 v = { 0, step, evaluate_terrain_height(x,y + step, terrain_length) - z }; + vec3 u = { step, 0, evaluate_terrain_height(x + step,y) - z }; + vec3 v = { 0, step, evaluate_terrain_height(x,y + step) - z }; return cross(v, u); } diff --git a/projet-code/scenes_inf443/base/src/ball.hpp b/projet-code/scenes_inf443/base/src/ball.hpp index 1e8fd587b611b8f5e9bedbbbd00e12351c533d54..1f82ba92000da51212284cd382a7760407a42e99 100644 --- a/projet-code/scenes_inf443/base/src/ball.hpp +++ b/projet-code/scenes_inf443/base/src/ball.hpp @@ -14,10 +14,10 @@ struct ball { mesh_drawable mesh; void initialize(int n); - void simulate(float dt, float terrain_length); + void simulate(float dt); void add_ball(vec3 new_pos, vec3 new_dir); void reset(); }; -vec3 terrain_orientation(float x, float y, float terrain_length); +vec3 terrain_orientation(float x, float y); diff --git a/projet-code/scenes_inf443/base/src/bat.cpp b/projet-code/scenes_inf443/base/src/bat.cpp index df8518f997d884dafde0ecd2ed692e85a1ee9186..1198b79527d5938306c901ecacf9bd0be1b84a74 100644 --- a/projet-code/scenes_inf443/base/src/bat.cpp +++ b/projet-code/scenes_inf443/base/src/bat.cpp @@ -4,84 +4,14 @@ #include "interpolation.hpp" #include "terrain.hpp" -void bat::initialize_bat() +void bat::initialize_mvt(vec3 p, numarray<vec3> key_positions, numarray<float> key_times) { - - // Initialize the temporary mesh_drawable that will be inserted in the hierarchy - mesh_drawable body; - mesh_drawable wing1; - mesh_drawable wing2; - - // Create the geometry of the meshes - // Note: this geometry must be set in their local coordinates with respect to their position in the hierarchy (and with respect to their animation) - - body.initialize_data_on_gpu(mesh_load_file_obj(project::path + "assets/batbodyok.obj")); - wing1.initialize_data_on_gpu(mesh_load_file_obj(project::path + "assets/batwingleft.obj")); - wing2.initialize_data_on_gpu(mesh_load_file_obj(project::path + "assets/batwingright.obj")); - - - // Scale the model - //body.model.scaling = 0.2f; - //wing1.model.scaling = 0.2f; - //wing2.model.scaling = 0.2f; - - - - // Set the color of some elements - body.material.color = { 0.3f,0.3f,0.3f }; - wing1.material.color = { 0.2f,0.2f,0.2f }; - wing2.material.color = { 0.2f,0.2f,0.2f }; - - - - - - - - // Add the elements in the hierarchy - // The syntax is hierarchy.add(mesh_drawable, "name of the parent element", [optional: local translation in the hierarchy]) - // Notes: - // - An element must necessarily be added after its parent - // - The first element (without explicit name of its parent) is assumed to be the root. - - bat.add(body, "Bat base"); - bat.add(wing1, "Bat wing left1", "Bat base", { -0.05f,0,0 }); - bat.add(wing2, "Bat wing right1", "Bat base", { 0.05f,0,0 }); - - - N = 0; - size.resize(N); - isdead.resize(N); - pos.resize(N); - pos2.resize(N); - keyframe.resize(N); -} - - - -void bat::initialize_mvt(vec3 p, int m, float terrain_length) -{ - // Definition of the initial data - //--------------------------------------// - - // Key 3D positions - numarray<vec3> key_positions = - { {-2,1,0}, {0,1,0}, {2,1,0}, {1,3,0}, {2,3,0}, {2,3,1}, {2,2.5,1.5}, {1.5,0,1}, {1.5,0,-1}, {0,0,-1}, {0,-0.5,-1}, {-2,1,-1} }; - - float h = 20 + evaluate_terrain_height(0, 0, terrain_length); for (int i = 0; i < key_positions.size(); i++) { - key_positions[i] *= size[m]; - key_positions[i][2] += h; key_positions[i] += p; } - // Key times (time at which the position must pass in the corresponding position) - numarray<float> key_times = - { 0.0f, 1.0f, 2.0f, 2.5f, 3.0f, 3.5f, 3.75f, 4.5f, 5.0f, 6.0f, 7.0f, 8.0f }; - // Initialize the helping structure to display/interact with these positions - keyframe[m].initialize(key_positions, key_times); - + keyframe.initialize(key_positions, key_times); // Set timer bounds // The timer must span a time interval on which the interpolation can be conducted @@ -92,48 +22,20 @@ void bat::initialize_mvt(vec3 p, int m, float terrain_length) timer_mvt.t = timer_mvt.t_min; } -void bat::display_mvt() +void bat::update_mvt() { - // Update the current time timer_mvt.update(); float t = timer_mvt.t; + // clear trajectory when the timer restart + if (t < timer_mvt.t_min + 0.1f) + keyframe.trajectory.clear(); - for (int m = 0; m < N; m++) { - // clear trajectory when the timer restart - if (t < timer_mvt.t_min + 0.1f) - keyframe[m].trajectory.clear(); - - if (t + 0.1f > timer_mvt.t_max) pos2[m] = interpolation(0.01f, keyframe[m].key_positions, keyframe[m].key_times, 0.5f); - else pos2[m] = interpolation((t + 0.1f), keyframe[m].key_positions, keyframe[m].key_times, 0.5f); - - // Display the key positions and lines b/w positions - //keyframe.display_key_positions(environment); - - // Compute the interpolated position - // This is this function that you need to complete - pos[m] = interpolation(t, keyframe[m].key_positions, keyframe[m].key_times, 0.5f); - - // Display the interpolated position (and its trajectory) - //keyframe.display_current_position(p, environment); - } -} - - -void bat::add_bat(vec3 new_pos, float terrain_length) { - N++; - pos.resize(N); - pos2.resize(N); - isdead.resize(N); - size.resize(N); - keyframe.resize(N); - - - pos[N - 1] = new_pos; - isdead[N - 1] = false; - size[N - 1] = rand_interval(0.05f, 1.0f);; - initialize_mvt(new_pos, N - 1, terrain_length); + if (t + 0.1f > timer_mvt.t_max) pos_futur = interpolation(0.01f, keyframe.key_positions, keyframe.key_times, 0.5f); + else pos_futur = interpolation((t + 0.1f), keyframe.key_positions, keyframe.key_times, 0.5f); + // Compute the interpolated position + pos = interpolation(t, keyframe.key_positions, keyframe.key_times, 0.5f); } diff --git a/projet-code/scenes_inf443/base/src/bat.hpp b/projet-code/scenes_inf443/base/src/bat.hpp index 5cb0a25eec8fca49de0602283269b84756a648ce..2b83f21cdca07494b2bca59cb169457ff27254c8 100644 --- a/projet-code/scenes_inf443/base/src/bat.hpp +++ b/projet-code/scenes_inf443/base/src/bat.hpp @@ -8,20 +8,17 @@ using namespace cgp; // The entire hierarchy struct bat{ - cgp::hierarchy_mesh_drawable bat; + double size; + bool isdead; + vec3 pos; + vec3 pos_futur; - int N; - std::vector<double> size; - std::vector<bool> isdead; - std::vector<vec3> pos; - std::vector<vec3> pos2; // Timer used for the interpolation of the position cgp::timer_interval timer_mvt; + // A helper structure used to store and display the key positions/time - std::vector<keyframe_structure> keyframe; + keyframe_structure keyframe; - void initialize_bat(); - void add_bat(vec3 new_pos, float terrain_length); - void initialize_mvt(vec3 p, int i, float terrain_length); - void display_mvt(); + void initialize_mvt(vec3 p, numarray<vec3> key_positions, numarray<float> key_times); + void update_mvt(); }; \ No newline at end of file diff --git a/projet-code/scenes_inf443/base/src/bats.cpp b/projet-code/scenes_inf443/base/src/bats.cpp new file mode 100644 index 0000000000000000000000000000000000000000..55b5d4340769e45a5c4b41f0909dd0490d262d2e --- /dev/null +++ b/projet-code/scenes_inf443/base/src/bats.cpp @@ -0,0 +1,61 @@ +#include "bats.hpp" +#include "environment.hpp" +#include "key_positions_structure.hpp" +#include "interpolation.hpp" +#include "terrain.hpp" + +void bats::initialize_bats() +{ + // Initialize the temporary mesh_drawable that will be inserted in the hierarchy + mesh_drawable body; + mesh_drawable wing1; + mesh_drawable wing2; + + // Create the geometry of the meshes + // Note: this geometry must be set in their local coordinates with respect to their position in the hierarchy (and with respect to their animation) + body.initialize_data_on_gpu(mesh_load_file_obj(project::path + "assets/batbodyok.obj")); + wing1.initialize_data_on_gpu(mesh_load_file_obj(project::path + "assets/batwingleft.obj")); + wing2.initialize_data_on_gpu(mesh_load_file_obj(project::path + "assets/batwingright.obj")); + + // Scale the model + //body.model.scaling = 0.2f; + //wing1.model.scaling = 0.2f; + //wing2.model.scaling = 0.2f; + + // Set the color of some elements + body.material.color = { 0.3f,0.3f,0.3f }; + wing1.material.color = { 0.2f,0.2f,0.2f }; + wing2.material.color = { 0.2f,0.2f,0.2f }; + + // Add the elements in the hierarchy + // The syntax is hierarchy.add(mesh_drawable, "name of the parent element", [optional: local translation in the hierarchy]) + // Notes: + // - An element must necessarily be added after its parent + // - The first element (without explicit name of its parent) is assumed to be the root. + + bat_mesh.add(body, "Bat base"); + bat_mesh.add(wing1, "Bat wing left1", "Bat base"); + bat_mesh.add(wing2, "Bat wing right1", "Bat base"); + + N = 0; +} + +void bats::update_mvt() +{ + for (int i = 0; i < N; i++) { + bats_prop[i].update_mvt(); + } +} + + +void bats::add_bat(vec3 new_pos, float _size, numarray<vec3> key_positions, numarray<float> key_times) { + N++; + bats_prop.resize(N); + + bats_prop[N - 1].pos = new_pos; + bats_prop[N - 1].isdead = false; + bats_prop[N - 1].size = _size; + bats_prop[N - 1].initialize_mvt(new_pos, key_positions, key_times); + +} + diff --git a/projet-code/scenes_inf443/base/src/bats.hpp b/projet-code/scenes_inf443/base/src/bats.hpp new file mode 100644 index 0000000000000000000000000000000000000000..0b3f147fbf61e1db23f4dd667c72dfc304eca58d --- /dev/null +++ b/projet-code/scenes_inf443/base/src/bats.hpp @@ -0,0 +1,21 @@ +#pragma once + +#include "cgp/cgp.hpp" +#include "key_positions_structure.hpp" +#include "bat.hpp" + +using namespace cgp; + +// The entire hierarchy + +struct bats{ + cgp::hierarchy_mesh_drawable bat_mesh; + + int N; + + std::vector<bat> bats_prop; + + void initialize_bats(); + void add_bat(vec3 new_pos, float _size, numarray<vec3> key_positions, numarray<float> key_times); + void update_mvt(); +}; \ No newline at end of file diff --git a/projet-code/scenes_inf443/base/src/projectile.cpp b/projet-code/scenes_inf443/base/src/projectile.cpp index cdb6ced6bc719b813fb24e1fdee3514396429a05..58c7c008430ac94ec381d179f881bb4fa3fba093 100644 --- a/projet-code/scenes_inf443/base/src/projectile.cpp +++ b/projet-code/scenes_inf443/base/src/projectile.cpp @@ -1,67 +1,22 @@ #include "projectile.hpp" #include "terrain.hpp" +#include "settings.hpp" -void projectile::initialize() -{ - N = 0; - pos.resize(N); - v.resize(N); - color.resize(N); - elemental_types.resize(N); - mesh.initialize_data_on_gpu(mesh_primitive_sphere(0.1f)); - - -} - -void projectile::reset() { - N = 0; - pos.resize(N); - v.resize(N); - color.resize(N); -} - -void projectile::add_ball(vec3 new_pos, vec3 new_dir) { - N++; - pos.resize(N); - v.resize(N); - color.resize(N); - elemental_types.resize(N); - - - pos[N-1] = new_pos; - v[N-1] = new_dir; - elemental_types[N - 1] = types[N%5]; - if (elemental_types[N - 1] == projectile_type::fire) { - color[N - 1] = {0.886, 0.345, 0.133}; - }else if (elemental_types[N - 1] == projectile_type::ice) { - color[N - 1] = {1,1,1}; - }else if (elemental_types[N - 1] == projectile_type::rock) { - color[N - 1] = {0.3,0.22,0.2}; - }else if (elemental_types[N - 1] == projectile_type::electric) { - color[N - 1] = {1, 1, 0.2 }; - }else if (elemental_types[N - 1] == projectile_type::water) { - color[N - 1] = {0, 0, 1 }; +void projectile::simulateParabolic(float dt) { + if (pos[2] < -1 || cgp::abs(pos[0]) > terrain_length() / 2 || cgp::abs(pos[1]) > terrain_length() / 2) { + pos = { 0,0, evaluate_terrain_height(0,0) }; + v = { 3 * rand_interval(), 3 * rand_interval(), 4}; + } + else { + pos += v * dt; + v[2] -= 10 * dt; } -} - -void projectile::simulate(float dt, float terrain_length) { - for (int i = 0; i < N; i++) { - if (pos[i][2] < -1 || cgp::abs(pos[i][0]) > terrain_length / 2 || cgp::abs(pos[i][1]) > terrain_length / 2) { - pos[i] = { 0,0, evaluate_terrain_height(0,0, terrain_length) }; - v[i] = { 3 * rand_interval(), 3 * rand_interval(), 4 + i }; - } - else { - pos[i] += v[i] * dt; - v[i][2] -= 10 * dt; - } - - if (pos[i][2] < evaluate_terrain_height(pos[i][0], pos[i][1], terrain_length)) { - pos[i] = { 0, 0, -1}; - v[i] = { 0,0,0 }; - } + if (pos[2] < evaluate_terrain_height(pos[0], pos[1])) { + pos = { 0, 0, -1}; + v = { 0,0,0 }; } } diff --git a/projet-code/scenes_inf443/base/src/projectile.hpp b/projet-code/scenes_inf443/base/src/projectile.hpp index dea718ed40c75a50ea2b2cbe94d40eb027498ac2..ad67623be153160770dab116f402f9177a9f6629 100644 --- a/projet-code/scenes_inf443/base/src/projectile.hpp +++ b/projet-code/scenes_inf443/base/src/projectile.hpp @@ -5,22 +5,16 @@ using namespace cgp; struct projectile { - int N; - - std::vector<vec3> v; - std::vector<vec3> pos; - std::vector<vec3> color; - - - mesh_drawable mesh; - - enum class projectile_type {fire, ice, electric, rock, water}; - std::vector<projectile_type> elemental_types; - - std::vector<projectile_type> types = { projectile_type::fire, projectile_type::ice, projectile_type::rock, projectile_type::electric, projectile_type::water }; - - void initialize(); - void simulate(float dt, float terrain_length); - void add_ball(vec3 new_pos, vec3 new_dir); - void reset(); + vec3 v; + vec3 pos; + vec3 color; + float size; + + //projectile types, in global so projectiles also can access it + enum class projectile_type { fire, ice, electric, rock, water }; + //for ease of use + std::vector<projectile_type> el_types = { projectile_type::fire, projectile_type::ice, projectile_type::rock, projectile_type::electric, projectile_type::water }; + projectile_type elemental_type; + + void simulateParabolic(float dt); }; diff --git a/projet-code/scenes_inf443/base/src/projectiles.cpp b/projet-code/scenes_inf443/base/src/projectiles.cpp new file mode 100644 index 0000000000000000000000000000000000000000..84c2b82bd6df4a5f08c8af96a5fc849a5611a138 --- /dev/null +++ b/projet-code/scenes_inf443/base/src/projectiles.cpp @@ -0,0 +1,43 @@ +#include "projectiles.hpp" +#include "terrain.hpp" + +void projectiles::initialize() +{ + N = 0; + projectiles_prop.resize(N); + + mesh.initialize_data_on_gpu(mesh_primitive_sphere(0.1f)); +} + +void projectiles::reset() { + N = 0; + projectiles_prop.resize(N); +} + +void projectiles::add_ball(vec3 new_pos, vec3 new_dir) { + N++; + projectiles_prop.resize(N); + + projectiles_prop[N - 1].pos = new_pos; + projectiles_prop[N - 1].v = new_dir; + projectiles_prop[N - 1].elemental_type = el_types[N%5]; + if (projectiles_prop[N - 1].elemental_type == projectile::projectile_type::fire) { + projectiles_prop[N - 1].color = {0.886, 0.345, 0.133}; + }else if (projectiles_prop[N - 1].elemental_type == projectile::projectile_type::ice) { + projectiles_prop[N - 1].color = {1,1,1}; + }else if (projectiles_prop[N - 1].elemental_type == projectile::projectile_type::rock) { + projectiles_prop[N - 1].color = {0.3,0.22,0.2}; + }else if (projectiles_prop[N - 1].elemental_type == projectile::projectile_type::electric) { + projectiles_prop[N - 1].color = {1, 1, 0.2 }; + }else if (projectiles_prop[N - 1].elemental_type == projectile::projectile_type::water) { + projectiles_prop[N - 1].color = {0, 0, 1 }; + } + +} + +void projectiles::simulate(float dt) { + for (int i = 0; i < N; i++) { + projectiles_prop[i].simulateParabolic(dt); + } +} + diff --git a/projet-code/scenes_inf443/base/src/projectiles.hpp b/projet-code/scenes_inf443/base/src/projectiles.hpp new file mode 100644 index 0000000000000000000000000000000000000000..10bb78e04112e5c3616c830f2ddfa9401f2fff3b --- /dev/null +++ b/projet-code/scenes_inf443/base/src/projectiles.hpp @@ -0,0 +1,22 @@ +#pragma once + +#include "cgp/cgp.hpp" +#include "projectile.hpp" + +using namespace cgp; + + +struct projectiles { + int N; + + std::vector<projectile> projectiles_prop; + + std::vector<projectile::projectile_type> el_types = { projectile::projectile_type::fire, projectile::projectile_type::ice, projectile::projectile_type::rock, projectile::projectile_type::electric, projectile::projectile_type::water }; + + mesh_drawable mesh; + + void initialize(); + void simulate(float dt); + void add_ball(vec3 new_pos, vec3 new_dir); + void reset(); +}; diff --git a/projet-code/scenes_inf443/base/src/scene.cpp b/projet-code/scenes_inf443/base/src/scene.cpp index a8a94b6fc421d76ac81d3a36f82bc549d2642f9c..42b330bacb66ac884acce5c14d5e42fff4c4eb48 100644 --- a/projet-code/scenes_inf443/base/src/scene.cpp +++ b/projet-code/scenes_inf443/base/src/scene.cpp @@ -8,17 +8,16 @@ #include "terrain.hpp" #include "projectile.hpp" #include "sapin.hpp" +#include "settings.hpp" using namespace cgp; -int num_trees = 200; -int num_grass = 200; + std::vector<vec3> tree_position; std::vector<vec3> grass_position; -float terrain_length = 250; void scene_structure::initialize() { - + //CAMERA camera_control.initialize(inputs, window); // Give access to the inputs and window global state to the camera controler //for orbit camera @@ -26,11 +25,13 @@ void scene_structure::initialize() //camera_control.look_at({ 20.0f,15.0f,15.0f }, {0,0,0}); //for first person camera - camera_control.camera_model.position_camera = { 0,0,evaluate_terrain_height(0,0,terrain_length)+10}; + camera_control.camera_model.position_camera = { 0,0,evaluate_terrain_height(0,0)+10}; camera_control.camera_model.set_rotation_axis({ 0,0,1 }); //custum function we added to ..first_person_euler global_frame.initialize_data_on_gpu(mesh_primitive_frame()); + + //SKYBOX //skybox_debug.png for debugging image_structure image_skybox_template = image_load_file("assets/skybox2.jpg"); std::vector<image_structure> image_grid = image_split_grid(image_skybox_template, 4, 3); @@ -45,8 +46,10 @@ void scene_structure::initialize() + + //TERRAIN int N_terrain_samples = 500; - mesh const terrain_mesh = create_terrain_mesh(N_terrain_samples, terrain_length); + mesh const terrain_mesh = create_terrain_mesh(N_terrain_samples); terrain.initialize_data_on_gpu(terrain_mesh); // terrain.material.color = { 0.6f,0.85f,0.5f }; terrain de couleur de base verte terrain.material.color = { 1,1,1 }; @@ -60,6 +63,8 @@ void scene_structure::initialize() GL_REPEAT, GL_MIRRORED_REPEAT); + + //OBJECTS int r = 1; int h = 5; mesh cyl_mesh = create_cylinder_mesh(r, h); @@ -81,12 +86,12 @@ void scene_structure::initialize() float x = 1.0; float y = 2.0; - tree.model.translation = { x, y, evaluate_terrain_height(x,y, terrain_length) }; + tree.model.translation = { x, y, evaluate_terrain_height(x,y) }; - tree_position = generate_positions_on_terrain(num_trees, terrain_length-1); + tree_position = generate_positions_on_terrain(num_trees()); - grass_position = generate_positions_on_terrain(num_grass, terrain_length-1); + grass_position = generate_positions_on_terrain(num_grass()); mesh quadrangle_mesh; quadrangle_mesh.position = { {0,0,0},{1, 0, 0}, {1,0,1}, {0, 0,1} }; quadrangle_mesh.uv = { {0,0},{1,0}, {1,1}, {0,1} }; @@ -98,49 +103,27 @@ void scene_structure::initialize() GL_CLAMP_TO_BORDER, GL_CLAMP_TO_BORDER); - bird1.initialize_bird(); - //initialize_mvt(); chain1.initialize(); bouncing.initialize(10); //10 balls - bat1.initialize_bat(); - bat1.add_bat({0,0,0}, terrain_length); - projectiles.initialize(); - sapin1.initialize_sapin(); - sapin1.sapin["Trunk"].transform_local.rotation = rotation_transform::from_axis_angle({ 1,0,0 }, Pi / 2); -} - -/* -void scene_structure::initialize_mvt() -{ - // Definition of the initial data - //--------------------------------------// - - // Key 3D positions - numarray<vec3> key_positions = - { {-1,1,0}, {0,1,0}, {1,1,0}, {1,2,0}, {2,2,0}, {2,2,1}, {2,0,1.5}, {1.5,-1,1}, {1.5,-1,0}, {1,-1,0}, {0,-0.5,0}, {-1,1,0} }; - float h = 20+evaluate_terrain_height(0,0,terrain_length); - for (int i = 0; i < key_positions.size(); i++) key_positions[i][2] += h; + bats.initialize_bats(); - // Key times (time at which the position must pass in the corresponding position) - numarray<float> key_times = - { 0.0f, 1.0f, 2.0f, 2.5f, 3.0f, 3.5f, 3.75f, 4.5f, 5.0f, 6.0f, 7.0f, 8.0f }; - - // Initialize the helping structure to display/interact with these positions - keyframe.initialize(key_positions, key_times); - - - // Set timer bounds - // The timer must span a time interval on which the interpolation can be conducted - // By default, set the minimal time to be key_times[1], and the maximal time to be key_time[N-2] (enables cubic interpolation) - int N = key_times.size(); - timer_mvt.t_min = key_times[0]; - timer_mvt.t_max = key_times[N - 1]; - timer_mvt.t = timer_mvt.t_min; + vec3 bat_pos1 = { 0,0,evaluate_terrain_height(0,0) + 20 }; + float bat_size1 = 0.2f; + numarray<vec3> bat_keypos1 = { {-1,1,0}, {0,1,0}, {1,1,0}, {1,2,0}, {2,2,0}, {2,2,1}, {2,0,1.5}, {1.5,-1,1}, {1.5,-1,0}, {1,-1,0}, {0,-0.5,0}, {-1,1,0} }; + numarray<float> bat_keytimes1 = { 0.0f, 1.0f, 2.0f, 2.5f, 3.0f, 3.5f, 3.75f, 4.5f, 5.0f, 6.0f, 7.0f, 8.0f }; + bats.add_bat(bat_pos1, bat_size1, bat_keypos1, bat_keytimes1); + + vec3 bat_pos2 = { 5,5,evaluate_terrain_height(0,0) + 10 }; + float bat_size2 = 0.3f; + numarray<vec3> bat_keypos2 = { {-1,1,0}, {0,1,0}, {1,1,0}, {1,2,0}, {2,2,0}, {2,2,1}, {2,0,1.5}, {1.5,-1,1}, {1.5,-1,0}, {1,-1,0}, {0,-0.5,0}, {-1,1,0} }; + numarray<float> bat_keytimes2 = { 0.0f, 1.0f, 2.0f, 2.5f, 3.0f, 3.5f, 3.75f, 4.5f, 5.0f, 6.0f, 7.0f, 8.0f }; + bats.add_bat(bat_pos2, bat_size2, bat_keypos2, bat_keytimes2); + projectiles.initialize(); + sapin1.initialize_sapin(); + sapin1.sapin["Trunk"].transform_local.rotation = rotation_transform::from_axis_angle({ 1,0,0 }, Pi / 2); } -*/ - void scene_structure::display_frame() { @@ -155,7 +138,7 @@ void scene_structure::display_frame() //Walking on ground if (!gui.fly) { vec3 eye_level = camera_control.camera_model.position_camera; - eye_level[2] = evaluate_terrain_height(eye_level[0], eye_level[1], terrain_length) + 0.75; + eye_level[2] = evaluate_terrain_height(eye_level[0], eye_level[1]) + 0.75; camera_control.camera_model.position_camera = eye_level; } @@ -169,7 +152,7 @@ void scene_structure::display_frame() if (gui.display_wireframe) draw_wireframe(terrain, environment); - for (int i = 0; i < num_trees; i++) { + for (int i = 0; i < num_trees(); i++) { //tree.model.translation = tree_position[i]; //draw(tree, environment); sapin1.sapin["Trunk"].transform_local.translation = tree_position[i]; @@ -180,7 +163,7 @@ void scene_structure::display_frame() //display_bird(p); //display_chain(p); display_ball(); - display_bat(); + display_bats(); display_projectiles(); @@ -191,71 +174,30 @@ void scene_structure::display_frame() } -/* -void scene_structure::display_bird(vec3 p) -{ - // Apply transformation to some elements of the hierarchy - bird1.bird["Bird head"].transform_local.rotation = rotation_transform::from_axis_angle({ 0,1,0 }, 0.3 * cos(timer.t)); - bird1.bird["Bird wing left1"].transform_local.rotation = rotation_transform::from_axis_angle({ 1,0,0 }, 0.5 * cos(5 * timer.t)); - bird1.bird["Bird wing left2"].transform_local.rotation = rotation_transform::from_axis_angle({ 1,0,0 }, 0.7 * cos(5 * timer.t)); - bird1.bird["Bird wing right1"].transform_local.rotation = rotation_transform::from_axis_angle({ 1,0,0 }, -0.5 * cos(5 * timer.t)); - bird1.bird["Bird wing right2"].transform_local.rotation = rotation_transform::from_axis_angle({ 1,0,0 }, -0.7 * cos(5 * timer.t)); - - - // This function must be called before the drawing in order to propagate the deformations through the hierarchy - bird1.bird.update_local_to_global_coordinates(); - - //Orientation and position of the bird along the path - float t = timer_mvt.t; - vec3 p2; - if(t+0.1f > timer_mvt.t_max) p2 = interpolation(0.01f, keyframe.key_positions, keyframe.key_times, gui.k); - else p2 = interpolation((t + 0.1f), keyframe.key_positions, keyframe.key_times, gui.k); - bird1.bird["Bird base"].transform_local.rotation = rotation_transform::from_vector_transform({1,0,0}, normalize(p2 - p)); - bird1.bird["Bird base"].transform_local.translation = p; - - /* Exemple TD5 - hierarchy["Cylinder1"].transform_local.rotation = rotation_transform::from_axis_angle({ 0,0,1 }, timer.t); - hierarchy["Cube1"].transform_local.rotation = rotation_transform::from_axis_angle({ 1,0,0 }, -3 * timer.t); - hierarchy["Cyl2"].transform_local.rotation = rotation_transform::from_axis_angle({ 0,0,1 }, 6 * timer.t); - hierarchy["Cyl3"].transform_local.rotation = rotation_transform::from_axis_angle({ 0,0,1 }, 6 * timer.t); - hierarchy["Cube base"].transform_local.rotation = rotation_transform::from_axis_angle({ 1,0,0 }, 0.8 * cos(3 * timer.t)); - - hierarchy.update_local_to_global_coordinates(); - - - draw(bird1.bird, environment); - if (gui.display_wireframe) { - //draw_wireframe(hierarchy, environment); - draw_wireframe(bird1.bird, environment); - } - - -} -*/ - -void scene_structure::display_bat() +void scene_structure::display_bats() { - // Apply transformation to some elements of the hierarchy - bat1.bat["Bat wing left1"].transform_local.rotation = rotation_transform::from_axis_angle({ 0,1,0 }, 0.5 * cos(5 * timer.t)); - bat1.bat["Bat wing right1"].transform_local.rotation = rotation_transform::from_axis_angle({ 0,1,0 }, -0.5 * cos(5 * timer.t)); - + bats.update_mvt(); - // This function must be called before the drawing in order to propagate the deformations through the hierarchy - bat1.bat.update_local_to_global_coordinates(); - - bat1.display_mvt(); - for (int m = 0; m < bat1.N; m++) { + for (int i = 0; i < bats.N; i++) { + //Wing animation + bats.bat_mesh["Bat wing left1"].transform_local.rotation = rotation_transform::from_axis_angle({ 0,1,0 }, 0.5 * cos(5 * bats.bats_prop[i].timer_mvt.t)); + bats.bat_mesh["Bat wing right1"].transform_local.rotation = rotation_transform::from_axis_angle({ 0,1,0 }, -0.5 * cos(5 * bats.bats_prop[i].timer_mvt.t)); //Rescale - bat1.bat["Bat base"].drawable.model.scaling = bat1.size[m]; - bat1.bat["Bat wing left1"].drawable.model.scaling = bat1.size[m]; - bat1.bat["Bat wing right1"].drawable.model.scaling = bat1.size[m]; + bats.bat_mesh["Bat base"].drawable.model.scaling = bats.bats_prop[i].size; + bats.bat_mesh["Bat wing left1"].drawable.model.scaling = bats.bats_prop[i].size; + bats.bat_mesh["Bat wing right1"].drawable.model.scaling = bats.bats_prop[i].size; + //Make sure wings are at the right distance + bats.bat_mesh["Bat wing left1"].transform_local.translation = { -0.25f * bats.bats_prop[i].size, 0, 0 }; + bats.bat_mesh["Bat wing right1"].transform_local.translation = { 0.25f * bats.bats_prop[i].size, 0, 0 }; + //Orientation and position of the bat along the path - bat1.bat["Bat base"].transform_local.rotation = rotation_transform::from_vector_transform({ 0,-1,0 }, normalize(bat1.pos2[m] - bat1.pos[m])); - bat1.bat["Bat base"].transform_local.translation = bat1.pos[m]; + bats.bat_mesh["Bat base"].transform_local.rotation = rotation_transform::from_vector_transform({ 0,-1,0 }, normalize(bats.bats_prop[i].pos_futur - bats.bats_prop[i].pos)); + bats.bat_mesh["Bat base"].transform_local.translation = bats.bats_prop[i].pos; - if (!bat1.isdead[m]) draw(bat1.bat, environment); + bats.bat_mesh.update_local_to_global_coordinates(); + if (!bats.bats_prop[i].isdead) draw(bats.bat_mesh, environment); if (gui.display_wireframe) { - draw_wireframe(bat1.bat, environment); + draw_wireframe(bats.bat_mesh, environment); } } } @@ -280,7 +222,7 @@ void scene_structure::display_semiTransparent() vec3 const right = camera.right(); // Rotation such that the grass follows the right-vector of the camera, while pointing toward the z-direction - for (int i = 0; i < num_grass; i++) { + for (int i = 0; i < num_grass(); i++) { grass.model.translation = grass_position[i]; rotation_transform R = rotation_transform::from_frame_transform({ 1,0,0 }, { 0,0,1 }, right, { 0,0,1 }); grass.model.rotation = R; @@ -292,33 +234,6 @@ void scene_structure::display_semiTransparent() glDisable(GL_BLEND); } - - - -/* -vec3 scene_structure::display_mvt() -{ - - // Update the current time - timer_mvt.update(); - float t = timer_mvt.t; - - // clear trajectory when the timer restart - if (t < timer_mvt.t_min + 0.1f) - keyframe.trajectory.clear(); - - // Display the key positions and lines b/w positions - keyframe.display_key_positions(environment); - - // Compute the interpolated position - // This is this function that you need to complete - return interpolation(t, keyframe.key_positions, keyframe.key_times, gui.k); - - // Display the interpolated position (and its trajectory) - //keyframe.display_current_position(p, environment); -} -*/ - void scene_structure::draw_segment(vec3 const& a, vec3 const& b) { chain1.segment.vbo_position.update(numarray<vec3>{ a, b }); @@ -363,7 +278,7 @@ void scene_structure::display_gui() void scene_structure::display_ball() { - bouncing.simulate(timer.scale * 0.01f, terrain_length); + bouncing.simulate(timer.scale * 0.01f); for (int i = 0; i < bouncing.N; i++) { bouncing.mesh.model.translation = bouncing.pos[i]; bouncing.mesh.material.color = bouncing.color[i]; @@ -373,10 +288,10 @@ void scene_structure::display_ball() { void scene_structure::display_projectiles() { - projectiles.simulate(timer.scale * 0.03f, terrain_length); + projectiles.simulate(timer.scale * 0.03f); for (int i = 0; i < projectiles.N; i++) { - projectiles.mesh.model.translation = projectiles.pos[i]; - projectiles.mesh.material.color = projectiles.color[i]; + projectiles.mesh.model.translation = projectiles.projectiles_prop[i].pos; + projectiles.mesh.material.color = projectiles.projectiles_prop[i].color; draw(projectiles.mesh, environment); } } diff --git a/projet-code/scenes_inf443/base/src/scene.hpp b/projet-code/scenes_inf443/base/src/scene.hpp index 3e65910e1abe05cc0337fdab0846a6fb12ab57a9..a92f82595839cee464a489f0be79ba413e53eb0a 100644 --- a/projet-code/scenes_inf443/base/src/scene.hpp +++ b/projet-code/scenes_inf443/base/src/scene.hpp @@ -7,8 +7,8 @@ #include "ball.hpp" #include "bird.hpp" #include "chain.hpp" -#include "bat.hpp" -#include "projectile.hpp" +#include "bats.hpp" +#include "projectiles.hpp" #include "sapin.hpp" @@ -58,11 +58,6 @@ struct scene_structure : cgp::scene_inputs_generic { cgp::mesh_drawable cone; cgp::mesh_drawable tree; cgp::mesh_drawable grass; - - - - - // Timer used for the animation timer_basic timer_chain; @@ -70,8 +65,8 @@ struct scene_structure : cgp::scene_inputs_generic { ball bouncing; bird bird1; chain chain1; - bat bat1; - projectile projectiles; + bats bats; + projectiles projectiles; sapin sapin1; // ****************************** // @@ -82,12 +77,9 @@ struct scene_structure : cgp::scene_inputs_generic { void display_frame(); // The frame display to be called within the animation loop void display_gui(); // The display of the GUI, also called within the animation loop void display_semiTransparent(); - void display_chain(vec3 bird_pos); - void display_bird(vec3 p); - void display_bat(); - - void initialize_mvt(); - vec3 display_mvt(); + void display_chain(vec3 end_pos); + //void display_bird(vec3 p); + void display_bats(); void mouse_move_event(); void mouse_click_event(); diff --git a/projet-code/scenes_inf443/base/src/terrain.cpp b/projet-code/scenes_inf443/base/src/terrain.cpp index 13f56bf46e6fc2f76c3f2f3f035c8ddcc9d999ef..739a9ab8af521eb7647c3898618627c814a3bafe 100644 --- a/projet-code/scenes_inf443/base/src/terrain.cpp +++ b/projet-code/scenes_inf443/base/src/terrain.cpp @@ -1,12 +1,11 @@ - #include "terrain.hpp" - +#include "settings.hpp" using namespace cgp; // Evaluate 3D position of the terrain for any (x,y) -float evaluate_terrain_height(float x, float y, float terrain_length) +float evaluate_terrain_height(float x, float y) { //p, h, sigma -> positions, heights and wideness of bell curves vec2 p[] = { {-10, -10}, {5, 5}, {-3, 4}, {6, 4} }; @@ -24,15 +23,14 @@ float evaluate_terrain_height(float x, float y, float terrain_length) parameters.frequency_gain = 2.4; parameters.persistency = 0.33; - - float perlin_noise = parameters.terrain_height * noise_perlin(vec2(3*x / terrain_length, 3*y / terrain_length), parameters.octave, parameters.persistency, parameters.frequency_gain); + float perlin_noise = parameters.terrain_height * noise_perlin(vec2(3*x / terrain_length(), 3 * y / terrain_length()), parameters.octave, parameters.persistency, parameters.frequency_gain); return perlin_noise; } -mesh create_terrain_mesh(int N, float terrain_length) +mesh create_terrain_mesh(int N) { mesh terrain; // temporary terrain storage (CPU only) @@ -58,18 +56,18 @@ mesh create_terrain_mesh(int N, float terrain_length) float v = kv/(N-1.0f); // Compute the real coordinates (x,y) of the terrain in [-terrain_length/2, +terrain_length/2] - float x = (u - 0.5f) * terrain_length; - float y = (v - 0.5f) * terrain_length; + float x = (u - 0.5f) * terrain_length(); + float y = (v - 0.5f) * terrain_length(); // Compute the surface height function at the given sampled coordinate - float z = evaluate_terrain_height(x,y, terrain_length); + float z = evaluate_terrain_height(x,y); // Store vertex coordinates terrain.position[kv+N*ku] = {x,y,z}; terrain.uv[kv+N*ku] = {x,y}; //blending parameter for color - perlin_noise = parameters.terrain_height * noise_perlin(vec2(3 * x / terrain_length, 3 * y / terrain_length), parameters.octave, parameters.persistency, parameters.frequency_gain); + perlin_noise = parameters.terrain_height * noise_perlin(vec2(3 * x / terrain_length(), 3 * y / terrain_length()), parameters.octave, parameters.persistency, parameters.frequency_gain); float b = std::min(1.0, exp((z + perlin_noise - 20) / 2) / exp(6)); terrain.color[kv + N * ku] = std::max(0.0f,(1-b))*vec3(0,0.3f,0) + b * 1.5 * vec3(1, 1, 1); @@ -98,14 +96,14 @@ mesh create_terrain_mesh(int N, float terrain_length) return terrain; } -std::vector<cgp::vec3> generate_positions_on_terrain(int N, float terrain_length) { +std::vector<cgp::vec3> generate_positions_on_terrain(int N) { std::vector<vec3> rand_pos; float x, y; - float d = terrain_length / 2.0f; + float d = terrain_length() / 2.0f; for (int i = 0; i < N; i++) { x = rand_interval(-d, d); y = rand_interval(-d, d); - rand_pos.push_back({ x,y, evaluate_terrain_height(x, y, terrain_length) }); + rand_pos.push_back({ x,y, evaluate_terrain_height(x, y) }); } return rand_pos; diff --git a/projet-code/scenes_inf443/base/src/terrain.hpp b/projet-code/scenes_inf443/base/src/terrain.hpp index 96f8be2b972e2a9996042d5c16ab7d54f983d5df..9ced8dc623928feee1d2db37bd87d414d95a844f 100644 --- a/projet-code/scenes_inf443/base/src/terrain.hpp +++ b/projet-code/scenes_inf443/base/src/terrain.hpp @@ -10,13 +10,13 @@ struct perlin_noise_parameters float terrain_height = 0.5f; }; -float evaluate_terrain_height(float x, float y, float terrain_length); +float evaluate_terrain_height(float x, float y); /** Compute a terrain mesh The (x,y) coordinates of the terrain are set in [-length/2, length/2]. The z coordinates of the vertices are computed using evaluate_terrain_height(x,y). The vertices are sampled along a regular grid structure in (x,y) directions. The total number of vertices is N*N (N along each direction x/y) */ -cgp::mesh create_terrain_mesh(int N, float length); +cgp::mesh create_terrain_mesh(int N); -std::vector<cgp::vec3> generate_positions_on_terrain(int N, float terrain_length); \ No newline at end of file +std::vector<cgp::vec3> generate_positions_on_terrain(int N); \ No newline at end of file