c++ - FBX node transform calculation -


recently, trying use fbx sdk import 3d model made 3dmax, got in trouble transformations. simple mesh(a sphere split in 2 halves) consisting of 2 nodes has 1 of it's nodes offset no matter what. tried several(quite ambiguous) ways of calculating transform latest sdk documentation provides... result same. i'll provide code , mesh in case can point out mistakes.

helper functions:

fbxamatrix meshmanager::getglobalposition(fbxnode* pnode, const fbxtime& ptime, fbxpose* ppose, fbxamatrix* pparentglobalposition) {     fbxamatrix lglobalposition;     bool        lpositionfound = false;      if (ppose)     {         int lnodeindex = ppose->find(pnode);          if (lnodeindex > -1)         {             // bind pose global matrix.             // if have rest pose, need check if             // stored in global or local space.             if (ppose->isbindpose() || !ppose->islocalmatrix(lnodeindex))             {                 lglobalposition = getposematrix(ppose, lnodeindex);             }             else             {                 // have local matrix, need convert                 // global space matrix.                 fbxamatrix lparentglobalposition;                  if (pparentglobalposition)                 {                     lparentglobalposition = *pparentglobalposition;                 }                 else                 {                     if (pnode->getparent())                     {                         lparentglobalposition = getglobalposition(pnode->getparent(), ptime, ppose);                     }                 }                  fbxamatrix llocalposition = getposematrix(ppose, lnodeindex);                 lglobalposition = lparentglobalposition * llocalposition;             }              lpositionfound = true;         }     }      if (!lpositionfound)     {         // there no pose entry node, current global position instead.          // ideally use parent global position , local position compute global position.         // unfortunately equation          //    lglobalposition = pparentglobalposition * llocalposition         // not hold when inheritance type other "parent" (rsrs).         // compute parent rotation , scaling tricky in rrss , rrs cases.         lglobalposition = pnode->evaluateglobaltransform(ptime);     }      return lglobalposition; }  // matrix of given pose fbxamatrix meshmanager::getposematrix(fbxpose* ppose, int pnodeindex) {     fbxamatrix lposematrix;     fbxmatrix lmatrix = ppose->getmatrix(pnodeindex);      memcpy((double*)lposematrix, (double*)lmatrix, sizeof(lmatrix.mdata));      return lposematrix; }  // geometry offset node. never inherited children. fbxamatrix meshmanager::getgeometry(fbxnode* pnode) {     const fbxvector4 lt = pnode->getgeometrictranslation(fbxnode::esourcepivot);     const fbxvector4 lr = pnode->getgeometricrotation(fbxnode::esourcepivot);     const fbxvector4 ls = pnode->getgeometricscaling(fbxnode::esourcepivot);      return fbxamatrix(lt, lr, ls); }  mat4 fbxmattoglm(const fbxamatrix& mat) {     dvec4 c0 = glm::make_vec4((double*)mat.getcolumn(0).buffer());     dvec4 c1 = glm::make_vec4((double*)mat.getcolumn(1).buffer());     dvec4 c2 = glm::make_vec4((double*)mat.getcolumn(2).buffer());     dvec4 c3 = glm::make_vec4((double*)mat.getcolumn(3).buffer());     glm::mat4 convertmatr = mat4(c0, c1, c2, c3);     return inverse(convertmatr); } 

mesh extraction:

void meshmanager::extractmeshrecursive(fbxscene* mscene, fbxnode* pnode, fbxamatrix& pparentglobalposition, shared_ptr<mesh> mesh, unsigned &currentnode) {     // find out type of node     fbxnodeattribute* lnodeattribute = pnode->getnodeattribute();      fbxamatrix lglobalposition = getglobalposition(pnode, 1, mscene->getpose(-1) , &pparentglobalposition);     fbxamatrix lgeometryoffset = getgeometry(pnode);     fbxamatrix lglobaloffsetposition = lglobalposition * lgeometryoffset;      if (lnodeattribute)     {         // actual node mesh data if mesh time         // (you use sample draw other nodes cameras)         if (lnodeattribute->getattributetype() == fbxnodeattribute::emesh)         {             // draw actual mesh data             fbxmesh* lmesh = pnode->getmesh();              if (lmesh->istrianglemesh() == false) {                 fbxgeometryconverter conv(mfbxmanager);                 conv.triangulate(lnodeattribute, true);             }              const uint lvertexcount = lmesh->getcontrolpointscount();             const uint ltrianglecount = lmesh->getpolygoncount();              // may not have vertex data             if (lvertexcount == 0) return;              mesh->nodes.push_back(meshnode());              fbxvector4* pcontrolpoints = lmesh->getcontrolpoints();             (uint = 0; < lvertexcount; i++)             {                 mesh->nodes[currentnode].vertices.push_back(vec3((float)pcontrolpoints[i].mdata[0], (float)pcontrolpoints[i].mdata[1], (float)pcontrolpoints[i].mdata[2]));             }              mesh->nodes[currentnode].localtransform = fbxmattoglm(lglobaloffsetposition);          }          currentnode++;      } ... extracting other vertex attributes , materials ...  // check if node has children attached     const int lchildcount = pnode->getchildcount();     (int lchildindex = 0; lchildindex < lchildcount; ++lchildindex)     {         // draw child         extractmeshrecursive(mscene, pnode->getchild(lchildindex), lglobalposition, mesh, currentnode);     } } 

i result looks this:enter image description here opposed to: enter image description here

a mesh

incorrect part here:

mat4 fbxmattoglm(const fbxamatrix& mat) {     dvec4 c0 = glm::make_vec4((double*)mat.getcolumn(0).buffer());     dvec4 c1 = glm::make_vec4((double*)mat.getcolumn(1).buffer());     dvec4 c2 = glm::make_vec4((double*)mat.getcolumn(2).buffer());     dvec4 c3 = glm::make_vec4((double*)mat.getcolumn(3).buffer());     glm::mat4 convertmatr = mat4(c0, c1, c2, c3);     return inverse(convertmatr); // <---  incorrect } 

there no need inverse resulting matrix. should've been transposed instead. did @ first, unadjusted mesh scale huge couldn't see in renderer , started tinkering it. after putting millimeters unit's in 3d studio's fbx export window, transforms correct.


Comments

Popular posts from this blog

routing - AngularJS State management ->load multiple states in one page -

python - GRASS parser() error -

Swift game error message -