Jump to content

  • Log In with Google      Sign In   
  • Create Account

Interested in a FREE copy of HTML5 game maker Construct 2?

We'll be giving away three Personal Edition licences in next Tuesday's GDNet Direct email newsletter!

Sign up from the right-hand sidebar on our homepage and read Tuesday's newsletter for details!


We're also offering banner ads on our site from just $5! 1. Details HERE. 2. GDNet+ Subscriptions HERE. 3. Ad upload HERE.


DX11 FBX Animtion System


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
1 reply to this topic

#1 KNunweiler   Members   -  Reputation: 101

Like
0Likes
Like

Posted 12 August 2012 - 10:34 PM

I am currently writing an fbx importer/Animtion system for my portfolio class in school. I have got all my rendering done but am now struggling with getting my animtion system to work correctly, I am currently loading in one frame of animtion data and animating in software to test before moving it into my shaders. Here is the code I hope someone can point out my errors as I have asked multiple teachers and, since none of them are familiar with FBX, seem to think the animtion code is relativly correct but still cannot get it working when helping me.

[source lang="cpp"]void FBXModel::InitializeSdkObjects(FbxManager*& pManager, FbxScene*& pScene){ //The first thing to do is to create the FBX Manager which is the object allocator for almost all the classes in the SDK pManager = FbxManager::Create(); if( !pManager ) { exit(1); } //Create an IOSettings object. This object holds all import/export settings. FbxIOSettings* ios = FbxIOSettings::Create(pManager, IOSROOT); pManager->SetIOSettings(ios); //Load plugins from the executable directory (optional) FbxString lPath = FbxGetApplicationDirectory(); pManager->LoadPluginsDirectory(lPath.Buffer()); //Create an FBX scene. This object holds most objects imported/exported from/to files. pScene = FbxScene::Create(pManager, "My Scene"); if( !pScene ) { exit(1); }}bool FBXModel::LoadScene(const char* pFilename){ // Create an importer. FbxImporter* lImporter = FbxImporter::Create(mSdkManager,""); // Initialize the importer by providing a filename. const bool lImportStatus = lImporter->Initialize(pFilename, -1, mSdkManager->GetIOSettings()); if( !lImportStatus ) { return false; } //Check to make sure the file is a fbx file if (!lImporter->IsFBX()) { return false; } // Import the scene. if(!lImporter->Import(mpScene)) { return false; } //Destroy the importer lImporter->Destroy(); return true;}void FBXModel::AddMesh(){ FbxNode* lRootNode = mpScene->GetRootNode(); for( int i = 0; i < lRootNode->GetChildCount(); i++) { AddMesh(lRootNode->GetChild(i)); } for(int i = 0; i < mMeshArray.Size(); ++i) { FbxMesh* pMesh = mMeshArray[i]; FbxGeometryConverter converter( mSdkManager ); pMesh = converter.TriangulateMesh( pMesh );//========================================================================================================================// TODO: MOVE INTO SHADER//======================================================================================================================== //Load In Vertex Data LoadPosNormTex(pMesh, i); //Load Bone Data LoadBones(pMesh); //Place the Bones Recursively using the bone tree PlaceBones(); //Multiply Verts By bond Pose Inverse TestMoveVertInverse(); //load Animation Data LoadAnimationData(0); //Place Bones in new locations PlaceBones(); //Move Bones Back into TestMoveVert(); }}void FBXModel::AddMesh(FbxNode* pNode){ FbxNodeAttribute::EType nodeType = pNode->GetNodeAttribute()->GetAttributeType(); if(nodeType == FbxNodeAttribute::eMesh) { mMeshArray.Add( (FbxMesh*) pNode->GetNodeAttribute() ); } for(int i = 0; i < pNode->GetChildCount(); i++) { AddMesh(pNode->GetChild(i)); }}void FBXModel::LoadPosNormTex(FbxMesh* pMesh, int i){ FbxVector4* pMeshVertices = new FbxVector4[pMesh->GetControlPointsCount()]; memcpy(pMeshVertices, pMesh->GetControlPoints(), pMesh->GetControlPointsCount()*sizeof(FbxVector4)); // Create the vertex array. mVertexCount = pMesh->GetControlPointsCount(); vertices = new VertexType[mVertexCount]; FbxLayerElementUV* texCoords = pMesh->GetLayer(i)->GetUVs(); for( int i = 0; i < mVertexCount; ++i ) { VertexType v; //Vertex v.mPosition = D3DXVECTOR3( (float)pMeshVertices[ i ].mData[0], (float)pMeshVertices[ i ].mData[1], (float)pMeshVertices[ i ].mData[2] ); //Normal v.mNormal = D3DXVECTOR3 ( (float)pMesh->GetElementNormal(0)->GetDirectArray().GetAt(i).mData[0], (float)pMesh->GetElementNormal(0)->GetDirectArray().GetAt(i).mData[1], (float)pMesh->GetElementNormal(0)->GetDirectArray().GetAt(i).mData[2] ); //Texture if(texCoords) { v.mTexture = D3DXVECTOR2 ( (float)texCoords->GetDirectArray().GetAt(i).mData[0], (float)texCoords->GetDirectArray().GetAt(i).mData[1] ); } else { v.mTexture = D3DXVECTOR2(0.7f, 0.7f); } vertices[i] = v; } delete [] pMeshVertices; // Create the index array. mIndexCount = pMesh->GetPolygonVertexCount(); indices = new unsigned short[mIndexCount]; for(int i = 0; i < pMesh->GetPolygonVertexCount(); ++i ) { indices[i] = pMesh->GetPolygonVertices()[i]; }}void FBXModel::LoadBones(FbxGeometry* pGeometry){ int lSkinCount = pGeometry->GetDeformerCount(FbxDeformer::eSkin); for(int i = 0; i!=lSkinCount; ++i) { int lClusterCount = ((FbxSkin *) pGeometry->GetDeformer(i, FbxDeformer::eSkin))->GetClusterCount(); mBoneCount = lClusterCount; mBones = new Bone[lClusterCount]; for (int j = 0; j != lClusterCount; ++j) { FbxCluster* lCluster = ((FbxSkin *) pGeometry->GetDeformer(i, FbxDeformer::eSkin))->GetCluster(j); FbxNode* link = lCluster->GetLink(); const char* linkname = link->GetName(); mBones[j].mChildCount = link->GetChildCount(); mBones[j].mChildren = new Bone*[mBones[j].mChildCount]; if(lCluster->GetLink() != NULL) { mBones[j].mName = (char*)lCluster->GetLink()->GetName(); } FbxAMatrix lMatrix; lMatrix = lCluster->GetTransformLinkMatrix(lMatrix); //Transform Matrix D3DXMATRIX D3DTranslate; D3DXMATRIX D3DRotate; D3DXMATRIX D3DScale; D3DXMatrixIdentity(&D3DTranslate); D3DXMatrixIdentity(&D3DRotate); D3DXMatrixIdentity(&D3DScale); float rx = lMatrix.GetR().mData[0]; float ry = lMatrix.GetR().mData[1]; float rz = lMatrix.GetR().mData[2]; float sx = lMatrix.GetS().mData[0]; float sy = lMatrix.GetS().mData[1]; float sz = lMatrix.GetS().mData[2]; D3DXMatrixTranslation(&D3DTranslate, (float)lMatrix.GetT().mData[0], (float)lMatrix.GetT().mData[1], (float)lMatrix.GetT().mData[2]); D3DXMatrixRotationYawPitchRoll(&D3DRotate, DEG2RAD((float)lMatrix.GetR().mData[0]), DEG2RAD((float)lMatrix.GetR().mData[1]), DEG2RAD((float)lMatrix.GetR().mData[2])); D3DXMatrixScaling(&D3DScale, (float)lMatrix.GetS().mData[0], (float)lMatrix.GetS().mData[1], (float)lMatrix.GetS().mData[2]); mBones[j].mTransformPositionMatrix = D3DRotate * D3DTranslate * D3DScale; mBones[j].mBindPoseMatrix = D3DRotate * D3DTranslate * D3DScale; D3DXMatrixInverse(&mBones[j].mBindPoseInverse, NULL, &mBones[j].mTransformPositionMatrix); } //Create the bone tree and set bone weights for (int j = 0; j != lClusterCount; ++j) { FbxCluster* lCluster = ((FbxSkin *) pGeometry->GetDeformer(i, FbxDeformer::eSkin))->GetCluster(j); FbxNode* link = lCluster->GetLink(); for(int k = 0; k < mBones[j].mChildCount; ++k) { FbxNode* childNode = link->GetChild(k); int ChildId = GetBoneIdByName( childNode->GetName() ); mBones[j].mChildren[k] = &mBones[ChildId]; mBones[j].mChildren[k]->mParent = &mBones[j]; } int indicesCount = lCluster->GetControlPointIndicesCount(); if(indicesCount) { int* Boneindcies = lCluster->GetControlPointIndices(); double* BoneWeights = lCluster->GetControlPointWeights(); int indicesCount = lCluster->GetControlPointIndicesCount(); for(int l = 0; l < indicesCount; ++l) { for(int m = 0; m < 4; ++m) { if(vertices[Boneindcies[l]].mBoneIds[m] == 0) { vertices[Boneindcies[l]].mBoneIds[m] = j; vertices[Boneindcies[l]].mBoneWeights[m] = BoneWeights[l]; break; } } } } } } //Copy in loaded data from verts into findPoseVerts to create bind pose position verticesBindPose = new VertexType[mVertexCount]; memcpy(verticesBindPose, vertices, sizeof(VertexType) * mVertexCount);}int FBXModel::GetBoneIdByName(const char* name){ for(int i = 0; i < mBoneCount; ++i) { if(name == mBones[i].mName) { return i; } } return -1;}void FBXModel::LoadAnimationData(int key){ for(int h = 0; h < mBoneCount; ++h) { FbxNode* lNode = mpScene->FindNodeByName(mBones[h].mName); int AnimationStackCount = mpScene->GetSrcObjectCount(FBX_TYPE(FbxAnimStack)); for (int i = 0; i < AnimationStackCount; ++i) { FbxAnimStack* lAnimStack = FbxCast<FbxAnimStack>( mpScene->GetSrcObject(FbxAnimStack::ClassId, i) ); int nbAnimLayerCount = lAnimStack->GetMemberCount(FBX_TYPE(FbxAnimLayer)); for (int l = 0; l < nbAnimLayerCount; l++) { FbxAnimLayer* lAnimLayer = lAnimStack->GetMember(FBX_TYPE(FbxAnimLayer), l); const char* AnimLayerName = lAnimLayer->GetName(); FbxAnimCurveNode* lAnimCurve = lNode->LclTranslation.GetCurveNode(); FbxAnimCurve* lAnimCurveTX = lAnimCurve->GetCurve(0); FbxAnimCurve* lAnimCurveTY = lAnimCurve->GetCurve(1); FbxAnimCurve* lAnimCurveTZ = lAnimCurve->GetCurve(2); lAnimCurve = lNode->LclRotation.GetCurveNode(); FbxAnimCurve* lAnimCurveRX = lAnimCurve->GetCurve(0); FbxAnimCurve* lAnimCurveRY = lAnimCurve->GetCurve(1); FbxAnimCurve* lAnimCurveRZ = lAnimCurve->GetCurve(2); lAnimCurve = lNode->LclScaling.GetCurveNode(); FbxAnimCurve* lAnimCurveSX = lAnimCurve->GetCurve(0); FbxAnimCurve* lAnimCurveSY = lAnimCurve->GetCurve(1); FbxAnimCurve* lAnimCurveSZ = lAnimCurve->GetCurve(2); float SX = 1.0f; float SY = 1.0f; float SZ = 1.0f; float TX = 0; float TY = 0; float TZ = 0; float RX = 0; float RY = 0; float RZ = 0; //Load Translations Data if(lAnimCurveTX && key < lAnimCurveTX->KeyGetCount()) TX = lAnimCurveTX->KeyGet(key).GetValue(); if(lAnimCurveTY && key < lAnimCurveTY->KeyGetCount()) TY = lAnimCurveTY->KeyGet(key).GetValue(); if(lAnimCurveTZ && key < lAnimCurveTZ->KeyGetCount()) TZ = lAnimCurveTZ->KeyGet(key).GetValue(); //Load Rotation Data if(lAnimCurveRX && key < lAnimCurveRX->KeyGetCount()) RX = lAnimCurveRX->KeyGet(key).GetValue(); if(lAnimCurveRY && key < lAnimCurveRY->KeyGetCount()) RY = lAnimCurveRY->KeyGet(key).GetValue(); if(lAnimCurveRZ && key < lAnimCurveRZ->KeyGetCount()) RZ = lAnimCurveRZ->KeyGet(key).GetValue(); //Load Scale Data if(lAnimCurveSX && key < lAnimCurveSX->KeyGetCount()) SX = lAnimCurveSX->KeyGet(key).GetValue(); if(lAnimCurveSY && key < lAnimCurveSY->KeyGetCount()) SY = lAnimCurveSY->KeyGet(key).GetValue(); if(lAnimCurveSZ && key < lAnimCurveSZ->KeyGetCount()) SZ = lAnimCurveSZ->KeyGet(key).GetValue(); //Transform Matrix D3DXMATRIX D3DTranslate; D3DXMATRIX D3DRotate; D3DXMATRIX D3DScale; D3DXMatrixIdentity(&D3DTranslate); D3DXMatrixIdentity(&D3DRotate); D3DXMatrixIdentity(&D3DScale); D3DXMatrixTranslation(&D3DTranslate, TX, TY, TZ); D3DXMatrixRotationYawPitchRoll(&D3DRotate, DEG2RAD(RX), DEG2RAD(RY), DEG2RAD(RZ)); D3DXMatrixScaling(&D3DScale, SX, SY, SZ); mBones[h].mTransformPositionMatrix = D3DRotate * D3DTranslate * D3DScale; } } }}void FBXModel::TestMoveVert(){ for(int i = 0; i < mVertexCount; ++i) { D3DXVECTOR3 pos1; D3DXVECTOR3 pos2; D3DXVECTOR3 pos3; D3DXVECTOR3 pos4; D3DXVec3TransformCoord(&pos1, &verticesBindPose[i].mPosition, &mBones[vertices[i].mBoneIds[0]].mWorldTransformPositionMatrix ); D3DXVec3TransformCoord(&pos2, &verticesBindPose[i].mPosition, &mBones[vertices[i].mBoneIds[1]].mWorldTransformPositionMatrix ); D3DXVec3TransformCoord(&pos3, &verticesBindPose[i].mPosition, &mBones[vertices[i].mBoneIds[2]].mWorldTransformPositionMatrix ); D3DXVec3TransformCoord(&pos4, &verticesBindPose[i].mPosition, &mBones[vertices[i].mBoneIds[3]].mWorldTransformPositionMatrix ); vertices[i].mPosition = (pos1*vertices[i].mBoneWeights[0]) + (pos2*vertices[i].mBoneWeights[1]) + (pos3*vertices[i].mBoneWeights[2]) + (pos4*vertices[i].mBoneWeights[3]); }}void FBXModel::TestMoveVertInverse(){ for(int i = 0; i < mVertexCount; ++i) { D3DXVECTOR3 pos1; D3DXVECTOR3 pos2; D3DXVECTOR3 pos3; D3DXVECTOR3 pos4; D3DXVec3TransformCoord(&pos1, &vertices[i].mPosition, &mBones[vertices[i].mBoneIds[0]].mBindPoseInverse); D3DXVec3TransformCoord(&pos2, &vertices[i].mPosition, &mBones[vertices[i].mBoneIds[1]].mBindPoseInverse ); D3DXVec3TransformCoord(&pos3, &vertices[i].mPosition, &mBones[vertices[i].mBoneIds[2]].mBindPoseInverse ); D3DXVec3TransformCoord(&pos4, &vertices[i].mPosition, &mBones[vertices[i].mBoneIds[3]].mBindPoseInverse ); verticesBindPose[i].mPosition = (pos1*vertices[i].mBoneWeights[0]) + (pos2*vertices[i].mBoneWeights[1]) + (pos3*vertices[i].mBoneWeights[2]) + (pos4*vertices[i].mBoneWeights[3]); }}void FBXModel::PlaceBones(){ mBones[0].mWorldTransformPositionMatrix = mBones[0].mTransformPositionMatrix; for(int i = 0; i < mBones[0].mChildCount; ++i) { PlaceBones(mBones[0].mChildren[i], mBones[0].mTransformPositionMatrix ); }}void FBXModel::PlaceBones( Bone* bone, D3DXMATRIX parent ){ bone->mWorldTransformPositionMatrix = bone->mTransformPositionMatrix * parent; for(int j = 0; j < bone->mChildCount; ++j) { PlaceBones( bone->mChildren[j], bone->mWorldTransformPositionMatrix); }}[/source]

Sponsor:

#2 Doug Rogers   Members   -  Reputation: 173

Like
0Likes
Like

Posted 14 August 2012 - 04:47 PM

Try posting here:

http://area.autodesk.com/forum/autodesk-fbx/fbx-sdk/




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS