chore: move xmodel packages

This commit is contained in:
Jan
2024-03-30 15:19:11 +01:00
parent abc3003b5b
commit d4ef9fa3d9
22 changed files with 18 additions and 18 deletions

View File

@ -0,0 +1,33 @@
#include "AbstractXModelWriter.h"
AbstractXModelWriter::AbstractXModelWriter() = default;
void AbstractXModelWriter::AddObject(XModelObject object)
{
m_objects.emplace_back(std::move(object));
}
void AbstractXModelWriter::AddBone(XModelBone bone)
{
m_bones.emplace_back(std::move(bone));
}
void AbstractXModelWriter::AddMaterial(XModelMaterial material)
{
m_materials.emplace_back(std::move(material));
}
void AbstractXModelWriter::AddVertex(XModelVertex vertex)
{
m_vertices.emplace_back(vertex);
}
void AbstractXModelWriter::AddVertexBoneWeights(XModelVertexBoneWeights vertexBoneWeights)
{
m_vertex_bone_weights.emplace_back(vertexBoneWeights);
}
void AbstractXModelWriter::AddFace(XModelFace face)
{
m_faces.emplace_back(face);
}

View File

@ -0,0 +1,26 @@
#pragma once
#include "XModel/XModelCommon.h"
#include <vector>
class AbstractXModelWriter
{
protected:
std::vector<XModelObject> m_objects;
std::vector<XModelBone> m_bones;
std::vector<XModelMaterial> m_materials;
std::vector<XModelVertex> m_vertices;
std::vector<XModelVertexBoneWeights> m_vertex_bone_weights;
std::vector<XModelFace> m_faces;
public:
AbstractXModelWriter();
void AddObject(XModelObject object);
void AddBone(XModelBone bone);
void AddMaterial(XModelMaterial material);
void AddVertex(XModelVertex vertex);
void AddVertexBoneWeights(XModelVertexBoneWeights vertexBoneWeights);
void AddFace(XModelFace face);
};

View File

