/// <summary>
        /// Gets the available types or maps for the currently selcted item given a specified race and part
        /// Hair, Face, and Mounts that are demihuman, contain types, all others do not.
        /// </summary>
        private void PartComboBoxChanged()
        {
            var info = MTRL.GetMTRLData(selectedItem, selectedRace.ID, selectedCategory, selectedPart.Name, imcVersion, "", "", VFXVersion);

            mtrlData = info.Item1;

            if (selectedItem.ItemName.Equals(Strings.Face) || selectedItem.ItemName.Equals(Strings.Hair))
            {
                TypeComboBox = info.Item2;
                TypeIndex    = 0;
            }
            else if (selectedCategory.Equals(Strings.Mounts))
            {
                bool isDemiHuman = selectedItem.PrimaryMTRLFolder.Contains("demihuman");

                if (isDemiHuman)
                {
                    TypeComboBox = info.Item2;
                    TypeIndex    = 0;
                }
                else
                {
                    MapComboBox = info.Item2;
                    MapIndex    = currMap;
                }
            }
            else
            {
                MapComboBox = info.Item2;
                MapIndex    = currMap;
            }

            if (TypeComboBox.Count > 1)
            {
                TypeEnabled = true;
            }
            else
            {
                TypeEnabled = false;
            }

            if (MapComboBox.Count > 0)
            {
                MapEnabled = true;
            }
            else
            {
                MapEnabled = false;
            }
        }
Beispiel #2
0
        /// <summary>
        /// Gets the available maps for the currently selected item given a specified race, part, and type
        /// </summary>
        private void TypeComboBoxChanged()
        {
            string type;

            if (selectedCategory.Equals(Strings.Mounts))
            {
                bool isDemiHuman = selectedItem.PrimaryMTRLFolder.Contains("demihuman");

                if (isDemiHuman)
                {
                    type = Info.slotAbr[selectedType.Name];
                }
                else
                {
                    type = selectedType.Name;
                }
            }
            else
            {
                type = selectedType.Name;
            }


            var info = MTRL.GetMTRLDatafromType(selectedItem, selectedRace.ID, selectedPart.Name, type, imcVersion, selectedCategory, "a");

            mtrlData = info.Item1;

            MapComboBox = info.Item2;

            if (MapComboBox.Count > 0)
            {
                MapEnabled = true;
            }
            else
            {
                MapEnabled = false;
            }

            if (MapComboBox.Count < (currMap + 1))
            {
                MapIndex = currMap;
            }
            else
            {
                MapIndex = 0;
            }
        }
Beispiel #3
0
        /// <summary>
        /// Imports the items color set into a dat file
        /// </summary>
        /// <param name="mtrlData">MTRL data for the currently displayed color set</param>
        /// <param name="category">The items category</param>
        /// <param name="itemName">The items name</param>
        /// <param name="toggle">Toggle value for translucency</param>
        public static int TranslucencyToggle(MTRLData mtrlData, string category, string itemName, bool toggle)
        {
            int newOffset = 0;

            List <byte> mtrlBytes = new List <byte>();
            List <byte> newMTRL   = new List <byte>();

            JsonEntry modEntry = null;
            int       offset   = mtrlData.MTRLOffset;
            int       lineNum  = 0;
            short     fileSize;
            bool      inModList = false;

            int datNum = ((offset / 8) & 0x000f) / 2;

            try
            {
                using (StreamReader sr = new StreamReader(Properties.Settings.Default.Modlist_Directory))
                {
                    string line;
                    while ((line = sr.ReadLine()) != null)
                    {
                        modEntry = JsonConvert.DeserializeObject <JsonEntry>(line);
                        if (modEntry.fullPath.Equals(mtrlData.MTRLPath))
                        {
                            inModList = true;
                            break;
                        }
                        lineNum++;
                    }
                }
            }
            catch (Exception ex)
            {
                FlexibleMessageBox.Show("Error Accessing .modlist File \n" + ex.Message, "ImportTex Error " + Info.appVersion, MessageBoxButtons.OK, MessageBoxIcon.Error);
            }

            using (BinaryReader br = new BinaryReader(new MemoryStream(Helper.GetType2DecompressedData(offset, datNum, Strings.ItemsDat))))
            {
                bool enableAlpha = false;
                br.BaseStream.Seek(4, SeekOrigin.Begin);
                fileSize = br.ReadInt16();
                short colorDataSize   = br.ReadInt16();
                short textureNameSize = br.ReadInt16();
                short toSHPK          = br.ReadInt16();
                byte  numOfTextures   = br.ReadByte();
                byte  numOfMaps       = br.ReadByte();
                byte  numOfColorSets  = br.ReadByte();
                byte  unknown         = br.ReadByte();

                int endOfHeader = 16 + ((numOfTextures + numOfMaps + numOfColorSets) * 4);

                br.BaseStream.Seek(0, SeekOrigin.Begin);

                mtrlBytes.AddRange(br.ReadBytes(endOfHeader));
                mtrlBytes.AddRange(br.ReadBytes(textureNameSize + 4));
                mtrlBytes.AddRange(br.ReadBytes(colorDataSize));

                mtrlBytes.AddRange(br.ReadBytes(8));
                br.ReadByte();
                mtrlBytes.Add(toggle ? (byte)0x1D : (byte)0x0D);

                mtrlBytes.AddRange(br.ReadBytes(fileSize - (int)br.BaseStream.Position));
            }

            var compressed = Compressor(mtrlBytes.ToArray());
            int padding    = 128 - (compressed.Length % 128);

            newMTRL.AddRange(MakeMTRLHeader(fileSize, compressed.Length + padding));
            newMTRL.AddRange(BitConverter.GetBytes(16));
            newMTRL.AddRange(BitConverter.GetBytes(0));
            newMTRL.AddRange(BitConverter.GetBytes(compressed.Length));
            newMTRL.AddRange(BitConverter.GetBytes((int)fileSize));
            newMTRL.AddRange(compressed);
            newMTRL.AddRange(new byte[padding]);

            return(ImportTex.WriteToDat(newMTRL, modEntry, inModList, mtrlData.MTRLPath, category, itemName, lineNum, Strings.ItemsDat));
        }
Beispiel #4
0
        /// <summary>
        /// Saves the currently displayed texture map as a DDS file.
        /// </summary>
        /// <param name="selectedCategory">The items category.</param>
        /// <param name="selectedItem">The currently selected item.</param>
        /// <param name="internalFilePath">The internal file path of the texture map.</param>
        /// <param name="textureMap">The name of the currently selected texture map.</param>
        /// <param name="mtrlData">The items mtrl file data</param>
        /// <param name="texData">The items tex file data</param>
        public static void SaveDDS(string selectedCategory, string selectedItem, string internalFilePath, string textureMap, MTRLData mtrlData, TEXData texData)
        {
            string savePath = Properties.Settings.Default.Save_Directory + "/" + selectedCategory + "/" + selectedItem;

            Directory.CreateDirectory(savePath);

            var fullSavePath = Path.Combine(savePath, (Path.GetFileNameWithoutExtension(internalFilePath) + ".dds"));

            List <byte> DDS = new List <byte>();

            if (textureMap.Equals(Strings.ColorSet))
            {
                if (mtrlData.ColorFlags != null)
                {
                    var colorFlagsDir = Path.Combine(savePath, (Path.GetFileNameWithoutExtension(internalFilePath) + ".dat"));
                    File.WriteAllBytes(colorFlagsDir, mtrlData.ColorFlags);
                }

                DDS.AddRange(CreateColorDDSHeader());
                DDS.AddRange(mtrlData.ColorData);
            }
            else
            {
                DDS.AddRange(CreateDDSHeader(texData));
                DDS.AddRange(texData.RawTexData);
            }

            File.WriteAllBytes(fullSavePath, DDS.ToArray());
        }
        /// <summary>
        /// Imports the items color set into a dat file
        /// </summary>
        /// <param name="mtrlData">MTRL data for the currently displayed color set</param>
        /// <param name="category">The items category</param>
        /// <param name="itemName">The items name</param>
        public static Tuple <int, byte[]> ImportColor(MTRLData mtrlData, string category, string itemName)
        {
            var savePath  = Properties.Settings.Default.Save_Directory + "/" + category + "/" + itemName + "/" + Path.GetFileNameWithoutExtension(mtrlData.MTRLPath) + ".dds";
            int newOffset = 0;

            if (File.Exists(savePath))
            {
                List <byte> mtrlBytes = new List <byte>();
                List <byte> newMTRL   = new List <byte>();

                JsonEntry modEntry = null;
                int       offset   = mtrlData.MTRLOffset;
                int       lineNum  = 0;
                short     fileSize;
                bool      inModList = false;
                byte[]    colorData;

                int datNum = ((offset / 8) & 0x000f) / 2;

                try
                {
                    using (StreamReader sr = new StreamReader(Properties.Settings.Default.Modlist_Directory))
                    {
                        string line;
                        while ((line = sr.ReadLine()) != null)
                        {
                            modEntry = JsonConvert.DeserializeObject <JsonEntry>(line);
                            if (modEntry.fullPath.Equals(mtrlData.MTRLPath))
                            {
                                inModList = true;
                                break;
                            }
                            lineNum++;
                        }
                    }
                }
                catch (Exception ex)
                {
                    FlexibleMessageBox.Show("Error Accessing .modlist File \n" + ex.Message, "ImportTex Error " + Info.appVersion, MessageBoxButtons.OK, MessageBoxIcon.Error);
                }


                using (BinaryReader br = new BinaryReader(new MemoryStream(Helper.GetType2DecompressedData(offset, datNum, Strings.ItemsDat))))
                {
                    br.BaseStream.Seek(4, SeekOrigin.Begin);
                    fileSize = br.ReadInt16();
                    short colorDataSize   = br.ReadInt16();
                    short textureNameSize = br.ReadInt16();
                    short toSHPK          = br.ReadInt16();
                    byte  numOfTextures   = br.ReadByte();
                    byte  numOfMaps       = br.ReadByte();
                    byte  numOfColorSets  = br.ReadByte();
                    byte  unknown         = br.ReadByte();

                    int endOfHeader = 16 + ((numOfTextures + numOfMaps + numOfColorSets) * 4);

                    br.BaseStream.Seek(0, SeekOrigin.Begin);

                    mtrlBytes.AddRange(br.ReadBytes(endOfHeader));
                    mtrlBytes.AddRange(br.ReadBytes(textureNameSize + 4));
                    br.ReadBytes(colorDataSize);

                    if (colorDataSize == 544)
                    {
                        using (BinaryReader br1 = new BinaryReader(File.OpenRead(savePath)))
                        {
                            br1.BaseStream.Seek(128, SeekOrigin.Begin);
                            colorData = br1.ReadBytes(colorDataSize - 32);

                            mtrlBytes.AddRange(colorData);
                        }

                        string flagsPath = Path.Combine(Path.GetDirectoryName(savePath), (Path.GetFileNameWithoutExtension(savePath) + ".dat"));

                        using (BinaryReader br1 = new BinaryReader(File.OpenRead(flagsPath)))
                        {
                            br1.BaseStream.Seek(0, SeekOrigin.Begin);

                            mtrlBytes.AddRange(br1.ReadBytes(32));
                        }
                    }
                    else
                    {
                        using (BinaryReader br1 = new BinaryReader(File.OpenRead(savePath)))
                        {
                            br1.BaseStream.Seek(128, SeekOrigin.Begin);
                            colorData = br1.ReadBytes(colorDataSize);

                            mtrlBytes.AddRange(colorData);
                        }
                    }

                    mtrlBytes.AddRange(br.ReadBytes(fileSize - (int)br.BaseStream.Position));
                }

                var compressed = Compressor(mtrlBytes.ToArray());
                int padding    = 128 - (compressed.Length % 128);

                newMTRL.AddRange(MakeMTRLHeader(fileSize, compressed.Length + padding));
                newMTRL.AddRange(BitConverter.GetBytes(16));
                newMTRL.AddRange(BitConverter.GetBytes(0));
                newMTRL.AddRange(BitConverter.GetBytes(compressed.Length));
                newMTRL.AddRange(BitConverter.GetBytes((int)fileSize));
                newMTRL.AddRange(compressed);
                newMTRL.AddRange(new byte[padding]);

                newOffset = WriteToDat(newMTRL, modEntry, inModList, mtrlData.MTRLPath, category, itemName, lineNum, Strings.ItemsDat);

                return(new Tuple <int, byte[]>(newOffset, colorData));
            }
            else
            {
                FlexibleMessageBox.Show("Could not find file \n" + savePath, "File read Error", MessageBoxButtons.OK, MessageBoxIcon.Error);
                return(new Tuple <int, byte[]>(0, null));
            }
        }
