mirror of https://github.com/AxioDL/metaforce.git
initial HMDL/CMDL implementation
This commit is contained in:
parent
9bbe5da6da
commit
79cf5f12ca
|
@ -1129,7 +1129,7 @@ bool WriteCMDL(const HECL::ProjectPath& outPath, const HECL::ProjectPath& inPath
|
|||
false, false, groupIdx);
|
||||
|
||||
endOff = targetMSet.materials.back().binarySize(endOff);
|
||||
targetMSet.addMaterialEndOff(endOff);
|
||||
targetMSet.head.addMaterialEndOff(endOff);
|
||||
}
|
||||
|
||||
for (const HECL::ProjectPath& path : texPaths)
|
||||
|
@ -1139,7 +1139,7 @@ bool WriteCMDL(const HECL::ProjectPath& outPath, const HECL::ProjectPath& inPath
|
|||
/* TODO: incorporate hecl hashes */
|
||||
size_t search = relPath.find(_S("TXTR_"));
|
||||
if (search != HECL::SystemString::npos)
|
||||
targetMSet.addTexture(relPath.c_str() + search + 5);
|
||||
targetMSet.head.addTexture(relPath.c_str() + search + 5);
|
||||
else
|
||||
LogDNACommon.report(LogVisor::FatalError, "unable to get hash from path");
|
||||
}
|
||||
|
@ -1259,9 +1259,9 @@ bool WriteCMDL(const HECL::ProjectPath& outPath, const HECL::ProjectPath& inPath
|
|||
|
||||
/* Surfaces */
|
||||
GX::Primitive prim;
|
||||
if (mesh.outputMode == Mesh::OutputTriangles)
|
||||
if (mesh.topology == HECL::TopologyTriangles)
|
||||
prim = GX::TRIANGLES;
|
||||
else if (mesh.outputMode == Mesh::OutputTriStrips)
|
||||
else if (mesh.topology == HECL::TopologyTriStrips)
|
||||
prim = GX::TRIANGLESTRIP;
|
||||
else
|
||||
LogDNACommon.report(LogVisor::FatalError, "unrecognized mesh output mode");
|
||||
|
@ -1313,6 +1313,181 @@ bool WriteCMDL(const HECL::ProjectPath& outPath, const HECL::ProjectPath& inPath
|
|||
return true;
|
||||
}
|
||||
|
||||
template <class MaterialSet, class SurfaceHeader, atUint32 Version>
|
||||
bool WriteHMDLCMDL(const HECL::ProjectPath& outPath, const HECL::ProjectPath& inPath, const Mesh& mesh)
|
||||
{
|
||||
Header head;
|
||||
head.magic = 0xDEADBABE;
|
||||
head.version = 0x10000 | Version;
|
||||
head.aabbMin = mesh.aabbMin.val;
|
||||
head.aabbMax = mesh.aabbMax.val;
|
||||
head.matSetCount = mesh.materialSets.size();
|
||||
head.secCount = head.matSetCount + 5 + mesh.surfaces.size();
|
||||
head.secSizes.reserve(head.secCount);
|
||||
|
||||
/* Lengths of padding to insert while writing */
|
||||
std::vector<size_t> paddingSizes;
|
||||
paddingSizes.reserve(head.secCount);
|
||||
|
||||
/* Build material sets */
|
||||
std::vector<MaterialSet> matSets;
|
||||
matSets.reserve(mesh.materialSets.size());
|
||||
{
|
||||
HECL::Frontend::Frontend FE;
|
||||
for (const std::vector<Mesh::Material>& mset : mesh.materialSets)
|
||||
{
|
||||
matSets.emplace_back();
|
||||
MaterialSet& targetMSet = matSets.back();
|
||||
std::vector<HECL::ProjectPath> texPaths;
|
||||
texPaths.reserve(mset.size()*4);
|
||||
for (const Mesh::Material& mat : mset)
|
||||
{
|
||||
for (const HECL::ProjectPath& path : mat.texs)
|
||||
{
|
||||
bool found = false;
|
||||
for (const HECL::ProjectPath& ePath : texPaths)
|
||||
{
|
||||
if (path == ePath)
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
texPaths.push_back(path);
|
||||
}
|
||||
}
|
||||
|
||||
size_t endOff = 0;
|
||||
for (const Mesh::Material& mat : mset)
|
||||
{
|
||||
std::string diagName = HECL::Format("%s:%s", inPath.getLastComponentUTF8(), mat.name.c_str());
|
||||
targetMSet.materials.emplace_back(FE, diagName, mat, mat.iprops, texPaths);
|
||||
endOff = targetMSet.materials.back().binarySize(endOff);
|
||||
targetMSet.head.addMaterialEndOff(endOff);
|
||||
}
|
||||
|
||||
for (const HECL::ProjectPath& path : texPaths)
|
||||
{
|
||||
const HECL::SystemString& relPath = path.getRelativePath();
|
||||
|
||||
/* TODO: incorporate hecl hashes */
|
||||
size_t search = relPath.find(_S("TXTR_"));
|
||||
if (search != HECL::SystemString::npos)
|
||||
targetMSet.head.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);
|
||||
}
|
||||
}
|
||||
|
||||
HECL::HMDLBuffers bufs = mesh.getHMDLBuffers();
|
||||
|
||||
/* Metadata */
|
||||
size_t secSz = bufs.m_metaSz;
|
||||
size_t secSz32 = ROUND_UP_32(secSz);
|
||||
if (secSz32 == 0)
|
||||
secSz32 = 32;
|
||||
head.secSizes.push_back(secSz32);
|
||||
paddingSizes.push_back(secSz32 - secSz);
|
||||
|
||||
/* VBO */
|
||||
secSz = bufs.m_vboSz;
|
||||
secSz32 = ROUND_UP_32(secSz);
|
||||
if (secSz32 == 0)
|
||||
secSz32 = 32;
|
||||
head.secSizes.push_back(secSz32);
|
||||
paddingSizes.push_back(secSz32 - secSz);
|
||||
|
||||
/* IBO */
|
||||
secSz = bufs.m_iboSz;
|
||||
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(bufs.m_surfaces.size());
|
||||
secSz = bufs.m_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 HECL::HMDLBuffers::Surface& surf : bufs.m_surfaces)
|
||||
{
|
||||
head.secSizes.push_back(64);
|
||||
paddingSizes.push_back(0);
|
||||
endOff += 64;
|
||||
surfEndOffs.push_back(endOff);
|
||||
}
|
||||
|
||||
/* Write sections */
|
||||
Athena::io::FileWriter writer(outPath.getAbsolutePath());
|
||||
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;
|
||||
}
|
||||
|
||||
/* Metadata */
|
||||
writer.writeUBytes(bufs.m_metaData.get(), bufs.m_metaSz);
|
||||
writer.fill(atUint8(0), *padIt);
|
||||
++padIt;
|
||||
|
||||
/* VBO */
|
||||
writer.writeUBytes(bufs.m_vboData.get(), bufs.m_vboSz);
|
||||
writer.fill(atUint8(0), *padIt);
|
||||
++padIt;
|
||||
|
||||
/* IBO */
|
||||
writer.writeUBytes(bufs.m_iboData.get(), bufs.m_iboSz);
|
||||
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 HECL::HMDLBuffers::Surface& surf : bufs.m_surfaces)
|
||||
{
|
||||
const Mesh::Surface& osurf = surf.m_origSurf;
|
||||
|
||||
SurfaceHeader header;
|
||||
header.centroid = osurf.centroid;
|
||||
header.matIdx = osurf.materialIdx;
|
||||
header.reflectionNormal = osurf.reflectionNormal;
|
||||
header.unk1 = surf.m_start;
|
||||
header.unk2 = surf.m_count;
|
||||
header.write(writer);
|
||||
|
||||
writer.fill(atUint8(0), *padIt);
|
||||
++padIt;
|
||||
}
|
||||
|
||||
writer.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -53,7 +53,7 @@ struct CMDL
|
|||
/* Cook and re-extract test */
|
||||
HECL::ProjectPath tempOut = outPath.getWithExtension(_S(".recook"), true);
|
||||
HECL::BlenderConnection::DataStream ds = conn.beginData();
|
||||
DNACMDL::Mesh mesh = ds.compileMesh(DNACMDL::Mesh::OutputTriStrips, -1);
|
||||
DNACMDL::Mesh mesh = ds.compileMesh(HECL::TopologyTriStrips, -1);
|
||||
ds.close();
|
||||
DNACMDL::WriteCMDL<MaterialSet, DNACMDL::SurfaceHeader_1_2, 2>(tempOut, outPath, mesh);
|
||||
|
||||
|
@ -108,6 +108,34 @@ struct CMDL
|
|||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool HMDLCook(const HECL::ProjectPath& outPath,
|
||||
const HECL::ProjectPath& inPath,
|
||||
const DNACMDL::Mesh& mesh)
|
||||
{
|
||||
HECL::ProjectPath tempOut = outPath.getWithExtension(_S(".recook"));
|
||||
if (mesh.skins.size())
|
||||
{
|
||||
if (!DNACMDL::WriteHMDLCMDL<HMDLMaterialSet, DNACMDL::SurfaceHeader_1_2, 2>(tempOut, inPath, mesh))
|
||||
return false;
|
||||
|
||||
/* Output skinning intermediate */
|
||||
Athena::io::FileWriter writer(outPath.getWithExtension(_S(".skin")).getAbsolutePath());
|
||||
writer.writeUint32Big(mesh.skinBanks.banks.size());
|
||||
for (const DNACMDL::Mesh::SkinBanks::Bank& sb : mesh.skinBanks.banks)
|
||||
{
|
||||
writer.writeUint32Big(sb.m_boneIdxs.size());
|
||||
for (uint32_t bind : sb.m_boneIdxs)
|
||||
writer.writeUint32Big(bind);
|
||||
}
|
||||
writer.writeUint32Big(mesh.boneNames.size());
|
||||
for (const std::string& boneName : mesh.boneNames)
|
||||
writer.writeString(boneName);
|
||||
}
|
||||
else if (!DNACMDL::WriteHMDLCMDL<HMDLMaterialSet, DNACMDL::SurfaceHeader_1_2, 2>(tempOut, inPath, mesh))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -1139,7 +1139,7 @@ MaterialSet::Material::Material(const HECL::Backend::GX& gx,
|
|||
{
|
||||
found = true;
|
||||
++uvAnimsCount;
|
||||
uvAnims.emplace_back(tcg);
|
||||
uvAnims.emplace_back(tcg.m_gameFunction, tcg.m_gameArgs);
|
||||
uvAnimsSize = uvAnims.back().binarySize(uvAnimsSize);
|
||||
break;
|
||||
}
|
||||
|
@ -1149,62 +1149,151 @@ MaterialSet::Material::Material(const HECL::Backend::GX& gx,
|
|||
}
|
||||
}
|
||||
|
||||
MaterialSet::Material::UVAnimation::UVAnimation(const HECL::Backend::GX::TexCoordGen& tcg)
|
||||
HMDLMaterialSet::Material::Material(HECL::Frontend::Frontend& FE,
|
||||
const std::string& diagName,
|
||||
const HECL::BlenderConnection::DataStream::Mesh::Material& mat,
|
||||
const std::unordered_map<std::string, int32_t>& iprops,
|
||||
const std::vector<HECL::ProjectPath>& texPaths)
|
||||
{
|
||||
if (!tcg.m_gameFunction.compare("RetroUVMode0Node"))
|
||||
auto search = iprops.find("retro_depth_sort");
|
||||
if (search != iprops.end())
|
||||
flags.setDepthSorting(search->second != 0);
|
||||
|
||||
search = iprops.find("retro_punchthrough_alpha");
|
||||
if (search != iprops.end())
|
||||
flags.setPunchthroughAlpha(search->second != 0);
|
||||
|
||||
search = iprops.find("retro_samus_reflection");
|
||||
if (search != iprops.end())
|
||||
flags.setSamusReflection(search->second != 0);
|
||||
|
||||
search = iprops.find("retro_depth_write");
|
||||
if (search != iprops.end())
|
||||
flags.setDepthWrite(search->second != 0);
|
||||
|
||||
search = iprops.find("retro_samus_reflection_persp");
|
||||
if (search != iprops.end())
|
||||
flags.setSamusReflectionSurfaceEye(search->second != 0);
|
||||
|
||||
search = iprops.find("retro_shadow_occluder");
|
||||
if (search != iprops.end())
|
||||
flags.setShadowOccluderMesh(search->second != 0);
|
||||
|
||||
search = iprops.find("retro_samus_reflection_indirect");
|
||||
if (search != iprops.end())
|
||||
flags.setSamusReflectionIndirectTexture(search->second != 0);
|
||||
|
||||
search = iprops.find("retro_lightmapped");
|
||||
if (search != iprops.end())
|
||||
flags.setLightmap(search->second != 0);
|
||||
|
||||
for (const HECL::ProjectPath& path : mat.texs)
|
||||
{
|
||||
size_t idx = 0;
|
||||
for (const HECL::ProjectPath& tPath : texPaths)
|
||||
{
|
||||
if (path == tPath)
|
||||
{
|
||||
textureIdxs.push_back(idx);
|
||||
++textureCount;
|
||||
break;
|
||||
}
|
||||
++idx;
|
||||
}
|
||||
}
|
||||
|
||||
if (flags.samusReflectionIndirectTexture())
|
||||
indTexSlot.push_back(textureIdxs.size());
|
||||
|
||||
heclSource = mat.source;
|
||||
heclIr = FE.compileSource(mat.source, diagName);
|
||||
|
||||
uvAnimsSize = 4;
|
||||
uvAnimsCount = 0;
|
||||
for (const HECL::Frontend::IR::Instruction& inst : heclIr.m_instructions)
|
||||
{
|
||||
if (inst.m_op != HECL::Frontend::IR::OpCall)
|
||||
continue;
|
||||
if (inst.m_call.m_name.compare("Texture"))
|
||||
continue;
|
||||
|
||||
const HECL::Frontend::IR::Instruction& sourceInst = inst.getChildInst(heclIr, 1);
|
||||
if (sourceInst.m_op != HECL::Frontend::IR::OpCall)
|
||||
continue;
|
||||
if (sourceInst.m_call.m_name.compare(0, 11, "RetroUVMode"))
|
||||
continue;
|
||||
|
||||
std::vector<atVec4f> gameArgs;
|
||||
gameArgs.reserve(inst.getChildCount() - 1);
|
||||
for (int i=1 ; i<inst.getChildCount() ; ++i)
|
||||
{
|
||||
const HECL::Frontend::IR::Instruction& ci = sourceInst.getChildInst(heclIr, i);
|
||||
gameArgs.push_back(ci.getImmVec());
|
||||
}
|
||||
|
||||
++uvAnimsCount;
|
||||
uvAnims.emplace_back(sourceInst.m_call.m_name, gameArgs);
|
||||
uvAnimsSize = uvAnims.back().binarySize(uvAnimsSize);
|
||||
}
|
||||
}
|
||||
|
||||
MaterialSet::Material::UVAnimation::UVAnimation(const std::string& gameFunction,
|
||||
const std::vector<atVec4f>& gameArgs)
|
||||
{
|
||||
if (!gameFunction.compare("RetroUVMode0Node"))
|
||||
mode = ANIM_MV_INV_NOTRANS;
|
||||
else if (!tcg.m_gameFunction.compare("RetroUVMode1Node"))
|
||||
else if (!gameFunction.compare("RetroUVMode1Node"))
|
||||
mode = ANIM_MV_INV;
|
||||
else if (!tcg.m_gameFunction.compare("RetroUVMode2Node"))
|
||||
else if (!gameFunction.compare("RetroUVMode2Node"))
|
||||
{
|
||||
mode = ANIM_SCROLL;
|
||||
if (tcg.m_gameArgs.size() < 2)
|
||||
if (gameArgs.size() < 2)
|
||||
Log.report(LogVisor::FatalError, "Mode2 UV anim requires 2 vector arguments");
|
||||
vals[0] = tcg.m_gameArgs[0].vec[0];
|
||||
vals[1] = tcg.m_gameArgs[0].vec[1];
|
||||
vals[2] = tcg.m_gameArgs[1].vec[0];
|
||||
vals[3] = tcg.m_gameArgs[1].vec[1];
|
||||
vals[0] = gameArgs[0].vec[0];
|
||||
vals[1] = gameArgs[0].vec[1];
|
||||
vals[2] = gameArgs[1].vec[0];
|
||||
vals[3] = gameArgs[1].vec[1];
|
||||
}
|
||||
else if (!tcg.m_gameFunction.compare("RetroUVMode3Node"))
|
||||
else if (!gameFunction.compare("RetroUVMode3Node"))
|
||||
{
|
||||
mode = ANIM_ROTATION;
|
||||
if (tcg.m_gameArgs.size() < 2)
|
||||
if (gameArgs.size() < 2)
|
||||
Log.report(LogVisor::FatalError, "Mode3 UV anim requires 2 arguments");
|
||||
vals[0] = tcg.m_gameArgs[0].vec[0];
|
||||
vals[1] = tcg.m_gameArgs[1].vec[0];
|
||||
vals[0] = gameArgs[0].vec[0];
|
||||
vals[1] = gameArgs[1].vec[0];
|
||||
}
|
||||
else if (!tcg.m_gameFunction.compare("RetroUVMode4Node"))
|
||||
else if (!gameFunction.compare("RetroUVMode4Node"))
|
||||
{
|
||||
mode = ANIM_HSTRIP;
|
||||
if (tcg.m_gameArgs.size() < 4)
|
||||
if (gameArgs.size() < 4)
|
||||
Log.report(LogVisor::FatalError, "Mode4 UV anim requires 4 arguments");
|
||||
vals[0] = tcg.m_gameArgs[0].vec[0];
|
||||
vals[1] = tcg.m_gameArgs[1].vec[0];
|
||||
vals[2] = tcg.m_gameArgs[2].vec[0];
|
||||
vals[3] = tcg.m_gameArgs[3].vec[0];
|
||||
vals[0] = gameArgs[0].vec[0];
|
||||
vals[1] = gameArgs[1].vec[0];
|
||||
vals[2] = gameArgs[2].vec[0];
|
||||
vals[3] = gameArgs[3].vec[0];
|
||||
}
|
||||
else if (!tcg.m_gameFunction.compare("RetroUVMode5Node"))
|
||||
else if (!gameFunction.compare("RetroUVMode5Node"))
|
||||
{
|
||||
mode = ANIM_VSTRIP;
|
||||
if (tcg.m_gameArgs.size() < 4)
|
||||
if (gameArgs.size() < 4)
|
||||
Log.report(LogVisor::FatalError, "Mode5 UV anim requires 4 arguments");
|
||||
vals[0] = tcg.m_gameArgs[0].vec[0];
|
||||
vals[1] = tcg.m_gameArgs[1].vec[0];
|
||||
vals[2] = tcg.m_gameArgs[2].vec[0];
|
||||
vals[3] = tcg.m_gameArgs[3].vec[0];
|
||||
vals[0] = gameArgs[0].vec[0];
|
||||
vals[1] = gameArgs[1].vec[0];
|
||||
vals[2] = gameArgs[2].vec[0];
|
||||
vals[3] = gameArgs[3].vec[0];
|
||||
}
|
||||
else if (!tcg.m_gameFunction.compare("RetroUVMode6Node"))
|
||||
else if (!gameFunction.compare("RetroUVMode6Node"))
|
||||
mode = ANIM_MODEL;
|
||||
else if (!tcg.m_gameFunction.compare("RetroUVMode7Node"))
|
||||
else if (!gameFunction.compare("RetroUVMode7Node"))
|
||||
{
|
||||
mode = ANIM_MODE_WHO_MUST_NOT_BE_NAMED;
|
||||
if (tcg.m_gameArgs.size() < 2)
|
||||
if (gameArgs.size() < 2)
|
||||
Log.report(LogVisor::FatalError, "Mode7 UV anim requires 2 arguments");
|
||||
vals[0] = tcg.m_gameArgs[0].vec[0];
|
||||
vals[1] = tcg.m_gameArgs[1].vec[0];
|
||||
vals[0] = gameArgs[0].vec[0];
|
||||
vals[1] = gameArgs[1].vec[0];
|
||||
}
|
||||
else
|
||||
Log.report(LogVisor::FatalError, "unsupported UV anim '%s'", tcg.m_gameFunction.c_str());
|
||||
Log.report(LogVisor::FatalError, "unsupported UV anim '%s'", gameFunction.c_str());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -24,9 +24,10 @@ struct MaterialSet : BigDNA
|
|||
Vector<UniqueID32, DNA_COUNT(textureCount)> textureIDs;
|
||||
Value<atUint32> materialCount = 0;
|
||||
Vector<atUint32, DNA_COUNT(materialCount)> materialEndOffs;
|
||||
|
||||
void addTexture(const UniqueID32& id) {textureIDs.push_back(id); ++textureCount;}
|
||||
void addMaterialEndOff(atUint32 off) {materialEndOffs.push_back(off); ++materialCount;}
|
||||
} 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
|
||||
{
|
||||
|
@ -370,7 +371,8 @@ struct MaterialSet : BigDNA
|
|||
}
|
||||
|
||||
UVAnimation() = default;
|
||||
UVAnimation(const HECL::Backend::GX::TexCoordGen& tcg);
|
||||
UVAnimation(const std::string& gameFunction,
|
||||
const std::vector<atVec4f>& gameArgs);
|
||||
};
|
||||
Vector<UVAnimation, DNA_COUNT(uvAnimsCount)> uvAnims;
|
||||
|
||||
|
@ -455,6 +457,40 @@ struct MaterialSet : BigDNA
|
|||
|
||||
};
|
||||
|
||||
struct HMDLMaterialSet : BigDNA
|
||||
{
|
||||
static constexpr bool OneSection() {return false;}
|
||||
|
||||
DECL_DNA
|
||||
MaterialSet::MaterialSetHead head;
|
||||
|
||||
struct Material : BigDNA
|
||||
{
|
||||
DECL_DNA
|
||||
MaterialSet::Material::Flags flags;
|
||||
|
||||
Value<atUint32> textureCount = 0;
|
||||
Vector<atUint32, DNA_COUNT(textureCount)> textureIdxs;
|
||||
|
||||
Vector<atUint32, DNA_COUNT(flags.samusReflectionIndirectTexture())> indTexSlot;
|
||||
|
||||
Value<atUint32> uvAnimsSize = 4;
|
||||
Value<atUint32> uvAnimsCount = 0;
|
||||
Vector<MaterialSet::Material::UVAnimation, DNA_COUNT(uvAnimsCount)> uvAnims;
|
||||
|
||||
String<-1> heclSource;
|
||||
HECL::Frontend::IR heclIr;
|
||||
|
||||
Material() = default;
|
||||
Material(HECL::Frontend::Frontend& FE,
|
||||
const std::string& diagName,
|
||||
const HECL::BlenderConnection::DataStream::Mesh::Material& mat,
|
||||
const std::unordered_map<std::string, int32_t>& iprops,
|
||||
const std::vector<HECL::ProjectPath>& texPaths);
|
||||
};
|
||||
Vector<Material, DNA_COUNT(head.materialCount)> materials;
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -289,7 +289,7 @@ struct SpecMP1 : SpecBase
|
|||
void cookMesh(const HECL::ProjectPath& out, const HECL::ProjectPath& in,
|
||||
BlendStream& ds, bool fast, FCookProgress progress) const
|
||||
{
|
||||
Mesh mesh = ds.compileMesh(fast ? Mesh::OutputTriangles : Mesh::OutputTriStrips, -1,
|
||||
Mesh mesh = ds.compileMesh(fast ? HECL::TopologyTriangles : HECL::TopologyTriStrips, -1,
|
||||
[&progress](int surfCount)
|
||||
{
|
||||
progress(HECL::SysFormat(_S("%d"), surfCount).c_str());
|
||||
|
|
2
hecl
2
hecl
|
@ -1 +1 @@
|
|||
Subproject commit 0bf9065e42a62675aefcb139d808c493a0926de8
|
||||
Subproject commit d4460a3970f70e56248464533448169f81301ce3
|
Loading…
Reference in New Issue