Files
libremetaverse/Programs/PrimWorkshop/meshtoobj.cs
John Hurliman 07754f7016 OpenMetaverse:
* LLObject is gone, it is now merged into Primitive
* Avatar inherits from Primitive
Simian:
* Added SimulationObject to track prims
* Added IMeshingProvider and a connector to OpenMetaverse.Rendering plugins

git-svn-id: http://libopenmetaverse.googlecode.com/svn/trunk@2161 52acb1d6-8a22-11de-b505-999d5b087335
2008-08-24 05:06:51 +00:00

154 lines
6.3 KiB
C#

using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using OpenMetaverse;
using OpenMetaverse.Rendering;
namespace PrimWorkshop
{
public static class MeshToOBJ
{
public static bool MeshesToOBJ(List<FacetedMesh> meshes, string filename)
{
StringBuilder obj = new StringBuilder();
StringBuilder mtl = new StringBuilder();
FileInfo objFileInfo = new FileInfo(filename);
string mtlFilename = objFileInfo.FullName.Substring(objFileInfo.DirectoryName.Length + 1,
objFileInfo.FullName.Length - (objFileInfo.DirectoryName.Length + 1) - 4) + ".mtl";
obj.AppendLine("# Created by libprimrender");
obj.AppendLine("mtllib ./" + mtlFilename);
obj.AppendLine();
mtl.AppendLine("# Created by libprimrender");
mtl.AppendLine();
for (int i = 0; i < meshes.Count; i++)
{
FacetedMesh mesh = meshes[i];
for (int j = 0; j < mesh.Faces.Count; j++)
{
Face face = mesh.Faces[j];
if (face.Vertices.Count > 2)
{
string mtlName = String.Format("material{0}-{1}", i, face.ID);
Primitive.TextureEntryFace tex = face.TextureFace;
string texName = tex.TextureID.ToString() + ".tga";
// FIXME: Convert the source to TGA (if needed) and copy to the destination
float shiny = 0.00f;
switch (tex.Shiny)
{
case Shininess.High:
shiny = 1.00f;
break;
case Shininess.Medium:
shiny = 0.66f;
break;
case Shininess.Low:
shiny = 0.33f;
break;
}
obj.AppendFormat("g face{0}-{1}{2}", i, face.ID, Environment.NewLine);
mtl.AppendLine("newmtl " + mtlName);
mtl.AppendFormat("Ka {0} {1} {2}{3}", tex.RGBA.R, tex.RGBA.G, tex.RGBA.B, Environment.NewLine);
mtl.AppendFormat("Kd {0} {1} {2}{3}", tex.RGBA.R, tex.RGBA.G, tex.RGBA.B, Environment.NewLine);
//mtl.AppendFormat("Ks {0} {1} {2}{3}");
mtl.AppendLine("Tr " + tex.RGBA.A);
mtl.AppendLine("Ns " + shiny);
mtl.AppendLine("illum 1");
if (tex.TextureID != UUID.Zero && tex.TextureID != Primitive.TextureEntry.WHITE_TEXTURE)
mtl.AppendLine("map_Kd ./" + texName);
mtl.AppendLine();
// Write the vertices, texture coordinates, and vertex normals for this side
for (int k = 0; k < face.Vertices.Count; k++)
{
Vertex vertex = face.Vertices[k];
#region Vertex
Vector3 pos = vertex.Position;
// Apply scaling
pos *= mesh.Prim.Scale;
// Apply rotation
pos *= mesh.Prim.Rotation;
// The root prim position is sim-relative, while child prim positions are
// parent-relative. We want to apply parent-relative translations but not
// sim-relative ones
if (mesh.Prim.ParentID != 0)
pos += mesh.Prim.Position;
obj.AppendFormat("v {0} {1} {2}{3}", pos.X, pos.Y, pos.Z, Environment.NewLine);
#endregion Vertex
#region Texture Coord
obj.AppendFormat("vt {0} {1}{2}", vertex.TexCoord.X, vertex.TexCoord.Y,
Environment.NewLine);
#endregion Texture Coord
#region Vertex Normal
// HACK: Sometimes normals are getting set to <NaN,NaN,NaN>
if (!Single.IsNaN(vertex.Normal.X) && !Single.IsNaN(vertex.Normal.Y) && !Single.IsNaN(vertex.Normal.Z))
obj.AppendFormat("vn {0} {1} {2}{3}", vertex.Normal.X, vertex.Normal.Y, vertex.Normal.Z,
Environment.NewLine);
else
obj.AppendLine("vn 0.0 1.0 0.0");
#endregion Vertex Normal
}
obj.AppendFormat("# {0} vertices{1}", face.Vertices.Count, Environment.NewLine);
obj.AppendLine();
obj.AppendLine("usemtl " + mtlName);
#region Elements
// Write all of the faces (triangles) for this side
for (int k = 0; k < face.Indices.Count / 3; k++)
{
obj.AppendFormat("f -{0}/-{0}/-{0} -{1}/-{1}/-{1} -{2}/-{2}/-{2}{3}",
face.Vertices.Count - face.Indices[k * 3 + 0],
face.Vertices.Count - face.Indices[k * 3 + 1],
face.Vertices.Count - face.Indices[k * 3 + 2],
Environment.NewLine);
}
obj.AppendFormat("# {0} elements{1}", face.Indices.Count / 3, Environment.NewLine);
obj.AppendLine();
#endregion Elements
}
}
}
try
{
File.WriteAllText(filename, obj.ToString());
File.WriteAllText(mtlFilename, mtl.ToString());
}
catch (Exception)
{
return false;
}
return true;
}
}
}