Browse Source

Review camera module

This module still requires further work but 3rd person camera is less broken now...
pull/815/head
Ray 6 years ago
parent
commit
cc1dd6b410
1 changed files with 60 additions and 69 deletions
  1. +60
    -69
      src/camera.h

+ 60
- 69
src/camera.h View File

@ -16,13 +16,13 @@
* functions must be redefined to manage inputs accordingly. * functions must be redefined to manage inputs accordingly.
* *
* CONTRIBUTORS: * CONTRIBUTORS:
* Marc Palau: Initial implementation (2014)
* Ramon Santamaria: Supervision, review, update and maintenance * Ramon Santamaria: Supervision, review, update and maintenance
* Marc Palau: Initial implementation (2014)
* *
* *
* LICENSE: zlib/libpng * 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 * 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. * 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 // NOTE: Below types are required for CAMERA_STANDALONE usage
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
#if defined(CAMERA_STANDALONE) #if defined(CAMERA_STANDALONE)
// Camera modes
typedef enum {
CAMERA_CUSTOM = 0,
CAMERA_FREE,
CAMERA_ORBITAL,
CAMERA_FIRST_PERSON,
CAMERA_THIRD_PERSON
} CameraMode;
// Vector2 type // Vector2 type
typedef struct Vector2 { typedef struct Vector2 {
float x; float x;
@ -77,12 +68,30 @@
} Vector3; } Vector3;
// Camera type, defines a camera position/orientation in 3d space // 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 #endif
#ifdef __cplusplus #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 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 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, void SetCameraMoveControls(int frontKey, int backKey,
int rightKey, int leftKey, int rightKey, int leftKey,
int upKey, int downKey); // Set camera move controls (1st person and 3rd person cameras) 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) #if defined(CAMERA_IMPLEMENTATION)
#include <math.h> // Required for: sqrt(), sin(), cos()
#include <math.h> // Required for: sqrt(), sinf(), cosf()
#ifndef PI #ifndef PI
#define PI 3.14159265358979323846 #define PI 3.14159265358979323846
#endif #endif
#ifndef DEG2RAD #ifndef DEG2RAD
#define DEG2RAD (PI/180.0f) #define DEG2RAD (PI/180.0f)
#endif #endif
#ifndef RAD2DEG #ifndef RAD2DEG
#define RAD2DEG (180.0f/PI) #define RAD2DEG (180.0f/PI)
#endif #endif
@ -193,8 +200,8 @@ typedef enum {
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Global Variables Definition // Global Variables Definition
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
static Vector2 cameraAngle = { 0.0f, 0.0f }; // l">TODO: Remove! Compute it in UpdateCamera()
static float cameraTargetDistance = 0.0f; // l">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 float playerEyesPosition = 1.85f; // Default player eyes position from ground (in meters)
static int cameraMoveControl[6] = { 'W', 'S', 'D', 'A', 'E', 'Q' }; 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) // Select camera mode (multiple camera modes available)
void SetCameraMode(Camera camera, int mode) void SetCameraMode(Camera camera, int mode)
{ {
// TODO: cameraTargetDistance and cameraAngle should be
// calculated using camera parameters on UpdateCamera()
Vector3 v1 = camera.position; Vector3 v1 = camera.position;
Vector3 v2 = camera.target; Vector3 v2 = camera.target;
@ -254,9 +258,8 @@ void SetCameraMode(Camera camera, int mode)
playerEyesPosition = camera.position.y; playerEyesPosition = camera.position.y;
// Lock cursor for first person and third person cameras // 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; 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); 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; } break;
case CAMERA_ORBITAL: case CAMERA_ORBITAL:
@ -395,6 +403,11 @@ void UpdateCamera(Camera *camera)
// Camera distance clamp // Camera distance clamp
if (cameraTargetDistance < CAMERA_THIRD_PERSON_DISTANCE_CLAMP) cameraTargetDistance = CAMERA_THIRD_PERSON_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; } break;
case CAMERA_FIRST_PERSON: case CAMERA_FIRST_PERSON:
case CAMERA_THIRD_PERSON: case CAMERA_THIRD_PERSON:
@ -421,34 +434,17 @@ void UpdateCamera(Camera *camera)
cameraAngle.x += (mousePositionDelta.x*-CAMERA_MOUSE_MOVE_SENSITIVITY); cameraAngle.x += (mousePositionDelta.x*-CAMERA_MOUSE_MOVE_SENSITIVITY);
cameraAngle.y += (mousePositionDelta.y*-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++; if (isMoving) swingCounter++;
// Camera position update // 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.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; 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; } break;
default: 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) // 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; } void SetCameraAltControl(int altKey) { cameraAltControlKey = altKey; }
// Set camera smooth zoom key to combine with mouse (free camera) // 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) // Set camera move controls (1st person and 3rd person cameras)
void SetCameraMoveControls(int frontKey, int backKey, int rightKey, int leftKey, int upKey, int downKey) void SetCameraMoveControls(int frontKey, int backKey, int rightKey, int leftKey, int upKey, int downKey)

Loading…
Cancel
Save