示例#1
0
        public void RecalculateTangents()
        {
            if (HasUVs() == false)
            {
                UVs.Resize(Vertices.Count);
            }

            //partialy stolen from http://www.opengl-tutorial.org/intermediate-tutorials/tutorial-13-normal-mapping/

            int verticesNum = Vertices.Count;
            int indiciesNum = TriangleIndicies.Count;

            int[] counts = new int[verticesNum];

            Tangents.Clear();
            Tangents.Capacity = verticesNum;

            for (int i = 0; i < verticesNum; i++)
            {
                counts[i] = 0;
                Tangents.Add(Vector3.Zero);
            }

            for (int i = 0; i <= indiciesNum - 3; i += 3)
            {
                int ai = TriangleIndicies[i];
                int bi = TriangleIndicies[i + 1];
                int ci = TriangleIndicies[i + 2];

                if (ai < verticesNum && bi < verticesNum && ci < verticesNum)
                {
                    Vector3 av        = Vertices[ai];
                    Vector3 deltaPos1 = Vertices[bi] - av;
                    Vector3 deltaPos2 = Vertices[ci] - av;

                    Vector2 auv      = UVs[ai];
                    Vector2 deltaUV1 = UVs[bi] - auv;
                    Vector2 deltaUV2 = UVs[ci] - auv;

                    float   r = 1.0f / (deltaUV1.X * deltaUV2.Y - deltaUV1.Y * deltaUV2.X);
                    Vector3 t = (deltaPos1 * deltaUV2.Y - deltaPos2 * deltaUV1.Y) * r;

                    Tangents[ai] += t;
                    Tangents[bi] += t;
                    Tangents[ci] += t;

                    counts[ai]++;
                    counts[bi]++;
                    counts[ci]++;
                }
            }

            for (int i = 0; i < verticesNum; i++)
            {
                Tangents[i] /= counts[i];
            }
        }