mirror of https://github.com/AxioDL/metaforce.git
Correct handling of empty skinned models
This commit is contained in:
parent
3f7431286c
commit
87e5aea6f5
|
@ -1345,43 +1345,45 @@ bool ANCS::CookCSKR(const hecl::ProjectPath& outPath,
|
||||||
if (!modelCookFunc(*modelPath))
|
if (!modelCookFunc(*modelPath))
|
||||||
Log.report(logvisor::Fatal, _SYS_STR("unable to cook '%s'"), modelPath->getRelativePath().data());
|
Log.report(logvisor::Fatal, _SYS_STR("unable to cook '%s'"), modelPath->getRelativePath().data());
|
||||||
|
|
||||||
athena::io::FileReader skinIO(skinIntPath.getAbsolutePath(), 1024*32, false);
|
|
||||||
if (skinIO.hasError())
|
|
||||||
Log.report(logvisor::Fatal, _SYS_STR("unable to open '%s'"), skinIntPath.getRelativePath().data());
|
|
||||||
|
|
||||||
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());
|
|
||||||
|
|
||||||
std::vector<std::pair<std::vector<std::pair<uint32_t, float>>, uint32_t>> skins;
|
std::vector<std::pair<std::vector<std::pair<uint32_t, float>>, uint32_t>> skins;
|
||||||
uint32_t skinCount = skinIO.readUint32Big();
|
uint32_t posCount = 0;
|
||||||
skins.resize(skinCount);
|
uint32_t normCount = 0;
|
||||||
for (uint32_t i=0 ; i<skinCount ; ++i)
|
athena::io::FileReader skinIO(skinIntPath.getAbsolutePath(), 1024*32, false);
|
||||||
|
if (!skinIO.hasError())
|
||||||
{
|
{
|
||||||
std::pair<std::vector<std::pair<uint32_t, float>>, uint32_t>& virtualBone = skins[i];
|
std::vector<std::string> boneNames;
|
||||||
uint32_t bindCount = skinIO.readUint32Big();
|
uint32_t boneNameCount = skinIO.readUint32Big();
|
||||||
virtualBone.first.reserve(bindCount);
|
boneNames.reserve(boneNameCount);
|
||||||
for (uint32_t j=0 ; j<bindCount ; ++j)
|
for (uint32_t i=0 ; i<boneNameCount ; ++i)
|
||||||
|
boneNames.push_back(skinIO.readString());
|
||||||
|
|
||||||
|
uint32_t skinCount = skinIO.readUint32Big();
|
||||||
|
skins.resize(skinCount);
|
||||||
|
for (uint32_t i=0 ; i<skinCount ; ++i)
|
||||||
{
|
{
|
||||||
uint32_t bIdx = skinIO.readUint32Big();
|
std::pair<std::vector<std::pair<uint32_t, float>>, uint32_t>& virtualBone = skins[i];
|
||||||
float weight = skinIO.readFloatBig();
|
uint32_t bindCount = skinIO.readUint32Big();
|
||||||
const std::string& name = boneNames[bIdx];
|
virtualBone.first.reserve(bindCount);
|
||||||
auto search = boneIdMap.find(name);
|
for (uint32_t j=0 ; j<bindCount ; ++j)
|
||||||
if (search == boneIdMap.cend())
|
{
|
||||||
Log.report(logvisor::Fatal, "unable to find bone '%s' in %s",
|
uint32_t bIdx = skinIO.readUint32Big();
|
||||||
name.c_str(), inPath.getRelativePathUTF8().data());
|
float weight = skinIO.readFloatBig();
|
||||||
virtualBone.first.emplace_back(search->second, weight);
|
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().data());
|
||||||
|
virtualBone.first.emplace_back(search->second, weight);
|
||||||
|
}
|
||||||
|
virtualBone.second = skinIO.readUint32Big();
|
||||||
}
|
}
|
||||||
virtualBone.second = skinIO.readUint32Big();
|
|
||||||
|
posCount = skinIO.readUint32Big();
|
||||||
|
normCount = skinIO.readUint32Big();
|
||||||
|
|
||||||
|
skinIO.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t posCount = skinIO.readUint32Big();
|
|
||||||
uint32_t normCount = skinIO.readUint32Big();
|
|
||||||
|
|
||||||
skinIO.close();
|
|
||||||
|
|
||||||
athena::io::TransactionalFileWriter skinOut(outPath.getAbsolutePath());
|
athena::io::TransactionalFileWriter skinOut(outPath.getAbsolutePath());
|
||||||
|
|
||||||
skinOut.writeUint32Big(skins.size());
|
skinOut.writeUint32Big(skins.size());
|
||||||
|
@ -1483,58 +1485,61 @@ bool ANCS::CookCSKRPC(const hecl::ProjectPath& outPath,
|
||||||
if (!modelCookFunc(*modelPath))
|
if (!modelCookFunc(*modelPath))
|
||||||
Log.report(logvisor::Fatal, _SYS_STR("unable to cook '%s'"), modelPath->getRelativePath().data());
|
Log.report(logvisor::Fatal, _SYS_STR("unable to cook '%s'"), modelPath->getRelativePath().data());
|
||||||
|
|
||||||
athena::io::FileReader skinIO(skinIntPath.getAbsolutePath(), 1024*32, false);
|
uint32_t bankCount = 0;
|
||||||
if (skinIO.hasError())
|
|
||||||
Log.report(logvisor::Fatal, _SYS_STR("unable to open '%s'"), skinIntPath.getRelativePath().data());
|
|
||||||
|
|
||||||
std::vector<std::vector<uint32_t>> skinBanks;
|
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;
|
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());
|
|
||||||
|
|
||||||
std::vector<std::vector<std::pair<uint32_t, float>>> skins;
|
std::vector<std::vector<std::pair<uint32_t, float>>> skins;
|
||||||
uint32_t skinCount = skinIO.readUint32Big();
|
atUint64 uniquePoolIndexLen = 0;
|
||||||
skins.resize(skinCount);
|
std::unique_ptr<atUint8[]> uniquePoolIndexData;
|
||||||
for (uint32_t i=0 ; i<skinCount ; ++i)
|
athena::io::FileReader skinIO(skinIntPath.getAbsolutePath(), 1024*32, false);
|
||||||
|
if (!skinIO.hasError())
|
||||||
{
|
{
|
||||||
std::vector<std::pair<uint32_t, float>>& virtualBone = skins[i];
|
bankCount = skinIO.readUint32Big();
|
||||||
uint32_t bindCount = skinIO.readUint32Big();
|
skinBanks.reserve(bankCount);
|
||||||
virtualBone.reserve(bindCount);
|
for (uint32_t i=0 ; i<bankCount ; ++i)
|
||||||
for (uint32_t j=0 ; j<bindCount ; ++j)
|
|
||||||
{
|
{
|
||||||
uint32_t bIdx = skinIO.readUint32Big();
|
skinBanks.emplace_back();
|
||||||
float weight = skinIO.readFloatBig();
|
std::vector<uint32_t>& bonesOut = skinBanks.back();
|
||||||
const std::string& name = boneNames[bIdx];
|
uint32_t boneCount = skinIO.readUint32Big();
|
||||||
auto search = boneIdMap.find(name);
|
bonesOut.reserve(boneCount);
|
||||||
if (search == boneIdMap.cend())
|
for (uint32_t j=0 ; j<boneCount ; ++j)
|
||||||
Log.report(logvisor::Fatal, "unable to find bone '%s' in %s",
|
{
|
||||||
name.c_str(), inPath.getRelativePathUTF8().data());
|
uint32_t idx = skinIO.readUint32Big();
|
||||||
virtualBone.emplace_back(search->second, weight);
|
bonesOut.push_back(idx);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint32_t boneNameCount = skinIO.readUint32Big();
|
||||||
|
boneNames.reserve(boneNameCount);
|
||||||
|
for (uint32_t i=0 ; i<boneNameCount ; ++i)
|
||||||
|
boneNames.push_back(skinIO.readString());
|
||||||
|
|
||||||
|
uint32_t skinCount = skinIO.readUint32Big();
|
||||||
|
skins.resize(skinCount);
|
||||||
|
for (uint32_t i=0 ; i<skinCount ; ++i)
|
||||||
|
{
|
||||||
|
std::vector<std::pair<uint32_t, float>>& virtualBone = skins[i];
|
||||||
|
uint32_t bindCount = skinIO.readUint32Big();
|
||||||
|
virtualBone.reserve(bindCount);
|
||||||
|
for (uint32_t j=0 ; j<bindCount ; ++j)
|
||||||
|
{
|
||||||
|
uint32_t bIdx = skinIO.readUint32Big();
|
||||||
|
float weight = skinIO.readFloatBig();
|
||||||
|
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().data());
|
||||||
|
virtualBone.emplace_back(search->second, weight);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uniquePoolIndexLen = skinIO.length() - skinIO.position();
|
||||||
|
uniquePoolIndexData = skinIO.readUBytes(uniquePoolIndexLen);
|
||||||
|
|
||||||
|
skinIO.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
atUint64 uniquePoolIndexLen = skinIO.length() - skinIO.position();
|
|
||||||
auto uniquePoolIndexData = skinIO.readUBytes(uniquePoolIndexLen);
|
|
||||||
|
|
||||||
skinIO.close();
|
|
||||||
|
|
||||||
athena::io::TransactionalFileWriter skinOut(outPath.getAbsolutePath());
|
athena::io::TransactionalFileWriter skinOut(outPath.getAbsolutePath());
|
||||||
|
|
||||||
skinOut.writeUint32Big(bankCount);
|
skinOut.writeUint32Big(bankCount);
|
||||||
|
@ -1563,7 +1568,8 @@ bool ANCS::CookCSKRPC(const hecl::ProjectPath& outPath,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
skinOut.writeUBytes(uniquePoolIndexData.get(), uniquePoolIndexLen);
|
if (uniquePoolIndexLen)
|
||||||
|
skinOut.writeUBytes(uniquePoolIndexData.get(), uniquePoolIndexLen);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue