Example #1
0
        public MTL ToMTL(int Model)
        {
            if (Data.Models.Length == 0 || Data.Models.Length <= Model)
            {
                return(null);
            }
            var o = new MTL();
            var m = Data.Models[Model];

            //foreach (CMDL m in Models)
            {
                foreach (var vv in m.Materials)
                {
                    MTL.MTLMaterial mm = new MTL.MTLMaterial(vv.Name);
                    mm.DiffuseColor  = vv.MaterialColor.DiffuseU32;
                    mm.AmbientColor  = vv.MaterialColor.AmbientU32;
                    mm.Alpha         = vv.MaterialColor.Diffuse.W;
                    mm.SpecularColor = vv.MaterialColor.Specular0U32;
                    if (vv.Tex0 != null && vv.Tex0.TextureObject is ReferenceTexture /* && vv.TextureCoordiators[0].SourceCoordinate == 0*/)
                    {
                        mm.DiffuseMapPath = "Tex/" + ((ReferenceTexture)vv.Tex0.TextureObject).LinkedTextureName + ".png";
                    }
                    //else if (vv.Tex1 != null && vv.Tex1.TextureObject is ReferenceTexture && vv.TextureCoordiators[1].SourceCoordinate == 0) mm.DiffuseMapPath = "Tex/" + ((ReferenceTexture)vv.Tex1.TextureObject).LinkedTextureName + ".png";
                    //else if (vv.Tex2 != null && vv.Tex2.TextureObject is ReferenceTexture && vv.TextureCoordiators[2].SourceCoordinate == 0) mm.DiffuseMapPath = "Tex/" + ((ReferenceTexture)vv.Tex2.TextureObject).LinkedTextureName + ".png";
                    o.Materials.Add(mm);
                }
            }
            return(o);
        }
Example #2
0
        public static void N3DS_NW4C_GFX_ToOBJ(String BCMDLPath, int ModelIdx, String OBJPath)
        {
            CGFX c = new CGFX(File.ReadAllBytes(BCMDLPath));

            if (c.Data.Models == null || c.Data.Models.Length <= ModelIdx)
            {
                throw new Exception("Model does not exist in the specified CGFX file!");
            }
            CMDL Model = c.Data.Models[ModelIdx];
            OBJ  o     = Model.ToOBJ();

            o.MTLPath = Path.GetFileNameWithoutExtension(OBJPath) + ".mtl";
            MTL m = Model.ToMTL(Path.GetFileNameWithoutExtension(OBJPath) + "_Tex");

            byte[] d  = o.Write();
            byte[] d2 = m.Write();
            File.Create(OBJPath).Close();
            File.WriteAllBytes(OBJPath, d);
            File.Create(Path.ChangeExtension(OBJPath, "mtl")).Close();
            File.WriteAllBytes(Path.ChangeExtension(OBJPath, "mtl"), d2);
            Directory.CreateDirectory(Path.GetDirectoryName(OBJPath) + "\\" + Path.GetFileNameWithoutExtension(OBJPath) + "_Tex");
            foreach (var v in c.Data.Textures)
            {
                if (!(v is ImageTextureCtr))
                {
                    continue;
                }
                ((ImageTextureCtr)v).GetBitmap().Save(Path.GetDirectoryName(OBJPath) + "\\" + Path.GetFileNameWithoutExtension(OBJPath) + "_Tex\\" + v.Name + ".png");
            }
        }
        public OBJ ToOBJ(out MTL mtl)
        {
            OBJ o = new OBJ();
            int v = 0;
            HashSet <String> matnames = new HashSet <string>();

            foreach (var vv in Planes)
            {
                Triangle t = GetTriangle(vv);
                o.Vertices.Add(t.PointA);
                o.Vertices.Add(t.PointB);
                o.Vertices.Add(t.PointC);
                var f = new OBJ.OBJFace();
                f.Material = "mat_" + vv.CollisionType.ToString("X") + "_ID";
                matnames.Add(f.Material);
                f.VertexIndieces.Add(v);
                f.VertexIndieces.Add(v + 1);
                f.VertexIndieces.Add(v + 2);
                o.Faces.Add(f);
                v += 3;
            }
            mtl = new MTL();
            Random r = new Random();

            foreach (string s in matnames)
            {
                MTL.MTLMaterial m = new MTL.MTLMaterial(s);
                m.AmbientColor  = Color.Black;
                m.SpecularColor = Color.FromArgb(85, 85, 85);
                m.DiffuseColor  = Color.FromArgb(r.Next(0, 255), r.Next(0, 255), r.Next(0, 255));
                mtl.Materials.Add(m);
            }
            o.optimizeVertexCount();
            return(o);
        }
 public OBJWrapper(string path)
 {
     base_path = Path.GetDirectoryName(path);
     try
     {
         bool has_mtl = true;
         obj_data = new OBJ(File.ReadAllBytes(path));
         if (obj_data.MTLPath.Length > 0)
         {
             try
             {
                 obj_data.MTLPath.Replace("/", "\\");
                 mtl_data = new MTL(File.ReadAllBytes(base_path + "\\" + obj_data.MTLPath));
             }
             catch
             {
                 mtl_data = null;
                 has_mtl  = false;
             }
         }
         InitializeMaterials(has_mtl);
     }
     catch (Exception e)
     {
         MessageBox.Show("OBJ Wrapper Exception: \n\r" + e.ToString());
     }
 }
Example #5
0
        public override Asset Import(string path)
        {
            Material material;

            string name     = Path.GetFileNameWithoutExtension(path);
            MTL    mat      = MTL.Load(path);
            string fileName = mat.Textures[0];

            if (fileName == null || fileName == "")
            {
                material = new Material {
                    Name = name, Texture = new Texture()
                    {
                        Name = fileName
                    }
                };
            }
            else
            {
                material = new Material
                {
                    Name    = name,
                    Texture = SceneManager.Current.Content.Load <Texture, TDXImporter>(fileName, Path.GetDirectoryName(path))
                };
            }

            material.SupportingDocuments["Source"] = mat;

            return(material);
        }
Example #6
0
        public bool Convert(int FilterIndex, String Path)
        {
            switch (FilterIndex)
            {
            case 0:
            {
                DAE o = ToDAE(0);
                File.Create(Path).Close();
                File.WriteAllBytes(Path, o.Write());
                Directory.CreateDirectory(System.IO.Path.GetDirectoryName(Path) + "\\Tex");
                foreach (var v in Data.Textures)
                {
                    if (!(v is ImageTextureCtr))
                    {
                        continue;
                    }
                    ((ImageTextureCtr)v).GetBitmap().Save(System.IO.Path.GetDirectoryName(Path) + "\\Tex\\" + v.Name + ".png");
                }
                return(true);
            }

            case 1:
            {
                if (Data.Models.Length == 0)
                {
                    return(false);
                }
                OBJ o = ToOBJ(0);
                o.MTLPath = System.IO.Path.GetFileNameWithoutExtension(Path) + ".mtl";
                MTL    m  = ToMTL(0);
                byte[] d  = o.Write();
                byte[] d2 = m.Write();
                File.Create(Path).Close();
                File.WriteAllBytes(Path, d);
                File.Create(System.IO.Path.ChangeExtension(Path, "mtl")).Close();
                File.WriteAllBytes(System.IO.Path.ChangeExtension(Path, "mtl"), d2);
                Directory.CreateDirectory(System.IO.Path.GetDirectoryName(Path) + "\\Tex");
                foreach (var v in Data.Textures)
                {
                    //if (v.NrLevels > 2) v.GetBitmap(2).Save(System.IO.Path.GetDirectoryName(Path) + "\\Tex\\" + v.Name + ".png");
                    //else if (v.NrLevels > 1) v.GetBitmap(1).Save(System.IO.Path.GetDirectoryName(Path) + "\\Tex\\" + v.Name + ".png");
                    //else v.GetBitmap(0).Save(System.IO.Path.GetDirectoryName(Path) + "\\Tex\\" + v.Name + ".png");
                    if (!(v is ImageTextureCtr))
                    {
                        continue;
                    }
                    ((ImageTextureCtr)v).GetBitmap().Save(System.IO.Path.GetDirectoryName(Path) + "\\Tex\\" + v.Name + ".png");
                }
                return(true);
            }

            default:
                return(false);
            }
        }
