浏览代码

Improving camera system -IN PROGRESS-

pull/189/head
raysan5 8 年前
父节点
当前提交
753b549aa5
共有 5 个文件被更改,包括 131 次插入190 次删除
  1. +3
    -6
      examples/core_3d_camera_first_person.c
  2. +1
    -4
      examples/core_3d_camera_free.c
  3. +4
    -6
      examples/models_cubicmap.c
  4. +115
    -165
      src/camera.h
  5. +8
    -9
      src/raylib.h

+ 3
- 6
examples/core_3d_camera_first_person.c 查看文件

@ -23,7 +23,7 @@ int main()
InitWindow(screenWidth, screenHeight, "raylib [core] example - 3d camera first person"); InitWindow(screenWidth, screenHeight, "raylib [core] example - 3d camera first person");
// Define the camera to look into our 3d world (position, target, up vector) // Define the camera to look into our 3d world (position, target, up vector)
Camera camera = {{ 0.0f, 10.0f, 10.0f }, { 0.0f, 0.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, 60.0f };
Camera camera = {{ 4.0f, 2.0f, 4.0f }, { 0.0f, 2.0f, 0.0f }, { 0.0f, 1.0f, 0.0f }, 60.0f };
// Generates some random columns // Generates some random columns
float heights[MAX_COLUMNS]; float heights[MAX_COLUMNS];
@ -37,10 +37,7 @@ int main()
colors[i] = (Color){ GetRandomValue(20, 255), GetRandomValue(10, 55), 30, 255 }; colors[i] = (Color){ GetRandomValue(20, 255), GetRandomValue(10, 55), 30, 255 };
} }
Vector3 playerPosition = { 4.0f, 2.0f, 4.0f }; // Define player position
SetCameraMode(CAMERA_FIRST_PERSON); // Set a first person camera mode
SetCameraFovy(camera.fovy); // Set internal camera field-of-view Y
SetCameraMode(camera, CAMERA_FIRST_PERSON); // Set a first person camera mode
SetTargetFPS(60); // Set our game to run at 60 frames-per-second SetTargetFPS(60); // Set our game to run at 60 frames-per-second
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
@ -50,7 +47,7 @@ int main()
{ {
// Update // Update
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
UpdateCameraPlayer(&camera, &playerPosition); // Update camera and player position
UpdateCamera(&camera); // Update camera and player position
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Draw // Draw

+ 1
- 4
examples/core_3d_camera_free.c 查看文件

@ -29,10 +29,7 @@ int main()
Vector3 cubePosition = { 0.0f, 0.0f, 0.0f }; Vector3 cubePosition = { 0.0f, 0.0f, 0.0f };
SetCameraMode(CAMERA_FREE); // Set a free camera mode
SetCameraPosition(camera.position); // Set internal camera position to match our camera position
SetCameraTarget(camera.target); // Set internal camera target to match our camera target
SetCameraFovy(camera.fovy); // Set internal camera field-of-view Y
SetCameraMode(camera, CAMERA_FREE); // Set a free camera mode
SetTargetFPS(60); // Set our game to run at 60 frames-per-second SetTargetFPS(60); // Set our game to run at 60 frames-per-second
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------

+ 4
- 6
examples/models_cubicmap.c 查看文件

@ -35,19 +35,17 @@ int main()
UnloadImage(image); // Unload cubesmap image from RAM, already uploaded to VRAM UnloadImage(image); // Unload cubesmap image from RAM, already uploaded to VRAM
SetCameraMode(CAMERA_ORBITAL); // Set an orbital camera mode
SetCameraPosition(camera.position); // Set internal camera position to match our custom camera position
SetCameraFovy(camera.fovy); // Set internal camera field-of-view Y
SetCameraMode(camera, CAMERA_ORBITAL); // Set an orbital camera mode
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
SetTargetFPS(60); // Set our game to run at 60 frames-per-second
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
// Main game loop // Main game loop
while (!WindowShouldClose()) // Detect window close button or ESC key
while (!WindowShouldClose()) // Detect window close button or ESC key
{ {
// Update // Update
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
UpdateCamera(&camera); // Update internal camera and our camera
UpdateCamera(&camera); // Update internal camera and our camera
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Draw // Draw

+ 115
- 165
src/camera.h 查看文件

@ -47,7 +47,13 @@
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
#if defined(CAMERA_STANDALONE) #if defined(CAMERA_STANDALONE)
// Camera modes // Camera modes
typedef enum { CAMERA_CUSTOM = 0, CAMERA_FREE, CAMERA_ORBITAL, CAMERA_FIRST_PERSON, CAMERA_THIRD_PERSON } CameraMode;
typedef enum {
CAMERA_CUSTOM = 0,
CAMERA_FREE,
CAMERA_ORBITAL,
CAMERA_FIRST_PERSON,
CAMERA_THIRD_PERSON
} CameraMode;
// Vector2 type // Vector2 type
typedef struct Vector2 { typedef struct Vector2 {
@ -67,6 +73,7 @@
Vector3 position; Vector3 position;
Vector3 target; Vector3 target;
Vector3 up; Vector3 up;
float fovy;
} Camera; } Camera;
#endif #endif
@ -83,22 +90,16 @@ extern "C" { // Prevents name mangling of functions
// Module Functions Declaration // Module Functions Declaration
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
#if defined(CAMERA_STANDALONE) #if defined(CAMERA_STANDALONE)
void SetCameraMode(int mode); // Set camera mode (multiple camera modes available)
void SetCameraMode(n">Camera camera, int mode); // Set camera mode (multiple camera modes available)
void UpdateCamera(Camera *camera); // Update camera (player position is ignored) void UpdateCamera(Camera *camera); // Update camera (player position is ignored)
void UpdateCameraPlayer(Camera *camera, Vector3 *position); // Update camera and player position (1st person and 3rd person cameras)
void SetCameraPosition(Vector3 position); // Set internal camera position
void SetCameraTarget(Vector3 target); // Set internal camera target
void SetCameraFovy(float fovy); // Set internal camera field-of-view-y
// TODO: Do we really need all those functions?
void SetCameraPanControl(int panKey); // Set camera pan key to combine with mouse movement (free camera) void SetCameraPanControl(int panKey); // Set camera pan key to combine with mouse movement (free camera)
void SetCameraAltControl(int altKey); // Set camera alt key to combine with mouse movement (free camera) void SetCameraAltControl(int altKey); // Set camera alt key to combine with mouse movement (free camera)
void SetCameraSmoothZoomControl(int szKey); // Set camera smooth zoom key to combine with mouse (free camera) void SetCameraSmoothZoomControl(int szKey); // Set camera smooth zoom key to combine with mouse (free camera)
void SetCameraMoveControls(int frontKey, int backKey, void SetCameraMoveControls(int frontKey, int backKey,
int leftKey, int rightKey, int leftKey, int rightKey,
int upKey, int downKey); // Set camera move controls (1st person and 3rd person cameras) int upKey, int downKey); // Set camera move controls (1st person and 3rd person cameras)
void SetCameraMouseSensitivity(float sensitivity); // Set camera mouse sensitivity (1st person and 3rd person cameras)
#endif #endif
#ifdef __cplusplus #ifdef __cplusplus
@ -133,8 +134,10 @@ void SetCameraMouseSensitivity(float sensitivity); // Set camera mouse
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Defines and Macros // Defines and Macros
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// CAMERA_GENERIC
#define CAMERA_SCROLL_SENSITIVITY 1.5f
// Camera mouse movement sensitivity
#define CAMERA_MOUSE_MOVE_SENSITIVITY 0.003f
#define CAMERA_MOUSE_SCROLL_SENSITIVITY 1.5f
// FREE_CAMERA // FREE_CAMERA
#define CAMERA_FREE_MOUSE_SENSITIVITY 0.01f #define CAMERA_FREE_MOUSE_SENSITIVITY 0.01f
@ -182,20 +185,15 @@ typedef enum { MOVE_FRONT = 0, MOVE_LEFT, MOVE_BACK, MOVE_RIGHT, MOVE_UP, MOVE_D
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Global Variables Definition // Global Variables Definition
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
static Vector2 cameraAngle = { 0.0f, 0.0f };
static float cameraTargetDistance = 5.0f; // TODO: Remove! Use predefined camera->target to camera->position distance
static Vector2 cameraMousePosition = { 0.0f, 0.0f };
static Vector2 cameraMouseVariation = { 0.0f, 0.0f };
static Vector2 cameraAngle = { 0.0f, 0.0f }; // TODO: Remove! Compute it in UpdateCamera() using camera->target and camera->position
static float cameraTargetDistance = 5.0f; // TODO: Remove! Compute it in UpdateCamera() using camera->target and camera->position
static int cameraMoveControl[6] = { 'W', 'A', 'S', 'D', 'E', 'Q' }; static int cameraMoveControl[6] = { 'W', 'A', 'S', 'D', 'E', 'Q' };
static int cameraPanControlKey = 2; // raylib: MOUSE_MIDDLE_BUTTON static int cameraPanControlKey = 2; // raylib: MOUSE_MIDDLE_BUTTON
static int cameraAltControlKey = 342; // raylib: KEY_LEFT_ALT static int cameraAltControlKey = 342; // raylib: KEY_LEFT_ALT
static int cameraSmoothZoomControlKey = 341; // raylib: KEY_LEFT_CONTROL static int cameraSmoothZoomControlKey = 341; // raylib: KEY_LEFT_CONTROL
static int cameraMoveCounter = 0; // Used for 1st person swinging movement
static float cameraMouseSensitivity = 0.003f; // How sensible is camera movement to mouse movement
static int cameraMode = CAMERA_CUSTOM; // Current internal camera mode
static int cameraMode = CAMERA_CUSTOM; // Current camera mode
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Module specific Functions Declaration // Module specific Functions Declaration
@ -219,45 +217,21 @@ static int IsKeyDown(int key) { return 0; }
//---------------------------------------------------------------------------------- //----------------------------------------------------------------------------------
// Select camera mode (multiple camera modes available) // Select camera mode (multiple camera modes available)
// TODO: Review hardcoded values when changing modes...
void SetCameraMode(int mode)
void SetCameraMode(Camera camera, int mode)
{ {
if ((cameraMode == CAMERA_FIRST_PERSON) && (mode == CAMERA_FREE))
{
cameraTargetDistance = 5.0f; // TODO: Review hardcode!
cameraAngle.y = -40*DEG2RAD;
}
else if ((cameraMode == CAMERA_FIRST_PERSON) && (mode == CAMERA_ORBITAL))
{
cameraTargetDistance = 5.0f; // TODO: Review hardcode!
cameraAngle.y = -40*DEG2RAD;
}
else if ((cameraMode == CAMERA_CUSTOM) && (mode == CAMERA_FREE))
{
cameraTargetDistance = 10.0f; // TODO: Review hardcode!
cameraAngle.x = 45*DEG2RAD;
cameraAngle.y = -40*DEG2RAD;
ShowCursor();
}
else if ((cameraMode == CAMERA_CUSTOM) && (mode == CAMERA_ORBITAL))
{
//cameraTargetDistance = 10.0f; // TODO: Review hardcode!
cameraAngle.x = 225*DEG2RAD;
cameraAngle.y = -40*DEG2RAD;
}
/*
Vector3 v1 = internalCamera.position;
Vector3 v2 = internalCamera.target;
// TODO: cameraTargetDistance and cameraAngle should be
// calculated using camera parameters on UpdateCamera()
Vector3 v1 = camera.position;
Vector3 v2 = camera.target;
float dx = v2.x - v1.x; float dx = v2.x - v1.x;
float dy = v2.y - v1.y; float dy = v2.y - v1.y;
float dz = v2.z - v1.z; float dz = v2.z - v1.z;
cameraTargetDistance = sqrt(dx*dx + dy*dy + dz*dz); cameraTargetDistance = sqrt(dx*dx + dy*dy + dz*dz);
err">*/
cameraAngle.y = -40*DEG2RAD;
cameraMode = mode; cameraMode = mode;
} }
@ -266,48 +240,73 @@ void SetCameraMode(int mode)
// Mouse: GetMousePosition(), SetMousePosition(), IsMouseButtonDown(), GetMouseWheelMove() // Mouse: GetMousePosition(), SetMousePosition(), IsMouseButtonDown(), GetMouseWheelMove()
// System: GetScreenWidth(), GetScreenHeight(), ShowCursor(), HideCursor() // System: GetScreenWidth(), GetScreenHeight(), ShowCursor(), HideCursor()
// Keys: IsKeyDown() // Keys: IsKeyDown()
// TODO: Consider touch inputs for camera!
// TODO: Port to quaternion-based camera!
void UpdateCamera(Camera *camera) void UpdateCamera(Camera *camera)
{ {
static int swingCounter = 0; // Used for 1st person swinging movement
static Vector2 previousMousePosition = { 0.0f, 0.0f };
// TODO: Compute cameraTargetDistance and cameraAngle
// NOTE: If cameraTargetDistance and cameraAngle change, camera->position is accordingly updated
/* /*
if (cameraMode != CAMERA_CUSTOM)
{
}
Vector2 cameraAngle = { 0.0f, 0.0f };
float cameraTargetDistance = 0.0f;
float dx = camera->target.x - camera->position.x;
float dy = camera->target.y - camera->position.y;
float dz = camera->target.z - camera->position.z;
cameraTargetDistance = sqrt(dx*dx + dy*dy + dz*dz);
Vector2 distance = { 0.0f, 0.0f };
distance.x = sqrt(dx*dx + dy*dy);
distance.y = sqrt(dx*dx + dz*dz);
cameraAngle.x = asin(fabs(dx)/distance.x);
cameraAngle.y = asin(fabs(dz)/distance.y);
*/ */
// Mouse movement detection // Mouse movement detection
Vector2 mousePositionDelta = { 0.0f, 0.0f };
Vector2 mousePosition = GetMousePosition(); Vector2 mousePosition = GetMousePosition();
int mouseWheelMove = GetMouseWheelMove(); int mouseWheelMove = GetMouseWheelMove();
int panKey = IsMouseButtonDown(cameraPanControlKey); // bool value int panKey = IsMouseButtonDown(cameraPanControlKey); // bool value
int screenWidth = GetScreenWidth();
int screenHeight = GetScreenHeight();
if ((cameraMode != CAMERA_FREE) && (cameraMode != CAMERA_ORBITAL))
if (cameraMode != CAMERA_CUSTOM)
{ {
HideCursor();
// Get screen size
int screenWidth = GetScreenWidth();
int screenHeight = GetScreenHeight();
if ((cameraMode == CAMERA_FIRST_PERSON) ||
(cameraMode == CAMERA_THIRD_PERSON))
{
HideCursor();
if (mousePosition.x < screenHeight/3) SetMousePosition((Vector2){ screenWidth - screenHeight/3, mousePosition.y});
else if (mousePosition.y < screenHeight/3) SetMousePosition((Vector2){ mousePosition.x, screenHeight - screenHeight/3});
else if (mousePosition.x > screenWidth - screenHeight/3) SetMousePosition((Vector2) { screenHeight/3, mousePosition.y});
else if (mousePosition.y > screenHeight - screenHeight/3) SetMousePosition((Vector2){ mousePosition.x, screenHeight/3});
else
if (mousePosition.x < screenHeight/3) SetMousePosition((Vector2){ screenWidth - screenHeight/3, mousePosition.y});
else if (mousePosition.y < screenHeight/3) SetMousePosition((Vector2){ mousePosition.x, screenHeight - screenHeight/3});
else if (mousePosition.x > screenWidth - screenHeight/3) SetMousePosition((Vector2) { screenHeight/3, mousePosition.y});
else if (mousePosition.y > screenHeight - screenHeight/3) SetMousePosition((Vector2){ mousePosition.x, screenHeight/3});
else
{
mousePositionDelta.x = mousePosition.x - previousMousePosition.x;
mousePositionDelta.y = mousePosition.y - previousMousePosition.y;
}
}
else // CAMERA_FREE, CAMERA_ORBITAL
{ {
cameraMouseVariation.x = mousePosition.x - cameraMousePosition.x;
cameraMouseVariation.y = mousePosition.y - cameraMousePosition.y;
ShowCursor();
mousePositionDelta.x = mousePosition.x - previousMousePosition.x;
mousePositionDelta.y = mousePosition.y - previousMousePosition.y;
} }
}
else
{
ShowCursor();
cameraMouseVariation.x = mousePosition.x - cameraMousePosition.x;
cameraMouseVariation.y = mousePosition.y - cameraMousePosition.y;
// NOTE: We GetMousePosition() again because it can be modified by a previous SetMousePosition() call
// If using directly mousePosition variable we have problems on CAMERA_FIRST_PERSON and CAMERA_THIRD_PERSON
previousMousePosition = GetMousePosition();
} }
// NOTE: We GetMousePosition() again because it can be modified by a previous SetMousePosition() call
// If using directly mousePosition variable we have problems on CAMERA_FIRST_PERSON and CAMERA_THIRD_PERSON
cameraMousePosition = GetMousePosition();
// Support for multiple automatic camera modes // Support for multiple automatic camera modes
switch (cameraMode) switch (cameraMode)
{ {
@ -316,48 +315,48 @@ void UpdateCamera(Camera *camera)
// Camera zoom // Camera zoom
if ((cameraTargetDistance < CAMERA_FREE_DISTANCE_MAX_CLAMP) && (mouseWheelMove < 0)) if ((cameraTargetDistance < CAMERA_FREE_DISTANCE_MAX_CLAMP) && (mouseWheelMove < 0))
{ {
cameraTargetDistance -= (mouseWheelMove*CAMERA_SCROLL_SENSITIVITY);
cameraTargetDistance -= (mouseWheelMove*CAMERA_MOUSE_SCROLL_SENSITIVITY);
if (cameraTargetDistance > CAMERA_FREE_DISTANCE_MAX_CLAMP) cameraTargetDistance = CAMERA_FREE_DISTANCE_MAX_CLAMP; if (cameraTargetDistance > CAMERA_FREE_DISTANCE_MAX_CLAMP) cameraTargetDistance = CAMERA_FREE_DISTANCE_MAX_CLAMP;
} }
// Camera looking down // Camera looking down
else if ((camera->position.y > camera->target.y) && (cameraTargetDistance == CAMERA_FREE_DISTANCE_MAX_CLAMP) && (mouseWheelMove < 0)) else if ((camera->position.y > camera->target.y) && (cameraTargetDistance == CAMERA_FREE_DISTANCE_MAX_CLAMP) && (mouseWheelMove < 0))
{ {
camera->target.x += mouseWheelMove*(camera->target.x - camera->position.x)*CAMERA_SCROLL_SENSITIVITY/cameraTargetDistance;
camera->target.y += mouseWheelMove*(camera->target.y - camera->position.y)*CAMERA_SCROLL_SENSITIVITY/cameraTargetDistance;
camera->target.z += mouseWheelMove*(camera->target.z - camera->position.z)*CAMERA_SCROLL_SENSITIVITY/cameraTargetDistance;
camera->target.x += mouseWheelMove*(camera->target.x - camera->position.x)*CAMERA_MOUSE_SCROLL_SENSITIVITY/cameraTargetDistance;
camera->target.y += mouseWheelMove*(camera->target.y - camera->position.y)*CAMERA_MOUSE_SCROLL_SENSITIVITY/cameraTargetDistance;
camera->target.z += mouseWheelMove*(camera->target.z - camera->position.z)*CAMERA_MOUSE_SCROLL_SENSITIVITY/cameraTargetDistance;
} }
else if ((camera->position.y > camera->target.y) && (camera->target.y >= 0)) else if ((camera->position.y > camera->target.y) && (camera->target.y >= 0))
{ {
camera->target.x += mouseWheelMove*(camera->target.x - camera->position.x)*CAMERA_SCROLL_SENSITIVITY/cameraTargetDistance;
camera->target.y += mouseWheelMove*(camera->target.y - camera->position.y)*CAMERA_SCROLL_SENSITIVITY/cameraTargetDistance;
camera->target.z += mouseWheelMove*(camera->target.z - camera->position.z)*CAMERA_SCROLL_SENSITIVITY/cameraTargetDistance;
camera->target.x += mouseWheelMove*(camera->target.x - camera->position.x)*CAMERA_MOUSE_SCROLL_SENSITIVITY/cameraTargetDistance;
camera->target.y += mouseWheelMove*(camera->target.y - camera->position.y)*CAMERA_MOUSE_SCROLL_SENSITIVITY/cameraTargetDistance;
camera->target.z += mouseWheelMove*(camera->target.z - camera->position.z)*CAMERA_MOUSE_SCROLL_SENSITIVITY/cameraTargetDistance;
// if (camera->target.y < 0) camera->target.y = -0.001; // if (camera->target.y < 0) camera->target.y = -0.001;
} }
else if ((camera->position.y > camera->target.y) && (camera->target.y < 0) && (mouseWheelMove > 0)) else if ((camera->position.y > camera->target.y) && (camera->target.y < 0) && (mouseWheelMove > 0))
{ {
cameraTargetDistance -= (mouseWheelMove*CAMERA_SCROLL_SENSITIVITY);
cameraTargetDistance -= (mouseWheelMove*CAMERA_MOUSE_SCROLL_SENSITIVITY);
if (cameraTargetDistance < CAMERA_FREE_DISTANCE_MIN_CLAMP) cameraTargetDistance = CAMERA_FREE_DISTANCE_MIN_CLAMP; if (cameraTargetDistance < CAMERA_FREE_DISTANCE_MIN_CLAMP) cameraTargetDistance = CAMERA_FREE_DISTANCE_MIN_CLAMP;
} }
// Camera looking up // Camera looking up
else if ((camera->position.y < camera->target.y) && (cameraTargetDistance == CAMERA_FREE_DISTANCE_MAX_CLAMP) && (mouseWheelMove < 0)) else if ((camera->position.y < camera->target.y) && (cameraTargetDistance == CAMERA_FREE_DISTANCE_MAX_CLAMP) && (mouseWheelMove < 0))
{ {
camera->target.x += mouseWheelMove*(camera->target.x - camera->position.x)*CAMERA_SCROLL_SENSITIVITY/cameraTargetDistance;
camera->target.y += mouseWheelMove*(camera->target.y - camera->position.y)*CAMERA_SCROLL_SENSITIVITY/cameraTargetDistance;
camera->target.z += mouseWheelMove*(camera->target.z - camera->position.z)*CAMERA_SCROLL_SENSITIVITY/cameraTargetDistance;
camera->target.x += mouseWheelMove*(camera->target.x - camera->position.x)*CAMERA_MOUSE_SCROLL_SENSITIVITY/cameraTargetDistance;
camera->target.y += mouseWheelMove*(camera->target.y - camera->position.y)*CAMERA_MOUSE_SCROLL_SENSITIVITY/cameraTargetDistance;
camera->target.z += mouseWheelMove*(camera->target.z - camera->position.z)*CAMERA_MOUSE_SCROLL_SENSITIVITY/cameraTargetDistance;
} }
else if ((camera->position.y < camera->target.y) && (camera->target.y <= 0)) else if ((camera->position.y < camera->target.y) && (camera->target.y <= 0))
{ {
camera->target.x += mouseWheelMove*(camera->target.x - camera->position.x)*CAMERA_SCROLL_SENSITIVITY/cameraTargetDistance;
camera->target.y += mouseWheelMove*(camera->target.y - camera->position.y)*CAMERA_SCROLL_SENSITIVITY/cameraTargetDistance;
camera->target.z += mouseWheelMove*(camera->target.z - camera->position.z)*CAMERA_SCROLL_SENSITIVITY/cameraTargetDistance;
camera->target.x += mouseWheelMove*(camera->target.x - camera->position.x)*CAMERA_MOUSE_SCROLL_SENSITIVITY/cameraTargetDistance;
camera->target.y += mouseWheelMove*(camera->target.y - camera->position.y)*CAMERA_MOUSE_SCROLL_SENSITIVITY/cameraTargetDistance;
camera->target.z += mouseWheelMove*(camera->target.z - camera->position.z)*CAMERA_MOUSE_SCROLL_SENSITIVITY/cameraTargetDistance;
// if (camera->target.y > 0) camera->target.y = 0.001; // if (camera->target.y > 0) camera->target.y = 0.001;
} }
else if ((camera->position.y < camera->target.y) && (camera->target.y > 0) && (mouseWheelMove > 0)) else if ((camera->position.y < camera->target.y) && (camera->target.y > 0) && (mouseWheelMove > 0))
{ {
cameraTargetDistance -= (mouseWheelMove*CAMERA_SCROLL_SENSITIVITY);
cameraTargetDistance -= (mouseWheelMove*CAMERA_MOUSE_SCROLL_SENSITIVITY);
if (cameraTargetDistance < CAMERA_FREE_DISTANCE_MIN_CLAMP) cameraTargetDistance = CAMERA_FREE_DISTANCE_MIN_CLAMP; if (cameraTargetDistance < CAMERA_FREE_DISTANCE_MIN_CLAMP) cameraTargetDistance = CAMERA_FREE_DISTANCE_MIN_CLAMP;
} }
@ -367,15 +366,15 @@ void UpdateCamera(Camera *camera)
if (IsKeyDown(cameraSmoothZoomControlKey)) if (IsKeyDown(cameraSmoothZoomControlKey))
{ {
// Camera smooth zoom // Camera smooth zoom
if (panKey) cameraTargetDistance += (cameraMouseVariation.y*CAMERA_FREE_SMOOTH_ZOOM_SENSITIVITY);
if (panKey) cameraTargetDistance += (mousePositionDelta.y*CAMERA_FREE_SMOOTH_ZOOM_SENSITIVITY);
} }
// Camera orientation calculation // Camera orientation calculation
else if (panKey) else if (panKey)
{ {
// Camera orientation calculation // Camera orientation calculation
// Get the mouse sensitivity // Get the mouse sensitivity
cameraAngle.x += cameraMouseVariation.x*-CAMERA_FREE_MOUSE_SENSITIVITY;
cameraAngle.y += cameraMouseVariation.y*-CAMERA_FREE_MOUSE_SENSITIVITY;
cameraAngle.x += mousePositionDelta.x*-CAMERA_FREE_MOUSE_SENSITIVITY;
cameraAngle.y += mousePositionDelta.y*-CAMERA_FREE_MOUSE_SENSITIVITY;
// Angle clamp // Angle clamp
if (cameraAngle.y > CAMERA_FREE_MIN_CLAMP*DEG2RAD) cameraAngle.y = CAMERA_FREE_MIN_CLAMP*DEG2RAD; if (cameraAngle.y > CAMERA_FREE_MIN_CLAMP*DEG2RAD) cameraAngle.y = CAMERA_FREE_MIN_CLAMP*DEG2RAD;
@ -385,9 +384,9 @@ void UpdateCamera(Camera *camera)
// Paning // Paning
else if (panKey) else if (panKey)
{ {
camera->target.x += ((cameraMouseVariation.x*-CAMERA_FREE_MOUSE_SENSITIVITY)*cos(cameraAngle.x) + (cameraMouseVariation.y*CAMERA_FREE_MOUSE_SENSITIVITY)*sin(cameraAngle.x)*sin(cameraAngle.y))*(cameraTargetDistance/CAMERA_FREE_PANNING_DIVIDER);
camera->target.y += ((cameraMouseVariation.y*CAMERA_FREE_MOUSE_SENSITIVITY)*cos(cameraAngle.y))*(cameraTargetDistance/CAMERA_FREE_PANNING_DIVIDER);
camera->target.z += ((cameraMouseVariation.x*CAMERA_FREE_MOUSE_SENSITIVITY)*sin(cameraAngle.x) + (cameraMouseVariation.y*CAMERA_FREE_MOUSE_SENSITIVITY)*cos(cameraAngle.x)*sin(cameraAngle.y))*(cameraTargetDistance/CAMERA_FREE_PANNING_DIVIDER);
camera->target.x += ((mousePositionDelta.x*-CAMERA_FREE_MOUSE_SENSITIVITY)*cos(cameraAngle.x) + (mousePositionDelta.y*CAMERA_FREE_MOUSE_SENSITIVITY)*sin(cameraAngle.x)*sin(cameraAngle.y))*(cameraTargetDistance/CAMERA_FREE_PANNING_DIVIDER);
camera->target.y += ((mousePositionDelta.y*CAMERA_FREE_MOUSE_SENSITIVITY)*cos(cameraAngle.y))*(cameraTargetDistance/CAMERA_FREE_PANNING_DIVIDER);
camera->target.z += ((mousePositionDelta.x*CAMERA_FREE_MOUSE_SENSITIVITY)*sin(cameraAngle.x) + (mousePositionDelta.y*CAMERA_FREE_MOUSE_SENSITIVITY)*cos(cameraAngle.x)*sin(cameraAngle.y))*(cameraTargetDistance/CAMERA_FREE_PANNING_DIVIDER);
} }
// Focus to center // Focus to center
@ -396,10 +395,8 @@ void UpdateCamera(Camera *camera)
// Camera position update // Camera position update
camera->position.x = sin(cameraAngle.x)*cameraTargetDistance*cos(cameraAngle.y) + camera->target.x; camera->position.x = sin(cameraAngle.x)*cameraTargetDistance*cos(cameraAngle.y) + camera->target.x;
if (cameraAngle.y <= 0.0f) camera->position.y = sin(cameraAngle.y)*cameraTargetDistance*sin(cameraAngle.y) + camera->target.y; if (cameraAngle.y <= 0.0f) camera->position.y = sin(cameraAngle.y)*cameraTargetDistance*sin(cameraAngle.y) + camera->target.y;
else camera->position.y = -sin(cameraAngle.y)*cameraTargetDistance*sin(cameraAngle.y) + camera->target.y; else camera->position.y = -sin(cameraAngle.y)*cameraTargetDistance*sin(cameraAngle.y) + camera->target.y;
camera->position.z = cos(cameraAngle.x)*cameraTargetDistance*cos(cameraAngle.y) + camera->target.z; camera->position.z = cos(cameraAngle.x)*cameraTargetDistance*cos(cameraAngle.y) + camera->target.z;
} break; } break;
@ -408,7 +405,7 @@ void UpdateCamera(Camera *camera)
cameraAngle.x += CAMERA_ORBITAL_SPEED; cameraAngle.x += CAMERA_ORBITAL_SPEED;
// Camera zoom // Camera zoom
cameraTargetDistance -= (mouseWheelMove*CAMERA_SCROLL_SENSITIVITY);
cameraTargetDistance -= (mouseWheelMove*CAMERA_MOUSE_SCROLL_SENSITIVITY);
// Camera distance clamp // Camera distance clamp
if (cameraTargetDistance < CAMERA_THIRD_PERSON_DISTANCE_CLAMP) cameraTargetDistance = CAMERA_THIRD_PERSON_DISTANCE_CLAMP; if (cameraTargetDistance < CAMERA_THIRD_PERSON_DISTANCE_CLAMP) cameraTargetDistance = CAMERA_THIRD_PERSON_DISTANCE_CLAMP;
@ -417,19 +414,20 @@ void UpdateCamera(Camera *camera)
if (IsKeyDown('Z')) camera->target = (Vector3){ 0.0f, 0.0f, 0.0f }; if (IsKeyDown('Z')) camera->target = (Vector3){ 0.0f, 0.0f, 0.0f };
// Camera position update // Camera position update
// TODO: It seems camera->position is not correctly updated or some rounding issue makes the camera move straight to camera->target...
camera->position.x = sin(cameraAngle.x)*cameraTargetDistance*cos(cameraAngle.y) + camera->target.x; camera->position.x = sin(cameraAngle.x)*cameraTargetDistance*cos(cameraAngle.y) + camera->target.x;
if (cameraAngle.y <= 0.0f) camera->position.y = sin(cameraAngle.y)*cameraTargetDistance*sin(cameraAngle.y) + camera->target.y; if (cameraAngle.y <= 0.0f) camera->position.y = sin(cameraAngle.y)*cameraTargetDistance*sin(cameraAngle.y) + camera->target.y;
else camera->position.y = -sin(cameraAngle.y)*cameraTargetDistance*sin(cameraAngle.y) + camera->target.y; else camera->position.y = -sin(cameraAngle.y)*cameraTargetDistance*sin(cameraAngle.y) + camera->target.y;
camera->position.z = cos(cameraAngle.x)*cameraTargetDistance*cos(cameraAngle.y) + camera->target.z; camera->position.z = cos(cameraAngle.x)*cameraTargetDistance*cos(cameraAngle.y) + camera->target.z;
} break; } break;
case CAMERA_FIRST_PERSON: case CAMERA_FIRST_PERSON:
case CAMERA_THIRD_PERSON: case CAMERA_THIRD_PERSON:
{ {
bool isMoving = false;
bool isMoving = false; // TODO: Really required for swinging?
// TODO: Get movement direction value [-1, 0, 1] in XZ and just multiply
// Keyboard inputs // Keyboard inputs
if (IsKeyDown(cameraMoveControl[MOVE_FRONT])) if (IsKeyDown(cameraMoveControl[MOVE_FRONT]))
{ {
@ -469,15 +467,15 @@ void UpdateCamera(Camera *camera)
if (cameraMode == CAMERA_THIRD_PERSON) if (cameraMode == CAMERA_THIRD_PERSON)
{ {
// Camera orientation calculation // Camera orientation calculation
cameraAngle.x += cameraMouseVariation.x*-cameraMouseSensitivity;
cameraAngle.y += cameraMouseVariation.y*-cameraMouseSensitivity;
cameraAngle.x += mousePositionDelta.x*-CAMERA_MOUSE_MOVE_SENSITIVITY;
cameraAngle.y += mousePositionDelta.y*-CAMERA_MOUSE_MOVE_SENSITIVITY;
// Angle clamp // Angle clamp
if (cameraAngle.y > CAMERA_THIRD_PERSON_MIN_CLAMP*DEG2RAD) cameraAngle.y = CAMERA_THIRD_PERSON_MIN_CLAMP*DEG2RAD; if (cameraAngle.y > CAMERA_THIRD_PERSON_MIN_CLAMP*DEG2RAD) cameraAngle.y = CAMERA_THIRD_PERSON_MIN_CLAMP*DEG2RAD;
else if (cameraAngle.y < CAMERA_THIRD_PERSON_MAX_CLAMP*DEG2RAD) cameraAngle.y = CAMERA_THIRD_PERSON_MAX_CLAMP*DEG2RAD; else if (cameraAngle.y < CAMERA_THIRD_PERSON_MAX_CLAMP*DEG2RAD) cameraAngle.y = CAMERA_THIRD_PERSON_MAX_CLAMP*DEG2RAD;
// Camera zoom // Camera zoom
cameraTargetDistance -= (mouseWheelMove*CAMERA_SCROLL_SENSITIVITY);
cameraTargetDistance -= (mouseWheelMove*CAMERA_MOUSE_SCROLL_SENSITIVITY);
// Camera distance clamp // Camera distance clamp
if (cameraTargetDistance < CAMERA_THIRD_PERSON_DISTANCE_CLAMP) cameraTargetDistance = CAMERA_THIRD_PERSON_DISTANCE_CLAMP; if (cameraTargetDistance < CAMERA_THIRD_PERSON_DISTANCE_CLAMP) cameraTargetDistance = CAMERA_THIRD_PERSON_DISTANCE_CLAMP;
@ -489,19 +487,17 @@ void UpdateCamera(Camera *camera)
// Camera position update // Camera position update
camera->position.x = sin(cameraAngle.x)*cameraTargetDistance*cos(cameraAngle.y) + camera->target.x; camera->position.x = sin(cameraAngle.x)*cameraTargetDistance*cos(cameraAngle.y) + camera->target.x;
if (cameraAngle.y <= 0.0f) camera->position.y = sin(cameraAngle.y)*cameraTargetDistance*sin(cameraAngle.y) + camera->target.y; if (cameraAngle.y <= 0.0f) camera->position.y = sin(cameraAngle.y)*cameraTargetDistance*sin(cameraAngle.y) + camera->target.y;
else camera->position.y = -sin(cameraAngle.y)*cameraTargetDistance*sin(cameraAngle.y) + camera->target.y; else camera->position.y = -sin(cameraAngle.y)*cameraTargetDistance*sin(cameraAngle.y) + camera->target.y;
camera->position.z = cos(cameraAngle.x)*cameraTargetDistance*cos(cameraAngle.y) + camera->target.z; camera->position.z = cos(cameraAngle.x)*cameraTargetDistance*cos(cameraAngle.y) + camera->target.z;
} }
else // CAMERA_FIRST_PERSON else // CAMERA_FIRST_PERSON
{ {
if (isMoving) cameraMoveCounter++;
if (isMoving) swingCounter++;
// Camera orientation calculation // Camera orientation calculation
cameraAngle.x += (cameraMouseVariation.x*-cameraMouseSensitivity);
cameraAngle.y += (cameraMouseVariation.y*-cameraMouseSensitivity);
cameraAngle.x += (mousePositionDelta.x*-CAMERA_MOUSE_MOVE_SENSITIVITY);
cameraAngle.y += (mousePositionDelta.y*-CAMERA_MOUSE_MOVE_SENSITIVITY);
// Angle clamp // Angle clamp
if (cameraAngle.y > CAMERA_FIRST_PERSON_MIN_CLAMP*DEG2RAD) cameraAngle.y = CAMERA_FIRST_PERSON_MIN_CLAMP*DEG2RAD; if (cameraAngle.y > CAMERA_FIRST_PERSON_MIN_CLAMP*DEG2RAD) cameraAngle.y = CAMERA_FIRST_PERSON_MIN_CLAMP*DEG2RAD;
@ -514,67 +510,27 @@ void UpdateCamera(Camera *camera)
// Camera position update // Camera position update
//camera->position.y = (playerPosition.y + PLAYER_HEIGHT*CAMERA_FIRST_PERSON_HEIGHT_RELATIVE_EYES_POSITION) //camera->position.y = (playerPosition.y + PLAYER_HEIGHT*CAMERA_FIRST_PERSON_HEIGHT_RELATIVE_EYES_POSITION)
// - sin(cameraMoveCounter/CAMERA_FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER)/CAMERA_FIRST_PERSON_STEP_DIVIDER;
// - sin(swingCounter/CAMERA_FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER)/CAMERA_FIRST_PERSON_STEP_DIVIDER;
// TODO: Review limits, avoid moving under the ground (y = 0.0f) and over the 'eyes position', weird movement (rounding issues...) // TODO: Review limits, avoid moving under the ground (y = 0.0f) and over the 'eyes position', weird movement (rounding issues...)
camera->position.y -= sin(cameraMoveCounter/CAMERA_FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER)/CAMERA_FIRST_PERSON_STEP_DIVIDER;
camera->position.y -= sin(swingCounter/CAMERA_FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER)/CAMERA_FIRST_PERSON_STEP_DIVIDER;
camera->up.x = sin(cameraMoveCounter/(CAMERA_FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER*2))/CAMERA_FIRST_PERSON_WAVING_DIVIDER;
camera->up.z = -sin(cameraMoveCounter/(CAMERA_FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER*2))/CAMERA_FIRST_PERSON_WAVING_DIVIDER;
camera->up.x = sin(swingCounter/(CAMERA_FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER*2))/CAMERA_FIRST_PERSON_WAVING_DIVIDER;
camera->up.z = -sin(swingCounter/(CAMERA_FIRST_PERSON_STEP_TRIGONOMETRIC_DIVIDER*2))/CAMERA_FIRST_PERSON_WAVING_DIVIDER;
} }
} break; } break;
default: break; default: break;
} }
} }
/*
// Set internal camera position
void SetCameraPosition(Vector3 position)
{
internalCamera.position = position;
Vector3 v1 = internalCamera.position;
Vector3 v2 = internalCamera.target;
float dx = v2.x - v1.x;
float dy = v2.y - v1.y;
float dz = v2.z - v1.z;
cameraTargetDistance = sqrt(dx*dx + dy*dy + dz*dz);
}
// Set internal camera target
void SetCameraTarget(Vector3 target)
{
internalCamera.target = target;
Vector3 v1 = internalCamera.position;
Vector3 v2 = internalCamera.target;
float dx = v2.x - v1.x;
float dy = v2.y - v1.y;
float dz = v2.z - v1.z;
cameraTargetDistance = sqrt(dx*dx + dy*dy + dz*dz);
}
*/
// Set camera pan key to combine with mouse movement (free camera) // Set camera pan key to combine with mouse movement (free camera)
void SetCameraPanControl(int panKey)
{
cameraPanControlKey = panKey;
}
void SetCameraPanControl(int panKey) { cameraPanControlKey = panKey; }
// Set camera alt key to combine with mouse movement (free camera) // Set camera alt key to combine with mouse movement (free camera)
void SetCameraAltControl(int altKey)
{
cameraAltControlKey = altKey;
}
void SetCameraAltControl(int altKey) { cameraAltControlKey = altKey; }
// Set camera smooth zoom key to combine with mouse (free camera) // Set camera smooth zoom key to combine with mouse (free camera)
void SetCameraSmoothZoomControl(int szKey)
{
cameraSmoothZoomControlKey = szKey;
}
void SetCameraSmoothZoomControl(int szKey) { cameraSmoothZoomControlKey = szKey; }
// Set camera move controls (1st person and 3rd person cameras) // Set camera move controls (1st person and 3rd person cameras)
void SetCameraMoveControls(int frontKey, int backKey, int leftKey, int rightKey, int upKey, int downKey) void SetCameraMoveControls(int frontKey, int backKey, int leftKey, int rightKey, int upKey, int downKey)
@ -587,10 +543,4 @@ void SetCameraMoveControls(int frontKey, int backKey, int leftKey, int rightKey,
cameraMoveControl[MOVE_DOWN] = downKey; cameraMoveControl[MOVE_DOWN] = downKey;
} }
// Set camera mouse sensitivity (1st person and 3rd person cameras)
void SetCameraMouseSensitivity(float sensitivity)
{
cameraMouseSensitivity = (sensitivity/10000.0f);
}
#endif // CAMERA_IMPLEMENTATION #endif // CAMERA_IMPLEMENTATION

+ 8
- 9
src/raylib.h 查看文件

@ -559,7 +559,13 @@ typedef enum {
} Gestures; } Gestures;
// Camera system modes // Camera system modes
typedef enum { CAMERA_CUSTOM = 0, CAMERA_FREE, CAMERA_ORBITAL, CAMERA_FIRST_PERSON, CAMERA_THIRD_PERSON } CameraMode;
typedef enum {
CAMERA_CUSTOM = 0,
CAMERA_FREE,
CAMERA_ORBITAL,
CAMERA_FIRST_PERSON,
CAMERA_THIRD_PERSON
} CameraMode;
// Head Mounted Display devices // Head Mounted Display devices
typedef enum { typedef enum {
@ -698,22 +704,15 @@ RLAPI float GetGesturePinchAngle(void); // Get gesture pin
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
// Camera System Functions (Module: camera) // Camera System Functions (Module: camera)
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
RLAPI void SetCameraMode(int mode); // Set camera mode (multiple camera modes available)
RLAPI void SetCameraMode(n">Camera, int mode); // Set camera mode (multiple camera modes available)
RLAPI void UpdateCamera(Camera *camera); // Update camera (player position is ignored) RLAPI void UpdateCamera(Camera *camera); // Update camera (player position is ignored)
RLAPI void UpdateCameraPlayer(Camera *camera, Vector3 *position); // Update camera and player position (1st person and 3rd person cameras)
RLAPI void SetCameraPosition(Vector3 position); // Set internal camera position
RLAPI void SetCameraTarget(Vector3 target); // Set internal camera target
RLAPI void SetCameraFovy(float fovy); // Set internal camera field-of-view-y
RLAPI void SetCameraPanControl(int panKey); // Set camera pan key to combine with mouse movement (free camera) RLAPI void SetCameraPanControl(int panKey); // Set camera pan key to combine with mouse movement (free camera)
RLAPI void SetCameraAltControl(int altKey); // Set camera alt key to combine with mouse movement (free camera) RLAPI void SetCameraAltControl(int altKey); // Set camera alt key to combine with mouse movement (free camera)
RLAPI void SetCameraSmoothZoomControl(int szKey); // Set camera smooth zoom key to combine with mouse (free camera) RLAPI void SetCameraSmoothZoomControl(int szKey); // Set camera smooth zoom key to combine with mouse (free camera)
RLAPI void SetCameraMoveControls(int frontKey, int backKey, RLAPI void SetCameraMoveControls(int frontKey, int backKey,
int leftKey, int rightKey, int leftKey, int rightKey,
int upKey, int downKey); // Set camera move controls (1st person and 3rd person cameras) int upKey, int downKey); // Set camera move controls (1st person and 3rd person cameras)
RLAPI void SetCameraMouseSensitivity(float sensitivity); // Set camera mouse sensitivity (1st person and 3rd person cameras)
//------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------
// Basic Shapes Drawing Functions (Module: shapes) // Basic Shapes Drawing Functions (Module: shapes)

正在加载...
取消
保存