Resource factories now provided with self-ref

This commit is contained in:
Jack Andersen 2016-09-02 09:32:57 -10:00
parent 6dff9b241a
commit f4ea728a61
43 changed files with 201 additions and 135 deletions

View File

@ -335,7 +335,8 @@ bool ProjectResourceFactoryBase::SyncCook(const hecl::ProjectPath& working)
CFactoryFnReturn ProjectResourceFactoryBase::BuildSync(const SObjectTag& tag,
const hecl::ProjectPath& path,
const CVParamTransfer& paramXfer)
const CVParamTransfer& paramXfer,
CObjectReference* selfRef)
{
/* Ensure cooked rep is on the filesystem */
std::experimental::optional<athena::io::FileReader> fr;
@ -347,10 +348,10 @@ CFactoryFnReturn ProjectResourceFactoryBase::BuildSync(const SObjectTag& tag,
{
u32 length = fr->length();
std::unique_ptr<u8[]> memBuf = fr->readUBytes(length);
return m_factoryMgr.MakeObjectFromMemory(tag, std::move(memBuf), length, false, paramXfer);
return m_factoryMgr.MakeObjectFromMemory(tag, std::move(memBuf), length, false, paramXfer, selfRef);
}
return m_factoryMgr.MakeObject(tag, *fr, paramXfer);
return m_factoryMgr.MakeObject(tag, *fr, paramXfer, selfRef);
}
void ProjectResourceFactoryBase::AsyncTask::EnsurePath(const urde::SObjectTag& tag,
@ -518,7 +519,8 @@ ProjectResourceFactoryBase::PrepForReadSync(const SObjectTag& tag,
}
std::unique_ptr<urde::IObj> ProjectResourceFactoryBase::Build(const urde::SObjectTag& tag,
const urde::CVParamTransfer& paramXfer)
const urde::CVParamTransfer& paramXfer,
CObjectReference* selfRef)
{
const hecl::ProjectPath* resPath = nullptr;
if (!WaitForTagReady(tag, resPath))
@ -540,12 +542,12 @@ std::unique_ptr<urde::IObj> ProjectResourceFactoryBase::Build(const urde::SObjec
if (m_factoryMgr.CanMakeMemory(task.x0_tag))
{
newObj = m_factoryMgr.MakeObjectFromMemory(tag, std::move(task.x10_loadBuffer),
task.x14_resSize, false, task.x18_cvXfer);
task.x14_resSize, false, task.x18_cvXfer, selfRef);
}
else
{
athena::io::MemoryReader mr(task.x10_loadBuffer.get(), task.x14_resSize);
newObj = m_factoryMgr.MakeObject(task.x0_tag, mr, task.x18_cvXfer);
newObj = m_factoryMgr.MakeObject(task.x0_tag, mr, task.x18_cvXfer, selfRef);
}
*task.xc_targetObjPtr = newObj.get();
@ -564,24 +566,26 @@ std::unique_ptr<urde::IObj> ProjectResourceFactoryBase::Build(const urde::SObjec
}
/* Fall-back to sync build */
return BuildSync(tag, *resPath, paramXfer);
return BuildSync(tag, *resPath, paramXfer, selfRef);
}
std::shared_ptr<ProjectResourceFactoryBase::AsyncTask>
ProjectResourceFactoryBase::BuildAsyncInternal(const urde::SObjectTag& tag,
const urde::CVParamTransfer& paramXfer,
urde::IObj** objOut)
urde::IObj** objOut,
CObjectReference* selfRef)
{
if (m_asyncLoadList.find(tag) != m_asyncLoadList.end())
return {};
return m_asyncLoadList.emplace(std::make_pair(tag, std::make_unique<AsyncTask>(*this, tag, objOut, paramXfer))).first->second;
return m_asyncLoadList.emplace(std::make_pair(tag, std::make_unique<AsyncTask>(*this, tag, objOut, paramXfer, selfRef))).first->second;
}
void ProjectResourceFactoryBase::BuildAsync(const urde::SObjectTag& tag,
const urde::CVParamTransfer& paramXfer,
urde::IObj** objOut)
urde::IObj** objOut,
CObjectReference* selfRef)
{
BuildAsyncInternal(tag, paramXfer, objOut);
BuildAsyncInternal(tag, paramXfer, objOut, selfRef);
}
u32 ProjectResourceFactoryBase::ResourceSize(const SObjectTag& tag)
@ -765,12 +769,13 @@ void ProjectResourceFactoryBase::AsyncIdle()
if (m_factoryMgr.CanMakeMemory(task.x0_tag))
{
newObj = m_factoryMgr.MakeObjectFromMemory(task.x0_tag, std::move(task.x10_loadBuffer),
task.x14_resSize, false, task.x18_cvXfer);
task.x14_resSize, false, task.x18_cvXfer,
task.m_selfRef);
}
else
{
athena::io::MemoryReader mr(task.x10_loadBuffer.get(), task.x14_resSize);
newObj = m_factoryMgr.MakeObject(task.x0_tag, mr, task.x18_cvXfer);
newObj = m_factoryMgr.MakeObject(task.x0_tag, mr, task.x18_cvXfer, task.m_selfRef);
}
*task.xc_targetObjPtr = newObj.release();

View File

