2
0
mirror of https://github.com/AxioDL/metaforce.git synced 2025-07-25 12:05:34 +00:00

Rigging fixes

This commit is contained in:
Jack Andersen 2016-09-08 18:19:19 -10:00
parent 5c386d02a8
commit b6587d88fc
8 changed files with 100 additions and 37 deletions

View File

@ -399,6 +399,7 @@ bool ViewManager::proc()
m_voiceEngine->pumpAndMixVoices(); m_voiceEngine->pumpAndMixVoices();
m_projManager.asyncIdle(); m_projManager.asyncIdle();
m_mainWindow->waitForRetrace(); m_mainWindow->waitForRetrace();
CBooModel::ClearModelUniformCounters();
CGraphics::TickRenderTimings(); CGraphics::TickRenderTimings();
return true; return true;

View File

@ -313,7 +313,10 @@ void CAnimData::RecalcPoseBuilder(const CCharAnimTime* time)
if (id == 3) if (id == 3)
continue; continue;
CAnimPerSegmentData& segData = segSet[id]; CAnimPerSegmentData& segData = segSet[id];
x2fc_poseBuilder.Insert(id, segData.x0_rotation, segData.x10_offset); if (segData.x1c_hasOffset)
x2fc_poseBuilder.Insert(id, segData.x0_rotation, segData.x10_offset);
else
x2fc_poseBuilder.Insert(id, segData.x0_rotation);
} }
} }

View File