Beispiel #6
0
        /// <summary>
        /// Gets the available types or maps for the currently selcted item given a specified race and part
        /// Hair, Face, and Mounts that are demihuman, contain types, all others do not.
        /// </summary>
        private void PartComboBoxChanged()
        {
            if (selectedCategory != "UI")
            {
                var body    = "";
                var modelID = selectedItem.PrimaryModelID;
                var imc     = imcVersion;
                var vfx     = VFXVersion;
                var part    = selectedPart.Name;

                if (selectedItem.PrimaryMTRLFolder != null)
                {
                    if (selectedItem.PrimaryMTRLFolder.Contains("weapon"))
                    {
                        var imcData = IMC.GetVersion(selectedCategory, selectedItem, false);

                        imc = imcData.Item1;
                        vfx = imcData.Item2;

                        modelID = selectedItem.PrimaryModelID;
                        body    = selectedItem.PrimaryModelBody;
                        part    = selectedPart.Name;
                    }
                }


                if (SelectedPart.Name.Equals("s"))
                {
                    var imcData = IMC.GetVersion(selectedCategory, selectedItem, true);

                    imc = imcData.Item1;
                    vfx = imcData.Item2;

                    modelID = selectedItem.SecondaryModelID;
                    body    = selectedItem.SecondaryModelBody;
                    part    = "a";

                    if (body == null)
                    {
                        body = "0001";
                    }
                }

                if (selectedCategory.Equals(Strings.Pets))
                {
                    body = "a";
                }
                var info = MTRL.GetMTRLData(selectedItem, selectedRace.ID, selectedCategory, part, imc, body, modelID, vfx);
                mtrlData = info.Item1;

                if (selectedItem.ItemName.Equals(Strings.Face) || selectedItem.ItemName.Equals(Strings.Hair))
                {
                    TypeComboBox = info.Item2;
                    TypeIndex    = 0;
                }
                else if (selectedCategory.Equals(Strings.Mounts))
                {
                    bool isDemiHuman = selectedItem.PrimaryMTRLFolder.Contains("demihuman");

                    if (isDemiHuman)
                    {
                        TypeComboBox = info.Item2;
                        TypeIndex    = 0;
                    }
                    else
                    {
                        MapComboBox = info.Item2;
                        if (MapComboBox.Count < (currMap + 1))
                        {
                            MapIndex = 0;
                        }
                        else
                        {
                            MapIndex = currMap;
                        }
                        TypeComboBox.Clear();
                    }
                }
                else
                {
                    MapComboBox = info.Item2;
                    if (MapComboBox.Count < (currMap + 1))
                    {
                        MapIndex = 0;
                    }
                    else
                    {
                        MapIndex = currMap;
                    }
                    TypeComboBox.Clear();
                }
            }
            else
            {
                var info = MTRL.GetUIData(selectedItem);
                mtrlData    = info.Item1;
                MapComboBox = info.Item2;
                if (MapComboBox.Count < (currMap + 1))
                {
                    MapIndex = 0;
                }
                else
                {
                    MapIndex = currMap;
                }
                TypeComboBox.Clear();
            }


            if (TypeComboBox.Count > 1)
            {
                TypeEnabled = true;
            }
            else
            {
                TypeEnabled = false;
            }

            if (MapComboBox.Count > 0)
            {
                MapEnabled = true;
            }
            else
            {
                MapEnabled = false;
            }
        }
