Пример #1
0
        /// <summary>
        /// Read a binary MDL file
        /// a real mess !
        /// return true on success
        /// </summary>
        /// <param name="sFileName"></param>
        /// <returns></returns>
        public bool ReadFromFile(string sFileName)
        {
            FileStream cf;

            try
            {
                cf = new FileStream(sFileName, FileMode.Open, FileAccess.Read, FileShare.Read);
            }
            catch
            {
                return(false);
            }
            BinaryReader br     = new BinaryReader(cf);
            uint         cookie = br.ReadUInt32();

            if (cookie != 0xDEBADF00)
            {
                br.Close();
                cf.Close();
                return(false);
            }
            MDLHeader header = new MDLHeader();

            if (!header.ReadHeader(br))
            {
                br.Close();
                cf.Close();
                return(false);
            }
            NumTextures = 0;
            for (int i = 0; i < header.nb_tags; i++)
            {
                string tag = ParseString(br);
                header.TagsNames[i] = tag;
                if ((tag != "model") && (tag != "effect"))
                {
                    NumTextures++;
                }
            }
            int idx = 0;

            int[] TexturesIdx = new int[NumTextures];
            if (NumTextures != 0)
            {
                Textures = new string[NumTextures];
                for (int i = 0; i < header.nb_tags; i++)
                {
                    string tag = header.TagsNames[i];
                    if ((tag != "model") && (tag != "effect"))
                    {
                        Textures[idx]    = tag;
                        TexturesIdx[idx] = i;
                        idx++;
                    }
                }
            }

            // ASSERT(idx==NumTextures);
            for (int i = 0; i < header.l2; i++)
            {
                int    uk1 = br.ReadInt32();
                string tag = ParseString(br);
                header.L2Vals[i].Name  = tag;
                header.L2Vals[i].Value = uk1;
            }
            for (int i = 0; i < header.l3; i++)
            {
                string tag = ParseString(br);
                header.l3names[i] = tag;
            }
            // LOOP LEVEL 3

            int lastText = -1;

            //MDLObject lastObject = new MDLObject();
            MDLObject [] stackedObjects = new MDLObject[500];
            int[]        stack          = new int[200];
            int          sopos          = -1;

            for (int L3 = 0; L3 < header.l3; L3++)
            {
                int  l3val    = br.ReadInt32();
                bool cont     = true;
                int  stackpos = -1;
                // LOOL LEVEL 2
                while (cont)
                {
                    int token = br.ReadInt32();
                    switch (token)
                    {
                    case 5:
                    {
                        // start of group
                        // push # val
                        int nentry = br.ReadInt32();
                        stack[++stackpos] = nentry;
                        break;
                    }

                    case 9:
                    {
                        int l2idx = br.ReadInt32();
                        if ((l2idx < 0) || (l2idx > header.l2))
                        {
                            //ReadError.Format("unmatched l2idx = %s",l2idx);
                            cont = false;
                            break;
                        }
                        else
                        {
                            string l2type  = header.L2Vals[l2idx].Name;
                            bool   matched = false;
                            if (l2type == "MeshGeo")
                            {
                                matched = true;
                                int datatype = br.ReadInt32();
                                if (datatype != 7)
                                {
                                    cont = false;
                                    break;
                                }
                                MDLMesh mesh = new MDLMesh();
                                mesh.nvertex  = br.ReadInt32();
                                mesh.nfaces   = br.ReadInt32();
                                mesh.vertices = new MDLVertice[mesh.nvertex];
                                for (int n = 0; n < mesh.nvertex; n++)
                                {
                                    // read vertice
                                    MDLVertice vert = new MDLVertice();
                                    vert.x           = br.ReadSingle();
                                    vert.y           = br.ReadSingle();;
                                    vert.z           = br.ReadSingle();;
                                    vert.mx          = br.ReadSingle();;
                                    vert.my          = br.ReadSingle();;
                                    vert.nx          = br.ReadSingle();;
                                    vert.ny          = br.ReadSingle();;
                                    vert.nz          = br.ReadSingle();;
                                    mesh.vertices[n] = vert;
                                }
                                mesh.faces = new ushort[mesh.nfaces];
                                for (int n = 0; n < mesh.nfaces; n++)
                                {
                                    mesh.faces[n] = br.ReadUInt16();
                                }
                                stackedObjects[++sopos]    = NewMDLObject();
                                stackedObjects[sopos].mesh = mesh;
                                stackedObjects[sopos].type = MDLType.mdl_mesh;
                            }
                            if (l2type == "ModifiableNumber")
                            {
                                int six = br.ReadInt32();
                                matched = true;
                            }
                            if (l2type == "LightsGeo")
                            {
                                matched = true;
                                int datatype = br.ReadInt32();
                                if (datatype != 7)
                                {
                                    // ReadError.Format("bad data %d in LightsGeo",datatype);
                                    cont = false;
                                    break;
                                }
                                if (NumLights != 0)
                                {
                                    // ReadError.Format("double ligths!!!");
                                    cont = false;
                                    break;
                                }
                                int nlite = br.ReadInt32();
                                NumLights = nlite;
                                Lights    = new MDLLight[nlite];
                                for (int n = 0; n < nlite; n++)
                                {
                                    MDLLight lite = new MDLLight();
                                    lite.Read(br);
                                    Lights[n] = lite;
                                }
                            }
                            if (l2type == "FrameData")
                            {
                                matched = true;
                                int datatype = br.ReadInt32();
                                if (datatype != 7)
                                {
                                    //ReadError.Format("bad data %d in FrameData",datatype);
                                    cont = false;
                                    break;
                                }
                                if (NumFrameDatas != 0)
                                {
                                    // ReadError.Format("double framedata!!!");
                                    cont = false;
                                    break;
                                }
                                int ndata = br.ReadInt32();
                                NumFrameDatas = ndata;
                                FrameDatas    = new MDLFrameData[ndata];
                                for (int n = 0; n < ndata; n++)
                                {
                                    MDLFrameData data = new MDLFrameData();
                                    data.name = ParseString(br);
                                    data.Read(br);
                                    FrameDatas[n] = data;
                                }
                            }
                            if (l2type == "TextureGeo")
                            {
                                matched = true;
                                int six = br.ReadInt32();
                                // ASSERT(lastObject != NULL);
                                stackedObjects[sopos].textidx = lastText;
                            }
                            if (l2type == "LODGeo")
                            {
                                matched = true;
                                int       six        = br.ReadInt32();
                                MDLObject lastObject = NewMDLObject();
                                lastObject.type      = MDLType.mdl_lod;
                                lastObject.nchildren = stack[stackpos] + 1;
                                lastObject.childrens = new MDLObject[lastObject.nchildren];
                                for (int n = 0; n < lastObject.nchildren; n++)
                                {
                                    lastObject.childrens[n] = stackedObjects[sopos--];
                                }
                                stackedObjects[++sopos] = lastObject;
                                stackpos--;
                            }
                            if (l2type == "GroupGeo")
                            {
                                matched = true;
                                int       six        = br.ReadInt32();
                                MDLObject lastObject = NewMDLObject();
                                lastObject.type      = MDLType.mdl_group;
                                lastObject.nchildren = stack[stackpos];
                                lastObject.childrens = new MDLObject[lastObject.nchildren];
                                for (int n = 0; n < lastObject.nchildren; n++)
                                {
                                    lastObject.childrens[n] = stackedObjects[sopos--];
                                }
                                stackedObjects[++sopos] = lastObject;
                                stackpos--;
                            }
                            if (l2type == "time")
                            {
                                matched = true;
                                //ReadError.Format("!!time!!"),
                                cont = false;
                                break;
                            }
                            if (l2type == "ImportImage")
                            {
                                matched = true;
                                cont    = false;
                                int datatype = br.ReadInt32();
                                if (datatype != 7)
                                {
                                    // ReadError.Format("bad data %d in ImportImage",datatype);
                                    cont = false;
                                    break;
                                }
                                MDLImage img = new MDLImage(0, 0);
                                img.Read(br);
                                stackedObjects[++sopos]     = NewMDLObject();
                                stackedObjects[sopos].image = img;
                                stackedObjects[sopos].type  = MDLType.mdl_image;
                                break;
                            }
                            if (!matched)
                            {
                                for (int n = 0; n < header.nb_tags; n++)
                                {
                                    if (l2type == header.TagsNames[n])
                                    {
                                        matched  = true;
                                        lastText = -1;
                                        for (int p = 0; p < NumTextures; p++)
                                        {
                                            if (TexturesIdx[p] == header.L2Vals[l2idx].Value)
                                            {
                                                lastText = p;
                                            }
                                        }
                                        // ASSERT(lastText != -1);
                                    }
                                }
                            }
                            if (!matched)
                            {
                                //ReadError.Format("unmatched l2type = %s\n",l2type);
                                cont = false;
                                break;
                            }
                        }
                        break;
                    }

                    case 1:
                    {
                        float val = br.ReadSingle();
                        if (header.l3names[L3] == "frame")
                        {
                            FrameVal = val;
                        }
                        else
                        {
                            // ASSERT(lastObject != NULL);
                            stackedObjects[sopos].lodval = val;
                        }
                        break;
                    }

                    case 10:
                    {
                        // handle 10
                        break;
                    }

                    case 0:
                    {
                        if (stackpos >= 0)
                        {                                //stack[stackpos] -=1;
                        }
                        else
                        {
                            cont = false;
                        }
                        break;
                    }

                    default:
                        //ReadError.Format("unknow token = %d\n",token);
                        cont = false;
                        break;
                    }     // switch
                }         // while(cont)
            }             // l3
            RootObject = stackedObjects[sopos];
            br.Close();
            cf.Close();
            return(true);
        }
