Prechádzať zdrojové kódy

Review camera module

This module still requires further work but 3rd person camera is less broken now...
Ray 6 rokov pred
rodič
commit
cc1dd6b410
1 zmenil súbory, kde vykonal 60 pridanie a 69 odobranie
  1. 60 69
      src/camera.h

+ 60 - 69
src/camera.h

@@ -16,13 +16,13 @@
 *       functions must be redefined to manage inputs accordingly.
 *
 *   CONTRIBUTORS:
-*       Marc Palau:         Initial implementation (2014)
 *       Ramon Santamaria:   Supervision, review, update and maintenance
+*       Marc Palau:         Initial implementation (2014)
 *
 *
 *   LICENSE: zlib/libpng
 *
-*   Copyright (c) 2015-2017 Ramon Santamaria (@raysan5)
+*   Copyright (c) 2015-2019 Ramon Santamaria (@raysan5)
 *
 *   This software is provided "as-is", without any express or implied warranty. In no event
 *   will the authors be held liable for any damages arising from the use of this software.
@@ -54,15 +54,6 @@
 // NOTE: Below types are required for CAMERA_STANDALONE usage
 //----------------------------------------------------------------------------------
 #if defined(CAMERA_STANDALONE)
-    // Camera modes
-    typedef enum { 
-        CAMERA_CUSTOM = 0, 
-        CAMERA_FREE, 
-        CAMERA_ORBITAL, 
-        CAMERA_FIRST_PERSON, 
-        CAMERA_THIRD_PERSON 
-    } CameraMode;
-
     // Vector2 type
     typedef struct Vector2 {
         float x;
@@ -77,12 +68,30 @@
     } Vector3;
 
     // Camera type, defines a camera position/orientation in 3d space
-    typedef struct Camera {
-        Vector3 position;
-        Vector3 target;
-        Vector3 up;
-        float fovy;
-    } Camera;
+    typedef struct Camera3D {
+        Vector3 position;       // Camera position
+        Vector3 target;         // Camera target it looks-at
+        Vector3 up;             // Camera up vector (rotation over its axis)
+        float fovy;             // Camera field-of-view apperture in Y (degrees) in perspective, used as near plane width in orthographic
+        int type;               // Camera type, defines projection type: CAMERA_PERSPECTIVE or CAMERA_ORTHOGRAPHIC
+    } Camera3D;
+
+    typedef Camera3D Camera;    // Camera type fallback, defaults to Camera3D
+    
+    // Camera system modes
+    typedef enum {
+        CAMERA_CUSTOM = 0,
+        CAMERA_FREE,
+        CAMERA_ORBITAL,
+        CAMERA_FIRST_PERSON,
+        CAMERA_THIRD_PERSON
+    } CameraMode;
+
+    // Camera projection modes
+    typedef enum {
+        CAMERA_PERSPECTIVE = 0,
+        CAMERA_ORTHOGRAPHIC
+    } CameraType;
 #endif
 
 #ifdef __cplusplus
@@ -103,7 +112,7 @@ void UpdateCamera(Camera *camera);                          // Update camera pos
 
 void SetCameraPanControl(int panKey);                       // Set camera pan key to combine with mouse movement (free camera)
 void SetCameraAltControl(int altKey);                       // Set camera alt key to combine with mouse movement (free camera)
-void SetCameraSmoothZoomControl(int szKey);                 // Set camera smooth zoom key to combine with mouse (free camera)
+void SetCameraSmoothZoomControl(int szoomKey);              // Set camera smooth zoom key to combine with mouse (free camera)
 void SetCameraMoveControls(int frontKey, int backKey, 
                            int rightKey, int leftKey, 
                            int upKey, int downKey);         // Set camera move controls (1st person and 3rd person cameras)
