Exemple #1
0
        private void WriteMtl(ThreeDModel m3d, string mtlfn)
        {
            var opts  = Program.Options;
            var clr   = opts.OverrideColor;
            var dn    = this.fi.Directory.FullName;
            var p     = Path.Combine(dn, string.Concat(mtlfn, ".mtl"));
            var mtlfi = new FileInfo(p);

            using (var fs = mtlfi.Create())
                using (var sw = new StreamWriter(fs, new UTF8Encoding(false)))
                {
                    sw.NewLine = "\n";

                    sw.WriteLine("# Generated using MSET Converter by John Cena of PTF");
                    sw.WriteLine("# mset Version: {0}", Program.GetAssemblyVersion());
                    sw.WriteLine("# mset-obj Version: {0}", this.VersionID);
                    sw.WriteLine();
                    sw.WriteLine("# Default MSET material");
                    sw.WriteLine("newmtl JCMSet");
                    sw.WriteLine("Kd {0:0.000000} {1:0.000000} {2:0.000000}", clr.RFloat, clr.GFloat, clr.BFloat);
                    sw.WriteLine("d  {0:0.000000}", clr.AFloat);
                    sw.WriteLine("Tr {0:0.000000}", 1F - clr.AFloat);
                    sw.WriteLine();

                    sw.Flush();
                }

            if (opts.VerboseMode)
            {
                ULogger.W("OBJMTL", "Written MTL: {0}", mtlfi.FullName);
            }
        }
Exemple #2
0
        private static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
        {
            var ex = e.ExceptionObject != null && e.ExceptionObject is Exception ? (Exception)e.ExceptionObject : null;

            ULogger.W("ERR", "An error has occured within the application");
            if (ex != null)
            {
                ULogger.X("ERR", ex);
            }
            else
            {
                ULogger.W("ERR", "FATAL: No details are avaialble");
            }
        }
Exemple #3
0
 internal static void PrintUse()
 {
     ULogger.W("APP", "Usage: mset2 <arguments...> <files>");
     ULogger.N("APP");
     ULogger.W("APP", "Extraction options:");
     ULogger.W("APP", "  -e:<encoder>");
     ULogger.W("APP", "  Specifies output encoder. <encoder> must be a valid encoder. For available encoders, see readme.");
     ULogger.W("APP", "  Default value: OBJ");
     ULogger.N("APP");
     ULogger.W("APP", "  -d:<path>");
     ULogger.W("APP", "  Specifies output directory. <path> must be a valid directory path.");
     ULogger.W("APP", "  Default value: <null> (outputs to source files' directory)");
     ULogger.N("APP");
     ULogger.W("APP", "  -l");
     ULogger.W("APP", "  Lists models in a file then exists.");
     ULogger.N("APP");
     ULogger.W("APP", "  -m:<model_name>");
     ULogger.W("APP", "  Specifies extracting a specific model from input file(s). <model_name> is a model to extract.");
     ULogger.W("APP", "  Default value: <null> (extracts all models)");
     ULogger.N("APP");
     ULogger.W("APP", "  -c:<color>");
     ULogger.W("APP", "  Overrides vertex colors on resulting mesh. <color> is an unsigned 32-bit integer containing ARGB information.");
     ULogger.W("APP", "  Default value: <null> (does not override colors)");
     ULogger.N("APP");
     ULogger.W("APP", "  -o:<options>");
     ULogger.W("APP", "  Specifies selected encoder's options. <options> is a string of comma-separated key-value pairs. For examples and available encoder options, see readme.");
     ULogger.W("APP", "  Default value: <null> (use default options)");
     ULogger.N("APP");
     ULogger.W("APP", "  -r");
     ULogger.W("APP", "  Creates raw mesh dumps alongside output files. These are UTF-8-encoded text files describing raw input data.");
     ULogger.N("APP");
     ULogger.W("APP", "Program options:");
     ULogger.W("APP", "  -v");
     ULogger.W("APP", "  Enables verbose logging to console.");
     ULogger.N("APP");
     ULogger.W("APP", "  -v:<path>");
     ULogger.W("APP", "  Enables logging to file. Supersedes -v. <path> must be a valid file path.");
     ULogger.N("APP");
     ULogger.W("APP", "  -help");
     ULogger.W("APP", "  Prints this message and quits.");
     ULogger.N("APP");
 }
