static TSpace evalTspace(int face_indices[], final int iFaces, final int piTriListIn[], final TriInfo pTriInfos[],
            final MikkTSpaceContext mikkTSpace, final int iVertexRepresentative) {
        TSpace res = new TSpace();
        float fAngleSum = 0;        

        for (int face = 0; face < iFaces; face++) {
            final int f = face_indices[face];

            // only valid triangles get to add their contribution
            if ((pTriInfos[f].flag & GROUP_WITH_ANY) == 0) {
                
                int i = -1;
                if (piTriListIn[3 * f + 0] == iVertexRepresentative) {
                    i = 0;
                } else if (piTriListIn[3 * f + 1] == iVertexRepresentative) {
                    i = 1;
                } else if (piTriListIn[3 * f + 2] == iVertexRepresentative) {
                    i = 2;
                }
                assert (i >= 0 && i < 3);

                // project
                int index = piTriListIn[3 * f + i];
                Vector3f n = getNormal(mikkTSpace, index);
                Vector3f vOs = pTriInfos[f].os.subtract(n.mult(n.dot(pTriInfos[f].os)));
                Vector3f vOt = pTriInfos[f].ot.subtract(n.mult(n.dot(pTriInfos[f].ot)));
                vOs.normalizeLocal();
                vOt.normalizeLocal();

                int i2 = piTriListIn[3 * f + (i < 2 ? (i + 1) : 0)];
                int i1 = piTriListIn[3 * f + i];
                int i0 = piTriListIn[3 * f + (i > 0 ? (i - 1) : 2)];

                Vector3f p0 = getPosition(mikkTSpace, i0);
                Vector3f p1 = getPosition(mikkTSpace, i1);
                Vector3f  p2 = getPosition(mikkTSpace, i2);
                Vector3f v1 = p0.subtract(p1);
                Vector3f v2 = p2.subtract(p1);

                // project
                v1.subtractLocal(n.mult(n.dot(v1))).normalizeLocal();
                v2.subtractLocal(n.mult(n.dot(v2))).normalizeLocal();

                // weight contribution by the angle
                // between the two edge vectors
                float fCos = v1.dot(v2);
                fCos = fCos > 1 ? 1 : (fCos < (-1) ? (-1) : fCos);
                float fAngle = (float) Math.acos(fCos);
                float fMagS = pTriInfos[f].magS;
                float fMagT = pTriInfos[f].magT;

                res.os.addLocal(vOs.multLocal(fAngle));
                res.ot.addLocal(vOt.multLocal(fAngle));
                res.magS += (fAngle * fMagS);
                res.magT += (fAngle * fMagT);
                fAngleSum += fAngle;
            }
        }

        // normalize
        res.os.normalizeLocal();
        res.ot.normalizeLocal();

        if (fAngleSum > 0) {
            res.magS /= fAngleSum;
            res.magT /= fAngleSum;
        }

        return res;
    }
A private constructor to inhibit instantiation of this class.
jme3-core/src/main/java/com/jme3/util/mikktspace/MikktspaceTangentGenerator.java