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

View File

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

View File

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