Several initial character classes

This commit is contained in:
Jack Andersen 2016-04-09 18:49:02 -10:00
parent ac0d2d8828
commit 4f7d6e167f
30 changed files with 788 additions and 210 deletions

View File

@ -1,13 +1,14 @@
#include "DNACommon.hpp"
#include "PAK.hpp"
#include "boo/ThreadLocalPtr.hpp"
namespace DataSpec
{
logvisor::Module LogDNACommon("urde::DNACommon");
SpecBase* g_curSpec = nullptr;
PAKRouterBase* g_PakRouter = nullptr;
hecl::Database::Project* UniqueIDBridge::s_Project = nullptr;
ThreadLocalPtr<SpecBase> g_curSpec;
ThreadLocalPtr<PAKRouterBase> g_PakRouter;
ThreadLocalPtr<hecl::Database::Project> UniqueIDBridge::s_Project;
UniqueID32 UniqueID32::kInvalidId;
}

View File

@ -7,13 +7,14 @@
#include "hecl/hecl.hpp"
#include "hecl/Database.hpp"
#include "../SpecBase.hpp"
#include "boo/ThreadLocalPtr.hpp"
namespace DataSpec
{
extern logvisor::Module LogDNACommon;
extern SpecBase* g_curSpec;
extern class PAKRouterBase* g_PakRouter;
extern ThreadLocalPtr<SpecBase> g_curSpec;
extern ThreadLocalPtr<class PAKRouterBase> g_PakRouter;
/* This comes up a great deal */
typedef athena::io::DNA<athena::BigEndian> BigDNA;
@ -84,22 +85,24 @@ class UniqueIDBridge
friend class UniqueID32;
friend class UniqueID64;
static hecl::Database::Project* s_Project;
static ThreadLocalPtr<hecl::Database::Project> s_Project;
public:
template <class IDType>
static hecl::ProjectPath TranslatePakIdToPath(const IDType& id, bool silenceWarnings=false)
{
if (!g_PakRouter)
PAKRouterBase* pakRouter = g_PakRouter.get();
if (!pakRouter)
LogDNACommon.report(logvisor::Fatal,
"g_Project must be set to non-null before calling UniqueIDBridge::TranslatePakIdToPath");
return g_PakRouter->getWorking(id, silenceWarnings);
return pakRouter->getWorking(id, silenceWarnings);
}
static hecl::ProjectPath MakePathFromString(const std::string& str)
{
if (!s_Project)
hecl::Database::Project* project = s_Project.get();
if (!project)
LogDNACommon.report(logvisor::Fatal,
"UniqueIDBridge::setGlobalProject must be called before MakePathFromString");
return hecl::ProjectPath(*s_Project, str);
return hecl::ProjectPath(*project, str);
}
template <class IDType>
static void TransformOldHashToNewHash(IDType& id)
@ -109,7 +112,7 @@ public:
static void setGlobalProject(hecl::Database::Project& project)
{
s_Project = &project;
s_Project.reset(&project);
}
};

View File