@ -0,0 +1,222 @@
#include "XModelExportWriter.h"
#include "Math/Quaternion.h"
#include <chrono>
#include <iomanip>
#include <iostream>
class XModelExportWriterBase : public XModelExportWriter
{
protected:
std::string m_game_name;
std::string m_zone_name;
VertexMerger m_vertex_merger;
void PrepareVertexMerger()
{
m_vertex_merger = VertexMerger(m_vertices.size());
auto vertexOffset = 0u;
for (const auto& vertex : m_vertices)
{
XModelVertexBoneWeights weights{nullptr, 0};
if (vertexOffset < m_vertex_bone_weights.size())
weights = m_vertex_bone_weights[vertexOffset];
m_vertex_merger.Add(VertexMergerPos{vertex.coordinates[0], vertex.coordinates[1], vertex.coordinates[2], weights.weights, weights.weightCount});
vertexOffset++;
}
}
void WriteHeader(std::ostream& stream, const int version) const
{
stream << "// OpenAssetTools XMODEL_EXPORT File\n";
stream << "// Game Origin: " << m_game_name << "\n";
stream << "// Zone Origin: " << m_zone_name << "\n";
stream << "MODEL\n";
stream << "VERSION " << version << "\n";
stream << "\n";
}
void WriteBones(std::ostream& stream) const
{
stream << "NUMBONES " << m_bones.size() << "\n";
size_t boneNum = 0u;
for (const auto& bone : m_bones)
{
stream << "BONE " << boneNum << " ";
if (bone.parentIndex < 0)
stream << "-1";
else
stream << bone.parentIndex;
stream << " \"" << bone.name << "\"\n";
boneNum++;
}
stream << "\n";
boneNum = 0u;
for (const auto& bone : m_bones)
{
stream << "BONE " << boneNum << "\n";
stream << "OFFSET ";
stream << std::setprecision(6) << std::fixed << bone.globalOffset[0] << ", " << std::setprecision(6) << std::fixed << bone.globalOffset[1] << ", "
<< std::setprecision(6) << std::fixed << bone.globalOffset[2] << "\n";
stream << "SCALE ";
stream << std::setprecision(6) << std::fixed << bone.scale[0] << ", " << std::setprecision(6) << std::fixed << bone.scale[1] << ", "
<< std::setprecision(6) << std::fixed << bone.scale[2] << "\n";
const Matrix32 mat = bone.globalRotation.ToMatrix();
stream << "X " << std::setprecision(6) << std::fixed << mat.m_data[0][0] << ", " << std::setprecision(6) << std::fixed << mat.m_data[1][0] << ", "
<< std::setprecision(6) << std::fixed << mat.m_data[2][0] << "\n";
stream << "Y " << std::setprecision(6) << std::fixed << mat.m_data[0][1] << ", " << std::setprecision(6) << std::fixed << mat.m_data[1][1] << ", "
<< std::setprecision(6) << std::fixed << mat.m_data[2][1] << "\n";
stream << "Z " << std::setprecision(6) << std::fixed << mat.m_data[0][2] << ", " << std::setprecision(6) << std::fixed << mat.m_data[1][2] << ", "
<< std::setprecision(6) << std::fixed << mat.m_data[2][2] << "\n";
stream << "\n";
boneNum++;
}
}
XModelExportWriterBase(std::string gameName, std::string zoneName)
: m_game_name(std::move(gameName)),
m_zone_name(std::move(zoneName))
{
}
};
class XModelExportWriter6 final : public XModelExportWriterBase
{
void WriteVertices(std::ostream& stream) const
{
const auto& distinctVertexValues = m_vertex_merger.GetDistinctValues();
stream << "NUMVERTS " << distinctVertexValues.size() << "\n";
size_t vertexNum = 0u;
for (const auto& vertexPos : distinctVertexValues)
{
stream << "VERT " << vertexNum << "\n";
stream << "OFFSET ";
stream << std::setprecision(6) << std::fixed << vertexPos.x << ", " << std::setprecision(6) << std::fixed << vertexPos.y << ", "
<< std::setprecision(6) << std::fixed << vertexPos.z << "\n";
stream << "BONES " << vertexPos.weightCount << "\n";
for (auto weightIndex = 0u; weightIndex < vertexPos.weightCount; weightIndex++)
{
stream << "BONE " << vertexPos.weights[weightIndex].boneIndex << " " << std::setprecision(6) << std::fixed
<< vertexPos.weights[weightIndex].weight << "\n";
}
stream << "\n";
vertexNum++;
}
}
static void WriteFaceVertex(std::ostream& stream, const size_t index, const XModelVertex& vertex)
{
stream << "VERT " << index << "\n";
stream << "NORMAL " << std::setprecision(6) << std::fixed << vertex.normal[0] << " " << std::setprecision(6) << std::fixed << vertex.normal[1] << " "
<< std::setprecision(6) << std::fixed << vertex.normal[2] << "\n";
stream << "COLOR " << std::setprecision(6) << std::fixed << vertex.color[0] << " " << std::setprecision(6) << std::fixed << vertex.color[1] << " "
<< std::setprecision(6) << std::fixed << vertex.color[2] << " " << std::setprecision(6) << std::fixed << vertex.color[3] << "\n";
stream << "UV 1 " << std::setprecision(6) << std::fixed << vertex.uv[0] << " " << std::setprecision(6) << std::fixed << vertex.uv[1] << "\n";
}
void WriteFaces(std::ostream& stream) const
{
stream << "NUMFACES " << m_faces.size() << "\n";
for (const auto& face : m_faces)
{
const size_t distinctPositions[3]{
m_vertex_merger.GetDistinctPositionByInputPosition(face.vertexIndex[0]),
m_vertex_merger.GetDistinctPositionByInputPosition(face.vertexIndex[1]),
m_vertex_merger.GetDistinctPositionByInputPosition(face.vertexIndex[2]),
};
const XModelVertex& v0 = m_vertices[face.vertexIndex[0]];
const XModelVertex& v1 = m_vertices[face.vertexIndex[1]];
const XModelVertex& v2 = m_vertices[face.vertexIndex[2]];
stream << "TRI " << face.objectIndex << " " << face.materialIndex << " 0 0\n";
WriteFaceVertex(stream, distinctPositions[0], v0);
WriteFaceVertex(stream, distinctPositions[1], v1);
WriteFaceVertex(stream, distinctPositions[2], v2);
stream << "\n";
}
}
void WriteObjects(std::ostream& stream) const
{
stream << "NUMOBJECTS " << m_objects.size() << "\n";
size_t objectNum = 0u;
for (const auto& object : m_objects)
{
stream << "OBJECT " << objectNum << " \"" << object.name << "\"\n";
objectNum++;
}
stream << "\n";
}
void WriteMaterials(std::ostream& stream) const
{
stream << "NUMMATERIALS " << m_materials.size() << "\n";
size_t materialNum = 0u;
for (const auto& material : m_materials)
{
const auto colorMapPath = "../images/" + material.colorMapName + ".dds";
stream << "MATERIAL " << materialNum << " \"" << material.name << "\" \"" << material.materialTypeName << "\" \"" << colorMapPath << "\"\n";
stream << "COLOR " << std::setprecision(6) << std::fixed << material.color[0] << " " << std::setprecision(6) << std::fixed << material.color[1]
<< " " << std::setprecision(6) << std::fixed << material.color[2] << " " << std::setprecision(6) << std::fixed << material.color[3] << "\n";
stream << "TRANSPARENCY " << std::setprecision(6) << std::fixed << material.transparency[0] << " " << std::setprecision(6) << std::fixed
<< material.transparency[1] << " " << std::setprecision(6) << std::fixed << material.transparency[2] << " " << std::setprecision(6)
<< std::fixed << material.transparency[3] << "\n";
stream << "AMBIENTCOLOR " << std::setprecision(6) << std::fixed << material.ambientColor[0] << " " << std::setprecision(6) << std::fixed
<< material.ambientColor[1] << " " << std::setprecision(6) << std::fixed << material.ambientColor[2] << " " << std::setprecision(6)
<< std::fixed << material.ambientColor[3] << "\n";
stream << "INCANDESCENCE " << std::setprecision(6) << std::fixed << material.incandescence[0] << " " << std::setprecision(6) << std::fixed
<< material.incandescence[1] << " " << std::setprecision(6) << std::fixed << material.incandescence[2] << " " << std::setprecision(6)
<< std::fixed << material.incandescence[3] << "\n";
stream << "COEFFS " << std::setprecision(6) << std::fixed << material.coeffs[0] << " " << std::setprecision(6) << std::fixed << material.coeffs[1]
<< "\n";
stream << "GLOW " << std::setprecision(6) << std::fixed << material.glow.x << " " << material.glow.y << "\n";
stream << "REFRACTIVE " << material.refractive.x << " " << std::setprecision(6) << std::fixed << material.refractive.y << "\n";
stream << "SPECULARCOLOR " << std::setprecision(6) << std::fixed << material.specularColor[0] << " " << std::setprecision(6) << std::fixed
<< material.specularColor[1] << " " << std::setprecision(6) << std::fixed << material.specularColor[2] << " " << std::setprecision(6)
<< std::fixed << material.specularColor[3] << "\n";
stream << "REFLECTIVECOLOR " << std::setprecision(6) << std::fixed << material.reflectiveColor[0] << " " << std::setprecision(6) << std::fixed
<< material.reflectiveColor[1] << " " << std::setprecision(6) << std::fixed << material.reflectiveColor[2] << " " << std::setprecision(6)
<< std::fixed << material.reflectiveColor[3] << "\n";
stream << "REFLECTIVE " << material.reflective.x << " " << std::setprecision(6) << std::fixed << material.reflective.y << "\n";
stream << "BLINN " << std::setprecision(6) << std::fixed << material.blinn[0] << " " << std::setprecision(6) << std::fixed << material.blinn[1]
<< "\n";
stream << "PHONG " << std::setprecision(6) << std::fixed << material.phong << "\n";
stream << "\n";
materialNum++;
}
}
public:
XModelExportWriter6(std::string gameName, std::string zoneName)
: XModelExportWriterBase(std::move(gameName), std::move(zoneName))
{
}
void Write(std::ostream& stream) override
{
PrepareVertexMerger();
WriteHeader(stream, 6);
WriteBones(stream);
WriteVertices(stream);
WriteFaces(stream);
WriteObjects(stream);
WriteMaterials(stream);
}
};
std::unique_ptr<XModelExportWriter> XModelExportWriter::CreateWriterForVersion6(std::string gameName, std::string zoneName)
{
return std::make_unique<XModelExportWriter6>(std::move(gameName), std::move(zoneName));
}

