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);
|
false, false, groupIdx);
|
||||||
|
|
||||||
endOff = targetMSet.materials.back().binarySize(endOff);
|
endOff = targetMSet.materials.back().binarySize(endOff);
|
||||||
targetMSet.addMaterialEndOff(endOff);
|
targetMSet.head.addMaterialEndOff(endOff);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const HECL::ProjectPath& path : texPaths)
|
for (const HECL::ProjectPath& path : texPaths)
|
||||||
|
@ -1139,7 +1139,7 @@ bool WriteCMDL(const HECL::ProjectPath& outPath, const HECL::ProjectPath& inPath
|
||||||
/* TODO: incorporate hecl hashes */
|
/* TODO: incorporate hecl hashes */
|
||||||
size_t search = relPath.find(_S("TXTR_"));
|
size_t search = relPath.find(_S("TXTR_"));
|
||||||
if (search != HECL::SystemString::npos)
|
if (search != HECL::SystemString::npos)
|
||||||
targetMSet.addTexture(relPath.c_str() + search + 5);
|
targetMSet.head.addTexture(relPath.c_str() + search + 5);
|
||||||
else
|
else
|
||||||
LogDNACommon.report(LogVisor::FatalError, "unable to get hash from path");
|
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 */
|
/* Surfaces */
|
||||||
GX::Primitive prim;
|
GX::Primitive prim;
|
||||||
if (mesh.outputMode == Mesh::OutputTriangles)
|
if (mesh.topology == HECL::TopologyTriangles)
|
||||||
prim = GX::TRIANGLES;
|
prim = GX::TRIANGLES;
|
||||||
else if (mesh.outputMode == Mesh::OutputTriStrips)
|
else if (mesh.topology == HECL::TopologyTriStrips)
|
||||||
prim = GX::TRIANGLESTRIP;
|
prim = GX::TRIANGLESTRIP;
|
||||||
else
|
else
|
||||||
LogDNACommon.report(LogVisor::FatalError, "unrecognized mesh output mode");
|
LogDNACommon.report(LogVisor::FatalError, "unrecognized mesh output mode");
|
||||||
|
@ -1313,6 +1313,181 @@ bool WriteCMDL(const HECL::ProjectPath& outPath, const HECL::ProjectPath& inPath
|
||||||
return true;
|
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 */
|
/* Cook and re-extract test */
|
||||||
HECL::ProjectPath tempOut = outPath.getWithExtension(_S(".recook"), true);
|
HECL::ProjectPath tempOut = outPath.getWithExtension(_S(".recook"), true);
|
||||||
HECL::BlenderConnection::DataStream ds = conn.beginData();
|
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();
|
ds.close();
|
||||||
DNACMDL::WriteCMDL<MaterialSet, DNACMDL::SurfaceHeader_1_2, 2>(tempOut, outPath, mesh);
|
DNACMDL::WriteCMDL<MaterialSet, DNACMDL::SurfaceHeader_1_2, 2>(tempOut, outPath, mesh);
|
||||||
|
|
||||||
|
@ -108,6 +108,34 @@ struct CMDL
|
||||||
return false;
|
return false;
|
||||||
return true;
|
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;
|
found = true;
|
||||||
++uvAnimsCount;
|
++uvAnimsCount;
|
||||||
uvAnims.emplace_back(tcg);
|
uvAnims.emplace_back(tcg.m_gameFunction, tcg.m_gameArgs);
|
||||||
uvAnimsSize = uvAnims.back().binarySize(uvAnimsSize);
|
uvAnimsSize = uvAnims.back().binarySize(uvAnimsSize);
|
||||||
break;
|
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;
|
mode = ANIM_MV_INV_NOTRANS;
|
||||||
else if (!tcg.m_gameFunction.compare("RetroUVMode1Node"))
|
else if (!gameFunction.compare("RetroUVMode1Node"))
|
||||||
mode = ANIM_MV_INV;
|
mode = ANIM_MV_INV;
|
||||||
else if (!tcg.m_gameFunction.compare("RetroUVMode2Node"))
|
else if (!gameFunction.compare("RetroUVMode2Node"))
|
||||||
{
|
{
|
||||||
mode = ANIM_SCROLL;
|
mode = ANIM_SCROLL;
|
||||||
if (tcg.m_gameArgs.size() < 2)
|
if (gameArgs.size() < 2)
|
||||||
Log.report(LogVisor::FatalError, "Mode2 UV anim requires 2 vector arguments");
|
Log.report(LogVisor::FatalError, "Mode2 UV anim requires 2 vector arguments");
|
||||||
vals[0] = tcg.m_gameArgs[0].vec[0];
|
vals[0] = gameArgs[0].vec[0];
|
||||||
vals[1] = tcg.m_gameArgs[0].vec[1];
|
vals[1] = gameArgs[0].vec[1];
|
||||||
vals[2] = tcg.m_gameArgs[1].vec[0];
|
vals[2] = gameArgs[1].vec[0];
|
||||||
vals[3] = tcg.m_gameArgs[1].vec[1];
|
vals[3] = gameArgs[1].vec[1];
|
||||||
}
|
}
|
||||||
else if (!tcg.m_gameFunction.compare("RetroUVMode3Node"))
|
else if (!gameFunction.compare("RetroUVMode3Node"))
|
||||||
{
|
{
|
||||||
mode = ANIM_ROTATION;
|
mode = ANIM_ROTATION;
|
||||||
if (tcg.m_gameArgs.size() < 2)
|
if (gameArgs.size() < 2)
|
||||||
Log.report(LogVisor::FatalError, "Mode3 UV anim requires 2 arguments");
|
Log.report(LogVisor::FatalError, "Mode3 UV anim requires 2 arguments");
|
||||||
vals[0] = tcg.m_gameArgs[0].vec[0];
|
vals[0] = gameArgs[0].vec[0];
|
||||||
vals[1] = tcg.m_gameArgs[1].vec[0];
|
vals[1] = gameArgs[1].vec[0];
|
||||||
}
|
}
|
||||||
else if (!tcg.m_gameFunction.compare("RetroUVMode4Node"))
|
else if (!gameFunction.compare("RetroUVMode4Node"))
|
||||||
{
|
{
|
||||||
mode = ANIM_HSTRIP;
|
mode = ANIM_HSTRIP;
|
||||||
if (tcg.m_gameArgs.size() < 4)
|
if (gameArgs.size() < 4)
|
||||||
Log.report(LogVisor::FatalError, "Mode4 UV anim requires 4 arguments");
|
Log.report(LogVisor::FatalError, "Mode4 UV anim requires 4 arguments");
|
||||||
vals[0] = tcg.m_gameArgs[0].vec[0];
|
vals[0] = gameArgs[0].vec[0];
|
||||||
vals[1] = tcg.m_gameArgs[1].vec[0];
|
vals[1] = gameArgs[1].vec[0];
|
||||||
vals[2] = tcg.m_gameArgs[2].vec[0];
|
vals[2] = gameArgs[2].vec[0];
|
||||||
vals[3] = tcg.m_gameArgs[3].vec[0];
|
vals[3] = gameArgs[3].vec[0];
|
||||||
}
|
}
|
||||||
else if (!tcg.m_gameFunction.compare("RetroUVMode5Node"))
|
else if (!gameFunction.compare("RetroUVMode5Node"))
|
||||||
{
|
{
|
||||||
mode = ANIM_VSTRIP;
|
mode = ANIM_VSTRIP;
|
||||||
if (tcg.m_gameArgs.size() < 4)
|
if (gameArgs.size() < 4)
|
||||||
Log.report(LogVisor::FatalError, "Mode5 UV anim requires 4 arguments");
|
Log.report(LogVisor::FatalError, "Mode5 UV anim requires 4 arguments");
|
||||||
vals[0] = tcg.m_gameArgs[0].vec[0];
|
vals[0] = gameArgs[0].vec[0];
|
||||||
vals[1] = tcg.m_gameArgs[1].vec[0];
|
vals[1] = gameArgs[1].vec[0];
|
||||||
vals[2] = tcg.m_gameArgs[2].vec[0];
|
vals[2] = gameArgs[2].vec[0];
|
||||||
vals[3] = tcg.m_gameArgs[3].vec[0];
|
vals[3] = gameArgs[3].vec[0];
|
||||||
}
|
}
|
||||||
else if (!tcg.m_gameFunction.compare("RetroUVMode6Node"))
|
else if (!gameFunction.compare("RetroUVMode6Node"))
|
||||||
mode = ANIM_MODEL;
|
mode = ANIM_MODEL;
|
||||||
else if (!tcg.m_gameFunction.compare("RetroUVMode7Node"))
|
else if (!gameFunction.compare("RetroUVMode7Node"))
|
||||||
{
|
{
|
||||||
mode = ANIM_MODE_WHO_MUST_NOT_BE_NAMED;
|
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");
|
Log.report(LogVisor::FatalError, "Mode7 UV anim requires 2 arguments");
|
||||||
vals[0] = tcg.m_gameArgs[0].vec[0];
|
vals[0] = gameArgs[0].vec[0];
|
||||||
vals[1] = tcg.m_gameArgs[1].vec[0];
|
vals[1] = gameArgs[1].vec[0];
|
||||||
}
|
}
|
||||||
else
|
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;
|
Vector<UniqueID32, DNA_COUNT(textureCount)> textureIDs;
|
||||||
Value<atUint32> materialCount = 0;
|
Value<atUint32> materialCount = 0;
|
||||||
Vector<atUint32, DNA_COUNT(materialCount)> materialEndOffs;
|
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;
|
} 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
|
||||||
{
|
{
|
||||||
|
@ -370,7 +371,8 @@ struct MaterialSet : BigDNA
|
||||||
}
|
}
|
||||||
|
|
||||||
UVAnimation() = default;
|
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;
|
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,
|
void cookMesh(const HECL::ProjectPath& out, const HECL::ProjectPath& in,
|
||||||
BlendStream& ds, bool fast, FCookProgress progress) const
|
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](int surfCount)
|
||||||
{
|
{
|
||||||
progress(HECL::SysFormat(_S("%d"), surfCount).c_str());
|
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