2
0
mirror of https://github.com/AxioDL/metaforce.git synced 2025-12-08 14:24:56 +00:00

Add CPU-based skinning path for vertex manipulation effects

This commit is contained in:
Jack Andersen
2017-08-20 19:46:59 -10:00
parent d67d6a1aa7
commit c66f9d0ec7
28 changed files with 465 additions and 123 deletions

View File

@@ -1473,7 +1473,8 @@ template bool WriteCMDL<DNAMP1::MaterialSet, DNACMDL::SurfaceHeader_1, 2>
(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const Mesh& mesh);
template <class MaterialSet, class SurfaceHeader, atUint32 Version>
bool WriteHMDLCMDL(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const Mesh& mesh)
bool WriteHMDLCMDL(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath,
const Mesh& mesh, hecl::PoolSkinIndex& poolSkinIndex)
{
Header head;
head.magic = 0xDEADBABE;
@@ -1536,7 +1537,7 @@ bool WriteHMDLCMDL(const hecl::ProjectPath& outPath, const hecl::ProjectPath& in
}
}
hecl::HMDLBuffers bufs = mesh.getHMDLBuffers(false);
hecl::HMDLBuffers bufs = mesh.getHMDLBuffers(false, poolSkinIndex);
/* Metadata */
size_t secSz = bufs.m_meta.binarySize(0);
@@ -1643,7 +1644,8 @@ bool WriteHMDLCMDL(const hecl::ProjectPath& outPath, const hecl::ProjectPath& in
}
template bool WriteHMDLCMDL<DNAMP1::HMDLMaterialSet, DNACMDL::SurfaceHeader_2, 2>
(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const Mesh& mesh);
(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const Mesh& mesh,
hecl::PoolSkinIndex& poolSkinIndex);
template <class MaterialSet, class SurfaceHeader, class MeshHeader>
bool WriteMREASecs(std::vector<std::vector<uint8_t>>& secsOut, const hecl::ProjectPath& inPath,
@@ -1757,7 +1759,8 @@ bool WriteHMDLMREASecs(std::vector<std::vector<uint8_t>>& secsOut, const hecl::P
meshHeader.write(w);
}
hecl::HMDLBuffers bufs = mesh.getHMDLBuffers(true);
hecl::PoolSkinIndex poolSkinIndex;
hecl::HMDLBuffers bufs = mesh.getHMDLBuffers(true, poolSkinIndex);
std::vector<size_t> surfEndOffs;
surfEndOffs.reserve(bufs.m_surfaces.size());

View File

@@ -169,7 +169,8 @@ template <class MaterialSet, class SurfaceHeader, atUint32 Version>
bool WriteCMDL(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const Mesh& mesh);
template <class MaterialSet, class SurfaceHeader, atUint32 Version>
bool WriteHMDLCMDL(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const Mesh& mesh);
bool WriteHMDLCMDL(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath,
const Mesh& mesh, hecl::PoolSkinIndex& poolSkinIndex);
template <class MaterialSet, class SurfaceHeader, class MeshHeader>
bool WriteMREASecs(std::vector<std::vector<uint8_t>>& secsOut, const hecl::ProjectPath& inPath,

View File

@@ -34,12 +34,12 @@ struct SChargedShotParam : SShotParam
struct ITweakPlayerGun : ITweak
{
DECL_YAML
virtual float GetX24() const = 0; // x24
virtual float GetX28() const = 0; // x28
virtual float GetX2c() const = 0; // x2c
virtual float GetX30() const = 0; // x30
virtual float GetX34() const = 0; // x34
virtual float GetX38() const = 0; // x38
virtual float GetAimVerticalSpeed() const = 0; // x24
virtual float GetAimHorizontalSpeed() const = 0; // x28
virtual float GetBombFuseTime() const = 0; // x2c
virtual float GetBombDropDelayTime() const = 0; // x30
virtual float GetHoloHoldTime() const = 0; // x34
virtual float GetGunTransformTime() const = 0; // x38
virtual float GetGunHolsterTime() const=0;
virtual float GetGunNotFiringTime() const=0;
virtual float GetFixedVerticalAim() const=0;

View File

@@ -1263,6 +1263,30 @@ bool ANCS::CookCSKR(const hecl::ProjectPath& outPath,
for (uint32_t i=0 ; i<boneNameCount ; ++i)
boneNames.push_back(skinIO.readString());
std::vector<std::vector<std::pair<uint32_t, float>>> skins;
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().c_str());
virtualBone.emplace_back(search->second, weight);
}
}
atUint64 uniquePoolIndexLen = skinIO.length() - skinIO.position();
auto uniquePoolIndexData = skinIO.readUBytes(uniquePoolIndexLen);
skinIO.close();
athena::io::TransactionalFileWriter skinOut(outPath.getAbsolutePath());
@@ -1282,6 +1306,19 @@ bool ANCS::CookCSKR(const hecl::ProjectPath& outPath,
}
}
skinOut.writeUint32Big(skins.size());
for (auto& virtuaBone : skins)
{
skinOut.writeUint32Big(virtuaBone.size());
for (auto& bind : virtuaBone)
{
skinOut.writeUint32Big(bind.first);
skinOut.writeFloatBig(bind.second);
}
}
skinOut.writeUBytes(uniquePoolIndexData.get(), uniquePoolIndexLen);
return true;
}