Example #7
0
        private void toolStripButton1_Click(object sender, EventArgs e)
        {
            saveFileDialog1.FileName = Model.Name;
            if (saveFileDialog1.ShowDialog() == DialogResult.OK &&
                saveFileDialog1.FileName.Length > 0)
            {
                switch (saveFileDialog1.FilterIndex - 1)
                {
                case 0:
                {
                    DAE o = Model.ToDAE(Resource);
                    File.Create(saveFileDialog1.FileName).Close();
                    File.WriteAllBytes(saveFileDialog1.FileName, o.Write());
                    Directory.CreateDirectory(Path.GetDirectoryName(saveFileDialog1.FileName) + "\\Tex");
                    foreach (var v in Resource.Data.Textures)
                    {
                        if (!(v is ImageTextureCtr))
                        {
                            continue;
                        }
                        ((ImageTextureCtr)v).GetBitmap().Save(Path.GetDirectoryName(saveFileDialog1.FileName) + "\\Tex\\" + v.Name + ".png");
                    }
                    break;
                }

                case 1:
                {
                    OBJ o = Model.ToOBJ();
                    o.MTLPath = Path.GetFileNameWithoutExtension(saveFileDialog1.FileName) + ".mtl";
                    MTL    m  = Model.ToMTL("Tex");
                    byte[] d  = o.Write();
                    byte[] d2 = m.Write();
                    File.Create(saveFileDialog1.FileName).Close();
                    File.WriteAllBytes(saveFileDialog1.FileName, d);
                    File.Create(Path.ChangeExtension(saveFileDialog1.FileName, "mtl")).Close();
                    File.WriteAllBytes(Path.ChangeExtension(saveFileDialog1.FileName, "mtl"), d2);
                    Directory.CreateDirectory(Path.GetDirectoryName(saveFileDialog1.FileName) + "\\Tex");
                    foreach (var v in Resource.Data.Textures)
                    {
                        //if (v.NrLevels > 2) v.GetBitmap(2).Save(System.IO.Path.GetDirectoryName(Path) + "\\Tex\\" + v.Name + ".png");
                        //else if (v.NrLevels > 1) v.GetBitmap(1).Save(System.IO.Path.GetDirectoryName(Path) + "\\Tex\\" + v.Name + ".png");
                        //else v.GetBitmap(0).Save(System.IO.Path.GetDirectoryName(Path) + "\\Tex\\" + v.Name + ".png");
                        if (!(v is ImageTextureCtr))
                        {
                            continue;
                        }
                        ((ImageTextureCtr)v).GetBitmap().Save(Path.GetDirectoryName(saveFileDialog1.FileName) + "\\Tex\\" + v.Name + ".png");
                    }
                    break;
                }
                }
            }
        }
Example #8
0
            public MTL ToMTL()
            {
                MTL m = new MTL();

                foreach (var v in Materials)
                {
                    MTL.MTLMaterial mm = new MTL.MTLMaterial("M" + v.Key + "M");
                    mm.DiffuseColor   = Color.White;
                    mm.DiffuseMapPath = "Tex/" + v.Key + ".png";
                    m.Materials.Add(mm);
                }
                return(m);
            }
Example #9
0
        public override Asset Import(string path)
        {
            Material material;

            string name = Path.GetFileNameWithoutExtension(path);

            ToxicRagers.Generics.Material m = null;

            switch (Path.GetExtension(path).ToLower())
            {
            case ".mt2":
                m = MT2.Load(path);
                break;

            case ".mtl":
                m = MTL.Load(path);
                break;
            }

            if (m != null)
            {
                var    mat      = (m as MT2);
                string fileName = (mat != null ? mat.Texture : (m as MTL).Textures[0]);

                if (fileName == null || fileName == "")
                {
                    material = new Material {
                        Name = name, Texture = new Texture()
                        {
                            Name = fileName
                        }
                    };
                }
                else
                {
                    material = new Material {
                        Name = name, Texture = SceneManager.Current.Content.Load <Texture, TDXImporter>(fileName, Path.GetDirectoryName(path))
                    };
                }

                material.SupportingDocuments["Source"] = m;
            }
            else
            {
                material = new Material();
            }

            return(material);
        }
        public bool Convert(int FilterIndex, string Path)
        {
            switch (FilterIndex)
            {
            case 0:
                MTL    mtl     = null;
                OBJ    o       = ToOBJ(out mtl);
                string mtlPath = Path.Replace(".obj", ".mtl");
                o.MTLPath = System.IO.Path.GetFileName(mtlPath);
                byte[] d = o.Write();
                byte[] m = mtl.Write();
                File.Create(Path).Close();
                File.Create(mtlPath).Close();
                File.WriteAllBytes(Path, d);
                File.WriteAllBytes(mtlPath, m);
                return(true);

            default:
                return(false);
            }
        }
Example #11
0
        void ConvertEFE(byte[] Data, string Name)
        {
            _3DS.NintendoWare.GFX.CGFX mod = new _3DS.NintendoWare.GFX.CGFX(Data);
            CommonFiles.OBJ            o   = mod.Data.Models[0].ToOBJ();
            o.MTLPath = Path.GetFileNameWithoutExtension(Name) + ".mtl";
            MTL m = mod.Data.Models[0].ToMTL("Tex");

            byte[] d  = o.Write();
            byte[] d2 = m.Write();
            File.Create(Name).Close();
            File.WriteAllBytes(Name, d);
            File.Create(Path.ChangeExtension(Name, "mtl")).Close();
            File.WriteAllBytes(Path.ChangeExtension(Name, "mtl"), d2);
            Directory.CreateDirectory(Path.GetDirectoryName(Name) + "\\Tex");
            foreach (var v in mod.Data.Textures)
            {
                if (!(v is ImageTextureCtr))
                {
                    continue;
                }
                ((ImageTextureCtr)v).GetBitmap().Save(Path.GetDirectoryName(Name) + "\\Tex\\" + v.Name + ".png");
            }
        }
