forked from AerysBat/XNALara
-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathMeshAsciiExporter.cs
96 lines (93 loc) · 4.45 KB
/
MeshAsciiExporter.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
using System;
using System.IO;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
namespace XNALara
{
class MeshAsciiExporter
{
public static void ExportToMeshAscii(Model model, string filename, bool applyPose) {
StreamWriter file = new StreamWriter(filename);
Armature armature = model.Armature;
file.WriteLine("{0} # bones", model.Armature.Bones.Length);
foreach (Armature.Bone bone in model.Armature.Bones) {
file.WriteLine("{0}", bone.name);
file.WriteLine("{0}", bone.parent != null ? bone.parent.id : -1);
Vector3 position;
if (!applyPose) {
position = bone.absPosition * armature.WorldScale;
}
else {
position = Utils.GetTransformedBone(bone, armature.WorldMatrix);
}
file.WriteLine("{0} {1} {2}", position.X, position.Y, position.Z);
}
file.WriteLine("{0} # meshes", model.Meshes.Count);
foreach (MeshDesc meshDesc in model.MeshDescs) {
file.WriteLine("{0}", meshDesc.name);
file.WriteLine("{0} # uv layers", meshDesc.uvLayerCount);
file.WriteLine("{0} # textures", meshDesc.textures.Length);
foreach (MeshDesc.Texture texture in meshDesc.textures) {
file.WriteLine("{0}", ExtractFilename(texture.filename));
file.WriteLine("{0} # uv layer index", texture.uvLayerIndex);
}
file.WriteLine("{0} # vertices", meshDesc.vertices.Length);
foreach (MeshDesc.Vertex vertex in meshDesc.vertices) {
Vector3 position;
Vector3 normal;
if (!applyPose) {
position = vertex.position * armature.WorldScale;
normal = vertex.normal;
}
else {
Utils.TransformVertex(vertex,
armature.WorldMatrix, armature.BoneMatrices, meshDesc.boneIndexMap,
out position, out normal);
}
file.WriteLine("{0} {1} {2}", position.X, position.Y, position.Z);
file.WriteLine("{0} {1} {2}", normal.X, normal.Y, normal.Z);
Color color = VertexColorToColor(vertex.color);
file.WriteLine("{0} {1} {2} {3}", color.R, color.G, color.B, color.A);
for (int uvLayerID = 0; uvLayerID < meshDesc.uvLayerCount; uvLayerID++) {
Vector2 uv = vertex.texCoords[uvLayerID];
file.WriteLine("{0} {1}", uv.X, uv.Y);
}
if (model.Armature.Bones.Length > 0) {
file.WriteLine("{0} {1} {2} {3}",
vertex.boneIndicesGlobal[0],
vertex.boneIndicesGlobal[1],
vertex.boneIndicesGlobal[2],
vertex.boneIndicesGlobal[3]);
file.WriteLine("{0} {1} {2} {3}",
vertex.boneWeights[0],
vertex.boneWeights[1],
vertex.boneWeights[2],
vertex.boneWeights[3]);
}
}
file.WriteLine("{0} # faces", meshDesc.indices.Length / 3);
for (int i = 0; i < meshDesc.indices.Length; i += 3) {
file.WriteLine("{0} {1} {2}",
meshDesc.indices[i + 0],
meshDesc.indices[i + 1],
meshDesc.indices[i + 2]);
}
}
file.Close();
}
private static Color VertexColorToColor(Vector4 color) {
byte r = (byte)Math.Min(Math.Round(color.X * 255), 255);
byte g = (byte)Math.Min(Math.Round(color.Y * 255), 255);
byte b = (byte)Math.Min(Math.Round(color.Z * 255), 255);
byte a = (byte)Math.Min(Math.Round(color.W * 255), 255);
return new Color(r, g, b, a);
}
private static string ExtractFilename(string path) {
int pos = path.LastIndexOfAny(new char[] { ':', '\\', '/' });
if (pos < 0) {
return path;
}
return path.Substring(pos + 1);
}
}
}