Review camera module
This module still requires further work but 3rd person camera is less broken now...
This commit is contained in:
parent
f4ad144537
commit
cc1dd6b410
1 changed files with 60 additions and 69 deletions
127
src/camera.h
127
src/camera.h
|
@ -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 {
|
typedef struct Camera3D {
|
||||||
Vector3 position;
|
Vector3 position; // Camera position
|
||||||
Vector3 target;
|
Vector3 target; // Camera target it looks-at
|
||||||
Vector3 up;
|
Vector3 up; // Camera up vector (rotation over its axis)
|
||||||
float fovy;
|
float fovy; // Camera field-of-view apperture in Y (degrees) in perspective, used as near plane width in orthographic
|
||||||
} Camera;
|
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 }; // TODO: Remove! Compute it in UpdateCamera()
|
static Vector2 cameraAngle = { 0.0f, 0.0f }; // Camera angle in plane XZ
|
||||||
static float cameraTargetDistance = 0.0f; // TODO: Remove! Compute it in UpdateCamera()
|
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,8 +258,7 @@ 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) ||
|
if ((mode == CAMERA_FIRST_PERSON) || (mode == CAMERA_THIRD_PERSON)) DisableCursor();
|
||||||
(mode == CAMERA_THIRD_PERSON)) DisableCursor();
|
|
||||||
else EnableCursor();
|
else EnableCursor();
|
||||||
|
|
||||||
cameraMode = mode;
|
cameraMode = mode;
|
||||||
|
@ -386,6 +389,11 @@ void UpdateCamera(Camera *camera)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 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_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_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 (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…
Add table
Add a link
Reference in a new issue