Пример #1
0
        public void AddTempVertex(
            ref Vertex128 vertex128,
            ref Vector3 pos,
            ref Vector2 uv,
            ref Vector4 color,
            ref Vector3 normal)
        {
            TempVertexData vertex;
            Transform      transform;

            if (null == geoModel)
            {
                transform = Transform.Identity;
            }
            else
            {
                geoModel.Parent.BuildTransform(out transform);
                geoModel.AddVertex(MaterialFallback, ref vertex128);
            }
            vertex.position = transform.TransformPosition(pos);
            vertex.texCoord = uv;
            vertex.color    = color;
            vertex.normal   = transform.TransformVectorNoScale(normal);

            TempVertex.Add(ref MaterialFallback.references.list, ref vertex);
        }
Пример #2
0
        private void CalculateTangentBinormal(TempVertex vertex1, TempVertex vertex2, TempVertex vertex3, out Vector tangent, out Vector binormal)
        {
            // Calculate the two vectors for the this face.
            var vector1 = new[] { vertex2.x - vertex1.x, vertex2.y - vertex1.y, vertex2.z - vertex1.z };
            var vector2 = new[] { vertex3.x - vertex1.x, vertex3.y - vertex1.y, vertex3.z - vertex1.z };

            // Calculate the tu and tv texture space vectors.
            var tuVector = new[] { vertex2.tu - vertex1.tu, vertex3.tu - vertex1.tu };
            var tvVector = new[] { vertex2.tv - vertex1.tv, vertex3.tv - vertex1.tv };

            // Calculate the denominator of the tangent / binormal equation.
            var den = 1.0f / (tuVector[0] * tvVector[1] - tuVector[1] * tvVector[0]);

            // Calculate the cross products and multiply by the coefficient to get the tangent and binormal.
            tangent.x = (tvVector[1] * vector1[0] - tvVector[0] * vector2[0]) * den;
            tangent.y = (tvVector[1] * vector1[1] - tvVector[0] * vector2[1]) * den;
            tangent.z = (tvVector[1] * vector1[2] - tvVector[0] * vector2[2]) * den;

            binormal.x = (tuVector[0] * vector2[0] - tuVector[1] * vector1[0]) * den;
            binormal.y = (tuVector[0] * vector2[1] - tuVector[1] * vector1[1]) * den;
            binormal.z = (tuVector[0] * vector2[2] - tuVector[1] * vector1[2]) * den;

            // Calculate the length of this normal.
            var length = (float)Math.Sqrt(tangent.x * tangent.x + tangent.y * tangent.y + tangent.z * tangent.z);

            // Normalize the normal and the store it.
            tangent.x = tangent.x / length;
            tangent.y = tangent.y / length;
            tangent.z = tangent.z / length;

            // Calculate the length of this normal.
            length = (float)Math.Sqrt(binormal.x * binormal.x + binormal.y * binormal.y + binormal.z * binormal.z);

            // Normalize the normal and the store it.
            binormal.x = binormal.x / length;
            binormal.y = binormal.y / length;
            binormal.z = binormal.z / length;
        }
Пример #3
0
        public static ObjVolume LoadFromString(string obj)
        {
            // Seperate lines from the file
            List <String> lines = new List <string>(obj.Split('\n'));

            // Lists to hold model data
            List <Vector3> verts   = new List <Vector3>();
            List <Vector3> normals = new List <Vector3>();
            List <Vector2> texs    = new List <Vector2>();
            List <Tuple <TempVertex, TempVertex, TempVertex> > faces = new List <Tuple <TempVertex, TempVertex, TempVertex> >();

            // Base values
            verts.Add(new Vector3());
            texs.Add(new Vector2());
            normals.Add(new Vector3());

            int currentindice = 0;

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

                    Vector3 vec = new Vector3();

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

                        // Attempt to parse each part of the vertice
                        bool success = float.TryParse(vertparts[0], out vec.X);
                        success |= float.TryParse(vertparts[1], out vec.Y);
                        success |= float.TryParse(vertparts[2], out vec.Z);

                        // If any of the parses failed, report the error
                        if (!success)
                        {
                            Console.WriteLine("Error parsing vertex: {0}", line);
                        }
                    }
                    else
                    {
                        Console.WriteLine("Error parsing vertex: {0}", line);
                    }

                    verts.Add(vec);
                }
                else if (line.StartsWith("vt ")) // Texture coordinate
                {
                    // Cut off beginning of line
                    String temp = line.Substring(2);

                    Vector2 vec = new Vector2();

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

                        // Attempt to parse each part of the vertice
                        bool success = float.TryParse(texcoordparts[0], out vec.X);
                        success |= float.TryParse(texcoordparts[1], out vec.Y);

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

                    texs.Add(vec);
                }
                else if (line.StartsWith("vn ")) // Normal vector
                {
                    // Cut off beginning of line
                    String temp = line.Substring(2);

                    Vector3 vec = new Vector3();

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

                        // Attempt to parse each part of the vertice
                        bool success = float.TryParse(vertparts[0], out vec.X);
                        success |= float.TryParse(vertparts[1], out vec.Y);
                        success |= float.TryParse(vertparts[2], out vec.Z);

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

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

                    Tuple <TempVertex, TempVertex, TempVertex> face = new Tuple <TempVertex, TempVertex, TempVertex>(new TempVertex(), new TempVertex(), new TempVertex());

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

                        int v1, v2, v3;
                        int t1, t2, t3;
                        int n1, n2, n3;

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

                        if (faceparts[0].Count((char 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 (texs.Count > v1 && texs.Count > v2 && texs.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)
                        {
                            Console.WriteLine("Error parsing face: {0}", line);
                        }
                        else
                        {
                            TempVertex tv1 = new TempVertex(v1, n1, t1);
                            TempVertex tv2 = new TempVertex(v2, n2, t2);
                            TempVertex tv3 = new TempVertex(v3, n3, t3);
                            face = new Tuple <TempVertex, TempVertex, TempVertex>(tv1, tv2, tv3);
                            faces.Add(face);
                        }
                    }
                    else
                    {
                        Console.WriteLine("Error parsing face: {0}", line);
                    }
                }
            }

            // Create the ObjVolume
            ObjVolume vol = new ObjVolume();

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

                vol.faces.Add(new Tuple <FaceVertex, FaceVertex, FaceVertex>(v1, v2, v3));
            }

            return(vol);
        }