@@ -124,16 +133,14 @@ void SetCameraMoveControls(int frontKey, int backKey,
 
 #if defined(CAMERA_IMPLEMENTATION)
 
-#include <math.h>               // Required for: sqrt(), sin(), cos()
+#include <math.h>               // Required for: sqrt(), sinf(), cosf()
 
 #ifndef PI
     #define PI 3.14159265358979323846
 #endif
-
 #ifndef DEG2RAD
     #define DEG2RAD (PI/180.0f)
 #endif
-
 #ifndef RAD2DEG
     #define RAD2DEG (180.0f/PI)
 #endif
@@ -193,8 +200,8 @@ typedef enum {
 //----------------------------------------------------------------------------------
 // Global Variables Definition
 //----------------------------------------------------------------------------------
-static Vector2 cameraAngle = { 0.0f, 0.0f };          // TODO: Remove! Compute it in UpdateCamera()
-static float cameraTargetDistance = 0.0f;             // TODO: Remove! Compute it in UpdateCamera()
+static Vector2 cameraAngle = { 0.0f, 0.0f };          // Camera angle in plane XZ
+static float cameraTargetDistance = 0.0f;             // Camera distance from position to target 
 static float playerEyesPosition = 1.85f;              // Default player eyes position from ground (in meters) 
 
 static int cameraMoveControl[6]  = { 'W', 'S', 'D', 'A', 'E', 'Q' };
@@ -227,9 +234,6 @@ static Vector2 GetMousePosition() { return (Vector2){ 0.0f, 0.0f }; }
 // Select camera mode (multiple camera modes available)
 void SetCameraMode(Camera camera, int mode)
 {
-    // TODO: cameraTargetDistance and cameraAngle should be 
-    // calculated using camera parameters on UpdateCamera()
-
     Vector3 v1 = camera.position;
     Vector3 v2 = camera.target;
     
@@ -254,9 +258,8 @@ void SetCameraMode(Camera camera, int mode)
     playerEyesPosition = camera.position.y;
     
     // Lock cursor for first person and third person cameras
-    if ((mode == CAMERA_FIRST_PERSON) || 
-        (mode == CAMERA_THIRD_PERSON)) DisableCursor();
-    else EnableCursor(); 
+    if ((mode == CAMERA_FIRST_PERSON) || (mode == CAMERA_THIRD_PERSON)) DisableCursor();
+    else EnableCursor();
 
     cameraMode = mode;
 }
@@ -385,6 +388,11 @@ void UpdateCamera(Camera *camera)
                     camera->target.z += ((mousePositionDelta.x*CAMERA_FREE_MOUSE_SENSITIVITY)*sinf(cameraAngle.x) + (mousePositionDelta.y*CAMERA_FREE_MOUSE_SENSITIVITY)*cosf(cameraAngle.x)*sinf(cameraAngle.y))*(cameraTargetDistance/CAMERA_FREE_PANNING_DIVIDER);
                 }
             }
+            
+            // Update camera position with changes
+            camera->position.x = sinf(cameraAngle.x)*cameraTargetDistance*cosf(cameraAngle.y) + camera->target.x;
+            camera->position.y = ((cameraAngle.y <= 0.0f)? 1 : -1)*sinf(cameraAngle.y)*cameraTargetDistance*sinf(cameraAngle.y) + camera->target.y;
+            camera->position.z = cosf(cameraAngle.x)*cameraTargetDistance*cosf(cameraAngle.y) + camera->target.z;
 
         } break;
         case CAMERA_ORBITAL:
@@ -395,6 +403,11 @@ void UpdateCamera(Camera *camera)
             // Camera distance clamp
             if (cameraTargetDistance < CAMERA_THIRD_PERSON_DISTANCE_CLAMP) cameraTargetDistance = CAMERA_THIRD_PERSON_DISTANCE_CLAMP;
             
+            // Update camera position with changes
+            camera->position.x = sinf(cameraAngle.x)*cameraTargetDistance*cosf(cameraAngle.y) + camera->target.x;
+            camera->position.y = ((cameraAngle.y <= 0.0f)? 1 : -1)*sinf(cameraAngle.y)*cameraTargetDistance*sinf(cameraAngle.y) + camera->target.y;
+            camera->position.z = cosf(cameraAngle.x)*cameraTargetDistance*cosf(cameraAngle.y) + camera->target.z;
+   
         } break;
         case CAMERA_FIRST_PERSON:
         case CAMERA_THIRD_PERSON:
@@ -421,34 +434,17 @@ void UpdateCamera(Camera *camera)
             cameraAngle.x += (mousePositionDelta.x*-CAMERA_MOUSE_MOVE_SENSITIVITY);
             cameraAngle.y += (mousePositionDelta.y*-CAMERA_MOUSE_MOVE_SENSITIVITY);
             
