From 289e04a62a64a6e82aa5da3397baaa7f48cc45ed Mon Sep 17 00:00:00 2001 From: Ray Date: Wed, 10 Aug 2016 12:55:54 +0200 Subject: Ported camera module to header-only --- src/camera.h | 586 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 556 insertions(+), 30 deletions(-) (limited to 'src/camera.h') diff --git a/src/camera.h b/src/camera.h index 8d8029af..f5bb867d 100644 --- a/src/camera.h +++ b/src/camera.h @@ -2,7 +2,19 @@ * * raylib Camera System - Camera Modes Setup and Control Functions * -* Copyright (c) 2015 Marc Palau and Ramon Santamaria +* #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 +* or source files without problems. But only ONE file should hold the implementation. +* +* #define CAMERA_STANDALONE +* If defined, the library can be used as standalone as a camera system but some +* functions must be redefined to manage inputs accordingly. +* +* NOTE: Memory footprint of this library is aproximately 112 bytes +* +* Initial design by Marc Palau (2014) +* Reviewed by Ramon Santamaria (2015-2016) * * 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. @@ -24,13 +36,6 @@ #ifndef CAMERA_H #define CAMERA_H -#ifndef PI - #define PI 3.14159265358979323846 -#endif - -#define DEG2RAD (PI/180.0f) -#define RAD2DEG (180.0f/PI) - //---------------------------------------------------------------------------------- // Defines and Macros //---------------------------------------------------------------------------------- @@ -40,28 +45,30 @@ // Types and Structures Definition // NOTE: Below types are required for CAMERA_STANDALONE usage //---------------------------------------------------------------------------------- -// 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; - float y; -} Vector2; - -// Vector3 type -typedef struct Vector3 { - float x; - float y; - float z; -} Vector3; - -// Camera type, defines a camera position/orientation in 3d space -typedef struct Camera { - Vector3 position; - Vector3 target; - Vector3 up; -} Camera; +#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; + float y; + } Vector2; + + // Vector3 type + typedef struct Vector3 { + float x; + float y; + float z; + } Vector3; + + // Camera type, defines a camera position/orientation in 3d space + typedef struct Camera { + Vector3 position; + Vector3 target; + Vector3 up; + } Camera; +#endif #ifdef __cplusplus extern "C" { // Prevents name mangling of functions @@ -75,6 +82,7 @@ extern "C" { // Prevents name mangling of functions //---------------------------------------------------------------------------------- // Module Functions Declaration //---------------------------------------------------------------------------------- +#if defined(CAMERA_STANDALONE) void SetCameraMode(int mode); // Set camera mode (multiple camera modes available) void UpdateCamera(Camera *camera); // Update camera (player position is ignored) void UpdateCameraPlayer(Camera *camera, Vector3 *position); // Update camera and player position (1st person and 3rd person cameras) @@ -91,9 +99,527 @@ void SetCameraMoveControls(int frontKey, int backKey, int leftKey, int rightKey, int upKey, int downKey); // Set camera move controls (1st person and 3rd person cameras) void SetCameraMouseSensitivity(float sensitivity); // Set camera mouse sensitivity (1st person and 3rd person cameras) +#endif #ifdef __cplusplus } #endif #endif // CAMERA_H + + +/*********************************************************************************** +* +* CAMERA IMPLEMENTATION +* +************************************************************************************/ + +#if defined(CAMERA_IMPLEMENTATION) + +#include // Required for: sqrt(), sin(), cos() + +#ifndef PI + #define PI 3.14159265358979323846 +#endif + +#ifndef DEG2RAD + #define DEG2RAD (PI/180.0f) +#endif + +#ifndef RAD2DEG + #define RAD2DEG (180.0f/PI) +#endif + +//---------------------------------------------------------------------------------- +// Defines and Macros +//---------------------------------------------------------------------------------- +// CAMERA_GENERIC +#define CAMERA_SCROLL_SENSITIVITY 1.5f + +// FREE_CAMERA +#define CAMERA_FREE_MOUSE_SENSITIVITY 0.01f +#define CAMERA_FREE_DISTANCE_MIN_CLAMP 0.3f +#define CAMERA_FREE_DISTANCE_MAX_CLAMP 120.0f +#define CAMERA_FREE_MIN_CLAMP 85.0f +#define CAMERA_FREE_MAX_CLAMP -85.0f +#define CAMERA_FREE_SMOOTH_ZOOM_SENSITIVITY 0.05f +#define CAMERA_FREE_PANNING_DIVIDER 5.1f + +// ORBITAL_CAMERA +#define CAMERA_ORBITAL_SPEED 0.01f + +// FIRST_PERSON +//#define CAMERA_FIRST_PERSON_MOUSE_SENSITIVITY 0.003f +#define CAMERA_FIRST_PERSON_FOCUS_DISTANCE 25.0f +#define CAMERA_FIRST_PERSON_MIN_CLAMP 85.0f +#define CAMERA_FIRST_PERSON_MAX_CLAMP -85.0f + +#define CAMERA_FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER 5.0f +#define CAMERA_FIRST_PERSON_STEP_DIVIDER 30.0f +#define CAMERA_FIRST_PERSON_WAVING_DIVIDER 200.0f + +#define CAMERA_FIRST_PERSON_HEIGHT_RELATIVE_EYES_POSITION 0.85f + +// THIRD_PERSON +//#define CAMERA_THIRD_PERSON_MOUSE_SENSITIVITY 0.003f +#define CAMERA_THIRD_PERSON_DISTANCE_CLAMP 1.2f +#define CAMERA_THIRD_PERSON_MIN_CLAMP 5.0f +#define CAMERA_THIRD_PERSON_MAX_CLAMP -85.0f +#define CAMERA_THIRD_PERSON_OFFSET (Vector3){ 0.4f, 0.0f, 0.0f } + +// PLAYER (used by camera) +#define PLAYER_WIDTH 0.4f +#define PLAYER_HEIGHT 0.9f +#define PLAYER_DEPTH 0.4f +#define PLAYER_MOVEMENT_DIVIDER 20.0f + +//---------------------------------------------------------------------------------- +// Types and Structures Definition +//---------------------------------------------------------------------------------- +// Camera move modes (first person and third person cameras) +typedef enum { MOVE_FRONT = 0, MOVE_LEFT, MOVE_BACK, MOVE_RIGHT, MOVE_UP, MOVE_DOWN } CameraMove; + +//---------------------------------------------------------------------------------- +// Global Variables Definition +//---------------------------------------------------------------------------------- +static Camera internalCamera = {{ 2.0f, 0.0f, 2.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, 45.0f }; + +static Vector2 cameraAngle = { 0.0f, 0.0f }; +static float cameraTargetDistance = 5.0f; +static Vector2 cameraMousePosition = { 0.0f, 0.0f }; +static Vector2 cameraMouseVariation = { 0.0f, 0.0f }; + +static int cameraMoveControl[6] = { 'W', 'A', 'S', 'D', 'E', 'Q' }; +static int cameraPanControlKey = 2; // raylib: MOUSE_MIDDLE_BUTTON +static int cameraAltControlKey = 342; // raylib: KEY_LEFT_ALT +static int cameraSmoothZoomControlKey = 341; // raylib: KEY_LEFT_CONTROL + +static int cameraMoveCounter = 0; // Used for 1st person swinging movement +static float cameraMouseSensitivity = 0.003f; // How sensible is camera movement to mouse movement + +static int cameraMode = CAMERA_CUSTOM; // Current internal camera mode + +//---------------------------------------------------------------------------------- +// Module specific Functions Declaration +//---------------------------------------------------------------------------------- +static void ProcessCamera(Camera *camera, Vector3 *playerPosition); + +#if defined(CAMERA_STANDALONE) +// NOTE: Camera controls depend on some raylib input functions +// TODO: Set your own input functions (used in ProcessCamera()) +static Vector2 GetMousePosition() { return (Vector2){ 0.0f, 0.0f }; } +static void SetMousePosition(Vector2 pos) {} +static int IsMouseButtonDown(int button) { return 0;} +static int GetMouseWheelMove() { return 0; } +static int GetScreenWidth() { return 1280; } +static int GetScreenHeight() { return 720; } +static void ShowCursor() {} +static void HideCursor() {} +static int IsKeyDown(int key) { return 0; } +#endif + +//---------------------------------------------------------------------------------- +// Module Functions Definition +//---------------------------------------------------------------------------------- + +// Select camera mode (multiple camera modes available) +// TODO: Review hardcoded values when changing modes... +void SetCameraMode(int mode) +{ + if ((cameraMode == CAMERA_FIRST_PERSON) && (mode == CAMERA_FREE)) + { + cameraMode = CAMERA_THIRD_PERSON; + cameraTargetDistance = 5.0f; + cameraAngle.y = -40*DEG2RAD; + ProcessCamera(&internalCamera, &internalCamera.position); + } + else if ((cameraMode == CAMERA_FIRST_PERSON) && (mode == CAMERA_ORBITAL)) + { + cameraMode = CAMERA_THIRD_PERSON; + cameraTargetDistance = 5.0f; + cameraAngle.y = -40*DEG2RAD; + ProcessCamera(&internalCamera, &internalCamera.position); + } + else if ((cameraMode == CAMERA_CUSTOM) && (mode == CAMERA_FREE)) + { + cameraTargetDistance = 10.0f; + cameraAngle.x = 45*DEG2RAD; + cameraAngle.y = -40*DEG2RAD; + internalCamera.target = (Vector3){ 0.0f, 0.0f, 0.0f }; + ProcessCamera(&internalCamera, &internalCamera.position); + + ShowCursor(); + } + else if ((cameraMode == CAMERA_CUSTOM) && (mode == CAMERA_ORBITAL)) + { + cameraTargetDistance = 10.0f; + cameraAngle.x = 225*DEG2RAD; + cameraAngle.y = -40*DEG2RAD; + internalCamera.target = (Vector3){ 0.0f, 0.0f, 0.0f }; + ProcessCamera(&internalCamera, &internalCamera.position); + } + + cameraMode = mode; +} + +// Update camera (player position is ignored) +void UpdateCamera(Camera *camera) +{ + Vector3 position = { 0.0f, 0.0f, 0.0f }; + + // Process internal camera and player position (if required) + if (cameraMode != CAMERA_CUSTOM) ProcessCamera(&internalCamera, &position); + + *camera = internalCamera; +} + +// Update camera and player position (1st person and 3rd person cameras) +void UpdateCameraPlayer(Camera *camera, Vector3 *position) +{ + // Process internal camera and player position (if required) + if (cameraMode != CAMERA_CUSTOM) ProcessCamera(&internalCamera, position); + + *camera = internalCamera; +} + +// Set internal camera position +void SetCameraPosition(Vector3 position) +{ + internalCamera.position = position; + + Vector3 v1 = internalCamera.position; + Vector3 v2 = internalCamera.target; + + float dx = v2.x - v1.x; + float dy = v2.y - v1.y; + float dz = v2.z - v1.z; + + cameraTargetDistance = sqrt(dx*dx + dy*dy + dz*dz); +} + +// Set internal camera target +void SetCameraTarget(Vector3 target) +{ + internalCamera.target = target; + + Vector3 v1 = internalCamera.position; + Vector3 v2 = internalCamera.target; + + float dx = v2.x - v1.x; + float dy = v2.y - v1.y; + float dz = v2.z - v1.z; + + cameraTargetDistance = sqrt(dx*dx + dy*dy + dz*dz); +} + +// Set internal camera fovy +void SetCameraFovy(float fovy) +{ + internalCamera.fovy = fovy; +} + +// Set camera pan key to combine with mouse movement (free camera) +void SetCameraPanControl(int panKey) +{ + cameraPanControlKey = panKey; +} + +// Set camera alt key to combine with mouse movement (free camera) +void SetCameraAltControl(int altKey) +{ + cameraAltControlKey = altKey; +} + +// Set camera smooth zoom key to combine with mouse (free camera) +void SetCameraSmoothZoomControl(int szKey) +{ + cameraSmoothZoomControlKey = szKey; +} + +// Set camera move controls (1st person and 3rd person cameras) +void SetCameraMoveControls(int frontKey, int backKey, int leftKey, int rightKey, int upKey, int downKey) +{ + cameraMoveControl[MOVE_FRONT] = frontKey; + cameraMoveControl[MOVE_LEFT] = leftKey; + cameraMoveControl[MOVE_BACK] = backKey; + cameraMoveControl[MOVE_RIGHT] = rightKey; + cameraMoveControl[MOVE_UP] = upKey; + cameraMoveControl[MOVE_DOWN] = downKey; +} + +// Set camera mouse sensitivity (1st person and 3rd person cameras) +void SetCameracameraMouseSensitivity(float sensitivity) +{ + cameraMouseSensitivity = (sensitivity/10000.0f); +} + +//---------------------------------------------------------------------------------- +// Module specific Functions Definition +//---------------------------------------------------------------------------------- + +// Process desired camera mode and controls +// NOTE: Camera controls depend on some raylib functions: +// Mouse: GetMousePosition(), SetMousePosition(), IsMouseButtonDown(), GetMouseWheelMove() +// System: GetScreenWidth(), GetScreenHeight(), ShowCursor(), HideCursor() +// Keys: IsKeyDown() +static void ProcessCamera(Camera *camera, Vector3 *playerPosition) +{ + // Mouse movement detection + Vector2 mousePosition = GetMousePosition(); + int mouseWheelMove = GetMouseWheelMove(); + int panKey = IsMouseButtonDown(cameraPanControlKey); // bool value + + int screenWidth = GetScreenWidth(); + int screenHeight = GetScreenHeight(); + + if ((cameraMode != CAMERA_FREE) && (cameraMode != CAMERA_ORBITAL)) + { + HideCursor(); + + if (mousePosition.x < screenHeight/3) SetMousePosition((Vector2){ screenWidth - screenHeight/3, mousePosition.y}); + else if (mousePosition.y < screenHeight/3) SetMousePosition((Vector2){ mousePosition.x, screenHeight - screenHeight/3}); + else if (mousePosition.x > screenWidth - screenHeight/3) SetMousePosition((Vector2) { screenHeight/3, mousePosition.y}); + else if (mousePosition.y > screenHeight - screenHeight/3) SetMousePosition((Vector2){ mousePosition.x, screenHeight/3}); + else + { + cameraMouseVariation.x = mousePosition.x - cameraMousePosition.x; + cameraMouseVariation.y = mousePosition.y - cameraMousePosition.y; + } + } + else + { + ShowCursor(); + + cameraMouseVariation.x = mousePosition.x - cameraMousePosition.x; + cameraMouseVariation.y = mousePosition.y - cameraMousePosition.y; + } + + // NOTE: We GetMousePosition() again because it can be modified by a previous SetMousePosition() call + // If using directly mousePosition variable we have problems on CAMERA_FIRST_PERSON and CAMERA_THIRD_PERSON + cameraMousePosition = GetMousePosition(); + + // Support for multiple automatic camera modes + switch (cameraMode) + { + case CAMERA_FREE: + { + // Camera zoom + if ((cameraTargetDistance < CAMERA_FREE_DISTANCE_MAX_CLAMP) && (mouseWheelMove < 0)) + { + cameraTargetDistance -= (mouseWheelMove*CAMERA_SCROLL_SENSITIVITY); + + if (cameraTargetDistance > CAMERA_FREE_DISTANCE_MAX_CLAMP) cameraTargetDistance = CAMERA_FREE_DISTANCE_MAX_CLAMP; + } + // Camera looking down + 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_SCROLL_SENSITIVITY/cameraTargetDistance; + camera->target.y += mouseWheelMove*(camera->target.y - camera->position.y)*CAMERA_SCROLL_SENSITIVITY/cameraTargetDistance; + camera->target.z += mouseWheelMove*(camera->target.z - camera->position.z)*CAMERA_SCROLL_SENSITIVITY/cameraTargetDistance; + } + else if ((camera->position.y > camera->target.y) && (camera->target.y >= 0)) + { + camera->target.x += mouseWheelMove*(camera->target.x - camera->position.x)*CAMERA_SCROLL_SENSITIVITY/cameraTargetDistance; + camera->target.y += mouseWheelMove*(camera->target.y - camera->position.y)*CAMERA_SCROLL_SENSITIVITY/cameraTargetDistance; + camera->target.z += mouseWheelMove*(camera->target.z - camera->position.z)*CAMERA_SCROLL_SENSITIVITY/cameraTargetDistance; + + // if (camera->target.y < 0) camera->target.y = -0.001; + } + else if ((camera->position.y > camera->target.y) && (camera->target.y < 0) && (mouseWheelMove > 0)) + { + cameraTargetDistance -= (mouseWheelMove*CAMERA_SCROLL_SENSITIVITY); + if (cameraTargetDistance < CAMERA_FREE_DISTANCE_MIN_CLAMP) cameraTargetDistance = CAMERA_FREE_DISTANCE_MIN_CLAMP; + } + // Camera looking up + 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_SCROLL_SENSITIVITY/cameraTargetDistance; + camera->target.y += mouseWheelMove*(camera->target.y - camera->position.y)*CAMERA_SCROLL_SENSITIVITY/cameraTargetDistance; + camera->target.z += mouseWheelMove*(camera->target.z - camera->position.z)*CAMERA_SCROLL_SENSITIVITY/cameraTargetDistance; + } + else if ((camera->position.y < camera->target.y) && (camera->target.y <= 0)) + { + camera->target.x += mouseWheelMove*(camera->target.x - camera->position.x)*CAMERA_SCROLL_SENSITIVITY/cameraTargetDistance; + camera->target.y += mouseWheelMove*(camera->target.y - camera->position.y)*CAMERA_SCROLL_SENSITIVITY/cameraTargetDistance; + camera->target.z += mouseWheelMove*(camera->target.z - camera->position.z)*CAMERA_SCROLL_SENSITIVITY/cameraTargetDistance; + + // if (camera->target.y > 0) camera->target.y = 0.001; + } + else if ((camera->position.y < camera->target.y) && (camera->target.y > 0) && (mouseWheelMove > 0)) + { + cameraTargetDistance -= (mouseWheelMove*CAMERA_SCROLL_SENSITIVITY); + if (cameraTargetDistance < CAMERA_FREE_DISTANCE_MIN_CLAMP) cameraTargetDistance = CAMERA_FREE_DISTANCE_MIN_CLAMP; + } + + // Inputs + if (IsKeyDown(cameraAltControlKey)) + { + if (IsKeyDown(cameraSmoothZoomControlKey)) + { + // Camera smooth zoom + if (panKey) cameraTargetDistance += (cameraMouseVariation.y*CAMERA_FREE_SMOOTH_ZOOM_SENSITIVITY); + } + // Camera orientation calculation + else if (panKey) + { + // Camera orientation calculation + // Get the mouse sensitivity + cameraAngle.x += cameraMouseVariation.x*-CAMERA_FREE_MOUSE_SENSITIVITY; + cameraAngle.y += cameraMouseVariation.y*-CAMERA_FREE_MOUSE_SENSITIVITY; + + // Angle clamp + if (cameraAngle.y > CAMERA_FREE_MIN_CLAMP*DEG2RAD) cameraAngle.y = CAMERA_FREE_MIN_CLAMP*DEG2RAD; + else if (cameraAngle.y < CAMERA_FREE_MAX_CLAMP*DEG2RAD) cameraAngle.y = CAMERA_FREE_MAX_CLAMP*DEG2RAD; + } + } + // Paning + else if (panKey) + { + camera->target.x += ((cameraMouseVariation.x*-CAMERA_FREE_MOUSE_SENSITIVITY)*cos(cameraAngle.x) + (cameraMouseVariation.y*CAMERA_FREE_MOUSE_SENSITIVITY)*sin(cameraAngle.x)*sin(cameraAngle.y))*(cameraTargetDistance/CAMERA_FREE_PANNING_DIVIDER); + camera->target.y += ((cameraMouseVariation.y*CAMERA_FREE_MOUSE_SENSITIVITY)*cos(cameraAngle.y))*(cameraTargetDistance/CAMERA_FREE_PANNING_DIVIDER); + camera->target.z += ((cameraMouseVariation.x*CAMERA_FREE_MOUSE_SENSITIVITY)*sin(cameraAngle.x) + (cameraMouseVariation.y*CAMERA_FREE_MOUSE_SENSITIVITY)*cos(cameraAngle.x)*sin(cameraAngle.y))*(cameraTargetDistance/CAMERA_FREE_PANNING_DIVIDER); + } + + // Focus to center + // TODO: Move this function out of this module? + if (IsKeyDown('Z')) camera->target = (Vector3){ 0.0f, 0.0f, 0.0f }; + + // Camera position update + camera->position.x = sin(cameraAngle.x)*cameraTargetDistance*cos(cameraAngle.y) + camera->target.x; + + if (cameraAngle.y <= 0.0f) camera->position.y = sin(cameraAngle.y)*cameraTargetDistance*sin(cameraAngle.y) + camera->target.y; + else camera->position.y = -sin(cameraAngle.y)*cameraTargetDistance*sin(cameraAngle.y) + camera->target.y; + + camera->position.z = cos(cameraAngle.x)*cameraTargetDistance*cos(cameraAngle.y) + camera->target.z; + + } break; + case CAMERA_ORBITAL: + { + cameraAngle.x += CAMERA_ORBITAL_SPEED; + + // Camera zoom + cameraTargetDistance -= (mouseWheelMove*CAMERA_SCROLL_SENSITIVITY); + + // Camera distance clamp + if (cameraTargetDistance < CAMERA_THIRD_PERSON_DISTANCE_CLAMP) cameraTargetDistance = CAMERA_THIRD_PERSON_DISTANCE_CLAMP; + + // Focus to center + if (IsKeyDown('Z')) camera->target = (Vector3){ 0.0f, 0.0f, 0.0f }; + + // Camera position update + camera->position.x = sin(cameraAngle.x)*cameraTargetDistance*cos(cameraAngle.y) + camera->target.x; + + if (cameraAngle.y <= 0.0f) camera->position.y = sin(cameraAngle.y)*cameraTargetDistance*sin(cameraAngle.y) + camera->target.y; + else camera->position.y = -sin(cameraAngle.y)*cameraTargetDistance*sin(cameraAngle.y) + camera->target.y; + + camera->position.z = cos(cameraAngle.x)*cameraTargetDistance*cos(cameraAngle.y) + camera->target.z; + + } break; + case CAMERA_FIRST_PERSON: + case CAMERA_THIRD_PERSON: + { + bool isMoving = false; + + // Keyboard inputs + if (IsKeyDown(cameraMoveControl[MOVE_FRONT])) + { + playerPosition->x -= sin(cameraAngle.x)/PLAYER_MOVEMENT_DIVIDER; + playerPosition->z -= cos(cameraAngle.x)/PLAYER_MOVEMENT_DIVIDER; + + camera->position.y += sin(cameraAngle.y)/PLAYER_MOVEMENT_DIVIDER; + + isMoving = true; + } + else if (IsKeyDown(cameraMoveControl[MOVE_BACK])) + { + playerPosition->x += sin(cameraAngle.x)/PLAYER_MOVEMENT_DIVIDER; + playerPosition->z += cos(cameraAngle.x)/PLAYER_MOVEMENT_DIVIDER; + + camera->position.y -= sin(cameraAngle.y)/PLAYER_MOVEMENT_DIVIDER; + + isMoving = true; + } + + if (IsKeyDown(cameraMoveControl[MOVE_LEFT])) + { + playerPosition->x -= cos(cameraAngle.x)/PLAYER_MOVEMENT_DIVIDER; + playerPosition->z += sin(cameraAngle.x)/PLAYER_MOVEMENT_DIVIDER; + + isMoving = true; + } + else if (IsKeyDown(cameraMoveControl[MOVE_RIGHT])) + { + playerPosition->x += cos(cameraAngle.x)/PLAYER_MOVEMENT_DIVIDER; + playerPosition->z -= sin(cameraAngle.x)/PLAYER_MOVEMENT_DIVIDER; + + isMoving = true; + } + + if (IsKeyDown(cameraMoveControl[MOVE_UP])) + { + playerPosition->y += 1.0f/PLAYER_MOVEMENT_DIVIDER; + } + else if (IsKeyDown(cameraMoveControl[MOVE_DOWN])) + { + playerPosition->y -= 1.0f/PLAYER_MOVEMENT_DIVIDER; + } + + if (cameraMode == CAMERA_THIRD_PERSON) + { + // Camera orientation calculation + cameraAngle.x += cameraMouseVariation.x*-cameraMouseSensitivity; + cameraAngle.y += cameraMouseVariation.y*-cameraMouseSensitivity; + + // 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_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 = playerPosition->x + CAMERA_THIRD_PERSON_OFFSET.x*cos(cameraAngle.x) + CAMERA_THIRD_PERSON_OFFSET.z*sin(cameraAngle.x); + camera->target.y = playerPosition->y + PLAYER_HEIGHT*CAMERA_FIRST_PERSON_HEIGHT_RELATIVE_EYES_POSITION + CAMERA_THIRD_PERSON_OFFSET.y; + camera->target.z = playerPosition->z + CAMERA_THIRD_PERSON_OFFSET.z*sin(cameraAngle.x) - CAMERA_THIRD_PERSON_OFFSET.x*sin(cameraAngle.x); + + // Camera position update + camera->position.x = sin(cameraAngle.x)*cameraTargetDistance*cos(cameraAngle.y) + camera->target.x; + + if (cameraAngle.y <= 0.0f) camera->position.y = sin(cameraAngle.y)*cameraTargetDistance*sin(cameraAngle.y) + camera->target.y; + else camera->position.y = -sin(cameraAngle.y)*cameraTargetDistance*sin(cameraAngle.y) + camera->target.y; + + camera->position.z = cos(cameraAngle.x)*cameraTargetDistance*cos(cameraAngle.y) + camera->target.z; + } + else // CAMERA_FIRST_PERSON + { + if (isMoving) cameraMoveCounter++; + + // Camera orientation calculation + cameraAngle.x += (cameraMouseVariation.x*-cameraMouseSensitivity); + cameraAngle.y += (cameraMouseVariation.y*-cameraMouseSensitivity); + + // 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 - sin(cameraAngle.x)*CAMERA_FIRST_PERSON_FOCUS_DISTANCE; + camera->target.y = camera->position.y + sin(cameraAngle.y)*CAMERA_FIRST_PERSON_FOCUS_DISTANCE; + camera->target.z = camera->position.z - cos(cameraAngle.x)*CAMERA_FIRST_PERSON_FOCUS_DISTANCE; + + camera->position.x = playerPosition->x; + camera->position.y = (playerPosition->y + PLAYER_HEIGHT*CAMERA_FIRST_PERSON_HEIGHT_RELATIVE_EYES_POSITION) - sin(cameraMoveCounter/CAMERA_FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER)/CAMERA_FIRST_PERSON_STEP_DIVIDER; + camera->position.z = playerPosition->z; + + camera->up.x = sin(cameraMoveCounter/(CAMERA_FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER*2))/CAMERA_FIRST_PERSON_WAVING_DIVIDER; + camera->up.z = -sin(cameraMoveCounter/(CAMERA_FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER*2))/CAMERA_FIRST_PERSON_WAVING_DIVIDER; + } + } break; + default: break; + } +} + +#endif // CAMERA_IMPLEMENTATION -- cgit v1.2.3 From 1ffc4c7825ab732328040d2d650c6bf6d0e2f24c Mon Sep 17 00:00:00 2001 From: raysan5 Date: Mon, 15 Aug 2016 16:34:10 +0200 Subject: Corrected naming bug --- src/camera.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/camera.h') diff --git a/src/camera.h b/src/camera.h index f5bb867d..72a0e706 100644 --- a/src/camera.h +++ b/src/camera.h @@ -348,7 +348,7 @@ void SetCameraMoveControls(int frontKey, int backKey, int leftKey, int rightKey, } // Set camera mouse sensitivity (1st person and 3rd person cameras) -void SetCameracameraMouseSensitivity(float sensitivity) +void SetCameraMouseSensitivity(float sensitivity) { cameraMouseSensitivity = (sensitivity/10000.0f); } -- cgit v1.2.3 From 65d4eb5e826ee416feb951281e805df93a455a65 Mon Sep 17 00:00:00 2001 From: raysan5 Date: Thu, 22 Sep 2016 14:38:17 +0200 Subject: Simplify camera module -IN PROGRESS- Removed internal Camera, not required any more Removed useless functions --- src/camera.h | 231 ++++++++++++++++++++++++++--------------------------------- 1 file changed, 101 insertions(+), 130 deletions(-) (limited to 'src/camera.h') diff --git a/src/camera.h b/src/camera.h index 72a0e706..cda09df4 100644 --- a/src/camera.h +++ b/src/camera.h @@ -182,10 +182,8 @@ typedef enum { MOVE_FRONT = 0, MOVE_LEFT, MOVE_BACK, MOVE_RIGHT, MOVE_UP, MOVE_D //---------------------------------------------------------------------------------- // Global Variables Definition //---------------------------------------------------------------------------------- -static Camera internalCamera = {{ 2.0f, 0.0f, 2.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, 45.0f }; - static Vector2 cameraAngle = { 0.0f, 0.0f }; -static float cameraTargetDistance = 5.0f; +static float cameraTargetDistance = 5.0f; // TODO: Remove! Use predefined camera->target to camera->position distance static Vector2 cameraMousePosition = { 0.0f, 0.0f }; static Vector2 cameraMouseVariation = { 0.0f, 0.0f }; @@ -202,8 +200,6 @@ static int cameraMode = CAMERA_CUSTOM; // Current internal camera //---------------------------------------------------------------------------------- // Module specific Functions Declaration //---------------------------------------------------------------------------------- -static void ProcessCamera(Camera *camera, Vector3 *playerPosition); - #if defined(CAMERA_STANDALONE) // NOTE: Camera controls depend on some raylib input functions // TODO: Set your own input functions (used in ProcessCamera()) @@ -228,65 +224,30 @@ void SetCameraMode(int mode) { if ((cameraMode == CAMERA_FIRST_PERSON) && (mode == CAMERA_FREE)) { - cameraMode = CAMERA_THIRD_PERSON; - cameraTargetDistance = 5.0f; + cameraTargetDistance = 5.0f; // TODO: Review hardcode! cameraAngle.y = -40*DEG2RAD; - ProcessCamera(&internalCamera, &internalCamera.position); } else if ((cameraMode == CAMERA_FIRST_PERSON) && (mode == CAMERA_ORBITAL)) { - cameraMode = CAMERA_THIRD_PERSON; - cameraTargetDistance = 5.0f; + cameraTargetDistance = 5.0f; // TODO: Review hardcode! cameraAngle.y = -40*DEG2RAD; - ProcessCamera(&internalCamera, &internalCamera.position); } else if ((cameraMode == CAMERA_CUSTOM) && (mode == CAMERA_FREE)) { - cameraTargetDistance = 10.0f; + cameraTargetDistance = 10.0f; // TODO: Review hardcode! cameraAngle.x = 45*DEG2RAD; cameraAngle.y = -40*DEG2RAD; - internalCamera.target = (Vector3){ 0.0f, 0.0f, 0.0f }; - ProcessCamera(&internalCamera, &internalCamera.position); ShowCursor(); } else if ((cameraMode == CAMERA_CUSTOM) && (mode == CAMERA_ORBITAL)) { - cameraTargetDistance = 10.0f; + //cameraTargetDistance = 10.0f; // TODO: Review hardcode! cameraAngle.x = 225*DEG2RAD; cameraAngle.y = -40*DEG2RAD; - internalCamera.target = (Vector3){ 0.0f, 0.0f, 0.0f }; - ProcessCamera(&internalCamera, &internalCamera.position); } - - cameraMode = mode; -} - -// Update camera (player position is ignored) -void UpdateCamera(Camera *camera) -{ - Vector3 position = { 0.0f, 0.0f, 0.0f }; - - // Process internal camera and player position (if required) - if (cameraMode != CAMERA_CUSTOM) ProcessCamera(&internalCamera, &position); - - *camera = internalCamera; -} - -// Update camera and player position (1st person and 3rd person cameras) -void UpdateCameraPlayer(Camera *camera, Vector3 *position) -{ - // Process internal camera and player position (if required) - if (cameraMode != CAMERA_CUSTOM) ProcessCamera(&internalCamera, position); - - *camera = internalCamera; -} - -// Set internal camera position -void SetCameraPosition(Vector3 position) -{ - internalCamera.position = position; + /* Vector3 v1 = internalCamera.position; Vector3 v2 = internalCamera.target; @@ -295,75 +256,24 @@ void SetCameraPosition(Vector3 position) float dz = v2.z - v1.z; cameraTargetDistance = sqrt(dx*dx + dy*dy + dz*dz); -} - -// Set internal camera target -void SetCameraTarget(Vector3 target) -{ - internalCamera.target = target; - - Vector3 v1 = internalCamera.position; - Vector3 v2 = internalCamera.target; + */ - float dx = v2.x - v1.x; - float dy = v2.y - v1.y; - float dz = v2.z - v1.z; - - cameraTargetDistance = sqrt(dx*dx + dy*dy + dz*dz); -} - -// Set internal camera fovy -void SetCameraFovy(float fovy) -{ - internalCamera.fovy = fovy; -} - -// Set camera pan key to combine with mouse movement (free camera) -void SetCameraPanControl(int panKey) -{ - cameraPanControlKey = panKey; -} - -// Set camera alt key to combine with mouse movement (free camera) -void SetCameraAltControl(int altKey) -{ - cameraAltControlKey = altKey; -} - -// Set camera smooth zoom key to combine with mouse (free camera) -void SetCameraSmoothZoomControl(int szKey) -{ - cameraSmoothZoomControlKey = szKey; -} - -// Set camera move controls (1st person and 3rd person cameras) -void SetCameraMoveControls(int frontKey, int backKey, int leftKey, int rightKey, int upKey, int downKey) -{ - cameraMoveControl[MOVE_FRONT] = frontKey; - cameraMoveControl[MOVE_LEFT] = leftKey; - cameraMoveControl[MOVE_BACK] = backKey; - cameraMoveControl[MOVE_RIGHT] = rightKey; - cameraMoveControl[MOVE_UP] = upKey; - cameraMoveControl[MOVE_DOWN] = downKey; -} - -// Set camera mouse sensitivity (1st person and 3rd person cameras) -void SetCameraMouseSensitivity(float sensitivity) -{ - cameraMouseSensitivity = (sensitivity/10000.0f); + cameraMode = mode; } -//---------------------------------------------------------------------------------- -// Module specific Functions Definition -//---------------------------------------------------------------------------------- - -// Process desired camera mode and controls +// Update camera depending on selected mode // NOTE: Camera controls depend on some raylib functions: // Mouse: GetMousePosition(), SetMousePosition(), IsMouseButtonDown(), GetMouseWheelMove() // System: GetScreenWidth(), GetScreenHeight(), ShowCursor(), HideCursor() // Keys: IsKeyDown() -static void ProcessCamera(Camera *camera, Vector3 *playerPosition) +void UpdateCamera(Camera *camera) { + /* + if (cameraMode != CAMERA_CUSTOM) + { + + } + */ // Mouse movement detection Vector2 mousePosition = GetMousePosition(); int mouseWheelMove = GetMouseWheelMove(); @@ -523,46 +433,38 @@ static void ProcessCamera(Camera *camera, Vector3 *playerPosition) // Keyboard inputs if (IsKeyDown(cameraMoveControl[MOVE_FRONT])) { - playerPosition->x -= sin(cameraAngle.x)/PLAYER_MOVEMENT_DIVIDER; - playerPosition->z -= cos(cameraAngle.x)/PLAYER_MOVEMENT_DIVIDER; - + camera->position.x -= sin(cameraAngle.x)/PLAYER_MOVEMENT_DIVIDER; camera->position.y += sin(cameraAngle.y)/PLAYER_MOVEMENT_DIVIDER; + camera->position.z -= cos(cameraAngle.x)/PLAYER_MOVEMENT_DIVIDER; isMoving = true; } else if (IsKeyDown(cameraMoveControl[MOVE_BACK])) { - playerPosition->x += sin(cameraAngle.x)/PLAYER_MOVEMENT_DIVIDER; - playerPosition->z += cos(cameraAngle.x)/PLAYER_MOVEMENT_DIVIDER; - + camera->position.x += sin(cameraAngle.x)/PLAYER_MOVEMENT_DIVIDER; camera->position.y -= sin(cameraAngle.y)/PLAYER_MOVEMENT_DIVIDER; + camera->position.z += cos(cameraAngle.x)/PLAYER_MOVEMENT_DIVIDER; isMoving = true; } if (IsKeyDown(cameraMoveControl[MOVE_LEFT])) { - playerPosition->x -= cos(cameraAngle.x)/PLAYER_MOVEMENT_DIVIDER; - playerPosition->z += sin(cameraAngle.x)/PLAYER_MOVEMENT_DIVIDER; + camera->position.x -= cos(cameraAngle.x)/PLAYER_MOVEMENT_DIVIDER; + camera->position.z += sin(cameraAngle.x)/PLAYER_MOVEMENT_DIVIDER; isMoving = true; } else if (IsKeyDown(cameraMoveControl[MOVE_RIGHT])) { - playerPosition->x += cos(cameraAngle.x)/PLAYER_MOVEMENT_DIVIDER; - playerPosition->z -= sin(cameraAngle.x)/PLAYER_MOVEMENT_DIVIDER; + camera->position.x += cos(cameraAngle.x)/PLAYER_MOVEMENT_DIVIDER; + camera->position.z -= sin(cameraAngle.x)/PLAYER_MOVEMENT_DIVIDER; isMoving = true; } - if (IsKeyDown(cameraMoveControl[MOVE_UP])) - { - playerPosition->y += 1.0f/PLAYER_MOVEMENT_DIVIDER; - } - else if (IsKeyDown(cameraMoveControl[MOVE_DOWN])) - { - playerPosition->y -= 1.0f/PLAYER_MOVEMENT_DIVIDER; - } + if (IsKeyDown(cameraMoveControl[MOVE_UP])) camera->position.y += 1.0f/PLAYER_MOVEMENT_DIVIDER; + else if (IsKeyDown(cameraMoveControl[MOVE_DOWN])) camera->position.y -= 1.0f/PLAYER_MOVEMENT_DIVIDER; if (cameraMode == CAMERA_THIRD_PERSON) { @@ -581,9 +483,9 @@ static void ProcessCamera(Camera *camera, Vector3 *playerPosition) if (cameraTargetDistance < CAMERA_THIRD_PERSON_DISTANCE_CLAMP) cameraTargetDistance = CAMERA_THIRD_PERSON_DISTANCE_CLAMP; // Camera is always looking at player - camera->target.x = playerPosition->x + CAMERA_THIRD_PERSON_OFFSET.x*cos(cameraAngle.x) + CAMERA_THIRD_PERSON_OFFSET.z*sin(cameraAngle.x); - camera->target.y = playerPosition->y + PLAYER_HEIGHT*CAMERA_FIRST_PERSON_HEIGHT_RELATIVE_EYES_POSITION + CAMERA_THIRD_PERSON_OFFSET.y; - camera->target.z = playerPosition->z + CAMERA_THIRD_PERSON_OFFSET.z*sin(cameraAngle.x) - CAMERA_THIRD_PERSON_OFFSET.x*sin(cameraAngle.x); + camera->target.x = camera->position.x + CAMERA_THIRD_PERSON_OFFSET.x*cos(cameraAngle.x) + CAMERA_THIRD_PERSON_OFFSET.z*sin(cameraAngle.x); + camera->target.y = camera->position.y + PLAYER_HEIGHT*CAMERA_FIRST_PERSON_HEIGHT_RELATIVE_EYES_POSITION + CAMERA_THIRD_PERSON_OFFSET.y; + camera->target.z = camera->position.z + CAMERA_THIRD_PERSON_OFFSET.z*sin(cameraAngle.x) - CAMERA_THIRD_PERSON_OFFSET.x*sin(cameraAngle.x); // Camera position update camera->position.x = sin(cameraAngle.x)*cameraTargetDistance*cos(cameraAngle.y) + camera->target.x; @@ -610,9 +512,12 @@ static void ProcessCamera(Camera *camera, Vector3 *playerPosition) camera->target.y = camera->position.y + sin(cameraAngle.y)*CAMERA_FIRST_PERSON_FOCUS_DISTANCE; camera->target.z = camera->position.z - cos(cameraAngle.x)*CAMERA_FIRST_PERSON_FOCUS_DISTANCE; - camera->position.x = playerPosition->x; - camera->position.y = (playerPosition->y + PLAYER_HEIGHT*CAMERA_FIRST_PERSON_HEIGHT_RELATIVE_EYES_POSITION) - sin(cameraMoveCounter/CAMERA_FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER)/CAMERA_FIRST_PERSON_STEP_DIVIDER; - camera->position.z = playerPosition->z; + // Camera position update + //camera->position.y = (playerPosition.y + PLAYER_HEIGHT*CAMERA_FIRST_PERSON_HEIGHT_RELATIVE_EYES_POSITION) + // - sin(cameraMoveCounter/CAMERA_FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER)/CAMERA_FIRST_PERSON_STEP_DIVIDER; + + // TODO: Review limits, avoid moving under the ground (y = 0.0f) and over the 'eyes position', weird movement (rounding issues...) + camera->position.y -= sin(cameraMoveCounter/CAMERA_FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER)/CAMERA_FIRST_PERSON_STEP_DIVIDER; camera->up.x = sin(cameraMoveCounter/(CAMERA_FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER*2))/CAMERA_FIRST_PERSON_WAVING_DIVIDER; camera->up.z = -sin(cameraMoveCounter/(CAMERA_FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER*2))/CAMERA_FIRST_PERSON_WAVING_DIVIDER; @@ -622,4 +527,70 @@ static void ProcessCamera(Camera *camera, Vector3 *playerPosition) } } +/* +// Set internal camera position +void SetCameraPosition(Vector3 position) +{ + internalCamera.position = position; + + Vector3 v1 = internalCamera.position; + Vector3 v2 = internalCamera.target; + + float dx = v2.x - v1.x; + float dy = v2.y - v1.y; + float dz = v2.z - v1.z; + + cameraTargetDistance = sqrt(dx*dx + dy*dy + dz*dz); +} + +// Set internal camera target +void SetCameraTarget(Vector3 target) +{ + internalCamera.target = target; + + Vector3 v1 = internalCamera.position; + Vector3 v2 = internalCamera.target; + + float dx = v2.x - v1.x; + float dy = v2.y - v1.y; + float dz = v2.z - v1.z; + + cameraTargetDistance = sqrt(dx*dx + dy*dy + dz*dz); +} +*/ +// Set camera pan key to combine with mouse movement (free camera) +void SetCameraPanControl(int panKey) +{ + cameraPanControlKey = panKey; +} + +// Set camera alt key to combine with mouse movement (free camera) +void SetCameraAltControl(int altKey) +{ + cameraAltControlKey = altKey; +} + +// Set camera smooth zoom key to combine with mouse (free camera) +void SetCameraSmoothZoomControl(int szKey) +{ + cameraSmoothZoomControlKey = szKey; +} + +// Set camera move controls (1st person and 3rd person cameras) +void SetCameraMoveControls(int frontKey, int backKey, int leftKey, int rightKey, int upKey, int downKey) +{ + cameraMoveControl[MOVE_FRONT] = frontKey; + cameraMoveControl[MOVE_LEFT] = leftKey; + cameraMoveControl[MOVE_BACK] = backKey; + cameraMoveControl[MOVE_RIGHT] = rightKey; + cameraMoveControl[MOVE_UP] = upKey; + cameraMoveControl[MOVE_DOWN] = downKey; +} + +// Set camera mouse sensitivity (1st person and 3rd person cameras) +void SetCameraMouseSensitivity(float sensitivity) +{ + cameraMouseSensitivity = (sensitivity/10000.0f); +} + #endif // CAMERA_IMPLEMENTATION -- cgit v1.2.3 From 753b549aa5c6a010fc4de8acc2f64afdfce69cee Mon Sep 17 00:00:00 2001 From: raysan5 Date: Sun, 25 Sep 2016 14:28:24 +0200 Subject: Improving camera system -IN PROGRESS- --- examples/core_3d_camera_first_person.c | 9 +- examples/core_3d_camera_free.c | 5 +- examples/models_cubicmap.c | 10 +- src/camera.h | 280 ++++++++++++++------------------- src/raylib.h | 17 +- 5 files changed, 131 insertions(+), 190 deletions(-) (limited to 'src/camera.h') diff --git a/examples/core_3d_camera_first_person.c b/examples/core_3d_camera_first_person.c index 56e38a23..3675d46a 100644 --- a/examples/core_3d_camera_first_person.c +++ b/examples/core_3d_camera_first_person.c @@ -23,7 +23,7 @@ int main() InitWindow(screenWidth, screenHeight, "raylib [core] example - 3d camera first person"); // Define the camera to look into our 3d world (position, target, up vector) - Camera camera = {{ 0.0f, 10.0f, 10.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, 60.0f }; + Camera camera = {{ 4.0f, 2.0f, 4.0f }, { 0.0f, 2.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, 60.0f }; // Generates some random columns float heights[MAX_COLUMNS]; @@ -37,10 +37,7 @@ int main() colors[i] = (Color){ GetRandomValue(20, 255), GetRandomValue(10, 55), 30, 255 }; } - Vector3 playerPosition = { 4.0f, 2.0f, 4.0f }; // Define player position - - SetCameraMode(CAMERA_FIRST_PERSON); // Set a first person camera mode - SetCameraFovy(camera.fovy); // Set internal camera field-of-view Y + SetCameraMode(camera, CAMERA_FIRST_PERSON); // Set a first person camera mode SetTargetFPS(60); // Set our game to run at 60 frames-per-second //-------------------------------------------------------------------------------------- @@ -50,7 +47,7 @@ int main() { // Update //---------------------------------------------------------------------------------- - UpdateCameraPlayer(&camera, &playerPosition); // Update camera and player position + UpdateCamera(&camera); // Update camera and player position //---------------------------------------------------------------------------------- // Draw diff --git a/examples/core_3d_camera_free.c b/examples/core_3d_camera_free.c index fa7ad85f..257bb789 100644 --- a/examples/core_3d_camera_free.c +++ b/examples/core_3d_camera_free.c @@ -29,10 +29,7 @@ int main() Vector3 cubePosition = { 0.0f, 0.0f, 0.0f }; - SetCameraMode(CAMERA_FREE); // Set a free camera mode - SetCameraPosition(camera.position); // Set internal camera position to match our camera position - SetCameraTarget(camera.target); // Set internal camera target to match our camera target - SetCameraFovy(camera.fovy); // Set internal camera field-of-view Y + SetCameraMode(camera, CAMERA_FREE); // Set a free camera mode SetTargetFPS(60); // Set our game to run at 60 frames-per-second //-------------------------------------------------------------------------------------- diff --git a/examples/models_cubicmap.c b/examples/models_cubicmap.c index 89bc75cf..df700d65 100644 --- a/examples/models_cubicmap.c +++ b/examples/models_cubicmap.c @@ -35,19 +35,17 @@ int main() UnloadImage(image); // Unload cubesmap image from RAM, already uploaded to VRAM - SetCameraMode(CAMERA_ORBITAL); // Set an orbital camera mode - SetCameraPosition(camera.position); // Set internal camera position to match our custom camera position - SetCameraFovy(camera.fovy); // Set internal camera field-of-view Y + SetCameraMode(camera, CAMERA_ORBITAL); // Set an orbital camera mode - SetTargetFPS(60); // Set our game to run at 60 frames-per-second + SetTargetFPS(60); // Set our game to run at 60 frames-per-second //-------------------------------------------------------------------------------------- // Main game loop - while (!WindowShouldClose()) // Detect window close button or ESC key + while (!WindowShouldClose()) // Detect window close button or ESC key { // Update //---------------------------------------------------------------------------------- - UpdateCamera(&camera); // Update internal camera and our camera + UpdateCamera(&camera); // Update internal camera and our camera //---------------------------------------------------------------------------------- // Draw diff --git a/src/camera.h b/src/camera.h index cda09df4..0c7b5a13 100644 --- a/src/camera.h +++ b/src/camera.h @@ -47,7 +47,13 @@ //---------------------------------------------------------------------------------- #if defined(CAMERA_STANDALONE) // Camera modes - typedef enum { CAMERA_CUSTOM = 0, CAMERA_FREE, CAMERA_ORBITAL, CAMERA_FIRST_PERSON, CAMERA_THIRD_PERSON } CameraMode; + typedef enum { + CAMERA_CUSTOM = 0, + CAMERA_FREE, + CAMERA_ORBITAL, + CAMERA_FIRST_PERSON, + CAMERA_THIRD_PERSON + } CameraMode; // Vector2 type typedef struct Vector2 { @@ -67,6 +73,7 @@ Vector3 position; Vector3 target; Vector3 up; + float fovy; } Camera; #endif @@ -83,22 +90,16 @@ extern "C" { // Prevents name mangling of functions // Module Functions Declaration //---------------------------------------------------------------------------------- #if defined(CAMERA_STANDALONE) -void SetCameraMode(int mode); // Set camera mode (multiple camera modes available) +void SetCameraMode(Camera camera, int mode); // Set camera mode (multiple camera modes available) void UpdateCamera(Camera *camera); // Update camera (player position is ignored) -void UpdateCameraPlayer(Camera *camera, Vector3 *position); // Update camera and player position (1st person and 3rd person cameras) - -void SetCameraPosition(Vector3 position); // Set internal camera position -void SetCameraTarget(Vector3 target); // Set internal camera target -void SetCameraFovy(float fovy); // Set internal camera field-of-view-y +// TODO: Do we really need all those functions? 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 leftKey, int rightKey, int upKey, int downKey); // Set camera move controls (1st person and 3rd person cameras) -void SetCameraMouseSensitivity(float sensitivity); // Set camera mouse sensitivity (1st person and 3rd person cameras) #endif #ifdef __cplusplus @@ -133,8 +134,10 @@ void SetCameraMouseSensitivity(float sensitivity); // Set camera mouse //---------------------------------------------------------------------------------- // Defines and Macros //---------------------------------------------------------------------------------- -// CAMERA_GENERIC -#define CAMERA_SCROLL_SENSITIVITY 1.5f +// Camera mouse movement sensitivity +#define CAMERA_MOUSE_MOVE_SENSITIVITY 0.003f +#define CAMERA_MOUSE_SCROLL_SENSITIVITY 1.5f + // FREE_CAMERA #define CAMERA_FREE_MOUSE_SENSITIVITY 0.01f @@ -182,20 +185,15 @@ typedef enum { MOVE_FRONT = 0, MOVE_LEFT, MOVE_BACK, MOVE_RIGHT, MOVE_UP, MOVE_D //---------------------------------------------------------------------------------- // Global Variables Definition //---------------------------------------------------------------------------------- -static Vector2 cameraAngle = { 0.0f, 0.0f }; -static float cameraTargetDistance = 5.0f; // TODO: Remove! Use predefined camera->target to camera->position distance -static Vector2 cameraMousePosition = { 0.0f, 0.0f }; -static Vector2 cameraMouseVariation = { 0.0f, 0.0f }; +static Vector2 cameraAngle = { 0.0f, 0.0f }; // TODO: Remove! Compute it in UpdateCamera() using camera->target and camera->position +static float cameraTargetDistance = 5.0f; // TODO: Remove! Compute it in UpdateCamera() using camera->target and camera->position static int cameraMoveControl[6] = { 'W', 'A', 'S', 'D', 'E', 'Q' }; static int cameraPanControlKey = 2; // raylib: MOUSE_MIDDLE_BUTTON static int cameraAltControlKey = 342; // raylib: KEY_LEFT_ALT static int cameraSmoothZoomControlKey = 341; // raylib: KEY_LEFT_CONTROL -static int cameraMoveCounter = 0; // Used for 1st person swinging movement -static float cameraMouseSensitivity = 0.003f; // How sensible is camera movement to mouse movement - -static int cameraMode = CAMERA_CUSTOM; // Current internal camera mode +static int cameraMode = CAMERA_CUSTOM; // Current camera mode //---------------------------------------------------------------------------------- // Module specific Functions Declaration @@ -219,45 +217,21 @@ static int IsKeyDown(int key) { return 0; } //---------------------------------------------------------------------------------- // Select camera mode (multiple camera modes available) -// TODO: Review hardcoded values when changing modes... -void SetCameraMode(int mode) +void SetCameraMode(Camera camera, int mode) { - if ((cameraMode == CAMERA_FIRST_PERSON) && (mode == CAMERA_FREE)) - { - cameraTargetDistance = 5.0f; // TODO: Review hardcode! - cameraAngle.y = -40*DEG2RAD; - } - else if ((cameraMode == CAMERA_FIRST_PERSON) && (mode == CAMERA_ORBITAL)) - { - cameraTargetDistance = 5.0f; // TODO: Review hardcode! - cameraAngle.y = -40*DEG2RAD; - } - else if ((cameraMode == CAMERA_CUSTOM) && (mode == CAMERA_FREE)) - { - cameraTargetDistance = 10.0f; // TODO: Review hardcode! - cameraAngle.x = 45*DEG2RAD; - cameraAngle.y = -40*DEG2RAD; - - ShowCursor(); - } - else if ((cameraMode == CAMERA_CUSTOM) && (mode == CAMERA_ORBITAL)) - { - //cameraTargetDistance = 10.0f; // TODO: Review hardcode! - cameraAngle.x = 225*DEG2RAD; - cameraAngle.y = -40*DEG2RAD; - } - - /* - Vector3 v1 = internalCamera.position; - Vector3 v2 = internalCamera.target; + // 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 = sqrt(dx*dx + dy*dy + dz*dz); - */ - + cameraAngle.y = -40*DEG2RAD; + cameraMode = mode; } @@ -266,48 +240,73 @@ void SetCameraMode(int mode) // Mouse: GetMousePosition(), SetMousePosition(), IsMouseButtonDown(), GetMouseWheelMove() // System: GetScreenWidth(), GetScreenHeight(), ShowCursor(), HideCursor() // Keys: IsKeyDown() +// TODO: Consider touch inputs for camera! +// TODO: Port to quaternion-based camera! void UpdateCamera(Camera *camera) { + static int swingCounter = 0; // Used for 1st person swinging movement + static Vector2 previousMousePosition = { 0.0f, 0.0f }; + + // TODO: Compute cameraTargetDistance and cameraAngle + // NOTE: If cameraTargetDistance and cameraAngle change, camera->position is accordingly updated /* - if (cameraMode != CAMERA_CUSTOM) - { - - } + Vector2 cameraAngle = { 0.0f, 0.0f }; + float cameraTargetDistance = 0.0f; + + float dx = camera->target.x - camera->position.x; + float dy = camera->target.y - camera->position.y; + float dz = camera->target.z - camera->position.z; + + cameraTargetDistance = sqrt(dx*dx + dy*dy + dz*dz); + + Vector2 distance = { 0.0f, 0.0f }; + distance.x = sqrt(dx*dx + dy*dy); + distance.y = sqrt(dx*dx + dz*dz); + + cameraAngle.x = asin(fabs(dx)/distance.x); + cameraAngle.y = asin(fabs(dz)/distance.y); */ + // Mouse movement detection + Vector2 mousePositionDelta = { 0.0f, 0.0f }; Vector2 mousePosition = GetMousePosition(); int mouseWheelMove = GetMouseWheelMove(); int panKey = IsMouseButtonDown(cameraPanControlKey); // bool value - int screenWidth = GetScreenWidth(); - int screenHeight = GetScreenHeight(); - - if ((cameraMode != CAMERA_FREE) && (cameraMode != CAMERA_ORBITAL)) + if (cameraMode != CAMERA_CUSTOM) { - HideCursor(); + // Get screen size + int screenWidth = GetScreenWidth(); + int screenHeight = GetScreenHeight(); + + if ((cameraMode == CAMERA_FIRST_PERSON) || + (cameraMode == CAMERA_THIRD_PERSON)) + { + HideCursor(); - if (mousePosition.x < screenHeight/3) SetMousePosition((Vector2){ screenWidth - screenHeight/3, mousePosition.y}); - else if (mousePosition.y < screenHeight/3) SetMousePosition((Vector2){ mousePosition.x, screenHeight - screenHeight/3}); - else if (mousePosition.x > screenWidth - screenHeight/3) SetMousePosition((Vector2) { screenHeight/3, mousePosition.y}); - else if (mousePosition.y > screenHeight - screenHeight/3) SetMousePosition((Vector2){ mousePosition.x, screenHeight/3}); - else + if (mousePosition.x < screenHeight/3) SetMousePosition((Vector2){ screenWidth - screenHeight/3, mousePosition.y}); + else if (mousePosition.y < screenHeight/3) SetMousePosition((Vector2){ mousePosition.x, screenHeight - screenHeight/3}); + else if (mousePosition.x > screenWidth - screenHeight/3) SetMousePosition((Vector2) { screenHeight/3, mousePosition.y}); + else if (mousePosition.y > screenHeight - screenHeight/3) SetMousePosition((Vector2){ mousePosition.x, screenHeight/3}); + else + { + mousePositionDelta.x = mousePosition.x - previousMousePosition.x; + mousePositionDelta.y = mousePosition.y - previousMousePosition.y; + } + } + else // CAMERA_FREE, CAMERA_ORBITAL { - cameraMouseVariation.x = mousePosition.x - cameraMousePosition.x; - cameraMouseVariation.y = mousePosition.y - cameraMousePosition.y; + ShowCursor(); + + mousePositionDelta.x = mousePosition.x - previousMousePosition.x; + mousePositionDelta.y = mousePosition.y - previousMousePosition.y; } - } - else - { - ShowCursor(); - cameraMouseVariation.x = mousePosition.x - cameraMousePosition.x; - cameraMouseVariation.y = mousePosition.y - cameraMousePosition.y; + // NOTE: We GetMousePosition() again because it can be modified by a previous SetMousePosition() call + // If using directly mousePosition variable we have problems on CAMERA_FIRST_PERSON and CAMERA_THIRD_PERSON + previousMousePosition = GetMousePosition(); } - // NOTE: We GetMousePosition() again because it can be modified by a previous SetMousePosition() call - // If using directly mousePosition variable we have problems on CAMERA_FIRST_PERSON and CAMERA_THIRD_PERSON - cameraMousePosition = GetMousePosition(); - // Support for multiple automatic camera modes switch (cameraMode) { @@ -316,48 +315,48 @@ void UpdateCamera(Camera *camera) // Camera zoom if ((cameraTargetDistance < CAMERA_FREE_DISTANCE_MAX_CLAMP) && (mouseWheelMove < 0)) { - cameraTargetDistance -= (mouseWheelMove*CAMERA_SCROLL_SENSITIVITY); + cameraTargetDistance -= (mouseWheelMove*CAMERA_MOUSE_SCROLL_SENSITIVITY); if (cameraTargetDistance > CAMERA_FREE_DISTANCE_MAX_CLAMP) cameraTargetDistance = CAMERA_FREE_DISTANCE_MAX_CLAMP; } // Camera looking down 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_SCROLL_SENSITIVITY/cameraTargetDistance; - camera->target.y += mouseWheelMove*(camera->target.y - camera->position.y)*CAMERA_SCROLL_SENSITIVITY/cameraTargetDistance; - camera->target.z += mouseWheelMove*(camera->target.z - camera->position.z)*CAMERA_SCROLL_SENSITIVITY/cameraTargetDistance; + camera->target.x += mouseWheelMove*(camera->target.x - camera->position.x)*CAMERA_MOUSE_SCROLL_SENSITIVITY/cameraTargetDistance; + camera->target.y += mouseWheelMove*(camera->target.y - camera->position.y)*CAMERA_MOUSE_SCROLL_SENSITIVITY/cameraTargetDistance; + camera->target.z += mouseWheelMove*(camera->target.z - camera->position.z)*CAMERA_MOUSE_SCROLL_SENSITIVITY/cameraTargetDistance; } else if ((camera->position.y > camera->target.y) && (camera->target.y >= 0)) { - camera->target.x += mouseWheelMove*(camera->target.x - camera->position.x)*CAMERA_SCROLL_SENSITIVITY/cameraTargetDistance; - camera->target.y += mouseWheelMove*(camera->target.y - camera->position.y)*CAMERA_SCROLL_SENSITIVITY/cameraTargetDistance; - camera->target.z += mouseWheelMove*(camera->target.z - camera->position.z)*CAMERA_SCROLL_SENSITIVITY/cameraTargetDistance; + camera->target.x += mouseWheelMove*(camera->target.x - camera->position.x)*CAMERA_MOUSE_SCROLL_SENSITIVITY/cameraTargetDistance; + camera->target.y += mouseWheelMove*(camera->target.y - camera->position.y)*CAMERA_MOUSE_SCROLL_SENSITIVITY/cameraTargetDistance; + camera->target.z += mouseWheelMove*(camera->target.z - camera->position.z)*CAMERA_MOUSE_SCROLL_SENSITIVITY/cameraTargetDistance; // if (camera->target.y < 0) camera->target.y = -0.001; } else if ((camera->position.y > camera->target.y) && (camera->target.y < 0) && (mouseWheelMove > 0)) { - cameraTargetDistance -= (mouseWheelMove*CAMERA_SCROLL_SENSITIVITY); + cameraTargetDistance -= (mouseWheelMove*CAMERA_MOUSE_SCROLL_SENSITIVITY); if (cameraTargetDistance < CAMERA_FREE_DISTANCE_MIN_CLAMP) cameraTargetDistance = CAMERA_FREE_DISTANCE_MIN_CLAMP; } // Camera looking up 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_SCROLL_SENSITIVITY/cameraTargetDistance; - camera->target.y += mouseWheelMove*(camera->target.y - camera->position.y)*CAMERA_SCROLL_SENSITIVITY/cameraTargetDistance; - camera->target.z += mouseWheelMove*(camera->target.z - camera->position.z)*CAMERA_SCROLL_SENSITIVITY/cameraTargetDistance; + camera->target.x += mouseWheelMove*(camera->target.x - camera->position.x)*CAMERA_MOUSE_SCROLL_SENSITIVITY/cameraTargetDistance; + camera->target.y += mouseWheelMove*(camera->target.y - camera->position.y)*CAMERA_MOUSE_SCROLL_SENSITIVITY/cameraTargetDistance; + camera->target.z += mouseWheelMove*(camera->target.z - camera->position.z)*CAMERA_MOUSE_SCROLL_SENSITIVITY/cameraTargetDistance; } else if ((camera->position.y < camera->target.y) && (camera->target.y <= 0)) { - camera->target.x += mouseWheelMove*(camera->target.x - camera->position.x)*CAMERA_SCROLL_SENSITIVITY/cameraTargetDistance; - camera->target.y += mouseWheelMove*(camera->target.y - camera->position.y)*CAMERA_SCROLL_SENSITIVITY/cameraTargetDistance; - camera->target.z += mouseWheelMove*(camera->target.z - camera->position.z)*CAMERA_SCROLL_SENSITIVITY/cameraTargetDistance; + camera->target.x += mouseWheelMove*(camera->target.x - camera->position.x)*CAMERA_MOUSE_SCROLL_SENSITIVITY/cameraTargetDistance; + camera->target.y += mouseWheelMove*(camera->target.y - camera->position.y)*CAMERA_MOUSE_SCROLL_SENSITIVITY/cameraTargetDistance; + camera->target.z += mouseWheelMove*(camera->target.z - camera->position.z)*CAMERA_MOUSE_SCROLL_SENSITIVITY/cameraTargetDistance; // if (camera->target.y > 0) camera->target.y = 0.001; } else if ((camera->position.y < camera->target.y) && (camera->target.y > 0) && (mouseWheelMove > 0)) { - cameraTargetDistance -= (mouseWheelMove*CAMERA_SCROLL_SENSITIVITY); + cameraTargetDistance -= (mouseWheelMove*CAMERA_MOUSE_SCROLL_SENSITIVITY); if (cameraTargetDistance < CAMERA_FREE_DISTANCE_MIN_CLAMP) cameraTargetDistance = CAMERA_FREE_DISTANCE_MIN_CLAMP; } @@ -367,15 +366,15 @@ void UpdateCamera(Camera *camera) if (IsKeyDown(cameraSmoothZoomControlKey)) { // Camera smooth zoom - if (panKey) cameraTargetDistance += (cameraMouseVariation.y*CAMERA_FREE_SMOOTH_ZOOM_SENSITIVITY); + if (panKey) cameraTargetDistance += (mousePositionDelta.y*CAMERA_FREE_SMOOTH_ZOOM_SENSITIVITY); } // Camera orientation calculation else if (panKey) { // Camera orientation calculation // Get the mouse sensitivity - cameraAngle.x += cameraMouseVariation.x*-CAMERA_FREE_MOUSE_SENSITIVITY; - cameraAngle.y += cameraMouseVariation.y*-CAMERA_FREE_MOUSE_SENSITIVITY; + cameraAngle.x += mousePositionDelta.x*-CAMERA_FREE_MOUSE_SENSITIVITY; + cameraAngle.y += mousePositionDelta.y*-CAMERA_FREE_MOUSE_SENSITIVITY; // Angle clamp if (cameraAngle.y > CAMERA_FREE_MIN_CLAMP*DEG2RAD) cameraAngle.y = CAMERA_FREE_MIN_CLAMP*DEG2RAD; @@ -385,9 +384,9 @@ void UpdateCamera(Camera *camera) // Paning else if (panKey) { - camera->target.x += ((cameraMouseVariation.x*-CAMERA_FREE_MOUSE_SENSITIVITY)*cos(cameraAngle.x) + (cameraMouseVariation.y*CAMERA_FREE_MOUSE_SENSITIVITY)*sin(cameraAngle.x)*sin(cameraAngle.y))*(cameraTargetDistance/CAMERA_FREE_PANNING_DIVIDER); - camera->target.y += ((cameraMouseVariation.y*CAMERA_FREE_MOUSE_SENSITIVITY)*cos(cameraAngle.y))*(cameraTargetDistance/CAMERA_FREE_PANNING_DIVIDER); - camera->target.z += ((cameraMouseVariation.x*CAMERA_FREE_MOUSE_SENSITIVITY)*sin(cameraAngle.x) + (cameraMouseVariation.y*CAMERA_FREE_MOUSE_SENSITIVITY)*cos(cameraAngle.x)*sin(cameraAngle.y))*(cameraTargetDistance/CAMERA_FREE_PANNING_DIVIDER); + camera->target.x += ((mousePositionDelta.x*-CAMERA_FREE_MOUSE_SENSITIVITY)*cos(cameraAngle.x) + (mousePositionDelta.y*CAMERA_FREE_MOUSE_SENSITIVITY)*sin(cameraAngle.x)*sin(cameraAngle.y))*(cameraTargetDistance/CAMERA_FREE_PANNING_DIVIDER); + camera->target.y += ((mousePositionDelta.y*CAMERA_FREE_MOUSE_SENSITIVITY)*cos(cameraAngle.y))*(cameraTargetDistance/CAMERA_FREE_PANNING_DIVIDER); + camera->target.z += ((mousePositionDelta.x*CAMERA_FREE_MOUSE_SENSITIVITY)*sin(cameraAngle.x) + (mousePositionDelta.y*CAMERA_FREE_MOUSE_SENSITIVITY)*cos(cameraAngle.x)*sin(cameraAngle.y))*(cameraTargetDistance/CAMERA_FREE_PANNING_DIVIDER); } // Focus to center @@ -396,10 +395,8 @@ void UpdateCamera(Camera *camera) // Camera position update camera->position.x = sin(cameraAngle.x)*cameraTargetDistance*cos(cameraAngle.y) + camera->target.x; - if (cameraAngle.y <= 0.0f) camera->position.y = sin(cameraAngle.y)*cameraTargetDistance*sin(cameraAngle.y) + camera->target.y; else camera->position.y = -sin(cameraAngle.y)*cameraTargetDistance*sin(cameraAngle.y) + camera->target.y; - camera->position.z = cos(cameraAngle.x)*cameraTargetDistance*cos(cameraAngle.y) + camera->target.z; } break; @@ -408,7 +405,7 @@ void UpdateCamera(Camera *camera) cameraAngle.x += CAMERA_ORBITAL_SPEED; // Camera zoom - cameraTargetDistance -= (mouseWheelMove*CAMERA_SCROLL_SENSITIVITY); + cameraTargetDistance -= (mouseWheelMove*CAMERA_MOUSE_SCROLL_SENSITIVITY); // Camera distance clamp if (cameraTargetDistance < CAMERA_THIRD_PERSON_DISTANCE_CLAMP) cameraTargetDistance = CAMERA_THIRD_PERSON_DISTANCE_CLAMP; @@ -417,19 +414,20 @@ void UpdateCamera(Camera *camera) if (IsKeyDown('Z')) camera->target = (Vector3){ 0.0f, 0.0f, 0.0f }; // Camera position update + // TODO: It seems camera->position is not correctly updated or some rounding issue makes the camera move straight to camera->target... camera->position.x = sin(cameraAngle.x)*cameraTargetDistance*cos(cameraAngle.y) + camera->target.x; - if (cameraAngle.y <= 0.0f) camera->position.y = sin(cameraAngle.y)*cameraTargetDistance*sin(cameraAngle.y) + camera->target.y; else camera->position.y = -sin(cameraAngle.y)*cameraTargetDistance*sin(cameraAngle.y) + camera->target.y; - camera->position.z = cos(cameraAngle.x)*cameraTargetDistance*cos(cameraAngle.y) + camera->target.z; } break; case CAMERA_FIRST_PERSON: case CAMERA_THIRD_PERSON: { - bool isMoving = false; + bool isMoving = false; // TODO: Really required for swinging? + // TODO: Get movement direction value [-1, 0, 1] in XZ and just multiply + // Keyboard inputs if (IsKeyDown(cameraMoveControl[MOVE_FRONT])) { @@ -469,15 +467,15 @@ void UpdateCamera(Camera *camera) if (cameraMode == CAMERA_THIRD_PERSON) { // Camera orientation calculation - cameraAngle.x += cameraMouseVariation.x*-cameraMouseSensitivity; - cameraAngle.y += cameraMouseVariation.y*-cameraMouseSensitivity; + 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_SCROLL_SENSITIVITY); + cameraTargetDistance -= (mouseWheelMove*CAMERA_MOUSE_SCROLL_SENSITIVITY); // Camera distance clamp if (cameraTargetDistance < CAMERA_THIRD_PERSON_DISTANCE_CLAMP) cameraTargetDistance = CAMERA_THIRD_PERSON_DISTANCE_CLAMP; @@ -489,19 +487,17 @@ void UpdateCamera(Camera *camera) // Camera position update camera->position.x = sin(cameraAngle.x)*cameraTargetDistance*cos(cameraAngle.y) + camera->target.x; - if (cameraAngle.y <= 0.0f) camera->position.y = sin(cameraAngle.y)*cameraTargetDistance*sin(cameraAngle.y) + camera->target.y; else camera->position.y = -sin(cameraAngle.y)*cameraTargetDistance*sin(cameraAngle.y) + camera->target.y; - camera->position.z = cos(cameraAngle.x)*cameraTargetDistance*cos(cameraAngle.y) + camera->target.z; } else // CAMERA_FIRST_PERSON { - if (isMoving) cameraMoveCounter++; + if (isMoving) swingCounter++; // Camera orientation calculation - cameraAngle.x += (cameraMouseVariation.x*-cameraMouseSensitivity); - cameraAngle.y += (cameraMouseVariation.y*-cameraMouseSensitivity); + cameraAngle.x += (mousePositionDelta.x*-CAMERA_MOUSE_MOVE_SENSITIVITY); + cameraAngle.y += (mousePositionDelta.y*-CAMERA_MOUSE_MOVE_SENSITIVITY); // Angle clamp if (cameraAngle.y > CAMERA_FIRST_PERSON_MIN_CLAMP*DEG2RAD) cameraAngle.y = CAMERA_FIRST_PERSON_MIN_CLAMP*DEG2RAD; @@ -514,67 +510,27 @@ void UpdateCamera(Camera *camera) // Camera position update //camera->position.y = (playerPosition.y + PLAYER_HEIGHT*CAMERA_FIRST_PERSON_HEIGHT_RELATIVE_EYES_POSITION) - // - sin(cameraMoveCounter/CAMERA_FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER)/CAMERA_FIRST_PERSON_STEP_DIVIDER; + // - sin(swingCounter/CAMERA_FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER)/CAMERA_FIRST_PERSON_STEP_DIVIDER; // TODO: Review limits, avoid moving under the ground (y = 0.0f) and over the 'eyes position', weird movement (rounding issues...) - camera->position.y -= sin(cameraMoveCounter/CAMERA_FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER)/CAMERA_FIRST_PERSON_STEP_DIVIDER; + camera->position.y -= sin(swingCounter/CAMERA_FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER)/CAMERA_FIRST_PERSON_STEP_DIVIDER; - camera->up.x = sin(cameraMoveCounter/(CAMERA_FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER*2))/CAMERA_FIRST_PERSON_WAVING_DIVIDER; - camera->up.z = -sin(cameraMoveCounter/(CAMERA_FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER*2))/CAMERA_FIRST_PERSON_WAVING_DIVIDER; + camera->up.x = sin(swingCounter/(CAMERA_FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER*2))/CAMERA_FIRST_PERSON_WAVING_DIVIDER; + camera->up.z = -sin(swingCounter/(CAMERA_FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER*2))/CAMERA_FIRST_PERSON_WAVING_DIVIDER; } } break; default: break; } } -/* -// Set internal camera position -void SetCameraPosition(Vector3 position) -{ - internalCamera.position = position; - - Vector3 v1 = internalCamera.position; - Vector3 v2 = internalCamera.target; - - float dx = v2.x - v1.x; - float dy = v2.y - v1.y; - float dz = v2.z - v1.z; - - cameraTargetDistance = sqrt(dx*dx + dy*dy + dz*dz); -} - -// Set internal camera target -void SetCameraTarget(Vector3 target) -{ - internalCamera.target = target; - - Vector3 v1 = internalCamera.position; - Vector3 v2 = internalCamera.target; - - float dx = v2.x - v1.x; - float dy = v2.y - v1.y; - float dz = v2.z - v1.z; - - cameraTargetDistance = sqrt(dx*dx + dy*dy + dz*dz); -} -*/ // Set camera pan key to combine with mouse movement (free camera) -void SetCameraPanControl(int panKey) -{ - cameraPanControlKey = panKey; -} +void SetCameraPanControl(int panKey) { cameraPanControlKey = panKey; } // Set camera alt key to combine with mouse movement (free camera) -void SetCameraAltControl(int altKey) -{ - cameraAltControlKey = altKey; -} +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 szKey) { cameraSmoothZoomControlKey = szKey; } // Set camera move controls (1st person and 3rd person cameras) void SetCameraMoveControls(int frontKey, int backKey, int leftKey, int rightKey, int upKey, int downKey) @@ -587,10 +543,4 @@ void SetCameraMoveControls(int frontKey, int backKey, int leftKey, int rightKey, cameraMoveControl[MOVE_DOWN] = downKey; } -// Set camera mouse sensitivity (1st person and 3rd person cameras) -void SetCameraMouseSensitivity(float sensitivity) -{ - cameraMouseSensitivity = (sensitivity/10000.0f); -} - #endif // CAMERA_IMPLEMENTATION diff --git a/src/raylib.h b/src/raylib.h index 3c815031..66260ca2 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -559,7 +559,13 @@ typedef enum { } Gestures; // Camera system modes -typedef enum { CAMERA_CUSTOM = 0, CAMERA_FREE, CAMERA_ORBITAL, CAMERA_FIRST_PERSON, CAMERA_THIRD_PERSON } CameraMode; +typedef enum { + CAMERA_CUSTOM = 0, + CAMERA_FREE, + CAMERA_ORBITAL, + CAMERA_FIRST_PERSON, + CAMERA_THIRD_PERSON +} CameraMode; // Head Mounted Display devices typedef enum { @@ -698,22 +704,15 @@ RLAPI float GetGesturePinchAngle(void); // Get gesture pin //------------------------------------------------------------------------------------ // Camera System Functions (Module: camera) //------------------------------------------------------------------------------------ -RLAPI void SetCameraMode(int mode); // Set camera mode (multiple camera modes available) +RLAPI void SetCameraMode(Camera, int mode); // Set camera mode (multiple camera modes available) RLAPI void UpdateCamera(Camera *camera); // Update camera (player position is ignored) -RLAPI void UpdateCameraPlayer(Camera *camera, Vector3 *position); // Update camera and player position (1st person and 3rd person cameras) - -RLAPI void SetCameraPosition(Vector3 position); // Set internal camera position -RLAPI void SetCameraTarget(Vector3 target); // Set internal camera target -RLAPI void SetCameraFovy(float fovy); // Set internal camera field-of-view-y RLAPI void SetCameraPanControl(int panKey); // Set camera pan key to combine with mouse movement (free camera) RLAPI void SetCameraAltControl(int altKey); // Set camera alt key to combine with mouse movement (free camera) RLAPI void SetCameraSmoothZoomControl(int szKey); // Set camera smooth zoom key to combine with mouse (free camera) - RLAPI void SetCameraMoveControls(int frontKey, int backKey, int leftKey, int rightKey, int upKey, int downKey); // Set camera move controls (1st person and 3rd person cameras) -RLAPI void SetCameraMouseSensitivity(float sensitivity); // Set camera mouse sensitivity (1st person and 3rd person cameras) //------------------------------------------------------------------------------------ // Basic Shapes Drawing Functions (Module: shapes) -- cgit v1.2.3 From 978c49472a1cdffa0bf12aba1638806c65e3f8ba Mon Sep 17 00:00:00 2001 From: raysan5 Date: Mon, 26 Sep 2016 19:15:44 +0200 Subject: Working on camera system... --- examples/core_3d_camera_first_person.c | 2 +- examples/core_3d_camera_free.c | 4 +- examples/shaders_model_shader.c | 17 ++- src/camera.h | 215 +++++++++++++-------------------- src/raylib.h | 6 +- 5 files changed, 98 insertions(+), 146 deletions(-) (limited to 'src/camera.h') diff --git a/examples/core_3d_camera_first_person.c b/examples/core_3d_camera_first_person.c index 3675d46a..27ff5135 100644 --- a/examples/core_3d_camera_first_person.c +++ b/examples/core_3d_camera_first_person.c @@ -23,7 +23,7 @@ int main() InitWindow(screenWidth, screenHeight, "raylib [core] example - 3d camera first person"); // Define the camera to look into our 3d world (position, target, up vector) - Camera camera = {{ 4.0f, 2.0f, 4.0f }, { 0.0f, 2.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, 60.0f }; + Camera camera = {{ 4.0f, 2.0f, 4.0f }, { 0.0f, 1.8f, 0.0f }, { 0.0f, 1.0f, 0.0f }, 60.0f }; // Generates some random columns float heights[MAX_COLUMNS]; diff --git a/examples/core_3d_camera_free.c b/examples/core_3d_camera_free.c index 257bb789..c798f225 100644 --- a/examples/core_3d_camera_free.c +++ b/examples/core_3d_camera_free.c @@ -22,7 +22,7 @@ int main() // Define the camera to look into our 3d world Camera camera; - camera.position = (Vector3){ 0.0f, 10.0f, 10.0f }; // Camera position + camera.position = (Vector3){ 10.0f, 10.0f, 10.0f }; // Camera position camera.target = (Vector3){ 0.0f, 0.0f, 0.0f }; // Camera looking at point camera.up = (Vector3){ 0.0f, 1.0f, 0.0f }; // Camera up vector (rotation towards target) camera.fovy = 45.0f; // Camera field-of-view Y @@ -40,6 +40,8 @@ int main() // Update //---------------------------------------------------------------------------------- UpdateCamera(&camera); // Update internal camera and our camera + + if (IsKeyDown('Z')) camera.target = (Vector3){ 0.0f, 0.0f, 0.0f }; //---------------------------------------------------------------------------------- // Draw diff --git a/examples/shaders_model_shader.c b/examples/shaders_model_shader.c index a1e00671..a5516eba 100644 --- a/examples/shaders_model_shader.c +++ b/examples/shaders_model_shader.c @@ -37,25 +37,22 @@ int main() Shader shader = LoadShader("resources/shaders/glsl330/base.vs", "resources/shaders/glsl330/grayscale.fs"); // Load model shader - dwarf.material.shader = shader; // Set shader effect to 3d model - dwarf.material.texDiffuse = texture; // Bind texture to model + dwarf.material.shader = shader; // Set shader effect to 3d model + dwarf.material.texDiffuse = texture; // Bind texture to model - Vector3 position = { 0.0f, 0.0f, 0.0f }; // Set model position + Vector3 position = { 0.0f, 0.0f, 0.0f }; // Set model position - // Setup orbital camera - SetCameraMode(CAMERA_ORBITAL); // Set an orbital camera mode - SetCameraPosition(camera.position); // Set internal camera position to match our camera position - SetCameraTarget(camera.target); // Set internal camera target to match our camera target + SetCameraMode(camera, CAMERA_ORBITAL); // Set an orbital camera mode - SetTargetFPS(60); // Set our game to run at 60 frames-per-second + SetTargetFPS(60); // Set our game to run at 60 frames-per-second //-------------------------------------------------------------------------------------- // Main game loop - while (!WindowShouldClose()) // Detect window close button or ESC key + while (!WindowShouldClose()) // Detect window close button or ESC key { // Update //---------------------------------------------------------------------------------- - UpdateCamera(&camera); // Update internal camera and our camera + UpdateCamera(&camera); // Update internal camera and our camera //---------------------------------------------------------------------------------- // Draw diff --git a/src/camera.h b/src/camera.h index 0c7b5a13..9bf9132b 100644 --- a/src/camera.h +++ b/src/camera.h @@ -11,7 +11,7 @@ * If defined, the library can be used as standalone as a camera system but some * functions must be redefined to manage inputs accordingly. * -* NOTE: Memory footprint of this library is aproximately 112 bytes +* NOTE: Memory footprint of this library is aproximately 52 bytes (global variables) * * Initial design by Marc Palau (2014) * Reviewed by Ramon Santamaria (2015-2016) @@ -91,14 +91,13 @@ extern "C" { // Prevents name mangling of functions //---------------------------------------------------------------------------------- #if defined(CAMERA_STANDALONE) void SetCameraMode(Camera camera, int mode); // Set camera mode (multiple camera modes available) -void UpdateCamera(Camera *camera); // Update camera (player position is ignored) +void UpdateCamera(Camera *camera); // Update camera position for selected mode -// TODO: Do we really need all those functions? 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 leftKey, int rightKey, + int rightKey, int leftKey, int upKey, int downKey); // Set camera move controls (1st person and 3rd person cameras) #endif @@ -138,7 +137,6 @@ void SetCameraMoveControls(int frontKey, int backKey, #define CAMERA_MOUSE_MOVE_SENSITIVITY 0.003f #define CAMERA_MOUSE_SCROLL_SENSITIVITY 1.5f - // FREE_CAMERA #define CAMERA_FREE_MOUSE_SENSITIVITY 0.01f #define CAMERA_FREE_DISTANCE_MIN_CLAMP 0.3f @@ -171,24 +169,21 @@ void SetCameraMoveControls(int frontKey, int backKey, #define CAMERA_THIRD_PERSON_OFFSET (Vector3){ 0.4f, 0.0f, 0.0f } // PLAYER (used by camera) -#define PLAYER_WIDTH 0.4f -#define PLAYER_HEIGHT 0.9f -#define PLAYER_DEPTH 0.4f -#define PLAYER_MOVEMENT_DIVIDER 20.0f +#define PLAYER_MOVEMENT_DIVIDER 20.0f //---------------------------------------------------------------------------------- // Types and Structures Definition //---------------------------------------------------------------------------------- // Camera move modes (first person and third person cameras) -typedef enum { MOVE_FRONT = 0, MOVE_LEFT, MOVE_BACK, MOVE_RIGHT, MOVE_UP, MOVE_DOWN } CameraMove; +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() using camera->target and camera->position -static float cameraTargetDistance = 5.0f; // TODO: Remove! Compute it in UpdateCamera() using camera->target and camera->position +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 int cameraMoveControl[6] = { 'W', 'A', 'S', 'D', 'E', 'Q' }; +static int cameraMoveControl[6] = { 'W', 'S', 'D', 'A', 'E', 'Q' }; static int cameraPanControlKey = 2; // raylib: MOUSE_MIDDLE_BUTTON static int cameraAltControlKey = 342; // raylib: KEY_LEFT_ALT static int cameraSmoothZoomControlKey = 341; // raylib: KEY_LEFT_CONTROL @@ -200,7 +195,7 @@ static int cameraMode = CAMERA_CUSTOM; // Current camera mode //---------------------------------------------------------------------------------- #if defined(CAMERA_STANDALONE) // NOTE: Camera controls depend on some raylib input functions -// TODO: Set your own input functions (used in ProcessCamera()) +// TODO: Set your own input functions (used in UpdateCamera()) static Vector2 GetMousePosition() { return (Vector2){ 0.0f, 0.0f }; } static void SetMousePosition(Vector2 pos) {} static int IsMouseButtonDown(int button) { return 0;} @@ -230,7 +225,18 @@ void SetCameraMode(Camera camera, int mode) float dz = v2.z - v1.z; cameraTargetDistance = sqrt(dx*dx + dy*dy + dz*dz); - cameraAngle.y = -40*DEG2RAD; + + Vector2 distance = { 0.0f, 0.0f }; + distance.x = sqrt(dx*dx + dy*dy); + distance.y = sqrt(dx*dx + dz*dz); + + // TODO: Review cameraAngle calculation + //cameraAngle.x = asin(fabs(dx)/distance.x); + //cameraAngle.y = -asin(fabs(dz)/distance.y); + + // NOTE: Just testing what cameraAngle means + cameraAngle.x = 90.0f*DEG2RAD; // Camera angle in plane XZ (0 aligned with Z, move positive CCW) + cameraAngle.y = -80.0f*DEG2RAD; // Camera angle in plane XY (0 aligned with X, move positive CW) cameraMode = mode; } @@ -240,39 +246,33 @@ void SetCameraMode(Camera camera, int mode) // Mouse: GetMousePosition(), SetMousePosition(), IsMouseButtonDown(), GetMouseWheelMove() // System: GetScreenWidth(), GetScreenHeight(), ShowCursor(), HideCursor() // Keys: IsKeyDown() -// TODO: Consider touch inputs for camera! -// TODO: Port to quaternion-based camera! +// TODO: Port to quaternion-based camera void UpdateCamera(Camera *camera) { static int swingCounter = 0; // Used for 1st person swinging movement static Vector2 previousMousePosition = { 0.0f, 0.0f }; - // TODO: Compute cameraTargetDistance and cameraAngle - // NOTE: If cameraTargetDistance and cameraAngle change, camera->position is accordingly updated - /* - Vector2 cameraAngle = { 0.0f, 0.0f }; - float cameraTargetDistance = 0.0f; - - float dx = camera->target.x - camera->position.x; - float dy = camera->target.y - camera->position.y; - float dz = camera->target.z - camera->position.z; - - cameraTargetDistance = sqrt(dx*dx + dy*dy + dz*dz); - - Vector2 distance = { 0.0f, 0.0f }; - distance.x = sqrt(dx*dx + dy*dy); - distance.y = sqrt(dx*dx + dz*dz); - - cameraAngle.x = asin(fabs(dx)/distance.x); - cameraAngle.y = asin(fabs(dz)/distance.y); - */ + // TODO: Compute cameraTargetDistance and cameraAngle here // Mouse movement detection Vector2 mousePositionDelta = { 0.0f, 0.0f }; Vector2 mousePosition = GetMousePosition(); int mouseWheelMove = GetMouseWheelMove(); - int panKey = IsMouseButtonDown(cameraPanControlKey); // bool value + // 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) { // Get screen size @@ -284,10 +284,10 @@ void UpdateCamera(Camera *camera) { HideCursor(); - if (mousePosition.x < screenHeight/3) SetMousePosition((Vector2){ screenWidth - screenHeight/3, mousePosition.y}); - else if (mousePosition.y < screenHeight/3) SetMousePosition((Vector2){ mousePosition.x, screenHeight - screenHeight/3}); - else if (mousePosition.x > screenWidth - screenHeight/3) SetMousePosition((Vector2) { screenHeight/3, mousePosition.y}); - else if (mousePosition.y > screenHeight - screenHeight/3) SetMousePosition((Vector2){ mousePosition.x, screenHeight/3}); + if (mousePosition.x < screenHeight/3) SetMousePosition((Vector2){ screenWidth - screenHeight/3, mousePosition.y }); + else if (mousePosition.y < screenHeight/3) SetMousePosition((Vector2){ mousePosition.x, screenHeight - screenHeight/3 }); + else if (mousePosition.x > (screenWidth - screenHeight/3)) SetMousePosition((Vector2){ screenHeight/3, mousePosition.y }); + else if (mousePosition.y > (screenHeight - screenHeight/3)) SetMousePosition((Vector2){ mousePosition.x, screenHeight/3 }); else { mousePositionDelta.x = mousePosition.x - previousMousePosition.x; @@ -360,19 +360,15 @@ void UpdateCamera(Camera *camera) if (cameraTargetDistance < CAMERA_FREE_DISTANCE_MIN_CLAMP) cameraTargetDistance = CAMERA_FREE_DISTANCE_MIN_CLAMP; } - // Inputs - if (IsKeyDown(cameraAltControlKey)) + // Input keys checks + if (altKey) { - if (IsKeyDown(cameraSmoothZoomControlKey)) + if (szoomKey) // Camera smooth zoom { - // Camera smooth zoom if (panKey) cameraTargetDistance += (mousePositionDelta.y*CAMERA_FREE_SMOOTH_ZOOM_SENSITIVITY); } - // Camera orientation calculation else if (panKey) { - // Camera orientation calculation - // Get the mouse sensitivity cameraAngle.x += mousePositionDelta.x*-CAMERA_FREE_MOUSE_SENSITIVITY; cameraAngle.y += mousePositionDelta.y*-CAMERA_FREE_MOUSE_SENSITIVITY; @@ -381,95 +377,50 @@ void UpdateCamera(Camera *camera) else if (cameraAngle.y < CAMERA_FREE_MAX_CLAMP*DEG2RAD) cameraAngle.y = CAMERA_FREE_MAX_CLAMP*DEG2RAD; } } - // Paning - else if (panKey) + else if (panKey) // Paning { camera->target.x += ((mousePositionDelta.x*-CAMERA_FREE_MOUSE_SENSITIVITY)*cos(cameraAngle.x) + (mousePositionDelta.y*CAMERA_FREE_MOUSE_SENSITIVITY)*sin(cameraAngle.x)*sin(cameraAngle.y))*(cameraTargetDistance/CAMERA_FREE_PANNING_DIVIDER); camera->target.y += ((mousePositionDelta.y*CAMERA_FREE_MOUSE_SENSITIVITY)*cos(cameraAngle.y))*(cameraTargetDistance/CAMERA_FREE_PANNING_DIVIDER); camera->target.z += ((mousePositionDelta.x*CAMERA_FREE_MOUSE_SENSITIVITY)*sin(cameraAngle.x) + (mousePositionDelta.y*CAMERA_FREE_MOUSE_SENSITIVITY)*cos(cameraAngle.x)*sin(cameraAngle.y))*(cameraTargetDistance/CAMERA_FREE_PANNING_DIVIDER); } - // Focus to center - // TODO: Move this function out of this module? - if (IsKeyDown('Z')) camera->target = (Vector3){ 0.0f, 0.0f, 0.0f }; - - // Camera position update - camera->position.x = sin(cameraAngle.x)*cameraTargetDistance*cos(cameraAngle.y) + camera->target.x; - if (cameraAngle.y <= 0.0f) camera->position.y = sin(cameraAngle.y)*cameraTargetDistance*sin(cameraAngle.y) + camera->target.y; - else camera->position.y = -sin(cameraAngle.y)*cameraTargetDistance*sin(cameraAngle.y) + camera->target.y; - camera->position.z = cos(cameraAngle.x)*cameraTargetDistance*cos(cameraAngle.y) + camera->target.z; - } break; case CAMERA_ORBITAL: { - cameraAngle.x += CAMERA_ORBITAL_SPEED; - - // Camera zoom - cameraTargetDistance -= (mouseWheelMove*CAMERA_MOUSE_SCROLL_SENSITIVITY); + 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; - - // Focus to center - if (IsKeyDown('Z')) camera->target = (Vector3){ 0.0f, 0.0f, 0.0f }; - - // Camera position update - // TODO: It seems camera->position is not correctly updated or some rounding issue makes the camera move straight to camera->target... - camera->position.x = sin(cameraAngle.x)*cameraTargetDistance*cos(cameraAngle.y) + camera->target.x; - if (cameraAngle.y <= 0.0f) camera->position.y = sin(cameraAngle.y)*cameraTargetDistance*sin(cameraAngle.y) + camera->target.y; - else camera->position.y = -sin(cameraAngle.y)*cameraTargetDistance*sin(cameraAngle.y) + camera->target.y; - camera->position.z = cos(cameraAngle.x)*cameraTargetDistance*cos(cameraAngle.y) + camera->target.z; - + } break; case CAMERA_FIRST_PERSON: case CAMERA_THIRD_PERSON: { + camera->position.x += (sin(cameraAngle.x)*direction[MOVE_BACK] - + sin(cameraAngle.x)*direction[MOVE_FRONT] - + cos(cameraAngle.x)*direction[MOVE_LEFT] + + cos(cameraAngle.x)*direction[MOVE_RIGHT])/PLAYER_MOVEMENT_DIVIDER; + + camera->position.y += (sin(cameraAngle.y)*direction[MOVE_FRONT] - + sin(cameraAngle.y)*direction[MOVE_BACK] + + 1.0f*direction[MOVE_UP] - 1.0f*direction[MOVE_DOWN])/PLAYER_MOVEMENT_DIVIDER; + + camera->position.z += (cos(cameraAngle.x)*direction[MOVE_BACK] - + cos(cameraAngle.x)*direction[MOVE_FRONT] + + sin(cameraAngle.x)*direction[MOVE_LEFT] - + sin(cameraAngle.x)*direction[MOVE_RIGHT])/PLAYER_MOVEMENT_DIVIDER; + bool isMoving = false; // TODO: Really required for swinging? - // TODO: Get movement direction value [-1, 0, 1] in XZ and just multiply + //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); - // Keyboard inputs - if (IsKeyDown(cameraMoveControl[MOVE_FRONT])) - { - camera->position.x -= sin(cameraAngle.x)/PLAYER_MOVEMENT_DIVIDER; - camera->position.y += sin(cameraAngle.y)/PLAYER_MOVEMENT_DIVIDER; - camera->position.z -= cos(cameraAngle.x)/PLAYER_MOVEMENT_DIVIDER; - - isMoving = true; - } - else if (IsKeyDown(cameraMoveControl[MOVE_BACK])) - { - camera->position.x += sin(cameraAngle.x)/PLAYER_MOVEMENT_DIVIDER; - camera->position.y -= sin(cameraAngle.y)/PLAYER_MOVEMENT_DIVIDER; - camera->position.z += cos(cameraAngle.x)/PLAYER_MOVEMENT_DIVIDER; - - isMoving = true; - } - - if (IsKeyDown(cameraMoveControl[MOVE_LEFT])) - { - camera->position.x -= cos(cameraAngle.x)/PLAYER_MOVEMENT_DIVIDER; - camera->position.z += sin(cameraAngle.x)/PLAYER_MOVEMENT_DIVIDER; - - isMoving = true; - } - else if (IsKeyDown(cameraMoveControl[MOVE_RIGHT])) - { - camera->position.x += cos(cameraAngle.x)/PLAYER_MOVEMENT_DIVIDER; - camera->position.z -= sin(cameraAngle.x)/PLAYER_MOVEMENT_DIVIDER; - - isMoving = true; - } - - if (IsKeyDown(cameraMoveControl[MOVE_UP])) camera->position.y += 1.0f/PLAYER_MOVEMENT_DIVIDER; - else if (IsKeyDown(cameraMoveControl[MOVE_DOWN])) camera->position.y -= 1.0f/PLAYER_MOVEMENT_DIVIDER; - if (cameraMode == CAMERA_THIRD_PERSON) { - // 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; @@ -482,23 +433,11 @@ void UpdateCamera(Camera *camera) // Camera is always looking at player camera->target.x = camera->position.x + CAMERA_THIRD_PERSON_OFFSET.x*cos(cameraAngle.x) + CAMERA_THIRD_PERSON_OFFSET.z*sin(cameraAngle.x); - camera->target.y = camera->position.y + PLAYER_HEIGHT*CAMERA_FIRST_PERSON_HEIGHT_RELATIVE_EYES_POSITION + CAMERA_THIRD_PERSON_OFFSET.y; + camera->target.y = camera->position.y + CAMERA_FIRST_PERSON_HEIGHT_RELATIVE_EYES_POSITION + CAMERA_THIRD_PERSON_OFFSET.y; camera->target.z = camera->position.z + CAMERA_THIRD_PERSON_OFFSET.z*sin(cameraAngle.x) - CAMERA_THIRD_PERSON_OFFSET.x*sin(cameraAngle.x); - - // Camera position update - camera->position.x = sin(cameraAngle.x)*cameraTargetDistance*cos(cameraAngle.y) + camera->target.x; - if (cameraAngle.y <= 0.0f) camera->position.y = sin(cameraAngle.y)*cameraTargetDistance*sin(cameraAngle.y) + camera->target.y; - else camera->position.y = -sin(cameraAngle.y)*cameraTargetDistance*sin(cameraAngle.y) + camera->target.y; - camera->position.z = cos(cameraAngle.x)*cameraTargetDistance*cos(cameraAngle.y) + camera->target.z; } else // CAMERA_FIRST_PERSON { - if (isMoving) swingCounter++; - - // 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_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; @@ -507,6 +446,8 @@ void UpdateCamera(Camera *camera) camera->target.x = camera->position.x - sin(cameraAngle.x)*CAMERA_FIRST_PERSON_FOCUS_DISTANCE; camera->target.y = camera->position.y + sin(cameraAngle.y)*CAMERA_FIRST_PERSON_FOCUS_DISTANCE; camera->target.z = camera->position.z - cos(cameraAngle.x)*CAMERA_FIRST_PERSON_FOCUS_DISTANCE; + + if (isMoving) swingCounter++; // Camera position update //camera->position.y = (playerPosition.y + PLAYER_HEIGHT*CAMERA_FIRST_PERSON_HEIGHT_RELATIVE_EYES_POSITION) @@ -521,6 +462,18 @@ void UpdateCamera(Camera *camera) } 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 = sin(cameraAngle.x)*cameraTargetDistance*cos(cameraAngle.y) + camera->target.x; + if (cameraAngle.y <= 0.0f) camera->position.y = sin(cameraAngle.y)*cameraTargetDistance*sin(cameraAngle.y) + camera->target.y; + else camera->position.y = -sin(cameraAngle.y)*cameraTargetDistance*sin(cameraAngle.y) + camera->target.y; + camera->position.z = cos(cameraAngle.x)*cameraTargetDistance*cos(cameraAngle.y) + camera->target.z; + } } // Set camera pan key to combine with mouse movement (free camera) @@ -533,12 +486,12 @@ void SetCameraAltControl(int altKey) { cameraAltControlKey = altKey; } void SetCameraSmoothZoomControl(int szKey) { cameraSmoothZoomControlKey = szKey; } // Set camera move controls (1st person and 3rd person cameras) -void SetCameraMoveControls(int frontKey, int backKey, int leftKey, int rightKey, int upKey, int downKey) +void SetCameraMoveControls(int frontKey, int backKey, int rightKey, int leftKey, int upKey, int downKey) { cameraMoveControl[MOVE_FRONT] = frontKey; - cameraMoveControl[MOVE_LEFT] = leftKey; cameraMoveControl[MOVE_BACK] = backKey; cameraMoveControl[MOVE_RIGHT] = rightKey; + cameraMoveControl[MOVE_LEFT] = leftKey; cameraMoveControl[MOVE_UP] = upKey; cameraMoveControl[MOVE_DOWN] = downKey; } diff --git a/src/raylib.h b/src/raylib.h index 66260ca2..35319d6a 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -705,14 +705,14 @@ RLAPI float GetGesturePinchAngle(void); // Get gesture pin // Camera System Functions (Module: camera) //------------------------------------------------------------------------------------ RLAPI void SetCameraMode(Camera, int mode); // Set camera mode (multiple camera modes available) -RLAPI void UpdateCamera(Camera *camera); // Update camera (player position is ignored) +RLAPI void UpdateCamera(Camera *camera); // Update camera position for selected mode RLAPI void SetCameraPanControl(int panKey); // Set camera pan key to combine with mouse movement (free camera) RLAPI void SetCameraAltControl(int altKey); // Set camera alt key to combine with mouse movement (free camera) RLAPI void SetCameraSmoothZoomControl(int szKey); // Set camera smooth zoom key to combine with mouse (free camera) RLAPI void SetCameraMoveControls(int frontKey, int backKey, - int leftKey, int rightKey, - int upKey, int downKey); // Set camera move controls (1st person and 3rd person cameras) + int rightKey, int leftKey, + int upKey, int downKey); // Set camera move controls (1st person and 3rd person cameras) //------------------------------------------------------------------------------------ // Basic Shapes Drawing Functions (Module: shapes) -- cgit v1.2.3 From 637d3195ec705e7f014395ad20cd574bc7fa015e Mon Sep 17 00:00:00 2001 From: raysan5 Date: Mon, 3 Oct 2016 13:27:22 +0200 Subject: More review on camera system... Sincerely, don't like it... it should be ported to quaternions... the way it manages cameraTargetDistange and cameraAngle is confusing... --- src/camera.h | 80 +++++++++++++++++++++++++++++++----------------------------- 1 file changed, 42 insertions(+), 38 deletions(-) (limited to 'src/camera.h') diff --git a/src/camera.h b/src/camera.h index 9bf9132b..33220390 100644 --- a/src/camera.h +++ b/src/camera.h @@ -147,7 +147,7 @@ void SetCameraMoveControls(int frontKey, int backKey, #define CAMERA_FREE_PANNING_DIVIDER 5.1f // ORBITAL_CAMERA -#define CAMERA_ORBITAL_SPEED 0.01f +#define CAMERA_ORBITAL_SPEED 0.01f // Radians per frame // FIRST_PERSON //#define CAMERA_FIRST_PERSON_MOUSE_SENSITIVITY 0.003f @@ -159,8 +159,6 @@ void SetCameraMoveControls(int frontKey, int backKey, #define CAMERA_FIRST_PERSON_STEP_DIVIDER 30.0f #define CAMERA_FIRST_PERSON_WAVING_DIVIDER 200.0f -#define CAMERA_FIRST_PERSON_HEIGHT_RELATIVE_EYES_POSITION 0.85f - // THIRD_PERSON //#define CAMERA_THIRD_PERSON_MOUSE_SENSITIVITY 0.003f #define CAMERA_THIRD_PERSON_DISTANCE_CLAMP 1.2f @@ -169,7 +167,7 @@ void SetCameraMoveControls(int frontKey, int backKey, #define CAMERA_THIRD_PERSON_OFFSET (Vector3){ 0.4f, 0.0f, 0.0f } // PLAYER (used by camera) -#define PLAYER_MOVEMENT_DIVIDER 20.0f +#define PLAYER_MOVEMENT_SENSITIVITY 20.0f //---------------------------------------------------------------------------------- // Types and Structures Definition @@ -182,6 +180,7 @@ typedef enum { MOVE_FRONT = 0, MOVE_BACK, MOVE_RIGHT, MOVE_LEFT, MOVE_UP, MOVE_D //---------------------------------------------------------------------------------- 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 int cameraMoveControl[6] = { 'W', 'S', 'D', 'A', 'E', 'Q' }; static int cameraPanControlKey = 2; // raylib: MOUSE_MIDDLE_BUTTON @@ -227,16 +226,18 @@ void SetCameraMode(Camera camera, int mode) cameraTargetDistance = sqrt(dx*dx + dy*dy + dz*dz); Vector2 distance = { 0.0f, 0.0f }; - distance.x = sqrt(dx*dx + dy*dy); - distance.y = sqrt(dx*dx + dz*dz); + distance.x = sqrt(dx*dx + dz*dz); + distance.y = sqrt(dx*dx + dy*dy); - // TODO: Review cameraAngle calculation - //cameraAngle.x = asin(fabs(dx)/distance.x); - //cameraAngle.y = -asin(fabs(dz)/distance.y); + // Camera angle calculation + cameraAngle.x = asin(fabs(dx)/distance.x); // Camera angle in plane XZ (0 aligned with Z, move positive CCW) + cameraAngle.y = -asin(fabs(dy)/distance.y); // Camera angle in plane XY (0 aligned with X, move positive CW) // NOTE: Just testing what cameraAngle means - cameraAngle.x = 90.0f*DEG2RAD; // Camera angle in plane XZ (0 aligned with Z, move positive CCW) - cameraAngle.y = -80.0f*DEG2RAD; // Camera angle in plane XY (0 aligned with X, move positive CW) + //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) + + playerEyesPosition = camera.position.y; cameraMode = mode; } @@ -361,28 +362,34 @@ void UpdateCamera(Camera *camera) } // Input keys checks - if (altKey) + if (panKey) { - if (szoomKey) // Camera smooth zoom + if (altKey) // Alternative key behaviour { - if (panKey) cameraTargetDistance += (mousePositionDelta.y*CAMERA_FREE_SMOOTH_ZOOM_SENSITIVITY); + if (szoomKey) + { + // Camera smooth zoom + cameraTargetDistance += (mousePositionDelta.y*CAMERA_FREE_SMOOTH_ZOOM_SENSITIVITY); + } + else + { + // Camera rotation + cameraAngle.x += mousePositionDelta.x*-CAMERA_FREE_MOUSE_SENSITIVITY; + cameraAngle.y += mousePositionDelta.y*-CAMERA_FREE_MOUSE_SENSITIVITY; + + // Angle clamp + if (cameraAngle.y > CAMERA_FREE_MIN_CLAMP*DEG2RAD) cameraAngle.y = CAMERA_FREE_MIN_CLAMP*DEG2RAD; + else if (cameraAngle.y < CAMERA_FREE_MAX_CLAMP*DEG2RAD) cameraAngle.y = CAMERA_FREE_MAX_CLAMP*DEG2RAD; + } } - else if (panKey) + else { - cameraAngle.x += mousePositionDelta.x*-CAMERA_FREE_MOUSE_SENSITIVITY; - cameraAngle.y += mousePositionDelta.y*-CAMERA_FREE_MOUSE_SENSITIVITY; - - // Angle clamp - if (cameraAngle.y > CAMERA_FREE_MIN_CLAMP*DEG2RAD) cameraAngle.y = CAMERA_FREE_MIN_CLAMP*DEG2RAD; - else if (cameraAngle.y < CAMERA_FREE_MAX_CLAMP*DEG2RAD) cameraAngle.y = CAMERA_FREE_MAX_CLAMP*DEG2RAD; + // Camera panning + camera->target.x += ((mousePositionDelta.x*-CAMERA_FREE_MOUSE_SENSITIVITY)*cos(cameraAngle.x) + (mousePositionDelta.y*CAMERA_FREE_MOUSE_SENSITIVITY)*sin(cameraAngle.x)*sin(cameraAngle.y))*(cameraTargetDistance/CAMERA_FREE_PANNING_DIVIDER); + camera->target.y += ((mousePositionDelta.y*CAMERA_FREE_MOUSE_SENSITIVITY)*cos(cameraAngle.y))*(cameraTargetDistance/CAMERA_FREE_PANNING_DIVIDER); + camera->target.z += ((mousePositionDelta.x*CAMERA_FREE_MOUSE_SENSITIVITY)*sin(cameraAngle.x) + (mousePositionDelta.y*CAMERA_FREE_MOUSE_SENSITIVITY)*cos(cameraAngle.x)*sin(cameraAngle.y))*(cameraTargetDistance/CAMERA_FREE_PANNING_DIVIDER); } } - else if (panKey) // Paning - { - camera->target.x += ((mousePositionDelta.x*-CAMERA_FREE_MOUSE_SENSITIVITY)*cos(cameraAngle.x) + (mousePositionDelta.y*CAMERA_FREE_MOUSE_SENSITIVITY)*sin(cameraAngle.x)*sin(cameraAngle.y))*(cameraTargetDistance/CAMERA_FREE_PANNING_DIVIDER); - camera->target.y += ((mousePositionDelta.y*CAMERA_FREE_MOUSE_SENSITIVITY)*cos(cameraAngle.y))*(cameraTargetDistance/CAMERA_FREE_PANNING_DIVIDER); - camera->target.z += ((mousePositionDelta.x*CAMERA_FREE_MOUSE_SENSITIVITY)*sin(cameraAngle.x) + (mousePositionDelta.y*CAMERA_FREE_MOUSE_SENSITIVITY)*cos(cameraAngle.x)*sin(cameraAngle.y))*(cameraTargetDistance/CAMERA_FREE_PANNING_DIVIDER); - } } break; case CAMERA_ORBITAL: @@ -400,20 +407,20 @@ void UpdateCamera(Camera *camera) camera->position.x += (sin(cameraAngle.x)*direction[MOVE_BACK] - sin(cameraAngle.x)*direction[MOVE_FRONT] - cos(cameraAngle.x)*direction[MOVE_LEFT] + - cos(cameraAngle.x)*direction[MOVE_RIGHT])/PLAYER_MOVEMENT_DIVIDER; + cos(cameraAngle.x)*direction[MOVE_RIGHT])/PLAYER_MOVEMENT_SENSITIVITY; camera->position.y += (sin(cameraAngle.y)*direction[MOVE_FRONT] - sin(cameraAngle.y)*direction[MOVE_BACK] + - 1.0f*direction[MOVE_UP] - 1.0f*direction[MOVE_DOWN])/PLAYER_MOVEMENT_DIVIDER; + 1.0f*direction[MOVE_UP] - 1.0f*direction[MOVE_DOWN])/PLAYER_MOVEMENT_SENSITIVITY; camera->position.z += (cos(cameraAngle.x)*direction[MOVE_BACK] - cos(cameraAngle.x)*direction[MOVE_FRONT] + sin(cameraAngle.x)*direction[MOVE_LEFT] - - sin(cameraAngle.x)*direction[MOVE_RIGHT])/PLAYER_MOVEMENT_DIVIDER; + sin(cameraAngle.x)*direction[MOVE_RIGHT])/PLAYER_MOVEMENT_SENSITIVITY; - bool isMoving = false; // TODO: Really 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 cameraAngle.x += (mousePositionDelta.x*-CAMERA_MOUSE_MOVE_SENSITIVITY); @@ -433,7 +440,7 @@ void UpdateCamera(Camera *camera) // Camera is always looking at player camera->target.x = camera->position.x + CAMERA_THIRD_PERSON_OFFSET.x*cos(cameraAngle.x) + CAMERA_THIRD_PERSON_OFFSET.z*sin(cameraAngle.x); - camera->target.y = camera->position.y + CAMERA_FIRST_PERSON_HEIGHT_RELATIVE_EYES_POSITION + CAMERA_THIRD_PERSON_OFFSET.y; + camera->target.y = camera->position.y + CAMERA_THIRD_PERSON_OFFSET.y; camera->target.z = camera->position.z + CAMERA_THIRD_PERSON_OFFSET.z*sin(cameraAngle.x) - CAMERA_THIRD_PERSON_OFFSET.x*sin(cameraAngle.x); } else // CAMERA_FIRST_PERSON @@ -450,11 +457,8 @@ void UpdateCamera(Camera *camera) if (isMoving) swingCounter++; // Camera position update - //camera->position.y = (playerPosition.y + PLAYER_HEIGHT*CAMERA_FIRST_PERSON_HEIGHT_RELATIVE_EYES_POSITION) - // - sin(swingCounter/CAMERA_FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER)/CAMERA_FIRST_PERSON_STEP_DIVIDER; - - // TODO: Review limits, avoid moving under the ground (y = 0.0f) and over the 'eyes position', weird movement (rounding issues...) - camera->position.y -= sin(swingCounter/CAMERA_FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER)/CAMERA_FIRST_PERSON_STEP_DIVIDER; + // NOTE: On CAMERA_FIRST_PERSON player Y-movement is limited to player 'eyes position' + camera->position.y = playerEyesPosition - sin(swingCounter/CAMERA_FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER)/CAMERA_FIRST_PERSON_STEP_DIVIDER; camera->up.x = sin(swingCounter/(CAMERA_FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER*2))/CAMERA_FIRST_PERSON_WAVING_DIVIDER; camera->up.z = -sin(swingCounter/(CAMERA_FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER*2))/CAMERA_FIRST_PERSON_WAVING_DIVIDER; -- cgit v1.2.3