@ -224,7 +224,7 @@ void PAKRouter<BRIDGETYPE>::build(std::vector<BRIDGETYPE>& bridges, std::functio
template <class BRIDGETYPE>
void PAKRouter<BRIDGETYPE>::enterPAKBridge(const BRIDGETYPE& pakBridge)
{
g_PakRouter = this;
g_PakRouter.reset(this);
auto pit = m_bridgePaths.begin();
size_t bridgeIdx = 0;
for (const BRIDGETYPE& bridge : *m_bridges)

View File

@ -2,6 +2,8 @@
namespace DataSpec
{
extern hecl::Database::DataSpecEntry SpecEntMP1PC;
namespace DNAMP1
{
@ -1005,6 +1007,255 @@ const char* ANCS::AnimationSet::DNAType()
return "urde::DNAMP1::ANCS::AnimationSet";
}
bool ANCS::Extract(const SpecBase& dataSpec,
PAKEntryReadStream& rs,
const hecl::ProjectPath& outPath,
PAKRouter<PAKBridge>& pakRouter,
const PAK::Entry& entry,
bool force,
hecl::BlenderToken& btok,
std::function<void(const hecl::SystemChar*)> fileChanged)
{
hecl::ProjectPath yamlPath = outPath.getWithExtension(_S(".yaml"));
hecl::ProjectPath::Type yamlType = yamlPath.getPathType();
hecl::ProjectPath blendPath = outPath.getWithExtension(_S(".blend"));
hecl::ProjectPath::Type blendType = blendPath.getPathType();
ANCS ancs;
ancs.read(rs);
if (force ||
yamlType == hecl::ProjectPath::Type::None ||
blendType == hecl::ProjectPath::Type::None)
{
if (force || yamlType == hecl::ProjectPath::Type::None)
{
FILE* fp = hecl::Fopen(yamlPath.getAbsolutePath().c_str(), _S("w"));
ancs.toYAMLFile(fp);
fclose(fp);
}
if (force || blendType == hecl::ProjectPath::Type::None)
{
hecl::BlenderConnection& conn = btok.getBlenderConnection();
DNAANCS::ReadANCSToBlender<PAKRouter<PAKBridge>, ANCS, MaterialSet, DNACMDL::SurfaceHeader_1, 2>
(conn, ancs, blendPath, pakRouter, entry, dataSpec, fileChanged, force);
}
}
/* Extract EVNTs */
std::map<atUint32, DNAANCS::AnimationResInfo<UniqueID32>> animRes;
ancs.getAnimationResInfo(animRes);
for (const auto& res : animRes)
{
if (res.second.evntId)
{
hecl::SystemStringView sysStr(res.second.name);
hecl::ProjectPath evntYamlPath = outPath.getWithExtension((hecl::SystemString(_S(".")) +
sysStr.sys_str() +
_S(".evnt.yaml")).c_str());
hecl::ProjectPath::Type evntYamlType = evntYamlPath.getPathType();
if (force || evntYamlType == hecl::ProjectPath::Type::None)
{
EVNT evnt;
if (pakRouter.lookupAndReadDNA(res.second.evntId, evnt, true))
{
FILE* fp = hecl::Fopen(evntYamlPath.getAbsolutePath().c_str(), _S("w"));
evnt.toYAMLFile(fp);
fclose(fp);
}
}
}
}
return true;
}
bool ANCS::Cook(const hecl::ProjectPath& outPath,
const hecl::ProjectPath& inPath,
const DNAANCS::Actor& actor,
const std::function<bool(const hecl::ProjectPath& modelPath)>& modelCookFunc)
{
/* Search for yaml */
hecl::ProjectPath yamlPath = inPath.getWithExtension(_S(".yaml"), true);
if (yamlPath.getPathType() != hecl::ProjectPath::Type::File)
Log.report(logvisor::Fatal, _S("'%s' not found as file"),
yamlPath.getRelativePath().c_str());
athena::io::FileReader yamlReader(yamlPath.getAbsolutePath());
if (!BigYAML::ValidateFromYAMLFile<ANCS>(yamlReader))
Log.report(logvisor::Fatal, _S("'%s' is not urde::DNAMP1::ANCS type"),
yamlPath.getRelativePath().c_str());
ANCS ancs;
ancs.read(yamlReader);
/* Set Character Resource IDs */
for (ANCS::CharacterSet::CharacterInfo& ch : ancs.characterSet.characters)
{
hecl::ProjectPath path = UniqueIDBridge::TranslatePakIdToPath(ch.cmdl);
if (path)
ch.cskr = path.ensureAuxInfo(_S("skin"));
for (const DNAANCS::Actor::Subtype& sub : actor.subtypes)
{
if (!sub.name.compare(ch.name))
{
if (sub.armature >= 0)
{
const DNAANCS::Actor::Armature& arm = actor.armatures[sub.armature];
hecl::SystemStringView chSysName(arm.name);
ch.cinf = inPath.ensureAuxInfo(chSysName.c_str());
break;
}
}
}
path = UniqueIDBridge::TranslatePakIdToPath(ch.cmdlOverlay);
if (path)
ch.cskrOverlay = path.ensureAuxInfo(_S("skin"));
}
/* Set Animation Resource IDs */
ancs.enumeratePrimitives([&](AnimationSet::MetaAnimPrimitive& prim) -> bool
{
hecl::SystemStringView sysStr(prim.animName);
hecl::ProjectPath pathOut = inPath.getWithExtension((_S('.') + sysStr.sys_str()).c_str(), true);
prim.animId = pathOut;
return true;
});
std::unordered_map<std::string, atInt32> boneIdMap;
/* Write out CINF resources */
for (const DNAANCS::Actor::Armature& arm : actor.armatures)
{
hecl::SystemStringView sysStr(arm.name);
hecl::ProjectPath pathOut = inPath.getWithExtension((_S('.') + sysStr.sys_str()).c_str(), true);
athena::io::FileWriter w(pathOut.getAbsolutePath(), true, false);
if (w.hasError())
Log.report(logvisor::Fatal, _S("unable to open '%s' for writing"),
pathOut.getRelativePath().c_str());
CINF cinf(arm, boneIdMap);
cinf.write(w);
}
/* Write out CSKR resources */
for (ANCS::CharacterSet::CharacterInfo& ch : ancs.characterSet.characters)
{
hecl::ProjectPath path = UniqueIDBridge::TranslatePakIdToPath(ch.cmdl);
if (path.getPathType() != hecl::ProjectPath::Type::File)
Log.report(logvisor::Fatal, _S("unable to resolve '%s'"), path.getRelativePath().c_str());
hecl::ProjectPath skinIntPath = path.getCookedPath(SpecEntMP1PC).getWithExtension(_S(".skinint"));
if (skinIntPath.getModtime() < path.getModtime())
if (!modelCookFunc(path))
Log.report(logvisor::Fatal, _S("unable to cook '%s'"), path.getRelativePath().c_str());
athena::io::FileReader skinIO(skinIntPath.getAbsolutePath(), 1024*32, false);
if (skinIO.hasError())
Log.report(logvisor::Fatal, _S("unable to open '%s'"), skinIntPath.getRelativePath().c_str());
std::vector<std::vector<uint32_t>> skinBanks;
uint32_t bankCount = skinIO.readUint32Big();
skinBanks.reserve(bankCount);
for (uint32_t i=0 ; i<bankCount ; ++i)
{
skinBanks.emplace_back();
std::vector<uint32_t>& bonesOut = skinBanks.back();
uint32_t boneCount = skinIO.readUint32Big();
bonesOut.reserve(boneCount);
for (uint32_t j=0 ; j<boneCount ; ++j)
{
uint32_t idx = skinIO.readUint32Big();
bonesOut.push_back(idx);
}
}
std::vector<std::string> boneNames;
uint32_t boneNameCount = skinIO.readUint32Big();
boneNames.reserve(boneNameCount);
for (uint32_t i=0 ; i<boneNameCount ; ++i)
boneNames.push_back(skinIO.readString());
skinIO.close();
hecl::ProjectPath skinPath = path.getCookedPath(SpecEntMP1PC).getWithExtension(_S(".skin"));
athena::io::FileWriter skinOut(skinPath.getAbsolutePath(), true, false);
if (skinOut.hasError())
Log.report(logvisor::Fatal, _S("unable to open '%s' for writing"),
skinPath.getRelativePath().c_str());
skinOut.writeUint32Big(bankCount);
for (const std::vector<uint32_t>& bank : skinBanks)
{
skinOut.writeUint32Big(bank.size());
for (uint32_t bIdx : bank)
{
const std::string& name = boneNames[bIdx];
auto search = boneIdMap.find(name);
if (search == boneIdMap.cend())
Log.report(logvisor::Fatal, "unable to find bone '%s' in %s",
name.c_str(), inPath.getRelativePathUTF8().c_str());
skinOut.writeUint32Big(search->second);
}
}
}
/* Write out ANIM resources */
ancs.animationSet.animResources.reserve(actor.actions.size());
for (const DNAANCS::Actor::Action& act : actor.actions)
{
hecl::SystemStringView sysStr(act.name);
hecl::ProjectPath pathOut = inPath.getWithExtension((_S('.') + sysStr.sys_str()).c_str(), true);
athena::io::FileWriter w(pathOut.getAbsolutePath(), true, false);
if (w.hasError())
Log.report(logvisor::Fatal, _S("unable to open '%s' for writing"),
pathOut.getRelativePath().c_str());
ANIM anim(act, boneIdMap);
ancs.animationSet.animResources.emplace_back();
ancs.animationSet.animResources.back().animId = pathOut;
/* Check for associated EVNT YAML */
hecl::ProjectPath evntYamlPath = inPath.getWithExtension((hecl::SystemString(_S(".")) +
sysStr.sys_str() +
_S(".evnt.yaml")).c_str(), true);
if (evntYamlPath.getPathType() == hecl::ProjectPath::Type::File)
{
FILE* fp = hecl::Fopen(evntYamlPath.getAbsolutePath().c_str(), _S("r"));
if (fp)
{
EVNT evnt;
evnt.fromYAMLFile(fp);
fclose(fp);
anim.m_anim->evnt = evntYamlPath;
hecl::ProjectPath evntYamlOut = pathOut.getWithExtension(_S(".evnt"));
athena::io::FileWriter w(evntYamlOut.getAbsolutePath(), true, false);
if (w.hasError())
Log.report(logvisor::Fatal, _S("unable to open '%s' for writing"),
evntYamlOut.getRelativePath().c_str());
evnt.write(w);
ancs.animationSet.animResources.back().evntId = evntYamlPath;
}
}
anim.write(w);
}
/* Write out ANCS */
athena::io::FileWriter w(outPath.getAbsolutePath(), true, false);
if (w.hasError())
Log.report(logvisor::Fatal, _S("unable to open '%s' for writing"),
outPath.getRelativePath().c_str());
ancs.write(w);
return true;
}
}
}

View File

@ -534,183 +534,12 @@ struct ANCS : BigYAML
const PAK::Entry& entry,
bool force,
hecl::BlenderToken& btok,
std::function<void(const hecl::SystemChar*)> fileChanged)
{
hecl::ProjectPath yamlPath = outPath.getWithExtension(_S(".yaml"));
hecl::ProjectPath::Type yamlType = yamlPath.getPathType();
hecl::ProjectPath blendPath = outPath.getWithExtension(_S(".blend"));
hecl::ProjectPath::Type blendType = blendPath.getPathType();
ANCS ancs;
ancs.read(rs);
if (force ||
yamlType == hecl::ProjectPath::Type::None ||
blendType == hecl::ProjectPath::Type::None)
{
if (force || yamlType == hecl::ProjectPath::Type::None)
{
FILE* fp = hecl::Fopen(yamlPath.getAbsolutePath().c_str(), _S("w"));
ancs.toYAMLFile(fp);
fclose(fp);
}
if (force || blendType == hecl::ProjectPath::Type::None)
{
hecl::BlenderConnection& conn = btok.getBlenderConnection();
DNAANCS::ReadANCSToBlender<PAKRouter<PAKBridge>, ANCS, MaterialSet, DNACMDL::SurfaceHeader_1, 2>
(conn, ancs, blendPath, pakRouter, entry, dataSpec, fileChanged, force);
}
}
/* Extract EVNTs */
std::map<atUint32, DNAANCS::AnimationResInfo<UniqueID32>> animRes;
ancs.getAnimationResInfo(animRes);
for (const auto& res : animRes)
{
if (res.second.evntId)
{
hecl::SystemStringView sysStr(res.second.name);
hecl::ProjectPath evntYamlPath = outPath.getWithExtension((hecl::SystemString(_S(".")) +
sysStr.sys_str() +
_S(".evnt.yaml")).c_str());
hecl::ProjectPath::Type evntYamlType = evntYamlPath.getPathType();
if (force || evntYamlType == hecl::ProjectPath::Type::None)
{
EVNT evnt;
if (pakRouter.lookupAndReadDNA(res.second.evntId, evnt, true))
{
FILE* fp = hecl::Fopen(evntYamlPath.getAbsolutePath().c_str(), _S("w"));
evnt.toYAMLFile(fp);
fclose(fp);
}
}
}
}
return true;
}
std::function<void(const hecl::SystemChar*)> fileChanged);
static bool Cook(const hecl::ProjectPath& outPath,
const hecl::ProjectPath& inPath,
const DNAANCS::Actor& actor)
{
/* Search for yaml */
hecl::ProjectPath yamlPath = inPath.getWithExtension(_S(".yaml"), true);
if (yamlPath.getPathType() != hecl::ProjectPath::Type::File)
Log.report(logvisor::Fatal, _S("'%s' not found as file"),
yamlPath.getRelativePath().c_str());
athena::io::FileReader yamlReader(yamlPath.getAbsolutePath());
if (!BigYAML::ValidateFromYAMLFile<ANCS>(yamlReader))
Log.report(logvisor::Fatal, _S("'%s' is not urde::DNAMP1::ANCS type"),
yamlPath.getRelativePath().c_str());
ANCS ancs;
ancs.read(yamlReader);
/* Set Character Resource IDs */
for (ANCS::CharacterSet::CharacterInfo& ch : ancs.characterSet.characters)
{
hecl::ProjectPath path = UniqueIDBridge::TranslatePakIdToPath(ch.cmdl);
if (path)
ch.cskr = path.ensureAuxInfo(_S("skin"));
for (const DNAANCS::Actor::Subtype& sub : actor.subtypes)
{
if (!sub.name.compare(ch.name))
{
if (sub.armature >= 0)
{
const DNAANCS::Actor::Armature& arm = actor.armatures[sub.armature];
hecl::SystemStringView chSysName(arm.name);
ch.cinf = inPath.ensureAuxInfo(chSysName.c_str());
break;
}
}
}
path = UniqueIDBridge::TranslatePakIdToPath(ch.cmdlOverlay);
if (path)
ch.cskrOverlay = path.ensureAuxInfo(_S("skin"));
}
/* Set Animation Resource IDs */
ancs.enumeratePrimitives([&](AnimationSet::MetaAnimPrimitive& prim) -> bool
{
hecl::SystemStringView sysStr(prim.animName);
hecl::ProjectPath pathOut = inPath.getWithExtension((_S('.') + sysStr.sys_str()).c_str(), true);
prim.animId = pathOut;
return true;
});
std::unordered_map<std::string, atInt32> boneIdMap;
/* Write out CINF resources */
for (const DNAANCS::Actor::Armature& arm : actor.armatures)
{
hecl::SystemStringView sysStr(arm.name);
hecl::ProjectPath pathOut = inPath.getWithExtension((_S('.') + sysStr.sys_str()).c_str(), true);
athena::io::FileWriter w(pathOut.getAbsolutePath(), true, false);
if (w.hasError())
Log.report(logvisor::Fatal, _S("unable to open '%s' for writing"),
pathOut.getRelativePath().c_str());
CINF cinf(arm, boneIdMap);
cinf.write(w);
}
/* Write out ANIM resources */
ancs.animationSet.animResources.reserve(actor.actions.size());
for (const DNAANCS::Actor::Action& act : actor.actions)
{
hecl::SystemStringView sysStr(act.name);
hecl::ProjectPath pathOut = inPath.getWithExtension((_S('.') + sysStr.sys_str()).c_str(), true);
athena::io::FileWriter w(pathOut.getAbsolutePath(), true, false);
if (w.hasError())
Log.report(logvisor::Fatal, _S("unable to open '%s' for writing"),
pathOut.getRelativePath().c_str());
ANIM anim(act, boneIdMap);
ancs.animationSet.animResources.emplace_back();
ancs.animationSet.animResources.back().animId = pathOut;
/* Check for associated EVNT YAML */
hecl::ProjectPath evntYamlPath = inPath.getWithExtension((hecl::SystemString(_S(".")) +
sysStr.sys_str() +
_S(".evnt.yaml")).c_str(), true);
if (evntYamlPath.getPathType() == hecl::ProjectPath::Type::File)
{
FILE* fp = hecl::Fopen(evntYamlPath.getAbsolutePath().c_str(), _S("r"));
if (fp)
{
EVNT evnt;
evnt.fromYAMLFile(fp);
fclose(fp);
anim.m_anim->evnt = evntYamlPath;
hecl::ProjectPath evntYamlOut = pathOut.getWithExtension(_S(".evnt"));
athena::io::FileWriter w(evntYamlOut.getAbsolutePath(), true, false);
if (w.hasError())
Log.report(logvisor::Fatal, _S("unable to open '%s' for writing"),
evntYamlOut.getRelativePath().c_str());
evnt.write(w);
ancs.animationSet.animResources.back().evntId = evntYamlPath;
}
}
anim.write(w);
}
/* Write out ANCS */
athena::io::FileWriter w(outPath.getAbsolutePath(), true, false);
if (w.hasError())
Log.report(logvisor::Fatal, _S("unable to open '%s' for writing"),
outPath.getRelativePath().c_str());
ancs.write(w);
return true;
}
const DNAANCS::Actor& actor,
const std::function<bool(const hecl::ProjectPath& modelPath)>& modelCookFunc);
};
}

