mostly correct camera movement
authorBrendan Hansen <brendan.f.hansen@gmail.com>
Fri, 17 Dec 2021 04:04:07 +0000 (22:04 -0600)
committerBrendan Hansen <brendan.f.hansen@gmail.com>
Fri, 17 Dec 2021 04:04:07 +0000 (22:04 -0600)
src/main.onyx

index c9bcf3fe7c7c5952fe2a932435d6f831e842144c..e59602d217dbd5c43c6ddf9a32b429e16fb89849 100644 (file)
@@ -15,6 +15,8 @@ create_window :: () => {
     glfwSwapInterval(1);
     glfwSetWindowSizeCallback(window, "on_resize");
     glfwSetKeyCallback(window, "on_key");
+
+    glfwSetInputMode(window, GLFW_CURSOR, GLFW_CURSOR_DISABLED);
 }
 
 #export "on_resize" (window: GLFWwindow_p, width, height: u32) {
@@ -159,7 +161,7 @@ setup_opengl :: () {
     cube_mesh = make_cube_mesh();
 
     update_view_matrix();
-    update_world_matrix();
+    // update_world_matrix();
 }
 
 update_view_matrix :: () {
@@ -186,17 +188,44 @@ update_view_matrix :: () {
     glBindBuffer(GL_UNIFORM_BUFFER, -1);
 }
 
-update_world_matrix :: () {
-    #persist t := 0.0f;
-    t += 0.01;
+Vector3 :: struct {
+    x, y, z: f32;
+
+    neg :: macro (v: Vector3) => Vector3.{ -v.x, -v.y, -v.z };
+
+    dot :: macro (v1, v2: Vector3) -> f32 {
+        return v1.x * v2.x + v1.y * v2.y + v1.z * v2.z;
+    }
+
+    norm :: macro (v: Vector3) -> Vector3 {
+        l := math.sqrt(v.x * v.x + v.y * v.y + v.z * v.z);
+        return .{ v.x / l, v.y / l, v.z / l };
+    }
+
+    cross :: macro (v1, v2: Vector3) -> Vector3 {
+        return .{
+            v1.y * v2.z - v1.z * v2.y,
+            v1.z * v2.x - v1.x * v2.z,
+            v1.x * v2.y - v1.y * v2.x,
+        };
+    }
+}
+
+#operator + macro (v1, v2: Vector3) => Vector3.{ v1.x + v2.x, v1.y + v2.y, v1.z + v2.z };
+#operator - macro (v1, v2: Vector3) => Vector3.{ v1.x - v2.x, v1.y - v2.y, v1.z - v2.z };
+
+update_world_matrix :: (position: Vector3, facing: Vector3, up: Vector3) {
+    forward := Vector3.norm(facing); //center - position);
+    side    := Vector3.cross(forward, up) |> Vector3.norm();
+    new_up  := Vector3.cross(side, forward);
+
+    neg_pos := Vector3.neg(position);
 
-    c := math.cos(t);
-    s := math.sin(t);
     matrix := GLfloat.[
-        1, 0, 0, 0,
-        0, c, s, 0,
-        0, -s, c, 0,
-        0, 0, -3, 1,
+        side.x, new_up.x, -forward.x, 0,
+        side.y, new_up.y, -forward.y, 0,
+        side.z, new_up.z, -forward.z, 0,
+        Vector3.dot(side, neg_pos), Vector3.dot(new_up, neg_pos), Vector3.dot(Vector3.neg(forward), neg_pos), 1,
     ];
 
     glBindBuffer(GL_UNIFORM_BUFFER, matrix_block_buffer);
@@ -204,8 +233,31 @@ update_world_matrix :: () {
     glBindBuffer(GL_UNIFORM_BUFFER, -1);
 }
 
+theta := 0.0f; // y-axis
+phi := 0.0f; // x-axis
+
 update :: (dt: f32) {
-    update_world_matrix();
+    #persist t := 0.0f;
+    t += dt;
+
+    #persist last_mouse_x: f64;
+    #persist last_mouse_y: f64;
+
+    mx, my: f64;
+    glfwGetCursorPos(window, ^mx, ^my);
+    theta += ~~(last_mouse_x - mx) / 400.0f;
+    phi += ~~(my - last_mouse_y) / 400.0f;
+    phi = math.clamp(phi, -math.PI / 2 + 0.1, math.PI / 2 - 0.1);
+    last_mouse_x = mx;
+    last_mouse_y = my;
+
+    facing := Vector3.{
+        math.cos(phi) * math.sin(theta),
+        -math.sin(phi),
+        math.cos(theta) * math.cos(phi)
+    };
+
+    update_world_matrix(.{ 5, 5, 5 }, facing, .{ 0, 1, 0 });
 }
 
 draw :: () {
@@ -223,7 +275,6 @@ draw :: () {
 main_loop :: () {
     while !glfwWindowShouldClose(window) {
         glfwPollEvents();
-
         update(1.0f / 60);
         draw();
     }