Introduction to Ani3D exercises

Download Ani3D exercises

Download any of these archive containing all the necessary codes
assets/download_targz.png Download code_epita_ani3d.tar.gz
(Linux/MacOS)
assets/download_zip.png Download code_epita_ani3d.zip
(Windows)
Side notes:

Introductory scene

The first introductory scene is available in the directory scenes_epita_ani3d/01_introduction/
\(\Rightarrow\) Compile and execute the code of this scene.
Note: If you are not familiar with C++/OpenGL compilation on your system, follow first these instructions to compile the scene: Detailed Installation and Compilation Instructions
Notes on the requirements
Once executed, you should observe a basic scene as seen below.
A camera model is already provided. The camera is defined by a position and an orientation relative to a center around which it can rotate. You should be able to interactively control the parameters of the camera as follow:

General information on the code structure and editing

General structure of the code

Role of the different high level directories

Code editor

The library contains multiples files. Make sure you use a sufficiently advanced (or well parameterized) IDE to have

Use of the code library and program structure

Adding a shape in the scene

We will see an example of creating and adding a shape (a triangulated sphere) in the 3D sphere. This is done in 3 steps using the files scene.cpp and scene.hpp:
mesh_drawable sphere;
mesh sphere_mesh = mesh_primitive_sphere();
sphere.initialize_data_on_gpu(sphere_mesh);
draw(sphere, environment);
> Recompile and run the new code, a white sphere should appear at the origin of the scene.
Note that there is two type of mesh structures in use
In the case of the example:

Modification of the sphere

You can adapt some global parameter attach to the shape such as its material (color, shading), and model matrix (translation, rotation, scaling) in modifying pre-defined variables of the mesh_drawable class. For instance, write in the initialize() function (after the line sphere.initialize_data_on_gpu(...)):
// to add after "sphere.initialize(sphere_mesh, "Sphere");"
sphere.model.scaling = 0.2f; // coordinates are multiplied by 0.2 in the shader
sphere.model.translation = {1,2,0}; // coordinates are offseted by {1,2,0} in the shader
sphere.material.color = { 1,0.5f,0.5f }; // sphere will appear red (r,g,b components in [0,1])
> Re-compile and run again the code to observe the modification.
assets/sphere.jpg
Notes:

Load external mesh

CGP library provides pre-coded basic primitives (spheres, cube, cylinder, cone, etc) via the call "mesh_primitive_xxx". For more complex shapes, you can also load a mesh from an external file (dowloaded file or created from 3D modeler such as Blender) using the obj file loader provided by default.
This example shows the load of a file representing a camel.
mesh_drawable camel;
// mesh_load_file_obj: read a .obj file and return a mesh structure
mesh camel_mesh = mesh_load_file_obj("assets/camel.obj");

// Classical initialization of a mesh_drawable structure
camel.initialize_data_on_gpu(camel_mesh);

// Adjusting size and position of the shape
camel.model.scaling = 0.5f;
camel.model.translation = { -1,1,0.5f };
draw(camel, environment);
assets/camel.jpg

Wireframe draw

It is often usefull to visualize the mesh in wireframe to better understand the triangulation structure and/or debuging. The function draw_wireframe(mesh_drawable, environment) is provided by the library to this end.
Add the following lines in the display_frame() et observe the additional wireframe display.
draw_wireframe(ground, environment);
draw_wireframe(sphere, environment);
draw_wireframe(cube, environment);
draw_wireframe(camel, environment);
assets/camel_wireframe.jpg
Note that the wireframe is displayed in blue color by default. A specific (r,g,b) color can be set when calling the function as in the following:
// Wireframe displayed in red thanks to the third argument {r,g,b}
draw_wireframe(camel, environment, {1,0,0});

Checkbox interface

We will now add a GUI checkbox (button that can be checked) to activate/deactivate the wireframe display of the sphere. The principle is the following:
struct gui_parameters {
    ...
    bool display_wireframe = false;
};
ImGui::Checkbox("Wireframe", &gui.display_wireframe);
if (gui_display_wireframe==true) {
    draw_wireframe(ground, environment);
    draw_wireframe(sphere, environment);
    draw_wireframe(cube, environment);
    draw_wireframe(camel, environment);
}

Placing several similar elements

// (In the scene_structure header)
std::vector<vec3> cone_positions;
mesh_drawable cone;
// (In the initialization function)
cone.initialize_data_on_gpu( mesh_primitive_cone(0.1f, 0.2f) );
const int N_cone = 40;
for (int k = 0; k < N_cone; ++k)
{
    float x = rand_interval(-2, 2);
    float z = rand_interval(-2, 2);

    cone_positions.push_back( {x,-1,z} );
}
// (In the display_frame function)
for (int k = 0; k < cone_positions.size(); ++k)
{
    cone.model.translation = cone_positions[k];
    draw(cone, environment);
}
Display the scene and observe the result (you should see a set of cones on the floor)
Note that

Exercise