Skip to content
Snippets Groups Projects
Commit 9832a778 authored by Noé's avatar Noé
Browse files

Rassification du code pour projectiles et bats

parent 50420094
No related branches found
No related tags found
No related merge requests found
Showing
with 277 additions and 376 deletions
#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);
}
......@@ -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);
......@@ -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);
}
......@@ -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
#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);
}
#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
#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 };
}
}
......@@ -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);
};
#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);
}
}
#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();
};
......@@ -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);
}
}
......
......@@ -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();
......
#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;
......
......@@ -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
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment