Jump to content
  • Advertisement
Sign in to follow this  
dealer2couleurs

tangent space coordinate calcul

This topic is 3412 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hi I'm programmer in CGI, I try to make a plugin to store deformations of 3d meshs on tangent space coordinate. The plugin is usefull to transfert some deformation from a surface to an other. It get deformation vector in cartesian coordinate from a base mesh, depending the surface, it store the deformation in tangent space and we use this new deformation vector to transfert it on an other surface depending the tangent space. Not sure about me but I think it can work in theory. I'm programming it with the API from Autodesk Maya but my major issue is that I'm not sure about my maths. MY CODE TO GET TANGENTE SPACE VECTORS I use it to get the initial and the final tangent space. Not sure about the normalization of all the vectors and about the computation of the per vertex normal,tangent and binormals to compute per vertex tangent and binormals, I take the mean value of the per face vectors
for (meshIt.reset() ; !meshIt.isDone(); meshIt.next())
{
     MIntArray faceList(meshIt.count());
     meshIt.getConnectedFaces(faceList);
     tangentes[meshIt.index()] = MVector(0.0,0.0,0.0);
     binormals[meshIt.index()] = MVector(0.0,0.0,0.0);
     for(unsigned int i=0; i< faceList.length(); i++)
     {
         MVector tempNorm(0.0,0.0,0.0);
         myMesh.getFaceVertexNormal(faceList,meshIt.index(),tempNorm, MSpace::kObject);
         tempNorm.normalize();
         normals[meshIt.index()] +=tempNorm;

         MVector tempTang(0.0,0.0,0.0);
         myMesh.getFaceVertexTangent(faceList,meshIt.index(), tempTang,MSpace::kObject);
         tempTang.normalize();
         tangentes[meshIt.index()] += tempTang;
                    
         MVector tempBin(0.0,0.0,0.0);
         myMesh.getFaceVertexBinormal(faceList,meshIt.index(),
tempBin,MSpace::kObject);
         tempBin.normalize();
         binormals[meshIt.index()] += tempBin;
     }

        normals[meshIt.index()] = normals[meshIt.index()] / faceList.length();
        binormals[meshIt.index()] = binormals[meshIt.index()]/faceList.length();
        tangentes[meshIt.index()] = tangentes[meshIt.index()]/faceList.length();

        normals[meshIt.index()].normalize();
        binormals[meshIt.index()].normalize();
        tangentes[meshIt.index()].normalize();
}

MY CODE TO COMPUTE NEW DEFORMATION VALUE I use it to compute the new deformation vector based on the original one and the two tangent space. Not sure about the creation of the matrix.
MMatrix oldM;
oldM[0][0] = tangentes[meshIt.index()].x;        
oldM[0][1] = tangentes[meshIt.index()].y;        
oldM[0][2] = tangentes[meshIt.index()].z;        

oldM[1][0] = binormals[meshIt.index()].x;        
oldM[1][1] = binormals[meshIt.index()].y;        
oldM[1][2] = binormals[meshIt.index()].z;    

oldM[2][0] = normals[meshIt.index()].x;            
oldM[2][1] = normals[meshIt.index()].y;            
oldM[2][2] = normals[meshIt.index()].z;        

MMatrix newM;
newM[0][0] = newTangs[meshIt.index()].x;        
newM[0][1] = newTangs[meshIt.index()].y;        
newM[0][2] = newTangs[meshIt.index()].z;        

newM[1][0] = newBinorms[meshIt.index()].x;        
newM[1][1] = newBinorms[meshIt.index()].y;        
newM[1][2] = newBinorms[meshIt.index()].z;        

newM[2][0] = newNorms[meshIt.index()].x;        
newM[2][1] = newNorms[meshIt.index()].y;        
newM[2][2] = newNorms[meshIt.index()].z;        
            
oldM.homogenize();
newM.homogenize();

MVector deformValue(result[0],result[1],result[2]);
MVector newdeformValue = newM* (oldM.inverse() * deformValue);

Share this post


Link to post
Share on other sites
Advertisement
OK it works...

I have finally found the issues in my code. I have to had some calcul to ensure the tangent and the normal are orthogonal and after I compute the binormal with the crossproduct to ensure an orthogonal space

here is the new version

MY CODE TO GET TANGENTE SPACE VECTORS
I use it to get the initial and the final tangent space. Not sure about the normalization of all the vectors and about the computation of the per vertex normal,tangent and binormals
for (meshIt.reset(); !meshIt.isDone(); meshIt.next())
{
MIntArray faceList(meshIt.count());
meshIt.getConnectedFaces(faceList);
tangentes[meshIt.index()] = MVector(0.0,0.0,0.0);
for(unsigned int i=0; i< faceList.length(); i++)
{
MVector tempNorm(0.0,0.0,0.0);
myMesh.getFaceVertexNormal(faceList,meshIt.index(),tempNorm, MSpace::kObject);
tempNorm.normalize();
normals[meshIt.index()] +=tempNorm;

MVector tempTang(0.0,0.0,0.0);
myMesh.getFaceVertexTangent(faceList,meshIt.index(), tempTang,MSpace::kObject);
tempTang.normalize();
tangentes[meshIt.index()] += tempTang;
}
normals[meshIt.index()].normalize();
tangentes[meshIt.index()].normalize();

//Gram-Schmidt orthogonalization
MVector temp =normals[meshIt.index()] * scalarProduct(normals[meshIt.index()], tangentes[meshIt.index()]);
temp.normalize();
tangentes[meshIt.index()] -= temp;
}


MY CODE TO COMPUTE NEW DEFORMATION VALUE
I sue it to compute the new deformation vector based on the original one and the two tangent space. Not sure about the creation of the matrix.
//Right handed TBN New space ?
MVector binormalNew = crossProduct(newNorms[meshIt.index()], newTangs[meshIt.index()]);
bool rigthHanded = scalarProduct(crossProduct(newTangs[meshIt.index()], binormalNew), newNorms[meshIt.index()]) >= 0;
if(!rigthHanded)
binormalNew *= -1;

//Right handed TBN old space ?
MVector binormalold = crossProduct(normals[meshIt.index()], tangentes[meshIt.index()]);
rigthHanded = scalarProduct(crossProduct(tangentes[meshIt.index()], binormalold), normals[meshIt.index()]) >= 0;
if(!rigthHanded)
binormalold *= -1;

MMatrix oldM;
oldM[0][0] = tangentes[meshIt.index()].x;
oldM[1][0] = tangentes[meshIt.index()].y;
oldM[2][0] = tangentes[meshIt.index()].z;
oldM[0][1] = binormalold.x;
oldM[1][1] = binormalold.y;
oldM[2][1] = binormalold.z;
oldM[0][2] = normals[meshIt.index()].x;
oldM[1][2] = normals[meshIt.index()].y;
oldM[2][2] = normals[meshIt.index()].z;

MMatrix newM;
newM[0][0] = newTangs[meshIt.index()].x;
newM[1][0] = newTangs[meshIt.index()].y;
newM[2][0] = newTangs[meshIt.index()].z;
newM[0][1] = binormalNew.x;
newM[1][1] = binormalNew.y;
newM[2][1] = binormalNew.z;
newM[0][2] = newNorms[meshIt.index()].x;
newM[1][2] = newNorms[meshIt.index()].y;
newM[2][2] = newNorms[meshIt.index()].z;

oldM.homogenize();
newM.homogenize();

MVector deformValue(result[0],result[1],result[2]);
MVector newdeformValue = newM* (oldM.inverse() *deformValue);

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!