Пример #4
0
        public static OBJVolume LoadFromString(string obj, string filename = null)
        {
            List <string> lines = new List <string>(obj.Split('\n'));

            List <Vector3> vertices      = new List <Vector3>();
            List <Vector2> textureCoords = new List <Vector2>();
            var            faces         = new List <Tuple <TempVertex, TempVertex, TempVertex> >();

            vertices.Add(new Vector3());
            textureCoords.Add(new Vector2());

            foreach (string l in lines)
            {
                if (l.StartsWith("v "))
                {
                    // remove 'v '
                    string temp = l.Substring(2);

                    Vector3 v = new Vector3();

                    // Check if there's enough elements for a vertex (3)
                    if (temp.Count((char c) => c == ' ') == 2)
                    {
                        string[] vertParts = temp.Split(' ');

                        bool success = float.TryParse(vertParts[0], out v.X);
                        success |= float.TryParse(vertParts[1], out v.Y);
                        success |= float.TryParse(vertParts[2], out v.Z);

                        if (!success)
                        {
                            if (filename != null)
                            {
                                Console.WriteLine("!!! ERROR: cannot parse vertex (line: {0}, file: {1}) !!!",
                                                  l, filename);
                            }
                            else
                            {
                                Console.WriteLine("!!! ERROR: cannot parse vertex (line: {0}, from string) !!!",
                                                  l);
                            }
                        }
                    }
                    vertices.Add(v);
                }
                else if (l.StartsWith("vt "))
                {
                    // cut off 'vt '
                    string temp = l.Substring(3);

                    Vector2 v = new Vector2();

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

                        bool success = float.TryParse(textureCoordParts[0], out v.X);
                        success |= float.TryParse(textureCoordParts[1], out v.Y);

                        if (filename != null)
                        {
                            Console.WriteLine("!!! ERROR: cannot parse texture coordinate (line: {0}, file: {1}) !!!",
                                              l, filename);
                        }
                        else
                        {
                            Console.WriteLine("!!! ERROR: cannot parse texture coordinate (line: {0}, from string) !!!",
                                              l);
                        }
                    }
                    else
                    {
                        if (filename != null)
                        {
                            Console.WriteLine("!!! ERROR: cannot parse texture coordinate (line: {0}, file: {1}) !!!",
                                              l, filename);
                        }
                        else
                        {
                            Console.WriteLine("!!! ERROR: cannot parse texture coordinate (line: {0}, from string) !!!",
                                              l);
                        }
                    }

                    textureCoords.Add(v);
                }
                else if (l.StartsWith("f "))
                {
                    // remove 'f '
                    string temp = l.Substring(2);

                    var face = new Tuple <TempVertex, TempVertex, TempVertex>
                               (
                        new TempVertex(),
                        new TempVertex(),
                        new TempVertex()
                               );

                    // Check if there's enough elements for a face (3)
                    if (temp.Trim().Count((char c) => c == ' ') == 2)
                    {
                        string[] faceParts = temp.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
                        int      i1, i2, i3;
                        int      t1, t2, t3;

                        bool success = int.TryParse(faceParts[0].Split('/')[0], out i1);
                        success |= int.TryParse(faceParts[1].Split('/')[0], out i2);
                        success |= int.TryParse(faceParts[2].Split('/')[0], out i3);

                        if (faceParts[0].Count((char 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);
                        }
                        else
                        {
                            t1 = i1;
                            t2 = i2;
                            t3 = i3;
                        }

                        if (!success)
                        {
                            if (filename != null)
                            {
                                Console.WriteLine("!!! ERROR: cannot parse face (line: {0}, file: {1}) !!!",
                                                  l, filename);
                            }
                            else
                            {
                                Console.WriteLine("!!! ERROR: cannot parse face (line: {0}, from string) !!!",
                                                  l);
                            }
                        }
                        else
                        {
                            TempVertex v1 = new TempVertex(i1, 0, t1);
                            TempVertex v2 = new TempVertex(i2, 0, t2);
                            TempVertex v3 = new TempVertex(i3, 0, t3);

                            if (textureCoords.Count < t1)
                            {
                                textureCoords.Add(new Vector2());
                            }
                            if (textureCoords.Count < t2)
                            {
                                textureCoords.Add(new Vector2());
                            }
                            if (textureCoords.Count < t3)
                            {
                                textureCoords.Add(new Vector2());
                            }
                            face = new Tuple <TempVertex, TempVertex, TempVertex>(v1, v2, v3);
                            faces.Add(face);
                        }
                    }
                }
            }

            OBJVolume volume = new OBJVolume();

            textureCoords.Add(new Vector2());
            textureCoords.Add(new Vector2());
            textureCoords.Add(new Vector2());

            foreach (var f in faces)
            {
                FaceVertex v1 = new FaceVertex
                                (
                    vertices[f.Item1.Vertex],
                    new Vector3(),
                    textureCoords[f.Item1.TextureCoord]
                                );
                FaceVertex v2 = new FaceVertex
                                (
                    vertices[f.Item2.Vertex],
                    new Vector3(),
                    textureCoords[f.Item2.TextureCoord]
                                );
                FaceVertex v3 = new FaceVertex
                                (
                    vertices[f.Item3.Vertex],
                    new Vector3(),
                    textureCoords[f.Item3.TextureCoord]
                                );

                volume.faces.Add(new Tuple <FaceVertex, FaceVertex, FaceVertex>(v1, v2, v3));
            }

            return(volume);
        }
