mirror of
				https://github.com/Laupetin/OpenAssetTools.git
				synced 2025-10-31 02:26:59 +00: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