示例#1
0
        private vec3[] ArrangeNormals(ObjVNFContext context)
        {
            var        normals = new vec3[context.vertexCount];
            ObjVNFMesh mesh    = context.Mesh;

            for (int i = 0; i < context.faceCount; i++)
            {
                ObjVNFFace face          = mesh.faces[i];
                uint[]     normalIndexes = (from item in face.NormalIndexes() select item).ToArray();
                uint[]     vertexIndexes = (from item in face.VertexIndexes() select item).ToArray();

                if (normalIndexes.Length != vertexIndexes.Length)
                {
                    throw new Exception(string.Format(
                                            "normalIndexes.Length [{0}] != vertexIndexes.Length [{1}]!",
                                            normalIndexes.Length, vertexIndexes.Length));
                }

                for (int t = 0; t < vertexIndexes.Length; t++)
                {
                    normals[vertexIndexes[t]] = mesh.normals[normalIndexes[t]];
                }
            }

            return(normals);
        }
        private vec2[] ArrangeTexCoords(ObjVNFContext context)
        {
            var        texCoords = new vec2[context.vertexCount];
            ObjVNFMesh mesh      = context.Mesh;

            for (int i = 0; i < context.faceCount; i++)
            {
                ObjVNFFace face            = mesh.faces[i];
                uint[]     texCoordIndexes = face.TexCoordIndexes();
                uint[]     vertexIndexes   = face.VertexIndexes();

                if (texCoordIndexes.Length != vertexIndexes.Length)
                {
                    throw new Exception(string.Format(
                                            "texCoordIndexes.Length [{0}] != vertexIndexes.Length [{1}]!",
                                            texCoordIndexes.Length, vertexIndexes.Length));
                }

                for (int t = 0; t < vertexIndexes.Length; t++)
                {
                    texCoords[vertexIndexes[t]] = mesh.texCoords[texCoordIndexes[t]];
                }
            }

            return(texCoords);
        }
        public override void Parse(ObjVNFContext context)
        {
            ObjVNFMesh mesh = context.Mesh;

            if (mesh.texCoords.Length > 0)
            {
                vec2[] texCoords = ArrangeTexCoords(context);
                mesh.texCoords = texCoords;
            }
        }
示例#4
0
        /// <summary>
        /// Reads mesh's vertex count, normal count and face count.
        /// </summary>
        /// <param name="context"></param>
        public override void Parse(ObjVNFContext context)
        {
            int        triangleFaceCount = 0;
            ObjVNFMesh mesh = context.Mesh;

            for (int i = 0; i < context.faceCount; i++)
            {
                ObjVNFFace face          = mesh.faces[i];
                uint[]     normalIndexes = (from item in face.NormalIndexes() select item).ToArray();
                uint[]     vertexIndexes = (from item in face.VertexIndexes() select item).ToArray();

                if (normalIndexes.Length != vertexIndexes.Length)
                {
                    throw new Exception(string.Format(
                                            "normalIndexes.Length [{0}] != vertexIndexes.Length [{0}]!",
                                            normalIndexes.Length, vertexIndexes.Length));
                }

                if (face is ObjVNFTriangle)
                {
                    triangleFaceCount++;
                }
                else if (face is ObjVNFQuad)
                {
                    triangleFaceCount += 2;
                }
            }

            if (triangleFaceCount != context.faceCount)
            {
                var faces = new ObjVNFTriangle[triangleFaceCount];
                for (int i = 0, j = 0; i < context.faceCount; i++)
                {
                    ObjVNFFace face = mesh.faces[i];
                    if (face is ObjVNFTriangle)
                    {
                        faces[j++] = face as ObjVNFTriangle;
                    }
                    else if (face is ObjVNFQuad)
                    {
                        var quad = face as ObjVNFQuad;
                        faces[j++] = new ObjVNFTriangle(
                            quad.vertexIndexes[0], quad.vertexIndexes[1], quad.vertexIndexes[2],
                            quad.normalIndexes[0], quad.normalIndexes[1], quad.normalIndexes[2],
                            quad.texCoordIndexes[0], quad.texCoordIndexes[1], quad.texCoordIndexes[2]);
                        faces[j++] = new ObjVNFTriangle(
                            quad.vertexIndexes[0], quad.vertexIndexes[2], quad.vertexIndexes[3],
                            quad.normalIndexes[0], quad.normalIndexes[2], quad.normalIndexes[3],
                            quad.texCoordIndexes[0], quad.texCoordIndexes[2], quad.texCoordIndexes[3]);
                    }
                }
                mesh.faces        = faces;
                context.faceCount = triangleFaceCount;
            }
        }
