aboutsummaryrefslogtreecommitdiff
path: root/deps/raylib/src/rcamera.h
diff options
context:
space:
mode:
authorbonmas14 <bonmas14@gmail.com>2025-09-20 22:28:15 +0300
committerbonmas14 <bonmas14@gmail.com>2025-09-20 22:28:15 +0300
commitcdda4c4182c9ee068567529715e4a5c68a8efb58 (patch)
tree38a63f62a64018a2d35fc33354f8589fd33b7514 /deps/raylib/src/rcamera.h
downloadc_wizard-cdda4c4182c9ee068567529715e4a5c68a8efb58.tar.gz
c_wizard-cdda4c4182c9ee068567529715e4a5c68a8efb58.zip
Init commit v1.0
Diffstat (limited to 'deps/raylib/src/rcamera.h')
-rw-r--r--deps/raylib/src/rcamera.h555
1 files changed, 555 insertions, 0 deletions
diff --git a/deps/raylib/src/rcamera.h b/deps/raylib/src/rcamera.h
new file mode 100644
index 0000000..bd2b36e
--- /dev/null
+++ b/deps/raylib/src/rcamera.h
@@ -0,0 +1,555 @@
+/*******************************************************************************************
+*
+* rcamera - Basic camera system with support for multiple camera modes
+*
+* CONFIGURATION:
+* #define RCAMERA_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 RCAMERA_STANDALONE
+* If defined, the library can be used as standalone as a camera system but some
+* functions must be redefined to manage inputs accordingly.
+*
+* CONTRIBUTORS:
+* Ramon Santamaria: Supervision, review, update and maintenance
+* Christoph Wagner: Complete redesign, using raymath (2022)
+* Marc Palau: Initial implementation (2014)
+*
+*
+* LICENSE: zlib/libpng
+*
+* Copyright (c) 2022-2024 Christoph Wagner (@Crydsch) & 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.
+*
+**********************************************************************************************/
+
+#ifndef RCAMERA_H
+#define RCAMERA_H
+
+//----------------------------------------------------------------------------------
+// Defines and Macros
+//----------------------------------------------------------------------------------
+// Function specifiers definition
+
+// Function specifiers in case library is build/used as a shared library (Windows)
+// NOTE: Microsoft specifiers to tell compiler that symbols are imported/exported from a .dll
+#if defined(_WIN32)
+#if defined(BUILD_LIBTYPE_SHARED)
+#if defined(__TINYC__)
+#define __declspec(x) __attribute__((x))
+#endif
+#define RLAPI __declspec(dllexport) // We are building the library as a Win32 shared library (.dll)
+#elif defined(USE_LIBTYPE_SHARED)
+#define RLAPI __declspec(dllimport) // We are using the library as a Win32 shared library (.dll)
+#endif
+#endif
+
+#ifndef RLAPI
+ #define RLAPI // Functions defined as 'extern' by default (implicit specifiers)
+#endif
+
+#if defined(RCAMERA_STANDALONE)
+ #define CAMERA_CULL_DISTANCE_NEAR 0.01
+ #define CAMERA_CULL_DISTANCE_FAR 1000.0
+#else
+ #define CAMERA_CULL_DISTANCE_NEAR RL_CULL_DISTANCE_NEAR
+ #define CAMERA_CULL_DISTANCE_FAR RL_CULL_DISTANCE_FAR
+#endif
+
+//----------------------------------------------------------------------------------
+// Types and Structures Definition
+// NOTE: Below types are required for standalone usage
+//----------------------------------------------------------------------------------
+#if defined(RCAMERA_STANDALONE)
+ // Vector2, 2 components
+ typedef struct Vector2 {
+ float x; // Vector x component
+ float y; // Vector y component
+ } Vector2;
+
+ // Vector3, 3 components
+ typedef struct Vector3 {
+ float x; // Vector x component
+ float y; // Vector y component
+ float z; // Vector z component
+ } Vector3;
+
+ // Matrix, 4x4 components, column major, OpenGL style, right-handed
+ typedef struct Matrix {
+ float m0, m4, m8, m12; // Matrix first row (4 components)
+ float m1, m5, m9, m13; // Matrix second row (4 components)
+ float m2, m6, m10, m14; // Matrix third row (4 components)
+ float m3, m7, m11, m15; // Matrix fourth row (4 components)
+ } Matrix;
+
+ // Camera type, defines a camera position/orientation in 3d space
+ typedef struct Camera3D {
+ Vector3 position; // Camera position
+ Vector3 target; // Camera target it looks-at
+ Vector3 up; // Camera up vector (rotation over its axis)
+ float fovy; // Camera field-of-view apperture in Y (degrees) in perspective, used as near plane width in orthographic
+ int projection; // Camera projection type: CAMERA_PERSPECTIVE or CAMERA_ORTHOGRAPHIC
+ } Camera3D;
+
+ typedef Camera3D Camera; // Camera type fallback, defaults to Camera3D
+
+ // Camera projection
+ typedef enum {
+ CAMERA_PERSPECTIVE = 0, // Perspective projection
+ CAMERA_ORTHOGRAPHIC // Orthographic projection
+ } CameraProjection;
+
+ // Camera system modes
+ typedef enum {
+ CAMERA_CUSTOM = 0, // Camera custom, controlled by user (UpdateCamera() does nothing)
+ CAMERA_FREE, // Camera free mode
+ CAMERA_ORBITAL, // Camera orbital, around target, zoom supported
+ CAMERA_FIRST_PERSON, // Camera first person
+ CAMERA_THIRD_PERSON // Camera third person
+ } CameraMode;
+#endif
+
+//----------------------------------------------------------------------------------
+// Global Variables Definition
+//----------------------------------------------------------------------------------
+//...
+
+//----------------------------------------------------------------------------------
+// Module Functions Declaration
+//----------------------------------------------------------------------------------
+
+#if defined(__cplusplus)
+extern "C" { // Prevents name mangling of functions
+#endif
+
+RLAPI Vector3 GetCameraForward(Camera *camera);
+RLAPI Vector3 GetCameraUp(Camera *camera);
+RLAPI Vector3 GetCameraRight(Camera *camera);
+
+// Camera movement
+RLAPI void CameraMoveForward(Camera *camera, float distance, bool moveInWorldPlane);
+RLAPI void CameraMoveUp(Camera *camera, float distance);
+RLAPI void CameraMoveRight(Camera *camera, float distance, bool moveInWorldPlane);
+RLAPI void CameraMoveToTarget(Camera *camera, float delta);
+
+// Camera rotation
+RLAPI void CameraYaw(Camera *camera, float angle, bool rotateAroundTarget);
+RLAPI void CameraPitch(Camera *camera, float angle, bool lockView, bool rotateAroundTarget, bool rotateUp);
+RLAPI void CameraRoll(Camera *camera, float angle);
+
+RLAPI Matrix GetCameraViewMatrix(Camera *camera);
+RLAPI Matrix GetCameraProjectionMatrix(Camera* camera, float aspect);
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif // RCAMERA_H
+
+/***********************************************************************************
+*
+* CAMERA IMPLEMENTATION
+*
+************************************************************************************/
+
+#if defined(RCAMERA_IMPLEMENTATION)
+
+#include "raymath.h" // Required for vector maths:
+ // Vector3Add()
+ // Vector3Subtract()
+ // Vector3Scale()
+ // Vector3Normalize()
+ // Vector3Distance()
+ // Vector3CrossProduct()
+ // Vector3RotateByAxisAngle()
+ // Vector3Angle()
+ // Vector3Negate()
+ // MatrixLookAt()
+ // MatrixPerspective()
+ // MatrixOrtho()
+ // MatrixIdentity()
+
+// raylib required functionality:
+ // GetMouseDelta()
+ // GetMouseWheelMove()
+ // IsKeyDown()
+ // IsKeyPressed()
+ // GetFrameTime()
+
+//----------------------------------------------------------------------------------
+// Defines and Macros
+//----------------------------------------------------------------------------------
+#define CAMERA_MOVE_SPEED 5.4f // Units per second
+#define CAMERA_ROTATION_SPEED 0.03f
+#define CAMERA_PAN_SPEED 0.2f
+
+// Camera mouse movement sensitivity
+#define CAMERA_MOUSE_MOVE_SENSITIVITY 0.003f
+
+// Camera orbital speed in CAMERA_ORBITAL mode
+#define CAMERA_ORBITAL_SPEED 0.5f // Radians per second
+
+//----------------------------------------------------------------------------------
+// Types and Structures Definition
+//----------------------------------------------------------------------------------
+//...
+
+//----------------------------------------------------------------------------------
+// Global Variables Definition
+//----------------------------------------------------------------------------------
+//...
+
+//----------------------------------------------------------------------------------
+// Module specific Functions Declaration
+//----------------------------------------------------------------------------------
+//...
+
+//----------------------------------------------------------------------------------
+// Module Functions Definition
+//----------------------------------------------------------------------------------
+// Returns the cameras forward vector (normalized)
+Vector3 GetCameraForward(Camera *camera)
+{
+ return Vector3Normalize(Vector3Subtract(camera->target, camera->position));
+}
+
+// Returns the cameras up vector (normalized)
+// Note: The up vector might not be perpendicular to the forward vector
+Vector3 GetCameraUp(Camera *camera)
+{
+ return Vector3Normalize(camera->up);
+}
+
+// Returns the cameras right vector (normalized)
+Vector3 GetCameraRight(Camera *camera)
+{
+ Vector3 forward = GetCameraForward(camera);
+ Vector3 up = GetCameraUp(camera);
+
+ return Vector3Normalize(Vector3CrossProduct(forward, up));
+}
+
+// Moves the camera in its forward direction
+void CameraMoveForward(Camera *camera, float distance, bool moveInWorldPlane)
+{
+ Vector3 forward = GetCameraForward(camera);
+
+ if (moveInWorldPlane)
+ {
+ // Project vector onto world plane
+ forward.y = 0;
+ forward = Vector3Normalize(forward);
+ }
+
+ // Scale by distance
+ forward = Vector3Scale(forward, distance);
+
+ // Move position and target
+ camera->position = Vector3Add(camera->position, forward);
+ camera->target = Vector3Add(camera->target, forward);
+}
+
+// Moves the camera in its up direction
+void CameraMoveUp(Camera *camera, float distance)
+{
+ Vector3 up = GetCameraUp(camera);
+
+ // Scale by distance
+ up = Vector3Scale(up, distance);
+
+ // Move position and target
+ camera->position = Vector3Add(camera->position, up);
+ camera->target = Vector3Add(camera->target, up);
+}
+
+// Moves the camera target in its current right direction
+void CameraMoveRight(Camera *camera, float distance, bool moveInWorldPlane)
+{
+ Vector3 right = GetCameraRight(camera);
+
+ if (moveInWorldPlane)
+ {
+ // Project vector onto world plane
+ right.y = 0;
+ right = Vector3Normalize(right);
+ }
+
+ // Scale by distance
+ right = Vector3Scale(right, distance);
+
+ // Move position and target
+ camera->position = Vector3Add(camera->position, right);
+ camera->target = Vector3Add(camera->target, right);
+}
+
+// Moves the camera position closer/farther to/from the camera target
+void CameraMoveToTarget(Camera *camera, float delta)
+{
+ float distance = Vector3Distance(camera->position, camera->target);
+
+ // Apply delta
+ distance += delta;
+
+ // Distance must be greater than 0
+ if (distance <= 0) distance = 0.001f;
+
+ // Set new distance by moving the position along the forward vector
+ Vector3 forward = GetCameraForward(camera);
+ camera->position = Vector3Add(camera->target, Vector3Scale(forward, -distance));
+}
+
+// Rotates the camera around its up vector
+// Yaw is "looking left and right"
+// If rotateAroundTarget is false, the camera rotates around its position
+// Note: angle must be provided in radians
+void CameraYaw(Camera *camera, float angle, bool rotateAroundTarget)
+{
+ // Rotation axis
+ Vector3 up = GetCameraUp(camera);
+
+ // View vector
+ Vector3 targetPosition = Vector3Subtract(camera->target, camera->position);
+
+ // Rotate view vector around up axis
+ targetPosition = Vector3RotateByAxisAngle(targetPosition, up, angle);
+
+ if (rotateAroundTarget)
+ {
+ // Move position relative to target
+ camera->position = Vector3Subtract(camera->target, targetPosition);
+ }
+ else // rotate around camera.position
+ {
+ // Move target relative to position
+ camera->target = Vector3Add(camera->position, targetPosition);
+ }
+}
+
+// Rotates the camera around its right vector, pitch is "looking up and down"
+// - lockView prevents camera overrotation (aka "somersaults")
+// - rotateAroundTarget defines if rotation is around target or around its position
+// - rotateUp rotates the up direction as well (typically only usefull in CAMERA_FREE)
+// NOTE: angle must be provided in radians
+void CameraPitch(Camera *camera, float angle, bool lockView, bool rotateAroundTarget, bool rotateUp)
+{
+ // Up direction
+ Vector3 up = GetCameraUp(camera);
+
+ // View vector
+ Vector3 targetPosition = Vector3Subtract(camera->target, camera->position);
+
+ if (lockView)
+ {
+ // In these camera modes we clamp the Pitch angle
+ // to allow only viewing straight up or down.
+
+ // Clamp view up
+ float maxAngleUp = Vector3Angle(up, targetPosition);
+ maxAngleUp -= 0.001f; // avoid numerical errors
+ if (angle > maxAngleUp) angle = maxAngleUp;
+
+ // Clamp view down
+ float maxAngleDown = Vector3Angle(Vector3Negate(up), targetPosition);
+ maxAngleDown *= -1.0f; // downwards angle is negative
+ maxAngleDown += 0.001f; // avoid numerical errors
+ if (angle < maxAngleDown) angle = maxAngleDown;
+ }
+
+ // Rotation axis
+ Vector3 right = GetCameraRight(camera);
+
+ // Rotate view vector around right axis
+ targetPosition = Vector3RotateByAxisAngle(targetPosition, right, angle);
+
+ if (rotateAroundTarget)
+ {
+ // Move position relative to target
+ camera->position = Vector3Subtract(camera->target, targetPosition);
+ }
+ else // rotate around camera.position
+ {
+ // Move target relative to position
+ camera->target = Vector3Add(camera->position, targetPosition);
+ }
+
+ if (rotateUp)
+ {
+ // Rotate up direction around right axis
+ camera->up = Vector3RotateByAxisAngle(camera->up, right, angle);
+ }
+}
+
+// Rotates the camera around its forward vector
+// Roll is "turning your head sideways to the left or right"
+// Note: angle must be provided in radians
+void CameraRoll(Camera *camera, float angle)
+{
+ // Rotation axis
+ Vector3 forward = GetCameraForward(camera);
+
+ // Rotate up direction around forward axis
+ camera->up = Vector3RotateByAxisAngle(camera->up, forward, angle);
+}
+
+// Returns the camera view matrix
+Matrix GetCameraViewMatrix(Camera *camera)
+{
+ return MatrixLookAt(camera->position, camera->target, camera->up);
+}
+
+// Returns the camera projection matrix
+Matrix GetCameraProjectionMatrix(Camera *camera, float aspect)
+{
+ if (camera->projection == CAMERA_PERSPECTIVE)
+ {
+ return MatrixPerspective(camera->fovy*DEG2RAD, aspect, CAMERA_CULL_DISTANCE_NEAR, CAMERA_CULL_DISTANCE_FAR);
+ }
+ else if (camera->projection == CAMERA_ORTHOGRAPHIC)
+ {
+ double top = camera->fovy/2.0;
+ double right = top*aspect;
+
+ return MatrixOrtho(-right, right, -top, top, CAMERA_CULL_DISTANCE_NEAR, CAMERA_CULL_DISTANCE_FAR);
+ }
+
+ return MatrixIdentity();
+}
+
+#if !defined(RCAMERA_STANDALONE)
+// Update camera position for selected mode
+// Camera mode: CAMERA_FREE, CAMERA_FIRST_PERSON, CAMERA_THIRD_PERSON, CAMERA_ORBITAL or CUSTOM
+void UpdateCamera(Camera *camera, int mode)
+{
+ Vector2 mousePositionDelta = GetMouseDelta();
+
+ bool moveInWorldPlane = ((mode == CAMERA_FIRST_PERSON) || (mode == CAMERA_THIRD_PERSON));
+ bool rotateAroundTarget = ((mode == CAMERA_THIRD_PERSON) || (mode == CAMERA_ORBITAL));
+ bool lockView = ((mode == CAMERA_FREE) || (mode == CAMERA_FIRST_PERSON) || (mode == CAMERA_THIRD_PERSON) || (mode == CAMERA_ORBITAL));
+ bool rotateUp = false;
+
+ // Camera speeds based on frame time
+ float cameraMoveSpeed = CAMERA_MOVE_SPEED*GetFrameTime();
+ float cameraRotationSpeed = CAMERA_ROTATION_SPEED*GetFrameTime();
+ float cameraPanSpeed = CAMERA_PAN_SPEED*GetFrameTime();
+ float cameraOrbitalSpeed = CAMERA_ORBITAL_SPEED*GetFrameTime();
+
+ if (mode == CAMERA_CUSTOM) {}
+ else if (mode == CAMERA_ORBITAL)
+ {
+ // Orbital can just orbit
+ Matrix rotation = MatrixRotate(GetCameraUp(camera), cameraOrbitalSpeed);
+ Vector3 view = Vector3Subtract(camera->position, camera->target);
+ view = Vector3Transform(view, rotation);
+ camera->position = Vector3Add(camera->target, view);
+ }
+ else
+ {
+ // Camera rotation
+ if (IsKeyDown(KEY_DOWN)) CameraPitch(camera, -cameraRotationSpeed, lockView, rotateAroundTarget, rotateUp);
+ if (IsKeyDown(KEY_UP)) CameraPitch(camera, cameraRotationSpeed, lockView, rotateAroundTarget, rotateUp);
+ if (IsKeyDown(KEY_RIGHT)) CameraYaw(camera, -cameraRotationSpeed, rotateAroundTarget);
+ if (IsKeyDown(KEY_LEFT)) CameraYaw(camera, cameraRotationSpeed, rotateAroundTarget);
+ if (IsKeyDown(KEY_Q)) CameraRoll(camera, -cameraRotationSpeed);
+ if (IsKeyDown(KEY_E)) CameraRoll(camera, cameraRotationSpeed);
+
+ // Camera movement
+ // Camera pan (for CAMERA_FREE)
+ if ((mode == CAMERA_FREE) && (IsMouseButtonDown(MOUSE_BUTTON_MIDDLE)))
+ {
+ const Vector2 mouseDelta = GetMouseDelta();
+ if (mouseDelta.x > 0.0f) CameraMoveRight(camera, cameraPanSpeed, moveInWorldPlane);
+ if (mouseDelta.x < 0.0f) CameraMoveRight(camera, -cameraPanSpeed, moveInWorldPlane);
+ if (mouseDelta.y > 0.0f) CameraMoveUp(camera, -cameraPanSpeed);
+ if (mouseDelta.y < 0.0f) CameraMoveUp(camera, cameraPanSpeed);
+ }
+ else
+ {
+ // Mouse support
+ CameraYaw(camera, -mousePositionDelta.x*CAMERA_MOUSE_MOVE_SENSITIVITY, rotateAroundTarget);
+ CameraPitch(camera, -mousePositionDelta.y*CAMERA_MOUSE_MOVE_SENSITIVITY, lockView, rotateAroundTarget, rotateUp);
+ }
+
+ // Keyboard support
+ if (IsKeyDown(KEY_W)) CameraMoveForward(camera, cameraMoveSpeed, moveInWorldPlane);
+ if (IsKeyDown(KEY_A)) CameraMoveRight(camera, -cameraMoveSpeed, moveInWorldPlane);
+ if (IsKeyDown(KEY_S)) CameraMoveForward(camera, -cameraMoveSpeed, moveInWorldPlane);
+ if (IsKeyDown(KEY_D)) CameraMoveRight(camera, cameraMoveSpeed, moveInWorldPlane);
+
+ // Gamepad movement
+ if (IsGamepadAvailable(0))
+ {
+ // Gamepad controller support
+ CameraYaw(camera, -(GetGamepadAxisMovement(0, GAMEPAD_AXIS_RIGHT_X)*2)*CAMERA_MOUSE_MOVE_SENSITIVITY, rotateAroundTarget);
+ CameraPitch(camera, -(GetGamepadAxisMovement(0, GAMEPAD_AXIS_RIGHT_Y)*2)*CAMERA_MOUSE_MOVE_SENSITIVITY, lockView, rotateAroundTarget, rotateUp);
+
+ if (GetGamepadAxisMovement(0, GAMEPAD_AXIS_LEFT_Y) <= -0.25f) CameraMoveForward(camera, cameraMoveSpeed, moveInWorldPlane);
+ if (GetGamepadAxisMovement(0, GAMEPAD_AXIS_LEFT_X) <= -0.25f) CameraMoveRight(camera, -cameraMoveSpeed, moveInWorldPlane);
+ if (GetGamepadAxisMovement(0, GAMEPAD_AXIS_LEFT_Y) >= 0.25f) CameraMoveForward(camera, -cameraMoveSpeed, moveInWorldPlane);
+ if (GetGamepadAxisMovement(0, GAMEPAD_AXIS_LEFT_X) >= 0.25f) CameraMoveRight(camera, cameraMoveSpeed, moveInWorldPlane);
+ }
+
+ if (mode == CAMERA_FREE)
+ {
+ if (IsKeyDown(KEY_SPACE)) CameraMoveUp(camera, cameraMoveSpeed);
+ if (IsKeyDown(KEY_LEFT_CONTROL)) CameraMoveUp(camera, -cameraMoveSpeed);
+ }
+ }
+
+ if ((mode == CAMERA_THIRD_PERSON) || (mode == CAMERA_ORBITAL) || (mode == CAMERA_FREE))
+ {
+ // Zoom target distance
+ CameraMoveToTarget(camera, -GetMouseWheelMove());
+ if (IsKeyPressed(KEY_KP_SUBTRACT)) CameraMoveToTarget(camera, 2.0f);
+ if (IsKeyPressed(KEY_KP_ADD)) CameraMoveToTarget(camera, -2.0f);
+ }
+}
+#endif // !RCAMERA_STANDALONE
+
+// Update camera movement, movement/rotation values should be provided by user
+void UpdateCameraPro(Camera *camera, Vector3 movement, Vector3 rotation, float zoom)
+{
+ // Required values
+ // movement.x - Move forward/backward
+ // movement.y - Move right/left
+ // movement.z - Move up/down
+ // rotation.x - yaw
+ // rotation.y - pitch
+ // rotation.z - roll
+ // zoom - Move towards target
+
+ bool lockView = true;
+ bool rotateAroundTarget = false;
+ bool rotateUp = false;
+ bool moveInWorldPlane = true;
+
+ // Camera rotation
+ CameraPitch(camera, -rotation.y*DEG2RAD, lockView, rotateAroundTarget, rotateUp);
+ CameraYaw(camera, -rotation.x*DEG2RAD, rotateAroundTarget);
+ CameraRoll(camera, rotation.z*DEG2RAD);
+
+ // Camera movement
+ CameraMoveForward(camera, movement.x, moveInWorldPlane);
+ CameraMoveRight(camera, movement.y, moveInWorldPlane);
+ CameraMoveUp(camera, movement.z);
+
+ // Zoom target distance
+ CameraMoveToTarget(camera, zoom);
+}
+
+#endif // RCAMERA_IMPLEMENTATION