@ -15,9 +15,9 @@ void CHierarchyPoseBuilder::BuildIntoHierarchy(const CCharLayoutInfo& layout,
{ {
xcec_rootId = boneId; xcec_rootId = boneId;
xcf0_hasRoot = true; xcf0_hasRoot = true;
zeus::CVector3f origin = layout.GetFromParentUnrotated(boneId); //zeus::CVector3f origin = layout.GetFromParentUnrotated(boneId);
CTreeNode& node = x38_treeMap[boneId]; //CTreeNode& node = x38_treeMap[boneId];
node.x14_offset = origin; //node.x14_offset = origin;
} }
else else
{ {

View File

@ -82,9 +82,9 @@ CSkinnedModel& CModelData::PickAnimatedModel(EWhichModel which) const
return *x10_animData->xd8_modelData.GetObj(); return *x10_animData->xd8_modelData.GetObj();
} }
std::unique_ptr<CBooModel>& CModelData::PickStaticModel(EWhichModel which) const std::unique_ptr<CBooModel>& CModelData::PickStaticModel(EWhichModel which) const
{ {
std::unique_ptr<CBooModel>* ret = nullptr; const std::unique_ptr<CBooModel>* ret = nullptr;
switch (which) switch (which)
{ {
case EWhichModel::XRay: case EWhichModel::XRay:
@ -153,7 +153,7 @@ bool CModelData::IsDefinitelyOpaque(EWhichModel which)
} }
else else
{ {
std::unique_ptr<CBooModel>& model = PickStaticModel(which); const auto& model = PickStaticModel(which);
return model->IsOpaque(); return model->IsOpaque();
} }
} }
@ -307,7 +307,7 @@ void CModelData::RenderThermal(const zeus::CTransform& xf,
} }
else else
{ {
std::unique_ptr<CBooModel>& model = PickStaticModel(EWhichModel::Thermal); const auto& model = PickStaticModel(EWhichModel::Thermal);
model->Draw(drawFlags, nullptr, nullptr); model->Draw(drawFlags, nullptr, nullptr);
} }
} }
@ -324,7 +324,7 @@ void CModelData::RenderUnsortedParts(EWhichModel which, const zeus::CTransform&
CGraphics::SetModelMatrix(xf * zeus::CTransform::Scale(x0_scale)); CGraphics::SetModelMatrix(xf * zeus::CTransform::Scale(x0_scale));
std::unique_ptr<CBooModel>& model = PickStaticModel(which); const auto& model = PickStaticModel(which);
if (lights) if (lights)
lights->ActivateLights(*model); lights->ActivateLights(*model);
else else
@ -360,7 +360,7 @@ void CModelData::Render(EWhichModel which, const zeus::CTransform& xf,
} }
else else
{ {
std::unique_ptr<CBooModel>& model = PickStaticModel(which); const auto& model = PickStaticModel(which);
if (lights) if (lights)
lights->ActivateLights(*model); lights->ActivateLights(*model);
else else

View File

@ -87,6 +87,14 @@ class CModelData
std::unique_ptr<CBooModel> m_xrayModelInst; std::unique_ptr<CBooModel> m_xrayModelInst;
std::unique_ptr<CBooModel> m_infraModelInst; std::unique_ptr<CBooModel> m_infraModelInst;
struct WeakModelInsts
{
std::weak_ptr<CBooModel> m_normalModelInst;
std::weak_ptr<CBooModel> m_xrayModelInst;
std::weak_ptr<CBooModel> m_infraModelInst;
};
std::vector<WeakModelInsts> m_weakInsts;
public: public:
enum class EWhichModel enum class EWhichModel
{ {
@ -110,7 +118,7 @@ public:
const CActorLights* lights, const CModelFlags& drawFlags); const CActorLights* lights, const CModelFlags& drawFlags);
EWhichModel GetRenderingModel(const CStateManager& stateMgr) const; EWhichModel GetRenderingModel(const CStateManager& stateMgr) const;
CSkinnedModel& PickAnimatedModel(EWhichModel which) const; CSkinnedModel& PickAnimatedModel(EWhichModel which) const;
std::unique_ptr<CBooModel>& PickStaticModel(EWhichModel which); const std::unique_ptr<CBooModel>& PickStaticModel(EWhichModel which) const;
void SetXRayModel(const std::pair<ResId, ResId>& modelSkin); void SetXRayModel(const std::pair<ResId, ResId>& modelSkin);
void SetInfraModel(const std::pair<ResId, ResId>& modelSkin); void SetInfraModel(const std::pair<ResId, ResId>& modelSkin);
bool IsDefinitelyOpaque(EWhichModel); bool IsDefinitelyOpaque(EWhichModel);

View File

@ -80,6 +80,9 @@ public:
}; };
private: private:
CBooModel* m_next = nullptr;
CBooModel* m_prev = nullptr;
size_t m_uniUpdateCount = 0;
TLockedToken<CModel> m_model; TLockedToken<CModel> m_model;
std::vector<CBooSurface>* x0_surfaces; std::vector<CBooSurface>* x0_surfaces;
const MaterialSet* x4_matSet; const MaterialSet* x4_matSet;
@ -108,12 +111,16 @@ private:
CModelShaders::LightingUniform m_lightingData; CModelShaders::LightingUniform m_lightingData;
/* urde addition: boo! */ /* urde addition: boo! */
boo::GraphicsDataToken m_gfxToken;
size_t m_uniformDataSize = 0; size_t m_uniformDataSize = 0;
boo::IGraphicsBufferD* m_uniformBuffer = nullptr; struct ModelInstance
std::vector<std::vector<boo::IShaderDataBinding*>> m_shaderDataBindings; {
boo::GraphicsDataToken m_gfxToken;
boo::IGraphicsBufferD* m_uniformBuffer;
std::vector<std::vector<boo::IShaderDataBinding*>> m_shaderDataBindings;
};
std::vector<ModelInstance> m_instances;
void BuildGfxToken(); ModelInstance* PushNewModelInstance();
void DrawAlphaSurfaces(const CModelFlags& flags) const; void DrawAlphaSurfaces(const CModelFlags& flags) const;
void DrawNormalSurfaces(const CModelFlags& flags) const; void DrawNormalSurfaces(const CModelFlags& flags) const;
void DrawSurfaces(const CModelFlags& flags) const; void DrawSurfaces(const CModelFlags& flags) const;
@ -122,6 +129,7 @@ private:
void VerifyCurrentShader(int shaderIdx); void VerifyCurrentShader(int shaderIdx);
public: public:
~CBooModel();
CBooModel(TToken<CModel>& token, std::vector<CBooSurface>* surfaces, SShader& shader, CBooModel(TToken<CModel>& token, std::vector<CBooSurface>* surfaces, SShader& shader,
boo::IVertexFormat* vtxFmt, boo::IGraphicsBufferS* vbo, boo::IGraphicsBufferS* ibo, boo::IVertexFormat* vtxFmt, boo::IGraphicsBufferS* vbo, boo::IGraphicsBufferS* ibo,
size_t weightVecCount, size_t skinBankCount, const zeus::CAABox& aabb); size_t weightVecCount, size_t skinBankCount, const zeus::CAABox& aabb);
@ -154,6 +162,9 @@ public:
return x4_matSet->materials.at(idx); return x4_matSet->materials.at(idx);
} }
void ClearUniformCounter() { m_uniUpdateCount = 0; }
static void ClearModelUniformCounters();
static bool g_DrawingOccluders; static bool g_DrawingOccluders;
static void SetDrawingOccluders(bool occ) {g_DrawingOccluders = occ;} static void SetDrawingOccluders(bool occ) {g_DrawingOccluders = occ;}
}; };

