Logo

index : raylib-jai

Bindings from https://solarium.technology

  • summary
  • about
  • tree
  • log
  • branches
<< path: root/public/raylib-jai.git/html/Raylib/raylib/src/rcamera.h blob: 3e9f830958c7a7418bc84b3f871e9e18a6788c99 [raw] [clear marker]

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