* 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
154 lines
6.3 KiB
C#
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;
|
|
}
|
|
}
|
|
}
|