示例#5
0
        /// <summary>
        /// move mesh to center of model space.
        /// </summary>
        /// <param name="context"></param>
        public override void Parse(ObjVNFContext context)
        {
            if (context.vertexCount <= 0)
            {
                return;
            }

            vec3[] vertexes = context.Mesh.vertexes;
            vec3   min      = vertexes[0];
            vec3   max      = min;

            for (int i = 1; i < vertexes.Length; i++)
            {
                vec3 position = vertexes[i];
                if (position.x < min.x)
                {
                    min.x = position.x;
                }
                if (position.y < min.y)
                {
                    min.y = position.y;
                }
                if (position.z < min.z)
                {
                    min.z = position.z;
                }
                if (max.x < position.x)
                {
                    max.x = position.x;
                }
                if (max.y < position.y)
                {
                    max.y = position.y;
                }
                if (max.z < position.z)
                {
                    max.z = position.z;
                }
            }

            vec3 center = min / 2 + max / 2;
            vec3 size   = max - min;

            context.Mesh.Position = center;// position in world space.
            context.Mesh.Size     = size;
            // move vertexes to center of model space.
            for (int i = 0; i < vertexes.Length; i++)
            {
                vertexes[i] = vertexes[i] - center;
            }
        }
示例#6
0
        public override void Parse(ObjVNFContext context)
        {
            vec3[]     normals = null;
            ObjVNFMesh mesh    = context.Mesh;

            if (mesh.normals.Length == 0)
            {
                normals = CalculateNormals(context);
            }
            else
            {
                normals = ArrangeNormals(context);
            }

            mesh.normals = normals;
        }
示例#7
0
        private vec3[] CalculateNormals(ObjVNFContext context)
        {
            ObjVNFMesh mesh        = context.Mesh;
            var        faceNormals = new vec3[context.faceCount];

            for (int i = 0; i < context.faceCount; i++)
            {
                ObjVNFFace face          = mesh.faces[i];
                uint[]     vertexIndexes = (from item in face.VertexIndexes() select item).ToArray();
                vec3       v0            = mesh.vertexes[vertexIndexes[0]];
                vec3       v1            = mesh.vertexes[vertexIndexes[1]];
                vec3       v2            = mesh.vertexes[vertexIndexes[2]];

                vec3 normal = (v0 - v1).cross(v0 - v2).normalize();
                faceNormals[i] = normal;
            }

            var normals  = new vec3[context.vertexCount];
            var counters = new int[context.vertexCount];

            for (int i = 0; i < context.faceCount; i++)
            {
                ObjVNFFace face          = mesh.faces[i];
                uint[]     vertexIndexes = (from item in face.VertexIndexes() select item).ToArray();
                vec3       v0            = mesh.vertexes[vertexIndexes[0]];
                vec3       v1            = mesh.vertexes[vertexIndexes[1]];
                vec3       v2            = mesh.vertexes[vertexIndexes[2]];

                normals[vertexIndexes[0]] += faceNormals[i];
                counters[vertexIndexes[0]]++;
                normals[vertexIndexes[1]] += faceNormals[i];
                counters[vertexIndexes[1]]++;
                normals[vertexIndexes[2]] += faceNormals[i];
                counters[vertexIndexes[2]]++;
            }
            for (int i = 0; i < normals.Length; i++)
            {
                if (counters[i] > 0)
                {
                    normals[i] = normals[i].normalize();
                }
            }

            return(normals);
        }
