Browse Source

ADDED: `UpdateCameraPro()` -Experimental-

REVIEWED: rcamera module formating
REVIEWED: `core_3d_camera_example`
pull/2957/head
Ray 1 year ago
parent
commit
f9c4cc2040
2 changed files with 104 additions and 59 deletions
  1. +19
    -0
      examples/core/core_3d_camera_first_person.c
  2. +85
    -59
      src/rcamera.h

+ 19
- 0
examples/core/core_3d_camera_first_person.c 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
/*
// 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

+ 85
- 59
src/rcamera.h View File

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

Loading…
Cancel
Save