@ -32,6 +32,7 @@ public:
u32 x14_resSize = UINT32_MAX;
u32 x14_resOffset = 0;
CVParamTransfer x18_cvXfer;
CObjectReference* m_selfRef = nullptr;
hecl::ProjectPath m_workingPath;
hecl::ProjectPath m_cookedPath;
@ -50,8 +51,8 @@ public:
x14_resOffset(off) {}
AsyncTask(ProjectResourceFactoryBase& parent, const SObjectTag& tag,
IObj** ptr, const CVParamTransfer& xfer)
: m_parent(parent), x0_tag(tag), xc_targetObjPtr(ptr), x18_cvXfer(xfer) {}
IObj** ptr, const CVParamTransfer& xfer, CObjectReference* selfRef)
: m_parent(parent), x0_tag(tag), xc_targetObjPtr(ptr), x18_cvXfer(xfer), m_selfRef(selfRef) {}
void EnsurePath(const urde::SObjectTag& tag,
const hecl::ProjectPath& path);
@ -104,13 +105,13 @@ protected:
hecl::ProjectPath GetCookedPath(const hecl::ProjectPath& working, bool pcTarget) const;
bool SyncCook(const hecl::ProjectPath& working);
CFactoryFnReturn BuildSync(const SObjectTag& tag, const hecl::ProjectPath& path,
const CVParamTransfer& paramXfer);
const CVParamTransfer& paramXfer, CObjectReference* selfRef);
public:
ProjectResourceFactoryBase(hecl::ClientProcess& clientProc) : m_clientProc(clientProc) {}
std::unique_ptr<urde::IObj> Build(const urde::SObjectTag&, const urde::CVParamTransfer&);
void BuildAsync(const urde::SObjectTag&, const urde::CVParamTransfer&, urde::IObj**);
std::shared_ptr<AsyncTask> BuildAsyncInternal(const urde::SObjectTag&, const urde::CVParamTransfer&, urde::IObj**);
std::unique_ptr<urde::IObj> Build(const urde::SObjectTag&, const urde::CVParamTransfer&, CObjectReference* selfRef);
void BuildAsync(const urde::SObjectTag&, const urde::CVParamTransfer&, urde::IObj**, CObjectReference* selfRef);
std::shared_ptr<AsyncTask> BuildAsyncInternal(const urde::SObjectTag&, const urde::CVParamTransfer&, urde::IObj**, CObjectReference* selfRef);
void CancelBuild(const urde::SObjectTag&);
bool CanBuild(const urde::SObjectTag&);
const urde::SObjectTag* GetResourceIdByName(const char*) const;

View File

@ -31,7 +31,8 @@ CAudioGroupSet::CAudioGroupSet(std::unique_ptr<u8[]>&& in)
CFactoryFnReturn FAudioGroupSetDataFactory(const urde::SObjectTag& tag,
std::unique_ptr<u8[]>&& in, u32 len,
const urde::CVParamTransfer& vparms)
const urde::CVParamTransfer& vparms,
CObjectReference* selfRef)
{
return TToken<CAudioGroupSet>::GetIObjObjectFor(std::make_unique<CAudioGroupSet>(std::move(in)));
}

View File

@ -25,7 +25,8 @@ public:
CFactoryFnReturn FAudioGroupSetDataFactory(const urde::SObjectTag& tag,
std::unique_ptr<u8[]>&& in, u32 len,
const urde::CVParamTransfer& vparms);
const urde::CVParamTransfer& vparms,
CObjectReference* selfRef);
}

View File

@ -16,7 +16,8 @@ void CDependencyGroup::ReadFromStream(CInputStream& in)
x0_objectTags.emplace_back(in);
}
CFactoryFnReturn FDependencyGroupFactory(const SObjectTag& /*tag*/, CInputStream& in, const CVParamTransfer& /*param*/)
CFactoryFnReturn FDependencyGroupFactory(const SObjectTag& /*tag*/, CInputStream& in, const CVParamTransfer& /*param*/,
CObjectReference* selfRef)
{
return TToken<CDependencyGroup>::GetIObjObjectFor(std::unique_ptr<CDependencyGroup>(new CDependencyGroup(in)));
}

View File

@ -14,7 +14,8 @@ public:
std::vector<SObjectTag> GetObjectTagVector() const { return x0_objectTags; }
};
CFactoryFnReturn FDependencyGroupFactory(const SObjectTag& tag, CInputStream& in, const CVParamTransfer& param);
CFactoryFnReturn FDependencyGroupFactory(const SObjectTag& tag, CInputStream& in, const CVParamTransfer& param,
CObjectReference* selfRef);
}
#endif // CDEPENDENCYGROUP_HPP

View File

@ -5,13 +5,13 @@ namespace urde
{
CFactoryFnReturn CFactoryMgr::MakeObject(const SObjectTag& tag, urde::CInputStream& in,
const CVParamTransfer& paramXfer)
const CVParamTransfer& paramXfer, CObjectReference* selfRef)
{
auto search = m_factories.find(tag.type);
if (search == m_factories.end())
return {};
return search->second(tag, in, paramXfer);
return search->second(tag, in, paramXfer, selfRef);
}
bool CFactoryMgr::CanMakeMemory(const urde::SObjectTag& tag) const
@ -21,7 +21,8 @@ bool CFactoryMgr::CanMakeMemory(const urde::SObjectTag& tag) const
}
CFactoryFnReturn CFactoryMgr::MakeObjectFromMemory(const SObjectTag& tag, std::unique_ptr<u8[]>&& buf, int size,
bool compressed, const CVParamTransfer& paramXfer)
bool compressed, const CVParamTransfer& paramXfer,
CObjectReference* selfRef)
{
std::unique_ptr<u8[]> localBuf = std::move(buf);
@ -35,11 +36,11 @@ CFactoryFnReturn CFactoryMgr::MakeObjectFromMemory(const SObjectTag& tag, std::u
u32 decompLen = compRead->readUint32Big();
CZipInputStream r(std::move(compRead));
std::unique_ptr<u8[]> decompBuf = r.readUBytes(decompLen);
return search->second(tag, std::move(decompBuf), decompLen, paramXfer);
return search->second(tag, std::move(decompBuf), decompLen, paramXfer, selfRef);
}
else
{
return search->second(tag, std::move(localBuf), size, paramXfer);
return search->second(tag, std::move(localBuf), size, paramXfer, selfRef);
}
}
else
@ -54,12 +55,12 @@ CFactoryFnReturn CFactoryMgr::MakeObjectFromMemory(const SObjectTag& tag, std::u
std::make_unique<athena::io::MemoryReader>(localBuf.get(), size);
u32 decompLen = compRead->readUint32Big();
CZipInputStream r(std::move(compRead));
return search->second(tag, r, paramXfer);
return search->second(tag, r, paramXfer, selfRef);
}
else
{
CMemoryInStream r(localBuf.get(), size);
return search->second(tag, r, paramXfer);
return search->second(tag, r, paramXfer, selfRef);
}
}
}

View File

@ -18,12 +18,13 @@ class CFactoryMgr
std::unordered_map<FourCC, FMemFactoryFunc> m_memFactories;
public:
CFactoryFnReturn MakeObject(const SObjectTag& tag, urde::CInputStream& in,
const CVParamTransfer& paramXfer);
const CVParamTransfer& paramXfer, CObjectReference* selfRef);
bool CanMakeMemory(const urde::SObjectTag& tag) const;
CFactoryFnReturn MakeObjectFromMemory(const SObjectTag& tag,
std::unique_ptr<u8[]>&& buf,
int size, bool compressed,
const CVParamTransfer& paramXfer);
const CVParamTransfer& paramXfer,
CObjectReference* selfRef);
void AddFactory(FourCC key, FFactoryFunc func) {m_factories[key] = func;}
void AddFactory(FourCC key, FMemFactoryFunc func) {m_memFactories[key] = func;}
};

View File

@ -74,7 +74,7 @@ class CObjectReference
if (!x10_object && !x3_loading)
{
IFactory& fac = xC_objectStore->GetFactory();
fac.BuildAsync(x4_objTag, x14_params, &x10_object);
fac.BuildAsync(x4_objTag, x14_params, &x10_object, this);
x3_loading = true;
}
}
@ -102,7 +102,7 @@ class CObjectReference
if (!x10_object)
{
IFactory& factory = xC_objectStore->GetFactory();
x10_object = factory.Build(x4_objTag, x14_params).release();
x10_object = factory.Build(x4_objTag, x14_params, this).release();
}
x3_loading = false;
return x10_object;
@ -128,6 +128,7 @@ public:
class CToken
{
friend class CSimplePool;
friend class CModel;
CObjectReference* x0_objRef = nullptr;
bool x4_lockHeld = false;

View File

@ -69,7 +69,8 @@ CAllFormatsAnimSource::CAllFormatsAnimSource(CInputStream& in,
: CAnimFormatUnion(in, store), x74_tag(tag) {}
CFactoryFnReturn AnimSourceFactory(const SObjectTag& tag, CInputStream& in,
const CVParamTransfer& params)
const CVParamTransfer& params,
CObjectReference* selfRef)
{
CSimplePool* sp = static_cast<CSimplePool*>(
static_cast<TObjOwnerParam<IObjectStore*>*>(

View File

@ -47,7 +47,8 @@ public:
const CCharAnimTime& startTime);
};
CFactoryFnReturn AnimSourceFactory(const SObjectTag& tag, CInputStream& in, const CVParamTransfer& params);
CFactoryFnReturn AnimSourceFactory(const SObjectTag& tag, CInputStream& in, const CVParamTransfer& params,
CObjectReference* selfRef);
}

View File

@ -7,7 +7,8 @@ namespace urde
CAnimCharacterSet::CAnimCharacterSet(CInputStream& in)
: x0_version(in.readUint16Big()), x4_characterSet(in), x1c_animationSet(in) {}
CFactoryFnReturn FAnimCharacterSet(const SObjectTag&, CInputStream& in, const CVParamTransfer&)
CFactoryFnReturn FAnimCharacterSet(const SObjectTag&, CInputStream& in, const CVParamTransfer&,
CObjectReference* selfRef)
{
return TToken<CAnimCharacterSet>::GetIObjObjectFor(std::make_unique<CAnimCharacterSet>(in));
}

View File

@ -19,7 +19,8 @@ public:
const CAnimationSet& GetAnimationSet() const {return x1c_animationSet;}
};
CFactoryFnReturn FAnimCharacterSet(const SObjectTag&, CInputStream&, const CVParamTransfer&);
CFactoryFnReturn FAnimCharacterSet(const SObjectTag&, CInputStream&, const CVParamTransfer&,
CObjectReference* selfRef);
}

View File

@ -32,7 +32,8 @@ CAnimPOIData::CAnimPOIData(CInputStream& in)
}
CFactoryFnReturn AnimPOIDataFactory(const SObjectTag& tag, CInputStream& in,
const CVParamTransfer& parms)
const CVParamTransfer& parms,
CObjectReference* selfRef)
{
return TToken<CAnimPOIData>::GetIObjObjectFor(std::make_unique<CAnimPOIData>(in));
}

View File

@ -27,7 +27,8 @@ public:
};
CFactoryFnReturn AnimPOIDataFactory(const SObjectTag& tag, CInputStream& in,
const CVParamTransfer& parms);
const CVParamTransfer& parms,
CObjectReference* selfRef);
}

View File

@ -9,7 +9,8 @@ namespace urde
{
CFactoryFnReturn CCharacterFactoryBuilder::CDummyFactory::Build(const SObjectTag& tag,
const CVParamTransfer&)
const CVParamTransfer&,
CObjectReference* selfRef)
{
TLockedToken<CAnimCharacterSet> ancs =
g_SimplePool->GetObj({SBIG('ANCS'), tag.id});
@ -19,9 +20,10 @@ CFactoryFnReturn CCharacterFactoryBuilder::CDummyFactory::Build(const SObjectTag
void CCharacterFactoryBuilder::CDummyFactory::BuildAsync(const SObjectTag& tag,
const CVParamTransfer& parms,
IObj** objOut)
IObj** objOut,
CObjectReference* selfRef)
{
*objOut = Build(tag, parms).release();
*objOut = Build(tag, parms, selfRef).release();
}
void CCharacterFactoryBuilder::CDummyFactory::CancelBuild(const SObjectTag&)

View File

@ -17,8 +17,8 @@ public:
class CDummyFactory : public IFactory
{
public:
CFactoryFnReturn Build(const SObjectTag&, const CVParamTransfer&);
void BuildAsync(const SObjectTag&, const CVParamTransfer&, IObj**);
CFactoryFnReturn Build(const SObjectTag&, const CVParamTransfer&, CObjectReference* selfRef);
void BuildAsync(const SObjectTag&, const CVParamTransfer&, IObj**, CObjectReference* selfRef);
void CancelBuild(const SObjectTag&);
bool CanBuild(const SObjectTag&);
const SObjectTag* GetResourceIdByName(const char*) const;

View File

@ -50,7 +50,8 @@ CCharLayoutInfo::CCharLayoutInfo(CInputStream& in)
}
}
CFactoryFnReturn FCharLayoutInfo(const SObjectTag&, CInputStream& in, const CVParamTransfer&)
CFactoryFnReturn FCharLayoutInfo(const SObjectTag&, CInputStream& in, const CVParamTransfer&,
CObjectReference* selfRef)
{
return TToken<CCharLayoutInfo>::GetIObjObjectFor(std::make_unique<CCharLayoutInfo>(in));
}

