boarfds
This commit is contained in:
parent
80d8141b5a
commit
eae91de89d
8 changed files with 641 additions and 280 deletions
|
|
@ -1,112 +1,118 @@
|
|||
#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];
|
||||
#include "defines.h"
|
||||
|
||||
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};
|
||||
Face *f = &m->faces[m->num_faces++];
|
||||
f->a = a;
|
||||
f->b = b;
|
||||
f->c = c;
|
||||
f->color = col;
|
||||
f->force_wire = 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++) {
|
||||
int i, j, v_base;
|
||||
v_base = m->num_verts;
|
||||
|
||||
for (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++) {
|
||||
for (i = 0; i < det; i++) {
|
||||
Vector3 *v = &m->verts[m->num_verts];
|
||||
Vector3 *n = &m->v_normals[m->num_verts];
|
||||
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)};
|
||||
|
||||
v->x = x + f_mul(r, f_mul(sin_phi, cos_th));
|
||||
v->y = y + f_mul(r, cos_phi);
|
||||
v->z = z + f_mul(r, f_mul(sin_phi, sin_th));
|
||||
|
||||
n->x = f_mul(sin_phi, cos_th);
|
||||
n->y = cos_phi;
|
||||
n->z = 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);
|
||||
for (j = 0; j < det; j++) {
|
||||
for (i = 0; i < det; i++) {
|
||||
int a = v_base + j * det + i;
|
||||
int b = v_base + j * det + (i + 1) % det;
|
||||
int c = v_base + (j + 1) * det + i;
|
||||
int 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++;
|
||||
int i, v_base;
|
||||
v_base = m->num_verts;
|
||||
|
||||
for (i = 0; i < det; i++) {
|
||||
Vector3 *v1 = &m->verts[m->num_verts];
|
||||
Vector3 *n1 = &m->v_normals[m->num_verts];
|
||||
fixed s = sintab[(i * 360 / det) % 360];
|
||||
fixed c = costab[(i * 360 / det) % 360];
|
||||
|
||||
v1->x = x + f_mul(r, c); v1->y = y - h / 2; v1->z = z + f_mul(r, s);
|
||||
n1->x = c; n1->y = 0; n1->z = s;
|
||||
m->num_verts++;
|
||||
|
||||
{ // Bloc pour v2/n2
|
||||
Vector3 *v2 = &m->verts[m->num_verts];
|
||||
Vector3 *n2 = &m->v_normals[m->num_verts];
|
||||
v2->x = x + f_mul(r, c); v2->y = y + h / 2; v2->z = z + f_mul(r, s);
|
||||
n2->x = c; n2->y = 0; n2->z = 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);
|
||||
for (i = 0; i < det; i++) {
|
||||
int a = v_base + i * 2;
|
||||
int b = v_base + ((i * 2 + 2) % (det * 2));
|
||||
int c = a + 1;
|
||||
int 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);
|
||||
FILE *f = fopen(fn, "wb");
|
||||
if (!f) return;
|
||||
fwrite(&m->num_verts, sizeof(int), 1, f);
|
||||
fwrite(&m->num_faces, sizeof(int), 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;
|
||||
Mesh *m;
|
||||
FILE *f = fopen(fname, "rb");
|
||||
if (!f) return NULL;
|
||||
|
||||
m = (Mesh*)malloc(sizeof(Mesh));
|
||||
fread(&m->num_verts, sizeof(int), 1, f);
|
||||
fread(&m->num_faces, sizeof(int), 1, f);
|
||||
// Suppression de is_wire_only car absent du .h
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue