private List <SegaSaturnTextureVerticesIndexes> GetTextureVerticesIndexes() { MeshSource textureSource = this.MeshSources.FirstOrDefault(item => item.MeshSourceKind == MeshSource.MeshSourceKindEnum.Texcoord); if (textureSource == null) { throw new InvalidOperationException("no Texcoord source in Collada"); } if (this.GeometryType == GeometryTypeEnum.QuadPolylist) { List <SegaSaturnTextureVerticesIndexes> toReturn = new List <SegaSaturnTextureVerticesIndexes>(); int i = textureSource.IndexOffset; while (i < this.VertexIndexes.Count) { SegaSaturnTextureVerticesIndexes coord = new SegaSaturnTextureVerticesIndexes(); coord.Vertice1 = this.VertexIndexes[i]; i += this.IndexOffsetRange + 1; coord.Vertice2 = this.VertexIndexes[i]; i += this.IndexOffsetRange + 1; coord.Vertice3 = this.VertexIndexes[i]; i += this.IndexOffsetRange + 1; coord.Vertice4 = this.VertexIndexes[i]; i += this.IndexOffsetRange + 1; toReturn.Add(coord); } return(toReturn); } if (this.GeometryType == GeometryTypeEnum.Polygons) { int vcountIndex = 0; List <SegaSaturnTextureVerticesIndexes> toReturn = new List <SegaSaturnTextureVerticesIndexes>(); int i = textureSource.IndexOffset; while (i < this.VertexIndexes.Count) { SegaSaturnTextureVerticesIndexes coord = new SegaSaturnTextureVerticesIndexes(); coord.Vertice1 = this.VertexIndexes[i]; i += this.IndexOffsetRange + 1; coord.Vertice2 = this.VertexIndexes[i]; i += this.IndexOffsetRange + 1; coord.Vertice3 = this.VertexIndexes[i]; if (this.VertexCount[vcountIndex] == 4) { i += this.IndexOffsetRange + 1; } coord.Vertice4 = this.VertexIndexes[i]; i += this.IndexOffsetRange + 1; toReturn.Add(coord); ++vcountIndex; } return(toReturn); } else { List <SegaSaturnTextureVerticesIndexes> toReturn = new List <SegaSaturnTextureVerticesIndexes>(); int i = textureSource.IndexOffset; while (i < this.VertexIndexes.Count) { SegaSaturnTextureVerticesIndexes coord = new SegaSaturnTextureVerticesIndexes(); coord.Vertice1 = this.VertexIndexes[i]; i += this.IndexOffsetRange + 1; coord.Vertice2 = this.VertexIndexes[i]; i += this.IndexOffsetRange + 1; coord.Vertice3 = this.VertexIndexes[i]; coord.Vertice4 = this.VertexIndexes[i];/*same as previous*/ i += this.IndexOffsetRange + 1; toReturn.Add(coord); } 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); }