C++ FBX Animation Importer Using the FBX SDK

Posted by Mike Sawayda on Game Development See other posts from Game Development or by Mike Sawayda
Published on 2013-07-19T09:50:31Z Indexed on 2013/10/17 22:23 UTC
Read the original article Hit count: 990

Filed under:
|
|
|

Does anyone have any experience using the FBX SDK to load in animations. I got the meshes loaded in correctly with all of their verts, indices, UV's, and normals. I am just now trying to get the Animations working correctly. I have looked at the FBX SDK documentation with little help. If someone could just help me get started or point me in the right direction I would greatly appreciate it. I added some code so you can kinda get an idea of what I am doing. I should be able to place that code anywhere in the load FBX function and have it work.

//GETTING ANIMAION DATA
for(int i = 0; i < scene->GetSrcObjectCount<FbxAnimStack>(); ++i)
{
    FbxAnimStack* lAnimStack = scene->GetSrcObject<FbxAnimStack>(i);

    FbxString stackName = "Animation Stack Name: ";
    stackName += lAnimStack->GetName();
    string sStackName = stackName;

    int numLayers = lAnimStack->GetMemberCount<FbxAnimLayer>();
    for(int j = 0; j < numLayers; ++j)
    {
        FbxAnimLayer* lAnimLayer = lAnimStack->GetMember<FbxAnimLayer>(j);

        FbxString layerName = "Animation Stack Name: ";
        layerName += lAnimLayer->GetName();
        string sLayerName = layerName;

        queue<FbxNode*> nodes;

        FbxNode* tempNode = scene->GetRootNode();

        while(tempNode != NULL)
        {
            FbxAnimCurve* lAnimCurve = tempNode->LclTranslation.GetCurve(lAnimLayer, FBXSDK_CURVENODE_COMPONENT_X);

            if(lAnimCurve != NULL)
            {
                //I know something needs to be done here but I dont know what.
            }

            for(int i = 0; i < tempNode->GetChildCount(false); ++i)
            {
                nodes.push(tempNode->GetChild(i));
            }

            if(nodes.size() > 0)
            {
                tempNode = nodes.front();
                nodes.pop();
            }
            else
            {
                tempNode = NULL;
            }
        }               
    }       
}

Here is the full function