示例#8
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="filename"></param>
        /// <returns></returns>
        public ObjVNFResult Parse(string filename)
        {
            ObjVNFResult result  = new ObjVNFResult();
            var          context = new ObjVNFContext(filename);

            try {
                foreach (var item in this.parserList)
                {
                    item.Parse(context);
                }

                result.Mesh = context.Mesh;
            }
            catch (Exception ex) {
                result.Error = ex;
            }

            return(result);
        }
        /// <summary>
        /// Reads mesh's vertex count, normal count and face count.
        /// </summary>
        /// <param name="context"></param>
        public override void Parse(ObjVNFContext context)
        {
            string filename = context.ObjFilename;

            using (var reader = new System.IO.StreamReader(filename))
            {
                int vertexCount = 0, normalCount = 0, texCoordCount = 0, faceCount = 0;
                while (!reader.EndOfStream)
                {
                    string   line  = reader.ReadLine();
                    string[] parts = line.Split(separator, StringSplitOptions.RemoveEmptyEntries);
                    if (parts.Length <= 0)
                    {
                        continue;
                    }

                    if (parts[0] == "v")
                    {
                        vertexCount++;
                    }
                    else if (parts[0] == "vn")
                    {
                        normalCount++;
                    }
                    else if (parts[0] == "vt")
                    {
                        texCoordCount++;
                    }
                    else if (parts[0] == "f")
                    {
                        faceCount++;
                    }
                }
                context.vertexCount   = vertexCount;
                context.normalCount   = normalCount;
                context.texCoordCount = texCoordCount;
                context.faceCount     = faceCount;
            }
        }
        /// <summary>
        /// Reads mesh's vertex count, normal count and face count.
        /// </summary>
        /// <param name="context"></param>
        public override void Parse(ObjVNFContext context) {
            int triangleFaceCount = 0;
            ObjVNFMesh mesh = context.Mesh;
            for (int i = 0; i < context.faceCount; i++) {
                ObjVNFFace face = mesh.faces[i];
                uint[] vertexIndexes = face.VertexIndexes();

                if (face is ObjVNFTriangle) {
                    triangleFaceCount++;
                }
                else if (face is ObjVNFQuad) {
                    triangleFaceCount += 2;
                }
            }

            if (triangleFaceCount != context.faceCount) {
                var faces = new ObjVNFTriangle[triangleFaceCount];
                for (int i = 0, j = 0; i < context.faceCount; i++) {
                    ObjVNFFace face = mesh.faces[i];
                    if (face is ObjVNFTriangle) {
                        faces[j++] = face as ObjVNFTriangle;
                    }
                    else if (face is ObjVNFQuad) {
                        var quad = face as ObjVNFQuad;
                        faces[j++] = new ObjVNFTriangle(
                            quad.vertexIndexes[0], quad.vertexIndexes[1], quad.vertexIndexes[2],
                            quad.normalIndexes[0], quad.normalIndexes[1], quad.normalIndexes[2],
                            quad.texCoordIndexes[0], quad.texCoordIndexes[1], quad.texCoordIndexes[2]);
                        faces[j++] = new ObjVNFTriangle(
                            quad.vertexIndexes[0], quad.vertexIndexes[2], quad.vertexIndexes[3],
                            quad.normalIndexes[0], quad.normalIndexes[2], quad.normalIndexes[3],
                            quad.texCoordIndexes[0], quad.texCoordIndexes[2], quad.texCoordIndexes[3]);
                    }
                }
                mesh.faces = faces;
                context.faceCount = triangleFaceCount;
            }
        }
