2019-04-11 00:42:45 +02:00
|
|
|
|
using System;
|
|
|
|
|
using System.Collections.Generic;
|
|
|
|
|
using System.Text;
|
|
|
|
|
using System.IO;
|
|
|
|
|
using OpenTK;
|
|
|
|
|
|
2019-07-16 23:35:21 +02:00
|
|
|
|
namespace Toolbox.Library
|
2019-04-11 00:42:45 +02:00
|
|
|
|
{
|
|
|
|
|
public class OBJ
|
|
|
|
|
{
|
|
|
|
|
public static void ExportModel(string FileName, STGenericModel Model, List<STGenericTexture> Textures)
|
|
|
|
|
{
|
|
|
|
|
string fileNoExt = Path.GetFileNameWithoutExtension(FileName);
|
2019-04-11 00:58:17 +02:00
|
|
|
|
string fileMtlPath = FileName.Replace("obj", "mtl");
|
2019-04-11 00:42:45 +02:00
|
|
|
|
|
|
|
|
|
//Write model
|
|
|
|
|
StringBuilder writer = new StringBuilder();
|
|
|
|
|
SaveMeshes(writer, Model, $"{fileNoExt}.mtl");
|
|
|
|
|
File.WriteAllText(FileName, writer.ToString());
|
|
|
|
|
|
|
|
|
|
//Write materials
|
|
|
|
|
StringBuilder writerMtl = new StringBuilder();
|
2019-04-11 00:58:17 +02:00
|
|
|
|
SaveMaterials(writerMtl, Model);
|
|
|
|
|
File.WriteAllText(fileMtlPath, writerMtl.ToString());
|
2019-04-11 00:42:45 +02:00
|
|
|
|
}
|
|
|
|
|
|
2019-05-03 01:45:55 +02:00
|
|
|
|
public static void ExportMesh(string FileName, STGenericObject genericMesh)
|
|
|
|
|
{
|
|
|
|
|
string fileNoExt = Path.GetFileNameWithoutExtension(FileName);
|
|
|
|
|
string fileMtlPath = FileName.Replace("obj", "mtl");
|
|
|
|
|
|
|
|
|
|
//Write mesh
|
|
|
|
|
StringBuilder writer = new StringBuilder();
|
|
|
|
|
SaveMesh(writer, genericMesh, null, 0);
|
|
|
|
|
File.WriteAllText(FileName, writer.ToString());
|
|
|
|
|
}
|
|
|
|
|
|
2019-04-11 00:42:45 +02:00
|
|
|
|
private static void SaveMeshes(StringBuilder writer, STGenericModel Model, string MtlName)
|
|
|
|
|
{
|
|
|
|
|
writer.AppendLine($"mtllib {MtlName}");
|
|
|
|
|
|
2019-04-11 01:59:57 +02:00
|
|
|
|
int VertexCount = 1;
|
2019-04-11 00:42:45 +02:00
|
|
|
|
foreach (STGenericObject mesh in Model.Nodes[0].Nodes)
|
|
|
|
|
{
|
|
|
|
|
var mat = GetMaterial(mesh.MaterialIndex, Model);
|
2019-05-03 01:45:55 +02:00
|
|
|
|
SaveMesh(writer, mesh, mat, VertexCount);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static void SaveMesh(StringBuilder writer, STGenericObject mesh, STGenericMaterial mat, int VertexCount)
|
|
|
|
|
{
|
|
|
|
|
writer.AppendLine($"o {mesh.Text}");
|
|
|
|
|
writer.AppendLine($"g {mesh.Text}");
|
|
|
|
|
|
|
|
|
|
foreach (var v in mesh.vertices)
|
|
|
|
|
{
|
|
|
|
|
writer.AppendLine($"v {v.pos.X} {v.pos.Y} {v.pos.Z}");
|
|
|
|
|
writer.AppendLine($"vn {v.nrm.X} {v.nrm.Y} {v.nrm.Z}");
|
|
|
|
|
writer.AppendLine($"vt {v.uv0.X} {v.uv0.Y}");
|
|
|
|
|
}
|
2019-04-11 00:42:45 +02:00
|
|
|
|
|
2019-05-03 01:45:55 +02:00
|
|
|
|
if (mat != null)
|
|
|
|
|
writer.AppendLine($"usemtl {mat.Text}");
|
2019-04-11 00:42:45 +02:00
|
|
|
|
|
2019-05-03 01:45:55 +02:00
|
|
|
|
for (int i = 0; i < mesh.faces.Count; i++)
|
|
|
|
|
{
|
|
|
|
|
int[] indices = new int[3]
|
2019-04-11 00:42:45 +02:00
|
|
|
|
{
|
2019-04-11 01:59:57 +02:00
|
|
|
|
mesh.faces[i++],
|
|
|
|
|
mesh.faces[i++],
|
|
|
|
|
mesh.faces[i]
|
2019-05-03 01:45:55 +02:00
|
|
|
|
};
|
2019-04-11 00:42:45 +02:00
|
|
|
|
|
2019-05-03 01:45:55 +02:00
|
|
|
|
writer.AppendLine($"f {indices[0] + VertexCount}/{indices[0] + VertexCount}/{indices[0] + VertexCount}" +
|
|
|
|
|
$" {indices[1] + VertexCount}/{indices[1] + VertexCount}/{indices[1] + VertexCount}" +
|
|
|
|
|
$" {indices[2] + VertexCount}/{indices[2] + VertexCount}/{indices[2] + VertexCount}");
|
2019-04-11 00:42:45 +02:00
|
|
|
|
}
|
2019-05-03 01:45:55 +02:00
|
|
|
|
|
|
|
|
|
VertexCount += mesh.vertices.Count;
|
2019-04-11 00:42:45 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private static STGenericMaterial GetMaterial(int MaterialIndex, STGenericModel Model)
|
|
|
|
|
{
|
|
|
|
|
if (MaterialIndex < Model.Nodes[1].Nodes.Count)
|
|
|
|
|
return (STGenericMaterial)Model.Nodes[1].Nodes[MaterialIndex];
|
|
|
|
|
else
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
public static float Ns = -3.921569f;
|
|
|
|
|
public static Vector3 Ka = new Vector3(1.000000f, 1.000000f, 1.000000f);
|
|
|
|
|
public static Vector3 Kd = new Vector3(0.640000f, 0.640000f, 0.640000f);
|
|
|
|
|
public static Vector3 Ks = new Vector3(0.500000f, 0.500000f, 0.500000f);
|
|
|
|
|
public static Vector3 Ke = new Vector3(0.000000f, 0.000000f, 0.000000f);
|
|
|
|
|
public static float Ni = -1f;
|
|
|
|
|
public static float d = -1f;
|
|
|
|
|
public static float illum = 2;
|
|
|
|
|
|
|
|
|
|
private static void SaveMaterials(StringBuilder writer, STGenericModel Model)
|
|
|
|
|
{
|
|
|
|
|
foreach (STGenericMaterial mat in Model.Nodes[1].Nodes)
|
|
|
|
|
{
|
|
|
|
|
writer.AppendLine($"newmtl {mat.Text}");
|
|
|
|
|
writer.AppendLine($"Ns {Ns}");
|
2019-04-11 00:58:17 +02:00
|
|
|
|
writer.AppendLine($"Ka {Ka.X} {Ka.Y} {Ka.Z}");
|
|
|
|
|
writer.AppendLine($"Kd {Kd.X} {Kd.Y} {Kd.Z}");
|
|
|
|
|
writer.AppendLine($"Ks {Ks.X} {Ks.Y} {Ks.Z}");
|
|
|
|
|
writer.AppendLine($"Ke {Ke.X} {Ke.Y} {Ke.Z}");
|
2019-04-11 00:42:45 +02:00
|
|
|
|
writer.AppendLine($"Ni {Ni}");
|
|
|
|
|
writer.AppendLine($"d {d}");
|
|
|
|
|
writer.AppendLine($"illum {illum}");
|
|
|
|
|
|
|
|
|
|
foreach (var tex in mat.TextureMaps)
|
|
|
|
|
{
|
|
|
|
|
if (tex.Type == STGenericMatTexture.TextureType.Diffuse)
|
|
|
|
|
writer.AppendLine($"map_Kd {tex.Name}.png");
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|