Ejemplo n.º 1
0
            public SegaSaturnPolygonData GetPolygonData(List <Texture> textures, Option option)
            {
                bool   hasTexture = this.MeshSources.Any(item => item.MeshSourceKind == MeshSource.MeshSourceKindEnum.Texcoord);
                string name       = this.Name ?? this.Id ?? this.GetHashCode().ToString();

                name = Regex.Replace(name, "[^A-Za-z0-9]", "");
                if (this.GeometryIndex > 1)
                {
                    name += this.GeometryIndex.ToString();
                }
                SegaSaturnPolygonData toReturn = new SegaSaturnPolygonData
                {
                    Points = this.GetPoints(),
                    Name   = name
                };

                if (this.PolygonCount > 10000)
                {
                    MessageBox.Show(String.Format("{0} polygons({1}) ? Seriously !? It's a Sega Saturn not a PS4 :)", this.PolygonCount, toReturn.Name), Editor.Instance.Text, MessageBoxButtons.OK, MessageBoxIcon.Error);
                    throw new InvalidOperationException("Too many polygons");
                }
                List <SegaSaturnVertices> vertices = this.GetVertices();
                List <SegaSaturnNormal>   normals  = this.GetNormals();

retry:
                toReturn.Textures   = new List <SegaSaturnTexture>();
                toReturn.Polygons   = new List <SegaSaturnPolygon>();
                toReturn.Attributes = new List <SegaSaturnAttribute>();
                for (int i = 0; i < this.PolygonCount; ++i)
                {
                    toReturn.Polygons.Add(new SegaSaturnPolygon
                    {
                        Normal   = normals[i],
                        Vertices = vertices[i]
                    });
                    toReturn.Attributes.Add(new SegaSaturnAttribute
                    {
                        FrontBackPlane     = SegaSaturnAttribute.FrontBackPlaneEnum.Dual,
                        ZSortSpecification = SegaSaturnAttribute.ZSortSpecificationEnum.Cen,
                        Color          = new SegaSaturnColor(Collada.DefaultColors[(this.GeometryIndex - 1) % Collada.DefaultColors.Count]),
                        UseLight       = option.UseLight,
                        UseScreenDoors = option.UseScreenDoors
                    });
                }
                if (hasTexture)
                {
                    toReturn.Textures = this.GetTextures(textures, toReturn.Attributes, 64);
                }
                else
                {
                    toReturn.Textures = new List <SegaSaturnTexture>();
                }
                if (toReturn.Textures.Count > 64)
                {
                    if (MessageBox.Show(String.Format("{0} textured polygons({1}) is too much for the Sega Saturn but would you like to export the mesh without textures ?", this.PolygonCount, toReturn.Name), Editor.Instance.Text, MessageBoxButtons.YesNo, MessageBoxIcon.Warning) == DialogResult.No)
                    {
                        throw new InvalidOperationException("Too many polygons");
                    }
                    hasTexture = false;
                    goto retry;
                }
                return(toReturn);
            }
Ejemplo n.º 2
0
        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);
        }