View File

@ -39,7 +39,8 @@ public:
zeus::CVector3f GetFromParentUnrotated(const CSegId& id) const;
};
CFactoryFnReturn FCharLayoutInfo(const SObjectTag&, CInputStream&, const CVParamTransfer&);
CFactoryFnReturn FCharLayoutInfo(const SObjectTag&, CInputStream&, const CVParamTransfer&,
CObjectReference* selfRef);
}

View File

@ -18,7 +18,8 @@ namespace urde
{
CFactoryFnReturn CCharacterFactory::CDummyFactory::Build(const SObjectTag& tag,
const CVParamTransfer& params)
const CVParamTransfer& params,
CObjectReference* selfRef)
{
const CCharacterInfo& charInfo =
@ -49,9 +50,10 @@ CFactoryFnReturn CCharacterFactory::CDummyFactory::Build(const SObjectTag& tag,
void CCharacterFactory::CDummyFactory::BuildAsync(const SObjectTag& tag,
const CVParamTransfer& parms,
IObj** objOut)
IObj** objOut,
CObjectReference* selfRef)
{
*objOut = Build(tag, parms).release();
*objOut = Build(tag, parms, selfRef).release();
}
void CCharacterFactory::CDummyFactory::CancelBuild(const SObjectTag&)

View File

@ -26,8 +26,8 @@ public:
class CDummyFactory : public IFactory
{
public:
CFactoryFnReturn Build(const SObjectTag&, const CVParamTransfer&);
void BuildAsync(const SObjectTag&, const CVParamTransfer&, IObj**);
CFactoryFnReturn Build(const SObjectTag&, const CVParamTransfer&, CObjectReference* selfRef);
void BuildAsync(const SObjectTag&, const CVParamTransfer&, IObj**, CObjectReference* selfRef);
void CancelBuild(const SObjectTag&);
bool CanBuild(const SObjectTag&);
const SObjectTag* GetResourceIdByName(const char*) const;

View File

@ -29,6 +29,7 @@ CModelData::CModelData(const CStaticRes& res)
x1c_normalModel = g_SimplePool->GetObj({SBIG('CMDL'), res.GetId()});
if (!x1c_normalModel)
Log.report(logvisor::Fatal, "unable to find CMDL %08X", res.GetId());
m_normalModelInst = x1c_normalModel->MakeNewInstance(0);
}
CModelData::CModelData(const CAnimRes& res)
@ -82,20 +83,20 @@ CSkinnedModel& CModelData::PickAnimatedModel(EWhichModel which) const
return *x10_animData->xd8_modelData.GetObj();
}
TLockedToken<CModel>& CModelData::PickStaticModel(EWhichModel which)
std::unique_ptr<CBooModel>& CModelData::PickStaticModel(EWhichModel which)
{
TLockedToken<CModel>* ret = nullptr;
std::unique_ptr<CBooModel>* ret = nullptr;
switch (which)
{
case EWhichModel::XRay:
ret = &x2c_xrayModel;
ret = &m_xrayModelInst;
case EWhichModel::Thermal:
ret = &x3c_infraModel;
ret = &m_infraModelInst;
default: break;
}
if (ret)
return *ret;
return x1c_normalModel;
return m_normalModelInst;
}
void CModelData::SetXRayModel(const std::pair<ResId, ResId>& modelSkin)
@ -113,6 +114,9 @@ void CModelData::SetXRayModel(const std::pair<ResId, ResId>& modelSkin)
else
{
x2c_xrayModel = g_SimplePool->GetObj({SBIG('CMDL'), modelSkin.first});
if (!x2c_xrayModel)
Log.report(logvisor::Fatal, "unable to find CMDL %08X", modelSkin.first);
m_xrayModelInst = x2c_xrayModel->MakeNewInstance(0);
}
}
}
@ -133,6 +137,9 @@ void CModelData::SetInfraModel(const std::pair<ResId, ResId>& modelSkin)
else
{
x3c_infraModel = g_SimplePool->GetObj({SBIG('CMDL'), modelSkin.first});
if (!x3c_infraModel)
Log.report(logvisor::Fatal, "unable to find CMDL %08X", modelSkin.first);
m_infraModelInst = x3c_infraModel->MakeNewInstance(0);
}
}
}
@ -143,12 +150,12 @@ bool CModelData::IsDefinitelyOpaque(EWhichModel which)
if (x10_animData)
{
CSkinnedModel& model = PickAnimatedModel(which);
return model.GetModel()->GetInstance().IsOpaque();
return model.GetModelInst()->IsOpaque();
}
else
{
TLockedToken<CModel>& model = PickStaticModel(which);
return model->GetInstance().IsOpaque();
std::unique_ptr<CBooModel>& model = PickStaticModel(which);
return model->IsOpaque();
}
}
@ -301,8 +308,8 @@ void CModelData::RenderThermal(const zeus::CTransform& xf,
}
else
{
TLockedToken<CModel>& model = PickStaticModel(EWhichModel::Thermal);
model->Draw(drawFlags);
std::unique_ptr<CBooModel>& model = PickStaticModel(EWhichModel::Thermal);
model->Draw(drawFlags, nullptr, nullptr);
}
}
@ -318,13 +325,13 @@ void CModelData::RenderUnsortedParts(EWhichModel which, const zeus::CTransform&
CGraphics::SetModelMatrix(xf * zeus::CTransform::Scale(x0_particleScale));
TLockedToken<CModel>& model = PickStaticModel(which);
std::unique_ptr<CBooModel>& model = PickStaticModel(which);
if (lights)
lights->ActivateLights(model->GetInstance());
lights->ActivateLights(*model);
else
model->GetInstance().ActivateLights({});
model->ActivateLights({});
model->DrawUnsortedParts(drawFlags);
model->DrawNormal(drawFlags, nullptr, nullptr);
// Set ambient to white
CGraphics::DisableAllLights();
const_cast<CModelData*>(this)->x14_24_renderSorted = true;
@ -346,24 +353,24 @@ void CModelData::Render(EWhichModel which, const zeus::CTransform& xf,
{
CSkinnedModel& model = PickAnimatedModel(which);
if (lights)
lights->ActivateLights(model.GetModel()->GetInstance());
lights->ActivateLights(*model.GetModelInst());
else
model.GetModel()->GetInstance().ActivateLights({});
model.GetModelInst()->ActivateLights({});
x10_animData->Render(model, drawFlags, {}, nullptr);
}
else
{
TLockedToken<CModel>& model = PickStaticModel(which);
std::unique_ptr<CBooModel>& model = PickStaticModel(which);
if (lights)
lights->ActivateLights(model->GetInstance());
lights->ActivateLights(*model);
else
model->GetInstance().ActivateLights({});
model->ActivateLights({});
if (x14_24_renderSorted)
model->DrawSortedParts(drawFlags);
model->DrawAlpha(drawFlags, nullptr, nullptr);
else
model->Draw(drawFlags);
model->Draw(drawFlags, nullptr, nullptr);
}
// Set ambient to white

View File

@ -7,6 +7,7 @@
#include "RetroTypes.hpp"
#include "CToken.hpp"
#include "CAnimData.hpp"
#include "Graphics/CModel.hpp"
namespace urde
{
@ -78,10 +79,15 @@ class CModelData
u32 _flags = 0;
};
zeus::CColor x18_ambientColor;
TLockedToken<CModel> x1c_normalModel;
TLockedToken<CModel> x2c_xrayModel;
TLockedToken<CModel> x3c_infraModel;
std::unique_ptr<CBooModel> m_normalModelInst;
std::unique_ptr<CBooModel> m_xrayModelInst;
std::unique_ptr<CBooModel> m_infraModelInst;
public:
enum class EWhichModel
{
@ -105,7 +111,7 @@ public:
const CActorLights* lights, const CModelFlags& drawFlags);
EWhichModel GetRenderingModel(const CStateManager& stateMgr) const;
CSkinnedModel& PickAnimatedModel(EWhichModel which) const;
TLockedToken<CModel>& PickStaticModel(EWhichModel which);
std::unique_ptr<CBooModel>& PickStaticModel(EWhichModel which);
void SetXRayModel(const std::pair<ResId, ResId>& modelSkin);
void SetInfraModel(const std::pair<ResId, ResId>& modelSkin);
bool IsDefinitelyOpaque(EWhichModel);

View File

@ -12,7 +12,8 @@ CSkinRules::CSkinRules(CInputStream& in)
x0_skinBanks.emplace_back(in);
}
CFactoryFnReturn FSkinRulesFactory(const SObjectTag& tag, CInputStream& in, const CVParamTransfer& params)
CFactoryFnReturn FSkinRulesFactory(const SObjectTag& tag, CInputStream& in, const CVParamTransfer& params,
CObjectReference* selfRef)
{
return TToken<CSkinRules>::GetIObjObjectFor(std::make_unique<CSkinRules>(in));
}

View File

@ -22,7 +22,8 @@ public:
}
};
CFactoryFnReturn FSkinRulesFactory(const SObjectTag& tag, CInputStream& in, const CVParamTransfer& params);
CFactoryFnReturn FSkinRulesFactory(const SObjectTag& tag, CInputStream& in, const CVParamTransfer& params,
CObjectReference* selfRef);
}