示例#11
0
        /// <summary>
        /// Reads mesh's vertexes, normals and faces.
        /// </summary>
        /// <param name="context"></param>
        public override void Parse(ObjVNFContext context)
        {
            var    objVNF = new ObjVNFMesh();
            var    vertexes = new vec3[context.vertexCount];
            var    normals = new vec3[context.normalCount];
            var    texCoords = new vec2[context.texCoordCount];
            var    faces = new ObjVNFFace[context.faceCount];
            string filename = context.ObjFilename;
            int    vertexIndex = 0, normalIndex = 0, texCoordIndex = 0, faceIndex = 0;

            using (var reader = new System.IO.StreamReader(filename))
            {
                while (!reader.EndOfStream)
                {
                    string   line  = reader.ReadLine();
                    string[] parts = line.Split(separator, StringSplitOptions.RemoveEmptyEntries);
                    if (parts.Length <= 0)
                    {
                        continue;
                    }

                    if (parts[0] == "v")
                    {
                        vertexes[vertexIndex++] = ParseVec3(parts);
                    }
                    else if (parts[0] == "vn")
                    {
                        normals[normalIndex++] = ParseVec3(parts);
                    }
                    else if (parts[0] == "vt")
                    {
                        texCoords[texCoordIndex++] = ParseVec2(parts);
                    }
                    else if (parts[0] == "f")
                    {
                        faces[faceIndex++] = ParseFace(parts);
                    }
                }
            }

            objVNF.vertexes  = vertexes;
            objVNF.normals   = normals;
            objVNF.texCoords = texCoords;
            objVNF.faces     = faces;

            context.Mesh = objVNF;

            if (vertexIndex != context.vertexCount)
            {
                throw new Exception(string.Format("v: [{0}] not equals to [{1}] in MeshParser!", vertexIndex, context.vertexCount));
            }
            if (normalIndex != context.normalCount)
            {
                throw new Exception(string.Format("vn: [{0}] not equals to [{1}] in MeshParser!", normalIndex, context.normalCount));
            }
            if (texCoordIndex != context.texCoordCount)
            {
                throw new Exception(string.Format("vt: [{0}] not equals to [{1}] in MeshParser!", texCoordIndex, context.texCoordCount));
            }
            if (faceIndex != context.faceCount)
            {
                throw new Exception(string.Format("f: [{0}] not equals to [{1}] in MeshParser!", vertexIndex, context.vertexCount));
            }
            if (faceIndex > 0)
            {
                Type type = faces[0].GetType();
                for (int i = 1; i < faceIndex; i++)
                {
                    if (faces[i].GetType() != type)
                    {
                        throw new Exception(string.Format("Different face types [{0}] vs [{1}]!", type, faces[i].GetType()));
                    }
                }
            }
        }
示例#12
0
        public override void Parse(ObjVNFContext context)
        {
            ObjVNFMesh mesh = context.Mesh;

            vec3[] vertexes  = mesh.vertexes;// positions
            vec2[] texCoords = mesh.texCoords;
            vec3[] normals   = mesh.normals;
            if (vertexes == null || texCoords == null || normals == null)
            {
                return;
            }
            if (vertexes.Length != texCoords.Length || vertexes.Length != normals.Length)
            {
                return;
            }

            ObjVNFFace[] faces = mesh.faces;
            if (faces == null || faces.Length == 0)
            {
                return;
            }
            // if (not triangles) { return; }
            if (faces[0].VertexIndexes().Count() != 3)
            {
                return;
            }

            var tangents = new vec3[normals.Length];

            for (int i = 0; i < faces.Length; i++)
            {
                var face = faces[i] as ObjVNFTriangle;
                if (face == null)
                {
                    return;
                }                             // no dealing with quad.
                uint[] vertexIndexes = face.VertexIndexes();
                vec3   p0 = vertexes[vertexIndexes[0]];
                vec3   p1 = vertexes[vertexIndexes[1]];
                vec3   p2 = vertexes[vertexIndexes[2]];
                vec2   uv0 = texCoords[vertexIndexes[0]];
                vec2   uv1 = texCoords[vertexIndexes[1]];
                vec2   uv2 = texCoords[vertexIndexes[2]];
                vec3   q0 = p1 - p0, q1 = p2 - p0;
                float  u0 = uv0.x, v0 = uv0.y, u1 = uv1.x, v1 = uv1.y, u2 = uv2.x, v2 = uv2.y;
                float  coefficient = 1.0f / ((u1 - u0) * (v2 - v0) - (v1 - v0) * (u2 - u0));
                vec3   tangentFace;
                tangentFace.x = (v2 - v0) * q0.x + (v0 - v1) * q1.x;
                tangentFace.y = (v2 - v0) * q0.y + (v0 - v1) * q1.y;
                tangentFace.z = (v2 - v0) * q0.z + (v0 - v1) * q1.z;
                //vec3 binormalFace;
                //binormalFace.x = (u0 - u2) * q0.x + (u1 - u0) * q1.x;
                //binormalFace.y = (u0 - u2) * q0.y + (u1 - u0) * q1.y;
                //binormalFace.z = (u0 - u2) * q0.z + (u1 - u0) * q1.z;
                for (int t = 0; t < vertexIndexes.Length; t++)
                {
                    vec3 n = normals[vertexIndexes[t]].normalize();
                    tangents[vertexIndexes[t]] = tangentFace - tangentFace.dot(n) * n;
                }
            }

            mesh.tangents = tangents;
        }
