From 418b1201a032ba80e770d77a3d3efccbf351f51e Mon Sep 17 00:00:00 2001 From: Cooliokid956 <68075390+Cooliokid956@users.noreply.github.com> Date: Mon, 21 Oct 2024 20:04:46 -0500 Subject: [PATCH] Various FOV fixes and additions (#384) * interpolate all fovs * perfected the fov equation just the facts * create fov coefficient function use it to scale units along with fov * add get_current_fov returns the current fov --- autogen/lua_definitions/functions.lua | 10 ++++++++ docs/lua/functions-3.md | 36 +++++++++++++++++++++++++++ docs/lua/functions.md | 2 ++ src/game/camera.c | 3 ++- src/game/rendering_graph_node.c | 6 ++--- src/pc/djui/djui_hud_utils.c | 24 ++++++++++++------ src/pc/djui/djui_hud_utils.h | 2 ++ src/pc/lua/smlua_functions_autogen.c | 32 ++++++++++++++++++++++++ 8 files changed, 103 insertions(+), 12 deletions(-) diff --git a/autogen/lua_definitions/functions.lua b/autogen/lua_definitions/functions.lua index c96badca..ac261e3f 100644 --- a/autogen/lua_definitions/functions.lua +++ b/autogen/lua_definitions/functions.lua @@ -3070,6 +3070,11 @@ function djui_hud_get_font() -- ... end +--- @return number +function djui_hud_get_fov_coeff() + -- ... +end + --- @return number function djui_hud_get_mouse_x() -- ... @@ -3220,6 +3225,11 @@ function djui_open_pause_menu() -- ... end +--- @return number +function get_current_fov() + -- ... +end + --- @param message string --- @param lines integer function djui_popup_create(message, lines) diff --git a/docs/lua/functions-3.md b/docs/lua/functions-3.md index 961ffb8e..185315d7 100644 --- a/docs/lua/functions-3.md +++ b/docs/lua/functions-3.md @@ -2170,6 +2170,24 @@
+## [djui_hud_get_fov_coeff](#djui_hud_get_fov_coeff) + +### Lua Example +`local numberValue = djui_hud_get_fov_coeff()` + +### Parameters +- None + +### Returns +- `number` + +### C Prototype +`f32 djui_hud_get_fov_coeff();` + +[:arrow_up_small:](#) + +
+ ## [djui_hud_get_mouse_x](#djui_hud_get_mouse_x) ### Lua Example @@ -2658,6 +2676,24 @@
+## [get_current_fov](#get_current_fov) + +### Lua Example +`local numberValue = get_current_fov()` + +### Parameters +- None + +### Returns +- `number` + +### C Prototype +`f32 get_current_fov();` + +[:arrow_up_small:](#) + +
+ --- # functions from djui_popup.h diff --git a/docs/lua/functions.md b/docs/lua/functions.md index ce7b3baf..2829b664 100644 --- a/docs/lua/functions.md +++ b/docs/lua/functions.md @@ -748,6 +748,7 @@ - [djui_hud_get_color](functions-3.md#djui_hud_get_color) - [djui_hud_get_filter](functions-3.md#djui_hud_get_filter) - [djui_hud_get_font](functions-3.md#djui_hud_get_font) + - [djui_hud_get_fov_coeff](functions-3.md#djui_hud_get_fov_coeff) - [djui_hud_get_mouse_x](functions-3.md#djui_hud_get_mouse_x) - [djui_hud_get_mouse_y](functions-3.md#djui_hud_get_mouse_y) - [djui_hud_get_raw_mouse_x](functions-3.md#djui_hud_get_raw_mouse_x) @@ -772,6 +773,7 @@ - [djui_hud_set_rotation_interpolated](functions-3.md#djui_hud_set_rotation_interpolated) - [djui_hud_world_pos_to_screen_pos](functions-3.md#djui_hud_world_pos_to_screen_pos) - [djui_open_pause_menu](functions-3.md#djui_open_pause_menu) + - [get_current_fov](functions-3.md#get_current_fov)
diff --git a/src/game/camera.c b/src/game/camera.c index 8b93e124..89c82e53 100644 --- a/src/game/camera.c +++ b/src/game/camera.c @@ -36,6 +36,7 @@ #include "pc/lua/smlua_hooks.h" #include "pc/djui/djui.h" #include "first_person_cam.h" +#include "rendering_graph_node.h" #define CBUTTON_MASK (U_CBUTTONS | D_CBUTTONS | L_CBUTTONS | R_CBUTTONS) @@ -12027,7 +12028,7 @@ Gfx *geo_camera_fov(s32 callContext, struct GraphNode *g, UNUSED void *context) } } - perspective->fov = gFOVState.fov; + perspective->fov = get_first_person_enabled() ? gFirstPersonCamera.fov : not_zero(gFOVState.fov, gOverrideFOV); shake_camera_fov(perspective); return NULL; } diff --git a/src/game/rendering_graph_node.c b/src/game/rendering_graph_node.c index 9f7adeac..46b66a78 100644 --- a/src/game/rendering_graph_node.c +++ b/src/game/rendering_graph_node.c @@ -237,7 +237,7 @@ void patch_mtx_interpolated(f32 delta) { u16 perspNorm; f32 fovInterpolated = delta_interpolate_f32(sPerspectiveNode->prevFov, sPerspectiveNode->fov, delta); f32 near = MIN(sPerspectiveNode->near, gProjectionMaxNearValue); - guPerspective(sPerspectiveMtx, &perspNorm, get_first_person_enabled() ? gFirstPersonCamera.fov : not_zero(fovInterpolated, gOverrideFOV), sPerspectiveAspect, get_first_person_enabled() ? 1 : not_zero(near, gOverrideNear), not_zero(sPerspectiveNode->far, gOverrideFar), 1.0f); + guPerspective(sPerspectiveMtx, &perspNorm, fovInterpolated, sPerspectiveAspect, get_first_person_enabled() ? 1 : not_zero(near, gOverrideNear), not_zero(sPerspectiveNode->far, gOverrideFar), 1.0f); gSPMatrix(sPerspectivePos, VIRTUAL_TO_PHYSICAL(sPerspectiveNode), G_MTX_PROJECTION | G_MTX_LOAD | G_MTX_NOPUSH); } @@ -488,7 +488,7 @@ static void geo_process_perspective(struct GraphNodePerspective *node) { gProjectionVanillaNearValue = node->near; gProjectionVanillaFarValue = node->far; f32 near = MIN(node->near, gProjectionMaxNearValue); - guPerspective(mtx, &perspNorm, not_zero(node->prevFov, gOverrideFOV), aspect, get_first_person_enabled() ? 1 : not_zero(near, gOverrideNear), not_zero(node->far, gOverrideFar), 1.0f); + guPerspective(mtx, &perspNorm, node->prevFov, aspect, get_first_person_enabled() ? 1 : not_zero(near, gOverrideNear), not_zero(node->far, gOverrideFar), 1.0f); sPerspectiveNode = node; sPerspectiveMtx = mtx; @@ -1156,7 +1156,7 @@ static s32 obj_is_in_view(struct GraphNodeObject *node, Mat4 matrix) { // visibly pop in or out at the edge of the screen. // // Half of the fov in in-game angle units instead of degrees. - s16 halfFov = ((get_first_person_enabled() ? gFirstPersonCamera.fov : not_zero(gCurGraphNodeCamFrustum->fov, gOverrideFOV)) / 2.0f + 1.0f) * 32768.0f / 180.0f + 0.5f; + s16 halfFov = (gCurGraphNodeCamFrustum->fov / 2.0f + 1.0f) * 32768.0f / 180.0f + 0.5f; f32 divisor = coss(halfFov); if (divisor == 0) { divisor = 1; } diff --git a/src/pc/djui/djui_hud_utils.c b/src/pc/djui/djui_hud_utils.c index 9fbb72ca..cf532ddb 100644 --- a/src/pc/djui/djui_hud_utils.c +++ b/src/pc/djui/djui_hud_utils.c @@ -614,6 +614,19 @@ static void hud_rotate_and_translate_vec3f(Vec3f vec, Mat4* mtx, Vec3f out) { out[2] += (*mtx)[3][2]; } +f32 get_current_fov() { + return get_first_person_enabled() ? gFirstPersonCamera.fov : not_zero(gFOVState.fov, gOverrideFOV) + gFOVState.fovOffset; +} + +f32 djui_hud_get_fov_coeff() { + // fov of 45.0 is the default fov + f32 fov = get_current_fov(); + f32 fovDefault = tanf(45.f * ((f32)M_PI / 360.0f)); + f32 fovCurrent = tanf(fov * ((f32)M_PI / 360.0f)); + + return (fovDefault / fovCurrent) * 1.13f; +} + bool djui_hud_world_pos_to_screen_pos(Vec3f pos, Vec3f out) { if (!gCamera) { return false; } hud_rotate_and_translate_vec3f(pos, &gCamera->mtx, out); @@ -624,15 +637,10 @@ bool djui_hud_world_pos_to_screen_pos(Vec3f pos, Vec3f out) { out[0] *= 256.0f / -out[2]; out[1] *= 256.0f / out[2]; - // fov of 45.0 is the default fov - f32 fov = get_first_person_enabled() ? gFirstPersonCamera.fov : not_zero(45.0f, gOverrideFOV); - f32 fovDefault = tanf(fov * ((f32)M_PI / 360.0f)); - f32 fovCurrent = tanf((fov + gFOVState.fovOffset) * ((f32)M_PI / 360.0f)); + f32 fovCoeff = djui_hud_get_fov_coeff(); - f32 fovDifference = (fovDefault / fovCurrent) * 1.13f; - - out[0] *= fovDifference; - out[1] *= fovDifference; + out[0] *= fovCoeff; + out[1] *= fovCoeff; out[0] += djui_hud_get_screen_width() / 2.0f; out[1] += djui_hud_get_screen_height() / 2.0f; diff --git a/src/pc/djui/djui_hud_utils.h b/src/pc/djui/djui_hud_utils.h index d001fbd7..f2a38229 100644 --- a/src/pc/djui/djui_hud_utils.h +++ b/src/pc/djui/djui_hud_utils.h @@ -87,6 +87,8 @@ void djui_hud_render_texture_tile_interpolated(struct TextureInfo* texInfo, f32 void djui_hud_render_rect(f32 x, f32 y, f32 width, f32 height); void djui_hud_render_rect_interpolated(f32 prevX, f32 prevY, f32 prevWidth, f32 prevHeight, f32 x, f32 y, f32 width, f32 height); +f32 get_current_fov(); +f32 djui_hud_get_fov_coeff(); bool djui_hud_world_pos_to_screen_pos(Vec3f pos, Vec3f out); bool djui_hud_is_pause_menu_created(void); diff --git a/src/pc/lua/smlua_functions_autogen.c b/src/pc/lua/smlua_functions_autogen.c index a24cfd88..d3b79cdd 100644 --- a/src/pc/lua/smlua_functions_autogen.c +++ b/src/pc/lua/smlua_functions_autogen.c @@ -12295,6 +12295,21 @@ int smlua_func_djui_hud_get_font(UNUSED lua_State* L) { return 1; } +int smlua_func_djui_hud_get_fov_coeff(UNUSED lua_State* L) { + if (L == NULL) { return 0; } + + int top = lua_gettop(L); + if (top != 0) { + LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "djui_hud_get_fov_coeff", 0, top); + return 0; + } + + + lua_pushnumber(L, djui_hud_get_fov_coeff()); + + return 1; +} + int smlua_func_djui_hud_get_mouse_x(UNUSED lua_State* L) { if (L == NULL) { return 0; } @@ -12757,6 +12772,21 @@ int smlua_func_djui_open_pause_menu(UNUSED lua_State* L) { return 1; } +int smlua_func_get_current_fov(UNUSED lua_State* L) { + if (L == NULL) { return 0; } + + int top = lua_gettop(L); + if (top != 0) { + LOG_LUA_LINE("Improper param count for '%s': Expected %u, Received %u", "get_current_fov", 0, top); + return 0; + } + + + lua_pushnumber(L, get_current_fov()); + + return 1; +} + ////////////////// // djui_popup.h // ////////////////// @@ -33957,6 +33987,7 @@ void smlua_bind_functions_autogen(void) { smlua_bind_function(L, "djui_hud_get_color", smlua_func_djui_hud_get_color); smlua_bind_function(L, "djui_hud_get_filter", smlua_func_djui_hud_get_filter); smlua_bind_function(L, "djui_hud_get_font", smlua_func_djui_hud_get_font); + smlua_bind_function(L, "djui_hud_get_fov_coeff", smlua_func_djui_hud_get_fov_coeff); smlua_bind_function(L, "djui_hud_get_mouse_x", smlua_func_djui_hud_get_mouse_x); smlua_bind_function(L, "djui_hud_get_mouse_y", smlua_func_djui_hud_get_mouse_y); smlua_bind_function(L, "djui_hud_get_raw_mouse_x", smlua_func_djui_hud_get_raw_mouse_x); @@ -33981,6 +34012,7 @@ void smlua_bind_functions_autogen(void) { smlua_bind_function(L, "djui_hud_set_rotation_interpolated", smlua_func_djui_hud_set_rotation_interpolated); smlua_bind_function(L, "djui_hud_world_pos_to_screen_pos", smlua_func_djui_hud_world_pos_to_screen_pos); smlua_bind_function(L, "djui_open_pause_menu", smlua_func_djui_open_pause_menu); + smlua_bind_function(L, "get_current_fov", smlua_func_get_current_fov); // djui_popup.h smlua_bind_function(L, "djui_popup_create", smlua_func_djui_popup_create);