Skip to content

Commit

Permalink
Deduplicate code shared between animrig, animseq and models
Browse files Browse the repository at this point in the history
Model_AddSequenceRefs and AnimRig_AddSequenceRefs have been deduplicated into AnimSeq_AddSequenceRefs.
  • Loading branch information
Mauler125 committed Dec 3, 2024
1 parent f00ffb7 commit 47907e8
Show file tree
Hide file tree
Showing 4 changed files with 74 additions and 117 deletions.
45 changes: 3 additions & 42 deletions src/assets/animrig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,46 +4,7 @@
#include "public/material.h"
#include <public/animrig.h>

bool AnimRig_AddSequenceRefs(CPakDataChunk* chunk, CPakFile* pak, AnimRigAssetHeader_t* hdr, const rapidjson::Value& mapEntry)
{
rapidjson::Value::ConstMemberIterator it;

if (!JSON_GetIterator(mapEntry, "sequences", JSONFieldType_e::kArray, it))
return false;

std::vector<PakGuid_t> sequenceGuids;

for (const auto& sequenceElem : it->value.GetArray())
{
if (!sequenceElem.IsString())
continue;

if (sequenceElem.GetStringLength() == 0)
continue;

PakGuid_t guid;

if (!JSON_ParseNumber(sequenceElem, guid))
{
guid = RTech::StringToGuid(sequenceElem.GetString());
Assets::AddAnimSeqAsset(pak, guid, sequenceElem.GetString());
}

sequenceGuids.emplace_back(guid);
hdr->sequenceCount++;
}

CPakDataChunk guidsChunk = pak->CreateDataChunk(sizeof(PakGuid_t) * sequenceGuids.size(), SF_CPU, 64);

PakGuid_t* const pGuids = reinterpret_cast<PakGuid_t*>(guidsChunk.Data());
for (int i = 0; i < sequenceGuids.size(); ++i)
{
pGuids[i] = sequenceGuids[i];
}

*chunk = guidsChunk;
return true;
}
extern bool AnimSeq_AddSequenceRefs(CPakDataChunk* const chunk, CPakFile* const pak, uint32_t* const sequenceCount, const rapidjson::Value& mapEntry);