Example #12
0
        private void FrmObjImport_Load(object sender, EventArgs e)
        {
            OpenFileDialog opn = new OpenFileDialog();

            opn.Title  = "Open a model file";
            opn.Filter = "Supported formats (.bcmdl, .obj)|*.bcmdl; *.obj";
            bool ok = true;

            if (opn.ShowDialog() != DialogResult.OK)
            {
                ok = false;
            }
            if (Path.GetExtension(opn.FileName).ToLower() == ".obj")
            {
                if (MessageBox.Show("The obj will be converted to bcmdl with Every File Explorer's method, this is known to have problems, especially with models made in sketchup.\r\nDo you want to continue ?", "Warning", MessageBoxButtons.YesNo) == DialogResult.Yes)
                {
                    modelPath    = opn.FileName;
                    ObjModelPath = modelPath;
                    IsObj        = true;
                    render.addModel(modelPath, "Model", new System.Windows.Media.Media3D.Vector3D(0, 0, 0), new System.Windows.Media.Media3D.Vector3D(1, 1, 1), 0, 0, 0);
                }
                else
                {
                    MessageBox.Show("You can convert the model to bcmdl with the leaked tools");
                    this.Close();
                }
            }
            else if (Path.GetExtension(opn.FileName).ToLower() == ".bcmdl")
            {
                tmpPath = Path.GetTempPath() + "TmpT4D";
                string Name = tmpPath + "\\model.obj";
                Directory.CreateDirectory(tmpPath);
                CGFX mod = null;
                mod = new _3DS.NintendoWare.GFX.CGFX(File.ReadAllBytes(opn.FileName));
                CommonFiles.OBJ o = mod.Data.Models[0].ToOBJ();
                o.MTLPath = Path.GetFileNameWithoutExtension(Name) + ".mtl";
                MTL    m  = mod.Data.Models[0].ToMTL("Tex");
                byte[] d  = o.Write();
                byte[] d2 = m.Write();
                File.Create(Name).Close();
                File.WriteAllBytes(Name, d);
                File.Create(Path.ChangeExtension(Name, "mtl")).Close();
                File.WriteAllBytes(Path.ChangeExtension(Name, "mtl"), d2);
                Directory.CreateDirectory(tmpPath + "\\Tex");
                foreach (var v in mod.Data.Textures)
                {
                    if (!(v is ImageTextureCtr))
                    {
                        continue;
                    }
                    ((ImageTextureCtr)v).GetBitmap().Save(tmpPath + "\\Tex\\" + v.Name + ".png");
                }
                modelPath    = opn.FileName;
                ObjModelPath = Name;
                IsObj        = false;
                render.addModel(Name, "Model", new System.Windows.Media.Media3D.Vector3D(0, 0, 0), new System.Windows.Media.Media3D.Vector3D(1, 1, 1), 0, 0, 0);
                textBox1.Text    = mod.Data.Models[0].Name;
                textBox1.Enabled = false;
                render.SetSortFrequency(0);
            }
            else
            {
                if (ok)
                {
                    MessageBox.Show("File not supported");
                }
                else
                {
                    MessageBox.Show("You must select your model file to use this function");
                }
                this.Close();
            }
        }
        public static void FromOBJ(CGFX c, String OBJPath, String ModelName = "EFEModel")
        {
            OBJ Model = new OBJ(File.ReadAllBytes(OBJPath));

            if (Model.MTLPath == null)
            {
                throw new Exception("Model without materials not supported!");
            }
            String        MtlPath  = Path.GetDirectoryName(OBJPath) + "\\" + Model.MTLPath;
            MTL           MatLib   = new MTL(File.ReadAllBytes(MtlPath));
            List <String> MatNames = new List <string>();

            foreach (var f in Model.Faces)
            {
                if (!MatNames.Contains(f.Material))
                {
                    MatNames.Add(f.Material);
                }
            }
            Bitmap[] Textures   = new Bitmap[MatLib.Materials.Count];
            int      q          = 0;
            int      NrTextures = 0;

            foreach (var v in MatLib.Materials)
            {
                if (!MatNames.Contains(v.Name))
                {
                    q++; continue;
                }
                if (v.DiffuseMapPath != null)
                {
                    Textures[q] = new Bitmap(new MemoryStream(File.ReadAllBytes(Path.GetDirectoryName(MtlPath) + "\\" + v.DiffuseMapPath)));
                    NrTextures++;
                }
                q++;
            }
            c.Data.Dictionaries[0] = new DICT();
            c.Data.Dictionaries[0].Add(ModelName);
            c.Data.Models    = new CMDL[1];
            c.Data.Models[0] = new CMDL(ModelName);
            CMDL cmdl = c.Data.Models[0];

            //Mesh Node Visibility
            {
                cmdl.NrMeshNodes = 1;
                cmdl.MeshNodeVisibilitiesDict = new DICT();
                cmdl.MeshNodeVisibilitiesDict.Add("CompleteModel");
                cmdl.MeshNodeVisibilities = new CMDL.MeshNodeVisibilityCtr[] { new CMDL.MeshNodeVisibilityCtr("CompleteModel") };
            }
            //Meshes
            {
                cmdl.NrMeshes = (uint)MatNames.Count;
                cmdl.Meshes   = new CMDL.Mesh[MatNames.Count];
                for (int i = 0; i < MatNames.Count; i++)
                {
                    cmdl.Meshes[i] = new CMDL.Mesh();
                    cmdl.Meshes[i].MeshNodeName  = "CompleteModel";
                    cmdl.Meshes[i].MaterialIndex = (uint)i;
                    cmdl.Meshes[i].ShapeIndex    = (uint)i;
                }
            }
            //Materials
            {
                cmdl.NrMaterials   = (uint)MatNames.Count;
                cmdl.MaterialsDict = new DICT();
                cmdl.Materials     = new CMDL.MTOB[MatNames.Count];
                for (int i = 0; i < MatNames.Count; i++)
                {
                    cmdl.MaterialsDict.Add(MatNames[i]);
                    cmdl.Materials[i] = new CMDL.MTOB(MatNames[i]);
                    cmdl.Materials[i].FragShader.TextureCombiners[0].SrcRgb   = 0xEE0;
                    cmdl.Materials[i].FragShader.TextureCombiners[0].SrcAlpha = 0xEE0;
                    for (int qq = 1; qq < 6; qq++)
                    {
                        cmdl.Materials[i].FragShader.TextureCombiners[qq].SrcRgb   = 0xEEF;
                        cmdl.Materials[i].FragShader.TextureCombiners[qq].SrcAlpha = 0xEEF;
                    }
                    Bitmap tex = Textures[MatLib.Materials.IndexOf(MatLib.GetMaterialByName(MatNames[i]))];
                    if (tex != null)
                    {
                        cmdl.Materials[i].NrActiveTextureCoordiators  = 1;
                        cmdl.Materials[i].TextureCoordiators[0].Scale = new LibEveryFileExplorer.Collections.Vector2(1, 1);
                        cmdl.Materials[i].Tex0 = new CMDL.MTOB.TexInfo(MatNames[i]);
                        cmdl.Materials[i].FragShader.TextureCombiners[0].SrcRgb       = 0xE30;
                        cmdl.Materials[i].FragShader.TextureCombiners[0].SrcAlpha     = 0xE30;
                        cmdl.Materials[i].FragShader.TextureCombiners[0].CombineRgb   = 1;
                        cmdl.Materials[i].FragShader.TextureCombiners[0].CombineAlpha = 1;
                    }
                }
            }
            //Shapes
            {
                cmdl.NrShapes = (uint)MatNames.Count;
                cmdl.Shapes   = new CMDL.SeparateDataShape[MatNames.Count];
                for (int i = 0; i < MatNames.Count; i++)
                {
                    cmdl.Shapes[i] = new CMDL.SeparateDataShape();
                    Vector3 min       = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue);
                    Vector3 max       = new Vector3(float.MinValue, float.MinValue, float.MinValue);
                    int     nrfaces   = 0;
                    bool    texcoords = false;
                    foreach (var f in Model.Faces)
                    {
                        if (f.Material != MatNames[i])
                        {
                            continue;
                        }
                        nrfaces++;
                        if (f.TexCoordIndieces.Count > 0)
                        {
                            texcoords = true;
                        }
                        foreach (var qqq in f.VertexIndieces)
                        {
                            if (Model.Vertices[qqq].X < min.X)
                            {
                                min.X = Model.Vertices[qqq].X;
                            }
                            if (Model.Vertices[qqq].Y < min.Y)
                            {
                                min.Y = Model.Vertices[qqq].Y;
                            }
                            if (Model.Vertices[qqq].Z < min.Z)
                            {
                                min.Z = Model.Vertices[qqq].Z;
                            }
                            if (Model.Vertices[qqq].X > max.X)
                            {
                                max.X = Model.Vertices[qqq].X;
                            }
                            if (Model.Vertices[qqq].Y > max.Y)
                            {
                                max.Y = Model.Vertices[qqq].Y;
                            }
                            if (Model.Vertices[qqq].Z > max.Z)
                            {
                                max.Z = Model.Vertices[qqq].Z;
                            }
                        }
                    }
                    ((OrientedBoundingBox)cmdl.Shapes[i].BoundingBox).CenterPosition = (min + max) / 2;
                    ((OrientedBoundingBox)cmdl.Shapes[i].BoundingBox).Size           = max - min;
                    cmdl.Shapes[i].NrPrimitiveSets  = 1;
                    cmdl.Shapes[i].PrimitiveSets    = new CMDL.SeparateDataShape.PrimitiveSet[1];
                    cmdl.Shapes[i].PrimitiveSets[0] = new CMDL.SeparateDataShape.PrimitiveSet();
                    cmdl.Shapes[i].PrimitiveSets[0].NrPrimitives  = 1;
                    cmdl.Shapes[i].PrimitiveSets[0].Primitives    = new CMDL.SeparateDataShape.PrimitiveSet.Primitive[1];
                    cmdl.Shapes[i].PrimitiveSets[0].Primitives[0] = new CMDL.SeparateDataShape.PrimitiveSet.Primitive();
                    cmdl.Shapes[i].PrimitiveSets[0].Primitives[0].NrBufferObjects = 1;
                    cmdl.Shapes[i].PrimitiveSets[0].Primitives[0].BufferObjects   = new uint[] { 0 };
                    cmdl.Shapes[i].PrimitiveSets[0].Primitives[0].NrIndexStreams  = 1;
                    cmdl.Shapes[i].PrimitiveSets[0].Primitives[0].IndexStreams    = new CMDL.SeparateDataShape.PrimitiveSet.Primitive.IndexStreamCtr[1];
                    cmdl.Shapes[i].PrimitiveSets[0].Primitives[0].IndexStreams[0] = new CMDL.SeparateDataShape.PrimitiveSet.Primitive.IndexStreamCtr();
                    if (nrfaces * 3 > 255)
                    {
                        cmdl.Shapes[i].PrimitiveSets[0].Primitives[0].IndexStreams[0].FormatType = 0x1403;
                    }
                    cmdl.Shapes[i].PrimitiveSets[0].Primitives[0].IndexStreams[0].FaceDataLength = (uint)(nrfaces * 3 * ((nrfaces * 3 > 255) ? 2 : 1));
                    cmdl.Shapes[i].PrimitiveSets[0].Primitives[0].IndexStreams[0].FaceData       = new byte[cmdl.Shapes[i].PrimitiveSets[0].Primitives[0].IndexStreams[0].FaceDataLength];
                    int offs = 0;
                    int idx  = 0;
                    foreach (var f in Model.Faces)
                    {
                        if (f.Material != MatNames[i])
                        {
                            continue;
                        }
                        if (nrfaces * 3 > 255)
                        {
                            IOUtil.WriteU16LE(cmdl.Shapes[i].PrimitiveSets[0].Primitives[0].IndexStreams[0].FaceData, offs, (ushort)idx);
                            IOUtil.WriteU16LE(cmdl.Shapes[i].PrimitiveSets[0].Primitives[0].IndexStreams[0].FaceData, offs + 2, (ushort)(idx + 1));
                            IOUtil.WriteU16LE(cmdl.Shapes[i].PrimitiveSets[0].Primitives[0].IndexStreams[0].FaceData, offs + 4, (ushort)(idx + 2));
                            offs += 2 * 3;
                        }
                        else
                        {
                            cmdl.Shapes[i].PrimitiveSets[0].Primitives[0].IndexStreams[0].FaceData[idx]     = (byte)idx;
                            cmdl.Shapes[i].PrimitiveSets[0].Primitives[0].IndexStreams[0].FaceData[idx + 1] = (byte)(idx + 1);
                            cmdl.Shapes[i].PrimitiveSets[0].Primitives[0].IndexStreams[0].FaceData[idx + 2] = (byte)(idx + 2);
                            offs += 3;
                        }
                        idx += 3;
                    }
                    cmdl.Shapes[i].NrVertexAttributes = 2;
                    cmdl.Shapes[i].VertexAttributes   = new CMDL.SeparateDataShape.VertexAttributeCtr[2];
                    //interleaved
                    cmdl.Shapes[i].VertexAttributes[0] = new CMDL.SeparateDataShape.InterleavedVertexStreamCtr();
                    ((CMDL.SeparateDataShape.InterleavedVertexStreamCtr)cmdl.Shapes[i].VertexAttributes[0]).NrVertexStreams  = (texcoords ? 2u : 1u);
                    ((CMDL.SeparateDataShape.InterleavedVertexStreamCtr)cmdl.Shapes[i].VertexAttributes[0]).VertexStreams    = new CMDL.SeparateDataShape.InterleavedVertexStreamCtr.VertexStreamCtr[texcoords ? 2 : 1];
                    ((CMDL.SeparateDataShape.InterleavedVertexStreamCtr)cmdl.Shapes[i].VertexAttributes[0]).VertexStreams[0] = new CMDL.SeparateDataShape.InterleavedVertexStreamCtr.VertexStreamCtr(CMDL.SeparateDataShape.VertexAttributeCtr.VertexAttributeUsage.Position, CMDL.SeparateDataShape.DataType.GL_FLOAT, 3, 0);
                    if (texcoords)
                    {
                        ((CMDL.SeparateDataShape.InterleavedVertexStreamCtr)cmdl.Shapes[i].VertexAttributes[0]).VertexStreams[1] = new CMDL.SeparateDataShape.InterleavedVertexStreamCtr.VertexStreamCtr(CMDL.SeparateDataShape.VertexAttributeCtr.VertexAttributeUsage.TextureCoordinate0, CMDL.SeparateDataShape.DataType.GL_FLOAT, 2, 12);
                    }
                    ((CMDL.SeparateDataShape.InterleavedVertexStreamCtr)cmdl.Shapes[i].VertexAttributes[0]).VertexDataEntrySize = (texcoords ? 20u : 12u);
                    byte[] Result = new byte[nrfaces * 3 * ((CMDL.SeparateDataShape.InterleavedVertexStreamCtr)cmdl.Shapes[i].VertexAttributes[0]).VertexDataEntrySize];
                    offs = 0;
                    foreach (var f in Model.Faces)
                    {
                        if (f.Material != MatNames[i])
                        {
                            continue;
                        }
                        for (int qqq = 0; qqq < 3; qqq++)
                        {
                            Vector3 Pos = Model.Vertices[f.VertexIndieces[qqq]];
                            IOUtil.WriteSingleLE(Result, offs, Pos.X);
                            IOUtil.WriteSingleLE(Result, offs + 4, Pos.Y);
                            IOUtil.WriteSingleLE(Result, offs + 8, Pos.Z);
                            offs += 12;
                            if (texcoords)
                            {
                                Vector2 Tex = Model.TexCoords[f.TexCoordIndieces[qqq]];
                                IOUtil.WriteSingleLE(Result, offs, Tex.X);
                                IOUtil.WriteSingleLE(Result, offs + 4, Tex.Y);
                                offs += 8;
                            }
                        }
                    }
                    ((CMDL.SeparateDataShape.InterleavedVertexStreamCtr)cmdl.Shapes[i].VertexAttributes[0]).VertexStreamLength = (uint)Result.Length;
                    ((CMDL.SeparateDataShape.InterleavedVertexStreamCtr)cmdl.Shapes[i].VertexAttributes[0]).VertexStream       = Result;
                    //color
                    cmdl.Shapes[i].VertexAttributes[1] = new CMDL.SeparateDataShape.VertexParamAttributeCtr(CMDL.SeparateDataShape.VertexAttributeCtr.VertexAttributeUsage.Color, 1, 1, 1, MatLib.GetMaterialByName(MatNames[i]).Alpha);
                }
            }
            if (NrTextures != 0)
            {
                c.Data.Dictionaries[1] = new DICT();
                c.Data.Textures        = new TXOB[NrTextures];
                int qqq = 0;
                int idx = 0;
                foreach (Bitmap b in Textures)
                {
                    if (b == null)
                    {
                        qqq++; continue;
                    }
                    c.Data.Dictionaries[1].Add(MatLib.Materials[qqq].Name);
                    c.Data.Textures[idx] = new ImageTextureCtr(MatLib.Materials[qqq].Name, b, GPU.Textures.ImageFormat.ETC1A4);
                    idx++;
                    qqq++;
                }
            }
        }