View File

@ -0,0 +1,21 @@
#pragma once
#include "XModel/AbstractXModelWriter.h"
#include <memory>
#include <ostream>
class XModelExportWriter : public AbstractXModelWriter
{
public:
XModelExportWriter() = default;
virtual ~XModelExportWriter() = default;
XModelExportWriter(const XModelExportWriter& other) = default;
XModelExportWriter(XModelExportWriter&& other) noexcept = default;
XModelExportWriter& operator=(const XModelExportWriter& other) = default;
XModelExportWriter& operator=(XModelExportWriter&& other) noexcept = default;
virtual void Write(std::ostream& stream) = 0;
static std::unique_ptr<XModelExportWriter> CreateWriterForVersion6(std::string gameName, std::string zoneName);
};

View File

@ -0,0 +1,157 @@
#include "ObjWriter.h"
#include "Game/IW4/CommonIW4.h"
ObjWriter::ObjWriter(std::string gameName, std::string zoneName)
: m_game_name(std::move(gameName)),
m_zone_name(std::move(zoneName))
{
}
void ObjWriter::AddObject(ObjObject object)
{
m_objects.emplace_back(std::move(object));
m_object_data.emplace_back();
}
void ObjWriter::AddMaterial(MtlMaterial material)
{
m_materials.emplace_back(std::move(material));
}
void ObjWriter::AddVertex(const int objectId, const ObjVertex vertex)
{
if (objectId < 0 || static_cast<unsigned>(objectId) >= m_object_data.size())
return;
m_object_data[objectId].m_vertices.Add(vertex);
}
void ObjWriter::AddNormal(const int objectId, const ObjNormal normal)
{
if (objectId < 0 || static_cast<unsigned>(objectId) >= m_object_data.size())
return;
m_object_data[objectId].m_normals.Add(normal);
}
void ObjWriter::AddUv(const int objectId, const ObjUv uv)
{
if (objectId < 0 || static_cast<unsigned>(objectId) >= m_object_data.size())
return;
m_object_data[objectId].m_uvs.Add(uv);
}
void ObjWriter::AddFace(const int objectId, const ObjFace face)
{
if (objectId < 0 || static_cast<unsigned>(objectId) >= m_object_data.size())
return;
m_object_data[objectId].m_faces.push_back(face);
}
void ObjWriter::GetObjObjectDataOffsets(std::vector<ObjObjectDataOffsets>& inputOffsets, std::vector<ObjObjectDataOffsets>& distinctOffsets)
{
ObjObjectDataOffsets currentInputOffsets{};
ObjObjectDataOffsets currentDistinctOffsets{};
for (const auto& objectData : m_object_data)
{
inputOffsets.push_back(currentInputOffsets);
distinctOffsets.push_back(currentDistinctOffsets);
currentInputOffsets.vertexOffset += objectData.m_vertices.GetInputValueCount();
currentInputOffsets.normalOffset += objectData.m_normals.GetInputValueCount();
currentInputOffsets.uvOffset += objectData.m_uvs.GetInputValueCount();
currentDistinctOffsets.vertexOffset += objectData.m_vertices.GetDistinctValueCount();
currentDistinctOffsets.normalOffset += objectData.m_normals.GetDistinctValueCount();
currentDistinctOffsets.uvOffset += objectData.m_uvs.GetDistinctValueCount();
}
}
void ObjWriter::WriteObj(std::ostream& stream)
{
WriteObj(stream, std::string());
}
void ObjWriter::WriteObj(std::ostream& stream, const std::string& mtlName)
{
stream << "# OpenAssetTools OBJ File ( " << m_game_name << ")\n";
stream << "# Game Origin: " << m_game_name << "\n";
stream << "# Zone Origin: " << m_zone_name << "\n";
if (!mtlName.empty())
stream << "mtllib " << mtlName << "\n";
std::vector<ObjObjectDataOffsets> inputOffsetsByObject;
std::vector<ObjObjectDataOffsets> distinctOffsetsByObject;
GetObjObjectDataOffsets(inputOffsetsByObject, distinctOffsetsByObject);
auto objectIndex = 0;
for (const auto& object : m_objects)
{
const auto& objectData = m_object_data[objectIndex];
stream << "o " << object.name << "\n";
for (const auto& v : objectData.m_vertices.GetDistinctValues())
stream << "v " << v.coordinates[0] << " " << v.coordinates[1] << " " << v.coordinates[2] << "\n";
for (const auto& uv : objectData.m_uvs.GetDistinctValues())
stream << "vt " << uv.uv[0] << " " << uv.uv[1] << "\n";
for (const auto& n : objectData.m_normals.GetDistinctValues())
stream << "vn " << n.normal[0] << " " << n.normal[1] << " " << n.normal[2] << "\n";
if (object.materialIndex >= 0 && static_cast<unsigned>(object.materialIndex) < m_materials.size())
stream << "usemtl " << m_materials[object.materialIndex].materialName << "\n";
for (const auto& f : objectData.m_faces)
{
const size_t v[3]{objectData.m_vertices.GetDistinctPositionByInputPosition(f.vertexIndex[0] - inputOffsetsByObject[objectIndex].vertexOffset)
+ distinctOffsetsByObject[objectIndex].vertexOffset + 1,
objectData.m_vertices.GetDistinctPositionByInputPosition(f.vertexIndex[1] - inputOffsetsByObject[objectIndex].vertexOffset)
+ distinctOffsetsByObject[objectIndex].vertexOffset + 1,
objectData.m_vertices.GetDistinctPositionByInputPosition(f.vertexIndex[2] - inputOffsetsByObject[objectIndex].vertexOffset)
+ distinctOffsetsByObject[objectIndex].vertexOffset + 1};
const size_t n[3]{objectData.m_normals.GetDistinctPositionByInputPosition(f.normalIndex[0] - inputOffsetsByObject[objectIndex].normalOffset)
+ distinctOffsetsByObject[objectIndex].normalOffset + 1,
objectData.m_normals.GetDistinctPositionByInputPosition(f.normalIndex[1] - inputOffsetsByObject[objectIndex].normalOffset)
+ distinctOffsetsByObject[objectIndex].normalOffset + 1,
objectData.m_normals.GetDistinctPositionByInputPosition(f.normalIndex[2] - inputOffsetsByObject[objectIndex].normalOffset)
+ distinctOffsetsByObject[objectIndex].normalOffset + 1};
const size_t uv[3]{objectData.m_uvs.GetDistinctPositionByInputPosition(f.uvIndex[0] - inputOffsetsByObject[objectIndex].uvOffset)
+ distinctOffsetsByObject[objectIndex].uvOffset + 1,
objectData.m_uvs.GetDistinctPositionByInputPosition(f.uvIndex[1] - inputOffsetsByObject[objectIndex].uvOffset)
+ distinctOffsetsByObject[objectIndex].uvOffset + 1,
objectData.m_uvs.GetDistinctPositionByInputPosition(f.uvIndex[2] - inputOffsetsByObject[objectIndex].uvOffset)
+ distinctOffsetsByObject[objectIndex].uvOffset + 1};
stream << "f " << v[0] << "/" << uv[0] << "/" << n[0] << " " << v[1] << "/" << uv[1] << "/" << n[1] << " " << v[2] << "/" << uv[2] << "/" << n[2]
<< "\n";
}
objectIndex++;
}
}
void ObjWriter::WriteMtl(std::ostream& stream)
{
stream << "# OpenAssetTools MAT File ( " << m_game_name << ")\n";
stream << "# Game Origin: " << m_game_name << "\n";
stream << "# Zone Origin: " << m_zone_name << "\n";
stream << "# Material count: " << m_materials.size() << "\n";
for (const auto& material : m_materials)
{
stream << "\n";
stream << "newmtl " << material.materialName << "\n";
if (!material.colorMapName.empty())
stream << "map_Kd ../images/" << material.colorMapName << ".dds\n";
if (!material.normalMapName.empty())
stream << "map_bump ../images/" << material.normalMapName << ".dds\n";
if (!material.specularMapName.empty())
stream << "map_Ks ../images/" << material.specularMapName << ".dds\n";
}
}

