mirror of
https://github.com/AxioDL/metaforce.git
synced 2025-12-08 21:07:42 +00:00
GameCube spec cook fixes
This commit is contained in:
@@ -775,9 +775,9 @@ atUint32 ReadGeomSectionsToBlender(hecl::blender::PyOutStream& os,
|
||||
size_t normCount = secSizes[s] / 6;
|
||||
for (size_t i=0 ; i<normCount ; ++i)
|
||||
{
|
||||
float x = reader.readInt16Big() / 16834.0f;
|
||||
float y = reader.readInt16Big() / 16834.0f;
|
||||
float z = reader.readInt16Big() / 16834.0f;
|
||||
float x = reader.readInt16Big() / 16384.0f;
|
||||
float y = reader.readInt16Big() / 16384.0f;
|
||||
float z = reader.readInt16Big() / 16384.0f;
|
||||
os.format("norm_list.append((%f,%f,%f))\n",
|
||||
x, y, z);
|
||||
}
|
||||
@@ -1218,13 +1218,18 @@ static void WriteDLVal(W& writer, GX::AttrType type, atUint32 val)
|
||||
template <class MaterialSet, class SurfaceHeader, atUint32 Version>
|
||||
bool WriteCMDL(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath, const Mesh& mesh)
|
||||
{
|
||||
bool skinned = !mesh.skins.empty();
|
||||
|
||||
Header head;
|
||||
head.magic = 0xDEADBABE;
|
||||
head.version = Version;
|
||||
head.flags.setSkinned(skinned);
|
||||
head.flags.setShortNormals(!skinned);
|
||||
head.flags.setShortUVs(true); /* This just means there's an (empty) short UV section */
|
||||
head.aabbMin = mesh.aabbMin.val;
|
||||
head.aabbMax = mesh.aabbMax.val;
|
||||
head.matSetCount = mesh.materialSets.size();
|
||||
head.secCount = head.matSetCount + 5 + mesh.surfaces.size();
|
||||
head.secCount = head.matSetCount + 6 + mesh.surfaces.size();
|
||||
head.secSizes.reserve(head.secCount);
|
||||
|
||||
/* Lengths of padding to insert while writing */
|
||||
@@ -1238,6 +1243,8 @@ bool WriteCMDL(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath
|
||||
hecl::Frontend::Frontend FE;
|
||||
for (const std::vector<Material>& mset : mesh.materialSets)
|
||||
{
|
||||
std::unordered_map<uint64_t, int> uniqueMatMap;
|
||||
|
||||
matSets.emplace_back();
|
||||
MaterialSet& targetMSet = matSets.back();
|
||||
std::vector<hecl::ProjectPath> texPaths;
|
||||
@@ -1245,7 +1252,6 @@ bool WriteCMDL(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath
|
||||
setBackends.reserve(mset.size());
|
||||
|
||||
size_t endOff = 0;
|
||||
atUint32 nextGroupIdx = 0;
|
||||
for (const Material& mat : mset)
|
||||
{
|
||||
std::string diagName = hecl::Format("%s:%s", inPath.getLastComponentUTF8().data(), mat.name.c_str());
|
||||
@@ -1254,25 +1260,9 @@ bool WriteCMDL(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath
|
||||
hecl::Backend::GX& matGX = setBackends.back();
|
||||
matGX.reset(matIR, FE.getDiagnostics());
|
||||
|
||||
atUint32 groupIdx = -1;
|
||||
if (matSets.size() == 1)
|
||||
{
|
||||
for (size_t i=0 ; i<setBackends.size()-1 ; ++i)
|
||||
{
|
||||
const hecl::Backend::GX& other = setBackends[i];
|
||||
if (matGX == other)
|
||||
{
|
||||
groupIdx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (groupIdx == -1)
|
||||
groupIdx = nextGroupIdx++;
|
||||
}
|
||||
|
||||
targetMSet.materials.emplace_back(matGX, mat.iprops, mat.texs, texPaths,
|
||||
mesh.colorLayerCount, mesh.uvLayerCount,
|
||||
false, false, groupIdx);
|
||||
false, false, uniqueMatMap);
|
||||
|
||||
targetMSet.materials.back().binarySize(endOff);
|
||||
targetMSet.head.addMaterialEndOff(endOff);
|
||||
@@ -1317,7 +1307,7 @@ bool WriteCMDL(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath
|
||||
paddingSizes.push_back(secSz32 - secSz);
|
||||
|
||||
/* Vertex Normals */
|
||||
secSz = mesh.norm.size() * 12;
|
||||
secSz = mesh.norm.size() * (skinned ? 12 : 6);
|
||||
secSz32 = ROUND_UP_32(secSz);
|
||||
if (secSz32 == 0)
|
||||
secSz32 = 32;
|
||||
@@ -1340,6 +1330,12 @@ bool WriteCMDL(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath
|
||||
head.secSizes.push_back(secSz32);
|
||||
paddingSizes.push_back(secSz32 - secSz);
|
||||
|
||||
/* LUV coords */
|
||||
secSz = 0;
|
||||
secSz32 = ROUND_UP_32(secSz);
|
||||
head.secSizes.push_back(secSz32);
|
||||
paddingSizes.push_back(secSz32 - secSz);
|
||||
|
||||
/* Surface index */
|
||||
std::vector<size_t> surfEndOffs;
|
||||
surfEndOffs.reserve(mesh.surfaces.size());
|
||||
@@ -1388,7 +1384,21 @@ bool WriteCMDL(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath
|
||||
|
||||
/* Vertex Normals */
|
||||
for (const atVec3f& norm : mesh.norm)
|
||||
writer.writeVec3fBig(norm);
|
||||
{
|
||||
if (skinned)
|
||||
{
|
||||
writer.writeVec3fBig(norm);
|
||||
}
|
||||
else
|
||||
{
|
||||
for (int i = 0; i < 3; ++i)
|
||||
{
|
||||
int tmpV = int(norm.vec[i] * 16384.f);
|
||||
tmpV = zeus::clamp(-32768, tmpV, 32767);
|
||||
writer.writeInt16Big(atInt16(tmpV));
|
||||
}
|
||||
}
|
||||
}
|
||||
writer.fill(atUint8(0), *padIt);
|
||||
++padIt;
|
||||
|
||||
@@ -1407,6 +1417,10 @@ bool WriteCMDL(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath
|
||||
writer.fill(atUint8(0), *padIt);
|
||||
++padIt;
|
||||
|
||||
/* LUV coords */
|
||||
writer.fill(atUint8(0), *padIt);
|
||||
++padIt;
|
||||
|
||||
/* Surface index */
|
||||
writer.writeUint32Big(surfEndOffs.size());
|
||||
for (size_t off : surfEndOffs)
|
||||
@@ -1435,7 +1449,9 @@ bool WriteCMDL(const hecl::ProjectPath& outPath, const hecl::ProjectPath& inPath
|
||||
header.reflectionNormal = surf.reflectionNormal;
|
||||
header.write(writer);
|
||||
|
||||
writer.writeUByte(prim);
|
||||
/* VAT0 = float normals, float UVs
|
||||
* VAT1 = short normals, float UVs */
|
||||
writer.writeUByte(prim | (skinned ? 0x0 : 0x1));
|
||||
writer.writeUint16Big(surf.verts.size());
|
||||
|
||||
for (const Mesh::Surface::Vert& vert : surf.verts)
|
||||
@@ -1680,6 +1696,7 @@ bool WriteMREASecs(std::vector<std::vector<uint8_t>>& secsOut, const hecl::Proje
|
||||
MaterialSet matSet;
|
||||
{
|
||||
MaterialPool matPool;
|
||||
std::unordered_map<uint64_t, int> uniqueMatMap;
|
||||
|
||||
size_t surfCount = 0;
|
||||
for (const Mesh& mesh : meshes)
|
||||
@@ -1690,7 +1707,6 @@ bool WriteMREASecs(std::vector<std::vector<uint8_t>>& secsOut, const hecl::Proje
|
||||
size_t endOff = 0;
|
||||
std::vector<hecl::ProjectPath> texPaths;
|
||||
std::vector<hecl::Backend::GX> setBackends;
|
||||
atUint32 nextGroupIdx = 0;
|
||||
for (const Mesh& mesh : meshes)
|
||||
{
|
||||
if (mesh.materialSets.size())
|
||||
@@ -1727,25 +1743,12 @@ bool WriteMREASecs(std::vector<std::vector<uint8_t>>& secsOut, const hecl::Proje
|
||||
hecl::Backend::GX& matGX = setBackends.back();
|
||||
matGX.reset(matIR, FE.getDiagnostics());
|
||||
|
||||
atUint32 groupIdx = -1;
|
||||
for (size_t i=0 ; i<setBackends.size()-1 ; ++i)
|
||||
{
|
||||
const hecl::Backend::GX& other = setBackends[i];
|
||||
if (matGX == other)
|
||||
{
|
||||
groupIdx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (groupIdx == -1)
|
||||
groupIdx = nextGroupIdx++;
|
||||
|
||||
auto lightmapped = mat.iprops.find("retro_lightmapped");
|
||||
bool lm = lightmapped != mat.iprops.cend() && lightmapped->second != 0;
|
||||
|
||||
matSet.materials.emplace_back(matGX, mat.iprops, mat.texs, texPaths,
|
||||
mesh.colorLayerCount, mesh.uvLayerCount,
|
||||
lm, false, groupIdx);
|
||||
lm, false, uniqueMatMap);
|
||||
|
||||
matSet.materials.back().binarySize(endOff);
|
||||
matSet.head.addMaterialEndOff(endOff);
|
||||
@@ -1834,7 +1837,7 @@ bool WriteMREASecs(std::vector<std::vector<uint8_t>>& secsOut, const hecl::Proje
|
||||
zeus::CVector3f preXfNorm = (meshXf.basis * zeus::CVector3f(v)).normalized();
|
||||
for (int i=0 ; i<3 ; ++i)
|
||||
{
|
||||
int tmpV = int(preXfNorm[i] * 16834.f);
|
||||
int tmpV = int(preXfNorm[i] * 16384.f);
|
||||
tmpV = zeus::clamp(-32768, tmpV, 32767);
|
||||
w.writeInt16Big(atInt16(tmpV));
|
||||
}
|
||||
@@ -1904,8 +1907,8 @@ bool WriteMREASecs(std::vector<std::vector<uint8_t>>& secsOut, const hecl::Proje
|
||||
for (const Mesh::Surface& surf : mesh.surfaces)
|
||||
{
|
||||
size_t matIdx = *matIt++;
|
||||
const typename MaterialSet::Material::VAFlags& vaFlags =
|
||||
matSet.materials.at(matIdx).getVAFlags();
|
||||
const typename MaterialSet::Material& mat = matSet.materials.at(matIdx);
|
||||
const typename MaterialSet::Material::VAFlags& vaFlags = mat.getVAFlags();
|
||||
size_t vertSz = vaFlags.vertDLSize();
|
||||
|
||||
SurfaceHeader header;
|
||||
@@ -1927,7 +1930,9 @@ bool WriteMREASecs(std::vector<std::vector<uint8_t>>& secsOut, const hecl::Proje
|
||||
athena::io::MemoryWriter w(secsOut.back().data(), secsOut.back().size());
|
||||
header.write(w);
|
||||
|
||||
w.writeUByte(prim);
|
||||
/* VAT1 = short normals, float UVs
|
||||
* VAT2 = short normals, short UVs */
|
||||
w.writeUByte(prim | (mat.flags.lightmapUVArray() ? 0x2 : 0x1));
|
||||
w.writeUint16Big(surf.verts.size());
|
||||
|
||||
for (const Mesh::Surface::Vert& vert : surf.verts)
|
||||
|
||||
@@ -24,6 +24,8 @@ struct Header : BigDNA
|
||||
{
|
||||
AT_DECL_DNA
|
||||
Value<atUint32> flags = 0;
|
||||
bool skinned() const {return (flags & 0x1) != 0;}
|
||||
void setSkinned(bool val) {flags &= ~0x1; flags |= val;}
|
||||
bool shortNormals() const {return (flags & 0x2) != 0;}
|
||||
void setShortNormals(bool val) {flags &= ~0x2; flags |= val << 1;}
|
||||
bool shortUVs() const {return (flags & 0x4) != 0;}
|
||||
|
||||
@@ -17,9 +17,28 @@ struct AT_SPECIALIZE_PARMS(DataSpec::UniqueID32, DataSpec::UniqueID64) DGRP : Bi
|
||||
AT_DECL_DNA_YAML
|
||||
DNAFourCC type;
|
||||
Value<IDType> id;
|
||||
|
||||
bool validate() const
|
||||
{
|
||||
if (!id.operator bool())
|
||||
return false;
|
||||
hecl::ProjectPath path = UniqueIDBridge::TranslatePakIdToPath(id);
|
||||
return path && !path.isNone();
|
||||
}
|
||||
};
|
||||
|
||||
Vector<ObjectTag, AT_DNA_COUNT(dependCount)> depends;
|
||||
|
||||
void validateDeps()
|
||||
{
|
||||
std::vector<ObjectTag> newDeps;
|
||||
newDeps.reserve(depends.size());
|
||||
for (const ObjectTag& tag : depends)
|
||||
if (tag.validate())
|
||||
newDeps.push_back(tag);
|
||||
depends = std::move(newDeps);
|
||||
dependCount = atUint32(depends.size());
|
||||
}
|
||||
};
|
||||
|
||||
template <class IDType>
|
||||
|
||||
@@ -142,6 +142,22 @@ std::string UniqueID32::toString() const
|
||||
return std::string(buf);
|
||||
}
|
||||
|
||||
template <>
|
||||
void UniqueID32Zero::Enumerate<BigDNA::Read>(typename Read::StreamT& reader)
|
||||
{UniqueID32::Enumerate<BigDNA::Read>(reader);}
|
||||
template <>
|
||||
void UniqueID32Zero::Enumerate<BigDNA::Write>(typename Write::StreamT& writer)
|
||||
{writer.writeUint32Big(*this ? m_id : 0);}
|
||||
template <>
|
||||
void UniqueID32Zero::Enumerate<BigDNA::ReadYaml>(typename ReadYaml::StreamT& reader)
|
||||
{UniqueID32::Enumerate<BigDNA::ReadYaml>(reader);}
|
||||
template <>
|
||||
void UniqueID32Zero::Enumerate<BigDNA::WriteYaml>(typename WriteYaml::StreamT& writer)
|
||||
{UniqueID32::Enumerate<BigDNA::WriteYaml>(writer);}
|
||||
template <>
|
||||
void UniqueID32Zero::Enumerate<BigDNA::BinarySize>(typename BinarySize::StreamT& s)
|
||||
{UniqueID32::Enumerate<BigDNA::BinarySize>(s);}
|
||||
|
||||
AuxiliaryID32& AuxiliaryID32::operator=(const hecl::ProjectPath& path)
|
||||
{
|
||||
assign(path.ensureAuxInfo(m_auxStr).hash().val32());
|
||||
|
||||
@@ -223,6 +223,15 @@ public:
|
||||
static constexpr size_t BinarySize() {return 4;}
|
||||
};
|
||||
|
||||
/** PAK 32-bit Unique ID - writes zero when invalid */
|
||||
class UniqueID32Zero : public UniqueID32
|
||||
{
|
||||
public:
|
||||
AT_DECL_DNA_YAML
|
||||
Delete __d2;
|
||||
using UniqueID32::UniqueID32;
|
||||
};
|
||||
|
||||
class AuxiliaryID32 : public UniqueID32
|
||||
{
|
||||
const hecl::SystemChar* m_auxStr;
|
||||
@@ -352,6 +361,10 @@ public:
|
||||
static constexpr size_t BinarySize() {return 16;}
|
||||
};
|
||||
|
||||
/** Casts ID type to its null-zero equivalent */
|
||||
template <class T>
|
||||
using CastIDToZero = typename std::conditional_t<std::is_same_v<T, UniqueID32>, UniqueID32Zero, T>;
|
||||
|
||||
/** Word Bitmap reader/writer */
|
||||
class WordBitmap
|
||||
{
|
||||
|
||||
@@ -820,7 +820,7 @@ struct UVEConstant : IUVElement
|
||||
{
|
||||
AT_DECL_EXPLICIT_DNA_YAML
|
||||
AT_SUBDECL_DNA
|
||||
IDType tex;
|
||||
CastIDToZero<IDType> tex;
|
||||
const char* ClassID() const {return "CNST";}
|
||||
|
||||
void gatherDependencies(std::vector<hecl::ProjectPath>& pathsOut) const
|
||||
@@ -834,7 +834,7 @@ struct UVEAnimTexture : IUVElement
|
||||
{
|
||||
AT_DECL_EXPLICIT_DNA_YAML
|
||||
AT_SUBDECL_DNA
|
||||
IDType tex;
|
||||
CastIDToZero<IDType> tex;
|
||||
IntElementFactory tileW;
|
||||
IntElementFactory tileH;
|
||||
IntElementFactory strideW;
|
||||
|
||||
@@ -621,8 +621,8 @@ static uint8_t* EncodePaletteSPLT(png_structp png, png_infop info, int numEntrie
|
||||
|
||||
((uint32_t*)data)[0] = hecl::SBig(format);
|
||||
data += 4;
|
||||
((uint16_t*)data)[0] = hecl::SBig(uint16_t(numEntries));
|
||||
((uint16_t*)data)[1] = hecl::SBig(uint16_t(1));
|
||||
((uint16_t*)data)[0] = hecl::SBig(uint16_t(1));
|
||||
((uint16_t*)data)[1] = hecl::SBig(uint16_t(numEntries));
|
||||
data += 4;
|
||||
|
||||
switch (format)
|
||||
@@ -1415,7 +1415,7 @@ bool TXTR::Cook(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPat
|
||||
width >= 4 && height >= 4;
|
||||
|
||||
/* Read into mip0 image buffer */
|
||||
for (int r=height-1 ; r>=0 ; --r)
|
||||
for (int r=0 ; r<height ; ++r)
|
||||
{
|
||||
if (colorType == PNG_COLOR_TYPE_RGB)
|
||||
{
|
||||
@@ -1545,6 +1545,7 @@ bool TXTR::Cook(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPat
|
||||
filterHeight = height;
|
||||
const uint8_t* rgbaIn = bufOut.get();
|
||||
uint8_t* blocksOut = compOut.get();
|
||||
memset(blocksOut, 0, compLen);
|
||||
for (size_t i=0 ; i<numMips ; ++i)
|
||||
{
|
||||
int thisLen = squish::GetStorageRequirements(filterWidth, filterHeight, squish::kDxt1);
|
||||
@@ -1563,10 +1564,15 @@ bool TXTR::Cook(const hecl::ProjectPath& inPath, const hecl::ProjectPath& outPat
|
||||
int filterHeight = height;
|
||||
compLen = bufLen;
|
||||
if (colorType == PNG_COLOR_TYPE_PALETTE)
|
||||
{
|
||||
if (nPaletteEntries == 16)
|
||||
compLen /= 2;
|
||||
compLen += 8 + nPaletteEntries * 2;
|
||||
}
|
||||
compOut.reset(new uint8_t[compLen]);
|
||||
const uint8_t* rgbaIn = bufOut.get();
|
||||
uint8_t* dataOut = compOut.get();
|
||||
memset(dataOut, 0, compLen);
|
||||
for (size_t i=0 ; i<numMips ; ++i)
|
||||
{
|
||||
switch (colorType)
|
||||
|
||||
Reference in New Issue
Block a user