View File

@ -94,7 +94,7 @@ struct CMDL
/* Output skinning intermediate */
auto vertCountIt = skinMesh.contiguousSkinVertCounts.cbegin();
athena::io::FileWriter writer(outPath.getWithExtension(_S(".skin")).getAbsolutePath());
athena::io::FileWriter writer(outPath.getWithExtension(_S(".skinint")).getAbsolutePath());
writer.writeUint32Big(skinMesh.skins.size());
for (const std::vector<DNACMDL::Mesh::SkinBind> skin : skinMesh.skins)
{
@ -126,7 +126,7 @@ struct CMDL
return false;
/* Output skinning intermediate */
athena::io::FileWriter writer(outPath.getWithExtension(_S(".skin")).getAbsolutePath());
athena::io::FileWriter writer(outPath.getWithExtension(_S(".skinint")).getAbsolutePath());
writer.writeUint32Big(mesh.skinBanks.banks.size());
for (const DNACMDL::Mesh::SkinBanks::Bank& sb : mesh.skinBanks.banks)
{

View File

@ -93,7 +93,7 @@ bool SpecBase::canExtract(const ExtractPassInfo& info, std::vector<ExtractReport
void SpecBase::doExtract(const ExtractPassInfo& info, FProgress progress)
{
DataSpec::g_curSpec = this;
DataSpec::g_curSpec.reset(this);
if (!Blender::BuildMasterShader(m_masterShader))
Log.report(logvisor::Fatal, "Unable to build master shader blend");
if (m_isWii)
@ -173,7 +173,7 @@ const hecl::Database::DataSpecEntry* SpecBase::overrideDataSpec(const hecl::Proj
void SpecBase::doCook(const hecl::ProjectPath& path, const hecl::ProjectPath& cookedPath,
bool fast, hecl::BlenderToken& btok, FCookProgress progress)
{
DataSpec::g_curSpec = this;
DataSpec::g_curSpec.reset(this);
if (hecl::IsPathBlend(path))
{
hecl::BlenderConnection& conn = btok.getBlenderConnection();
@ -184,19 +184,19 @@ void SpecBase::doCook(const hecl::ProjectPath& path, const hecl::ProjectPath& co
case hecl::BlenderConnection::BlendType::Mesh:
{
hecl::BlenderConnection::DataStream ds = conn.beginData();
cookMesh(cookedPath, path, ds, fast, progress);
cookMesh(cookedPath, path, ds, fast, btok, progress);
break;
}
case hecl::BlenderConnection::BlendType::Actor:
{
hecl::BlenderConnection::DataStream ds = conn.beginData();
cookActor(cookedPath, path, ds, fast, progress);
cookActor(cookedPath, path, ds, fast, btok, progress);
break;
}
case hecl::BlenderConnection::BlendType::Area:
{
hecl::BlenderConnection::DataStream ds = conn.beginData();
cookArea(cookedPath, path, ds, fast, progress);
cookArea(cookedPath, path, ds, fast, btok, progress);
break;
}
default: break;

View File

@ -56,13 +56,16 @@ struct SpecBase : hecl::Database::IDataSpec
using Actor = BlendStream::Actor;
virtual void cookMesh(const hecl::ProjectPath& out, const hecl::ProjectPath& in,
BlendStream& ds, bool fast, FCookProgress progress) const=0;
BlendStream& ds, bool fast, hecl::BlenderToken& btok,
FCookProgress progress)=0;
virtual void cookActor(const hecl::ProjectPath& out, const hecl::ProjectPath& in,
BlendStream& ds, bool fast, FCookProgress progress) const=0;
BlendStream& ds, bool fast, hecl::BlenderToken& btok,
FCookProgress progress)=0;
virtual void cookArea(const hecl::ProjectPath& out, const hecl::ProjectPath& in,
BlendStream& ds, bool fast, FCookProgress progress) const=0;
BlendStream& ds, bool fast, hecl::BlenderToken& btok,
FCookProgress progress)=0;
virtual void cookYAML(const hecl::ProjectPath& out, const hecl::ProjectPath& in,
FILE* fin, FCookProgress progress) const=0;
FILE* fin, FCookProgress progress)=0;
const hecl::ProjectPath& getMasterShaderPath() const {return m_masterShader;}

View File

@ -23,6 +23,7 @@ namespace DataSpec
static logvisor::Module Log("urde::SpecMP1");
extern hecl::Database::DataSpecEntry SpecEntMP1;
extern hecl::Database::DataSpecEntry SpecEntMP1PC;
struct SpecMP1 : SpecBase
{
@ -343,7 +344,8 @@ struct SpecMP1 : SpecBase
}
void cookMesh(const hecl::ProjectPath& out, const hecl::ProjectPath& in,
BlendStream& ds, bool fast, FCookProgress progress) const
BlendStream& ds, bool fast, hecl::BlenderToken& btok,
FCookProgress progress)
{
Mesh mesh = ds.compileMesh(fast ? hecl::HMDLTopology::Triangles : hecl::HMDLTopology::TriStrips, -1,
[&progress](int surfCount)
@ -358,19 +360,31 @@ struct SpecMP1 : SpecBase
}
void cookActor(const hecl::ProjectPath& out, const hecl::ProjectPath& in,
BlendStream& ds, bool fast, FCookProgress progress) const
BlendStream& ds, bool fast, hecl::BlenderToken& btok,
FCookProgress progress)
{
Actor actor = ds.compileActor();
DNAMP1::ANCS::Cook(out, in, actor);
DNAMP1::ANCS::Cook(out, in, actor,
[&](const hecl::ProjectPath& modelPath) -> bool
{
hecl::ProjectPath cooked;
if (m_pc)
cooked = modelPath.getCookedPath(SpecEntMP1PC);
else
cooked = modelPath.getCookedPath(SpecEntMP1);
doCook(modelPath, cooked, fast, btok, progress);
return true;
});
}
void cookArea(const hecl::ProjectPath& out, const hecl::ProjectPath& in,
BlendStream& ds, bool fast, FCookProgress progress) const
BlendStream& ds, bool fast, hecl::BlenderToken& btok,
FCookProgress progress)
{
}
void cookYAML(const hecl::ProjectPath& out, const hecl::ProjectPath& in,
FILE* fin, FCookProgress progress) const
FILE* fin, FCookProgress progress)
{
athena::io::YAMLDocReader reader;
yaml_parser_set_input_file(reader.getParser(), fin);

View File

@ -295,22 +295,25 @@ struct SpecMP2 : SpecBase
}
void cookMesh(const hecl::ProjectPath& out, const hecl::ProjectPath& in,
BlendStream& ds, bool fast, FCookProgress progress) const
BlendStream& ds, bool fast, hecl::BlenderToken& btok,
FCookProgress progress)
{
}
void cookActor(const hecl::ProjectPath& out, const hecl::ProjectPath& in,
BlendStream& ds, bool fast, FCookProgress progress) const
BlendStream& ds, bool fast, hecl::BlenderToken& btok,
FCookProgress progress)
{
}
void cookArea(const hecl::ProjectPath& out, const hecl::ProjectPath& in,
BlendStream& ds, bool fast, FCookProgress progress) const
BlendStream& ds, bool fast, hecl::BlenderToken& btok,
FCookProgress progress)
{
}
void cookYAML(const hecl::ProjectPath& out, const hecl::ProjectPath& in,
FILE* fin, FCookProgress progress) const
FILE* fin, FCookProgress progress)
{
}
};

