private static void MeshesToFile(MeshFilter[] mf, string folder, string filename, WorldtoLocalParam param = null) { Dictionary <string, ObjMaterial> materialList = PrepareFileWrite(); using (StreamWriter sw = new StreamWriter(folder + "/" + filename + ".obj")) { sw.Write("mtllib ./" + filename + ".mtl\n"); for (int i = mf.Length - 1; i >= 0; i--) { sw.Write(MeshToString(mf[i], materialList, param)); } } MaterialsToFile(materialList, folder, filename); }
private static string MeshToString(MeshFilter mf, Dictionary <string, ObjMaterial> materialList, WorldtoLocalParam param = null) { Mesh m = mf.sharedMesh; Material[] mats = mf.GetComponent <Renderer>().sharedMaterials; StringBuilder sb = new StringBuilder(); sb.Append("g ").Append(mf.name).Append("\n"); foreach (Vector3 lv in m.vertices) { Vector3 vec = lv; //通过参数,可以还原原流星里的任意的 模型。 //if (param != null) //{ // vec = vec + param.vec; // vec = param.rotation * vec; //} //Vector3 wv = mf.transform.TransformPoint(lv); Vector3 wv = vec; //This is sort of ugly - inverting x-component since we're in //a different coordinate system than "everyone" is "used to". sb.Append(string.Format("v {0} {1} {2}\n", -wv.x, wv.y, wv.z)); } sb.Append("\n"); foreach (Vector3 lv in m.normals) { Vector3 wv = mf.transform.TransformDirection(lv); //Vector3 wv = lv; sb.Append(string.Format("vn {0} {1} {2}\n", -wv.x, wv.y, wv.z)); } sb.Append("\n"); foreach (Vector3 v in m.uv) { sb.Append(string.Format("vt {0} {1}\n", v.x, v.y)); } for (int material = 0; material < m.subMeshCount; material++) { sb.Append("\n"); //See if this material is already in the materiallist. try { if (material >= mats.Length) { continue; } if (mats[material] == null) { continue; } ObjMaterial objMaterial = new ObjMaterial(); if (mats[material].mainTexture) { //objMaterial.textureName = AssetDatabase.GetAssetPath(mats[material].mainTexture); } else { objMaterial.textureName = null; } string[] s = null; string ss = null; if (!string.IsNullOrEmpty(objMaterial.textureName)) { s = objMaterial.textureName.Split(new char[] { '/' }, System.StringSplitOptions.RemoveEmptyEntries); if (s != null && s.Length != 0) { ss = s[s.Length - 1]; } } objMaterial.name = mats[material].name + "_" + ss; if (!materialList.ContainsKey(objMaterial.name)) { materialList.Add(objMaterial.name, objMaterial); } sb.Append("usemtl ").Append(objMaterial.name).Append("\n"); sb.Append("usemap ").Append(objMaterial.name).Append("\n"); } catch (ArgumentException) { //Already in the dictionary } int[] triangles = m.GetTriangles(material); for (int i = 0; i < triangles.Length; i += 3) { //Because we inverted the x-component, we also needed to alter the triangle winding. sb.Append(string.Format("f {1}/{1}/{1} {0}/{0}/{0} {2}/{2}/{2}\n", triangles[i] + 1 + vertexOffset, triangles[i + 1] + 1 + normalOffset, triangles[i + 2] + 1 + uvOffset)); } } vertexOffset += m.vertices.Length; normalOffset += m.normals.Length; uvOffset += m.uv.Length; return(sb.ToString()); }