Exemple #1
0
        private void CalculateTangentArray(
            int vertexCount, Vector3[] vertex, Vector3[] normal, Vector2[] texcoord, int triangleCount, Face[] triangles, 
            out Vector3[] Bitangent, out Vector3[] Tangent)
        {
            Vector3[] tan1 = new Vector3[vertexCount];
            Vector3[] tan2 = new Vector3[vertexCount];
            //Normals = new Vector3[vertexCount];


            for (int a = 0; a < triangleCount; a++)
            {
                //Store Vertex Index's
                int i1 = triangles[a].VertexIndices[0];
                int i2 = triangles[a].VertexIndices[1];
                int i3 = triangles[a].VertexIndices[2];

                int n1 = triangles[a].NormalIndices[0];
                int n2 = triangles[a].NormalIndices[1];
                int n3 = triangles[a].NormalIndices[2];

                int vt1 = triangles[a].TexcoordIndices[0];
                int vt2 = triangles[a].TexcoordIndices[1];
                int vt3 = triangles[a].TexcoordIndices[2];

                //From Vertex Array Copy Coordinates of Vertex's
                Vector3 v1 = vertex[i1];
                Vector3 v2 = vertex[i2];
                Vector3 v3 = vertex[i3];

                //From Texture Array Copy Coordinates of Vertex's
                Vector2 w1 = texcoord[vt1];
                Vector2 w2 = texcoord[vt2];
                Vector2 w3 = texcoord[vt3];

                //Make Relative to Vertex 1
                //Vertex Coordinates
                float x1 = v2.X - v1.X;
                float x2 = v3.X - v1.X;
                float y1 = v2.Y - v1.Y;
                float y2 = v3.Y - v1.Y;
                float z1 = v2.Z - v1.Z;
                float z2 = v3.Z - v1.Z;
                //Texture Coordinates
                float s1 = w2.X - w1.X;
                float s2 = w3.X - w1.X;
                float t1 = w2.Y - w1.Y;
                float t2 = w3.Y - w1.Y;

                float r = 1.0F / (s1 * t2 - s2 * t1);
                Vector3 sdir = new Vector3((t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r, (t2 * z1 - t1 * z2) * r);
                Vector3 tdir = new Vector3((s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r, (s1 * z2 - s2 * z1) * r);
                AngleFucker AF = new AngleFucker(v1, v2, v3);

                tan1[i1] += Vector3.Multiply(sdir, AF.Get_v1_Angle());
                tan1[i2] += Vector3.Multiply(sdir, AF.Get_v2_Angle());
                tan1[i3] += Vector3.Multiply(sdir, AF.Get_v3_Angle());

                tan2[i1] += Vector3.Multiply(tdir, AF.Get_v1_Angle());
                tan2[i2] += Vector3.Multiply(tdir, AF.Get_v2_Angle());
                tan2[i3] += Vector3.Multiply(tdir, AF.Get_v3_Angle());
            }

            Tangent = new Vector3[vertexCount];
            Bitangent = new Vector3[vertexCount];

            for (int a = 0; a < vertexCount; a++)
            {
                Vector3 n = normal[a];
               //Normals[a] = Round(normal[a]);
                Vector3 b = tan2[a];
                Vector3 t = tan1[a];

                // Gram-Schmidt orthogonalize
                Vector3 temp = Vector3.Subtract(t, Vector3.Multiply(n, Vector3.Dot(n, t)));
                temp.Normalize();

                Tangent[a] = Round(temp);

                // Calculate handedness
                float W = (Vector3.Dot(Vector3.Cross(n, t), b) < 0.0F) ? -1.0F : 1.0F;

                //Calculate Bitangent
                Bitangent[a] = Vector3.Multiply((Vector3.Cross(n, temp)), W);
                Bitangent[a] = Round(Bitangent[a]);
            }

        }
        public WavefrontObject(Stream stream)
        {
            //I'm very very sorry :{
            //For everything that follows...

            StreamReader sr = new StreamReader(stream);
            string s = sr.ReadToEnd();
            sr.Close();
            string[] Lines = s.Split(new string[] { "\r\n", "\n\r", "\n", "\r" }, StringSplitOptions.RemoveEmptyEntries);
            s = "";

            int Material = -1;
            int Group = -1;

            string Line;
            string[] components;
            string t;
            string last;
            int Length;

            bool Scan = true;

            for (int Pass = 0; Pass < 2; Pass++)
            {
                for (int i = 0; i < Lines.Length; i++)
                {
                    Line = Lines[i].Trim();
                    Length = Line.IndexOf(" ");
                    if (Length > 0)
                        Line = Line.Substring(0, Length);
                    last = s;
                    switch (Line)
                    {
                        case "v":
                            t = Lines[i].Trim();
                            components = t.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);
                            if (Scan)
                                VertexCount++;
                            else
                            {
                                float x = float.Parse(components[1]);
                                float y = float.Parse(components[2]);
                                float z = float.Parse(components[3]);
                                Vertices.Add(new Vector3(x, y, z));
                            }
                            break;
                        case "vt":
                            t = Lines[i].Trim();
                            components = t.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);
                            if (Scan)
                                TexcoordCount++;
                            else
                            {
                                float u = float.Parse(components[1]);
                                float v = float.Parse(components[2]);
                                Texcoords.Add(new Vector2(u, v));
                            }
                            break;
                        case "vn":
                            t = Lines[i].Trim();
                            components = t.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);
                            if (Scan)
                                NormalCount++;
                            else
                            {
                                float x = float.Parse(components[1]);
                                float y = float.Parse(components[2]);
                                float z = float.Parse(components[3]);
                                Normals.Add(new Vector3(x, y, z));
                            }
                            break;
                        case "f":
                            t = Lines[i].Trim();
                            components = t.Split(new string[] { " ", "/" }, StringSplitOptions.RemoveEmptyEntries);
                            if (Scan)
                                FaceCount++;
                            else
                            {
                                Face temp = new Face(components);
                                temp.MaterialID = Material;
                                temp.GroupID = Group;
                                Faces.Add(temp);
                            }
                            break;
                        //case "l":
                        //    t = Lines[i].Trim();
                        //    if (Scan)
                        //        LineCount++;
                        //    else
                        //    {
                        //        Line temp = new Line(t);
                        //        Lines.Add(temp);
                        //    }
                        //    break;
                        case "g":
                            t = Lines[i].Trim();
                            components = t.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);
                            if (Scan)
                                GroupCount++;
                            else
                            {
                                if (!(components.Length == 1) && !Groups.ContainsKey(components[1]))
                                {
                                    Groups.Add(components[1], Groups.Count);
                                    Group = Groups[components[1]];
                                }
                                else if (!(components.Length == 1))
                                    Group = Groups[components[1]];
                            }
                            break;
                        case "usemtl":
                            t = Lines[i].Trim();
                            components = t.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);
                            if (Scan)
                                MaterialCount++;
                            else
                            {
                                if (!Materials.ContainsKey(components[1]))
                                    Materials.Add(components[1], Materials.Count);
                                Material = Materials[components[1]];
                            }
                            break;
                        default:
                            break;
                    }
                }

                if (Scan)
                {
                    Initialize();
                    Scan = false;
                }
            }
        }
