r5sdk/r5dev/thirdparty/cppnet/cppkore/CoDXAssetExport.cpp
Kawe Mazidjatari 04bee896be Fix string/wstring type conflict
cppkore uses string/wstring as StringBase while we use std::string/std::wstring as string/wstring. Changed all types in cppkore to String/WString instead.
2022-05-21 21:51:35 +02:00

252 lines
7.0 KiB
C++

#include "stdafx.h"
#include "CoDXAssetExport.h"
#include "File.h"
#include "Path.h"
#include "Matrix.h"
#include "StreamWriter.h"
namespace Assets::Exporters
{
bool CoDXAssetExport::ExportAnimation(const Animation& Animation, const String& Path)
{
return false;
}
bool CoDXAssetExport::ExportModel(const Model& Model, const String& Path)
{
auto Writer = IO::StreamWriter(IO::File::Create(Path));
Writer.WriteLine(
"MODEL\nVERSION 6\n"
);
Writer.WriteLineFmt("NUMBONES %d", Model.Bones.Count());
uint32_t BoneIndex = 0;
for (auto& Bone : Model.Bones)
{
Writer.WriteLineFmt("BONE %d %d \"%s\"", BoneIndex, Bone.Parent(), (char*)Bone.Name());
BoneIndex++;
}
Writer.Write("\n");
BoneIndex = 0;
for (auto& Bone : Model.Bones)
{
auto Rotation = ::Math::Matrix::CreateFromQuaternion(Bone.GlobalRotation());
auto& Position = Bone.GlobalPosition();
auto& Scale = Bone.Scale();
Writer.WriteLineFmt(
"BONE %d\n"
"OFFSET %f, %f, %f\n"
"SCALE %f, %f, %f\n"
"X %f, %f, %f\n"
"Y %f, %f, %f\n"
"Z %f, %f, %f\n",
BoneIndex,
Position.X, Position.Y, Position.Z,
Scale.X, Scale.Y, Scale.Z,
MathHelper::Clamp(Rotation.Mat(0, 0), -1.f, 1.f), MathHelper::Clamp(Rotation.Mat(0, 1), -1.f, 1.f), MathHelper::Clamp(Rotation.Mat(0, 2), -1.f, 1.f),
MathHelper::Clamp(Rotation.Mat(1, 0), -1.f, 1.f), MathHelper::Clamp(Rotation.Mat(1, 1), -1.f, 1.f), MathHelper::Clamp(Rotation.Mat(1, 2), -1.f, 1.f),
MathHelper::Clamp(Rotation.Mat(2, 0), -1.f, 1.f), MathHelper::Clamp(Rotation.Mat(2, 1), -1.f, 1.f), MathHelper::Clamp(Rotation.Mat(2, 2), -1.f, 1.f)
);
BoneIndex++;
}
auto TotalVertexCount = Model.VertexCount();
auto TotalFaceCount = Model.FaceCount();
if (TotalVertexCount > UINT16_MAX)
Writer.WriteLineFmt("NUMVERTS32 %d", TotalVertexCount);
else
Writer.WriteLineFmt("NUMVERTS %d", TotalVertexCount);
uint32_t VertexIndex = 0;
for (auto& Submesh : Model.Meshes)
{
for (auto& Vertex : Submesh.Vertices)
{
auto& Position = Vertex.Position();
if (TotalVertexCount > UINT16_MAX)
Writer.WriteLineFmt(
"VERT32 %d\n"
"OFFSET %f, %f, %f",
VertexIndex,
Position.X, Position.Y, Position.Z
);
else
Writer.WriteLineFmt(
"VERT %d\n"
"OFFSET %f, %f, %f",
VertexIndex,
Position.X, Position.Y, Position.Z
);
if (Vertex.WeightCount() == 1)
Writer.WriteLineFmt(
"BONES 1\n"
"BONE %d 1.0\n",
Vertex.Weights(0).Bone
);
else
{
Writer.WriteLineFmt("BONES %d", Vertex.WeightCount());
for (uint8_t i = 0; i < Vertex.WeightCount(); i++)
Writer.WriteLineFmt("BONE %d %f", Vertex.Weights(i).Bone, Vertex.Weights(i).Value);
Writer.Write("\n");
}
VertexIndex++;
}
}
Writer.WriteLineFmt("NUMFACES %d", TotalFaceCount);
uint32_t SubmeshIndex = 0;
VertexIndex = 0;
for (auto& Submesh : Model.Meshes)
{
for (auto& Face : Submesh.Faces)
{
if (SubmeshIndex > UINT8_MAX || Submesh.MaterialIndices[0] > UINT8_MAX)
Writer.WriteLineFmt("TRI16 %d %d 0 0", SubmeshIndex, Submesh.MaterialIndices[0]);
else
Writer.WriteLineFmt("TRI %d %d 0 0", SubmeshIndex, Submesh.MaterialIndices[0]);
//
// Face vertex [2]
//
Writer.WriteLineFmt((TotalVertexCount > UINT16_MAX) ? "VERT32 %d" : "VERT %d", (Face[2] + VertexIndex));
auto& Face1Normal = Submesh.Vertices[Face[2]].Normal();
auto& Face1Color = Submesh.Vertices[Face[2]].Color();
Writer.WriteFmt(
"NORMAL %f %f %f\n"
"COLOR %f %f %f %f\n"
"UV %d",
Face1Normal.X, Face1Normal.Y, Face1Normal.Z,
Face1Color[0], Face1Color[1], Face1Color[2], Face1Color[3],
Submesh.Vertices.UVLayerCount()
);
for (uint8_t i = 0; i < Submesh.Vertices.UVLayerCount(); i++)
Writer.WriteFmt(" %f %f", Submesh.Vertices[Face[2]].UVLayers(i).U, Submesh.Vertices[Face[2]].UVLayers(i).V);
Writer.Write("\n");
//
// Face vertex [0]
//
Writer.WriteLineFmt((TotalVertexCount > UINT16_MAX) ? "VERT32 %d" : "VERT %d", (Face[0] + VertexIndex));
auto& Face2Normal = Submesh.Vertices[Face[0]].Normal();
auto& Face2Color = Submesh.Vertices[Face[0]].Color();
Writer.WriteFmt(
"NORMAL %f %f %f\n"
"COLOR %f %f %f %f\n"
"UV %d",
Face2Normal.X, Face2Normal.Y, Face2Normal.Z,
Face2Color[0], Face2Color[1], Face2Color[2], Face2Color[3],
Submesh.Vertices.UVLayerCount()
);
for (uint8_t i = 0; i < Submesh.Vertices.UVLayerCount(); i++)
Writer.WriteFmt(" %f %f", Submesh.Vertices[Face[0]].UVLayers(i).U, Submesh.Vertices[Face[0]].UVLayers(i).V);
Writer.Write("\n");
//
// Face vertex [1]
//
Writer.WriteLineFmt((TotalVertexCount > UINT16_MAX) ? "VERT32 %d" : "VERT %d", (Face[1] + VertexIndex));
auto& Face3Normal = Submesh.Vertices[Face[1]].Normal();
auto& Face3Color = Submesh.Vertices[Face[1]].Color();
Writer.WriteFmt(
"NORMAL %f %f %f\n"
"COLOR %f %f %f %f\n"
"UV %d",
Face3Normal.X, Face3Normal.Y, Face3Normal.Z,
Face3Color[0], Face3Color[1], Face3Color[2], Face3Color[3],
Submesh.Vertices.UVLayerCount()
);
for (uint8_t i = 0; i < Submesh.Vertices.UVLayerCount(); i++)
Writer.WriteFmt(" %f %f", Submesh.Vertices[Face[1]].UVLayers(i).U, Submesh.Vertices[Face[1]].UVLayers(i).V);
Writer.Write("\n");
}
VertexIndex += Submesh.Vertices.Count();
SubmeshIndex++;
}
Writer.WriteLineFmt("\nNUMOBJECTS %d", Model.Meshes.Count());
SubmeshIndex = 0;
for (auto& Submesh : Model.Meshes)
Writer.WriteLineFmt("OBJECT %d \"KoreMesh_%d\"", SubmeshIndex, SubmeshIndex++);
Writer.Write("\n");
Writer.WriteLineFmt("NUMMATERIALS %d", Model.Materials.Count());
uint32_t MaterialIndex = 0;
for (auto& Material : Model.Materials)
{
Writer.WriteFmt("MATERIAL %d \"%s\" \"Phong\" \"", MaterialIndex, (char*)Material.Name);
if (Material.Slots.ContainsKey(MaterialSlotType::Albedo))
Writer.WriteFmt("color:%s", (char*)Material.Slots[MaterialSlotType::Albedo].first);
else if (Material.Slots.ContainsKey(MaterialSlotType::Diffuse))
Writer.WriteFmt("color:%s", (char*)Material.Slots[MaterialSlotType::Diffuse].first);
Writer.WriteLine("\"\nCOLOR 0.000000 0.000000 0.000000 1.000000\nTRANSPARENCY 0.000000 0.000000 0.000000 1.000000\nAMBIENTCOLOR 1.000000 1.000000 1.000000 1.000000\nINCANDESCENCE 0.000000 0.000000 0.000000 1.000000\nCOEFFS 0.800000 0.000000\nGLOW 0.000000 0\nREFRACTIVE 6 1.000000\nSPECULARCOLOR 0.500000 0.500000 0.500000 1.000000\nREFLECTIVECOLOR 0.000000 0.000000 0.000000 1.000000\nREFLECTIVE 1 0.500000\nBLINN -1.000000 -1.000000\nPHONG 20.000000");
MaterialIndex++;
}
return true;
}
imstring CoDXAssetExport::ModelExtension()
{
return ".xmodel_export";
}
imstring CoDXAssetExport::AnimationExtension()
{
return ".xanim_export";
}
ExporterScale CoDXAssetExport::ExportScale()
{
// Call of Duty uses inches as the primary scale constant.
return ExporterScale::Inch;
}
bool CoDXAssetExport::SupportsAnimations()
{
return true;
}
bool CoDXAssetExport::SupportsModels()
{
return true;
}
}