View File

@ -490,22 +490,25 @@ struct SpecMP3 : SpecBase
}
void cookMesh(const hecl::ProjectPath& out, const hecl::ProjectPath& in,
BlendStream& ds, bool fast, FCookProgress progress) const
BlendStream& ds, bool fast, hecl::BlenderToken& btok,
FCookProgress progress)
{
}
void cookActor(const hecl::ProjectPath& out, const hecl::ProjectPath& in,
BlendStream& ds, bool fast, FCookProgress progress) const
BlendStream& ds, bool fast, hecl::BlenderToken& btok,
FCookProgress progress)
{
}
void cookArea(const hecl::ProjectPath& out, const hecl::ProjectPath& in,
BlendStream& ds, bool fast, FCookProgress progress) const
BlendStream& ds, bool fast, hecl::BlenderToken& btok,
FCookProgress progress)
{
}
void cookYAML(const hecl::ProjectPath& out, const hecl::ProjectPath& in,
FILE* fin, FCookProgress progress) const
FILE* fin, FCookProgress progress)
{
}
};

View File

@ -0,0 +1,15 @@
#include "CAnimCharacterSet.hpp"
#include "CToken.hpp"
namespace urde
{
CAnimCharacterSet::CAnimCharacterSet(CInputStream& in)
: x0_version(in.readUint16Big()), x4_characterSet(in), x1c_animationSet(in) {}
CFactoryFnReturn FAnimCharacterSet(const SObjectTag&, CInputStream& in, const CVParamTransfer&)
{
return TToken<CAnimCharacterSet>::GetIObjObjectFor(std::make_unique<CAnimCharacterSet>(in));
}
}