Exemple #4
0
        /*
         * COMMANDLINE OPTIONS
         *
         * Extraction options:
         *   -e:<encoder>
         *   Specifies output encoder. <encoder> must be a valid encoder. For available encoders, see readme.
         *   Default value: OBJ
         *
         *   -d:<path>
         *   Specifies output directory. <path> must be a valid directory path.
         *   Default value: <null> (outputs to source files' directory)
         *
         *   -l
         *   Lists models in a file then exists.
         *
         *   -m:<model_name>
         *   Specifies extracting a specific model from input file(s). <model_name> is a model to extract.
         *   Default value: <null> (extracts all models)
         *
         *   -c:<color>
         *   Overrides vertex colors on resulting mesh. <color> is an unsigned 32-bit integer containing ARGB information.
         *   Default value: <null> (does not override colors)
         *
         *   -o:<options>
         *   Specifies selected encoder's options. <options> is a string of comma-separated key-value pairs. For examples and available encoder options, see readme.
         *   Default value: <null> (use default options)
         *
         *   -r
         *   Creates raw mesh dumps alongside output files. These are UTF-8-encoded text files describing raw input data.
         *
         * Program options:
         *   -v
         *   Enables verbose logging to console.
         *
         *   -v:<path>
         *   Enables logging to file. Supersedes -v. <path> must be a valid file path.
         */
        internal static void Main(string[] args)
        {
            ULogger.D(Debugger.IsAttached);
            ULogger.R(Console.Out);

            ULogger.W("MSET2", "Initializing");

            AppDomain.CurrentDomain.UnhandledException += CurrentDomain_UnhandledException;

            var cmdl = ParseCommandLine(args);

            Options = cmdl;

            if (cmdl.VerboseMode)
            {
                if (cmdl.VerboseModeLogFile != null)
                {
                    var tw = new StreamWriter(cmdl.VerboseModeLogFile.Create(), new UTF8Encoding(false));
                    ULogger.R(tw);
                }

                ULogger.W("APP", "Commandline options:");
                ULogger.W("APP", "  Encoder: {0} (ver. {1})", cmdl.ModelWriter.WriterID, cmdl.ModelWriter.VersionID);
                ULogger.W("APP", "  Output path: {0}", cmdl.OutputDirectory != null ? cmdl.OutputDirectory.FullName : "<null>");
                ULogger.W("APP", "  Just list models: {0}", cmdl.ListModels ? "Yes" : "No");
                ULogger.W("APP", "  Model name: {0}", cmdl.ModelName != null ? cmdl.ModelName : "<null>");
                ULogger.W("APP", "  Override color: {0}", cmdl.IsColorDefined ? string.Format("Yes (RGBA #{0:X2}{1:X2}{2:X2}{3:X2})", cmdl.OverrideColor.R, cmdl.OverrideColor.G, cmdl.OverrideColor.B, cmdl.OverrideColor.A) : "No");
                ULogger.W("APP", "  Encoder options specified: {0}", cmdl.ModelWriterOptions.Count);
                ULogger.W("APP", "  Create raw meshes: {0}", cmdl.CreateRawMeshes ? "Yes" : "No");
                ULogger.W("APP", "  Verbose mode: {0}", cmdl.VerboseMode ? "Yes" : "No");
                ULogger.W("APP", "  Log file: {0}", cmdl.VerboseModeLogFile != null ? cmdl.VerboseModeLogFile.FullName : "<null>");
                ULogger.N("APP");
                ULogger.W("APP", "Invalid arguments specified: {0}", cmdl.HasInvalidArguments ? "Yes" : "No");
                ULogger.N("APP");
                ULogger.W("APP", "Input files ({0}):", cmdl.InputFiles.Count());
                foreach (var infile in cmdl.InputFiles)
                {
                    ULogger.W("APP", "'{0}'", infile.FullName);
                }
                ULogger.N("APP");
            }

            if (cmdl.HasInvalidArguments && cmdl.ArgumentException != null)
            {
                ULogger.X("APP", cmdl.ArgumentException);
                ULogger.N("APP");
            }

            if (cmdl.HelpMode || cmdl.HasInvalidArguments)
            {
                PrintUse();
                ULogger.Q();
                return;
            }

            var msetrdr = new MSetReader();
            var msetdmp = new RawDumper();

            foreach (var kvp in cmdl.ModelWriterOptions)
            {
                cmdl.ModelWriter.Options.Add(kvp.Key, kvp.Value);
            }
            var m3dw = cmdl.ModelWriter;
            var utf8 = new UTF8Encoding(false);

            try
            {
                foreach (var msetf in cmdl.InputFiles)
                {
                    if (cmdl.VerboseMode)
                    {
                        ULogger.W("MSETLDR", "Loading '{0}'", msetf.FullName);
                    }

                    var mset = msetrdr.Load(msetf);
                    var m3ds = msetrdr.Create3DModels(mset).ToList();

                    if (cmdl.VerboseMode)
                    {
                        ULogger.W("MSETLDR", "Loaded {0} models", m3ds.Count);
                    }

                    foreach (var m3d in m3ds)
                    {
                        ULogger.W("M3D", "Model '{0}' in file '{1}'", m3d.ModelName, msetf.FullName);
                        if (cmdl.ListModels)
                        {
                            continue;
                        }

                        if (cmdl.ModelName != null && m3d.ModelName != cmdl.ModelName)
                        {
                            continue;
                        }

                        ULogger.W("M3DWRTR", "Extracting '{0}'", m3d.ModelName);
                        var opath = cmdl.OutputDirectory != null ? cmdl.OutputDirectory.FullName : msetf.Directory.FullName;
                        //var msetn = msetf.Name.Substring(0, msetf.Name.Length - msetf.Extension.Length);
                        var msetn = m3d.ModelName;
                        msetn = string.Concat(msetn, m3dw.FileExtension);
                        opath = Path.Combine(opath, msetn);
                        var m3df = new FileInfo(opath);

                        m3dw.WriteModel(m3d, m3df);

                        if (cmdl.CreateRawMeshes)
                        {
                            if (cmdl.VerboseMode)
                            {
                                ULogger.W("M3D RAW", "Creating raw dump");
                            }

                            opath = string.Concat(opath, ".raw_3d");
                            var m3drf = new FileInfo(opath);

                            msetdmp.WriteRawMesh(m3d, msetf, m3drf, utf8);
                        }
                    }
                }
            }
            catch (Exception ex)
            {
                ULogger.W("APP ERROR", "CRITICAL: ERROR WHILE UNPACKING MSET");
                ULogger.X("APP ERROR", ex);
            }

            ULogger.W("MSET2", "Conversion completed");
            ULogger.Q();

            if (Debugger.IsAttached)
            {
                Console.ReadKey();
            }
        }