Example #14
0
        protected override void _Read(BinaryReader reader)
        {
            List <Vector3> vertices = new List <Vector3>();
            List <Vector3> normals  = new List <Vector3>();
            List <Vector2> uvs      = new List <Vector2>();

            Dictionary <int, Vertex> nodeVertices = new Dictionary <int, Vertex>();

            MeshFace currentFace = null;

            int currentTextureIndex = -1;

            MTL mtl = null;

            Textures.Clear();
            RootNode         = new ModelNode();
            RootNode.HasMesh = true;

            bool hasUV              = false;
            bool hasNormals         = false;
            bool faceTextureChanged = false;

            string[] lines = reader.ReadToEnd().Split('\n');
            foreach (string line in lines)
            {
                if (line.StartsWith("#") || String.IsNullOrEmpty(line))
                {
                    continue;
                }
                else if (line.StartsWith("mtllib "))
                {
                    string[] values = line.Split(' ');
                    if (values.Length < 2)
                    {
                        continue;
                    }

                    string mtlPath = "";
                    string dir     = Path.GetDirectoryName(FilePath);
                    mtlPath = String.Format("{0}\\{1}", Path.GetDirectoryName(FilePath), values[1]);

                    if (File.Exists(mtlPath))
                    {
                        mtl      = new MTL(mtlPath);
                        Textures = mtl.Textures;
                    }
                }
                else if (line.StartsWith("v "))
                {
                    string[] values = line.Split(' ');
                    if (values.Length < 4)
                    {
                        continue;
                    }
                    Vector3 vertex = new Vector3();
                    vertex.X = float.Parse(values[1], m_cultureInfo);
                    vertex.Y = float.Parse(values[2], m_cultureInfo);
                    vertex.Z = float.Parse(values[3], m_cultureInfo);
                    RootNode.VertexPositions.Add(vertex);
                }
                else if (line.StartsWith("vt "))
                {
                    string[] values = line.Split(' ');
                    if (values.Length < 3)
                    {
                        continue;
                    }
                    Vector2 uv = new Vector2();
                    uv.X = float.Parse(values[1], m_cultureInfo);
                    uv.Y = float.Parse(values[2], m_cultureInfo);
                    RootNode.VertexUVs.Add(uv);
                }
                else if (line.StartsWith("vn "))
                {
                    string[] values = line.Split(' ');
                    if (values.Length < 4)
                    {
                        continue;
                    }
                    Vector3 normal = new Vector3();
                    normal.X = float.Parse(values[1], m_cultureInfo);
                    normal.Y = float.Parse(values[2], m_cultureInfo);
                    normal.Z = float.Parse(values[3], m_cultureInfo);
                    RootNode.VertexNormals.Add(normal);
                }
                else if (line.StartsWith("f "))
                {
                    if (currentFace == null)
                    {
                        continue;
                    }

                    if (line.Contains("//"))
                    {
                        string[] stringSeparators = new string[] { "//" };

                        string[] values = line.Split(' ');
                        if (values.Length < 4)
                        {
                            continue;
                        }

                        string[] vert1Values = values[1].Split(stringSeparators, StringSplitOptions.None);
                        string[] vert2Values = values[2].Split(stringSeparators, StringSplitOptions.None);
                        string[] vert3Values = values[3].Split(stringSeparators, StringSplitOptions.None);

                        currentFace.PositionIndices.Add((ushort)(int.Parse(vert1Values[0]) - 1));
                        currentFace.NormalIndices.Add((ushort)(int.Parse(vert1Values[1]) - 1));
                        currentFace.PositionIndices.Add((ushort)(int.Parse(vert2Values[0]) - 1));
                        currentFace.NormalIndices.Add((ushort)(int.Parse(vert2Values[1]) - 1));
                        currentFace.PositionIndices.Add((ushort)(int.Parse(vert3Values[0]) - 1));
                        currentFace.NormalIndices.Add((ushort)(int.Parse(vert3Values[1]) - 1));
                    }
                    else if (line.Contains("/"))
                    {
                        string[] stringSeparators = new string[] { "/" };

                        string[] values = line.Split(' ');
                        if (values.Length < 4)
                        {
                            continue;
                        }

                        string[] vert1Values = values[1].Split(stringSeparators, StringSplitOptions.None);
                        string[] vert2Values = values[2].Split(stringSeparators, StringSplitOptions.None);
                        string[] vert3Values = values[3].Split(stringSeparators, StringSplitOptions.None);

                        currentFace.PositionIndices.Add((ushort)(int.Parse(vert1Values[0]) - 1));
                        currentFace.UVIndices.Add((ushort)(int.Parse(vert1Values[1]) - 1));
                        if (vert1Values.Length > 2)
                        {
                            currentFace.NormalIndices.Add((ushort)(int.Parse(vert1Values[2]) - 1));
                        }

                        currentFace.PositionIndices.Add((ushort)(int.Parse(vert2Values[0]) - 1));
                        currentFace.UVIndices.Add((ushort)(int.Parse(vert2Values[1]) - 1));
                        if (vert2Values.Length > 2)
                        {
                            currentFace.NormalIndices.Add((ushort)(int.Parse(vert2Values[2]) - 1));
                        }

                        currentFace.PositionIndices.Add((ushort)(int.Parse(vert3Values[0]) - 1));
                        currentFace.UVIndices.Add((ushort)(int.Parse(vert3Values[1]) - 1));
                        if (vert3Values.Length > 2)
                        {
                            currentFace.NormalIndices.Add((ushort)(int.Parse(vert3Values[2]) - 1));
                        }
                    }
                    else
                    {
                        string[] values = line.Split(' ');
                        if (values.Length < 4)
                        {
                            continue;
                        }

                        currentFace.PositionIndices.Add((ushort)(int.Parse(values[0]) - 1));
                        currentFace.PositionIndices.Add((ushort)(int.Parse(values[1]) - 1));
                        currentFace.PositionIndices.Add((ushort)(int.Parse(values[2]) - 1));
                    }
                }
                else if (line.StartsWith("usemtl "))
                {
                    if (mtl == null)
                    {
                        continue;
                    }
                    string[] values = line.Split(' ');
                    if (values.Length < 2)
                    {
                        continue;
                    }

                    if (faceTextureChanged)
                    {
                        RootNode.Faces.Add(currentFace);
                    }
                    currentFace              = new MeshFace();
                    currentTextureIndex      = mtl.GetMaterialTextureIndex(values[1]);
                    currentFace.TextureIndex = (uint)currentTextureIndex;
                    faceTextureChanged       = true;
                }
                else if (line.StartsWith("o ") || line.StartsWith("g "))
                {
                    if (currentFace != null)
                    {
                        RootNode.Faces.Add(currentFace);
                    }
                    currentFace        = new MeshFace();
                    faceTextureChanged = false;
                }
            }
            RootNode.Faces.Add(currentFace);
            RootNode.ResolveFaceTextures(Textures);
        }
