metaforce/Runtime/MP1/CSamusFaceReflection.cpp

106 lines
4.6 KiB
C++

#include "Runtime/MP1/CSamusFaceReflection.hpp"
#include "Runtime/CStateManager.hpp"
#include "Runtime/GameGlobalObjects.hpp"
#include "Runtime/Camera/CFirstPersonCamera.hpp"
#include "Runtime/World/CPlayer.hpp"
#include "Runtime/World/CWorld.hpp"
#include "TCastTo.hpp" // Generated file, do not modify include path
namespace metaforce::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::skOne3f, 0, true))
, x4c_lights(std::make_unique<CActorLights>(8, zeus::skZero3f, 4, 4, false, false, false, 0.1f)) {
x60_lookDir = zeus::skForward;
constexpr CAnimPlaybackParms parms(0, -1, 1.f, true);
x0_modelData.GetAnimationData()->SetAnimation(parms, false);
}
void CSamusFaceReflection::PreDraw(const CStateManager& mgr) {
if (x6c_ != 2 && (x4c_lights->GetActiveLightCount() >= 1 || (x6c_ != 0 && x6c_ != 3))) {
if (!TCastToConstPtr<CFirstPersonCamera>(mgr.GetCameraManager()->GetCurrentCamera(mgr))) {
x70_hidden = true;
} else {
x70_hidden = false;
x0_modelData.GetAnimationData()->PreRender();
}
}
}
void CSamusFaceReflection::Draw(const CStateManager& mgr) {
if (x70_hidden)
return;
if (TCastToConstPtr<CFirstPersonCamera> fpCam = (mgr.GetCameraManager()->GetCurrentCamera(mgr))) {
SCOPED_GRAPHICS_DEBUG_GROUP("CSamusFaceReflection::Draw", zeus::skBlue);
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) {
x0_modelData.Render(mgr, modelXf, lights, CModelFlags(0, 0, 3, zeus::skWhite));
} else {
float transFactor;
if (mgr.GetPlayerState()->GetActiveVisor(mgr) == CPlayerState::EPlayerVisor::Combat)
transFactor = mgr.GetPlayerState()->GetVisorTransitionFactor();
else
transFactor = 0.f;
if (transFactor > 0.f) {
x0_modelData.Render(mgr, modelXf, nullptr, CModelFlags(7, 0, 3, zeus::skBlack));
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<CFirstPersonCamera> 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::skForward, 2.f * M_PIF).transform(x60_lookDir);
zeus::CQuaternion xfLook2 = zeus::CQuaternion::lookAt(zeus::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->GetFreeLookSpeed() / lookAng : 0.f),
1.f));
x60_lookDir = lookDir;
}
}
} // namespace metaforce::MP1