minesweeper

A minewseeper implementation to play around with Hare and Raylib
git clone https://git.tronto.net/minesweeper
Download | Log | Files | Refs | README | LICENSE

rcamera.h (21819B)


      1 /*******************************************************************************************
      2 *
      3 *   rcamera - Basic camera system with support for multiple camera modes
      4 *
      5 *   CONFIGURATION:
      6 *       #define RCAMERA_IMPLEMENTATION
      7 *           Generates the implementation of the library into the included file.
      8 *           If not defined, the library is in header only mode and can be included in other headers
      9 *           or source files without problems. But only ONE file should hold the implementation.
     10 *
     11 *       #define RCAMERA_STANDALONE
     12 *           If defined, the library can be used as standalone as a camera system but some
     13 *           functions must be redefined to manage inputs accordingly.
     14 *
     15 *   CONTRIBUTORS:
     16 *       Ramon Santamaria:   Supervision, review, update and maintenance
     17 *       Christoph Wagner:   Complete redesign, using raymath (2022)
     18 *       Marc Palau:         Initial implementation (2014)
     19 *
     20 *
     21 *   LICENSE: zlib/libpng
     22 *
     23 *   Copyright (c) 2022-2024 Christoph Wagner (@Crydsch) & Ramon Santamaria (@raysan5)
     24 *
     25 *   This software is provided "as-is", without any express or implied warranty. In no event
     26 *   will the authors be held liable for any damages arising from the use of this software.
     27 *
     28 *   Permission is granted to anyone to use this software for any purpose, including commercial
     29 *   applications, and to alter it and redistribute it freely, subject to the following restrictions:
     30 *
     31 *     1. The origin of this software must not be misrepresented; you must not claim that you
     32 *     wrote the original software. If you use this software in a product, an acknowledgment
     33 *     in the product documentation would be appreciated but is not required.
     34 *
     35 *     2. Altered source versions must be plainly marked as such, and must not be misrepresented
     36 *     as being the original software.
     37 *
     38 *     3. This notice may not be removed or altered from any source distribution.
     39 *
     40 **********************************************************************************************/
     41 
     42 #ifndef RCAMERA_H
     43 #define RCAMERA_H
     44 
     45 //----------------------------------------------------------------------------------
     46 // Defines and Macros
     47 //----------------------------------------------------------------------------------
     48 // Function specifiers definition
     49 
     50 // Function specifiers in case library is build/used as a shared library (Windows)
     51 // NOTE: Microsoft specifiers to tell compiler that symbols are imported/exported from a .dll
     52 #if defined(_WIN32)
     53 #if defined(BUILD_LIBTYPE_SHARED)
     54 #if defined(__TINYC__)
     55 #define __declspec(x) __attribute__((x))
     56 #endif
     57 #define RLAPI __declspec(dllexport)     // We are building the library as a Win32 shared library (.dll)
     58 #elif defined(USE_LIBTYPE_SHARED)
     59 #define RLAPI __declspec(dllimport)     // We are using the library as a Win32 shared library (.dll)
     60 #endif
     61 #endif
     62 
     63 #ifndef RLAPI
     64     #define RLAPI       // Functions defined as 'extern' by default (implicit specifiers)
     65 #endif
     66 
     67 #if defined(RCAMERA_STANDALONE)
     68     #define CAMERA_CULL_DISTANCE_NEAR      0.01
     69     #define CAMERA_CULL_DISTANCE_FAR    1000.0
     70 #else
     71     #define CAMERA_CULL_DISTANCE_NEAR   RL_CULL_DISTANCE_NEAR
     72     #define CAMERA_CULL_DISTANCE_FAR    RL_CULL_DISTANCE_FAR
     73 #endif
     74 
     75 //----------------------------------------------------------------------------------
     76 // Types and Structures Definition
     77 // NOTE: Below types are required for standalone usage
     78 //----------------------------------------------------------------------------------
     79 #if defined(RCAMERA_STANDALONE)
     80     // Vector2, 2 components
     81     typedef struct Vector2 {
     82         float x;                // Vector x component
     83         float y;                // Vector y component
     84     } Vector2;
     85 
     86     // Vector3, 3 components
     87     typedef struct Vector3 {
     88         float x;                // Vector x component
     89         float y;                // Vector y component
     90         float z;                // Vector z component
     91     } Vector3;
     92 
     93     // Matrix, 4x4 components, column major, OpenGL style, right-handed
     94     typedef struct Matrix {
     95         float m0, m4, m8, m12;  // Matrix first row (4 components)
     96         float m1, m5, m9, m13;  // Matrix second row (4 components)
     97         float m2, m6, m10, m14; // Matrix third row (4 components)
     98         float m3, m7, m11, m15; // Matrix fourth row (4 components)
     99     } Matrix;
    100 
    101     // Camera type, defines a camera position/orientation in 3d space
    102     typedef struct Camera3D {
    103         Vector3 position;       // Camera position
    104         Vector3 target;         // Camera target it looks-at
    105         Vector3 up;             // Camera up vector (rotation over its axis)
    106         float fovy;             // Camera field-of-view apperture in Y (degrees) in perspective, used as near plane width in orthographic
    107         int projection;         // Camera projection type: CAMERA_PERSPECTIVE or CAMERA_ORTHOGRAPHIC
    108     } Camera3D;
    109 
    110     typedef Camera3D Camera;    // Camera type fallback, defaults to Camera3D
    111 
    112     // Camera projection
    113     typedef enum {
    114         CAMERA_PERSPECTIVE = 0, // Perspective projection
    115         CAMERA_ORTHOGRAPHIC     // Orthographic projection
    116     } CameraProjection;
    117 
    118     // Camera system modes
    119     typedef enum {
    120         CAMERA_CUSTOM = 0,      // Camera custom, controlled by user (UpdateCamera() does nothing)
    121         CAMERA_FREE,            // Camera free mode
    122         CAMERA_ORBITAL,         // Camera orbital, around target, zoom supported
    123         CAMERA_FIRST_PERSON,    // Camera first person
    124         CAMERA_THIRD_PERSON     // Camera third person
    125     } CameraMode;
    126 #endif
    127 
    128 //----------------------------------------------------------------------------------
    129 // Global Variables Definition
    130 //----------------------------------------------------------------------------------
    131 //...
    132 
    133 //----------------------------------------------------------------------------------
    134 // Module Functions Declaration
    135 //----------------------------------------------------------------------------------
    136 
    137 #if defined(__cplusplus)
    138 extern "C" {            // Prevents name mangling of functions
    139 #endif
    140 
    141 RLAPI Vector3 GetCameraForward(Camera *camera);
    142 RLAPI Vector3 GetCameraUp(Camera *camera);
    143 RLAPI Vector3 GetCameraRight(Camera *camera);
    144 
    145 // Camera movement
    146 RLAPI void CameraMoveForward(Camera *camera, float distance, bool moveInWorldPlane);
    147 RLAPI void CameraMoveUp(Camera *camera, float distance);
    148 RLAPI void CameraMoveRight(Camera *camera, float distance, bool moveInWorldPlane);
    149 RLAPI void CameraMoveToTarget(Camera *camera, float delta);
    150 
    151 // Camera rotation
    152 RLAPI void CameraYaw(Camera *camera, float angle, bool rotateAroundTarget);
    153 RLAPI void CameraPitch(Camera *camera, float angle, bool lockView, bool rotateAroundTarget, bool rotateUp);
    154 RLAPI void CameraRoll(Camera *camera, float angle);
    155 
    156 RLAPI Matrix GetCameraViewMatrix(Camera *camera);
    157 RLAPI Matrix GetCameraProjectionMatrix(Camera* camera, float aspect);
    158 
    159 #if defined(__cplusplus)
    160 }
    161 #endif
    162 
    163 #endif // RCAMERA_H
    164 
    165 /***********************************************************************************
    166 *
    167 *   CAMERA IMPLEMENTATION
    168 *
    169 ************************************************************************************/
    170 
    171 #if defined(RCAMERA_IMPLEMENTATION)
    172 
    173 #include "raymath.h"        // Required for vector maths:
    174                             // Vector3Add()
    175                             // Vector3Subtract()
    176                             // Vector3Scale()
    177                             // Vector3Normalize()
    178                             // Vector3Distance()
    179                             // Vector3CrossProduct()
    180                             // Vector3RotateByAxisAngle()
    181                             // Vector3Angle()
    182                             // Vector3Negate()
    183                             // MatrixLookAt()
    184                             // MatrixPerspective()
    185                             // MatrixOrtho()
    186                             // MatrixIdentity()
    187 
    188 // raylib required functionality:
    189                             // GetMouseDelta()
    190                             // GetMouseWheelMove()
    191                             // IsKeyDown()
    192                             // IsKeyPressed()
    193                             // GetFrameTime()
    194 
    195 //----------------------------------------------------------------------------------
    196 // Defines and Macros
    197 //----------------------------------------------------------------------------------
    198 #define CAMERA_MOVE_SPEED                               5.4f       // Units per second
    199 #define CAMERA_ROTATION_SPEED                           0.03f
    200 #define CAMERA_PAN_SPEED                                0.2f
    201 
    202 // Camera mouse movement sensitivity
    203 #define CAMERA_MOUSE_MOVE_SENSITIVITY                   0.003f
    204 
    205 // Camera orbital speed in CAMERA_ORBITAL mode
    206 #define CAMERA_ORBITAL_SPEED                            0.5f       // Radians per second
    207 
    208 //----------------------------------------------------------------------------------
    209 // Types and Structures Definition
    210 //----------------------------------------------------------------------------------
    211 //...
    212 
    213 //----------------------------------------------------------------------------------
    214 // Global Variables Definition
    215 //----------------------------------------------------------------------------------
    216 //...
    217 
    218 //----------------------------------------------------------------------------------
    219 // Module specific Functions Declaration
    220 //----------------------------------------------------------------------------------
    221 //...
    222 
    223 //----------------------------------------------------------------------------------
    224 // Module Functions Definition
    225 //----------------------------------------------------------------------------------
    226 // Returns the cameras forward vector (normalized)
    227 Vector3 GetCameraForward(Camera *camera)
    228 {
    229     return Vector3Normalize(Vector3Subtract(camera->target, camera->position));
    230 }
    231 
    232 // Returns the cameras up vector (normalized)
    233 // Note: The up vector might not be perpendicular to the forward vector
    234 Vector3 GetCameraUp(Camera *camera)
    235 {
    236     return Vector3Normalize(camera->up);
    237 }
    238 
    239 // Returns the cameras right vector (normalized)
    240 Vector3 GetCameraRight(Camera *camera)
    241 {
    242     Vector3 forward = GetCameraForward(camera);
    243     Vector3 up = GetCameraUp(camera);
    244 
    245     return Vector3Normalize(Vector3CrossProduct(forward, up));
    246 }
    247 
    248 // Moves the camera in its forward direction
    249 void CameraMoveForward(Camera *camera, float distance, bool moveInWorldPlane)
    250 {
    251     Vector3 forward = GetCameraForward(camera);
    252 
    253     if (moveInWorldPlane)
    254     {
    255         // Project vector onto world plane
    256         forward.y = 0;
    257         forward = Vector3Normalize(forward);
    258     }
    259 
    260     // Scale by distance
    261     forward = Vector3Scale(forward, distance);
    262 
    263     // Move position and target
    264     camera->position = Vector3Add(camera->position, forward);
    265     camera->target = Vector3Add(camera->target, forward);
    266 }
    267 
    268 // Moves the camera in its up direction
    269 void CameraMoveUp(Camera *camera, float distance)
    270 {
    271     Vector3 up = GetCameraUp(camera);
    272 
    273     // Scale by distance
    274     up = Vector3Scale(up, distance);
    275 
    276     // Move position and target
    277     camera->position = Vector3Add(camera->position, up);
    278     camera->target = Vector3Add(camera->target, up);
    279 }
    280 
    281 // Moves the camera target in its current right direction
    282 void CameraMoveRight(Camera *camera, float distance, bool moveInWorldPlane)
    283 {
    284     Vector3 right = GetCameraRight(camera);
    285 
    286     if (moveInWorldPlane)
    287     {
    288         // Project vector onto world plane
    289         right.y = 0;
    290         right = Vector3Normalize(right);
    291     }
    292 
    293     // Scale by distance
    294     right = Vector3Scale(right, distance);
    295 
    296     // Move position and target
    297     camera->position = Vector3Add(camera->position, right);
    298     camera->target = Vector3Add(camera->target, right);
    299 }
    300 
    301 // Moves the camera position closer/farther to/from the camera target
    302 void CameraMoveToTarget(Camera *camera, float delta)
    303 {
    304     float distance = Vector3Distance(camera->position, camera->target);
    305 
    306     // Apply delta
    307     distance += delta;
    308 
    309     // Distance must be greater than 0
    310     if (distance <= 0) distance = 0.001f;
    311 
    312     // Set new distance by moving the position along the forward vector
    313     Vector3 forward = GetCameraForward(camera);
    314     camera->position = Vector3Add(camera->target, Vector3Scale(forward, -distance));
    315 }
    316 
    317 // Rotates the camera around its up vector
    318 // Yaw is "looking left and right"
    319 // If rotateAroundTarget is false, the camera rotates around its position
    320 // Note: angle must be provided in radians
    321 void CameraYaw(Camera *camera, float angle, bool rotateAroundTarget)
    322 {
    323     // Rotation axis
    324     Vector3 up = GetCameraUp(camera);
    325 
    326     // View vector
    327     Vector3 targetPosition = Vector3Subtract(camera->target, camera->position);
    328 
    329     // Rotate view vector around up axis
    330     targetPosition = Vector3RotateByAxisAngle(targetPosition, up, angle);
    331 
    332     if (rotateAroundTarget)
    333     {
    334         // Move position relative to target
    335         camera->position = Vector3Subtract(camera->target, targetPosition);
    336     }
    337     else // rotate around camera.position
    338     {
    339         // Move target relative to position
    340         camera->target = Vector3Add(camera->position, targetPosition);
    341     }
    342 }
    343 
    344 // Rotates the camera around its right vector, pitch is "looking up and down"
    345 //  - lockView prevents camera overrotation (aka "somersaults")
    346 //  - rotateAroundTarget defines if rotation is around target or around its position
    347 //  - rotateUp rotates the up direction as well (typically only usefull in CAMERA_FREE)
    348 // NOTE: angle must be provided in radians
    349 void CameraPitch(Camera *camera, float angle, bool lockView, bool rotateAroundTarget, bool rotateUp)
    350 {
    351     // Up direction
    352     Vector3 up = GetCameraUp(camera);
    353 
    354     // View vector
    355     Vector3 targetPosition = Vector3Subtract(camera->target, camera->position);
    356 
    357     if (lockView)
    358     {
    359         // In these camera modes we clamp the Pitch angle
    360         // to allow only viewing straight up or down.
    361 
    362         // Clamp view up
    363         float maxAngleUp = Vector3Angle(up, targetPosition);
    364         maxAngleUp -= 0.001f; // avoid numerical errors
    365         if (angle > maxAngleUp) angle = maxAngleUp;
    366 
    367         // Clamp view down
    368         float maxAngleDown = Vector3Angle(Vector3Negate(up), targetPosition);
    369         maxAngleDown *= -1.0f; // downwards angle is negative
    370         maxAngleDown += 0.001f; // avoid numerical errors
    371         if (angle < maxAngleDown) angle = maxAngleDown;
    372     }
    373 
    374     // Rotation axis
    375     Vector3 right = GetCameraRight(camera);
    376 
    377     // Rotate view vector around right axis
    378     targetPosition = Vector3RotateByAxisAngle(targetPosition, right, angle);
    379 
    380     if (rotateAroundTarget)
    381     {
    382         // Move position relative to target
    383         camera->position = Vector3Subtract(camera->target, targetPosition);
    384     }
    385     else // rotate around camera.position
    386     {
    387         // Move target relative to position
    388         camera->target = Vector3Add(camera->position, targetPosition);
    389     }
    390 
    391     if (rotateUp)
    392     {
    393         // Rotate up direction around right axis
    394         camera->up = Vector3RotateByAxisAngle(camera->up, right, angle);
    395     }
    396 }
    397 
    398 // Rotates the camera around its forward vector
    399 // Roll is "turning your head sideways to the left or right"
    400 // Note: angle must be provided in radians
    401 void CameraRoll(Camera *camera, float angle)
    402 {
    403     // Rotation axis
    404     Vector3 forward = GetCameraForward(camera);
    405 
    406     // Rotate up direction around forward axis
    407     camera->up = Vector3RotateByAxisAngle(camera->up, forward, angle);
    408 }
    409 
    410 // Returns the camera view matrix
    411 Matrix GetCameraViewMatrix(Camera *camera)
    412 {
    413     return MatrixLookAt(camera->position, camera->target, camera->up);
    414 }
    415 
    416 // Returns the camera projection matrix
    417 Matrix GetCameraProjectionMatrix(Camera *camera, float aspect)
    418 {
    419     if (camera->projection == CAMERA_PERSPECTIVE)
    420     {
    421         return MatrixPerspective(camera->fovy*DEG2RAD, aspect, CAMERA_CULL_DISTANCE_NEAR, CAMERA_CULL_DISTANCE_FAR);
    422     }
    423     else if (camera->projection == CAMERA_ORTHOGRAPHIC)
    424     {
    425         double top = camera->fovy/2.0;
    426         double right = top*aspect;
    427 
    428         return MatrixOrtho(-right, right, -top, top, CAMERA_CULL_DISTANCE_NEAR, CAMERA_CULL_DISTANCE_FAR);
    429     }
    430 
    431     return MatrixIdentity();
    432 }
    433 
    434 #if !defined(RCAMERA_STANDALONE)
    435 // Update camera position for selected mode
    436 // Camera mode: CAMERA_FREE, CAMERA_FIRST_PERSON, CAMERA_THIRD_PERSON, CAMERA_ORBITAL or CUSTOM
    437 void UpdateCamera(Camera *camera, int mode)
    438 {
    439     Vector2 mousePositionDelta = GetMouseDelta();
    440 
    441     bool moveInWorldPlane = ((mode == CAMERA_FIRST_PERSON) || (mode == CAMERA_THIRD_PERSON));
    442     bool rotateAroundTarget = ((mode == CAMERA_THIRD_PERSON) || (mode == CAMERA_ORBITAL));
    443     bool lockView = ((mode == CAMERA_FREE) || (mode == CAMERA_FIRST_PERSON) || (mode == CAMERA_THIRD_PERSON) || (mode == CAMERA_ORBITAL));
    444     bool rotateUp = false;
    445 
    446     // Camera speeds based on frame time
    447     float cameraMoveSpeed = CAMERA_MOVE_SPEED*GetFrameTime();
    448     float cameraRotationSpeed = CAMERA_ROTATION_SPEED*GetFrameTime();
    449     float cameraPanSpeed = CAMERA_PAN_SPEED*GetFrameTime();
    450     float cameraOrbitalSpeed = CAMERA_ORBITAL_SPEED*GetFrameTime();
    451 
    452     if (mode == CAMERA_CUSTOM) {}
    453     else if (mode == CAMERA_ORBITAL)
    454     {
    455         // Orbital can just orbit
    456         Matrix rotation = MatrixRotate(GetCameraUp(camera), cameraOrbitalSpeed);
    457         Vector3 view = Vector3Subtract(camera->position, camera->target);
    458         view = Vector3Transform(view, rotation);
    459         camera->position = Vector3Add(camera->target, view);
    460     }
    461     else
    462     {
    463         // Camera rotation
    464         if (IsKeyDown(KEY_DOWN)) CameraPitch(camera, -cameraRotationSpeed, lockView, rotateAroundTarget, rotateUp);
    465         if (IsKeyDown(KEY_UP)) CameraPitch(camera, cameraRotationSpeed, lockView, rotateAroundTarget, rotateUp);
    466         if (IsKeyDown(KEY_RIGHT)) CameraYaw(camera, -cameraRotationSpeed, rotateAroundTarget);
    467         if (IsKeyDown(KEY_LEFT)) CameraYaw(camera, cameraRotationSpeed, rotateAroundTarget);
    468         if (IsKeyDown(KEY_Q)) CameraRoll(camera, -cameraRotationSpeed);
    469         if (IsKeyDown(KEY_E)) CameraRoll(camera, cameraRotationSpeed);
    470 
    471         // Camera movement
    472         // Camera pan (for CAMERA_FREE)
    473         if ((mode == CAMERA_FREE) && (IsMouseButtonDown(MOUSE_BUTTON_MIDDLE)))
    474         {
    475             const Vector2 mouseDelta = GetMouseDelta();
    476             if (mouseDelta.x > 0.0f) CameraMoveRight(camera, cameraPanSpeed, moveInWorldPlane);
    477             if (mouseDelta.x < 0.0f) CameraMoveRight(camera, -cameraPanSpeed, moveInWorldPlane);
    478             if (mouseDelta.y > 0.0f) CameraMoveUp(camera, -cameraPanSpeed);
    479             if (mouseDelta.y < 0.0f) CameraMoveUp(camera, cameraPanSpeed);
    480         }
    481         else
    482         {
    483             // Mouse support
    484             CameraYaw(camera, -mousePositionDelta.x*CAMERA_MOUSE_MOVE_SENSITIVITY, rotateAroundTarget);
    485             CameraPitch(camera, -mousePositionDelta.y*CAMERA_MOUSE_MOVE_SENSITIVITY, lockView, rotateAroundTarget, rotateUp);
    486         }
    487 
    488         // Keyboard support
    489         if (IsKeyDown(KEY_W)) CameraMoveForward(camera, cameraMoveSpeed, moveInWorldPlane);
    490         if (IsKeyDown(KEY_A)) CameraMoveRight(camera, -cameraMoveSpeed, moveInWorldPlane);
    491         if (IsKeyDown(KEY_S)) CameraMoveForward(camera, -cameraMoveSpeed, moveInWorldPlane);
    492         if (IsKeyDown(KEY_D)) CameraMoveRight(camera, cameraMoveSpeed, moveInWorldPlane);
    493 
    494         // Gamepad movement
    495         if (IsGamepadAvailable(0))
    496         {
    497             // Gamepad controller support
    498             CameraYaw(camera, -(GetGamepadAxisMovement(0, GAMEPAD_AXIS_RIGHT_X)*2)*CAMERA_MOUSE_MOVE_SENSITIVITY, rotateAroundTarget);
    499             CameraPitch(camera, -(GetGamepadAxisMovement(0, GAMEPAD_AXIS_RIGHT_Y)*2)*CAMERA_MOUSE_MOVE_SENSITIVITY, lockView, rotateAroundTarget, rotateUp);
    500 
    501             if (GetGamepadAxisMovement(0, GAMEPAD_AXIS_LEFT_Y) <= -0.25f) CameraMoveForward(camera, cameraMoveSpeed, moveInWorldPlane);
    502             if (GetGamepadAxisMovement(0, GAMEPAD_AXIS_LEFT_X) <= -0.25f) CameraMoveRight(camera, -cameraMoveSpeed, moveInWorldPlane);
    503             if (GetGamepadAxisMovement(0, GAMEPAD_AXIS_LEFT_Y) >= 0.25f) CameraMoveForward(camera, -cameraMoveSpeed, moveInWorldPlane);
    504             if (GetGamepadAxisMovement(0, GAMEPAD_AXIS_LEFT_X) >= 0.25f) CameraMoveRight(camera, cameraMoveSpeed, moveInWorldPlane);
    505         }
    506 
    507         if (mode == CAMERA_FREE)
    508         {
    509             if (IsKeyDown(KEY_SPACE)) CameraMoveUp(camera, cameraMoveSpeed);
    510             if (IsKeyDown(KEY_LEFT_CONTROL)) CameraMoveUp(camera, -cameraMoveSpeed);
    511         }
    512     }
    513 
    514     if ((mode == CAMERA_THIRD_PERSON) || (mode == CAMERA_ORBITAL) || (mode == CAMERA_FREE))
    515     {
    516         // Zoom target distance
    517         CameraMoveToTarget(camera, -GetMouseWheelMove());
    518         if (IsKeyPressed(KEY_KP_SUBTRACT)) CameraMoveToTarget(camera, 2.0f);
    519         if (IsKeyPressed(KEY_KP_ADD)) CameraMoveToTarget(camera, -2.0f);
    520     }
    521 }
    522 #endif // !RCAMERA_STANDALONE
    523 
    524 // Update camera movement, movement/rotation values should be provided by user
    525 void UpdateCameraPro(Camera *camera, Vector3 movement, Vector3 rotation, float zoom)
    526 {
    527     // Required values
    528     // movement.x - Move forward/backward
    529     // movement.y - Move right/left
    530     // movement.z - Move up/down
    531     // rotation.x - yaw
    532     // rotation.y - pitch
    533     // rotation.z - roll
    534     // zoom - Move towards target
    535 
    536     bool lockView = true;
    537     bool rotateAroundTarget = false;
    538     bool rotateUp = false;
    539     bool moveInWorldPlane = true;
    540 
    541     // Camera rotation
    542     CameraPitch(camera, -rotation.y*DEG2RAD, lockView, rotateAroundTarget, rotateUp);
    543     CameraYaw(camera, -rotation.x*DEG2RAD, rotateAroundTarget);
    544     CameraRoll(camera, rotation.z*DEG2RAD);
    545 
    546     // Camera movement
    547     CameraMoveForward(camera, movement.x, moveInWorldPlane);
    548     CameraMoveRight(camera, movement.y, moveInWorldPlane);
    549     CameraMoveUp(camera, movement.z);
    550 
    551     // Zoom target distance
    552     CameraMoveToTarget(camera, zoom);
    553 }
    554 
    555 #endif // RCAMERA_IMPLEMENTATION