Example #15
0
        protected override void _Write(BinaryWriter writer)
        {
            int objNum = 0;

            int totalPositions = 0;
            int totalNormals   = 0;
            int totalUVs       = 0;

            MTL mtl = new MTL(Textures);

            if (String.IsNullOrEmpty(FilePath))
            {
                //TODO: Make this somehow better
                throw new ArgumentException("Filepath was not given.");
            }

            string mtlPath = "";
            string dir     = Path.GetDirectoryName(FilePath);

            if (String.IsNullOrEmpty(dir) || dir == "\\" || Path.GetExtension(FilePath) == ".OBJ" || Path.GetExtension(FilePath) == ".obj")
            {
                mtlPath = Path.ChangeExtension(FilePath, ".mtl");
            }
            else
            {
                mtlPath = String.Format("{0}\\{1}", Path.GetDirectoryName(FilePath), Path.ChangeExtension(FilePath, ".mtl"));
            }
            mtl.Write(mtlPath);

            writer.WriteASCII("# OBJ Generated by ShenmueDKSharp\n");

            writer.WriteASCII(String.Format("mtllib {0}\n", Path.GetFileName(mtlPath)));

            StringBuilder sbVertices = new StringBuilder();
            StringBuilder sbNormals  = new StringBuilder();
            StringBuilder sbUVs      = new StringBuilder();

            StringBuilder sbMeshes = new StringBuilder();

            foreach (ModelNode node in RootNode.GetAllNodes())
            {
                Matrix4 transformMatrix = node.GetTransformMatrix();

                if (node.Faces.Count == 0)
                {
                    continue;
                }

                Vector3[] positions = node.VertexPositions.ToArray();
                Vector3[] normals   = node.VertexNormals.ToArray();
                Vector2[] uvs       = node.VertexUVs.ToArray();
                if (positions.Length == 0)
                {
                    continue;
                }

                sbMeshes.Append(String.Format("o obj_{0}\n", objNum));

                for (int i = 0; i < positions.Length; i++)
                {
                    positions[i] = Vector3.TransformPosition(positions[i], transformMatrix);
                    sbVertices.Append(String.Format(m_cultureInfo, "v {0:F6} {1:F6} {2:F6}\n", positions[i].X, positions[i].Y, positions[i].Z));
                }

                if (uvs.Length > 0)
                {
                    for (int i = 0; i < uvs.Length; i++)
                    {
                        sbUVs.Append(String.Format(m_cultureInfo, "vt {0:F6} {1:F6}\n", uvs[i].X, uvs[i].Y));
                    }
                }

                if (normals.Length > 0)
                {
                    for (int i = 0; i < normals.Length; i++)
                    {
                        //normals[i] = Vector3.TransformPosition(normals[i], transformMatrix);
                        sbNormals.Append(String.Format(m_cultureInfo, "vn {0:F6} {1:F6} {2:F6}\n", normals[i].X, normals[i].Y, normals[i].Z));
                    }
                }

                foreach (MeshFace face in node.Faces)
                {
                    uint    textureIndex = face.TextureIndex;
                    Texture texture      = face.Material.Texture;

                    if (textureIndex < mtl.MaterialNames.Count)
                    {
                        sbMeshes.Append(String.Format("usemtl {0}\n", mtl.MaterialNames[(int)textureIndex]));
                    }
                    sbMeshes.Append("s 1\n");

                    bool hasUV     = face.UVIndices.Count > 0;
                    bool hasNormal = face.NormalIndices.Count > 0;

                    if (face.Type == MeshFace.PrimitiveType.Triangles)
                    {
                        for (int i = 0; i < face.PositionIndices.Count - 2; i += 3)
                        {
                            int posIndex1 = face.PositionIndices[i] + totalPositions + 1;
                            int posIndex2 = face.PositionIndices[i + 1] + totalPositions + 1;
                            int posIndex3 = face.PositionIndices[i + 2] + totalPositions + 1;
                            if (hasNormal)
                            {
                                int normIndex1 = face.NormalIndices[i] + totalNormals + 1;
                                int normIndex2 = face.NormalIndices[i + 1] + totalNormals + 1;
                                int normIndex3 = face.NormalIndices[i + 2] + totalNormals + 1;
                                if (hasUV)
                                {
                                    int uvIndex1 = face.UVIndices[i] + totalUVs + 1;
                                    int uvIndex2 = face.UVIndices[i + 1] + totalUVs + 1;
                                    int uvIndex3 = face.UVIndices[i + 2] + totalUVs + 1;
                                    sbMeshes.Append(String.Format(GetVertexFormatString(hasUV, hasNormal), posIndex1, posIndex2, posIndex3,
                                                                  uvIndex1, uvIndex2, uvIndex3,
                                                                  normIndex1, normIndex2, normIndex3));
                                }
                                else
                                {
                                    sbMeshes.Append(String.Format(GetVertexFormatString(hasUV, hasNormal), posIndex1, posIndex2, posIndex3,
                                                                  normIndex1, normIndex2, normIndex3));
                                }
                            }
                            else
                            {
                                sbMeshes.Append(String.Format(GetVertexFormatString(hasUV, hasNormal), posIndex1, posIndex2, posIndex3));
                            }
                        }
                    }
                    else if (face.Type == MeshFace.PrimitiveType.TriangleStrip)
                    {
                        for (int i = 0; i < face.PositionIndices.Count - 2; i++)
                        {
                            int posIndex1 = face.PositionIndices[i] + totalPositions + 1;
                            int posIndex2 = face.PositionIndices[i + 1] + totalPositions + 1;
                            int posIndex3 = face.PositionIndices[i + 2] + totalPositions + 1;
                            if (hasNormal)
                            {
                                int normIndex1 = face.NormalIndices[i] + totalNormals + 1;
                                int normIndex2 = face.NormalIndices[i + 1] + totalNormals + 1;
                                int normIndex3 = face.NormalIndices[i + 2] + totalNormals + 1;
                                if (hasUV)
                                {
                                    int uvIndex1 = face.UVIndices[i] + totalUVs + 1;
                                    int uvIndex2 = face.UVIndices[i + 1] + totalUVs + 1;
                                    int uvIndex3 = face.UVIndices[i + 2] + totalUVs + 1;
                                    if ((i & 1) == 1)
                                    {
                                        sbMeshes.Append(String.Format(GetVertexFormatString(hasUV, hasNormal), posIndex1, posIndex2, posIndex3,
                                                                      uvIndex1, uvIndex2, uvIndex3,
                                                                      normIndex1, normIndex2, normIndex3));
                                    }
                                    else
                                    {
                                        sbMeshes.Append(String.Format(GetVertexFormatString(hasUV, hasNormal), posIndex1, posIndex3, posIndex2,
                                                                      uvIndex1, uvIndex3, uvIndex2,
                                                                      normIndex1, normIndex3, normIndex2));
                                    }
                                }
                                else
                                {
                                    if ((i & 1) == 1)
                                    {
                                        sbMeshes.Append(String.Format(GetVertexFormatString(hasUV, hasNormal), posIndex1, posIndex2, posIndex3,
                                                                      normIndex1, normIndex2, normIndex3));
                                    }
                                    else
                                    {
                                        sbMeshes.Append(String.Format(GetVertexFormatString(hasUV, hasNormal), posIndex1, posIndex3, posIndex2,
                                                                      normIndex1, normIndex3, normIndex2));
                                    }
                                }
                            }
                            else
                            {
                                if ((i & 1) == 1)
                                {
                                    sbMeshes.Append(String.Format(GetVertexFormatString(hasUV, hasNormal), posIndex1, posIndex2, posIndex3));
                                }
                                else
                                {
                                    sbMeshes.Append(String.Format(GetVertexFormatString(hasUV, hasNormal), posIndex1, posIndex3, posIndex2));
                                }
                            }
                        }
                    }
                }
                objNum++;
                totalPositions += positions.Length;
                totalNormals   += normals.Length;
                totalUVs       += uvs.Length;
            }

            writer.WriteASCII(sbVertices.ToString());
            writer.WriteASCII(sbUVs.ToString());
            writer.WriteASCII(sbNormals.ToString());
            writer.WriteASCII(sbMeshes.ToString());
            writer.WriteASCII(String.Format("# Total Positions: {0}\n", totalPositions));
            writer.WriteASCII(String.Format("# Total Normals: {0}\n", totalNormals));
            writer.WriteASCII(String.Format("# Total UVs: {0}\n", totalUVs));
        }