View File

@ -65,7 +65,8 @@ void CCollidableOBBTreeGroup::SetStaticTableIndex(u32 index)
}
CFactoryFnReturn FCollidableOBBTreeGroupFactory(const SObjectTag &tag, CInputStream& in,
const CVParamTransfer &vparms)
const CVParamTransfer& vparms,
CObjectReference* selfRef)
{
return TToken<CCollidableOBBTreeGroup>::GetIObjObjectFor(std::make_unique<CCollidableOBBTreeGroup>(in));
}

View File

@ -31,7 +31,8 @@ public:
};
CFactoryFnReturn FCollidableOBBTreeGroupFactory(const SObjectTag &tag, CInputStream& in,
const CVParamTransfer &vparms);
const CVParamTransfer& vparms,
CObjectReference* selfRef);
}

View File

@ -19,6 +19,7 @@ class CTexture;
class CLight;
class CSkinRules;
class CPoseAsTransforms;
class CModel;
struct CModelFlags
{
@ -73,19 +74,23 @@ public:
std::vector<TCachedToken<CTexture>> x0_textures;
std::vector<std::vector<boo::IShaderPipeline*>> m_shaders;
MaterialSet m_matSet;
int m_matSetIdx;
SShader(int idx) : m_matSetIdx(idx) {}
void UnlockTextures();
};
private:
TLockedToken<CModel> m_model;
std::vector<CBooSurface>* x0_surfaces;
const MaterialSet* x4_matSet;
int m_matSetIdx = -1;
const std::vector<std::vector<boo::IShaderPipeline*>>* m_pipelines;
boo::IVertexFormat* m_vtxFmt;
boo::IGraphicsBufferS* x8_vbo;
boo::IGraphicsBufferS* xc_ibo;
size_t m_weightVecCount;
size_t m_skinBankCount;
std::vector<TCachedToken<CTexture>>* x1c_textures;
std::vector<TCachedToken<CTexture>> x1c_textures;
zeus::CAABox x20_aabb;
CBooSurface* x38_firstUnsortedSurface = nullptr;
CBooSurface* x3c_firstSortedSurface = nullptr;
@ -114,8 +119,10 @@ private:
void DrawSurfaces(const CModelFlags& flags) const;
void DrawSurface(const CBooSurface& surf, const CModelFlags& flags) const;
void VerifyCurrentShader(int shaderIdx);
public:
CBooModel(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,
size_t weightVecCount, size_t skinBankCount, const zeus::CAABox& aabb);
@ -128,6 +135,7 @@ public:
void RemapMaterialData(SShader& shader);
bool TryLockTextures() const;
void UnlockTextures() const;
void Touch(int shaderIdx) const;
void UpdateUniformData(const CModelFlags& flags,
const CSkinRules* cskr,
const CPoseAsTransforms* pose) const;
@ -152,8 +160,10 @@ public:
class CModel
{
friend class CBooModel;
//std::unique_ptr<u8[]> x0_data;
//u32 x4_dataLen;
TToken<CModel> m_selfToken; /* DO NOT LOCK! */
zeus::CAABox m_aabb;
std::vector<CBooSurface> x8_surfaces;
std::vector<CBooModel::SShader> x18_matSets;
@ -167,16 +177,13 @@ class CModel
boo::IGraphicsBufferS* m_ibo;
boo::IVertexFormat* m_vtxFmt;
void VerifyCurrentShader(int shaderIdx) const;
public:
using MaterialSet = DataSpec::DNAMP1::HMDLMaterialSet;
CModel(std::unique_ptr<u8[]>&& in, u32 dataLen, IObjectStore* store);
CModel(std::unique_ptr<u8[]>&& in, u32 dataLen, IObjectStore* store, CObjectReference* selfRef);
void DrawSortedParts(const CModelFlags& flags) const;
void DrawUnsortedParts(const CModelFlags& flags) const;
void Draw(const CModelFlags& flags) const;
void Touch(int shaderIdx) const;
bool IsLoaded(int shaderIdx) const;
const zeus::CAABox& GetAABB() const {return m_aabb;}
@ -187,7 +194,8 @@ public:
CFactoryFnReturn FModelFactory(const urde::SObjectTag& tag,
std::unique_ptr<u8[]>&& in, u32 len,
const urde::CVParamTransfer& vparms);
const urde::CVParamTransfer& vparms,
CObjectReference* selfRef);
}

