From b0bf4f593b4030d1e574ffba2ead4b41fedcfe7a Mon Sep 17 00:00:00 2001
From: Abdelrahman <said.abdelrahman89@gmail.com>
Date: Sat, 13 Jul 2024 19:32:02 +0100
Subject: [PATCH] Add h values for scene_triangle_t

---
 include/rasteriser/rasteriser.h |  3 ++
 src/rasteriser/main.c           | 36 ++++++++++------
 src/rasteriser/rasteriser.c     | 76 ++++++++++++++++++++++++++-------
 3 files changed, 87 insertions(+), 28 deletions(-)

diff --git a/include/rasteriser/rasteriser.h b/include/rasteriser/rasteriser.h
index 20a70b9..f67b8f6 100644
--- a/include/rasteriser/rasteriser.h
+++ b/include/rasteriser/rasteriser.h
@@ -14,6 +14,9 @@ typedef struct {
   i64 idx0;
   i64 idx1;
   i64 idx2;
+  f32 h0;
+  f32 h1;
+  f32 h2;
   colour_t colour;
 } scene_triangle_t;
 
diff --git a/src/rasteriser/main.c b/src/rasteriser/main.c
index 8d8a897..d083ea6 100644
--- a/src/rasteriser/main.c
+++ b/src/rasteriser/main.c
@@ -53,18 +53,30 @@ int main(void) {
   }
   // Triangles
   scene_triangle_t tris[] = {
-      (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}},
+      (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}},
   };
   for (u64 i = 0; i < ARR_LEN(tris); ++i) {
     list_append(scene_triangle_t, arena, triangles, tris[i]);
diff --git a/src/rasteriser/rasteriser.c b/src/rasteriser/rasteriser.c
index 60a6041..331ec56 100644
--- a/src/rasteriser/rasteriser.c
+++ b/src/rasteriser/rasteriser.c
@@ -11,6 +11,11 @@
 #include <string.h>
 #include <sys/mman.h>
 
+typedef struct {
+  vec3f_t point;
+  f32 h;
+} segment_intersection_result_t;
+
 internal void render_instance(window_t *wnd, const rasteriser_scene_t *scene,
                               Arena *arena, mat4x4f_t camera_matrix,
                               mat3x4f_t projection_matrix,
@@ -29,8 +34,9 @@ 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 vec3f_t segment_intersection(const vec3f_t *a, const vec3f_t *b,
-                                             const clipping_plane_t *plane);
+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 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,
@@ -119,9 +125,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 = 1.0f,
-        .h1 = 1.0f,
-        .h2 = 1.0f,
+        .h0 = triangle.h0,
+        .h1 = triangle.h1,
+        .h2 = triangle.h2,
         .colour = triangle.colour,
     };
 
@@ -351,72 +357,106 @@ internal void clip_triangle_against_plane(Arena *arena, model_t *model,
     vec3f_t *vp;
     vec3f_t *vn0;
     vec3f_t *vn1;
+    f32 *hp;
+    f32 *hn0;
+    f32 *hn1;
     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);
     }
 
-    list_append(vec3f_t, arena, model->vertices,
-                segment_intersection(vp, vn0, plane));
-    list_append(vec3f_t, arena, model->vertices,
-                segment_intersection(vp, vn1, plane));
+    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);
 
     *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;
     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);
     }
 
-    list_append(vec3f_t, arena, model->vertices,
-                segment_intersection(vp0, vn, plane));
-    list_append(vec3f_t, arena, model->vertices,
-                segment_intersection(vp1, vn, plane));
+    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);
 
     *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,
     };
 
@@ -489,8 +529,9 @@ get_bounding_sphere(const list_vec3f_t *vertices) {
   };
 }
 
-internal inline vec3f_t segment_intersection(const vec3f_t *a, const vec3f_t *b,
-                                             const clipping_plane_t *plane) {
+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) {
   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);
@@ -498,7 +539,10 @@ internal inline vec3f_t segment_intersection(const vec3f_t *a, const vec3f_t *b,
 
   f32 t = (neg_d - na_dot) / nba_dot;
 
-  return vec_add(vec3f_t, *a, vec_mul_num(vec3f_t, ba, t));
+  return (segment_intersection_result_t){
+      .point = vec_add(vec3f_t, *a, vec_mul_num(vec3f_t, ba, t)),
+      .h = ha + t * (hb - ha),
+  };
 }
 
 internal inline void copy_triangles(Arena *arena, list_scene_triangle_t *dst,