View File

@ -0,0 +1,24 @@
#ifndef __PSHAG_CANIMCHARACTERSET_HPP__
#define __PSHAG_CANIMCHARACTERSET_HPP__
#include "CFactoryMgr.hpp"
#include "CCharacterSet.hpp"
#include "CAnimationSet.hpp"
namespace urde
{
class CAnimCharacterSet
{
u16 x0_version;
CCharacterSet x4_characterSet;
CAnimationSet x1c_animationSet;
public:
CAnimCharacterSet(CInputStream& in);
};
CFactoryFnReturn FAnimCharacterSet(const SObjectTag&, CInputStream&, const CVParamTransfer&);
}
#endif // __PSHAG_CANIMCHARACTERSET_HPP__

View File

View File

@ -0,0 +1,17 @@
#ifndef __PSHAG_CANIMATIONSET_HPP__
#define __PSHAG_CANIMATIONSET_HPP__
#include "IOStreams.hpp"
namespace urde
{
class CAnimationSet
{
public:
CAnimationSet(CInputStream& in);
};
}
#endif // __PSHAG_CANIMATIONSET_HPP__

View File

@ -0,0 +1,32 @@
#include "CCharacterInfo.hpp"
namespace urde
{
static std::vector<std::pair<u32, std::pair<std::string, std::string>>>
MakeAnimInfoVector(CInputStream& in)
{
std::vector<std::pair<u32, std::pair<std::string, std::string>>> ret;
u32 animInfoCount = in.readUint32Big();
ret.reserve(animInfoCount);
for (u32 i=0 ; i<animInfoCount ; ++i)
{
u32 idx = in.readUint32Big();
std::string a = in.readString();
std::string b = in.readString();
ret.emplace_back(idx, std::make_pair(a, b));
}
return ret;
}
CCharacterInfo::CCharacterInfo(CInputStream& in)
: x0_tableCount(in.readUint16Big()),
x4_name(in.readString()),
x14_cmdl(in.readUint32Big()),
x18_cskr(in.readUint32Big()),
x1c_cinf(in.readUint32Big()),
x20_animInfo(MakeAnimInfoVector(in)),
x30_pasDatabase(in)
{}
}

