mirror of
https://github.com/AxioDL/metaforce.git
synced 2025-05-14 11:51:21 +00:00
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.
134 lines
3.9 KiB
C++
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
|