diff --git a/README.md b/README.md index a9842a1..a232bc0 100644 --- a/README.md +++ b/README.md @@ -274,7 +274,7 @@ Particulièrement utile pour orienter une primitive lors de l'initialisation (ex --- -## Orbite de l'observateur (`main.c`) +## Orbite et distance (`main.c`) Les objets ont des positions de base fixes dans l'espace scène, définies par rapport au centre `(0, 0, 300)` : @@ -283,13 +283,13 @@ Les objets ont des positions de base fixes dans l'espace scène, définies par r | Sphère (universe[0]) | (+60, 0, 0) | | Cylindre (universe[1]) | (−60, 0, 0) | -Chaque frame, la matrice d'orbite `orbit = rotX(anglex) × rotY(angley)` est calculée et appliquée uniformément à chaque objet (transform 3D complet sur `base_pos`) : +Chaque frame, la matrice d'orbite `orbit = rotX(anglex) × rotY(angley)` est calculée et appliquée uniformément à chaque objet (transform 3D complet sur `base_pos`). La distance (initialement 300) peut être modifiée : ```c obj->rot = orbit; obj->pos.x = f_mul(bx, orbit.m[0][0]) + f_mul(by, orbit.m[1][0]) + f_mul(bz, orbit.m[2][0]); obj->pos.y = f_mul(bx, orbit.m[0][1]) + f_mul(by, orbit.m[1][1]) + f_mul(bz, orbit.m[2][1]); -obj->pos.z = int_to_f(300) + f_mul(bx, orbit.m[0][2]) + f_mul(by, orbit.m[1][2]) + f_mul(bz, orbit.m[2][2]); +obj->pos.z = distance + f_mul(bx, orbit.m) + f_mul(by, orbit.m) + f_mul(bz, orbit.m); ``` Les trois composantes de `base_pos` (bx, by, bz) sont toutes prises en compte — les objets à `base_pos.y != 0` ou `base_pos.z != 0` sont correctement transformés. @@ -305,13 +305,13 @@ La caméra reste à l'origine (+ translations clavier). L'effet visuel est celui | Z / S | Caméra avance / recule (axe Z) | | Q / D | Caméra gauche / droite (axe X) | | A / E | Caméra haut / bas (axe Y) | -| + / − | Orbite vertical (anglex ±3°) | -| / / * | Orbite horizontal (angley ±3°) | -| 1 / 2 / 3 | Mode fil-de-fer / caché / solide | +| Flèche Haut / Bas | Orbite vertical (anglex ±3°) | +| Flèche Gauche / Droite | Orbite horizontal (angley ±3°) | +| F1 / F2 / F3 | Mode fil-de-fer / caché / solide | | R | Reset caméra + angles | | Esc | Quitter | -Les touches étendues (F1–F12, flèches…) retournent `0` depuis `getch()` ; le scan code suivant est consommé sans effet. +Les touches étendues (F1–F12, flèches…) retournent `0` depuis `getch()` ; le scan code suivant est alors consommé pour identifier la touche spéciale. --- diff --git a/WORKDOC.md b/WORKDOC.md index 244ebb7..39f880f 100644 --- a/WORKDOC.md +++ b/WORKDOC.md @@ -193,7 +193,7 @@ add_math_surface(uni, 0, 0, 0, int_to_f(120), int_to_f(120), 30, 30, COLOR6, 0, --- -## Orbite de l'observateur (`main.c`) +## Orbite et distance (`main.c`) Les objets ont des positions de base fixes dans l'espace scène, définies par rapport au centre `(0, 0, 300)` : @@ -202,13 +202,13 @@ Les objets ont des positions de base fixes dans l'espace scène, définies par r | Sphère (universe[0]) | (+60, 0, 0) | | Cylindre (universe[1]) | (−60, 0, 0) | -Chaque frame, la matrice d'orbite `orbit = rotX(anglex) × rotY(angley)` est calculée et appliquée uniformément à chaque objet (transform 3D complet sur `base_pos`) : +Chaque frame, la matrice d'orbite `orbit = rotX(anglex) × rotY(angley)` est calculée et appliquée uniformément à chaque objet (transform 3D complet sur `base_pos`). La distance (initialement 300) peut être modifiée : ```c obj->rot = orbit; obj->pos.x = f_mul(bx, orbit.m[0][0]) + f_mul(by, orbit.m[1][0]) + f_mul(bz, orbit.m[2][0]); obj->pos.y = f_mul(bx, orbit.m[0][1]) + f_mul(by, orbit.m[1][1]) + f_mul(bz, orbit.m[2][1]); -obj->pos.z = int_to_f(300) + f_mul(bx, orbit.m[0][2]) + f_mul(by, orbit.m[1][2]) + f_mul(bz, orbit.m[2][2]); +obj->pos.z = distance + f_mul(bx, orbit.m) + f_mul(by, orbit.m) + f_mul(bz, orbit.m); ``` Les trois composantes de `base_pos` (bx, by, bz) sont toutes prises en compte — les objets à `base_pos.y != 0` ou `base_pos.z != 0` sont correctement transformés. @@ -224,13 +224,13 @@ La caméra reste à l'origine (+ translations clavier). L'effet visuel est celui | Z / S | Caméra avance / recule (axe Z) | | Q / D | Caméra gauche / droite (axe X) | | A / E | Caméra haut / bas (axe Y) | -| + / − | Orbite vertical (anglex ±3°) | -| / / * | Orbite horizontal (angley ±3°) | -| 1 / 2 / 3 | Mode fil-de-fer / caché / solide | +| Flèche Haut / Bas | Orbite vertical (anglex ±3°) | +| Flèche Gauche / Droite | Orbite horizontal (angley ±3°) | +| F1 / F2 / F3 | Mode fil-de-fer / caché / solide | | R | Reset caméra + angles | | Esc | Quitter | -Les touches étendues (F1–F12, flèches…) retournent `0` depuis `getch()` ; le scan code suivant est consommé sans effet. +Les touches étendues (F1–F12, flèches…) retournent `0` depuis `getch()` ; le scan code suivant est alors consommé pour identifier la touche spéciale. --- diff --git a/src/main/main.c b/src/main/main.c index b0f6498..3fd22f4 100644 --- a/src/main/main.c +++ b/src/main/main.c @@ -5,11 +5,13 @@ int main(void) { Object3D *sph, *cyl, *tmp_obj; Camera cam; Matrix3 rotX, rotY, orbit; + int special=0; int anglex, angley, key, render, o; - fixed bx, by, bz; + fixed bx, by, bz, distance; anglex = angley = key = 0; render = MODE_SOLID; + distance = int_to_f(300); init_engine_math(); @@ -50,25 +52,38 @@ int main(void) { while (key != 27) { if (kbhit()) { + special = 0; key = getch(); if (key == 0) { - getch(); /* touche étendue (F1-F12, flèches…) : consommer le scan code */ + special = 1; + key = getch(); /* touche étendue (F1-F12, flèches…) : consommer le scan code */ + switch (key) { + case 59: render = MODE_WIRE; break; /* F1 */ + case 60: render = MODE_HIDDEN; break; /* F2 */ + case 61: render = MODE_SOLID; break; /* F3 */ + case 71: distance -= int_to_f(10); break; /* Home : Rapprocher le centre */ + case 79: distance += int_to_f(10); break; /* End : Eloigner le centre */ + case 72: anglex = ((anglex - 3) % 360 + 360) % 360; break; /* Flèche Haut */ + case 80: anglex = (anglex + 3) % 360; break; /* Flèche Bas */ + case 75: angley = ((angley - 3) % 360 + 360) % 360; break; /* Flèche Gauche */ + case 77: angley = (angley + 3) % 360; break; /* Flèche Droite */ + } } else { switch (key) { - case 'Z': case 'z': cam.pos.z += int_to_f(10); break; - case 'S': case 's': cam.pos.z -= int_to_f(10); break; - case 'Q': case 'q': cam.pos.x -= int_to_f(10); break; - case 'D': case 'd': cam.pos.x += int_to_f(10); break; - case 'A': case 'a': cam.pos.y -= int_to_f(10); break; - case 'E': case 'e': cam.pos.y += int_to_f(10); break; - case 'R': case 'r': cam.pos.x = cam.pos.y = cam.pos.z = 0; anglex = angley = 0; break; - case '+': anglex = (anglex + 3) % 360; break; - case '-': anglex = ((anglex - 3) % 360 + 360) % 360; break; - case '/': angley = (angley + 3) % 360; break; - case '*': angley = ((angley - 3) % 360 + 360) % 360; break; - case '1': render = MODE_WIRE; break; - case '2': render = MODE_HIDDEN; break; - case '3': render = MODE_SOLID; break; + case 'Z': + case 'z': cam.pos.z += int_to_f(10); break; + case 'S': + case 's': cam.pos.z -= int_to_f(10); break; + case 'Q': + case 'q': cam.pos.x -= int_to_f(10); break; + case 'D': + case 'd': cam.pos.x += int_to_f(10); break; + case 'A': + case 'a': cam.pos.y -= int_to_f(10); break; + case 'E': + case 'e': cam.pos.y += int_to_f(10); break; + case 'R': + case 'r': cam.pos.x = cam.pos.y = cam.pos.z = 0; anglex = angley = 0; distance = int_to_f(300); break; } } } @@ -84,9 +99,9 @@ int main(void) { by = obj->base_pos.y; bz = obj->base_pos.z; obj->rot = orbit; - obj->pos.x = f_mul(bx, orbit.m[0][0]) + f_mul(by, orbit.m[1][0]) + f_mul(bz, orbit.m[2][0]); - obj->pos.y = f_mul(bx, orbit.m[0][1]) + f_mul(by, orbit.m[1][1]) + f_mul(bz, orbit.m[2][1]); - obj->pos.z = int_to_f(300) + f_mul(bx, orbit.m[0][2]) + f_mul(by, orbit.m[1][2]) + f_mul(bz, orbit.m[2][2]); + obj->pos.x = f_mul(bx, orbit.m[0][0]) + f_mul(by, orbit.m[1][0]) + f_mul(bz, orbit.m[2][0]); + obj->pos.y = f_mul(bx, orbit.m[0][1]) + f_mul(by, orbit.m[1][1]) + f_mul(bz, orbit.m[2][1]); + obj->pos.z = distance + f_mul(bx, orbit.m[0][2]) + f_mul(by, orbit.m[1][2]) + f_mul(bz, orbit.m[2][2]); } clear_buffers(0);