mirror of
https://github.com/PrimeDecomp/prime.git
synced 2025-10-24 20:50:22 +00:00
116 lines
4.1 KiB
C++
116 lines
4.1 KiB
C++
#include "MetroidPrime/ScriptObjects/CHUDBillboardEffect.hpp"
|
|
|
|
#include "MetroidPrime/CStateManager.hpp"
|
|
#include "MetroidPrime/CWorld.hpp"
|
|
#include "MetroidPrime/Cameras/CCameraManager.hpp"
|
|
#include "MetroidPrime/Cameras/CGameCamera.hpp"
|
|
#include "MetroidPrime/Player/CPlayer.hpp"
|
|
|
|
#include "MetaRender/CCubeRenderer.hpp"
|
|
|
|
#include "Kyoto/Particles/CElementGen.hpp"
|
|
#include "Kyoto/Particles/CParticleElectric.hpp"
|
|
|
|
#include "rstl/math.hpp"
|
|
|
|
int CHUDBillboardEffect::g_BillboardCount = 0;
|
|
int CHUDBillboardEffect::g_IndirectTexturedBillboardCount = 0;
|
|
|
|
float CHUDBillboardEffect::CalcGenRate() {
|
|
float f1 = (g_BillboardCount + g_IndirectTexturedBillboardCount <= 4)
|
|
? 0.f
|
|
: g_BillboardCount * 0.2f + g_IndirectTexturedBillboardCount * 0.1f;
|
|
return 1.f - rstl::min_val(0.8f, f1);
|
|
}
|
|
|
|
const CVector3f& CHUDBillboardEffect::GetScaleForPOV(const CStateManager& mgr) {
|
|
static CVector3f result(0.155f, 1.f, 0.155f);
|
|
return result;
|
|
}
|
|
|
|
float CHUDBillboardEffect::GetNearClipDistance(const CStateManager& mgr) {
|
|
return mgr.GetCameraManager()->GetCurrentCamera(mgr).GetNearClipDistance() + 0.01f;
|
|
}
|
|
|
|
CHUDBillboardEffect::CHUDBillboardEffect(
|
|
const rstl::optional_object< TToken< CGenDescription > >& particle,
|
|
const rstl::optional_object< TToken< CElectricDescription > >& electric, TUniqueId uid,
|
|
bool active, const rstl::string& name, float dist, const CVector3f& scale0, const CColor& color,
|
|
const CVector3f& scale1, const CVector3f& translation)
|
|
: CEffect(uid, CEntityInfo(kInvalidAreaId, CEntity::NullConnectionList), active, name,
|
|
CTransform4f::Identity())
|
|
|
|
, xec_translation(translation.GetX(), translation.GetY() + dist, translation.GetZ())
|
|
, xf8_localScale(CVector3f::ByElementMultiply(scale1, scale0))
|
|
, x104_24_renderAsParticleGen(true)
|
|
, x104_25_enableRender(false)
|
|
, x104_26_isElementGen(false)
|
|
, x104_27_runIndefinitely(false)
|
|
, x108_timeoutTimer(0.f) {
|
|
|
|
if (particle) {
|
|
x104_26_isElementGen = true;
|
|
xe8_generator = new CElementGen(*particle);
|
|
if (static_cast< CElementGen& >(*xe8_generator).IsIndirectTextured())
|
|
++g_IndirectTexturedBillboardCount;
|
|
} else {
|
|
xe8_generator = new CParticleElectric(TToken< CElectricDescription >(*electric));
|
|
}
|
|
++g_BillboardCount;
|
|
xe8_generator->SetModulationColor(color);
|
|
xe8_generator->SetLocalScale(xf8_localScale);
|
|
}
|
|
|
|
CHUDBillboardEffect::~CHUDBillboardEffect() {
|
|
--g_BillboardCount;
|
|
if (xe8_generator->Get4CharId() == 'PART')
|
|
if (static_cast< CElementGen& >(*xe8_generator).IsIndirectTextured())
|
|
--g_IndirectTexturedBillboardCount;
|
|
}
|
|
|
|
void CHUDBillboardEffect::AddToRenderer(const CFrustumPlanes& frustum,
|
|
const CStateManager& mgr) const {
|
|
if (x104_25_enableRender && x104_24_renderAsParticleGen) {
|
|
gpRender->AddParticleGen(*xe8_generator);
|
|
}
|
|
}
|
|
|
|
void CHUDBillboardEffect::PreRender(CStateManager& mgr, const CFrustumPlanes& frustum) {
|
|
if (mgr.GetPlayer()->GetCameraState() == CPlayer::kCS_FirstPerson) {
|
|
CTransform4f camXf = mgr.GetCameraManager()->GetCurrentCameraTransform(mgr);
|
|
xe8_generator->SetGlobalTranslation(camXf * xec_translation);
|
|
xe8_generator->SetGlobalOrientation(camXf);
|
|
x104_25_enableRender = true;
|
|
} else {
|
|
x104_25_enableRender = false;
|
|
}
|
|
x104_24_renderAsParticleGen = !mgr.RenderLast(GetUniqueId());
|
|
}
|
|
|
|
void CHUDBillboardEffect::Render(const CStateManager& mgr) const {
|
|
if (x104_25_enableRender && !x104_24_renderAsParticleGen) {
|
|
xe8_generator->Render();
|
|
}
|
|
}
|
|
|
|
void CHUDBillboardEffect::Think(float dt, CStateManager& mgr) {
|
|
if (GetActive()) {
|
|
mgr.SetActorAreaId(*this, mgr.GetWorld()->GetCurrentAreaId());
|
|
float oldGenRate = xe8_generator->GetGeneratorRate();
|
|
xe8_generator->SetGeneratorRate(oldGenRate * CalcGenRate());
|
|
xe8_generator->Update(dt);
|
|
xe8_generator->SetGeneratorRate(oldGenRate);
|
|
if (!x104_27_runIndefinitely) {
|
|
x108_timeoutTimer += dt;
|
|
if (x108_timeoutTimer > 30.f) {
|
|
mgr.FreeScriptObject(GetUniqueId());
|
|
return;
|
|
}
|
|
}
|
|
if (xe8_generator->IsSystemDeletable())
|
|
mgr.FreeScriptObject(GetUniqueId());
|
|
}
|
|
}
|
|
|
|
void CHUDBillboardEffect::Accept(IVisitor& visitor) { visitor.Visit(*this); }
|