Exemple #3
0
        public void ExportWavefrontObject(Shader[] shaders)
        {
            WavefrontObject wfo = new WavefrontObject();
            wfo.Vertices = new List<Vector3>( _Vertices);
            wfo.VertexCount = _Vertices.Length;
            wfo.Texcoords = new List<Vector2>(Texcoords);
            wfo.TexcoordCount = Texcoords.Length;
            wfo.Normals = new List<Vector3>(Normals);
            wfo.NormalCount = Normals.Length;
            wfo.Materials = new Dictionary<string, int>();
            for (int i = 0; i < shaders.Length; i++)
                wfo.Materials.Add("Default_" + i.ToString(), i);
            wfo.GroupCount = Groups.Length;


            List<Face> FaceArray = new List<Face>(Indices.Length);

            for (int i = 0; i < Groups.Length; i++)
            {
                int Start = Groups[i].IndiceStart;
                int End = Groups[i].IndiceStart + Groups[i].IndiceCount - 2;
                bool Winding = true;

                for (int x = Start; x < End; x++)
                {
                    Face Temp = new Face(
                        Indices[x], 
                        Indices[x + 1], 
                        Indices[x + 2], 
                        Indices[x], 
                        Indices[x + 1], 
                        Indices[x + 2], 
                        Indices[x], 
                        Indices[x + 1], 
                        Indices[x + 2]
                        );
                    Temp.MaterialID = Groups[i].ShaderIndex;
                    Temp.GroupID = i;
                    if (!Temp.IsDegenerate)
                    {
                        FaceArray.Add(Temp);
                        if (Winding == false)
                        {
                            short y = Temp.VertexIndices[1];
                            short z = Temp.VertexIndices[2];
                            Temp.VertexIndices[1] = z;
                            Temp.VertexIndices[2] = y;
                            y = Temp.TexcoordIndices[1];
                            z = Temp.TexcoordIndices[2];
                            Temp.TexcoordIndices[1] = z;
                            Temp.TexcoordIndices[2] = y;
                            y = Temp.NormalIndices[1];
                            z = Temp.NormalIndices[2];
                            Temp.NormalIndices[1] = z;
                            Temp.NormalIndices[2] = y;
                            Winding = true;
                        }
                        else
                        {
                            Winding = false;
                        }

                    }
                    else
                    {
                        if (Winding == false) { Winding = true; }
                        else { Winding = false; }
                    }
                }
            }
            FaceArray.TrimExcess();
            wfo.Faces = FaceArray;
            wfo.FaceCount = FaceArray.Count;

            Wavefront.CreateWavefrontOBJFile(wfo, "O:\\test.obj");
        }
        public static WavefrontObject ParseWavefrontOBJFile(string filename)
        {
            StreamReader sr = new StreamReader(File.Open(filename, FileMode.Open, FileAccess.Read, FileShare.ReadWrite));
            string s = sr.ReadToEnd();
            sr.Close();
            string[] Lines = s.Split(new string[] { "\r\n", "\n\r", "\n", "\r" }, StringSplitOptions.RemoveEmptyEntries);
            s = "";

            WavefrontObject Wavefront = new WavefrontObject();

            int Material = -1;
            int Group = -1;

            string Line;
            string[] components;
            string t;
            string last;
            int Length;

            bool Scan = true;

            for (int Pass = 0; Pass < 2; Pass++)
            {
                for (int i = 0; i < Lines.Length; i++)
                {
                    Line = Lines[i].Trim();
                    Length = Line.IndexOf(" ");
                    if (Length > 0)
                        Line = Line.Substring(0, Length);
                    last = s;
                    switch (Line)
                    {
                        case "v":
                            t = Lines[i].Trim();
                            components = t.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);
                            if (Scan)
                                Wavefront.VertexCount++;
                            else
                            {
                                float x = float.Parse(components[1]);
                                float y = float.Parse(components[2]);
                                float z = float.Parse(components[3]);
                                Wavefront.Vertices.Add(new Vector3(x, y, z));
                            }
                            break;
                        case "vt":
                            t = Lines[i].Trim();
                            components = t.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);
                            if (Scan)
                                Wavefront.TexcoordCount++;
                            else
                            {
                                float u = float.Parse(components[1]);
                                float v = float.Parse(components[2]);
                                Wavefront.Texcoords.Add(new Vector2(u, v));
                            }
                            break;
                        case "vn":
                            t = Lines[i].Trim();
                            components = t.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);
                            if (Scan)
                                Wavefront.NormalCount++;
                            else
                            {
                                float x = float.Parse(components[1]);
                                float y = float.Parse(components[2]);
                                float z = float.Parse(components[3]);
                                Wavefront.Normals.Add(new Vector3(x, y, z));
                            }
                            break;
                        case "f":
                            t = Lines[i].Trim();
                            components = t.Split(new string[] { " ", "/" }, StringSplitOptions.RemoveEmptyEntries);
                            if (Scan)
                                Wavefront.FaceCount++;
                            else
                            {
                                Face temp = new Face(components);
                                temp.MaterialID = Material;
                                temp.GroupID = Group;
                                Wavefront.Faces.Add(temp);
                            }
                            break;
                        case "l":
                            t = Lines[i].Trim();
                            if (Scan)
                                Wavefront.LineCount++;
                            else
                            {
                                Line temp = new Line(t);
                                Wavefront.Lines.Add(temp);
                            }
                            break;
                        case "g":
                            t = Lines[i].Trim();
                            components = t.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);
                            if (Scan)
                                Wavefront.GroupCount++;
                            else
                            {
                                if (!(components.Length == 1) && !Wavefront.Groups.ContainsKey(components[1]))
                                {
                                    Wavefront.Groups.Add(components[1], Wavefront.Groups.Count);
                                    Group = Wavefront.Groups[components[1]];
                                }
                                else if (!(components.Length == 1))
                                    Group = Wavefront.Groups[components[1]];
                            }
                            break;
                        case "usemtl":
                            t = Lines[i].Trim();
                            components = t.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries);
                            if (Scan)
                                Wavefront.MaterialCount++;
                            else
                            {
                                if (!Wavefront.Materials.ContainsKey(components[1]))
                                    Wavefront.Materials.Add(components[1], Wavefront.Materials.Count);
                                Material = Wavefront.Materials[components[1]];
                            }
                            break;
                        default:
                            break;
                    }
                }

                if (Scan)
                {
                    Wavefront.Initialize();
                    Scan = false;
                }
            }
            return Wavefront;
        }