From d8bd8634ab7d5179cb1481206176af1f8e592e75 Mon Sep 17 00:00:00 2001 From: raysan5 Date: Sat, 5 Mar 2016 13:05:45 +0100 Subject: 3d Camera: Added support for field-of-view Y --- src/camera.h | 1 + 1 file changed, 1 insertion(+) (limited to 'src/camera.h') diff --git a/src/camera.h b/src/camera.h index 9ad09c6f..8d8029af 100644 --- a/src/camera.h +++ b/src/camera.h @@ -81,6 +81,7 @@ void UpdateCameraPlayer(Camera *camera, Vector3 *position); // Update camera and 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 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) -- cgit v1.2.3 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/Makefile | 4 - src/camera.c | 523 ---------------------------------------------------- src/camera.h | 586 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- src/core.c | 3 + 4 files changed, 559 insertions(+), 557 deletions(-) delete mode 100644 src/camera.c (limited to 'src/camera.h') diff --git a/src/Makefile b/src/Makefile index e82c2861..b4eccdb2 100644 --- a/src/Makefile +++ b/src/Makefile @@ -203,10 +203,6 @@ external/stb_vorbis.o: external/stb_vorbis.c external/stb_vorbis.h utils.o : utils.c utils.h $(CC) -c $< $(CFLAGS) $(INCLUDES) -D$(PLATFORM) -# compile camera module -camera.o : camera.c raylib.h - $(CC) -c $< $(CFLAGS) $(INCLUDES) - # It installs generated and needed files to compile projects using raylib. # The installation works manually. # TODO: add other platforms. diff --git a/src/camera.c b/src/camera.c deleted file mode 100644 index 11571cca..00000000 --- a/src/camera.c +++ /dev/null @@ -1,523 +0,0 @@ -/********************************************************************************************** -* -* raylib Camera System - Camera Modes Setup and Control Functions -* -* Copyright (c) 2015 Marc Palau and Ramon Santamaria (@raysan5) -* -* This software is provided "as-is", without any express or implied warranty. In no event -* will the authors be held liable for any damages arising from the use of this software. -* -* Permission is granted to anyone to use this software for any purpose, including commercial -* applications, and to alter it and redistribute it freely, subject to the following restrictions: -* -* 1. The origin of this software must not be misrepresented; you must not claim that you -* wrote the original software. If you use this software in a product, an acknowledgment -* in the product documentation would be appreciated but is not required. -* -* 2. Altered source versions must be plainly marked as such, and must not be misrepresented -* as being the original software. -* -* 3. This notice may not be removed or altered from any source distribution. -* -**********************************************************************************************/ - -//#define CAMERA_STANDALONE // NOTE: To use the camera module as standalone lib, just uncomment this line - // NOTE: ProcessCamera() should be reviewed to adapt inputs to other systems - -#if defined(CAMERA_STANDALONE) - #include "camera.h" -#else - #include "raylib.h" -#endif - -#include // Required for: sqrt(), sin(), cos() - -//---------------------------------------------------------------------------------- -// Defines and Macros -//---------------------------------------------------------------------------------- -// CAMERA_GENERIC -#define CAMERA_SCROLL_SENSITIVITY 1.5f - -// FREE_CAMERA -#define FREE_CAMERA_MOUSE_SENSITIVITY 0.01f -#define FREE_CAMERA_DISTANCE_MIN_CLAMP 0.3f -#define FREE_CAMERA_DISTANCE_MAX_CLAMP 120.0f -#define FREE_CAMERA_MIN_CLAMP 85.0f -#define FREE_CAMERA_MAX_CLAMP -85.0f -#define FREE_CAMERA_SMOOTH_ZOOM_SENSITIVITY 0.05f -#define FREE_CAMERA_PANNING_DIVIDER 5.1f - -// ORBITAL_CAMERA -#define ORBITAL_CAMERA_SPEED 0.01f - -// FIRST_PERSON -//#define FIRST_PERSON_MOUSE_SENSITIVITY 0.003f -#define FIRST_PERSON_FOCUS_DISTANCE 25.0f -#define FIRST_PERSON_MIN_CLAMP 85.0f -#define FIRST_PERSON_MAX_CLAMP -85.0f - -#define FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER 5.0f -#define FIRST_PERSON_STEP_DIVIDER 30.0f -#define FIRST_PERSON_WAVING_DIVIDER 200.0f - -#define FIRST_PERSON_HEIGHT_RELATIVE_EYES_POSITION 0.85f - -// THIRD_PERSON -//#define THIRD_PERSON_MOUSE_SENSITIVITY 0.003f -#define THIRD_PERSON_DISTANCE_CLAMP 1.2f -#define THIRD_PERSON_MIN_CLAMP 5.0f -#define THIRD_PERSON_MAX_CLAMP -85.0f -#define 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 float mouseSensitivity = 0.003f; -static int cameraMoveControl[6] = { 'W', 'A', 'S', 'D', 'E', 'Q' }; -static int cameraMoveCounter = 0; -static int cameraUseGravity = 1; -static int panControlKey = 2; // raylib: MOUSE_MIDDLE_BUTTON -static int altControlKey = 342; // raylib: KEY_LEFT_ALT -static int smoothZoomControlKey = 341; // raylib: KEY_LEFT_CONTROL - -static int cameraMode = CAMERA_CUSTOM; - -//---------------------------------------------------------------------------------- -// 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) -{ - panControlKey = panKey; -} - -// Set camera alt key to combine with mouse movement (free camera) -void SetCameraAltControl(int altKey) -{ - altControlKey = altKey; -} - -// Set camera smooth zoom key to combine with mouse (free camera) -void SetCameraSmoothZoomControl(int szKey) -{ - smoothZoomControlKey = 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) -{ - mouseSensitivity = (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(panControlKey); // 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 < FREE_CAMERA_DISTANCE_MAX_CLAMP) && (mouseWheelMove < 0)) - { - cameraTargetDistance -= (mouseWheelMove*CAMERA_SCROLL_SENSITIVITY); - - if (cameraTargetDistance > FREE_CAMERA_DISTANCE_MAX_CLAMP) cameraTargetDistance = FREE_CAMERA_DISTANCE_MAX_CLAMP; - } - // Camera looking down - else if ((camera->position.y > camera->target.y) && (cameraTargetDistance == FREE_CAMERA_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 < FREE_CAMERA_DISTANCE_MIN_CLAMP) cameraTargetDistance = FREE_CAMERA_DISTANCE_MIN_CLAMP; - } - // Camera looking up - else if ((camera->position.y < camera->target.y) && (cameraTargetDistance == FREE_CAMERA_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 < FREE_CAMERA_DISTANCE_MIN_CLAMP) cameraTargetDistance = FREE_CAMERA_DISTANCE_MIN_CLAMP; - } - - // Inputs - if (IsKeyDown(altControlKey)) - { - if (IsKeyDown(smoothZoomControlKey)) - { - // Camera smooth zoom - if (panKey) cameraTargetDistance += (cameraMouseVariation.y*FREE_CAMERA_SMOOTH_ZOOM_SENSITIVITY); - } - // Camera orientation calculation - else if (panKey) - { - // Camera orientation calculation - // Get the mouse sensitivity - cameraAngle.x += cameraMouseVariation.x*-FREE_CAMERA_MOUSE_SENSITIVITY; - cameraAngle.y += cameraMouseVariation.y*-FREE_CAMERA_MOUSE_SENSITIVITY; - - // Angle clamp - if (cameraAngle.y > FREE_CAMERA_MIN_CLAMP*DEG2RAD) cameraAngle.y = FREE_CAMERA_MIN_CLAMP*DEG2RAD; - else if (cameraAngle.y < FREE_CAMERA_MAX_CLAMP*DEG2RAD) cameraAngle.y = FREE_CAMERA_MAX_CLAMP*DEG2RAD; - } - } - // Paning - else if (panKey) - { - camera->target.x += ((cameraMouseVariation.x*-FREE_CAMERA_MOUSE_SENSITIVITY)*cos(cameraAngle.x) + (cameraMouseVariation.y*FREE_CAMERA_MOUSE_SENSITIVITY)*sin(cameraAngle.x)*sin(cameraAngle.y))*(cameraTargetDistance/FREE_CAMERA_PANNING_DIVIDER); - camera->target.y += ((cameraMouseVariation.y*FREE_CAMERA_MOUSE_SENSITIVITY)*cos(cameraAngle.y))*(cameraTargetDistance/FREE_CAMERA_PANNING_DIVIDER); - camera->target.z += ((cameraMouseVariation.x*FREE_CAMERA_MOUSE_SENSITIVITY)*sin(cameraAngle.x) + (cameraMouseVariation.y*FREE_CAMERA_MOUSE_SENSITIVITY)*cos(cameraAngle.x)*sin(cameraAngle.y))*(cameraTargetDistance/FREE_CAMERA_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 += ORBITAL_CAMERA_SPEED; - - // Camera zoom - cameraTargetDistance -= (mouseWheelMove*CAMERA_SCROLL_SENSITIVITY); - - // Camera distance clamp - if (cameraTargetDistance < THIRD_PERSON_DISTANCE_CLAMP) cameraTargetDistance = 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; - - if (!cameraUseGravity) 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; - - if (!cameraUseGravity) 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])) - { - if (!cameraUseGravity) playerPosition->y += 1.0f/PLAYER_MOVEMENT_DIVIDER; - } - else if (IsKeyDown(cameraMoveControl[MOVE_DOWN])) - { - if (!cameraUseGravity) playerPosition->y -= 1.0f/PLAYER_MOVEMENT_DIVIDER; - } - - if (cameraMode == CAMERA_THIRD_PERSON) - { - // Camera orientation calculation - cameraAngle.x += cameraMouseVariation.x*-mouseSensitivity; - cameraAngle.y += cameraMouseVariation.y*-mouseSensitivity; - - // Angle clamp - if (cameraAngle.y > THIRD_PERSON_MIN_CLAMP*DEG2RAD) cameraAngle.y = THIRD_PERSON_MIN_CLAMP*DEG2RAD; - else if (cameraAngle.y < THIRD_PERSON_MAX_CLAMP*DEG2RAD) cameraAngle.y = THIRD_PERSON_MAX_CLAMP*DEG2RAD; - - // Camera zoom - cameraTargetDistance -= (mouseWheelMove*CAMERA_SCROLL_SENSITIVITY); - - // Camera distance clamp - if (cameraTargetDistance < THIRD_PERSON_DISTANCE_CLAMP) cameraTargetDistance = THIRD_PERSON_DISTANCE_CLAMP; - - // Camera is always looking at player - camera->target.x = playerPosition->x + THIRD_PERSON_OFFSET.x*cos(cameraAngle.x) + THIRD_PERSON_OFFSET.z*sin(cameraAngle.x); - camera->target.y = playerPosition->y + PLAYER_HEIGHT*FIRST_PERSON_HEIGHT_RELATIVE_EYES_POSITION + THIRD_PERSON_OFFSET.y; - camera->target.z = playerPosition->z + THIRD_PERSON_OFFSET.z*sin(cameraAngle.x) - 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 * -mouseSensitivity); - cameraAngle.y += (cameraMouseVariation.y * -mouseSensitivity); - - // Angle clamp - if (cameraAngle.y > FIRST_PERSON_MIN_CLAMP*DEG2RAD) cameraAngle.y = FIRST_PERSON_MIN_CLAMP*DEG2RAD; - else if (cameraAngle.y < FIRST_PERSON_MAX_CLAMP*DEG2RAD) cameraAngle.y = FIRST_PERSON_MAX_CLAMP*DEG2RAD; - - // Camera is always looking at player - camera->target.x = camera->position.x - sin(cameraAngle.x)*FIRST_PERSON_FOCUS_DISTANCE; - camera->target.y = camera->position.y + sin(cameraAngle.y)*FIRST_PERSON_FOCUS_DISTANCE; - camera->target.z = camera->position.z - cos(cameraAngle.x)*FIRST_PERSON_FOCUS_DISTANCE; - - camera->position.x = playerPosition->x; - camera->position.y = (playerPosition->y + PLAYER_HEIGHT*FIRST_PERSON_HEIGHT_RELATIVE_EYES_POSITION) - sin(cameraMoveCounter/FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER)/FIRST_PERSON_STEP_DIVIDER; - camera->position.z = playerPosition->z; - - camera->up.x = sin(cameraMoveCounter/(FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER*2))/FIRST_PERSON_WAVING_DIVIDER; - camera->up.z = -sin(cameraMoveCounter/(FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER*2))/FIRST_PERSON_WAVING_DIVIDER; - } - } break; - default: break; - } -} 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 diff --git a/src/core.c b/src/core.c index 4cb34b0a..2b5329e3 100644 --- a/src/core.c +++ b/src/core.c @@ -48,6 +48,9 @@ #define GESTURES_IMPLEMENTATION #include "gestures.h" // Gestures detection functionality +#define CAMERA_IMPLEMENTATION +#include "camera.h" // Camera system functionality + #include // Standard input / output lib #include // Declares malloc() and free() for memory management, rand(), atexit() #include // Required for typedef unsigned long long int uint64_t, used by hi-res timer -- 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 From 377dcb025fb6957f73263e1913dfc5f29ba21a58 Mon Sep 17 00:00:00 2001 From: Ray Date: Mon, 5 Dec 2016 01:14:18 +0100 Subject: Corrected some warnings --- src/audio.c | 16 ++++++++------ src/camera.h | 70 ++++++++++++++++++++++++++++++---------------------------- src/core.c | 4 ++-- src/gestures.h | 12 +++++----- src/models.c | 6 +++-- src/raymath.h | 16 +++++++------- src/rlgl.c | 10 ++++++--- src/shapes.c | 15 +++++++------ src/text.c | 33 +++++++++++++-------------- src/textures.c | 25 +++++++++++---------- 10 files changed, 108 insertions(+), 99 deletions(-) (limited to 'src/camera.h') diff --git a/src/audio.c b/src/audio.c index 49aca4b0..eef07154 100644 --- a/src/audio.c +++ b/src/audio.c @@ -411,6 +411,7 @@ Sound LoadSoundFromRES(const char *rresName, int resId) else { // Depending on type, skip the right amount of parameters + /* TODO: Review switch (infoHeader.type) { case 0: fseek(rresFile, 6, SEEK_CUR); break; // IMAGE: Jump 6 bytes of parameters @@ -420,6 +421,7 @@ Sound LoadSoundFromRES(const char *rresName, int resId) case 4: break; // RAW: No parameters default: break; } + */ // Jump DATA to read next infoHeader fseek(rresFile, infoHeader.size, SEEK_CUR); @@ -604,7 +606,7 @@ void WaveFormat(Wave *wave, int sampleRate, int sampleSize, int channels) // Copy a wave to a new wave Wave WaveCopy(Wave wave) { - Wave newWave; + Wave newWave = { 0 }; if (wave.sampleSize == 8) newWave.data = (unsigned char *)malloc(wave.sampleCount*wave.channels*sizeof(unsigned char)); else if (wave.sampleSize == 16) newWave.data = (short *)malloc(wave.sampleCount*wave.channels*sizeof(short)); @@ -822,8 +824,8 @@ void UpdateMusicStream(Music music) if (processed > 0) { bool active = true; - short pcm[AUDIO_BUFFER_SIZE]; - float pcmf[AUDIO_BUFFER_SIZE]; + short pcm[AUDIO_BUFFER_SIZE]; // TODO: Dynamic allocation (uses more than 16KB of stack) + float pcmf[AUDIO_BUFFER_SIZE]; // TODO: Dynamic allocation (uses more than 16KB of stack) int numBuffersToProcess = processed; int numSamples = 0; // Total size of data steamed in L+R samples for xm floats, @@ -952,7 +954,7 @@ float GetMusicTimePlayed(Music music) float secondsPlayed = 0.0f; unsigned int samplesPlayed = music->totalSamples - music->samplesLeft; - secondsPlayed = (float)samplesPlayed/(music->stream.sampleRate*music->stream.channels); + secondsPlayed = (float)(samplesPlayed/(music->stream.sampleRate*music->stream.channels)); return secondsPlayed; } @@ -1004,17 +1006,17 @@ AudioStream InitAudioStream(unsigned int sampleRate, unsigned int sampleSize, un { if (stream.sampleSize == 8) { - unsigned char pcm[AUDIO_BUFFER_SIZE] = { 0 }; + unsigned char pcm[AUDIO_BUFFER_SIZE] = { 0 }; // TODO: Dynamic allocation (uses more than 16KB of stack) alBufferData(stream.buffers[i], stream.format, pcm, AUDIO_BUFFER_SIZE*sizeof(unsigned char), stream.sampleRate); } else if (stream.sampleSize == 16) { - short pcm[AUDIO_BUFFER_SIZE] = { 0 }; + short pcm[AUDIO_BUFFER_SIZE] = { 0 }; // TODO: Dynamic allocation (uses more than 16KB of stack) alBufferData(stream.buffers[i], stream.format, pcm, AUDIO_BUFFER_SIZE*sizeof(short), stream.sampleRate); } else if (stream.sampleSize == 32) { - float pcm[AUDIO_BUFFER_SIZE] = { 0.0f }; + float pcm[AUDIO_BUFFER_SIZE] = { 0.0f }; // TODO: Dynamic allocation (uses more than 16KB of stack) alBufferData(stream.buffers[i], stream.format, pcm, AUDIO_BUFFER_SIZE*sizeof(float), stream.sampleRate); } } diff --git a/src/camera.h b/src/camera.h index 33220390..cf542288 100644 --- a/src/camera.h +++ b/src/camera.h @@ -223,15 +223,15 @@ void SetCameraMode(Camera camera, int mode) float dy = v2.y - v1.y; float dz = v2.z - v1.z; - cameraTargetDistance = sqrt(dx*dx + dy*dy + dz*dz); + cameraTargetDistance = sqrtf(dx*dx + dy*dy + dz*dz); Vector2 distance = { 0.0f, 0.0f }; - distance.x = sqrt(dx*dx + dz*dz); - distance.y = sqrt(dx*dx + dy*dy); + distance.x = sqrtf(dx*dx + dz*dz); + distance.y = sqrtf(dx*dx + dy*dy); // 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) + cameraAngle.x = asinf(fabsf(dx)/distance.x); // Camera angle in plane XZ (0 aligned with Z, move positive CCW) + cameraAngle.y = -asinf(fabsf(dy)/distance.y); // Camera angle in plane XY (0 aligned with X, move positive CW) // NOTE: Just testing what cameraAngle means //cameraAngle.x = 0.0f*DEG2RAD; // Camera angle in plane XZ (0 aligned with Z, move positive CCW) @@ -285,10 +285,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 < (float)screenHeight/3.0f) SetMousePosition((Vector2){ screenWidth - screenHeight/3, mousePosition.y }); + else if (mousePosition.y < (float)screenHeight/3.0f) SetMousePosition((Vector2){ mousePosition.x, screenHeight - screenHeight/3 }); + else if (mousePosition.x > (screenWidth - (float)screenHeight/3.0f)) SetMousePosition((Vector2){ screenHeight/3, mousePosition.y }); + else if (mousePosition.y > (screenHeight - (float)screenHeight/3.0f)) SetMousePosition((Vector2){ mousePosition.x, screenHeight/3 }); else { mousePositionDelta.x = mousePosition.x - previousMousePosition.x; @@ -321,6 +321,7 @@ void UpdateCamera(Camera *camera) if (cameraTargetDistance > CAMERA_FREE_DISTANCE_MAX_CLAMP) cameraTargetDistance = CAMERA_FREE_DISTANCE_MAX_CLAMP; } // Camera looking down + // TODO: Review, weird comparisson of cameraTargetDistance == 120.0f? else if ((camera->position.y > camera->target.y) && (cameraTargetDistance == CAMERA_FREE_DISTANCE_MAX_CLAMP) && (mouseWheelMove < 0)) { camera->target.x += mouseWheelMove*(camera->target.x - camera->position.x)*CAMERA_MOUSE_SCROLL_SENSITIVITY/cameraTargetDistance; @@ -341,6 +342,7 @@ void UpdateCamera(Camera *camera) if (cameraTargetDistance < CAMERA_FREE_DISTANCE_MIN_CLAMP) cameraTargetDistance = CAMERA_FREE_DISTANCE_MIN_CLAMP; } // Camera looking up + // TODO: Review, weird comparisson of cameraTargetDistance == 120.0f? else if ((camera->position.y < camera->target.y) && (cameraTargetDistance == CAMERA_FREE_DISTANCE_MAX_CLAMP) && (mouseWheelMove < 0)) { camera->target.x += mouseWheelMove*(camera->target.x - camera->position.x)*CAMERA_MOUSE_SCROLL_SENSITIVITY/cameraTargetDistance; @@ -385,9 +387,9 @@ void UpdateCamera(Camera *camera) else { // 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); + camera->target.x += ((mousePositionDelta.x*-CAMERA_FREE_MOUSE_SENSITIVITY)*cosf(cameraAngle.x) + (mousePositionDelta.y*CAMERA_FREE_MOUSE_SENSITIVITY)*sinf(cameraAngle.x)*sinf(cameraAngle.y))*(cameraTargetDistance/CAMERA_FREE_PANNING_DIVIDER); + camera->target.y += ((mousePositionDelta.y*CAMERA_FREE_MOUSE_SENSITIVITY)*cosf(cameraAngle.y))*(cameraTargetDistance/CAMERA_FREE_PANNING_DIVIDER); + camera->target.z += ((mousePositionDelta.x*CAMERA_FREE_MOUSE_SENSITIVITY)*sinf(cameraAngle.x) + (mousePositionDelta.y*CAMERA_FREE_MOUSE_SENSITIVITY)*cosf(cameraAngle.x)*sinf(cameraAngle.y))*(cameraTargetDistance/CAMERA_FREE_PANNING_DIVIDER); } } @@ -404,19 +406,19 @@ void UpdateCamera(Camera *camera) 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_SENSITIVITY; + camera->position.x += (sinf(cameraAngle.x)*direction[MOVE_BACK] - + sinf(cameraAngle.x)*direction[MOVE_FRONT] - + cosf(cameraAngle.x)*direction[MOVE_LEFT] + + cosf(cameraAngle.x)*direction[MOVE_RIGHT])/PLAYER_MOVEMENT_SENSITIVITY; - camera->position.y += (sin(cameraAngle.y)*direction[MOVE_FRONT] - - sin(cameraAngle.y)*direction[MOVE_BACK] + + camera->position.y += (sinf(cameraAngle.y)*direction[MOVE_FRONT] - + sinf(cameraAngle.y)*direction[MOVE_BACK] + 1.0f*direction[MOVE_UP] - 1.0f*direction[MOVE_DOWN])/PLAYER_MOVEMENT_SENSITIVITY; - camera->position.z += (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_SENSITIVITY; + camera->position.z += (cosf(cameraAngle.x)*direction[MOVE_BACK] - + cosf(cameraAngle.x)*direction[MOVE_FRONT] + + sinf(cameraAngle.x)*direction[MOVE_LEFT] - + sinf(cameraAngle.x)*direction[MOVE_RIGHT])/PLAYER_MOVEMENT_SENSITIVITY; bool isMoving = false; // Required for swinging @@ -439,9 +441,9 @@ void UpdateCamera(Camera *camera) if (cameraTargetDistance < CAMERA_THIRD_PERSON_DISTANCE_CLAMP) cameraTargetDistance = CAMERA_THIRD_PERSON_DISTANCE_CLAMP; // Camera is always looking at player - camera->target.x = camera->position.x + CAMERA_THIRD_PERSON_OFFSET.x*cos(cameraAngle.x) + CAMERA_THIRD_PERSON_OFFSET.z*sin(cameraAngle.x); + camera->target.x = camera->position.x + CAMERA_THIRD_PERSON_OFFSET.x*cosf(cameraAngle.x) + CAMERA_THIRD_PERSON_OFFSET.z*sinf(cameraAngle.x); camera->target.y = camera->position.y + CAMERA_THIRD_PERSON_OFFSET.y; - camera->target.z = camera->position.z + CAMERA_THIRD_PERSON_OFFSET.z*sin(cameraAngle.x) - CAMERA_THIRD_PERSON_OFFSET.x*sin(cameraAngle.x); + camera->target.z = camera->position.z + CAMERA_THIRD_PERSON_OFFSET.z*sinf(cameraAngle.x) - CAMERA_THIRD_PERSON_OFFSET.x*sinf(cameraAngle.x); } else // CAMERA_FIRST_PERSON { @@ -450,18 +452,18 @@ void UpdateCamera(Camera *camera) 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->target.x = camera->position.x - sinf(cameraAngle.x)*CAMERA_FIRST_PERSON_FOCUS_DISTANCE; + camera->target.y = camera->position.y + sinf(cameraAngle.y)*CAMERA_FIRST_PERSON_FOCUS_DISTANCE; + camera->target.z = camera->position.z - cosf(cameraAngle.x)*CAMERA_FIRST_PERSON_FOCUS_DISTANCE; if (isMoving) swingCounter++; // Camera position update // NOTE: On CAMERA_FIRST_PERSON player Y-movement is limited to player 'eyes position' - camera->position.y = playerEyesPosition - sin(swingCounter/CAMERA_FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER)/CAMERA_FIRST_PERSON_STEP_DIVIDER; + camera->position.y = playerEyesPosition - sinf(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; + camera->up.x = sinf(swingCounter/(CAMERA_FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER*2))/CAMERA_FIRST_PERSON_WAVING_DIVIDER; + camera->up.z = -sinf(swingCounter/(CAMERA_FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER*2))/CAMERA_FIRST_PERSON_WAVING_DIVIDER; } } break; default: break; @@ -473,10 +475,10 @@ void UpdateCamera(Camera *camera) (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; + camera->position.x = sinf(cameraAngle.x)*cameraTargetDistance*cosf(cameraAngle.y) + camera->target.x; + if (cameraAngle.y <= 0.0f) camera->position.y = sinf(cameraAngle.y)*cameraTargetDistance*sinf(cameraAngle.y) + camera->target.y; + else camera->position.y = -sinf(cameraAngle.y)*cameraTargetDistance*sinf(cameraAngle.y) + camera->target.y; + camera->position.z = cosf(cameraAngle.x)*cameraTargetDistance*cosf(cameraAngle.y) + camera->target.z; } } diff --git a/src/core.c b/src/core.c index 241772ec..7fa20979 100644 --- a/src/core.c +++ b/src/core.c @@ -779,7 +779,7 @@ float GetFrameTime(void) // As we are operate quite a lot with frameTime, // it could be no stable, so we round it before passing it around // NOTE: There are still problems with high framerates (>500fps) - double roundedFrameTime = round(frameTime*10000)/10000.0; + double roundedFrameTime = round(frameTime*10000)/10000.0; return (float)roundedFrameTime; // Time in seconds to run a frame } @@ -1089,7 +1089,7 @@ Vector2 GetWorldToScreen(Vector3 position, Camera camera) QuaternionTransform(&worldPos, matProj); // Calculate normalized device coordinates (inverted y) - Vector3 ndcPos = { worldPos.x/worldPos.w, -worldPos.y/worldPos.w, worldPos.z/worldPos.z }; + Vector3 ndcPos = { worldPos.x/worldPos.w, -worldPos.y/worldPos.w, worldPos.z/worldPos.w }; // Calculate 2d screen position vector Vector2 screenPosition = { (ndcPos.x + 1.0f)/2.0f*(float)GetScreenWidth(), (ndcPos.y + 1.0f)/2.0f*(float)GetScreenHeight() }; diff --git a/src/gestures.h b/src/gestures.h index 481ef317..19b09269 100644 --- a/src/gestures.h +++ b/src/gestures.h @@ -179,7 +179,7 @@ static int tapCounter = 0; // TAP counter (one tap implies // Hold gesture variables static bool resetHold = false; // HOLD reset to get first touch point again -static float timeHold = 0.0f; // HOLD duration in milliseconds +static double timeHold = 0.0f; // HOLD duration in milliseconds // Drag gesture variables static Vector2 dragVector = { 0.0f , 0.0f }; // DRAG vector (between initial and current position) @@ -423,11 +423,11 @@ float GetGestureHoldDuration(void) { // NOTE: time is calculated on current gesture HOLD - float time = 0.0f; + double time = 0.0; - if (currentGesture == GESTURE_HOLD) time = (float)GetCurrentTime() - timeHold; + if (currentGesture == GESTURE_HOLD) time = GetCurrentTime() - timeHold; - return time; + return (float)time; } // Get drag vector (between initial touch point to current) @@ -474,7 +474,7 @@ static float Vector2Angle(Vector2 initialPosition, Vector2 finalPosition) { float angle; - angle = atan2(finalPosition.y - initialPosition.y, finalPosition.x - initialPosition.x)*(180.0f/PI); + angle = atan2f(finalPosition.y - initialPosition.y, finalPosition.x - initialPosition.x)*(180.0f/PI); if (angle < 0) angle += 360.0f; @@ -489,7 +489,7 @@ static float Vector2Distance(Vector2 v1, Vector2 v2) float dx = v2.x - v1.x; float dy = v2.y - v1.y; - result = sqrt(dx*dx + dy*dy); + result = (float)sqrt(dx*dx + dy*dy); return result; } diff --git a/src/models.c b/src/models.c index 48f8b813..97c84abc 100644 --- a/src/models.c +++ b/src/models.c @@ -707,6 +707,7 @@ Model LoadModelFromRES(const char *rresName, int resId) else { // Depending on type, skip the right amount of parameters + /* Review switch (infoHeader.type) { case 0: fseek(rresFile, 6, SEEK_CUR); break; // IMAGE: Jump 6 bytes of parameters @@ -716,6 +717,7 @@ Model LoadModelFromRES(const char *rresName, int resId) case 4: break; // RAW: No parameters default: break; } + */ // Jump DATA to read next infoHeader fseek(rresFile, infoHeader.size, SEEK_CUR); @@ -1517,8 +1519,8 @@ bool CheckCollisionRayBox(Ray ray, BoundingBox box) t[3] = (box.max.y - ray.position.y)/ray.direction.y; t[4] = (box.min.z - ray.position.z)/ray.direction.z; t[5] = (box.max.z - ray.position.z)/ray.direction.z; - t[6] = fmax(fmax(fmin(t[0], t[1]), fmin(t[2], t[3])), fmin(t[4], t[5])); - t[7] = fmin(fmin(fmax(t[0], t[1]), fmax(t[2], t[3])), fmax(t[4], t[5])); + t[6] = (float)fmax(fmax(fmin(t[0], t[1]), fmin(t[2], t[3])), fmin(t[4], t[5])); + t[7] = (float)fmin(fmin(fmax(t[0], t[1]), fmax(t[2], t[3])), fmax(t[4], t[5])); collision = !(t[7] < 0 || t[6] > t[7]); diff --git a/src/raymath.h b/src/raymath.h index 10eabb6b..3cd1394e 100644 --- a/src/raymath.h +++ b/src/raymath.h @@ -222,16 +222,16 @@ RMDEF Vector3 VectorPerpendicular(Vector3 v) { Vector3 result; - float min = fabs(v.x); + float min = fabsf(v.x); Vector3 cardinalAxis = {1.0f, 0.0f, 0.0f}; - if (fabs(v.y) < min) + if (fabsf(v.y) < min) { - min = fabs(v.y); + min = fabsf(v.y); cardinalAxis = (Vector3){0.0f, 1.0f, 0.0f}; } - if(fabs(v.z) < min) + if(fabsf(v.z) < min) { cardinalAxis = (Vector3){0.0f, 0.0f, 1.0f}; } @@ -256,7 +256,7 @@ RMDEF float VectorLength(const Vector3 v) { float length; - length = sqrt(v.x*v.x + v.y*v.y + v.z*v.z); + length = sqrtf(v.x*v.x + v.y*v.y + v.z*v.z); return length; } @@ -284,7 +284,7 @@ RMDEF void VectorNormalize(Vector3 *v) length = VectorLength(*v); - if (length == 0) length = 1.0f; + if (length == 0.0f) length = 1.0f; ilength = 1.0f/length; @@ -302,7 +302,7 @@ RMDEF float VectorDistance(Vector3 v1, Vector3 v2) float dy = v2.y - v1.y; float dz = v2.z - v1.z; - result = sqrt(dx*dx + dy*dy + dz*dz); + result = sqrtf(dx*dx + dy*dy + dz*dz); return result; } @@ -590,7 +590,7 @@ RMDEF Matrix MatrixRotate(Vector3 axis, float angle) float x = axis.x, y = axis.y, z = axis.z; - float length = sqrt(x*x + y*y + z*z); + float length = sqrtf(x*x + y*y + z*z); if ((length != 1.0f) && (length != 0.0f)) { diff --git a/src/rlgl.c b/src/rlgl.c index 47e2a57d..83cc7050 100644 --- a/src/rlgl.c +++ b/src/rlgl.c @@ -902,6 +902,10 @@ void rlDisableTexture(void) #if defined(GRAPHICS_API_OPENGL_11) glDisable(GL_TEXTURE_2D); glBindTexture(GL_TEXTURE_2D, 0); +#else + // NOTE: If quads batch limit is reached, + // we force a draw call and next batch starts + if (quads.vCounter/4 >= MAX_QUADS_BATCH) rlglDraw(); #endif } @@ -922,11 +926,11 @@ void rlTextureParameters(unsigned int id, int param, int value) case RL_TEXTURE_MIN_FILTER: glTexParameteri(GL_TEXTURE_2D, param, value); break; case RL_TEXTURE_ANISOTROPIC_FILTER: { - if (value <= maxAnisotropicLevel) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, value); + if (value <= maxAnisotropicLevel) glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, (float)value); else if (maxAnisotropicLevel > 0.0f) { TraceLog(WARNING, "[TEX ID %i] Maximum anisotropic filter level supported is %iX", id, maxAnisotropicLevel); - glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, value); + glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, (float)value); } else TraceLog(WARNING, "Anisotropic filtering not supported"); } break; @@ -1776,7 +1780,7 @@ void rlglGenerateMipmaps(Texture2D *texture) #define MIN(a,b) (((a)<(b))?(a):(b)) #define MAX(a,b) (((a)>(b))?(a):(b)) - texture->mipmaps = 1 + floor(log2(MAX(texture->width, texture->height))); + texture->mipmaps = 1 + (int)floor(log2(MAX(texture->width, texture->height))); #endif } else TraceLog(WARNING, "[TEX ID %i] Mipmaps can not be generated", texture->id); diff --git a/src/shapes.c b/src/shapes.c index 70aad59a..3d3333c1 100644 --- a/src/shapes.c +++ b/src/shapes.c @@ -453,16 +453,17 @@ bool CheckCollisionCircleRec(Vector2 center, float radius, Rectangle rec) int recCenterX = rec.x + rec.width/2; int recCenterY = rec.y + rec.height/2; - float dx = fabs(center.x - recCenterX); - float dy = fabs(center.y - recCenterY); + float dx = fabsf(center.x - recCenterX); + float dy = fabsf(center.y - recCenterY); - if (dx > (rec.width/2 + radius)) { return false; } - if (dy > (rec.height/2 + radius)) { return false; } + if (dx > ((float)rec.width/2.0f + radius)) { return false; } + if (dy > ((float)rec.height/2.0f + radius)) { return false; } - if (dx <= (rec.width/2)) { return true; } - if (dy <= (rec.height/2)) { return true; } + if (dx <= ((float)rec.width/2.0f)) { return true; } + if (dy <= ((float)rec.height/2.0f)) { return true; } - float cornerDistanceSq = (dx - rec.width/2)*(dx - rec.width/2) + (dy - rec.height/2)*(dy - rec.height/2); + float cornerDistanceSq = (dx - (float)rec.width/2.0f)*(dx - (float)rec.width/2.0f) + + (dy - (float)rec.height/2.0f)*(dy - (float)rec.height/2.0f); return (cornerDistanceSq <= (radius*radius)); } diff --git a/src/text.c b/src/text.c index c394889e..27b0a9ce 100644 --- a/src/text.c +++ b/src/text.c @@ -367,7 +367,7 @@ void DrawTextEx(SpriteFont spriteFont, const char *text, Vector2 position, float if ((unsigned char)text[i] == '\n') { // NOTE: Fixed line spacing of 1.5 lines - textOffsetY += ((spriteFont.size + spriteFont.size/2)*scaleFactor); + textOffsetY += (int)((spriteFont.size + spriteFont.size/2)*scaleFactor); textOffsetX = 0; } else @@ -394,8 +394,8 @@ void DrawTextEx(SpriteFont spriteFont, const char *text, Vector2 position, float spriteFont.charRecs[index].width*scaleFactor, spriteFont.charRecs[index].height*scaleFactor }, (Vector2){ 0, 0 }, 0.0f, tint); - if (spriteFont.charAdvanceX[index] == 0) textOffsetX += (spriteFont.charRecs[index].width*scaleFactor + spacing); - else textOffsetX += (spriteFont.charAdvanceX[index]*scaleFactor + spacing); + if (spriteFont.charAdvanceX[index] == 0) textOffsetX += (int)(spriteFont.charRecs[index].width*scaleFactor + spacing); + else textOffsetX += (int)(spriteFont.charAdvanceX[index]*scaleFactor + spacing); } } } @@ -460,14 +460,14 @@ int MeasureText(const char *text, int fontSize) Vector2 MeasureTextEx(SpriteFont spriteFont, const char *text, float fontSize, int spacing) { int len = strlen(text); - int tempLen = 0; // Used to count longer text line num chars + int tempLen = 0; // Used to count longer text line num chars int lenCounter = 0; - int textWidth = 0; - int tempTextWidth = 0; // Used to count longer text line width + float textWidth = 0; + float tempTextWidth = 0; // Used to count longer text line width - int textHeight = spriteFont.size; - float scaleFactor = fontSize/spriteFont.size; + float textHeight = (float)spriteFont.size; + float scaleFactor = fontSize/(float)spriteFont.size; for (int i = 0; i < len; i++) { @@ -485,7 +485,7 @@ Vector2 MeasureTextEx(SpriteFont spriteFont, const char *text, float fontSize, i if (tempTextWidth < textWidth) tempTextWidth = textWidth; lenCounter = 0; textWidth = 0; - textHeight += (spriteFont.size + spriteFont.size/2); // NOTE: Fixed line spacing of 1.5 lines + textHeight += ((float)spriteFont.size*1.5f); // NOTE: Fixed line spacing of 1.5 lines } if (tempLen < lenCounter) tempLen = lenCounter; @@ -494,8 +494,8 @@ Vector2 MeasureTextEx(SpriteFont spriteFont, const char *text, float fontSize, i if (tempTextWidth < textWidth) tempTextWidth = textWidth; Vector2 vec; - vec.x = (float)tempTextWidth*scaleFactor + (tempLen - 1)*spacing; // Adds chars spacing to measure - vec.y = (float)textHeight*scaleFactor; + vec.x = tempTextWidth*scaleFactor + (float)((tempLen - 1)*spacing); // Adds chars spacing to measure + vec.y = textHeight*scaleFactor; return vec; } @@ -504,10 +504,8 @@ Vector2 MeasureTextEx(SpriteFont spriteFont, const char *text, float fontSize, i // NOTE: Uses default font void DrawFPS(int posX, int posY) { - char buffer[20]; - // NOTE: We are rendering fps every second for better viewing on high framerates - // TODO: Not working properly on ANDROID and RPI + // TODO: Not working properly on ANDROID and RPI (for high framerates) static float fps = 0.0f; static int counter = 0; @@ -520,12 +518,11 @@ void DrawFPS(int posX, int posY) else { fps = GetFPS(); - refreshRate = fps; + refreshRate = (int)fps; counter = 0; } - - sprintf(buffer, "%2.0f FPS", fps); - DrawText(buffer, posX, posY, 20, LIME); + + DrawText(FormatText("%2.0f FPS", fps), posX, posY, 20, LIME); } //---------------------------------------------------------------------------------- diff --git a/src/textures.c b/src/textures.c index 126adad3..631468f9 100644 --- a/src/textures.c +++ b/src/textures.c @@ -317,6 +317,7 @@ Image LoadImageFromRES(const char *rresName, int resId) else { // Depending on type, skip the right amount of parameters + /* TODO: Review switch (infoHeader.type) { case 0: fseek(rresFile, 6, SEEK_CUR); break; // IMAGE: Jump 6 bytes of parameters @@ -326,7 +327,7 @@ Image LoadImageFromRES(const char *rresName, int resId) case 4: break; // RAW: No parameters default: break; } - + */ // Jump DATA to read next infoHeader fseek(rresFile, infoHeader.size, SEEK_CUR); } @@ -1100,18 +1101,18 @@ void ImageResizeNN(Image *image,int newWidth,int newHeight) Color *output = (Color *)malloc(newWidth*newHeight*sizeof(Color)); // EDIT: added +1 to account for an early rounding problem - int x_ratio = (int)((image->width<<16)/newWidth) + 1; - int y_ratio = (int)((image->height<<16)/newHeight) + 1; + int xRatio = (int)((image->width << 16)/newWidth) + 1; + int yRatio = (int)((image->height << 16)/newHeight) + 1; int x2, y2; - for (int i = 0; i < newHeight; i++) + for (int y = 0; y < newHeight; y++) { - for (int j = 0; j < newWidth; j++) + for (int x = 0; x < newWidth; x++) { - x2 = ((j*x_ratio) >> 16); - y2 = ((i*y_ratio) >> 16); + x2 = ((x*xRatio) >> 16); + y2 = ((y*yRatio) >> 16); - output[(i*newWidth) + j] = pixels[(y2*image->width) + x2] ; + output[(y*newWidth) + x] = pixels[(y2*image->width) + x2] ; } } @@ -1584,7 +1585,7 @@ void DrawTexturePro(Texture2D texture, Rectangle sourceRec, Rectangle destRec, V rlEnableTexture(texture.id); rlPushMatrix(); - rlTranslatef(destRec.x, destRec.y, 0); + rlTranslatef((float)destRec.x, (float)destRec.y, 0); rlRotatef(rotation, 0, 0, 1); rlTranslatef(-origin.x, -origin.y, 0); @@ -1598,15 +1599,15 @@ void DrawTexturePro(Texture2D texture, Rectangle sourceRec, Rectangle destRec, V // Bottom-right corner for texture and quad rlTexCoord2f((float)sourceRec.x/texture.width, (float)(sourceRec.y + sourceRec.height)/texture.height); - rlVertex2f(0.0f, destRec.height); + rlVertex2f(0.0f, (float)destRec.height); // Top-right corner for texture and quad rlTexCoord2f((float)(sourceRec.x + sourceRec.width)/texture.width, (float)(sourceRec.y + sourceRec.height)/texture.height); - rlVertex2f(destRec.width, destRec.height); + rlVertex2f((float)destRec.width, (float)destRec.height); // Top-left corner for texture and quad rlTexCoord2f((float)(sourceRec.x + sourceRec.width)/texture.width, (float)sourceRec.y/texture.height); - rlVertex2f(destRec.width, 0.0f); + rlVertex2f((float)destRec.width, 0.0f); rlEnd(); rlPopMatrix(); -- cgit v1.2.3 From 05cff44d0a9af5bcb41ddd0baa6b7693f6ac116b Mon Sep 17 00:00:00 2001 From: Ray Date: Thu, 16 Feb 2017 00:50:02 +0100 Subject: Improved modules description -IN PROGRESS- Working in modules configuration flags... --- src/audio.c | 56 +++++++++++++++++++++++++++++++++++++------------------- src/audio.h | 4 +++- src/camera.h | 14 +++++++++++--- src/core.c | 55 +++++++++++++++++++++++++++++++++++++------------------ src/gestures.h | 17 +++++++++++++---- src/models.c | 13 +++++++------ src/physac.h | 15 +++++++++------ src/raylib.h | 44 +++++++++++++++++++++++++++----------------- src/raymath.h | 25 +++++++++++++------------ src/rlgl.c | 46 ++++++++++++++++++++++++++++++++++++---------- src/rres.h | 18 +++++++++++------- src/shapes.c | 11 ++++------- src/text.c | 36 +++++++++++++++++++++--------------- src/textures.c | 35 +++++++++++++++++++++++++++-------- src/utils.c | 19 +++++++++++++------ 15 files changed, 269 insertions(+), 139 deletions(-) (limited to 'src/camera.h') diff --git a/src/audio.c b/src/audio.c index 58699035..690a41eb 100644 --- a/src/audio.c +++ b/src/audio.c @@ -3,32 +3,50 @@ * raylib.audio * * This module provides basic functionality to work with audio: -* Manage audio device (init/close) -* Load and Unload audio files (WAV, OGG, FLAC, XM, MOD) -* Play/Stop/Pause/Resume loaded audio -* Manage mixing channels -* Manage raw audio context +* Manage audio device (init/close) +* Load and Unload audio files (WAV, OGG, FLAC, XM, MOD) +* Play/Stop/Pause/Resume loaded audio +* Manage mixing channels +* Manage raw audio context * -* External libs: +* NOTES: +* +* Only up to two channels supported: MONO and STEREO (for additional channels, use AL_EXT_MCFORMATS) +* Only the following sample sizes supported: 8bit PCM, 16bit PCM, 32-bit float PCM (using AL_EXT_FLOAT32) +* +* CONFIGURATION: +* +* #define AUDIO_STANDALONE +* If defined, the module can be used as standalone library (independently of raylib). +* Required types and functions are defined in the same module. +* +* #define SUPPORT_FILEFORMAT_WAV / SUPPORT_LOAD_WAV / ENABLE_LOAD_WAV +* #define SUPPORT_FILEFORMAT_OGG +* #define SUPPORT_FILEFORMAT_XM +* #define SUPPORT_FILEFORMAT_MOD +* #define SUPPORT_FILEFORMAT_FLAC +* Selected desired fileformats to be supported for loading. Some of those formats are +* supported by default, to remove support, just comment unrequired #define in this module +* +* #define SUPPORT_RAW_AUDIO_BUFFERS +* +* DEPENDENCIES: * OpenAL Soft - Audio device management (http://kcat.strangesoft.net/openal.html) * stb_vorbis - OGG audio files loading (http://www.nothings.org/stb_vorbis/) * jar_xm - XM module file loading * jar_mod - MOD audio file loading * dr_flac - FLAC audio file loading * -* Module Configuration Flags: -* AUDIO_STANDALONE - Use this module as standalone library (independently of raylib) -* -* Some design decisions: -* Support only up to two channels: MONO and STEREO (for additional channels, AL_EXT_MCFORMATS) -* Support only the following sample sizes: 8bit PCM, 16bit PCM, 32-bit float PCM (using AL_EXT_FLOAT32) +* CONTRIBUTORS: * * Many thanks to Joshua Reisenauer (github: @kd7tck) for the following additions: -* XM audio module support (jar_xm) -* MOD audio module support (jar_mod) -* Mixing channels support -* Raw audio context support +* XM audio module support (jar_xm) +* MOD audio module support (jar_mod) +* Mixing channels support +* Raw audio context support +* * +* LICENSE: zlib/libpng * * Copyright (c) 2014-2016 Ramon Santamaria (@raysan5) * @@ -246,11 +264,11 @@ Wave LoadWave(const char *fileName) else if (strcmp(GetExtension(fileName), "flac") == 0) wave = LoadFLAC(fileName); else if (strcmp(GetExtension(fileName),"rres") == 0) { - RRESData rres = LoadResource(fileName); + RRES rres = LoadResource(fileName, 0); - // NOTE: Parameters for RRES_WAVE type are: sampleCount, sampleRate, sampleSize, channels + // NOTE: Parameters for RRES_TYPE_WAVE are: sampleCount, sampleRate, sampleSize, channels - if (rres.type == RRES_WAVE) wave = LoadWaveEx(rres.data, rres.param1, rres.param2, rres.param3, rres.param4); + if (rres[0].type == RRES_TYPE_WAVE) wave = LoadWaveEx(rres[0].data, rres[0].param1, rres[0].param2, rres[0].param3, rres[0].param4); else TraceLog(WARNING, "[%s] Resource file does not contain wave data", fileName); UnloadResource(rres); diff --git a/src/audio.h b/src/audio.h index 99b58e15..01ed9f72 100644 --- a/src/audio.h +++ b/src/audio.h @@ -9,7 +9,7 @@ * Manage mixing channels * Manage raw audio context * -* External libs: +* DEPENDENCIES: * OpenAL Soft - Audio device management (http://kcat.strangesoft.net/openal.html) * stb_vorbis - OGG audio files loading (http://www.nothings.org/stb_vorbis/) * jar_xm - XM module file loading @@ -23,6 +23,8 @@ * Raw audio context support * * +* LICENSE: zlib/libpng +* * Copyright (c) 2014-2016 Ramon Santamaria (@raysan5) * * This software is provided "as-is", without any express or implied warranty. In no event diff --git a/src/camera.h b/src/camera.h index cf542288..87ba1942 100644 --- a/src/camera.h +++ b/src/camera.h @@ -2,6 +2,10 @@ * * raylib Camera System - Camera Modes Setup and Control Functions * +* NOTE: Memory footprint of this library is aproximately 52 bytes (global variables) +* +* CONFIGURATION: +* * #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 @@ -11,10 +15,14 @@ * 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 52 bytes (global variables) +* CONTRIBUTORS: +* Marc Palau: Initial implementation (2014) +* Ramon Santamaria: Supervision, review, update and maintenance +* +* +* LICENSE: zlib/libpng * -* Initial design by Marc Palau (2014) -* Reviewed by Ramon Santamaria (2015-2016) +* Copyright (c) 2015-2016 Ramon Santamaria (@raysan5) * * This software is provided "as-is", without any express or implied warranty. In no event * will the authors be held liable for any damages arising from the use of this software. diff --git a/src/core.c b/src/core.c index 28f73345..9d40edcc 100644 --- a/src/core.c +++ b/src/core.c @@ -1,27 +1,46 @@ /********************************************************************************************** * -* raylib.core -* -* Basic functions to manage windows, OpenGL context and input on multiple platforms +* raylib.core - Basic functions to manage windows, OpenGL context and input on multiple platforms * * The following platforms are supported: Windows, Linux, Mac (OSX), Android, Raspberry Pi, HTML5, Oculus Rift CV1 * -* External libs: +* CONFIGURATION: +* +* #define PLATFORM_DESKTOP +* Windowing and input system configured for desktop platforms: Windows, Linux, OSX (managed by GLFW3 library) +* NOTE: Oculus Rift CV1 requires PLATFORM_DESKTOP for mirror rendering - View [rlgl] module to enable it +* +* #define PLATFORM_ANDROID +* Windowing and input system configured for Android device, app activity managed internally in this module. +* NOTE: OpenGL ES 2.0 is required and graphic device is managed by EGL +* +* #define PLATFORM_RPI +* Windowing and input system configured for Raspberry Pi (tested on Raspbian), graphic device is managed by EGL +* and inputs are processed is raw mode, reading from /dev/input/ +* +* #define PLATFORM_WEB +* Windowing and input system configured for HTML5 (run on browser), code converted from C to asm.js +* using emscripten compiler. OpenGL ES 2.0 required for direct translation to WebGL equivalent code. +* +* #define LOAD_DEFAULT_FONT (defined by default) +* Default font is loaded on window initialization to be available for the user to render simple text. +* NOTE: If enabled, uses external module functions to load default raylib font (module: text) +* +* #define INCLUDE_CAMERA_SYSTEM / SUPPORT_CAMERA_SYSTEM +* +* #define INCLUDE_GESTURES_SYSTEM / SUPPORT_GESTURES_SYSTEM +* +* #define SUPPORT_MOUSE_GESTURES +* Mouse gestures are directly mapped like touches and processed by gestures system. +* +* DEPENDENCIES: * GLFW3 - Manage graphic device, OpenGL context and inputs on PLATFORM_DESKTOP (Windows, Linux, OSX) * raymath - 3D math functionality (Vector3, Matrix, Quaternion) * camera - Multiple 3D camera modes (free, orbital, 1st person, 3rd person) * gestures - Gestures system for touch-ready devices (or simulated from mouse inputs) * -* Module Configuration Flags: -* PLATFORM_DESKTOP - Windows, Linux, Mac (OSX) -* PLATFORM_ANDROID - Android (only OpenGL ES 2.0 devices), graphic device is managed by EGL and input system by Android activity. -* PLATFORM_RPI - Rapsberry Pi (tested on Raspbian), graphic device is managed by EGL and input system is coded in raw mode. -* PLATFORM_WEB - HTML5 (using emscripten compiler) -* -* RL_LOAD_DEFAULT_FONT - Use external module functions to load default raylib font (module: text) -* -* NOTE: Oculus Rift CV1 requires PLATFORM_DESKTOP for render mirror - View [rlgl] module to enable it * +* LICENSE: zlib/libpng * * Copyright (c) 2014-2016 Ramon Santamaria (@raysan5) * @@ -140,7 +159,7 @@ #define MAX_GAMEPAD_BUTTONS 32 // Max bumber of buttons supported (per gamepad) #define MAX_GAMEPAD_AXIS 8 // Max number of axis supported (per gamepad) -#define RL_LOAD_DEFAULT_FONT // Load default font on window initialization (module: text) +#define LOAD_DEFAULT_FONT // Load default font on window initialization (module: text) //---------------------------------------------------------------------------------- // Types and Structures Definition @@ -256,7 +275,7 @@ static bool showLogo = false; // Track if showing logo at init is //---------------------------------------------------------------------------------- // Other Modules Functions Declaration (required by core) //---------------------------------------------------------------------------------- -#if defined(RL_LOAD_DEFAULT_FONT) +#if defined(LOAD_DEFAULT_FONT) extern void LoadDefaultFont(void); // [Module: text] Loads default font on InitWindow() extern void UnloadDefaultFont(void); // [Module: text] Unloads default font from GPU memory #endif @@ -338,7 +357,7 @@ void InitWindow(int width, int height, const char *title) // Init graphics device (display device and OpenGL context) InitGraphicsDevice(width, height); -#if defined(RL_LOAD_DEFAULT_FONT) +#if defined(LOAD_DEFAULT_FONT) // Load default font // NOTE: External function (defined in module: text) LoadDefaultFont(); @@ -450,7 +469,7 @@ void InitWindow(int width, int height, void *state) // Close Window and Terminate Context void CloseWindow(void) { -#if defined(RL_LOAD_DEFAULT_FONT) +#if defined(LOAD_DEFAULT_FONT) UnloadDefaultFont(); #endif @@ -2410,7 +2429,7 @@ static void AndroidCommandCallback(struct android_app *app, int32_t cmd) // Init graphics device (display device and OpenGL context) InitGraphicsDevice(screenWidth, screenHeight); - #if defined(RL_LOAD_DEFAULT_FONT) + #if defined(LOAD_DEFAULT_FONT) // Load default font // NOTE: External function (defined in module: text) LoadDefaultFont(); diff --git a/src/gestures.h b/src/gestures.h index f4dcb133..99f49d2a 100644 --- a/src/gestures.h +++ b/src/gestures.h @@ -2,6 +2,10 @@ * * raylib Gestures System - Gestures Processing based on input gesture events (touch/mouse) * +* NOTE: Memory footprint of this library is aproximately 128 bytes (global variables) +* +* CONFIGURATION: +* * #define GESTURES_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 @@ -11,11 +15,16 @@ * If defined, the library can be used as standalone to process gesture events with * no external dependencies. * -* NOTE: Memory footprint of this library is aproximately 128 bytes +* CONTRIBUTORS: +* Marc Palau: Initial implementation (2014) +* Albert Martos: Complete redesign and testing (2015) +* Ian Eito: Complete redesign and testing (2015) +* Ramon Santamaria: Supervision, review, update and maintenance +* +* +* LICENSE: zlib/libpng * -* Initial design by Marc Palau (2014) -* Redesigned by Albert Martos and Ian Eito (2015) -* Reviewed by Ramon Santamaria (2015-2016) +* Copyright (c) 2014-2016 Ramon Santamaria (@raysan5) * * This software is provided "as-is", without any express or implied warranty. In no event * will the authors be held liable for any damages arising from the use of this software. diff --git a/src/models.c b/src/models.c index 43821691..bef19e10 100644 --- a/src/models.c +++ b/src/models.c @@ -1,14 +1,15 @@ /********************************************************************************************** * -* raylib.models +* raylib.models - Basic functions to draw 3d shapes and 3d models * -* Basic functions to draw 3d shapes and load/draw 3d models (.OBJ) +* CONFIGURATION: * -* External libs: -* rlgl - raylib OpenGL abstraction layer +* #define SUPPORT_FILEFORMAT_OBJ / SUPPORT_LOAD_OBJ * -* Module Configuration Flags: -* ... +* #define SUPPORT_FILEFORMAT_MTL +* +* +* LICENSE: zlib/libpng * * Copyright (c) 2014-2016 Ramon Santamaria (@raysan5) * diff --git a/src/physac.h b/src/physac.h index d958c701..cb0e3f3c 100644 --- a/src/physac.h +++ b/src/physac.h @@ -1,11 +1,13 @@ /********************************************************************************************** * -* Physac - 2D Physics library for videogames +* Physac v1.0 - 2D Physics library for videogames * -* Description: Physac is a small 2D physics engine written in pure C. The engine uses a fixed time-step thread loop -* to simluate physics. A physics step contains the following phases: get collision information, apply dynamics, -* collision solving and position correction. It uses a very simple struct for physic bodies with a position vector -* to be used in any 3D rendering API. +* DESCRIPTION: +* +* Physac is a small 2D physics engine written in pure C. The engine uses a fixed time-step thread loop +* to simluate physics. A physics step contains the following phases: get collision information, +* apply dynamics, collision solving and position correction. It uses a very simple struct for physic +* bodies with a position vector to be used in any 3D rendering API. * * CONFIGURATION: * @@ -37,7 +39,8 @@ * Otherwise it will include stdlib.h and use the C standard library malloc()/free() function. * * VERY THANKS TO: -* - Ramón Santamaria (@raysan5) +* Ramón Santamaria (@raysan5) +* * * LICENSE: zlib/libpng * diff --git a/src/raylib.h b/src/raylib.h index 800ab2be..3ff0d28f 100644 --- a/src/raylib.h +++ b/src/raylib.h @@ -1,10 +1,10 @@ /********************************************************************************************** * -* raylib 1.7.0 (www.raylib.com) +* raylib v1.7.0 (www.raylib.com) * * A simple and easy-to-use library to learn videogames programming * -* Features: +* FEATURES: * Library written in plain C code (C99) * Uses PascalCase/camelCase notation * Hardware accelerated with OpenGL (1.1, 2.1, 3.3 or ES 2.0) @@ -20,7 +20,13 @@ * Minimal external dependencies (GLFW3, OpenGL, OpenAL) * Complete binding for Lua [rlua] * -* External libs: +* NOTES: +* 32bit Colors - All defined color are always RGBA (struct Color is 4 byte) +* One custom default font could be loaded automatically when InitWindow() [core] +* If using OpenGL 3.3 or ES2, several vertex buffers (VAO/VBO) are created to manage lines-triangles-quads +* If using OpenGL 3.3 or ES2, two default shaders could be loaded automatically (internally defined) +* +* DEPENDENCIES: * GLFW3 (www.glfw.org) for window/context management and input [core] * GLAD for OpenGL extensions loading (3.3 Core profile, only PLATFORM_DESKTOP) [rlgl] * stb_image (Sean Barret) for images loading (JPEG, PNG, BMP, TGA) [textures] @@ -33,13 +39,8 @@ * OpenAL Soft for audio device/context management [audio] * tinfl for data decompression (DEFLATE algorithm) [utils] * -* Some design decisions: -* 32bit Colors - All defined color are always RGBA (struct Color is 4 byte) -* One custom default font could be loaded automatically when InitWindow() [core] -* If using OpenGL 3.3 or ES2, several vertex buffers (VAO/VBO) are created to manage lines-triangles-quads -* If using OpenGL 3.3 or ES2, two default shaders could be loaded automatically (internally defined) * -* -- LICENSE -- +* LICENSE: zlib/libpng * * raylib is licensed under an unmodified zlib/libpng license, which is an OSI-certified, * BSD-like license that allows static linking with closed source software: @@ -592,8 +593,9 @@ typedef enum { HMD_FOVE_VR, } VrDevice; -// rRES data returned when reading a resource, it contains all required data for user (24 byte) -typedef struct { +// rRES data returned when reading a resource, +// it contains all required data for user (24 byte) +typedef struct RRESData { unsigned int type; // Resource type (4 byte) unsigned int param1; // Resouce parameter 1 (4 byte) @@ -604,14 +606,21 @@ typedef struct { void *data; // Resource data pointer (4 byte) } RRESData; -typedef enum { - RRES_RAW = 0, - RRES_IMAGE, - RRES_WAVE, - RRES_VERTEX, - RRES_TEXT +// RRESData type +typedef enum { + RRES_TYPE_RAW = 0, + RRES_TYPE_IMAGE, + RRES_TYPE_WAVE, + RRES_TYPE_VERTEX, + RRES_TYPE_TEXT, + RRES_TYPE_FONT_IMAGE, + RRES_TYPE_FONT_CHARDATA, // CharInfo data array + RRES_TYPE_DIRECTORY } RRESDataType; +// RRES type (pointer to RRESData array) +typedef struct RRESData *RRES; + #ifdef __cplusplus extern "C" { // Prevents name mangling of functions #endif @@ -758,6 +767,7 @@ RLAPI void DrawCircleV(Vector2 center, float radius, Color color); RLAPI void DrawCircleLines(int centerX, int centerY, float radius, Color color); // Draw circle outline RLAPI void DrawRectangle(int posX, int posY, int width, int height, Color color); // Draw a color-filled rectangle RLAPI void DrawRectangleRec(Rectangle rec, Color color); // Draw a color-filled rectangle +RLAPI void DrawRectanglePro(Rectangle rec, Vector2 origin, float rotation, Color color); // Draw a color-filled rectangle with pro parameters RLAPI void DrawRectangleGradient(int posX, int posY, int width, int height, Color color1, Color color2); // Draw a gradient-filled rectangle RLAPI void DrawRectangleV(Vector2 position, Vector2 size, Color color); // Draw a color-filled rectangle (Vector version) RLAPI void DrawRectangleLines(int posX, int posY, int width, int height, Color color); // Draw rectangle outline diff --git a/src/raymath.h b/src/raymath.h index c073b72d..a2263f19 100644 --- a/src/raymath.h +++ b/src/raymath.h @@ -1,22 +1,23 @@ /********************************************************************************************** * -* raymath (header only file) +* raymath v1.0 - Some useful functions to work with Vector3, Matrix and Quaternions * -* Some useful functions to work with Vector3, Matrix and Quaternions +* CONFIGURATION: * -* You must: -* #define RAYMATH_IMPLEMENTATION -* before you include this file in *only one* C or C++ file to create the implementation. +* #define RAYMATH_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. * -* Example: -* #define RAYMATH_IMPLEMENTATION -* #include "raymath.h" +* #define RAYMATH_EXTERN_INLINE +* Inlines all functions code, so it runs faster. This requires lots of memory on system. +* +* #define RAYMATH_STANDALONE +* Avoid raylib.h header inclusion in this file. +* Vector3 and Matrix data types are defined internally in raymath module. * -* You can also use: -* #define RAYMATH_EXTERN_INLINE // Inlines all functions code, so it runs faster. -* // This requires lots of memory on system. -* #define RAYMATH_STANDALONE // Not dependent on raylib.h structs: Vector3, Matrix. * +* LICENSE: zlib/libpng * * Copyright (c) 2015 Ramon Santamaria (@raysan5) * diff --git a/src/rlgl.c b/src/rlgl.c index ce17adc3..ffc9d741 100644 --- a/src/rlgl.c +++ b/src/rlgl.c @@ -2,6 +2,8 @@ * * rlgl - raylib OpenGL abstraction layer * +* DESCRIPTION: +* * rlgl allows usage of OpenGL 1.1 style functions (rlVertex) that are internally mapped to * selected OpenGL version (1.1, 2.1, 3.3 Core, ES 2.0). * @@ -11,20 +13,44 @@ * rlglDraw() - Process internal buffers and send required draw calls * rlglClose() - De-initialize internal buffers data and other auxiliar resources * -* External libs: +* CONFIGURATION: +* +* #define GRAPHICS_API_OPENGL_11 +* Use OpenGL 1.1 backend +* +* #define GRAPHICS_API_OPENGL_21 +* Use OpenGL 2.1 backend +* +* #define GRAPHICS_API_OPENGL_33 +* Use OpenGL 3.3 Core profile backend +* +* #define GRAPHICS_API_OPENGL_ES2 +* Use OpenGL ES 2.0 backend +* +* #define RLGL_STANDALONE +* Use rlgl as standalone library (no raylib dependency) +* +* #define RLGL_NO_DISTORTION_SHADER +* Avoid stereo rendering distortion sahder (shader_distortion.h) inclusion +* +* #define SUPPORT_SHADER_DEFAULT / ENABLE_SHADER_DEFAULT +* +* #define SUPPORT_SHADER_DISTORTION +* +* +* #define SUPPORT_OCULUS_RIFT_CV1 / RLGL_OCULUS_SUPPORT +* Enable Oculus Rift CV1 functionality +* +* #define SUPPORT_STEREO_RENDERING +* +* #define RLGL_NO_DEFAULT_SHADER +* +* DEPENDENCIES: * raymath - 3D math functionality (Vector3, Matrix, Quaternion) * GLAD - OpenGL extensions loading (OpenGL 3.3 Core only) * -* Module Configuration Flags: -* GRAPHICS_API_OPENGL_11 - Use OpenGL 1.1 backend -* GRAPHICS_API_OPENGL_21 - Use OpenGL 2.1 backend -* GRAPHICS_API_OPENGL_33 - Use OpenGL 3.3 Core profile backend -* GRAPHICS_API_OPENGL_ES2 - Use OpenGL ES 2.0 backend -* -* RLGL_STANDALONE - Use rlgl as standalone library (no raylib dependency) -* RLGL_NO_DISTORTION_SHADER - Avoid stereo rendering distortion sahder (shader_distortion.h) inclusion -* RLGL_OCULUS_SUPPORT - Enable Oculus Rift CV1 functionality * +* LICENSE: zlib/libpng * * Copyright (c) 2014-2016 Ramon Santamaria (@raysan5) * diff --git a/src/rres.h b/src/rres.h index bed28723..362da10d 100644 --- a/src/rres.h +++ b/src/rres.h @@ -4,14 +4,18 @@ * * Basic functions to load/save rRES resource files * -* External libs: -* tinfl - DEFLATE decompression functions +* CONFIGURATION: +* +* #define RREM_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. * -* Module Configuration Flags: +* DEPENDENCIES: +* tinfl - DEFLATE decompression functions * -* #define RREM_IMPLEMENTATION -* Generates the implementation of the library into the included file. * +* LICENSE: zlib/libpng * * Copyright (c) 2016-2017 Ramon Santamaria (@raysan5) * @@ -81,7 +85,7 @@ RRES_TYPE_VERTEX, RRES_TYPE_TEXT, RRES_TYPE_FONT_IMAGE, - RRES_TYPE_FONT_DATA, // Character { int value, recX, recY, recWidth, recHeight, offsetX, offsetY, xAdvance } + RRES_TYPE_FONT_CHARDATA, // Character { int value, recX, recY, recWidth, recHeight, offsetX, offsetY, xAdvance } RRES_TYPE_DIRECTORY } RRESDataType; @@ -243,7 +247,7 @@ static void *DecompressData(const unsigned char *data, unsigned long compSize, i // NOTE: Returns uncompressed data with parameters, search resource by id RRESDEF RRES LoadResource(const char *fileName, int rresId) { - RRES rres; + RRES rres = { 0 }; RRESFileHeader fileHeader; RRESInfoHeader infoHeader; diff --git a/src/shapes.c b/src/shapes.c index 83b80182..a42b0551 100644 --- a/src/shapes.c +++ b/src/shapes.c @@ -1,17 +1,14 @@ /********************************************************************************************** * -* raylib.shapes -* -* Basic functions to draw 2d Shapes and check collisions -* -* DEPENDENCIES: -* rlgl - raylib OpenGL abstraction layer +* raylib.shapes - Basic functions to draw 2d Shapes and check collisions * * CONFIGURATION: * * #define SUPPORT_QUADS_ONLY +* Draw shapes using only QUADS, vertex are accumulated in QUADS arrays (like textures) * - #define SUPPORT_TRIANGLES_ONLY +* #define SUPPORT_TRIANGLES_ONLY +* Draw shapes using only TRIANGLES, vertex are accumulated in TRIANGLES arrays * * * LICENSE: zlib/libpng diff --git a/src/text.c b/src/text.c index 4deae25c..6f18b391 100644 --- a/src/text.c +++ b/src/text.c @@ -1,14 +1,22 @@ /********************************************************************************************** * -* raylib.text +* raylib.text - Basic functions to load SpriteFonts and draw Text * -* Basic functions to load SpriteFonts and draw Text +* CONFIGURATION: * -* External libs: +* #define SUPPORT_FILEFORMAT_FNT +* #define SUPPORT_FILEFORMAT_TTF / INCLUDE_STB_TRUETYPE +* #define SUPPORT_FILEFORMAT_IMAGE_FONT +* Selected desired fileformats to be supported for loading. Some of those formats are +* supported by default, to remove support, just comment unrequired #define in this module +* +* #define INCLUDE_DEFAULT_FONT / SUPPORT_DEFAULT_FONT +* +* DEPENDENCIES: * stb_truetype - Load TTF file and rasterize characters data * -* Module Configuration Flags: -* ... +* +* LICENSE: zlib/libpng * * Copyright (c) 2014-2016 Ramon Santamaria (@raysan5) * @@ -262,30 +270,28 @@ SpriteFont LoadSpriteFont(const char *fileName) else if (strcmp(GetExtension(fileName),"rres") == 0) { // TODO: Read multiple resource blocks from file (RRES_FONT_IMAGE, RRES_FONT_CHARDATA) - RRESData rres = LoadResource(fileName); + RRES rres = LoadResource(fileName, 0); // Load sprite font texture - /* - if (rres.type == RRES_FONT_IMAGE) + if (rres[0].type == RRES_TYPE_FONT_IMAGE) { // NOTE: Parameters for RRES_FONT_IMAGE type are: width, height, format, mipmaps - Image image = LoadImagePro(rres.data, rres.param1, rres.param2, rres.param3); + Image image = LoadImagePro(rres[0].data, rres[0].param1, rres[0].param2, rres[0].param3); spriteFont.texture = LoadTextureFromImage(image); UnloadImage(image); } // Load sprite characters data - if (rres.type == RRES_FONT_CHARDATA) + if (rres[1].type == RRES_TYPE_FONT_CHARDATA) { // NOTE: Parameters for RRES_FONT_CHARDATA type are: fontSize, charsCount - spriteFont.baseSize = rres.param1; - spriteFont.charsCount = rres.param2; - spriteFont.chars = rres.data; + spriteFont.baseSize = rres[1].param1; + spriteFont.charsCount = rres[1].param2; + spriteFont.chars = rres[1].data; } - */ // TODO: Do not free rres.data memory (chars info data!) - UnloadResource(rres); + //UnloadResource(rres[0]); } else { diff --git a/src/textures.c b/src/textures.c index 5b2e4775..7db3bf56 100644 --- a/src/textures.c +++ b/src/textures.c @@ -1,16 +1,35 @@ /********************************************************************************************** * -* raylib.textures +* raylib.textures - Basic functions to load and draw Textures (2d) * -* Basic functions to load and draw Textures (2d) +* CONFIGURATION: * -* External libs: +* #define SUPPORT_STB_IMAGE / INCLUDE_STB_IMAGE +* +* #define SUPPORT_FILEFORMAT_BMP / SUPPORT_LOAD_BMP +* #define SUPPORT_FILEFORMAT_PNG / SUPPORT_LOAD_PNG +* #define SUPPORT_FILEFORMAT_TGA +* #define SUPPORT_FILEFORMAT_JPG / ENABLE_LOAD_JPG +* #define SUPPORT_FILEFORMAT_GIF +* #define SUPPORT_FILEFORMAT_HDR +* #define SUPPORT_FILEFORMAT_DDS / ENABLE_LOAD_DDS +* #define SUPPORT_FILEFORMAT_PKM +* #define SUPPORT_FILEFORMAT_KTX +* #define SUPPORT_FILEFORMAT_PVR +* #define SUPPORT_FILEFORMAT_ASTC +* Selected desired fileformats to be supported for loading. Some of those formats are +* supported by default, to remove support, just comment unrequired #define in this module +* +* #define SUPPORT_IMAGE_RESIZE / INCLUDE_STB_IMAGE_RESIZE +* #define SUPPORT_IMAGE_MANIPULATION +* +* DEPENDENCIES: * stb_image - Multiple image formats loading (JPEG, PNG, BMP, TGA, PSD, GIF, PIC) * NOTE: stb_image has been slightly modified to support Android platform. * stb_image_resize - Multiple image resize algorythms * -* Module Configuration Flags: -* ... +* +* LICENSE: zlib/libpng * * Copyright (c) 2014-2016 Ramon Santamaria (@raysan5) * @@ -143,11 +162,11 @@ Image LoadImage(const char *fileName) else if (strcmp(GetExtension(fileName),"astc") == 0) image = LoadASTC(fileName); else if (strcmp(GetExtension(fileName),"rres") == 0) { - RRESData rres = LoadResource(fileName); + RRES rres = LoadResource(fileName, 0); - // NOTE: Parameters for RRES_IMAGE type are: width, height, format, mipmaps + // NOTE: Parameters for RRES_TYPE_IMAGE are: width, height, format, mipmaps - if (rres.type == RRES_IMAGE) image = LoadImagePro(rres.data, rres.param1, rres.param2, rres.param3); + if (rres[0].type == RRES_TYPE_IMAGE) image = LoadImagePro(rres[0].data, rres[0].param1, rres[0].param2, rres[0].param3); else TraceLog(WARNING, "[%s] Resource file does not contain image data", fileName); UnloadResource(rres); diff --git a/src/utils.c b/src/utils.c index e5e05955..9a2a723a 100644 --- a/src/utils.c +++ b/src/utils.c @@ -1,16 +1,23 @@ /********************************************************************************************** * -* raylib.utils +* raylib.utils - Some common utility functions * -* Some utility functions +* CONFIGURATION: * -* External libs: -* tinfl - zlib DEFLATE algorithm decompression +* #define SUPPORT_SAVE_PNG +* Enable saving PNG fileformat +* NOTE: Requires stb_image_write library +* +* #define SUPPORT_SAVE_BMP +* +* #define DO_NOT_TRACE_DEBUG_MSGS +* Avoid showing DEBUG TraceLog() messages +* +* DEPENDENCIES: * stb_image_write - PNG writting functions * -* Module Configuration Flags: -* DO_NOT_TRACE_DEBUG_MSGS - Avoid showing DEBUG TraceLog() messages * +* LICENSE: zlib/libpng * * Copyright (c) 2014-2016 Ramon Santamaria (@raysan5) * -- cgit v1.2.3