metaforce/Runtime/Graphics/CSkinnedModel.cpp

84 lines
3.1 KiB
C++
Raw Normal View History

#include "CSkinnedModel.hpp"
2016-08-22 20:12:50 -07:00
#include "Character/CSkinRules.hpp"
#include "CVertexMorphEffect.hpp"
namespace urde
{
2016-08-31 16:08:09 -07:00
static logvisor::Module Log("urde::CSkinnedModel");
2016-08-21 13:39:18 -07:00
CSkinnedModel::CSkinnedModel(TLockedToken<CModel> model,
TLockedToken<CSkinRules> skinRules,
TLockedToken<CCharLayoutInfo> layoutInfo,
2016-09-11 21:53:28 -07:00
int shaderIdx, int drawInsts)
2016-04-14 14:42:47 -07:00
: x4_model(model), x10_skinRules(skinRules), x1c_layoutInfo(layoutInfo)
{
2016-08-31 16:08:09 -07:00
if (!model)
Log.report(logvisor::Fatal, "bad model token provided to CSkinnedModel");
if (!skinRules)
Log.report(logvisor::Fatal, "bad skin token provided to CSkinnedModel");
if (!layoutInfo)
Log.report(logvisor::Fatal, "bad character layout token provided to CSkinnedModel");
2016-09-11 21:53:28 -07:00
m_modelInst = model->MakeNewInstance(shaderIdx, drawInsts);
}
2017-08-12 22:26:14 -07:00
CSkinnedModel::CSkinnedModel(IObjectStore& store, CAssetId model,
CAssetId skinRules, CAssetId layoutInfo,
2016-09-11 21:53:28 -07:00
int shaderIdx, int drawInsts)
2016-08-21 13:39:18 -07:00
: CSkinnedModel(store.GetObj(SObjectTag{FOURCC('CMDL'), model}),
store.GetObj(SObjectTag{FOURCC('CSKR'), skinRules}),
store.GetObj(SObjectTag{FOURCC('CINF'), layoutInfo}),
2016-09-11 21:53:28 -07:00
shaderIdx, drawInsts)
2016-04-14 20:02:21 -07:00
{
}
void CSkinnedModel::Calculate(const CPoseAsTransforms& pose,
2016-08-21 13:39:18 -07:00
const CModelFlags& drawFlags,
const std::experimental::optional<CVertexMorphEffect>& morphEffect,
2016-08-21 13:39:18 -07:00
const float* morphMagnitudes)
{
if (morphEffect || g_PointGenFunc)
{
2018-05-10 00:25:26 -07:00
if (boo::ObjToken<boo::IGraphicsBufferD> vertBuf =
m_modelInst->UpdateUniformData(drawFlags, nullptr, nullptr))
2018-01-14 23:39:25 -08:00
{
x10_skinRules->TransformVerticesCPU(m_vertWorkspace, pose, *x4_model);
if (morphEffect)
morphEffect->MorphVertices(m_vertWorkspace, morphMagnitudes, x10_skinRules, pose);
if (g_PointGenFunc)
g_PointGenFunc(g_PointGenCtx, m_vertWorkspace);
x4_model->ApplyVerticesCPU(vertBuf, m_vertWorkspace);
2018-05-10 00:25:26 -07:00
m_modifiedVBO = true;
2018-01-14 23:39:25 -08:00
}
}
else
{
2018-05-10 00:25:26 -07:00
if (boo::ObjToken<boo::IGraphicsBufferD> vertBuf =
m_modelInst->UpdateUniformData(drawFlags, x10_skinRules.GetObj(), &pose))
{
if (m_modifiedVBO)
{
x4_model->RestoreVerticesCPU(vertBuf);
m_modifiedVBO = false;
}
}
}
2016-08-21 13:39:18 -07:00
}
void CSkinnedModel::Draw(const CModelFlags& drawFlags) const
{
2016-08-21 13:39:18 -07:00
if (m_modelInst->TryLockTextures())
m_modelInst->DrawSurfaces(drawFlags);
}
2017-08-12 22:26:14 -07:00
CMorphableSkinnedModel::CMorphableSkinnedModel(IObjectStore& store, CAssetId model,
CAssetId skinRules, CAssetId layoutInfo,
2016-09-11 21:53:28 -07:00
int shaderIdx, int drawInsts)
: CSkinnedModel(store, model, skinRules, layoutInfo, shaderIdx, drawInsts)
2016-04-14 20:02:21 -07:00
{
}
2017-03-25 22:53:04 -07:00
CSkinnedModel::FPointGenerator CSkinnedModel::g_PointGenFunc = nullptr;
void* CSkinnedModel::g_PointGenCtx = nullptr;
}