mirror of
https://github.com/zeldaret/mm.git
synced 2026-06-28 10:20:44 -04:00
b292647ea2
* update extract_assets script * git subrepo pull --force tools/ZAPD subrepo: subdir: "tools/ZAPD" merged: "820678b4" upstream: origin: "https://github.com/zeldaret/ZAPD.git" branch: "master" commit: "820678b4" git-subrepo: version: "0.4.3" origin: "???" commit: "???" * fixes and rgba16 format change * git subrepo pull --force tools/ZAPD subrepo: subdir: "tools/ZAPD" merged: "6be9af65d" upstream: origin: "https://github.com/zeldaret/ZAPD.git" branch: "master" commit: "6be9af65d" git-subrepo: version: "0.4.3" origin: "???" commit: "???" * Update warning counts
1186 lines
29 KiB
C++
1186 lines
29 KiB
C++
#include "HLModelIntermediette.h"
|
|
#include "../File.h"
|
|
#include "../Globals.h"
|
|
#include "../Path.h"
|
|
#include "../StringHelper.h"
|
|
#include "../ZDisplayList.h"
|
|
|
|
#ifdef USE_ASSIMP
|
|
#include <assimp/Exporter.hpp>
|
|
#include <assimp/Importer.hpp>
|
|
#include <assimp/postprocess.h>
|
|
#include <assimp/scene.h>
|
|
#endif
|
|
|
|
using namespace tinyxml2;
|
|
|
|
HLModelIntermediette::HLModelIntermediette()
|
|
{
|
|
blocks = std::vector<HLIntermediette*>();
|
|
startIndex = 0;
|
|
meshStartIndex = 0;
|
|
hasSkeleton = false;
|
|
lastTrans = Vec3s(0, 0, 0);
|
|
}
|
|
|
|
HLModelIntermediette::~HLModelIntermediette()
|
|
{
|
|
}
|
|
|
|
HLModelIntermediette* HLModelIntermediette::FromXML(tinyxml2::XMLElement* root)
|
|
{
|
|
HLModelIntermediette* model = new HLModelIntermediette();
|
|
|
|
for (XMLElement* child = root->FirstChildElement(); child != NULL;
|
|
child = child->NextSiblingElement())
|
|
{
|
|
std::string childName = child->Name();
|
|
HLIntermediette* block = nullptr;
|
|
|
|
if (childName == "Mesh")
|
|
block = new HLMeshIntermediette();
|
|
else if (childName == "Limb")
|
|
block = new HLLimbIntermediette();
|
|
else if (childName == "Vertices")
|
|
block = new HLVerticesIntermediette();
|
|
else if (childName == "Texture")
|
|
block = new HLTextureIntermediette();
|
|
else if (childName == "Material")
|
|
block = new HLMaterialIntermediette();
|
|
|
|
if (block != nullptr)
|
|
{
|
|
block->parent = model;
|
|
block->InitFromXML(child);
|
|
model->blocks.push_back(block);
|
|
}
|
|
}
|
|
|
|
return model;
|
|
}
|
|
|
|
void HLModelIntermediette::FromZDisplayList(HLModelIntermediette* model, ZDisplayList* zDisplayList)
|
|
{
|
|
HLLimbIntermediette* limb = new HLLimbIntermediette();
|
|
limb->name = zDisplayList->GetName();
|
|
|
|
// Go through verts
|
|
std::vector<ZVtx> finalVerts;
|
|
|
|
int32_t vStart = -1;
|
|
|
|
for (auto& pair : zDisplayList->vertices)
|
|
{
|
|
if (vStart == -1) // TODO: Find a better way to do this
|
|
vStart = pair.first;
|
|
|
|
for (auto& v : pair.second)
|
|
finalVerts.push_back(v);
|
|
}
|
|
|
|
HLVerticesIntermediette* vertIntr = new HLVerticesIntermediette();
|
|
vertIntr->vertices = finalVerts;
|
|
vertIntr->name = StringHelper::Sprintf("%s_verts", zDisplayList->GetName().c_str());
|
|
model->blocks.push_back(vertIntr);
|
|
|
|
// Go through textures
|
|
// TODO: Textures are now stored directly in ZFile
|
|
/*
|
|
for (pair<uint32_t, ZTexture*> pair : zDisplayList->textures)
|
|
{
|
|
HLTextureIntermediette* texIntr = new HLTextureIntermediette();
|
|
texIntr->tex = pair.second;
|
|
texIntr->name = texIntr->tex->GetName();
|
|
|
|
model->blocks.push_back(texIntr);
|
|
}
|
|
*/
|
|
|
|
// Analyze display lists to determine components
|
|
HLDisplayListIntermediette* dList = new HLDisplayListIntermediette();
|
|
dList->address = zDisplayList->GetRawDataIndex();
|
|
int32_t startIndex = 0;
|
|
|
|
// Go through the display lists and setup commands
|
|
int32_t meshCnt = 0;
|
|
|
|
HLMeshIntermediette* mesh = new HLMeshIntermediette();
|
|
mesh->name = StringHelper::Sprintf("%s_%i", zDisplayList->GetName().c_str(), meshCnt);
|
|
|
|
int32_t matCnt = 0;
|
|
HLMaterialIntermediette* lastMat = new HLMaterialIntermediette();
|
|
lastMat->name = StringHelper::Sprintf("Material_%i", matCnt);
|
|
|
|
uint8_t lastClrR = 0, lastClrG = 0, lastClrB = 0, lastClrA = 0, lastClrM = 0, lastClrL = 0;
|
|
|
|
startIndex = 0;
|
|
|
|
for (size_t i = startIndex; i < zDisplayList->instructions.size(); i++)
|
|
{
|
|
uint64_t data = zDisplayList->instructions[i];
|
|
F3DZEXOpcode opcode = (F3DZEXOpcode)(data >> 56);
|
|
|
|
if (opcode == F3DZEXOpcode::G_SETOTHERMODE_L)
|
|
{
|
|
}
|
|
else if (opcode == F3DZEXOpcode::G_SETPRIMCOLOR)
|
|
{
|
|
int32_t mm = (data & 0x0000FF0000000000) >> 40;
|
|
int32_t ff = (data & 0x000000FF00000000) >> 32;
|
|
int32_t rr = (data & 0x00000000FF000000) >> 24;
|
|
int32_t gg = (data & 0x0000000000FF0000) >> 16;
|
|
int32_t bb = (data & 0x000000000000FF00) >> 8;
|
|
int32_t aa = (data & 0x00000000000000FF) >> 0;
|
|
|
|
lastClrR = rr;
|
|
lastClrG = gg;
|
|
lastClrB = bb;
|
|
lastClrA = aa;
|
|
lastClrL = ff;
|
|
lastClrM = mm;
|
|
|
|
lastMat->clrR = rr;
|
|
lastMat->clrG = gg;
|
|
lastMat->clrB = bb;
|
|
lastMat->clrA = aa;
|
|
lastMat->clrL = ff;
|
|
lastMat->clrM = mm;
|
|
}
|
|
else if (opcode == F3DZEXOpcode::G_SETTILE &&
|
|
(F3DZEXOpcode)(zDisplayList->instructions[i - 1] >> 56) !=
|
|
F3DZEXOpcode::G_RDPPIPESYNC)
|
|
{
|
|
int32_t cc =
|
|
(data & 0b0000000000000000000000000000000000000000000011000000000000000000) >> 18;
|
|
int32_t dd =
|
|
(data & 0b0000000000000000000000000000000000000000000000000000001100000000) >> 8;
|
|
|
|
lastMat->cmtH = (HLMaterialCmt)cc;
|
|
lastMat->cmtV = (HLMaterialCmt)dd;
|
|
|
|
matCnt++;
|
|
|
|
if (matCnt > 1 && mesh->commands.size() > 0)
|
|
{
|
|
model->blocks.push_back(lastMat);
|
|
limb->commands.push_back(new HLLimbCommand(mesh->name, lastMat->name));
|
|
lastMat = new HLMaterialIntermediette();
|
|
lastMat->name = StringHelper::Sprintf("Material_%i", matCnt);
|
|
|
|
lastMat->clrR = lastClrR;
|
|
lastMat->clrG = lastClrG;
|
|
lastMat->clrB = lastClrB;
|
|
lastMat->clrA = lastClrA;
|
|
lastMat->clrL = lastClrL;
|
|
lastMat->clrM = lastClrM;
|
|
|
|
// Bit of a hack here...
|
|
// int32_t lastData = (int32_t)(zDisplayList->instructions[i - 1]);
|
|
// TODO
|
|
// string texName = zDisplayList->textures[lastData & 0x00FFFFFF]->GetName();
|
|
// lastMat->textureName = texName;
|
|
|
|
// --------------------------
|
|
model->blocks.push_back(mesh);
|
|
|
|
meshCnt++;
|
|
|
|
mesh = new HLMeshIntermediette();
|
|
mesh->name =
|
|
StringHelper::Sprintf("%s_%i", zDisplayList->GetName().c_str(), meshCnt);
|
|
}
|
|
}
|
|
else if (opcode == F3DZEXOpcode::G_SETTIMG)
|
|
{
|
|
// int32_t texAddress = data & 0x00FFFFFF;
|
|
|
|
// TODO
|
|
// string texName = zDisplayList->textures[texAddress]->GetName();
|
|
// lastMat->textureName = texName;
|
|
}
|
|
else if (opcode == F3DZEXOpcode::G_VTX)
|
|
{
|
|
int32_t nn = (data & 0x000FF00000000000ULL) >> 44;
|
|
int32_t aa = (data & 0x000000FF00000000ULL) >> 32;
|
|
int32_t startIndex = ((aa >> 1) - nn);
|
|
uint32_t vtxAddr = data & 0x00FFFFFF;
|
|
uint32_t diff = vtxAddr - vStart;
|
|
|
|
startIndex += diff / 16;
|
|
|
|
mesh->commands.push_back(new HLMeshCmdLoadVertices(nn, startIndex));
|
|
}
|
|
else if (opcode == F3DZEXOpcode::G_TRI1)
|
|
{
|
|
int32_t aa = ((data & 0x00FF000000000000ULL) >> 48) / 2;
|
|
int32_t bb = ((data & 0x0000FF0000000000ULL) >> 40) / 2;
|
|
int32_t cc = ((data & 0x000000FF00000000ULL) >> 32) / 2;
|
|
|
|
mesh->commands.push_back(new HLMeshCmdTriangle1(aa, bb, cc, 0));
|
|
}
|
|
else if (opcode == F3DZEXOpcode::G_TRI2)
|
|
{
|
|
int32_t aa = ((data & 0x00FF000000000000ULL) >> 48) / 2;
|
|
int32_t bb = ((data & 0x0000FF0000000000ULL) >> 40) / 2;
|
|
int32_t cc = ((data & 0x000000FF00000000ULL) >> 32) / 2;
|
|
int32_t dd = ((data & 0x00000000FF0000ULL) >> 16) / 2;
|
|
int32_t ee = ((data & 0x0000000000FF00ULL) >> 8) / 2;
|
|
int32_t ff = ((data & 0x000000000000FFULL) >> 0) / 2;
|
|
|
|
mesh->commands.push_back(new HLMeshCmdTriangle2(aa, bb, cc, 0, dd, ee, ff, 0));
|
|
}
|
|
|
|
// int32_t bp = 0;
|
|
}
|
|
|
|
limb->commands.push_back(new HLLimbCommand(mesh->name, lastMat->name));
|
|
model->blocks.push_back(lastMat);
|
|
model->blocks.push_back(mesh);
|
|
model->blocks.push_back(limb);
|
|
}
|
|
|
|
void HLModelIntermediette::FromZSkeleton(HLModelIntermediette* model, ZSkeleton* zSkeleton)
|
|
{
|
|
model->hasSkeleton = true;
|
|
|
|
// Start at the root skeleton node, go down...
|
|
// ProcessZSkeletonLimb(model, zSkeleton, zSkeleton->limbs[0]);
|
|
}
|
|
|
|
void HLModelIntermediette::ProcessZSkeletonLimb(HLModelIntermediette* model, ZSkeleton* zSkeleton,
|
|
ZLimb* limb)
|
|
{
|
|
/*
|
|
if (limb->dList == nullptr && limb->dListPtr != 0)
|
|
limb->dList = (ZDisplayList*)zSkeleton->parent->FindResource(limb->dListPtr);
|
|
|
|
if (limb->dList != nullptr)
|
|
{
|
|
auto cmdTrans = new HLSetTranslation(limb->transX, limb->transY, limb->transZ);
|
|
cmdTrans->parent = model;
|
|
model->blocks.push_back(cmdTrans);
|
|
|
|
FromZDisplayList(model, limb->dList);
|
|
}
|
|
*/
|
|
|
|
/*for (ZLimb* childLimb : limb->children)
|
|
{
|
|
ProcessZSkeletonLimb(model, zSkeleton, childLimb);
|
|
}*/
|
|
}
|
|
|
|
std::string HLModelIntermediette::ToOBJFile()
|
|
{
|
|
std::string output = "";
|
|
|
|
for (HLIntermediette* block : blocks)
|
|
{
|
|
block->parent = this;
|
|
std::string code = block->OutputOBJ();
|
|
|
|
output += code;
|
|
|
|
if (code != "")
|
|
output += "\n";
|
|
}
|
|
|
|
return output;
|
|
}
|
|
|
|
std::string HLModelIntermediette::ToAssimpFile()
|
|
{
|
|
#ifdef USE_ASSIMP
|
|
Assimp::Exporter exporter;
|
|
aiScene* newScene = new aiScene();
|
|
newScene->mMeshes = new aiMesh*[128];
|
|
newScene->mRootNode = new aiNode();
|
|
newScene->mRootNode->mName = "RootNode";
|
|
|
|
std::vector<aiVector3D> vertices;
|
|
|
|
int32_t idx = 0;
|
|
|
|
for (HLIntermediette* block : blocks)
|
|
{
|
|
block->parent = this;
|
|
block->OutputAssimp(newScene, &vertices);
|
|
|
|
idx++;
|
|
}
|
|
|
|
newScene->mRootNode->mNumChildren += newScene->mNumMeshes;
|
|
newScene->mRootNode->mChildren = new aiNode*[newScene->mRootNode->mNumChildren];
|
|
|
|
for (size_t i = 0; i < newScene->mNumMeshes; i++)
|
|
{
|
|
aiNode* child = new aiNode();
|
|
child->mName = StringHelper::Sprintf("OBJ_%i", i);
|
|
child->mNumMeshes = 1;
|
|
child->mMeshes = new uint32_t[1];
|
|
child->mMeshes[0] = i;
|
|
child->mTransformation.Translation(aiVector3D(meshTranslations[i].x * 10,
|
|
meshTranslations[i].y * 10,
|
|
meshTranslations[i].z * 10),
|
|
child->mTransformation);
|
|
newScene->mRootNode->mChildren[i] = child;
|
|
}
|
|
|
|
newScene->mNumMaterials = 1;
|
|
newScene->mMaterials = new aiMaterial*[1];
|
|
newScene->mMaterials[0] = new aiMaterial();
|
|
|
|
exporter.Export(newScene, "fbx", "__export.fbx");
|
|
#endif
|
|
|
|
return "";
|
|
}
|
|
|
|
std::string HLModelIntermediette::OutputCode()
|
|
{
|
|
std::string output = "";
|
|
|
|
for (HLIntermediette* block : blocks)
|
|
{
|
|
std::string code = block->OutputCode();
|
|
|
|
output += code;
|
|
|
|
if (code != "")
|
|
output += "\n";
|
|
}
|
|
|
|
return output;
|
|
}
|
|
|
|
std::string HLModelIntermediette::OutputXML()
|
|
{
|
|
std::string output = "";
|
|
XMLDocument doc;
|
|
|
|
XMLElement* root = doc.NewElement("HLModelIntermediette");
|
|
|
|
for (HLIntermediette* block : blocks)
|
|
block->OutputXML(&doc, root);
|
|
|
|
doc.InsertEndChild(root);
|
|
|
|
XMLPrinter printer;
|
|
|
|
doc.Accept(&printer);
|
|
return printer.CStr();
|
|
}
|
|
|
|
template <typename T>
|
|
inline T* HLModelIntermediette::FindByName(std::string name)
|
|
{
|
|
for (HLIntermediette* block : blocks)
|
|
{
|
|
if (typeid(*block) == typeid(T))
|
|
{
|
|
if (block->name == name)
|
|
return (T*)block;
|
|
}
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
template <typename T>
|
|
inline T* HLModelIntermediette::FindByType()
|
|
{
|
|
for (HLIntermediette* block : blocks)
|
|
{
|
|
if (typeid(*block) == typeid(T))
|
|
return (T*)block;
|
|
}
|
|
|
|
return nullptr;
|
|
}
|
|
|
|
HLIntermediette::HLIntermediette()
|
|
{
|
|
name = "";
|
|
parent = nullptr;
|
|
}
|
|
|
|
HLIntermediette::~HLIntermediette()
|
|
{
|
|
}
|
|
|
|
void HLIntermediette::InitFromXML(XMLElement* xmlElement)
|
|
{
|
|
name = xmlElement->Attribute("Name");
|
|
}
|
|
|
|
std::string HLIntermediette::OutputCode()
|
|
{
|
|
return "";
|
|
}
|
|
|
|
std::string HLIntermediette::OutputOBJ()
|
|
{
|
|
return "";
|
|
}
|
|
|
|
void HLIntermediette::OutputAssimp(aiScene* scene, std::vector<aiVector3D>* verts)
|
|
{
|
|
}
|
|
|
|
void HLIntermediette::OutputXML(tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* root)
|
|
{
|
|
}
|
|
|
|
void HLMeshCommand::InitFromXML(XMLElement* xmlElement)
|
|
{
|
|
}
|
|
|
|
std::string HLMeshCommand::OutputCode(HLModelIntermediette* parent)
|
|
{
|
|
return "";
|
|
}
|
|
|
|
std::string HLMeshCommand::OutputOBJ(HLModelIntermediette* parent)
|
|
{
|
|
return "";
|
|
}
|
|
|
|
void HLMeshCommand::OutputAssimp(HLModelIntermediette* parent, aiScene* scene, aiMesh* mesh)
|
|
{
|
|
}
|
|
|
|
void HLMeshCommand::OutputXML(tinyxml2::XMLElement* parent)
|
|
{
|
|
}
|
|
|
|
HLVerticesIntermediette::HLVerticesIntermediette() : HLIntermediette()
|
|
{
|
|
vertices = std::vector<ZVtx>();
|
|
}
|
|
|
|
void HLVerticesIntermediette::InitFromXML(XMLElement* verticesElement)
|
|
{
|
|
name = verticesElement->Attribute("Name");
|
|
|
|
/*
|
|
for (XMLElement* child = verticesElement->FirstChildElement(); child != NULL;
|
|
child = child->NextSiblingElement())
|
|
vertices.push_back(ZVtx(child->IntAttribute("X"), child->IntAttribute("Y"),
|
|
child->IntAttribute("Z"), child->IntAttribute("Flags"),
|
|
child->IntAttribute("S"), child->IntAttribute("T"),
|
|
child->IntAttribute("R"), child->IntAttribute("G"),
|
|
child->IntAttribute("B"), child->IntAttribute("A")));
|
|
*/
|
|
}
|
|
|
|
void HLVerticesIntermediette::InitFromVertices(std::vector<ZVtx> dispListVertices)
|
|
{
|
|
for (auto v : dispListVertices)
|
|
vertices.push_back(v);
|
|
}
|
|
|
|
std::string HLVerticesIntermediette::OutputCode(HLModelIntermediette* parent)
|
|
{
|
|
std::string output = "";
|
|
|
|
output += StringHelper::Sprintf("Vtx %s_verts[] = \n{\n", name.c_str());
|
|
|
|
for (auto v : vertices)
|
|
{
|
|
output += StringHelper::Sprintf(" { %i, %i, %i, %i, %i, %i, %i, %i, %i, %i },\n", v.x,
|
|
v.y, v.z, v.flag, v.s, v.t, v.r, v.g, v.b, v.a);
|
|
}
|
|
|
|
output += StringHelper::Sprintf("};\n");
|
|
|
|
return output;
|
|
}
|
|
|
|
std::string HLVerticesIntermediette::OutputOBJ()
|
|
{
|
|
std::string output = "";
|
|
|
|
for (auto& v : vertices)
|
|
{
|
|
output += StringHelper::Sprintf("v %f %f %f %i %i %i %i\n", (float)v.x * 0.1f,
|
|
(float)v.y * 0.1f, (float)v.z * 0.1f, v.r, v.g, v.b, v.a);
|
|
}
|
|
|
|
return output;
|
|
}
|
|
|
|
void HLVerticesIntermediette::OutputAssimp(aiScene* scene, std::vector<aiVector3D>* verts)
|
|
{
|
|
verts->clear();
|
|
|
|
for (size_t i = 0; i < vertices.size(); i++)
|
|
{
|
|
verts->push_back(aiVector3D(vertices[i].x, vertices[i].y, vertices[i].z));
|
|
}
|
|
}
|
|
|
|
void HLVerticesIntermediette::OutputXML(tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* root)
|
|
{
|
|
XMLElement* element = doc->NewElement("Vertices");
|
|
|
|
element->SetAttribute("Name", name.c_str());
|
|
|
|
for (auto& v : vertices)
|
|
{
|
|
XMLElement* vElem = doc->NewElement("Vertex");
|
|
vElem->SetAttribute("X", v.x);
|
|
vElem->SetAttribute("Y", v.y);
|
|
vElem->SetAttribute("Z", v.z);
|
|
vElem->SetAttribute("Flag", v.flag);
|
|
vElem->SetAttribute("S", v.s);
|
|
vElem->SetAttribute("T", v.t);
|
|
vElem->SetAttribute("R", v.r);
|
|
vElem->SetAttribute("G", v.g);
|
|
vElem->SetAttribute("B", v.b);
|
|
vElem->SetAttribute("A", v.a);
|
|
|
|
element->InsertEndChild(vElem);
|
|
}
|
|
|
|
root->InsertEndChild(element);
|
|
}
|
|
|
|
HLMeshCmdGeoSettings::HLMeshCmdGeoSettings()
|
|
{
|
|
on = "";
|
|
off = "";
|
|
}
|
|
|
|
void HLMeshCmdGeoSettings::InitFromXML(tinyxml2::XMLElement* xmlElement)
|
|
{
|
|
on = xmlElement->Attribute("On");
|
|
off = xmlElement->Attribute("Off");
|
|
}
|
|
|
|
std::string HLMeshCmdGeoSettings::OutputCode(HLModelIntermediette* parent)
|
|
{
|
|
std::string output = "";
|
|
|
|
if (off != "")
|
|
output +=
|
|
StringHelper::Sprintf("gsSPClearGeometryMode(G_TEXTURE_ENABLE | %s),\n", off.c_str());
|
|
|
|
if (on != "")
|
|
output += StringHelper::Sprintf("gsSPSetGeometryMode(G_TEXTURE_ENABLE | %s),", on.c_str());
|
|
|
|
return output;
|
|
}
|
|
|
|
HLMeshCmdTriangle1::HLMeshCmdTriangle1()
|
|
{
|
|
v0 = 0;
|
|
v1 = 0;
|
|
v2 = 0;
|
|
flag = 0;
|
|
}
|
|
|
|
HLMeshCmdTriangle1::HLMeshCmdTriangle1(int32_t nV0, int32_t nV1, int32_t nV2, int32_t nFlag)
|
|
{
|
|
v0 = nV0;
|
|
v1 = nV1;
|
|
v2 = nV2;
|
|
flag = nFlag;
|
|
}
|
|
|
|
void HLMeshCmdTriangle1::InitFromXML(tinyxml2::XMLElement* xmlElement)
|
|
{
|
|
v0 = xmlElement->IntAttribute("v0");
|
|
v1 = xmlElement->IntAttribute("v1");
|
|
v2 = xmlElement->IntAttribute("v2");
|
|
flag = xmlElement->IntAttribute("flag");
|
|
}
|
|
|
|
std::string HLMeshCmdTriangle1::OutputCode(HLModelIntermediette* parent)
|
|
{
|
|
return StringHelper::Sprintf("gsSP1Triangle(%i, %i, %i, %i),", v0, v1, v2, flag);
|
|
}
|
|
|
|
void HLMeshCmdTriangle1::OutputAssimp(HLModelIntermediette* parent, aiScene* scene, aiMesh* mesh)
|
|
{
|
|
aiFace* face = new aiFace();
|
|
face->mNumIndices = 3;
|
|
face->mIndices = new uint32_t[3];
|
|
face->mIndices[0] = parent->startIndex + v0;
|
|
face->mIndices[1] = parent->startIndex + v1;
|
|
face->mIndices[2] = parent->startIndex + v2;
|
|
|
|
mesh->mFaces[mesh->mNumFaces++] = face[0];
|
|
}
|
|
|
|
void HLMeshCmdTriangle1::OutputXML(tinyxml2::XMLElement* parent)
|
|
{
|
|
XMLElement* elem = parent->GetDocument()->NewElement("Triangle1");
|
|
|
|
elem->SetAttribute("V0", v0);
|
|
elem->SetAttribute("V1", v1);
|
|
elem->SetAttribute("V2", v2);
|
|
elem->SetAttribute("Flag", flag);
|
|
|
|
parent->InsertEndChild(elem);
|
|
}
|
|
|
|
HLMeshCmdTriangle2::HLMeshCmdTriangle2()
|
|
{
|
|
v0 = 0;
|
|
v1 = 0;
|
|
v2 = 0;
|
|
flag0 = 0;
|
|
v10 = 0;
|
|
v11 = 0;
|
|
v12 = 0;
|
|
flag1 = 0;
|
|
}
|
|
|
|
HLMeshCmdTriangle2::HLMeshCmdTriangle2(int32_t nV0, int32_t nV1, int32_t nV2, int32_t nFlag0,
|
|
int32_t nV10, int32_t nV11, int32_t nV12, int32_t nFlag1)
|
|
{
|
|
v0 = nV0;
|
|
v1 = nV1;
|
|
v2 = nV2;
|
|
flag0 = nFlag0;
|
|
v10 = nV10;
|
|
v11 = nV11;
|
|
v12 = nV12;
|
|
flag1 = nFlag1;
|
|
}
|
|
|
|
void HLMeshCmdTriangle2::InitFromXML(tinyxml2::XMLElement* xmlElement)
|
|
{
|
|
v0 = xmlElement->IntAttribute("V0");
|
|
v1 = xmlElement->IntAttribute("V1");
|
|
v2 = xmlElement->IntAttribute("V2");
|
|
flag0 = xmlElement->IntAttribute("Flag0");
|
|
v10 = xmlElement->IntAttribute("V10");
|
|
v11 = xmlElement->IntAttribute("V11");
|
|
v12 = xmlElement->IntAttribute("V12");
|
|
flag1 = xmlElement->IntAttribute("Flag1");
|
|
}
|
|
|
|
std::string HLMeshCmdTriangle2::OutputCode(HLModelIntermediette* parent)
|
|
{
|
|
return StringHelper::Sprintf("gsSP2Triangles(%i, %i, %i, %i, %i, %i, %i, %i),", v0, v1, v2,
|
|
flag0, v10, v11, v12, flag1);
|
|
}
|
|
|
|
std::string HLMeshCmdTriangle2::OutputOBJ(HLModelIntermediette* parent)
|
|
{
|
|
std::string output = "";
|
|
|
|
int32_t startIndex = parent->startIndex;
|
|
|
|
output += StringHelper::Sprintf("f %i %i %i\n", startIndex + v0 + 1, startIndex + v1 + 1,
|
|
startIndex + v2 + 1);
|
|
output += StringHelper::Sprintf("f %i %i %i\n", startIndex + v10 + 1, startIndex + v11 + 1,
|
|
startIndex + v12 + 1);
|
|
|
|
return output;
|
|
}
|
|
|
|
void HLMeshCmdTriangle2::OutputAssimp(HLModelIntermediette* parent, aiScene* scene, aiMesh* mesh)
|
|
{
|
|
{
|
|
aiFace* face = new aiFace();
|
|
face->mNumIndices = 3;
|
|
face->mIndices = new uint32_t[3];
|
|
face->mIndices[0] = parent->startIndex + v0;
|
|
face->mIndices[1] = parent->startIndex + v1;
|
|
face->mIndices[2] = parent->startIndex + v2;
|
|
|
|
mesh->mFaces[mesh->mNumFaces++] = face[0];
|
|
}
|
|
|
|
{
|
|
aiFace* face = new aiFace();
|
|
face->mNumIndices = 3;
|
|
face->mIndices = new uint32_t[3];
|
|
face->mIndices[0] = parent->startIndex + v10;
|
|
face->mIndices[1] = parent->startIndex + v11;
|
|
face->mIndices[2] = parent->startIndex + v12;
|
|
|
|
mesh->mFaces[mesh->mNumFaces++] = face[0];
|
|
}
|
|
}
|
|
|
|
void HLMeshCmdTriangle2::OutputXML(tinyxml2::XMLElement* parent)
|
|
{
|
|
XMLElement* elem = parent->GetDocument()->NewElement("Triangle2");
|
|
|
|
elem->SetAttribute("V0", v0);
|
|
elem->SetAttribute("V1", v1);
|
|
elem->SetAttribute("V2", v2);
|
|
elem->SetAttribute("Flag0", flag0);
|
|
elem->SetAttribute("V10", v10);
|
|
elem->SetAttribute("V11", v11);
|
|
elem->SetAttribute("V12", v12);
|
|
elem->SetAttribute("Flag1", flag1);
|
|
|
|
parent->InsertEndChild(elem);
|
|
}
|
|
|
|
HLMeshCmdLoadVertices::HLMeshCmdLoadVertices() : HLMeshCommand()
|
|
{
|
|
numVerts = 0;
|
|
startIndex = 0;
|
|
}
|
|
|
|
HLMeshCmdLoadVertices::HLMeshCmdLoadVertices(uint8_t nNumVerts, uint8_t nStartIndex)
|
|
{
|
|
numVerts = nNumVerts;
|
|
startIndex = nStartIndex;
|
|
}
|
|
|
|
void HLMeshCmdLoadVertices::OutputXML(tinyxml2::XMLElement* parent)
|
|
{
|
|
XMLElement* elem = parent->GetDocument()->NewElement("LoadVertices");
|
|
|
|
elem->SetAttribute("StartIndex", startIndex);
|
|
elem->SetAttribute("NumVerts", numVerts);
|
|
|
|
parent->InsertEndChild(elem);
|
|
}
|
|
|
|
void HLMeshCmdLoadVertices::InitFromXML(tinyxml2::XMLElement* xmlElement)
|
|
{
|
|
numVerts = xmlElement->IntAttribute("NumVerts", 0);
|
|
startIndex = xmlElement->IntAttribute("StartIndex", 0);
|
|
}
|
|
|
|
std::string HLMeshCmdLoadVertices::OutputOBJ(HLModelIntermediette* parent)
|
|
{
|
|
parent->startIndex = startIndex;
|
|
return "";
|
|
}
|
|
|
|
void HLMeshCmdLoadVertices::OutputAssimp(HLModelIntermediette* parent, aiScene* scene, aiMesh* mesh)
|
|
{
|
|
parent->startIndex = startIndex;
|
|
}
|
|
|
|
std::string HLMeshCmdLoadVertices::OutputCode(HLModelIntermediette* parent)
|
|
{
|
|
HLVerticesIntermediette* verts = parent->FindByType<HLVerticesIntermediette>();
|
|
return StringHelper::Sprintf("gsSPVertex(&%s[%i], %i, %i),", verts->name.c_str(), startIndex,
|
|
numVerts, 0);
|
|
}
|
|
|
|
HLMaterialIntermediette::HLMaterialIntermediette()
|
|
{
|
|
textureName = "";
|
|
clrR = 0;
|
|
clrG = 0;
|
|
clrB = 0;
|
|
clrA = 0;
|
|
clrM = 0;
|
|
clrL = 0;
|
|
cmtH = HLMaterialCmt::Wrap;
|
|
cmtV = HLMaterialCmt::Wrap;
|
|
}
|
|
|
|
void HLMaterialIntermediette::InitFromXML(tinyxml2::XMLElement* xmlElement)
|
|
{
|
|
name = xmlElement->Attribute("Name");
|
|
textureName = xmlElement->Attribute("TextureName");
|
|
clrR = xmlElement->IntAttribute("ClrR");
|
|
clrG = xmlElement->IntAttribute("ClrG");
|
|
clrB = xmlElement->IntAttribute("ClrB");
|
|
clrA = xmlElement->IntAttribute("ClrA");
|
|
clrM = xmlElement->IntAttribute("ClrM");
|
|
clrL = xmlElement->IntAttribute("ClrL");
|
|
}
|
|
|
|
std::string HLMaterialIntermediette::OutputCode()
|
|
{
|
|
return "";
|
|
}
|
|
|
|
void HLMaterialIntermediette::OutputXML(tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* parent)
|
|
{
|
|
XMLElement* elem = parent->GetDocument()->NewElement("Material");
|
|
|
|
elem->SetAttribute("Name", name.c_str());
|
|
elem->SetAttribute("TextureName", textureName.c_str());
|
|
elem->SetAttribute("ClrR", clrR);
|
|
elem->SetAttribute("ClrG", clrG);
|
|
elem->SetAttribute("ClrB", clrB);
|
|
elem->SetAttribute("ClrA", clrA);
|
|
elem->SetAttribute("ClrL", clrL);
|
|
elem->SetAttribute("ClrM", clrM);
|
|
elem->SetAttribute("CmtH", (int32_t)cmtH);
|
|
elem->SetAttribute("CmtV", (int32_t)cmtV);
|
|
|
|
parent->InsertEndChild(elem);
|
|
}
|
|
|
|
HLDisplayListIntermediette::HLDisplayListIntermediette()
|
|
{
|
|
commands = std::vector<HLDisplayListCommand*>();
|
|
}
|
|
|
|
std::string HLDisplayListIntermediette::OutputCode()
|
|
{
|
|
return std::string();
|
|
}
|
|
|
|
void HLDisplayListIntermediette::InitFromXML(tinyxml2::XMLElement* xmlElement)
|
|
{
|
|
for (XMLElement* child = xmlElement->FirstChildElement(); child != NULL;
|
|
child = child->NextSiblingElement())
|
|
{
|
|
std::string name = child->Name();
|
|
|
|
HLDisplayListCommand* cmd = nullptr;
|
|
|
|
if (name == "DrawMesh")
|
|
cmd = new HLDisplayListCmdDrawMesh();
|
|
else if (name == "PipeSync")
|
|
cmd = new HLDisplayListCmdPipeSync();
|
|
|
|
if (cmd != nullptr)
|
|
{
|
|
cmd->InitFromXML(child);
|
|
commands.push_back(cmd);
|
|
}
|
|
}
|
|
}
|
|
|
|
void HLDisplayListCommand::InitFromXML(tinyxml2::XMLElement* xmlElement)
|
|
{
|
|
}
|
|
|
|
std::string HLDisplayListCommand::OutputCode()
|
|
{
|
|
return "";
|
|
}
|
|
|
|
void HLDisplayListCmdDrawMesh::InitFromXML(tinyxml2::XMLElement* xmlElement)
|
|
{
|
|
meshName = xmlElement->Attribute("Mesh");
|
|
materialName = xmlElement->Attribute("Material");
|
|
}
|
|
|
|
std::string HLDisplayListCmdDrawMesh::OutputCode()
|
|
{
|
|
return "";
|
|
}
|
|
|
|
HLTextureIntermediette::HLTextureIntermediette()
|
|
{
|
|
tex = nullptr;
|
|
}
|
|
|
|
void HLTextureIntermediette::InitFromXML(tinyxml2::XMLElement* xmlElement)
|
|
{
|
|
name = xmlElement->Attribute("Name");
|
|
|
|
fileName = xmlElement->Attribute("TextureName");
|
|
// std::string format = xmlElement->Attribute("Format");
|
|
std::string format = "rgba16"; // TEST
|
|
|
|
// tex = HLTexture::FromPNG(fileName,
|
|
// (HLTextureType)ZTexture::GetTextureTypeFromString(format));
|
|
tex = new ZTexture(nullptr);
|
|
tex->ZTexture::FromPNG(Path::GetDirectoryName(Globals::Instance->inputPath.string()) + "/" +
|
|
fileName,
|
|
ZTexture::GetTextureTypeFromString(format));
|
|
}
|
|
|
|
std::string HLTextureIntermediette::OutputCode()
|
|
{
|
|
return StringHelper::Sprintf("#include <../%s/%s.inc.c>", Globals::Instance->outputPath.c_str(),
|
|
name.c_str());
|
|
}
|
|
|
|
void HLTextureIntermediette::OutputXML(tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* root)
|
|
{
|
|
XMLElement* element = doc->NewElement("Texture");
|
|
|
|
element->SetAttribute("Name", name.c_str());
|
|
element->SetAttribute("TextureName",
|
|
(name + "." + tex->GetExternalExtension() + ".png").c_str());
|
|
tex->Save(Globals::Instance->outputPath.string());
|
|
|
|
root->InsertEndChild(element);
|
|
}
|
|
|
|
void HLDisplayListCmdPipeSync::InitFromXML(tinyxml2::XMLElement* xmlElement)
|
|
{
|
|
}
|
|
|
|
std::string HLDisplayListCmdPipeSync::OutputCode()
|
|
{
|
|
return "gsDPPipeSync(),";
|
|
}
|
|
|
|
HLMeshCmdCull::HLMeshCmdCull() : HLMeshCommand()
|
|
{
|
|
indexStart = 0;
|
|
indexEnd = 0;
|
|
}
|
|
|
|
void HLMeshCmdCull::InitFromXML(tinyxml2::XMLElement* xmlElement)
|
|
{
|
|
indexStart = xmlElement->IntAttribute("IndexStart", 0);
|
|
indexEnd = xmlElement->IntAttribute("IndexEnd", 0);
|
|
}
|
|
|
|
std::string HLMeshCmdCull::OutputCode(HLModelIntermediette* parent)
|
|
{
|
|
return StringHelper::Sprintf("gsSPCullDisplayList(%i, %i),", indexStart, indexEnd);
|
|
}
|
|
|
|
HLMeshIntermediette::HLMeshIntermediette() : HLIntermediette()
|
|
{
|
|
commands = std::vector<HLMeshCommand*>();
|
|
}
|
|
|
|
void HLMeshIntermediette::InitFromXML(tinyxml2::XMLElement* xmlElement)
|
|
{
|
|
name = xmlElement->Attribute("Name");
|
|
|
|
for (XMLElement* child = xmlElement->FirstChildElement(); child != NULL;
|
|
child = child->NextSiblingElement())
|
|
{
|
|
std::string name = child->Name();
|
|
|
|
HLMeshCommand* cmd = nullptr;
|
|
|
|
if (name == "Triangle1")
|
|
cmd = new HLMeshCmdTriangle1();
|
|
else if (name == "Triangle2")
|
|
cmd = new HLMeshCmdTriangle2();
|
|
else if (name == "LoadVertices")
|
|
cmd = new HLMeshCmdLoadVertices();
|
|
else if (name == "GeoSettings")
|
|
cmd = new HLMeshCmdGeoSettings();
|
|
else if (name == "Cull")
|
|
cmd = new HLMeshCmdCull();
|
|
|
|
if (cmd != nullptr)
|
|
{
|
|
cmd->InitFromXML(child);
|
|
commands.push_back(cmd);
|
|
}
|
|
}
|
|
}
|
|
|
|
std::string HLMeshIntermediette::OutputCode(std::string materialName)
|
|
{
|
|
std::string output = "";
|
|
|
|
HLMaterialIntermediette* mat = parent->FindByName<HLMaterialIntermediette>(materialName);
|
|
HLTextureIntermediette* tex = parent->FindByName<HLTextureIntermediette>(mat->textureName);
|
|
|
|
output += StringHelper::Sprintf(" gsDPPipeSync(),\n");
|
|
output += StringHelper::Sprintf(" gsDPSetPrimColor(%i, %i, %i, %i, %i, %i),\n", mat->clrL,
|
|
mat->clrM, mat->clrR, mat->clrG, mat->clrB, mat->clrA);
|
|
output += StringHelper::Sprintf(" gsDPPipeSync(),\n");
|
|
output += StringHelper::Sprintf(" gsSPTexture(65535, 65535, 0, 0, G_ON),\n");
|
|
|
|
output += StringHelper::Sprintf(
|
|
" gsDPLoadMultiBlock(%s, 0, 0, %s, %s, %i, %i, 0, 0, 0, 5, 5, 0, 0),\n",
|
|
mat->textureName.c_str(), tex->tex->GetIMFmtFromType().c_str(),
|
|
tex->tex->GetIMSizFromType().c_str(), tex->tex->GetWidth(), tex->tex->GetHeight());
|
|
|
|
for (HLMeshCommand* cmd : commands)
|
|
output += " " + cmd->OutputCode(parent) + "\n";
|
|
|
|
return output;
|
|
}
|
|
|
|
std::string HLMeshIntermediette::OutputOBJ()
|
|
{
|
|
std::string output = "";
|
|
|
|
output += StringHelper::Sprintf("o %s\n", name.c_str());
|
|
|
|
for (HLMeshCommand* cmd : commands)
|
|
output += cmd->OutputOBJ(parent);
|
|
|
|
return output;
|
|
}
|
|
|
|
void HLMeshIntermediette::OutputAssimp(aiScene* scene, std::vector<aiVector3D>* verts)
|
|
{
|
|
aiMesh* mesh = new aiMesh();
|
|
mesh->mVertices =
|
|
new aiVector3D[8192]; // TODO: Replace these hardcoded counts with the actual count
|
|
mesh->mNormals = new aiVector3D[8192];
|
|
mesh->mFaces = new aiFace[8192];
|
|
mesh->mPrimitiveTypes = 8;
|
|
mesh->mName = name;
|
|
|
|
for (HLMeshCommand* cmd : commands)
|
|
{
|
|
cmd->OutputAssimp(parent, scene, mesh);
|
|
}
|
|
|
|
parent->meshTranslations.push_back(parent->lastTrans);
|
|
// parent->objects.push_back(new HLModelObj(parent->lastTransX, ))
|
|
|
|
scene->mMeshes[scene->mNumMeshes++] = mesh;
|
|
}
|
|
|
|
void HLMeshIntermediette::OutputXML(tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* root)
|
|
{
|
|
XMLElement* element = doc->NewElement("Mesh");
|
|
|
|
element->SetAttribute("Name", name.c_str());
|
|
|
|
for (HLMeshCommand* cmd : commands)
|
|
{
|
|
cmd->OutputXML(element);
|
|
}
|
|
|
|
root->InsertEndChild(element);
|
|
}
|
|
|
|
HLLimbIntermediette::HLLimbIntermediette()
|
|
{
|
|
commands = std::vector<HLLimbCommand*>();
|
|
}
|
|
|
|
void HLLimbIntermediette::InitFromXML(tinyxml2::XMLElement* xmlElement)
|
|
{
|
|
name = xmlElement->Attribute("Name");
|
|
|
|
for (XMLElement* child = xmlElement->FirstChildElement(); child != NULL;
|
|
child = child->NextSiblingElement())
|
|
{
|
|
std::string name = child->Name();
|
|
|
|
HLLimbCommand* cmd = nullptr;
|
|
|
|
if (name == "DrawMesh")
|
|
cmd = new HLLimbCommand();
|
|
|
|
if (cmd != nullptr)
|
|
{
|
|
cmd->InitFromXML(child);
|
|
commands.push_back(cmd);
|
|
}
|
|
}
|
|
}
|
|
|
|
std::string HLLimbIntermediette::OutputCode()
|
|
{
|
|
std::string output = "";
|
|
|
|
output += StringHelper::Sprintf("Gfx %s[] = \n{\n", name.c_str());
|
|
|
|
for (HLLimbCommand* cmd : commands)
|
|
output += cmd->OutputCode(parent);
|
|
|
|
output += StringHelper::Sprintf(" gsSPEndDisplayList(),\n");
|
|
output += StringHelper::Sprintf("};\n");
|
|
|
|
return output;
|
|
}
|
|
|
|
void HLLimbIntermediette::OutputXML(tinyxml2::XMLDocument* doc, tinyxml2::XMLElement* root)
|
|
{
|
|
XMLElement* element = doc->NewElement("Limb");
|
|
|
|
element->SetAttribute("Name", name.c_str());
|
|
|
|
for (HLLimbCommand* cmd : commands)
|
|
cmd->OutputXML(element);
|
|
|
|
root->InsertEndChild(element);
|
|
}
|
|
|
|
HLLimbCommand::HLLimbCommand()
|
|
{
|
|
meshName = "";
|
|
materialName = "";
|
|
}
|
|
|
|
HLLimbCommand::HLLimbCommand(std::string nMeshName, std::string nMaterialName)
|
|
{
|
|
meshName = nMeshName;
|
|
materialName = nMaterialName;
|
|
}
|
|
|
|
void HLLimbCommand::InitFromXML(tinyxml2::XMLElement* xmlElement)
|
|
{
|
|
meshName = xmlElement->Attribute("Mesh");
|
|
materialName = xmlElement->Attribute("Material");
|
|
}
|
|
|
|
void HLLimbCommand::OutputXML(tinyxml2::XMLElement* parent)
|
|
{
|
|
XMLElement* elem = parent->GetDocument()->NewElement("DrawMesh");
|
|
|
|
elem->SetAttribute("Mesh", meshName.c_str());
|
|
elem->SetAttribute("Material", materialName.c_str());
|
|
|
|
parent->InsertEndChild(elem);
|
|
}
|
|
|
|
std::string HLLimbCommand::OutputCode(HLModelIntermediette* parent)
|
|
{
|
|
std::string output = "";
|
|
|
|
// Time to generate the display list...
|
|
HLMeshIntermediette* mesh = parent->FindByName<HLMeshIntermediette>(meshName);
|
|
|
|
output += mesh->OutputCode(materialName);
|
|
|
|
return output;
|
|
}
|
|
|
|
HLTerminator::HLTerminator()
|
|
{
|
|
}
|
|
|
|
HLTerminator::~HLTerminator()
|
|
{
|
|
}
|
|
|
|
void HLTerminator::OutputAssimp(aiScene* scene, std::vector<aiVector3D>* verts)
|
|
{
|
|
for (uint32_t i = parent->meshStartIndex; i < scene->mNumMeshes; i++)
|
|
{
|
|
scene->mMeshes[i]->mNumVertices = verts->size();
|
|
|
|
for (uint32_t j = 0; j < verts->size(); j++)
|
|
scene->mMeshes[i]->mVertices[j] = verts[0][j];
|
|
|
|
parent->meshStartIndex++;
|
|
}
|
|
|
|
verts->clear();
|
|
}
|
|
|
|
HLSetTranslation::HLSetTranslation()
|
|
{
|
|
transX = 0;
|
|
transY = 0;
|
|
transZ = 0;
|
|
}
|
|
|
|
HLSetTranslation::HLSetTranslation(float nTransX, float nTransY, float nTransZ)
|
|
{
|
|
transX = nTransX;
|
|
transY = nTransY;
|
|
transZ = nTransZ;
|
|
}
|
|
|
|
void HLSetTranslation::OutputAssimp(aiScene* scene, std::vector<aiVector3D>* verts)
|
|
{
|
|
parent->lastTrans = Vec3s(transX, transY, transZ);
|
|
}
|
|
|
|
HLModelObj::HLModelObj(Vec3s nPos, Vec3s nRot, std::vector<aiVector3D> nVerts,
|
|
std::vector<int32_t> nIndices)
|
|
{
|
|
pos = nPos;
|
|
rot = nRot;
|
|
vertices = nVerts;
|
|
indices = nIndices;
|
|
}
|