mirror of https://github.com/AxioDL/metaforce.git
Initial CMDL cooking in place
This commit is contained in:
parent
58c0fd5ad2
commit
bf8a007514
|
@ -24,7 +24,7 @@ struct Header : BigDNA
|
||||||
struct Flags : BigDNA
|
struct Flags : BigDNA
|
||||||
{
|
{
|
||||||
DECL_DNA
|
DECL_DNA
|
||||||
Value<atUint32> flags;
|
Value<atUint32> flags = 0;
|
||||||
bool shortNormals() const {return (flags & 0x2) != 0;}
|
bool shortNormals() const {return (flags & 0x2) != 0;}
|
||||||
void setShortNormals(bool val) {flags &= ~0x2; flags |= val << 1;}
|
void setShortNormals(bool val) {flags &= ~0x2; flags |= val << 1;}
|
||||||
bool shortUVs() const {return (flags & 0x4) != 0;}
|
bool shortUVs() const {return (flags & 0x4) != 0;}
|
||||||
|
@ -42,12 +42,12 @@ struct SurfaceHeader_1_2 : BigDNA
|
||||||
{
|
{
|
||||||
DECL_DNA
|
DECL_DNA
|
||||||
Value<atVec3f> centroid;
|
Value<atVec3f> centroid;
|
||||||
Value<atUint32> matIdx;
|
Value<atUint32> matIdx = 0;
|
||||||
Value<atInt16> qDiv;
|
Value<atUint16> qDiv = 0x8000;
|
||||||
Value<atUint16> dlSize;
|
Value<atUint16> dlSize = 0;
|
||||||
Value<atUint32> unk1;
|
Value<atUint32> unk1 = 0;
|
||||||
Value<atUint32> unk2;
|
Value<atUint32> unk2 = 0;
|
||||||
Value<atUint32> aabbSz;
|
Value<atUint32> aabbSz = 0;
|
||||||
Value<atVec3f> reflectionNormal;
|
Value<atVec3f> reflectionNormal;
|
||||||
Seek<DNA_COUNT(aabbSz), Athena::Current> seek2;
|
Seek<DNA_COUNT(aabbSz), Athena::Current> seek2;
|
||||||
Align<32> align;
|
Align<32> align;
|
||||||
|
@ -60,12 +60,12 @@ struct SurfaceHeader_3 : BigDNA
|
||||||
{
|
{
|
||||||
DECL_DNA
|
DECL_DNA
|
||||||
Value<atVec3f> centroid;
|
Value<atVec3f> centroid;
|
||||||
Value<atUint32> matIdx;
|
Value<atUint32> matIdx = 0;
|
||||||
Value<atInt16> qDiv;
|
Value<atUint16> qDiv = 0x8000;
|
||||||
Value<atUint16> dlSize;
|
Value<atUint16> dlSize = 0;
|
||||||
Value<atUint32> unk1;
|
Value<atUint32> unk1 = 0;
|
||||||
Value<atUint32> unk2;
|
Value<atUint32> unk2 = 0;
|
||||||
Value<atUint32> aabbSz;
|
Value<atUint32> aabbSz = 0;
|
||||||
Value<atVec3f> reflectionNormal;
|
Value<atVec3f> reflectionNormal;
|
||||||
Value<atInt16> skinMtxBankIdx;
|
Value<atInt16> skinMtxBankIdx;
|
||||||
Value<atUint16> unk3;
|
Value<atUint16> unk3;
|
||||||
|
@ -1024,21 +1024,39 @@ bool ReadCMDLToBlender(HECL::BlenderConnection& conn,
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void WriteDLVal(Athena::io::FileWriter& writer, GX::AttrType type, atUint32 val)
|
||||||
|
{
|
||||||
|
switch (type)
|
||||||
|
{
|
||||||
|
case GX::DIRECT:
|
||||||
|
case GX::INDEX8:
|
||||||
|
writer.writeUByte(atUint8(val));
|
||||||
|
break;
|
||||||
|
case GX::INDEX16:
|
||||||
|
writer.writeUint16Big(atUint16(val));
|
||||||
|
break;
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
template <class MaterialSet, class SurfaceHeader, atUint32 Version>
|
template <class MaterialSet, class SurfaceHeader, atUint32 Version>
|
||||||
bool WriteCMDL(const HECL::ProjectPath& outPath, const HECL::ProjectPath& inPath, const Mesh& mesh)
|
bool WriteCMDL(const HECL::ProjectPath& outPath, const HECL::ProjectPath& inPath, const Mesh& mesh)
|
||||||
{
|
{
|
||||||
//Athena::io::FileWriter writer(outPath.getAbsolutePath());
|
Athena::io::FileWriter writer(outPath.getWithExtension(_S(".recook")).getAbsolutePath());
|
||||||
|
|
||||||
Header head;
|
Header head;
|
||||||
head.magic = 0xDEADBABE;
|
head.magic = 0xDEADBABE;
|
||||||
head.version = Version;
|
head.version = Version;
|
||||||
head.flags.flags = 0;
|
|
||||||
head.aabbMin = mesh.aabbMin.val;
|
head.aabbMin = mesh.aabbMin.val;
|
||||||
head.aabbMax = mesh.aabbMax.val;
|
head.aabbMax = mesh.aabbMax.val;
|
||||||
head.matSetCount = mesh.materialSets.size();
|
head.matSetCount = mesh.materialSets.size();
|
||||||
head.secCount = head.matSetCount + 5 + mesh.surfaces.size();
|
head.secCount = head.matSetCount + 5 + mesh.surfaces.size();
|
||||||
head.secSizes.reserve(head.secCount);
|
head.secSizes.reserve(head.secCount);
|
||||||
|
|
||||||
|
/* Lengths of padding to insert while writing */
|
||||||
|
std::vector<size_t> paddingSizes;
|
||||||
|
paddingSizes.reserve(head.secCount);
|
||||||
|
|
||||||
/* Build material sets */
|
/* Build material sets */
|
||||||
std::vector<MaterialSet> matSets;
|
std::vector<MaterialSet> matSets;
|
||||||
matSets.reserve(mesh.materialSets.size());
|
matSets.reserve(mesh.materialSets.size());
|
||||||
|
@ -1049,23 +1067,213 @@ bool WriteCMDL(const HECL::ProjectPath& outPath, const HECL::ProjectPath& inPath
|
||||||
matSets.emplace_back();
|
matSets.emplace_back();
|
||||||
MaterialSet& targetMSet = matSets.back();
|
MaterialSet& targetMSet = matSets.back();
|
||||||
std::vector<HECL::ProjectPath> texPaths;
|
std::vector<HECL::ProjectPath> texPaths;
|
||||||
|
std::vector<HECL::Backend::GX> setBackends;
|
||||||
|
setBackends.reserve(mset.size());
|
||||||
|
|
||||||
|
size_t endOff = 0;
|
||||||
|
atUint32 nextGroupIdx = 0;
|
||||||
for (const Mesh::Material& mat : mset)
|
for (const Mesh::Material& mat : mset)
|
||||||
{
|
{
|
||||||
std::string diagName = HECL::Format("%s:%s", inPath.getLastComponentUTF8(), mat.name.c_str());
|
std::string diagName = HECL::Format("%s:%s", inPath.getLastComponentUTF8(), mat.name.c_str());
|
||||||
HECL::Frontend::IR matIR = FE.compileSource(mat.source, diagName);
|
HECL::Frontend::IR matIR = FE.compileSource(mat.source, diagName);
|
||||||
HECL::Backend::GX matGX;
|
setBackends.emplace_back();
|
||||||
|
HECL::Backend::GX& matGX = setBackends.back();
|
||||||
matGX.reset(matIR, FE.getDiagnostics());
|
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,
|
targetMSet.materials.emplace_back(matGX, mat.iprops, mat.texs, texPaths,
|
||||||
mesh.colorLayerCount, mesh.uvLayerCount,
|
mesh.colorLayerCount, mesh.uvLayerCount,
|
||||||
false, false, 0);
|
false, false, groupIdx);
|
||||||
|
|
||||||
|
endOff = targetMSet.materials.back().binarySize(endOff);
|
||||||
|
targetMSet.addMaterialEndOff(endOff);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (const HECL::ProjectPath& path : texPaths)
|
||||||
|
{
|
||||||
|
const HECL::SystemString& relPath = path.getRelativePath();
|
||||||
|
|
||||||
|
/* TODO: incorporate hecl hashes */
|
||||||
|
size_t search = relPath.find("TXTR_");
|
||||||
|
if (search != HECL::SystemString::npos)
|
||||||
|
targetMSet.addTexture(relPath.c_str() + search + 5);
|
||||||
|
else
|
||||||
|
LogDNACommon.report(LogVisor::FatalError, "unable to get hash from path");
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t secSz = targetMSet.binarySize(0);
|
||||||
|
size_t secSz32 = ROUND_UP_32(secSz);
|
||||||
|
head.secSizes.push_back(secSz32);
|
||||||
|
paddingSizes.push_back(secSz32 - secSz);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//head.write(writer);
|
/* Vertex Positions */
|
||||||
|
size_t secSz = mesh.pos.size() * 12;
|
||||||
|
size_t secSz32 = ROUND_UP_32(secSz);
|
||||||
|
if (secSz32 == 0)
|
||||||
|
secSz32 = 32;
|
||||||
|
head.secSizes.push_back(secSz32);
|
||||||
|
paddingSizes.push_back(secSz32 - secSz);
|
||||||
|
|
||||||
|
/* Vertex Normals */
|
||||||
|
secSz = mesh.norm.size() * 12;
|
||||||
|
secSz32 = ROUND_UP_32(secSz);
|
||||||
|
if (secSz32 == 0)
|
||||||
|
secSz32 = 32;
|
||||||
|
head.secSizes.push_back(secSz32);
|
||||||
|
paddingSizes.push_back(secSz32 - secSz);
|
||||||
|
|
||||||
|
/* Vertex Colors */
|
||||||
|
secSz = mesh.color.size() * 4;
|
||||||
|
secSz32 = ROUND_UP_32(secSz);
|
||||||
|
if (secSz32 == 0)
|
||||||
|
secSz32 = 32;
|
||||||
|
head.secSizes.push_back(secSz32);
|
||||||
|
paddingSizes.push_back(secSz32 - secSz);
|
||||||
|
|
||||||
|
/* UV coords */
|
||||||
|
secSz = mesh.uv.size() * 8;
|
||||||
|
secSz32 = ROUND_UP_32(secSz);
|
||||||
|
if (secSz32 == 0)
|
||||||
|
secSz32 = 32;
|
||||||
|
head.secSizes.push_back(secSz32);
|
||||||
|
paddingSizes.push_back(secSz32 - secSz);
|
||||||
|
|
||||||
|
/* Surface index */
|
||||||
|
std::vector<size_t> surfEndOffs;
|
||||||
|
surfEndOffs.reserve(mesh.surfaces.size());
|
||||||
|
secSz = mesh.surfaces.size() * 4 + 4;
|
||||||
|
secSz32 = ROUND_UP_32(secSz);
|
||||||
|
if (secSz32 == 0)
|
||||||
|
secSz32 = 32;
|
||||||
|
head.secSizes.push_back(secSz32);
|
||||||
|
paddingSizes.push_back(secSz32 - secSz);
|
||||||
|
|
||||||
|
/* Surfaces */
|
||||||
|
size_t endOff = 0;
|
||||||
|
for (const Mesh::Surface& surf : mesh.surfaces)
|
||||||
|
{
|
||||||
|
size_t vertSz = matSets.at(0).materials.at(surf.materialIdx).getVAFlags().vertDLSize();
|
||||||
|
if (surf.verts.size() > 65536)
|
||||||
|
LogDNACommon.report(LogVisor::FatalError, "GX DisplayList overflow");
|
||||||
|
size_t secSz = 67 + surf.verts.size() * vertSz;
|
||||||
|
secSz32 = ROUND_UP_32(secSz);
|
||||||
|
if (secSz32 == 0)
|
||||||
|
secSz32 = 32;
|
||||||
|
head.secSizes.push_back(secSz32);
|
||||||
|
paddingSizes.push_back(secSz32 - secSz);
|
||||||
|
endOff += secSz32;
|
||||||
|
surfEndOffs.push_back(endOff);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Write sections */
|
||||||
|
head.write(writer);
|
||||||
|
std::vector<size_t>::const_iterator padIt = paddingSizes.cbegin();
|
||||||
|
|
||||||
|
/* Material Sets */
|
||||||
|
for (const MaterialSet& mset : matSets)
|
||||||
|
{
|
||||||
|
mset.write(writer);
|
||||||
|
writer.fill(atUint8(0), *padIt);
|
||||||
|
++padIt;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Vertex Positions */
|
||||||
|
for (const atVec3f& pos : mesh.pos)
|
||||||
|
writer.writeVec3fBig(pos);
|
||||||
|
writer.fill(atUint8(0), *padIt);
|
||||||
|
++padIt;
|
||||||
|
|
||||||
|
/* Vertex Normals */
|
||||||
|
for (const atVec3f& norm : mesh.norm)
|
||||||
|
writer.writeVec3fBig(norm);
|
||||||
|
writer.fill(atUint8(0), *padIt);
|
||||||
|
++padIt;
|
||||||
|
|
||||||
|
/* Vertex Colors */
|
||||||
|
for (const atVec3f& col : mesh.color)
|
||||||
|
{
|
||||||
|
GX::Color qCol(col);
|
||||||
|
qCol.write(writer);
|
||||||
|
}
|
||||||
|
writer.fill(atUint8(0), *padIt);
|
||||||
|
++padIt;
|
||||||
|
|
||||||
|
/* UV coords */
|
||||||
|
for (const atVec2f& uv : mesh.uv)
|
||||||
|
writer.writeVec2fBig(uv);
|
||||||
|
writer.fill(atUint8(0), *padIt);
|
||||||
|
++padIt;
|
||||||
|
|
||||||
|
/* Surface index */
|
||||||
|
writer.writeUint32Big(surfEndOffs.size());
|
||||||
|
for (size_t off : surfEndOffs)
|
||||||
|
writer.writeUint32Big(off);
|
||||||
|
writer.fill(atUint8(0), *padIt);
|
||||||
|
++padIt;
|
||||||
|
|
||||||
|
/* Surfaces */
|
||||||
|
for (const Mesh::Surface& surf : mesh.surfaces)
|
||||||
|
{
|
||||||
|
const typename MaterialSet::Material::VAFlags& vaFlags =
|
||||||
|
matSets.at(0).materials.at(surf.materialIdx).getVAFlags();
|
||||||
|
size_t vertSz = vaFlags.vertDLSize();
|
||||||
|
|
||||||
|
SurfaceHeader header;
|
||||||
|
header.centroid = surf.centroid;
|
||||||
|
header.matIdx = surf.materialIdx;
|
||||||
|
header.dlSize = 3 + surf.verts.size() * vertSz;
|
||||||
|
header.reflectionNormal = surf.reflectionNormal;
|
||||||
|
header.write(writer);
|
||||||
|
|
||||||
|
writer.writeUByte(GX::TRIANGLESTRIP);
|
||||||
|
writer.writeUint16Big(surf.verts.size());
|
||||||
|
|
||||||
|
for (const Mesh::Surface::Vert& vert : surf.verts)
|
||||||
|
{
|
||||||
|
atUint32 skinIdx = vert.iBankSkin * 3;
|
||||||
|
WriteDLVal(writer, vaFlags.pnMatIdx(), skinIdx);
|
||||||
|
WriteDLVal(writer, vaFlags.tex0MatIdx(), skinIdx);
|
||||||
|
WriteDLVal(writer, vaFlags.tex1MatIdx(), skinIdx);
|
||||||
|
WriteDLVal(writer, vaFlags.tex2MatIdx(), skinIdx);
|
||||||
|
WriteDLVal(writer, vaFlags.tex3MatIdx(), skinIdx);
|
||||||
|
WriteDLVal(writer, vaFlags.tex4MatIdx(), skinIdx);
|
||||||
|
WriteDLVal(writer, vaFlags.tex5MatIdx(), skinIdx);
|
||||||
|
WriteDLVal(writer, vaFlags.tex6MatIdx(), skinIdx);
|
||||||
|
WriteDLVal(writer, vaFlags.position(), vert.iPos);
|
||||||
|
WriteDLVal(writer, vaFlags.normal(), vert.iNorm);
|
||||||
|
WriteDLVal(writer, vaFlags.color0(), vert.iColor[0]);
|
||||||
|
WriteDLVal(writer, vaFlags.color1(), vert.iColor[1]);
|
||||||
|
WriteDLVal(writer, vaFlags.tex0(), vert.iUv[0]);
|
||||||
|
WriteDLVal(writer, vaFlags.tex1(), vert.iUv[1]);
|
||||||
|
WriteDLVal(writer, vaFlags.tex2(), vert.iUv[2]);
|
||||||
|
WriteDLVal(writer, vaFlags.tex3(), vert.iUv[3]);
|
||||||
|
WriteDLVal(writer, vaFlags.tex4(), vert.iUv[4]);
|
||||||
|
WriteDLVal(writer, vaFlags.tex5(), vert.iUv[5]);
|
||||||
|
WriteDLVal(writer, vaFlags.tex6(), vert.iUv[6]);
|
||||||
|
}
|
||||||
|
|
||||||
|
writer.fill(atUint8(0), *padIt);
|
||||||
|
++padIt;
|
||||||
|
}
|
||||||
|
|
||||||
|
writer.close();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -71,6 +71,15 @@ public:
|
||||||
snprintf(buf, 9, "%08X", m_id);
|
snprintf(buf, 9, "%08X", m_id);
|
||||||
return std::string(buf);
|
return std::string(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UniqueID32() = default;
|
||||||
|
UniqueID32(const char* hexStr)
|
||||||
|
{
|
||||||
|
char copy[9];
|
||||||
|
strncpy(copy, hexStr, 8);
|
||||||
|
copy[8] = '\0';
|
||||||
|
m_id = strtoul(copy, nullptr, 16);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/* PAK 64-bit Unique ID */
|
/* PAK 64-bit Unique ID */
|
||||||
|
@ -100,6 +109,15 @@ public:
|
||||||
snprintf(buf, 17, "%016" PRIX64, m_id);
|
snprintf(buf, 17, "%016" PRIX64, m_id);
|
||||||
return std::string(buf);
|
return std::string(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
UniqueID64() = default;
|
||||||
|
UniqueID64(const char* hexStr)
|
||||||
|
{
|
||||||
|
char copy[17];
|
||||||
|
strncpy(copy, hexStr, 16);
|
||||||
|
copy[16] = '\0';
|
||||||
|
m_id = strtouq(copy, nullptr, 16);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
/* PAK 128-bit Unique ID */
|
/* PAK 128-bit Unique ID */
|
||||||
|
|
|
@ -20,11 +20,13 @@ struct MaterialSet : BigDNA
|
||||||
struct MaterialSetHead : BigDNA
|
struct MaterialSetHead : BigDNA
|
||||||
{
|
{
|
||||||
DECL_DNA
|
DECL_DNA
|
||||||
Value<atUint32> textureCount;
|
Value<atUint32> textureCount = 0;
|
||||||
Vector<UniqueID32, DNA_COUNT(textureCount)> textureIDs;
|
Vector<UniqueID32, DNA_COUNT(textureCount)> textureIDs;
|
||||||
Value<atUint32> materialCount;
|
Value<atUint32> materialCount = 0;
|
||||||
Vector<atUint32, DNA_COUNT(materialCount)> materialEndOffs;
|
Vector<atUint32, DNA_COUNT(materialCount)> materialEndOffs;
|
||||||
} head;
|
} head;
|
||||||
|
void addTexture(const UniqueID32& id) {head.textureIDs.push_back(id); ++head.textureCount;}
|
||||||
|
void addMaterialEndOff(atUint32 off) {head.materialEndOffs.push_back(off); ++head.materialCount;}
|
||||||
|
|
||||||
struct Material : BigDNA
|
struct Material : BigDNA
|
||||||
{
|
{
|
||||||
|
@ -102,6 +104,32 @@ struct MaterialSet : BigDNA
|
||||||
void setTex5MatIdx(GX::AttrType val) {vaFlags &= ~0x40000000; vaFlags |= atUint32(val & 0x1) << 30;}
|
void setTex5MatIdx(GX::AttrType val) {vaFlags &= ~0x40000000; vaFlags |= atUint32(val & 0x1) << 30;}
|
||||||
GX::AttrType tex6MatIdx() const {return GX::AttrType(vaFlags >> 31 & 0x1);}
|
GX::AttrType tex6MatIdx() const {return GX::AttrType(vaFlags >> 31 & 0x1);}
|
||||||
void setTex6MatIdx(GX::AttrType val) {vaFlags &= ~0x80000000; vaFlags |= atUint32(val & 0x1) << 31;}
|
void setTex6MatIdx(GX::AttrType val) {vaFlags &= ~0x80000000; vaFlags |= atUint32(val & 0x1) << 31;}
|
||||||
|
|
||||||
|
size_t vertDLSize() const
|
||||||
|
{
|
||||||
|
static size_t ATTR_SZ[] = {0,1,1,2};
|
||||||
|
size_t ret = 0;
|
||||||
|
ret += ATTR_SZ[position()];
|
||||||
|
ret += ATTR_SZ[normal()];
|
||||||
|
ret += ATTR_SZ[color0()];
|
||||||
|
ret += ATTR_SZ[color1()];
|
||||||
|
ret += ATTR_SZ[tex0()];
|
||||||
|
ret += ATTR_SZ[tex1()];
|
||||||
|
ret += ATTR_SZ[tex2()];
|
||||||
|
ret += ATTR_SZ[tex3()];
|
||||||
|
ret += ATTR_SZ[tex4()];
|
||||||
|
ret += ATTR_SZ[tex5()];
|
||||||
|
ret += ATTR_SZ[tex6()];
|
||||||
|
ret += ATTR_SZ[pnMatIdx()];
|
||||||
|
ret += ATTR_SZ[tex0MatIdx()];
|
||||||
|
ret += ATTR_SZ[tex1MatIdx()];
|
||||||
|
ret += ATTR_SZ[tex2MatIdx()];
|
||||||
|
ret += ATTR_SZ[tex3MatIdx()];
|
||||||
|
ret += ATTR_SZ[tex4MatIdx()];
|
||||||
|
ret += ATTR_SZ[tex5MatIdx()];
|
||||||
|
ret += ATTR_SZ[tex6MatIdx()];
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
} vaFlags;
|
} vaFlags;
|
||||||
const VAFlags& getVAFlags() const {return vaFlags;}
|
const VAFlags& getVAFlags() const {return vaFlags;}
|
||||||
Value<atUint32> groupIdx;
|
Value<atUint32> groupIdx;
|
||||||
|
|
|
@ -18,6 +18,10 @@ struct MaterialSet : BigDNA
|
||||||
DECL_DNA
|
DECL_DNA
|
||||||
Value<atUint32> materialCount;
|
Value<atUint32> materialCount;
|
||||||
|
|
||||||
|
/* Dummy methods from MP1/2 */
|
||||||
|
void addTexture(const UniqueID32&) {}
|
||||||
|
void addMaterialEndOff(atUint32) {++materialCount;}
|
||||||
|
|
||||||
struct Material : BigDNA
|
struct Material : BigDNA
|
||||||
{
|
{
|
||||||
Delete expl;
|
Delete expl;
|
||||||
|
|
|
@ -282,7 +282,7 @@ struct SpecMP1 : SpecBase
|
||||||
|
|
||||||
void cookMesh(const HECL::ProjectPath& out, const HECL::ProjectPath& in, BlendStream& ds) const
|
void cookMesh(const HECL::ProjectPath& out, const HECL::ProjectPath& in, BlendStream& ds) const
|
||||||
{
|
{
|
||||||
Mesh mesh = ds.compileMesh();
|
Mesh mesh = ds.compileMesh(-1);
|
||||||
DNAMP1::CMDL::Cook(out, in, mesh);
|
DNAMP1::CMDL::Cook(out, in, mesh);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
2
hecl
2
hecl
|
@ -1 +1 @@
|
||||||
Subproject commit 7dac1ffef13697a8fe2478c1f29292cd2c95e67d
|
Subproject commit ad061af83e93d766aab3bd0985a7984f9cbea5bf
|
Loading…
Reference in New Issue