metaforce/DataSpec/DNAMP1/CMDL.hpp

171 lines
6.6 KiB
C++
Raw Normal View History

2015-07-25 03:43:49 +00:00
#ifndef _DNAMP1_CMDL_HPP_
#define _DNAMP1_CMDL_HPP_
#include "../DNACommon/DNACommon.hpp"
#include "../DNACommon/CMDL.hpp"
2015-07-25 03:43:49 +00:00
#include "CMDLMaterials.hpp"
#include "DNAMP1.hpp"
2015-08-13 07:29:00 +00:00
#include "CINF.hpp"
#include "CSKR.hpp"
2015-07-25 03:43:49 +00:00
2016-03-04 23:04:53 +00:00
#include <athena/FileReader.hpp>
2015-10-21 01:34:35 +00:00
2016-02-13 09:02:47 +00:00
namespace DataSpec
2015-07-25 03:43:49 +00:00
{
namespace DNAMP1
{
2015-07-28 02:24:36 +00:00
struct CMDL
2015-07-25 03:43:49 +00:00
{
2015-08-05 21:46:07 +00:00
static bool Extract(const SpecBase& dataSpec,
PAKEntryReadStream& rs,
2016-03-04 23:04:53 +00:00
const hecl::ProjectPath& outPath,
PAKRouter<PAKBridge>& pakRouter,
2015-08-11 23:32:02 +00:00
const PAK::Entry& entry,
bool force,
2016-04-01 04:25:00 +00:00
hecl::BlenderToken& btok,
2016-03-04 23:04:53 +00:00
std::function<void(const hecl::SystemChar*)> fileChanged)
2015-07-28 02:24:36 +00:00
{
/* Check for RigPair */
const PAKRouter<PAKBridge>::RigPair* rp = pakRouter.lookupCMDLRigPair(entry.id);
CINF cinf;
CSKR cskr;
std::pair<CSKR*,CINF*> loadRp(nullptr, nullptr);
if (rp)
{
pakRouter.lookupAndReadDNA(rp->first, cskr);
pakRouter.lookupAndReadDNA(rp->second, cinf);
loadRp.first = &cskr;
loadRp.second = &cinf;
}
/* Do extract */
2016-04-01 04:25:00 +00:00
hecl::BlenderConnection& conn = btok.getBlenderConnection();
2016-03-04 23:04:53 +00:00
if (!conn.createBlend(outPath, hecl::BlenderConnection::BlendType::Mesh))
2015-07-28 02:24:36 +00:00
return false;
DNACMDL::ReadCMDLToBlender<PAKRouter<PAKBridge>, MaterialSet, std::pair<CSKR*,CINF*>, DNACMDL::SurfaceHeader_1, 2>
(conn, rs, pakRouter, entry, dataSpec, loadRp);
2015-10-21 01:34:35 +00:00
conn.saveBlend();
2015-11-14 23:42:58 +00:00
#if 0
2015-10-21 01:34:35 +00:00
/* Cook and re-extract test */
2016-03-04 23:04:53 +00:00
hecl::ProjectPath tempOut = outPath.getWithExtension(_S(".recook"), true);
hecl::BlenderConnection::DataStream ds = conn.beginData();
DNACMDL::Mesh mesh = ds.compileMesh(hecl::TopologyTriStrips, -1);
2015-10-21 01:34:35 +00:00
ds.close();
DNACMDL::WriteCMDL<MaterialSet, DNACMDL::SurfaceHeader_1_2, 2>(tempOut, outPath, mesh);
2016-03-04 23:04:53 +00:00
athena::io::FileReader reader(tempOut.getAbsolutePath());
hecl::ProjectPath tempBlend = outPath.getWithExtension(_S(".recook.blend"), true);
if (!conn.createBlend(tempBlend, hecl::BlenderConnection::TypeMesh))
2015-10-21 01:34:35 +00:00
return false;
DNACMDL::ReadCMDLToBlender<PAKRouter<PAKBridge>, MaterialSet, std::pair<CSKR*,CINF*>, DNACMDL::SurfaceHeader_1_2, 2>
(conn, reader, pakRouter, entry, dataSpec, loadRp);
2015-08-05 21:46:07 +00:00
return conn.saveBlend();
#elif 0
2015-11-14 23:42:58 +00:00
/* HMDL cook test */
2016-03-04 23:04:53 +00:00
hecl::ProjectPath tempOut = outPath.getWithExtension(_S(".recook"), true);
hecl::BlenderConnection::DataStream ds = conn.beginData();
DNACMDL::Mesh mesh = ds.compileMesh(hecl::HMDLTopology::TriStrips, 16);
2015-11-14 23:42:58 +00:00
ds.close();
DNACMDL::WriteHMDLCMDL<HMDLMaterialSet, DNACMDL::SurfaceHeader_1, 2>(tempOut, outPath, mesh);
2015-11-14 23:42:58 +00:00
#endif
return true;
2015-07-28 02:24:36 +00:00
}
2015-10-07 01:17:17 +00:00
static void Name(const SpecBase& dataSpec,
PAKEntryReadStream& rs,
PAKRouter<PAKBridge>& pakRouter,
PAK::Entry& entry)
{
DNACMDL::NameCMDL<PAKRouter<PAKBridge>, MaterialSet>(rs, pakRouter, entry, dataSpec);
}
2016-03-04 23:04:53 +00:00
static bool Cook(const hecl::ProjectPath& outPath,
const hecl::ProjectPath& inPath,
2015-10-14 23:07:29 +00:00
const DNACMDL::Mesh& mesh)
2015-10-07 01:17:17 +00:00
{
if (mesh.skins.size())
{
DNACMDL::Mesh skinMesh = mesh.getContiguousSkinningVersion();
2016-03-31 18:56:43 +00:00
if (!DNACMDL::WriteCMDL<MaterialSet, DNACMDL::SurfaceHeader_1, 2>(outPath, inPath, skinMesh))
return false;
/* Output skinning intermediate */
auto vertCountIt = skinMesh.contiguousSkinVertCounts.cbegin();
2016-04-10 04:49:02 +00:00
athena::io::FileWriter writer(outPath.getWithExtension(_S(".skinint")).getAbsolutePath());
writer.writeUint32Big(skinMesh.skins.size());
for (const std::vector<DNACMDL::Mesh::SkinBind> skin : skinMesh.skins)
{
writer.writeUint32Big(skin.size());
for (const DNACMDL::Mesh::SkinBind& bind : skin)
{
writer.writeUint32Big(bind.boneIdx);
writer.writeFloatBig(bind.weight);
}
writer.writeUint32Big(*vertCountIt++);
}
2015-10-23 00:45:26 +00:00
writer.writeUint32Big(skinMesh.pos.size());
writer.writeUint32Big(skinMesh.boneNames.size());
for (const std::string& boneName : skinMesh.boneNames)
writer.writeString(boneName);
}
2016-03-31 18:56:43 +00:00
else if (!DNACMDL::WriteCMDL<MaterialSet, DNACMDL::SurfaceHeader_1, 2>(outPath, inPath, mesh))
return false;
return true;
2015-10-07 01:17:17 +00:00
}
2015-11-14 02:28:45 +00:00
2016-03-04 23:04:53 +00:00
static bool HMDLCook(const hecl::ProjectPath& outPath,
const hecl::ProjectPath& inPath,
2015-11-14 02:28:45 +00:00
const DNACMDL::Mesh& mesh)
{
hecl::PoolSkinIndex poolSkinIndex;
2015-11-14 02:28:45 +00:00
if (mesh.skins.size())
{
if (!DNACMDL::WriteHMDLCMDL<HMDLMaterialSet, DNACMDL::SurfaceHeader_2, 2>(
outPath, inPath, mesh, poolSkinIndex))
2015-11-14 02:28:45 +00:00
return false;
/* Output skinning intermediate */
2016-04-10 04:49:02 +00:00
athena::io::FileWriter writer(outPath.getWithExtension(_S(".skinint")).getAbsolutePath());
2015-11-14 02:28:45 +00:00
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);
/* 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]);
2015-11-14 02:28:45 +00:00
}
else if (!DNACMDL::WriteHMDLCMDL<HMDLMaterialSet, DNACMDL::SurfaceHeader_2, 2>(
outPath, inPath, mesh, poolSkinIndex))
2015-11-14 02:28:45 +00:00
return false;
return true;
}
2015-07-25 03:43:49 +00:00
};
}
}
#endif // _DNAMP1_CMDL_HPP_