Пример #5
0
        /// <summary>
        /// Does not load correctly, yet
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static Model LoadFromString(string obj)
        {
            List <string> lines = new List <string>(obj.Split('\n'));

            // Lists to hold model data
            List <Vector3> verts   = new List <Vector3>();
            List <Vector3> normals = new List <Vector3>();
            List <Vector2> texs    = new List <Vector2>();
            List <Tuple <TempVertex, TempVertex, TempVertex> > faces = new List <Tuple <TempVertex, TempVertex, TempVertex> >();
            List <Tuple <int, int, int> > faceIndices = new List <Tuple <int, int, int> >();

            // Base values
            verts.Add(new Vector3());
            texs.Add(new Vector2());
            normals.Add(new Vector3());

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

                    Vector3 vec = new Vector3();

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

                        // Attempt to parse each part of the vertice
                        bool success = float.TryParse(vertparts[0], out vec.X);
                        success |= float.TryParse(vertparts[1], out vec.Y);
                        success |= float.TryParse(vertparts[2], out vec.Z);

                        // If any of the parses failed, report the error
                        if (!success)
                        {
                            Console.WriteLine("Error parsing vertex: {0}", line);
                        }
                    }
                    else
                    {
                        Console.WriteLine("Error parsing vertex: {0}", line);
                    }

                    verts.Add(vec);
                }
                else if (line.StartsWith("vt ")) // Texture coordinate
                {
                    // Cut off beginning of line
                    string temp = line.Substring(2);

                    Vector2 vec = new Vector2();

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

                        // Attempt to parse each part of the vertice
                        bool success = float.TryParse(texcoordparts[0], out vec.X);
                        success |= float.TryParse(texcoordparts[1], out vec.Y);

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

                    texs.Add(vec);
                }
                else if (line.StartsWith("vn ")) // Normal vector
                {
                    // Cut off beginning of line
                    string temp = line.Substring(2);

                    Vector3 vec = new Vector3();

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

                        // Attempt to parse each part of the vertice
                        bool success = float.TryParse(vertparts[0], out vec.X);
                        success |= float.TryParse(vertparts[1], out vec.Y);
                        success |= float.TryParse(vertparts[2], out vec.Z);

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

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

                    Tuple <TempVertex, TempVertex, TempVertex> face = new Tuple <TempVertex, TempVertex, TempVertex>(new TempVertex(), new TempVertex(), new TempVertex());

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

                        int v1, v2, v3;
                        int t1, t2, t3;
                        int n1, n2, n3;

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

                        if (faceparts[0].Count((char 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 (texs.Count > v1 && texs.Count > v2 && texs.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)
                        {
                            Console.WriteLine("Error parsing face: {0}", line);
                        }
                        else
                        {
                            faceIndices.Add(new Tuple <int, int, int>(v1, v2, v3));

                            TempVertex tv1 = new TempVertex(v1, n1, t1);
                            TempVertex tv2 = new TempVertex(v2, n2, t2);
                            TempVertex tv3 = new TempVertex(v3, n3, t3);
                            face = new Tuple <TempVertex, TempVertex, TempVertex>(tv1, tv2, tv3);
                            faces.Add(face);
                        }
                    }
                    else
                    {
                        Console.WriteLine("Error parsing face: {0}", line);
                    }
                }
            }

            Mesh mesh = new Mesh();

            for (int i = 0; i < faces.Count; i += 3)
            {
                var face = faces[i];

                Mesh.Vertex vert1 = new Mesh.Vertex
                {
                    Position          = verts[face.Item1.Vertex],
                    Normal            = normals[face.Item1.Normal],
                    TextureCoordinate = texs[face.Item1.Texcoord]
                };
                mesh.Vertices.Add(vert1);

                Mesh.Vertex vert2 = new Mesh.Vertex
                {
                    Position          = verts[face.Item2.Vertex],
                    Normal            = normals[face.Item2.Normal],
                    TextureCoordinate = texs[face.Item2.Texcoord]
                };
                mesh.Vertices.Add(vert2);

                Mesh.Vertex vert3 = new Mesh.Vertex
                {
                    Position          = verts[face.Item3.Vertex],
                    Normal            = normals[face.Item3.Normal],
                    TextureCoordinate = texs[face.Item3.Texcoord]
                };
                mesh.Vertices.Add(vert3);

                mesh.Faces.Add(new Mesh.Face
                {
                    X = faceIndices[i].Item1,
                    Y = faceIndices[i].Item2,
                    Z = faceIndices[i].Item3
                });
            }

            for (int i = 0; i < faces.Count; i++)
            {
                mesh.Indices.Add(faceIndices[i].Item1);
                mesh.Indices.Add(faceIndices[i].Item2);
                mesh.Indices.Add(faceIndices[i].Item3);
            }

            mesh.VertexCount = mesh.Vertices.Count;
            mesh.FaceCount   = mesh.Faces.Count;
            mesh.IndexCount  = mesh.Indices.Count;

            return(Model.CreateFromMesh(mesh));
        }
        private static Model LoadFromString(string text)
        {
            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 texs     = new List <Vector2>();
            var faces    = new List <(TempVertex, TempVertex, TempVertex)>();

            // Base values
            vertices.Add(new Vector3());
            texs.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);

                    var vec = new Vector3();

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

                        // Attempt to parse each part of the vertice
                        var success = float.TryParse(vertparts[0], style, culture, out vec.X);
                        success |= float.TryParse(vertparts[1], style, culture, out vec.Y);
                        success |= float.TryParse(vertparts[2], style, culture, out vec.Z);

                        // 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);
                }
                else if (line.StartsWith("vt ")) // Texture coordinate
                {
                    // Cut off beginning of line
                    var temp = line.Substring(2);

                    var vec = new Vector2();

                    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 vertice
                        var success = float.TryParse(texcoordparts[0], style, culture, out vec.X);
                        success |= float.TryParse(texcoordparts[1], style, culture, out vec.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}");
                    }

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

                    var vec = new Vector3();

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

                        // Attempt to parse each part of the vertice
                        var success = float.TryParse(vertparts[0], style, culture, out vec.X);
                        success |= float.TryParse(vertparts[1], style, culture, out vec.Y);
                        success |= float.TryParse(vertparts[2], style, culture, out vec.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);
                }
                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 (texs.Count > v1 && texs.Count > v2 && texs.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 Model.FaceVertex(vertices[face.Item1.Vertex], normals[face.Item1.Normal], texs[face.Item1.TexCoords]);
                var v2 = new Model.FaceVertex(vertices[face.Item2.Vertex], normals[face.Item2.Normal], texs[face.Item2.TexCoords]);
                var v3 = new Model.FaceVertex(vertices[face.Item3.Vertex], normals[face.Item3.Normal], texs[face.Item3.TexCoords]);

                vol.Faces.Add((v1, v2, v3));
            }

            return(vol);
        }
