rotation d'objet

This commit is contained in:
Frater 2026-05-11 17:53:07 +02:00
commit 69b06b5b14
3 changed files with 108 additions and 6 deletions

View file

@ -234,6 +234,45 @@ add_math_surface(uni, 0, 0, 0, int_to_f(120), int_to_f(120), 30, 30, COLOR6, 0,
---
## Manipulation des Mesh
Une fois générés, les objets peuvent être positionnés, transformés ou recolorés à l'aide des fonctions suivantes (définies dans `engine.c` / `geometry.c`) :
* **`void set_object_pos(Object3D *obj, fixed x, fixed y, fixed z);`**
```
void set_object_pos (Object3D *obj, fixed x, fixed y, fixed z);
```
Définit la position locale absolue de l'objet (`base_pos`) par rapport au centre de son espace d'orbite.
* **`void move_object(Object3D *obj, fixed dx, fixed dy, fixed dz);`**
```
void move_object (Object3D *obj, fixed dx, fixed dy, fixed dz);
```
Applique une translation relative à l'objet en ajoutant le décalage spécifié à sa position courante.
* **`void set_object_color(Object3D *obj, uint8_t col);`**
```
void set_object_color (Object3D *obj, uint8_t col);
```
Modifie l'index de couleur de base (0-15) utilisé pour le rendu de l'ensemble des faces de l'objet.
* **`void bake_object_rotation(Universe *uni, Object3D *obj, int ax, int ay, int az);`**
```
void bake_object_rotation(Universe *uni, Object3D *obj, int ax, int ay, int az);
```
Applique une rotation *permanente* (Baking) aux sommets et aux normales de l'objet directement dans le pool de l'univers.
Particulièrement utile pour orienter une primitive lors de l'initialisation (ex: coucher un cylindre sur le flanc) sans induire le moindre coût de calcul matriciel supplémentaire pendant la boucle de rendu en temps réel.
---
## Orbite de l'observateur (`main.c`)
Les objets ont des positions de base fixes dans l'espace scène, définies par rapport au centre `(0, 0, 300)` :

View file

@ -81,7 +81,12 @@ typedef struct {
} Camera;
/* Mesh dynamique conservé pour save/load uniquement */
typedef struct { Vector3 *verts; Vector3 *v_normals; Face *faces; int num_verts, num_faces; } Mesh;
typedef struct {
Vector3 *verts;
Vector3 *v_normals;
Face *faces;
int num_verts, num_faces;
} Mesh;
/* Globales */
extern fixed sintab[360], costab[360];
@ -101,9 +106,10 @@ void mat3_rotate_x(Matrix3 *m, int angle);
void mat3_rotate_y(Matrix3 *m, int angle);
void mat3_mul(Matrix3 *res, Matrix3 *a, Matrix3 *b);
void set_object_pos(Object3D *obj, fixed x, fixed y, fixed z);
void move_object(Object3D *obj, fixed dx, fixed dy, fixed dz);
void set_object_color(Object3D *obj, uint8_t col);
void set_object_pos (Object3D *obj, fixed x, fixed y, fixed z);
void move_object (Object3D *obj, fixed dx, fixed dy, fixed dz);
void set_object_color (Object3D *obj, uint8_t col);
void bake_object_rotation(Universe *uni, Object3D *obj, int ax, int ay, int az);
/* Retournent un pointeur sur le nouvel Object3D, NULL si pool saturé */
Object3D* add_box (Universe *uni, fixed x, fixed y, fixed z, fixed dx, fixed dy, fixed dz, uint8_t col, uint8_t wire);

View file

@ -34,14 +34,71 @@ void mat3_rotate_x(Matrix3 *m, int angle) {
int a = ((angle % 360) + 360) % 360;
fixed c = costab[a], s = sintab[a];
mat3_identity(m);
m->m[1][1] = c; m->m[1][2] = -s; m->m[2][1] = s; m->m[2][2] = c;
m->m[1][1] = c;
m->m[1][2] = -s;
m->m[2][1] = s;
m->m[2][2] = c;
}
void mat3_rotate_y(Matrix3 *m, int angle) {
int a = ((angle % 360) + 360) % 360;
fixed c = costab[a], s = sintab[a];
mat3_identity(m);
m->m[0][0] = c; m->m[0][2] = s; m->m[2][0] = -s; m->m[2][2] = c;
m->m[0][0] = c;
m->m[0][2] = s;
m->m[2][0] = -s;
m->m[2][2] = c;
}
void mat3_rotate_z(Matrix3 *m, int angle) {
int a = ((angle % 360) + 360) % 360;
fixed c = costab[a], s = sintab[a];
mat3_identity(m);
m->m[0][0] = c;
m->m[0][1] = s;
m->m[1][0] = -s;
m->m[1][1] = c;
}
/* Fait pivoter la géométrie locale de l'objet de façon permanente */
void bake_object_rotation(Universe *uni, Object3D *obj, int ax, int ay, int az) {
Matrix3 rx, ry, rz, tmp, rot;
Vector3 *v, *n;
int i, vi;
fixed vx, vy, vz;
if (!obj || !uni) return;
/* Composition de la matrice de rotation */
mat3_rotate_x(&rx, ax);
mat3_rotate_y(&ry, ay);
mat3_rotate_z(&rz, az);
mat3_mul(&tmp, &rx, &ry);
mat3_mul(&rot, &tmp, &rz);
/* Application à tous les sommets et normales de l'objet */
for (i = 0; i < obj->num_verts; i++) {
vi = obj->vert_start + i;
v = &uni->verts[vi];
n = &uni->v_normals[vi];
/* Sommets */
vx = f_mul(v->x, rot.m[0][0]) + f_mul(v->y, rot.m[1][0]) + f_mul(v->z, rot.m[2][0]);
vy = f_mul(v->x, rot.m[0][1]) + f_mul(v->y, rot.m[1][1]) + f_mul(v->z, rot.m[2][1]);
vz = f_mul(v->x, rot.m[0][2]) + f_mul(v->y, rot.m[1][2]) + f_mul(v->z, rot.m[2][2]);
v->x = vx;
v->y = vy;
v->z = vz;
/* Normales (doivent aussi pivoter pour l'ombrage Gouraud !) */
vx = f_mul(n->x, rot.m[0][0]) + f_mul(n->y, rot.m[1][0]) + f_mul(n->z, rot.m[2][0]);
vy = f_mul(n->x, rot.m[0][1]) + f_mul(n->y, rot.m[1][1]) + f_mul(n->z, rot.m[2][1]);
vz = f_mul(n->x, rot.m[0][2]) + f_mul(n->y, rot.m[1][2]) + f_mul(n->z, rot.m[2][2]);
n->x = vx;
n->y = vy;
n->z = vz;
}
}
void render_universe(Universe *uni, Camera *cam, int mode) {