summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGarrett Cox <garrettjcox@gmail.com>2024-08-09 15:42:34 -0500
committerGitHub <noreply@github.com>2024-08-09 16:42:34 -0400
commit4a57bdbc5f429feacad94c06e3a05967f374fb70 (patch)
treeaade9f7e13d6b60845361a52a6675b44b73b0888
parent0ec23b34ba71f410c04a28fc89a255a23adceebe (diff)
Add widescreen actor culling option (#652)
-rw-r--r--mm/2s2h/BenGui/BenMenuBar.cpp9
-rw-r--r--mm/src/code/z_actor.c42
2 files changed, 33 insertions, 18 deletions
diff --git a/mm/2s2h/BenGui/BenMenuBar.cpp b/mm/2s2h/BenGui/BenMenuBar.cpp
index afdb52871..cadc3bbe8 100644
--- a/mm/2s2h/BenGui/BenMenuBar.cpp
+++ b/mm/2s2h/BenGui/BenMenuBar.cpp
@@ -562,11 +562,10 @@ void DrawEnhancementsMenu() {
{ .tooltip =
"Disables the distance check for scene geometry, allowing it to be drawn no matter how far "
"away it is from the player. This may have unintended side effects." });
- // BENTODO: Not implemented yet
- // UIWidgets::CVarCheckbox("Widescreen Actor Culling",
- // "gEnhancements.Graphics.ActorCullingAccountsForWidescreen",
- // { .tooltip = "Adjusts the culling planes to account for widescreen resolutions. "
- // "This may have unintended side effects." });
+ UIWidgets::CVarCheckbox("Widescreen Actor Culling",
+ "gEnhancements.Graphics.ActorCullingAccountsForWidescreen",
+ { .tooltip = "Adjusts the culling planes to account for widescreen resolutions. "
+ "This may have unintended side effects." });
if (UIWidgets::CVarSliderInt(
"Increase Actor Draw Distance: %dx", "gEnhancements.Graphics.IncreaseActorDrawDistance", 1, 5, 1,
{ .tooltip =
diff --git a/mm/src/code/z_actor.c b/mm/src/code/z_actor.c
index 2a967694b..8be769e81 100644
--- a/mm/src/code/z_actor.c
+++ b/mm/src/code/z_actor.c
@@ -23,6 +23,7 @@
#include <string.h>
#include "2s2h/Enhancements/FrameInterpolation/FrameInterpolation.h"
#include "2s2h/Enhancements/GameInteractor/GameInteractor.h"
+#include "2s2h/BenPort.h"
// bss
// FaultClient sActorFaultClient; // 2 funcs
@@ -3084,24 +3085,38 @@ void Ship_CalcShouldDrawAndUpdate(PlayState* play, Actor* actor, Vec3f* projecte
(projectedPos->z < ((actor->uncullZoneForward * drawMulti) + (actor->uncullZoneScale * drawMulti)));
if (updateCheck || drawCheck) {
- f32 phi_f12;
- f32 phi_f2 = CLAMP_MIN(projectedW, 1.0f);
- f32 phi_f14;
- f32 phi_f16;
+ // Ensure the projected W value is at least 1.0
+ f32 clampedProjectedW = CLAMP_MIN(projectedW, 1.0f);
+ f32 uncullZoneScaleDiagonal;
+ f32 uncullZoneScaleVertical;
+ f32 uncullZoneDownwardAdjusted;
+ // Adjust calculations if the field of view is not the default 60 degrees
if (play->view.fovy != 60.0f) {
- phi_f12 = actor->uncullZoneScale * play->projectionMtxFDiagonal.x * 0.76980036f; // sqrt(16/27)
+ uncullZoneScaleDiagonal =
+ actor->uncullZoneScale * play->projectionMtxFDiagonal.x * 0.76980036f; // sqrt(16/27)
- phi_f14 = play->projectionMtxFDiagonal.y * 0.57735026f; // 1 / sqrt(3)
- phi_f16 = actor->uncullZoneScale * phi_f14;
- phi_f14 *= actor->uncullZoneDownward;
+ uncullZoneScaleVertical = play->projectionMtxFDiagonal.y * 0.57735026f; // 1 / sqrt(3)
+ uncullZoneDownwardAdjusted = actor->uncullZoneScale * uncullZoneScaleVertical;
+ uncullZoneScaleVertical *= actor->uncullZoneDownward;
} else {
- phi_f16 = phi_f12 = actor->uncullZoneScale;
- phi_f14 = actor->uncullZoneDownward;
+ uncullZoneDownwardAdjusted = uncullZoneScaleDiagonal = actor->uncullZoneScale;
+ uncullZoneScaleVertical = actor->uncullZoneDownward;
}
- if (((fabsf(projectedPos->x) - phi_f12) < phi_f2) && ((-phi_f2 < (projectedPos->y + phi_f14))) &&
- ((projectedPos->y - phi_f16) < phi_f2)) {
+ if (CVarGetInteger("gEnhancements.Graphics.ActorCullingAccountsForWidescreen", 0)) {
+ float originalAspectRatio = 4.0f / 3.0f;
+ float currentAspectRatio = OTRGetAspectRatio();
+ float aspectRatioMultiplier = MAX(currentAspectRatio / originalAspectRatio, 1.0f);
+
+ clampedProjectedW *= aspectRatioMultiplier;
+ }
+
+ bool isWithinHorizontalCullZone = ((fabsf(projectedPos->x) - uncullZoneScaleDiagonal) < clampedProjectedW);
+ bool isAboveBottomOfCullZone = ((-clampedProjectedW < (projectedPos->y + uncullZoneScaleVertical)));
+ bool isBelowTopOfCullZone = ((projectedPos->y - uncullZoneDownwardAdjusted) < clampedProjectedW);
+
+ if (isWithinHorizontalCullZone && isAboveBottomOfCullZone && isBelowTopOfCullZone) {
*shouldDraw = drawCheck;
*shouldUpdate = updateCheck;
}
@@ -3148,7 +3163,8 @@ void Actor_DrawAll(PlayState* play, ActorContext* actorCtx) {
bool shipShouldDraw = false;
bool shipShouldUpdate = false;
if (CVarGetInteger("gEnhancements.Graphics.IncreaseActorDrawDistance", 1) > 1 ||
- CVarGetInteger("gEnhancements.Graphics.IncreaseActorUpdateDistance", 1) > 1) {
+ CVarGetInteger("gEnhancements.Graphics.IncreaseActorUpdateDistance", 1) > 1 ||
+ CVarGetInteger("gEnhancements.Graphics.ActorCullingAccountsForWidescreen", 0)) {
Ship_CalcShouldDrawAndUpdate(play, actor, &actor->projectedPos, actor->projectedW, &shipShouldDraw,
&shipShouldUpdate);