View File

@ -0,0 +1,48 @@
#pragma once
#include "Utils/DistinctMapper.h"
#include "XModel/Obj/ObjCommon.h"
#include <ostream>
#include <vector>
class ObjWriter
{
protected:
struct ObjObjectData
{
DistinctMapper<ObjVertex> m_vertices;
DistinctMapper<ObjNormal> m_normals;
DistinctMapper<ObjUv> m_uvs;
std::vector<ObjFace> m_faces;
};
struct ObjObjectDataOffsets
{
size_t vertexOffset;
size_t normalOffset;
size_t uvOffset;
};
std::string m_game_name;
std::string m_zone_name;
std::vector<ObjObject> m_objects;
std::vector<ObjObjectData> m_object_data;
std::vector<MtlMaterial> m_materials;
void GetObjObjectDataOffsets(std::vector<ObjObjectDataOffsets>& inputOffsets, std::vector<ObjObjectDataOffsets>& distinctOffsets);
public:
ObjWriter(std::string gameName, std::string zoneName);
void AddObject(ObjObject object);
void AddMaterial(MtlMaterial material);
void AddVertex(int objectId, ObjVertex vertex);
void AddNormal(int objectId, ObjNormal normal);
void AddUv(int objectId, ObjUv uv);
void AddFace(int objectId, ObjFace face);
void WriteObj(std::ostream& stream);
void WriteObj(std::ostream& stream, const std::string& mtlName);
void WriteMtl(std::ostream& stream);
};