ADDED: UpdateCameraPro() -Experimental-

REVIEWED: rcamera module formating
REVIEWED: `core_3d_camera_example`
This commit is contained in:
Ray 2023-03-12 19:28:42 +01:00
parent b436c8d7e5
commit f9c4cc2040
2 changed files with 104 additions and 59 deletions

View File

@ -113,7 +113,26 @@ int main(void)
} }
} }
// Update camera computes movement internally depending on the camera mode
// Some default standard keyboard/mouse inputs are hardcoded to simplify use
// For advance camera controls, it's reecommended to compute camera movement manually
UpdateCamera(&camera, cameraMode); // Update camera UpdateCamera(&camera, cameraMode); // Update camera
/*
// Camera PRO usage example (EXPERIMENTAL)
// This new camera function allows custom movement/rotation values to be directly provided
// as input parameters, with this approach, rcamera module is internally independent of raylib inputs
UpdateCameraPro(&camera,
(IsKeyDown(KEY_W) || IsKeyDown(KEY_UP))*0.1f - // Move forward-backward
(IsKeyDown(KEY_S) || IsKeyDown(KEY_DOWN))*0.1f,
(IsKeyDown(KEY_D) || IsKeyDown(KEY_RIGHT))*0.1f - // Move right-left
(IsKeyDown(KEY_A) || IsKeyDown(KEY_LEFT))*0.1f,
0.0f, // Move up-down
GetMouseWheelMove()*2.0f, // Move to target (zoom)
GetMouseDelta().x*0.05f, // Rotation: yaw
GetMouseDelta().y*0.05f, // Rotation: pitch
0.0f); // Rotation: roll
*/
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Draw // Draw

View File

