diff --git a/README.md b/README.md index 72f966f..7e35f44 100644 --- a/README.md +++ b/README.md @@ -138,6 +138,10 @@ Le shade final est clampé dans [0, 15] — y compris vers le bas (intensité n ### Sphère (`add_sphere`) +``` +Object3D *add_sphere(Universe *uni, fixed x, fixed y, fixed z, fixed r, int det, uint8_t col, uint8_t wire); +``` + Paramètres : centre local, rayon `r`, détail `det` (nombre de subdivisions). Génère `(det+1) × det` sommets et `det × det × 2` faces. Les normales sont les vecteurs de position unitaires (normales sphériques exactes). @@ -162,24 +166,51 @@ Paramètres : centre local, rayon `r`, hauteur `h`, détail `det`. **Total par cylindre (det=16) :** 2+4×det = 66 sommets, 4×det = 64 faces. ### Boîte / Cube (`add_box`) + +``` +Object3D *add_box(Universe *uni, fixed x, fixed y, fixed z, fixed dx, fixed dy, fixed dz, uint8_t col, uint8_t wire); +``` + Paramètres : centre local, dimensions indépendantes `dx, dy, dz`. Génère 24 sommets (4 par face pour ne pas lisser les arêtes avec Gouraud) et 12 faces. Normales : alignées sur les axes orthogonaux (±X, ±Y, ±Z). ### Cône (`add_cone`) + +``` +Object3D *add_cone(Universe *uni, fixed x, fixed y, fixed z, fixed r, fixed h, int det, uint8_t col, uint8_t wire); +``` + Paramètres : centre local, rayon `r`, hauteur `h`, détail `det`. Dérivé du cylindre, mais la boucle supérieure converge en un point unique avec des sommets dupliqués pour préserver l'interpolation radiale des normales du corps. Ne possède qu'un "fond bas". ### Plan / Grille (`add_plane`) + +``` +Object3D *add_plane(Universe *uni, fixed x, fixed y, fixed z, fixed w, fixed d, int seg_x, int seg_z, uint8_t col, uint8_t wire); +``` + Paramètres : centre local, largeur `w`, profondeur `d`, segments `seg_x`, `seg_z`. Génère une surface plane subdivisée (idéal pour les sols et l'ombrage Gouraud par point). Normales : dirigées vers le haut (+Y). ### Tore (`add_torus`) + +``` +Object3D *add_torus(Universe *uni, fixed x, fixed y, fixed z, fixed r_main, fixed r_tube, int seg_main, int seg_tube, uint8_t col, uint8_t wire); +``` + Paramètres : centre local, rayon principal `r_main`, rayon du tube `r_tube`, subdivisions `seg_main`, `seg_tube`. Génère un anneau ("donut") via deux boucles trigonométriques imbriquées. Excellente primitive de test pour l'éclairage. ### Surface Mathématique (`add_math_surface`) + +``` +Object3D *add_math_surface(Universe *uni, fixed x, fixed y, fixed z, + fixed w, fixed d, int seg_x, int seg_z, + uint8_t col, uint8_t wire, SurfaceFunc func); +``` + Paramètres : similaires au plan, plus un pointeur de fonction `SurfaceFunc`. Cette primitive génère une grille dont la hauteur Y est calculée dynamiquement par la fonction utilisateur passée en paramètre. La fonction utilisateur doit respecter la signature : `fixed ma_fonction(fixed x, fixed z)`. diff --git a/src/main/main.c b/src/main/main.c index 5f6e2fa..d84ec9a 100644 --- a/src/main/main.c +++ b/src/main/main.c @@ -19,19 +19,21 @@ int main(void) { uni->num_verts = uni->num_faces = uni->num_objects = 0; /* --- Ajout des objets : géométrie locale en (0,0,0) --- */ - /* sph = add_sphere(uni, 0, 0, 0, int_to_f(30), 8, COLOR4, 0); if (!sph) { free(uni); return 1; } - set_object_pos(sph,int_to_f(60),0,0); + set_object_pos(sph,int_to_f(70),0,0); //set_object_color(COLOR4); cyl = add_cylinder(uni, 0, 0, 0, int_to_f(20), int_to_f(60), 12, COLOR2, 0); if (!cyl) { free(uni); return 1; } - set_object_pos(cyl,int_to_f(-60),0,0); + set_object_pos(cyl,int_to_f(-70),0,0); //set_object_color(COLOR2); - */ - tmp_obj = add_math_surface(uni, 0, 0, 0, int_to_f(120), int_to_f(120), 30, 30, COLOR2, 0); + tmp_obj = add_box(uni, 0, 0, 0, int_to_f(45), int_to_f(60), int_to_f(70), COLOR1, 0); + + + + // tmp_obj = add_math_surface(uni, 0, 0, 0, int_to_f(120), int_to_f(120), 30, 30, COLOR2, 0); // set_object_pos(tmp_obj, 0, int_to_f(-40), 0); diff --git a/src/part3D/geometry.c b/src/part3D/geometry.c index da26afa..da58e82 100644 --- a/src/part3D/geometry.c +++ b/src/part3D/geometry.c @@ -54,9 +54,39 @@ Object3D *add_box(Universe *uni, fixed x, fixed y, fixed z, fixed dx, fixed dy, fixed nz[6] = {int_to_f(1), -int_to_f(1), 0, 0, 0, 0}; /* Configuration des sommets pour respecter le "face culling" (sens trigo) */ + /* int sx[24] = {-1, 1, 1, -1, 1, -1, -1, 1, -1, 1, 1, -1, -1, -1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1}; int sy[24] = {-1, -1, 1, 1, -1, -1, 1, 1, 1, 1, 1, 1, -1, -1, -1, -1, -1, 1, 1, -1, -1, -1, 1, 1}; int sz[24] = { 1, 1, 1, 1, -1, -1, -1, -1, -1, -1, 1, 1, -1, 1, 1, -1, -1, -1, 1, 1, -1, 1, 1, -1}; + */ + +/* Ordre CCW rigoureux pour que le "back-face culling" affiche les 6 faces */ + int sx[24] = { + -1, 1, 1, -1, /* Face +Z (Avant) */ + 1, -1, -1, 1, /* Face -Z (Arrière) */ + -1, 1, 1, -1, /* Face +Y (Haut) */ + -1, 1, 1, -1, /* Face -Y (Bas) */ + 1, 1, 1, 1, /* Face +X (Droite) */ + -1, -1, -1, -1 /* Face -X (Gauche) */ + }; + + int sy[24] = { + -1, -1, 1, 1, /* Face +Z */ + -1, -1, 1, 1, /* Face -Z */ + 1, 1, 1, 1, /* Face +Y */ + -1, -1, -1, -1, /* Face -Y */ + -1, -1, 1, 1, /* Face +X */ + -1, -1, 1, 1 /* Face -X */ + }; + + int sz[24] = { + 1, 1, 1, 1, /* Face +Z */ + -1, -1, -1, -1, /* Face -Z */ + 1, 1, -1, -1, /* Face +Y */ + -1, -1, 1, 1, /* Face -Y */ + 1, -1, -1, 1, /* Face +X */ + -1, 1, 1, -1 /* Face -X */ + }; if (uni->num_objects >= MAX_OBJECTS) return NULL; if (uni->num_verts + 24 > MAX_VERTEX) return NULL;