56#if defined(CAMERA_STANDALONE)
110#if defined(CAMERA_STANDALONE)
118 int keyRight,
int keyLeft,
119 int keyUp,
int keyDown);
135#if defined(CAMERA_IMPLEMENTATION)
143 #define PI 3.14159265358979323846
146 #define DEG2RAD (PI/180.0f)
149 #define RAD2DEG (180.0f/PI)
153#define CAMERA_MOUSE_MOVE_SENSITIVITY 0.003f
154#define CAMERA_MOUSE_SCROLL_SENSITIVITY 1.5f
157#define CAMERA_FREE_MOUSE_SENSITIVITY 0.01f
158#define CAMERA_FREE_DISTANCE_MIN_CLAMP 0.3f
159#define CAMERA_FREE_DISTANCE_MAX_CLAMP 120.0f
160#define CAMERA_FREE_MIN_CLAMP 85.0f
161#define CAMERA_FREE_MAX_CLAMP -85.0f
162#define CAMERA_FREE_SMOOTH_ZOOM_SENSITIVITY 0.05f
163#define CAMERA_FREE_PANNING_DIVIDER 5.1f
166#define CAMERA_ORBITAL_SPEED 0.01f
170#define CAMERA_FIRST_PERSON_FOCUS_DISTANCE 25.0f
171#define CAMERA_FIRST_PERSON_MIN_CLAMP 89.0f
172#define CAMERA_FIRST_PERSON_MAX_CLAMP -89.0f
174#define CAMERA_FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER 8.0f
175#define CAMERA_FIRST_PERSON_STEP_DIVIDER 30.0f
176#define CAMERA_FIRST_PERSON_WAVING_DIVIDER 200.0f
180#define CAMERA_THIRD_PERSON_DISTANCE_CLAMP 1.2f
181#define CAMERA_THIRD_PERSON_MIN_CLAMP 5.0f
182#define CAMERA_THIRD_PERSON_MAX_CLAMP -85.0f
183#define CAMERA_THIRD_PERSON_OFFSET (Vector3){ 0.4f, 0.0f, 0.0f }
186#define PLAYER_MOVEMENT_SENSITIVITY 20.0f
204 float targetDistance;
205 float playerEyesPosition;
211 int smoothZoomControl;
219static CameraData CAMERA = {
222 .playerEyesPosition = 1.85f,
224 .previousMousePosition = { 0 },
225 .moveControl = {
'W',
'S',
'D',
'A',
'E',
'Q' },
226 .smoothZoomControl = 341,
234#if defined(CAMERA_STANDALONE)
239static int IsKeyDown(
int key) {
return 0; }
256 float dx = v2.
x - v1.
x;
257 float dy = v2.
y - v1.
y;
258 float dz = v2.
z - v1.
z;
260 CAMERA.targetDistance = sqrtf(dx*dx + dy*dy + dz*dz);
263 CAMERA.angle.x = atan2f(dx, dz);
264 CAMERA.angle.y = atan2f(dy, sqrtf(dx*dx + dz*dz));
266 CAMERA.playerEyesPosition = camera.
position.
y;
284 static int swingCounter = 0;
289 Vector2 mousePositionDelta = { 0.0f, 0.0f };
296 bool keyAlt =
IsKeyDown(CAMERA.altControl);
297 bool szoomKey =
IsKeyDown(CAMERA.smoothZoomControl);
298 bool direction[6] = {
IsKeyDown(CAMERA.moveControl[MOVE_FRONT]),
299 IsKeyDown(CAMERA.moveControl[MOVE_BACK]),
300 IsKeyDown(CAMERA.moveControl[MOVE_RIGHT]),
301 IsKeyDown(CAMERA.moveControl[MOVE_LEFT]),
303 IsKeyDown(CAMERA.moveControl[MOVE_DOWN]) };
307 mousePositionDelta.
x = mousePosition.
x - CAMERA.previousMousePosition.x;
308 mousePositionDelta.
y = mousePosition.
y - CAMERA.previousMousePosition.y;
310 CAMERA.previousMousePosition = mousePosition;
320 if ((CAMERA.targetDistance < CAMERA_FREE_DISTANCE_MAX_CLAMP) && (mouseWheelMove < 0))
322 CAMERA.targetDistance -= (mouseWheelMove*CAMERA_MOUSE_SCROLL_SENSITIVITY);
323 if (CAMERA.targetDistance > CAMERA_FREE_DISTANCE_MAX_CLAMP) CAMERA.targetDistance = CAMERA_FREE_DISTANCE_MAX_CLAMP;
327 else if ((camera->
position.
y > camera->
target.
y) && (CAMERA.targetDistance == CAMERA_FREE_DISTANCE_MAX_CLAMP) && (mouseWheelMove < 0))
329 camera->
target.
x += mouseWheelMove*(camera->
target.
x - camera->
position.
x)*CAMERA_MOUSE_SCROLL_SENSITIVITY/CAMERA.targetDistance;
330 camera->
target.
y += mouseWheelMove*(camera->
target.
y - camera->
position.
y)*CAMERA_MOUSE_SCROLL_SENSITIVITY/CAMERA.targetDistance;
331 camera->
target.
z += mouseWheelMove*(camera->
target.
z - camera->
position.
z)*CAMERA_MOUSE_SCROLL_SENSITIVITY/CAMERA.targetDistance;
335 camera->
target.
x += mouseWheelMove*(camera->
target.
x - camera->
position.
x)*CAMERA_MOUSE_SCROLL_SENSITIVITY/CAMERA.targetDistance;
336 camera->
target.
y += mouseWheelMove*(camera->
target.
y - camera->
position.
y)*CAMERA_MOUSE_SCROLL_SENSITIVITY/CAMERA.targetDistance;
337 camera->
target.
z += mouseWheelMove*(camera->
target.
z - camera->
position.
z)*CAMERA_MOUSE_SCROLL_SENSITIVITY/CAMERA.targetDistance;
343 CAMERA.targetDistance -= (mouseWheelMove*CAMERA_MOUSE_SCROLL_SENSITIVITY);
344 if (CAMERA.targetDistance < CAMERA_FREE_DISTANCE_MIN_CLAMP) CAMERA.targetDistance = CAMERA_FREE_DISTANCE_MIN_CLAMP;
347 else if ((camera->
position.
y < camera->
target.
y) && (CAMERA.targetDistance == CAMERA_FREE_DISTANCE_MAX_CLAMP) && (mouseWheelMove < 0))
349 camera->
target.
x += mouseWheelMove*(camera->
target.
x - camera->
position.
x)*CAMERA_MOUSE_SCROLL_SENSITIVITY/CAMERA.targetDistance;
350 camera->
target.
y += mouseWheelMove*(camera->
target.
y - camera->
position.
y)*CAMERA_MOUSE_SCROLL_SENSITIVITY/CAMERA.targetDistance;
351 camera->
target.
z += mouseWheelMove*(camera->
target.
z - camera->
position.
z)*CAMERA_MOUSE_SCROLL_SENSITIVITY/CAMERA.targetDistance;
355 camera->
target.
x += mouseWheelMove*(camera->
target.
x - camera->
position.
x)*CAMERA_MOUSE_SCROLL_SENSITIVITY/CAMERA.targetDistance;
356 camera->
target.
y += mouseWheelMove*(camera->
target.
y - camera->
position.
y)*CAMERA_MOUSE_SCROLL_SENSITIVITY/CAMERA.targetDistance;
357 camera->
target.
z += mouseWheelMove*(camera->
target.
z - camera->
position.
z)*CAMERA_MOUSE_SCROLL_SENSITIVITY/CAMERA.targetDistance;
363 CAMERA.targetDistance -= (mouseWheelMove*CAMERA_MOUSE_SCROLL_SENSITIVITY);
364 if (CAMERA.targetDistance < CAMERA_FREE_DISTANCE_MIN_CLAMP) CAMERA.targetDistance = CAMERA_FREE_DISTANCE_MIN_CLAMP;
375 CAMERA.targetDistance += (mousePositionDelta.
y*CAMERA_FREE_SMOOTH_ZOOM_SENSITIVITY);
380 CAMERA.angle.x += mousePositionDelta.
x*-CAMERA_FREE_MOUSE_SENSITIVITY;
381 CAMERA.angle.y += mousePositionDelta.
y*-CAMERA_FREE_MOUSE_SENSITIVITY;
384 if (CAMERA.angle.y > CAMERA_FREE_MIN_CLAMP*
DEG2RAD) CAMERA.angle.y = CAMERA_FREE_MIN_CLAMP*
DEG2RAD;
385 else if (CAMERA.angle.y < CAMERA_FREE_MAX_CLAMP*
DEG2RAD) CAMERA.angle.y = CAMERA_FREE_MAX_CLAMP*
DEG2RAD;
391 camera->
target.
x += ((mousePositionDelta.
x*CAMERA_FREE_MOUSE_SENSITIVITY)*cosf(CAMERA.angle.x) + (mousePositionDelta.
y*-CAMERA_FREE_MOUSE_SENSITIVITY)*sinf(CAMERA.angle.x)*sinf(CAMERA.angle.y))*(CAMERA.targetDistance/CAMERA_FREE_PANNING_DIVIDER);
392 camera->
target.
y += ((mousePositionDelta.
y*CAMERA_FREE_MOUSE_SENSITIVITY)*cosf(CAMERA.angle.y))*(CAMERA.targetDistance/CAMERA_FREE_PANNING_DIVIDER);
393 camera->
target.
z += ((mousePositionDelta.
x*-CAMERA_FREE_MOUSE_SENSITIVITY)*sinf(CAMERA.angle.x) + (mousePositionDelta.
y*-CAMERA_FREE_MOUSE_SENSITIVITY)*cosf(CAMERA.angle.x)*sinf(CAMERA.angle.y))*(CAMERA.targetDistance/CAMERA_FREE_PANNING_DIVIDER);
398 camera->
position.
x = -sinf(CAMERA.angle.x)*CAMERA.targetDistance*cosf(CAMERA.angle.y) + camera->
target.
x;
399 camera->
position.
y = -sinf(CAMERA.angle.y)*CAMERA.targetDistance + camera->
target.
y;
400 camera->
position.
z = -cosf(CAMERA.angle.x)*CAMERA.targetDistance*cosf(CAMERA.angle.y) + camera->
target.
z;
405 CAMERA.angle.x += CAMERA_ORBITAL_SPEED;
406 CAMERA.targetDistance -= (mouseWheelMove*CAMERA_MOUSE_SCROLL_SENSITIVITY);
409 if (CAMERA.targetDistance < CAMERA_THIRD_PERSON_DISTANCE_CLAMP) CAMERA.targetDistance = CAMERA_THIRD_PERSON_DISTANCE_CLAMP;
412 camera->
position.
x = sinf(CAMERA.angle.x)*CAMERA.targetDistance*cosf(CAMERA.angle.y) + camera->
target.
x;
413 camera->
position.
y = ((CAMERA.angle.y <= 0.0f)? 1 : -1)*sinf(CAMERA.angle.y)*CAMERA.targetDistance*sinf(CAMERA.angle.y) + camera->
target.
y;
414 camera->
position.
z = cosf(CAMERA.angle.x)*CAMERA.targetDistance*cosf(CAMERA.angle.y) + camera->
target.
z;
419 camera->
position.
x += (sinf(CAMERA.angle.x)*direction[MOVE_BACK] -
420 sinf(CAMERA.angle.x)*direction[MOVE_FRONT] -
421 cosf(CAMERA.angle.x)*direction[MOVE_LEFT] +
422 cosf(CAMERA.angle.x)*direction[MOVE_RIGHT])/PLAYER_MOVEMENT_SENSITIVITY;
424 camera->
position.
y += (sinf(CAMERA.angle.y)*direction[MOVE_FRONT] -
425 sinf(CAMERA.angle.y)*direction[MOVE_BACK] +
426 1.0f*direction[MOVE_UP] - 1.0f*direction[MOVE_DOWN])/PLAYER_MOVEMENT_SENSITIVITY;
428 camera->
position.
z += (cosf(CAMERA.angle.x)*direction[MOVE_BACK] -
429 cosf(CAMERA.angle.x)*direction[MOVE_FRONT] +
430 sinf(CAMERA.angle.x)*direction[MOVE_LEFT] -
431 sinf(CAMERA.angle.x)*direction[MOVE_RIGHT])/PLAYER_MOVEMENT_SENSITIVITY;
434 CAMERA.angle.x += (mousePositionDelta.
x*-CAMERA_MOUSE_MOVE_SENSITIVITY);
435 CAMERA.angle.y += (mousePositionDelta.
y*-CAMERA_MOUSE_MOVE_SENSITIVITY);
438 if (CAMERA.angle.y > CAMERA_FIRST_PERSON_MIN_CLAMP*
DEG2RAD) CAMERA.angle.y = CAMERA_FIRST_PERSON_MIN_CLAMP*
DEG2RAD;
439 else if (CAMERA.angle.y < CAMERA_FIRST_PERSON_MAX_CLAMP*
DEG2RAD) CAMERA.angle.y = CAMERA_FIRST_PERSON_MAX_CLAMP*
DEG2RAD;
442 Matrix matTranslation = { 1.0f, 0.0f, 0.0f, 0.0f,
443 0.0f, 1.0f, 0.0f, 0.0f,
444 0.0f, 0.0f, 1.0f, (CAMERA.targetDistance/CAMERA_FREE_PANNING_DIVIDER),
445 0.0f, 0.0f, 0.0f, 1.0f };
448 Matrix matRotation = { 1.0f, 0.0f, 0.0f, 0.0f,
449 0.0f, 1.0f, 0.0f, 0.0f,
450 0.0f, 0.0f, 1.0f, 0.0f,
451 0.0f, 0.0f, 0.0f, 1.0f };
453 float cosz = cosf(0.0f);
454 float sinz = sinf(0.0f);
455 float cosy = cosf(-(
PI*2 - CAMERA.angle.x));
456 float siny = sinf(-(
PI*2 - CAMERA.angle.x));
457 float cosx = cosf(-(
PI*2 - CAMERA.angle.y));
458 float sinx = sinf(-(
PI*2 - CAMERA.angle.y));
460 matRotation.
m0 = cosz*cosy;
461 matRotation.
m4 = (cosz*siny*sinx) - (sinz*cosx);
462 matRotation.
m8 = (cosz*siny*cosx) + (sinz*sinx);
463 matRotation.
m1 = sinz*cosy;
464 matRotation.
m5 = (sinz*siny*sinx) + (cosz*cosx);
465 matRotation.
m9 = (sinz*siny*cosx) - (cosz*sinx);
466 matRotation.
m2 = -siny;
467 matRotation.
m6 = cosy*sinx;
468 matRotation.
m10= cosy*cosx;
471 Matrix matTransform = { 0 };
472 matTransform.
m0 = matTranslation.
m0*matRotation.
m0 + matTranslation.
m1*matRotation.
m4 + matTranslation.
m2*matRotation.
m8 + matTranslation.
m3*matRotation.
m12;
473 matTransform.
m1 = matTranslation.
m0*matRotation.
m1 + matTranslation.
m1*matRotation.
m5 + matTranslation.
m2*matRotation.
m9 + matTranslation.
m3*matRotation.
m13;
474 matTransform.
m2 = matTranslation.
m0*matRotation.
m2 + matTranslation.
m1*matRotation.
m6 + matTranslation.
m2*matRotation.
m10 + matTranslation.
m3*matRotation.
m14;
475 matTransform.
m3 = matTranslation.
m0*matRotation.
m3 + matTranslation.
m1*matRotation.
m7 + matTranslation.
m2*matRotation.
m11 + matTranslation.
m3*matRotation.
m15;
476 matTransform.
m4 = matTranslation.
m4*matRotation.
m0 + matTranslation.
m5*matRotation.
m4 + matTranslation.
m6*matRotation.
m8 + matTranslation.
m7*matRotation.
m12;
477 matTransform.
m5 = matTranslation.
m4*matRotation.
m1 + matTranslation.
m5*matRotation.
m5 + matTranslation.
m6*matRotation.
m9 + matTranslation.
m7*matRotation.
m13;
478 matTransform.
m6 = matTranslation.
m4*matRotation.
m2 + matTranslation.
m5*matRotation.
m6 + matTranslation.
m6*matRotation.
m10 + matTranslation.
m7*matRotation.
m14;
479 matTransform.
m7 = matTranslation.
m4*matRotation.
m3 + matTranslation.
m5*matRotation.
m7 + matTranslation.
m6*matRotation.
m11 + matTranslation.
m7*matRotation.
m15;
480 matTransform.
m8 = matTranslation.
m8*matRotation.
m0 + matTranslation.
m9*matRotation.
m4 + matTranslation.
m10*matRotation.
m8 + matTranslation.
m11*matRotation.
m12;
481 matTransform.
m9 = matTranslation.
m8*matRotation.
m1 + matTranslation.
m9*matRotation.
m5 + matTranslation.
m10*matRotation.
m9 + matTranslation.
m11*matRotation.
m13;
482 matTransform.
m10 = matTranslation.
m8*matRotation.
m2 + matTranslation.
m9*matRotation.
m6 + matTranslation.
m10*matRotation.
m10 + matTranslation.
m11*matRotation.
m14;
483 matTransform.
m11 = matTranslation.
m8*matRotation.
m3 + matTranslation.
m9*matRotation.
m7 + matTranslation.
m10*matRotation.
m11 + matTranslation.
m11*matRotation.
m15;
484 matTransform.
m12 = matTranslation.
m12*matRotation.
m0 + matTranslation.
m13*matRotation.
m4 + matTranslation.
m14*matRotation.
m8 + matTranslation.
m15*matRotation.
m12;
485 matTransform.
m13 = matTranslation.
m12*matRotation.
m1 + matTranslation.
m13*matRotation.
m5 + matTranslation.
m14*matRotation.
m9 + matTranslation.
m15*matRotation.
m13;
486 matTransform.
m14 = matTranslation.
m12*matRotation.
m2 + matTranslation.
m13*matRotation.
m6 + matTranslation.
m14*matRotation.
m10 + matTranslation.
m15*matRotation.
m14;
487 matTransform.
m15 = matTranslation.
m12*matRotation.
m3 + matTranslation.
m13*matRotation.
m7 + matTranslation.
m14*matRotation.
m11 + matTranslation.
m15*matRotation.
m15;
494 for (
int i = 0; i < 6; i++)
if (direction[i]) { swingCounter++;
break; }
498 camera->
position.
y = CAMERA.playerEyesPosition - sinf(swingCounter/CAMERA_FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER)/CAMERA_FIRST_PERSON_STEP_DIVIDER;
500 camera->
up.
x = sinf(swingCounter/(CAMERA_FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER*2))/CAMERA_FIRST_PERSON_WAVING_DIVIDER;
501 camera->
up.
z = -sinf(swingCounter/(CAMERA_FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER*2))/CAMERA_FIRST_PERSON_WAVING_DIVIDER;
506 camera->
position.
x += (sinf(CAMERA.angle.x)*direction[MOVE_BACK] -
507 sinf(CAMERA.angle.x)*direction[MOVE_FRONT] -
508 cosf(CAMERA.angle.x)*direction[MOVE_LEFT] +
509 cosf(CAMERA.angle.x)*direction[MOVE_RIGHT])/PLAYER_MOVEMENT_SENSITIVITY;
511 camera->
position.
y += (sinf(CAMERA.angle.y)*direction[MOVE_FRONT] -
512 sinf(CAMERA.angle.y)*direction[MOVE_BACK] +
513 1.0f*direction[MOVE_UP] - 1.0f*direction[MOVE_DOWN])/PLAYER_MOVEMENT_SENSITIVITY;
515 camera->
position.
z += (cosf(CAMERA.angle.x)*direction[MOVE_BACK] -
516 cosf(CAMERA.angle.x)*direction[MOVE_FRONT] +
517 sinf(CAMERA.angle.x)*direction[MOVE_LEFT] -
518 sinf(CAMERA.angle.x)*direction[MOVE_RIGHT])/PLAYER_MOVEMENT_SENSITIVITY;
521 CAMERA.angle.x += (mousePositionDelta.
x*-CAMERA_MOUSE_MOVE_SENSITIVITY);
522 CAMERA.angle.y += (mousePositionDelta.
y*-CAMERA_MOUSE_MOVE_SENSITIVITY);
525 if (CAMERA.angle.y > CAMERA_THIRD_PERSON_MIN_CLAMP*
DEG2RAD) CAMERA.angle.y = CAMERA_THIRD_PERSON_MIN_CLAMP*
DEG2RAD;
526 else if (CAMERA.angle.y < CAMERA_THIRD_PERSON_MAX_CLAMP*
DEG2RAD) CAMERA.angle.y = CAMERA_THIRD_PERSON_MAX_CLAMP*
DEG2RAD;
529 CAMERA.targetDistance -= (mouseWheelMove*CAMERA_MOUSE_SCROLL_SENSITIVITY);
532 if (CAMERA.targetDistance < CAMERA_THIRD_PERSON_DISTANCE_CLAMP) CAMERA.targetDistance = CAMERA_THIRD_PERSON_DISTANCE_CLAMP;
534 camera->
position.
x = sinf(CAMERA.angle.x)*CAMERA.targetDistance*cosf(CAMERA.angle.y) + camera->
target.
x;
536 if (CAMERA.angle.y <= 0.0f) camera->
position.
y = sinf(CAMERA.angle.y)*CAMERA.targetDistance*sinf(CAMERA.angle.y) + camera->
target.
y;
537 else camera->
position.
y = -sinf(CAMERA.angle.y)*CAMERA.targetDistance*sinf(CAMERA.angle.y) + camera->
target.
y;
539 camera->
position.
z = cosf(CAMERA.angle.x)*CAMERA.targetDistance*cosf(CAMERA.angle.y) + camera->
target.
z;
557void SetCameraMoveControls(
int keyFront,
int keyBack,
int keyRight,
int keyLeft,
int keyUp,
int keyDown)
559 CAMERA.moveControl[MOVE_FRONT] = keyFront;
560 CAMERA.moveControl[MOVE_BACK] = keyBack;
561 CAMERA.moveControl[MOVE_RIGHT] = keyRight;
562 CAMERA.moveControl[MOVE_LEFT] = keyLeft;
563 CAMERA.moveControl[MOVE_UP] = keyUp;
564 CAMERA.moveControl[MOVE_DOWN] = keyDown;
RLAPI void SetCameraPanControl(int keyPan)
RLAPI float GetMouseWheelMove(void)
RLAPI void SetCameraSmoothZoomControl(int keySmoothZoom)
RLAPI bool IsMouseButtonDown(int button)
RLAPI void UpdateCamera(Camera *camera)
RLAPI bool IsKeyDown(int key)
RLAPI void SetCameraAltControl(int keyAlt)
RLAPI Vector2 GetMousePosition(void)
RLAPI void DisableCursor(void)
RLAPI void SetCameraMoveControls(int keyFront, int keyBack, int keyRight, int keyLeft, int keyUp, int keyDown)
RLAPI void SetCameraMode(Camera camera, int mode)
RLAPI void EnableCursor(void)