Transpose the qug array, remove pug array in favour of individual columns
authorNick Downing <nick@ndcode.org>
Wed, 20 Apr 2022 06:34:53 +0000 (16:34 +1000)
committerNick Downing <nick@ndcode.org>
Wed, 20 Apr 2022 06:34:53 +0000 (16:34 +1000)
render.c

index d60a505..2da329f 100644 (file)
--- a/render.c
+++ b/render.c
@@ -159,19 +159,24 @@ struct array *mat_unproject(struct array *A) {
   return B;
 }
 
-// special for column-wise vertex arrays
-// construct row-wise array for a given face
-struct array *gather(struct array *A, int n_cols, int *cols) {
+struct array *mat_column(struct array *A, size_t col) {
   assert(A->n_dims == 3);
   assert(A->dim[2] == sizeof(float));
-  size_t J = A->dim[0];
-  struct array *B = array_new3(n_cols, J, sizeof(float));
-  for (int i = 0; i < n_cols; ++i) {
-    int col = cols[i];
-    assert(col >= 0 && col < A->dim[1]);
-    for (size_t j = 0; j < J; ++j)
-      *(float *)array_index2(B, i, j) = *(float *)array_index2(A, j, col);
-  }
+  size_t I = A->dim[0];
+  struct array *B = array_new2(I, sizeof(float));
+  for (size_t i = 0; i < I; ++i)
+    *(float *)array_index1(B, i) = *(float *)array_index2(A, i, col);
+  return B; 
+}
+
+struct array *mat_columns(struct array *A, size_t n_cols, size_t *cols) {
+  assert(A->n_dims == 3);
+  assert(A->dim[2] == sizeof(float));
+  size_t I = A->dim[0];
+  struct array *B = array_new3(I, n_cols, sizeof(float));
+  for (size_t i = 0; i < I; ++i)
+    for (size_t j = 0; j < n_cols; ++j)
+      *(float *)array_index2(B, i, j) = *(float *)array_index2(A, i, cols[j]);
   return B; 
 }
 
@@ -324,7 +329,7 @@ int main(void) {
         *(float *)array_index2(model_vertices, 2, l) = v[2];
         *(float *)array_index2(model_vertices, 3, l) = v[3];
       }
-  int model_lines[12][2] = {
+  size_t model_lines[12][2] = {
     {0, 1}, // 0, 0, 0 -> 0, 0, 1
     {0, 2}, // 0, 0, 0 -> 0, 1, 0
     {0, 4}, // 0, 0, 0 -> 1, 0, 0
@@ -528,79 +533,76 @@ int main(void) {
       for (int i = 0; i < I; ++i) {
         int J = obj->sv[i].pc;
         for (int j = 0; j < J; ++j) {
-          int v[3] = {
-            (int)obj->sv[i].pv[j].vi[0],
-            (int)obj->sv[i].pv[j].vi[1],
-            (int)obj->sv[i].pv[j].vi[2]
+          size_t v[3] = {
+            obj->sv[i].pv[j].vi[0],
+            obj->sv[i].pv[j].vi[1],
+            obj->sv[i].pv[j].vi[2]
           };
 
 #if 1
           // check face visibility
-          struct array *pug = gather(pu, 3, v);
-          struct array *pug0 = array_dup1(pug, 0);
-          struct array *pug1 = array_dup1(pug, 1);
-          struct array *pug2 = array_dup1(pug, 2);
-          struct array *dir1 = vec_sub(pug1, pug0);
-          struct array *dir2 = vec_sub(pug2, pug0);
+          struct array *pu0 = mat_column(pu, v[0]);
+          struct array *pu1 = mat_column(pu, v[1]);
+          struct array *pu2 = mat_column(pu, v[2]);
+          struct array *dir1 = vec_sub(pu1, pu0);
+          struct array *dir2 = vec_sub(pu2, pu0);
           struct array *norm = vec_cross(dir1, dir2); // outward pointing
           if (
             /*vec_dot(norm, norm) < EPSILON ||*/ // degenerate face
-            vec_dot(norm, pug0) >= -EPSILON // origin is on underside of face
+            vec_dot(norm, pu0) >= -EPSILON // origin is on underside of face
           ) {
             array_free(norm);
             array_free(dir2);
             array_free(dir1);
-            array_free(pug2);
-            array_free(pug1);
-            array_free(pug0);
-            array_free(pug);
+            array_free(pu2);
+            array_free(pu1);
+            array_free(pu0);
             continue;
           }
           array_free(norm);
           array_free(dir2);
           array_free(dir1);
-          array_free(pug2);
-          array_free(pug1);
-          array_free(pug0);
-          array_free(pug);
+          array_free(pu2);
+          array_free(pu1);
+          array_free(pu0);
 #endif
 
-          struct array *qug = gather(qu, 3, v);
+          struct array *qug = mat_columns(qu, 3, v);
           SDL_RenderDrawLine(
             renderer,
             *(float *)array_index2(qug, 0, 0),
-            *(float *)array_index2(qug, 0, 1),
             *(float *)array_index2(qug, 1, 0),
+            *(float *)array_index2(qug, 0, 1),
             *(float *)array_index2(qug, 1, 1)
           );
           SDL_RenderDrawLine(
             renderer,
-            *(float *)array_index2(qug, 1, 0),
+            *(float *)array_index2(qug, 0, 1),
             *(float *)array_index2(qug, 1, 1),
-            *(float *)array_index2(qug, 2, 0),
-            *(float *)array_index2(qug, 2, 1)
+            *(float *)array_index2(qug, 0, 2),
+            *(float *)array_index2(qug, 1, 2)
           );
           SDL_RenderDrawLine(
             renderer,
-            *(float *)array_index2(qug, 2, 0),
-            *(float *)array_index2(qug, 2, 1),
+            *(float *)array_index2(qug, 0, 2),
+            *(float *)array_index2(qug, 1, 2),
             *(float *)array_index2(qug, 0, 0),
-            *(float *)array_index2(qug, 0, 1)
+            *(float *)array_index2(qug, 1, 0)
           );
           array_free(qug);
         }
         /*int*/ J = obj->sv[i].lc;
         for (int j = 0; j < J; ++j) {
-          int v[2] = {
-            (int)obj->sv[i].lv[j].vi[0],
-            (int)obj->sv[i].lv[j].vi[1]
+          size_t v[2] = {
+            obj->sv[i].lv[j].vi[0],
+            obj->sv[i].lv[j].vi[1]
           };
-          struct array *qug = gather(qu, 2, v);
+          struct array *qug = mat_columns(qu, 2, v);
           SDL_RenderDrawLine(
             renderer,
             *(float *)array_index2(qug, 0, 0),
-            *(float *)array_index2(qug, 0, 1),
             *(float *)array_index2(qug, 1, 0),
+            *(float *)array_index2(qug, 0, 1),
             *(float *)array_index2(qug, 1, 1)
           );
           array_free(qug);
@@ -609,12 +611,12 @@ int main(void) {
     }
 #else
     for (int i = 0; i < 12; ++i) {
-      struct array *qug = gather(qu, 2, model_lines[i]);
+      struct array *qug = mat_columns(qu, 2, model_lines[i]);
       SDL_RenderDrawLine(
         renderer,
         *(float *)array_index2(qug, 0, 0),
-        *(float *)array_index2(qug, 0, 1),
         *(float *)array_index2(qug, 1, 0),
+        *(float *)array_index2(qug, 0, 1),
         *(float *)array_index2(qug, 1, 1)
       );
       array_free(qug);