Fix mirror decal not rendering on some walls (#7052)

This commit is contained in:
Philip Dubé
2026-08-09 22:01:31 +00:00
committed by GitHub
parent 4e39d06acc
commit f27ddede59
3 changed files with 26 additions and 1 deletions
+15
View File
@@ -8,6 +8,7 @@ extern "C" {
#include "include/z64camera.h"
#include "src/overlays/actors/ovl_En_Test/z_en_test.h"
#include "src/overlays/actors/ovl_En_Horse/z_en_horse.h"
#include "src/overlays/actors/ovl_Mir_Ray/z_mir_ray.h"
void UnregisterActorSkeletons(struct Actor* actor);
extern void Player_UseItem(PlayState*, Player*, s32);
extern PlayState* gPlayState;
@@ -110,6 +111,20 @@ void RegisterAlwaysOnFixes() {
}
});
// Mir_Ray draws the reflection image straight on the collision poly's plane, but CollisionPoly
// stores that plane quantized (s16 normal, integer dist), so for about half of all walls it
// lands a fraction of a unit inside the drawn surface. N64 RDP's decal mode handled that,
// but our graphics pipeline does not. Lift the image off the plane along the poly normal.
COND_VB_SHOULD(VB_MIRRAY_DRAW_REFLECTION, true, {
if (*should) {
MirRayShieldReflection* reflection = va_arg(args, MirRayShieldReflection*);
CollisionPoly* poly = reflection->reflectionPoly;
reflection->pos.x += COLPOLY_GET_NORMAL(poly->normal.x);
reflection->pos.y += COLPOLY_GET_NORMAL(poly->normal.y);
reflection->pos.z += COLPOLY_GET_NORMAL(poly->normal.z);
}
});
// Handle first person aiming camera settings
COND_VB_SHOULD(VB_CHANGE_AIMING_CAMERA, true, {
s8* heldItemAction = va_arg(args, s8*);
@@ -1640,6 +1640,14 @@ typedef enum {
// - `*EnMd`
VB_MIDO_SPAWN,
// #### `result`
// ```c
// reflection[i].reflectionPoly != NULL
// ```
// #### `args`
// - `*MirRayShieldReflection`
VB_MIRRAY_DRAW_REFLECTION,
// #### `result`
// ```c
// false
@@ -7,6 +7,7 @@
#include "z_mir_ray.h"
#include "objects/object_mir_ray/object_mir_ray.h"
#include "soh/frame_interpolation.h"
#include "soh/Enhancements/game-interactor/GameInteractor_Hooks.h"
#define FLAGS (ACTOR_FLAG_UPDATE_CULLING_DISABLED | ACTOR_FLAG_DRAW_CULLING_DISABLED)
@@ -510,7 +511,8 @@ void MirRay_Draw(Actor* thisx, PlayState* play) {
}
}
for (i = 0; i < 6; i++) {
if (reflection[i].reflectionPoly != NULL) {
if (GameInteractor_Should(VB_MIRRAY_DRAW_REFLECTION, reflection[i].reflectionPoly != NULL,
&reflection[i])) {
FrameInterpolation_RecordOpenChild(&reflection[i], i);
Matrix_Translate(reflection[i].pos.x, reflection[i].pos.y, reflection[i].pos.z, MTXMODE_NEW);
Matrix_Scale(0.01f, 0.01f, 0.01f, MTXMODE_APPLY);