示例#1
0
        /// <summary>
        /// Initializes a new instance of the <see cref="HaloModel"/> class.
        /// </summary>
        /// <param name="entry">The model Halo 2 index entry.</param>
        public HaloModel(MapFile map, IndexEntry entry)
        {
            //Check
            if (map == null)
            {
                throw new ArgumentNullException(nameof(map));
            }
            if (entry == null)
            {
                throw new ArgumentNullException(nameof(entry));
            }
            else if (entry.Root != HaloTags.mode)
            {
                throw new ArgumentException("Index entry is not render model.", nameof(entry));
            }

            //Setup
            this.map   = map;
            this.entry = entry;
            tag        = new ModelTag(entry);
            meshes     = new Mesh[tag.Regions.Length][][];

            //Setup property accessors
            compressionInfo = new CompressionInfoProperties(this);
            regions         = new RegionProperties[tag.Regions.Length];
            for (int i = 0; i < tag.Regions.Length; i++)
            {
                regions[i] = new RegionProperties(this, i);
            }
            permutations = new PermutationProperties[tag.Regions.Length][];
            for (int i = 0; i < tag.Regions.Length; i++)
            {
                permutations[i] = new PermutationProperties[tag.Permutations[i].Length];
                for (int j = 0; j < tag.Permutations[i].Length; j++)
                {
                    permutations[i][j] = new PermutationProperties(this, i, j);
                }
            }
            sections = new SectionProperties[tag.Sections.Length];
            for (int i = 0; i < tag.Sections.Length; i++)
            {
                sections[i] = new SectionProperties(this, i);
            }
            resources = new ResourceProperties[tag.Sections.Length][];
            for (int i = 0; i < tag.Sections.Length; i++)
            {
                resources[i] = new ResourceProperties[tag.Resources[i].Length];
                for (int j = 0; j < tag.Resources[i].Length; j++)
                {
                    resources[i][j] = new ResourceProperties(this, i, j);
                }
            }

            //Loop through regions
            for (int r = 0; r < tag.Regions.Length; r++)
            {
                //Setup
                ModelTagGroup.Region region = tag.Regions[r];
                meshes[r] = new Mesh[region.Permutations.Count][];

                //Loop through permutations
                for (int p = 0; p < region.Permutations.Count; p++)
                {
                    //Setup
                    ModelTagGroup.Region.Permutation permutation = tag.Permutations[r][p];
                    meshes[r][p] = new Mesh[6];

                    //Loop through LODs
                    byte[] sourceData = null;
                    for (int l = 0; l < 6; l++)
                    {
                        //Get source data
                        int sectionIndex = -1;
                        switch (l)
                        {
                        case 0: sectionIndex = permutation.L1SectionIndex; break;

                        case 1: sectionIndex = permutation.L2SectionIndex; break;

                        case 2: sectionIndex = permutation.L3SectionIndex; break;

                        case 3: sectionIndex = permutation.L4SectionIndex; break;

                        case 4: sectionIndex = permutation.L5SectionIndex; break;

                        case 5: sectionIndex = permutation.L6SectionIndex; break;
                        }

                        //Check
                        if (sectionIndex >= 0 && sectionIndex < sections.Length)
                        {
                            //Get properties
                            ModelTagGroup.Section section = tag.Sections[sectionIndex];

                            //Check
                            if (section.RawOffset != uint.MaxValue)
                            {
                                RawLocation rawLocation = (RawLocation)(section.RawOffset & 0xC0000000);
                                if (rawLocation == RawLocation.Local)
                                {
                                    sourceData = entry.Raws[RawSection.Model][(int)section.RawOffset].ToArray();
                                }
                                else
                                {
                                    string fileLocation = string.Empty;
                                    int    rawOffset    = (int)(section.RawOffset & (uint)RawLocation.LocalMask);
                                    switch (rawLocation)
                                    {
                                    case RawLocation.Shared:
                                        fileLocation = HaloSettings.SharedPath;
                                        break;

                                    case RawLocation.Mainmenu:
                                        fileLocation = HaloSettings.MainmenuPath;
                                        break;

                                    case RawLocation.SinglePlayerShared:
                                        fileLocation = HaloSettings.SingleplayerSharedPath;
                                        break;
                                    }

                                    //Check
                                    if (File.Exists(fileLocation))
                                    {
                                        using (FileStream fs = new FileStream(fileLocation, FileMode.Open))
                                            using (BinaryReader mapReader = new BinaryReader(fs))
                                            {
                                                fs.Seek(rawOffset, SeekOrigin.Begin);
                                                sourceData = mapReader.ReadBytes((int)section.RawSize);
                                            }
                                    }
                                }
                            }

                            //Set
                            if (sourceData.Length == 0)
                            {
                                continue;
                            }

                            //Dump
                            try
                            {
                                using (FileStream fs = new FileStream(@"F:\model.bin", FileMode.Create, FileAccess.ReadWrite, FileShare.Read))
                                    fs.Write(sourceData, 0, sourceData.Length);
                            }
                            catch { }

                            //Create Mesh
                            meshes[r][p][l] = Mesh.Halo2Mesh(resources[sectionIndex], sourceData);
                        }
                    }
                }
            }
        }