Пример #7
0
        private void CalculateTangentBinormal(TempVertex vertex1, TempVertex vertex2, TempVertex vertex3, out Vector tangent, out Vector binormal)
        {
            // Calculate the two vectors for the this face.
            var vector1 = new[] { vertex2.x - vertex1.x, vertex2.y - vertex1.y, vertex2.z - vertex1.z };
            var vector2 = new[] { vertex3.x - vertex1.x, vertex3.y - vertex1.y, vertex3.z - vertex1.z };

            // Calculate the tu and tv texture space vectors.
            var tuVector = new[] { vertex2.tu - vertex1.tu, vertex3.tu - vertex1.tu };
            var tvVector = new[] { vertex2.tv - vertex1.tv, vertex3.tv - vertex1.tv };

            // Calculate the denominator of the tangent / binormal equation.
            var den = 1.0f / (tuVector[0] * tvVector[1] - tuVector[1] * tvVector[0]);

            // Calculate the cross products and multiply by the coefficient to get the tangent and binormal.
            tangent.x = (tvVector[1] * vector1[0] - tvVector[0] * vector2[0]) * den;
            tangent.y = (tvVector[1] * vector1[1] - tvVector[0] * vector2[1]) * den;
            tangent.z = (tvVector[1] * vector1[2] - tvVector[0] * vector2[2]) * den;

            binormal.x = (tuVector[0] * vector2[0] - tuVector[1] * vector1[0]) * den;
            binormal.y = (tuVector[0] * vector2[1] - tuVector[1] * vector1[1]) * den;
            binormal.z = (tuVector[0] * vector2[2] - tuVector[1] * vector1[2]) * den;

            // Calculate the length of this normal.
            var length = (float)Math.Sqrt(tangent.x * tangent.x + tangent.y * tangent.y + tangent.z * tangent.z);

            // Normalize the normal and the store it.
            tangent.x = tangent.x / length;
            tangent.y = tangent.y / length;
            tangent.z = tangent.z / length;

            // Calculate the length of this normal.
            length = (float)Math.Sqrt(binormal.x * binormal.x + binormal.y * binormal.y + binormal.z * binormal.z);

            // Normalize the normal and the store it.
            binormal.x = binormal.x / length;
            binormal.y = binormal.y / length;
            binormal.z = binormal.z / length;
        }
Пример #8
0
        public void myRender()
        {
            // List<Vertex> VertList = new List<Vertex>();

            GL.GenBuffers(1, out gl_vbo);
            for (int i = 0; i < vertCount; i++)
            {
                TempVertex vert = new TempVertex();

                try
                {
                    foreach (BFRESAttribute att in attributes)
                    {
                        DataOff = (BufferOffsets[att.bufferIndex].DataOffsetData) + (attributes[att.bufferIndex].bufferOffset);
                        FileData d = new FileData(new FileData(BuffSizes[att.bufferIndex].BuffSizes).getSection(0, -1));
                        d.Endian = Endianness.Little;
                        d.seek(att.bufferOffset + i * BufferOffsets[att.bufferIndex].VertexStrideSizeData);
                        switch (att.Text)
                        {
                        case "_p0":
                            if (att.format.Equals(0x518))
                            {
                                vert.x = d.readFloat();
                                vert.y = d.readFloat();
                                vert.z = d.readFloat();
                            }
                            else if (att.format.Equals(0x515))
                            {
                                vert.x = d.readHalfFloat();
                                vert.y = d.readHalfFloat();
                                vert.z = d.readHalfFloat();
                                d.readHalfFloat();     //w
                            }
                            else
                            {
                                Console.WriteLine("Unkown Format!! " + att.format.ToString());
                            }
                            break;

                        case "_n0":
                            if (att.format.Equals(0x20E))
                            {
                                int normVal = (int)d.readInt();
                                vert.nx = FileData.sign10Bit((normVal) & 0x3FF) / 511f;
                                vert.ny = FileData.sign10Bit((normVal >> 10) & 0x3FF) / 511f;
                                vert.nz = FileData.sign10Bit((normVal >> 20) & 0x3FF) / 511f;
                                break;
                            }
                            else
                            {
                                Console.WriteLine("Unkown Format!! " + att.format.ToString() + " " + att.Text);
                            }
                            break;

                        case "_i0":
                            if (att.format.Equals(0x20B))
                            {
                                vert.i1 = d.readByte();
                                vert.i2 = d.readByte();
                                vert.i3 = d.readByte();
                                vert.i4 = d.readByte();
                            }
                            else if (att.format.Equals(0x302))
                            {
                                vert.i1 = d.readByte();
                                vert.w1 = 1;
                            }
                            else if (att.format.Equals(0x309))
                            {
                                vert.i1 = d.readByte();
                                vert.i2 = d.readByte();
                            }
                            else if (att.format.Equals(0x30B))
                            {
                                vert.i1 = d.readByte();
                                vert.i2 = d.readByte();
                                vert.i3 = d.readByte();
                                vert.i4 = d.readByte();
                            }
                            else if (att.format.Equals(0x118))
                            {
                                vert.i1 = d.readInt();
                                vert.i2 = d.readInt();
                                vert.i3 = d.readInt();
                            }
                            else if (att.format.Equals(0x117))
                            {
                                vert.i1 = d.readInt();
                                vert.i2 = d.readInt();
                            }
                            else if (att.format.Equals(0x115))
                            {
                                vert.i1 = d.readShort();
                                vert.i2 = d.readShort();
                            }
                            else
                            {
                                Console.WriteLine("Unkown Format!! " + att.format.ToString() + " " + att.Text);
                            }
                            break;

                        case "_u0":
                            if (att.format.Equals(0x112))
                            {
                                vert.uv0.X = ((float)d.readShort()) / 65535;
                                vert.uv0.Y = ((float)d.readShort()) / 65535;
                            }
                            else if (att.format.Equals(0x109))
                            {
                                vert.uv0.X = d.readByte() / (float)255;
                                vert.uv0.Y = d.readByte() / (float)255;
                            }
                            else if (att.format.Equals(0x209))
                            {
                                vert.uv0.X = d.readByte() / (float)127;
                                vert.uv0.Y = d.readByte() / (float)127;
                            }
                            else if (att.format.Equals(0x212))
                            {
                                vert.uv0.X = d.readShort() / (float)32767;
                                vert.uv0.Y = d.readShort() / (float)32767;
                            }
                            else if (att.format.Equals(0x512))
                            {
                                vert.uv0.X = d.readHalfFloat();
                                vert.uv0.Y = d.readHalfFloat();
                            }
                            else if (att.format.Equals(0x517))
                            {
                                vert.uv0.X = d.readFloat();
                                vert.uv0.Y = d.readFloat();
                            }
                            else
                            {
                                Console.WriteLine("Unkown Format!! " + att.format.ToString() + " " + att.Text);
                            }
                            break;

                        case "_w0":
                            if (att.format.Equals(0x102))
                            {
                                vert.w1 = d.readByte();
                            }
                            else if (att.format.Equals(0x109))
                            {
                                vert.w1 = d.readByte() / (float)255;
                                vert.w2 = d.readByte() / (float)255;
                            }
                            else if (att.format.Equals(0x10B))
                            {
                                vert.w1 = d.readByte() / (float)255;
                                vert.w2 = d.readByte() / (float)255;
                                vert.w3 = d.readByte() / (float)255;
                                vert.w4 = d.readByte() / (float)255;
                            }
                            else if (att.format.Equals(0x112))
                            {
                                vert.w1 = d.readShort() / (float)0xFFFF;
                                vert.w2 = d.readShort() / (float)0xFFFF;
                            }
                            break;

                        default:
                            //d.skip(d.size());
                            // Console.WriteLine(Text + " Unknown type " + att.format.ToString("x") + " 0x");
                            break;
                        }
                    }

                    VertData.Add(new BaseRenderData.Vertex()
                    {
                        x   = vert.x,
                        y   = vert.y,
                        z   = vert.z,
                        nx  = vert.nx,
                        ny  = vert.ny,
                        nz  = vert.nz,
                        uv0 = vert.uv0,
                        i1  = vert.i1,
                        i2  = vert.i2,
                        i3  = vert.i3,
                        i4  = vert.i4,
                        w1  = vert.w1,
                        w2  = vert.w2,
                        w3  = vert.w3,
                        w4  = vert.w4,
                    });
                }
                catch (Exception ex)
                {
                    MessageBox.Show("A buffer broke :( \n\n" + ex, "Error");
                }
            }

            /*(Vertex item in data)
             * {
             *  Console.WriteLine("X = " + item.x + " Y = " + item.y + " Z = " + item.z);
             * }*/



            GL.BindBuffer(BufferTarget.ArrayBuffer, gl_vbo);
            GL.BufferData <BaseRenderData.Vertex>(BufferTarget.ArrayBuffer, (IntPtr)(VertData.Count * BaseRenderData.Vertex.Stride), VertData.ToArray(), BufferUsageHint.StaticDraw);
            GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
        }
Пример #9
0
        private void myRender()
        {
            GL.GenBuffers(1, out gl_vbo);

            Console.WriteLine("Prerender start");

            for (int i = 0; i < vertCount; i++)
            {
                TempVertex vert = new TempVertex();

                foreach (BFRESAttribute att in attributes)
                {
                    FileData d = new FileData(buffers[att.bufferIndex].data);
                    d.seek(att.bufferOffset + i * buffers[att.bufferIndex].stride);
                    switch (att.format)
                    {
                    /*
                     * case 0x10C: data.Add(d.readFloat()); break;
                     * case 0x20A: data.Add(((sbyte)d.readByte()) / 128); break;
                     * case 0x80D: data.Add(d.readFloat()); break;
                     * case 0x813: data.Add(d.readFloat()); break;*/
                    case 0x004:
                        vert.w1 = d.readByte() / (float)255;
                        vert.w2 = d.readByte() / (float)255;
                        break;

                    case 0x007:
                        if (att.Text.Equals("_u2"))
                        {
                            vert.uv0.X = d.readShort() / (float)0xFFFF;
                            vert.uv0.Y = d.readShort() / (float)0xFFFF;
                        }
                        else
                        {
                            vert.w1 = d.readShort() / (float)0xFFFF;
                            vert.w2 = d.readShort() / (float)0xFFFF;
                        }
                        break;

                    case 0x00A:
                        vert.w1 = d.readByte() / (float)255;
                        vert.w2 = d.readByte() / (float)255;
                        vert.w3 = d.readByte() / (float)255;
                        vert.w4 = d.readByte() / (float)255;
                        break;

                    case 0x100:
                        vert.i1 = d.readByte();
                        vert.w1 = 1;
                        break;

                    case 0x104:
                        vert.i1 = d.readByte();
                        vert.i2 = d.readByte();
                        break;

                    case 0x10A:
                        vert.i1 = d.readByte();
                        vert.i2 = d.readByte();
                        vert.i3 = d.readByte();
                        vert.i4 = d.readByte();
                        break;

                    case 0x20B:
                        int normVal = (int)d.readInt();
                        vert.nx = FileData.sign10Bit((normVal) & 0x3FF) / 511f;
                        vert.ny = FileData.sign10Bit((normVal >> 10) & 0x3FF) / 511f;
                        vert.nz = FileData.sign10Bit((normVal >> 20) & 0x3FF) / 511f;
                        break;

                    case 0x80F:
                        vert.x = d.readHalfFloat();
                        vert.y = d.readHalfFloat();
                        vert.z = d.readHalfFloat();
                        d.readHalfFloat();     //w
                        break;

                    case 0x811:
                        vert.x = d.readFloat();
                        vert.y = d.readFloat();
                        vert.z = d.readFloat();
                        d.readFloat();     //w
                        break;

                    default:
                        //d.skip(d.size());
                        //Console.WriteLine(Text + " Unknown type " + att.format.ToString("x") + " 0x" + (att.bufferOffset + buffers[bufferIndex].dataOffset).ToString("x"));
                        break;
                    }
                }
                data.Add(new Vertex()
                {
                    x   = vert.x, y = vert.y, z = vert.z,
                    nx  = vert.nx, ny = vert.ny, nz = vert.nz,
                    uv0 = vert.uv0,
                    i1  = vert.i1, i2 = vert.i2, i3 = vert.i3, i4 = vert.i4,
                    w1  = vert.i1, w2 = vert.i2, w3 = vert.i3, w4 = vert.i4,
                });
            }
            Console.WriteLine("Prerender end");

            GL.BindBuffer(BufferTarget.ArrayBuffer, gl_vbo);
            GL.BufferData <Vertex>(BufferTarget.ArrayBuffer, (IntPtr)(data.Count * Vertex.Stride), data.ToArray(), BufferUsageHint.StaticDraw);
            GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
        }
