metaforce/DataSpec/DNAMP1/ANCS.cpp

1311 lines
38 KiB
C++
Raw Normal View History

2015-08-08 04:49:42 +00:00
#include "ANCS.hpp"
2016-02-13 09:02:47 +00:00
namespace DataSpec
2015-08-08 04:49:42 +00:00
{
2016-08-22 00:11:18 +00:00
extern hecl::Database::DataSpecEntry SpecEntMP1;
2016-04-10 04:49:02 +00:00
extern hecl::Database::DataSpecEntry SpecEntMP1PC;
2015-08-08 04:49:42 +00:00
namespace DNAMP1
{
2016-03-04 23:04:53 +00:00
void ANCS::CharacterSet::CharacterInfo::PASDatabase::AnimState::ParmInfo::read(athena::io::IStreamReader& reader)
2015-08-08 04:49:42 +00:00
{
parmType = reader.readUint32Big();
unk1 = reader.readUint32Big();
unk2 = reader.readFloatBig();
2015-08-08 23:24:17 +00:00
switch (DataType(parmType))
2015-08-08 04:49:42 +00:00
{
2015-11-21 01:16:07 +00:00
case DataType::Int32:
parmVals[0].int32 = reader.readInt32Big();
parmVals[1].int32 = reader.readInt32Big();
2015-08-08 04:49:42 +00:00
break;
2015-11-21 01:16:07 +00:00
case DataType::UInt32:
case DataType::Enum:
parmVals[0].uint32 = reader.readUint32Big();
parmVals[1].uint32 = reader.readUint32Big();
2015-08-08 04:49:42 +00:00
break;
2015-11-21 01:16:07 +00:00
case DataType::Float:
parmVals[0].float32 = reader.readFloatBig();
parmVals[1].float32 = reader.readFloatBig();
2015-08-08 04:49:42 +00:00
break;
2015-11-21 01:16:07 +00:00
case DataType::Bool:
2015-08-08 04:49:42 +00:00
parmVals[0].bool1 = reader.readBool();
parmVals[1].bool1 = reader.readBool();
break;
}
}
2016-03-04 23:04:53 +00:00
void ANCS::CharacterSet::CharacterInfo::PASDatabase::AnimState::ParmInfo::write(athena::io::IStreamWriter& writer) const
2015-08-08 04:49:42 +00:00
{
writer.writeUint32Big(parmType);
writer.writeUint32Big(unk1);
writer.writeFloatBig(unk2);
2015-08-08 23:24:17 +00:00
switch (DataType(parmType))
2015-08-08 04:49:42 +00:00
{
2015-11-21 01:16:07 +00:00
case DataType::Int32:
writer.writeInt32Big(parmVals[0].int32);
writer.writeInt32Big(parmVals[1].int32);
2015-08-08 04:49:42 +00:00
break;
2015-11-21 01:16:07 +00:00
case DataType::UInt32:
case DataType::Enum:
writer.writeUint32Big(parmVals[0].uint32);
writer.writeUint32Big(parmVals[0].uint32);
2015-08-08 04:49:42 +00:00
break;
2015-11-21 01:16:07 +00:00
case DataType::Float:
writer.writeFloatBig(parmVals[0].float32);
writer.writeFloatBig(parmVals[0].float32);
2015-08-08 04:49:42 +00:00
break;
2015-11-21 01:16:07 +00:00
case DataType::Bool:
2015-08-08 04:49:42 +00:00
writer.writeBool(parmVals[0].bool1);
writer.writeBool(parmVals[0].bool1);
break;
}
}
size_t ANCS::CharacterSet::CharacterInfo::PASDatabase::AnimState::ParmInfo::binarySize(size_t __isz) const
{
__isz += 12;
switch (DataType(parmType))
{
2015-11-21 01:16:07 +00:00
case DataType::Int32:
case DataType::UInt32:
case DataType::Enum:
case DataType::Float:
__isz += 8;
break;
2015-11-21 01:16:07 +00:00
case DataType::Bool:
__isz += 2;
break;
}
return __isz;
}
2016-03-04 23:04:53 +00:00
void ANCS::CharacterSet::CharacterInfo::PASDatabase::AnimState::ParmInfo::read(athena::io::YAMLDocReader& reader)
2015-08-08 04:49:42 +00:00
{
parmType = reader.readUint32("parmType");
unk1 = reader.readUint32("unk1");
unk2 = reader.readFloat("unk2");
2016-03-05 00:03:41 +00:00
size_t parmValCount;
reader.enterSubVector("parmVals", parmValCount);
2015-08-08 23:24:17 +00:00
switch (DataType(parmType))
2015-08-08 04:49:42 +00:00
{
2015-11-21 01:16:07 +00:00
case DataType::Int32:
2015-08-08 04:49:42 +00:00
parmVals[0].int32 = reader.readInt32(nullptr);
parmVals[1].int32 = reader.readInt32(nullptr);
break;
2015-11-21 01:16:07 +00:00
case DataType::UInt32:
case DataType::Enum:
2015-08-08 04:49:42 +00:00
parmVals[0].uint32 = reader.readUint32(nullptr);
parmVals[1].uint32 = reader.readUint32(nullptr);
break;
2015-11-21 01:16:07 +00:00
case DataType::Float:
2015-08-08 04:49:42 +00:00
parmVals[0].float32 = reader.readFloat(nullptr);
parmVals[1].float32 = reader.readFloat(nullptr);
break;
2015-11-21 01:16:07 +00:00
case DataType::Bool:
2015-08-08 04:49:42 +00:00
parmVals[0].bool1 = reader.readBool(nullptr);
parmVals[1].bool1 = reader.readBool(nullptr);
break;
default: break;
}
reader.leaveSubVector();
}
2016-03-04 23:04:53 +00:00
void ANCS::CharacterSet::CharacterInfo::PASDatabase::AnimState::ParmInfo::write(athena::io::YAMLDocWriter& writer) const
2015-08-08 04:49:42 +00:00
{
writer.writeUint32("parmType", parmType);
writer.writeUint32("unk1", unk1);
writer.writeFloat("unk2", unk2);
writer.enterSubVector("parmVals");
2015-08-08 23:24:17 +00:00
switch (DataType(parmType))
2015-08-08 04:49:42 +00:00
{
2015-11-21 01:16:07 +00:00
case DataType::Int32:
2015-08-08 04:49:42 +00:00
writer.writeInt32(nullptr, parmVals[0].int32);
writer.writeInt32(nullptr, parmVals[1].int32);
break;
2015-11-21 01:16:07 +00:00
case DataType::UInt32:
case DataType::Enum:
2015-08-08 04:49:42 +00:00
writer.writeUint32(nullptr, parmVals[0].uint32);
writer.writeUint32(nullptr, parmVals[0].uint32);
break;
2015-11-21 01:16:07 +00:00
case DataType::Float:
2015-08-08 04:49:42 +00:00
writer.writeFloat(nullptr, parmVals[0].float32);
writer.writeFloat(nullptr, parmVals[0].float32);
break;
2015-11-21 01:16:07 +00:00
case DataType::Bool:
2015-08-08 04:49:42 +00:00
writer.writeBool(nullptr, parmVals[0].bool1);
writer.writeBool(nullptr, parmVals[0].bool1);
break;
}
writer.leaveSubVector();
}
2015-10-01 00:40:21 +00:00
const char* ANCS::CharacterSet::CharacterInfo::PASDatabase::AnimState::ParmInfo::DNAType()
{
2016-03-04 23:04:53 +00:00
return "urde::DNAMP1::ANCS::CharacterSet::CharacterInfo::PASDatabase::AnimState::ParmInfo";
2015-10-01 00:40:21 +00:00
}
2016-03-04 23:04:53 +00:00
void ANCS::CharacterSet::CharacterInfo::PASDatabase::AnimState::read(athena::io::IStreamReader& reader)
2015-08-08 04:49:42 +00:00
{
id = reader.readUint32Big();
atUint32 parmInfoCount = reader.readUint32Big();
atUint32 animInfoCount = reader.readUint32Big();
2015-08-08 04:49:42 +00:00
2015-08-08 23:24:17 +00:00
reader.enumerate(parmInfos, parmInfoCount);
2015-08-08 04:49:42 +00:00
2015-08-08 23:24:17 +00:00
animInfos.clear();
2015-08-08 04:49:42 +00:00
animInfos.reserve(animInfoCount);
2015-08-08 23:24:17 +00:00
reader.enumerate<AnimInfo>(animInfos, animInfoCount,
2016-03-04 23:04:53 +00:00
[this, parmInfoCount](athena::io::IStreamReader& reader, AnimInfo& ai)
2015-08-08 04:49:42 +00:00
{
ai.id = reader.readUint32Big();
2015-08-08 04:49:42 +00:00
ai.parmVals.reserve(parmInfoCount);
for (const ParmInfo& pi : parmInfos)
{
2015-08-08 23:24:17 +00:00
switch (ParmInfo::DataType(pi.parmType))
2015-08-08 04:49:42 +00:00
{
2015-11-21 01:16:07 +00:00
case ParmInfo::DataType::Int32:
ai.parmVals.emplace_back(reader.readInt32Big());
2015-08-08 04:49:42 +00:00
break;
2015-11-21 01:16:07 +00:00
case ParmInfo::DataType::UInt32:
case ParmInfo::DataType::Enum:
ai.parmVals.emplace_back(reader.readUint32Big());
2015-08-08 04:49:42 +00:00
break;
2015-11-21 01:16:07 +00:00
case ParmInfo::DataType::Float:
ai.parmVals.emplace_back(reader.readFloatBig());
2015-08-08 04:49:42 +00:00
break;
2015-11-21 01:16:07 +00:00
case ParmInfo::DataType::Bool:
2015-08-08 04:49:42 +00:00
ai.parmVals.emplace_back(reader.readBool());
break;
default: break;
}
}
2015-08-08 23:24:17 +00:00
});
2015-08-08 04:49:42 +00:00
}
2016-03-04 23:04:53 +00:00
void ANCS::CharacterSet::CharacterInfo::PASDatabase::AnimState::write(athena::io::IStreamWriter& writer) const
2015-08-08 04:49:42 +00:00
{
writer.writeUint32Big(id);
writer.writeUint32Big(parmInfos.size());
writer.writeUint32Big(animInfos.size());
2015-08-08 04:49:42 +00:00
for (const ParmInfo& pi : parmInfos)
pi.write(writer);
for (const AnimInfo& ai : animInfos)
{
writer.writeUint32Big(ai.id);
2015-08-08 04:49:42 +00:00
auto it = ai.parmVals.begin();
for (const ParmInfo& pi : parmInfos)
{
ParmInfo::Parm pVal;
if (it != ai.parmVals.end())
pVal = *it++;
2015-08-08 23:24:17 +00:00
switch (ParmInfo::DataType(pi.parmType))
2015-08-08 04:49:42 +00:00
{
2015-11-21 01:16:07 +00:00
case ParmInfo::DataType::Int32:
writer.writeInt32Big(pVal.int32);
2015-08-08 04:49:42 +00:00
break;
2015-11-21 01:16:07 +00:00
case ParmInfo::DataType::UInt32:
case ParmInfo::DataType::Enum:
writer.writeUint32Big(pVal.uint32);
2015-08-08 04:49:42 +00:00
break;
2015-11-21 01:16:07 +00:00
case ParmInfo::DataType::Float:
writer.writeFloatBig(pVal.float32);
2015-08-08 04:49:42 +00:00
break;
2015-11-21 01:16:07 +00:00
case ParmInfo::DataType::Bool:
2015-08-08 04:49:42 +00:00
writer.writeBool(pVal.bool1);
break;
default: break;
}
}
}
}
size_t ANCS::CharacterSet::CharacterInfo::PASDatabase::AnimState::binarySize(size_t __isz) const
{
__isz += 12;
__isz = __EnumerateSize(__isz, parmInfos);
__isz += animInfos.size() * 4;
for (const ParmInfo& pi : parmInfos)
{
switch (ParmInfo::DataType(pi.parmType))
{
2015-11-21 01:16:07 +00:00
case ParmInfo::DataType::Int32:
case ParmInfo::DataType::UInt32:
case ParmInfo::DataType::Enum:
case ParmInfo::DataType::Float:
__isz += animInfos.size() * 4;
break;
2015-11-21 01:16:07 +00:00
case ParmInfo::DataType::Bool:
__isz += animInfos.size();
break;
default: break;
}
}
return __isz;
}
2016-03-04 23:04:53 +00:00
void ANCS::CharacterSet::CharacterInfo::PASDatabase::AnimState::read(athena::io::YAMLDocReader& reader)
2015-08-08 04:49:42 +00:00
{
id = reader.readUint32("id");
2016-03-04 01:01:37 +00:00
size_t parmInfoCount = reader.enumerate("parmInfos", parmInfos);
2015-08-08 04:49:42 +00:00
2016-03-04 01:01:37 +00:00
reader.enumerate<AnimInfo>("animInfos", animInfos,
2016-03-04 23:04:53 +00:00
[this, parmInfoCount](athena::io::YAMLDocReader& reader, AnimInfo& ai)
2015-08-08 04:49:42 +00:00
{
ai.id = reader.readUint32("id");
ai.parmVals.reserve(parmInfoCount);
2016-03-04 23:04:53 +00:00
size_t parmValCount;
reader.enterSubVector("parmVals", parmValCount);
2015-08-08 04:49:42 +00:00
for (const ParmInfo& pi : parmInfos)
{
2015-08-08 23:24:17 +00:00
switch (ParmInfo::DataType(pi.parmType))
2015-08-08 04:49:42 +00:00
{
2015-11-21 01:16:07 +00:00
case ParmInfo::DataType::Int32:
2015-08-08 04:49:42 +00:00
ai.parmVals.emplace_back(reader.readInt32(nullptr));
break;
2015-11-21 01:16:07 +00:00
case ParmInfo::DataType::UInt32:
case ParmInfo::DataType::Enum:
2015-08-08 04:49:42 +00:00
ai.parmVals.emplace_back(reader.readUint32(nullptr));
break;
2015-11-21 01:16:07 +00:00
case ParmInfo::DataType::Float:
2015-08-08 04:49:42 +00:00
ai.parmVals.emplace_back(reader.readFloat(nullptr));
break;
2015-11-21 01:16:07 +00:00
case ParmInfo::DataType::Bool:
2015-08-08 04:49:42 +00:00
ai.parmVals.emplace_back(reader.readBool(nullptr));
break;
default: break;
}
}
reader.leaveSubVector();
2015-08-08 23:24:17 +00:00
});
2015-08-08 04:49:42 +00:00
}
2016-03-04 23:04:53 +00:00
void ANCS::CharacterSet::CharacterInfo::PASDatabase::AnimState::write(athena::io::YAMLDocWriter& writer) const
2015-08-08 04:49:42 +00:00
{
writer.writeUint32("id", id);
2015-08-08 23:24:17 +00:00
writer.enumerate("parmInfos", parmInfos);
2015-08-08 04:49:42 +00:00
2015-08-08 23:24:17 +00:00
writer.enumerate<AnimInfo>("animInfos", animInfos,
2016-03-04 23:04:53 +00:00
[this](athena::io::YAMLDocWriter& writer, const AnimInfo& ai)
2015-08-08 04:49:42 +00:00
{
writer.writeUint32("id", ai.id);
auto it = ai.parmVals.begin();
writer.enterSubVector("parms");
for (const ParmInfo& pi : parmInfos)
{
ParmInfo::Parm pVal;
if (it != ai.parmVals.end())
pVal = *it++;
2015-08-08 23:24:17 +00:00
switch (ParmInfo::DataType(pi.parmType))
2015-08-08 04:49:42 +00:00
{
2015-11-21 01:16:07 +00:00
case ParmInfo::DataType::Int32:
2015-08-08 04:49:42 +00:00
writer.writeInt32(nullptr, pVal.int32);
break;
2015-11-21 01:16:07 +00:00
case ParmInfo::DataType::UInt32:
case ParmInfo::DataType::Enum:
2015-08-08 04:49:42 +00:00
writer.writeUint32(nullptr, pVal.uint32);
break;
2015-11-21 01:16:07 +00:00
case ParmInfo::DataType::Float:
2015-08-08 04:49:42 +00:00
writer.writeFloat(nullptr, pVal.float32);
break;
2015-11-21 01:16:07 +00:00
case ParmInfo::DataType::Bool:
2015-08-08 04:49:42 +00:00
writer.writeBool(nullptr, pVal.bool1);
break;
default: break;
}
}
writer.leaveSubVector();
2015-08-08 23:24:17 +00:00
});
2015-08-08 04:49:42 +00:00
}
2015-10-01 00:40:21 +00:00
const char* ANCS::CharacterSet::CharacterInfo::PASDatabase::AnimState::DNAType()
{
2016-03-04 23:04:53 +00:00
return "urde::DNAMP1::ANCS::CharacterSet::CharacterInfo::PASDatabase::AnimState";
2015-10-01 00:40:21 +00:00
}
2016-03-04 23:04:53 +00:00
void ANCS::CharacterSet::CharacterInfo::read(athena::io::IStreamReader& reader)
2015-08-08 04:49:42 +00:00
{
idx = reader.readUint32Big();
atUint16 sectionCount = reader.readUint16Big();
2015-08-08 04:49:42 +00:00
name = reader.readString();
cmdl.read(reader);
cskr.read(reader);
cinf.read(reader);
atUint32 animationCount = reader.readUint32Big();
2015-08-08 23:24:17 +00:00
reader.enumerate(animations, animationCount);
2015-08-08 04:49:42 +00:00
pasDatabase.read(reader);
atUint32 partCount = reader.readUint32Big();
2015-08-08 23:24:17 +00:00
reader.enumerate(partResData.part, partCount);
2015-08-08 04:49:42 +00:00
atUint32 swhcCount = reader.readUint32Big();
2015-08-08 23:24:17 +00:00
reader.enumerate(partResData.swhc, swhcCount);
2015-08-08 04:49:42 +00:00
atUint32 unkCount = reader.readUint32Big();
2015-08-08 23:24:17 +00:00
reader.enumerate(partResData.unk, unkCount);
2015-08-08 04:49:42 +00:00
2015-08-08 23:24:17 +00:00
partResData.elsc.clear();
2015-08-08 04:49:42 +00:00
if (sectionCount > 5)
{
atUint32 elscCount = reader.readUint32Big();
2015-08-08 23:24:17 +00:00
reader.enumerate(partResData.elsc, elscCount);
2015-08-08 04:49:42 +00:00
}
unk1 = reader.readUint32Big();
2015-08-08 04:49:42 +00:00
animAABBs.clear();
if (sectionCount > 1)
{
atUint32 aabbCount = reader.readUint32Big();
2015-08-08 23:24:17 +00:00
reader.enumerate(animAABBs, aabbCount);
2015-08-08 04:49:42 +00:00
}
effects.clear();
if (sectionCount > 2)
{
atUint32 effectCount = reader.readUint32Big();
2015-08-08 23:24:17 +00:00
reader.enumerate(effects, effectCount);
2015-08-08 04:49:42 +00:00
}
if (sectionCount > 3)
{
2015-09-26 03:12:08 +00:00
cmdlOverlay.read(reader);
cskrOverlay.read(reader);
2015-08-08 04:49:42 +00:00
}
animIdxs.clear();
if (sectionCount > 4)
{
atUint32 aidxCount = reader.readUint32Big();
reader.enumerateBig(animIdxs, aidxCount);
2015-08-08 04:49:42 +00:00
}
}
2016-03-04 23:04:53 +00:00
void ANCS::CharacterSet::CharacterInfo::write(athena::io::IStreamWriter& writer) const
2015-08-08 04:49:42 +00:00
{
writer.writeUint32Big(idx);
2015-08-08 04:49:42 +00:00
atUint16 sectionCount;
2015-08-15 04:12:15 +00:00
if (partResData.elsc.size())
2015-08-08 04:49:42 +00:00
sectionCount = 6;
else if (animIdxs.size())
sectionCount = 5;
2015-09-26 03:12:08 +00:00
else if (cmdlOverlay)
2015-08-08 04:49:42 +00:00
sectionCount = 4;
else if (effects.size())
sectionCount = 3;
else if (animAABBs.size())
sectionCount = 2;
else
sectionCount = 1;
writer.writeUint16Big(sectionCount);
2015-08-08 04:49:42 +00:00
writer.writeString(name);
cmdl.UniqueID32::write(writer);
cskr.UniqueID32::write(writer);
cinf.UniqueID32::write(writer);
2015-08-08 04:49:42 +00:00
writer.writeUint32Big(animations.size());
2015-08-08 23:24:17 +00:00
writer.enumerate(animations);
2015-08-08 04:49:42 +00:00
pasDatabase.write(writer);
writer.writeUint32Big(partResData.part.size());
2015-08-08 23:24:17 +00:00
writer.enumerate(partResData.part);
2015-08-08 04:49:42 +00:00
writer.writeUint32Big(partResData.swhc.size());
2015-08-08 23:24:17 +00:00
writer.enumerate(partResData.swhc);
2015-08-08 04:49:42 +00:00
writer.writeUint32Big(partResData.unk.size());
2015-08-08 23:24:17 +00:00
writer.enumerate(partResData.unk);
2015-08-08 04:49:42 +00:00
if (sectionCount > 5)
{
writer.writeUint32Big(partResData.elsc.size());
2015-08-08 23:24:17 +00:00
writer.enumerate(partResData.elsc);
2015-08-08 04:49:42 +00:00
}
writer.writeUint32Big(unk1);
2015-08-08 04:49:42 +00:00
if (sectionCount > 1)
{
writer.writeUint32Big(animAABBs.size());
2015-08-08 23:24:17 +00:00
writer.enumerate(animAABBs);
2015-08-08 04:49:42 +00:00
}
if (sectionCount > 2)
{
writer.writeUint32Big(effects.size());
2015-08-08 23:24:17 +00:00
writer.enumerate(effects);
2015-08-08 04:49:42 +00:00
}
if (sectionCount > 3)
{
cmdlOverlay.UniqueID32::write(writer);
cskrOverlay.UniqueID32::write(writer);
2015-08-08 04:49:42 +00:00
}
if (sectionCount > 4)
{
writer.writeUint32Big(animIdxs.size());
2015-08-08 04:49:42 +00:00
for (atUint32 idx : animIdxs)
writer.writeUint32Big(idx);
2015-08-08 04:49:42 +00:00
}
}
size_t ANCS::CharacterSet::CharacterInfo::binarySize(size_t __isz) const
{
__isz += 6;
atUint16 sectionCount;
if (partResData.elsc.size())
sectionCount = 6;
else if (animIdxs.size())
sectionCount = 5;
else if (cmdlOverlay)
sectionCount = 4;
else if (effects.size())
sectionCount = 3;
else if (animAABBs.size())
sectionCount = 2;
else
sectionCount = 1;
__isz += name.size() + 1;
__isz += 12;
__isz += 4;
__isz = __EnumerateSize(__isz, animations);
__isz = pasDatabase.binarySize(__isz);
__isz += 4;
__isz = __EnumerateSize(__isz, partResData.part);
__isz += 4;
__isz = __EnumerateSize(__isz, partResData.swhc);
__isz += 4;
__isz = __EnumerateSize(__isz, partResData.unk);
if (sectionCount > 5)
{
__isz += 4;
__isz = __EnumerateSize(__isz, partResData.elsc);
}
__isz += 4;
if (sectionCount > 1)
{
__isz += 4;
__isz = __EnumerateSize(__isz, animAABBs);
}
if (sectionCount > 2)
{
__isz += 4;
__isz = __EnumerateSize(__isz, effects);
}
if (sectionCount > 3)
__isz += 8;
if (sectionCount > 4)
__isz += 4 + animIdxs.size() * 4;
return __isz;
}
2016-03-04 23:04:53 +00:00
void ANCS::CharacterSet::CharacterInfo::read(athena::io::YAMLDocReader& reader)
2015-08-08 04:49:42 +00:00
{
idx = reader.readUint32("idx");
atUint16 sectionCount = reader.readUint16("sectionCount");
name = reader.readString("name");
2015-08-08 23:24:17 +00:00
reader.enumerate("cmdl", cmdl);
2015-08-08 04:49:42 +00:00
2016-03-04 01:01:37 +00:00
reader.enumerate("animations", animations);
2015-08-08 04:49:42 +00:00
2015-08-08 23:24:17 +00:00
reader.enumerate("pasDatabase", pasDatabase);
2015-08-08 04:49:42 +00:00
2016-03-04 01:01:37 +00:00
reader.enumerate("part", partResData.part);
2015-08-08 04:49:42 +00:00
2016-03-04 01:01:37 +00:00
reader.enumerate("swhc", partResData.swhc);
2015-08-08 04:49:42 +00:00
2016-03-04 01:01:37 +00:00
reader.enumerate("unk", partResData.unk);
2015-08-08 04:49:42 +00:00
2015-08-08 23:24:17 +00:00
partResData.elsc.clear();
2015-08-08 04:49:42 +00:00
if (sectionCount > 5)
{
2016-03-04 01:01:37 +00:00
reader.enumerate("elsc", partResData.elsc);
2015-08-08 04:49:42 +00:00
}
unk1 = reader.readUint32("unk1");
animAABBs.clear();
if (sectionCount > 1)
{
2016-03-04 01:01:37 +00:00
reader.enumerate("part", animAABBs);
2015-08-08 04:49:42 +00:00
}
effects.clear();
if (sectionCount > 2)
{
2016-03-04 01:01:37 +00:00
reader.enumerate("effects", effects);
2015-08-08 04:49:42 +00:00
}
if (sectionCount > 3)
{
2015-09-26 03:12:08 +00:00
reader.enumerate("cmdlOverride", cmdlOverlay);
2015-08-08 04:49:42 +00:00
}
animIdxs.clear();
if (sectionCount > 4)
{
2016-03-04 01:01:37 +00:00
reader.enumerate("animIdxs", animIdxs);
2015-08-08 04:49:42 +00:00
}
}
2016-03-04 23:04:53 +00:00
void ANCS::CharacterSet::CharacterInfo::write(athena::io::YAMLDocWriter& writer) const
2015-08-08 04:49:42 +00:00
{
writer.writeUint32("idx", idx);
atUint16 sectionCount;
2015-08-15 04:12:15 +00:00
if (partResData.elsc.size())
2015-08-08 04:49:42 +00:00
sectionCount = 6;
else if (animIdxs.size())
sectionCount = 5;
2015-09-26 03:12:08 +00:00
else if (cmdlOverlay)
2015-08-08 04:49:42 +00:00
sectionCount = 4;
else if (effects.size())
sectionCount = 3;
else if (animAABBs.size())
sectionCount = 2;
else
sectionCount = 1;
writer.writeUint16("sectionCount", sectionCount);
writer.writeString("name", name);
2015-08-08 23:24:17 +00:00
writer.enumerate("cmdl", cmdl);
2015-08-08 04:49:42 +00:00
2015-08-08 23:24:17 +00:00
writer.enumerate("animations", animations);
2015-08-08 04:49:42 +00:00
2015-08-08 23:24:17 +00:00
writer.enumerate("pasDatabase", pasDatabase);
2015-08-08 04:49:42 +00:00
2015-08-08 23:24:17 +00:00
writer.enumerate("part", partResData.part);
2015-08-08 04:49:42 +00:00
2015-08-08 23:24:17 +00:00
writer.enumerate("swhc", partResData.swhc);
2015-08-08 04:49:42 +00:00
2015-08-08 23:24:17 +00:00
writer.enumerate("unk", partResData.unk);
2015-08-08 04:49:42 +00:00
if (sectionCount > 5)
{
2015-08-08 23:24:17 +00:00
writer.enumerate("elsc", partResData.elsc);
2015-08-08 04:49:42 +00:00
}
writer.writeUint32("unk1", unk1);
if (sectionCount > 1)
{
2015-08-08 23:24:17 +00:00
writer.enumerate("animAABBs", animAABBs);
2015-08-08 04:49:42 +00:00
}
if (sectionCount > 2)
{
2015-08-08 23:24:17 +00:00
writer.enumerate("effects", effects);
2015-08-08 04:49:42 +00:00
}
if (sectionCount > 3)
{
2015-09-26 03:12:08 +00:00
writer.enumerate("cmdlOverride", cmdlOverlay);
2015-08-08 04:49:42 +00:00
}
if (sectionCount > 4)
{
2015-08-08 23:24:17 +00:00
writer.enumerate("animIdxs", animIdxs);
2015-08-08 04:49:42 +00:00
}
}
2015-10-01 00:40:21 +00:00
const char* ANCS::CharacterSet::CharacterInfo::DNAType()
{
2016-03-04 23:04:53 +00:00
return "urde::DNAMP1::ANCS::CharacterSet::CharacterInfo";
2015-10-01 00:40:21 +00:00
}
2016-03-04 23:04:53 +00:00
void ANCS::AnimationSet::MetaAnimFactory::read(athena::io::IStreamReader& reader)
2015-08-08 04:49:42 +00:00
{
IMetaAnim::Type type(IMetaAnim::Type(reader.readUint32Big()));
2015-08-08 04:49:42 +00:00
switch (type)
{
2015-11-21 01:16:07 +00:00
case IMetaAnim::Type::Primitive:
2016-04-07 03:40:25 +00:00
m_anim.reset(new struct MetaAnimPrimitive);
2015-08-08 04:49:42 +00:00
m_anim->read(reader);
break;
2015-11-21 01:16:07 +00:00
case IMetaAnim::Type::Blend:
2016-04-07 03:40:25 +00:00
m_anim.reset(new struct MetaAnimBlend);
2015-08-08 04:49:42 +00:00
m_anim->read(reader);
break;
2015-11-21 01:16:07 +00:00
case IMetaAnim::Type::PhaseBlend:
2016-04-07 03:40:25 +00:00
m_anim.reset(new struct MetaAnimPhaseBlend);
2015-08-08 04:49:42 +00:00
m_anim->read(reader);
break;
2015-11-21 01:16:07 +00:00
case IMetaAnim::Type::Random:
2016-04-07 03:40:25 +00:00
m_anim.reset(new struct MetaAnimRandom);
2015-08-08 04:49:42 +00:00
m_anim->read(reader);
break;
2015-11-21 01:16:07 +00:00
case IMetaAnim::Type::Sequence:
2016-04-07 03:40:25 +00:00
m_anim.reset(new struct MetaAnimSequence);
2015-08-08 04:49:42 +00:00
m_anim->read(reader);
break;
default:
m_anim.reset(nullptr);
break;
}
}
2016-03-04 23:04:53 +00:00
void ANCS::AnimationSet::MetaAnimFactory::write(athena::io::IStreamWriter& writer) const
2015-08-08 04:49:42 +00:00
{
if (!m_anim)
return;
2015-11-21 01:16:07 +00:00
writer.writeInt32Big(atUint32(m_anim->m_type));
2015-08-08 04:49:42 +00:00
m_anim->write(writer);
}
size_t ANCS::AnimationSet::MetaAnimFactory::binarySize(size_t __isz) const
{
if (!m_anim)
return __isz;
return m_anim->binarySize(__isz + 4);
}
2016-03-04 23:04:53 +00:00
void ANCS::AnimationSet::MetaAnimFactory::read(athena::io::YAMLDocReader& reader)
2015-08-08 04:49:42 +00:00
{
std::string type = reader.readString("type");
std::transform(type.begin(), type.end(), type.begin(), tolower);
if (!type.compare("primitive"))
{
2016-04-07 03:40:25 +00:00
m_anim.reset(new struct MetaAnimPrimitive);
2016-01-04 05:31:02 +00:00
m_anim->read(reader);
2015-08-08 04:49:42 +00:00
}
else if (!type.compare("blend"))
{
2016-04-07 03:40:25 +00:00
m_anim.reset(new struct MetaAnimBlend);
2016-01-04 05:31:02 +00:00
m_anim->read(reader);
2015-08-08 04:49:42 +00:00
}
else if (!type.compare("phaseblend"))
{
2016-04-07 03:40:25 +00:00
m_anim.reset(new struct MetaAnimPhaseBlend);
2016-01-04 05:31:02 +00:00
m_anim->read(reader);
2015-08-08 04:49:42 +00:00
}
else if (!type.compare("random"))
{
2016-04-07 03:40:25 +00:00
m_anim.reset(new struct MetaAnimRandom);
2016-01-04 05:31:02 +00:00
m_anim->read(reader);
2015-08-08 04:49:42 +00:00
}
else if (!type.compare("sequence"))
{
2016-04-07 03:40:25 +00:00
m_anim.reset(new struct MetaAnimSequence);
2016-01-04 05:31:02 +00:00
m_anim->read(reader);
2015-08-08 04:49:42 +00:00
}
else
{
m_anim.reset(nullptr);
}
}
2016-03-04 23:04:53 +00:00
void ANCS::AnimationSet::MetaAnimFactory::write(athena::io::YAMLDocWriter& writer) const
2015-08-08 23:24:17 +00:00
{
if (!m_anim)
return;
writer.writeString("type", m_anim->m_typeStr);
2016-01-04 05:31:02 +00:00
m_anim->write(writer);
2015-08-08 23:24:17 +00:00
}
2015-10-01 00:40:21 +00:00
const char* ANCS::AnimationSet::MetaAnimFactory::DNAType()
{
2016-03-04 23:04:53 +00:00
return "urde::DNAMP1::ANCS::AnimationSet::MetaAnimFactory";
2015-10-01 00:40:21 +00:00
}
2016-03-04 23:04:53 +00:00
void ANCS::AnimationSet::MetaTransFactory::read(athena::io::IStreamReader& reader)
2015-08-08 04:49:42 +00:00
{
IMetaTrans::Type type(IMetaTrans::Type(reader.readUint32Big()));
2015-08-08 04:49:42 +00:00
switch (type)
{
2015-11-21 01:16:07 +00:00
case IMetaTrans::Type::MetaAnim:
2016-04-07 03:40:25 +00:00
m_trans.reset(new struct MetaTransMetaAnim);
2015-08-08 04:49:42 +00:00
m_trans->read(reader);
break;
2015-11-21 01:16:07 +00:00
case IMetaTrans::Type::Trans:
2016-04-07 03:40:25 +00:00
m_trans.reset(new struct MetaTransTrans);
2015-08-08 04:49:42 +00:00
m_trans->read(reader);
break;
2015-11-21 01:16:07 +00:00
case IMetaTrans::Type::PhaseTrans:
2016-04-07 03:40:25 +00:00
m_trans.reset(new struct MetaTransPhaseTrans);
2015-08-08 04:49:42 +00:00
m_trans->read(reader);
break;
2015-11-21 01:16:07 +00:00
case IMetaTrans::Type::NoTrans:
2015-08-08 04:49:42 +00:00
default:
m_trans.reset(nullptr);
break;
}
}
2016-03-04 23:04:53 +00:00
void ANCS::AnimationSet::MetaTransFactory::write(athena::io::IStreamWriter& writer) const
2015-08-08 04:49:42 +00:00
{
if (!m_trans)
{
2015-11-21 01:16:07 +00:00
writer.writeInt32Big(atUint32(IMetaTrans::Type::NoTrans));
2015-08-08 04:49:42 +00:00
return;
}
2015-11-21 01:16:07 +00:00
writer.writeInt32Big(atUint32(m_trans->m_type));
2015-08-08 04:49:42 +00:00
m_trans->write(writer);
}
size_t ANCS::AnimationSet::MetaTransFactory::binarySize(size_t __isz) const
{
if (!m_trans)
return __isz + 4;
return m_trans->binarySize(__isz + 4);
}
2016-03-04 23:04:53 +00:00
void ANCS::AnimationSet::MetaTransFactory::read(athena::io::YAMLDocReader& reader)
2015-08-08 04:49:42 +00:00
{
std::string type = reader.readString("type");
std::transform(type.begin(), type.end(), type.begin(), tolower);
if (!type.compare("metaanim"))
{
2016-04-07 03:40:25 +00:00
m_trans.reset(new struct MetaTransMetaAnim);
2016-01-04 05:31:02 +00:00
m_trans->read(reader);
2015-08-08 04:49:42 +00:00
}
else if (!type.compare("trans"))
{
2016-04-07 03:40:25 +00:00
m_trans.reset(new struct MetaTransTrans);
2016-01-04 05:31:02 +00:00
m_trans->read(reader);
2015-08-08 04:49:42 +00:00
}
else if (!type.compare("phasetrans"))
{
2016-04-07 03:40:25 +00:00
m_trans.reset(new struct MetaTransPhaseTrans);
2016-01-04 05:31:02 +00:00
m_trans->read(reader);
2015-08-08 04:49:42 +00:00
}
else
{
m_trans.reset(nullptr);
}
}
2016-03-04 23:04:53 +00:00
void ANCS::AnimationSet::MetaTransFactory::write(athena::io::YAMLDocWriter& writer) const
2015-08-08 04:49:42 +00:00
{
if (!m_trans)
{
writer.writeString("type", "NoTrans");
return;
}
writer.writeString("type", m_trans->m_typeStr?m_trans->m_typeStr:"NoTrans");
2016-01-04 05:31:02 +00:00
m_trans->write(writer);
2015-08-08 04:49:42 +00:00
}
2015-10-01 00:40:21 +00:00
const char* ANCS::AnimationSet::MetaTransFactory::DNAType()
{
2016-03-04 23:04:53 +00:00
return "urde::DNAMP1::ANCS::AnimationSet::MetaTransFactory";
2015-10-01 00:40:21 +00:00
}
2016-03-04 23:04:53 +00:00
void ANCS::AnimationSet::read(athena::io::IStreamReader& reader)
2015-08-08 04:49:42 +00:00
{
atUint16 sectionCount = reader.readUint16Big();
2015-08-08 04:49:42 +00:00
atUint32 animationCount = reader.readUint32Big();
2016-04-07 03:40:25 +00:00
reader.enumerate(animations, animationCount);
2015-08-08 04:49:42 +00:00
atUint32 transitionCount = reader.readUint32Big();
2016-04-07 03:40:25 +00:00
reader.enumerate(transitions, transitionCount);
2015-08-08 23:24:17 +00:00
defaultTransition.read(reader);
2015-08-08 04:49:42 +00:00
2015-08-08 23:24:17 +00:00
additiveAnims.clear();
2015-08-08 04:49:42 +00:00
if (sectionCount > 1)
{
atUint32 additiveAnimCount = reader.readUint32Big();
2015-08-08 23:24:17 +00:00
reader.enumerate(additiveAnims, additiveAnimCount);
floatA = reader.readFloatBig();
floatB = reader.readFloatBig();
2015-08-08 04:49:42 +00:00
}
2015-08-08 23:24:17 +00:00
halfTransitions.clear();
2015-08-08 04:49:42 +00:00
if (sectionCount > 2)
{
2016-04-07 03:40:25 +00:00
atUint32 halfTransitionCount = reader.readUint32Big();
reader.enumerate(halfTransitions, halfTransitionCount);
2015-08-08 04:49:42 +00:00
}
2015-08-08 23:24:17 +00:00
animResources.clear();
2015-08-08 04:49:42 +00:00
if (sectionCount > 3)
{
atUint32 animResourcesCount = reader.readUint32Big();
2015-08-08 23:24:17 +00:00
reader.enumerate(animResources, animResourcesCount);
2015-08-08 04:49:42 +00:00
}
}
2016-03-04 23:04:53 +00:00
void ANCS::AnimationSet::write(athena::io::IStreamWriter& writer) const
2015-08-08 04:49:42 +00:00
{
atUint16 sectionCount;
if (animResources.size())
sectionCount = 4;
else if (halfTransitions.size())
sectionCount = 3;
else if (additiveAnims.size())
sectionCount = 2;
else
sectionCount = 1;
writer.writeUint16Big(sectionCount);
2015-08-08 04:49:42 +00:00
writer.writeUint32Big(animations.size());
2015-08-08 23:24:17 +00:00
writer.enumerate(animations);
2015-08-08 04:49:42 +00:00
writer.writeUint32Big(transitions.size());
2015-08-08 23:24:17 +00:00
writer.enumerate(transitions);
defaultTransition.write(writer);
2015-08-08 04:49:42 +00:00
if (sectionCount > 1)
{
writer.writeUint32Big(additiveAnims.size());
2015-08-08 23:24:17 +00:00
writer.enumerate(additiveAnims);
writer.writeFloatBig(floatA);
writer.writeFloatBig(floatB);
2015-08-08 04:49:42 +00:00
}
if (sectionCount > 2)
{
writer.writeUint32Big(halfTransitions.size());
2015-08-08 23:24:17 +00:00
writer.enumerate(halfTransitions);
2015-08-08 04:49:42 +00:00
}
if (sectionCount > 3)
{
writer.writeUint32Big(animResources.size());
2015-08-08 23:24:17 +00:00
writer.enumerate(animResources);
2015-08-08 04:49:42 +00:00
}
}
size_t ANCS::AnimationSet::binarySize(size_t __isz) const
{
atUint16 sectionCount;
if (animResources.size())
sectionCount = 4;
else if (halfTransitions.size())
sectionCount = 3;
else if (additiveAnims.size())
sectionCount = 2;
else
sectionCount = 1;
__isz += 6;
__isz = __EnumerateSize(__isz, animations);
__isz += 4;
__isz = __EnumerateSize(__isz, transitions);
__isz = defaultTransition.binarySize(__isz);
if (sectionCount > 1)
{
__isz += 4;
__isz = __EnumerateSize(__isz, additiveAnims);
__isz += 8;
}
if (sectionCount > 2)
{
__isz += 4;
__isz = __EnumerateSize(__isz, halfTransitions);
}
if (sectionCount > 3)
{
__isz += 4;
__isz = __EnumerateSize(__isz, animResources);
}
return __isz;
}
2016-03-04 23:04:53 +00:00
void ANCS::AnimationSet::read(athena::io::YAMLDocReader& reader)
2015-08-08 04:49:42 +00:00
{
atUint16 sectionCount = reader.readUint16("sectionCount");
2016-04-07 03:40:25 +00:00
reader.enumerate("animations", animations);
2015-08-08 04:49:42 +00:00
2016-04-07 03:40:25 +00:00
reader.enumerate("transitions", transitions);
2015-08-08 23:24:17 +00:00
reader.enumerate("defaultTransition", defaultTransition);
2015-08-08 04:49:42 +00:00
2015-08-08 23:24:17 +00:00
additiveAnims.clear();
2015-08-08 04:49:42 +00:00
if (sectionCount > 1)
{
2016-03-04 01:01:37 +00:00
reader.enumerate("additiveAnims", additiveAnims);
2015-08-08 04:49:42 +00:00
floatA = reader.readFloat("floatA");
floatB = reader.readFloat("floatB");
}
2015-08-08 23:24:17 +00:00
halfTransitions.clear();
2015-08-08 04:49:42 +00:00
if (sectionCount > 2)
{
2016-04-07 03:40:25 +00:00
reader.enumerate("halfTransitions", halfTransitions);
2015-08-08 04:49:42 +00:00
}
2015-08-08 23:24:17 +00:00
animResources.clear();
2015-08-08 04:49:42 +00:00
if (sectionCount > 3)
{
2016-03-04 01:01:37 +00:00
reader.enumerate("animResources", animResources);
2015-08-08 04:49:42 +00:00
}
}
2016-03-04 23:04:53 +00:00
void ANCS::AnimationSet::write(athena::io::YAMLDocWriter& writer) const
2015-08-08 04:49:42 +00:00
{
atUint16 sectionCount;
if (animResources.size())
sectionCount = 4;
else if (halfTransitions.size())
sectionCount = 3;
else if (additiveAnims.size())
sectionCount = 2;
else
sectionCount = 1;
writer.writeUint16("sectionCount", sectionCount);
2015-08-08 23:24:17 +00:00
writer.enumerate("animations", animations);
2015-08-08 04:49:42 +00:00
2015-08-08 23:24:17 +00:00
writer.enumerate("transitions", transitions);
writer.enumerate("defaultTransition", defaultTransition);
2015-08-08 04:49:42 +00:00
if (sectionCount > 1)
{
2015-08-08 23:24:17 +00:00
writer.enumerate("additiveAnims", additiveAnims);
2015-08-08 04:49:42 +00:00
writer.writeFloat("floatA", floatA);
writer.writeFloat("floatB", floatB);
}
if (sectionCount > 2)
{
2015-08-08 23:24:17 +00:00
writer.enumerate("halfTransitions", halfTransitions);
2015-08-08 04:49:42 +00:00
}
if (sectionCount > 3)
{
2015-08-08 23:24:17 +00:00
writer.enumerate("animResources", animResources);
2015-08-08 04:49:42 +00:00
}
}
2015-10-01 00:40:21 +00:00
const char* ANCS::AnimationSet::DNAType()
{
2016-03-04 23:04:53 +00:00
return "urde::DNAMP1::ANCS::AnimationSet";
2015-10-01 00:40:21 +00:00
}
2016-04-10 04:49:02 +00:00
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)
{
2016-09-18 23:47:48 +00:00
hecl::ProjectPath yamlPath = outPath.getWithExtension(_S(".yaml"), true);
2016-04-10 04:49:02 +00:00
hecl::ProjectPath::Type yamlType = yamlPath.getPathType();
2016-09-18 23:47:48 +00:00
hecl::ProjectPath blendPath = outPath.getWithExtension(_S(".blend"), true);
2016-04-10 04:49:02 +00:00
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)
{
2016-08-22 03:47:48 +00:00
athena::io::FileWriter writer(yamlPath.getAbsolutePath());
ancs.toYAMLStream(writer);
2016-04-10 04:49:02 +00:00
}
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() +
2016-09-18 23:47:48 +00:00
_S(".evnt.yaml")).c_str(), true);
2016-04-10 04:49:02 +00:00
hecl::ProjectPath::Type evntYamlType = evntYamlPath.getPathType();
if (force || evntYamlType == hecl::ProjectPath::Type::None)
{
EVNT evnt;
if (pakRouter.lookupAndReadDNA(res.second.evntId, evnt, true))
{
2016-08-22 03:47:48 +00:00
athena::io::FileWriter writer(evntYamlPath.getAbsolutePath());
evnt.toYAMLStream(writer);
2016-04-10 04:49:02 +00:00
}
}
}
}
return true;
}
bool ANCS::Cook(const hecl::ProjectPath& outPath,
const hecl::ProjectPath& inPath,
const DNAANCS::Actor& actor,
2016-08-22 00:11:18 +00:00
hecl::BlenderConnection::DataStream& ds,
bool pc,
2016-04-10 04:49:02 +00:00
const std::function<bool(const hecl::ProjectPath& modelPath)>& modelCookFunc)
{
/* Search for yaml */
hecl::ProjectPath yamlPath = inPath.getWithExtension(_S(".yaml"), true);
2016-09-18 23:47:48 +00:00
if (!yamlPath.isFile())
2016-04-10 04:49:02 +00:00
Log.report(logvisor::Fatal, _S("'%s' not found as file"),
yamlPath.getRelativePath().c_str());
2016-08-22 03:47:48 +00:00
athena::io::FileReader reader(yamlPath.getAbsolutePath());
if (!reader.isOpen())
2016-08-21 20:39:18 +00:00
Log.report(logvisor::Fatal, _S("can't open '%s' for reading"),
yamlPath.getRelativePath().c_str());
2016-08-22 03:47:48 +00:00
if (!BigYAML::ValidateFromYAMLStream<ANCS>(reader))
2016-08-21 20:39:18 +00:00
{
2016-04-10 04:49:02 +00:00
Log.report(logvisor::Fatal, _S("'%s' is not urde::DNAMP1::ANCS type"),
yamlPath.getRelativePath().c_str());
2016-08-21 20:39:18 +00:00
}
athena::io::YAMLDocReader yamlReader;
2016-08-22 03:47:48 +00:00
if (!yamlReader.parse(&reader))
2016-08-21 20:39:18 +00:00
{
Log.report(logvisor::Fatal, _S("unable to parse '%s'"),
yamlPath.getRelativePath().c_str());
}
2016-04-10 04:49:02 +00:00
ANCS ancs;
ancs.read(yamlReader);
/* Set Character Resource IDs */
for (ANCS::CharacterSet::CharacterInfo& ch : ancs.characterSet.characters)
{
ch.cmdl = UniqueID32{};
ch.cskr = UniqueID32{};
ch.cinf = UniqueID32{};
ch.cmdlOverlay = UniqueID32{};
ch.cskrOverlay = UniqueID32{};
hecl::SystemStringView chSysName(ch.name);
ch.cskr = inPath.ensureAuxInfo(chSysName.sys_str() + _S(".CSKR"));
2016-04-10 04:49:02 +00:00
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 armSysName(arm.name);
ch.cinf = inPath.ensureAuxInfo(armSysName.sys_str() + _S(".CINF"));
ch.cmdl = sub.mesh;
if (sub.overlayMeshes.size())
{
ch.cmdlOverlay = sub.overlayMeshes[0].second;
ch.cskrOverlay = inPath.ensureAuxInfo(chSysName.sys_str() + _S(".over.CSKR"));
}
2016-04-10 04:49:02 +00:00
break;
}
}
}
}
/* Set Animation Resource IDs */
ancs.enumeratePrimitives([&](AnimationSet::MetaAnimPrimitive& prim) -> bool
{
hecl::SystemStringView sysStr(prim.animName);
hecl::ProjectPath pathOut = inPath.ensureAuxInfo(sysStr.sys_str() + _S(".ANIM"));
2016-04-10 04:49:02 +00:00
prim.animId = pathOut;
return true;
});
std::unordered_map<std::string, atInt32> boneIdMap;
2016-09-06 05:52:51 +00:00
std::experimental::optional<CINF> rigCinf;
2016-08-22 00:11:18 +00:00
std::experimental::optional<DNAANIM::RigInverter<CINF>> rigInv;
2016-04-10 04:49:02 +00:00
/* Write out CINF resources */
for (const DNAANCS::Actor::Armature& arm : actor.armatures)
2016-08-22 00:11:18 +00:00
{
2016-04-10 04:49:02 +00:00
hecl::SystemStringView sysStr(arm.name);
hecl::ProjectPath pathOut = inPath.ensureAuxInfo(sysStr.sys_str() + _S(".CINF")).getCookedPath(SpecEntMP1);
2016-10-08 03:41:08 +00:00
pathOut.makeDirChain(false);
2016-04-10 04:49:02 +00:00
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);
2016-08-22 00:11:18 +00:00
if (!rigInv)
{
2016-09-06 05:52:51 +00:00
rigCinf.emplace(cinf);
2016-08-22 00:11:18 +00:00
auto matrices = ds.getBoneMatrices(arm.name);
2016-09-06 05:52:51 +00:00
rigInv.emplace(*rigCinf, matrices);
2016-08-22 00:11:18 +00:00
}
2016-04-10 04:49:02 +00:00
}
2016-08-22 00:11:18 +00:00
ds.close();
2016-04-10 04:49:02 +00:00
/* Write out CSKR resources */
for (ANCS::CharacterSet::CharacterInfo& ch : ancs.characterSet.characters)
{
2016-08-22 00:11:18 +00:00
const DNAANCS::Actor::Subtype* subtype = nullptr;
for (const DNAANCS::Actor::Subtype& sub : actor.subtypes)
{
if (!sub.name.compare(ch.name))
{
subtype = &sub;
break;
}
}
if (!subtype)
Log.report(logvisor::Fatal, "unable to find subtype '%s'", ch.name.c_str());
const hecl::ProjectPath& modelPath = subtype->mesh;
2016-04-10 04:49:02 +00:00
2016-09-18 23:47:48 +00:00
if (!modelPath.isFile())
Log.report(logvisor::Fatal, _S("unable to resolve '%s'"), modelPath.getRelativePath().c_str());
2016-04-10 04:49:02 +00:00
hecl::ProjectPath skinIntPath = modelPath.getCookedPath(SpecEntMP1PC).getWithExtension(_S(".skinint"));
2016-09-18 23:47:48 +00:00
if (!skinIntPath.isFileOrGlob() || skinIntPath.getModtime() < modelPath.getModtime())
if (!modelCookFunc(modelPath))
Log.report(logvisor::Fatal, _S("unable to cook '%s'"), modelPath.getRelativePath().c_str());
2016-04-10 04:49:02 +00:00
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::SystemStringView sysStr(ch.name);
hecl::ProjectPath skinPath = inPath.ensureAuxInfo(sysStr.sys_str() + _S(".CSKR")).getCookedPath(SpecEntMP1PC);
2016-10-08 03:41:08 +00:00
skinPath.makeDirChain(false);
2016-04-10 04:49:02 +00:00
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.ensureAuxInfo(sysStr.sys_str() + _S(".ANIM"));
hecl::ProjectPath cookedOut = pathOut.getCookedPath(SpecEntMP1PC);
2016-10-08 03:41:08 +00:00
cookedOut.makeDirChain(false);
2016-08-22 00:11:18 +00:00
athena::io::FileWriter w(cookedOut.getAbsolutePath(), true, false);
2016-04-10 04:49:02 +00:00
if (w.hasError())
Log.report(logvisor::Fatal, _S("unable to open '%s' for writing"),
2016-08-22 00:11:18 +00:00
cookedOut.getRelativePath().c_str());
ANIM anim(act, boneIdMap, *rigInv, pc);
2016-04-10 04:49:02 +00:00
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);
2016-09-18 23:47:48 +00:00
if (evntYamlPath.isFile())
2016-04-10 04:49:02 +00:00
{
2016-08-22 03:47:48 +00:00
athena::io::FileReader reader(evntYamlPath.getAbsolutePath());
if (reader.isOpen())
2016-04-10 04:49:02 +00:00
{
EVNT evnt;
2016-08-22 03:47:48 +00:00
evnt.fromYAMLStream(reader);
2016-04-10 04:49:02 +00:00
hecl::ProjectPath evntCookedOut = evntYamlPath.getCookedPath(SpecEntMP1);
2016-10-08 03:41:08 +00:00
evntCookedOut.makeDirChain(false);
athena::io::FileWriter w(evntCookedOut.getAbsolutePath(), true, false);
2016-04-10 04:49:02 +00:00
if (w.hasError())
Log.report(logvisor::Fatal, _S("unable to open '%s' for writing"),
evntCookedOut.getRelativePath().c_str());
2016-04-10 04:49:02 +00:00
evnt.write(w);
ancs.animationSet.animResources.back().evntId = evntYamlPath;
anim.m_anim->evnt = evntYamlPath;
2016-04-10 04:49:02 +00:00
}
}
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;
}
2015-08-08 04:49:42 +00:00
}
}