Exemple #5
0
        private void WriteInternal(ThreeDModel m3d)
        {
            var opts   = Program.Options;
            var usemtl = this.opts.ContainsKey("usemtl") && this.opts["usemtl"] == "true";

            if (usemtl && !opts.IsColorDefined)
            {
                ULogger.W("OBJWRITE", "usemtl set to true but no override color defined; ignoring...");
            }
            usemtl = usemtl && opts.IsColorDefined;
            if (!usemtl && opts.IsColorDefined && opts.OverrideColor.A != 255)
            {
                ULogger.W("OBJWRITE", "usemtl is not set to true, but override color has Alpha different from 255 -- it won't be written!");
            }

            this.tw.WriteLine("# Converted using MSET Converter by John Cena of PTF");
            this.tw.WriteLine("# mset Version: {0}", Program.GetAssemblyVersion());
            this.tw.WriteLine("# mset-obj Version: {0}", this.VersionID);
            this.tw.WriteLine("# ");
            this.tw.WriteLine("# Model Summary: ");
            this.tw.WriteLine("# Name: {0}", m3d.ModelName);
            this.tw.WriteLine("# Vertex Count: {0:#,##0} ", m3d.VertexCount);
            this.tw.WriteLine("# Face Count: {0:#,##0} ", m3d.FaceCount);
            this.tw.WriteLine("# ");
            this.tw.WriteLine("# Writer options:");
            foreach (var kvp in this.opts)
            {
                this.tw.WriteLine("# {0}={1}", kvp.Key, kvp.Value);
            }
            this.tw.WriteLine();

            var hasclr  = m3d.Colors != null;
            var hasnorm = m3d.Normals != null;
            var hastex  = m3d.TextureCoordinates != null;
            var mtlfn   = (string)null;

            if (this.fi != null && usemtl)
            {
                mtlfn = this.fi.Name.Substring(0, this.fi.Name.Length - this.fi.Extension.Length);
                this.tw.WriteLine("mtllib {0}.mtl", mtlfn);
            }

            this.tw.WriteLine("o Mset.1");
            this.tw.WriteLine();

            this.tw.WriteLine("# Vertices");
            //foreach (var vert in m3d.Vertices)
            for (int i = 0; i < m3d.VertexCount; i++)
            {
                var vert = m3d.Vertices[i];
                var clr  = hasclr && !usemtl ? m3d.Colors[i] : default(ThreeDColor);

                if (hasclr && !usemtl)
                {
                    this.tw.WriteLine("v {0:0.000000} {1:0.000000} {2:0.000000} {3:0.000000} {4:0.000000} {5:0.000000}", vert.X, vert.Y, vert.Z, clr.RFloat, clr.GFloat, clr.BFloat);
                }
                else
                {
                    this.tw.WriteLine("v {0:0.000000} {1:0.000000} {2:0.000000}", vert.X, vert.Y, vert.Z);
                }
            }
            this.tw.WriteLine("");

            if (hasnorm)
            {
                this.tw.WriteLine("# Normals");
                foreach (var norm in m3d.Normals)
                {
                    this.tw.WriteLine("vn {0:0.000000} {1:0.000000} {2:0.000000}", norm.X, norm.Y, norm.Z);
                }
                this.tw.WriteLine("");
            }

            if (hastex)
            {
                this.tw.WriteLine("# Texture Coordinates");
                foreach (var texcoord in m3d.TextureCoordinates)
                {
                    this.tw.WriteLine("vt {0:0.000000} {1:0.000000}", texcoord.U, texcoord.V);
                }
                this.tw.WriteLine("");
            }

            this.tw.WriteLine("# Faces");
            if (this.fi != null && usemtl)
            {
                this.tw.WriteLine("usemtl JCMset");
            }
            //foreach (var face in m3d.Faces)
            for (int i = 0; i < m3d.FaceCount; i++)
            {
                var face = m3d.Faces[i];

                if (hastex && hasnorm)
                {
                    this.tw.WriteLine("f {0:0}/{0:0}/{0:0} {1:0}/{1:0}/{1:0} {2:0}/{2:0}/{2:0}", face.Vertex1 + 1, face.Vertex2 + 1, face.Vertex3 + 1);
                }
                else if (hastex && !hasnorm)
                {
                    this.tw.WriteLine("f {0:0}/{0:0} {1:0}/{1:0} {2:0}/{2:0}", face.Vertex1 + 1, face.Vertex2 + 1, face.Vertex3 + 1);
                }
                else if (!hastex && hasnorm)
                {
                    this.tw.WriteLine("f {0:0}//{0:0} {1:0}//{1:0} {2:0}//{2:0}", face.Vertex1 + 1, face.Vertex2 + 1, face.Vertex3 + 1);
                }
                else
                {
                    this.tw.WriteLine("f {0:0} {1:0} {2:0}", face.Vertex1 + 1, face.Vertex2 + 1, face.Vertex3 + 1);
                }
            }
            this.tw.WriteLine("");

            this.tw.Flush();

            if (usemtl)
            {
                this.WriteMtl(m3d, mtlfn);
            }
        }