View File

@ -0,0 +1,26 @@
#ifndef __PSHAG_CCHARACTERINFO_HPP__
#define __PSHAG_CCHARACTERINFO_HPP__
#include "IOStreams.hpp"
#include "CPASDatabase.hpp"
namespace urde
{
class CCharacterInfo
{
u16 x0_tableCount;
std::string x4_name;
TResId x14_cmdl;
TResId x18_cskr;
TResId x1c_cinf;
std::vector<std::pair<u32, std::pair<std::string, std::string>>> x20_animInfo;
CPASDatabase x30_pasDatabase;
public:
CCharacterInfo(CInputStream& in);
};
}
#endif // __PSHAG_CCHARACTERINFO_HPP__

View File

@ -0,0 +1,17 @@
#include "CCharacterSet.hpp"
namespace urde
{
CCharacterSet::CCharacterSet(CInputStream& in)
: x0_version(in.readUint16Big())
{
u32 charCount = in.readUint32Big();
for (u32 i=0 ; i<charCount ; ++i)
{
u32 id = in.readUint32Big();
x4_characters.emplace(id, in);
}
}
}

View File

@ -0,0 +1,20 @@
#ifndef __PSHAG_CCHARACTERSET_HPP__
#define __PSHAG_CCHARACTERSET_HPP__
#include "IOStreams.hpp"
#include "CCharacterInfo.hpp"
namespace urde
{
class CCharacterSet
{
u16 x0_version;
std::map<u32, CCharacterInfo> x4_characters;
public:
CCharacterSet(CInputStream& in);
};
}
#endif // __PSHAG_CCHARACTERSET_HPP__