示例#2
0
            public ModelTag(IndexEntry entry)
            {
                //Prepare
                using (BinaryReader reader = entry.TagData.CreateReader())
                {
                    //Goto
                    entry.TagData.Seek(entry.Offset, SeekOrigin.Begin);

                    //Read Tag Header
                    Header = reader.Read <ModelTagGroup>();

                    //Read Compression Information
                    if (Header.CompressionInfos.Count > 0)
                    {
                        CompressionInfo = new ComponentCompression();
                        entry.TagData.Seek(Header.CompressionInfos.Offset, SeekOrigin.Begin);
                        CompressionInfo = reader.Read <ComponentCompression>();
                    }

                    //Read Regions
                    Regions = new ModelTagGroup.Region[Header.Regions.Count];
                    entry.TagData.Seek(Header.Regions.Offset, SeekOrigin.Begin);
                    for (int i = 0; i < Header.Regions.Count; i++)
                    {
                        Regions[i] = reader.Read <ModelTagGroup.Region>();
                    }

                    //Read Perumtations
                    Permutations = new ModelTagGroup.Region.Permutation[Header.Regions.Count][];
                    for (int i = 0; i < Header.Regions.Count; i++)
                    {
                        Permutations[i] = new ModelTagGroup.Region.Permutation[Regions[i].Permutations.Count];
                        entry.TagData.Seek(Regions[i].Permutations.Offset, SeekOrigin.Begin);
                        for (int j = 0; j < Regions[i].Permutations.Count; j++)
                        {
                            Permutations[i][j] = reader.Read <ModelTagGroup.Region.Permutation>();
                        }
                    }

                    //Read Sections
                    Sections = new ModelTagGroup.Section[Header.Sections.Count];
                    entry.TagData.Seek(Header.Sections.Offset, SeekOrigin.Begin);
                    for (int i = 0; i < Header.Sections.Count; i++)
                    {
                        Sections[i] = reader.Read <ModelTagGroup.Section>();
                    }

                    //Read Resources
                    Resources = new ModelTagGroup.Section.Resource[Header.Sections.Count][];
                    for (int i = 0; i < Header.Sections.Count; i++)
                    {
                        Resources[i] = new ModelTagGroup.Section.Resource[Sections[i].Resources.Count];
                        entry.TagData.Seek(Sections[i].Resources.Offset, SeekOrigin.Begin);
                        for (int j = 0; j < Sections[i].Resources.Count; j++)
                        {
                            Resources[i][j] = reader.Read <ModelTagGroup.Section.Resource>();
                        }
                    }

                    //Read Materials
                    Materials = new ModelTagGroup.Material[Header.Materials.Count];
                    entry.TagData.Seek(Header.Materials.Offset, SeekOrigin.Begin);
                    for (int i = 0; i < Header.Materials.Count; i++)
                    {
                        Materials[i] = reader.Read <ModelTagGroup.Material>();
                    }
                }
            }