metaforce/Runtime/Character/CCharacterFactory.cpp

213 lines
8.0 KiB
C++
Raw Normal View History

2016-04-13 06:07:23 +00:00
#include "CCharacterFactory.hpp"
#include "CAnimCharacterSet.hpp"
#include "CSimplePool.hpp"
#include "CTransitionDatabaseGame.hpp"
#include "CAnimationDatabaseGame.hpp"
#include "CAnimationManager.hpp"
#include "CTransitionManager.hpp"
#include "CRandom16.hpp"
#include "CPrimitive.hpp"
2016-04-15 03:02:21 +00:00
#include "CAnimData.hpp"
2016-04-16 03:24:25 +00:00
#include "CAdditiveAnimPlayback.hpp"
2016-04-15 03:02:21 +00:00
#include "GameGlobalObjects.hpp"
#include "CParticleGenInfo.hpp"
2016-04-15 03:02:21 +00:00
#include "Graphics/CSkinnedModel.hpp"
2016-08-23 03:12:50 +00:00
#include "Character/CCharLayoutInfo.hpp"
2016-04-13 06:07:23 +00:00
namespace urde
{
2016-04-15 03:02:21 +00:00
CFactoryFnReturn CCharacterFactory::CDummyFactory::Build(const SObjectTag& tag,
const CVParamTransfer& params,
CObjectReference* selfRef)
2016-04-13 06:07:23 +00:00
{
2016-04-15 03:02:21 +00:00
2016-12-23 06:41:39 +00:00
const CCharacterInfo& charInfo = *params.GetOwnedObj<const CCharacterInfo*>();
2016-04-15 03:02:21 +00:00
2016-09-12 04:53:28 +00:00
switch (tag.type.toUint32() & 0x1)
2016-04-15 03:02:21 +00:00
{
case 0:
return TToken<CSkinnedModel>::GetIObjObjectFor(
std::make_unique<CSkinnedModel>(*g_SimplePool,
charInfo.GetModelId(),
charInfo.GetSkinRulesId(),
charInfo.GetCharLayoutInfoId(),
2016-09-12 04:53:28 +00:00
0, tag.type.toUint32() >> 16));
2016-04-15 03:02:21 +00:00
case 1:
return TToken<CSkinnedModel>::GetIObjObjectFor(
std::make_unique<CMorphableSkinnedModel>(*g_SimplePool,
charInfo.GetIceModelId(),
charInfo.GetIceSkinRulesId(),
charInfo.GetCharLayoutInfoId(),
2016-09-12 04:53:28 +00:00
0, tag.type.toUint32() >> 16));
2016-04-15 03:02:21 +00:00
default:
break;
}
2016-04-13 06:07:23 +00:00
return {};
}
2016-04-15 03:02:21 +00:00
void CCharacterFactory::CDummyFactory::BuildAsync(const SObjectTag& tag,
const CVParamTransfer& parms,
IObj** objOut,
CObjectReference* selfRef)
2016-04-13 06:07:23 +00:00
{
*objOut = Build(tag, parms, selfRef).release();
2016-04-13 06:07:23 +00:00
}
void CCharacterFactory::CDummyFactory::CancelBuild(const SObjectTag&)
{
}
bool CCharacterFactory::CDummyFactory::CanBuild(const SObjectTag&)
{
return true;
}
const SObjectTag* CCharacterFactory::CDummyFactory::GetResourceIdByName(const char*) const
{
return nullptr;
}
2016-04-14 21:42:47 +00:00
FourCC CCharacterFactory::CDummyFactory::GetResourceTypeById(ResId id) const
{
2016-04-15 03:02:21 +00:00
return {};
}
2016-09-25 01:58:20 +00:00
void CCharacterFactory::CDummyFactory::EnumerateResources(
const std::function<bool(const SObjectTag&)>& lambda) const
{
}
void CCharacterFactory::CDummyFactory::EnumerateNamedResources(
const std::function<bool(const std::string&, const SObjectTag&)>& lambda) const
{
}
u32 CCharacterFactory::CDummyFactory::ResourceSize(const urde::SObjectTag& tag)
{
return 0;
}
bool CCharacterFactory::CDummyFactory::LoadResourceAsync(const urde::SObjectTag& tag,
std::unique_ptr<u8[]>& target)
{
return false;
}
bool CCharacterFactory::CDummyFactory::LoadResourcePartAsync(const urde::SObjectTag& tag,
u32 size, u32 off,
std::unique_ptr<u8[]>& target)
{
return false;
}
std::unique_ptr<u8[]> CCharacterFactory::CDummyFactory::LoadResourceSync(const urde::SObjectTag& tag)
{
return {};
}
std::unique_ptr<u8[]> CCharacterFactory::CDummyFactory::LoadResourcePartSync(const urde::SObjectTag& tag,
u32 size, u32 off)
{
return {};
}
2016-04-15 03:02:21 +00:00
std::unique_ptr<CAnimData>
CCharacterFactory::CreateCharacter(int charIdx, bool loop,
const TLockedToken<CCharacterFactory>& factory,
2016-09-12 04:53:28 +00:00
int defaultAnim, int drawInsts) const
2016-04-15 03:02:21 +00:00
{
const CCharacterInfo& charInfo = x4_charInfoDB[charIdx];
CVParamTransfer charParm(new TObjOwnerParam<const CCharacterInfo*>(&charInfo));
TToken<CSkinnedModel> skinnedModel =
2016-09-12 04:53:28 +00:00
const_cast<CCharacterFactory*>(this)->x70_cacheResPool.GetObj
({FourCC(drawInsts << 16), charInfo.GetModelId()}, charParm);
2016-04-15 03:02:21 +00:00
2016-04-29 10:08:46 +00:00
rstl::optional_object<TToken<CMorphableSkinnedModel>> iceModel;
if (charInfo.GetIceModelId() != 0xffffffff &&
charInfo.GetIceSkinRulesId() != 0xffffffff)
2016-09-12 04:53:28 +00:00
iceModel.emplace(const_cast<CCharacterFactory*>(this)->x70_cacheResPool.GetObj
({FourCC((drawInsts << 16) | 1), charInfo.GetIceModelId()}, charParm));
2016-04-15 03:02:21 +00:00
return std::make_unique<CAnimData>(x68_selfId, charInfo, defaultAnim, charIdx, loop,
x14_charLayoutInfoDB[charIdx], skinnedModel,
iceModel, x24_sysContext, x28_animMgr, x2c_transMgr,
2016-09-12 04:53:28 +00:00
factory, drawInsts);
2016-04-14 21:42:47 +00:00
}
2016-04-15 03:02:21 +00:00
ResId CCharacterFactory::GetEventResourceIdForAnimResourceId(ResId id) const
2016-04-13 06:07:23 +00:00
{
2016-04-15 03:02:21 +00:00
auto search = std::find_if(x58_animResources.cbegin(), x58_animResources.cend(),
[&](const std::pair<ResId, ResId>& elem) -> bool
{
return id == elem.first;
});
if (search == x58_animResources.cend())
return -1;
return search->second;
2016-04-13 06:07:23 +00:00
}
2017-03-01 06:02:54 +00:00
const CAdditiveAnimationInfo& CCharacterFactory::FindAdditiveInfo(u32 idx) const
{
auto search = std::lower_bound(x40_additiveInfo.cbegin(), x40_additiveInfo.cend(), idx,
[](const auto& anim, u32 test) -> bool { return anim.first < test; });
if (search == x40_additiveInfo.cend() || idx != search->first)
return x50_defaultAdditiveInfo;
return search->second;
}
2016-04-13 06:07:23 +00:00
std::vector<CCharacterInfo>
CCharacterFactory::GetCharacterInfoDB(const CAnimCharacterSet& ancs)
{
std::vector<CCharacterInfo> ret;
const std::map<u32, CCharacterInfo>& charInfoMap = ancs.GetCharacterSet().GetCharacterInfoMap();
ret.reserve(charInfoMap.size());
for (const auto& charInfo : charInfoMap)
ret.push_back(charInfo.second);
return ret;
}
std::vector<TLockedToken<CCharLayoutInfo>>
CCharacterFactory::GetCharLayoutInfoDB(CSimplePool& store,
const std::vector<CCharacterInfo>& chars)
{
std::vector<TLockedToken<CCharLayoutInfo>> ret;
ret.reserve(chars.size());
for (const CCharacterInfo& charInfo : chars)
ret.push_back(store.GetObj({SBIG('CINF'), charInfo.GetCharLayoutInfoId()}));
return ret;
}
CCharacterFactory::CCharacterFactory(CSimplePool& store,
const CAnimCharacterSet& ancs,
2016-04-14 21:42:47 +00:00
ResId selfId)
2016-04-13 06:07:23 +00:00
: x4_charInfoDB(GetCharacterInfoDB(ancs)),
x14_charLayoutInfoDB(GetCharLayoutInfoDB(store, x4_charInfoDB)),
x24_sysContext(std::make_shared<CAnimSysContext>(
TToken<CTransitionDatabaseGame>(
std::make_unique<CTransitionDatabaseGame>(ancs.GetAnimationSet().GetTransitions(),
ancs.GetAnimationSet().GetHalfTransitions(),
ancs.GetAnimationSet().GetDefaultTransition())),
2334, store)),
x28_animMgr(std::make_shared<CAnimationManager>(
TToken<CAnimationDatabaseGame>(
std::make_unique<CAnimationDatabaseGame>(
ancs.GetAnimationSet().GetAnimations())), *x24_sysContext)),
x2c_transMgr(std::make_shared<CTransitionManager>(*x24_sysContext)),
x40_additiveInfo(ancs.GetAnimationSet().GetAdditiveInfo()),
x50_defaultAdditiveInfo(ancs.GetAnimationSet().GetDefaultAdditiveInfo()),
x58_animResources(ancs.GetAnimationSet().GetAnimResIds()),
x68_selfId(selfId),
x70_cacheResPool(x6c_dummyFactory)
{
std::vector<CPrimitive> primitives;
x28_animMgr->GetAnimationDatabase()->GetAllUniquePrimitives(primitives);
x30_animSourceDB.reserve(primitives.size());
for (const CPrimitive& prim : primitives)
x30_animSourceDB.push_back(store.GetObj({SBIG('ANIM'), prim.GetAnimResId()}));
}
}