// anim rigs are stored in rmdl's. use this to read it out.
extern char* Model_ReadRMDLFile(const std::string& path);
Expand Down Expand Up @@ -73,13 +34,13 @@ void Assets::AddAnimRigAsset_v4(CPakFile* const pak, const char* const assetPath

std::vector<PakGuidRefHdr_t> guids{};
CPakDataChunk guidsChunk;
if (AnimRig_AddSequenceRefs(&guidsChunk, pak, pHdr, mapEntry))
if (AnimSeq_AddSequenceRefs(&guidsChunk, pak, &pHdr->sequenceCount, mapEntry))
{
pHdr->pSequences = guidsChunk.GetPointer();

pak->AddPointer(hdrChunk.GetPointer(offsetof(AnimRigAssetHeader_t, pSequences)));

for (int i = 0; i < pHdr->sequenceCount; ++i)
for (uint32_t i = 0; i < pHdr->sequenceCount; ++i)
{
guids.emplace_back(guidsChunk.GetPointer(8 * i));
}
Expand Down
57 changes: 57 additions & 0 deletions src/assets/animseq.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,63 @@
#include "assets.h"
#include "public/studio.h"

bool AnimSeq_AddSequenceRefs(CPakDataChunk* const chunk, CPakFile* const pak, uint32_t* const sequenceCount, const rapidjson::Value& mapEntry)
{
rapidjson::Value::ConstMemberIterator sequencesIt;
const bool hasSequences = JSON_GetIterator(mapEntry, "$sequences", JSONFieldType_e::kArray, sequencesIt);

if (!hasSequences)
return false;

const rapidjson::Value::ConstArray sequencesArray = sequencesIt->value.GetArray();
const size_t numSequences = sequencesArray.Size();

(*sequenceCount) = static_cast<uint32_t>(numSequences);
std::vector<PakGuid_t> sequenceGuids(numSequences);

int seqIndex = -1;
for (const auto& sequence : sequencesArray)
{
seqIndex++;
PakGuid_t guid;

if (!JSON_ParseNumber(sequence, guid))
{
if (!sequence.IsString())
Error("Sequence #%i is of unsupported type; expected %s or %s, found %s.\n", seqIndex,
JSON_TypeToString(JSONFieldType_e::kUint64), JSON_TypeToString(JSONFieldType_e::kString),
JSON_TypeToString(JSON_ExtractType(sequence)));

if (sequence.GetStringLength() == 0)
Error("Sequence #%i was defined as an invalid empty string.\n", seqIndex);

const char* const sequencePath = sequence.GetString();
Log("Auto-adding aseq asset \"%s\".\n", sequencePath);

guid = RTech::StringToGuid(sequencePath);
Assets::AddAnimSeqAsset(pak, guid, sequencePath);
}

sequenceGuids[seqIndex] = guid;

// note(amos): initially this was incremented from whatever we had before
// however since we read and write up to the chunk size, it should be set
// to the total number of sequences we're going to add here.
//(*sequenceCount)++;
}

CPakDataChunk guidsChunk = pak->CreateDataChunk(sizeof(PakGuid_t) * numSequences, SF_CPU, 64);
PakGuid_t* const pGuids = reinterpret_cast<PakGuid_t*>(guidsChunk.Data());

for (size_t i = 0; i < numSequences; ++i)
{
pGuids[i] = sequenceGuids[i];
}

*chunk = guidsChunk;
return true;
}

void Assets::AddAnimSeqAsset(CPakFile* const pak, const PakGuid_t guidOverride, const char* const assetPath)
{
const PakGuid_t assetGuid = guidOverride != 0
Expand Down
87 changes: 13 additions & 74 deletions src/assets/model.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -60,63 +60,7 @@ char* Model_ReadVGFile(const std::string& path, size_t* const pFileSize)
return buf;
}

static void Model_CheckAssetRef(const rapidjson::Value& val, const char* assetType, const int index)
{
if (!val.IsNumber())
{
if (!val.IsString())
Error("%s #%i is of unsupported type; expected %s or %s, found %s\n", assetType, index,
JSON_TypeToString(JSONFieldType_e::kUint64), JSON_TypeToString(JSONFieldType_e::kString),
JSON_TypeToString(JSON_ExtractType(val)));

if (val.GetStringLength() == 0)
Error("%s #%i was defined as an invalid empty string\n", assetType, index);
}
}

bool Model_AddSequenceRefs(CPakDataChunk* chunk, CPakFile* pak, ModelAssetHeader_t* hdr, const rapidjson::Value& mapEntry)
{
rapidjson::Value::ConstMemberIterator sequencesIt;
const bool hasSequences = JSON_GetIterator(mapEntry, "$sequences", JSONFieldType_e::kArray, sequencesIt);

if (!hasSequences)
return false;

const rapidjson::Value::ConstArray sequencesArray = sequencesIt->value.GetArray();
std::vector<PakGuid_t> sequenceGuids;

int seqIndex = -1;
for (const auto& sequence : sequencesArray)
{
seqIndex++;
Model_CheckAssetRef(sequence, "sequence", seqIndex);

PakGuid_t guid;

if (!JSON_ParseNumber(sequence, guid))
{
const char* const sequencePath = sequence.GetString();
Log("Auto-adding aseq asset \"%s\".\n", sequencePath);

guid = RTech::StringToGuid(sequencePath);
Assets::AddAnimSeqAsset(pak, guid, sequencePath);
}

sequenceGuids.emplace_back(guid);
hdr->sequenceCount++;
}

CPakDataChunk guidsChunk = pak->CreateDataChunk(sizeof(PakGuid_t) * sequenceGuids.size(), SF_CPU, 64);

PakGuid_t* pGuids = reinterpret_cast<PakGuid_t*>(guidsChunk.Data());
for (size_t i = 0; i < sequenceGuids.size(); ++i)
{
pGuids[i] = sequenceGuids[i];
}

*chunk = guidsChunk;
return true;
}
extern bool AnimSeq_AddSequenceRefs(CPakDataChunk* const chunk, CPakFile* const pak, uint32_t* const sequenceCount, const rapidjson::Value& mapEntry);

void Assets::AddModelAsset_v9(CPakFile* const pak, const char* const assetPath, const rapidjson::Value& mapEntry)
{
Expand Down Expand Up @@ -186,12 +130,10 @@ void Assets::AddModelAsset_v9(CPakFile* const pak, const char* const assetPath,
for (const auto& animrig : animrigs)
{
i++;
Model_CheckAssetRef(animrig, "animrig", i);

PakGuid_t guid;
const PakGuid_t guid = Pak_ParseGuid(animrig);

if (!JSON_ParseNumber(animrig, guid))
guid = RTech::StringToGuid(animrig.GetString());
if (!guid)
Error("Unable to parse animrig #%i\n", i);

arigBuf.write<PakGuid_t>(guid);

Expand All @@ -211,7 +153,7 @@ void Assets::AddModelAsset_v9(CPakFile* const pak, const char* const assetPath,
}

CPakDataChunk sequencesChunk;
if (Model_AddSequenceRefs(&sequencesChunk, pak, pHdr, mapEntry))
if (AnimSeq_AddSequenceRefs(&sequencesChunk, pak, &pHdr->sequenceCount, mapEntry))
{
pHdr->pSequences = sequencesChunk.GetPointer();

Expand Down Expand Up @@ -298,24 +240,21 @@ void Assets::AddModelAsset_v9(CPakFile* const pak, const char* const assetPath,

if (materialArray.Size() > i)
{
const rapidjson::Value& matlEntry = materialArray[i];
Model_CheckAssetRef(matlEntry, "material", i);

PakGuid_t guid;
const PakGuid_t guid = Pak_ParseGuid(materialArray[i]);

if (!JSON_ParseNumber(matlEntry, guid))
guid = RTech::StringToGuid(matlEntry.GetString());
if (!guid)
Error("Unable to parse material #%i\n", i);

tex->guid = guid;
}
}

if (tex->guid != 0)
{
size_t pos = (char*)tex - pDataBuf;
pak->AddGuidDescriptor(&guids, dataChunk.GetPointer(static_cast<int>(pos) + offsetof(mstudiotexture_t, guid)));
const size_t pos = (char*)tex - pDataBuf;
pak->AddGuidDescriptor(&guids, dataChunk.GetPointer(pos + offsetof(mstudiotexture_t, guid)));

PakAsset_t* asset = pak->GetAssetByGuid(tex->guid);
PakAsset_t* const asset = pak->GetAssetByGuid(tex->guid);

if (asset)
{
Expand All @@ -327,8 +266,8 @@ void Assets::AddModelAsset_v9(CPakFile* const pak, const char* const assetPath,

if (matlHdr->materialType != studiohdr->materialType(i))
{
Warning("Setting material of unexpected type in material slot %i for model asset '%s'. Expected type '%s', found material with type '%s'.\n",
i, assetPath, s_materialShaderTypeNames[studiohdr->materialType(i)], s_materialShaderTypeNames[matlHdr->materialType]);
Error("Unexpected shader type for material in slot #%i, expected '%s', found '%s'.\n",
i, s_materialShaderTypeNames[studiohdr->materialType(i)], s_materialShaderTypeNames[matlHdr->materialType]);
}

pak->SetCurrentAssetAsDependentForAsset(asset);
Expand Down
2 changes: 1 addition & 1 deletion src/public/animrig.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ struct AnimRigAssetHeader_t
PagePtr_t data;
PagePtr_t name;
char gap_10[4];
int sequenceCount;
uint32_t sequenceCount;
PagePtr_t pSequences;
char gap_20[8];
};
Expand Down

0 comments on commit 47907e8

Please sign in to comment.