#include "CSamusFaceReflection.hpp" #include "GameGlobalObjects.hpp" #include "CStateManager.hpp" #include "TCastTo.hpp" #include "Camera/CFirstPersonCamera.hpp" #include "World/CPlayer.hpp" #include "World/CWorld.hpp" namespace urde { namespace MP1 { static const zeus::CTransform PreXf = zeus::CTransform::Scale(0.3f) * zeus::CTransform::Translate(0.f, 0.5f, 0.f); CSamusFaceReflection::CSamusFaceReflection(CStateManager& stateMgr) : x0_modelData(CAnimRes(g_ResFactory->GetResourceIdByName("ACS_SamusFace")->id, 0, zeus::CVector3f::skOne, 0, true)), x4c_lights(std::make_unique(8, zeus::CVector3f::skZero, 4, 4, false, 0, 0, 0.1f)) { x60_lookDir = zeus::CVector3f::skForward; CAnimPlaybackParms parms(0, -1, 1.f, true); x0_modelData.AnimationData()->SetAnimation(parms, false); } void CSamusFaceReflection::PreDraw(const CStateManager& mgr) { if (x6c_ != 2 && (x4c_lights->GetActiveLightCount() >= 1 || (x6c_ != 0 && x6c_ != 3))) { if (!TCastToConstPtr(mgr.GetCameraManager()->GetCurrentCamera(mgr))) { x70_hidden = true; } else { x70_hidden = false; x0_modelData.AnimationData()->PreRender(); } } } void CSamusFaceReflection::Draw(const CStateManager& mgr) const { if (x70_hidden) return; if (TCastToConstPtr fpCam = (mgr.GetCameraManager()->GetCurrentCamera(mgr))) { zeus::CQuaternion camRot(fpCam->GetTransform().basis); float dist = ITweakGui::FaceReflectionDistanceDebugValueToActualValue(g_tweakGui->GetFaceReflectionDistance()); float height = ITweakGui::FaceReflectionHeightDebugValueToActualValue(g_tweakGui->GetFaceReflectionHeight()); float aspect = ITweakGui::FaceReflectionAspectDebugValueToActualValue(g_tweakGui->GetFaceReflectionAspect()); float orthoWidth = ITweakGui::FaceReflectionOrthoWidthDebugValueToActualValue(g_tweakGui->GetFaceReflectionOrthoWidth()); float orthoHeight = ITweakGui::FaceReflectionOrthoHeightDebugValueToActualValue(g_tweakGui->GetFaceReflectionOrthoHeight()); zeus::CTransform modelXf = zeus::CTransform(camRot * x50_lookRot, fpCam->GetTransform().basis[1] * dist + fpCam->GetTransform().origin + fpCam->GetTransform().basis[2] * height) * PreXf; CGraphics::SetViewPointMatrix(fpCam->GetTransform()); CGraphics::SetOrtho(aspect * -orthoWidth, aspect * orthoWidth, orthoHeight, -orthoHeight, -10.f, 10.f); CActorLights* lights = x6c_ == 1 ? nullptr : x4c_lights.get(); if (x6c_ == 3) { const_cast(x0_modelData).Render(mgr, modelXf, lights, CModelFlags(0, 0, 3, zeus::CColor::skWhite)); } else { float transFactor; if (mgr.GetPlayerState()->GetActiveVisor(mgr) == CPlayerState::EPlayerVisor::Combat) transFactor = mgr.GetPlayerState()->GetVisorTransitionFactor(); else transFactor = 0.f; if (transFactor > 0.f) { const_cast(x0_modelData).Render(mgr, modelXf, nullptr, CModelFlags(7, 0, 3, zeus::CColor::skBlack)); const_cast(x0_modelData).Render(mgr, modelXf, lights, CModelFlags(7, 0, 1, zeus::CColor(1.f, transFactor))); } } } } void CSamusFaceReflection::Update(float dt, const CStateManager& mgr, CRandom16& rand) { if (TCastToConstPtr fpCam = (mgr.GetCameraManager()->GetCurrentCamera(mgr))) { x0_modelData.AdvanceAnimationIgnoreParticles(dt, rand, true); x4c_lights->SetFindShadowLight(false); TAreaId areaId = mgr.GetPlayer().GetAreaIdAlways(); if (areaId == kInvalidAreaId) return; zeus::CAABox aabb(fpCam->GetTranslation() - 0.125f, fpCam->GetTranslation() + 0.125f); const CGameArea* area = mgr.GetWorld()->GetAreaAlways(areaId); x4c_lights->BuildFaceLightList(mgr, *area, aabb); zeus::CUnitVector3f lookDir(fpCam->GetTransform().basis[1]); zeus::CUnitVector3f xfLook = zeus::CQuaternion::lookAt(lookDir, zeus::CVector3f::skForward, 2.f * M_PIF).transform(x60_lookDir); zeus::CQuaternion xfLook2 = zeus::CQuaternion::lookAt(zeus::CVector3f::skForward, xfLook, 2.f * M_PIF); xfLook2 *= xfLook2; zeus::CMatrix3f newXf(xfLook2); zeus::CMatrix3f prevXf(x50_lookRot); float lookDot = prevXf[1].dot(newXf[1]); if (std::fabs(lookDot) > 1.f) lookDot = lookDot > 0.f ? 1.f : -1.f; float lookAng = std::acos(lookDot); x50_lookRot = zeus::CQuaternion::slerp(x50_lookRot, xfLook2, zeus::clamp(0.f, 18.f * dt * ((lookAng > 0.f) ? 0.5f * dt * g_tweakPlayer->GetHudLagAmount() / lookAng : 0.f), 1.f)); x60_lookDir = lookDir; } } } }