Update C sources

This commit is contained in:
Milan Nikolic 2019-11-25 03:34:31 +01:00
parent 02424e2e10
commit bd6bf15356
No known key found for this signature in database
GPG key ID: 9229D0EAA3AA4E75
53 changed files with 62247 additions and 9914 deletions

View file

@ -8,7 +8,7 @@
*
* #define CAMERA_IMPLEMENTATION
* Generates the implementation of the library into the included file.
* If not defined, the library is in header only mode and can be included in other headers
* If not defined, the library is in header only mode and can be included in other headers
* or source files without problems. But only ONE file should hold the implementation.
*
* #define CAMERA_STANDALONE
@ -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,9 +112,9 @@ 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 SetCameraMoveControls(int frontKey, int backKey,
int rightKey, int leftKey,
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)
#endif
@ -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
@ -181,21 +188,21 @@ void SetCameraMoveControls(int frontKey, int backKey,
// Types and Structures Definition
//----------------------------------------------------------------------------------
// Camera move modes (first person and third person cameras)
typedef enum {
MOVE_FRONT = 0,
MOVE_BACK,
MOVE_RIGHT,
MOVE_LEFT,
MOVE_UP,
MOVE_DOWN
typedef enum {
MOVE_FRONT = 0,
MOVE_BACK,
MOVE_RIGHT,
MOVE_LEFT,
MOVE_UP,
MOVE_DOWN
} CameraMove;
//----------------------------------------------------------------------------------
// 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 float playerEyesPosition = 1.85f; // Default player eyes position from ground (in meters)
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' };
static int cameraPanControlKey = 2; // raylib: MOUSE_MIDDLE_BUTTON
@ -227,36 +234,24 @@ 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;
float dx = v2.x - v1.x;
float dy = v2.y - v1.y;
float dz = v2.z - v1.z;
cameraTargetDistance = sqrtf(dx*dx + dy*dy + dz*dz);
Vector2 distance = { 0.0f, 0.0f };
distance.x = sqrtf(dx*dx + dz*dz);
distance.y = sqrtf(dx*dx + dy*dy);
// Camera angle calculation
cameraAngle.x = asinf( (float)fabs(dx)/distance.x); // Camera angle in plane XZ (0 aligned with Z, move positive CCW)
cameraAngle.y = -asinf( (float)fabs(dy)/distance.y); // Camera angle in plane XY (0 aligned with X, move positive CW)
// NOTE: Just testing what cameraAngle means
//cameraAngle.x = 0.0f*DEG2RAD; // Camera angle in plane XZ (0 aligned with Z, move positive CCW)
//cameraAngle.y = -60.0f*DEG2RAD; // Camera angle in plane XY (0 aligned with X, move positive CW)
cameraAngle.x = atan2f(dx, dz); // Camera angle in plane XZ (0 aligned with Z, move positive CCW)
cameraAngle.y = atan2f(dy, sqrtf(dx*dx + dz*dz)); // Camera angle in plane XY (0 aligned with X, move positive CW)
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;
}
@ -273,24 +268,24 @@ void UpdateCamera(Camera *camera)
static Vector2 previousMousePosition = { 0.0f, 0.0f };
// TODO: Compute cameraTargetDistance and cameraAngle here
// Mouse movement detection
Vector2 mousePositionDelta = { 0.0f, 0.0f };
Vector2 mousePosition = GetMousePosition();
int mouseWheelMove = GetMouseWheelMove();
// Keys input detection
bool panKey = IsMouseButtonDown(cameraPanControlKey);
bool altKey = IsKeyDown(cameraAltControlKey);
bool szoomKey = IsKeyDown(cameraSmoothZoomControlKey);
bool direction[6] = { IsKeyDown(cameraMoveControl[MOVE_FRONT]),
IsKeyDown(cameraMoveControl[MOVE_BACK]),
IsKeyDown(cameraMoveControl[MOVE_RIGHT]),
IsKeyDown(cameraMoveControl[MOVE_LEFT]),
IsKeyDown(cameraMoveControl[MOVE_UP]),
IsKeyDown(cameraMoveControl[MOVE_DOWN]) };
// TODO: Consider touch inputs for camera
if (cameraMode != CAMERA_CUSTOM)
@ -314,7 +309,7 @@ void UpdateCamera(Camera *camera)
if (cameraTargetDistance > CAMERA_FREE_DISTANCE_MAX_CLAMP) cameraTargetDistance = CAMERA_FREE_DISTANCE_MAX_CLAMP;
}
// Camera looking down
// TODO: Review, weird comparisson of cameraTargetDistance == 120.0f?
// TODO: Review, weird comparisson of cameraTargetDistance == 120.0f?
else if ((camera->position.y > camera->target.y) && (cameraTargetDistance == CAMERA_FREE_DISTANCE_MAX_CLAMP) && (mouseWheelMove < 0))
{
camera->target.x += mouseWheelMove*(camera->target.x - camera->position.x)*CAMERA_MOUSE_SCROLL_SENSITIVITY/cameraTargetDistance;
@ -335,7 +330,7 @@ void UpdateCamera(Camera *camera)
if (cameraTargetDistance < CAMERA_FREE_DISTANCE_MIN_CLAMP) cameraTargetDistance = CAMERA_FREE_DISTANCE_MIN_CLAMP;
}
// Camera looking up
// TODO: Review, weird comparisson of cameraTargetDistance == 120.0f?
// TODO: Review, weird comparisson of cameraTargetDistance == 120.0f?
else if ((camera->position.y < camera->target.y) && (cameraTargetDistance == CAMERA_FREE_DISTANCE_MAX_CLAMP) && (mouseWheelMove < 0))
{
camera->target.x += mouseWheelMove*(camera->target.x - camera->position.x)*CAMERA_MOUSE_SCROLL_SENSITIVITY/cameraTargetDistance;
@ -380,34 +375,42 @@ void UpdateCamera(Camera *camera)
else
{
// Camera panning
camera->target.x += ((mousePositionDelta.x*-CAMERA_FREE_MOUSE_SENSITIVITY)*cosf(cameraAngle.x) + (mousePositionDelta.y*CAMERA_FREE_MOUSE_SENSITIVITY)*sinf(cameraAngle.x)*sinf(cameraAngle.y))*(cameraTargetDistance/CAMERA_FREE_PANNING_DIVIDER);
camera->target.x += ((mousePositionDelta.x*CAMERA_FREE_MOUSE_SENSITIVITY)*cosf(cameraAngle.x) + (mousePositionDelta.y*CAMERA_FREE_MOUSE_SENSITIVITY)*sinf(cameraAngle.x)*sinf(cameraAngle.y))*(cameraTargetDistance/CAMERA_FREE_PANNING_DIVIDER);
camera->target.y += ((mousePositionDelta.y*CAMERA_FREE_MOUSE_SENSITIVITY)*cosf(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);
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 = -sinf(cameraAngle.y)*cameraTargetDistance + camera->target.y;
camera->position.z = -cosf(cameraAngle.x)*cameraTargetDistance*cosf(cameraAngle.y) + camera->target.z;
} break;
case CAMERA_ORBITAL:
{
cameraAngle.x += CAMERA_ORBITAL_SPEED; // Camera orbit angle
cameraTargetDistance -= (mouseWheelMove*CAMERA_MOUSE_SCROLL_SENSITIVITY); // Camera zoom
// 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:
{
camera->position.x += (sinf(cameraAngle.x)*direction[MOVE_BACK] -
sinf(cameraAngle.x)*direction[MOVE_FRONT] -
cosf(cameraAngle.x)*direction[MOVE_LEFT] +
cosf(cameraAngle.x)*direction[MOVE_RIGHT])/PLAYER_MOVEMENT_SENSITIVITY;
camera->position.y += (sinf(cameraAngle.y)*direction[MOVE_FRONT] -
sinf(cameraAngle.y)*direction[MOVE_BACK] +
1.0f*direction[MOVE_UP] - 1.0f*direction[MOVE_DOWN])/PLAYER_MOVEMENT_SENSITIVITY;
camera->position.z += (cosf(cameraAngle.x)*direction[MOVE_BACK] -
cosf(cameraAngle.x)*direction[MOVE_FRONT] +
sinf(cameraAngle.x)*direction[MOVE_LEFT] -
@ -416,63 +419,70 @@ void UpdateCamera(Camera *camera)
bool isMoving = false; // Required for swinging
for (int i = 0; i < 6; i++) if (direction[i]) { isMoving = true; break; }
// Camera orientation calculation
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);
// 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 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 - 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;
// 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;
if (isMoving) swingCounter++;
// 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
// NOTE: On CAMERA_FIRST_PERSON player Y-movement is limited to player 'eyes position'
camera->position.y = playerEyesPosition - sinf(swingCounter/CAMERA_FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER)/CAMERA_FIRST_PERSON_STEP_DIVIDER;
// Camera position update
// NOTE: On CAMERA_FIRST_PERSON player Y-movement is limited to player 'eyes position'
camera->position.y = playerEyesPosition - sinf(swingCounter/CAMERA_FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER)/CAMERA_FIRST_PERSON_STEP_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;
} break;
case CAMERA_THIRD_PERSON:
{
camera->position.x += (sinf(cameraAngle.x)*direction[MOVE_BACK] -
sinf(cameraAngle.x)*direction[MOVE_FRONT] -
cosf(cameraAngle.x)*direction[MOVE_LEFT] +
cosf(cameraAngle.x)*direction[MOVE_RIGHT])/PLAYER_MOVEMENT_SENSITIVITY;
camera->position.y += (sinf(cameraAngle.y)*direction[MOVE_FRONT] -
sinf(cameraAngle.y)*direction[MOVE_BACK] +
1.0f*direction[MOVE_UP] - 1.0f*direction[MOVE_DOWN])/PLAYER_MOVEMENT_SENSITIVITY;
camera->position.z += (cosf(cameraAngle.x)*direction[MOVE_BACK] -
cosf(cameraAngle.x)*direction[MOVE_FRONT] +
sinf(cameraAngle.x)*direction[MOVE_LEFT] -
sinf(cameraAngle.x)*direction[MOVE_RIGHT])/PLAYER_MOVEMENT_SENSITIVITY;
// Camera orientation calculation
cameraAngle.x += (mousePositionDelta.x*-CAMERA_MOUSE_MOVE_SENSITIVITY);
cameraAngle.y += (mousePositionDelta.y*-CAMERA_MOUSE_MOVE_SENSITIVITY);
// 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;
// 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;
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;
}
} 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 +492,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)