bool FBXLoader::LoadFBX(ParentMeshObject* _parentMesh, char* _filePath, bool _hasTexture)
{
    FbxManager* fbxManager = FbxManager::Create();
if(!fbxManager)
{
    printf( "ERROR %s : %d failed creating FBX Manager!\n", __FILE__, __LINE__ );
}

FbxIOSettings* ioSettings = FbxIOSettings::Create(fbxManager, IOSROOT);
fbxManager->SetIOSettings(ioSettings);

FbxString filePath = FbxGetApplicationDirectory();
fbxManager->LoadPluginsDirectory(filePath.Buffer());

FbxScene* scene = FbxScene::Create(fbxManager, "");

int fileMinor, fileRevision;
int sdkMajor, sdkMinor, sdkRevision;
int fileFormat;

FbxManager::GetFileFormatVersion(sdkMajor, sdkMinor, sdkRevision);
FbxImporter* importer = FbxImporter::Create(fbxManager, "");

if(!fbxManager->GetIOPluginRegistry()->DetectReaderFileFormat(_filePath, fileFormat))
{
    //Unrecognizable file format. Try to fall back on FbxImorter::eFBX_BINARY
    fileFormat = fbxManager->GetIOPluginRegistry()->FindReaderIDByDescription("FBX binary (*.fbx)");
}

bool importStatus = importer->Initialize(_filePath, fileFormat, fbxManager->GetIOSettings());
importer->GetFileVersion(fileMinor, fileMinor, fileRevision);

if(!importStatus)
{
    printf( "ERROR %s : %d FbxImporter Initialize failed!\n", __FILE__, __LINE__ );
    return false;
}

importStatus = importer->Import(scene);

if(!importStatus)
{
    printf( "ERROR %s : %d FbxImporter failed to import the file to the scene!\n", __FILE__, __LINE__ );
    return false;
}

FbxAxisSystem sceneAxisSystem = scene->GetGlobalSettings().GetAxisSystem();
FbxAxisSystem axisSystem( FbxAxisSystem::eYAxis, FbxAxisSystem::eParityOdd, FbxAxisSystem::eLeftHanded );

if(sceneAxisSystem != axisSystem)
{
    axisSystem.ConvertScene(scene);
}

TriangulateRecursive(scene->GetRootNode());

FbxArray<FbxMesh*> meshes;
FillMeshArray(scene, meshes);

unsigned short vertexCount = 0;
unsigned short triangleCount = 0;
unsigned short faceCount = 0;
unsigned short materialCount = 0;

int numberOfVertices = 0;
for(int i = 0; i < meshes.GetCount(); ++i)
{
    numberOfVertices += meshes[i]->GetPolygonVertexCount();
}



Face face;
vector<Face> faces;
int indicesCount = 0;

int ptrMove = 0;

float wValue = 0.0f;

if(!_hasTexture)
{
    wValue = 1.0f;
}

for(int i = 0; i < meshes.GetCount(); ++i)
{
    int vertexCount = 0;
    vertexCount = meshes[i]->GetControlPointsCount();
    if(vertexCount == 0)
        continue;

    VertexType* vertices;
    vertices = new VertexType[vertexCount];

    int triangleCount = meshes[i]->GetPolygonVertexCount() / 3;
    indicesCount = meshes[i]->GetPolygonVertexCount();

    FbxVector4* fbxVerts = new FbxVector4[vertexCount];
    int arrayIndex = 0;
    memcpy(fbxVerts, meshes[i]->GetControlPoints(), vertexCount * sizeof(FbxVector4));

    for(int j = 0; j < triangleCount; ++j)
    {
        int index = 0;
        FbxVector4 fbxNorm(0, 0, 0, 0);
        FbxVector2 fbxUV(0, 0);
        bool texCoordFound = false;
        face.indices[0] = index = meshes[i]->GetPolygonVertex(j, 0);
        vertices[index].position.x = (float)fbxVerts[index][0];
        vertices[index].position.y = (float)fbxVerts[index][1];
        vertices[index].position.z = (float)fbxVerts[index][2];
        vertices[index].position.w = wValue;
        meshes[i]->GetPolygonVertexNormal(j, 0, fbxNorm);
        vertices[index].normal.x = (float)fbxNorm[0];
        vertices[index].normal.y = (float)fbxNorm[1];
        vertices[index].normal.z = (float)fbxNorm[2];
        texCoordFound = meshes[i]->GetPolygonVertexUV(j, 0, "map1", fbxUV);
        vertices[index].texture.x = (float)fbxUV[0];
        vertices[index].texture.y = (float)fbxUV[1];

        face.indices[1] = index = meshes[i]->GetPolygonVertex(j, 1);
        vertices[index].position.x = (float)fbxVerts[index][0];
        vertices[index].position.y = (float)fbxVerts[index][1];
        vertices[index].position.z = (float)fbxVerts[index][2];
        vertices[index].position.w = wValue;
        meshes[i]->GetPolygonVertexNormal(j, 1, fbxNorm);
        vertices[index].normal.x = (float)fbxNorm[0];
        vertices[index].normal.y = (float)fbxNorm[1];
        vertices[index].normal.z = (float)fbxNorm[2];
        texCoordFound = meshes[i]->GetPolygonVertexUV(j, 1, "map1", fbxUV);
        vertices[index].texture.x = (float)fbxUV[0];
        vertices[index].texture.y = (float)fbxUV[1];

        face.indices[2] = index = meshes[i]->GetPolygonVertex(j, 2);
        vertices[index].position.x = (float)fbxVerts[index][0];
        vertices[index].position.y = (float)fbxVerts[index][1];
        vertices[index].position.z = (float)fbxVerts[index][2];
        vertices[index].position.w = wValue;
        meshes[i]->GetPolygonVertexNormal(j, 2, fbxNorm);
        vertices[index].normal.x = (float)fbxNorm[0];
        vertices[index].normal.y = (float)fbxNorm[1];
        vertices[index].normal.z = (float)fbxNorm[2];
        texCoordFound = meshes[i]->GetPolygonVertexUV(j, 2, "map1", fbxUV);
        vertices[index].texture.x = (float)fbxUV[0];
        vertices[index].texture.y = (float)fbxUV[1];

        faces.push_back(face);
    }

    meshes[i]->Destroy();
    meshes[i] = NULL;

    int indexCount = faces.size() * 3;
    unsigned long* indices = new unsigned long[faces.size() * 3]; 
    int indicie = 0;
    for(unsigned int i = 0; i < faces.size(); ++i)
    {
        indices[indicie++] = faces[i].indices[0];
        indices[indicie++] = faces[i].indices[1];
        indices[indicie++] = faces[i].indices[2];
    }
    faces.clear();
    _parentMesh->AddChild(vertices, indices, vertexCount, indexCount);
}

return true;
}

© Game Development or respective owner

Related posts about c++

Related posts about engine