Exemple #1
0
 public ModelTriangle(FaceVertex fv1 = default,
                      FaceVertex fv2 = default, FaceVertex fv3 = default, Material?material = default)
 {
     FV1      = fv1;
     FV2      = fv2;
     FV3      = fv3;
     Material = material ?? Material.Error;
     Normal   = (FV2.Position - FV1.Position).Cross(FV3.Position - FV1.Position).Normalize();
 }
Exemple #2
0
        private static Model LoadFromString(string text, Material?material, float scale, Vector3 position,
                                            Vector3 rotationAxis, float angle)
        {
            const NumberStyles style = NumberStyles.Number;
            var culture = CultureInfo.CreateSpecificCulture("en-GB");
            // Separate lines from the file
            var lines = new List <string>(text.Split('\n'));

            // Lists to hold model data
            var vertices      = new List <Vector3>();
            var normals       = new List <Vector3>();
            var textureCoords = new List <Vector2>();
            var faces         = new List <(TempVertex, TempVertex, TempVertex)>();

            // Base values
            vertices.Add(new Vector3());
            textureCoords.Add(new Vector2());
            normals.Add(new Vector3());

            // Read file line by line
            foreach (var line in lines)
            {
                if (line.StartsWith("v ")) // Vertex definition
                {
                    // Cut off beginning of line
                    var temp = line.Substring(2);

                    Vector3?vec = null;

                    if (temp.Trim().Count(c => c == ' ') == 2) // Check if there's enough elements for a vertex
                    {
                        var vertexParts = temp.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);

                        // Attempt to parse each part of the vertice
                        var success = float.TryParse(vertexParts[0], style, culture, out var x);
                        success |= float.TryParse(vertexParts[1], style, culture, out var y);
                        success |= float.TryParse(vertexParts[2], style, culture, out var z);

                        vec = new Vector3(x, y, z);
                        vec = Vector3.Transform(vec.Value, scale, position, rotationAxis, angle);
                        // If any of the parses failed, report the error
                        if (!success)
                        {
                            Logger.LogConsole($"Error parsing vertex: {line}");
                        }
                    }
                    else
                    {
                        Logger.LogConsole($"Error parsing vertex: {line}");
                    }

                    vertices.Add(vec ?? new Vector3());
                }
                else if (line.StartsWith("vt ")) // Texture coordinate
                {
                    // Cut off beginning of line
                    var temp = line.Substring(2);

                    Vector2?vec = null;

                    if (temp.Trim().Count(c => c == ' ') > 0) // Check if there's enough elements for a vertex
                    {
                        var texCoordParts = temp.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);

                        // Attempt to parse each part of the vertex
                        var success = float.TryParse(texCoordParts[0], style, culture, out var x);
                        success |= float.TryParse(texCoordParts[1], style, culture, out var y);

                        vec = new Vector2(x, y);

                        // If any of the parses failed, report the error
                        if (!success)
                        {
                            Logger.LogConsole($"Error parsing texture coordinate: {line}");
                        }
                    }
                    else
                    {
                        Logger.LogConsole($"Error parsing texture coordinate: {line}");
                    }

                    textureCoords.Add(vec ?? new Vector2());
                }
                else if (line.StartsWith("vn ")) // Normal vector
                {
                    // Cut off beginning of line
                    var temp = line.Substring(2);

                    Vector3?vec = null;

                    if (temp.Trim().Count(c => c == ' ') == 2) // Check if there's enough elements for a normal
                    {
                        var vertexParts = temp.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);

                        // Attempt to parse each part of the vertice
                        var success = float.TryParse(vertexParts[0], style, culture, out var x);
                        success |= float.TryParse(vertexParts[1], style, culture, out var y);
                        success |= float.TryParse(vertexParts[2], style, culture, out var z);

                        vec = new Vector3(x, y, z);

                        // If any of the parses failed, report the error
                        if (!success)
                        {
                            Logger.LogConsole($"Error parsing normal: {line}");
                        }
                    }
                    else
                    {
                        Logger.LogConsole($"Error parsing normal: {line}");
                    }

                    normals.Add(vec ?? new Vector3());
                }
                else if (line.StartsWith("f ")) // Face definition
                {
                    // Cut off beginning of line
                    var temp = line.Substring(2);

                    if (temp.Trim().Count(c => c == ' ') == 2) // Check if there's enough elements for a face
                    {
                        var faceParts = temp.Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);

                        int t1, t2, t3;
                        int n1, n2, n3;

                        // Attempt to parse each part of the face
                        var success = int.TryParse(faceParts[0].Split('/')[0], out var v1);
                        success |= int.TryParse(faceParts[1].Split('/')[0], out var v2);
                        success |= int.TryParse(faceParts[2].Split('/')[0], out var v3);

                        if (faceParts[0].Count(c => c == '/') >= 2)
                        {
                            success |= int.TryParse(faceParts[0].Split('/')[1], out t1);
                            success |= int.TryParse(faceParts[1].Split('/')[1], out t2);
                            success |= int.TryParse(faceParts[2].Split('/')[1], out t3);
                            success |= int.TryParse(faceParts[0].Split('/')[2], out n1);
                            success |= int.TryParse(faceParts[1].Split('/')[2], out n2);
                            success |= int.TryParse(faceParts[2].Split('/')[2], out n3);
                        }
                        else
                        {
                            if (textureCoords.Count > v1 && textureCoords.Count > v2 && textureCoords.Count > v3)
                            {
                                t1 = v1;
                                t2 = v2;
                                t3 = v3;
                            }
                            else
                            {
                                t1 = 0;
                                t2 = 0;
                                t3 = 0;
                            }


                            if (normals.Count > v1 && normals.Count > v2 && normals.Count > v3)
                            {
                                n1 = v1;
                                n2 = v2;
                                n3 = v3;
                            }
                            else
                            {
                                n1 = 0;
                                n2 = 0;
                                n3 = 0;
                            }
                        }


                        // If any of the parses failed, report the error
                        if (!success)
                        {
                            Logger.LogConsole($"Error parsing face: {line}");
                        }
                        else
                        {
                            var tv1 = new TempVertex(v1, n1, t1);
                            var tv2 = new TempVertex(v2, n2, t2);
                            var tv3 = new TempVertex(v3, n3, t3);
                            faces.Add((tv1, tv2, tv3));
                        }
                    }
                    else
                    {
                        Logger.LogConsole($"Error parsing face: {line}");
                    }
                }
            }

            // Create the Model
            var vol = new Model();

            foreach (var face in faces)
            {
                var v1 = new FaceVertex(vertices[face.Item1.Vertex], normals[face.Item1.Normal],
                                        textureCoords[face.Item1.TexCoords]);
                var v2 = new FaceVertex(vertices[face.Item2.Vertex], normals[face.Item2.Normal],
                                        textureCoords[face.Item2.TexCoords]);
                var v3 = new FaceVertex(vertices[face.Item3.Vertex], normals[face.Item3.Normal],
                                        textureCoords[face.Item3.TexCoords]);

                vol.Triangles.Add(new ModelTriangle(v1, v2, v3, material));
            }

            return(vol);
        }