Example #16
0
 public MTL ToMTL()
 {
     MTL m = new MTL();
     foreach (var v in Materials)
     {
         MTL.MTLMaterial mm = new MTL.MTLMaterial("M" + v.Key + "M");
         mm.DiffuseColor = Color.White;
         mm.DiffuseMapPath = "Tex/" + v.Key + ".png";
         m.Materials.Add(mm);
     }
     return m;
 }
Example #17
0
 public MTL ToMTL(String TexDir)
 {
     var o = new MTL();
     var m = this;//Data.Models[Model];
     //foreach (CMDL m in Models)
     {
         foreach (var vv in m.Materials)
         {
             MTL.MTLMaterial mm = new MTL.MTLMaterial(vv.Name);
             mm.DiffuseColor = vv.MaterialColor.DiffuseU32;
             mm.AmbientColor = vv.MaterialColor.AmbientU32;
             mm.Alpha = vv.MaterialColor.Diffuse.W;
             mm.SpecularColor = vv.MaterialColor.Specular0U32;
             if (vv.Tex0 != null && vv.Tex0.TextureObject is ReferenceTexture) mm.DiffuseMapPath = TexDir.Replace('\\', '/').TrimEnd('/') + "/" + ((ReferenceTexture)vv.Tex0.TextureObject).LinkedTextureName + ".png";
             o.Materials.Add(mm);
         }
     }
     return o;
 }
 public static void FromOBJ(CGFX c, String OBJPath, String ModelName = "EFEModel")
 {
     OBJ Model = new OBJ(File.ReadAllBytes(OBJPath));
     if (Model.MTLPath == null) throw new Exception("Model without materials not supported!");
     String MtlPath = Path.GetDirectoryName(OBJPath) + "\\" + Model.MTLPath;
     MTL MatLib = new MTL(File.ReadAllBytes(MtlPath));
     List<String> MatNames = new List<string>();
     foreach (var f in Model.Faces)
     {
         if (!MatNames.Contains(f.Material)) MatNames.Add(f.Material);
     }
     Bitmap[] Textures = new Bitmap[MatLib.Materials.Count];
     int q = 0;
     int NrTextures = 0;
     foreach (var v in MatLib.Materials)
     {
         if (!MatNames.Contains(v.Name)) { q++; continue; }
         if (v.DiffuseMapPath != null)
         {
             Textures[q] = new Bitmap(new MemoryStream(File.ReadAllBytes(Path.GetDirectoryName(MtlPath) + "\\" + v.DiffuseMapPath)));
             NrTextures++;
         }
         q++;
     }
     c.Data.Dictionaries[0] = new DICT();
     c.Data.Dictionaries[0].Add(ModelName);
     c.Data.Models = new CMDL[1];
     c.Data.Models[0] = new CMDL(ModelName);
     CMDL cmdl = c.Data.Models[0];
     //Mesh Node Visibility
     {
         cmdl.NrMeshNodes = 1;
         cmdl.MeshNodeVisibilitiesDict = new DICT();
         cmdl.MeshNodeVisibilitiesDict.Add("CompleteModel");
         cmdl.MeshNodeVisibilities = new CMDL.MeshNodeVisibilityCtr[] { new CMDL.MeshNodeVisibilityCtr("CompleteModel") };
     }
     //Meshes
     {
         cmdl.NrMeshes = (uint)MatNames.Count;
         cmdl.Meshes = new CMDL.Mesh[MatNames.Count];
         for (int i = 0; i < MatNames.Count; i++)
         {
             cmdl.Meshes[i] = new CMDL.Mesh();
             cmdl.Meshes[i].MeshNodeName = "CompleteModel";
             cmdl.Meshes[i].MaterialIndex = (uint)i;
             cmdl.Meshes[i].ShapeIndex = (uint)i;
         }
     }
     //Materials
     {
         cmdl.NrMaterials = (uint)MatNames.Count;
         cmdl.MaterialsDict = new DICT();
         cmdl.Materials = new CMDL.MTOB[MatNames.Count];
         for (int i = 0; i < MatNames.Count; i++)
         {
             cmdl.MaterialsDict.Add(MatNames[i]);
             cmdl.Materials[i] = new CMDL.MTOB(MatNames[i]);
             cmdl.Materials[i].FragShader.TextureCombiners[0].SrcRgb = 0xEE0;
             cmdl.Materials[i].FragShader.TextureCombiners[0].SrcAlpha = 0xEE0;
             for (int qq = 1; qq < 6; qq++)
             {
                 cmdl.Materials[i].FragShader.TextureCombiners[qq].SrcRgb = 0xEEF;
                 cmdl.Materials[i].FragShader.TextureCombiners[qq].SrcAlpha = 0xEEF;
             }
             Bitmap tex = Textures[MatLib.Materials.IndexOf(MatLib.GetMaterialByName(MatNames[i]))];
             if (tex != null)
             {
                 cmdl.Materials[i].NrActiveTextureCoordiators = 1;
                 cmdl.Materials[i].TextureCoordiators[0].Scale = new LibEveryFileExplorer.Collections.Vector2(1, 1);
                 cmdl.Materials[i].Tex0 = new CMDL.MTOB.TexInfo(MatNames[i]);
                 cmdl.Materials[i].FragShader.TextureCombiners[0].SrcRgb = 0xE30;
                 cmdl.Materials[i].FragShader.TextureCombiners[0].SrcAlpha = 0xE30;
                 cmdl.Materials[i].FragShader.TextureCombiners[0].CombineRgb = 1;
                 cmdl.Materials[i].FragShader.TextureCombiners[0].CombineAlpha = 1;
             }
         }
     }
     //Shapes
     {
         cmdl.NrShapes = (uint)MatNames.Count;
         cmdl.Shapes = new CMDL.SeparateDataShape[MatNames.Count];
         for (int i = 0; i < MatNames.Count; i++)
         {
             cmdl.Shapes[i] = new CMDL.SeparateDataShape();
             Vector3 min = new Vector3(float.MaxValue, float.MaxValue, float.MaxValue);
             Vector3 max = new Vector3(float.MinValue, float.MinValue, float.MinValue);
             int nrfaces = 0;
             bool texcoords = false;
             foreach (var f in Model.Faces)
             {
                 if (f.Material != MatNames[i]) continue;
                 nrfaces++;
                 if (f.TexCoordIndieces.Count > 0) texcoords = true;
                 foreach (var qqq in f.VertexIndieces)
                 {
                     if (Model.Vertices[qqq].X < min.X) min.X = Model.Vertices[qqq].X;
                     if (Model.Vertices[qqq].Y < min.Y) min.Y = Model.Vertices[qqq].Y;
                     if (Model.Vertices[qqq].Z < min.Z) min.Z = Model.Vertices[qqq].Z;
                     if (Model.Vertices[qqq].X > max.X) max.X = Model.Vertices[qqq].X;
                     if (Model.Vertices[qqq].Y > max.Y) max.Y = Model.Vertices[qqq].Y;
                     if (Model.Vertices[qqq].Z > max.Z) max.Z = Model.Vertices[qqq].Z;
                 }
             }
             ((OrientedBoundingBox)cmdl.Shapes[i].BoundingBox).CenterPosition = (min + max) / 2;
             ((OrientedBoundingBox)cmdl.Shapes[i].BoundingBox).Size = max - min;
             cmdl.Shapes[i].NrPrimitiveSets = 1;
             cmdl.Shapes[i].PrimitiveSets = new CMDL.SeparateDataShape.PrimitiveSet[1];
             cmdl.Shapes[i].PrimitiveSets[0] = new CMDL.SeparateDataShape.PrimitiveSet();
             cmdl.Shapes[i].PrimitiveSets[0].NrPrimitives = 1;
             cmdl.Shapes[i].PrimitiveSets[0].Primitives = new CMDL.SeparateDataShape.PrimitiveSet.Primitive[1];
             cmdl.Shapes[i].PrimitiveSets[0].Primitives[0] = new CMDL.SeparateDataShape.PrimitiveSet.Primitive();
             cmdl.Shapes[i].PrimitiveSets[0].Primitives[0].NrBufferObjects = 1;
             cmdl.Shapes[i].PrimitiveSets[0].Primitives[0].BufferObjects = new uint[] { 0 };
             cmdl.Shapes[i].PrimitiveSets[0].Primitives[0].NrIndexStreams = 1;
             cmdl.Shapes[i].PrimitiveSets[0].Primitives[0].IndexStreams = new CMDL.SeparateDataShape.PrimitiveSet.Primitive.IndexStreamCtr[1];
             cmdl.Shapes[i].PrimitiveSets[0].Primitives[0].IndexStreams[0] = new CMDL.SeparateDataShape.PrimitiveSet.Primitive.IndexStreamCtr();
             if (nrfaces * 3 > 255) cmdl.Shapes[i].PrimitiveSets[0].Primitives[0].IndexStreams[0].FormatType = 0x1403;
             cmdl.Shapes[i].PrimitiveSets[0].Primitives[0].IndexStreams[0].FaceDataLength = (uint)(nrfaces * 3 * ((nrfaces * 3 > 255) ? 2 : 1));
             cmdl.Shapes[i].PrimitiveSets[0].Primitives[0].IndexStreams[0].FaceData = new byte[cmdl.Shapes[i].PrimitiveSets[0].Primitives[0].IndexStreams[0].FaceDataLength];
             int offs = 0;
             int idx = 0;
             foreach (var f in Model.Faces)
             {
                 if (f.Material != MatNames[i]) continue;
                 if (nrfaces * 3 > 255)
                 {
                     IOUtil.WriteU16LE(cmdl.Shapes[i].PrimitiveSets[0].Primitives[0].IndexStreams[0].FaceData, offs, (ushort)idx);
                     IOUtil.WriteU16LE(cmdl.Shapes[i].PrimitiveSets[0].Primitives[0].IndexStreams[0].FaceData, offs + 2, (ushort)(idx + 1));
                     IOUtil.WriteU16LE(cmdl.Shapes[i].PrimitiveSets[0].Primitives[0].IndexStreams[0].FaceData, offs + 4, (ushort)(idx + 2));
                     offs += 2 * 3;
                 }
                 else
                 {
                     cmdl.Shapes[i].PrimitiveSets[0].Primitives[0].IndexStreams[0].FaceData[idx] = (byte)idx;
                     cmdl.Shapes[i].PrimitiveSets[0].Primitives[0].IndexStreams[0].FaceData[idx + 1] = (byte)(idx + 1);
                     cmdl.Shapes[i].PrimitiveSets[0].Primitives[0].IndexStreams[0].FaceData[idx + 2] = (byte)(idx + 2);
                     offs += 3;
                 }
                 idx += 3;
             }
             cmdl.Shapes[i].NrVertexAttributes = 2;
             cmdl.Shapes[i].VertexAttributes = new CMDL.SeparateDataShape.VertexAttributeCtr[2];
             //interleaved
             cmdl.Shapes[i].VertexAttributes[0] = new CMDL.SeparateDataShape.InterleavedVertexStreamCtr();
             ((CMDL.SeparateDataShape.InterleavedVertexStreamCtr)cmdl.Shapes[i].VertexAttributes[0]).NrVertexStreams = (texcoords ? 2u : 1u);
             ((CMDL.SeparateDataShape.InterleavedVertexStreamCtr)cmdl.Shapes[i].VertexAttributes[0]).VertexStreams = new CMDL.SeparateDataShape.InterleavedVertexStreamCtr.VertexStreamCtr[texcoords ? 2 : 1];
             ((CMDL.SeparateDataShape.InterleavedVertexStreamCtr)cmdl.Shapes[i].VertexAttributes[0]).VertexStreams[0] = new CMDL.SeparateDataShape.InterleavedVertexStreamCtr.VertexStreamCtr(CMDL.SeparateDataShape.VertexAttributeCtr.VertexAttributeUsage.Position, CMDL.SeparateDataShape.DataType.GL_FLOAT, 3, 0);
             if (texcoords) ((CMDL.SeparateDataShape.InterleavedVertexStreamCtr)cmdl.Shapes[i].VertexAttributes[0]).VertexStreams[1] = new CMDL.SeparateDataShape.InterleavedVertexStreamCtr.VertexStreamCtr(CMDL.SeparateDataShape.VertexAttributeCtr.VertexAttributeUsage.TextureCoordinate0, CMDL.SeparateDataShape.DataType.GL_FLOAT, 2, 12);
             ((CMDL.SeparateDataShape.InterleavedVertexStreamCtr)cmdl.Shapes[i].VertexAttributes[0]).VertexDataEntrySize = (texcoords ? 20u : 12u);
             byte[] Result = new byte[nrfaces * 3 * ((CMDL.SeparateDataShape.InterleavedVertexStreamCtr)cmdl.Shapes[i].VertexAttributes[0]).VertexDataEntrySize];
             offs = 0;
             foreach (var f in Model.Faces)
             {
                 if (f.Material != MatNames[i]) continue;
                 for (int qqq = 0; qqq < 3; qqq++)
                 {
                     Vector3 Pos = Model.Vertices[f.VertexIndieces[qqq]];
                     IOUtil.WriteSingleLE(Result, offs, Pos.X);
                     IOUtil.WriteSingleLE(Result, offs + 4, Pos.Y);
                     IOUtil.WriteSingleLE(Result, offs + 8, Pos.Z);
                     offs += 12;
                     if (texcoords)
                     {
                         Vector2 Tex = Model.TexCoords[f.TexCoordIndieces[qqq]];
                         IOUtil.WriteSingleLE(Result, offs, Tex.X);
                         IOUtil.WriteSingleLE(Result, offs + 4, Tex.Y);
                         offs += 8;
                     }
                 }
             }
             ((CMDL.SeparateDataShape.InterleavedVertexStreamCtr)cmdl.Shapes[i].VertexAttributes[0]).VertexStreamLength = (uint)Result.Length;
             ((CMDL.SeparateDataShape.InterleavedVertexStreamCtr)cmdl.Shapes[i].VertexAttributes[0]).VertexStream = Result;
             //color
             cmdl.Shapes[i].VertexAttributes[1] = new CMDL.SeparateDataShape.VertexParamAttributeCtr(CMDL.SeparateDataShape.VertexAttributeCtr.VertexAttributeUsage.Color, 1, 1, 1, MatLib.GetMaterialByName(MatNames[i]).Alpha);
         }
     }
     if (NrTextures != 0)
     {
         c.Data.Dictionaries[1] = new DICT();
         c.Data.Textures = new TXOB[NrTextures];
         int qqq = 0;
         int idx = 0;
         foreach (Bitmap b in Textures)
         {
             if (b == null) { qqq++; continue; }
             c.Data.Dictionaries[1].Add(MatLib.Materials[qqq].Name);
             c.Data.Textures[idx] = new ImageTextureCtr(MatLib.Materials[qqq].Name, b, GPU.Textures.ImageFormat.ETC1A4);
             idx++;
             qqq++;
         }
     }
 }