View File

@ -16,12 +16,12 @@ namespace urde
static logvisor::Module Log("urde::CBooModel");
bool CBooModel::g_DrawingOccluders = false;
CBooModel::CBooModel(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,
size_t weightVecCount, size_t skinBankCount, const zeus::CAABox& aabb)
: x0_surfaces(surfaces), x4_matSet(&shader.m_matSet), m_pipelines(&shader.m_shaders),
m_vtxFmt(vtxFmt), x8_vbo(vbo), xc_ibo(ibo), m_weightVecCount(weightVecCount),
m_skinBankCount(skinBankCount), x1c_textures(&shader.x0_textures), x20_aabb(aabb),
: m_model(token), x0_surfaces(surfaces), x4_matSet(&shader.m_matSet), m_matSetIdx(shader.m_matSetIdx),
m_pipelines(&shader.m_shaders), m_vtxFmt(vtxFmt), x8_vbo(vbo), xc_ibo(ibo), m_weightVecCount(weightVecCount),
m_skinBankCount(skinBankCount), x1c_textures(shader.x0_textures), x20_aabb(aabb),
x40_24_texturesLoaded(false), x40_25_modelVisible(0)
{
for (CBooSurface& surf : *x0_surfaces)
@ -131,7 +131,7 @@ void CBooModel::BuildGfxToken()
texs.reserve(8);
for (atUint32 idx : mat.textureIdxs)
{
TCachedToken<CTexture>& tex = (*x1c_textures)[idx];
TCachedToken<CTexture>& tex = x1c_textures[idx];
texs.push_back(tex.GetObj()->GetBooTexture());
}
texs.resize(8);
@ -235,7 +235,8 @@ void CBooModel::ActivateLights(const std::vector<CLight>& lights)
void CBooModel::RemapMaterialData(SShader& shader)
{
x4_matSet = &shader.m_matSet;
x1c_textures = &shader.x0_textures;
m_matSetIdx = shader.m_matSetIdx;
x1c_textures = shader.x0_textures;
m_pipelines = &shader.m_shaders;
x40_24_texturesLoaded = false;
m_gfxToken.doDestroy();
@ -246,7 +247,7 @@ bool CBooModel::TryLockTextures() const
if (!x40_24_texturesLoaded)
{
bool allLoad = true;
for (TCachedToken<CTexture>& tex : *x1c_textures)
for (TCachedToken<CTexture>& tex : const_cast<std::vector<TCachedToken<CTexture>>&>(x1c_textures))
{
tex.Lock();
if (!tex.IsLoaded())
@ -263,7 +264,7 @@ bool CBooModel::TryLockTextures() const
void CBooModel::UnlockTextures() const
{
for (TCachedToken<CTexture>& tex : *x1c_textures)
for (TCachedToken<CTexture>& tex : const_cast<std::vector<TCachedToken<CTexture>>&>(x1c_textures))
tex.Unlock();
const_cast<CBooModel*>(this)->x40_24_texturesLoaded = false;
}
@ -615,11 +616,12 @@ std::unique_ptr<CBooModel> CModel::MakeNewInstance(int shaderIdx)
{
if (shaderIdx >= x18_matSets.size())
shaderIdx = 0;
return std::make_unique<CBooModel>(&x8_surfaces, x18_matSets[shaderIdx],
return std::make_unique<CBooModel>(m_selfToken, &x8_surfaces, x18_matSets[shaderIdx],
m_vtxFmt, m_vbo, m_ibo, 0, 0, m_aabb);
}
CModel::CModel(std::unique_ptr<u8[]>&& in, u32 /* dataLen */, IObjectStore* store)
CModel::CModel(std::unique_ptr<u8[]>&& in, u32 /* dataLen */, IObjectStore* store, CObjectReference* selfRef)
: m_selfToken(selfRef)
{
std::unique_ptr<u8[]> data = std::move(in);
@ -637,7 +639,7 @@ CModel::CModel(std::unique_ptr<u8[]>&& in, u32 /* dataLen */, IObjectStore* stor
{
u32 matSetSz = hecl::SBig(*secSizeCur);
const u8* sec = MemoryFromPartData(dataCur, secSizeCur);
x18_matSets.emplace_back();
x18_matSets.emplace_back(i);
CBooModel::SShader& shader = x18_matSets.back();
athena::io::MemoryReader r(sec, matSetSz);
shader.m_matSet.read(r);
@ -703,44 +705,42 @@ void CBooModel::SShader::UnlockTextures()
tex.Unlock();
}
void CModel::VerifyCurrentShader(int shaderIdx) const
void CBooModel::VerifyCurrentShader(int shaderIdx)
{
int idx = 0;
for (const CBooModel::SShader& shader : x18_matSets)
if (idx++ != shaderIdx)
((CBooModel::SShader&)shader).UnlockTextures();
if (shaderIdx != m_matSetIdx)
RemapMaterialData(m_model->x18_matSets[shaderIdx]);
}
void CBooModel::Touch(int shaderIdx) const
{
const_cast<CBooModel*>(this)->VerifyCurrentShader(shaderIdx);
TryLockTextures();
}
void CModel::DrawSortedParts(const CModelFlags& flags) const
{
VerifyCurrentShader(flags.m_matSetIdx);
const_cast<CBooModel&>(*x28_modelInst).VerifyCurrentShader(flags.m_matSetIdx);
x28_modelInst->DrawAlpha(flags, nullptr, nullptr);
}
void CModel::DrawUnsortedParts(const CModelFlags& flags) const
{
VerifyCurrentShader(flags.m_matSetIdx);
const_cast<CBooModel&>(*x28_modelInst).VerifyCurrentShader(flags.m_matSetIdx);
x28_modelInst->DrawNormal(flags, nullptr, nullptr);
}
void CModel::Draw(const CModelFlags& flags) const
{
VerifyCurrentShader(flags.m_matSetIdx);
const_cast<CBooModel&>(*x28_modelInst).VerifyCurrentShader(flags.m_matSetIdx);
x28_modelInst->Draw(flags, nullptr, nullptr);
}
void CModel::Touch(int shaderIdx) const
{
VerifyCurrentShader(shaderIdx);
x28_modelInst->TryLockTextures();
}
bool CModel::IsLoaded(int shaderIdx) const
{
VerifyCurrentShader(shaderIdx);
std::vector<TCachedToken<CTexture>>* texs = x28_modelInst->x1c_textures;
const_cast<CBooModel&>(*x28_modelInst).VerifyCurrentShader(shaderIdx);
std::vector<TCachedToken<CTexture>>& texs = x28_modelInst->x1c_textures;
bool loaded = true;
for (TCachedToken<CTexture>& tex : *texs)
for (TCachedToken<CTexture>& tex : texs)
{
if (!tex.IsLoaded())
{
@ -753,10 +753,11 @@ bool CModel::IsLoaded(int shaderIdx) const
CFactoryFnReturn FModelFactory(const urde::SObjectTag& tag,
std::unique_ptr<u8[]>&& in, u32 len,
const urde::CVParamTransfer& vparms)
const urde::CVParamTransfer& vparms,
CObjectReference* selfRef)
{
IObjectStore* store = static_cast<TObjOwnerParam<IObjectStore*>*>(vparms.GetObj())->GetParam();
CFactoryFnReturn ret = TToken<CModel>::GetIObjObjectFor(std::make_unique<CModel>(std::move(in), len, store));
CFactoryFnReturn ret = TToken<CModel>::GetIObjObjectFor(std::make_unique<CModel>(std::move(in), len, store, selfRef));
return ret;
}

View File

@ -35,6 +35,7 @@ public:
ResId layoutInfo, int shaderIdx);
TLockedToken<CModel>& GetModel() {return x4_model;}
std::unique_ptr<CBooModel>& GetModelInst() {return m_modelInst;}
TLockedToken<CSkinRules>& GetSkinRules() {return x10_skinRules;}
TLockedToken<CCharLayoutInfo>& GetLayoutInfo() {return x1c_layoutInfo;}

View File

@ -59,7 +59,8 @@ public:
CFactoryFnReturn FTextureFactory(const urde::SObjectTag& tag,
std::unique_ptr<u8[]>&& in, u32 len,
const urde::CVParamTransfer& vparms);
const urde::CVParamTransfer& vparms,
CObjectReference* selfRef);
}

View File

@ -739,7 +739,8 @@ void CTexture::Load(int slot, EClampMode clamp) const
CFactoryFnReturn FTextureFactory(const urde::SObjectTag& tag,
std::unique_ptr<u8[]>&& in, u32 len,
const urde::CVParamTransfer& vparms)
const urde::CVParamTransfer& vparms,
CObjectReference* selfRef)
{
return TToken<CTexture>::GetIObjObjectFor(std::make_unique<CTexture>(std::move(in), len));
}

View File

@ -634,7 +634,8 @@ CGuiFrame* CGuiFrame::CreateFrame(ResId frmeId, CGuiSys& sys, CInputStream& in)
}
std::unique_ptr<IObj> RGuiFrameFactoryInGame(const SObjectTag& tag, CInputStream& in,
const CVParamTransfer&)
const CVParamTransfer&,
CObjectReference* selfRef)
{
std::unique_ptr<CGuiFrame> frame(CGuiFrame::CreateFrame(tag.id, *g_GuiSys, in));
return TToken<CGuiFrame>::GetIObjObjectFor(std::move(frame));

View File

@ -18,6 +18,7 @@ class CGuiHeadWidget;
class CFinalInput;
class CGuiLight;
class CVParamTransfer;
class CObjectReference;
enum class EFrameTransitionOptions
{
@ -134,7 +135,8 @@ public:
};
std::unique_ptr<IObj> RGuiFrameFactoryInGame(const SObjectTag& tag, CInputStream& in,
const CVParamTransfer& vparms);
const CVParamTransfer& vparms,
CObjectReference* selfRef);
}

View File

@ -31,7 +31,7 @@ bool CGuiModel::GetIsFinishedLoadingWidgetSpecific() const
const CModel* model = xf8_model.GetObj();
if (!model)
return false;
model->Touch(0);
model->GetInstance().Touch(0);
return model->IsLoaded(0);
}
@ -39,7 +39,7 @@ void CGuiModel::Touch() const
{
const CModel* model = xf8_model.GetObj();
if (model)
model->Touch(0);
model->GetInstance().Touch(0);
}
void CGuiModel::Draw(const CGuiWidgetDrawParms& parms) const

View File

@ -192,7 +192,8 @@ void CRasterFont::GetSize(const CDrawStringOptions& opts, int& width, int& heigh
}
}
std::unique_ptr<IObj> FRasterFontFactory(const SObjectTag& tag, CInputStream& in, const CVParamTransfer& vparms)
std::unique_ptr<IObj> FRasterFontFactory(const SObjectTag& tag, CInputStream& in, const CVParamTransfer& vparms,
CObjectReference* selfRef)
{
return TToken<CRasterFont>::GetIObjObjectFor(
std::make_unique<CRasterFont>(in, *static_cast<TObjOwnerParam<IObjectStore*>*>(vparms.GetObj())->GetParam()));

View File

@ -149,7 +149,8 @@ public:
TToken<CTexture>& GetTexture() { return x80_texture; }
};
std::unique_ptr<IObj> FRasterFontFactory(const SObjectTag& tag, CInputStream& in, const CVParamTransfer& vparms);
std::unique_ptr<IObj> FRasterFontFactory(const SObjectTag& tag, CInputStream& in, const CVParamTransfer& vparms,
CObjectReference* selfRef);
}
#endif // __URDE_CRASTERFONT_HPP__