View File

@ -16,4 +16,13 @@ add_library(RuntimeCommonCharacter
CSegIdList.hpp CSegIdList.cpp
CSegId.hpp CSegId.cpp
CSkinRules.hpp CSkinRules.cpp
CAnimCharacterSet.hpp CAnimCharacterSet.cpp
CAnimationSet.hpp CAnimationSet.cpp
CCharacterSet.hpp CCharacterSet.cpp
CCharacterInfo.hpp CCharacterInfo.cpp
CPASDatabase.hpp CPASDatabase.cpp
CPASAnimState.hpp CPASAnimState.cpp
CPASParmInfo.hpp CPASParmInfo.cpp
CPASAnimInfo.hpp CPASAnimInfo.cpp
CPASAnimParm.hpp CPASAnimParm.cpp
CBodyState.hpp)

View File

@ -0,0 +1,9 @@
#include "CPASAnimInfo.hpp"
namespace urde
{
CPASAnimInfo::CPASAnimInfo(u32 id, rstl::reserved_vector<CPASAnimParm::UParmValue, 8>&& parms)
: x0_id(id), x4_parms(std::move(parms)) {}
}

View File

@ -0,0 +1,22 @@
#ifndef __PSHAG_CPASANIMINFO_HPP__
#define __PSHAG_CPASANIMINFO_HPP__
#include "IOStreams.hpp"
#include "rstl.hpp"
#include "CPASAnimParm.hpp"
namespace urde
{
class CPASAnimInfo
{
u32 x0_id;
rstl::reserved_vector<CPASAnimParm::UParmValue, 8> x4_parms;
public:
CPASAnimInfo(u32 id, rstl::reserved_vector<CPASAnimParm::UParmValue, 8>&& parms);
u32 GetId() const {return x0_id;}
};
}
#endif // __PSHAG_CPASANIMINFO_HPP__

View File

View File

@ -0,0 +1,86 @@
#ifndef __PSHAG_CPASANIMPARM_HPP__
#define __PSHAG_CPASANIMPARM_HPP__
#include "RetroTypes.hpp"
namespace urde
{
class CPASAnimParm
{
public:
enum class EParmType
{
None = -1,
Int32 = 0,
UInt32 = 1,
Float = 2,
Bool = 3,
Enum = 4
};
union UParmValue
{
s32 m_int;
u32 m_uint;
float m_float;
bool m_bool;
};
private:
UParmValue x0_value;
EParmType x4_type;
public:
CPASAnimParm(UParmValue val, EParmType tp) : x4_type(tp), x0_value(val) {}
s32 GetEnumValue() const {return x0_value.m_int;}
bool GetBoolValue() const {return x0_value.m_bool;}
float GetReal32Value() const {return x0_value.m_float;}
u32 GetUint32Value() const {return x0_value.m_uint;}
s32 GetInt32Value() const {return x0_value.m_int;}
static CPASAnimParm FromEnum(s32 val)
{
UParmValue valin;
valin.m_int = val;
return CPASAnimParm(valin, EParmType::Enum);
}
static CPASAnimParm FromBool(bool val)
{
UParmValue valin;
valin.m_bool = val;
return CPASAnimParm(valin, EParmType::Bool);
}
static CPASAnimParm FromReal32(float val)
{
UParmValue valin;
valin.m_float = val;
return CPASAnimParm(valin, EParmType::Float);
}
static CPASAnimParm FromUint32(u32 val)
{
UParmValue valin;
valin.m_uint = val;
return CPASAnimParm(valin, EParmType::UInt32);
}
static CPASAnimParm FromInt32(s32 val)
{
UParmValue valin;
valin.m_int = val;
return CPASAnimParm(valin, EParmType::Int32);
}
static CPASAnimParm NoParameter()
{
UParmValue valin;
valin.m_int = -1;
return CPASAnimParm(valin, EParmType::None);
}
};
}
#endif // __PSHAG_CPASANIMPARM_HPP__

View File

