/// <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; } }
/// <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; } }
/// <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)); }
/// <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)); } }
/// <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; } }
/// <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); }
/// <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); } }
/// <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); }
/// <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); }
/// <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); }