fistcommit
This commit is contained in:
commit
80d8141b5a
8 changed files with 497 additions and 0 deletions
112
src/part3D/geometry.c
Normal file
112
src/part3D/geometry.c
Normal file
|
|
@ -0,0 +1,112 @@
|
|||
#define GEOMETRY_H
|
||||
|
||||
#define MODE_WIRE 0 // Transparent total
|
||||
#define MODE_HIDDEN 1 // Fil de fer avec surfaces cachées
|
||||
#define MODE_SOLID 2 // Plein (Gouraud)
|
||||
|
||||
Point2D v_cache[5000];
|
||||
|
||||
void add_face(Mesh *m, int a, int b, int c, uint8_t col, uint8_t wire) {
|
||||
m->faces[m->num_faces++] = (Face){a, b, c, col, wire};
|
||||
}
|
||||
|
||||
void add_sphere(Mesh *m, fixed x, fixed y, fixed z, fixed r, int det, uint8_t col, uint8_t wire) {
|
||||
int v_base = m->num_verts;
|
||||
for (int j = 0; j <= det; j++) {
|
||||
fixed sin_phi = sintab[(j * 180 / det) % 360];
|
||||
fixed cos_phi = costab[(j * 180 / det) % 360];
|
||||
for (int i = 0; i < det; i++) {
|
||||
fixed sin_th = sintab[(i * 360 / det) % 360];
|
||||
fixed cos_th = costab[(i * 360 / det) % 360];
|
||||
m->verts[m->num_verts] = (Vector3){x + f_mul(r, f_mul(sin_phi, cos_th)), y + f_mul(r, cos_phi), z + f_mul(r, f_mul(sin_phi, sin_th))};
|
||||
m->v_normals[m->num_verts] = (Vector3){f_mul(sin_phi, cos_th), cos_phi, f_mul(sin_phi, sin_th)};
|
||||
m->num_verts++;
|
||||
}
|
||||
}
|
||||
for (int j = 0; j < det; j++) {
|
||||
for (int i = 0; i < det; i++) {
|
||||
int a = v_base + j * det + i, b = v_base + j * det + (i + 1) % det;
|
||||
int c = v_base + (j + 1) * det + i, d = v_base + (j + 1) * det + (i + 1) % det;
|
||||
add_face(m, a, b, c, col, wire); add_face(m, b, d, c, col, wire);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void add_cylinder(Mesh *m, fixed x, fixed y, fixed z, fixed r, fixed h, int det, uint8_t col, uint8_t wire) {
|
||||
int v_base = m->num_verts;
|
||||
for (int i = 0; i < det; i++) {
|
||||
fixed s = sintab[(i * 360 / det) % 360], c = costab[(i * 360 / det) % 360];
|
||||
m->verts[m->num_verts] = (Vector3){x + f_mul(r, c), y - h / 2, z + f_mul(r, s)};
|
||||
m->v_normals[m->num_verts] = (Vector3){c, 0, s}; m->num_verts++;
|
||||
m->verts[m->num_verts] = (Vector3){x + f_mul(r, c), y + h / 2, z + f_mul(r, s)};
|
||||
m->v_normals[m->num_verts] = (Vector3){c, 0, s}; m->num_verts++;
|
||||
}
|
||||
for (int i = 0; i < det; i++) {
|
||||
int a = v_base + i * 2, b = v_base + ((i * 2 + 2) % (det * 2)), c = a + 1, d = b + 1;
|
||||
add_face(m, a, b, c, col, wire); add_face(m, b, d, c, col, wire);
|
||||
}
|
||||
}
|
||||
|
||||
void save_mesh(Mesh *m, const char *fn) {
|
||||
FILE *f = fopen(fn, "wb");
|
||||
fwrite(&m->num_verts, 4, 1, f);
|
||||
fwrite(&m->num_faces, 4, 1, f);
|
||||
fwrite(m->verts, sizeof(Vector3), m->num_verts, f);
|
||||
fwrite(m->v_normals, sizeof(Vector3), m->num_verts, f);
|
||||
fwrite(m->faces, sizeof(Face), m->num_faces, f);
|
||||
fclose(f);
|
||||
}
|
||||
|
||||
Mesh* load_mesh(const char *fname) {
|
||||
FILE *f = fopen(fname, "rb");
|
||||
if (!f) return NULL;
|
||||
Mesh *m = (Mesh*)malloc(sizeof(Mesh));
|
||||
fread(&m->num_verts, 4, 1, f);
|
||||
fread(&m->num_faces, 4, 1, f);
|
||||
fread(&m->is_wire_only, 1, 1, f);
|
||||
m->verts = (Vector3*)malloc(sizeof(Vector3) * m->num_verts);
|
||||
m->v_normals = (Vector3*)malloc(sizeof(Vector3) * m->num_verts);
|
||||
m->faces = (Face*)malloc(sizeof(Face) * m->num_faces);
|
||||
fread(m->verts, sizeof(Vector3), m->num_verts, f);
|
||||
fread(m->v_normals, sizeof(Vector3), m->num_verts, f);
|
||||
fread(m->faces, sizeof(Face), m->num_faces, f);
|
||||
fclose(f);
|
||||
return m;
|
||||
}
|
||||
|
||||
void free_mesh(Mesh *m) {
|
||||
if (!m) return;
|
||||
if (m->verts) free(m->verts);
|
||||
if (m->faces) free(m->faces);
|
||||
if (m->v_normals) free(m->v_normals);
|
||||
free(m);
|
||||
}
|
||||
|
||||
void render_scene(Mesh *m, Matrix3 *rot, int global_mode) {
|
||||
for (int i = 0; i < m->num_verts; i++) {
|
||||
Vector3 *v = &m->verts[i]; Vector3 *n = &m->v_normals[i];
|
||||
fixed 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]);
|
||||
int intensity = f_to_int(nz * 15); if (intensity < 0) intensity = 0;
|
||||
v_cache[i].z = v->z; v_cache[i].intensity = intensity;
|
||||
v_cache[i].x = 160 + f_to_int(f_div(v->x << 8, v->z));
|
||||
v_cache[i].y = 100 - f_to_int(f_div(v->y << 8, v->z));
|
||||
}
|
||||
|
||||
for (int 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];
|
||||
int back = (p2->x - p1->x) * (p3->y - p1->y) - (p2->y - p1->y) * (p3->x - p1->x);
|
||||
|
||||
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); // Pas de couleur, juste Z
|
||||
draw_line_z(p1, p2, f->color, 1); draw_line_z(p2, p3, f->color, 1);
|
||||
} else {
|
||||
fill_triangle_gouraud(p1, p2, p3, f->color);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue