记录下,使用C#将obj模型转换为collada格式
完整代码如下
1、这个脚本定义了部分使用到的结构
using System;
using System.Collections.Generic;
namespace ModelProcess
{
class MathUtils
{
public class Vector3
{
public float x, y, z;
public Vector3() { }
public Vector3(float x, float y, float z)
{
this.x = x;
this.y = y;
this.z = z;
}
public static Vector3 Min
{
get
{
return new Vector3(float.MinValue, float.MinValue, float.MinValue);
}
}
public static Vector3 Max
{
get
{
return new Vector3(float.MaxValue, float.MaxValue, float.MaxValue);
}
}
public static Vector3 operator +(Vector3 a, Vector3 b)
{
return new Vector3(a.x + b.x, a.y + b.y, a.z + b.z);
}
public static Vector3 operator -(Vector3 a, Vector3 b)
{
return new Vector3(a.x - b.x, a.y - b.y, a.z - b.z);
}
public static Vector3 operator *(Vector3 v, float a)
{
return new Vector3(v.x * a, v.y * a, v.z * a);
}
public static Vector3 operator /(Vector3 v, float a)
{
if (a == 0) throw new Exception("除数不能为0!");
return new Vector3(v.x / a, v.y / a, v.z / a);
}
/// <summary>
/// 获取向量长度
/// </summary>
/// <returns></returns>
public float Length()
{
return (float)Math.Sqrt(x * x + y * y + z * z);
}
/// <summary>
/// 向量单位化
/// </summary>
/// <returns></returns>
public Vector3 Normalize()
{
float length = Length();
if (length == 0) return new Vector3(x, y, z);
return new Vector3(x / length, y / length, z / length);
}
/// <summary>
/// 获取两个向量中的更小元素,用于获取包围盒
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <returns></returns>
public static Vector3 GetMaxComponent(Vector3 a, Vector3 b)
{
return new Vector3(Math.Max(a.x, b.x), Math.Max(a.y, b.y), Math.Max(a.z, b.z));
}
/// <summary>
/// 获取两个向量中的更大元素,用于获取包围盒
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <returns></returns>
public static Vector3 GetMinComponent(Vector3 a, Vector3 b)
{
return new Vector3(Math.Min(a.x, b.x), Math.Min(a.y, b.y), Math.Min(a.z, b.z));
}
/// <summary>
/// 向量叉乘
/// </summary>
/// <param name="a"></param>
/// <param name="b"></param>
/// <returns></returns>
public static Vector3 Cross(Vector3 a, Vector3 b)
{
if (Equals(Dot(a, b), 1.0)) return new Vector3(0, 0, 0);
Vector3 res = new Vector3
{
x = a.y * b.z - a.z * b.y,
y = a.z * b.x - a.x * b.z,
z = a.x * b.y - a.y * b.x
};
return res;
}
public static float Dot(Vector3 a, Vector3 b)
{
return a.x * b.x + a.y * b.y + a.z * b.z;
}
public override string ToString()
{
return "x : " + x + " y : " + y + " z : " + z;
}
}
public class Vector2
{
public float x, y;
public Vector2() { }
public Vector2(float x,float y)
{
this.x = x;
this.y = y;
}
}
public class Triangle
{
// vertex
public int a;
public int b;
public int c;
// normal
public int an;
public int bn;
public int cn;
// uv
public int au;
public int bu;
public int cu;
public bool hasNormal;
public bool hasUv;
}
public class Group
{
public string groupName;
public string mtlName;
public List<Triangle> triangles;
}
public class ColladaMaterial
{
public Vector3 diffuse;
public Vector3 emissive;
public string diffuseMap;
public ColladaMaterial()
{
diffuse = new Vector3(1, 1, 1);
emissive = new Vector3(0, 0, 0);
diffuseMap = "";
}
}
}
}
2、这个脚本定义了将obj转换为collada的函数,调用方式为ExportColladaFromObj. Export(objPath,outputPath),记得引入命名空间
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Xml;
using static ModelProcess.MathUtils;
namespace ModelProcess
{
class ExportColladaFromObj
{
/// <summary>
/// 将obj模型转换为collada格式
/// </summary>
/// <param name="objPath">完整的obj路径</param>
/// <param name="outputPath">完整的collada路径,带后缀.dae</param>
public static void Export(string objPath, string outputPath)
{
List<Vector3> vertices = new List<Vector3>();
List<Vector3> normals = new List<Vector3>();
List<Vector2> uvs = new List<Vector2>();
List<Group> groups = new List<Group>();
Dictionary<string, ColladaMaterial> materials = new Dictionary<string, ColladaMaterial>();
GetObjInfo(objPath, ref vertices, ref normals, ref uvs, ref groups);
GetMtlInfo(objPath, ref materials);
FileStream fs = new FileStream(outputPath, FileMode.Create, FileAccess.Write);
StreamWriter sw = new StreamWriter(fs);
sw.WriteLine("<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"no\"?>");
sw.WriteLine("<COLLADA xmlns=\"http://www.collada.org/2005/11/COLLADASchema\" version=\"1.4.1\">");
// asset
WriteAsset(sw);
List<string> mapName = WriteImage(sw, materials);
CopyTexture(mapName, Path.GetDirectoryName(objPath), Path.GetDirectoryName(outputPath));
WriteEffects(sw, materials);
WriteMaterials(sw, materials);
WriteGeometry(sw, vertices, normals, uvs, groups);
WriteVisualScene(sw, groups, Path.GetFileNameWithoutExtension(objPath));
WriteScene(sw);
sw.WriteLine("</COLLADA>");
sw.Close();
fs.Close();
}
static void CopyTexture(List<string> mapName,string inputPath,string outputPath)
{
for(int i = 0; i < mapName.Count; i++)
{
Console.WriteLine(mapName[i]);
File.Copy(Path.Combine(inputPath, mapName[i]), Path.Combine(outputPath, mapName[i]), true);
}
}
static void WriteAsset(StreamWriter sw)
{
sw.WriteLine("\t<asset>"); // start asset
sw.WriteLine("\t\t<contributor>"); // start contributor
sw.WriteLine("\t\t\t<authoring_tool>export collada from obj</authoring_tool>"); // authoring_tool
sw.WriteLine("\t\t</contributor>"); // end contributor
DateTime date = DateTime.Now;
sw.WriteLine("\t\t<created>" + date.ToString() + "</created>"); // created
sw.WriteLine("\t\t<modified>" + date.ToString() + "</modified>"); // modified
sw.WriteLine("\t\t<unit name=\"meter\" meter=\"1\"/>"); //start unit
sw.WriteLine("\t\t<up_axis>Y_UP</up_axis>"); // up_axis
sw.WriteLine("\t</asset>");// end asset
}
static List<string> WriteImage(StreamWriter sw, Dictionary<string, ColladaMaterial> materials)
{
sw.WriteLine("\t<library_images>"); // start library_images
List<string> mapName = new List<string>();
foreach (ColladaMaterial mat in materials.Values)
{
if (!string.IsNullOrEmpty(mat.diffuseMap))
{
if (!mapName.Contains(mat.diffuseMap))
{
sw.WriteLine("\t\t<image id=\"" + mat.diffuseMap + "\" name=\"" + mat.diffuseMap + "\">"); // start image
sw.WriteLine("\t\t\t<init_from>" + mat.diffuseMap + "</init_from>"); // start image
sw.WriteLine("\t\t</image>");
mapName.Add(mat.diffuseMap);
}
}
}
sw.WriteLine("\t</library_images>"); // end library_images
return mapName;
}
static void WriteEffects(StreamWriter sw, Dictionary<string, ColladaMaterial> materials)
{
sw.WriteLine("\t<library_effects>"); // start library_effects
foreach (string matName in materials.Keys)
{
sw.WriteLine("\t\t<effect id=\"" + matName + "-effect\">"); // start effect
sw.WriteLine("\t\t\t<profile_COMMON>"); // start profile_COMMON
// map
if (!string.IsNullOrEmpty(materials[matName].diffuseMap))
{
sw.WriteLine("\t\t\t\t<newparam sid=\"diffuse-surface\">"); // start newparam
sw.WriteLine("\t\t\t\t\t<surface type=\"2D\">"); // start surface
sw.WriteLine("\t\t\t\t\t\t<init_from>" + materials[matName].diffuseMap + "</init_from>");
sw.WriteLine("\t\t\t\t\t</surface>"); // end surface
sw.WriteLine("\t\t\t\t</newparam>"); // end newparam
sw.WriteLine("\t\t\t\t<newparam sid=\"diffuse-sampler\">"); // start newparam
sw.WriteLine("\t\t\t\t\t<sampler2D>"); // start sampler2D
sw.WriteLine("\t\t\t\t\t\t<source>diffuse-surface</source>");
sw.WriteLine("\t\t\t\t\t</sampler2D>"); // end sampler2D
sw.WriteLine("\t\t\t\t</newparam>"); // end newparam
}
sw.WriteLine("\t\t\t\t<technique sid=\"" + matName + "\">"); // start technique
sw.WriteLine("\t\t\t\t\t<lambert>"); // start lambert
//emission
sw.WriteLine("\t\t\t\t\t\t<emission>"); // start emission
sw.WriteLine("\t\t\t\t\t\t\t<color sid=\"emission\">" + materials[matName].emissive.x + " " + materials[matName].emissive.y + " " + materials[matName].emissive.z + " " + 1 + "</color>");
sw.WriteLine("\t\t\t\t\t\t</emission>"); // end emission
//diffuse
sw.WriteLine("\t\t\t\t\t\t<diffuse>"); // start diffuse
if (string.IsNullOrEmpty(materials[matName].diffuseMap))
{
sw.WriteLine("\t\t\t\t\t\t\t<color sid=\"diffuse\">" + materials[matName].diffuse.x + " " + materials[matName].diffuse.y + " " + materials[matName].diffuse.z + " " + 1 + "</color>");
}
else
{
sw.WriteLine("\t\t\t\t\t\t\t<texture texture=\"diffuse-sampler\" texcoord=\"TEXCOORD\" />");
}
//myXmlTextWriter.WriteAttributeString("sid", "diffuse");
sw.WriteLine("\t\t\t\t\t\t</diffuse>"); // end diffuse
//reflective
sw.WriteLine("\t\t\t\t\t\t<reflective>"); // start reflective
sw.WriteLine("\t\t\t\t\t\t\t<color>" + materials[matName].diffuse.x + " " + materials[matName].diffuse.y + " " + materials[matName].diffuse.z + " " + 1 + "</color>");
//myXmlTextWriter.WriteAttributeString("sid", "reflective");
sw.WriteLine("\t\t\t\t\t\t</reflective>"); // end reflective
sw.WriteLine("\t\t\t\t\t</lambert>"); // end lambert
sw.WriteLine("\t\t\t\t</technique>"); // end technique
sw.WriteLine("\t\t\t</profile_COMMON>"); // end profile_COMMON
sw.WriteLine("\t\t</effect>"); // end effect
}
sw.WriteLine("\t</library_effects>"); // end library_effects
}
static void WriteMaterials(StreamWriter sw, Dictionary<string, ColladaMaterial> materials)
{
sw.WriteLine("\t<library_materials>"); // start library_materials
foreach (string mtlName in materials.Keys)
{
sw.WriteLine("\t\t<material id=\"" + mtlName + "\">"); // start material
sw.WriteLine("\t\t\t<instance_effect url=\"#" + mtlName + "-effect\" />");
sw.WriteLine("\t\t</material>"); // end material
}
sw.WriteLine("\t</library_materials>"); // end library_materials
}
static void WriteGeometry(StreamWriter sw, List<Vector3> vertices, List<Vector3> normals, List<Vector2> uvs, List<Group> groups)
{
sw.WriteLine("\t<library_geometries>"); //start library_geometries
int count = 0;
foreach (Group group in groups)
{
sw.WriteLine("\t\t<geometry id=\"" + group.groupName + "\">");//start geometry
sw.WriteLine("\t\t\t<mesh>");//start mesh
//vertices
sw.WriteLine("\t\t\t\t<source id=\"" + group.groupName + "-position\">");//start source
sw.Write("\t\t\t\t\t<float_array id=\"" + group.groupName + "-position-array\" count=\"" + group.triangles.Count * 9 + "\">");
for (int i = 0; i < group.triangles.Count; i++)
{
sw.Write(vertices[group.triangles[i].a].x + " ");
sw.Write(vertices[group.triangles[i].a].y + " ");
sw.Write(vertices[group.triangles[i].a].z + " ");
sw.Write(vertices[group.triangles[i].b].x + " ");
sw.Write(vertices[group.triangles[i].b].y + " ");
sw.Write(vertices[group.triangles[i].b].z + " ");
sw.Write(vertices[group.triangles[i].c].x + " ");
sw.Write(vertices[group.triangles[i].c].y + " ");
sw.Write(vertices[group.triangles[i].c].z);
if (i != group.triangles.Count - 1) sw.Write(" ");
}
sw.Write("</float_array>\n");
sw.WriteLine("\t\t\t\t\t<technique_common>");//start technique_common
sw.WriteLine("\t\t\t\t\t\t<accessor source=\"#" + group.groupName + "-position-array\" count=\"" + group.triangles.Count * 3 + "\" stride=\"3\">");//start accessor
sw.WriteLine("\t\t\t\t\t\t\t<param name=\"X\" type=\"float\" />");
sw.WriteLine("\t\t\t\t\t\t\t<param name=\"Y\" type=\"float\" />");
sw.WriteLine("\t\t\t\t\t\t\t<param name=\"Z\" type=\"float\" />");
sw.WriteLine("\t\t\t\t\t\t</accessor>");//end accessor
sw.WriteLine("\t\t\t\t\t</technique_common>");// end technique_common
sw.WriteLine("\t\t\t\t</source>"); // end source
sw.WriteLine("\t\t\t\t<vertices id=\"" + group.groupName + "-vertices\">"); //start vertices
sw.WriteLine("\t\t\t\t\t<input semantic=\"POSITION\" source=\"#" + group.groupName + "-position\" />");
sw.WriteLine("\t\t\t\t</vertices>"); // end vertices
//normal
if (normals.Count > 0)
{
sw.WriteLine("\t\t\t\t<source id=\"" + group.groupName + "-normal\">");//start source
sw.Write("\t\t\t\t\t<float_array id=\"" + group.groupName + "-normal-array\" count=\"" + group.triangles.Count * 9 + "\">");
for (int i = 0; i < group.triangles.Count; i++)
{
sw.Write(normals[group.triangles[i].an].x + " ");
sw.Write(normals[group.triangles[i].an].y + " ");
sw.Write(normals[group.triangles[i].an].z + " ");
sw.Write(normals[group.triangles[i].bn].x + " ");
sw.Write(normals[group.triangles[i].bn].y + " ");
sw.Write(normals[group.triangles[i].bn].z + " ");
sw.Write(normals[group.triangles[i].cn].x + " ");
sw.Write(normals[group.triangles[i].cn].y + " ");
sw.Write(normals[group.triangles[i].cn].z);
if (i != group.triangles.Count - 1) sw.Write(" ");
}
sw.Write("</float_array>\n");
sw.WriteLine("\t\t\t\t\t<technique_common>");//start technique_common
sw.WriteLine("\t\t\t\t\t\t<accessor source=\"#" + group.groupName + "-normal-array\" count=\"" + group.triangles.Count * 3 + "\" stride=\"3\">");//start accessor
sw.WriteLine("\t\t\t\t\t\t\t<param name=\"X\" type=\"float\" />");
sw.WriteLine("\t\t\t\t\t\t\t<param name=\"Y\" type=\"float\" />");
sw.WriteLine("\t\t\t\t\t\t\t<param name=\"Z\" type=\"float\" />");
sw.WriteLine("\t\t\t\t\t\t</accessor>");//end accessor
sw.WriteLine("\t\t\t\t\t</technique_common>");// end technique_common
sw.WriteLine("\t\t\t\t</source>"); // end source
}
//uvs
if (uvs.Count > 0)
{
sw.WriteLine("\t\t\t\t<source id=\"" + group.groupName + "-texcoord\">");//start source
sw.Write("\t\t\t\t\t<float_array id=\"" + group.groupName + "-texcoord-array\" count=\"" + group.triangles.Count * 6 + "\">");
for (int i = 0; i < group.triangles.Count; i++)
{
sw.Write(uvs[group.triangles[i].au].x + " ");
sw.Write(uvs[group.triangles[i].au].y + " ");
sw.Write(uvs[group.triangles[i].bu].x + " ");
sw.Write(uvs[group.triangles[i].bu].y + " ");
sw.Write(uvs[group.triangles[i].cu].x + " ");
sw.Write(uvs[group.triangles[i].cu].y);
if (i != group.triangles.Count - 1) sw.Write(" ");
}
sw.Write("</float_array>\n");
sw.WriteLine("\t\t\t\t\t<technique_common>");//start technique_common
sw.WriteLine("\t\t\t\t\t\t<accessor source=\"#" + group.groupName + "-texcoord-array\" count=\"" + group.triangles.Count * 3 + "\" stride=\"2\">");//start accessor
sw.WriteLine("\t\t\t\t\t\t\t<param name=\"S\" type=\"float\" />");
sw.WriteLine("\t\t\t\t\t\t\t<param name=\"T\" type=\"float\" />");
sw.WriteLine("\t\t\t\t\t\t</accessor>");//end accessor
sw.WriteLine("\t\t\t\t\t</technique_common>");// end technique_common
sw.WriteLine("\t\t\t\t</source>"); // end source
}
// triangle
sw.WriteLine("\t\t\t\t<triangles material=\"" + group.mtlName + "\" count=\"" + group.triangles.Count + "\">"); // start triangles
sw.WriteLine("\t\t\t\t\t<input semantic=\"VERTEX\" source=\"#" + group.groupName + "-vertices\" offset =\"0\" />");
if (normals.Count > 0)
{
sw.WriteLine("\t\t\t\t\t<input semantic=\"NORMAL\" source=\"#" + group.groupName + "-normal\" offset =\"0\" />");
}
if (uvs.Count > 0)
{
sw.WriteLine("\t\t\t\t\t<input semantic=\"TEXCOORD\" source=\"#" + group.groupName + "-texcoord\" offset =\"0\" set=\"" + count + "\" />");
}
sw.Write("\t\t\t\t\t<p>");
for (int i = 0; i < group.triangles.Count; i++)
{
sw.Write(i * 3 + " " + (i * 3 + 1) + " " + (i * 3 + 2));
if (i != group.triangles.Count - 1)
{
sw.Write(" ");
}
}
sw.Write("</p>\n");
sw.WriteLine("\t\t\t\t</triangles>");//end triangles
sw.WriteLine("\t\t\t</mesh>"); // end mesh
sw.WriteLine("\t\t</geometry>"); // end geometry
count++;
}
sw.WriteLine("\t</library_geometries>"); // end library_geometries
}
static void WriteVisualScene(StreamWriter sw, List<Group> groups, string objName)
{
sw.WriteLine("\t<library_visual_scenes>"); // start library_visual_scenes
sw.WriteLine("\t\t<visual_scene id=\"Scene\" name=\"" + objName + "\">"); //start visual_scene
int count = 0;
foreach (Group group in groups)
{
sw.WriteLine("\t\t\t<node name=\"" + group.groupName + "\">");// start node
sw.WriteLine("\t\t\t\t<matrix>1 0 0 0 0 1 0 0 0 0 1 0 0 0 0 1</matrix>");
sw.WriteLine("\t\t\t\t<instance_geometry url=\"#" + group.groupName + "\">");// start instance_geometry
sw.WriteLine("\t\t\t\t\t<bind_material>");// start bind_material
sw.WriteLine("\t\t\t\t\t\t<technique_common>"); // start technique_common
sw.WriteLine("\t\t\t\t\t\t\t<instance_material symbol=\"" + group.mtlName + "\" target=\"#" + group.mtlName + "\" >");//start instance_material
sw.WriteLine("\t\t\t\t\t\t\t\t<bind_vertex_input semantic=\"TEXCOORD\" input_semantic=\"TEXCOORD\" input_set=\"" + count + "\" />");
sw.WriteLine("\t\t\t\t\t\t\t</instance_material>");//end instance_material
sw.WriteLine("\t\t\t\t\t\t</technique_common>"); // end technique_common
sw.WriteLine("\t\t\t\t\t</bind_material>");// end bind_material
sw.WriteLine("\t\t\t\t</instance_geometry>");// end instance_geometry
sw.WriteLine("\t\t\t</node>");// end node
count++;
}
sw.WriteLine("\t\t</visual_scene>"); //end visual_scene
sw.WriteLine("\t</library_visual_scenes>"); // end library_visual_scenes
}
static void WriteScene(StreamWriter sw)
{
sw.WriteLine("\t<scene>");
sw.WriteLine("\t\t<instance_visual_scene url=\"#Scene\"/>");
sw.WriteLine("\t</scene>");
}
static void GetObjInfo(string objPath, ref List<Vector3> vertices, ref List<Vector3> normals, ref List<Vector2> uvs, ref List<Group> groups)
{
FileStream fs = new FileStream(objPath, FileMode.Open, FileAccess.Read);
StreamReader sr = new StreamReader(fs);
Group currenGroup = null;
string line = "";
while (!sr.EndOfStream)
{
line = Utils.GetStrFields(sr.ReadLine()).Trim();
if (line.StartsWith("v "))
{
string[] strs = line.Split(' ');
if (strs.Length >= 4)
{
vertices.Add(new Vector3(float.Parse(strs[1]), float.Parse(strs[2]), float.Parse(strs[3])));
}
}
else if (line.StartsWith("vn "))
{
string[] strs = line.Split(' ');
if (strs.Length >= 4)
{
normals.Add(new Vector3(float.Parse(strs[1]), float.Parse(strs[2]), float.Parse(strs[3])));
}
}
else if (line.StartsWith("vt "))
{
string[] strs = line.Split(' ');
if (strs.Length >= 3)
{
uvs.Add(new Vector2(float.Parse(strs[1]), float.Parse(strs[2])));
}
}
}
fs.Seek(0, SeekOrigin.Begin);
string currenGroupName = "";
string currenMtlName = "";
int avi, ani, aui, bvi, bni, bui, cvi, cni, cui;
while (!sr.EndOfStream)
{
line = Utils.GetStrFields(sr.ReadLine()).Trim();
if (line.StartsWith("g "))
{
if (line.Length <= 2) currenGroupName = Utils.GetTimestamp();
else currenGroupName = Utils.ReplaceAll(line.Substring(2), " ", "_");
currenGroup = null;
//Console.WriteLine(currenGroupName);
}
else if (line.StartsWith("usemtl "))
{
currenMtlName = Utils.ReplaceAll(line.Substring(7), " ", "_");
//Console.WriteLine(currenMtlName);
}
else if (line.StartsWith("f "))
{
if (currenGroup == null)
{
currenGroup = new Group
{
groupName = currenGroupName,
mtlName = currenMtlName,
triangles = new List<Triangle>()
};
groups.Add(currenGroup);
}
string[] strs = line.Split(' ');
string[] first = strs[1].Split('/');
avi = int.Parse(first[0]);
if (avi < 0) avi += vertices.Count;
else avi -= 1;
ani = 0;
aui = 0;
if (first.Length >= 2 && !string.IsNullOrEmpty(first[1]))
{
aui = int.Parse(first[1]);
}
if (first.Length >= 3 && !string.IsNullOrEmpty(first[2]))
{
ani = int.Parse(first[2]);
}
for (int k = 2; k < strs.Length - 1; k++)
{
string[] second = strs[k].Split('/');
string[] third = strs[k + 1].Split('/');
bvi = int.Parse(second[0]);
if (bvi < 0) bvi += vertices.Count;
else bvi -= 1;
cvi = int.Parse(third[0]);
if (cvi < 0) cvi += vertices.Count;
else cvi -= 1;
Triangle t = new Triangle()
{
a = avi,
b = bvi,
c = cvi
};
currenGroup.triangles.Add(t);
if (aui != 0)
{
if (aui < 0) aui += uvs.Count;
else aui -= 1;
bui = int.Parse(second[1]);
if (bui < 0) bui += uvs.Count;
else bui -= 1;
cui = int.Parse(third[1]);
if (cui < 0) cui += uvs.Count;
else cui -= 1;
t.au = aui;
t.bu = bui;
t.cu = cui;
t.hasUv = true;
}
if (ani != 0)
{
if (ani < 0) ani += normals.Count;
else ani -= 1;
bni = int.Parse(second[2]);
if (bni < 0) bni += normals.Count;
else bni -= 1;
cni = int.Parse(third[2]);
if (cni < 0) cni += normals.Count;
else cni -= 1;
t.an = ani;
t.bn = bni;
t.cn = cni;
t.hasNormal = true;
}
}
}
}
sr.Close();
fs.Close();
}
static void GetMtlInfo(string objPath, ref Dictionary<string, ColladaMaterial> materials)
{
string mtlPath = Utils.GetFirstModelPath(Path.GetDirectoryName(objPath), new string[] { ".mtl" });
if (!string.IsNullOrEmpty(mtlPath))
{
FileStream fs = new FileStream(mtlPath, FileMode.Open, FileAccess.Read);
StreamReader sr = new StreamReader(fs);
string line = "";
ColladaMaterial mat = null;
while (!sr.EndOfStream)
{
line = Utils.GetStrFields(sr.ReadLine()).Trim();
if (line.StartsWith("newmtl "))
{
string name = Utils.ReplaceAll(line.Substring(7), " ", "_");
mat = new ColladaMaterial();
if (!materials.ContainsKey(name))
materials.Add(name, mat);
}
else if (line.StartsWith("Kd "))
{
string[] strs = line.Split(' ');
if (strs.Length >= 4)
{
mat.diffuse = new Vector3(float.Parse(strs[1]), float.Parse(strs[2]), float.Parse(strs[3]));
}
}
else if (line.StartsWith("Ke "))
{
string[] strs = line.Split(' ');
if (strs.Length >= 4)
{
mat.emissive = new Vector3(float.Parse(strs[1]), float.Parse(strs[2]), float.Parse(strs[3]));
}
}
else if (line.StartsWith("map_Kd "))
{
mat.diffuseMap = line.Substring(7);
}
}
sr.Close();
fs.Close();
}
}
}
}