public static void ToFile(string file, ModelFile data) { using(var s= File.OpenWrite(file)) using(var w= new BinaryWriter(s)) { System.Diagnostics.Debug.Assert(data.NumBones == data.Bones.Count); System.Diagnostics.Debug.Assert(data.NumMaterials == data.Materials.Count); System.Diagnostics.Debug.Assert(data.Mesh.NumPrims == data.Mesh.Primitives.Count); System.Diagnostics.Debug.Assert(data.Mesh.NumRefBones == data.Mesh.RefBones.Count); System.Diagnostics.Debug.Assert(data.Mesh.NumTangents == 0); System.Diagnostics.Debug.Assert(data.Mesh.NumVerts == data.Mesh.Vertices.Count); foreach(var i in data.Mesh.Primitives) System.Diagnostics.Debug.Assert(i.NumIndices == i.Indices.Count); WriteString(w, data.Magic); w.Write(data.Version); Write(w, WriteString, data.Descriptions); w.Write(data.NumBones); Write(w, WriteBone, data.Bones); Write(w, w.Write, data.Bones.Select(i => i.ParentID)); Write(w, (v) => Write(w, w.Write, v), data.Bones.Select(i => i.Params)); WriteMesh(w, data.Mesh); w.Write(data.NumMaterials); Write(w, WriteMaterial, data.Materials); WriteParamList(w, data.Params); w.Flush(); s.SetLength(s.Position); } }
public override void Export(string filename, ModelFile model) { var mtlfile = Path.ChangeExtension(filename, ".mtl"); ExportMTL(mtlfile, model); ExportOBJ(filename, model); }
public static ModelFile FromFile(string file) { var data= new ModelFile() { FileName= file }; using(var s= File.OpenRead(file)) using(var r = new BinaryReader(s)) { data.Magic = ReadString(r); data.Version = r.ReadInt32(); data.Descriptions= ReadList(r, 2, ReadString); data.NumBones = r.ReadInt32(); data.Bones = ReadList(r, data.NumBones, ReadBone); foreach(var i in data.Bones) i.ParentID = r.ReadInt32(); foreach(var i in data.Bones) i.Params = ReadSingleArray(r, 7); data.Mesh = ReadMesh(r); data.NumMaterials= r.ReadInt32(); //System.Diagnostics.Debug.Assert(data.NumMaterials == 1); data.Materials = ReadList(r, data.NumMaterials, ReadMaterial); data.Params = ReadParamList(r); } return data; }
public override void Export(string filename, ModelFile model) { FileName = filename; Directory = Path.GetDirectoryName(filename); CreateRoot(model); // DAE作成 var xws = new XmlWriterSettings() { Indent = true, IndentChars = "\t", NewLineChars = Environment.NewLine, CloseOutput = true, NewLineHandling = NewLineHandling.None, }; using(var w= XmlWriter.Create(filename, xws)) { var settings = new DaeIMExportSettings() { BoneRefType= RefType.SID }; var dae = new DaeIMWriter(w) { Settings= settings }; dae.Write(Root); } }
protected void ChangeShader(ModelFile model) { if(Settings.ChangeShader && Settings.Shader.Length > 0) { foreach(var i in model.Materials) { i.Descriptions[1] = "CM3D2/" + Settings.Shader; i.Descriptions[2] = "CM3D2__" + Settings.Shader; } } }
private void ExportMTL(string filename, ModelFile model) { var dir = Path.GetDirectoryName(filename); using(var w = new StreamWriter(filename, false, Encoding.Default)) { foreach(var i in model.Materials) { var maintex = GetTexFile(i.GetAs<ParamTex>("_MainTex")); var col = i.GetAs<ParamCol>("_Color"); var shine = i.GetAs<ParamF>("_Shininess"); if(null == col) col = new ParamCol() { R= 1, G= 1, B= 1 }; w.WriteLine("newmtl {0}", i.Descriptions[0]); w.WriteLine(" Ns {0:F8}", 10.0000f); w.WriteLine(" Ni {0:F8}", 1.5000f); w.WriteLine(" d {0:F8}", 1.0000f); w.WriteLine(" Tr {0:F8}", 0.0000f); w.WriteLine(" Tf {0:F8} {1:F8} {2:F8}", 1.0000f, 1.0000f, 1.0000f); w.WriteLine(" illum {0}", 2); w.WriteLine(" Ka {0:F8} {1:F8} {2:F8}", col.R, col.G, col.B); w.WriteLine(" Kd {0:F8} {1:F8} {2:F8}", 0.50f, 0.50f, 0.50f); w.WriteLine(" Ks {0:F8} {1:F8} {2:F8}", 0.00f, 0.00f, 0.00f); w.WriteLine(" Ke {0:F8} {1:F8} {2:F8}", 0.00f, 0.00f, 0.00f); if(null != maintex) { var texname = Path.GetFileName(maintex.AssetPath); maintex.GetImage().Save(Path.Combine(dir, texname)); //w.WriteLine(" map_Ka {0}", texname); //w.WriteLine(" map_Kd {0}", texname); w.WriteLine(" map_Ka {0}", Path.Combine(dir, texname)); w.WriteLine(" map_Kd {0}", Path.Combine(dir, texname)); } } } }
public override void Import(string filename, ModelFile model) { var obj = ObjFile.FromFile(filename); obj.Dump(); var mgen = new ModelGenerator(); var g = obj.Groups.FirstOrDefault(i => i.Name == "base"); var p = obj.Positions; var n = obj.Normals; var t = obj.TexCoords; foreach(var i in g.Meshes) { mgen.BeginPrimitive(); for(int j= 0; j < i.FaceCount; ++j) { var fp = i.PositionFaces[j]; var fn = i.NormalFaces[j]; var ft = i.TexCoordFaces[j]; mgen.AddVertex(p[fp.A], n[fn.A], t[ft.A]); mgen.AddVertex(p[fp.B], n[fn.B], t[ft.B]); mgen.AddVertex(p[fp.C], n[fn.C], t[ft.C]); } mgen.EndPrimitive(); } mgen.MorphMin= Settings.MorphMin; mgen.MorphMax= Settings.MorphMax; mgen.ReplaceModel(model, Settings.RefModel); // shader ChangeShader(model); }
public override void Export(string filename, ModelFile model) { var dir = Path.GetDirectoryName(filename); var index = filename.IndexOf("\\model\\"); var basedir = filename.Substring(0, index); var texdir = Path.Combine(basedir, "texture"); texdir = texdir.Replace("model_", "texture_"); using(var w = new StreamWriter(filename, false, Encoding.Default)) { w.WriteLine("Metasequoia Document"); w.WriteLine("Format Text Ver 1.0"); //w.WriteLine(""); //w.WriteLine("IncludeXml \"test.mqx\""); w.WriteLine(""); w.WriteLine("Scene {"); w.WriteLine(" pos 0.0000 0.0000 8.0000"); w.WriteLine(" lookat 0.0000 0.0000 0.0000"); w.WriteLine(" head -0.5236"); w.WriteLine(" pich 0.5236"); w.WriteLine(" bank 0.0000"); w.WriteLine(" ortho 0"); w.WriteLine(" zoom2 500"); w.WriteLine(" amb 0.250 0.250 0.250"); w.WriteLine(" dirlights 1 {"); w.WriteLine(" light {"); w.WriteLine(" dir 0.408 0.408 0.816"); w.WriteLine(" color 1.000 1.000 1.000"); w.WriteLine(" }"); w.WriteLine(" }"); w.WriteLine("}"); w.WriteLine(""); w.WriteLine("Material {0} {{", model.Materials.Count); var sb = new StringBuilder(); foreach(var i in model.Materials) { sb.Length = 0; var col = i.GetAs<ParamCol>("_Color"); var tex = i.GetAs<ParamTex>("_MainTex"); var texpath = ""; var pathtok = tex.TexAsset.Split('/', '\\'); for(int j= pathtok.Length - 2; j >= 0; --j) { texpath = Path.Combine(texdir, string.Join("\\", pathtok.Skip(j).ToArray())); texpath = texpath.Replace(".png", ".tex"); if(File.Exists(texpath)) break; } sb.AppendFormat(" \"{0}\"", i.Descriptions[0]) .AppendFormat(" shader({0})", 4) .AppendFormat(" col({0:F4} {1:F4} {2:F4} {3:F4})", col.R, col.G, col.B, col.A) .AppendFormat(" dif({0:F4})", 1.0f) .AppendFormat(" amb({0:F4})", 0.5f) .AppendFormat(" emi({0:F4})", 0.0f) .AppendFormat(" spc({0:F4})", 0.0f) .AppendFormat(" power({0:F4})", 0.0f); if(File.Exists(texpath)) { var texdata = TexFile.FromFile(texpath); var image = texdata.GetImage(); var name = Path.GetFileName(texdata.AssetPath); image.Save(Path.Combine(dir, name)); //sb.AppendFormat(" tex(\"{0}\")", texpath); sb.AppendFormat(" tex(\"{0}\")", name); } w.WriteLine(sb.ToString()); } w.WriteLine("}"); w.WriteLine(""); w.WriteLine("Object \"mesh\" {"); w.WriteLine(" depth 1"); w.WriteLine(" folding 0"); w.WriteLine(" scale 1.00000 1.00000 -1.00000"); w.WriteLine(" rotation 0.00000 0.00000 0.00000"); w.WriteLine(" translation 10.00000 30.00000 -20.00000"); w.WriteLine(" visible 15"); w.WriteLine(" locking 1"); w.WriteLine(" shading 1"); w.WriteLine(" facet 45.0"); w.WriteLine(" color 0.5 0.5 0.5"); w.WriteLine(" color_type 0"); w.WriteLine(" vertex {0} {{", model.Mesh.NumVerts); foreach(var i in model.Mesh.Vertices) //w.WriteLine(" {0:F4} {1:F4} {2:F4}", i.X, i.Y, i.Z); w.WriteLine(" {0:F4} {1:F4} {2:F4}", -i.P.X, i.P.Z, -i.P.Y); w.WriteLine(" }"); var nfaces = model.Mesh.Primitives.Sum(i => i.NumIndices) / 3; w.WriteLine(" face {0} {{", nfaces / 3); for(var mat= 0; mat < model.Mesh.NumPrims; ++mat) { var prim = model.Mesh.Primitives[mat]; for(int i= 0, n= prim.NumIndices; i < n; i+=3) { var i1 = prim.Indices[i+0]; var i2 = prim.Indices[i+1]; var i3 = prim.Indices[i+2]; var v1 = model.Mesh.Vertices[i1]; var v2 = model.Mesh.Vertices[i2]; var v3 = model.Mesh.Vertices[i3]; w.WriteLine(" 3 V({0} {1} {2}) M({3}) UV({4:F4} {5:F4} {6:F4} {7:F4} {8:F4} {9:F4})", i1, i2, i3, mat, v1.T.X, 1-v1.T.Y, v2.T.X, 1-v2.T.Y, v3.T.X, 1-v3.T.Y); } } w.WriteLine(" }"); w.WriteLine("}"); foreach(var i in model.Params.OfType<ParamMorph>()) { var v = model.Mesh.Vertices.Select(j => new Vector3(j.P.X, j.P.Y, j.P.Z)).ToArray(); foreach(var j in i.Vertices) { v[j.Index].X +=j.X; v[j.Index].Y +=j.Y; v[j.Index].Z +=j.Z; } w.WriteLine(""); w.WriteLine("Object \"elem:{0}-base\" {{", i.Name); w.WriteLine(" depth 1"); w.WriteLine(" folding 0"); w.WriteLine(" scale 1.00000 1.00000 -1.00000"); w.WriteLine(" rotation 0.00000 0.00000 0.00000"); w.WriteLine(" translation 10.00000 30.00000 -20.00000"); w.WriteLine(" visible 15"); w.WriteLine(" locking 1"); w.WriteLine(" shading 1"); w.WriteLine(" facet 45.0"); w.WriteLine(" color 0.5 0.5 0.5"); w.WriteLine(" color_type 0"); w.WriteLine(" vertex {0} {{", model.Mesh.NumVerts); foreach(var j in v) //w.WriteLine(" {0:F4} {1:F4} {2:F4}", i.X, i.Y, i.Z); w.WriteLine(" {0:F4} {1:F4} {2:F4}", -j.X, j.Z, -j.Y); w.WriteLine(" }"); nfaces = model.Mesh.Primitives.Sum(j => j.NumIndices) / 3; w.WriteLine(" face {0} {{", nfaces / 3); for(var mat= 0; mat < model.Mesh.NumPrims; ++mat) { var prim = model.Mesh.Primitives[mat]; for(int j= 0, n= prim.NumIndices; j < n; j+=3) { var i1 = prim.Indices[j+0]; var i2 = prim.Indices[j+1]; var i3 = prim.Indices[j+2]; var v1 = model.Mesh.Vertices[i1]; var v2 = model.Mesh.Vertices[i2]; var v3 = model.Mesh.Vertices[i3]; w.WriteLine(" 3 V({0} {1} {2}) M({3}) UV({4:F4} {5:F4} {6:F4} {7:F4} {8:F4} {9:F4})", i1, i2, i3, mat, v1.T.X, 1-v1.T.Y, v2.T.X, 1-v2.T.Y, v3.T.X, 1-v3.T.Y); } } w.WriteLine(" }"); w.WriteLine("}"); } w.WriteLine("Eof"); } }
public void ReplaceModel(ModelFile model, ModelFile refmodel) { var vertices= Vertices.Keys.ToList(); Closest = vertices.Select(i => FindClosest(refmodel.Mesh.Vertices, i.P)).ToList(); // スキンの生成 var sv = new List<ModelSkin>(); foreach(var i in Closest) sv.Add(refmodel.Mesh.Skins[i]); sv = Closest.Select(i => refmodel.Mesh.Skins[i]).ToList(); // モーフィングの作成 var rr = MorphMax - MorphMin; var morphs = new List<ParamMorph>(); foreach(var i in refmodel.Params.OfType<ParamMorph>()) // 元のモーフィングを列挙 { var dic = i.Vertices.ToDictionary(j => j.Index); var newmorph= new ParamMorph() { Vertices= new List<MorphVertex>() }; System.Diagnostics.Debug.Print("Morph:{0}", i.Name); morphs.Add(newmorph); for(int j= 0; j < vertices.Count; ++j) { var v1 = vertices[j]; // 新しい頂点 var v0 = refmodel.Mesh.Vertices[Closest[j]]; // 元の頂点で一番近いもの var x = v1.P.X - v0.P.X; var y = v1.P.Y - v0.P.Y; var z = v1.P.Z - v0.P.Z; var d = (float)Math.Sqrt(x*x + y*y + z*z); // 両頂点の距離 // 一定以上離れていたら、モーフィングを引き継がない if(d > MorphMax) { //System.Diagnostics.Debug.Print(" V {0} too far {1:F5}", // j.ToString().PadLeft(4), d); continue; } MorphVertex mv; // 元の頂点のモーフィングを検索 if(!dic.TryGetValue((ushort)Closest[j], out mv)) { //System.Diagnostics.Debug.Print(" V {0} => {1} not found", // j.ToString().PadLeft(4), Closest[j].ToString().PadLeft(4)); continue; } // 距離により影響度を算出(MorphMin:1.0 ... MorphMax:0.0) var r = d <= MorphMin ? 1.0f : 1 - (d - MorphMin) / rr; //r *=MorphScale; //var n0 = new Vector3(v0.N.X + mv.NX, v0.N.Y + mv.NY, v0.N.Z + mv.NZ); // 元の頂点のモーフィング後頂点 //System.Diagnostics.Debug.Print(" V {0} => {1} dist={2:F5} weight{3:F5}", // j.ToString().PadLeft(4), Closest[j].ToString().PadLeft(4), d, r); // モーフィング頂点の作成 newmorph.Vertices.Add(new MorphVertex() { Index = (ushort)j, X = mv.X * r, Y = mv.Y * r, Z = mv.Z * r, NX = mv.NX * r, NY = mv.NY * r, NZ = mv.NZ * r, //NX = (n0.X - v1.N.X) * r, //NY = (n0.Y - v1.N.Y) * r, //NZ = (n0.Z - v1.N.Z) * r, }); } System.Diagnostics.Debug.Print("Old={0} New={1}", i.Vertices.Count, newmorph.Vertices.Count); newmorph.Name = i.Name; newmorph.NumVertices= newmorph.Vertices.Count; } // モデルの更新 model.Mesh.Vertices = vertices; model.Mesh.NumVerts = vertices.Count; model.Mesh.Primitives = Primitives; model.Mesh.NumPrims = Primitives.Count; model.Mesh.Skins = sv; model.Params = model.Params.Where(i => !(i is ParamMorph)).ToList(); model.Params.InsertRange(0, morphs.Cast<Param>()); }
private void tsbRestore_Click(object sender, EventArgs e) { if(Data.Restore()) Data = ModelFile.FromFile(Data.FileName); }
private void SetData(ModelFile value) { if(value == data) return; data = value; UpdateView(); }
public override void Import(string filename, ModelFile model) { //MorphRange = MorphMax - MorphMin; var importer = new DaeIMImpoter(); Root = importer.Import(filename); var geoms = Root.Instances.OfType<Geometry> ().ToArray(); Vertices = new Dictionary<ModelVertex, int>(); Indices = new List<int>(); var geom = geoms.First(); var mesh = geom.Get<Mesh>("Data"); var posch = mesh.Channels.FirstOrDefault(i => i.Semantic == GeometrySemantic.Position); var nrmch = mesh.Channels.FirstOrDefault(i => i.Semantic == GeometrySemantic.Normal); var texch = mesh.Channels.FirstOrDefault(i => i.Semantic == GeometrySemantic.TexCoord); var pos = posch.GetDataAsList<SlimDX.Vector3>(); var nrm = nrmch.GetDataAsList<SlimDX.Vector3>(); var tex = texch.GetDataAsList<SlimDX.Vector2>(); var posface = posch.GetIndicesAsList(mesh); var nrmface = nrmch.GetIndicesAsList(mesh); var texface = texch.GetIndicesAsList(mesh); var numidx = posface.Count; for(int i= 0; i < numidx; ++i) { var p = pos[posface[i]]; var n = nrm[nrmface[i]]; var t = tex[texface[i]]; var v = new ModelVertex() { P = new Vector3(p.X, p.Y, p.Z), N = new Vector3(n.X, n.Y, n.Z), T = new Vector2(t.X, t.Y), }; int index; if(!Vertices.TryGetValue(v, out index)) Vertices.Add(v, index= Vertices.Count); Indices.Add(index); } var prims = new List<ModelPrimitive>(); var start = 0; foreach(var i in mesh.Primitives) { var prim = new ModelPrimitive(); prim.Indices = Indices.Skip(start).Take(i.Count).Select(j => (ushort)j).ToList(); prim.NumIndices = Indices.Count; start +=Indices.Count; prims.Add(prim); } model.Mesh.Skins = Vertices.Keys .Select(i => model.Mesh.Skins[FindClosest(model.Mesh.Vertices, i.P)]) .ToList(); model.Mesh.Vertices = Vertices.Keys.ToList(); model.Mesh.NumVerts = model.Mesh.Vertices.Count; model.Mesh.Primitives = prims; model.Mesh.NumPrims = prims.Count; // モーフィングをボディから反映 var morphs = model.Params.OfType<ParamMorph>().ToList(); var body001 = DataManager.Instance.Body001; foreach(var i in morphs) { var index = (ushort)0; var bodymorph = body001.Params.FirstOrDefault(j => j.Name == i.Name) as ParamMorph; var dic = bodymorph.Vertices.ToDictionary(j => j.Index); var dic2 = new Dictionary<int, MorphVertex>(); var rr = Settings.MorphMax - Settings.MorphMin; MorphVertex mv; foreach(var j in model.Mesh.Vertices) { ++index; var near = FindClosest(body001.Mesh.Vertices, j.P); if(!dic.TryGetValue((ushort)near, out mv)) continue; var v = body001.Mesh.Vertices[near]; var x = v.P.X - j.P.X; var y = v.P.Y - j.P.Y; var z = v.P.Z - j.P.Z; var d = (float)Math.Sqrt(x*x + y*y + z*z); if(d >= Settings.MorphMax) continue; var r = d <= Settings.MorphMin ? 1.0f : 1.0f - (d-Settings.MorphMin) / rr; //r = r * MorphScale; var mv2 = new MorphVertex(index-1, mv.X*r, mv.Y*r, mv.Z*r, mv.NX*r, mv.NY*r, mv.NZ*r); dic2.Add((ushort)(index-1), mv2); } i.Vertices = dic2.OrderBy(j => j.Key).Select(j => j.Value).ToList(); i.NumVertices = i.Vertices.Count; } ModelFile.ToFile(model.FileName, model); System.Diagnostics.Debug.Print("終了"); }
public void ImportOld(string filename, ModelFile model) { var importer = new DaeIMImpoter(); Root = importer.Import(filename); var skins = Root.Instances.OfType<SkinDeclaraion> ().ToArray(); var morphs = Root.Instances.OfType<MorphingDeclaraion>().ToArray(); var geoms = Root.Instances.OfType<Geometry> ().ToArray(); Vertices = new Dictionary<ModelVertex, int>(); Indices = new List<int>(); //Skins = new Dictionary<int, ModelSkin>(); if(morphs.Length > 0) { var geom = morphs.First().Source as Geometry; var mesh = geom.Get<Mesh>("Data"); var posch = mesh.Channels.FirstOrDefault(i => i.Semantic == GeometrySemantic.Position); var nrmch = mesh.Channels.FirstOrDefault(i => i.Semantic == GeometrySemantic.Normal); var texch = mesh.Channels.FirstOrDefault(i => i.Semantic == GeometrySemantic.TexCoord); var pos = posch.GetDataAsList<SlimDX.Vector3>(); var nrm = nrmch.GetDataAsList<SlimDX.Vector3>(); var tex = texch.GetDataAsList<SlimDX.Vector2>(); var posface = posch.GetIndicesAsList(mesh); var nrmface = nrmch.GetIndicesAsList(mesh); var texface = texch.GetIndicesAsList(mesh); var numidx = posface.Count; for(int i= 0; i < numidx; ++i) { var p = pos[posface[i]]; var n = nrm[nrmface[i]]; var t = tex[texface[i]]; var v = new ModelVertex() { P = new Vector3(p.X, p.Y, p.Z), N = new Vector3(n.X, n.Y, n.Z), T = new Vector2(t.X, t.Y), }; int index; if(!Vertices.TryGetValue(v, out index)) Vertices.Add(v, index= Vertices.Count); Indices.Add(index); } var prims = new List<ModelPrimitive>(); var start = 0; foreach(var i in mesh.Primitives) { var prim = new ModelPrimitive(); prim.Indices = Indices.Skip(start).Take(i.Count).Select(j => (ushort)j).ToList(); prim.NumIndices = Indices.Count; start +=Indices.Count; prims.Add(prim); } model.Mesh.Skins = Vertices.Keys .Select(i => model.Mesh.Skins[FindClosest(model.Mesh.Vertices, i.P)]) .ToList(); model.Mesh.Vertices = Vertices.Keys.ToList(); model.Mesh.NumVerts = model.Mesh.Vertices.Count; model.Mesh.Primitives = prims; model.Mesh.NumPrims = prims.Count; // モーフィング model.Params = model.Params.Where(i => !(i is ParamMorph)).ToList(); foreach(var i in morphs.First().Channels) { var mmesh = i.Geometry.Get<Mesh>("Data"); var mposch = mmesh.Channels.FirstOrDefault(j => j.Semantic == GeometrySemantic.Position); var mpos = mposch.GetDataAsList<SlimDX.Vector3>(); var mposidx = mposch.GetIndicesAsList(mmesh); var dic = new Dictionary<int, MorphVertex>(); var mnrm = new SlimDX.Vector3[mpos.Count]; // 法線計算 for(int j= 0; j < mposidx.Count; j+=3) { var a = mpos[mposidx[j+0]]; var b = mpos[mposidx[j+1]]; var c = mpos[mposidx[j+2]]; var ab = SlimDX.Vector3.Normalize(SlimDX.Vector3.Subtract(b, a)); var ac = SlimDX.Vector3.Normalize(SlimDX.Vector3.Subtract(c, a)); var n = SlimDX.Vector3.Normalize(SlimDX.Vector3.Cross(ab, ac)); mnrm[mposidx[j+0]] = SlimDX.Vector3.Add(mnrm[mposidx[j+0]], n); mnrm[mposidx[j+1]] = SlimDX.Vector3.Add(mnrm[mposidx[j+1]], n); mnrm[mposidx[j+2]] = SlimDX.Vector3.Add(mnrm[mposidx[j+2]], n); } for(int j= 0; j < mnrm.Length; ++j) mnrm[j] = SlimDX.Vector3.Normalize(mnrm[j]); for(int j= 0; j < mposidx.Count; ++j) { var ii = (ushort)Indices[j]; var v = model.Mesh.Vertices[ii]; var p = mpos[mposidx[j]]; var n = mnrm[mposidx[j]]; p.X -=v.P.X; p.Y -=v.P.Y; p.Z -=v.P.Z; n.X -=v.N.X; n.Y -=v.N.Y; n.Z -=v.N.Z; dic[ii] = new MorphVertex(ii, p.X, p.Y, p.Z, n.X, n.Y, n.Z); } var morph = new ParamMorph() { Name = i.Geometry.Name, Vertices = dic.OrderBy(j => j.Key).Select(j => j.Value).ToList(), NumVertices = dic.Count, }; model.Params.Insert(0, morph); } } else { throw new Exception(); } ModelFile.ToFile(model.FileName, model); System.Diagnostics.Debug.Print("終了"); }
public abstract void Export(string filename, ModelFile model);
private void AddModel(ModelFile model) { AddFiles(model.Materials .SelectMany(i => i.Params) .OfType<ParamTex>() .Where(i => i.TexAsset != null) .Select(i => DataManager.Instance.FindItem(i.TexFileName) as BaseFile) .Where(i => i != null)); }
private void CreateRoot(ModelFile model) { Root = new Root(); Scene = new VisualScene() { ID= "VisualScene-1", Name= "VisualScene-1" }; Materials = new Dictionary<string, Material>(); Bitmaps = new Dictionary<string, BitmapTexture>(); Bones = new List<VisualNode>(); var no = 0; // ボーン foreach(var i in model.Bones) CreateBone(i, no++); // マテリアル foreach(var i in model.Materials) CreateMaterial(i); // メッシュ CreateMesh(model); Root.Scenes.Add(Scene); }
private void CreateMesh(ModelFile model) { var id = "Mesh-"+model.Descriptions[0]; var name = model.Descriptions[1]; var mesh = new Mesh(id, name); var geom = new Geometry("Geom-"+id, name); var node = Bones.FirstOrDefault(i => i.Name == name); var pos = new GeometryChannel("Pos-"+id, name, GeometrySemantic.Position, 0); var nrm = new GeometryChannel("Nrm-"+id, name, GeometrySemantic.Normal, 0); var tex = new GeometryChannel("Tex-"+id, name, GeometrySemantic.TexCoord, 1); var indices = new List<int>(); var mats = Materials.Values.ToArray(); var no = 0; foreach(var i in model.Mesh.Primitives) { var prim = new TrianglePrimitive(); prim.Start = indices.Count; indices.AddRange(i.Indices.Select(j => (int)j)); prim.Count = indices.Count - prim.Start; prim.Material= mats[no++]; mesh.Primitives.Add(prim); } pos.SetData(ToSlimDX(model.Mesh.Vertices.Select(i => i.P)).ToList()); nrm.SetData(ToSlimDX(model.Mesh.Vertices.Select(i => i.N)).ToList()); tex.SetData(ToSlimDX(model.Mesh.Vertices.Select(i => i.T)).ToList()); var array = indices.ToArray(); pos.SetIndices(array); nrm.SetIndices(array); tex.SetIndices(array); mesh.Channels.Add(pos); mesh.Channels.Add(nrm); mesh.Channels.Add(tex); geom.SetData(mesh); Root.Instances.Add(geom); // モーフィング if(Settings.Morph) { Morph = new MorphingDeclaraion() { ID= "Morph-"+id, Name= "Morph"+name, Method= MorphingMethod.Normalized }; var morphs = model.Params.OfType<ParamMorph>().ToArray(); foreach(var i in morphs) { var v = ToSlimDX(model.Mesh.Vertices.Select(j => j.P)).ToArray(); foreach(var j in i.Vertices) { v[j.Index].X +=j.X; v[j.Index].Y +=j.Y; v[j.Index].Z +=j.Z; } var mm = new Mesh() { ID= "MorphMesh-" +i.Name, Name= i.Name }; var mg = new Geometry() { ID= "MorphGeom-" +i.Name, Name= i.Name }; var mc = new MorphingChannel() { ID= "MorphChannel-"+i.Name, Name= i.Name, Weight= 0.0f, Geometry= mg }; var c = new GeometryChannel() { ID= "MorphPos-" +i.Name, Name= i.Name, Semantic= GeometrySemantic.Position, Index= 0 }; Morph.Channels.Add(mc); Root.Instances.Add(mg); mg.SetData(mm); mm.Channels.Add(c); mm.Primitives.AddRange(mesh.Primitives); c.SetData(v.ToList()); c.SetIndices(mesh.Channels[0].GetIndicesAsArray(mesh)); } Root.Instances.Add(Morph); } // スキン if(Settings.Skin) { Skin = new SkinDeclaraion() { ID= "Skin-"+id, Name= "Skin"+name, Bind= SlimDX.Matrix.Identity }; var skinbones= model.Mesh.RefBones.Select(i => Bones.First(j => j.Name == i.Name)).ToList(); var bonemats= model.Mesh.RefBones.Select(i => new SlimDX.Matrix() { M11 = i.Matrix[ 0], M12 = i.Matrix[ 1], M13 = i.Matrix[ 2], M14 = i.Matrix[ 3], M21 = i.Matrix[ 4], M22 = i.Matrix[ 5], M23 = i.Matrix[ 6], M24 = i.Matrix[ 7], M31 = i.Matrix[ 8], M32 = i.Matrix[ 9], M33 = i.Matrix[10], M34 = i.Matrix[11], M41 = i.Matrix[12], M42 = i.Matrix[13], M43 = i.Matrix[14], M44 = i.Matrix[15] }).ToList(); Skin.Skeleton = new Skeleton() { Node= Scene.Nodes.First() }; var verts = new List<SkinVertices>(); var v = new List<SkinVertex>(); foreach(var i in model.Mesh.Skins) { v.Clear(); if(0 != i.W1) v.Add(new SkinVertex(i.B1, i.W1)); if(0 != i.W2) v.Add(new SkinVertex(i.B2, i.W2)); if(0 != i.W3) v.Add(new SkinVertex(i.B3, i.W3)); if(0 != i.W4) v.Add(new SkinVertex(i.B4, i.W4)); verts.Add(new SkinVertices(v)); } Skin.Vertices .AddRange(verts); Skin.Bones .AddRange(skinbones.Cast<Node>()); Skin.BindMatrices.AddRange(bonemats); Root.Instances.Add(Skin); } if(null == Skin) { if(null == Morph) { node.Instance = geom; } else { Morph.Source = geom; node.Instance = Morph; } } else { if(null == Morph) { Skin.Source = geom; node.Instance = Skin; } else { Morph.Source = geom; Skin.Source = Morph; node.Instance = Skin; } } }
private void ExportOBJ(string filename, ModelFile model) { var mtlfile = Path.ChangeExtension(filename, ".mtl"); using(var w = new StreamWriter(filename, false, Encoding.Default)) { int voffset = 1; w.WriteLine("mtllib {0}", Path.GetFileName(mtlfile)); // ベースのモデル foreach(var i in model.Mesh.Vertices) WriteObjV(w, i.P.X, i.P.Y, i.P.Z); foreach(var i in model.Mesh.Vertices) WriteObjVN(w, i.P.X, i.P.Y, i.P.Z); foreach(var i in model.Mesh.Vertices) WriteObjVT(w, i.T.X, i.T.Y); w.WriteLine("g {0}", "base"); for(var mat= 0; mat < model.Mesh.NumPrims; ++mat) { w.WriteLine("usemtl {0}", model.Materials[mat].Descriptions[0]); //w.WriteLine("s {0}", mat); var prim = model.Mesh.Primitives[mat]; for(int i= 0, num= prim.NumIndices; i < num; i+=3) { var i1 = prim.Indices[i+0] + voffset; var i2 = prim.Indices[i+1] + voffset; var i3 = prim.Indices[i+2] + voffset; w.WriteLine("f {0}/{0}/{0} {1}/{1}/{1} {2}/{2}/{2}", i1, i2, i3); } } // モーフィング if(Settings.Morph) foreach(var morph in model.Params.OfType<ParamMorph>()) { voffset +=model.Mesh.Vertices.Count; var v = model.Mesh.Vertices.Select(j => new Vector3(j.P.X, j.P.Y, j.P.Z)).ToArray(); var n = model.Mesh.Vertices.Select(j => new Vector3(j.N.X, j.N.Y, j.N.Z)).ToArray(); foreach(var i in morph.Vertices) { v[i.Index].X +=i.X; v[i.Index].Y +=i.Y; v[i.Index].Z +=i.Z; } foreach(var i in morph.Vertices) { n[i.Index].X +=i.NX; n[i.Index].Y +=i.NY; n[i.Index].Z +=i.NZ; } foreach(var i in v) //WriteObjV(w, -i.X, i.Z, -i.Y); WriteObjV(w, i.X, i.Y, i.Z); foreach(var i in n) //WriteObjVN(w, -i.X, i.Z, -i.Y); WriteObjVN(w, i.X, i.Y, i.Z); foreach(var i in model.Mesh.Vertices) WriteObjVT(w, i.T.X, i.T.Y); w.WriteLine("g morph_{0}", morph.Name); for(var mat= 0; mat < model.Mesh.NumPrims; ++mat) { w.WriteLine("usemtl {0}", model.Materials[mat].Descriptions[0]); //w.WriteLine("s {0}", mat); var prim = model.Mesh.Primitives[mat]; for(int i= 0, num= prim.NumIndices; i < num; i+=3) { var i1 = prim.Indices[i+0] + voffset; var i2 = prim.Indices[i+1] + voffset; var i3 = prim.Indices[i+2] + voffset; w.WriteLine("f {0}/{0}/{0} {1}/{1}/{1} {2}/{2}/{2}", i1, i2, i3); } } } } }