Create vertex_t and move h data to it

This commit is contained in:
Abdelrahman Said 2024-07-13 22:00:48 +01:00
parent b0bf4f593b
commit e236cd8bbe
3 changed files with 81 additions and 116 deletions

View File

@ -10,13 +10,15 @@
#define INVALID_VERTEX -1 #define INVALID_VERTEX -1
typedef struct {
vec3f_t position;
f32 h;
} vertex_t;
typedef struct { typedef struct {
i64 idx0; i64 idx0;
i64 idx1; i64 idx1;
i64 idx2; i64 idx2;
f32 h0;
f32 h1;
f32 h2;
colour_t colour; colour_t colour;
} scene_triangle_t; } scene_triangle_t;
@ -24,6 +26,7 @@ MAKE_LIST_TYPE(f32);
MAKE_LIST_TYPE(vec2i_t); MAKE_LIST_TYPE(vec2i_t);
MAKE_LIST_TYPE(vec3f_t); MAKE_LIST_TYPE(vec3f_t);
MAKE_LIST_TYPE(vec4f_t); MAKE_LIST_TYPE(vec4f_t);
MAKE_LIST_TYPE(vertex_t);
MAKE_LIST_TYPE(scene_triangle_t); MAKE_LIST_TYPE(scene_triangle_t);
typedef struct { typedef struct {
@ -42,7 +45,7 @@ typedef struct {
} triangle_t; } triangle_t;
typedef struct { typedef struct {
list_vec3f_t *vertices; list_vertex_t *vertices;
list_scene_triangle_t *triangles; list_scene_triangle_t *triangles;
} model_t; } model_t;
#define NULL_MODEL ((model_t){0}) #define NULL_MODEL ((model_t){0})

View File

@ -33,18 +33,23 @@ int main(void) {
return EXIT_FAILURE; return EXIT_FAILURE;
} }
list_vec3f_t *vertices = list_create(vec3f_t, arena); list_vertex_t *vertices = list_create(vertex_t, arena);
if (!vertices) { if (!vertices) {
return EXIT_FAILURE; return EXIT_FAILURE;
} }
// Vertices // Vertices
vec3f_t verts[] = { vertex_t verts[] = {
(vec3f_t){1, 1, 1}, (vec3f_t){-1, 1, 1}, (vec3f_t){-1, -1, 1}, (vertex_t){.position = {1, 1, 1}, .h = 1.0f},
(vec3f_t){1, -1, 1}, (vec3f_t){1, 1, -1}, (vec3f_t){-1, 1, -1}, (vertex_t){.position = {-1, 1, 1}, .h = 1.0f},
(vec3f_t){-1, -1, -1}, (vec3f_t){1, -1, -1}, (vertex_t){.position = {-1, -1, 1}, .h = 1.0f},
(vertex_t){.position = {1, -1, 1}, .h = 1.0f},
(vertex_t){.position = {1, 1, -1}, .h = 1.0f},
(vertex_t){.position = {-1, 1, -1}, .h = 1.0f},
(vertex_t){.position = {-1, -1, -1}, .h = 1.0f},
(vertex_t){.position = {1, -1, -1}, .h = 1.0f},
}; };
for (u64 i = 0; i < ARR_LEN(verts); ++i) { for (u64 i = 0; i < ARR_LEN(verts); ++i) {
list_append(vec3f_t, arena, vertices, verts[i]); list_append(vertex_t, arena, vertices, verts[i]);
} }
list_scene_triangle_t *triangles = list_create(scene_triangle_t, arena); list_scene_triangle_t *triangles = list_create(scene_triangle_t, arena);
@ -53,30 +58,18 @@ int main(void) {
} }
// Triangles // Triangles
scene_triangle_t tris[] = { scene_triangle_t tris[] = {
(scene_triangle_t){0, 1, 2, 1.0f, 1.0f, 1.0f, (scene_triangle_t){0, 1, 2, (colour_t){.colour = 0xff0000ff}},
(colour_t){.colour = 0xff0000ff}}, (scene_triangle_t){0, 2, 3, (colour_t){.colour = 0xff0000ff}},
(scene_triangle_t){0, 2, 3, 1.0f, 1.0f, 1.0f, (scene_triangle_t){4, 0, 3, (colour_t){.colour = 0x00ff00ff}},
(colour_t){.colour = 0xff0000ff}}, (scene_triangle_t){4, 3, 7, (colour_t){.colour = 0x00ff00ff}},
(scene_triangle_t){4, 0, 3, 1.0f, 1.0f, 1.0f, (scene_triangle_t){5, 4, 7, (colour_t){.colour = 0x0000ffff}},
(colour_t){.colour = 0x00ff00ff}}, (scene_triangle_t){5, 7, 6, (colour_t){.colour = 0x0000ffff}},
(scene_triangle_t){4, 3, 7, 1.0f, 1.0f, 1.0f, (scene_triangle_t){1, 5, 6, (colour_t){.colour = 0xffff00ff}},
(colour_t){.colour = 0x00ff00ff}}, (scene_triangle_t){1, 6, 2, (colour_t){.colour = 0xffff00ff}},
(scene_triangle_t){5, 4, 7, 1.0f, 1.0f, 1.0f, (scene_triangle_t){4, 5, 1, (colour_t){.colour = 0xff00ffff}},
(colour_t){.colour = 0x0000ffff}}, (scene_triangle_t){4, 1, 0, (colour_t){.colour = 0xff00ffff}},
(scene_triangle_t){5, 7, 6, 1.0f, 1.0f, 1.0f, (scene_triangle_t){2, 6, 7, (colour_t){.colour = 0x00ffffff}},
(colour_t){.colour = 0x0000ffff}}, (scene_triangle_t){2, 7, 3, (colour_t){.colour = 0x00ffffff}},
(scene_triangle_t){1, 5, 6, 1.0f, 1.0f, 1.0f,
(colour_t){.colour = 0xffff00ff}},
(scene_triangle_t){1, 6, 2, 1.0f, 1.0f, 1.0f,
(colour_t){.colour = 0xffff00ff}},
(scene_triangle_t){4, 5, 1, 1.0f, 1.0f, 1.0f,
(colour_t){.colour = 0xff00ffff}},
(scene_triangle_t){4, 1, 0, 1.0f, 1.0f, 1.0f,
(colour_t){.colour = 0xff00ffff}},
(scene_triangle_t){2, 6, 7, 1.0f, 1.0f, 1.0f,
(colour_t){.colour = 0x00ffffff}},
(scene_triangle_t){2, 7, 3, 1.0f, 1.0f, 1.0f,
(colour_t){.colour = 0x00ffffff}},
}; };
for (u64 i = 0; i < ARR_LEN(tris); ++i) { for (u64 i = 0; i < ARR_LEN(tris); ++i) {
list_append(scene_triangle_t, arena, triangles, tris[i]); list_append(scene_triangle_t, arena, triangles, tris[i]);

View File

@ -33,9 +33,9 @@ internal void clip_triangle_against_plane(Arena *arena, model_t *model,
internal list_float *interpolate(Arena *arena, i32 i0, f32 d0, i32 i1, f32 d1); internal list_float *interpolate(Arena *arena, i32 i0, f32 d0, i32 i1, f32 d1);
internal inline void order_triangle_points(triangle_t *triangle); internal inline void order_triangle_points(triangle_t *triangle);
internal inline bounding_sphere_t internal inline bounding_sphere_t
get_bounding_sphere(const list_vec3f_t *vertices); get_bounding_sphere(const list_vertex_t *vertices);
internal inline segment_intersection_result_t internal inline vertex_t segment_intersection(const vertex_t *a,
segment_intersection(const vec3f_t *a, const vec3f_t *b, f32 ha, f32 hb, const vertex_t *b,
const clipping_plane_t *plane); const clipping_plane_t *plane);
internal inline void copy_triangles(Arena *arena, list_scene_triangle_t *dst, internal inline void copy_triangles(Arena *arena, list_scene_triangle_t *dst,
const list_scene_triangle_t *src); const list_scene_triangle_t *src);
@ -61,9 +61,9 @@ internal void render_instance(window_t *wnd, const rasteriser_scene_t *scene,
Arena *arena, mat4x4f_t camera_matrix, Arena *arena, mat4x4f_t camera_matrix,
mat3x4f_t projection_matrix, mat3x4f_t projection_matrix,
const instance_t *instance) { const instance_t *instance) {
list_vec3f_t *transformed = list_create_with_capacity( list_vertex_t *transformed = list_create_with_capacity(
vec3f_t, arena, vertex_t, arena,
(instance->model->vertices->count + 10) * sizeof(vec3f_t)); (instance->model->vertices->count + 10) * sizeof(vertex_t));
list_scene_triangle_t *triangles = list_create_with_capacity( list_scene_triangle_t *triangles = list_create_with_capacity(
scene_triangle_t, arena, scene_triangle_t, arena,
(instance->model->triangles->count + 10) * sizeof(scene_triangle_t)); (instance->model->triangles->count + 10) * sizeof(scene_triangle_t));
@ -83,18 +83,19 @@ internal void render_instance(window_t *wnd, const rasteriser_scene_t *scene,
mat4x4f_t xf_cam_mat = mul_mat4x4f(camera_matrix, trs_mat); mat4x4f_t xf_cam_mat = mul_mat4x4f(camera_matrix, trs_mat);
vec3f_t vertex = {0}; vertex_t vertex = {0};
vec4f_t xf_vertex = {0}; vec4f_t xf_vertex = {0};
for (u64 i = 0; i < instance->model->vertices->count; ++i) { for (u64 i = 0; i < instance->model->vertices->count; ++i) {
vertex = list_get(instance->model->vertices, i); vertex = list_get(instance->model->vertices, i);
xf_vertex = mul_mat4x4f_by_vec4f( xf_vertex = mul_mat4x4f_by_vec4f(
xf_cam_mat, (vec4f_t){vertex.x, vertex.y, vertex.z, 1.0f}); xf_cam_mat, (vec4f_t){vertex.position.x, vertex.position.y,
vertex.position.z, 1.0f});
xf_vertex = vec_div_num(vec4f_t, xf_vertex, xf_vertex.w); xf_vertex = vec_div_num(vec4f_t, xf_vertex, xf_vertex.w);
vertex = (vec3f_t){xf_vertex.x, xf_vertex.y, xf_vertex.z}; vertex.position = (vec3f_t){xf_vertex.x, xf_vertex.y, xf_vertex.z};
list_append(vec3f_t, arena, transformed, vertex); list_append(vertex_t, arena, transformed, vertex);
} }
model_t model = {transformed, triangles}; model_t model = {transformed, triangles};
@ -112,9 +113,11 @@ internal void render_instance(window_t *wnd, const rasteriser_scene_t *scene,
vec2i_t point = {0}; vec2i_t point = {0};
for (u64 i = 0; i < transformed->count; ++i) { for (u64 i = 0; i < transformed->count; ++i) {
vertex = list_get(transformed, i); vertex = list_get(transformed, i);
vertex = mul_mat3x4f_by_vec4f( vertex.position = mul_mat3x4f_by_vec4f(
projection_matrix, (vec4f_t){vertex.x, vertex.y, vertex.z, 1.0f}); projection_matrix, (vec4f_t){vertex.position.x, vertex.position.y,
point = (vec2i_t){(i32)(vertex.x / vertex.z), (i32)(vertex.y / vertex.z)}; vertex.position.z, 1.0f});
point = (vec2i_t){(i32)(vertex.position.x / vertex.position.z),
(i32)(vertex.position.y / vertex.position.z)};
list_append(vec2i_t, arena, projected, point); list_append(vec2i_t, arena, projected, point);
} }
@ -125,9 +128,9 @@ internal void render_instance(window_t *wnd, const rasteriser_scene_t *scene,
.p0 = list_get(projected, triangle.idx0), .p0 = list_get(projected, triangle.idx0),
.p1 = list_get(projected, triangle.idx1), .p1 = list_get(projected, triangle.idx1),
.p2 = list_get(projected, triangle.idx2), .p2 = list_get(projected, triangle.idx2),
.h0 = triangle.h0, .h0 = list_get(transformed, triangle.idx0).h,
.h1 = triangle.h1, .h1 = list_get(transformed, triangle.idx1).h,
.h2 = triangle.h2, .h2 = list_get(transformed, triangle.idx2).h,
.colour = triangle.colour, .colour = triangle.colour,
}; };
@ -338,13 +341,13 @@ internal void clip_triangle_against_plane(Arena *arena, model_t *model,
i64 triangle_index, i64 triangle_index,
const clipping_plane_t *plane) { const clipping_plane_t *plane) {
scene_triangle_t *triangle = &(list_get(model->triangles, triangle_index)); scene_triangle_t *triangle = &(list_get(model->triangles, triangle_index));
vec3f_t *v0 = &(list_get(model->vertices, triangle->idx0)); vertex_t *v0 = &(list_get(model->vertices, triangle->idx0));
vec3f_t *v1 = &(list_get(model->vertices, triangle->idx1)); vertex_t *v1 = &(list_get(model->vertices, triangle->idx1));
vec3f_t *v2 = &(list_get(model->vertices, triangle->idx2)); vertex_t *v2 = &(list_get(model->vertices, triangle->idx2));
f32 d0 = signed_distance(v0, plane); f32 d0 = signed_distance(&(v0->position), plane);
f32 d1 = signed_distance(v1, plane); f32 d1 = signed_distance(&(v1->position), plane);
f32 d2 = signed_distance(v2, plane); f32 d2 = signed_distance(&(v2->position), plane);
if (d0 >= 0.0f && d1 >= 0.0f && d2 >= 0.0f) { if (d0 >= 0.0f && d1 >= 0.0f && d2 >= 0.0f) {
return; return;
@ -354,109 +357,75 @@ internal void clip_triangle_against_plane(Arena *arena, model_t *model,
triangle->idx2 = INVALID_VERTEX; triangle->idx2 = INVALID_VERTEX;
} else if ((d0 < 0.0f && d1 < 0.0f) || (d0 < 0.0f && d2 < 0.0f) || } else if ((d0 < 0.0f && d1 < 0.0f) || (d0 < 0.0f && d2 < 0.0f) ||
(d1 < 0.0f && d2 < 0.0f)) { (d1 < 0.0f && d2 < 0.0f)) {
vec3f_t *vp; vertex_t *vp;
vec3f_t *vn0; vertex_t *vn0;
vec3f_t *vn1; vertex_t *vn1;
f32 *hp;
f32 *hn0;
f32 *hn1;
i64 *in0; i64 *in0;
i64 *in1; i64 *in1;
if (d0 > 0.0f) { if (d0 > 0.0f) {
vp = v0; vp = v0;
vn0 = v1; vn0 = v1;
vn1 = v2; vn1 = v2;
hp = &(triangle->h0);
hn0 = &(triangle->h1);
hn1 = &(triangle->h2);
in0 = &(triangle->idx1); in0 = &(triangle->idx1);
in1 = &(triangle->idx2); in1 = &(triangle->idx2);
} else if (d1 > 0.0f) { } else if (d1 > 0.0f) {
vp = v1; vp = v1;
vn0 = v0; vn0 = v0;
vn1 = v2; vn1 = v2;
hp = &(triangle->h1);
hn0 = &(triangle->h0);
hn1 = &(triangle->h2);
in0 = &(triangle->idx0); in0 = &(triangle->idx0);
in1 = &(triangle->idx2); in1 = &(triangle->idx2);
} else { } else {
vp = v2; vp = v2;
vn0 = v0; vn0 = v0;
vn1 = v1; vn1 = v1;
hp = &(triangle->h2);
hn0 = &(triangle->h0);
hn1 = &(triangle->h1);
in0 = &(triangle->idx0); in0 = &(triangle->idx0);
in1 = &(triangle->idx1); in1 = &(triangle->idx1);
} }
segment_intersection_result_t r0 = vertex_t r0 = segment_intersection(vp, vn0, plane);
segment_intersection(vp, vn0, *hp, *hn0, plane); vertex_t r1 = segment_intersection(vp, vn1, plane);
segment_intersection_result_t r1 = list_append(vertex_t, arena, model->vertices, r0);
segment_intersection(vp, vn1, *hp, *hn1, plane); list_append(vertex_t, arena, model->vertices, r1);
list_append(vec3f_t, arena, model->vertices, r0.point);
list_append(vec3f_t, arena, model->vertices, r1.point);
*in0 = model->vertices->count - 2; *in0 = model->vertices->count - 2;
*in1 = model->vertices->count - 1; *in1 = model->vertices->count - 1;
*hn0 = r0.h;
*hn1 = r1.h;
} else { } else {
vec3f_t *vn; vertex_t *vn;
vec3f_t *vp0; vertex_t *vp0;
vec3f_t *vp1; vertex_t *vp1;
f32 *hn;
f32 *hp0;
f32 *hp1;
i64 *in; i64 *in;
i64 *ip; i64 *ip;
if (d0 < 0.0f) { if (d0 < 0.0f) {
vn = v0; vn = v0;
vp0 = v1; vp0 = v1;
vp1 = v2; vp1 = v2;
hn = &(triangle->h0);
hp0 = &(triangle->h1);
hp1 = &(triangle->h2);
in = &(triangle->idx0); in = &(triangle->idx0);
ip = &(triangle->idx2); ip = &(triangle->idx2);
} else if (d1 < 0.0f) { } else if (d1 < 0.0f) {
vn = v1; vn = v1;
vp0 = v0; vp0 = v0;
vp1 = v2; vp1 = v2;
hn = &(triangle->h1);
hp0 = &(triangle->h0);
hp1 = &(triangle->h2);
in = &(triangle->idx1); in = &(triangle->idx1);
ip = &(triangle->idx2); ip = &(triangle->idx2);
} else { } else {
vn = v2; vn = v2;
vp0 = v0; vp0 = v0;
vp1 = v1; vp1 = v1;
hn = &(triangle->h2);
hp0 = &(triangle->h0);
hp1 = &(triangle->h1);
in = &(triangle->idx2); in = &(triangle->idx2);
ip = &(triangle->idx1); ip = &(triangle->idx1);
} }
segment_intersection_result_t r0 = vertex_t r0 = segment_intersection(vp0, vn, plane);
segment_intersection(vp0, vn, *hp0, *hn, plane); vertex_t r1 = segment_intersection(vp1, vn, plane);
segment_intersection_result_t r1 = list_append(vertex_t, arena, model->vertices, r0);
segment_intersection(vp1, vn, *hp1, *hn, plane); list_append(vertex_t, arena, model->vertices, r1);
list_append(vec3f_t, arena, model->vertices, r0.point);
list_append(vec3f_t, arena, model->vertices, r1.point);
*in = model->vertices->count - 2; *in = model->vertices->count - 2;
*hn = r0.h;
scene_triangle_t tri = { scene_triangle_t tri = {
.idx0 = *in, .idx0 = *in,
.idx1 = *ip, .idx1 = *ip,
.idx2 = model->vertices->count - 1, .idx2 = model->vertices->count - 1,
.h0 = *hn,
.h1 = *hp1,
.h2 = r1.h,
.colour = triangle->colour, .colour = triangle->colour,
}; };
@ -507,10 +476,10 @@ internal inline void order_triangle_points(triangle_t *triangle) {
} }
internal inline bounding_sphere_t internal inline bounding_sphere_t
get_bounding_sphere(const list_vec3f_t *vertices) { get_bounding_sphere(const list_vertex_t *vertices) {
vec3f_t sum = {0}; vec3f_t sum = {0};
for (u64 i = 0; i < vertices->count; ++i) { for (u64 i = 0; i < vertices->count; ++i) {
sum = vec_add(vec3f_t, list_get(vertices, i), sum); sum = vec_add(vec3f_t, list_get(vertices, i).position, sum);
} }
vec3f_t centre = vec_div_num(vec3f_t, sum, vertices->count); vec3f_t centre = vec_div_num(vec3f_t, sum, vertices->count);
@ -518,7 +487,7 @@ get_bounding_sphere(const list_vec3f_t *vertices) {
f32 tmp = 0.0f; f32 tmp = 0.0f;
vec3f_t dst = {0}; vec3f_t dst = {0};
for (u64 i = 0; i < vertices->count; ++i) { for (u64 i = 0; i < vertices->count; ++i) {
dst = vec_sub(vec3f_t, list_get(vertices, i), centre); dst = vec_sub(vec3f_t, list_get(vertices, i).position, centre);
tmp = vec_magnitude(vec3f_t, dst); tmp = vec_magnitude(vec3f_t, dst);
radius = tmp > radius ? tmp : radius; radius = tmp > radius ? tmp : radius;
} }
@ -529,19 +498,19 @@ get_bounding_sphere(const list_vec3f_t *vertices) {
}; };
} }
internal inline segment_intersection_result_t internal inline vertex_t segment_intersection(const vertex_t *a,
segment_intersection(const vec3f_t *a, const vec3f_t *b, f32 ha, f32 hb, const vertex_t *b,
const clipping_plane_t *plane) { const clipping_plane_t *plane) {
f32 neg_d = plane->distance * -1.0f; f32 neg_d = plane->distance * -1.0f;
f32 na_dot = vec_dot(vec3f_t, plane->normal, *a); f32 na_dot = vec_dot(vec3f_t, plane->normal, a->position);
vec3f_t ba = vec_sub(vec3f_t, *b, *a); vec3f_t ba = vec_sub(vec3f_t, b->position, a->position);
f32 nba_dot = vec_dot(vec3f_t, plane->normal, ba); f32 nba_dot = vec_dot(vec3f_t, plane->normal, ba);
f32 t = (neg_d - na_dot) / nba_dot; f32 t = (neg_d - na_dot) / nba_dot;
return (segment_intersection_result_t){ return (vertex_t){
.point = vec_add(vec3f_t, *a, vec_mul_num(vec3f_t, ba, t)), .position = vec_add(vec3f_t, a->position, vec_mul_num(vec3f_t, ba, t)),
.h = ha + t * (hb - ha), .h = a->h + t * (b->h - a->h),
}; };
} }