public static TriangleData processTriangle(int[] index, Vector3f[] v, Vector2f[] t) {
        TempVars tmp = TempVars.get();
        try {
            Vector3f edge1 = tmp.vect1;
            Vector3f edge2 = tmp.vect2;
            Vector2f edge1uv = tmp.vect2d;
            Vector2f edge2uv = tmp.vect2d2;

            Vector3f tangent = tmp.vect3;
            Vector3f binormal = tmp.vect4;
            Vector3f normal = tmp.vect5;

            t[1].subtract(t[0], edge1uv);
            t[2].subtract(t[0], edge2uv);
            float det = edge1uv.x * edge2uv.y - edge1uv.y * edge2uv.x;

            boolean normalize = false;
            if (Math.abs(det) < ZERO_TOLERANCE) {
                log.log(Level.WARNING, "Collinear uv coordinates for triangle "
                        + "[{0}, {1}, {2}]; tex0 = [{3}, {4}], "
                        + "tex1 = [{5}, {6}], tex2 = [{7}, {8}]",
                        new Object[]{index[0], index[1], index[2],
                            t[0].x, t[0].y, t[1].x, t[1].y, t[2].x, t[2].y});
                det = 1;
                normalize = true;
            }

            v[1].subtract(v[0], edge1);
            v[2].subtract(v[0], edge2);

            tangent.set(edge1);
            tangent.normalizeLocal();
            binormal.set(edge2);
            binormal.normalizeLocal();

            if (Math.abs(Math.abs(tangent.dot(binormal)) - 1) < ZERO_TOLERANCE) {
                log.log(Level.WARNING, "Vertices are on the same line for triangle [{0}, {1}, {2}].",
                        new Object[]{index[0], index[1], index[2]});
            }

            float factor = 1 / det;
            tangent.x = (edge2uv.y * edge1.x - edge1uv.y * edge2.x) * factor;
            tangent.y = (edge2uv.y * edge1.y - edge1uv.y * edge2.y) * factor;
            tangent.z = (edge2uv.y * edge1.z - edge1uv.y * edge2.z) * factor;
            if (normalize) {
                tangent.normalizeLocal();
            }

            binormal.x = (edge1uv.x * edge2.x - edge2uv.x * edge1.x) * factor;
            binormal.y = (edge1uv.x * edge2.y - edge2uv.x * edge1.y) * factor;
            binormal.z = (edge1uv.x * edge2.z - edge2uv.x * edge1.z) * factor;
            if (normalize) {
                binormal.normalizeLocal();
            }

            tangent.cross(binormal, normal);
            normal.normalizeLocal();

            return new TriangleData(tangent.clone(), binormal.clone(), normal.clone());
            
        } finally {
            tmp.release();
        }
    }
A private constructor to inhibit instantiation of this class.
jme3-core/src/main/java/com/jme3/util/TangentBinormalGenerator.java