Gildor's Forums

Author Topic: Calculating tangent space  (Read 3809 times)
warrantyvoider
Full Member
***
Posts: 109


View Profile
Calculating tangent space
« on: October 30, 2012, 17:47 »

Hi,
I try to recreate the tangent space for wedges in static meshes. So far I know that the structure for one entry is like this:

struct Wedge
{
Vector4 Tangent;
Vector4 BiTangent; //???
Vector2[] UV;
}

I also know that a Vector4 is here stored packed in 4 bytes. Then I tried to use follow function to calc tangents for a given triangle:
(C#)

public Vector4[] CalcTangent(Vector3 v1,Vector3 v2,Vector3 v3,Vector2 w1,Vector2 w2,Vector2 w3)
        {
            Vector3[] tan1 = new Vector3[3];
            Vector3[] tan2 = new Vector3[3];
            Vector3[] norm = new Vector3[3];
            Vector4[] tangents = new Vector4[3];

            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;

            float s1 = w2.X - w1.X;
            float s2 = w3.X - w1.X;
            float t1 = w2.Y - w1.Y;
            float t2 = w3.Y - w1.Y;

            Vector3 edge1 = v2 - v1;
            Vector3 edge2 = v3 - v1;
            norm[0] = Vector3.Cross(edge1, edge2);
            edge1 = v3 - v2;
            edge2 = v1 - v2;
            norm[1] = Vector3.Cross(edge1, edge2);
            edge1 = v1 - v3;
            edge2 = v2 - v3;
            norm[2] = Vector3.Cross(edge1, edge2);
            norm[0].Normalize();
            norm[1].Normalize();
            norm[2].Normalize();
            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);

            tan1[0] += sdir;
            tan1[1] += sdir;
            tan1[2] += sdir;

            tan2[1] += tdir;
            tan2[2] += tdir;
            tan2[3] += tdir;
            for (int a = 0; a < 3; ++a)
            {
                Vector3 n = norm[a];
                Vector3 t = tan1[a];
                Vector3 tmp = (t - n * Vector3.Dot(n, t));
                tmp.Normalize();
                tangents[a] = new Vector4(tmp.X, tmp.Y, tmp.Z,0);
                tangents[a].W = (Vector3.Dot(Vector3.Cross(n, t), tan2[a]) < 0.0f) ? -1.0f : 1.0f;
            }
            return tangents;
        }

Can someone (maybe gildor) help me rewrite it to calc the bitangents (or binormals?) too? And yeah for now I dont want to smooth over sourrounding faces. Any help would be really appreciated, thanks in advance.

greetz WV
Logged
warrantyvoider
Full Member
***
Posts: 109


View Profile
Re: Calculating tangent space
« Reply #1 on: October 30, 2012, 22:49 »

Well I guess I found it out myself:
just switch:
for (int a = 0; a < 3; ++a)
            {
                Vector3 n = norm[a];
                Vector3 t = tan1[a];
                Vector3 tmp = (t - n * Vector3.Dot(n, t));
                tmp.Normalize();
                tangents[a] = new Vector4(tmp.X, tmp.Y, tmp.Z,0);
                tangents[a].W = (Vector3.Dot(Vector3.Cross(n, t), tan2[a]) < 0.0f) ? -1.0f : 1.0f;
            }

to:

for (int a = 0; a < 3; ++a)
            {
                Vector3 n = norm[a];
                Vector3 t = tan2[a];
                Vector3 tmp = (t - n * Vector3.Dot(n, t));
                tmp.Normalize();
                tangents[a] = new Vector4(tmp.X, tmp.Y, tmp.Z,0);
                tangents[a].W = (Vector3.Dot(Vector3.Cross(n, t), tan1[a]) < 0.0f) ? -1.0f : 1.0f;
            }
Logged
warrantyvoider
Full Member
***
Posts: 109


View Profile
Re: Calculating tangent space
« Reply #2 on: October 31, 2012, 01:01 »

It seems to work fine:

greetz WV
Logged
Jump to:  

Powered by SMF | SMF © 2006-2009, Simple Machines LLC
Leviathan design by Bloc | XHTML | CSS