View File

@@ -120,9 +120,11 @@ struct CMDL
const hecl::ProjectPath& inPath,
const DNACMDL::Mesh& mesh)
{
hecl::PoolSkinIndex poolSkinIndex;
if (mesh.skins.size())
{
if (!DNACMDL::WriteHMDLCMDL<HMDLMaterialSet, DNACMDL::SurfaceHeader_2, 2>(outPath, inPath, mesh))
if (!DNACMDL::WriteHMDLCMDL<HMDLMaterialSet, DNACMDL::SurfaceHeader_2, 2>(
outPath, inPath, mesh, poolSkinIndex))
return false;
/* Output skinning intermediate */
@@ -137,8 +139,26 @@ struct CMDL
writer.writeUint32Big(mesh.boneNames.size());
for (const std::string& boneName : mesh.boneNames)
writer.writeString(boneName);
/* CVirtualBone structure just like original (for CPU skinning) */
writer.writeUint32Big(mesh.skins.size());
for (auto& s : mesh.skins)
{
writer.writeUint32Big(s.size());
for (auto& b : s)
{
writer.writeUint32Big(b.boneIdx);
writer.writeFloatBig(b.weight);
}
}
/* Write indirection table mapping pool verts to CVirtualBones */
writer.writeUint32Big(poolSkinIndex.m_poolSz);
for (uint32_t i=0 ; i<poolSkinIndex.m_poolSz ; ++i)
writer.writeUint32Big(poolSkinIndex.m_poolToSkinIndex[i]);
}
else if (!DNACMDL::WriteHMDLCMDL<HMDLMaterialSet, DNACMDL::SurfaceHeader_2, 2>(outPath, inPath, mesh))
else if (!DNACMDL::WriteHMDLCMDL<HMDLMaterialSet, DNACMDL::SurfaceHeader_2, 2>(
outPath, inPath, mesh, poolSkinIndex))
return false;
return true;
}

View File

@@ -19,12 +19,12 @@ struct CTweakPlayerGun : ITweakPlayerGun
Value<float> x18_;
Value<float> x1c_;
Value<float> x20_;
Value<float> x24_;
Value<float> x28_;
Value<float> x2c_;
Value<float> x30_;
Value<float> x34_;
Value<float> x38_;
Value<float> x24_aimVerticalSpeed;
Value<float> x28_aimHorizontalSpeed;
Value<float> x2c_bombFuseTime;
Value<float> x30_bombDropDelayTime;
Value<float> x34_holoHoldTime;
Value<float> x38_gunTransformTime;
Value<float> x3c_gunHolsterTime;
Value<float> x40_gunNotFiringTime;
Value<float> x44_fixedVerticalAim;
@@ -53,12 +53,12 @@ struct CTweakPlayerGun : ITweakPlayerGun
x44_fixedVerticalAim = zeus::degToRad(x44_fixedVerticalAim);
}
float GetX24() const { return x24_; }
float GetX28() const { return x28_; }
float GetX2c() const { return x2c_; }
float GetX30() const { return x30_; }
float GetX34() const { return x34_; }
float GetX38() const { return x38_; }
float GetAimVerticalSpeed() const { return x24_aimVerticalSpeed; }
float GetAimHorizontalSpeed() const { return x28_aimHorizontalSpeed; }
float GetBombFuseTime() const { return x2c_bombFuseTime; }
float GetBombDropDelayTime() const { return x30_bombDropDelayTime; }
float GetHoloHoldTime() const { return x34_holoHoldTime; }
float GetGunTransformTime() const { return x38_gunTransformTime; }
float GetGunHolsterTime() const { return x3c_gunHolsterTime; }
float GetGunNotFiringTime() const { return x40_gunNotFiringTime; }
float GetFixedVerticalAim() const { return x44_fixedVerticalAim; }