Add light visualization (requires custom models)

This commit is contained in:
Phillip Stephens 2020-12-12 23:39:55 -08:00
parent 6f7d3b4dc5
commit 28561081d7
Signed by: Antidote
GPG Key ID: F8BEE4C83DACA60D
5 changed files with 110 additions and 4 deletions

View File

@ -543,8 +543,15 @@ void CStateManager::DrawDebugStuff() const {
if (CPathFindSearch* path = ai->GetSearchPath()) {
path->DebugDraw();
}
} else if (const TCastToPtr<CGameLight> light = ent) {
light->DebugDraw();
}
}
auto* gameArea = x850_world->GetArea(x850_world->GetCurrentAreaId());
if (gameArea != nullptr) {
gameArea->DebugDraw();
}
if (xf70_currentMaze) {
xf70_currentMaze->DebugRender();
}

View File

@ -1199,10 +1199,69 @@ void CGameArea::SetAreaAttributes(const CScriptAreaAttributes* areaAttributes) {
x12c_postConstructed->x1128_worldLightingLevel = areaAttributes->GetWorldLightingLevel();
}
bool CGameArea::CAreaObjectList::IsQualified(const CEntity& ent) const { return (ent.GetAreaIdAlways() == x200c_areaIdx); }
bool CGameArea::CAreaObjectList::IsQualified(const CEntity& ent) const {
return (ent.GetAreaIdAlways() == x200c_areaIdx);
}
void CGameArea::WarmupShaders(const SObjectTag& mreaTag) {
// Calling this version of the constructor performs warmup implicitly
[[maybe_unused]] CGameArea area(mreaTag.id);
}
void CGameArea::DebugDraw() {
if (!m_debugSphereRes) {
const auto* tok = g_ResFactory->GetResourceIdByName("CMDL_DebugSphere");
if (tok != nullptr && tok->type == FOURCC('CMDL')) {
m_debugSphereRes = CStaticRes(tok->id, zeus::skOne3f);
}
}
if (m_debugSphereRes && !m_debugSphereModel) {
m_debugSphereModel = std::make_unique<CModelData>(*m_debugSphereRes);
}
if (!m_debugConeRes) {
const auto* tok = g_ResFactory->GetResourceIdByName("CMDL_DebugLightCone");
if (tok != nullptr && tok->type == FOURCC('CMDL')) {
m_debugConeRes = CStaticRes(tok->id, zeus::skOne3f);
}
}
if (m_debugConeRes && !m_debugConeModel) {
m_debugConeModel = std::make_unique<CModelData>(*m_debugConeRes);
}
if (IsPostConstructed()) {
for (const auto& light : x12c_postConstructed->x70_gfxLightsA) {
DebugDrawLight(light);
}
for (const auto& light : x12c_postConstructed->x90_gfxLightsB) {
DebugDrawLight(light);
}
}
}
void CGameArea::DebugDrawLight(const CLight& light) {
if (light.GetType() == ELightType::LocalAmbient) {
return;
}
g_Renderer->SetGXRegister1Color(light.GetColor());
CModelFlags modelFlags;
modelFlags.x0_blendMode = 5;
modelFlags.x4_color = zeus::skWhite;
modelFlags.x4_color.a() = 0.5f;
if ((light.GetType() == ELightType::Spot || light.GetType() == ELightType::Directional) && m_debugConeModel) {
m_debugConeModel->Render(CModelData::EWhichModel::Normal,
zeus::lookAt(light.GetPosition(), light.GetPosition() + light.GetDirection()) *
zeus::CTransform::Scale(zeus::clamp(-90.f, light.GetRadius(), 90.f)),
nullptr, modelFlags);
} else if (m_debugSphereModel) {
m_debugSphereModel->Render(CModelData::EWhichModel::Normal, zeus::CTransform::Translate(light.GetPosition()),
nullptr, modelFlags);
m_debugSphereModel->Render(CModelData::EWhichModel::Normal,
zeus::CTransform::Translate(light.GetPosition()) *
zeus::CTransform::Scale(light.GetRadius()),
nullptr, modelFlags);
}
}
} // namespace urde

View File

@ -15,7 +15,7 @@
#include "Runtime/World/CPathFindArea.hpp"
#include "Runtime/World/CWorldLight.hpp"
#include "Runtime/World/IGameArea.hpp"
#include "Runtime/Character/CModelData.hpp"
#include <hecl/ClientProcess.hpp>
#include <zeus/CAABox.hpp>
@ -268,6 +268,10 @@ private:
void UpdateThermalVisor(float dt);
void UpdateWeaponWorldLighting(float dt);
std::optional<CStaticRes> m_debugSphereRes;
std::unique_ptr<CModelData> m_debugSphereModel;
std::optional<CStaticRes> m_debugConeRes;
std::unique_ptr<CModelData> m_debugConeModel;
public:
explicit CGameArea(CInputStream& in, int idx, int mlvlVersion);
explicit CGameArea(CAssetId mreaId); // Warmup constructor
@ -362,6 +366,8 @@ public:
CGameArea* GetNext() const { return x130_next; }
static void WarmupShaders(const SObjectTag& mreaTag);
void DebugDraw();
void DebugDrawLight(const CLight& light);
};
} // namespace urde

View File

@ -2,6 +2,9 @@
#include "Runtime/CStateManager.hpp"
#include "Runtime/World/CActorParameters.hpp"
#include "Runtime/GameGlobalObjects.hpp"
#include "Runtime/CSimplePool.hpp"
#include "Graphics/CBooRenderer.hpp"
#include "TCastTo.hpp" // Generated file, do not modify include path
@ -53,4 +56,30 @@ CLight CGameLight::GetLight() const {
return ret;
}
void CGameLight::DebugDraw() {
if (!m_debugRes) {
const auto* tok = (xec_light.GetType() == ELightType::Spot || xec_light.GetType() == ELightType::Directional)
? g_ResFactory->GetResourceIdByName("CMDL_DebugLightCone")
: g_ResFactory->GetResourceIdByName("CMDL_DebugSphere");
if (tok != nullptr && tok->type == FOURCC('CMDL')) {
m_debugRes = CStaticRes(tok->id, zeus::skOne3f);
}
}
if (m_debugRes && !m_debugModel) {
m_debugModel = std::make_unique<CModelData>(*m_debugRes);
}
if (m_debugModel) {
g_Renderer->SetGXRegister1Color(xec_light.GetColor());
CModelFlags modelFlags;
modelFlags.x0_blendMode = 5;
modelFlags.x4_color = zeus::skWhite;
modelFlags.x4_color.a() = 0.5f;
m_debugModel->Render(CModelData::EWhichModel::Normal, zeus::CTransform::Translate(xec_light.GetPosition()), nullptr,
modelFlags);
m_debugModel->Render(CModelData::EWhichModel::Normal, x34_transform, nullptr, modelFlags);
}
}
} // namespace urde

View File

@ -14,6 +14,9 @@ class CGameLight : public CActor {
u32 x140_priority;
float x144_lifeTime;
std::optional<CStaticRes> m_debugRes;
std::unique_ptr<CModelData> m_debugModel;
public:
CGameLight(TUniqueId uid, TAreaId aid, bool active, std::string_view name, const zeus::CTransform& xf,
TUniqueId parentId, const CLight& light, u32 sourceId, u32 priority, float lifeTime);
@ -24,5 +27,7 @@ public:
void SetLight(const CLight& light);
CLight GetLight() const;
TUniqueId GetParentId() const { return xe8_parentId; }
void DebugDraw();
};
} // namespace urde