Part of the Khronos Group
OpenGL.org

The Industry's Foundation for High Performance Graphics

from games to virtual reality, mobile phones to supercomputers

Results 1 to 6 of 6

Thread: New challenge!, inverse transpose matrix under GLSL 120... !!!

  1. #1
    Junior Member Newbie
    Join Date
    Apr 2012
    Posts
    5

    New challenge!, inverse transpose matrix under GLSL 120... !!!

    Hi Guys!,

    I'm having some troubles, of how I could obtain the transpose(inverse(mat3 mat)) under GLSL 120.
    This is because I'm using GPU Skinning to render organic meshes.

    So the most important code is:

    //Here we made all the magic to get a Mat4 that allow us to put the Vertex in the correct place ( Local Position )
    mat4 matTransform = obtainMatTransformCurrentAnimation( ... );


    //Made Multiplication to Vertex
    vec4 vLocalPos = matTransform * glVertex;

    //Now, we multiply it with the gl_ModelViewProjectionMatrix to get the final position
    gl_Position = gl_ModelViewProjectionMatrix * vLocalPos;

    //So here is the problem, to calculate the normals you need the transpose(inverse(matTransform))
    mat3 normalMat = transpose( ddeInverse( matTransform ) );
    normalMat = gl_NormalMatrix * normalMat;

    //Now we made the normal Multiplication to the normal varying variable
    pNormal = normalMat * gl_Normal;

    //Here are the ddeInverse and ddeDeterminant Methods.
    float ddeDeterminant( mat3 A )
    {
    //Calculate the determinant

    float determinant = +A[0][0] * ( A[1][1] * A[2][2] - A[2][1] * A[1][2] )
    -A[0][1] * ( A[1][0] * A[2][2] - A[1][2] * A[2][0] )
    +A[0][2] * ( A[1][0] * A[2][1] - A[1][1] * A[2][0] );

    return determinant;
    }


    mat3 ddeInverse(const in mat3 Matrix)
    {
    // Calculate the determinant...
    float D = ddeDeterminant(Matrix);

    // Singular matrix, problem...
    if(D == 0.0)
    return mat3(0.0);


    // Calculate the transpose...
    mat3 MatrixT = transpose(Matrix);


    // Calculate needed determinants...
    float D00 = MatrixT[1][1] * MatrixT[2][2] + MatrixT[2][1] * MatrixT[1][2];
    float D10 = MatrixT[0][1] * MatrixT[2][2] + MatrixT[2][1] * MatrixT[0][2];
    float D20 = MatrixT[0][1] * MatrixT[1][2] + MatrixT[1][1] * MatrixT[0][2];
    float D01 = MatrixT[1][0] * MatrixT[2][2] + MatrixT[2][0] * MatrixT[1][2];
    float D11 = MatrixT[0][0] * MatrixT[2][2] + MatrixT[2][0] * MatrixT[0][2];
    float D21 = MatrixT[0][0] * MatrixT[1][2] + MatrixT[1][0] * MatrixT[0][2];
    float D02 = MatrixT[1][0] * MatrixT[2][1] + MatrixT[2][0] * MatrixT[1][1];
    float D12 = MatrixT[0][0] * MatrixT[2][1] + MatrixT[2][0] * MatrixT[0][1];
    float D22 = MatrixT[0][0] * MatrixT[1][1] + MatrixT[1][0] * MatrixT[0][1];

    // Assemble matrix of cofactors...
    mat3 MatrixAdjugate;
    MatrixAdjugate[0] = vec3( D00, -D01, D02);
    MatrixAdjugate[1] = vec3(-D10, D11, -D12);
    MatrixAdjugate[2] = vec3( D20, -D21, D22);

    // Calculate the inverse...
    return (1.0 / D) * MatrixAdjugate;
    }

    I'm limited to GLSL 120 because the shader is running under a 7800GTX... so any advice?.

    Thanks in advance!!! =).

  2. #2
    Senior Member OpenGL Guru Dark Photon's Avatar
    Join Date
    Oct 2004
    Location
    Druidia
    Posts
    2,882
    Quote Originally Posted by S-h-0-X View Post
    I'm having some troubles, of how I could obtain the transpose(inverse(mat3 mat)) under GLSL 120.
    This is because I'm using GPU Skinning to render organic meshes. ...so any advice?
    Yep. Looking at the problem and taking a step back, first question whether you need to. Suggestion:

    Only allow rigid transformations for your joint transforms (both joint orientation and animation transforms, and thus joint final transforms as well), and then inverse = transpose and there's no need to mess with this inverse transpose stuff. Just use the rotation component of your skinning transform to skin your normals.

    Note: rigid transform = rotates and translates only (no scales or shears)

    Note that even the blended inverse transpose transformed normal is not precisely the correct normal, but it's typically regarded as good enough.

    Also note that even if you allow uniform scale, IIRC inverse transpose is still overkill. You can optimize that.

    If you use linear blend skinning, keep in mind that blending matrices is really garbage (thus joint collapse, rigid transforms becoming deorthonormalized, etc.). Consider quaternion-based methods.

    You could even use quaternions instead of normals too.
    Last edited by Dark Photon; 05-18-2012 at 05:13 PM.

  3. #3
    Junior Member Newbie
    Join Date
    Apr 2012
    Posts
    5
    Right now, I processed the Gpu Skinning with a static boneMatrix[61], and skin like this:

    //Weight Vector
    vec4 weight = gl_MultiTexCoord1;

    //Matrix Bone Index
    vec4 matIndex = gl_MultiTexCoord2;
    int matIndex0 = int(matIndex.x);
    int matIndex1 = int(matIndex.y);
    int matIndex2 = int(matIndex.z);
    int matIndex3 = int(matIndex.w);

    //Matrix Transformation
    mat4 matTransform = boneMatrix[matIndex0] * weight.x;
    matTransform += boneMatrix[matIndex1] * weight.y;
    matTransform += boneMatrix[matIndex2] * weight.z;

    //Local Position Computation
    float finalWeight = 1.0f - ( weight.x + weight.y + weight.z );
    matTransform += boneMatrix[matIndex3] * finalWeight;

    So per mesh... I can use 61 bones max.

  4. #4
    Senior Member OpenGL Guru Dark Photon's Avatar
    Join Date
    Oct 2004
    Location
    Druidia
    Posts
    2,882
    Quote Originally Posted by S-h-0-X View Post
    Right now, I processed the Gpu Skinning with a static boneMatrix[61], and skin like this:
    Code :
         //Weight Vector
         vec4 weight    = gl_MultiTexCoord1;
     
         //Matrix Bone Index
         vec4 matIndex  = gl_MultiTexCoord2;
         int  matIndex0 = int(matIndex.x);
         int  matIndex1 = int(matIndex.y);
         int  matIndex2 = int(matIndex.z);
         int  matIndex3 = int(matIndex.w);
    Please put \[code\]...\[/code\] tags (without backslashes) around your code blocks. Makes it more readable.

    Just FYI, the above should work and takes 2 16-byte input attributes (32 bytes total). If you care, you can pass in the same info using only 1/4 of the space (8 bytes) by passing in a uvec2 into a single vtx attrib. In .x store 4 8-bit packed joint/bone indices. In .y store 4 8-bit packed weights (0..255). Just make sure you populate it on the C++ side using glVertexAttribIPointer, not glVertexAttribPointer.

    Actually, you said GLSL 1.2, which doesn't have bit shifts or uint/uvec. Not sure if you can run a higher version on a GeForce 7 or not by forcing it, but if not guess you can't do the above on that GPU.

    Code :
         //Matrix Transformation
         mat4 matTransform  = boneMatrix[matIndex0] * weight.x ...
         matTransform += boneMatrix[matIndex1] * weight.y;
    ...
    Ok, so standard linear blend skinning (LBS) so the usual caveats apply.

    Re your inverse transpose question presumably directed toward skinning your vertex normal, if your joint/bone matrices are rigid transforms, just use mat3( matTransform ) to transform the normal.
    Last edited by Dark Photon; 05-18-2012 at 05:52 PM.

  5. #5
    Junior Member Newbie
    Join Date
    Apr 2012
    Posts
    5
    Hi there!,

    Thanks Dark Photon for the advice, but the engine must run on Linux / Mac / Windows, and right now is not a good idea to made some kind of "hacking" to improve the upload of the joints and weights to the Gpu, It seems that I really can made some kind of optimization under Linux, but I cannot made it work under Windows so... U_U no luck at the moment.

    I'm trying to test what you said in the previous post, but neither the mat3( matTransform ) or the transpose( mat3( matTransform ) ) seems to work.

    Code :
    mat3 normaMat = gl_NormalMatrix * mat3(matTransform);

    The implementation is based on the MD5 one, so no scales or shares are applied, so I really cannot understand why is not working properly...

    Here is the code from CPU side to fill the VBO.

    Code :
    [COLOR=#ff00ff][COLOR=#0000ff]void[/COLOR]ddeCL::ddeMeshBuild[COLOR=#8000ff]( [/COLOR][COLOR=#000080]ddeMesh[/COLOR][COLOR=#8000ff] *[/COLOR][COLOR=#0000ff]tempMesh[/COLOR][COLOR=#8000ff] )[/COLOR][/COLOR]
    [COLOR=#8000ff]{[/COLOR]
    [COLOR=#008000]/* Local variables */[/COLOR]
    [COLOR=#8000ff]   [COLOR=#000080]Vertex[/COLOR]                    *[COLOR=#000080]tempVert[/COLOR]            = NULL;[/COLOR]
    [COLOR=#8000ff]    [COLOR=#000080]Weight[/COLOR]                   *[COLOR=#000080]tempWeight[/COLOR]        = NULL;[/COLOR]
    [COLOR=#8000ff]    [COLOR=#000080]Joint[/COLOR]                       *[COLOR=#000080]tempJoint[/COLOR]           = NULL;[/COLOR]
    [COLOR=#8000ff]    [COLOR=#000080]ddeFloat[/COLOR]                 *[COLOR=#000080]currVBOPos[/COLOR]        = NULL;[/COLOR]
    [COLOR=#8000ff]    [COLOR=#000080]ddeFloat[/COLOR]                 *[COLOR=#000080]VBOCPU[/COLOR]             = NULL;[/COLOR]
    [COLOR=#8000ff]    ddeMath::[COLOR=#000080]vec3[/COLOR]         [COLOR=#000080]tan1[/COLOR]   [[COLOR=#0000ff]tempMesh[/COLOR]->[COLOR=#800080]numVerts[/COLOR]];[/COLOR]
    [COLOR=#8000ff]    ddeMath::[COLOR=#000080]vec3[/COLOR]         [COLOR=#000080]tan2[/COLOR]   [[COLOR=#0000ff]tempMesh[/COLOR]->[COLOR=#800080]numVerts[/COLOR]];[/COLOR]
    [COLOR=#8000ff]    [U]vector[/U]<ddeMath::[COLOR=#000080]vec4[/COLOR]> [COLOR=#000080]WeightBuffer[/COLOR];[/COLOR]
    [COLOR=#8000ff]    [U]vector[/U]<ddeMath::[COLOR=#000080]vec4[/COLOR]> [COLOR=#000080]BoneIndexBuffer[/COLOR];[/COLOR][COLOR=#008000]
    [/COLOR]
    [COLOR=#0000ff]if[COLOR=#8000ff]( [/COLOR]tempMesh[COLOR=#8000ff]->[/COLOR][COLOR=#800080]isSkinned[/COLOR][COLOR=#8000ff] == [/COLOR]false[COLOR=#8000ff] )[/COLOR][/COLOR]
    [COLOR=#8000ff]                {[/COLOR]
    [COLOR=#808080][COLOR=#8000ff][U]printf[/U][/COLOR][COLOR=#8000ff]( [/COLOR]"Processing Mesh... %s\n"[COLOR=#8000ff], [/COLOR][COLOR=#0000ff]tempMesh[/COLOR][COLOR=#8000ff]->[/COLOR][COLOR=#800080]meshName[/COLOR][COLOR=#8000ff] );[/COLOR][/COLOR]
    [COLOR=#008000]//We create a temporary array in order to copy all the meshes from the file to the VBOCPU Array,[/COLOR]
    [COLOR=#008000]//We don't need 64 bytes  of information for each vertex, but this way we will made a perfect pre-fetching[/COLOR]
    [COLOR=#008000]//and no cache miss on GPU, so that's why we send dummy information[/COLOR]
    [COLOR=#8000ff]                    [COLOR=#000080]VBOCPU[/COLOR]  = ( [COLOR=#000080]ddeFloat[/COLOR]* )[U]malloc[/U]( ( [COLOR=#0000ff]tempMesh[/COLOR]->[COLOR=#800080]numVerts[/COLOR] * [COLOR=#ff8000]16[/COLOR] )  * [COLOR=#0000ff]sizeof[/COLOR]( [COLOR=#0000ff]float[/COLOR] ) );[/COLOR]
     
    [COLOR=#000080][COLOR=#0000ff]for[/COLOR][COLOR=#8000ff] ( [/COLOR]ddeIntj[COLOR=#8000ff] = [/COLOR][COLOR=#ff8000]0[/COLOR][COLOR=#8000ff], [/COLOR]vboCpuIterator[COLOR=#8000ff] = [/COLOR][COLOR=#ff8000]0[/COLOR][COLOR=#8000ff]; [/COLOR]j[COLOR=#8000ff] < [/COLOR][COLOR=#0000ff]tempMesh[/COLOR][COLOR=#8000ff]->[/COLOR][COLOR=#800080]numVerts[/COLOR][COLOR=#8000ff]; [/COLOR]j[COLOR=#8000ff]++, [/COLOR]vboCpuIterator[COLOR=#8000ff] += [/COLOR][COLOR=#ff8000]16[/COLOR][COLOR=#8000ff] )[/COLOR][/COLOR]
    [COLOR=#8000ff]                    {[/COLOR]
    [COLOR=#008000]//Temp Variables for boneweight and index matrix[/COLOR]
    [COLOR=#8000ff]                        ddeMath::[COLOR=#000080]vec4[/COLOR] [COLOR=#000080]boneIndices[/COLOR] = ddeMath::[COLOR=#000080]vec4[/COLOR]([COLOR=#ff8000]0[/COLOR]);[/COLOR]
    [COLOR=#8000ff]                        ddeMath::[COLOR=#000080]vec4[/COLOR] [COLOR=#000080]boneWeights[/COLOR] = ddeMath::[COLOR=#000080]vec4[/COLOR]([COLOR=#ff8000]0[/COLOR]);[/COLOR]
     
    [COLOR=#8000ff]                        [COLOR=#000080]tempVert[/COLOR] = &[COLOR=#0000ff]tempMesh[/COLOR]->[COLOR=#800080]verts[/COLOR][[COLOR=#000080]j[/COLOR]];[/COLOR]
     
    [COLOR=#8000ff]                        [COLOR=#000080]tempVert[/COLOR]->[COLOR=#800080]pos[/COLOR].[COLOR=#800080]x[/COLOR] = [COLOR=#000080]tempVert[/COLOR]->[COLOR=#800080]pos[/COLOR].[COLOR=#800080]y[/COLOR] = [COLOR=#000080]tempVert[/COLOR]->[COLOR=#800080]pos[/COLOR].[COLOR=#800080]z[/COLOR] = [COLOR=#ff8000]0.0[/COLOR];[/COLOR]
    [COLOR=#8000ff]                        [COLOR=#000080]tempVert[/COLOR]->[COLOR=#800080]n[/COLOR].[COLOR=#800080]x[/COLOR]   = [COLOR=#000080]tempVert[/COLOR]->[COLOR=#800080]n[/COLOR].[COLOR=#800080]y[/COLOR]   = [COLOR=#000080]tempVert[/COLOR]->[COLOR=#800080]n[/COLOR].[COLOR=#800080]z[/COLOR]   = [COLOR=#ff8000]0.0[/COLOR];                             [/COLOR]
     
     
    [COLOR=#8000ff]                        [COLOR=#0000ff]for[/COLOR] ( [COLOR=#000080]ddeInt[/COLOR] [COLOR=#000080]k[/COLOR]=[COLOR=#ff8000]0[/COLOR]; [COLOR=#000080]k[/COLOR] < [COLOR=#000080]tempVert[/COLOR]->[COLOR=#800080]weightCount[/COLOR]; [COLOR=#000080]k[/COLOR]++ )[/COLOR]
    [COLOR=#8000ff]                        {                        [/COLOR]
    [COLOR=#8000ff]                            [COLOR=#000080]tempWeight[/COLOR] =  &[COLOR=#0000ff]tempMesh[/COLOR]->[COLOR=#800080]weights[/COLOR][ [COLOR=#000080]tempVert[/COLOR]->[COLOR=#800080]weightIndex[/COLOR] + [COLOR=#000080]k[/COLOR] ];[/COLOR]
    [COLOR=#8000ff]                            [COLOR=#000080]tempJoint[/COLOR]  =  &[COLOR=#0000ff]tempMesh[/COLOR]->[COLOR=#800080]joints[/COLOR] [ [COLOR=#000080]tempWeight[/COLOR]->[COLOR=#800080]joint[/COLOR]         ];                     [/COLOR]
    [COLOR=#8000ff]                            ddeMath::[COLOR=#000080]quat[/COLOR] [COLOR=#000080]q[/COLOR];[/COLOR]
     
    [COLOR=#8000ff]                            ddeMath::[COLOR=#000080]vec3[/COLOR] [COLOR=#000080]result[/COLOR] = [COLOR=#000080]tempJoint[/COLOR]->[COLOR=#800080]quat[/COLOR] * ddeMath::[COLOR=#000080]vec3[/COLOR]( [COLOR=#000080]tempWeight[/COLOR]->[COLOR=#800080]pos[/COLOR][[COLOR=#ff8000]0[/COLOR]],[/COLOR]
    [COLOR=#8000ff]                                                                                    [COLOR=#000080]tempWeight[/COLOR]->[COLOR=#800080]pos[/COLOR][[COLOR=#ff8000]1[/COLOR]],[/COLOR]
    [COLOR=#8000ff]                                                                                    [COLOR=#000080]tempWeight[/COLOR]->[COLOR=#800080]pos[/COLOR][[COLOR=#ff8000]2[/COLOR]] );[/COLOR]
     
    [COLOR=#000080]tempVert[COLOR=#8000ff]->[/COLOR][COLOR=#800080]pos[/COLOR][COLOR=#8000ff].[/COLOR][COLOR=#800080]x[/COLOR][COLOR=#8000ff] += ( [/COLOR]tempJoint[COLOR=#8000ff]->[/COLOR][COLOR=#800080]pos[/COLOR][COLOR=#8000ff][[/COLOR][COLOR=#ff8000]0[/COLOR][COLOR=#8000ff]] +  [/COLOR]result[COLOR=#8000ff].[/COLOR][COLOR=#800080]x[/COLOR][COLOR=#8000ff] ) * [/COLOR]tempWeight[COLOR=#8000ff]->[/COLOR][COLOR=#800080]w[/COLOR][COLOR=#8000ff];[/COLOR][/COLOR]
    [COLOR=#000080]tempVert[COLOR=#8000ff]->[/COLOR][COLOR=#800080]pos[/COLOR][COLOR=#8000ff].[/COLOR][COLOR=#800080]y[/COLOR][COLOR=#8000ff] += ( [/COLOR]tempJoint[COLOR=#8000ff]->[/COLOR][COLOR=#800080]pos[/COLOR][COLOR=#8000ff][[/COLOR][COLOR=#ff8000]1[/COLOR][COLOR=#8000ff]] +  [/COLOR]result[COLOR=#8000ff].[/COLOR][COLOR=#800080]y[/COLOR][COLOR=#8000ff] ) * [/COLOR]tempWeight[COLOR=#8000ff]->[/COLOR][COLOR=#800080]w[/COLOR][COLOR=#8000ff];[/COLOR][/COLOR]
    [COLOR=#000080]tempVert[COLOR=#8000ff]->[/COLOR][COLOR=#800080]pos[/COLOR][COLOR=#8000ff].[/COLOR][COLOR=#800080]z[/COLOR][COLOR=#8000ff] += ( [/COLOR]tempJoint[COLOR=#8000ff]->[/COLOR][COLOR=#800080]pos[/COLOR][COLOR=#8000ff][[/COLOR][COLOR=#ff8000]2[/COLOR][COLOR=#8000ff]] +  [/COLOR]result[COLOR=#8000ff].[/COLOR][COLOR=#800080]z[/COLOR][COLOR=#8000ff] ) * [/COLOR]tempWeight[COLOR=#8000ff]->[/COLOR][COLOR=#800080]w[/COLOR][COLOR=#8000ff];[/COLOR][/COLOR]
    [COLOR=#000080]boneIndices[COLOR=#8000ff][[/COLOR]k[COLOR=#8000ff]]   = ( [/COLOR][COLOR=#0000ff]float[/COLOR][COLOR=#8000ff] )[/COLOR]tempWeight[COLOR=#8000ff]->[/COLOR][COLOR=#800080]joint[/COLOR][COLOR=#8000ff];[/COLOR][/COLOR]
    [COLOR=#8000ff]                            [COLOR=#000080]boneWeights[/COLOR][[COLOR=#000080]k[/COLOR]]   = [COLOR=#000080]tempWeight[/COLOR]->[COLOR=#800080]w[/COLOR];                        [/COLOR]
    [COLOR=#008000][COLOR=#8000ff]                        } [/COLOR]// for (weights)                [/COLOR]
     
    [COLOR=#008000]// Copy the 3 new vertices to the temporary VBO [/COLOR]
    [COLOR=#000080]currVBOPos[COLOR=#8000ff]    = &[/COLOR]VBOCPU[COLOR=#8000ff][[/COLOR]vboCpuIterator[COLOR=#8000ff]];[/COLOR][/COLOR]
    [COLOR=#000080]currVBOPos[COLOR=#8000ff][[/COLOR][COLOR=#ff8000]0[/COLOR][COLOR=#8000ff]] = [/COLOR]tempVert[COLOR=#8000ff]->[/COLOR][COLOR=#800080]pos[/COLOR][COLOR=#8000ff].[/COLOR][COLOR=#800080]x[/COLOR][COLOR=#8000ff]; [/COLOR][COLOR=#008000]//Vertex Pos0.[/COLOR][/COLOR]
    [COLOR=#000080]currVBOPos[COLOR=#8000ff][[/COLOR][COLOR=#ff8000]1[/COLOR][COLOR=#8000ff]] = [/COLOR]tempVert[COLOR=#8000ff]->[/COLOR][COLOR=#800080]pos[/COLOR][COLOR=#8000ff].[/COLOR][COLOR=#800080]y[/COLOR][COLOR=#8000ff]; [/COLOR][COLOR=#008000]//Vertex Pos1.[/COLOR][/COLOR]
    [COLOR=#000080]currVBOPos[COLOR=#8000ff][[/COLOR][COLOR=#ff8000]2[/COLOR][COLOR=#8000ff]] = [/COLOR]tempVert[COLOR=#8000ff]->[/COLOR][COLOR=#800080]pos[/COLOR][COLOR=#8000ff].[/COLOR][COLOR=#800080]z[/COLOR][COLOR=#8000ff]; [/COLOR][COLOR=#008000]//Vertex Pos2.[/COLOR][/COLOR]
    [COLOR=#8000ff]                        [COLOR=#000080]currVBOPos[/COLOR][[COLOR=#ff8000]3[/COLOR]] = [COLOR=#ff8000]0.0[/COLOR]f;            [COLOR=#008000]//Vertex Pos3 (Dummy).[/COLOR][/COLOR]
     
    [COLOR=#000080]currVBOPos[COLOR=#8000ff][[/COLOR][COLOR=#ff8000]8[/COLOR][COLOR=#8000ff]] = [/COLOR]tempVert[COLOR=#8000ff]->[/COLOR][COLOR=#800080]tc[/COLOR][COLOR=#8000ff].[/COLOR][COLOR=#800080]x[/COLOR][COLOR=#8000ff];  [/COLOR][COLOR=#008000]//Texture Coord 0.[/COLOR][/COLOR]
    [COLOR=#000080]currVBOPos[COLOR=#8000ff][[/COLOR][COLOR=#ff8000]9[/COLOR][COLOR=#8000ff]] = [/COLOR]tempVert[COLOR=#8000ff]->[/COLOR][COLOR=#800080]tc[/COLOR][COLOR=#8000ff].[/COLOR][COLOR=#800080]y[/COLOR][COLOR=#8000ff];  [/COLOR][COLOR=#008000]//Texture Coord 1.[/COLOR][/COLOR]
     
     
    [COLOR=#8000ff]                        [COLOR=#0000ff]#ifdef[/COLOR] DDEDEBUG[/COLOR]
    [COLOR=#008000]//Check for duplicates Verts in the VBO[/COLOR]
    [COLOR=#8000ff]                        ddeCheckCurrVertexVBO( tempVert->pos.x,[/COLOR]
    [COLOR=#8000ff]                                               tempVert->pos.y,[/COLOR]
    [COLOR=#8000ff]                                               tempVert->pos.z,[/COLOR]
    [COLOR=#8000ff]                                               VBOCPU,[/COLOR]
    [COLOR=#8000ff]                                               j,[/COLOR]
    [COLOR=#8000ff]                                               tempMesh->meshName );[/COLOR]
    [COLOR=#8000ff]                        [COLOR=#0000ff]#endif[/COLOR][/COLOR]
     
     
     
    [COLOR=#000080]WeightBuffer[COLOR=#8000ff].[/COLOR][COLOR=#8000ff][U]push_back[/U][/COLOR][COLOR=#8000ff]   ([/COLOR]boneWeights[COLOR=#8000ff]);[/COLOR][/COLOR]
    [COLOR=#000080]BoneIndexBuffer[COLOR=#8000ff].[/COLOR][COLOR=#8000ff][U]push_back[/U][/COLOR][COLOR=#8000ff]([/COLOR]boneIndices[COLOR=#8000ff]);[/COLOR][/COLOR]
    [COLOR=#008000][COLOR=#8000ff]                    } [/COLOR]// for (mesh vertices)[/COLOR]
     
     
     
    [COLOR=#008000]// For each normal, add contribution to normal from every face that vertex [/COLOR]
    [COLOR=#008000]// is part of and also made the first pass for the Tangent Creation[/COLOR]
    [COLOR=#808080][COLOR=#8000ff][U]printf[/U][/COLOR][COLOR=#8000ff]( [/COLOR]"Calculating Normals...\n"[COLOR=#8000ff] );[/COLOR][/COLOR]
    [COLOR=#8000ff]                    [COLOR=#0000ff]for[/COLOR]( [COLOR=#000080]ddeInt[/COLOR] [COLOR=#000080]j[/COLOR] = [COLOR=#ff8000]0[/COLOR]; [COLOR=#000080]j[/COLOR] < [COLOR=#0000ff]tempMesh[/COLOR]->[COLOR=#800080]numTris[/COLOR]; [COLOR=#000080]j[/COLOR]++ )[/COLOR]
    [COLOR=#8000ff]                    {[/COLOR]
    [COLOR=#008000]//Normal Stuff[/COLOR]
    [COLOR=#008000]//Retrieves Vertex from Index List [/COLOR]
    [COLOR=#8000ff]                        [COLOR=#000080]Vertex[/COLOR] *[COLOR=#000080]v0[/COLOR] = &[COLOR=#0000ff]tempMesh[/COLOR]->[COLOR=#800080]verts[/COLOR][ [COLOR=#0000ff]tempMesh[/COLOR]->[COLOR=#800080]tris[/COLOR][[COLOR=#000080]j[/COLOR]].[COLOR=#800080]v[/COLOR][[COLOR=#ff8000]0[/COLOR]] ];[/COLOR]
    [COLOR=#8000ff]                        [COLOR=#000080]Vertex[/COLOR] *[COLOR=#000080]v1[/COLOR] = &[COLOR=#0000ff]tempMesh[/COLOR]->[COLOR=#800080]verts[/COLOR][ [COLOR=#0000ff]tempMesh[/COLOR]->[COLOR=#800080]tris[/COLOR][[COLOR=#000080]j[/COLOR]].[COLOR=#800080]v[/COLOR][[COLOR=#ff8000]1[/COLOR]] ];[/COLOR]
    [COLOR=#8000ff]                        [COLOR=#000080]Vertex[/COLOR] *[COLOR=#000080]v2[/COLOR] = &[COLOR=#0000ff]tempMesh[/COLOR]->[COLOR=#800080]verts[/COLOR][ [COLOR=#0000ff]tempMesh[/COLOR]->[COLOR=#800080]tris[/COLOR][[COLOR=#000080]j[/COLOR]].[COLOR=#800080]v[/COLOR][[COLOR=#ff8000]2[/COLOR]] ];[/COLOR]
     
    [COLOR=#8000ff]                        [COLOR=#0000ff]float[/COLOR] [COLOR=#000080]Ax[/COLOR] = [COLOR=#000080]v1[/COLOR]->[COLOR=#800080]pos[/COLOR][[COLOR=#ff8000]0[/COLOR]] - [COLOR=#000080]v0[/COLOR]->[COLOR=#800080]pos[/COLOR][[COLOR=#ff8000]0[/COLOR]];[/COLOR]
    [COLOR=#8000ff]                        [COLOR=#0000ff]float[/COLOR] [COLOR=#000080]Ay[/COLOR] = [COLOR=#000080]v1[/COLOR]->[COLOR=#800080]pos[/COLOR][[COLOR=#ff8000]1[/COLOR]] - [COLOR=#000080]v0[/COLOR]->[COLOR=#800080]pos[/COLOR][[COLOR=#ff8000]1[/COLOR]];[/COLOR]
    [COLOR=#8000ff]                        [COLOR=#0000ff]float[/COLOR] [COLOR=#000080]Az[/COLOR] = [COLOR=#000080]v1[/COLOR]->[COLOR=#800080]pos[/COLOR][[COLOR=#ff8000]2[/COLOR]] - [COLOR=#000080]v0[/COLOR]->[COLOR=#800080]pos[/COLOR][[COLOR=#ff8000]2[/COLOR]];[/COLOR]
     
    [COLOR=#8000ff]                        [COLOR=#0000ff]float[/COLOR] [COLOR=#000080]Bx[/COLOR] = [COLOR=#000080]v2[/COLOR]->[COLOR=#800080]pos[/COLOR][[COLOR=#ff8000]0[/COLOR]] - [COLOR=#000080]v0[/COLOR]->[COLOR=#800080]pos[/COLOR][[COLOR=#ff8000]0[/COLOR]];[/COLOR]
    [COLOR=#8000ff]                        [COLOR=#0000ff]float[/COLOR] [COLOR=#000080]By[/COLOR] = [COLOR=#000080]v2[/COLOR]->[COLOR=#800080]pos[/COLOR][[COLOR=#ff8000]1[/COLOR]] - [COLOR=#000080]v0[/COLOR]->[COLOR=#800080]pos[/COLOR][[COLOR=#ff8000]1[/COLOR]];[/COLOR]
    [COLOR=#8000ff]                        [COLOR=#0000ff]float[/COLOR] [COLOR=#000080]Bz[/COLOR] = [COLOR=#000080]v2[/COLOR]->[COLOR=#800080]pos[/COLOR][[COLOR=#ff8000]2[/COLOR]] - [COLOR=#000080]v0[/COLOR]->[COLOR=#800080]pos[/COLOR][[COLOR=#ff8000]2[/COLOR]];[/COLOR]
     
    [COLOR=#8000ff]                        [COLOR=#0000ff]float[/COLOR] [COLOR=#000080]nx[/COLOR] =   [COLOR=#000080]Ay[/COLOR] * [COLOR=#000080]Bz[/COLOR] - [COLOR=#000080]By[/COLOR] * [COLOR=#000080]Az[/COLOR];[/COLOR]
    [COLOR=#8000ff]                        [COLOR=#0000ff]float[/COLOR] [COLOR=#000080]ny[/COLOR] = -([COLOR=#000080]Ax[/COLOR] * [COLOR=#000080]Bz[/COLOR] - [COLOR=#000080]Bx[/COLOR] * [COLOR=#000080]Az[/COLOR]);[/COLOR]
    [COLOR=#8000ff]                        [COLOR=#0000ff]float[/COLOR] [COLOR=#000080]nz[/COLOR] =   [COLOR=#000080]Ax[/COLOR] * [COLOR=#000080]By[/COLOR] - [COLOR=#000080]Bx[/COLOR] * [COLOR=#000080]Ay[/COLOR];[/COLOR]
     
    [COLOR=#8000ff]                        [COLOR=#000080]v0[/COLOR]->[COLOR=#800080]n[/COLOR][[COLOR=#ff8000]0[/COLOR]] += [COLOR=#000080]nx[/COLOR];[/COLOR]
    [COLOR=#8000ff]                        [COLOR=#000080]v0[/COLOR]->[COLOR=#800080]n[/COLOR][[COLOR=#ff8000]1[/COLOR]] += [COLOR=#000080]ny[/COLOR];[/COLOR]
    [COLOR=#8000ff]                        [COLOR=#000080]v0[/COLOR]->[COLOR=#800080]n[/COLOR][[COLOR=#ff8000]2[/COLOR]] += [COLOR=#000080]nz[/COLOR];[/COLOR]
     
    [COLOR=#8000ff]                        [COLOR=#000080]v1[/COLOR]->[COLOR=#800080]n[/COLOR][[COLOR=#ff8000]0[/COLOR]] += [COLOR=#000080]nx[/COLOR];[/COLOR]
    [COLOR=#8000ff]                        [COLOR=#000080]v1[/COLOR]->[COLOR=#800080]n[/COLOR][[COLOR=#ff8000]1[/COLOR]] += [COLOR=#000080]ny[/COLOR];[/COLOR]
    [COLOR=#8000ff]                        [COLOR=#000080]v1[/COLOR]->[COLOR=#800080]n[/COLOR][[COLOR=#ff8000]2[/COLOR]] += [COLOR=#000080]nz[/COLOR];[/COLOR]
     
    [COLOR=#8000ff]                        [COLOR=#000080]v2[/COLOR]->[COLOR=#800080]n[/COLOR][[COLOR=#ff8000]0[/COLOR]] += [COLOR=#000080]nx[/COLOR];[/COLOR]
    [COLOR=#8000ff]                        [COLOR=#000080]v2[/COLOR]->[COLOR=#800080]n[/COLOR][[COLOR=#ff8000]1[/COLOR]] += [COLOR=#000080]ny[/COLOR];[/COLOR]
    [COLOR=#8000ff]                        [COLOR=#000080]v2[/COLOR]->[COLOR=#800080]n[/COLOR][[COLOR=#ff8000]2[/COLOR]] += [COLOR=#000080]nz[/COLOR];[/COLOR]
    [COLOR=#8000ff]                    }[/COLOR]
     
     
    [COLOR=#808080][COLOR=#8000ff][U]printf[/U][/COLOR][COLOR=#8000ff]( [/COLOR]"Calculating First Pass Tangent...\n"[COLOR=#8000ff] );[/COLOR][/COLOR]
    [COLOR=#8000ff]                    [COLOR=#0000ff]for[/COLOR]( [COLOR=#000080]ddeInt[/COLOR] [COLOR=#000080]j[/COLOR] = [COLOR=#ff8000]0[/COLOR]; [COLOR=#000080]j[/COLOR] < [COLOR=#0000ff]tempMesh[/COLOR]->[COLOR=#800080]numTris[/COLOR]; [COLOR=#000080]j[/COLOR]++ )[/COLOR]
    [COLOR=#8000ff]                    {[/COLOR]
    [COLOR=#008000]//Tangent Stuff[/COLOR]
    [COLOR=#008000]//Retrieve Triangle from Index List[/COLOR]
    [COLOR=#8000ff]                        [COLOR=#000080]ddeLong[/COLOR] [COLOR=#000080]i1[/COLOR] = [COLOR=#0000ff]tempMesh[/COLOR]->[COLOR=#800080]tris[/COLOR][[COLOR=#000080]j[/COLOR]].[COLOR=#800080]v[/COLOR][[COLOR=#ff8000]0[/COLOR]];[/COLOR]
    [COLOR=#8000ff]                        [COLOR=#000080]ddeLong[/COLOR] [COLOR=#000080]i2[/COLOR] = [COLOR=#0000ff]tempMesh[/COLOR]->[COLOR=#800080]tris[/COLOR][[COLOR=#000080]j[/COLOR]].[COLOR=#800080]v[/COLOR][[COLOR=#ff8000]1[/COLOR]];[/COLOR]
    [COLOR=#8000ff]                        [COLOR=#000080]ddeLong[/COLOR] [COLOR=#000080]i3[/COLOR] = [COLOR=#0000ff]tempMesh[/COLOR]->[COLOR=#800080]tris[/COLOR][[COLOR=#000080]j[/COLOR]].[COLOR=#800080]v[/COLOR][[COLOR=#ff8000]2[/COLOR]];[/COLOR]
     
     
    [COLOR=#008000]//Fill the 3 Verts of the triangle[/COLOR]
    [COLOR=#8000ff]                        ddeMath::[COLOR=#000080]vec3[/COLOR] [COLOR=#000080]vert1[/COLOR] = ddeMath::[COLOR=#000080]vec3[/COLOR]( [COLOR=#0000ff]tempMesh[/COLOR]->[COLOR=#800080]verts[/COLOR][[COLOR=#000080]i1[/COLOR]].[COLOR=#800080]pos[/COLOR][[COLOR=#ff8000]0[/COLOR]],[/COLOR]
    [COLOR=#8000ff]                                                             [COLOR=#0000ff]tempMesh[/COLOR]->[COLOR=#800080]verts[/COLOR][[COLOR=#000080]i1[/COLOR]].[COLOR=#800080]pos[/COLOR][[COLOR=#ff8000]1[/COLOR]],[/COLOR]
    [COLOR=#8000ff]                                                             [COLOR=#0000ff]tempMesh[/COLOR]->[COLOR=#800080]verts[/COLOR][[COLOR=#000080]i1[/COLOR]].[COLOR=#800080]pos[/COLOR][[COLOR=#ff8000]2[/COLOR]] );[/COLOR]
     
     
    [COLOR=#8000ff]                        ddeMath::[COLOR=#000080]vec3[/COLOR] [COLOR=#000080]vert2[/COLOR] = ddeMath::[COLOR=#000080]vec3[/COLOR]( [COLOR=#0000ff]tempMesh[/COLOR]->[COLOR=#800080]verts[/COLOR][[COLOR=#000080]i2[/COLOR]].[COLOR=#800080]pos[/COLOR][[COLOR=#ff8000]0[/COLOR]],[/COLOR]
    [COLOR=#8000ff]                                                             [COLOR=#0000ff]tempMesh[/COLOR]->[COLOR=#800080]verts[/COLOR][[COLOR=#000080]i2[/COLOR]].[COLOR=#800080]pos[/COLOR][[COLOR=#ff8000]1[/COLOR]],[/COLOR]
    [COLOR=#8000ff]                                                             [COLOR=#0000ff]tempMesh[/COLOR]->[COLOR=#800080]verts[/COLOR][[COLOR=#000080]i2[/COLOR]].[COLOR=#800080]pos[/COLOR][[COLOR=#ff8000]2[/COLOR]] );[/COLOR]
     
     
    [COLOR=#8000ff]                        ddeMath::[COLOR=#000080]vec3[/COLOR] [COLOR=#000080]vert3[/COLOR] = ddeMath::[COLOR=#000080]vec3[/COLOR]( [COLOR=#0000ff]tempMesh[/COLOR]->[COLOR=#800080]verts[/COLOR][[COLOR=#000080]i3[/COLOR]].[COLOR=#800080]pos[/COLOR][[COLOR=#ff8000]0[/COLOR]],[/COLOR]
    [COLOR=#8000ff]                                                             [COLOR=#0000ff]tempMesh[/COLOR]->[COLOR=#800080]verts[/COLOR][[COLOR=#000080]i3[/COLOR]].[COLOR=#800080]pos[/COLOR][[COLOR=#ff8000]1[/COLOR]],[/COLOR]
    [COLOR=#8000ff]                                                             [COLOR=#0000ff]tempMesh[/COLOR]->[COLOR=#800080]verts[/COLOR][[COLOR=#000080]i3[/COLOR]].[COLOR=#800080]pos[/COLOR][[COLOR=#ff8000]2[/COLOR]] );[/COLOR]
     
     
    [COLOR=#008000]//Fill the 3 Texture Coords of each Vertex[/COLOR]
    [COLOR=#8000ff]                        ddeMath::[COLOR=#000080]vec2[/COLOR] [COLOR=#000080]tc1[/COLOR] = ddeMath::[COLOR=#000080]vec2[/COLOR]( [COLOR=#0000ff]tempMesh[/COLOR]->[COLOR=#800080]verts[/COLOR][[COLOR=#000080]i1[/COLOR]].[COLOR=#800080]tc[/COLOR][[COLOR=#ff8000]0[/COLOR]],[/COLOR]
    [COLOR=#8000ff]                                                           [COLOR=#0000ff]tempMesh[/COLOR]->[COLOR=#800080]verts[/COLOR][[COLOR=#000080]i1[/COLOR]].[COLOR=#800080]tc[/COLOR][[COLOR=#ff8000]1[/COLOR]] );[/COLOR]
     
     
    [COLOR=#8000ff]                        ddeMath::[COLOR=#000080]vec2[/COLOR] [COLOR=#000080]tc2[/COLOR] = ddeMath::[COLOR=#000080]vec2[/COLOR]( [COLOR=#0000ff]tempMesh[/COLOR]->[COLOR=#800080]verts[/COLOR][[COLOR=#000080]i2[/COLOR]].[COLOR=#800080]tc[/COLOR][[COLOR=#ff8000]0[/COLOR]],[/COLOR]
    [COLOR=#8000ff]                                                           [COLOR=#0000ff]tempMesh[/COLOR]->[COLOR=#800080]verts[/COLOR][[COLOR=#000080]i2[/COLOR]].[COLOR=#800080]tc[/COLOR][[COLOR=#ff8000]1[/COLOR]] );[/COLOR]
     
     
    [COLOR=#8000ff]                        ddeMath::[COLOR=#000080]vec2[/COLOR] [COLOR=#000080]tc3[/COLOR] = ddeMath::[COLOR=#000080]vec2[/COLOR]( [COLOR=#0000ff]tempMesh[/COLOR]->[COLOR=#800080]verts[/COLOR][[COLOR=#000080]i3[/COLOR]].[COLOR=#800080]tc[/COLOR][[COLOR=#ff8000]0[/COLOR]],[/COLOR]
    [COLOR=#8000ff]                                                            [COLOR=#0000ff]tempMesh[/COLOR]->[COLOR=#800080]verts[/COLOR][[COLOR=#000080]i3[/COLOR]].[COLOR=#800080]tc[/COLOR][[COLOR=#ff8000]1[/COLOR]] );[/COLOR]
     
     
    [COLOR=#008000]//Calculate the Tangent[/COLOR]
    [COLOR=#000080]ddeFloatx1[COLOR=#8000ff] = [/COLOR]vert2[COLOR=#8000ff].[/COLOR][COLOR=#800080]x[/COLOR][COLOR=#8000ff] - [/COLOR]vert1[COLOR=#8000ff].[/COLOR][COLOR=#800080]x[/COLOR][COLOR=#8000ff];[/COLOR][/COLOR]
    [COLOR=#000080]ddeFloatx2[COLOR=#8000ff] = [/COLOR]vert3[COLOR=#8000ff].[/COLOR][COLOR=#800080]x[/COLOR][COLOR=#8000ff] - [/COLOR]vert1[COLOR=#8000ff].[/COLOR][COLOR=#800080]x[/COLOR][COLOR=#8000ff];[/COLOR][/COLOR]
    [COLOR=#000080]ddeFloaty1[COLOR=#8000ff] = [/COLOR]vert2[COLOR=#8000ff].[/COLOR][COLOR=#800080]y[/COLOR][COLOR=#8000ff] - [/COLOR]vert1[COLOR=#8000ff].[/COLOR][COLOR=#800080]y[/COLOR][COLOR=#8000ff];[/COLOR][/COLOR]
    [COLOR=#000080]ddeFloaty2[COLOR=#8000ff] = [/COLOR]vert3[COLOR=#8000ff].[/COLOR][COLOR=#800080]y[/COLOR][COLOR=#8000ff] - [/COLOR]vert1[COLOR=#8000ff].[/COLOR][COLOR=#800080]y[/COLOR][COLOR=#8000ff];[/COLOR][/COLOR]
    [COLOR=#000080]ddeFloatz1[COLOR=#8000ff] = [/COLOR]vert2[COLOR=#8000ff].[/COLOR][COLOR=#800080]z[/COLOR][COLOR=#8000ff] - [/COLOR]vert1[COLOR=#8000ff].[/COLOR][COLOR=#800080]z[/COLOR][COLOR=#8000ff];[/COLOR][/COLOR]
    [COLOR=#000080]ddeFloatz2[COLOR=#8000ff] = [/COLOR]vert3[COLOR=#8000ff].[/COLOR][COLOR=#800080]z[/COLOR][COLOR=#8000ff] - [/COLOR]vert1[COLOR=#8000ff].[/COLOR][COLOR=#800080]z[/COLOR][COLOR=#8000ff];[/COLOR][/COLOR]
     
     
    [COLOR=#000080]ddeFloats1[COLOR=#8000ff] = [/COLOR]tc2[COLOR=#8000ff].[/COLOR][COLOR=#800080]x[/COLOR][COLOR=#8000ff] - [/COLOR]tc1[COLOR=#8000ff].[/COLOR][COLOR=#800080]x[/COLOR][COLOR=#8000ff];[/COLOR][/COLOR]
    [COLOR=#000080]ddeFloats2[COLOR=#8000ff] = [/COLOR]tc3[COLOR=#8000ff].[/COLOR][COLOR=#800080]x[/COLOR][COLOR=#8000ff] - [/COLOR]tc1[COLOR=#8000ff].[/COLOR][COLOR=#800080]x[/COLOR][COLOR=#8000ff];[/COLOR][/COLOR]
    [COLOR=#000080]ddeFloatt1[COLOR=#8000ff] = [/COLOR]tc2[COLOR=#8000ff].[/COLOR][COLOR=#800080]y[/COLOR][COLOR=#8000ff] - [/COLOR]tc1[COLOR=#8000ff].[/COLOR][COLOR=#800080]y[/COLOR][COLOR=#8000ff];[/COLOR][/COLOR]
    [COLOR=#000080]ddeFloatt2[COLOR=#8000ff] = [/COLOR]tc3[COLOR=#8000ff].[/COLOR][COLOR=#800080]y[/COLOR][COLOR=#8000ff] - [/COLOR]tc1[COLOR=#8000ff].[/COLOR][COLOR=#800080]y[/COLOR][COLOR=#8000ff];[/COLOR][/COLOR]
     
     
    [COLOR=#8000ff]                        [COLOR=#000080]ddeFloat[/COLOR] [COLOR=#000080]r[/COLOR] = [COLOR=#ff8000]1.0[/COLOR]f / ([COLOR=#000080]s1[/COLOR] * [COLOR=#000080]t2[/COLOR] - [COLOR=#000080]s2[/COLOR] * [COLOR=#000080]t1[/COLOR]);[/COLOR]
     
     
    [COLOR=#8000ff]                        ddeMath::[COLOR=#000080]vec3[/COLOR] [COLOR=#000080]sdir[/COLOR] = ddeMath::[COLOR=#000080]vec3[/COLOR]( ( [COLOR=#000080]t2[/COLOR] * [COLOR=#000080]x1[/COLOR] - [COLOR=#000080]t1[/COLOR] * [COLOR=#000080]x2[/COLOR] ) * [COLOR=#000080]r[/COLOR],[/COLOR]
    [COLOR=#8000ff]                                                            ( [COLOR=#000080]t2[/COLOR] * [COLOR=#000080]y1[/COLOR] - [COLOR=#000080]t1[/COLOR] * [COLOR=#000080]y2[/COLOR] ) * [COLOR=#000080]r[/COLOR],[/COLOR]
    [COLOR=#8000ff]                                                            ( [COLOR=#000080]t2[/COLOR] * [COLOR=#000080]z1[/COLOR] - [COLOR=#000080]t1[/COLOR] * [COLOR=#000080]z2[/COLOR] ) * [COLOR=#000080]r[/COLOR] );[/COLOR]
     
     
    [COLOR=#8000ff]                        ddeMath::[COLOR=#000080]vec3[/COLOR] [COLOR=#000080]tdir[/COLOR] = ddeMath::[COLOR=#000080]vec3[/COLOR]( ( [COLOR=#000080]s1[/COLOR] * [COLOR=#000080]x2[/COLOR] - [COLOR=#000080]s2[/COLOR] * [COLOR=#000080]x1[/COLOR] ) * [COLOR=#000080]r[/COLOR],[/COLOR]
    [COLOR=#8000ff]                                                            ( [COLOR=#000080]s1[/COLOR] * [COLOR=#000080]y2[/COLOR] - [COLOR=#000080]s2[/COLOR] * [COLOR=#000080]y1[/COLOR] ) * [COLOR=#000080]r[/COLOR],[/COLOR]
    [COLOR=#8000ff]                                                            ( [COLOR=#000080]s1[/COLOR] * [COLOR=#000080]z2[/COLOR] - [COLOR=#000080]s2[/COLOR] * [COLOR=#000080]z1[/COLOR] ) * [COLOR=#000080]r[/COLOR] );[/COLOR]
     
     
    [COLOR=#008000]//Add the result for each tangent[/COLOR]
    [COLOR=#8000ff]                        [COLOR=#000080]tan1[/COLOR][[COLOR=#000080]i1[/COLOR]] += [COLOR=#000080]sdir[/COLOR]; [COLOR=#000080]tan2[/COLOR][[COLOR=#000080]i1[/COLOR]] += [COLOR=#000080]tdir[/COLOR];[/COLOR]
    [COLOR=#8000ff]                        [COLOR=#000080]tan2[/COLOR][[COLOR=#000080]i2[/COLOR]] += [COLOR=#000080]sdir[/COLOR]; [COLOR=#000080]tan2[/COLOR][[COLOR=#000080]i2[/COLOR]] += [COLOR=#000080]tdir[/COLOR];[/COLOR]
    [COLOR=#8000ff]                        [COLOR=#000080]tan2[/COLOR][[COLOR=#000080]i3[/COLOR]] += [COLOR=#000080]sdir[/COLOR]; [COLOR=#000080]tan2[/COLOR][[COLOR=#000080]i3[/COLOR]] += [COLOR=#000080]tdir[/COLOR];[/COLOR]
    [COLOR=#8000ff]                    }[/COLOR]
     
    [COLOR=#008000]// Normalize each normal && Calculate Final Tangent and BiNormal[/COLOR]
    [COLOR=#808080][COLOR=#8000ff][U]printf[/U][/COLOR][COLOR=#8000ff]( [/COLOR]"Filling Normal - Tangent - BiNormal...\n"[COLOR=#8000ff] );[/COLOR][/COLOR]
    [COLOR=#000080][COLOR=#0000ff]for[/COLOR][COLOR=#8000ff]( [/COLOR]ddeIntj[COLOR=#8000ff] = [/COLOR][COLOR=#ff8000]0[/COLOR][COLOR=#8000ff], [/COLOR]vboCpuIterator[COLOR=#8000ff] = [/COLOR][COLOR=#ff8000]0[/COLOR][COLOR=#8000ff]; [/COLOR]j[COLOR=#8000ff] < [/COLOR][COLOR=#0000ff]tempMesh[/COLOR][COLOR=#8000ff]->[/COLOR][COLOR=#800080]numVerts[/COLOR][COLOR=#8000ff]; [/COLOR]j[COLOR=#8000ff]++, [/COLOR]vboCpuIterator[COLOR=#8000ff] += [/COLOR][COLOR=#ff8000]16[/COLOR][COLOR=#8000ff] )[/COLOR][/COLOR]
    [COLOR=#8000ff]                    {[/COLOR]
    [COLOR=#8000ff]                        [COLOR=#000080]Vertex[/COLOR] *[COLOR=#000080]v[/COLOR] = &[COLOR=#0000ff]tempMesh[/COLOR]->[COLOR=#800080]verts[/COLOR][[COLOR=#000080]j[/COLOR]];[/COLOR]
     
    [COLOR=#8000ff]                        [COLOR=#0000ff]float[/COLOR] [COLOR=#000080]mag[/COLOR] = ([COLOR=#0000ff]float[/COLOR])[U]sqrt[/U]( [COLOR=#0000ff]float[/COLOR]( [COLOR=#000080]v[/COLOR]->[COLOR=#800080]n[/COLOR][[COLOR=#ff8000]0[/COLOR]] * [COLOR=#000080]v[/COLOR]->[COLOR=#800080]n[/COLOR][[COLOR=#ff8000]0[/COLOR]] + [COLOR=#000080]v[/COLOR]->[COLOR=#800080]n[/COLOR][[COLOR=#ff8000]1[/COLOR]] * [COLOR=#000080]v[/COLOR]->[COLOR=#800080]n[/COLOR][[COLOR=#ff8000]1[/COLOR]] + [COLOR=#000080]v[/COLOR]->[COLOR=#800080]n[/COLOR][[COLOR=#ff8000]2[/COLOR]] * [COLOR=#000080]v[/COLOR]->[COLOR=#800080]n[/COLOR][[COLOR=#ff8000]2[/COLOR]] ) );[/COLOR]
     
    [COLOR=#008000]// Avoid Division By Zero  [/COLOR]
    [COLOR=#8000ff]                        [COLOR=#0000ff]if[/COLOR] ( [COLOR=#000080]mag[/COLOR] > [COLOR=#ff8000]0.0001[/COLOR]f ) [/COLOR]
    [COLOR=#8000ff]                        {[/COLOR]
    [COLOR=#8000ff]                            [COLOR=#000080]v[/COLOR]->[COLOR=#800080]n[/COLOR][[COLOR=#ff8000]0[/COLOR]] /= [COLOR=#000080]mag[/COLOR];[/COLOR]
    [COLOR=#8000ff]                            [COLOR=#000080]v[/COLOR]->[COLOR=#800080]n[/COLOR][[COLOR=#ff8000]1[/COLOR]] /= [COLOR=#000080]mag[/COLOR];[/COLOR]
    [COLOR=#8000ff]                            [COLOR=#000080]v[/COLOR]->[COLOR=#800080]n[/COLOR][[COLOR=#ff8000]2[/COLOR]] /= [COLOR=#000080]mag[/COLOR];[/COLOR]
    [COLOR=#8000ff]                        }[/COLOR]
     
    [COLOR=#008000]//Finish Tangent and Binormal Calculations[/COLOR]
    [COLOR=#8000ff]                        ddeMath::[COLOR=#000080]vec3[/COLOR] [COLOR=#000080]tmpNormal[/COLOR] = ddeMath::[COLOR=#000080]vec3[/COLOR]( [COLOR=#000080]v[/COLOR]->[COLOR=#800080]n[/COLOR][[COLOR=#ff8000]0[/COLOR]], [COLOR=#000080]v[/COLOR]->[COLOR=#800080]n[/COLOR][[COLOR=#ff8000]1[/COLOR]], [COLOR=#000080]v[/COLOR]->[COLOR=#800080]n[/COLOR][[COLOR=#ff8000]2[/COLOR]] );[/COLOR]
    [COLOR=#8000ff]                        ddeMath::[COLOR=#000080]vec3[/COLOR] [COLOR=#000080]tmpTan[/COLOR];[/COLOR]
     
     
    [COLOR=#8000ff]                        ( ddeMath::[COLOR=#ff00ff]dot[/COLOR]( ddeMath::[COLOR=#ff00ff]cross[/COLOR]( [COLOR=#000080]tmpNormal[/COLOR], [COLOR=#000080]tan1[/COLOR][[COLOR=#000080]j[/COLOR]] ), [COLOR=#000080]tan2[/COLOR][[COLOR=#000080]j[/COLOR]] ) < [COLOR=#ff8000]0.0[/COLOR]f) ?  [COLOR=#000080]tmpTan[/COLOR] = [COLOR=#000080]tan1[/COLOR][[COLOR=#000080]j[/COLOR]][/COLOR]
    [COLOR=#8000ff]                                                                                                 : [COLOR=#000080]tmpTan[/COLOR] = [COLOR=#000080]tan2[/COLOR][[COLOR=#000080]j[/COLOR]];[/COLOR]
     
    [COLOR=#8000ff]                        ddeMath::[COLOR=#ff00ff]orthonormalize[/COLOR]( [COLOR=#000080]tmpNormal[/COLOR], [COLOR=#000080]tmpTan[/COLOR] );
    [/COLOR]
    [COLOR=#8000ff]                        ddeMath::[COLOR=#000080]vec3[/COLOR] [COLOR=#000080]resultTan[/COLOR] = [COLOR=#000080]tmpTan[/COLOR];
    [/COLOR]
    [COLOR=#8000ff]                        ddeMath::[COLOR=#000080]vec3[/COLOR] [COLOR=#000080]biNormal[/COLOR] = ddeMath::[COLOR=#ff00ff]cross[/COLOR]( [COLOR=#000080]tmpTan[/COLOR], [COLOR=#000080]tmpNormal[/COLOR]  );[/COLOR]
     
    [COLOR=#008000]// Now save Normals in the VBO Array  [/COLOR]
    [COLOR=#000080]currVBOPos[COLOR=#8000ff]    = &[/COLOR]VBOCPU[COLOR=#8000ff][[/COLOR]vboCpuIterator[COLOR=#8000ff]];[/COLOR][/COLOR]
    [COLOR=#8000ff]                        [COLOR=#000080]currVBOPos[/COLOR][[COLOR=#ff8000]4[/COLOR]] = [COLOR=#000080]v[/COLOR]->[COLOR=#800080]n[/COLOR][[COLOR=#ff8000]0[/COLOR]]; [COLOR=#008000]//Normal 0.  [/COLOR][/COLOR]
    [COLOR=#8000ff]                        [COLOR=#000080]currVBOPos[/COLOR][[COLOR=#ff8000]5[/COLOR]] = [COLOR=#000080]v[/COLOR]->[COLOR=#800080]n[/COLOR][[COLOR=#ff8000]1[/COLOR]]; [COLOR=#008000]//Normal 1.[/COLOR][/COLOR]
    [COLOR=#8000ff]                        [COLOR=#000080]currVBOPos[/COLOR][[COLOR=#ff8000]6[/COLOR]] = [COLOR=#000080]v[/COLOR]->[COLOR=#800080]n[/COLOR][[COLOR=#ff8000]2[/COLOR]]; [COLOR=#008000]//Normal 2.[/COLOR][/COLOR]
    [COLOR=#008000][COLOR=#000080]currVBOPos[/COLOR][COLOR=#8000ff][[/COLOR][COLOR=#ff8000]7[/COLOR][COLOR=#8000ff]] = [/COLOR][COLOR=#ff8000]0.0[/COLOR][COLOR=#8000ff]f;    [/COLOR]//Normal 3. (Dummy).[/COLOR]
     
    [COLOR=#000080]currVBOPos[COLOR=#8000ff][[/COLOR][COLOR=#ff8000]10[/COLOR][COLOR=#8000ff]] = [/COLOR]tmpTan[COLOR=#8000ff].[/COLOR][COLOR=#800080]x[/COLOR][COLOR=#8000ff];   [/COLOR][COLOR=#008000]//Tangent x.[/COLOR][/COLOR]
    [COLOR=#000080]currVBOPos[COLOR=#8000ff][[/COLOR][COLOR=#ff8000]11[/COLOR][COLOR=#8000ff]] = [/COLOR]tmpTan[COLOR=#8000ff].[/COLOR][COLOR=#800080]y[/COLOR][COLOR=#8000ff];   [/COLOR][COLOR=#008000]//Tangent y.[/COLOR][/COLOR]
    [COLOR=#000080]currVBOPos[COLOR=#8000ff][[/COLOR][COLOR=#ff8000]12[/COLOR][COLOR=#8000ff]] = [/COLOR]tmpTan[COLOR=#8000ff].[/COLOR][COLOR=#800080]z[/COLOR][COLOR=#8000ff];   [/COLOR][COLOR=#008000]//Tangent z.[/COLOR][/COLOR]
     
    [COLOR=#000080]currVBOPos[COLOR=#8000ff][[/COLOR][COLOR=#ff8000]13[/COLOR][COLOR=#8000ff]] = [/COLOR]biNormal[COLOR=#8000ff].[/COLOR][COLOR=#800080]x[/COLOR][COLOR=#8000ff]; [/COLOR][COLOR=#008000]//Binormal x.[/COLOR][/COLOR]
    [COLOR=#000080]currVBOPos[COLOR=#8000ff][[/COLOR][COLOR=#ff8000]14[/COLOR][COLOR=#8000ff]] = [/COLOR]biNormal[COLOR=#8000ff].[/COLOR][COLOR=#800080]y[/COLOR][COLOR=#8000ff]; [/COLOR][COLOR=#008000]//Binormal y.[/COLOR][/COLOR]
    [COLOR=#000080]currVBOPos[COLOR=#8000ff][[/COLOR][COLOR=#ff8000]15[/COLOR][COLOR=#8000ff]] = [/COLOR]biNormal[COLOR=#8000ff].[/COLOR][COLOR=#800080]z[/COLOR][COLOR=#8000ff]; [/COLOR][COLOR=#008000]//Binormal z.[/COLOR][/COLOR]
    [COLOR=#8000ff]                    }                 [/COLOR]
     
     
    [COLOR=#008000]// Creates a new Vertex Buffer Object for Mesh, Normals and TexCoords && Populate it [/COLOR]
    [COLOR=#8000ff]                    glGenBuffersARB( [COLOR=#ff8000]1[/COLOR], &( [COLOR=#0000ff]tempMesh[/COLOR]->[COLOR=#800080]V_N_TC_VBO[/COLOR] ) );[/COLOR]
    [COLOR=#8000ff]                    glBindBufferARB( GL_ARRAY_BUFFER_ARB, [COLOR=#0000ff]tempMesh[/COLOR]->[COLOR=#800080]V_N_TC_VBO[/COLOR] );[/COLOR]
    [COLOR=#8000ff]                    glBufferDataARB( GL_ARRAY_BUFFER_ARB, ( ( [COLOR=#0000ff]tempMesh[/COLOR]->[COLOR=#800080]numVerts[/COLOR] * [COLOR=#ff8000]16[/COLOR] ) * [COLOR=#0000ff]sizeof[/COLOR]( [COLOR=#000080]GLfloat[/COLOR] ) ), [COLOR=#000080]VBOCPU[/COLOR],[/COLOR]
    [COLOR=#8000ff]                                                          GL_STATIC_DRAW_ARB                                         );[/COLOR]
     
    [COLOR=#008000]// Create a Buffer for the Bone Weights  [/COLOR]
    [COLOR=#8000ff]                    glGenBuffersARB( [COLOR=#ff8000]1[/COLOR], &( [COLOR=#0000ff]tempMesh[/COLOR]->[COLOR=#800080]BWEIGHT_VBO[/COLOR] ) );[/COLOR]
    [COLOR=#8000ff]                    glBindBufferARB( GL_ARRAY_BUFFER_ARB, [COLOR=#0000ff]tempMesh[/COLOR]->[COLOR=#800080]BWEIGHT_VBO[/COLOR] );[/COLOR]
    [COLOR=#8000ff]                    glBufferDataARB( GL_ARRAY_BUFFER_ARB, [COLOR=#0000ff]sizeof[/COLOR]( ddeMath::[COLOR=#000080]vec4[/COLOR] ) * [COLOR=#0000ff]tempMesh[/COLOR]->[COLOR=#800080]numVerts[/COLOR], &( [COLOR=#000080]WeightBuffer[/COLOR][[COLOR=#ff8000]0[/COLOR]] ),[/COLOR]
    [COLOR=#8000ff]                                                          GL_STATIC_DRAW_ARB                                              );[/COLOR]
     
    [COLOR=#008000]// Create a Buffer for the Bone Weights  [/COLOR]
    [COLOR=#8000ff]                    glGenBuffersARB( [COLOR=#ff8000]1[/COLOR], &( [COLOR=#0000ff]tempMesh[/COLOR]->[COLOR=#800080]BINDEX_VBO[/COLOR] ) );[/COLOR]
    [COLOR=#8000ff]                    glBindBufferARB( GL_ARRAY_BUFFER_ARB, [COLOR=#0000ff]tempMesh[/COLOR]->[COLOR=#800080]BINDEX_VBO[/COLOR] );[/COLOR]
    [COLOR=#8000ff]                    glBufferDataARB( GL_ARRAY_BUFFER_ARB, [COLOR=#0000ff]sizeof[/COLOR]( ddeMath::[COLOR=#000080]vec4[/COLOR] ) * [COLOR=#0000ff]tempMesh[/COLOR]->[COLOR=#800080]numVerts[/COLOR], &( [COLOR=#000080]BoneIndexBuffer[/COLOR][[COLOR=#ff8000]0[/COLOR]] ),[/COLOR]
    [COLOR=#8000ff]                                                          GL_STATIC_DRAW_ARB                                                    );[/COLOR]
     
    [COLOR=#008000]// Disables VBO Buffer  [/COLOR]
    [COLOR=#8000ff]                    glBindBufferARB( GL_ARRAY_BUFFER_ARB, [COLOR=#ff8000]0[/COLOR] );[/COLOR]
     
    [COLOR=#008000]// Also creates a Vertex Buffer Object for the Triagle List  [/COLOR]
    [COLOR=#8000ff]                    glGenBuffersARB( [COLOR=#ff8000]1[/COLOR], &( [COLOR=#0000ff]tempMesh[/COLOR]->[COLOR=#800080]T_VBO[/COLOR] )                  );[/COLOR]
    [COLOR=#8000ff]                    glBindBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB, [COLOR=#0000ff]tempMesh[/COLOR]->[COLOR=#800080]T_VBO[/COLOR] );[/COLOR]
     
    [COLOR=#008000]// At last we Populate the VBO  [/COLOR]
    [COLOR=#8000ff]                    glBufferDataARB( GL_ELEMENT_ARRAY_BUFFER_ARB, ( ( [COLOR=#0000ff]tempMesh[/COLOR]->[COLOR=#800080]numTris[/COLOR] * [COLOR=#ff8000]3[/COLOR] ) * [COLOR=#0000ff]sizeof[/COLOR]( [COLOR=#000080]GLfloat[/COLOR] ) ),[/COLOR]
    [COLOR=#8000ff]                                                                  [COLOR=#0000ff]tempMesh[/COLOR]->[COLOR=#800080]tris[/COLOR], GL_STATIC_DRAW_ARB                );[/COLOR]
     
     
    [COLOR=#008000]// Disables VBO Buffer  [/COLOR]
    [COLOR=#8000ff]                    glBindBufferARB( GL_ELEMENT_ARRAY_BUFFER_ARB, [COLOR=#ff8000]0[/COLOR] );[/COLOR]
    [COLOR=#0000ff]tempMesh[COLOR=#8000ff]->[/COLOR][COLOR=#800080]isSkinned[/COLOR][COLOR=#8000ff] = [/COLOR]true[COLOR=#8000ff];[/COLOR][/COLOR]
     
    [COLOR=#008000]//CheckError();[/COLOR]
     
    [COLOR=#008000]// Free the temporaries VBOs [/COLOR]
    [COLOR=#8000ff]                    [U]free[/U]( [COLOR=#000080]VBOCPU[/COLOR] );                                [/COLOR]
     
    [COLOR=#008000]//TESTING PURPOSE//[/COLOR]
    [COLOR=#8000ff]                    [U]free[/U]( [COLOR=#0000ff]tempMesh[/COLOR]->[COLOR=#800080]verts[/COLOR]   );[/COLOR]
    [COLOR=#8000ff]                    [U]free[/U]( [COLOR=#0000ff]tempMesh[/COLOR]->[COLOR=#800080]tris[/COLOR]    );[/COLOR]
    [COLOR=#8000ff]                    [U]free[/U]( [COLOR=#0000ff]tempMesh[/COLOR]->[COLOR=#800080]weights[/COLOR] );[/COLOR]
     
    [COLOR=#008000][COLOR=#8000ff]                }[/COLOR]// Only for non skinned meshes[/COLOR]
    [COLOR=#008000]//} // for (meshes)        [/COLOR]
    [COLOR=#8000ff]}[/COLOR]

    Well, I will keep looking for it!

    Thx!
    Last edited by S-h-0-X; 05-20-2012 at 08:27 AM.

  6. #6
    Senior Member OpenGL Guru Dark Photon's Avatar
    Join Date
    Oct 2004
    Location
    Druidia
    Posts
    2,882
    Quote Originally Posted by S-h-0-X View Post
    I'm trying to test what you said in the previous post, but neither the mat3( matTransform ) or the transpose( mat3( matTransform ) ) seems to work.
    Have you validated your skinning transforms are otherwise valid through another means?

    For instance, put the skin mesh aside (along with skinning and your existing code), and just render the graphical skeleton using 100% CPU code (aside from drawing the lines). For starters, just draw the bind pose (joint orientation transforms only) and draw the bones as simple lines. That'll verify your joint orientation transforms look reasonable. Then mix your joint animation transforms into that to get the skeleton moving. That'll verify that your joint animation transforms are probably reasonable. As a ++ solution (totally optional) if you want to see your joint-local space orientations, render a stick for the bones instead of just a line:


    If you find a problem just doing this, then perhaps your problem, or one of them at least, is bad joint transforms (or maybe misunderstanding what transforms you were given) rather than issues with skinning in your shader.

    Also, more detail on "neither seems to work" would be helpful. Prior to posting this thread, what are you seeing or what aren't you that leads you to believe there is a problem?
    Last edited by Dark Photon; 05-21-2012 at 05:42 AM.

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •