public static void To24BitsTga(SegaSaturnTexture texture, Stream output, SegaSaturnColor transparentColor = null) { using (Bitmap bmp = SegaSaturnImageConverter.ToBitmap(texture)) { SegaSaturnImageConverter.To24BitsTga(bmp, output, transparentColor); } }
public static void ToBin(SegaSaturnTexture texture, string path, bool header) { using (Stream stream = File.Create(path)) { SegaSaturnImageConverter.ToBin(texture, stream, header); } }
public static SegaSaturnTexture LoadFromBitmap(Bitmap bitmap, SegaSaturnColor transparentColor = null) { if (bitmap == null) { return(null); } SegaSaturnTexture toReturn = new SegaSaturnTexture(bitmap.Width, bitmap.Height); using (BmpPixelSnoop tmp = new BmpPixelSnoop(bitmap)) { for (int y = 0; y < tmp.Height; y++) { for (int x = 0; x < tmp.Width; x++) { Color c = tmp.GetPixel(x, y); if (c.A != 255 && transparentColor != null && transparentColor.A == 255) { c = transparentColor; } toReturn.SetPixel(x, y, c); } } } return(toReturn); }
private List <SegaSaturnTexture> GetTextures(List <Texture> textureLibrary, List <SegaSaturnAttribute> attributes, int maxTextureSize) { if (textureLibrary == null || textureLibrary.Count <= 0) { return(new List <SegaSaturnTexture>()); } if (textureLibrary.Count > 1) { MessageBox.Show("Sorry, only one texture per file are supported yet :'(", Editor.Instance.Text, MessageBoxButtons.OK, MessageBoxIcon.Error); throw new InvalidOperationException("Too many textures"); } MeshSource textureSource = this.MeshSources.FirstOrDefault(item => item.MeshSourceKind == MeshSource.MeshSourceKindEnum.Texcoord); if (textureSource == null) { return(new List <SegaSaturnTexture>()); } List <SegaSaturnTexture> toReturn = new List <SegaSaturnTexture>(); Dictionary <string, SegaSaturnTexture> dict = new Dictionary <string, SegaSaturnTexture>(); List <SegaSaturnTextureVerticesIndexes> list = this.GetTextureVerticesIndexes(); Texture tmp = textureLibrary.First(); Bitmap img = JoMapEditorTools.GetBitmap(tmp.Path); if (img.Width > maxTextureSize && img.Height > maxTextureSize) { img = JoMapEditorTools.ResizeImage(img, maxTextureSize, maxTextureSize); } else if (img.Width > maxTextureSize) { img = JoMapEditorTools.ResizeImage(img, maxTextureSize, img.Height); } else if (img.Height > maxTextureSize) { img = JoMapEditorTools.ResizeImage(img, img.Width, maxTextureSize); } for (int i = 0; i < list.Count; ++i) { SegaSaturnTextureCoordinates p1 = Geometry.ConvertToSegaSaturnTextureCoordinates(img, textureSource.Floats, list[i].Vertice1); SegaSaturnTextureCoordinates p2 = Geometry.ConvertToSegaSaturnTextureCoordinates(img, textureSource.Floats, list[i].Vertice2); SegaSaturnTextureCoordinates p3 = Geometry.ConvertToSegaSaturnTextureCoordinates(img, textureSource.Floats, list[i].Vertice3); SegaSaturnTextureCoordinates p4 = Geometry.ConvertToSegaSaturnTextureCoordinates(img, textureSource.Floats, list[i].Vertice4); if (p1.Hash == p2.Hash && p2.Hash == p3.Hash) { continue; } SegaSaturnTexture texture = SegaSaturnTexture.ConvertFrom(img, tmp.Name ?? Path.GetFileNameWithoutExtension(tmp.Path), p1, p2, p3, p4, list[i].IsTriangleMapping); if (!dict.ContainsKey(texture.Hash)) { texture.Name += toReturn.Count.ToString(); dict.Add(texture.Hash, texture); toReturn.Add(texture); } attributes[i].SpriteIndex = toReturn.FindIndex(item => item.Hash == texture.Hash); attributes[i].Color = null; } return(toReturn); }
public static void ToBin(SegaSaturnTexture texture, Stream outputStream, bool header) { using (BinaryWriter writer = new BinaryWriter(outputStream)) { if (header) { writer.Write((ushort)texture.Width); writer.Write((ushort)texture.Height); } for (int y = 0; y < texture.Height; y += texture.Width) { for (int x = 0; x < texture.Width; ++x) { writer.Write(texture.GetPixel(x, y).SaturnColor); } } } }
public static Bitmap ToBitmap(SegaSaturnTexture texture, SegaSaturnColor transparentColor = null) { if (texture == null) { return(null); } Bitmap toReturn = new Bitmap(texture.Width, texture.Height, PixelFormat.Format32bppArgb); using (BmpPixelSnoop tmp = new BmpPixelSnoop(toReturn)) { for (int y = 0; y < tmp.Height; y++) { for (int x = 0; x < tmp.Width; x++) { SegaSaturnColor color = texture.GetPixel(x, y); toReturn.SetPixel(x, y, transparentColor != null && color == transparentColor ? Color.Transparent : (Color)color); } } } return(toReturn); }
public static void ToPng(SegaSaturnTexture texture, string path, SegaSaturnColor transparentColor = null) { SegaSaturnImageConverter.ToBitmap(texture, transparentColor).Save(path, ImageFormat.Png); }
public static string ToSourceFile(SegaSaturnTexture texture, bool preprocessorInclusionProtection) { if (string.IsNullOrWhiteSpace(texture.Name)) { texture.Name = "Unnamed"; } StringBuilder sb = new StringBuilder(); if (preprocessorInclusionProtection) { #region Header sb.AppendLine("/*"); sb.AppendLine(" 3D Hardcoded image generated by SegaSaturn.NET.Converter"); sb.AppendLine("*/"); sb.AppendLine(); sb.AppendLine($"#ifndef __SPRITE{texture.Name.ToUpperInvariant()}_H__"); sb.AppendLine($"# define __SPRITE{texture.Name.ToUpperInvariant()}_H__"); sb.AppendLine(); #endregion } #region Bytes sb.AppendLine($"static const unsigned short SpriteData{texture.Name}[] = {{"); bool isFirstPixel = true; for (int y = 0; y < texture.Height; ++y) { for (int x = 0; x < texture.Width; ++x) { if (!isFirstPixel) { sb.Append(','); } sb.Append(texture.GetPixel(x, y).SaturnHexaString); isFirstPixel = false; } sb.AppendLine(); } sb.AppendLine("};"); sb.AppendLine(); #endregion #region jo_img sb.AppendLine($"const jo_img Sprite{texture.Name} = {{"); sb.AppendLine($" .width = {texture.Width},"); sb.AppendLine($" .height = {texture.Height},"); sb.AppendLine($" .data = (unsigned short *)SpriteData{texture.Name}"); sb.AppendLine("};"); sb.AppendLine(); #endregion if (preprocessorInclusionProtection) { #region Footer sb.AppendLine($"#endif /* !__SPRITE{texture.Name.ToUpperInvariant()}_H__ */"); #endregion } return(sb.ToString()); }
public List <SegaSaturnPolygonData> Parse(string path, Option option) { List <SegaSaturnPolygonData> toReturn = new List <SegaSaturnPolygonData>(); Dictionary <string, Material> material = new Dictionary <string, Material>(); Dictionary <string, SegaSaturnTexture> dict = new Dictionary <string, SegaSaturnTexture>(); List <SegaSaturnNormal> normals = new List <SegaSaturnNormal>(); List <SegaSaturnTextureCoordinates> textureCoordinates = new List <SegaSaturnTextureCoordinates>(); SegaSaturnPolygonData currentPolygonData = new SegaSaturnPolygonData(); Material currentMaterial = new Material(); bool newMesh = false; using (StreamReader reader = new StreamReader(path)) { string line; while ((line = reader.ReadLine()) != null) { string[] data = line.Split(new[] { " ", "\t" }, StringSplitOptions.RemoveEmptyEntries); if (data.Length <= 0) { continue; } switch (data[0].ToLower()) { case "usemtl": if (material.ContainsKey(data[1])) { currentMaterial = material[data[1]]; } else { currentMaterial = new Material(); } break; case "mtllib": material = this.ParseMaterial(data[1], option.WorkingDir, 128); break; case "g": if (String.IsNullOrWhiteSpace(currentPolygonData.Name)) { currentPolygonData.Name = data[1]; } break; case "v": if (newMesh) { dict.Clear(); newMesh = false; if (currentPolygonData != null) { if (String.IsNullOrWhiteSpace(currentPolygonData.Name)) { currentPolygonData.Name = String.Format("Unnamed{0}", toReturn.Count + 1); } toReturn.Add(currentPolygonData); } //normals = new List<SegaSaturnNormal>(); //textureCoordinates = new List<SegaSaturnTextureCoordinates>(); currentMaterial = new Material(); currentPolygonData = new SegaSaturnPolygonData(); } float x = float.Parse(data[1], CultureInfo.InvariantCulture) * (float)option.ZoomFactor; float y = float.Parse(data[2], CultureInfo.InvariantCulture) * (float)option.ZoomFactor; float z = float.Parse(data[3], CultureInfo.InvariantCulture) * (float)option.ZoomFactor; currentPolygonData.Points.Add(new SegaSaturnPoint(x, y, z)); break; case "vn": normals.Add(new SegaSaturnNormal(float.Parse(data[1], CultureInfo.InvariantCulture), float.Parse(data[2], CultureInfo.InvariantCulture), float.Parse(data[3], CultureInfo.InvariantCulture))); break; case "vt": textureCoordinates.Add(new SegaSaturnTextureCoordinates(float.Parse(data[1], CultureInfo.InvariantCulture), float.Parse(data[2], CultureInfo.InvariantCulture))); break; case "f": newMesh = true; if (data.Length > 5) { throw new NotSupportedException("Ngons are not supported"); } string v; string vt; string vn; this.ParseFace(data[1], out v, out vt, out vn); bool hasTexture = option.UseTexture && !String.IsNullOrEmpty(vt) && currentMaterial.Texture != null; bool hasNormal = !String.IsNullOrEmpty(vn); SegaSaturnAttribute attributes = new SegaSaturnAttribute { Color = hasTexture ? null : new SegaSaturnColor(Obj.DefaultColors[toReturn.Count % Obj.DefaultColors.Count]), ZSortSpecification = SegaSaturnAttribute.ZSortSpecificationEnum.Cen, FrontBackPlane = option.DualPlane ? SegaSaturnAttribute.FrontBackPlaneEnum.Dual : SegaSaturnAttribute.FrontBackPlaneEnum.Single, UseScreenDoors = option.UseScreenDoors, UseLight = option.UseLight }; currentPolygonData.Attributes.Add(attributes); SegaSaturnPolygon polygon = new SegaSaturnPolygon(); SegaSaturnTextureVerticesIndexes textureVertices = new SegaSaturnTextureVerticesIndexes(); if (hasNormal) { polygon.Normal = normals[int.Parse(vn, CultureInfo.InvariantCulture) - 1]; } polygon.Vertices = new SegaSaturnVertices(); //vertice #1 polygon.Vertices.Vertice1 = int.Parse(v, CultureInfo.InvariantCulture) - 1; textureVertices.Vertice1 = !String.IsNullOrWhiteSpace(vt) ? int.Parse(vt, CultureInfo.InvariantCulture) - 1 : 0; //vertice #2 this.ParseFace(data[2], out v, out vt, out vn); polygon.Vertices.Vertice2 = int.Parse(v, CultureInfo.InvariantCulture) - 1; textureVertices.Vertice2 = !String.IsNullOrWhiteSpace(vt) ? int.Parse(vt, CultureInfo.InvariantCulture) - 1 : 0; //vertice #3 this.ParseFace(data[3], out v, out vt, out vn); polygon.Vertices.Vertice3 = int.Parse(v, CultureInfo.InvariantCulture) - 1; textureVertices.Vertice3 = !String.IsNullOrWhiteSpace(vt) ? int.Parse(vt, CultureInfo.InvariantCulture) - 1 : 0; //vertice #4 if (data.Length <= 4) { polygon.Vertices.Vertice4 = polygon.Vertices.Vertice3; textureVertices.Vertice4 = textureVertices.Vertice3; } else { this.ParseFace(data[4], out v, out vt, out vn); polygon.Vertices.Vertice4 = int.Parse(v, CultureInfo.InvariantCulture) - 1; textureVertices.Vertice4 = !String.IsNullOrWhiteSpace(vt) ? int.Parse(vt, CultureInfo.InvariantCulture) - 1 : 0; } // Textures if (hasTexture) { SegaSaturnTextureCoordinates p1 = textureCoordinates[textureVertices.Vertice1]; p1.ComputeTextureCoordinates(currentMaterial.Texture.Width, currentMaterial.Texture.Height); SegaSaturnTextureCoordinates p2 = textureCoordinates[textureVertices.Vertice2]; p2.ComputeTextureCoordinates(currentMaterial.Texture.Width, currentMaterial.Texture.Height); SegaSaturnTextureCoordinates p3 = textureCoordinates[textureVertices.Vertice3]; p3.ComputeTextureCoordinates(currentMaterial.Texture.Width, currentMaterial.Texture.Height); SegaSaturnTextureCoordinates p4 = textureCoordinates[textureVertices.Vertice4]; p4.ComputeTextureCoordinates(currentMaterial.Texture.Width, currentMaterial.Texture.Height); if (p1.Hash != p2.Hash || p2.Hash != p3.Hash) { SegaSaturnTexture texture = SegaSaturnTexture.ConvertFrom(currentMaterial.Texture, currentMaterial.Name ?? Path.GetFileNameWithoutExtension(currentMaterial.TexturePath), p1, p2, p3, p4, textureVertices.IsTriangleMapping); if (!dict.ContainsKey(texture.Hash)) { texture.Name += currentPolygonData.Textures.Count.ToString(); dict.Add(texture.Hash, texture); currentPolygonData.Textures.Add(texture); } attributes.SpriteIndex = currentPolygonData.Textures.FindIndex(item => item.Hash == texture.Hash); attributes.Color = null; } } currentPolygonData.Polygons.Add(polygon); break; default: break; } } } if (currentPolygonData != null) { if (String.IsNullOrWhiteSpace(currentPolygonData.Name)) { currentPolygonData.Name = String.Format("Unnamed{0}", toReturn.Count + 1); } toReturn.Add(currentPolygonData); } return(toReturn); }