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);
            }
        }
예제 #5
0
 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();
        }
예제 #12
0
        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("終了");
        }
예제 #13
0
        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("終了");
        }
예제 #14
0
 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));
 }
예제 #16
0
        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);
        }
예제 #17
0
        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;
                }
            }
        }
예제 #18
0
        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);
                        }
                    }
                }
            }
        }