2
0
mirror of https://github.com/AxioDL/metaforce.git synced 2025-05-13 11:11:22 +00:00

Implement CHUDBillboardEffect, bug fixes

This commit is contained in:
Jack Andersen 2018-11-03 15:08:44 -10:00
parent d140f35886
commit 4c306e7e40
12 changed files with 129 additions and 49 deletions

View File

@ -67,7 +67,7 @@ void CWorldLayerState::InitializeWorldLayers(const std::vector<CWorldLayers::Are
u32 b = 0; u32 b = 0;
for (const CWorldLayers::Area& area : x0_areaLayers) for (const CWorldLayers::Area& area : x0_areaLayers)
{ {
for (u32 l=0 ; l<area.m_layerCount ; ++l) for (u32 l=1 ; l<area.m_layerCount ; ++l)
SetLayerActive(a, l, x10_saveLayers.getBit(b++)); SetLayerActive(a, l, x10_saveLayers.getBit(b++));
++a; ++a;
} }
@ -88,7 +88,7 @@ CWorldState::CWorldState(CBitStreamReader& reader, CAssetId mlvlId, const CSaveW
: x0_mlvlId(mlvlId) : x0_mlvlId(mlvlId)
{ {
x4_areaId = reader.ReadEncoded(32); x4_areaId = reader.ReadEncoded(32);
x10_desiredAreaAssetId = reader.ReadEncoded(32); x10_desiredAreaAssetId = u32(reader.ReadEncoded(32));
x8_relayTracker = std::make_shared<CRelayTracker>(reader, saveWorld); x8_relayTracker = std::make_shared<CRelayTracker>(reader, saveWorld);
xc_mapWorldInfo = std::make_shared<CMapWorldInfo>(reader, saveWorld, mlvlId); xc_mapWorldInfo = std::make_shared<CMapWorldInfo>(reader, saveWorld, mlvlId);
x14_layerState = std::make_shared<CWorldLayerState>(reader, saveWorld); x14_layerState = std::make_shared<CWorldLayerState>(reader, saveWorld);

View File

@ -912,7 +912,7 @@ void CStateManager::DrawWorld() const
CGraphics::SetDepthRange(DEPTH_SCREEN_ACTORS, DEPTH_GUN); CGraphics::SetDepthRange(DEPTH_SCREEN_ACTORS, DEPTH_GUN);
for (TUniqueId id : x86c_stateManagerContainer->xf39c_renderLast) for (TUniqueId id : x86c_stateManagerContainer->xf39c_renderLast)
if (const CActor* actor = static_cast<const CActor*>(GetObjectById(id))) if (const CActor* actor = static_cast<const CActor*>(GetObjectById(id)))
if (actor->xe6_27_thermalVisorFlags & 0x2) if (!thermal || actor->xe6_27_thermalVisorFlags & 0x2)
actor->Render(*this); actor->Render(*this);
CGraphics::SetDepthRange(DEPTH_WORLD, DEPTH_FAR); CGraphics::SetDepthRange(DEPTH_WORLD, DEPTH_FAR);
} }

View File

@ -29,7 +29,7 @@ CGameCamera::CGameCamera(TUniqueId uid, bool active, std::string_view name, cons
void CGameCamera::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr) void CGameCamera::AcceptScriptMsg(EScriptObjectMessage msg, TUniqueId uid, CStateManager& mgr)
{ {
if (msg == EScriptObjectMessage::UpdateSplashInhabitant) if (msg == EScriptObjectMessage::AddSplashInhabitant)
{ {
mgr.GetCameraManager()->SetInsideFluid(true, uid); mgr.GetCameraManager()->SetInsideFluid(true, uid);
return; return;

View File

@ -1046,8 +1046,7 @@ void CBooRenderer::PostRenderFogs()
void CBooRenderer::AddParticleGen(const CParticleGen& gen) void CBooRenderer::AddParticleGen(const CParticleGen& gen)
{ {
auto bounds = gen.GetBounds(); if (auto bounds = gen.GetBounds())
if (bounds)
{ {
zeus::CVector3f pt = bounds.value().closestPointAlongVector(xb0_viewPlane.vec); zeus::CVector3f pt = bounds.value().closestPointAlongVector(xb0_viewPlane.vec);
Buckets::Insert(pt, bounds.value(), EDrawableType::Particle, &gen, xb0_viewPlane, 0); Buckets::Insert(pt, bounds.value(), EDrawableType::Particle, &gen, xb0_viewPlane, 0);

View File

@ -1932,11 +1932,19 @@ void CElementGen::RenderParticlesIndirectTexture()
inst.pos[2] = zeus::CVector4f{viewPoint.x + size, viewPoint.y, viewPoint.z - size, 1.f}; inst.pos[2] = zeus::CVector4f{viewPoint.x + size, viewPoint.y, viewPoint.z - size, 1.f};
inst.pos[3] = zeus::CVector4f{viewPoint.x - size, viewPoint.y, viewPoint.z - size, 1.f}; inst.pos[3] = zeus::CVector4f{viewPoint.x - size, viewPoint.y, viewPoint.z - size, 1.f};
inst.color = particle.x34_color; inst.color = particle.x34_color;
inst.texrTindUVs[2] = zeus::CVector4f{uvs.xMax, uvs.yMax, uvsInd.xMin, uvsInd.yMin}; inst.texrTindUVs[0] = zeus::CVector4f{uvs.xMax, uvs.yMax, uvsInd.xMax, uvsInd.yMax};
inst.texrTindUVs[3] = zeus::CVector4f{uvs.xMin, uvs.yMax, uvsInd.xMin, uvsInd.yMax}; inst.texrTindUVs[1] = zeus::CVector4f{uvs.xMin, uvs.yMax, uvsInd.xMin, uvsInd.yMax};
inst.texrTindUVs[0] = zeus::CVector4f{uvs.xMax, uvs.yMin, uvsInd.xMax, uvsInd.yMin}; inst.texrTindUVs[2] = zeus::CVector4f{uvs.xMax, uvs.yMin, uvsInd.xMax, uvsInd.yMin};
inst.texrTindUVs[1] = zeus::CVector4f{uvs.xMin, uvs.yMin, uvsInd.xMax, uvsInd.yMax}; inst.texrTindUVs[3] = zeus::CVector4f{uvs.xMin, uvs.yMin, uvsInd.xMin, uvsInd.yMin};
inst.sceneUVs = zeus::CVector4f{clipRect.x18_uvXMin, clipRect.x24_uvYMax, clipRect.x1c_uvXMax, clipRect.x20_uvYMin}; switch (CGraphics::g_BooPlatform)
{
case boo::IGraphicsDataFactory::Platform::OpenGL:
inst.sceneUVs = zeus::CVector4f{clipRect.x18_uvXMin, clipRect.x24_uvYMax, clipRect.x1c_uvXMax, clipRect.x20_uvYMin};
break;
default:
inst.sceneUVs = zeus::CVector4f{clipRect.x18_uvXMin, 1.f - clipRect.x24_uvYMax, clipRect.x1c_uvXMax, 1.f - clipRect.x20_uvYMin};
break;
}
} }
if (g_instIndTexData.size()) if (g_instIndTexData.size())

View File

@ -32,7 +32,7 @@ public:
CSfxHandle x74_sfx; CSfxHandle x74_sfx;
std::unique_ptr<CElementGen> x78_; std::unique_ptr<CElementGen> x78_;
u32 x80_ = 0; u32 x80_ = 0;
u32 x84_ = -1; s32 x84_ = -1;
u32 x88_seed1 = 99; u32 x88_seed1 = 99;
rstl::reserved_vector<std::unique_ptr<CElementGen>, 4> x8c_thermalColdParticles; rstl::reserved_vector<std::unique_ptr<CElementGen>, 4> x8c_thermalColdParticles;
s32 xb0_ = -1; s32 xb0_ = -1;

View File

@ -57,7 +57,7 @@ CEnvFxManager::CEnvFxManager()
void CEnvFxManager::SetSplashEffectRate(float rate, const CStateManager& mgr) void CEnvFxManager::SetSplashEffectRate(float rate, const CStateManager& mgr)
{ {
if (TCastToPtr<CHUDBillboardEffect> splashEffect = mgr.ObjectById(xb68_envRainSplashId)) if (TCastToPtr<CHUDBillboardEffect> splashEffect = mgr.ObjectById(xb68_envRainSplashId))
if (splashEffect->GetX104_26()) if (splashEffect->IsElementGen())
splashEffect->GetParticleGen()->SetGeneratorRate(rate); splashEffect->GetParticleGen()->SetGeneratorRate(rate);
} }
@ -433,7 +433,7 @@ void CEnvFxManager::Update(float dt, CStateManager& mgr)
static zeus::CColor GetFlakeColor(const zeus::CMatrix4f& mvp, const CEnvFxShaders::Instance& inst) static zeus::CColor GetFlakeColor(const zeus::CMatrix4f& mvp, const CEnvFxShaders::Instance& inst)
{ {
float screenHeight = std::fabs(mvp.multiplyOneOverW(inst.positions[1]).y - float screenHeight = std::fabs(mvp.multiplyOneOverW(inst.positions[1]).y -
mvp.multiplyOneOverW(inst.positions[0]).y); mvp.multiplyOneOverW(inst.positions[0]).y) / 2.f;
screenHeight -= (32.f / 480.f); screenHeight -= (32.f / 480.f);
screenHeight /= (32.f / 480.f); screenHeight /= (32.f / 480.f);
return zeus::CColor(1.f - zeus::clamp(0.f, screenHeight, 1.f), 1.f); return zeus::CColor(1.f - zeus::clamp(0.f, screenHeight, 1.f), 1.f);
@ -668,7 +668,7 @@ void CEnvFxManager::AsyncLoadResources(CStateManager& mgr)
CHUDBillboardEffect::GetNearClipDistance(mgr), CHUDBillboardEffect::GetNearClipDistance(mgr),
CHUDBillboardEffect::GetScaleForPOV(mgr), zeus::CColor::skWhite, CHUDBillboardEffect::GetScaleForPOV(mgr), zeus::CColor::skWhite,
zeus::CVector3f::skOne, zeus::CVector3f::skZero); zeus::CVector3f::skOne, zeus::CVector3f::skZero);
effect->SetX104_27(true); effect->SetRunIndefinitely(true);
mgr.AddObject(effect); mgr.AddObject(effect);
} }

View File

@ -2,6 +2,10 @@
#include "TCastTo.hpp" #include "TCastTo.hpp"
#include "CStateManager.hpp" #include "CStateManager.hpp"
#include "Camera/CGameCamera.hpp" #include "Camera/CGameCamera.hpp"
#include "GameGlobalObjects.hpp"
#include "Graphics/CBooRenderer.hpp"
#include "World/CPlayer.hpp"
#include "World/CWorld.hpp"
namespace urde namespace urde
{ {
@ -11,21 +15,22 @@ u32 CHUDBillboardEffect::g_BillboardCount = 0;
CHUDBillboardEffect::CHUDBillboardEffect(const std::experimental::optional<TToken<CGenDescription>>& particle, CHUDBillboardEffect::CHUDBillboardEffect(const std::experimental::optional<TToken<CGenDescription>>& particle,
const std::experimental::optional<TToken<CElectricDescription>>& electric, const std::experimental::optional<TToken<CElectricDescription>>& electric,
TUniqueId uid, bool active, std::string_view name, float f, TUniqueId uid, bool active, std::string_view name, float dist,
const zeus::CVector3f& v0, const zeus::CColor& color, const zeus::CVector3f& scale0, const zeus::CColor& color,
const zeus::CVector3f& v1, const zeus::CVector3f& v2) const zeus::CVector3f& scale1, const zeus::CVector3f& translation)
: CEffect(uid, CEntityInfo(kInvalidAreaId, CEntity::NullConnectionList), active, name, zeus::CTransform::Identity()) : CEffect(uid, CEntityInfo(kInvalidAreaId, CEntity::NullConnectionList), active, name, zeus::CTransform::Identity())
{ {
xec_v2 = v2; xec_translation = translation;
xec_v2.y += f; xec_translation.y += dist;
xf8_ = v1 * v0; xf8_localScale = scale1 * scale0;
x104_24_ = true; x104_24_renderAsParticleGen = true;
x104_25_ = false; x104_25_enableRender = false;
x104_26_ = false; x104_26_isElementGen = false;
x104_27_ = false; x104_27_runIndefinitely = false;
if (particle) if (particle)
{ {
x104_26_isElementGen = true;
xe8_generator = std::make_unique<CElementGen>(*particle); xe8_generator = std::make_unique<CElementGen>(*particle);
if (static_cast<CElementGen&>(*xe8_generator).IsIndirectTextured()) if (static_cast<CElementGen&>(*xe8_generator).IsIndirectTextured())
++g_IndirectTexturedBillboardCount; ++g_IndirectTexturedBillboardCount;
@ -36,7 +41,7 @@ CHUDBillboardEffect::CHUDBillboardEffect(const std::experimental::optional<TToke
} }
++g_BillboardCount; ++g_BillboardCount;
xe8_generator->SetModulationColor(color); xe8_generator->SetModulationColor(color);
xe8_generator->SetLocalScale(xf8_); xe8_generator->SetLocalScale(xf8_localScale);
} }
CHUDBillboardEffect::~CHUDBillboardEffect() CHUDBillboardEffect::~CHUDBillboardEffect()
@ -49,6 +54,71 @@ CHUDBillboardEffect::~CHUDBillboardEffect()
void CHUDBillboardEffect::Accept(IVisitor& visitor) { visitor.Visit(this); } void CHUDBillboardEffect::Accept(IVisitor& visitor) { visitor.Visit(this); }
float CHUDBillboardEffect::CalcGenRate()
{
float f1;
if (g_BillboardCount + g_IndirectTexturedBillboardCount <= 4)
f1 = 0.f;
else
f1 = g_BillboardCount * 0.2f + g_IndirectTexturedBillboardCount * 0.1f;
return 1.f - std::min(f1, 0.8f);
}
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::AddToRenderer(const zeus::CFrustum& frustum, const CStateManager& mgr) const
{
if (x104_25_enableRender && x104_24_renderAsParticleGen)
{
g_Renderer->AddParticleGen(*xe8_generator);
}
}
void CHUDBillboardEffect::PreRender(CStateManager& mgr, const zeus::CFrustum& frustum)
{
if (mgr.GetPlayer().GetCameraState() == CPlayer::EPlayerCameraState::FirstPerson)
{
zeus::CTransform 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();
}
}
float CHUDBillboardEffect::GetNearClipDistance(CStateManager& mgr) float CHUDBillboardEffect::GetNearClipDistance(CStateManager& mgr)
{ {
return mgr.GetCameraManager()->GetCurrentCamera(mgr)->GetNearClipDistance() + 0.01f; return mgr.GetCameraManager()->GetCurrentCamera(mgr)->GetNearClipDistance() + 0.01f;
@ -59,4 +129,4 @@ zeus::CVector3f CHUDBillboardEffect::GetScaleForPOV(CStateManager& mgr)
return {0.155f, 1.f, 0.155f}; return {0.155f, 1.f, 0.155f};
} }
} }

View File

@ -15,24 +15,29 @@ class CElectricDescription;
class CHUDBillboardEffect : public CEffect class CHUDBillboardEffect : public CEffect
{ {
std::unique_ptr<CParticleGen> xe8_generator; std::unique_ptr<CParticleGen> xe8_generator;
zeus::CVector3f xec_v2; zeus::CVector3f xec_translation;
zeus::CVector3f xf8_; zeus::CVector3f xf8_localScale;
bool x104_24_ : 1; bool x104_24_renderAsParticleGen : 1;
bool x104_25_ : 1; bool x104_25_enableRender : 1;
bool x104_26_ : 1; bool x104_26_isElementGen : 1;
bool x104_27_ : 1; bool x104_27_runIndefinitely : 1;
float x108_ = 0.f; float x108_timeoutTimer = 0.f;
static u32 g_IndirectTexturedBillboardCount; static u32 g_IndirectTexturedBillboardCount;
static u32 g_BillboardCount; static u32 g_BillboardCount;
static float CalcGenRate();
public: public:
CHUDBillboardEffect(const std::experimental::optional<TToken<CGenDescription>>& particle, CHUDBillboardEffect(const std::experimental::optional<TToken<CGenDescription>>& particle,
const std::experimental::optional<TToken<CElectricDescription>>& electric, const std::experimental::optional<TToken<CElectricDescription>>& electric,
TUniqueId uid, bool active, std::string_view name, float, const zeus::CVector3f& v0, TUniqueId uid, bool active, std::string_view name, float dist, const zeus::CVector3f& scale0,
const zeus::CColor& color, const zeus::CVector3f& v1, const zeus::CVector3f& v2); const zeus::CColor& color, const zeus::CVector3f& scale1, const zeus::CVector3f& translation);
~CHUDBillboardEffect(); ~CHUDBillboardEffect();
void Accept(IVisitor& visitor); void Accept(IVisitor& visitor);
bool GetX104_26() const { return x104_26_; } void Think(float dt, CStateManager& mgr);
void SetX104_27(bool b) { x104_27_ = b; } void AddToRenderer(const zeus::CFrustum& frustum, const CStateManager& mgr) const;
void PreRender(CStateManager& mgr, const zeus::CFrustum& frustum);
void Render(const CStateManager& mgr) const;
bool IsElementGen() const { return x104_26_isElementGen; }
void SetRunIndefinitely(bool b) { x104_27_runIndefinitely = b; }
CParticleGen* GetParticleGen() const { return xe8_generator.get(); } CParticleGen* GetParticleGen() const { return xe8_generator.get(); }
static float GetNearClipDistance(CStateManager& mgr); static float GetNearClipDistance(CStateManager& mgr);

View File

@ -1723,7 +1723,7 @@ static const u8 BallSwooshColorsCharged[9][3] =
{0xFF, 0xE6, 0x00} {0xFF, 0xE6, 0x00}
}; };
static const u8 BallSwooshColorsLaggy[9][3] = static const u8 BallSwooshColorsJaggy[9][3] =
{ {
{0xFF, 0xCC, 0x00}, {0xFF, 0xCC, 0x00},
{0xFF, 0xCC, 0x00}, {0xFF, 0xCC, 0x00},
@ -1826,9 +1826,9 @@ void CMorphBall::Render(const CStateManager& mgr, const CActorLights* lights) co
if (x1df4_boostDrainTime > 0.f && speed > 23.f && swooshAlpha > 0.5f) if (x1df4_boostDrainTime > 0.f && speed > 23.f && swooshAlpha > 0.5f)
{ {
float laggyAlpha = zeus::clamp(0.f, (speed - 23.f) / 17.f, t); float laggyAlpha = zeus::clamp(0.f, (speed - 23.f) / 17.f, t);
c = BallSwooshColorsLaggy[x8_ballGlowColorIdx]; c = BallSwooshColorsJaggy[x8_ballGlowColorIdx];
zeus::CColor colorLaggy = {c[0] / 255.f, c[1] / 255.f, c[2] / 255.f, laggyAlpha}; zeus::CColor colorJaggy = {c[0] / 255.f, c[1] / 255.f, c[2] / 255.f, laggyAlpha};
x19c8_jaggyTrailGen->SetModulationColor(colorLaggy); x19c8_jaggyTrailGen->SetModulationColor(colorJaggy);
x19c8_jaggyTrailGen->Render(); x19c8_jaggyTrailGen->Render();
} }
@ -2433,11 +2433,11 @@ static const std::pair<const char*, u32> kSpiderBallGlassTable[] =
{"SamusSpiderBallGlassCMDL", 0}, {"SamusSpiderBallGlassCMDL", 0},
{"SamusSpiderBallGlassCMDL", 0}, {"SamusSpiderBallGlassCMDL", 0},
{"SamusSpiderBallGlassCMDL", 1}, {"SamusSpiderBallGlassCMDL", 1},
{"SamusPhazonBallGlassCMDL", 2}, {"SamusPhazonBallGlassCMDL", 0},
{"SamusSpiderBallGlassCMDL", 0},
{"SamusSpiderBallGlassCMDL", 0}, {"SamusSpiderBallGlassCMDL", 0},
{"SamusSpiderBallGlassCMDL", 2},
{"SamusSpiderBallGlassCMDL", 1}, {"SamusSpiderBallGlassCMDL", 1},
{"SamusPhazonBallGlassCMDL", 3} {"SamusPhazonBallGlassCMDL", 0}
}; };
static const u32 kSpiderBallGlowColorIdxTable[] = static const u32 kSpiderBallGlowColorIdxTable[] =

View File

@ -94,7 +94,7 @@ void CWorldLayers::ReadWorldLayers(athena::io::MemoryReader& r, int version, CAs
} }
u32 nameCount = r.readUint32Big(); u32 nameCount = r.readUint32Big();
ret.m_names.reserve(areaCount); ret.m_names.reserve(nameCount);
for (u32 i = 0; i < nameCount; ++i) for (u32 i = 0; i < nameCount; ++i)
ret.m_names.push_back(r.readString()); ret.m_names.push_back(r.readString());

View File

@ -261,9 +261,6 @@ fragment float4 fmain(VertToFrag vtf [[ stage_in ]],
#instattribute uv4 2 #instattribute uv4 2
#instattribute uv4 3 #instattribute uv4 3
#instattribute uv4 4 #instattribute uv4 4
#instattribute uv4 5
#instattribute uv4 6
#instattribute uv4 7
#srcfac srcalpha #srcfac srcalpha
#dstfac invsrcalpha #dstfac invsrcalpha
#depthtest none #depthtest none
@ -320,6 +317,7 @@ void main()
vec4 sceneTexel = texture(sceneMap, mix(vtf.uvScene.xy, vtf.uvScene.zw, tindTexel)); vec4 sceneTexel = texture(sceneMap, mix(vtf.uvScene.xy, vtf.uvScene.zw, tindTexel));
vec4 texrTexel = texture(texrMap, vtf.uvTexr); vec4 texrTexel = texture(texrMap, vtf.uvTexr);
colorOut = vtf.color * vec4(sceneTexel.rgb, 1.0) + texrTexel; colorOut = vtf.color * vec4(sceneTexel.rgb, 1.0) + texrTexel;
colorOut.a = vtf.color.a * texrTexel.a;
} }
#vertex hlsl #vertex hlsl