Пример #10
0
        public static OBJVolume LoadFromString(string obj, string filename = null)
        {
            List<string> lines = new List<string>(obj.Split('\n'));

            List<Vector3> vertices = new List<Vector3>();
            List<Vector2> textureCoords = new List<Vector2>();
            var faces = new List<Tuple<TempVertex, TempVertex, TempVertex>>();

            vertices.Add(new Vector3());
            textureCoords.Add(new Vector2());

            foreach (string l in lines)
            {
                if (l.StartsWith("v "))
                {
                    // remove 'v '
                    string temp = l.Substring(2);

                    Vector3 v = new Vector3();

                    // Check if there's enough elements for a vertex (3)
                    if (temp.Count((char c) => c == ' ') == 2)
                    {
                        string[] vertParts = temp.Split(' ');

                        bool success = float.TryParse(vertParts[0], out v.X);
                        success		|= float.TryParse(vertParts[1], out v.Y);
                        success		|= float.TryParse(vertParts[2], out v.Z);

                        if (!success)
                        {
                            if (filename != null)
                            {
                                Console.WriteLine("!!! ERROR: cannot parse vertex (line: {0}, file: {1}) !!!",
                                                l, filename);
                            }
                            else
                            {
                                Console.WriteLine("!!! ERROR: cannot parse vertex (line: {0}, from string) !!!",
                                                l);
                            }
                        }
                    }
                    vertices.Add(v);
                }
                else if (l.StartsWith("vt "))
                {
                    // cut off 'vt '
                    string temp = l.Substring(3);

                    Vector2 v = new Vector2();

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

                        bool success = float.TryParse(textureCoordParts[0], out v.X);
                        success		|= float.TryParse(textureCoordParts[1], out v.Y);

                        if (filename != null)
                        {
                            Console.WriteLine("!!! ERROR: cannot parse texture coordinate (line: {0}, file: {1}) !!!",
                                            l, filename);
                        }
                        else
                        {
                            Console.WriteLine("!!! ERROR: cannot parse texture coordinate (line: {0}, from string) !!!",
                                            l);
                        }
                    }
                    else
                    {
                        if (filename != null)
                        {
                            Console.WriteLine("!!! ERROR: cannot parse texture coordinate (line: {0}, file: {1}) !!!",
                                            l, filename);
                        }
                        else
                        {
                            Console.WriteLine("!!! ERROR: cannot parse texture coordinate (line: {0}, from string) !!!",
                                            l);
                        }
                    }

                    textureCoords.Add(v);
                }
                else if (l.StartsWith("f "))
                {
                    // remove 'f '
                    string temp = l.Substring(2);

                    var face = new Tuple<TempVertex, TempVertex, TempVertex>
                    (
                        new TempVertex(),
                        new TempVertex(),
                        new TempVertex()
                    );

                    // Check if there's enough elements for a face (3)
                    if (temp.Trim().Count((char c) => c == ' ') == 2)
                    {
                        string[] faceParts = temp.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
                        int i1, i2, i3;
                        int t1, t2, t3;

                        bool success = int.TryParse(faceParts[0].Split('/')[0], out i1);
                        success		|= int.TryParse(faceParts[1].Split('/')[0], out i2);
                        success		|= int.TryParse(faceParts[2].Split('/')[0], out i3);

                        if (faceParts[0].Count((char 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);
                        }
                        else
                        {
                            t1 = i1;
                            t2 = i2;
                            t3 = i3;
                        }

                        if (!success)
                        {
                            if (filename != null)
                            {
                                Console.WriteLine("!!! ERROR: cannot parse face (line: {0}, file: {1}) !!!",
                                                l, filename);
                            }
                            else
                            {
                                Console.WriteLine("!!! ERROR: cannot parse face (line: {0}, from string) !!!",
                                                l);
                            }
                        }
                        else
                        {
                            TempVertex v1 = new TempVertex(i1, 0, t1);
                            TempVertex v2 = new TempVertex(i2, 0, t2);
                            TempVertex v3 = new TempVertex(i3, 0, t3);

                            if (textureCoords.Count < t1)
                            {
                                textureCoords.Add(new Vector2());
                            }
                            if (textureCoords.Count < t2)
                            {
                                textureCoords.Add(new Vector2());
                            }
                            if (textureCoords.Count < t3)
                            {
                                textureCoords.Add(new Vector2());
                            }
                            face = new Tuple<TempVertex, TempVertex, TempVertex>(v1, v2, v3);
                            faces.Add(face);
                        }
                    }
                }
            }

            OBJVolume volume = new OBJVolume();
            textureCoords.Add(new Vector2());
            textureCoords.Add(new Vector2());
            textureCoords.Add(new Vector2());

            foreach (var f in faces)
            {
                FaceVertex v1 = new FaceVertex
                (
                    vertices[f.Item1.Vertex],
                    new Vector3(),
                    textureCoords[f.Item1.TextureCoord]
                );
                FaceVertex v2 = new FaceVertex
                (
                    vertices[f.Item2.Vertex],
                    new Vector3(),
                    textureCoords[f.Item2.TextureCoord]
                );
                FaceVertex v3 = new FaceVertex
                (
                    vertices[f.Item3.Vertex],
                    new Vector3(),
                    textureCoords[f.Item3.TextureCoord]
                );

                volume.faces.Add(new Tuple<FaceVertex, FaceVertex, FaceVertex>(v1, v2, v3));
            }

            return volume;
        }
Пример #11
0
        public void BuildData(List <Model3D.MeshData> meshes)
        {
            if (meshes.Count != 0)
            {
                System.Console.WriteLine("duplicate");
            }

            {
                int target_c = (int)TempMeshes.count + meshes.Count;
                if (meshes.Capacity < target_c)
                {
                    meshes.Capacity = target_c;
                }
            }

            Dictionary <TempVertex, TempVertex> vert_temp = null;

            Model3D.MeshData md;
            TempMesh         mesh_iter;
            TempVertex       vert_iter;
            uint             mesh_iter_n, vert_iter_n, next_ind, u_pos; int v_count;
            float            fw, fh;

            for (mesh_iter = TempMeshes.first,
                 mesh_iter_n = TempMeshes.count;
                 0 != mesh_iter_n;
                 mesh_iter = mesh_iter.next,
                 --mesh_iter_n)
            {
                v_count = null == (object)(
                    vert_temp = TempVertex.Process(ref mesh_iter.references.list, utilize: vert_temp)
                    ) ? 0 : vert_temp.Count;
                md = new Model3D.MeshData()
                {
                    vertices = new Vector3[v_count],
                    normals  = new Vector3[v_count],
                    colors   = new Vector4[v_count],
                    texCoord = new Vector2[v_count],
                    indices  = new uint[mesh_iter.references.list.count],
                    texture  = ContentPipe.LoadTexture(
                        mesh_iter.references.bmp,
                        mesh_iter.value.info.wrapS,
                        mesh_iter.value.info.wrapT),
                    material = mesh_iter.value.getMaterial(),
                };
                fw = ((uint)mesh_iter.references.bmp.Width << 5);
                fh = ((uint)mesh_iter.references.bmp.Height << 5);
                for (
                    u_pos = 0, next_ind = 0,
                    vert_iter = mesh_iter.references.list.first,
                    vert_iter_n = mesh_iter.references.list.count;
                    0 != vert_iter_n;
                    vert_iter = vert_iter.next,
                    u_pos++,
                    --vert_iter_n)
                {
                    md.indices[u_pos] = vert_iter.index;
                    if (vert_iter.index != next_ind)
                    {
                        continue;
                    }
                    md.vertices[next_ind]   = vert_iter.value.position;
                    md.texCoord[next_ind].X = vert_iter.value.texCoord.X / fw;
                    md.texCoord[next_ind].Y = vert_iter.value.texCoord.Y / fh;
                    md.normals[next_ind]    = vert_iter.value.normal;
                    md.colors[next_ind]     = vert_iter.value.color;
                    next_ind++;
                }
                meshes.Add(md);
            }
        }