-            if (cameraMode == CAMERA_THIRD_PERSON)
-            {
-                // Angle clamp
-                if (cameraAngle.y > CAMERA_THIRD_PERSON_MIN_CLAMP*DEG2RAD) cameraAngle.y = CAMERA_THIRD_PERSON_MIN_CLAMP*DEG2RAD;
-                else if (cameraAngle.y < CAMERA_THIRD_PERSON_MAX_CLAMP*DEG2RAD) cameraAngle.y = CAMERA_THIRD_PERSON_MAX_CLAMP*DEG2RAD;
-
-                // Camera zoom
-                cameraTargetDistance -= (mouseWheelMove*CAMERA_MOUSE_SCROLL_SENSITIVITY);
-
-                // Camera distance clamp
-                if (cameraTargetDistance < CAMERA_THIRD_PERSON_DISTANCE_CLAMP) cameraTargetDistance = CAMERA_THIRD_PERSON_DISTANCE_CLAMP;
-
-                // Camera is always looking at player
-                camera->target.x = camera->position.x + CAMERA_THIRD_PERSON_OFFSET.x*cosf(cameraAngle.x) + CAMERA_THIRD_PERSON_OFFSET.z*sinf(cameraAngle.x);
-                camera->target.y = camera->position.y + CAMERA_THIRD_PERSON_OFFSET.y;
-                camera->target.z = camera->position.z + CAMERA_THIRD_PERSON_OFFSET.z*sinf(cameraAngle.x) - CAMERA_THIRD_PERSON_OFFSET.x*sinf(cameraAngle.x);
-            }
-            else    // CAMERA_FIRST_PERSON
+            // Angle clamp
+            if (cameraAngle.y > CAMERA_FIRST_PERSON_MIN_CLAMP*DEG2RAD) cameraAngle.y = CAMERA_FIRST_PERSON_MIN_CLAMP*DEG2RAD;
+            else if (cameraAngle.y < CAMERA_FIRST_PERSON_MAX_CLAMP*DEG2RAD) cameraAngle.y = CAMERA_FIRST_PERSON_MAX_CLAMP*DEG2RAD;
+
+            // Camera is always looking at player
+            camera->target.x = camera->position.x - sinf(cameraAngle.x)*CAMERA_FIRST_PERSON_FOCUS_DISTANCE;
+            camera->target.y = camera->position.y + sinf(cameraAngle.y)*CAMERA_FIRST_PERSON_FOCUS_DISTANCE;
+            camera->target.z = camera->position.z - cosf(cameraAngle.x)*CAMERA_FIRST_PERSON_FOCUS_DISTANCE;
+            
+            if (cameraMode == CAMERA_FIRST_PERSON)
             {
-                // Angle clamp
-                if (cameraAngle.y > CAMERA_FIRST_PERSON_MIN_CLAMP*DEG2RAD) cameraAngle.y = CAMERA_FIRST_PERSON_MIN_CLAMP*DEG2RAD;
-                else if (cameraAngle.y < CAMERA_FIRST_PERSON_MAX_CLAMP*DEG2RAD) cameraAngle.y = CAMERA_FIRST_PERSON_MAX_CLAMP*DEG2RAD;
-
-                // Camera is always looking at player
-                camera->target.x = camera->position.x - sinf(cameraAngle.x)*CAMERA_FIRST_PERSON_FOCUS_DISTANCE;
-                camera->target.y = camera->position.y + sinf(cameraAngle.y)*CAMERA_FIRST_PERSON_FOCUS_DISTANCE;
-                camera->target.z = camera->position.z - cosf(cameraAngle.x)*CAMERA_FIRST_PERSON_FOCUS_DISTANCE;
-                
                 if (isMoving) swingCounter++;
 
                 // Camera position update
@@ -458,21 +454,16 @@ void UpdateCamera(Camera *camera)
                 camera->up.x = sinf(swingCounter/(CAMERA_FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER*2))/CAMERA_FIRST_PERSON_WAVING_DIVIDER;
                 camera->up.z = -sinf(swingCounter/(CAMERA_FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER*2))/CAMERA_FIRST_PERSON_WAVING_DIVIDER;
             }
+            else if (cameraMode == CAMERA_THIRD_PERSON)
+            {
+                // Camera zoom
+                cameraTargetDistance -= (mouseWheelMove*CAMERA_MOUSE_SCROLL_SENSITIVITY);
+                if (cameraTargetDistance < CAMERA_THIRD_PERSON_DISTANCE_CLAMP) cameraTargetDistance = CAMERA_THIRD_PERSON_DISTANCE_CLAMP;
+            }
+            
         } break;
         default: break;
     }
-    
-    // Update camera position with changes
-    if ((cameraMode == CAMERA_FREE) ||
-        (cameraMode == CAMERA_ORBITAL) ||
-        (cameraMode == CAMERA_THIRD_PERSON))
-    {
-        // TODO: It seems camera->position is not correctly updated or some rounding issue makes the camera move straight to camera->target...
-        camera->position.x = sinf(cameraAngle.x)*cameraTargetDistance*cosf(cameraAngle.y) + camera->target.x;
-        if (cameraAngle.y <= 0.0f) camera->position.y = sinf(cameraAngle.y)*cameraTargetDistance*sinf(cameraAngle.y) + camera->target.y;
-        else camera->position.y = -sinf(cameraAngle.y)*cameraTargetDistance*sinf(cameraAngle.y) + camera->target.y;
-        camera->position.z = cosf(cameraAngle.x)*cameraTargetDistance*cosf(cameraAngle.y) + camera->target.z;
-    }
 }
 
 // Set camera pan key to combine with mouse movement (free camera)
@@ -482,7 +473,7 @@ void SetCameraPanControl(int panKey) { cameraPanControlKey = panKey; }
 void SetCameraAltControl(int altKey) { cameraAltControlKey = altKey; }
 
 // Set camera smooth zoom key to combine with mouse (free camera)
-void SetCameraSmoothZoomControl(int szKey) { cameraSmoothZoomControlKey = szKey; }
+void SetCameraSmoothZoomControl(int szoomKey) { cameraSmoothZoomControlKey = szoomKey; }
 
 // Set camera move controls (1st person and 3rd person cameras)
 void SetCameraMoveControls(int frontKey, int backKey, int rightKey, int leftKey, int upKey, int downKey)