@@ -592,11 +592,15 @@ std::pair<glm::vec3, glm::fquat> CemuHooks::CalculateVRWorldPose(const BESeadLoo
592592 // in-game camera
593593 glm::mat4x3 viewMatrix = camera.mtx .getLEMatrix ();
594594 glm::mat4 worldGame = glm::inverse (glm::mat4 (viewMatrix));
595- glm::vec3 basePos = s_wsCameraPosition;
596- glm::quat baseRot = s_wsCameraRotation;
597- auto [swing, baseYaw] = swingTwistY (baseRot);
595+ glm::vec3 basePos = glm::vec3 (worldGame[3 ]);
596+ glm::quat baseRot = glm::quat_cast (worldGame);
597+
598+ // overwrite with our stored camera pos/rot
599+ basePos = s_wsCameraPosition;
600+ baseRot = s_wsCameraRotation;
598601
599- if (CemuHooks::IsFirstPerson ()) {
602+ auto [swing, baseYaw] = swingTwistY (baseRot);
603+ if (IsFirstPerson ()) {
600604 // take link's direction, then rotate the headset position
601605 BEMatrix34 playerMtx = {};
602606 readMemory (s_playerMtxAddress, &playerMtx);
@@ -613,7 +617,6 @@ std::pair<glm::vec3, glm::fquat> CemuHooks::CalculateVRWorldPose(const BESeadLoo
613617 }
614618
615619 basePos = playerPos;
616-
617620 if (auto eventSettings = GetFirstPersonSettingsForActiveEvent ()) {
618621 if (eventSettings->ignoreCameraRotation ) {
619622 glm::fquat playerRot = playerMtx.getRotLE ();
@@ -638,12 +641,11 @@ std::pair<glm::vec3, glm::fquat> CemuHooks::CalculateVRWorldPose(const BESeadLoo
638641 return { newPos, newRot };
639642}
640643
641- constexpr float VISIBILITY_CHECK_BUFFER = 1 .5f ;
642644void CemuHooks::hook_CheckIfCameraCanSeePos (PPCInterpreter_t* hCPU) {
643645 hCPU->instructionPointer = hCPU->sprNew .LR ;
644646
645647 if (VRManager::instance ().XR ->GetRenderer () == nullptr ) {
646- hCPU->gpr [3 ] = 1 ;
648+ hCPU->gpr [3 ] = 0 ;
647649 return ;
648650 }
649651
@@ -656,19 +658,18 @@ void CemuHooks::hook_CheckIfCameraCanSeePos(PPCInterpreter_t* hCPU) {
656658 BESeadLookAtCamera camera = {};
657659 readMemory (camPtr, &camera);
658660
659- struct {
660- uint32_t x, y, z;
661- } posRaw;
662- readMemory (posPtr, &posRaw);
661+ // uint32_t mainProjectionPtr = hCPU->gpr[5];
662+ // BESeadPerspectiveProjection mainProjection = {};
663+ // readMemory(mainProjectionPtr, &mainProjection);
664+ // uint32_t altProjectionPtr = hCPU->gpr[6];
665+ // BESeadPerspectiveProjection altProjection = {};
666+ // readMemory(altProjectionPtr, &altProjection);
663667
664- auto swapFloat = [](uint32_t val) -> float {
665- uint32_t swapped = ((val & 0xFF ) << 24 ) | ((val & 0xFF00 ) << 8 ) | ((val & 0xFF0000 ) >> 8 ) | ((val & 0xFF000000 ) >> 24 );
666- float f;
667- memcpy (&f, &swapped, 4 );
668- return f;
669- };
668+ // Log::print<INFO>("Main Projection{}: {}", hCPU->gpr[0] == 0 ? " yes " : " no ", mainProjection);
669+ // Log::print<INFO>("Alt Projection{}: {}", hCPU->gpr[0] == 1 ? " yes " : " no ", altProjection);
670670
671- glm::vec3 center (swapFloat (posRaw.x ), swapFloat (posRaw.y ), swapFloat (posRaw.z ));
671+ BEVec3 center;
672+ readMemory (posPtr, ¢er);
672673
673674 Frustum frustum;
674675 bool visible = false ;
@@ -677,19 +678,23 @@ void CemuHooks::hook_CheckIfCameraCanSeePos(PPCInterpreter_t* hCPU) {
677678 OpenXR::EyeSide side = (i == 0 ) ? OpenXR::EyeSide::LEFT : OpenXR::EyeSide::RIGHT;
678679 if (auto fovOpt = VRManager::instance ().XR ->GetRenderer ()->GetFOV (side)) {
679680 auto [pos, rot] = CalculateVRWorldPose (camera, side);
681+
682+ // pull the camera backwards a bit to account for it being a third-person game that encompassed a bigger area
683+ pos += rot * glm::vec3 (0 .0f , 0 .0f , 1 .0f );
684+
680685 glm::mat4 view = glm::inverse (glm::translate (glm::mat4 (1 .0f ), pos) * glm::mat4_cast (rot));
681- glm::mat4 proj = calculateProjectionMatrix (nearClip, farClip, fovOpt.value ());
686+ glm::mat4 proj = glm::transpose ( calculateProjectionMatrix (nearClip, farClip, fovOpt.value () ));
682687 glm::mat4 vp = proj * view;
683688
684689 frustum.update (vp);
685- if (frustum.checkSphere (center, radius+VISIBILITY_CHECK_BUFFER )) {
690+ if (frustum.checkSphere (center. getLE () , radius)) {
686691 visible = true ;
687692 break ;
688693 }
689694 }
690695 }
691696
692- Log::print<INFO >(" Checking visibility of {} (rad = {}, near = {}, far = {}): {}" , center, radius, nearClip, farClip, visible ? " visible" : " invisible" );
697+ Log::print<PPC >(" Checking visibility of {} (rad = {}, near = {}, far = {}): {}" , center, radius, nearClip, farClip, visible ? " visible" : " invisible" );
693698
694699 hCPU->gpr [3 ] = visible ? 1 : 0 ;
695700}
0 commit comments