private void ConvertToObj(MeshData mesh, string filename = "object", params bool[] flags) { mesh = mesh.Clone(); try { Queue <float> uvsq = new Queue <float>(); for (int i = 0; i < mesh.Uv.Length; i++) { if (i + 4 > mesh.UvCount) { continue; } float[] transform = new float[] { mesh.Uv[i], mesh.Uv[++i], mesh.Uv[++i], mesh.Uv[++i] }; if (flags[0]) { Mat22.Scale(transform, transform, new float[] { capi.BlockTextureAtlas.Size.Width / 32, -(capi.BlockTextureAtlas.Size.Height / 32) }); Mat22X.Translate(transform, transform, new float[] { 0.0f, 1.0f }); } if (flags[1]) { Mat22.Scale(transform, transform, new float[] { 1.0f, -1.0f }); Mat22X.Translate(transform, transform, new float[] { 0.0f, 1.0f }); } for (int j = 0; j < transform.Length; j++) { uvsq.Enqueue(transform[j]); } } mesh.Translate(-0.5f, -0.5f, -0.5f); float[] uvs = uvsq.ToArray(); using (TextWriter tw = new StreamWriter(Path.Combine(GamePaths.Binaries, filename + ".obj"))) { tw.WriteLine("o " + filename); for (int i = 0; i < mesh.xyz.Length; i++) { if (i % 3 == 0) { if (i != 0) { tw.WriteLine(); } tw.Write("v " + mesh.xyz[i].ToString("F6")); } else { tw.Write(" " + mesh.xyz[i].ToString("F6")); } } tw.WriteLine(); for (int i = 0; i < uvs.Length; i++) { if (i % 2 == 0) { if (i != 0) { tw.WriteLine(); } tw.Write("vt " + uvs[i].ToString("F6")); } else { tw.Write(" " + uvs[i].ToString("F6")); } } tw.WriteLine(); for (int i = 0; i < mesh.Indices.Length; i++) { tw.WriteLine( "f " + (mesh.Indices[i] + 1) + "/" + (mesh.Indices[i] + 1) + " " + (mesh.Indices[++i] + 1) + "/" + (mesh.Indices[i] + 1) + " " + (mesh.Indices[++i] + 1) + "/" + (mesh.Indices[i] + 1)); } tw.Close(); } } catch (Exception) { } }
public virtual void ExportAsObj() { try { Mesh.Translate(-0.5f, -0.5f, -0.5f); float[] uvs = Mesh.Uv; using (TextWriter tw = new StreamWriter(FilePath)) { tw.Write("o " + FileName); for (int i = 0; i < Mesh.Uv.Length / 4; i++) { if (i + 4 > Mesh.UvCount) { continue; } float[] transform = new float[] { Mesh.Uv[i * 4 + 0], Mesh.Uv[i * 4 + 1], Mesh.Uv[i * 4 + 2], Mesh.Uv[i * 4 + 3] }; Mat22.Scale(transform, transform, new float[] { 1.0f, -1.0f }); Mat22X.Translate(transform, transform, new float[] { 0.0f, 1.0f }); Mesh.Uv[i * 4 + 0] = transform[0]; Mesh.Uv[i * 4 + 1] = transform[1]; Mesh.Uv[i * 4 + 2] = transform[2]; Mesh.Uv[i * 4 + 3] = transform[3]; } for (int i = 0; i < Mesh.VerticesCount; i++) { tw.WriteLine(); tw.Write(string.Format("v {0} {1} {2}", Mesh.xyz[i * 3 + 0].ToString("F6"), Mesh.xyz[i * 3 + 1].ToString("F6"), Mesh.xyz[i * 3 + 2].ToString("F6"))); } for (int i = 0; i < Mesh.FlagsCount; i++) { tw.WriteLine(); tw.Write(string.Format("vf {0}", Mesh.Flags[i].ToString())); } for (int i = 0; i < (Mesh.CustomBytes?.Count ?? 0); i++) { tw.WriteLine(); tw.Write(string.Format("cb {0}", Mesh.CustomBytes.Values[i].ToString())); } for (int i = 0; i < (Mesh.CustomFloats?.Count ?? 0); i++) { tw.WriteLine(); tw.Write(string.Format("cf {0}", Mesh.CustomFloats.Values[i].ToString("F6"))); } for (int i = 0; i < (Mesh.CustomInts?.Count ?? 0); i++) { tw.WriteLine(); tw.Write(string.Format("ci {0}", Mesh.CustomInts.Values[i].ToString())); } for (int i = 0; i < (Mesh.CustomShorts?.Count ?? 0); i++) { tw.WriteLine(); tw.Write(string.Format("cs {0}", Mesh.CustomShorts.Values[i].ToString())); } for (int i = 0; i < uvs.Length / 2; i++) { tw.WriteLine(); tw.Write(string.Format("vt {0} {1}", uvs[i * 2 + 0].ToString("F6"), uvs[i * 2 + 1].ToString("F6"))); } tw.WriteLine(); tw.Write("usemtl TextureAtlas"); for (int i = 0; i < Mesh.Indices.Length / 3; i++) { tw.WriteLine(); tw.Write(string.Format("f {0}/{0} {1}/{1} {2}/{2}", Mesh.Indices[i * 3 + 0] + 1, Mesh.Indices[i * 3 + 1] + 1, Mesh.Indices[i * 3 + 2] + 1)); } tw.Close(); } } catch (Exception) { } }