From 11ee5c982808592c9fba540bf4a5804c494bb2af Mon Sep 17 00:00:00 2001 From: Zack Buhman Date: Sun, 9 Feb 2025 14:04:21 -0600 Subject: [PATCH] silhouette triangulation --- main.cpp | 131 ++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 124 insertions(+), 7 deletions(-) diff --git a/main.cpp b/main.cpp index 551a12e..c1b9421 100644 --- a/main.cpp +++ b/main.cpp @@ -433,6 +433,7 @@ void render_quad(SDL_Renderer * renderer, assert(SDL_SetRenderDrawColorFloat(renderer, 1, 0, 0, 1)); + /* vec3 origin = (position[quadrilateral->a.position] + position[quadrilateral->b.position] + position[quadrilateral->c.position] + @@ -441,6 +442,57 @@ void render_quad(SDL_Renderer * renderer, vec3 origin_t = transform_vertex(origin, scale); vec3 origin_n_t = transform_vertex(origin + n, scale); render_line_vtx(renderer, origin_t, origin_n_t); + */ +} + +struct edge { + int a; + int b; +}; + +struct tri { + int a; + int b; + int c; +}; + +void render_tri(SDL_Renderer * renderer, + const vec3 * position, + const vec3 color, + struct tri tri + ) +{ + assert(SDL_SetRenderDrawColorFloat(renderer, color.x, color.y, color.z, 1)); + + vec3 ap = position[tri.a]; + vec3 bp = position[tri.b]; + vec3 cp = position[tri.c]; + + float scale = 0.5f; + vec3 a = transform_vertex(ap, scale); + vec3 b = transform_vertex(bp, scale); + vec3 c = transform_vertex(cp, scale); + + render_line_vtx(renderer, a, b); + render_line_vtx(renderer, b, c); + render_line_vtx(renderer, c, a); +} + +struct tri generate_tri(struct edge * silhouette, + int * order, + int o0, + int o1) +{ + struct tri tri; + tri.a = silhouette[order[o0]].a; + tri.b = silhouette[order[o0]].b; + if (silhouette[order[o0]].a == silhouette[order[o1]].a || + silhouette[order[o0]].b == silhouette[order[o1]].a) { + tri.c = silhouette[order[o1]].b; + } else { + tri.c = silhouette[order[o1]].a; + } + return tri; } void render_silhouette(SDL_Renderer * renderer, @@ -450,20 +502,85 @@ void render_silhouette(SDL_Renderer * renderer, { assert(SDL_SetRenderDrawColorFloat(renderer, 1, 0.5, 0, 1)); + struct edge silhouette[6]; + int ix = 0; + for (int a = 0; a < edge_stride; a++) { for (int b = 0; b < edge_stride; b++) { uint8_t coloring = edge_coloring[a * edge_stride + b]; if (coloring == 0b11) { - vec3 ap = position[a]; - vec3 bp = position[b]; - - float scale = 0.5f; - vec3 av = transform_vertex(ap, scale); - vec3 bv = transform_vertex(bp, scale); - render_line_vtx(renderer, av, bv); + silhouette[ix++] = {a, b}; } } } + + assert(ix == 6); + + int order[6]; + order[0] = 0; + int order_ix = 1; + int vtx = silhouette[0].b; + + // calculate edge ordering + while (order_ix < 6) { + for (int i = 1; i < 6; i++) { + if (i == order[order_ix - 1]) + continue; + + if (silhouette[i].a == vtx) { + vtx = silhouette[i].b; + order[order_ix++] = i; + break; + } + if (silhouette[i].b == vtx) { + vtx = silhouette[i].a; + order[order_ix++] = i; + break; + } + } + } + + assert(order_ix == 6); + + const vec3 colors[] = { + {1, 0, 0}, // red + {1, 0.5, 0}, // orange + {1, 1, 0}, // yellow + {0, 1, 0}, // green + {0, 1, 1}, // cyan + {0.5, 0, 1}, // purple + }; + + /* + for (int i = 0; i < 6; i++) { + assert(SDL_SetRenderDrawColorFloat(renderer, colors[i].x, colors[i].y, colors[i].z, 1)); + + vec3 ap = position[silhouette[order[i]].a]; + vec3 bp = position[silhouette[order[i]].b]; + + float scale = 0.5f; + vec3 av = transform_vertex(ap, scale); + vec3 bv = transform_vertex(bp, scale); + render_line_vtx(renderer, av, bv); + } + */ + + // render triangulation + /* + {0.a, 0.b}, {1.a, 1.b}, {0._, 1._} + {2.a, 2.b}, {3.a, 3.b}, {2._, 3._} + {4.a, 4.b}, {5.a, 5.b}, {4._, 5._} + {0._, 1._}, {2._, 3._}, {4._, 5._} + */ + struct tri q = generate_tri(silhouette, order, 0, 1); + struct tri r = generate_tri(silhouette, order, 2, 3); + struct tri s = generate_tri(silhouette, order, 4, 5); + struct tri t = {q.c, r.c, s.c}; + + render_tri(renderer, position, colors[1], q); + render_tri(renderer, position, colors[2], r); + render_tri(renderer, position, colors[3], s); + render_tri(renderer, position, colors[0], t); } void render_cube(SDL_Renderer * renderer, const vec3 light_vec)