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);