mirror of
https://github.com/Laupetin/OpenAssetTools.git
synced 2025-06-16 09:48:00 -05:00
chore: move xmodel packages
This commit is contained in:
33
src/ObjWriting/XModel/AbstractXModelWriter.cpp
Normal file
33
src/ObjWriting/XModel/AbstractXModelWriter.cpp
Normal 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);
|
||||
}
|
26
src/ObjWriting/XModel/AbstractXModelWriter.h
Normal file
26
src/ObjWriting/XModel/AbstractXModelWriter.h
Normal 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);
|
||||
};
|
0
src/ObjWriting/XModel/Export/XModelBinWriter.cpp
Normal file
0
src/ObjWriting/XModel/Export/XModelBinWriter.cpp
Normal file
0
src/ObjWriting/XModel/Export/XModelBinWriter.h
Normal file
0
src/ObjWriting/XModel/Export/XModelBinWriter.h
Normal file
222
src/ObjWriting/XModel/Export/XModelExportWriter.cpp
Normal file
222
src/ObjWriting/XModel/Export/XModelExportWriter.cpp
Normal 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));
|
||||
}
|
21
src/ObjWriting/XModel/Export/XModelExportWriter.h
Normal file
21
src/ObjWriting/XModel/Export/XModelExportWriter.h
Normal 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);
|
||||
};
|
157
src/ObjWriting/XModel/Obj/ObjWriter.cpp
Normal file
157
src/ObjWriting/XModel/Obj/ObjWriter.cpp
Normal 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";
|
||||
}
|
||||
}
|
48
src/ObjWriting/XModel/Obj/ObjWriter.h
Normal file
48
src/ObjWriting/XModel/Obj/ObjWriter.h
Normal 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);
|
||||
};
|
Reference in New Issue
Block a user