[camera] Use global context

This commit is contained in:
Ray 2020-01-31 12:02:02 +01:00
parent 884b36c4c1
commit 8134050738

View File

@ -197,19 +197,31 @@ typedef enum {
MOVE_DOWN MOVE_DOWN
} CameraMove; } CameraMove;
typedef struct {
int mode; // Current camera mode
float targetDistance; // Camera distance from position to target
float playerEyesPosition; // Default player eyes position from ground (in meters)
Vector2 angle; // Camera angle in plane XZ
int moveControl[6];
int smoothZoomControl; // raylib: KEY_LEFT_CONTROL
int altControl; // raylib: KEY_LEFT_ALT
int panControl; // raylib: MOUSE_MIDDLE_BUTTON
} CameraData;
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Global Variables Definition // Global Variables Definition
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
static Vector2 cameraAngle = { 0.0f, 0.0f }; // Camera angle in plane XZ static CameraData CAMERA = {
static float cameraTargetDistance = 0.0f; // Camera distance from position to target .mode = 0,
static float playerEyesPosition = 1.85f; // Default player eyes position from ground (in meters) .targetDistance = 0,
.playerEyesPosition = 1.85f,
static int cameraMoveControl[6] = { 'W', 'S', 'D', 'A', 'E', 'Q' }; .angle = { 0 },
static int cameraPanControlKey = 2; // raylib: MOUSE_MIDDLE_BUTTON .moveControl = { 'W', 'S', 'D', 'A', 'E', 'Q' },
static int cameraAltControlKey = 342; // raylib: KEY_LEFT_ALT .smoothZoomControl = 341,
static int cameraSmoothZoomControlKey = 341; // raylib: KEY_LEFT_CONTROL .altControl = 342,
.panControl = 2
static int cameraMode = CAMERA_CUSTOM; // Current camera mode };
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Module specific Functions Declaration // Module specific Functions Declaration
@ -241,19 +253,19 @@ void SetCameraMode(Camera camera, int mode)
float dy = v2.y - v1.y; float dy = v2.y - v1.y;
float dz = v2.z - v1.z; float dz = v2.z - v1.z;
cameraTargetDistance = sqrtf(dx*dx + dy*dy + dz*dz); CAMERA.targetDistance = sqrtf(dx*dx + dy*dy + dz*dz);
// Camera angle calculation // Camera angle calculation
cameraAngle.x = atan2f(dx, dz); // Camera angle in plane XZ (0 aligned with Z, move positive CCW) CAMERA.angle.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) CAMERA.angle.y = atan2f(dy, sqrtf(dx*dx + dz*dz)); // Camera angle in plane XY (0 aligned with X, move positive CW)
playerEyesPosition = camera.position.y; CAMERA.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(); if ((mode == CAMERA_FIRST_PERSON) || (mode == CAMERA_THIRD_PERSON)) DisableCursor();
else EnableCursor(); else EnableCursor();
cameraMode = mode; CAMERA.mode = mode;
} }
// Update camera depending on selected mode // Update camera depending on selected mode
@ -267,7 +279,7 @@ void UpdateCamera(Camera *camera)
static int swingCounter = 0; // Used for 1st person swinging movement static int swingCounter = 0; // Used for 1st person swinging movement
static Vector2 previousMousePosition = { 0.0f, 0.0f }; static Vector2 previousMousePosition = { 0.0f, 0.0f };
// TODO: Compute cameraTargetDistance and cameraAngle here // TODO: Compute CAMERA.targetDistance and CAMERA.angle here
// Mouse movement detection // Mouse movement detection
Vector2 mousePositionDelta = { 0.0f, 0.0f }; Vector2 mousePositionDelta = { 0.0f, 0.0f };
@ -275,20 +287,20 @@ void UpdateCamera(Camera *camera)
int mouseWheelMove = GetMouseWheelMove(); int mouseWheelMove = GetMouseWheelMove();
// Keys input detection // Keys input detection
bool panKey = IsMouseButtonDown(cameraPanControlKey); bool panKey = IsMouseButtonDown(CAMERA.panControl);
bool altKey = IsKeyDown(cameraAltControlKey); bool altKey = IsKeyDown(CAMERA.altControl);
bool szoomKey = IsKeyDown(cameraSmoothZoomControlKey); bool szoomKey = IsKeyDown(CAMERA.smoothZoomControl);
bool direction[6] = { IsKeyDown(cameraMoveControl[MOVE_FRONT]), bool direction[6] = { IsKeyDown(CAMERA.moveControl[MOVE_FRONT]),
IsKeyDown(cameraMoveControl[MOVE_BACK]), IsKeyDown(CAMERA.moveControl[MOVE_BACK]),
IsKeyDown(cameraMoveControl[MOVE_RIGHT]), IsKeyDown(CAMERA.moveControl[MOVE_RIGHT]),
IsKeyDown(cameraMoveControl[MOVE_LEFT]), IsKeyDown(CAMERA.moveControl[MOVE_LEFT]),
IsKeyDown(cameraMoveControl[MOVE_UP]), IsKeyDown(CAMERA.moveControl[MOVE_UP]),
IsKeyDown(cameraMoveControl[MOVE_DOWN]) }; IsKeyDown(CAMERA.moveControl[MOVE_DOWN]) };
// TODO: Consider touch inputs for camera // TODO: Consider touch inputs for camera
if (cameraMode != CAMERA_CUSTOM) if (CAMERA.mode != CAMERA_CUSTOM)
{ {
mousePositionDelta.x = mousePosition.x - previousMousePosition.x; mousePositionDelta.x = mousePosition.x - previousMousePosition.x;
mousePositionDelta.y = mousePosition.y - previousMousePosition.y; mousePositionDelta.y = mousePosition.y - previousMousePosition.y;
@ -297,58 +309,58 @@ void UpdateCamera(Camera *camera)
} }
// Support for multiple automatic camera modes // Support for multiple automatic camera modes
switch (cameraMode) switch (CAMERA.mode)
{ {
case CAMERA_FREE: case CAMERA_FREE:
{ {
// Camera zoom // Camera zoom
if ((cameraTargetDistance < CAMERA_FREE_DISTANCE_MAX_CLAMP) && (mouseWheelMove < 0)) if ((CAMERA.targetDistance < CAMERA_FREE_DISTANCE_MAX_CLAMP) && (mouseWheelMove < 0))
{ {
cameraTargetDistance -= (mouseWheelMove*CAMERA_MOUSE_SCROLL_SENSITIVITY); CAMERA.targetDistance -= (mouseWheelMove*CAMERA_MOUSE_SCROLL_SENSITIVITY);
if (cameraTargetDistance > CAMERA_FREE_DISTANCE_MAX_CLAMP) cameraTargetDistance = CAMERA_FREE_DISTANCE_MAX_CLAMP; if (CAMERA.targetDistance > CAMERA_FREE_DISTANCE_MAX_CLAMP) CAMERA.targetDistance = CAMERA_FREE_DISTANCE_MAX_CLAMP;
} }
// Camera looking down // Camera looking down
// TODO: Review, weird comparisson of cameraTargetDistance == 120.0f? // TODO: Review, weird comparisson of CAMERA.targetDistance == 120.0f?
else if ((camera->position.y > camera->target.y) && (cameraTargetDistance == CAMERA_FREE_DISTANCE_MAX_CLAMP) && (mouseWheelMove < 0)) else if ((camera->position.y > camera->target.y) && (CAMERA.targetDistance == CAMERA_FREE_DISTANCE_MAX_CLAMP) && (mouseWheelMove < 0))
{ {
camera->target.x += mouseWheelMove*(camera->target.x - camera->position.x)*CAMERA_MOUSE_SCROLL_SENSITIVITY/cameraTargetDistance; camera->target.x += mouseWheelMove*(camera->target.x - camera->position.x)*CAMERA_MOUSE_SCROLL_SENSITIVITY/CAMERA.targetDistance;
camera->target.y += mouseWheelMove*(camera->target.y - camera->position.y)*CAMERA_MOUSE_SCROLL_SENSITIVITY/cameraTargetDistance; camera->target.y += mouseWheelMove*(camera->target.y - camera->position.y)*CAMERA_MOUSE_SCROLL_SENSITIVITY/CAMERA.targetDistance;
camera->target.z += mouseWheelMove*(camera->target.z - camera->position.z)*CAMERA_MOUSE_SCROLL_SENSITIVITY/cameraTargetDistance; camera->target.z += mouseWheelMove*(camera->target.z - camera->position.z)*CAMERA_MOUSE_SCROLL_SENSITIVITY/CAMERA.targetDistance;
} }
else if ((camera->position.y > camera->target.y) && (camera->target.y >= 0)) else if ((camera->position.y > camera->target.y) && (camera->target.y >= 0))
{ {
camera->target.x += mouseWheelMove*(camera->target.x - camera->position.x)*CAMERA_MOUSE_SCROLL_SENSITIVITY/cameraTargetDistance; camera->target.x += mouseWheelMove*(camera->target.x - camera->position.x)*CAMERA_MOUSE_SCROLL_SENSITIVITY/CAMERA.targetDistance;
camera->target.y += mouseWheelMove*(camera->target.y - camera->position.y)*CAMERA_MOUSE_SCROLL_SENSITIVITY/cameraTargetDistance; camera->target.y += mouseWheelMove*(camera->target.y - camera->position.y)*CAMERA_MOUSE_SCROLL_SENSITIVITY/CAMERA.targetDistance;
camera->target.z += mouseWheelMove*(camera->target.z - camera->position.z)*CAMERA_MOUSE_SCROLL_SENSITIVITY/cameraTargetDistance; camera->target.z += mouseWheelMove*(camera->target.z - camera->position.z)*CAMERA_MOUSE_SCROLL_SENSITIVITY/CAMERA.targetDistance;
// if (camera->target.y < 0) camera->target.y = -0.001; // if (camera->target.y < 0) camera->target.y = -0.001;
} }
else if ((camera->position.y > camera->target.y) && (camera->target.y < 0) && (mouseWheelMove > 0)) else if ((camera->position.y > camera->target.y) && (camera->target.y < 0) && (mouseWheelMove > 0))
{ {
cameraTargetDistance -= (mouseWheelMove*CAMERA_MOUSE_SCROLL_SENSITIVITY); CAMERA.targetDistance -= (mouseWheelMove*CAMERA_MOUSE_SCROLL_SENSITIVITY);
if (cameraTargetDistance < CAMERA_FREE_DISTANCE_MIN_CLAMP) cameraTargetDistance = CAMERA_FREE_DISTANCE_MIN_CLAMP; if (CAMERA.targetDistance < CAMERA_FREE_DISTANCE_MIN_CLAMP) CAMERA.targetDistance = CAMERA_FREE_DISTANCE_MIN_CLAMP;
} }
// Camera looking up // Camera looking up
// TODO: Review, weird comparisson of cameraTargetDistance == 120.0f? // TODO: Review, weird comparisson of CAMERA.targetDistance == 120.0f?
else if ((camera->position.y < camera->target.y) && (cameraTargetDistance == CAMERA_FREE_DISTANCE_MAX_CLAMP) && (mouseWheelMove < 0)) else if ((camera->position.y < camera->target.y) && (CAMERA.targetDistance == CAMERA_FREE_DISTANCE_MAX_CLAMP) && (mouseWheelMove < 0))
{ {
camera->target.x += mouseWheelMove*(camera->target.x - camera->position.x)*CAMERA_MOUSE_SCROLL_SENSITIVITY/cameraTargetDistance; camera->target.x += mouseWheelMove*(camera->target.x - camera->position.x)*CAMERA_MOUSE_SCROLL_SENSITIVITY/CAMERA.targetDistance;
camera->target.y += mouseWheelMove*(camera->target.y - camera->position.y)*CAMERA_MOUSE_SCROLL_SENSITIVITY/cameraTargetDistance; camera->target.y += mouseWheelMove*(camera->target.y - camera->position.y)*CAMERA_MOUSE_SCROLL_SENSITIVITY/CAMERA.targetDistance;
camera->target.z += mouseWheelMove*(camera->target.z - camera->position.z)*CAMERA_MOUSE_SCROLL_SENSITIVITY/cameraTargetDistance; camera->target.z += mouseWheelMove*(camera->target.z - camera->position.z)*CAMERA_MOUSE_SCROLL_SENSITIVITY/CAMERA.targetDistance;
} }
else if ((camera->position.y < camera->target.y) && (camera->target.y <= 0)) else if ((camera->position.y < camera->target.y) && (camera->target.y <= 0))
{ {
camera->target.x += mouseWheelMove*(camera->target.x - camera->position.x)*CAMERA_MOUSE_SCROLL_SENSITIVITY/cameraTargetDistance; camera->target.x += mouseWheelMove*(camera->target.x - camera->position.x)*CAMERA_MOUSE_SCROLL_SENSITIVITY/CAMERA.targetDistance;
camera->target.y += mouseWheelMove*(camera->target.y - camera->position.y)*CAMERA_MOUSE_SCROLL_SENSITIVITY/cameraTargetDistance; camera->target.y += mouseWheelMove*(camera->target.y - camera->position.y)*CAMERA_MOUSE_SCROLL_SENSITIVITY/CAMERA.targetDistance;
camera->target.z += mouseWheelMove*(camera->target.z - camera->position.z)*CAMERA_MOUSE_SCROLL_SENSITIVITY/cameraTargetDistance; camera->target.z += mouseWheelMove*(camera->target.z - camera->position.z)*CAMERA_MOUSE_SCROLL_SENSITIVITY/CAMERA.targetDistance;
// if (camera->target.y > 0) camera->target.y = 0.001; // if (camera->target.y > 0) camera->target.y = 0.001;
} }
else if ((camera->position.y < camera->target.y) && (camera->target.y > 0) && (mouseWheelMove > 0)) else if ((camera->position.y < camera->target.y) && (camera->target.y > 0) && (mouseWheelMove > 0))
{ {
cameraTargetDistance -= (mouseWheelMove*CAMERA_MOUSE_SCROLL_SENSITIVITY); CAMERA.targetDistance -= (mouseWheelMove*CAMERA_MOUSE_SCROLL_SENSITIVITY);
if (cameraTargetDistance < CAMERA_FREE_DISTANCE_MIN_CLAMP) cameraTargetDistance = CAMERA_FREE_DISTANCE_MIN_CLAMP; if (CAMERA.targetDistance < CAMERA_FREE_DISTANCE_MIN_CLAMP) CAMERA.targetDistance = CAMERA_FREE_DISTANCE_MIN_CLAMP;
} }
// Input keys checks // Input keys checks
@ -359,78 +371,78 @@ void UpdateCamera(Camera *camera)
if (szoomKey) if (szoomKey)
{ {
// Camera smooth zoom // Camera smooth zoom
cameraTargetDistance += (mousePositionDelta.y*CAMERA_FREE_SMOOTH_ZOOM_SENSITIVITY); CAMERA.targetDistance += (mousePositionDelta.y*CAMERA_FREE_SMOOTH_ZOOM_SENSITIVITY);
} }
else else
{ {
// Camera rotation // Camera rotation
cameraAngle.x += mousePositionDelta.x*-CAMERA_FREE_MOUSE_SENSITIVITY; CAMERA.angle.x += mousePositionDelta.x*-CAMERA_FREE_MOUSE_SENSITIVITY;
cameraAngle.y += mousePositionDelta.y*-CAMERA_FREE_MOUSE_SENSITIVITY; CAMERA.angle.y += mousePositionDelta.y*-CAMERA_FREE_MOUSE_SENSITIVITY;
// Angle clamp // Angle clamp
if (cameraAngle.y > CAMERA_FREE_MIN_CLAMP*DEG2RAD) cameraAngle.y = CAMERA_FREE_MIN_CLAMP*DEG2RAD; if (CAMERA.angle.y > CAMERA_FREE_MIN_CLAMP*DEG2RAD) CAMERA.angle.y = CAMERA_FREE_MIN_CLAMP*DEG2RAD;
else if (cameraAngle.y < CAMERA_FREE_MAX_CLAMP*DEG2RAD) cameraAngle.y = CAMERA_FREE_MAX_CLAMP*DEG2RAD; else if (CAMERA.angle.y < CAMERA_FREE_MAX_CLAMP*DEG2RAD) CAMERA.angle.y = CAMERA_FREE_MAX_CLAMP*DEG2RAD;
} }
} }
else else
{ {
// Camera panning // 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(CAMERA.angle.x) + (mousePositionDelta.y*CAMERA_FREE_MOUSE_SENSITIVITY)*sinf(CAMERA.angle.x)*sinf(CAMERA.angle.y))*(CAMERA.targetDistance/CAMERA_FREE_PANNING_DIVIDER);
camera->target.y += ((mousePositionDelta.y*CAMERA_FREE_MOUSE_SENSITIVITY)*cosf(cameraAngle.y))*(cameraTargetDistance/CAMERA_FREE_PANNING_DIVIDER); camera->target.y += ((mousePositionDelta.y*CAMERA_FREE_MOUSE_SENSITIVITY)*cosf(CAMERA.angle.y))*(CAMERA.targetDistance/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(CAMERA.angle.x) + (mousePositionDelta.y*CAMERA_FREE_MOUSE_SENSITIVITY)*cosf(CAMERA.angle.x)*sinf(CAMERA.angle.y))*(CAMERA.targetDistance/CAMERA_FREE_PANNING_DIVIDER);
} }
} }
// Update camera position with changes // Update camera position with changes
camera->position.x = -sinf(cameraAngle.x)*cameraTargetDistance*cosf(cameraAngle.y) + camera->target.x; camera->position.x = -sinf(CAMERA.angle.x)*CAMERA.targetDistance*cosf(CAMERA.angle.y) + camera->target.x;
camera->position.y = -sinf(cameraAngle.y)*cameraTargetDistance + camera->target.y; camera->position.y = -sinf(CAMERA.angle.y)*CAMERA.targetDistance + camera->target.y;
camera->position.z = -cosf(cameraAngle.x)*cameraTargetDistance*cosf(cameraAngle.y) + camera->target.z; camera->position.z = -cosf(CAMERA.angle.x)*CAMERA.targetDistance*cosf(CAMERA.angle.y) + camera->target.z;
} break; } break;
case CAMERA_ORBITAL: case CAMERA_ORBITAL:
{ {
cameraAngle.x += CAMERA_ORBITAL_SPEED; // Camera orbit angle CAMERA.angle.x += CAMERA_ORBITAL_SPEED; // Camera orbit angle
cameraTargetDistance -= (mouseWheelMove*CAMERA_MOUSE_SCROLL_SENSITIVITY); // Camera zoom CAMERA.targetDistance -= (mouseWheelMove*CAMERA_MOUSE_SCROLL_SENSITIVITY); // Camera zoom
// Camera distance clamp // Camera distance clamp
if (cameraTargetDistance < CAMERA_THIRD_PERSON_DISTANCE_CLAMP) cameraTargetDistance = CAMERA_THIRD_PERSON_DISTANCE_CLAMP; if (CAMERA.targetDistance < CAMERA_THIRD_PERSON_DISTANCE_CLAMP) CAMERA.targetDistance = CAMERA_THIRD_PERSON_DISTANCE_CLAMP;
// Update camera position with changes // Update camera position with changes
camera->position.x = sinf(cameraAngle.x)*cameraTargetDistance*cosf(cameraAngle.y) + camera->target.x; camera->position.x = sinf(CAMERA.angle.x)*CAMERA.targetDistance*cosf(CAMERA.angle.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.y = ((CAMERA.angle.y <= 0.0f)? 1 : -1)*sinf(CAMERA.angle.y)*CAMERA.targetDistance*sinf(CAMERA.angle.y) + camera->target.y;
camera->position.z = cosf(cameraAngle.x)*cameraTargetDistance*cosf(cameraAngle.y) + camera->target.z; camera->position.z = cosf(CAMERA.angle.x)*CAMERA.targetDistance*cosf(CAMERA.angle.y) + camera->target.z;
} break; } break;
case CAMERA_FIRST_PERSON: case CAMERA_FIRST_PERSON:
{ {
camera->position.x += (sinf(cameraAngle.x)*direction[MOVE_BACK] - camera->position.x += (sinf(CAMERA.angle.x)*direction[MOVE_BACK] -
sinf(cameraAngle.x)*direction[MOVE_FRONT] - sinf(CAMERA.angle.x)*direction[MOVE_FRONT] -
cosf(cameraAngle.x)*direction[MOVE_LEFT] + cosf(CAMERA.angle.x)*direction[MOVE_LEFT] +
cosf(cameraAngle.x)*direction[MOVE_RIGHT])/PLAYER_MOVEMENT_SENSITIVITY; cosf(CAMERA.angle.x)*direction[MOVE_RIGHT])/PLAYER_MOVEMENT_SENSITIVITY;
camera->position.y += (sinf(cameraAngle.y)*direction[MOVE_FRONT] - camera->position.y += (sinf(CAMERA.angle.y)*direction[MOVE_FRONT] -
sinf(cameraAngle.y)*direction[MOVE_BACK] + sinf(CAMERA.angle.y)*direction[MOVE_BACK] +
1.0f*direction[MOVE_UP] - 1.0f*direction[MOVE_DOWN])/PLAYER_MOVEMENT_SENSITIVITY; 1.0f*direction[MOVE_UP] - 1.0f*direction[MOVE_DOWN])/PLAYER_MOVEMENT_SENSITIVITY;
camera->position.z += (cosf(cameraAngle.x)*direction[MOVE_BACK] - camera->position.z += (cosf(CAMERA.angle.x)*direction[MOVE_BACK] -
cosf(cameraAngle.x)*direction[MOVE_FRONT] + cosf(CAMERA.angle.x)*direction[MOVE_FRONT] +
sinf(cameraAngle.x)*direction[MOVE_LEFT] - sinf(CAMERA.angle.x)*direction[MOVE_LEFT] -
sinf(cameraAngle.x)*direction[MOVE_RIGHT])/PLAYER_MOVEMENT_SENSITIVITY; sinf(CAMERA.angle.x)*direction[MOVE_RIGHT])/PLAYER_MOVEMENT_SENSITIVITY;
bool isMoving = false; // Required for swinging bool isMoving = false; // Required for swinging
for (int i = 0; i < 6; i++) if (direction[i]) { isMoving = true; break; } for (int i = 0; i < 6; i++) if (direction[i]) { isMoving = true; break; }
// Camera orientation calculation // Camera orientation calculation
cameraAngle.x += (mousePositionDelta.x*-CAMERA_MOUSE_MOVE_SENSITIVITY); CAMERA.angle.x += (mousePositionDelta.x*-CAMERA_MOUSE_MOVE_SENSITIVITY);
cameraAngle.y += (mousePositionDelta.y*-CAMERA_MOUSE_MOVE_SENSITIVITY); CAMERA.angle.y += (mousePositionDelta.y*-CAMERA_MOUSE_MOVE_SENSITIVITY);
// Angle clamp // Angle clamp
if (cameraAngle.y > CAMERA_FIRST_PERSON_MIN_CLAMP*DEG2RAD) cameraAngle.y = CAMERA_FIRST_PERSON_MIN_CLAMP*DEG2RAD; if (CAMERA.angle.y > CAMERA_FIRST_PERSON_MIN_CLAMP*DEG2RAD) CAMERA.angle.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; else if (CAMERA.angle.y < CAMERA_FIRST_PERSON_MAX_CLAMP*DEG2RAD) CAMERA.angle.y = CAMERA_FIRST_PERSON_MAX_CLAMP*DEG2RAD;
// Recalculate camera target considering translation and rotation // Recalculate camera target considering translation and rotation
Matrix translation = MatrixTranslate(0, 0, (cameraTargetDistance/CAMERA_FREE_PANNING_DIVIDER)); Matrix translation = MatrixTranslate(0, 0, (CAMERA.targetDistance/CAMERA_FREE_PANNING_DIVIDER));
Matrix rotation = MatrixRotateXYZ((Vector3){ PI*2 - cameraAngle.y, PI*2 - cameraAngle.x, 0 }); Matrix rotation = MatrixRotateXYZ((Vector3){ PI*2 - CAMERA.angle.y, PI*2 - CAMERA.angle.x, 0 });
Matrix transform = MatrixMultiply(translation, rotation); Matrix transform = MatrixMultiply(translation, rotation);
camera->target.x = camera->position.x - transform.m12; camera->target.x = camera->position.x - transform.m12;
@ -441,7 +453,7 @@ void UpdateCamera(Camera *camera)
// Camera position update // Camera position update
// NOTE: On CAMERA_FIRST_PERSON player Y-movement is limited to player 'eyes position' // 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.y = CAMERA.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.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;
@ -450,39 +462,39 @@ void UpdateCamera(Camera *camera)
} break; } break;
case CAMERA_THIRD_PERSON: case CAMERA_THIRD_PERSON:
{ {
camera->position.x += (sinf(cameraAngle.x)*direction[MOVE_BACK] - camera->position.x += (sinf(CAMERA.angle.x)*direction[MOVE_BACK] -
sinf(cameraAngle.x)*direction[MOVE_FRONT] - sinf(CAMERA.angle.x)*direction[MOVE_FRONT] -
cosf(cameraAngle.x)*direction[MOVE_LEFT] + cosf(CAMERA.angle.x)*direction[MOVE_LEFT] +
cosf(cameraAngle.x)*direction[MOVE_RIGHT])/PLAYER_MOVEMENT_SENSITIVITY; cosf(CAMERA.angle.x)*direction[MOVE_RIGHT])/PLAYER_MOVEMENT_SENSITIVITY;
camera->position.y += (sinf(cameraAngle.y)*direction[MOVE_FRONT] - camera->position.y += (sinf(CAMERA.angle.y)*direction[MOVE_FRONT] -
sinf(cameraAngle.y)*direction[MOVE_BACK] + sinf(CAMERA.angle.y)*direction[MOVE_BACK] +
1.0f*direction[MOVE_UP] - 1.0f*direction[MOVE_DOWN])/PLAYER_MOVEMENT_SENSITIVITY; 1.0f*direction[MOVE_UP] - 1.0f*direction[MOVE_DOWN])/PLAYER_MOVEMENT_SENSITIVITY;
camera->position.z += (cosf(cameraAngle.x)*direction[MOVE_BACK] - camera->position.z += (cosf(CAMERA.angle.x)*direction[MOVE_BACK] -
cosf(cameraAngle.x)*direction[MOVE_FRONT] + cosf(CAMERA.angle.x)*direction[MOVE_FRONT] +
sinf(cameraAngle.x)*direction[MOVE_LEFT] - sinf(CAMERA.angle.x)*direction[MOVE_LEFT] -
sinf(cameraAngle.x)*direction[MOVE_RIGHT])/PLAYER_MOVEMENT_SENSITIVITY; sinf(CAMERA.angle.x)*direction[MOVE_RIGHT])/PLAYER_MOVEMENT_SENSITIVITY;
// Camera orientation calculation // Camera orientation calculation
cameraAngle.x += (mousePositionDelta.x*-CAMERA_MOUSE_MOVE_SENSITIVITY); CAMERA.angle.x += (mousePositionDelta.x*-CAMERA_MOUSE_MOVE_SENSITIVITY);
cameraAngle.y += (mousePositionDelta.y*-CAMERA_MOUSE_MOVE_SENSITIVITY); CAMERA.angle.y += (mousePositionDelta.y*-CAMERA_MOUSE_MOVE_SENSITIVITY);
// Angle clamp // Angle clamp
if (cameraAngle.y > CAMERA_THIRD_PERSON_MIN_CLAMP*DEG2RAD) cameraAngle.y = CAMERA_THIRD_PERSON_MIN_CLAMP*DEG2RAD; if (CAMERA.angle.y > CAMERA_THIRD_PERSON_MIN_CLAMP*DEG2RAD) CAMERA.angle.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; else if (CAMERA.angle.y < CAMERA_THIRD_PERSON_MAX_CLAMP*DEG2RAD) CAMERA.angle.y = CAMERA_THIRD_PERSON_MAX_CLAMP*DEG2RAD;
// Camera zoom // Camera zoom
cameraTargetDistance -= (mouseWheelMove*CAMERA_MOUSE_SCROLL_SENSITIVITY); CAMERA.targetDistance -= (mouseWheelMove*CAMERA_MOUSE_SCROLL_SENSITIVITY);
// Camera distance clamp // Camera distance clamp
if (cameraTargetDistance < CAMERA_THIRD_PERSON_DISTANCE_CLAMP) cameraTargetDistance = CAMERA_THIRD_PERSON_DISTANCE_CLAMP; if (CAMERA.targetDistance < CAMERA_THIRD_PERSON_DISTANCE_CLAMP) CAMERA.targetDistance = 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... // 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; camera->position.x = sinf(CAMERA.angle.x)*CAMERA.targetDistance*cosf(CAMERA.angle.y) + camera->target.x;
if (cameraAngle.y <= 0.0f) camera->position.y = sinf(cameraAngle.y)*cameraTargetDistance*sinf(cameraAngle.y) + camera->target.y; if (CAMERA.angle.y <= 0.0f) camera->position.y = sinf(CAMERA.angle.y)*CAMERA.targetDistance*sinf(CAMERA.angle.y) + camera->target.y;
else camera->position.y = -sinf(cameraAngle.y)*cameraTargetDistance*sinf(cameraAngle.y) + camera->target.y; else camera->position.y = -sinf(CAMERA.angle.y)*CAMERA.targetDistance*sinf(CAMERA.angle.y) + camera->target.y;
camera->position.z = cosf(cameraAngle.x)*cameraTargetDistance*cosf(cameraAngle.y) + camera->target.z; camera->position.z = cosf(CAMERA.angle.x)*CAMERA.targetDistance*cosf(CAMERA.angle.y) + camera->target.z;
} break; } break;
default: break; default: break;
@ -490,23 +502,23 @@ void UpdateCamera(Camera *camera)
} }
// Set camera pan key to combine with mouse movement (free camera) // Set camera pan key to combine with mouse movement (free camera)
void SetCameraPanControl(int panKey) { cameraPanControlKey = panKey; } void SetCameraPanControl(int panKey) { CAMERA.panControl = panKey; }
// Set camera alt key to combine with mouse movement (free camera) // Set camera alt key to combine with mouse movement (free camera)
void SetCameraAltControl(int altKey) { cameraAltControlKey = altKey; } void SetCameraAltControl(int altKey) { CAMERA.altControl = 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 szoomKey) { cameraSmoothZoomControlKey = szoomKey; } void SetCameraSmoothZoomControl(int szoomKey) { CAMERA.smoothZoomControl = 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)
{ {
cameraMoveControl[MOVE_FRONT] = frontKey; CAMERA.moveControl[MOVE_FRONT] = frontKey;
cameraMoveControl[MOVE_BACK] = backKey; CAMERA.moveControl[MOVE_BACK] = backKey;
cameraMoveControl[MOVE_RIGHT] = rightKey; CAMERA.moveControl[MOVE_RIGHT] = rightKey;
cameraMoveControl[MOVE_LEFT] = leftKey; CAMERA.moveControl[MOVE_LEFT] = leftKey;
cameraMoveControl[MOVE_UP] = upKey; CAMERA.moveControl[MOVE_UP] = upKey;
cameraMoveControl[MOVE_DOWN] = downKey; CAMERA.moveControl[MOVE_DOWN] = downKey;
} }
#endif // CAMERA_IMPLEMENTATION #endif // CAMERA_IMPLEMENTATION