public ModListModel ParseEntry(JsonEntry entry) { ModListModel mlm = new ModListModel(); string race, map, part, type; if (entry.fullPath.Contains("mt_")) { Debug.WriteLine(entry.fullPath); } if (entry.fullPath.Contains("weapon") || entry.fullPath.Contains("accessory") || entry.fullPath.Contains("decal") || entry.fullPath.Contains("vfx") || entry.fullPath.Contains("ui/")) { race = Strings.All; } else if (entry.fullPath.Contains("monster") || entry.fullPath.Contains("demihuman")) { race = Strings.Monster; } else { race = entry.fullPath.Substring(entry.fullPath.LastIndexOf('/')); if (entry.fullPath.Contains("mt_") && entry.fullPath.Contains("_acc_")) { race = race.Substring(race.IndexOf("_") + 2, 4); } else if ((entry.fullPath.Contains("_fac_") || entry.fullPath.Contains("_etc_") || entry.fullPath.Contains("_acc_")) && Properties.Settings.Default.DX_Ver.Equals(Strings.DX11)) { race = race.Substring(race.LastIndexOf("--c") + 3, 4); } else if (entry.fullPath.Contains("_fac_") || entry.fullPath.Contains("_etc_") || entry.fullPath.Contains("_acc_")) { race = race.Substring(race.LastIndexOf("/c") + 2, 4); } else if (entry.fullPath.Contains("_c_")) { race = race.Substring(race.IndexOf("_c") + 2, 4); } else { if (entry.fullPath.Contains(".mdl") && entry.fullPath.Contains("_fac")) { race = race.Substring(race.IndexOf('c') + 1, 4); } else { race = race.Substring(race.LastIndexOf('c') + 1, 4); } } if (entry.fullPath.Contains("mt_")) { Debug.WriteLine(race + "\n"); } race = Info.IDRace[race]; } mlm.Race = race; if (entry.fullPath.Contains("_d.")) { map = Strings.Diffuse; } else if (entry.fullPath.Contains("_n.")) { map = Strings.Normal; } else if (entry.fullPath.Contains("_s.")) { map = Strings.Specular; } else if (entry.fullPath.Contains("material")) { map = Strings.ColorSet; } else if (entry.fullPath.Contains("model")) { map = "3D"; } else if (entry.fullPath.Contains("ui/")) { map = "UI"; } else { map = Strings.Mask; } mlm.Map = map; if (entry.fullPath.Contains("_b_")) { part = "b"; } else if (entry.fullPath.Contains("_c_")) { part = "c"; } else if (entry.fullPath.Contains("_d_")) { part = "d"; } else if (entry.fullPath.Contains("decal")) { part = entry.fullPath.Substring(entry.fullPath.LastIndexOf('_') + 1, entry.fullPath.LastIndexOf('.') - (entry.fullPath.LastIndexOf('_') + 1)); } else { part = "a"; } mlm.Part = part; if (entry.fullPath.Contains("_iri_")) { type = "Iris"; } else if (entry.fullPath.Contains("_etc_")) { type = "Etc."; } else if (entry.fullPath.Contains("_fac_")) { type = "Face"; } else if (entry.fullPath.Contains("_hir_")) { type = "Hair"; } else if (entry.fullPath.Contains("_acc_")) { type = "Accessory"; } else if (entry.fullPath.Contains("demihuman")) { type = entry.fullPath.Substring(entry.fullPath.LastIndexOf('_') - 3, 3); type = (Info.slotAbr).FirstOrDefault(x => x.Value == type).Key; } else { type = "-"; } mlm.Type = type; if (entry.fullPath.Contains("material")) { var info = MTRL.GetMTRLInfo(entry.modOffset, false); var bitmap = TEX.ColorSetToBitmap(info.ColorData); mlm.BMP = Imaging.CreateBitmapSourceFromHBitmap(bitmap.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions()); mlm.BMP.Freeze(); bitmap.Dispose(); } else if (entry.fullPath.Contains("model")) { mlm.BMP = new BitmapImage(new Uri("pack://application:,,,/FFXIV TexTools 2;component/Resources/3DModel.png")); } else { TEXData texData; if (entry.fullPath.Contains("vfx")) { texData = TEX.GetVFX(entry.modOffset, entry.datFile); } else { if (entry.fullPath.Contains("icon")) { texData = TEX.GetTex(entry.modOffset, entry.datFile); } else { texData = TEX.GetTex(entry.modOffset, entry.datFile); } } var scale = 1; if (texData.Width >= 4096 || texData.Height >= 4096) { scale = 16; } else if (texData.Width >= 2048 || texData.Height >= 2048) { scale = 8; } else if (texData.Width >= 1024 || texData.Height >= 1024) { scale = 4; } var nWidth = texData.Width / scale; var nHeight = texData.Height / scale; var resizedImage = TexHelper.CreateResizedImage(texData.BMPSouceNoAlpha, nWidth, nHeight); mlm.BMP = (BitmapSource)resizedImage; mlm.BMP.Freeze(); } var offset = Helper.GetDataOffset(FFCRC.GetHash(entry.fullPath.Substring(0, entry.fullPath.LastIndexOf("/"))), FFCRC.GetHash(Path.GetFileName(entry.fullPath)), entry.datFile); if (offset == entry.modOffset) { mlm.ActiveBorder = Brushes.Green; mlm.Active = Brushes.Transparent; mlm.ActiveOpacity = 1; } else if (offset == entry.originalOffset) { mlm.ActiveBorder = Brushes.Red; mlm.Active = Brushes.Gray; mlm.ActiveOpacity = 0.5f; } else { mlm.ActiveBorder = Brushes.Red; mlm.Active = Brushes.Red; mlm.ActiveOpacity = 1; } mlm.Entry = entry; return(mlm); }
/// <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); }