Пример #12
0
        public Mesh LoadFromString(string objModel)
        {
            // Seperate lines from the file
            List <string> lines = new List <string>(objModel.Split('\n'));

            // Lists to hold model data
            List <Vector3> verts   = new List <Vector3>();
            List <Vector3> normals = new List <Vector3>();
            List <Vector2> texs    = new List <Vector2>();

            List <Vector3> decodedVertices = new List <Vector3>();
            List <Vector3> decodedNormals  = new List <Vector3>();
            List <Vector2> decodedUvCoords = new List <Vector2>();

            List <Tuple <TempVertex, TempVertex, TempVertex> > faces = new List <Tuple <TempVertex, TempVertex, TempVertex> >();

            // Base values
            verts.Add(new Vector3());
            texs.Add(new Vector2());
            normals.Add(new Vector3());

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

                    Vector3 vec = new Vector3();

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

                        // Attempt to parse each part of the vertice
                        bool success = float.TryParse(vertparts[0], NumberStyles.Any, CultureInfo.InvariantCulture, out vec.X);
                        success |= float.TryParse(vertparts[1], NumberStyles.Any, CultureInfo.InvariantCulture, out vec.Y);
                        success |= float.TryParse(vertparts[2], NumberStyles.Any, CultureInfo.InvariantCulture, out vec.Z);

                        // If any of the parses failed, report the error
                        if (!success)
                        {
                            Console.WriteLine("Error parsing vertex: {0}", line);
                        }
                    }
                    else
                    {
                        Console.WriteLine("Error parsing vertex: {0}", line);
                    }

                    verts.Add(vec);
                }
                else if (line.StartsWith("vt ")) // Texture coordinate
                {
                    // Cut off beginning of line
                    String temp = line.Substring(2);

                    Vector2 vec = new Vector2();

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

                        // Attempt to parse each part of the vertice
                        bool success = float.TryParse(texcoordparts[0], NumberStyles.Any, CultureInfo.InvariantCulture, out vec.X);
                        success |= float.TryParse(texcoordparts[1], NumberStyles.Any, CultureInfo.InvariantCulture, out vec.Y);

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

                    texs.Add(vec);
                }
                else if (line.StartsWith("vn ")) // Normal vector
                {
                    // Cut off beginning of line
                    String temp = line.Substring(2);

                    Vector3 vec = new Vector3();

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


                        // Attempt to parse each part of the vertice
                        bool success = float.TryParse(vertparts[0], NumberStyles.Any, CultureInfo.InvariantCulture, out vec.X);
                        success |= float.TryParse(vertparts[1], NumberStyles.Any, CultureInfo.InvariantCulture, out vec.Y);
                        success |= float.TryParse(vertparts[2], NumberStyles.Any, CultureInfo.InvariantCulture, out vec.Z);

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

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

                    Tuple <TempVertex, TempVertex, TempVertex> face = new Tuple <TempVertex, TempVertex, TempVertex>(new TempVertex(), new TempVertex(), new TempVertex());

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

                        int v1, v2, v3;
                        int t1, t2, t3;
                        int n1, n2, n3;

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

                        if (faceparts[0].Count((char 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 (texs.Count > v1 && texs.Count > v2 && texs.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)
                        {
                            Console.WriteLine("Error parsing face: {0}", line);
                        }
                        else
                        {
                            TempVertex tv1 = new TempVertex(v1, n1, t1);
                            TempVertex tv2 = new TempVertex(v2, n2, t2);
                            TempVertex tv3 = new TempVertex(v3, n3, t3);
                            face = new Tuple <TempVertex, TempVertex, TempVertex>(tv1, tv2, tv3);
                            faces.Add(face);
                        }
                    }
                    else
                    {
                        Console.WriteLine("Error parsing face: {0}", line);
                    }
                }
            }

            // Create the ObjVolume
            Mesh loadedModel = new Mesh();

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

                Vector2 calculatedUV  = new Vector2(texs[face.Item1.Texcoord].X, 1.0f - texs[face.Item1.Texcoord].Y);
                Vector2 calculatedUV2 = new Vector2(texs[face.Item2.Texcoord].X, 1.0f - texs[face.Item2.Texcoord].Y);
                Vector2 calculatedUV3 = new Vector2(texs[face.Item3.Texcoord].X, 1.0f - texs[face.Item3.Texcoord].Y);

                decodedVertices.AddRange(new Vector3[] { verts[face.Item1.Vertex], verts[face.Item2.Vertex], verts[face.Item3.Vertex] });
                decodedNormals.AddRange(new Vector3[] { normals[face.Item1.Normal], normals[face.Item2.Normal], normals[face.Item3.Normal] });
                decodedUvCoords.AddRange(new Vector2[] { calculatedUV, calculatedUV2, calculatedUV3 });
            }

            loadedModel.Indeces  = Enumerable.Range(0, decodedVertices.Count).ToArray();
            loadedModel.Vertices = decodedVertices.ToArray();
            loadedModel.Normals  = decodedNormals.ToArray();
            loadedModel.UvCoords = decodedUvCoords.ToArray();

            return(loadedModel);
        }
