aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRay <raysan5@gmail.com>2019-04-23 23:27:08 +0200
committerRay <raysan5@gmail.com>2019-04-23 23:27:08 +0200
commitcc1dd6b410ca8c6ba2b9dd1a923c7740034cd1d9 (patch)
tree456977f57693a629832f8e907e4c2349b8f577a5
parentf4ad1445373ba0b5755645b8df9a6e293a714bff (diff)
downloadraylib-cc1dd6b410ca8c6ba2b9dd1a923c7740034cd1d9.tar.gz
raylib-cc1dd6b410ca8c6ba2b9dd1a923c7740034cd1d9.zip
Review camera module
This module still requires further work but 3rd person camera is less broken now...
-rw-r--r--src/camera.h129
1 files changed, 60 insertions, 69 deletions
diff --git a/src/camera.h b/src/camera.h
index 2ed35f3b..e103b293 100644
--- a/src/camera.h
+++ b/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)