Пример #2
0
        /// <summary>
        /// Read a binary MDL file
        /// a real mess !
        /// return true on success
        /// </summary>
        /// <param name="sFileName"></param>
        /// <returns></returns>
        public bool ReadFromFile(string sFileName)
        {
            FileStream cf;

            try
            {
                cf = new FileStream(sFileName, FileMode.Open, FileAccess.Read, FileShare.Read);
            }
            catch
            {
                return(false);
            }
            BinaryReader br = new BinaryReader(cf);



            header = new MDLHeader();
            if (!header.ReadHeader(br))
            {
                br.Close();
                cf.Close();
                return(false);
            }

            // Read in namespaces
            for (int i = 0; i < header.ImportedNameSpacesCount; i++)
            {
                string tag = ReadAlignedString(br);
                header.NameSpaces.Add(tag);
                //if ((tag != "model") && (tag != "effect"))
                //     NumTextures++;
            }
            // Count number of names spaecs we dont recognize and assume they are texture namespaces.
            NumTextures = header.NameSpaces.Count(x => x != "model" && x != "effect");

            Textures = header.NameSpaces.Where(x => x != "model" && x != "effect").ToDictionary(x => x, x => this.header.NameSpaces.IndexOf(x));

            // ASSERT(idx==NumTextures);
            for (int i = 0; i < header.ImportedSymoblCount; i++)
            {
                int        uk1 = br.ReadInt32();
                string     tag = ReadAlignedString(br);
                SymbolPair sp;
                sp.Name  = tag;
                sp.Value = uk1;
                header.ImportedSymbols.Add(sp);
            }

            for (int i = 0; i < header.ExportedSymbolCount; i++)
            {
                string tag = ReadAlignedString(br);
                header.ExportedSymbols.Add(tag);
            }
            // LOOP LEVEL 3

            int lastText = -1;

            //MDLObject lastObject = new MDLObject();
            MDLObject[] stackedObjects = new MDLObject[500];
            int[]       stack          = new int[200];
            int         sopos          = -1;

            for (int L3 = 0; L3 < header.ExportedSymbolCount; L3++)
            {
                int  l3val    = br.ReadInt32();
                bool cont     = true;
                int  stackpos = -1;
                // LOOL LEVEL 2
                while (cont)
                {
                    int token = br.ReadInt32();
                    switch (token)
                    {
                    case 5:
                    {
                        // start of group
                        // push # val
                        int nentry = br.ReadInt32();
                        stack[++stackpos] = nentry;
                        break;
                    }

                    case 9:
                    {
                        int l2idx = br.ReadInt32();
                        if ((l2idx < 0) || (l2idx > header.ImportedSymoblCount))
                        {
                            //ReadError.Format("unmatched l2idx = %s",l2idx);
                            cont = false;
                            break;
                        }
                        else
                        {
                            string l2type  = header.ImportedSymbols[l2idx].Name;
                            bool   matched = false;
                            if (l2type == "MeshGeo")
                            {
                                matched = true;
                                int datatype = br.ReadInt32();
                                if (datatype != 7)
                                {
                                    cont = false;
                                    break;
                                }
                                MDLMesh mesh = new MDLMesh();
                                mesh.nvertex  = br.ReadInt32();
                                mesh.nfaces   = br.ReadInt32();
                                mesh.vertices = new MDLVertice[mesh.nvertex];
                                for (int n = 0; n < mesh.nvertex; n++)
                                {
                                    // read vertice
                                    MDLVertice vert = new MDLVertice();
                                    vert.x           = br.ReadSingle();
                                    vert.y           = br.ReadSingle();;
                                    vert.z           = br.ReadSingle();;
                                    vert.mx          = br.ReadSingle();;
                                    vert.my          = br.ReadSingle();;
                                    vert.nx          = br.ReadSingle();;
                                    vert.ny          = br.ReadSingle();;
                                    vert.nz          = br.ReadSingle();;
                                    mesh.vertices[n] = vert;
                                }
                                mesh.faces = new ushort[mesh.nfaces];
                                for (int n = 0; n < mesh.nfaces; n++)
                                {
                                    mesh.faces[n] = br.ReadUInt16();
                                }
                                stackedObjects[++sopos]    = NewMDLObject();
                                stackedObjects[sopos].mesh = mesh;
                                stackedObjects[sopos].type = MDLType.mdl_mesh;
                            }
                            if (l2type == "ModifiableNumber")
                            {
                                int six = br.ReadInt32();
                                matched = true;
                            }
                            if (l2type == "LightsGeo")
                            {
                                matched = true;
                                int datatype = br.ReadInt32();
                                if (datatype != 7)
                                {
                                    // ReadError.Format("bad data %d in LightsGeo",datatype);
                                    cont = false;
                                    break;
                                }
                                if (NumLights != 0)
                                {
                                    // ReadError.Format("double ligths!!!");
                                    cont = false;
                                    break;
                                }
                                int nlite = br.ReadInt32();
                                NumLights = nlite;
                                Lights    = new List <MDLLight>();
                                for (int n = 0; n < nlite; n++)
                                {
                                    MDLLight lite = new MDLLight();
                                    lite.Read(br);
                                    Lights.Add(lite);
                                }
                            }
                            if (l2type == "FrameData")
                            {
                                matched = true;
                                int datatype = br.ReadInt32();
                                if (datatype != 7)
                                {
                                    //ReadError.Format("bad data %d in FrameData",datatype);
                                    cont = false;
                                    break;
                                }
                                if (NumFrameDatas != 0)
                                {
                                    // ReadError.Format("double framedata!!!");
                                    cont = false;
                                    break;
                                }
                                int ndata = br.ReadInt32();
                                NumFrameDatas = ndata;
                                FrameDatas    = new List <MDLFrameData>();
                                for (int n = 0; n < ndata; n++)
                                {
                                    MDLFrameData data = new MDLFrameData();
                                    data.name = ReadAlignedString(br);
                                    data.Read(br);
                                    FrameDatas.Add(data);
                                }
                            }
                            if (l2type == "TextureGeo")
                            {
                                matched = true;
                                int six = br.ReadInt32();
                                // ASSERT(lastObject != NULL);
                                stackedObjects[sopos].textidx = lastText;
                            }
                            if (l2type == "LODGeo")
                            {
                                matched = true;
                                int       six        = br.ReadInt32();
                                MDLObject lastObject = NewMDLObject();
                                lastObject.type      = MDLType.mdl_lod;
                                lastObject.nchildren = stack[stackpos] + 1;
                                lastObject.childrens = new MDLObject[lastObject.nchildren];
                                for (int n = 0; n < lastObject.nchildren; n++)
                                {
                                    lastObject.childrens[n] = stackedObjects[sopos--];
                                }
                                stackedObjects[++sopos] = lastObject;
                                stackpos--;
                            }
                            if (l2type == "GroupGeo")
                            {
                                matched = true;
                                int       six        = br.ReadInt32();
                                MDLObject lastObject = NewMDLObject();
                                lastObject.type      = MDLType.mdl_group;
                                lastObject.nchildren = stack[stackpos];
                                lastObject.childrens = new MDLObject[lastObject.nchildren];
                                for (int n = 0; n < lastObject.nchildren; n++)
                                {
                                    lastObject.childrens[n] = stackedObjects[sopos--];
                                }
                                stackedObjects[++sopos] = lastObject;
                                stackpos--;
                            }
                            if (l2type == "time")
                            {
                                matched = true;
                                //ReadError.Format("!!time!!"),
                                cont = false;
                                break;
                            }
                            if (l2type == "ImportImage")
                            {
                                matched = true;
                                cont    = false;
                                int datatype = br.ReadInt32();
                                if (datatype != 7)
                                {
                                    // ReadError.Format("bad data %d in ImportImage",datatype);
                                    cont = false;
                                    break;
                                }
                                MDLImage img = new MDLImage();
                                img.Read(br);
                                stackedObjects[++sopos]     = NewMDLObject();
                                stackedObjects[sopos].image = img;
                                stackedObjects[sopos].type  = MDLType.mdl_image;
                                break;
                            }
                            if (!matched)
                            {
                                for (int n = 0; n < header.ImportedNameSpacesCount; n++)
                                {
                                    if (l2type == header.NameSpaces[n])
                                    {
                                        matched  = true;
                                        lastText = -1;
                                        for (int p = 0; p < NumTextures; p++)
                                        {
                                            if (Textures.ElementAt(p).Value == header.ImportedSymbols[l2idx].Value)
                                            {
                                                lastText = p;
                                            }
                                        }
                                        // ASSERT(lastText != -1);
                                    }
                                }
                            }
                            if (!matched)
                            {
                                //ReadError.Format("unmatched l2type = %s\n",l2type);
                                cont = false;
                                break;
                            }
                        }
                        break;
                    }

                    case 1:
                    {
                        float val = br.ReadSingle();
                        if (header.ExportedSymbols[L3] == "frame")
                        {
                            FrameVal = val;
                        }
                        else
                        {
                            // ASSERT(lastObject != NULL);
                            stackedObjects[sopos].lodval = val;
                        }
                        break;
                    }

                    case 10:
                    {
                        // handle 10
                        break;
                    }

                    case 0:
                    {
                        if (stackpos >= 0)
                        {        //stack[stackpos] -=1;
                        }
                        else
                        {
                            cont = false;
                        }
                        break;
                    }

                    default:
                        //ReadError.Format("unknow token = %d\n",token);
                        cont = false;
                        break;
                    } // switch
                }     // while(cont)
            }         // l3
            RootObject = new List <MDLObject>(stackedObjects.Where(x => x != null));//[sopos];
            br.Close();
            cf.Close();
            return(true);
        }