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