@ -46,32 +46,35 @@
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Defines and Macros // Defines and Macros
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
//... // Function specifiers definition
#ifndef RLAPI
#define RLAPI // Functions defined as 'extern' by default (implicit specifiers)
#endif
#if defined(CAMERA_STANDALONE) #if defined(CAMERA_STANDALONE)
#define CAMERA_CULL_DISTANCE_NEAR 0.01 #define CAMERA_CULL_DISTANCE_NEAR 0.01
#define CAMERA_CULL_DISTANCE_FAR 1000.0 #define CAMERA_CULL_DISTANCE_FAR 1000.0
#else #else
#define CAMERA_CULL_DISTANCE_NEAR RL_CULL_DISTANCE_NEAR #define CAMERA_CULL_DISTANCE_NEAR RL_CULL_DISTANCE_NEAR
#define CAMERA_CULL_DISTANCE_FAR RL_CULL_DISTANCE_FAR #define CAMERA_CULL_DISTANCE_FAR RL_CULL_DISTANCE_FAR
#endif #endif
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Types and Structures Definition // Types and Structures Definition
// NOTE: Below types are required for CAMERA_STANDALONE usage // NOTE: Below types are required for CAMERA_STANDALONE usage
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// TODO review
#if defined(CAMERA_STANDALONE) #if defined(CAMERA_STANDALONE)
// Vector2 type // Vector2, 2 components
typedef struct Vector2 { typedef struct Vector2 {
float x; float x; // Vector x component
float y; float y; // Vector y component
} Vector2; } Vector2;
// Vector3 type // Vector3, 3 components
typedef struct Vector3 { typedef struct Vector3 {
float x; float x; // Vector x component
float y; float y; // Vector y component
float z; float z; // Vector z component
} Vector3; } Vector3;
// Camera type, defines a camera position/orientation in 3d space // Camera type, defines a camera position/orientation in 3d space
@ -80,31 +83,31 @@
Vector3 target; // Camera target it looks-at Vector3 target; // Camera target it looks-at
Vector3 up; // Camera up vector (rotation over its axis) Vector3 up; // Camera up vector (rotation over its axis)
float fovy; // Camera field-of-view apperture in Y (degrees) in perspective, used as near plane width in orthographic float fovy; // Camera field-of-view apperture in Y (degrees) in perspective, used as near plane width in orthographic
int projection; // Camera type, defines projection type: CAMERA_PERSPECTIVE or CAMERA_ORTHOGRAPHIC int projection; // Camera projection type: CAMERA_PERSPECTIVE or CAMERA_ORTHOGRAPHIC
} Camera3D; } Camera3D;
typedef Camera3D Camera; // Camera type fallback, defaults to Camera3D typedef Camera3D Camera; // Camera type fallback, defaults to Camera3D
// Camera projection
typedef enum {
CAMERA_PERSPECTIVE = 0, // Perspective projection
CAMERA_ORTHOGRAPHIC // Orthographic projection
} CameraProjection;
// Camera system modes // Camera system modes
typedef enum { typedef enum {
CAMERA_CUSTOM = 0, CAMERA_CUSTOM = 0, // Camera custom, controlled by user (UpdateCamera() does nothing)
CAMERA_FREE, CAMERA_FREE, // Camera free mode
CAMERA_ORBITAL, CAMERA_ORBITAL, // Camera orbital, around target, zoom supported
CAMERA_FIRST_PERSON, CAMERA_FIRST_PERSON, // Camera first person
CAMERA_THIRD_PERSON CAMERA_THIRD_PERSON // Camera third person
} CameraMode; } CameraMode;
// Camera projection modes
typedef enum {
CAMERA_PERSPECTIVE = 0,
CAMERA_ORTHOGRAPHIC
} CameraProjection;
#endif #endif
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Global Variables Definition // Global Variables Definition
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
//...
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Module Functions Declaration // Module Functions Declaration
@ -114,21 +117,23 @@
extern "C" { // Prevents name mangling of functions extern "C" { // Prevents name mangling of functions
#endif #endif
Vector3 GetCameraForward(Camera *camera); RLAPI Vector3 GetCameraForward(Camera *camera);
Vector3 GetCameraUp(Camera *camera); RLAPI Vector3 GetCameraUp(Camera *camera);
Vector3 GetCameraRight(Camera *camera); RLAPI Vector3 GetCameraRight(Camera *camera);
void CameraMoveForward(Camera *camera, float distance, bool moveInWorldPlane); // Camera movement
void CameraMoveUp(Camera *camera, float distance); RLAPI void CameraMoveForward(Camera *camera, float distance, bool moveInWorldPlane);
void CameraMoveRight(Camera *camera, float distance, bool moveInWorldPlane); RLAPI void CameraMoveUp(Camera *camera, float distance);
void CameraMoveToTarget(Camera *camera, float delta); RLAPI void CameraMoveRight(Camera *camera, float distance, bool moveInWorldPlane);
RLAPI void CameraMoveToTarget(Camera *camera, float delta);
void CameraYaw(Camera *camera, float angle, bool rotateAroundTarget); // Camera rotation
void CameraPitch(Camera *camera, float angle, bool lockView, bool rotateAroundTarget, bool rotateUp); RLAPI void CameraYaw(Camera *camera, float angle, bool rotateAroundTarget);
void CameraRoll(Camera *camera, float angle); RLAPI void CameraPitch(Camera *camera, float angle, bool lockView, bool rotateAroundTarget, bool rotateUp);
RLAPI void CameraRoll(Camera *camera, float angle);
Matrix GetCameraViewMatrix(Camera *camera); RLAPI Matrix GetCameraViewMatrix(Camera *camera);
Matrix GetCameraProjectionMatrix(Camera* camera, float aspect); RLAPI Matrix GetCameraProjectionMatrix(Camera* camera, float aspect);
#if defined(__cplusplus) #if defined(__cplusplus)
} }
@ -306,36 +311,35 @@ void CameraYaw(Camera *camera, float angle, bool rotateAroundTarget)
Vector3 up = GetCameraUp(camera); Vector3 up = GetCameraUp(camera);
// View vector // View vector
Vector3 target_position = Vector3Subtract(camera->target, camera->position); Vector3 targetPosition = Vector3Subtract(camera->target, camera->position);
// Rotate view vector around up axis // Rotate view vector around up axis
target_position = Vector3RotateByAxisAngle(target_position, up, angle); targetPosition = Vector3RotateByAxisAngle(targetPosition, up, angle);
if (rotateAroundTarget) if (rotateAroundTarget)
{ {
// Move position relative to target // Move position relative to target
camera->position = Vector3Subtract(camera->target, target_position); camera->position = Vector3Subtract(camera->target, targetPosition);
} }
else // rotate around camera.position else // rotate around camera.position
{ {
// Move target relative to position // Move target relative to position
camera->target = Vector3Add(camera->position, target_position); camera->target = Vector3Add(camera->position, targetPosition);
} }
} }
// Rotates the camera around its right vector // Rotates the camera around its right vector, pitch is "looking up and down"
// Pitch is "looking up and down" // - lockView prevents camera overrotation (aka "somersaults")
// lockView prevents camera overrotation (aka "somersaults") // - rotateAroundTarget defines if rotation is around target or around its position
// If rotateAroundTarget is false, the camera rotates around its position // - rotateUp rotates the up direction as well (typically only usefull in CAMERA_FREE)
// rotateUp rotates the up direction as well (typically only usefull in CAMERA_FREE) // NOTE: angle must be provided in radians
// Note: angle must be provided in radians
void CameraPitch(Camera *camera, float angle, bool lockView, bool rotateAroundTarget, bool rotateUp) void CameraPitch(Camera *camera, float angle, bool lockView, bool rotateAroundTarget, bool rotateUp)
{ {
// Up direction // Up direction
Vector3 up = GetCameraUp(camera); Vector3 up = GetCameraUp(camera);
// View vector // View vector
Vector3 target_position = Vector3Subtract(camera->target, camera->position); Vector3 targetPosition = Vector3Subtract(camera->target, camera->position);
if (lockView) if (lockView)
{ {
@ -343,32 +347,32 @@ void CameraPitch(Camera *camera, float angle, bool lockView, bool rotateAroundTa
// to allow only viewing straight up or down. // to allow only viewing straight up or down.
// Clamp view up // Clamp view up
float max_angle_up = Vector3Angle(up, target_position); float maxAngleUp = Vector3Angle(up, targetPosition);
max_angle_up -= 0.001f; // avoid numerical errors maxAngleUp -= 0.001f; // avoid numerical errors
if (angle > max_angle_up) angle = max_angle_up; if (angle > maxAngleUp) angle = maxAngleUp;
// Clamp view down // Clamp view down
float max_angle_down = Vector3Angle(Vector3Negate(up), target_position); float maxAngleDown = Vector3Angle(Vector3Negate(up), targetPosition);
max_angle_down *= -1.0f; // downwards angle is negative maxAngleDown *= -1.0f; // downwards angle is negative
max_angle_down += 0.001f; // avoid numerical errors maxAngleDown += 0.001f; // avoid numerical errors
if (angle < max_angle_down) angle = max_angle_down; if (angle < maxAngleDown) angle = maxAngleDown;
} }
// Rotation axis // Rotation axis
Vector3 right = GetCameraRight(camera); Vector3 right = GetCameraRight(camera);
// Rotate view vector around right axis // Rotate view vector around right axis
target_position = Vector3RotateByAxisAngle(target_position, right, angle); targetPosition = Vector3RotateByAxisAngle(targetPosition, right, angle);
if (rotateAroundTarget) if (rotateAroundTarget)
{ {
// Move position relative to target // Move position relative to target
camera->position = Vector3Subtract(camera->target, target_position); camera->position = Vector3Subtract(camera->target, targetPosition);
} }
else // rotate around camera.position else // rotate around camera.position
{ {
// Move target relative to position // Move target relative to position
camera->target = Vector3Add(camera->position, target_position); camera->target = Vector3Add(camera->position, targetPosition);
} }
if (rotateUp) if (rotateUp)
@ -466,4 +470,26 @@ void UpdateCamera(Camera *camera, int mode)
} }
#endif // !CAMERA_STANDALONE #endif // !CAMERA_STANDALONE
// Update camera movement, movement/rotation values should be provided by user
void UpdateCameraPro(Camera *camera, float moveForward, float moveRightLeft, float moveUpDown, float moveToTarget, float yaw, float pitch, float roll)
{
bool lockView = true;
bool rotateAroundTarget = false;
bool rotateUp = false;
bool moveInWorldPlane = true;
// Camera rotation
CameraPitch(camera, -pitch*DEG2RAD, lockView, rotateAroundTarget, rotateUp);
CameraYaw(camera, -yaw*DEG2RAD, rotateAroundTarget);
CameraRoll(camera, roll*DEG2RAD);
// Camera movement
CameraMoveForward(camera, moveForward, moveInWorldPlane);
CameraMoveRight(camera, moveRightLeft, moveInWorldPlane);
CameraMoveUp(camera, moveUpDown);
// Zoom target distance
CameraMoveToTarget(camera, moveToTarget);
}
#endif // CAMERA_IMPLEMENTATION #endif // CAMERA_IMPLEMENTATION