From 47907e83774ee8686ee767cfefe7f53a3ad45f39 Mon Sep 17 00:00:00 2001 From: Kawe Mazidjatari <48657826+Mauler125@users.noreply.github.com> Date: Tue, 3 Dec 2024 20:18:39 +0100 Subject: [PATCH] Deduplicate code shared between animrig, animseq and models Model_AddSequenceRefs and AnimRig_AddSequenceRefs have been deduplicated into AnimSeq_AddSequenceRefs. --- src/assets/animrig.cpp | 45 ++-------------------- src/assets/animseq.cpp | 57 +++++++++++++++++++++++++++ src/assets/model.cpp | 87 +++++++----------------------------------- src/public/animrig.h | 2 +- 4 files changed, 74 insertions(+), 117 deletions(-) diff --git a/src/assets/animrig.cpp b/src/assets/animrig.cpp index 1f83fde6..057b096b 100644 --- a/src/assets/animrig.cpp +++ b/src/assets/animrig.cpp @@ -4,46 +4,7 @@ #include "public/material.h" #include -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 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(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); @@ -73,13 +34,13 @@ void Assets::AddAnimRigAsset_v4(CPakFile* const pak, const char* const assetPath std::vector 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)); } diff --git a/src/assets/animseq.cpp b/src/assets/animseq.cpp index db05e45a..e7de130b 100644 --- a/src/assets/animseq.cpp +++ b/src/assets/animseq.cpp @@ -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(numSequences); + std::vector 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(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 diff --git a/src/assets/model.cpp b/src/assets/model.cpp index 5ffe139c..0946c917 100644 --- a/src/assets/model.cpp +++ b/src/assets/model.cpp @@ -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 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(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) { @@ -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(guid); @@ -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(); @@ -298,13 +240,10 @@ 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; } @@ -312,10 +251,10 @@ void Assets::AddModelAsset_v9(CPakFile* const pak, const char* const assetPath, if (tex->guid != 0) { - size_t pos = (char*)tex - pDataBuf; - pak->AddGuidDescriptor(&guids, dataChunk.GetPointer(static_cast(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) { @@ -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); diff --git a/src/public/animrig.h b/src/public/animrig.h index 05855747..7c80d543 100644 --- a/src/public/animrig.h +++ b/src/public/animrig.h @@ -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]; };