View File

@ -16,6 +16,24 @@ namespace urde
static logvisor::Module Log("urde::CBooModel"); static logvisor::Module Log("urde::CBooModel");
bool CBooModel::g_DrawingOccluders = false; bool CBooModel::g_DrawingOccluders = false;
static CBooModel* g_FirstModel = nullptr;
void CBooModel::ClearModelUniformCounters()
{
for (CBooModel* model = g_FirstModel ; model ; model = model->m_next)
model->ClearUniformCounter();
}
CBooModel::~CBooModel()
{
if (this == g_FirstModel)
g_FirstModel = nullptr;
if (m_prev)
m_prev->m_next = m_next;
if (m_next)
m_next->m_prev = m_prev;
}
CBooModel::CBooModel(TToken<CModel>& token, std::vector<CBooSurface>* surfaces, SShader& shader, CBooModel::CBooModel(TToken<CModel>& token, std::vector<CBooSurface>* surfaces, SShader& shader,
boo::IVertexFormat* vtxFmt, boo::IGraphicsBufferS* vbo, boo::IGraphicsBufferS* ibo, boo::IVertexFormat* vtxFmt, boo::IGraphicsBufferS* vbo, boo::IGraphicsBufferS* ibo,
size_t weightVecCount, size_t skinBankCount, const zeus::CAABox& aabb) size_t weightVecCount, size_t skinBankCount, const zeus::CAABox& aabb)
@ -24,6 +42,15 @@ CBooModel::CBooModel(TToken<CModel>& token, std::vector<CBooSurface>* surfaces,
m_skinBankCount(skinBankCount), x1c_textures(shader.x0_textures), x20_aabb(aabb), m_skinBankCount(skinBankCount), x1c_textures(shader.x0_textures), x20_aabb(aabb),
x40_24_texturesLoaded(false), x40_25_modelVisible(0) x40_24_texturesLoaded(false), x40_25_modelVisible(0)
{ {
if (!g_FirstModel)
g_FirstModel = this;
else
{
g_FirstModel->m_prev = this;
m_next = g_FirstModel;
g_FirstModel = this;
}
for (CBooSurface& surf : *x0_surfaces) for (CBooSurface& surf : *x0_surfaces)
surf.m_parent = this; surf.m_parent = this;
@ -42,14 +69,19 @@ CBooModel::CBooModel(TToken<CModel>& token, std::vector<CBooSurface>* surfaces,
x38_firstUnsortedSurface = &*it; x38_firstUnsortedSurface = &*it;
} }
} }
if (x40_24_texturesLoaded)
BuildGfxToken();
} }
void CBooModel::BuildGfxToken() CBooModel::ModelInstance* CBooModel::PushNewModelInstance()
{ {
m_gfxToken = CGraphics::CommitResources( if (!x40_24_texturesLoaded)
return nullptr;
if (m_instances.size() >= 256)
Log.report(logvisor::Fatal, "Model buffer overflow");
m_instances.emplace_back();
ModelInstance& newInst = m_instances.back();
newInst.m_gfxToken = CGraphics::CommitResources(
[&](boo::IGraphicsDataFactory::Context& ctx) -> bool [&](boo::IGraphicsDataFactory::Context& ctx) -> bool
{ {
/* Determine space required by uniform buffer */ /* Determine space required by uniform buffer */
@ -106,13 +138,12 @@ void CBooModel::BuildGfxToken()
/* Allocate resident buffer */ /* Allocate resident buffer */
m_uniformDataSize = uniBufSize; m_uniformDataSize = uniBufSize;
m_uniformBuffer = ctx.newDynamicBuffer(boo::BufferUse::Uniform, uniBufSize, 1); newInst.m_uniformBuffer = ctx.newDynamicBuffer(boo::BufferUse::Uniform, uniBufSize, 1);
boo::IGraphicsBuffer* bufs[] = {m_uniformBuffer, m_uniformBuffer, m_uniformBuffer}; boo::IGraphicsBuffer* bufs[] = {newInst.m_uniformBuffer, newInst.m_uniformBuffer, newInst.m_uniformBuffer};
/* Binding for each surface */ /* Binding for each surface */
m_shaderDataBindings.clear(); newInst.m_shaderDataBindings.reserve(x0_surfaces->size());
m_shaderDataBindings.reserve(x0_surfaces->size());
std::vector<boo::ITexture*> texs; std::vector<boo::ITexture*> texs;
size_t thisOffs[3]; size_t thisOffs[3];
@ -156,8 +187,8 @@ void CBooModel::BuildGfxToken()
const std::vector<boo::IShaderPipeline*>& pipelines = m_pipelines->at(surf.m_data.matIdx); const std::vector<boo::IShaderPipeline*>& pipelines = m_pipelines->at(surf.m_data.matIdx);
m_shaderDataBindings.emplace_back(); newInst.m_shaderDataBindings.emplace_back();
std::vector<boo::IShaderDataBinding*>& extendeds = m_shaderDataBindings.back(); std::vector<boo::IShaderDataBinding*>& extendeds = newInst.m_shaderDataBindings.back();
extendeds.reserve(pipelines.size()); extendeds.reserve(pipelines.size());
int idx = 0; int idx = 0;
@ -173,6 +204,8 @@ void CBooModel::BuildGfxToken()
} }
return true; return true;
}); });
return &newInst;
} }
void CBooModel::MakeTexuresFromMats(const MaterialSet& matSet, void CBooModel::MakeTexuresFromMats(const MaterialSet& matSet,
@ -239,7 +272,7 @@ void CBooModel::RemapMaterialData(SShader& shader)
x1c_textures = shader.x0_textures; x1c_textures = shader.x0_textures;
m_pipelines = &shader.m_shaders; m_pipelines = &shader.m_shaders;
x40_24_texturesLoaded = false; x40_24_texturesLoaded = false;
m_gfxToken.doDestroy(); m_instances.clear();
} }
bool CBooModel::TryLockTextures() const bool CBooModel::TryLockTextures() const
@ -256,16 +289,13 @@ bool CBooModel::TryLockTextures() const
const_cast<CBooModel*>(this)->x40_24_texturesLoaded = allLoad; const_cast<CBooModel*>(this)->x40_24_texturesLoaded = allLoad;
} }
if (!m_gfxToken && x40_24_texturesLoaded)
const_cast<CBooModel*>(this)->BuildGfxToken();
return x40_24_texturesLoaded; return x40_24_texturesLoaded;
} }
void CBooModel::UnlockTextures() const void CBooModel::UnlockTextures() const
{ {
const_cast<boo::GraphicsDataToken&>(m_gfxToken).doDestroy(); const_cast<CBooModel*>(this)->m_instances.clear();
for (TCachedToken<CTexture>& tex : const_cast<std::vector<TCachedToken<CTexture>>&>(x1c_textures)) for (TCachedToken<CTexture>& tex : const_cast<std::vector<TCachedToken<CTexture>>&>(x1c_textures))
tex.Unlock(); tex.Unlock();
const_cast<CBooModel*>(this)->x40_24_texturesLoaded = false; const_cast<CBooModel*>(this)->x40_24_texturesLoaded = false;
@ -310,11 +340,15 @@ void CBooModel::DrawSurfaces(const CModelFlags& flags) const
void CBooModel::DrawSurface(const CBooSurface& surf, const CModelFlags& flags) const void CBooModel::DrawSurface(const CBooSurface& surf, const CModelFlags& flags) const
{ {
if (m_uniUpdateCount > m_instances.size())
return;
const ModelInstance& inst = m_instances[m_uniUpdateCount-1];
const MaterialSet::Material& data = GetMaterialByIndex(surf.m_data.matIdx); const MaterialSet::Material& data = GetMaterialByIndex(surf.m_data.matIdx);
if (data.flags.shadowOccluderMesh() && !g_DrawingOccluders) if (data.flags.shadowOccluderMesh() && !g_DrawingOccluders)
return; return;
const std::vector<boo::IShaderDataBinding*>& extendeds = m_shaderDataBindings[surf.selfIdx]; const std::vector<boo::IShaderDataBinding*>& extendeds = inst.m_shaderDataBindings[surf.selfIdx];
boo::IShaderDataBinding* binding = extendeds[0]; boo::IShaderDataBinding* binding = extendeds[0];
if (flags.m_extendedShaderIdx < extendeds.size()) if (flags.m_extendedShaderIdx < extendeds.size())
binding = extendeds[flags.m_extendedShaderIdx]; binding = extendeds[flags.m_extendedShaderIdx];
@ -464,10 +498,16 @@ void CBooModel::UpdateUniformData(const CModelFlags& flags,
const CSkinRules* cskr, const CSkinRules* cskr,
const CPoseAsTransforms* pose) const const CPoseAsTransforms* pose) const
{ {
if (!m_uniformBuffer) const ModelInstance* inst;
if (m_instances.size() <= m_uniUpdateCount)
inst = const_cast<CBooModel*>(this)->PushNewModelInstance();
else
inst = &m_instances[m_uniUpdateCount];
if (!inst)
return; return;
++const_cast<CBooModel*>(this)->m_uniUpdateCount;
u8* dataOut = reinterpret_cast<u8*>(m_uniformBuffer->map(m_uniformDataSize)); u8* dataOut = reinterpret_cast<u8*>(inst->m_uniformBuffer->map(m_uniformDataSize));
u8* dataCur = dataOut; u8* dataCur = dataOut;
if (m_skinBankCount) if (m_skinBankCount)
@ -566,7 +606,7 @@ void CBooModel::UpdateUniformData(const CModelFlags& flags,
lightingOut.fog = CGraphics::g_Fog; lightingOut.fog = CGraphics::g_Fog;
} }
m_uniformBuffer->unmap(); inst->m_uniformBuffer->unmap();
} }
void CBooModel::DrawAlpha(const CModelFlags& flags, void CBooModel::DrawAlpha(const CModelFlags& flags,

2
hecl

@ -1 +1 @@
Subproject commit 354b9c853d6782d58c0184489b86d10f2771ed2a Subproject commit 27c91a5bbc604a2d781624b75835307c1cd66940