2
0
mirror of https://github.com/AxioDL/metaforce.git synced 2025-05-14 12:31:22 +00:00
metaforce/Runtime/GuiSys/CGuiModel.cpp
Lioncash 40fc3f9dd8 CModelBoo: Remove usages of const_cast
Many functions are modifying internals of CBooModel and const-casting
is performed in order to work around functions being const when they
really shouldn't be.

This amends the function signatures in order to allow these functions to
exist without const_cast, making code much nicer to read.
2020-03-25 02:01:46 -04:00

134 lines
3.9 KiB
C++

#include "Runtime/GuiSys/CGuiModel.hpp"
#include "Runtime/CSimplePool.hpp"
#include "Runtime/Graphics/CGraphics.hpp"
#include "Runtime/GuiSys/CGuiFrame.hpp"
#include "Runtime/GuiSys/CGuiSys.hpp"
#include "Runtime/GuiSys/CGuiWidgetDrawParms.hpp"
namespace urde {
CGuiModel::CGuiModel(const CGuiWidgetParms& parms, CSimplePool* sp, CAssetId modelId, u32 lightMask, bool flag)
: CGuiWidget(parms), xc8_modelId(modelId), xcc_lightMask(lightMask) {
if (!flag || !modelId.IsValid() || parms.x0_frame->GetGuiSys().GetUsageMode() == CGuiSys::EUsageMode::Two)
return;
xb8_model = sp->GetObj({SBIG('CMDL'), modelId});
}
bool CGuiModel::GetIsFinishedLoadingWidgetSpecific() {
if (!xb8_model) {
return true;
}
if (!xb8_model.IsLoaded()) {
return false;
}
xb8_model->GetInstance().Touch(0);
return xb8_model->IsLoaded(0);
}
void CGuiModel::Touch() {
CModel* const model = xb8_model.GetObj();
if (model == nullptr) {
return;
}
model->GetInstance().Touch(0);
}
void CGuiModel::Draw(const CGuiWidgetDrawParms& parms) {
CGraphics::SetModelMatrix(x34_worldXF);
if (!xb8_model) {
return;
}
if (!GetIsFinishedLoading()) {
return;
}
CModel* const model = xb8_model.GetObj();
if (!model) {
return;
}
if (GetIsVisible()) {
SCOPED_GRAPHICS_DEBUG_GROUP(fmt::format(fmt("CGuiModel::Draw {}"), m_name).c_str(), zeus::skCyan);
zeus::CColor moduCol = xa8_color2;
moduCol.a() *= parms.x0_alphaMod;
xb0_frame->EnableLights(xcc_lightMask, model->GetInstance());
// if (xb6_29_cullFaces)
// CGraphics::SetCullMode(ERglCullMode::Front);
switch (xac_drawFlags) {
case EGuiModelDrawFlags::Shadeless: {
CModelFlags flags(0, 0, 3, zeus::skWhite);
flags.m_extendedShader = EExtendedShader::Flat;
model->Draw(flags);
break;
}
case EGuiModelDrawFlags::Opaque: {
CModelFlags flags(1, 0, 3, moduCol);
flags.m_extendedShader = EExtendedShader::Lighting;
model->Draw(flags);
break;
}
case EGuiModelDrawFlags::Alpha: {
CModelFlags flags(5, 0, (u32(xb7_24_depthWrite) << 1) | u32(xb6_31_depthTest), moduCol);
flags.m_noCull = !xb6_29_cullFaces;
flags.m_noZWrite = !xb7_24_depthWrite;
model->Draw(flags);
break;
}
case EGuiModelDrawFlags::Additive: {
CModelFlags flags(7, 0, (u32(xb7_24_depthWrite) << 1) | u32(xb6_31_depthTest), moduCol);
flags.m_noCull = !xb6_29_cullFaces;
flags.m_noZWrite = !xb7_24_depthWrite;
flags.m_depthGreater = xb6_30_depthGreater;
model->Draw(flags);
break;
}
case EGuiModelDrawFlags::AlphaAdditiveOverdraw: {
CModelFlags flags(5, 0, xb6_31_depthTest, moduCol);
flags.m_noCull = !xb6_29_cullFaces;
flags.m_noZWrite = !xb7_24_depthWrite;
model->Draw(flags);
flags.x0_blendMode = 7;
flags.x1_matSetIdx = 0;
flags.x2_flags = (u32(xb7_24_depthWrite) << 1) | u32(xb6_31_depthTest);
flags.x4_color = moduCol;
flags.m_noCull = !xb6_29_cullFaces;
model->Draw(flags);
break;
}
default:
break;
}
// if (xb6_29_cullFaces)
// CGraphics::SetCullMode(ERglCullMode::None);
xb0_frame->DisableLights();
}
CGuiWidget::Draw(parms);
}
bool CGuiModel::TestCursorHit(const zeus::CMatrix4f& vp, const zeus::CVector2f& point) const {
if (!xb8_model || !xb8_model.IsLoaded())
return false;
return xb8_model->GetAABB().projectedPointTest(vp * x34_worldXF.toMatrix4f(), point);
}
std::shared_ptr<CGuiWidget> CGuiModel::Create(CGuiFrame* frame, CInputStream& in, CSimplePool* sp) {
CGuiWidgetParms parms = ReadWidgetHeader(frame, in);
CAssetId model = in.readUint32Big();
in.readUint32Big();
u32 lightMask = in.readUint32Big();
std::shared_ptr<CGuiWidget> ret = std::make_shared<CGuiModel>(parms, sp, model, lightMask, true);
ret->ParseBaseInfo(frame, in, parms);
return ret;
}
} // namespace urde