From 1b3e0ab2f68122e0123f8de6fbc3b2f2bb1b3bcf Mon Sep 17 00:00:00 2001 From: MegaMech Date: Tue, 7 Jan 2025 13:05:34 -0700 Subject: [PATCH] Freecam targetting fixed --- src/enhancements/freecam/freecam.cpp | 145 ++++++++-------------- src/enhancements/freecam/freecam.h | 2 - src/enhancements/freecam/freecam_engine.c | 106 ++++------------ src/enhancements/freecam/freecam_engine.h | 10 +- src/port/ui/FreecamWindow.cpp | 3 +- 5 files changed, 78 insertions(+), 188 deletions(-) diff --git a/src/enhancements/freecam/freecam.cpp b/src/enhancements/freecam/freecam.cpp index 83c33a666..56eb813d9 100644 --- a/src/enhancements/freecam/freecam.cpp +++ b/src/enhancements/freecam/freecam.cpp @@ -44,16 +44,6 @@ int rightMouseButtonDown = 0; // Track if right mouse button is held down u32 gFreecamControllerType = 0; -// void freecam_n64_calculate_forward_vector(Camera* camera, Vec3f forwardVector); -// void freecam_n64_move_camera_forward(Camera* camera, struct Controller *controller, f32 distance); -// void freecam_calculate_forward_vector(Camera* camera, Vec3f forwardVector); -// void freecam_move_camera_forward(Camera* camera, f32 distance); - -// void freecam_tick(Camera* camera, struct Controller *controller); -// void freecam_n64_controller_manager(Camera *camera, struct Controller *controller, Player *player); -// void freecam_target_player(Camera *camera, u32 playerIndex); -// void freecam_move_camera_up(Camera* camera, struct Controller *controller, f32 distance); - /** * Controls * @@ -77,7 +67,6 @@ u32 gFreecamControllerType = 0; * Camera mode 2: Enter freecam at previous freecam spot * */ - void freecam(Camera* camera, Player* player, s8 index) { struct Controller* controller = &gControllers[0]; f32 dirX; @@ -98,22 +87,6 @@ void freecam(Camera* camera, Player* player, s8 index) { } gIsHUDVisible = !CVarGetInteger("gFreecam", 0); - - if (CVarGetInteger("gFreecam", 0) == 1) { - - if (fMode && fModeInit) { - freecam_load_state(camera); - } else { - // !fMode or fMode not initialized - //freecam_target_player(camera, get_player_index_for_player(player)); - } - - return; - } else { - if (fMode) { - freecam_save_state(camera); - } - } } // Driving mode @@ -123,51 +96,22 @@ void freecam(Camera* camera, Player* player, s8 index) { return; } - // if (player == gPlayerOne) { return; } - - // player->type &= ~PLAYER_HUMAN; - // player->type |= PLAYER_HUMAN; - - // if ((player->type & PLAYER_START_SEQUENCE)) { return; } - + // Calculate forward direction freecam_calculate_forward_vector_allow_rotation(camera, freeCam.forwardVector); - freecam_mouse_manager(camera, freeCam.forwardVector); + + // Adjust camera rotation + if (fTargetPlayer) { + freecam_target_player(camera, freeCam.forwardVector); + } else { + freecam_mouse_manager(camera, freeCam.forwardVector); + } + + // Adjust camera position freecam_keyboard_manager(camera, freeCam.forwardVector); - if (fTargetPlayer) { - freecam_target_player(camera, D_800DC5EC->player); - } else { - freecam_tick(camera, freeCam.forwardVector); - } -} + // Apply final position, velocity, and lookAt + freecam_tick(camera, freeCam.forwardVector); -void freecam_save_state(Camera* camera) { - fState.pos[0] = camera->pos[0]; - fState.pos[1] = camera->pos[1]; - fState.pos[2] = camera->pos[2]; - - fState.lookAt[0] = camera->lookAt[0]; - fState.lookAt[1] = camera->lookAt[1]; - fState.lookAt[2] = camera->lookAt[2]; - - fState.rot[0] = camera->rot[0]; - fState.rot[1] = camera->rot[1]; - fState.rot[2] = camera->rot[2]; - fModeInit = true; -} - -void freecam_load_state(Camera* camera) { - camera->pos[0] = fState.pos[0]; - camera->pos[1] = fState.pos[1]; - camera->pos[2] = fState.pos[2]; - - camera->lookAt[0] = fState.lookAt[0]; - camera->lookAt[1] = fState.lookAt[1]; - camera->lookAt[2] = fState.lookAt[2]; - - camera->rot[0] = fState.rot[0]; - camera->rot[1] = fState.rot[1]; - camera->rot[2] = fState.rot[2]; } f32 gFreecamRotateSmoothingFactor = 0.85f; @@ -203,9 +147,6 @@ void freecam_mouse_manager(Camera* camera, Vec3f forwardVector) { camera->rot[2] = -15999; } - // Calculate the forward vector based on the new yaw and pitch - // freecam_calculate_forward_vector_allow_rotation(camera, forwardVector); - // Smoothly interpolate the lookAt position Vec3f targetLookAt = { camera->pos[0] + forwardVector[0], camera->pos[1] + forwardVector[1], camera->pos[2] + forwardVector[2] }; @@ -219,6 +160,36 @@ void freecam_mouse_manager(Camera* camera, Vec3f forwardVector) { f32 gFreecamSpeed = 3.0f; f32 gFreecamSpeedMultiplier = 2.0f; +bool prevPrev = false; + +#define MAX_KEYS 256 +static bool prevKeyState[MAX_KEYS] = { false }; + +// KeyDown function +bool FreecamKeyDown(int virtualKey) { + auto wnd = GameEngine::Instance->context->GetWindow(); + static bool prevKeyState[256] = { false }; // Store previous key states + bool isDownNow = false; + + if (wnd->GetWindowBackend() == Ship::WindowBackend::FAST3D_SDL_OPENGL) { + // Use SDL to check key states + const uint8_t* keystate = SDL_GetKeyboardState(NULL); + isDownNow = keystate[virtualKey] != 0; + } else if (wnd->GetWindowBackend() == Ship::WindowBackend::FAST3D_DXGI_DX11) { + // Use Windows GetKeyState for DirectX + SHORT keyState = GetKeyState(virtualKey); + isDownNow = (keyState & 0x8000) != 0; + } + + // Determine if this is a new key press + bool isKeyDownEvent = isDownNow && !prevKeyState[virtualKey]; + + // Update the previous state for this key + prevKeyState[virtualKey] = isDownNow; + + return isKeyDownEvent; +} + void freecam_keyboard_manager(Camera* camera, Vec3f forwardVector) { auto wnd = GameEngine::Instance->context->GetWindow(); @@ -236,7 +207,6 @@ void freecam_keyboard_manager(Camera* camera, Vec3f forwardVector) { // if (keystate[SDL_SCANCODE_G]) { // fTargetPlayer = false; // } - static bool prevPrev; bool TargetNextPlayer = false, TargetPreviousPlayer = false; bool prevNext; bool Forward = false, PanLeft = false, Backward = false, PanRight = false; bool Up = false, Down = false; @@ -253,7 +223,6 @@ void freecam_keyboard_manager(Camera* camera, Vec3f forwardVector) { if (controller->buttonPressed & R_TRIG) { fTargetPlayer = !fTargetPlayer; } - if (controller->buttonPressed & L_CBUTTONS) { TargetPreviousPlayer = true; } @@ -283,16 +252,13 @@ void freecam_keyboard_manager(Camera* camera, Vec3f forwardVector) { // } // Keyboard and mouse DX } else if (wnd->GetWindowBackend() == Ship::WindowBackend::FAST3D_DXGI_DX11) { - if (GetKeyState('F') & 0x8000) { + if (FreecamKeyDown('F')) { fTargetPlayer = !fTargetPlayer; } - if (GetKeyState('N') & 0x8000) { - if (!prevPrev) { - prevPrev = true; - TargetPreviousPlayer = true; - } + if (FreecamKeyDown('N')) { + TargetPreviousPlayer = true; } - if (GetKeyState('M') & 0x8000) { + if (FreecamKeyDown('M')) { TargetNextPlayer = true; } if (GetKeyState('W') & 0x8000) { @@ -320,13 +286,13 @@ void freecam_keyboard_manager(Camera* camera, Vec3f forwardVector) { // Keyboard/mouse OpenGL/SDL } else if (wnd->GetWindowBackend() == Ship::WindowBackend::FAST3D_SDL_OPENGL) { const uint8_t* keystate = SDL_GetKeyboardState(NULL); - if (keystate[SDL_SCANCODE_F]) { - fTargetPlayer != fTargetPlayer; + if (FreecamKeyDown(SDL_SCANCODE_F)) { + fTargetPlayer = !fTargetPlayer; } - if (keystate[SDL_SCANCODE_N]) { + if (FreecamKeyDown(SDL_SCANCODE_N)) { TargetPreviousPlayer = true; } - if (keystate[SDL_SCANCODE_M]) { + if (FreecamKeyDown(SDL_SCANCODE_M)) { TargetNextPlayer = true; } if (keystate[SDL_SCANCODE_W]) { @@ -370,13 +336,6 @@ void freecam_keyboard_manager(Camera* camera, Vec3f forwardVector) { } } - // Target camera at chosen player - if (fRankIndex != -1) { - //freecam_target_player(camera, gGPCurrentRacePlayerIdByRank[fRankIndex]); - // Don't run the other camera code. - //return; - } - if (FastMove) { moveSpeed *= gFreecamSpeedMultiplier; } @@ -406,10 +365,6 @@ void freecam_keyboard_manager(Camera* camera, Vec3f forwardVector) { freeCam.velocity[0] += totalMove[0]; freeCam.velocity[1] += totalMove[1]; freeCam.velocity[2] += totalMove[2]; - - // Update camera's lookAt position - camera->lookAt[0] = camera->pos[0] + forwardVector[0]; - camera->lookAt[2] = camera->pos[2] + forwardVector[2]; } void freecam_render_setup(void) { diff --git a/src/enhancements/freecam/freecam.h b/src/enhancements/freecam/freecam.h index b07edaa06..4eaa45a89 100644 --- a/src/enhancements/freecam/freecam.h +++ b/src/enhancements/freecam/freecam.h @@ -10,8 +10,6 @@ extern "C" { void freecam(Camera*, Player*, s8); void freecam_render_setup(void); -void freecam_save_state(Camera*); -void freecam_load_state(Camera*); void freecam_mouse_manager(Camera*, Vec3f); void freecam_keyboard_manager(Camera*, Vec3f); diff --git a/src/enhancements/freecam/freecam_engine.c b/src/enhancements/freecam/freecam_engine.c index 8a78917fd..1116de60f 100644 --- a/src/enhancements/freecam/freecam_engine.c +++ b/src/enhancements/freecam/freecam_engine.c @@ -33,49 +33,6 @@ void freecam_tick(Camera* camera, Vec3f forwardVector) { camera->lookAt[2] = camera->pos[2] + forwardVector[2]; } -// Function to move the camera forward or backward without changing its height -void freecam_move_camera_forward(Camera* camera, f32 moveSpeed, Vec3f forwardVector) { - // Calculate the forward vector - forwardVector[0] = camera->lookAt[0] - camera->pos[0]; - // forwardVector[1] = 0; // Don't change the height - forwardVector[2] = camera->lookAt[2] - camera->pos[2]; - - // Normalize the forward vector - f32 length = sqrtf(forwardVector[0] * forwardVector[0] + forwardVector[2] * forwardVector[2]); - if (length != 0) { - forwardVector[0] /= length; - forwardVector[2] /= length; - } - - // Update FreeCam velocity - freeCam.velocity[0] = forwardVector[0] * moveSpeed; - freeCam.velocity[2] = forwardVector[2] * moveSpeed; - - camera->lookAt[0] = camera->pos[0] + forwardVector[0]; - camera->lookAt[2] = camera->pos[0] + forwardVector[2]; -} - -void freecam_pan_camera(Camera* camera, f32 moveSpeed) { - Vec3f rightVector; - f32 length; - - // Calculate the right vector for pan movement - rightVector[0] = camera->lookAt[2] - camera->pos[2]; - // rightVector[1] = 0; // Maintain the same height - rightVector[2] = -(camera->lookAt[0] - camera->pos[0]); - - // Normalize the right vector - length = sqrtf(rightVector[0] * rightVector[0] + rightVector[2] * rightVector[2]); - if (length != 0) { - rightVector[0] /= length; - rightVector[2] /= length; - } - - // Update camera's position - freeCam.velocity[0] = rightVector[0] * moveSpeed; - freeCam.velocity[2] = rightVector[2] * moveSpeed; -} - void freecam_calculate_forward_vector_allow_rotation(Camera* camera, Vec3f forwardVector) { // Convert yaw from 0-65535 to degrees f32 pitch = (camera->rot[2] / 65535.0f) * 360.0f; @@ -91,51 +48,16 @@ void freecam_calculate_forward_vector_allow_rotation(Camera* camera, Vec3f forwa forwardVector[2] = cosf(yaw); } -// Calculates the forward direction vector based on camera orientation -void freecam_calculate_forward_vector(Camera* camera, Vec3f forwardVector) { - // Convert yaw from 0-65535 to degrees - f32 yaw = (camera->rot[0] / 65535.0f) * 360.0f; - f32 pitch = (camera->rot[2] / 65535.0f) * 360.0f; - - // Convert degrees to radians - yaw = yaw * M_PI / 180.0f; - pitch = pitch * M_PI / 180.0f; - - // Calculate the forward vector based on yaw and pitch - forwardVector[0] = -sinf(yaw) * cosf(pitch); // x-component - forwardVector[1] = sinf(pitch); // y-component (vertical) - forwardVector[2] = cosf(yaw) * cosf(pitch); // z-component -} - -// Function to move the camera forward -void freecam_move_camera_up(Camera* camera, f32 distance) { - // Update the velocity of the camera in the Y direction - freeCam.velocity[1] += distance; - camera->lookAt[1] += distance; -} -void freecam_move_camera_down(Camera* camera, f32 distance) { - // Update the velocity of the camera in the Y direction - freeCam.velocity[1] += distance; - camera->lookAt[1] += distance; -} - -void freecam_target_player(Camera* camera, Player* player) { - Vec3f forwardVector; // = 2.0f; - - // Update position - camera->pos[0] += freeCam.velocity[0] * gDeltaTime; - camera->pos[1] += freeCam.velocity[1] * gDeltaTime; - camera->pos[2] += freeCam.velocity[2] * gDeltaTime; - +void freecam_target_player(Camera* camera, Vec3f forwardVector) { // Apply damping to velocity freeCam.velocity[0] *= gDampValue; freeCam.velocity[1] *= gDampValue; freeCam.velocity[2] *= gDampValue; // Calculate the direction from the player to the camera - f32 dirX = player->pos[0] - camera->pos[0]; - f32 dirY = player->pos[1] - camera->pos[1]; - f32 dirZ = player->pos[2] - camera->pos[2]; + f32 dirX = gPlayers[fRankIndex].pos[0] - camera->pos[0]; + f32 dirY = gPlayers[fRankIndex].pos[1] - camera->pos[1]; + f32 dirZ = gPlayers[fRankIndex].pos[2] - camera->pos[2]; // Normalize the direction vector (if needed) f32 length = sqrtf(dirX * dirX + dirY * dirY + dirZ * dirZ); @@ -149,4 +71,24 @@ void freecam_target_player(Camera* camera, Player* player) { camera->lookAt[0] = camera->pos[0] + dirX; camera->lookAt[1] = camera->pos[1] + dirY; camera->lookAt[2] = camera->pos[2] + dirZ; + + // Calculate the forward vector based on the updated look-at direction + forwardVector[0] = camera->lookAt[0] - camera->pos[0]; + forwardVector[1] = camera->lookAt[1] - camera->pos[1]; + forwardVector[2] = camera->lookAt[2] - camera->pos[2]; + + // Normalize the forward vector + f32 forwardLength = sqrtf(forwardVector[0] * forwardVector[0] + + forwardVector[1] * forwardVector[1] + + forwardVector[2] * forwardVector[2]); + if (forwardLength > 0.0f) { + forwardVector[0] /= forwardLength; + forwardVector[1] /= forwardLength; + forwardVector[2] /= forwardLength; + } + + // Store or return the forward vector as needed for subsequent movement calculations + freeCam.forwardVector[0] = forwardVector[0]; + freeCam.forwardVector[1] = forwardVector[1]; + freeCam.forwardVector[2] = forwardVector[2]; } diff --git a/src/enhancements/freecam/freecam_engine.h b/src/enhancements/freecam/freecam_engine.h index 49e79d0ea..7c7ecc754 100644 --- a/src/enhancements/freecam/freecam_engine.h +++ b/src/enhancements/freecam/freecam_engine.h @@ -19,16 +19,12 @@ typedef struct { extern FreeCam freeCam; extern f32 gDampValue; +extern u32 fTargetPlayer; +extern u32 fRankIndex; -// void update_camera(Camera *camera, f32 deltaTime); -void freecam_pan_camera(Camera* camera, f32 moveSpeed); void freecam_calculate_forward_vector_allow_rotation(Camera* camera, Vec3f forwardVector); -void freecam_calculate_forward_vector(Camera* camera, Vec3f forwardVector); -void freecam_move_camera_forward(Camera* camera, f32 distance, Vec3f forwardVector); -void freecam_target_player(Camera* camera, Player* player); +void freecam_target_player(Camera* camera, Vec3f forwardVector); void freecam_tick(Camera* camera, Vec3f forwardVector); -void freecam_move_camera_up(Camera* camera, f32); -void freecam_move_camera_down(Camera* camera, f32); extern f32 gDampValue; diff --git a/src/port/ui/FreecamWindow.cpp b/src/port/ui/FreecamWindow.cpp index de9706c2f..fcf532747 100644 --- a/src/port/ui/FreecamWindow.cpp +++ b/src/port/ui/FreecamWindow.cpp @@ -61,8 +61,7 @@ void FreecamWindow::DrawElement() { gFreecamControllerType = current_item; } - ImGui::Text("Move: W,A,S,D\nUp: Space, Down: Shift\nFaster: Ctrl\nLook: Right-mouse button\nTarget previous " - "player: N, Target next player: M"); + ImGui::Text("Move: W,A,S,D\nUp: Space, Down: Shift\nFaster: Ctrl\nLook: Right-mouse button\nTarget Player Mode: F, Next: M, Previous: N"); ImGui::Spacing(); UIWidgets::CVarCheckbox("Enable Flycam", "gFreecam", { .tooltip = "Allows you to fly around the course" });