Allow to spin the cube
authorNick Downing <nick@ndcode.org>
Mon, 18 Apr 2022 14:46:17 +0000 (00:46 +1000)
committerNick Downing <nick@ndcode.org>
Mon, 18 Apr 2022 14:46:17 +0000 (00:46 +1000)
render.c

index 6d0931e..de2fa8d 100644 (file)
--- a/render.c
+++ b/render.c
@@ -8,6 +8,9 @@
 
 #define EPSILON 1e-6f
 
+#define COS_5DEG .99619470f // math.cos(5 * math.pi / 180.) 
+#define SIN_5DEG .087155743f // math.sin(5 * math.pi / 180.)
+
 SDL_Window *window;
 SDL_Renderer *renderer;
 SDL_Surface *window_surface;
@@ -99,6 +102,19 @@ void mul_mat34_mat44(struct array *A, struct array *B, struct array *C) {
       array_set2(C, &c, i, j);
     }
 }
+void mul_mat44_mat44(struct array *A, struct array *B, struct array *C) {
+  for (int i = 0; i < 4; ++i)
+    for (int j = 0; j < 4; ++j) {
+      float c = 0.f;
+      for (int k = 0; k < 4; ++k) {
+        float a, b;
+        array_get2(A, &a, i, k);
+        array_get2(B, &b, k, j);
+        c += a * b;
+      }
+      array_set2(C, &c, i, j);
+    }
+}
 void mul_mat34_vec4(struct array *A, struct array *B, struct array *C) {
   for (int i = 0; i < 3; ++i) {
     float c = 0.f;
@@ -112,6 +128,15 @@ void mul_mat34_vec4(struct array *A, struct array *B, struct array *C) {
   }
 }
 
+void rotate(const float (*v)[4], struct array *transform) {
+  struct array *t0 = array_new3(4, 4, sizeof(float));
+  array_set0(t0, v);
+  struct array *t1 = array_new3(4, 4, sizeof(float));
+  mul_mat44_mat44(t0, transform, t1);
+  size_t size;
+  array_set0(transform, array_index0(t1, &size));
+}
+
 int main(void) {
   if (SDL_Init(SDL_INIT_VIDEO) < 0) {
     fprintf(stderr, "SDL_Init(): %s\n\n", SDL_GetError());
@@ -177,7 +202,21 @@ int main(void) {
   printf("\n");
 
   // camera
-  struct array *camera_transform = array_new3(4, 4, sizeof(float));
+  struct array *camera_rotate = array_new3(4, 4, sizeof(float));
+  {
+    float v[4][4] = {
+      {1.f, 0.f, 0.f, 0.f},
+      {0.f, 1.f, 0.f, 0.f},
+      {0.f, 0.f, 1.f, 0.f},
+      {0.f, 0.f, 0.f, 1.f}
+    };
+    array_set0(camera_rotate, v);
+  }
+  printf("camera_rotate\n");
+  print_mat440(camera_rotate);
+  printf("\n");
+
+  struct array *camera_translate = array_new3(4, 4, sizeof(float));
   {
     float v[4][4] = {
       {1.f, 0.f, 0.f, 0.f},
@@ -185,10 +224,10 @@ int main(void) {
       {0.f, 0.f, 1.f, 0.f},
       {0.f, 0.f, 0.f, 1.f}
     };
-    array_set0(camera_transform, v);
+    array_set0(camera_translate, v);
   }
-  printf("camera_transform\n");
-  print_mat440(camera_transform);
+  printf("camera_translate\n");
+  print_mat440(camera_translate);
   printf("\n");
 
   // model
@@ -238,7 +277,7 @@ int main(void) {
     //{7, 3}, // 1, 1, 1 -> 0, 1, 1
   };
 
-  struct array *model_transform = array_new3(4, 4, sizeof(float));
+  struct array *model_rotate = array_new3(4, 4, sizeof(float));
   {
     float v[4][4] = {
       {1.f, 0.f, 0.f, 0.f},
@@ -246,10 +285,24 @@ int main(void) {
       {0.f, 0.f, 1.f, 0.f},
       {0.f, 0.f, 0.f, 1.f}
     };
-    array_set0(model_transform, v);
+    array_set0(model_rotate, v);
   }
-  printf("model_transform\n");
-  print_mat440(model_transform);
+  printf("model_rotate\n");
+  print_mat440(model_rotate);
+  printf("\n");
+
+  struct array *model_translate = array_new3(4, 4, sizeof(float));
+  {
+    float v[4][4] = {
+      {1.f, 0.f, 0.f, 0.f},
+      {0.f, 1.f, 0.f, 0.f},
+      {0.f, 0.f, 1.f, 0.f},
+      {0.f, 0.f, 0.f, 1.f}
+    };
+    array_set0(model_translate, v);
+  }
+  printf("model_translate\n");
+  print_mat440(model_translate);
   printf("\n");
 
   // main loop
@@ -259,6 +312,79 @@ int main(void) {
       switch (event.type) {
       case SDL_QUIT:
         goto quit;
+      case SDL_KEYDOWN:
+        {
+          SDL_KeyboardEvent *e = (SDL_KeyboardEvent *)&event;
+          switch (e->keysym.sym) {
+          case SDLK_u:
+            {
+              float v[4][4] = {
+                {COS_5DEG, 0.f, SIN_5DEG, 0.f},
+                {0.f, 1.f, 0.f, 0.f},
+                {-SIN_5DEG, 0.f, COS_5DEG, 0.f},
+                {0.f, 0.f, 0.f, 1.f}
+              };
+              rotate(v, model_rotate);
+            }
+            break;
+          case SDLK_i:
+            {
+              float v[4][4] = {
+                {1.f, 0.f, 0.f, 0.f},
+                {0.f, COS_5DEG, -SIN_5DEG, 0.f},
+                {0.f, SIN_5DEG, COS_5DEG, 0.f},
+                {0.f, 0.f, 0.f, 1.f}
+              };
+              rotate(v, model_rotate);
+            }
+            break;
+          case SDLK_o:
+            {
+              float v[4][4] = {
+                {COS_5DEG, 0.f, -SIN_5DEG, 0.f},
+                {0.f, 1.f, 0.f, 0.f},
+                {SIN_5DEG, 0.f, COS_5DEG, 0.f},
+                {0.f, 0.f, 0.f, 1.f}
+              };
+              rotate(v, model_rotate);
+            }
+            break;
+          case SDLK_j:
+            {
+              float v[4][4] = {
+                {COS_5DEG, SIN_5DEG, 0.f, 0.f},
+                {-SIN_5DEG, COS_5DEG, 0.f, 0.f},
+                {0.f, 0.f, 1.f, 0.f},
+                {0.f, 0.f, 0.f, 1.f}
+              };
+              rotate(v, model_rotate);
+            }
+            break;
+          case SDLK_k:
+            {
+              float v[4][4] = {
+                {1.f, 0.f, 0.f, 0.f},
+                {0.f, COS_5DEG, SIN_5DEG, 0.f},
+                {0.f, -SIN_5DEG, COS_5DEG, 0.f},
+                {0.f, 0.f, 0.f, 1.f}
+              };
+              rotate(v, model_rotate);
+            }
+            break;
+          case SDLK_l:
+            {
+              float v[4][4] = {
+                {COS_5DEG, -SIN_5DEG, 0.f, 0.f},
+                {SIN_5DEG, COS_5DEG, 0.f, 0.f},
+                {0.f, 0.f, 1.f, 0.f},
+                {0.f, 0.f, 0.f, 1.f}
+              };
+              rotate(v, model_rotate);
+            }
+            break;
+          }
+        }
+        break;
       }
 
     SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0xff);
@@ -268,9 +394,13 @@ int main(void) {
     struct array *t0 = array_new3(3, 4, sizeof(float));
     mul_mat33_mat34(device_transform, perspective_transform, t0);
     struct array *t1 = array_new3(3, 4, sizeof(float));
-    mul_mat34_mat44(t0, camera_transform, t1);
+    mul_mat34_mat44(t0, camera_rotate, t1);
     struct array *t2 = array_new3(3, 4, sizeof(float));
-    mul_mat34_mat44(t1, model_transform, t2);
+    mul_mat34_mat44(t1, camera_translate, t2);
+    struct array *t3 = array_new3(3, 4, sizeof(float));
+    mul_mat34_mat44(t2, model_rotate, t3);
+    struct array *t4 = array_new3(3, 4, sizeof(float));
+    mul_mat34_mat44(t3, model_translate, t4);
 
     // transform model points
     struct array *p = array_new3(8, 3, sizeof(float));
@@ -280,7 +410,7 @@ int main(void) {
         float c = 0.f;
         for (int k = 0; k < 4; ++k) {
           float a, b;
-          array_get2(t2, &a, j, k);
+          array_get2(t4, &a, j, k);
           array_get2(model_vertices, &b, i, k);
           c += a * b;
         }
@@ -310,6 +440,8 @@ int main(void) {
     }
 
     array_free(p);
+    array_free(t4);
+    array_free(t3);
     array_free(t2);
     array_free(t1);
     array_free(t0);