diff options
| author | Sebastiano Tronto <sebastiano@tronto.net> | 2025-04-21 11:09:56 +0200 |
|---|---|---|
| committer | Sebastiano Tronto <sebastiano@tronto.net> | 2025-04-21 11:09:56 +0200 |
| commit | 123144c93bfc77883c8fb517828b47bbe13b8671 (patch) | |
| tree | 762739afedb5f3f168051367515cb9b9a06ec68d /raylib/src/rcamera.h | |
| download | minesweeper-master.tar.gz minesweeper-master.zip | |
Diffstat (limited to 'raylib/src/rcamera.h')
| -rw-r--r-- | raylib/src/rcamera.h | 555 |
1 files changed, 555 insertions, 0 deletions
diff --git a/raylib/src/rcamera.h b/raylib/src/rcamera.h new file mode 100644 index 0000000..bd2b36e --- /dev/null +++ b/raylib/src/rcamera.h | |||
| @@ -0,0 +1,555 @@ | |||
| 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 | ||