Beispiel #7
0
        /// <summary>
        /// Gets the MTRL data of the given mesh
        /// </summary>
        /// <param name="mesh">The mesh to obtain the data from</param>
        /// <returns>The MTRLData of the given mesh</returns>
        public MTRLData MTRL3D(int mesh)
        {
            MTRLData mtrlData    = null;
            bool     isDemiHuman = false;

            if (selectedItem.PrimaryMTRLFolder != null)
            {
                isDemiHuman = selectedItem.PrimaryMTRLFolder.Contains("demihuman");
            }

            var itemVersion = IMC.GetVersion(selectedCategory, selectedItem, false).Item1;
            var itemType    = Helper.GetCategoryType(selectedCategory);

            try
            {
                if (selectedItem.ItemName.Equals(Strings.Face) || selectedItem.ItemName.Equals(Strings.Hair) || isDemiHuman)
                {
                    string slotAbr;

                    if (isDemiHuman)
                    {
                        slotAbr = Info.slotAbr[SelectedPart.Name];
                    }
                    else if (selectedCategory.Equals(Strings.Character))
                    {
                        var race = materialStrings[mesh].Substring(materialStrings[mesh].IndexOf("c") + 1, 4);

                        if (materialStrings[mesh].Contains("h00"))
                        {
                            var hairNum    = materialStrings[mesh].Substring(materialStrings[mesh].IndexOf("h00") + 1, 4);
                            var mtrlFolder = string.Format(Strings.HairMtrlFolder, race, hairNum);
                            slotAbr = materialStrings[mesh].Substring(materialStrings[mesh].LastIndexOf("_") - 3, 3);
                            slotAbr = Info.HairTypes.FirstOrDefault(x => x.Value == slotAbr).Key;

                            var hairInfo = MTRL.GetMTRLDatafromType(selectedItem, SelectedRace, hairNum, slotAbr, itemVersion, selectedCategory);
                            return(hairInfo.Item1);
                        }
                        else if (materialStrings[mesh].Contains("f00"))
                        {
                            var faceNum    = materialStrings[mesh].Substring(materialStrings[mesh].IndexOf("f00") + 1, 4);
                            var mtrlFolder = string.Format(Strings.FaceMtrlFolder, race, faceNum);
                            slotAbr = materialStrings[mesh].Substring(materialStrings[mesh].LastIndexOf("_") - 3, 3);
                            slotAbr = Info.FaceTypes.FirstOrDefault(x => x.Value == slotAbr).Key;

                            var faceInfo = MTRL.GetMTRLDatafromType(selectedItem, SelectedRace, faceNum, slotAbr, itemVersion, selectedCategory);
                            return(faceInfo.Item1);
                        }
                        else
                        {
                            slotAbr = selectedPart.Name;
                        }
                    }
                    else
                    {
                        slotAbr = selectedPart.Name;
                    }

                    var info = MTRL.GetMTRLDatafromType(selectedItem, SelectedRace, selectedPart.Name, slotAbr, itemVersion, selectedCategory);
                    mtrlData = info.Item1;
                }
                else
                {
                    Tuple <MTRLData, ObservableCollection <ComboBoxInfo> > info;

                    if (itemType.Equals("character") || itemType.Equals("equipment"))
                    {
                        try
                        {
                            if (materialStrings[mesh].Contains("b00") || materialStrings[mesh].Contains("t00") || materialStrings[mesh].Contains("h00"))
                            {
                                if (materialStrings[mesh].Contains("mt_c"))
                                {
                                    var mtrlFolder = "";
                                    var race       = materialStrings[mesh].Substring(materialStrings[mesh].IndexOf("c") + 1, 4);

                                    if (materialStrings[mesh].Contains("b00"))
                                    {
                                        mtrlFolder = string.Format(Strings.BodyMtrlFolder, race, materialStrings[mesh].Substring(materialStrings[mesh].IndexOf("b00") + 1, 4));
                                    }
                                    else if (materialStrings[mesh].Contains("t00"))
                                    {
                                        mtrlFolder = string.Format(Strings.TailMtrlFolder, race, materialStrings[mesh].Substring(materialStrings[mesh].IndexOf("t00") + 1, 4));
                                    }
                                    else if (materialStrings[mesh].Contains("h00"))
                                    {
                                        mtrlFolder = string.Format(Strings.HairMtrlFolder, race, materialStrings[mesh].Substring(materialStrings[mesh].IndexOf("h00") + 1, 4));
                                    }

                                    var mtrlFile = materialStrings[mesh].Substring(1);

                                    return(MTRL.GetMTRLInfo(Helper.GetItemOffset(FFCRC.GetHash(mtrlFolder), FFCRC.GetHash(mtrlFile)), true));
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            Debug.WriteLine(ex.Message);
                            Debug.WriteLine(ex.StackTrace);
                        }
                    }
                    else
                    {
                        info = MTRL.GetMTRLData(selectedItem, SelectedRace.ID, selectedCategory, SelectedPart.Name, itemVersion, "", "", "0000");
                    }

                    if (SelectedPart.Name.Equals("Secondary"))
                    {
                        info = MTRL.GetMTRLData(selectedItem, SelectedRace.ID, selectedCategory, SelectedPart.Name, itemVersion, "Secondary", "", "0000");
                    }
                    else
                    {
                        string part   = "a";
                        string itemID = selectedItem.PrimaryModelID;

                        if (materialStrings.Count > 1)
                        {
                            try
                            {
                                part   = materialStrings[mesh].Substring(materialStrings[mesh].LastIndexOf("_") + 1, 1);
                                itemID = materialStrings[mesh].Substring(materialStrings[mesh].IndexOf("_") + 2, 4);
                            }
                            catch (Exception ex)
                            {
                                Debug.WriteLine(ex.Message);
                                Debug.WriteLine(ex.StackTrace);
                            }
                        }

                        if (selectedCategory.Equals(Strings.Pets))
                        {
                            part = "1";
                        }

                        info = MTRL.GetMTRLData(selectedItem, SelectedRace.ID, selectedCategory, part, itemVersion, "", itemID, "0000");
                    }

                    if (info != null)
                    {
                        mtrlData = info.Item1;
                    }
                    else
                    {
                        var combo = new ComboBoxInfo()
                        {
                            Name = "Default", ID = materialStrings[mesh].Substring(materialStrings[mesh].IndexOf("c") + 1, 4), IsNum = false
                        };

                        if (SelectedPart.Name.Equals("-"))
                        {
                            info = MTRL.GetMTRLData(selectedItem, combo.ID, selectedCategory, "a", itemVersion, "", "", "0000");
                        }
                        else
                        {
                            info = MTRL.GetMTRLData(selectedItem, combo.ID, selectedCategory, SelectedPart.Name, itemVersion, "", "", "0000");
                        }

                        mtrlData = info.Item1;
                    }
                }
            }
            catch (Exception ex)
            {
                Debug.WriteLine(ex.Message);
                Debug.WriteLine(ex.StackTrace);
                return(null);
            }

            return(mtrlData);
        }
Beispiel #8
0
        /// <summary>
        /// Gets the model data and sets the display viewmodel
        /// </summary>
        private void MeshComboBoxChanged()
        {
            if (!is3DLoaded)
            {
                disposing = false;

                meshData = new List <MDLTEXData>();

                for (int i = 0; i < meshList.Count; i++)
                {
                    BitmapSource specularBMP = null;
                    BitmapSource diffuseBMP  = null;
                    BitmapSource normalBMP   = null;
                    BitmapSource colorBMP    = null;
                    BitmapSource alphaBMP    = null;
                    BitmapSource maskBMP     = null;

                    TEXData specularData = null;
                    TEXData diffuseData  = null;
                    TEXData normalData   = null;
                    TEXData maskData     = null;

                    bool isBody = false;
                    bool isFace = false;

                    MTRLData mtrlData = MTRL3D(i);

                    if (selectedCategory.Equals(Strings.Character))
                    {
                        if (selectedItem.ItemName.Equals(Strings.Tail) || selectedItem.ItemName.Equals(Strings.Hair))
                        {
                            normalData   = TEX.GetTex(mtrlData.NormalOffset);
                            specularData = TEX.GetTex(mtrlData.SpecularOffset);

                            if (mtrlData.DiffusePath != null)
                            {
                                diffuseData = TEX.GetTex(mtrlData.DiffuseOffset);
                            }

                            var maps = TexHelper.MakeCharacterMaps(normalData, diffuseData, null, specularData);

                            diffuseBMP  = maps[0];
                            specularBMP = maps[1];
                            normalBMP   = maps[2];
                            alphaBMP    = maps[3];

                            specularData.Dispose();
                            normalData.Dispose();
                            if (diffuseData != null)
                            {
                                diffuseData.Dispose();
                            }
                        }

                        if (selectedItem.ItemName.Equals(Strings.Body))
                        {
                            normalData = TEX.GetTex(mtrlData.NormalOffset);
                            //specularTI = TEX.GetTex(mInfo.SpecularOffset);
                            diffuseData = TEX.GetTex(mtrlData.DiffuseOffset);

                            isBody     = true;
                            diffuseBMP = Imaging.CreateBitmapSourceFromHBitmap(diffuseData.BMP.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
                            normalBMP  = Imaging.CreateBitmapSourceFromHBitmap(normalData.BMP.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
                        }

                        if (selectedItem.ItemName.Equals(Strings.Face))
                        {
                            normalData = TEX.GetTex(mtrlData.NormalOffset);

                            if (materialStrings[i].Contains("_fac_"))
                            {
                                specularData = TEX.GetTex(mtrlData.SpecularOffset);
                                diffuseData  = TEX.GetTex(mtrlData.DiffuseOffset);

                                var maps = TexHelper.MakeCharacterMaps(normalData, diffuseData, null, specularData);

                                diffuseBMP  = maps[0];
                                specularBMP = maps[1];
                                normalBMP   = maps[2];
                                alphaBMP    = maps[3];
                                isFace      = true;

                                specularData.Dispose();
                                diffuseData.Dispose();
                            }
                            else
                            {
                                specularData = TEX.GetTex(mtrlData.SpecularOffset);
                                var maps = TexHelper.MakeCharacterMaps(normalData, diffuseData, null, specularData);

                                diffuseBMP  = maps[0];
                                specularBMP = maps[1];
                                normalBMP   = maps[2];
                                alphaBMP    = maps[3];
                            }
                        }
                    }
                    else
                    {
                        if (mtrlData.ColorData != null)
                        {
                            var colorBmp = TEX.TextureToBitmap(mtrlData.ColorData, 9312, 4, 16);
                            colorBMP = Imaging.CreateBitmapSourceFromHBitmap(colorBmp.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
                        }

                        if (mtrlData.NormalOffset != 0)
                        {
                            normalData = TEX.GetTex(mtrlData.NormalOffset);
                        }

                        if (mtrlData.MaskOffset != 0)
                        {
                            maskData = TEX.GetTex(mtrlData.MaskOffset);
                            maskBMP  = Imaging.CreateBitmapSourceFromHBitmap(maskData.BMP.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
                        }

                        if (mtrlData.DiffuseOffset != 0)
                        {
                            diffuseData = TEX.GetTex(mtrlData.DiffuseOffset);
                            if (mtrlData.DiffusePath.Contains("human") && !mtrlData.DiffusePath.Contains("demi"))
                            {
                                isBody     = true;
                                diffuseBMP = Imaging.CreateBitmapSourceFromHBitmap(diffuseData.BMP.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
                                normalBMP  = Imaging.CreateBitmapSourceFromHBitmap(normalData.BMP.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
                            }
                        }

                        if (mtrlData.SpecularOffset != 0)
                        {
                            specularData = TEX.GetTex(mtrlData.SpecularOffset);
                            specularBMP  = Imaging.CreateBitmapSourceFromHBitmap(specularData.BMP.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
                        }

                        if (!isBody && specularData == null)
                        {
                            var maps = TexHelper.MakeModelTextureMaps(normalData, diffuseData, maskData, null, colorBMP);
                            diffuseBMP  = maps[0];
                            specularBMP = maps[1];
                            normalBMP   = maps[2];
                            alphaBMP    = maps[3];
                        }
                        else if (!isBody && specularData != null)
                        {
                            var maps = TexHelper.MakeModelTextureMaps(normalData, diffuseData, null, specularData, colorBMP);
                            diffuseBMP  = maps[0];
                            specularBMP = maps[1];
                            normalBMP   = maps[2];
                            alphaBMP    = maps[3];
                        }

                        if (normalData != null)
                        {
                            normalData.Dispose();
                        }

                        if (maskData != null)
                        {
                            maskData.Dispose();
                        }

                        if (diffuseData != null)
                        {
                            diffuseData.Dispose();
                        }

                        if (specularData != null)
                        {
                            specularData.Dispose();
                        }
                    }

                    var mData = new MDLTEXData()
                    {
                        Specular   = specularBMP,
                        ColorTable = colorBMP,
                        Diffuse    = diffuseBMP,
                        Normal     = normalBMP,
                        Alpha      = alphaBMP,
                        Mask       = maskBMP,

                        IsBody = isBody,
                        IsFace = isFace,

                        Mesh = meshList[i]
                    };

                    meshData.Add(mData);
                }

                CompositeVM = new Composite3DViewModel(meshData);

                is3DLoaded = true;

                ReflectionAmount = String.Format("{0:.##}", CompositeVM.SecondModelMaterial.SpecularShininess);

                try
                {
                }
                catch (Exception ex)
                {
                    MessageBox.Show("[Main] mesh 3D Error \n" + ex.Message, "Error", MessageBoxButton.OK, MessageBoxImage.Error);
                }
            }
            else
            {
                CompositeVM.Rendering(SelectedMesh.Name);
            }
        }
Beispiel #9
0
        /// <summary>
        /// Creates the bitmap data for the model
        /// </summary>
        /// <remarks>
        /// Because the original textures use channel packing, this method gets the pixel data of each texture
        /// and then recombines them to create the unpacked textures to use in the 3D model.
        /// <see cref="http://wiki.polycount.com/wiki/ChannelPacking"/>
        /// </remarks>
        /// <param name="normalTexData">The texture data of the normal map</param>
        /// <param name="diffuseTexData">The texture data of the diffuse map</param>
        /// <param name="maskTexData">The texture data of the mask map</param>
        /// <param name="specularTexData">The texture data of the specular map</param>
        /// <param name="colorMap">The bitmap of the color map</param>
        /// <returns>An array of bitmaps to be used on the model</returns>
        public static BitmapSource[] MakeModelTextureMaps(TEXData normalTexData, TEXData diffuseTexData, TEXData maskTexData, TEXData specularTexData, MTRLData mtrlData)
        {
            int    height       = normalTexData.Height;
            int    width        = normalTexData.Width;
            int    tSize        = height * width;
            Bitmap normalBitmap = null;

            if (diffuseTexData != null && (diffuseTexData.Height * diffuseTexData.Width) > tSize)
            {
                height = diffuseTexData.Height;
                width  = diffuseTexData.Width;
                tSize  = height * width;
            }

            if (maskTexData != null && (maskTexData.Height * maskTexData.Width) > tSize)
            {
                height = maskTexData.Height;
                width  = maskTexData.Width;
                tSize  = height * width;
            }

            if (specularTexData != null && (specularTexData.Height * specularTexData.Width) > tSize)
            {
                height = specularTexData.Height;
                width  = specularTexData.Width;
                tSize  = height * width;
            }

            byte[] maskPixels     = null;
            byte[] specularPixels = null;
            byte[] normalPixels   = null;
            byte[] diffusePixels  = null;

            List <System.Drawing.Color> colorList    = new List <System.Drawing.Color>();
            List <System.Drawing.Color> specularList = new List <System.Drawing.Color>();
            List <System.Drawing.Color> emissiveList = new List <System.Drawing.Color>();

            BitmapSource[] texBitmaps = new BitmapSource[5];

            if (mtrlData.ColorData != null)
            {
                var colorBitmap = TEX.TextureToBitmap(mtrlData.ColorData, 9312, 4, 16);
                var cbmp        = SetAlpha(colorBitmap, 255);
                var colorMap1   = Imaging.CreateBitmapSourceFromHBitmap(cbmp.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());

                int    colorSetStride = colorMap1.PixelWidth * (colorMap1.Format.BitsPerPixel / 8);
                byte[] colorPixels    = new byte[colorMap1.PixelHeight * colorSetStride];

                colorMap1.CopyPixels(colorPixels, colorSetStride, 0);

                for (int i = 0; i < colorPixels.Length; i += 16)
                {
                    int red   = colorPixels[i + 2];
                    int green = colorPixels[i + 1];
                    int blue  = colorPixels[i];
                    int alpha = colorPixels[i + 3];

                    colorList.Add(System.Drawing.Color.FromArgb(255, red, green, blue));

                    red   = colorPixels[i + 6];
                    green = colorPixels[i + 5];
                    blue  = colorPixels[i + 4];
                    alpha = colorPixels[i + 7];

                    specularList.Add(System.Drawing.Color.FromArgb(255, red, green, blue));

                    var r1 = colorPixels[i + 10];
                    var g1 = colorPixels[i + 9];
                    var b1 = colorPixels[i + 8];
                    var a1 = colorPixels[i + 11];

                    emissiveList.Add(System.Drawing.Color.FromArgb(255, r1, g1, b1));
                }
            }
            else if (mtrlData.ColorData == null)
            {
                for (int i = 0; i < 1024; i += 16)
                {
                    colorList.Add(System.Drawing.Color.FromArgb(255, 255, 255, 255));
                    specularList.Add(System.Drawing.Color.FromArgb(255, 0, 0, 0));
                    emissiveList.Add(System.Drawing.Color.FromArgb(255, 0, 0, 0));
                }
            }

            if (maskTexData != null)
            {
                if (tSize > (maskTexData.Height * maskTexData.Width))
                {
                    var maskBitmap   = ResizeImage(Image.FromHbitmap(maskTexData.BMP.GetHbitmap()), width, height);
                    var maskData     = maskBitmap.LockBits(new System.Drawing.Rectangle(0, 0, maskBitmap.Width, maskBitmap.Height), ImageLockMode.ReadOnly, maskBitmap.PixelFormat);
                    var bitmapLength = maskData.Stride * maskData.Height;
                    maskPixels = new byte[bitmapLength];
                    Marshal.Copy(maskData.Scan0, maskPixels, 0, bitmapLength);
                    maskBitmap.UnlockBits(maskData);
                }
                else
                {
                    var maskData     = maskTexData.BMP.LockBits(new System.Drawing.Rectangle(0, 0, maskTexData.Width, maskTexData.Height), ImageLockMode.ReadOnly, maskTexData.BMP.PixelFormat);
                    var bitmapLength = maskData.Stride * maskData.Height;
                    maskPixels = new byte[bitmapLength];
                    Marshal.Copy(maskData.Scan0, maskPixels, 0, bitmapLength);
                    maskTexData.BMP.UnlockBits(maskData);
                }
            }

            if (diffuseTexData != null)
            {
                if (tSize > (diffuseTexData.Height * diffuseTexData.Width))
                {
                    var diffuseBitmap = ResizeImage(Image.FromHbitmap(diffuseTexData.BMP.GetHbitmap()), width, height);
                    var diffData      = diffuseBitmap.LockBits(new System.Drawing.Rectangle(0, 0, diffuseBitmap.Width, diffuseBitmap.Height), ImageLockMode.ReadOnly, diffuseBitmap.PixelFormat);
                    var bitmapLength  = diffData.Stride * diffData.Height;
                    diffusePixels = new byte[bitmapLength];
                    Marshal.Copy(diffData.Scan0, diffusePixels, 0, bitmapLength);
                    diffuseBitmap.UnlockBits(diffData);
                }
                else
                {
                    var diffData     = diffuseTexData.BMP.LockBits(new System.Drawing.Rectangle(0, 0, diffuseTexData.Width, diffuseTexData.Height), ImageLockMode.ReadOnly, diffuseTexData.BMP.PixelFormat);
                    var bitmapLength = diffData.Stride * diffData.Height;
                    diffusePixels = new byte[bitmapLength];
                    Marshal.Copy(diffData.Scan0, diffusePixels, 0, bitmapLength);
                    diffuseTexData.BMP.UnlockBits(diffData);
                }
            }

            if (specularTexData != null)
            {
                if (tSize > (specularTexData.Height * specularTexData.Width))
                {
                    var specularBitmap = ResizeImage(Image.FromHbitmap(specularTexData.BMP.GetHbitmap()), width, height);
                    var specData       = specularBitmap.LockBits(new System.Drawing.Rectangle(0, 0, specularBitmap.Width, specularBitmap.Height), ImageLockMode.ReadOnly, specularBitmap.PixelFormat);
                    var bitmapLength   = specData.Stride * specData.Height;
                    specularPixels = new byte[bitmapLength];
                    Marshal.Copy(specData.Scan0, specularPixels, 0, bitmapLength);
                    specularBitmap.UnlockBits(specData);
                }
                else
                {
                    var specData     = specularTexData.BMP.LockBits(new System.Drawing.Rectangle(0, 0, specularTexData.BMP.Width, specularTexData.BMP.Height), ImageLockMode.ReadOnly, specularTexData.BMP.PixelFormat);
                    var bitmapLength = specData.Stride * specData.Height;
                    specularPixels = new byte[bitmapLength];
                    Marshal.Copy(specData.Scan0, specularPixels, 0, bitmapLength);
                    specularTexData.BMP.UnlockBits(specData);
                }
            }

            if (normalTexData != null)
            {
                if (tSize > (normalTexData.Height * normalTexData.Width))
                {
                    var normBitmap   = ResizeImage(Image.FromHbitmap(normalTexData.BMP.GetHbitmap()), width, height);
                    var normalData   = normBitmap.LockBits(new System.Drawing.Rectangle(0, 0, normBitmap.Width, normBitmap.Height), ImageLockMode.ReadOnly, normBitmap.PixelFormat);
                    var bitmapLength = normalData.Stride * normalData.Height;
                    normalPixels = new byte[bitmapLength];
                    Marshal.Copy(normalData.Scan0, normalPixels, 0, bitmapLength);
                    normBitmap.UnlockBits(normalData);
                    normalBitmap = normBitmap;
                }
                else
                {
                    var normalData   = normalTexData.BMP.LockBits(new System.Drawing.Rectangle(0, 0, normalTexData.Width, normalTexData.Height), ImageLockMode.ReadOnly, normalTexData.BMP.PixelFormat);
                    var bitmapLength = normalData.Stride * normalData.Height;
                    normalPixels = new byte[bitmapLength];
                    Marshal.Copy(normalData.Scan0, normalPixels, 0, bitmapLength);
                    normalTexData.BMP.UnlockBits(normalData);
                    normalBitmap = normalTexData.BMP;
                }
            }

            List <byte> diffuseMap  = new List <byte>();
            List <byte> specularMap = new List <byte>();
            List <byte> emissiveMap = new List <byte>();
            List <byte> alphaMap    = new List <byte>();

            float R  = 1;
            float G  = 1;
            float B  = 1;
            float R1 = 1;
            float G1 = 1;
            float B1 = 1;

            for (int i = 3; i < normalPixels.Length; i += 4)
            {
                int alpha = normalPixels[i - 3];

                if (maskTexData != null)
                {
                    B = maskPixels[i - 1];
                    R = maskPixels[i - 1];
                    G = maskPixels[i - 1];

                    B1 = maskPixels[i - 3];
                    R1 = maskPixels[i - 3];
                    G1 = maskPixels[i - 3];
                }
                else
                {
                    if (diffusePixels != null)
                    {
                        B = diffusePixels[i - 3];
                        G = diffusePixels[i - 2];
                        R = diffusePixels[i - 1];
                    }
                    else
                    {
                        B = 255;
                        G = 255;
                        R = 255;
                    }

                    if (specularPixels != null)
                    {
                        B1 = specularPixels[i - 2];
                        G1 = specularPixels[i - 2];
                        R1 = specularPixels[i - 2];
                    }
                    else
                    {
                        B1 = 255;
                        G1 = 255;
                        R1 = 255;
                    }
                }

                System.Drawing.Color diffuseColor;
                System.Drawing.Color specularColor;
                System.Drawing.Color emissiveColor;
                System.Drawing.Color alphaColor;


                float pixel = (normalPixels[i] / 255f) * 15f;
                //int colorLoc = (int)Math.Floor(pixel + 0.5f);
                float percent = (float)(pixel - Math.Truncate(pixel));

                if (percent != 0)
                {
                    var color2Loc = (int)(Math.Truncate(pixel));
                    var color1Loc = color2Loc + 1;

                    var color1 = System.Drawing.Color.FromArgb(alpha, colorList[color1Loc].R, colorList[color1Loc].G, colorList[color1Loc].B);
                    var color2 = System.Drawing.Color.FromArgb(alpha, colorList[color2Loc].R, colorList[color2Loc].G, colorList[color2Loc].B);

                    var diffuseBlend = Blend(color1, color2, percent);

                    color1 = System.Drawing.Color.FromArgb(255, specularList[color1Loc].R, specularList[color1Loc].G, specularList[color1Loc].B);
                    color2 = System.Drawing.Color.FromArgb(255, specularList[color2Loc].R, specularList[color2Loc].G, specularList[color2Loc].B);

                    var specBlend = Blend(color1, color2, percent);

                    color1 = System.Drawing.Color.FromArgb(255, emissiveList[color1Loc].R, emissiveList[color1Loc].G, emissiveList[color1Loc].B);
                    color2 = System.Drawing.Color.FromArgb(255, emissiveList[color2Loc].R, emissiveList[color2Loc].G, emissiveList[color2Loc].B);

                    var emisBlend = Blend(color1, color2, percent);

                    diffuseColor  = System.Drawing.Color.FromArgb(alpha, (int)((diffuseBlend.R / 255f) * R), (int)((diffuseBlend.G / 255f) * G), (int)((diffuseBlend.B / 255f) * B));
                    specularColor = System.Drawing.Color.FromArgb(255, (int)((specBlend.R / 255f) * R1), (int)((specBlend.G / 255f) * G1), (int)((specBlend.B / 255f) * B1));
                    emissiveColor = System.Drawing.Color.FromArgb(255, emisBlend.R, emisBlend.G, emisBlend.B);
                }
                else
                {
                    var colorLoc = (int)Math.Floor(pixel + 0.5f);

                    diffuseColor  = System.Drawing.Color.FromArgb(alpha, (int)((colorList[colorLoc].R / 255f) * R), (int)((colorList[colorLoc].G / 255f) * G), (int)((colorList[colorLoc].B / 255f) * B));
                    specularColor = System.Drawing.Color.FromArgb(255, (int)((specularList[colorLoc].R / 255f) * R1), (int)((specularList[colorLoc].G / 255f) * G1), (int)((specularList[colorLoc].B / 255f) * B1));
                    emissiveColor = System.Drawing.Color.FromArgb(255, emissiveList[colorLoc].R, emissiveList[colorLoc].G, emissiveList[colorLoc].B);
                }


                alphaColor = System.Drawing.Color.FromArgb(255, alpha, alpha, alpha);

                diffuseMap.AddRange(BitConverter.GetBytes(diffuseColor.ToArgb()));
                specularMap.AddRange(BitConverter.GetBytes(specularColor.ToArgb()));
                emissiveMap.AddRange(BitConverter.GetBytes(emissiveColor.ToArgb()));
                alphaMap.AddRange(BitConverter.GetBytes(alphaColor.ToArgb()));
            }

            int stride = normalBitmap.Width * (32 / 8);

            BitmapSource bitmapSource = BitmapSource.Create(width, height, normalBitmap.HorizontalResolution, normalBitmap.VerticalResolution, PixelFormats.Bgra32, null, diffuseMap.ToArray(), stride);

            texBitmaps[0] = bitmapSource;

            bitmapSource  = BitmapSource.Create(width, height, normalBitmap.HorizontalResolution, normalBitmap.VerticalResolution, PixelFormats.Bgra32, null, specularMap.ToArray(), stride);
            texBitmaps[1] = bitmapSource;

            var noAlphaNormal = SetAlpha(normalBitmap, 255);

            texBitmaps[2] = Imaging.CreateBitmapSourceFromHBitmap(noAlphaNormal.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());

            bitmapSource  = BitmapSource.Create(width, height, normalBitmap.HorizontalResolution, normalBitmap.VerticalResolution, PixelFormats.Bgra32, null, alphaMap.ToArray(), stride);
            texBitmaps[3] = bitmapSource;

            bitmapSource  = BitmapSource.Create(width, height, normalBitmap.HorizontalResolution, normalBitmap.VerticalResolution, PixelFormats.Bgra32, null, emissiveMap.ToArray(), stride);
            texBitmaps[4] = bitmapSource;


            if (normalTexData != null)
            {
                normalTexData.Dispose();
            }

            if (normalBitmap != null)
            {
                normalBitmap.Dispose();
            }

            if (diffuseTexData != null)
            {
                diffuseTexData.Dispose();
            }

            if (maskTexData != null)
            {
                maskTexData.Dispose();
            }

            if (specularTexData != null)
            {
                specularTexData.Dispose();
            }

            foreach (var tb in texBitmaps)
            {
                tb.Freeze();
            }


            return(texBitmaps);
        }
        /// <summary>
        /// Creates the bitmap data for the model
        /// </summary>
        /// <remarks>
        /// Because the original textures use channel packing, this method gets the pixel data of each texture
        /// and then recombines them to create the unpacked textures to use in the 3D model.
        /// <see cref="http://wiki.polycount.com/wiki/ChannelPacking"/>
        /// </remarks>
        /// <param name="normalTexData">The texture data of the normal map</param>
        /// <param name="diffuseTexData">The texture data of the diffuse map</param>
        /// <param name="maskTexData">The texture data of the mask map</param>
        /// <param name="specularTexData">The texture data of the specular map</param>
        /// <param name="colorMap">The bitmap of the color map</param>
        /// <returns>An array of bitmaps to be used on the model</returns>
        public static BitmapSource[] MakeModelTextureMaps(TEXData normalTexData, TEXData diffuseTexData, TEXData maskTexData, TEXData specularTexData, MTRLData mtrlData)
        {
            int height       = normalTexData.Height;
            int width        = normalTexData.Width;
            int tSize        = height * width;
            var normalBitmap = normalTexData.BMPSouceAlpha;

            if (diffuseTexData != null && (diffuseTexData.Height * diffuseTexData.Width) > tSize)
            {
                height = diffuseTexData.Height;
                width  = diffuseTexData.Width;
                tSize  = height * width;
            }

            if (maskTexData != null && (maskTexData.Height * maskTexData.Width) > tSize)
            {
                height = maskTexData.Height;
                width  = maskTexData.Width;
                tSize  = height * width;
            }

            if (specularTexData != null && (specularTexData.Height * specularTexData.Width) > tSize)
            {
                height = specularTexData.Height;
                width  = specularTexData.Width;
                tSize  = height * width;
            }

            byte[] maskPixels     = null;
            byte[] specularPixels = null;
            byte[] normalPixels   = null;
            byte[] diffusePixels  = null;

            List <System.Drawing.Color> colorList    = new List <System.Drawing.Color>();
            List <System.Drawing.Color> specularList = new List <System.Drawing.Color>();
            List <System.Drawing.Color> emissiveList = new List <System.Drawing.Color>();

            BitmapSource[] texBitmaps = new BitmapSource[5];

            if (mtrlData.ColorData != null)
            {
                BitmapSource colorMap1;
                using (var colorBitmap = TEX.ColorSetToBitmap(mtrlData.ColorData))
                {
                    SetAlpha(colorBitmap, 255);
                    colorMap1 = CreateBitmapSource(colorBitmap);
                }

                int    colorSetStride = colorMap1.PixelWidth * (colorMap1.Format.BitsPerPixel / 8);
                byte[] colorPixels    = new byte[colorMap1.PixelHeight * colorSetStride];

                colorMap1.CopyPixels(colorPixels, colorSetStride, 0);

                for (int i = 0; i < colorPixels.Length; i += 16)
                {
                    int red   = colorPixels[i + 2];
                    int green = colorPixels[i + 1];
                    int blue  = colorPixels[i];
                    int alpha = colorPixels[i + 3];

                    colorList.Add(System.Drawing.Color.FromArgb(255, red, green, blue));

                    red   = colorPixels[i + 6];
                    green = colorPixels[i + 5];
                    blue  = colorPixels[i + 4];
                    alpha = colorPixels[i + 7];

                    specularList.Add(System.Drawing.Color.FromArgb(255, red, green, blue));

                    var r1 = colorPixels[i + 10];
                    var g1 = colorPixels[i + 9];
                    var b1 = colorPixels[i + 8];
                    var a1 = colorPixels[i + 11];

                    emissiveList.Add(System.Drawing.Color.FromArgb(255, r1, g1, b1));
                }
            }
            else if (mtrlData.ColorData == null)
            {
                for (int i = 0; i < 1024; i += 16)
                {
                    colorList.Add(System.Drawing.Color.FromArgb(255, 255, 255, 255));
                    specularList.Add(System.Drawing.Color.FromArgb(255, 0, 0, 0));
                    emissiveList.Add(System.Drawing.Color.FromArgb(255, 0, 0, 0));
                }
            }

            if (maskTexData != null)
            {
                if (tSize > (maskTexData.Height * maskTexData.Width))
                {
                    var resized = CreateResizedImage(maskTexData.BMPSouceAlpha, width, height);
                    maskPixels = GetBytesFromBitmapSource((BitmapSource)resized);
                }
                else
                {
                    maskPixels = GetBytesFromBitmapSource(maskTexData.BMPSouceAlpha);
                }
            }

            if (diffuseTexData != null)
            {
                if (tSize > (diffuseTexData.Height * diffuseTexData.Width))
                {
                    var resized = CreateResizedImage(diffuseTexData.BMPSouceAlpha, width, height);
                    diffusePixels = GetBytesFromBitmapSource((BitmapSource)resized);
                }
                else
                {
                    diffusePixels = GetBytesFromBitmapSource(diffuseTexData.BMPSouceAlpha);
                }
            }

            if (specularTexData != null)
            {
                if (tSize > (specularTexData.Height * specularTexData.Width))
                {
                    var resized = CreateResizedImage(specularTexData.BMPSouceAlpha, width, height);
                    specularPixels = GetBytesFromBitmapSource((BitmapSource)resized);
                }
                else
                {
                    specularPixels = GetBytesFromBitmapSource(specularTexData.BMPSouceAlpha);
                }
            }

            if (normalTexData != null)
            {
                if (tSize > (normalTexData.Height * normalTexData.Width))
                {
                    var resized = CreateResizedImage(normalTexData.BMPSouceAlpha, width, height);
                    normalBitmap = (BitmapSource)resized;
                    normalPixels = GetBytesFromBitmapSource((BitmapSource)resized);
                }
                else
                {
                    normalPixels = GetBytesFromBitmapSource(normalTexData.BMPSouceAlpha);
                }
            }

            List <byte> diffuseMap  = new List <byte>();
            List <byte> specularMap = new List <byte>();
            List <byte> emissiveMap = new List <byte>();
            List <byte> alphaMap    = new List <byte>();

            float R  = 1;
            float G  = 1;
            float B  = 1;
            float R1 = 1;
            float G1 = 1;
            float B1 = 1;

            for (int i = 3; i < normalPixels.Length; i += 4)
            {
                int alpha = normalPixels[i - 3];

                if (maskTexData != null)
                {
                    B = maskPixels[i - 1];
                    R = maskPixels[i - 1];
                    G = maskPixels[i - 1];

                    B1 = maskPixels[i - 3];
                    R1 = maskPixels[i - 3];
                    G1 = maskPixels[i - 3];
                }
                else
                {
                    if (diffusePixels != null)
                    {
                        B = diffusePixels[i - 3];
                        G = diffusePixels[i - 2];
                        R = diffusePixels[i - 1];
                    }
                    else
                    {
                        B = 255;
                        G = 255;
                        R = 255;
                    }

                    if (specularPixels != null)
                    {
                        B1 = specularPixels[i - 2];
                        G1 = specularPixels[i - 2];
                        R1 = specularPixels[i - 2];
                    }
                    else
                    {
                        B1 = 255;
                        G1 = 255;
                        R1 = 255;
                    }
                }

                System.Drawing.Color diffuseColor;
                System.Drawing.Color specularColor;
                System.Drawing.Color emissiveColor;
                System.Drawing.Color alphaColor;


                float pixel = (normalPixels[i] / 255f) * 15f;
                //int colorLoc = (int)Math.Floor(pixel + 0.5f);
                float percent = (float)(pixel - Math.Truncate(pixel));

                if (percent != 0)
                {
                    var color2Loc = (int)(Math.Truncate(pixel));
                    var color1Loc = color2Loc + 1;

                    var color1 = System.Drawing.Color.FromArgb(alpha, colorList[color1Loc].R, colorList[color1Loc].G, colorList[color1Loc].B);
                    var color2 = System.Drawing.Color.FromArgb(alpha, colorList[color2Loc].R, colorList[color2Loc].G, colorList[color2Loc].B);

                    var diffuseBlend = Blend(color1, color2, percent);

                    color1 = System.Drawing.Color.FromArgb(255, specularList[color1Loc].R, specularList[color1Loc].G, specularList[color1Loc].B);
                    color2 = System.Drawing.Color.FromArgb(255, specularList[color2Loc].R, specularList[color2Loc].G, specularList[color2Loc].B);

                    var specBlend = Blend(color1, color2, percent);

                    color1 = System.Drawing.Color.FromArgb(255, emissiveList[color1Loc].R, emissiveList[color1Loc].G, emissiveList[color1Loc].B);
                    color2 = System.Drawing.Color.FromArgb(255, emissiveList[color2Loc].R, emissiveList[color2Loc].G, emissiveList[color2Loc].B);

                    var emisBlend = Blend(color1, color2, percent);

                    diffuseColor  = System.Drawing.Color.FromArgb(alpha, (int)((diffuseBlend.R / 255f) * R), (int)((diffuseBlend.G / 255f) * G), (int)((diffuseBlend.B / 255f) * B));
                    specularColor = System.Drawing.Color.FromArgb(255, (int)((specBlend.R / 255f) * R1), (int)((specBlend.G / 255f) * G1), (int)((specBlend.B / 255f) * B1));
                    emissiveColor = System.Drawing.Color.FromArgb(255, emisBlend.R, emisBlend.G, emisBlend.B);
                }
                else
                {
                    var colorLoc = (int)Math.Floor(pixel + 0.5f);

                    diffuseColor  = System.Drawing.Color.FromArgb(alpha, (int)((colorList[colorLoc].R / 255f) * R), (int)((colorList[colorLoc].G / 255f) * G), (int)((colorList[colorLoc].B / 255f) * B));
                    specularColor = System.Drawing.Color.FromArgb(255, (int)((specularList[colorLoc].R / 255f) * R1), (int)((specularList[colorLoc].G / 255f) * G1), (int)((specularList[colorLoc].B / 255f) * B1));
                    emissiveColor = System.Drawing.Color.FromArgb(255, emissiveList[colorLoc].R, emissiveList[colorLoc].G, emissiveList[colorLoc].B);
                }


                alphaColor = System.Drawing.Color.FromArgb(255, alpha, alpha, alpha);

                diffuseMap.AddRange(BitConverter.GetBytes(diffuseColor.ToArgb()));
                specularMap.AddRange(BitConverter.GetBytes(specularColor.ToArgb()));
                emissiveMap.AddRange(BitConverter.GetBytes(emissiveColor.ToArgb()));
                alphaMap.AddRange(BitConverter.GetBytes(alphaColor.ToArgb()));
            }

            int stride = (int)normalBitmap.Width * (32 / 8);


            var scale = 1;

            if (width >= 4096 || height >= 4096)
            {
                scale = 4;
            }
            else if (width >= 2048 || height >= 2048)
            {
                scale = 2;
            }

            var nWidth  = width / scale;
            var nHeight = height / scale;

            BitmapSource bitmapSource = BitmapSource.Create(width, height, normalBitmap.DpiX, normalBitmap.DpiY, PixelFormats.Bgra32, null, diffuseMap.ToArray(), stride);

            texBitmaps[0] = (BitmapSource)CreateResizedImage(bitmapSource, nWidth, nHeight);

            bitmapSource  = BitmapSource.Create(width, height, normalBitmap.DpiX, normalBitmap.DpiY, PixelFormats.Bgra32, null, specularMap.ToArray(), stride);
            texBitmaps[1] = (BitmapSource)CreateResizedImage(bitmapSource, nWidth, nHeight);

            //texBitmaps[2] = normalTexData.BMPSouceNoAlpha;
            texBitmaps[2] = (BitmapSource)CreateResizedImage(normalTexData.BMPSouceNoAlpha, nWidth, nHeight);

            bitmapSource  = BitmapSource.Create(width, height, normalBitmap.DpiX, normalBitmap.DpiY, PixelFormats.Bgra32, null, alphaMap.ToArray(), stride);
            texBitmaps[3] = (BitmapSource)CreateResizedImage(bitmapSource, nWidth, nHeight);

            bitmapSource  = BitmapSource.Create(width, height, normalBitmap.DpiX, normalBitmap.DpiY, PixelFormats.Bgra32, null, emissiveMap.ToArray(), stride);
            texBitmaps[4] = (BitmapSource)CreateResizedImage(bitmapSource, nWidth, nHeight);

            foreach (var tb in texBitmaps)
            {
                tb.Freeze();
            }

            return(texBitmaps);
        }
Beispiel #11
0
        /// <summary>
        /// Gets the data from the MTRL file
        /// </summary>
        /// <param name="offset">MTRL file offset</param>
        /// <param name="isUncompressed">DX compression</param>
        /// <returns>Data from MTRL file</returns>
        public static MTRLData GetMTRLInfo(int offset, bool isUncompressed)
        {
            int datNum = ((offset / 8) & 0x000f) / 2;

            MTRLData mtrlInfo = new MTRLData();

            using (BinaryReader br = new BinaryReader(new MemoryStream(Helper.GetType2DecompressedData(offset, datNum))))
            {
                br.BaseStream.Seek(6, SeekOrigin.Begin);
                short colorDataSize   = br.ReadInt16();
                short textureNameSize = br.ReadInt16();
                br.ReadBytes(2);
                byte numOfTextures  = br.ReadByte();
                byte numOfMaps      = br.ReadByte();
                byte numOfColorSets = br.ReadByte();
                byte unknown        = br.ReadByte();

                int headerEnd = 16 + ((numOfTextures + numOfMaps + numOfColorSets) * 4);

                int[] texPathOffsets = new int[numOfTextures + 1];

                for (int i = 0; i < numOfTextures + 1; i++)
                {
                    texPathOffsets[i] = br.ReadInt16();
                    br.ReadBytes(2);
                }

                br.ReadBytes((numOfMaps - 1) * 4);

                for (int i = 0; i < numOfTextures; i++)
                {
                    br.BaseStream.Seek(headerEnd + texPathOffsets[i], SeekOrigin.Begin);

                    string fullPath = Encoding.ASCII.GetString(br.ReadBytes(texPathOffsets[i + 1] - texPathOffsets[i])).Replace("\0", "");

                    string fileName = fullPath.Substring(fullPath.LastIndexOf("/") + 1);

                    if (Properties.Settings.Default.DX_Ver.Equals("DX11") && isUncompressed)
                    {
                        if (textureNameSize > 50)
                        {
                            fileName = fileName.Insert(0, "--");

                            int mtrlOffset = Helper.GetItemOffset(FFCRC.GetHash(fullPath.Substring(0, fullPath.LastIndexOf("/"))), FFCRC.GetHash(fileName));

                            if (mtrlOffset == 0)
                            {
                                fileName = fileName.Substring(2);
                            }
                        }
                    }

                    int texHash = FFCRC.GetHash(fileName);

                    string mapName = GetMapName(fileName);

                    if (fileName.Contains("_s.tex"))
                    {
                        mtrlInfo.SpecularPath = fullPath.Substring(0, fullPath.LastIndexOf("/")) + "/" + fileName;
                        mtrlInfo.TextureMaps.Add(new ComboBoxInfo()
                        {
                            Name = mapName, ID = "", IsNum = false
                        });
                        mtrlInfo.SpecularOffset = Helper.GetItemOffset(FFCRC.GetHash(fullPath.Substring(0, fullPath.LastIndexOf("/"))), FFCRC.GetHash(fileName));
                    }
                    else if (fileName.Contains("_d.tex"))
                    {
                        mtrlInfo.DiffusePath = fullPath.Substring(0, fullPath.LastIndexOf("/")) + "/" + fileName;
                        mtrlInfo.TextureMaps.Add(new ComboBoxInfo()
                        {
                            Name = mapName, ID = "", IsNum = false
                        });
                        mtrlInfo.DiffuseOffset = Helper.GetItemOffset(FFCRC.GetHash(fullPath.Substring(0, fullPath.LastIndexOf("/"))), FFCRC.GetHash(fileName));
                    }
                    else if (fileName.Contains("_n.tex"))
                    {
                        mtrlInfo.NormalPath = fullPath.Substring(0, fullPath.LastIndexOf("/")) + "/" + fileName;
                        mtrlInfo.TextureMaps.Add(new ComboBoxInfo()
                        {
                            Name = mapName, ID = "", IsNum = false
                        });
                        mtrlInfo.NormalOffset = Helper.GetItemOffset(FFCRC.GetHash(fullPath.Substring(0, fullPath.LastIndexOf("/"))), FFCRC.GetHash(fileName));
                    }
                    else if (fileName.Contains("_m.tex"))
                    {
                        mtrlInfo.MaskPath = fullPath.Substring(0, fullPath.LastIndexOf("/")) + "/" + fileName;
                        mtrlInfo.TextureMaps.Add(new ComboBoxInfo()
                        {
                            Name = mapName, ID = "", IsNum = false
                        });
                        mtrlInfo.MaskOffset = Helper.GetItemOffset(FFCRC.GetHash(fullPath.Substring(0, fullPath.LastIndexOf("/"))), FFCRC.GetHash(fileName));
                    }
                }

                if (numOfColorSets > 0 && colorDataSize > 0)
                {
                    br.BaseStream.Seek((16 + (numOfTextures * 4) + (numOfMaps * 4) + (numOfColorSets * 4) + textureNameSize + 4), SeekOrigin.Begin);
                    mtrlInfo.TextureMaps.Add(new ComboBoxInfo()
                    {
                        Name = Strings.ColorSet, ID = "", IsNum = false
                    });

                    if (colorDataSize == 544)
                    {
                        mtrlInfo.ColorData  = br.ReadBytes(colorDataSize - 32);
                        mtrlInfo.ColorFlags = br.ReadBytes(32);
                    }
                    else
                    {
                        mtrlInfo.ColorData = br.ReadBytes(colorDataSize);
                    }
                }
            }

            return(mtrlInfo);
        }
Beispiel #12
0
        /// <summary>
        /// Parses the data of the items MTRL file
        /// </summary>
        /// <param name="item">currently selected item</param>
        /// <param name="raceID">currently selected race</param>
        /// <param name="selectedCategory">the category of the item</param>
        /// <param name="part">currently selected part</param>
        /// <param name="IMCVersion">version of selected item</param>
        /// <param name="type">the items type</param>
        /// <returns>A tuple containing the MTRLInfo and Observable Collection containing texture map names</returns>
        public static Tuple <MTRLData, ObservableCollection <ComboBoxInfo> > GetMTRLData(ItemData item, string raceID, string selectedCategory, string part, string IMCVersion, string type, string modelID, string VFXVersion)
        {
            string MTRLFolder = "";
            string MTRLFile   = "";
            int    offset;
            ObservableCollection <ComboBoxInfo> cbiList;
            Tuple <MTRLData, ObservableCollection <ComboBoxInfo> > info;
            MTRLData mtrlInfo = null;

            if (item.ItemName.Equals(Strings.Face))
            {
                MTRLFolder = String.Format(Strings.FaceMtrlFolder, raceID, part.PadLeft(4, '0'));

                var fileHashList = Helper.GetAllFilesInFolder(FFCRC.GetHash(MTRLFolder));

                cbiList = new ObservableCollection <ComboBoxInfo>();

                if (fileHashList.Contains(FFCRC.GetHash(String.Format(Strings.FaceMtrlFile, raceID, part.PadLeft(4, '0'), "fac"))))
                {
                    cbiList.Add(new ComboBoxInfo()
                    {
                        Name = Strings.Face, ID = "", IsNum = false
                    });
                }

                if (fileHashList.Contains(FFCRC.GetHash(String.Format(Strings.FaceMtrlFile, raceID, part.PadLeft(4, '0'), "iri"))))
                {
                    cbiList.Add(new ComboBoxInfo()
                    {
                        Name = Strings.Iris, ID = "", IsNum = false
                    });
                }

                if (fileHashList.Contains(FFCRC.GetHash(String.Format(Strings.FaceMtrlFile, raceID, part.PadLeft(4, '0'), "etc"))))
                {
                    cbiList.Add(new ComboBoxInfo()
                    {
                        Name = Strings.Etc, ID = "", IsNum = false
                    });
                }

                info = new Tuple <MTRLData, ObservableCollection <ComboBoxInfo> >(mtrlInfo, cbiList);
            }
            else if (item.ItemName.Equals(Strings.Body))
            {
                MTRLFolder = String.Format(Strings.BodyMtrlFolder, raceID, part.PadLeft(4, '0'));
                MTRLFile   = String.Format(Strings.BodyMtrlFile, raceID, part.PadLeft(4, '0'));

                if (Helper.FileExists(FFCRC.GetHash(MTRLFile), FFCRC.GetHash(MTRLFolder)))
                {
                    offset = Helper.GetItemOffset(FFCRC.GetHash(MTRLFolder), FFCRC.GetHash(MTRLFile));

                    mtrlInfo = GetMTRLInfo(offset, true);

                    info = new Tuple <MTRLData, ObservableCollection <ComboBoxInfo> >(mtrlInfo, mtrlInfo.TextureMaps);
                }
                else
                {
                    return(null);
                }
            }
            else if (item.ItemName.Equals(Strings.Hair))
            {
                MTRLFolder = String.Format(Strings.HairMtrlFolder, raceID, part.PadLeft(4, '0'));

                var fileHashList = Helper.GetAllFilesInFolder(FFCRC.GetHash(MTRLFolder));

                cbiList = new ObservableCollection <ComboBoxInfo>();

                if (fileHashList.Contains(FFCRC.GetHash(String.Format(Strings.HairMtrlFile, raceID, part.PadLeft(4, '0'), "hir", "a"))))
                {
                    cbiList.Add(new ComboBoxInfo()
                    {
                        Name = Strings.Hair, ID = "", IsNum = false
                    });
                }

                if (fileHashList.Contains(FFCRC.GetHash(String.Format(Strings.HairMtrlFile, raceID, part.PadLeft(4, '0'), "acc", "b"))))
                {
                    cbiList.Add(new ComboBoxInfo()
                    {
                        Name = Strings.Accessory, ID = "", IsNum = false
                    });
                }

                info = new Tuple <MTRLData, ObservableCollection <ComboBoxInfo> >(mtrlInfo, cbiList);
            }
            else if (item.ItemName.Equals(Strings.Face_Paint) || item.ItemName.Equals(Strings.Equipment_Decals))
            {
                string texPath = "chara/common/texture/";

                if (item.ItemName.Equals(Strings.Face_Paint))
                {
                    texPath = texPath + "decal_face/_decal_{0}.tex";
                }
                else
                {
                    texPath = texPath + "decal_equip/-decal_{0}.tex";
                }

                cbiList = new ObservableCollection <ComboBoxInfo>
                {
                    new ComboBoxInfo()
                    {
                        Name = Strings.Mask, ID = "", IsNum = false
                    }
                }
                ;
                mtrlInfo = new MTRLData()
                {
                    MaskPath = texPath
                };
                info = new Tuple <MTRLData, ObservableCollection <ComboBoxInfo> >(mtrlInfo, cbiList);
            }
            else if (item.ItemName.Equals(Strings.Tail))
            {
                MTRLFolder = String.Format(Strings.TailMtrlFolder, raceID, part.PadLeft(4, '0'));
                MTRLFile   = string.Format(Strings.TailMtrlFile, raceID, part.PadLeft(4, '0'));

                if (Helper.FileExists(FFCRC.GetHash(MTRLFile), FFCRC.GetHash(MTRLFolder)))
                {
                    offset = Helper.GetItemOffset(FFCRC.GetHash(MTRLFolder), FFCRC.GetHash(MTRLFile));

                    mtrlInfo = GetMTRLInfo(offset, true);

                    info = new Tuple <MTRLData, ObservableCollection <ComboBoxInfo> >(mtrlInfo, mtrlInfo.TextureMaps);
                }
                else
                {
                    return(null);
                }
            }
            else if (selectedCategory.Equals(Strings.Pets))
            {
                int p = 1;

                if (item.ItemName.Equals(Strings.Selene) || item.ItemName.Equals(Strings.Bishop_Autoturret))
                {
                    p = 2;
                }

                MTRLFolder = String.Format(Strings.MonsterMtrlFolder, Info.petID[item.ItemName], p.ToString().PadLeft(4, '0')) + part.PadLeft(4, '0');
                MTRLFile   = String.Format(Strings.MonsterMtrlFile, Info.petID[item.ItemName], p.ToString().PadLeft(4, '0'), "a");

                if (Helper.FileExists(FFCRC.GetHash(MTRLFile), FFCRC.GetHash(MTRLFolder)))
                {
                    offset = Helper.GetItemOffset(FFCRC.GetHash(MTRLFolder), FFCRC.GetHash(MTRLFile));

                    mtrlInfo            = GetMTRLInfo(offset, false);
                    mtrlInfo.MTRLPath   = MTRLFolder + "/" + MTRLFile;
                    mtrlInfo.MTRLOffset = offset;

                    info = new Tuple <MTRLData, ObservableCollection <ComboBoxInfo> >(mtrlInfo, mtrlInfo.TextureMaps);
                }
                else
                {
                    return(null);
                }
            }
            else if (selectedCategory.Equals(Strings.Mounts))
            {
                if (item.PrimaryMTRLFolder.Contains("demihuman"))
                {
                    SortedSet <ComboBoxInfo> typeSet = new SortedSet <ComboBoxInfo>();

                    var fileHashList = Helper.GetAllFilesInFolder(FFCRC.GetHash(item.PrimaryMTRLFolder + IMCVersion));

                    foreach (string abr in Info.slotAbr.Values)
                    {
                        MTRLFile = String.Format(Strings.DemiMtrlFile, item.PrimaryModelID.PadLeft(4, '0'), item.PrimaryModelBody.PadLeft(4, '0'), abr);

                        if (fileHashList.Contains(FFCRC.GetHash(MTRLFile)))
                        {
                            typeSet.Add(new ComboBoxInfo()
                            {
                                Name = Info.slotAbr.FirstOrDefault(x => x.Value == abr).Key, ID = "", IsNum = false
                            });
                        }
                    }
                    info = new Tuple <MTRLData, ObservableCollection <ComboBoxInfo> >(mtrlInfo, new ObservableCollection <ComboBoxInfo>(typeSet.ToList()));
                }
                else
                {
                    MTRLFile = String.Format(Strings.MonsterMtrlFile, item.PrimaryModelID.PadLeft(4, '0'), item.PrimaryModelBody.PadLeft(4, '0'), part);

                    if (Helper.FileExists(FFCRC.GetHash(MTRLFile), FFCRC.GetHash(item.PrimaryMTRLFolder + IMCVersion)))
                    {
                        offset              = Helper.GetItemOffset(FFCRC.GetHash(item.PrimaryMTRLFolder + IMCVersion), FFCRC.GetHash(MTRLFile));
                        mtrlInfo            = GetMTRLInfo(offset, false);
                        mtrlInfo.MTRLPath   = item.PrimaryMTRLFolder + IMCVersion + "/" + MTRLFile;
                        mtrlInfo.MTRLOffset = offset;

                        info = new Tuple <MTRLData, ObservableCollection <ComboBoxInfo> >(mtrlInfo, mtrlInfo.TextureMaps);
                    }
                    else
                    {
                        return(null);
                    }
                }
            }
            else if (selectedCategory.Equals(Strings.Minions))
            {
                MTRLFile = String.Format(Strings.MonsterMtrlFile, item.PrimaryModelID.PadLeft(4, '0'), item.PrimaryModelBody.PadLeft(4, '0'), part);

                if (Helper.FileExists(FFCRC.GetHash(MTRLFile), FFCRC.GetHash(item.PrimaryMTRLFolder + IMCVersion)))
                {
                    offset              = Helper.GetItemOffset(FFCRC.GetHash(item.PrimaryMTRLFolder + IMCVersion), FFCRC.GetHash(MTRLFile));
                    mtrlInfo            = GetMTRLInfo(offset, false);
                    mtrlInfo.MTRLPath   = item.PrimaryMTRLFolder + IMCVersion + "/" + MTRLFile;
                    mtrlInfo.MTRLOffset = offset;

                    info = new Tuple <MTRLData, ObservableCollection <ComboBoxInfo> >(mtrlInfo, mtrlInfo.TextureMaps);
                }
                else
                {
                    return(null);
                }
            }
            else
            {
                var    categoryType = Helper.GetCategoryType(selectedCategory);
                string imcVersion   = IMCVersion;
                MTRLFolder = item.PrimaryMTRLFolder;

                if (categoryType.Equals("weapon"))
                {
                    if (!modelID.Equals(""))
                    {
                        MTRLFile   = String.Format(Strings.WeapMtrlFile, modelID, item.PrimaryModelBody, part);
                        MTRLFolder = item.PrimaryMTRLFolder.Substring(0, 14) + modelID + item.PrimaryMTRLFolder.Substring(18);
                    }
                    else
                    {
                        MTRLFile = String.Format(Strings.WeapMtrlFile, item.PrimaryModelID, item.PrimaryModelBody, part);
                    }

                    if (part.Equals("s") || type.Equals("Secondary"))
                    {
                        MTRLFolder = item.SecondaryMTRLFolder;
                        imcVersion = IMC.GetVersion(selectedCategory, item, true).Item1;
                        MTRLFile   = String.Format(Strings.WeapMtrlFile, item.SecondaryModelID, item.SecondaryModelBody, "a");
                    }
                }
                else if (categoryType.Equals("accessory"))
                {
                    MTRLFile = String.Format(Strings.AccMtrlFile, item.PrimaryModelID, Info.slotAbr[selectedCategory], part);
                }
                else if (categoryType.Equals("food"))
                {
                    MTRLFile = String.Format(Strings.WeapMtrlFile, item.PrimaryModelID, item.PrimaryModelBody, "a");
                }
                else
                {
                    MTRLFile = String.Format(Strings.EquipMtrlFile, raceID, item.PrimaryModelID, Info.slotAbr[selectedCategory], part);
                }

                string VFXFolder = "";
                string VFXFile   = "";

                ObservableCollection <ComboBoxInfo> cbi = new ObservableCollection <ComboBoxInfo>();

                if (Helper.FileExists(FFCRC.GetHash(MTRLFile), FFCRC.GetHash(MTRLFolder + imcVersion)))
                {
                    offset = Helper.GetItemOffset(FFCRC.GetHash(MTRLFolder + imcVersion), FFCRC.GetHash(MTRLFile));

                    mtrlInfo            = GetMTRLInfo(offset, false);
                    mtrlInfo.MTRLPath   = MTRLFolder + imcVersion + "/" + MTRLFile;
                    mtrlInfo.MTRLOffset = offset;

                    foreach (var texMap in mtrlInfo.TextureMaps)
                    {
                        cbi.Add(texMap);
                    }
                }
                else
                {
                    return(null);
                }

                if (!VFXVersion.Equals("0000"))
                {
                    if (categoryType.Equals("equipment"))
                    {
                        VFXFolder = string.Format(Strings.EquipVFXFolder, item.PrimaryModelID);
                        VFXFile   = string.Format(Strings.EquipVFXFile, VFXVersion);
                    }
                    else if (categoryType.Equals("weapon"))
                    {
                        VFXFolder = string.Format(Strings.WeapVFXFolder, item.PrimaryModelID, item.PrimaryModelBody);
                        VFXFile   = string.Format(Strings.WeapVFXFile, VFXVersion);
                    }

                    if (Helper.FileExists(FFCRC.GetHash(VFXFile), FFCRC.GetHash(VFXFolder)))
                    {
                        offset = Helper.GetItemOffset(FFCRC.GetHash(VFXFolder), FFCRC.GetHash(VFXFile));

                        var vfxData = GetVFXData(offset);

                        foreach (var vfx in vfxData.VFXPaths)
                        {
                            cbi.Add(new ComboBoxInfo()
                            {
                                Name = Path.GetFileNameWithoutExtension(vfx), ID = vfx, IsNum = false
                            });
                        }
                    }
                }

                info = new Tuple <MTRLData, ObservableCollection <ComboBoxInfo> >(mtrlInfo, cbi);
            }

            return(info);
        }