示例#13
0
        // https://www.cnblogs.com/bitzhuwei/p/opengl-Computing-Tangent-Space-Basis-Vectors.html
        public override void Parse(ObjVNFContext context)
        {
            ObjVNFMesh mesh = context.Mesh;

            vec3[] vertexes  = mesh.vertexes;// positions
            vec2[] texCoords = mesh.texCoords;
            vec3[] normals   = mesh.normals;
            if (vertexes == null || texCoords == null || normals == null)
            {
                return;
            }
            if (vertexes.Length != texCoords.Length || vertexes.Length != normals.Length)
            {
                return;
            }

            ObjVNFFace[] faces = mesh.faces;
            if (faces == null || faces.Length == 0)
            {
                return;
            }
            // if (not triangles) { return; }
            if (faces[0].VertexIndexes().Count() != 3)
            {
                return;
            }

            var tangents   = new vec3[normals.Length];
            var biTangents = new vec3[normals.Length];

            for (int i = 0; i < faces.Length; i++)
            {
                var face = faces[i] as ObjVNFTriangle;
                if (face == null)
                {
                    return;
                }                             // no dealing with quad.

                uint[] vertexIndexes = face.VertexIndexes();
                uint   i0            = vertexIndexes[0];
                uint   i1            = vertexIndexes[1];
                uint   i2            = vertexIndexes[2];
                vec3   p0            = vertexes[i0];
                vec3   p1            = vertexes[i1];
                vec3   p2            = vertexes[i2];
                vec2   uv0           = texCoords[i0];
                vec2   uv1           = texCoords[i1];
                vec2   uv2           = texCoords[i2];

                float x1 = p1.x - p0.x;
                float y1 = p1.y - p0.y;
                float z1 = p1.z - p0.z;
                float x2 = p2.x - p0.x;
                float y2 = p2.y - p0.y;
                float z2 = p2.z - p0.z;

                float s1 = uv1.x - uv0.x;
                float t1 = uv1.y - uv0.y;
                float s2 = uv2.x - uv0.x;
                float t2 = uv2.y - uv0.y;

                float r    = 1.0F / (s1 * t2 - s2 * t1);
                var   sdir = new vec3((t2 * x1 - t1 * x2) * r, (t2 * y1 - t1 * y2) * r,
                                      (t2 * z1 - t1 * z2) * r);
                var tdir = new vec3((s1 * x2 - s2 * x1) * r, (s1 * y2 - s2 * y1) * r,
                                    (s1 * z2 - s2 * z1) * r);

                //tangents[i0] += sdir;
                tangents[i0] = (float)i / (float)(i + 1) * tangents[i0] + sdir / (float)(i + 1);
                //tangents[i1] += sdir;
                tangents[i1] = (float)i / (float)(i + 1) * tangents[i1] + sdir / (float)(i + 1);
                //tangents[i2] += sdir;
                tangents[i2] = (float)i / (float)(i + 1) * tangents[i2] + sdir / (float)(i + 1);

                //biTangents[i0] += tdir;
                biTangents[i0] = (float)i / (float)(i + 1) * biTangents[i0] + sdir / (float)(i + 1);
                //biTangents[i1] += tdir;
                biTangents[i1] = (float)i / (float)(i + 1) * biTangents[i1] + sdir / (float)(i + 1);
                //biTangents[i2] += tdir;
                biTangents[i2] = (float)i / (float)(i + 1) * biTangents[i2] + sdir / (float)(i + 1);
            }

            var finalTangents = new vec4[normals.Length];

            for (long a = 0; a < normals.Length; a++)
            {
                vec3 n = normals[a];
                vec3 t = tangents[a];

                // Calculate handedness
                float w = (n.cross(t).dot(biTangents[a]) < 0.0F) ? -1.0F : 1.0F;

                // Gram-Schmidt orthogonalize
                finalTangents[a] = new vec4((t - n * n.dot(t)).normalize(), w);
            }

            mesh.tangents = finalTangents;
        }
示例#14
0
 public abstract void Parse(ObjVNFContext context);