@ -0,0 +1,54 @@
#include "CPASAnimState.hpp"
namespace urde
{
CPASAnimState::CPASAnimState(CInputStream& in)
{
x0_id = in.readUint32Big();
u32 parmCount = in.readUint32Big();
u32 animCount = in.readUint32Big();
x4_parms.reserve(parmCount);
x14_anims.reserve(animCount);
x24_.reserve(animCount);
for (u32 i=0 ; i<parmCount ; ++i)
x4_parms.emplace_back(in);
for (u32 i=0 ; i<animCount ; ++i)
{
u32 id = in.readUint32Big();
rstl::reserved_vector<CPASAnimParm::UParmValue, 8> parms;
for (const CPASParmInfo& parm : x4_parms)
{
CPASAnimParm::UParmValue val = {};
switch (parm.GetType())
{
case CPASAnimParm::EParmType::Int32:
val.m_int = in.readInt32Big();
break;
case CPASAnimParm::EParmType::UInt32:
val.m_uint = in.readUint32Big();
break;
case CPASAnimParm::EParmType::Float:
val.m_float = in.readFloatBig();
break;
case CPASAnimParm::EParmType::Bool:
val.m_bool = in.readBool();
break;
case CPASAnimParm::EParmType::Enum:
val.m_int = in.readInt32Big();
break;
default: break;
}
parms.push_back(val);
}
auto search = std::lower_bound(x14_anims.begin(), x14_anims.end(), id,
[](const CPASAnimInfo& item, const u32& testId) -> bool {return item.GetId() < testId;});
x14_anims.emplace(search, id, std::move(parms));
}
}
}

View File

@ -0,0 +1,24 @@
#ifndef __PSHAG_CPASANIMSTATE_HPP__
#define __PSHAG_CPASANIMSTATE_HPP__
#include "IOStreams.hpp"
#include "CPASParmInfo.hpp"
#include "CPASAnimInfo.hpp"
namespace urde
{
class CPASAnimState
{
u32 x0_id;
std::vector<CPASParmInfo> x4_parms;
std::vector<CPASAnimInfo> x14_anims;
std::vector<u32> x24_;
public:
CPASAnimState(CInputStream& in);
u32 GetId() const {return x0_id;}
};
}
#endif // __PSHAG_CPASANIMSTATE_HPP__

View File

@ -0,0 +1,30 @@
#include "CPASDatabase.hpp"
namespace urde
{
void CPASDatabase::AddAnimState(CPASAnimState&& state)
{
auto it = std::lower_bound(x0_states.begin(), x0_states.end(), state,
[](const CPASAnimState& item, const CPASAnimState& test) -> bool {return item.GetId() < test.GetId();});
x0_states.insert(it, std::move(state));
}
CPASDatabase::CPASDatabase(CInputStream& in)
{
in.readUint32Big();
u32 animStateCount = in.readUint32Big();
u32 defaultState = in.readUint32Big();
x0_states.reserve(animStateCount);
for (u32 i=0 ; i<animStateCount ; ++i)
{
CPASAnimState state(in);
AddAnimState(std::move(state));
}
if (animStateCount)
SetDefaultState(defaultState);
}
}

View File

@ -0,0 +1,22 @@
#ifndef __PSHAG_CPASDATABASE_HPP__
#define __PSHAG_CPASDATABASE_HPP__
#include "IOStreams.hpp"
#include "CPASAnimState.hpp"
namespace urde
{
class CPASDatabase
{
std::vector<CPASAnimState> x0_states;
u32 x10_defaultState;
void AddAnimState(CPASAnimState&& state);
void SetDefaultState(u32 state) {x10_defaultState = state;}
public:
CPASDatabase(CInputStream& in);
};
}
#endif // __PSHAG_CPASDATABASE_HPP__

View File

@ -0,0 +1,40 @@
#include "CPASParmInfo.hpp"
namespace urde
{
CPASParmInfo::CPASParmInfo(CInputStream& in)
{
xc_val1.m_int = 0;
x10_val2.m_int = 0;
x0_type = CPASAnimParm::EParmType(in.readUint32Big());
x4_unk1 = in.readUint32Big();
x8_unk2 = in.readFloatBig();
switch (x0_type)
{
case CPASAnimParm::EParmType::Int32:
xc_val1.m_int = in.readInt32Big();
x10_val2.m_int = in.readInt32Big();
break;
case CPASAnimParm::EParmType::UInt32:
xc_val1.m_uint = in.readUint32Big();
x10_val2.m_uint = in.readUint32Big();
break;
case CPASAnimParm::EParmType::Float:
xc_val1.m_float = in.readFloatBig();
x10_val2.m_float = in.readFloatBig();
break;
case CPASAnimParm::EParmType::Bool:
xc_val1.m_bool = in.readBool();
x10_val2.m_bool = in.readBool();
break;
case CPASAnimParm::EParmType::Enum:
xc_val1.m_int = in.readInt32Big();
x10_val2.m_int = in.readInt32Big();
break;
default: break;
}
}
}

View File

@ -0,0 +1,24 @@
#ifndef __PSHAG_CPASPARMINFO_HPP__
#define __PSHAG_CPASPARMINFO_HPP__
#include "IOStreams.hpp"
#include "CPASAnimParm.hpp"
namespace urde
{
class CPASParmInfo
{
CPASAnimParm::EParmType x0_type;
u32 x4_unk1;
float x8_unk2;
CPASAnimParm::UParmValue xc_val1;
CPASAnimParm::UParmValue x10_val2;
public:
CPASParmInfo(CInputStream& in);
CPASAnimParm::EParmType GetType() const {return x0_type;}
};
}
#endif // __PSHAG_CPASPARMINFO_HPP__