View File

@ -85,7 +85,8 @@ void CStringTable::SetLanguage(s32 lang)
mCurrentLanguage = skLanguages[lang];
}
CFactoryFnReturn FStringTableFactory(const SObjectTag&, CInputStream& in, const CVParamTransfer&)
CFactoryFnReturn FStringTableFactory(const SObjectTag&, CInputStream& in, const CVParamTransfer&,
CObjectReference* selfRef)
{
return TToken<CStringTable>::GetIObjObjectFor(std::make_unique<CStringTable>(in));
}

View File

@ -21,6 +21,7 @@ public:
static void SetLanguage(s32);
};
CFactoryFnReturn FStringTableFactory(const SObjectTag&, CInputStream&, const CVParamTransfer&);
CFactoryFnReturn FStringTableFactory(const SObjectTag&, CInputStream&, const CVParamTransfer&,
CObjectReference* selfRef);
}
#endif // __URDE_CSTRINGTABLE_HPP__

View File

@ -8,21 +8,24 @@ namespace urde
{
class CVParamTransfer;
class IObj;
class CObjectReference;
using CFactoryFnReturn = std::unique_ptr<IObj>;
using FFactoryFunc = std::function<CFactoryFnReturn(const urde::SObjectTag& tag,
urde::CInputStream& in,
const urde::CVParamTransfer& vparms)>;
const urde::CVParamTransfer& vparms,
CObjectReference* selfRef)>;
using FMemFactoryFunc = std::function<CFactoryFnReturn(const urde::SObjectTag& tag,
std::unique_ptr<u8[]>&& in, u32 len,
const urde::CVParamTransfer& vparms)>;
const urde::CVParamTransfer& vparms,
CObjectReference* selfRef)>;
class IFactory
{
public:
virtual ~IFactory() = default;
virtual CFactoryFnReturn Build(const SObjectTag&, const CVParamTransfer&)=0;
virtual void BuildAsync(const SObjectTag&, const CVParamTransfer&, IObj**)=0;
virtual CFactoryFnReturn Build(const SObjectTag&, const CVParamTransfer&, CObjectReference*)=0;
virtual void BuildAsync(const SObjectTag&, const CVParamTransfer&, IObj**, CObjectReference*)=0;
virtual void CancelBuild(const SObjectTag&)=0;
virtual bool CanBuild(const SObjectTag&)=0;
virtual const SObjectTag* GetResourceIdByName(const char*) const=0;

View File

@ -1157,7 +1157,8 @@ void CParticleDataFactory::LoadGPSMTokens(CGenDescription* desc)
}
CFactoryFnReturn FParticleFactory(const SObjectTag& tag, CInputStream& in,
const CVParamTransfer& vparms)
const CVParamTransfer& vparms,
CObjectReference* selfRef)
{
CSimplePool* sp = static_cast<CSimplePool*>(static_cast<TObjOwnerParam<IObjectStore*>*>(vparms.GetObj())->GetParam());
return TToken<CGenDescription>::GetIObjObjectFor(std::unique_ptr<CGenDescription>(CParticleDataFactory::GetGeneratorDesc(in, sp)));

View File

@ -97,7 +97,8 @@ public:
static CGenDescription* GetGeneratorDesc(CInputStream& in, CSimplePool* resPool);
};
CFactoryFnReturn FParticleFactory(const SObjectTag& tag, CInputStream& in, const CVParamTransfer& vparms);
CFactoryFnReturn FParticleFactory(const SObjectTag& tag, CInputStream& in, const CVParamTransfer& vparms,
CObjectReference* selfRef);
}

View File

@ -413,7 +413,7 @@ bool CWorld::CheckWorldComplete(CStateManager* mgr, TAreaId id, ResId mreaId)
if (!skybox)
return false;
skybox->Touch(0);
skybox->GetInstance().Touch(0);
if (!skybox->IsLoaded(0))
return false;