Newer
Older
#include "scene.hpp"
#include "tree.hpp"
#include "interpolation.hpp"
#include "ball.hpp"
#include "bird.hpp"
#include "terrain.hpp"
using namespace cgp;
int num_trees = 50;
int num_grass = 100;
std::vector<vec3> tree_position;
std::vector<vec3> grass_position;
float terrain_length = 20;
void scene_structure::initialize()
{
camera_control.initialize(inputs, window); // Give access to the inputs and window global state to the camera controler
//for orbit camera
//camera_control.set_rotation_axis_z();
//camera_control.look_at({ 20.0f,15.0f,15.0f }, {0,0,0});
//for first person camera
camera_control.camera_model.set_rotation_axis({ 0,0,1 });
//custum function we added to ..first_person_euler
camera_control.trap_cursor(gui.trap_cursor);
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
global_frame.initialize_data_on_gpu(mesh_primitive_frame());
int N_terrain_samples = 100;
mesh const terrain_mesh = create_terrain_mesh(N_terrain_samples, terrain_length);
terrain.initialize_data_on_gpu(terrain_mesh);
terrain.material.color = { 0.6f,0.85f,0.5f };
terrain.material.phong.specular = 0.0f; // non-specular terrain material
int r = 1;
int h = 5;
mesh cyl_mesh = create_cylinder_mesh(r, h);
cyl.initialize_data_on_gpu(cyl_mesh);
cyl.material.color = { 0.58f,0.294f,0.0f };
cyl.material.phong.specular = 0.0f;
r = 3;
h = 2;
int z = 3;
mesh cone_mesh = create_cone_mesh(r, h, z);
cone.initialize_data_on_gpu(cone_mesh);
cone.material.color = { 0.0f,0.8f,0.0f };
cone.material.phong.specular = 0.0f;
mesh tree_mesh = create_tree();
tree.initialize_data_on_gpu(tree_mesh);
float x = 1.0;
float y = 2.0;
tree.model.translation = { x, y, evaluate_terrain_height(x,y) };
tree_position = generate_positions_on_terrain(num_trees, terrain_length-1);
terrain.texture.load_and_initialize_texture_2d_on_gpu(project::path + "assets/texture_grass.jpg",
GL_REPEAT,
GL_MIRRORED_REPEAT);
grass_position = generate_positions_on_terrain(num_grass, terrain_length-1);
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} };
quadrangle_mesh.connectivity = { {0,1,2}, {0,2,3} };
quadrangle_mesh.fill_empty_field(); // (fill with some default values the other buffers (colors, normals) that we didn't filled before)
// Convert the mesh structure into a mesh_drawable structure
grass.initialize_data_on_gpu(quadrangle_mesh);
grass.texture.load_and_initialize_texture_2d_on_gpu(project::path + "assets/grass.png",
GL_CLAMP_TO_BORDER,
GL_CLAMP_TO_BORDER);
bird1.initialize_bird();
initialize_mvt();
chain1.initialize();
bouncing.initialize();
}
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 = 10.0f;
for (int i = 0; i < key_positions.size(); i++) key_positions[i][2] += h;
// 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;
}
void scene_structure::display_frame()
{
// Update the current time
timer.update();
//custom function we added to ..first_person_eulor, changes whether the cursor is trapped or not
camera_control.trap_cursor(gui.trap_cursor);
vec3 eye_level = camera_control.camera_model.position_camera;
eye_level[2] = evaluate_terrain_height(eye_level[0], eye_level[1]) + 0.75;
camera_control.camera_model.position_camera = eye_level;
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
// Set the light to the current position of the camera
environment.light = camera_control.camera_model.position();
if (gui.display_frame)
draw(global_frame, environment);
draw(terrain, environment);
if (gui.display_wireframe)
draw_wireframe(terrain, environment);
for (int i = 0; i < num_trees; i++) {
tree.model.translation = tree_position[i];
draw(tree, environment);
}
vec3 p = display_mvt();
display_bird(p);
display_chain(p);
display_ball();
if (gui.display_wireframe)
draw_wireframe(tree, environment);
display_semiTransparent();
}
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_semiTransparent()
{
// Enable use of alpha component as color blending for transparent elements
// alpha = current_color.alpha
// new color = previous_color * alpha + current_color * (1-alpha)
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
// Disable depth buffer writing
// - Transparent elements cannot use depth buffer
// - They are supposed to be display from furest to nearest elements
glDepthMask(false);
auto const& camera = camera_control.camera_model;
// Re-orient the grass shape to always face the camera direction
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++) {
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;
draw(grass, environment);
}
// Don't forget to re-activate the depth-buffer write
glDepthMask(true);
glDisable(GL_BLEND);
}
vec3 scene_structure::display_mvt()
{
// Basic elements of the scene
environment.light = camera_control.camera_model.position();
if (gui.display_frame)
draw(global_frame, environment);
// 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 });
draw(chain1.segment, environment);
}
void scene_structure::display_chain(vec3 bird_pos)
{
// Update the current time
timer_chain.update();
chain1.simulation_step(timer_chain.scale * 0.01f, bird_pos);
for (int i = 0; i < chain1.n; i++) {
chain1.particle_sphere.model.translation = chain1.p[i];
chain1.particle_sphere.material.color = { (float)i / chain1.n,(float)i / chain1.n,0 };
draw(chain1.particle_sphere, environment);
}
for (int i = 0; i < chain1.n - 1; i++) {
draw_segment(chain1.p[i], chain1.p[i + 1]);
}
}
void scene_structure::display_gui()
{
ImGui::Checkbox("Frame", &gui.display_frame);
ImGui::Checkbox("Wireframe", &gui.display_wireframe);
ImGui::Checkbox("Trapped Cursor", &gui.trap_cursor);
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
ImGui::SliderFloat("Time", &timer_mvt.t, timer_mvt.t_min, timer_mvt.t_max);
ImGui::SliderFloat("Time scale", &timer_mvt.scale, 0.0f, 2.0f);
ImGui::SliderFloat("K", &gui.k, 0.0f, 10.0f);
// Display the GUI associated to the key position
keyframe.display_gui();
}
void scene_structure::display_ball() {
bouncing.simulate(timer_chain.scale * 0.01f, terrain_length);
for (int i = 0; i < bouncing.N; i++) {
bouncing.mesh.model.translation = bouncing.pos[i];
bouncing.mesh.material.color = bouncing.color[i];
draw(bouncing.mesh, environment);
}
}
void scene_structure::mouse_move_event()
{
if (!inputs.keyboard.shift)
camera_control.action_mouse_move(environment.camera_view);
}
void scene_structure::mouse_click_event()
{
camera_control.action_mouse_click(environment.camera_view);
}
void scene_structure::keyboard_event()
{
camera_control.action_keyboard(environment.camera_view);
}
void scene_structure::idle_frame()
{
camera_control.idle_frame(environment.camera_view);
}