This commit is contained in:
Frater 2026-05-10 02:29:00 +02:00
commit c6d6f787f7
8 changed files with 667 additions and 485 deletions

View file

@ -1,6 +1,6 @@
#include "defines.h"
fixed sintab[360], costab[360], inv_table[321];
fixed sintab[360], costab[360];
Point2D v_cache[MAX_VERTEX];
void mat3_identity(Matrix3 *mat) {
@ -10,17 +10,13 @@ void mat3_identity(Matrix3 *mat) {
void init_engine_math() {
int i;
for (i = 0; i < 360; i++) {
double r = (double)i * 3.14159265 / 180.0;
sintab[i] = (fixed)(sin(r) * 65536.0);
costab[i] = (fixed)(cos(r) * 65536.0);
}
inv_table[0] = 0;
for (i = 1; i <= 320; i++) inv_table[i] = (int_to_f(1) / i);
}
// Normalisation pour le Gouraud (à la création uniquement)
void normalize(Vector3 *v) {
double dx = (double)v->x, dy = (double)v->y, dz = (double)v->z;
double d = sqrt(dx*dx + dy*dy + dz*dz);
@ -29,25 +25,6 @@ void normalize(Vector3 *v) {
}
}
// Génère une matrice de rotation sur l'axe X
void mat3_rotate_x(Matrix3 *m, int angle) {
fixed c = costab[angle % 360];
fixed s = sintab[angle % 360];
mat3_identity(m);
m->m[1][1] = c; m->m[1][2] = -s;
m->m[2][1] = s; m->m[2][2] = c;
}
// Génère une matrice de rotation sur l'axe Y
void mat3_rotate_y(Matrix3 *m, int angle) {
fixed c = costab[angle % 360];
fixed s = sintab[angle % 360];
mat3_identity(m);
m->m[0][0] = c; m->m[0][2] = s;
m->m[2][0] = -s; m->m[2][2] = c;
}
// Multiplie deux matrices 3x3 : res = a * b
void mat3_mul(Matrix3 *res, Matrix3 *a, Matrix3 *b) {
int i, j;
for (i = 0; i < 3; i++) {
@ -59,61 +36,77 @@ void mat3_mul(Matrix3 *res, Matrix3 *a, Matrix3 *b) {
}
}
void render_scene(Mesh *m, Matrix3 *rot, int global_mode) {
int i;
fixed pz, rx, ry, rz;
Vector3 *v;
Vector3 *n;
fixed nz;
int intensity;
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;
}
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;
}
for (i = 0; i < m->num_verts; i++) {
v = &m->verts[i];
n = &m->v_normals[i];
void render_universe(Object3D *objs, int num_objs, Camera *cam, int mode) {
int o, i, front;
fixed rx, ry, rz, pz, nz;
uint8_t wire_col;
// --- 1. Rotation de la normale (pour la lumière) ---
nz = f_mul(n->x, rot->m[0][2]) + f_mul(n->y, rot->m[1][2]) + f_mul(n->z, rot->m[2][2]);
intensity = f_to_int(nz * 15);
if (intensity < 0) intensity = 0;
for (o = 0; o < num_objs; o++) {
Object3D *obj = &objs[o];
Mesh *m = obj->mesh;
// --- 2. Rotation du sommet (LA PIÈCE MANQUANTE) ---
// On applique la multiplication Matrice * Vecteur
rx = f_mul(v->x, rot->m[0][0]) + f_mul(v->y, rot->m[1][0]) + f_mul(v->z, rot->m[2][0]);
ry = f_mul(v->x, rot->m[0][1]) + f_mul(v->y, rot->m[1][1]) + f_mul(v->z, rot->m[2][1]);
rz = f_mul(v->x, rot->m[0][2]) + f_mul(v->y, rot->m[1][2]) + f_mul(v->z, rot->m[2][2]);
for (i = 0; i < m->num_verts; i++) {
Vector3 *v = &m->verts[i], *n = &m->v_normals[i];
// --- 3. Projection avec les coordonnées tournées ---
pz = rz; // On utilise le Z tourné
if (pz < int_to_f(10)) pz = int_to_f(10);
rx = f_mul(v->x, obj->rot.m[0][0]) + f_mul(v->y, obj->rot.m[1][0]) + f_mul(v->z, obj->rot.m[2][0]) + obj->pos.x - cam->pos.x;
ry = f_mul(v->x, obj->rot.m[0][1]) + f_mul(v->y, obj->rot.m[1][1]) + f_mul(v->z, obj->rot.m[2][1]) + obj->pos.y - cam->pos.y;
rz = f_mul(v->x, obj->rot.m[0][2]) + f_mul(v->y, obj->rot.m[1][2]) + f_mul(v->z, obj->rot.m[2][2]) + obj->pos.z - cam->pos.z;
v_cache[i].z = pz;
v_cache[i].intensity = intensity;
v_cache[i].x = 160 + f_to_int(f_div(rx << 8, pz)); // On utilise rx tourné
v_cache[i].y = 100 - f_to_int(f_div(ry << 8, pz)); // On utilise ry tourné
}
pz = (rz < int_to_f(20)) ? int_to_f(20) : rz;
v_cache[i].z = pz;
v_cache[i].x = 160 + f_to_int(f_div(rx << 8, pz));
v_cache[i].y = 100 - f_to_int(f_div(ry << 8, pz));
for (i = 0; i < m->num_faces; i++) {
Face *f = &m->faces[i];
Point2D *p1 = &v_cache[f->a];
Point2D *p2 = &v_cache[f->b];
Point2D *p3 = &v_cache[f->c];
int back = (p2->x - p1->x) * (p3->y - p1->y) - (p2->y - p1->y) * (p3->x - p1->x);
nz = f_mul(n->x, obj->rot.m[0][2]) + f_mul(n->y, obj->rot.m[1][2]) + f_mul(n->z, obj->rot.m[2][2]);
v_cache[i].intensity = (nz >= 0) ? int_to_f(1) : ((-nz) * 14) + int_to_f(1);
}
if (global_mode == MODE_WIRE) {
draw_line_z(p1, p2, f->color, 0);
draw_line_z(p2, p3, f->color, 0);
draw_line_z(p3, p1, f->color, 0);
} else {
if (back < 0) {
if (f->force_wire || global_mode == MODE_HIDDEN) {
fill_triangle_zonly(p1, p2, p3);
draw_line_z(p1, p2, f->color, 1);
draw_line_z(p2, p3, f->color, 1);
draw_line_z(p3, p1, f->color, 1); // Ajouté pour fermer le triangle
} else {
fill_triangle_gouraud(p1, p2, p3, f->color);
}
wire_col = (uint8_t)((obj->color << 4) | 15);
for (i = 0; i < m->num_faces; i++) {
Face *f = &m->faces[i];
Point2D *p1 = &v_cache[f->a], *p2 = &v_cache[f->b], *p3 = &v_cache[f->c];
front = ((p2->x - p1->x) * (p3->y - p1->y) - (p2->y - p1->y) * (p3->x - p1->x)) > 0;
switch (mode) {
case MODE_WIRE:
draw_line_z(p1, p2, wire_col, 0);
draw_line_z(p2, p3, wire_col, 0);
draw_line_z(p3, p1, wire_col, 0);
break;
case MODE_HIDDEN:
if (front) {
draw_line_z(p1, p2, wire_col, 1);
draw_line_z(p2, p3, wire_col, 1);
draw_line_z(p3, p1, wire_col, 1);
}
break;
case MODE_SOLID:
default:
if (front) {
if (f->force_wire) {
draw_line_z(p1, p2, wire_col, 1);
draw_line_z(p2, p3, wire_col, 1);
draw_line_z(p3, p1, wire_col, 1);
} else {
fill_triangle_gouraud(p1, p2, p3, obj->color);
}
}
break;
}
}
}