Пример #13
0
        public static MyComplexObjectFactory3 LoadFromString(string obj)
        {
            Dictionary <String, int> materials = new Dictionary <string, int>();
            String curMaterial = "";

            NumberStyles style   = NumberStyles.Float;
            CultureInfo  culture = CultureInfo.CreateSpecificCulture("en-US");

            // Seperate lines from the file
            List <String> lines = new List <string>(obj.Split('\n'));

            // Lists to hold model data
            List <Vector3> verts   = new List <Vector3>();
            List <Vector3> normals = new List <Vector3>();
            List <Vector2> texs    = new List <Vector2>();
            List <Tuple <TempVertex, TempVertex, TempVertex> > faces = new List <Tuple <TempVertex, TempVertex, TempVertex> >();

            // Base values
            verts.Add(new Vector3());
            texs.Add(new Vector2());
            normals.Add(new Vector3());


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

                    Vector3 vec = new Vector3();

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

                        // Attempt to parse each part of the vertice
                        bool success = float.TryParse(vertparts[0], style, culture, out vec.X);
                        success |= float.TryParse(vertparts[1], style, culture, out vec.Y);
                        success |= float.TryParse(vertparts[2], style, culture, out vec.Z);

                        // If any of the parses failed, report the error
                        if (!success)
                        {
                            Console.WriteLine("Error parsing vertex: {0}", line);
                        }
                    }
                    else
                    {
                        Console.WriteLine("Error parsing vertex: {0}", line);
                    }

                    verts.Add(vec);
                }
                else if (line.StartsWith("vt ")) // Texture coordinate
                {
                    // Cut off beginning of line
                    String temp = line.Substring(2);

                    Vector2 vec = new Vector2();

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

                        // Attempt to parse each part of the vertice
                        bool success = float.TryParse(texcoordparts[0], style, culture, out vec.X);
                        success |= float.TryParse(texcoordparts[1], style, culture, out vec.Y);

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

                    texs.Add(vec);
                }
                else if (line.StartsWith("vn ")) // Normal vector
                {
                    // Cut off beginning of line
                    String temp = line.Substring(2);

                    Vector3 vec = new Vector3();

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

                        // Attempt to parse each part of the vertice
                        bool success = float.TryParse(vertparts[0], style, culture, out vec.X);
                        success |= float.TryParse(vertparts[1], style, culture, out vec.Y);
                        success |= float.TryParse(vertparts[2], style, culture, out vec.Z);

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

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

                    Tuple <TempVertex, TempVertex, TempVertex> face = new Tuple <TempVertex, TempVertex, TempVertex>(new TempVertex(), new TempVertex(), new TempVertex());

                    if (temp.Trim().Count((char c) => c == ' ') >= 2) // Check if there's enough elements for a face
                    {
                        String[] faceparts = temp.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
                        bool     success   = true;
                        if (temp.Trim().Count((char c) => c == ' ') == 3)
                        {
                            int v1, v2, v3;
                            int v11, v22, v33;
                            int t1, t2, t3;
                            int t11, t22, t33;
                            int n1, n2, n3;
                            int n11, n22, n33;

                            // Attempt to parse each part of the face
                            success  = int.TryParse(faceparts[0].Split('/')[0], out v1);
                            success |= int.TryParse(faceparts[1].Split('/')[0], out v2);
                            success |= int.TryParse(faceparts[2].Split('/')[0], out v3);
                            success |= int.TryParse(faceparts[0].Split('/')[0], out v11);
                            success |= int.TryParse(faceparts[2].Split('/')[0], out v22);
                            success |= int.TryParse(faceparts[3].Split('/')[0], out v33);
                            if (faceparts[0].Count((char 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('/')[1], out t11);
                                success |= int.TryParse(faceparts[2].Split('/')[1], out t22);
                                success |= int.TryParse(faceparts[3].Split('/')[1], out t33);
                                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);
                                success |= int.TryParse(faceparts[0].Split('/')[2], out n11);
                                success |= int.TryParse(faceparts[2].Split('/')[2], out n22);
                                success |= int.TryParse(faceparts[3].Split('/')[2], out n33);
                            }
                            else
                            {
                                t1 = t2 = t3 = t11 = t22 = t33 = n1 = n2 = n3 = n11 = n22 = n33 = 0;
                            }
                            // If any of the parses failed, report the error
                            if (!success)
                            {
                                Console.WriteLine("Error parsing face: {0}", line);
                            }
                            else
                            {
                                TempVertex tv1  = new TempVertex(v1, n1, t1, curMaterial);
                                TempVertex tv2  = new TempVertex(v2, n2, t2, curMaterial);
                                TempVertex tv3  = new TempVertex(v3, n3, t3, curMaterial);
                                TempVertex tv11 = new TempVertex(v11, n11, t11, curMaterial);
                                TempVertex tv22 = new TempVertex(v22, n22, t22, curMaterial);
                                TempVertex tv33 = new TempVertex(v33, n33, t33, curMaterial);
                                face = new Tuple <TempVertex, TempVertex, TempVertex>(tv1, tv2, tv3);
                                faces.Add(face);
                                face = new Tuple <TempVertex, TempVertex, TempVertex>(tv11, tv22, tv33);
                                faces.Add(face);
                            }
                        }
                        else
                        {
                            int v1, v2, v3;
                            int t1, t2, t3;
                            int n1, n2, n3;

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

                            if (faceparts[0].Count((char 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 (texs.Count > v1 && texs.Count > v2 && texs.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)
                            {
                                Console.WriteLine("Error parsing face: {0}", line);
                            }
                            else
                            {
                                TempVertex tv1 = new TempVertex(v1, n1, t1, curMaterial);
                                TempVertex tv2 = new TempVertex(v2, n2, t2, curMaterial);
                                TempVertex tv3 = new TempVertex(v3, n3, t3, curMaterial);
                                face = new Tuple <TempVertex, TempVertex, TempVertex>(tv1, tv2, tv3);
                                faces.Add(face);
                            }
                        }
                    }
                    else
                    {
                        Console.WriteLine("Error parsing face: {0}", line);
                    }
                }
                else if (line.StartsWith("usemtl "))
                {
                    String temp = line.Substring(7);
                    curMaterial = temp;
                }
            }

            // Create the ObjVolume
            MyComplexObjectFactory3 vol = new MyComplexObjectFactory3();

            foreach (var face in faces)
            {
                FaceVertex2 v1 = new FaceVertex2(verts[face.Item1.Vertex], normals[face.Item1.Normal], texs[face.Item1.Texcoord], face.Item1.matName);
                FaceVertex2 v2 = new FaceVertex2(verts[face.Item2.Vertex], normals[face.Item2.Normal], texs[face.Item2.Texcoord], face.Item2.matName);
                FaceVertex2 v3 = new FaceVertex2(verts[face.Item3.Vertex], normals[face.Item3.Normal], texs[face.Item3.Texcoord], face.Item3.matName);

                vol.faces.Add(new Tuple <FaceVertex2, FaceVertex2, FaceVertex2>(v1, v2, v3));
            }
            vol.mapIndices(vol.faces);
            return(vol);
        }
Пример #14
0
 public void AddValue(TempVertex vertex, Rectangle rect)
 {
     _values.Add((vertex, rect));
 }