rcamera.h 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555
  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-2025 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. #ifndef RCAMERA_H
  42. #define RCAMERA_H
  43. //----------------------------------------------------------------------------------
  44. // Defines and Macros
  45. //----------------------------------------------------------------------------------
  46. // Function specifiers definition
  47. // Function specifiers in case library is build/used as a shared library (Windows)
  48. // NOTE: Microsoft specifiers to tell compiler that symbols are imported/exported from a .dll
  49. #if defined(_WIN32)
  50. #if defined(BUILD_LIBTYPE_SHARED)
  51. #if defined(__TINYC__)
  52. #define __declspec(x) __attribute__((x))
  53. #endif
  54. #define RLAPI __declspec(dllexport) // We are building the library as a Win32 shared library (.dll)
  55. #elif defined(USE_LIBTYPE_SHARED)
  56. #define RLAPI __declspec(dllimport) // We are using the library as a Win32 shared library (.dll)
  57. #endif
  58. #endif
  59. #ifndef RLAPI
  60. #define RLAPI // Functions defined as 'extern' by default (implicit specifiers)
  61. #endif
  62. #if defined(RCAMERA_STANDALONE)
  63. #define CAMERA_CULL_DISTANCE_NEAR 0.05
  64. #define CAMERA_CULL_DISTANCE_FAR 4000.0
  65. #else
  66. #define CAMERA_CULL_DISTANCE_NEAR RL_CULL_DISTANCE_NEAR
  67. #define CAMERA_CULL_DISTANCE_FAR RL_CULL_DISTANCE_FAR
  68. #endif
  69. //----------------------------------------------------------------------------------
  70. // Types and Structures Definition
  71. // NOTE: Below types are required for standalone usage
  72. //----------------------------------------------------------------------------------
  73. #if defined(RCAMERA_STANDALONE)
  74. // Vector2, 2 components
  75. typedef struct Vector2 {
  76. float x; // Vector x component
  77. float y; // Vector y component
  78. } Vector2;
  79. // Vector3, 3 components
  80. typedef struct Vector3 {
  81. float x; // Vector x component
  82. float y; // Vector y component
  83. float z; // Vector z component
  84. } Vector3;
  85. // Matrix, 4x4 components, column major, OpenGL style, right-handed
  86. typedef struct Matrix {
  87. float m0, m4, m8, m12; // Matrix first row (4 components)
  88. float m1, m5, m9, m13; // Matrix second row (4 components)
  89. float m2, m6, m10, m14; // Matrix third row (4 components)
  90. float m3, m7, m11, m15; // Matrix fourth row (4 components)
  91. } Matrix;
  92. // Camera type, defines a camera position/orientation in 3d space
  93. typedef struct Camera3D {
  94. Vector3 position; // Camera position
  95. Vector3 target; // Camera target it looks-at
  96. Vector3 up; // Camera up vector (rotation over its axis)
  97. float fovy; // Camera field-of-view apperture in Y (degrees) in perspective, used as near plane width in orthographic
  98. int projection; // Camera projection type: CAMERA_PERSPECTIVE or CAMERA_ORTHOGRAPHIC
  99. } Camera3D;
  100. typedef Camera3D Camera; // Camera type fallback, defaults to Camera3D
  101. // Camera projection
  102. typedef enum {
  103. CAMERA_PERSPECTIVE = 0, // Perspective projection
  104. CAMERA_ORTHOGRAPHIC // Orthographic projection
  105. } CameraProjection;
  106. // Camera system modes
  107. typedef enum {
  108. CAMERA_CUSTOM = 0, // Camera custom, controlled by user (UpdateCamera() does nothing)
  109. CAMERA_FREE, // Camera free mode
  110. CAMERA_ORBITAL, // Camera orbital, around target, zoom supported
  111. CAMERA_FIRST_PERSON, // Camera first person
  112. CAMERA_THIRD_PERSON // Camera third person
  113. } CameraMode;
  114. #endif
  115. //----------------------------------------------------------------------------------
  116. // Global Variables Definition
  117. //----------------------------------------------------------------------------------
  118. //...
  119. //----------------------------------------------------------------------------------
  120. // Module Functions Declaration
  121. //----------------------------------------------------------------------------------
  122. #if defined(__cplusplus)
  123. extern "C" { // Prevents name mangling of functions
  124. #endif
  125. RLAPI Vector3 GetCameraForward(Camera *camera);
  126. RLAPI Vector3 GetCameraUp(Camera *camera);
  127. RLAPI Vector3 GetCameraRight(Camera *camera);
  128. // Camera movement
  129. RLAPI void CameraMoveForward(Camera *camera, float distance, bool moveInWorldPlane);
  130. RLAPI void CameraMoveUp(Camera *camera, float distance);
  131. RLAPI void CameraMoveRight(Camera *camera, float distance, bool moveInWorldPlane);
  132. RLAPI void CameraMoveToTarget(Camera *camera, float delta);
  133. // Camera rotation
  134. RLAPI void CameraYaw(Camera *camera, float angle, bool rotateAroundTarget);
  135. RLAPI void CameraPitch(Camera *camera, float angle, bool lockView, bool rotateAroundTarget, bool rotateUp);
  136. RLAPI void CameraRoll(Camera *camera, float angle);
  137. RLAPI Matrix GetCameraViewMatrix(Camera *camera);
  138. RLAPI Matrix GetCameraProjectionMatrix(Camera *camera, float aspect);
  139. #if defined(__cplusplus)
  140. }
  141. #endif
  142. #endif // RCAMERA_H
  143. /***********************************************************************************
  144. *
  145. * CAMERA IMPLEMENTATION
  146. *
  147. ************************************************************************************/
  148. #if defined(RCAMERA_IMPLEMENTATION)
  149. #include "raymath.h" // Required for vector maths:
  150. // Vector3Add()
  151. // Vector3Subtract()
  152. // Vector3Scale()
  153. // Vector3Normalize()
  154. // Vector3Distance()
  155. // Vector3CrossProduct()
  156. // Vector3RotateByAxisAngle()
  157. // Vector3Angle()
  158. // Vector3Negate()
  159. // MatrixLookAt()
  160. // MatrixPerspective()
  161. // MatrixOrtho()
  162. // MatrixIdentity()
  163. // raylib required functionality:
  164. // GetMouseDelta()
  165. // GetMouseWheelMove()
  166. // IsKeyDown()
  167. // IsKeyPressed()
  168. // GetFrameTime()
  169. //----------------------------------------------------------------------------------
  170. // Defines and Macros
  171. //----------------------------------------------------------------------------------
  172. #define CAMERA_MOVE_SPEED 5.4f // Units per second
  173. #define CAMERA_ROTATION_SPEED 0.03f
  174. #define CAMERA_PAN_SPEED 0.2f
  175. // Camera mouse movement sensitivity
  176. #define CAMERA_MOUSE_MOVE_SENSITIVITY 0.003f
  177. // Camera orbital speed in CAMERA_ORBITAL mode
  178. #define CAMERA_ORBITAL_SPEED 0.5f // Radians per second
  179. //----------------------------------------------------------------------------------
  180. // Types and Structures Definition
  181. //----------------------------------------------------------------------------------
  182. //...
  183. //----------------------------------------------------------------------------------
  184. // Global Variables Definition
  185. //----------------------------------------------------------------------------------
  186. //...
  187. //----------------------------------------------------------------------------------
  188. // Module Internal Functions Declaration
  189. //----------------------------------------------------------------------------------
  190. //...
  191. //----------------------------------------------------------------------------------
  192. // Module Functions Definition
  193. //----------------------------------------------------------------------------------
  194. // Returns the cameras forward vector (normalized)
  195. Vector3 GetCameraForward(Camera *camera)
  196. {
  197. return Vector3Normalize(Vector3Subtract(camera->target, camera->position));
  198. }
  199. // Returns the cameras up vector (normalized)
  200. // Note: The up vector might not be perpendicular to the forward vector
  201. Vector3 GetCameraUp(Camera *camera)
  202. {
  203. return Vector3Normalize(camera->up);
  204. }
  205. // Returns the cameras right vector (normalized)
  206. Vector3 GetCameraRight(Camera *camera)
  207. {
  208. Vector3 forward = GetCameraForward(camera);
  209. Vector3 up = GetCameraUp(camera);
  210. return Vector3Normalize(Vector3CrossProduct(forward, up));
  211. }
  212. // Moves the camera in its forward direction
  213. void CameraMoveForward(Camera *camera, float distance, bool moveInWorldPlane)
  214. {
  215. Vector3 forward = GetCameraForward(camera);
  216. if (moveInWorldPlane)
  217. {
  218. // Project vector onto world plane
  219. forward.y = 0;
  220. forward = Vector3Normalize(forward);
  221. }
  222. // Scale by distance
  223. forward = Vector3Scale(forward, distance);
  224. // Move position and target
  225. camera->position = Vector3Add(camera->position, forward);
  226. camera->target = Vector3Add(camera->target, forward);
  227. }
  228. // Moves the camera in its up direction
  229. void CameraMoveUp(Camera *camera, float distance)
  230. {
  231. Vector3 up = GetCameraUp(camera);
  232. // Scale by distance
  233. up = Vector3Scale(up, distance);
  234. // Move position and target
  235. camera->position = Vector3Add(camera->position, up);
  236. camera->target = Vector3Add(camera->target, up);
  237. }
  238. // Moves the camera target in its current right direction
  239. void CameraMoveRight(Camera *camera, float distance, bool moveInWorldPlane)
  240. {
  241. Vector3 right = GetCameraRight(camera);
  242. if (moveInWorldPlane)
  243. {
  244. // Project vector onto world plane
  245. right.y = 0;
  246. right = Vector3Normalize(right);
  247. }
  248. // Scale by distance
  249. right = Vector3Scale(right, distance);
  250. // Move position and target
  251. camera->position = Vector3Add(camera->position, right);
  252. camera->target = Vector3Add(camera->target, right);
  253. }
  254. // Moves the camera position closer/farther to/from the camera target
  255. void CameraMoveToTarget(Camera *camera, float delta)
  256. {
  257. float distance = Vector3Distance(camera->position, camera->target);
  258. // Apply delta
  259. distance += delta;
  260. // Distance must be greater than 0
  261. if (distance <= 0) distance = 0.001f;
  262. // Set new distance by moving the position along the forward vector
  263. Vector3 forward = GetCameraForward(camera);
  264. camera->position = Vector3Add(camera->target, Vector3Scale(forward, -distance));
  265. }
  266. // Rotates the camera around its up vector
  267. // Yaw is "looking left and right"
  268. // If rotateAroundTarget is false, the camera rotates around its position
  269. // Note: angle must be provided in radians
  270. void CameraYaw(Camera *camera, float angle, bool rotateAroundTarget)
  271. {
  272. // Rotation axis
  273. Vector3 up = GetCameraUp(camera);
  274. // View vector
  275. Vector3 targetPosition = Vector3Subtract(camera->target, camera->position);
  276. // Rotate view vector around up axis
  277. targetPosition = Vector3RotateByAxisAngle(targetPosition, up, angle);
  278. if (rotateAroundTarget)
  279. {
  280. // Move position relative to target
  281. camera->position = Vector3Subtract(camera->target, targetPosition);
  282. }
  283. else // rotate around camera.position
  284. {
  285. // Move target relative to position
  286. camera->target = Vector3Add(camera->position, targetPosition);
  287. }
  288. }
  289. // Rotates the camera around its right vector, pitch is "looking up and down"
  290. // - lockView prevents camera overrotation (aka "somersaults")
  291. // - rotateAroundTarget defines if rotation is around target or around its position
  292. // - rotateUp rotates the up direction as well (typically only usefull in CAMERA_FREE)
  293. // NOTE: angle must be provided in radians
  294. void CameraPitch(Camera *camera, float angle, bool lockView, bool rotateAroundTarget, bool rotateUp)
  295. {
  296. // Up direction
  297. Vector3 up = GetCameraUp(camera);
  298. // View vector
  299. Vector3 targetPosition = Vector3Subtract(camera->target, camera->position);
  300. if (lockView)
  301. {
  302. // In these camera modes we clamp the Pitch angle
  303. // to allow only viewing straight up or down.
  304. // Clamp view up
  305. float maxAngleUp = Vector3Angle(up, targetPosition);
  306. maxAngleUp -= 0.001f; // avoid numerical errors
  307. if (angle > maxAngleUp) angle = maxAngleUp;
  308. // Clamp view down
  309. float maxAngleDown = Vector3Angle(Vector3Negate(up), targetPosition);
  310. maxAngleDown *= -1.0f; // downwards angle is negative
  311. maxAngleDown += 0.001f; // avoid numerical errors
  312. if (angle < maxAngleDown) angle = maxAngleDown;
  313. }
  314. // Rotation axis
  315. Vector3 right = GetCameraRight(camera);
  316. // Rotate view vector around right axis
  317. targetPosition = Vector3RotateByAxisAngle(targetPosition, right, angle);
  318. if (rotateAroundTarget)
  319. {
  320. // Move position relative to target
  321. camera->position = Vector3Subtract(camera->target, targetPosition);
  322. }
  323. else // rotate around camera.position
  324. {
  325. // Move target relative to position
  326. camera->target = Vector3Add(camera->position, targetPosition);
  327. }
  328. if (rotateUp)
  329. {
  330. // Rotate up direction around right axis
  331. camera->up = Vector3RotateByAxisAngle(camera->up, right, angle);
  332. }
  333. }
  334. // Rotates the camera around its forward vector
  335. // Roll is "turning your head sideways to the left or right"
  336. // Note: angle must be provided in radians
  337. void CameraRoll(Camera *camera, float angle)
  338. {
  339. // Rotation axis
  340. Vector3 forward = GetCameraForward(camera);
  341. // Rotate up direction around forward axis
  342. camera->up = Vector3RotateByAxisAngle(camera->up, forward, angle);
  343. }
  344. // Returns the camera view matrix
  345. Matrix GetCameraViewMatrix(Camera *camera)
  346. {
  347. return MatrixLookAt(camera->position, camera->target, camera->up);
  348. }
  349. // Returns the camera projection matrix
  350. Matrix GetCameraProjectionMatrix(Camera *camera, float aspect)
  351. {
  352. if (camera->projection == CAMERA_PERSPECTIVE)
  353. {
  354. return MatrixPerspective(camera->fovy*DEG2RAD, aspect, CAMERA_CULL_DISTANCE_NEAR, CAMERA_CULL_DISTANCE_FAR);
  355. }
  356. else if (camera->projection == CAMERA_ORTHOGRAPHIC)
  357. {
  358. double top = camera->fovy/2.0;
  359. double right = top*aspect;
  360. return MatrixOrtho(-right, right, -top, top, CAMERA_CULL_DISTANCE_NEAR, CAMERA_CULL_DISTANCE_FAR);
  361. }
  362. return MatrixIdentity();
  363. }
  364. #if !defined(RCAMERA_STANDALONE)
  365. // Update camera position for selected mode
  366. // Camera mode: CAMERA_FREE, CAMERA_FIRST_PERSON, CAMERA_THIRD_PERSON, CAMERA_ORBITAL or CUSTOM
  367. void UpdateCamera(Camera *camera, int mode)
  368. {
  369. Vector2 mousePositionDelta = GetMouseDelta();
  370. bool moveInWorldPlane = ((mode == CAMERA_FIRST_PERSON) || (mode == CAMERA_THIRD_PERSON));
  371. bool rotateAroundTarget = ((mode == CAMERA_THIRD_PERSON) || (mode == CAMERA_ORBITAL));
  372. bool lockView = ((mode == CAMERA_FREE) || (mode == CAMERA_FIRST_PERSON) || (mode == CAMERA_THIRD_PERSON) || (mode == CAMERA_ORBITAL));
  373. bool rotateUp = false;
  374. // Camera speeds based on frame time
  375. float cameraMoveSpeed = CAMERA_MOVE_SPEED*GetFrameTime();
  376. float cameraRotationSpeed = CAMERA_ROTATION_SPEED*GetFrameTime();
  377. float cameraPanSpeed = CAMERA_PAN_SPEED*GetFrameTime();
  378. float cameraOrbitalSpeed = CAMERA_ORBITAL_SPEED*GetFrameTime();
  379. if (mode == CAMERA_CUSTOM) {}
  380. else if (mode == CAMERA_ORBITAL)
  381. {
  382. // Orbital can just orbit
  383. Matrix rotation = MatrixRotate(GetCameraUp(camera), cameraOrbitalSpeed);
  384. Vector3 view = Vector3Subtract(camera->position, camera->target);
  385. view = Vector3Transform(view, rotation);
  386. camera->position = Vector3Add(camera->target, view);
  387. }
  388. else
  389. {
  390. // Camera rotation
  391. if (IsKeyDown(KEY_DOWN)) CameraPitch(camera, -cameraRotationSpeed, lockView, rotateAroundTarget, rotateUp);
  392. if (IsKeyDown(KEY_UP)) CameraPitch(camera, cameraRotationSpeed, lockView, rotateAroundTarget, rotateUp);
  393. if (IsKeyDown(KEY_RIGHT)) CameraYaw(camera, -cameraRotationSpeed, rotateAroundTarget);
  394. if (IsKeyDown(KEY_LEFT)) CameraYaw(camera, cameraRotationSpeed, rotateAroundTarget);
  395. if (IsKeyDown(KEY_Q)) CameraRoll(camera, -cameraRotationSpeed);
  396. if (IsKeyDown(KEY_E)) CameraRoll(camera, cameraRotationSpeed);
  397. // Camera movement
  398. // Camera pan (for CAMERA_FREE)
  399. if ((mode == CAMERA_FREE) && (IsMouseButtonDown(MOUSE_BUTTON_MIDDLE)))
  400. {
  401. const Vector2 mouseDelta = GetMouseDelta();
  402. if (mouseDelta.x > 0.0f) CameraMoveRight(camera, cameraPanSpeed, moveInWorldPlane);
  403. if (mouseDelta.x < 0.0f) CameraMoveRight(camera, -cameraPanSpeed, moveInWorldPlane);
  404. if (mouseDelta.y > 0.0f) CameraMoveUp(camera, -cameraPanSpeed);
  405. if (mouseDelta.y < 0.0f) CameraMoveUp(camera, cameraPanSpeed);
  406. }
  407. else
  408. {
  409. // Mouse support
  410. CameraYaw(camera, -mousePositionDelta.x*CAMERA_MOUSE_MOVE_SENSITIVITY, rotateAroundTarget);
  411. CameraPitch(camera, -mousePositionDelta.y*CAMERA_MOUSE_MOVE_SENSITIVITY, lockView, rotateAroundTarget, rotateUp);
  412. }
  413. // Keyboard support
  414. if (IsKeyDown(KEY_W)) CameraMoveForward(camera, cameraMoveSpeed, moveInWorldPlane);
  415. if (IsKeyDown(KEY_A)) CameraMoveRight(camera, -cameraMoveSpeed, moveInWorldPlane);
  416. if (IsKeyDown(KEY_S)) CameraMoveForward(camera, -cameraMoveSpeed, moveInWorldPlane);
  417. if (IsKeyDown(KEY_D)) CameraMoveRight(camera, cameraMoveSpeed, moveInWorldPlane);
  418. // Gamepad movement
  419. if (IsGamepadAvailable(0))
  420. {
  421. // Gamepad controller support
  422. CameraYaw(camera, -(GetGamepadAxisMovement(0, GAMEPAD_AXIS_RIGHT_X)*2)*CAMERA_MOUSE_MOVE_SENSITIVITY, rotateAroundTarget);
  423. CameraPitch(camera, -(GetGamepadAxisMovement(0, GAMEPAD_AXIS_RIGHT_Y)*2)*CAMERA_MOUSE_MOVE_SENSITIVITY, lockView, rotateAroundTarget, rotateUp);
  424. if (GetGamepadAxisMovement(0, GAMEPAD_AXIS_LEFT_Y) <= -0.25f) CameraMoveForward(camera, cameraMoveSpeed, moveInWorldPlane);
  425. if (GetGamepadAxisMovement(0, GAMEPAD_AXIS_LEFT_X) <= -0.25f) CameraMoveRight(camera, -cameraMoveSpeed, moveInWorldPlane);
  426. if (GetGamepadAxisMovement(0, GAMEPAD_AXIS_LEFT_Y) >= 0.25f) CameraMoveForward(camera, -cameraMoveSpeed, moveInWorldPlane);
  427. if (GetGamepadAxisMovement(0, GAMEPAD_AXIS_LEFT_X) >= 0.25f) CameraMoveRight(camera, cameraMoveSpeed, moveInWorldPlane);
  428. }
  429. if (mode == CAMERA_FREE)
  430. {
  431. if (IsKeyDown(KEY_SPACE)) CameraMoveUp(camera, cameraMoveSpeed);
  432. if (IsKeyDown(KEY_LEFT_CONTROL)) CameraMoveUp(camera, -cameraMoveSpeed);
  433. }
  434. }
  435. if ((mode == CAMERA_THIRD_PERSON) || (mode == CAMERA_ORBITAL) || (mode == CAMERA_FREE))
  436. {
  437. // Zoom target distance
  438. CameraMoveToTarget(camera, -GetMouseWheelMove());
  439. if (IsKeyPressed(KEY_KP_SUBTRACT)) CameraMoveToTarget(camera, 2.0f);
  440. if (IsKeyPressed(KEY_KP_ADD)) CameraMoveToTarget(camera, -2.0f);
  441. }
  442. }
  443. #endif // !RCAMERA_STANDALONE
  444. // Update camera movement, movement/rotation values should be provided by user
  445. void UpdateCameraPro(Camera *camera, Vector3 movement, Vector3 rotation, float zoom)
  446. {
  447. // Required values
  448. // movement.x - Move forward/backward
  449. // movement.y - Move right/left
  450. // movement.z - Move up/down
  451. // rotation.x - yaw
  452. // rotation.y - pitch
  453. // rotation.z - roll
  454. // zoom - Move towards target
  455. bool lockView = true;
  456. bool rotateAroundTarget = false;
  457. bool rotateUp = false;
  458. bool moveInWorldPlane = true;
  459. // Camera rotation
  460. CameraPitch(camera, -rotation.y*DEG2RAD, lockView, rotateAroundTarget, rotateUp);
  461. CameraYaw(camera, -rotation.x*DEG2RAD, rotateAroundTarget);
  462. CameraRoll(camera, rotation.z*DEG2RAD);
  463. // Camera movement
  464. CameraMoveForward(camera, movement.x, moveInWorldPlane);
  465. CameraMoveRight(camera, movement.y, moveInWorldPlane);
  466. CameraMoveUp(camera, movement.z);
  467. // Zoom target distance
  468. CameraMoveToTarget(camera, zoom);
  469. }
  470. #endif // RCAMERA_IMPLEMENTATION