From 6ffdfcad123116e29ba580be7af5c69b635c8af3 Mon Sep 17 00:00:00 2001 From: Metadorius Date: Sun, 8 Feb 2026 19:57:15 +0200 Subject: [PATCH 1/3] Skip drawing invisible voxel sections --- CREDITS.md | 2 ++ YRpp | 2 +- docs/Fixed-or-Improved-Logics.md | 1 + docs/Whats-New.md | 1 + src/Misc/Hooks.BugFixes.cpp | 26 +++++++++++++++++++++++++- 5 files changed, 30 insertions(+), 2 deletions(-) diff --git a/CREDITS.md b/CREDITS.md index d7ed1274bd..d088f2eac2 100644 --- a/CREDITS.md +++ b/CREDITS.md @@ -52,6 +52,7 @@ This page lists all the individual contributions to the project by their author. - MP saves support for quicksave command and savegame trigger action - Ported XNA CnCNet Client MP save handling - Retint fix toggle + - Voxel drawing invisible sections skip - **Uranusian (Thrifinesma)**: - Mind Control enhancement - Custom warhead splash list @@ -532,6 +533,7 @@ This page lists all the individual contributions to the project by their author. - Fix a jumpjet crash related to voxel shadow drawing - Replace `BLOWFISH.DLL` using Red Alert source code - Adjust the dehardcoding of the 255 `OverlayType` limit to a different format + - Voxel drawing invisible sections skip - **CrimRecya**: - Fix `LimboKill` not working reliably - Allow using waypoints, area guard and attack move with aircraft diff --git a/YRpp b/YRpp index 7a43c8bc78..afc1cf3826 160000 --- a/YRpp +++ b/YRpp @@ -1 +1 @@ -Subproject commit 7a43c8bc7872d81c27ce470a4f0bf4d1c3a8e224 +Subproject commit afc1cf38261a53a17be15d10563117ae95532a0a diff --git a/docs/Fixed-or-Improved-Logics.md b/docs/Fixed-or-Improved-Logics.md index e3c3e714b9..3d5de3a4a2 100644 --- a/docs/Fixed-or-Improved-Logics.md +++ b/docs/Fixed-or-Improved-Logics.md @@ -297,6 +297,7 @@ This page describes all ingame logics that are fixed or improved in Phobos witho - Allow the default value of `DefaultToGuardArea` to be defined by `[General] -> DefaultToGuardArea`. - Fixed the bug that cause technos teleport to cell 0,0 by ChronoSphere superweapon. - Fixed the bug that techno in attack move will move to target if it cannot attack it. +- Voxel drawing code now skips sections that are invisible (have all zeros in the transform matrix main diagonal, meaning that the scale is 0% on all axes), thus increasing drawing performance for some voxels. ## Fixes / interactions with other extensions diff --git a/docs/Whats-New.md b/docs/Whats-New.md index 4d0c0394b1..6982766597 100644 --- a/docs/Whats-New.md +++ b/docs/Whats-New.md @@ -596,6 +596,7 @@ Vanilla fixes: - Fixed the issue where units recruited by a team with `AreTeamMembersRecruitable=false` cannot be recruited even if they have been liberated by that team (by TaranDahl) - Fixed the bug that cause technos teleport to cell 0,0 by ChronoSphere superweapon (by NetsuNegi) - Fixed the bug that techno in attack move will move to target if it cannot attack it (by NetsuNegi) +- Voxel drawing code now skips sections that are invisible (have all zeros in the transform matrix main diagonal, meaning that the scale is 0% on all axes), thus increasing drawing performance for some voxels (by Kerbiter, ZivDero) Phobos fixes: - Fixed the bug that `AllowAirstrike=no` cannot completely prevent air strikes from being launched against it (by NetsuNegi) diff --git a/src/Misc/Hooks.BugFixes.cpp b/src/Misc/Hooks.BugFixes.cpp index cb50b83ad8..02283f1fcd 100644 --- a/src/Misc/Hooks.BugFixes.cpp +++ b/src/Misc/Hooks.BugFixes.cpp @@ -1,6 +1,7 @@ #include #include #include +#include #include #include @@ -2716,7 +2717,7 @@ DEFINE_HOOK(0x5218C2, InfantryClass_UnmarkAllOccupationBits_ResetOwnerIdx, 0x6) const auto pExt = CellExt::ExtMap.Find(pCell); pExt->InfantryCount--; - // Vanilla check only the flag to decide if the InfantryOwnerIndex should be reset. + // Vanilla check only the flag to decide if the InfantryOwnerIndex should be reset. // But the tree take one of the flag bit. So if a infantry walk through a cell with a tree, the InfantryOwnerIndex won't be reset. return (newFlag & 0x1C) == 0 || pExt->InfantryCount == 0 ? Reset : NoReset; } @@ -3014,3 +3015,26 @@ DEFINE_HOOK(0x6EA870, TeamClass_LiberateMember_Start, 0x6) pMember->RecruitableB = true; return 0; } + +DEFINE_HOOK(0x706F64, TechnoClass_RenderVoxelObject_SkipInvisibleSections, 0x0) +{ + enum { SkipLayer = 0x706FDF }; + + GET(MotLib* const, pMotLib, EDI); + + // stolen code + if (!pMotLib) + return 0x706FBD; + + GET(int const, layer, EBX); + GET_STACK(unsigned int const, frame, STACK_OFFSET(0x13C, 0x18)); + + auto mtx = pMotLib->GetLayerMatrix(layer, frame); + + if (CLOSE_ENOUGH(mtx.row[0][0], 0.0) && CLOSE_ENOUGH(mtx.row[1][1], 0.0) && CLOSE_ENOUGH(mtx.row[2][2], 0.0)) + return SkipLayer; + + // stolen code + R->EAX(frame); + return 0x706F6F; +} From df28d0c3c00a498656450b805cf10c16c48e1351 Mon Sep 17 00:00:00 2001 From: Metadorius Date: Mon, 9 Feb 2026 17:13:24 +0200 Subject: [PATCH 2/3] Revert epsilon comparison back to exact 0.0 check --- src/Misc/Hooks.BugFixes.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Misc/Hooks.BugFixes.cpp b/src/Misc/Hooks.BugFixes.cpp index 02283f1fcd..2e37036a0d 100644 --- a/src/Misc/Hooks.BugFixes.cpp +++ b/src/Misc/Hooks.BugFixes.cpp @@ -3031,7 +3031,7 @@ DEFINE_HOOK(0x706F64, TechnoClass_RenderVoxelObject_SkipInvisibleSections, 0x0) auto mtx = pMotLib->GetLayerMatrix(layer, frame); - if (CLOSE_ENOUGH(mtx.row[0][0], 0.0) && CLOSE_ENOUGH(mtx.row[1][1], 0.0) && CLOSE_ENOUGH(mtx.row[2][2], 0.0)) + if (mtx.row[0][0] == 0.0 && mtx.row[1][1] == 0.0 && mtx.row[2][2] == 0.0) return SkipLayer; // stolen code From 013d61724eb77131f87c459cf39b1d9c8861a415 Mon Sep 17 00:00:00 2001 From: Metadorius Date: Tue, 10 Feb 2026 14:05:21 +0200 Subject: [PATCH 3/3] Test with the old method (to be reverted probably) --- src/Misc/Hooks.BugFixes.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Misc/Hooks.BugFixes.cpp b/src/Misc/Hooks.BugFixes.cpp index 2e37036a0d..2f8913025f 100644 --- a/src/Misc/Hooks.BugFixes.cpp +++ b/src/Misc/Hooks.BugFixes.cpp @@ -3031,7 +3031,7 @@ DEFINE_HOOK(0x706F64, TechnoClass_RenderVoxelObject_SkipInvisibleSections, 0x0) auto mtx = pMotLib->GetLayerMatrix(layer, frame); - if (mtx.row[0][0] == 0.0 && mtx.row[1][1] == 0.0 && mtx.row[2][2] == 0.0) + if (mtx.row[0][0] == 0.0 || mtx.row[1][1] == 0.0 || mtx.row[2][2] == 0.0) return SkipLayer; // stolen code