Exemple #6
0
        public IEnumerable <ThreeDModel> Create3DModels(MSetFile file)
        {
            var opts = Program.Options;
            var mzs  = file.Data;
            var mns  = new HashSet <string>();

            var ns = 0;

            foreach (var mz in mzs)
            {
                ns = Math.Max(ns, mz.Model);
            }

            var mzm = new MSetZlibStream[ns + 1, 12];

            for (int i = 0; i < mzs.Length; i++)
            {
                if (opts.VerboseMode)
                {
                    ULogger.W("3DMC", "Processing stream {0}", i);
                }

                var mz = mzs[i];

                int fc = file.Models[mz.Model].FaceCount;
                var vc = file.Models[mz.Model].VertexCount;

                var mzdat = new byte[mz.DecompressedLength];
                var y     = 0;

                if (mz.CompressedLength == 0 && mz.DecompressedLength > 0)
                {
                    while (y < mz.DecompressedLength)
                    {
                        y += mz.Data.Read(mzdat, y, mz.DecompressedLength - y);
                    }
                }
                else
                {
                    var mzlib = new ZlibStream(mz.Data, CompressionMode.Decompress);
                    while (y < mz.DecompressedLength)
                    {
                        y += mzlib.Read(mzdat, y, mz.DecompressedLength - y);
                    }
                }

                if (mz.IsEncoded)
                {
                    if (mz.DataStream == 0)
                    {
                        mzdat = DataOperations.DeltaDecompress(mzdat, DataType.I32S, 3, fc);
                    }
                    else if (mz.DataStream <= 4 || mz.DataStream >= 10)
                    {
                        mzdat = DataOperations.DeltaDecompress(mzdat, DataType.F32, 3, vc);
                    }
                    else if (mz.DataStream == 5 || mz.DataStream == 6)
                    {
                        mzdat = DataOperations.DeltaDecompress(mzdat, DataType.F32, 2, vc);
                    }
                }

                mz.DataProcessed             = mzdat;
                mzm[mz.Model, mz.DataStream] = mz;
            }

            if (file.Models.Length <= 0)
            {
                yield break;
            }

            for (int i = 0; i < ns + 1; i++)
            {
                if (opts.VerboseMode)
                {
                    ULogger.W("3DMC", "Processing model {0}", i);
                }

                var mz_tris     = mzm[i, 0];
                var mz_verts    = mzm[i, 1];
                var mz_norms    = mzm[i, 2];
                var mz_binorms  = mzm[i, 3];
                var mz_tangents = mzm[i, 4];
                var mz_sts      = mzm[i, 5];
                var mz_sts3     = mzm[i, 6];
                var mz_colors   = mzm[i, 7];
                //var mz_weights =  mzm[i, 8];
                //var mz_matidxs =  mzm[i, 9];
                var mz_verts2 = mzm[i, 10];
                var mz_norms2 = mzm[i, 11];

                int fc = file.Models[mz_tris.Model].FaceCount;
                var vc = file.Models[mz_tris.Model].VertexCount;

                // ...
                var l_tris     = mz_tris.DataProcessed != null ? new ThreeDFace[fc] : null;
                var l_verts    = mz_verts.DataProcessed != null ? new ThreeDVertex[vc] : null;
                var l_norms    = mz_norms.DataProcessed != null ? new ThreeDNormal[vc] : null;
                var l_binorms  = mz_binorms.DataProcessed != null ? new ThreeDBinormal[vc] : null;
                var l_tangents = mz_tangents.DataProcessed != null ? new ThreeDTangent[vc] : null;
                var l_sts      = mz_sts.DataProcessed != null ? new ThreeDTextureCoordinate[vc] : null;
                var l_sts3     = mz_sts3.DataProcessed != null ? new ThreeDTextureCoordinate[vc] : null;
                var l_colors   = mz_colors.DataProcessed != null ? new ThreeDColor[vc] : null;
                //var l_weights =  mz_matidxs.DataProcessed != null ? new ThreeDBoneWeight[] : null;
                //var l_matidxs =  mz_weights.DataProcessed != null ? new ThreeDBoneMaterials[] : null;
                var l_verts2 = mz_verts2.DataProcessed != null ? new ThreeDVertex[vc] : null;
                var l_norms2 = mz_norms2.DataProcessed != null ? new ThreeDNormal[vc] : null;

                if (l_tris != null)
                {
                    for (int j = 0; j < fc; j++)
                    {
                        int index = j * 12;

                        var f_v1 = BitConverter.ToInt32(mz_tris.DataProcessed, index + 0);
                        var f_v2 = BitConverter.ToInt32(mz_tris.DataProcessed, index + 4);
                        var f_v3 = BitConverter.ToInt32(mz_tris.DataProcessed, index + 8);

                        //l_tris.Add(new ThreeDFace(f_v1, f_v2, f_v3));
                        l_tris[j] = new ThreeDFace(f_v1, f_v2, f_v3);
                    }
                }

                for (int j = 0; j < vc; j++)
                {
                    int index1 = j * 12;
                    int index2 = j * 8;
                    int index3 = j * 4;

                    if (l_verts != null)
                    {
                        var v_x = BitConverter.ToSingle(mz_verts.DataProcessed, index1 + 0);
                        var v_y = BitConverter.ToSingle(mz_verts.DataProcessed, index1 + 4);
                        var v_z = BitConverter.ToSingle(mz_verts.DataProcessed, index1 + 8);

                        //l_verts.Add(new ThreeDVertex(v_x, v_y, v_z));
                        l_verts[j] = new ThreeDVertex(v_x, v_y, v_z);
                    }

                    if (l_norms != null)
                    {
                        var n_x = BitConverter.ToSingle(mz_norms.DataProcessed, index1 + 0);
                        var n_y = BitConverter.ToSingle(mz_norms.DataProcessed, index1 + 4);
                        var n_z = BitConverter.ToSingle(mz_norms.DataProcessed, index1 + 8);

                        //l_norms.Add(new ThreeDNormal(n_x, n_y, n_z));
                        l_norms[j] = new ThreeDNormal(n_x, n_y, n_z);
                    }

                    if (l_binorms != null)
                    {
                        var b_x = BitConverter.ToSingle(mz_binorms.DataProcessed, index1 + 0);
                        var b_y = BitConverter.ToSingle(mz_binorms.DataProcessed, index1 + 4);
                        var b_z = BitConverter.ToSingle(mz_binorms.DataProcessed, index1 + 8);

                        //l_binorms.Add(new ThreeDBinormal(b_x, b_y, b_z));
                        l_binorms[j] = new ThreeDBinormal(b_x, b_y, b_z);
                    }

                    if (l_tangents != null)
                    {
                        var t_x = BitConverter.ToSingle(mz_tangents.DataProcessed, index1 + 0);
                        var t_y = BitConverter.ToSingle(mz_tangents.DataProcessed, index1 + 4);
                        var t_z = BitConverter.ToSingle(mz_tangents.DataProcessed, index1 + 8);

                        //l_tangents.Add(new ThreeDTangent(t_x, t_y, t_z));
                        l_tangents[j] = new ThreeDTangent(t_x, t_y, t_z);
                    }

                    if (l_sts != null)
                    {
                        var t_u = BitConverter.ToSingle(mz_sts.DataProcessed, index2 + 0);
                        var t_v = 1F - BitConverter.ToSingle(mz_sts.DataProcessed, index2 + 4);

                        //l_sts.Add(new ThreeDTextureCoordinate(t_u, t_v));
                        l_sts[j] = new ThreeDTextureCoordinate(t_u, t_v);
                    }

                    if (l_sts3 != null)
                    {
                        var t_u = BitConverter.ToSingle(mz_sts3.DataProcessed, index2 + 0);
                        var t_v = 1F - BitConverter.ToSingle(mz_sts3.DataProcessed, index2 + 4);

                        //l_sts3.Add(new ThreeDTextureCoordinate(t_u, t_v));
                        l_sts3[j] = new ThreeDTextureCoordinate(t_u, t_v);
                    }

                    if (l_colors != null)
                    {
                        var c_r = mz_colors.DataProcessed[index3 + 0];
                        var c_g = mz_colors.DataProcessed[index3 + 1];
                        var c_b = mz_colors.DataProcessed[index3 + 2];
                        var c_a = mz_colors.DataProcessed[index3 + 3];

                        //l_colors.Add(new ThreeDColor(c_r, c_g, c_b, c_a));
                        l_colors[j] = new ThreeDColor(c_r, c_g, c_b, c_a);
                    }

                    if (l_verts2 != null)
                    {
                        var v_x = BitConverter.ToSingle(mz_verts2.DataProcessed, index1 + 0);
                        var v_y = BitConverter.ToSingle(mz_verts2.DataProcessed, index1 + 4);
                        var v_z = BitConverter.ToSingle(mz_verts2.DataProcessed, index1 + 8);

                        //l_verts2.Add(new ThreeDVertex(v_x, v_y, v_z));
                        l_verts2[j] = new ThreeDVertex(v_x, v_y, v_z);
                    }

                    if (l_norms2 != null)
                    {
                        var n_x = BitConverter.ToSingle(mz_norms2.DataProcessed, index1 + 0);
                        var n_y = BitConverter.ToSingle(mz_norms2.DataProcessed, index1 + 4);
                        var n_z = BitConverter.ToSingle(mz_norms2.DataProcessed, index1 + 8);

                        //l_norms2.Add(new ThreeDNormal(n_x, n_y, n_z));
                        l_norms2[j] = new ThreeDNormal(n_x, n_y, n_z);
                    }
                }

                var mname = this.GenerateUniqueName(mns, mz_tris.ModelName);
                mns.Add(mname);
                var m3d = new ThreeDModel
                {
                    ModelName   = mname,
                    VertexCount = vc,
                    FaceCount   = fc,

                    Faces = l_tris != null?Array.AsReadOnly(l_tris) : null,
                                Vertices = l_verts != null?Array.AsReadOnly(l_verts) : null,
                                               Normals = l_norms != null?Array.AsReadOnly(l_norms) : null,
                                                             Binormals = l_binorms != null?Array.AsReadOnly(l_binorms) : null,
                                                                             Tangents = l_tangents != null?Array.AsReadOnly(l_tangents) : null,
                                                                                            TextureCoordinates = l_sts != null?Array.AsReadOnly(l_sts) : null,
                                                                                                                     TextureCoordinates3 = l_sts3 != null?Array.AsReadOnly(l_sts3) : null,
                                                                                                                                               Colors = l_colors != null?Array.AsReadOnly(l_colors) : null,
                                                                                                                                                            //
                                                                                                                                                            //
                                                                                                                                                            Vertices2 = l_verts2 != null?Array.AsReadOnly(l_verts2) : null,
                                                                                                                                                                            Normals2 = l_norms2 != null?Array.AsReadOnly(l_norms2) : null
                };
                yield return(m3d);
            }
        }