- Main Page
- Classes
- Files
- Directories
- Examples

# ImportScene/DisplayAnimation.cxx

    /****************************************************************************************

       Copyright (C) 2012 Autodesk, Inc.
       All rights reserved.

       Use of this software is subject to the terms of the Autodesk license agreement
       provided at the time of installation or download, or which otherwise accompanies
       this software in either electronic or hard copy form.

    ****************************************************************************************/

    #include "DisplayCommon.h"
    #include "DisplayAnimation.h"

    void DisplayAnimation(FbxAnimStack* pAnimStack, FbxNode* pNode, bool isSwitcher = false);
    void DisplayAnimation(FbxAnimLayer* pAnimLayer, FbxNode* pNode, bool isSwitcher = false);
    void DisplayChannels(FbxNode* pNode, FbxAnimLayer* pAnimLayer, void (*DisplayCurve) (FbxAnimCurve* pCurve), void (*DisplayListCurve) (FbxAnimCurve* pCurve, FbxProperty* pProperty), bool isSwitcher);
    void DisplayCurveKeys(FbxAnimCurve* pCurve);
    void DisplayListCurveKeys(FbxAnimCurve* pCurve, FbxProperty* pProperty);

    void DisplayAnimation(FbxScene* pScene)
    {
        int i;
        for (i = 0; i < pScene->GetSrcObjectCount(FBX_TYPE(FbxAnimStack)); i++)
        {
            FbxAnimStack* lAnimStack = FbxCast<FbxAnimStack>(pScene->GetSrcObject(FBX_TYPE(FbxAnimStack), i));

            FbxString lOutputString = "Animation Stack Name: ";
            lOutputString += lAnimStack->GetName();
            lOutputString += "\n\n";
            FBXSDK_printf(lOutputString);

            DisplayAnimation(lAnimStack, pScene->GetRootNode(), true);
            DisplayAnimation(lAnimStack, pScene->GetRootNode());
        }
    }

    void DisplayAnimation(FbxAnimStack* pAnimStack, FbxNode* pNode, bool isSwitcher)
    {
        int l;
        int nbAnimLayers = pAnimStack->GetMemberCount(FBX_TYPE(FbxAnimLayer));
        FbxString lOutputString;

        lOutputString = "Animation stack contains ";
        lOutputString += nbAnimLayers;
        lOutputString += " Animation Layer(s)\n";
        FBXSDK_printf(lOutputString);

        for (l = 0; l < nbAnimLayers; l++)
        {
            FbxAnimLayer* lAnimLayer = pAnimStack->GetMember(FBX_TYPE(FbxAnimLayer), l);

            lOutputString = "AnimLayer ";
            lOutputString += l;
            lOutputString += "\n";
            FBXSDK_printf(lOutputString);

            DisplayAnimation(lAnimLayer, pNode, isSwitcher);
        }
    }

    void DisplayAnimation(FbxAnimLayer* pAnimLayer, FbxNode* pNode, bool isSwitcher)
    {
        int lModelCount;
        FbxString lOutputString;

        lOutputString = "     Node Name: ";
        lOutputString += pNode->GetName();
        lOutputString += "\n\n";
        FBXSDK_printf(lOutputString);

        DisplayChannels(pNode, pAnimLayer, DisplayCurveKeys, DisplayListCurveKeys, isSwitcher);
        FBXSDK_printf ("\n");

        for(lModelCount = 0; lModelCount < pNode->GetChildCount(); lModelCount++)
        {
            DisplayAnimation(pAnimLayer, pNode->GetChild(lModelCount), isSwitcher);
        }
    }

    void DisplayChannels(FbxNode* pNode, FbxAnimLayer* pAnimLayer, void (*DisplayCurve) (FbxAnimCurve* pCurve), void (*DisplayListCurve) (FbxAnimCurve* pCurve, FbxProperty* pProperty), bool isSwitcher)
    {
        FbxAnimCurve* lAnimCurve = NULL;

        // Display general curves.
        if (!isSwitcher)
        {
            lAnimCurve = pNode->LclTranslation.GetCurve<FbxAnimCurve>(pAnimLayer, FBXSDK_CURVENODE_COMPONENT_X);
            if (lAnimCurve)
            {
                FBXSDK_printf("        TX\n");
                DisplayCurve(lAnimCurve);
            }
            lAnimCurve = pNode->LclTranslation.GetCurve<FbxAnimCurve>(pAnimLayer, FBXSDK_CURVENODE_COMPONENT_Y);
            if (lAnimCurve)
            {
                FBXSDK_printf("        TY\n");
                DisplayCurve(lAnimCurve);
            }
            lAnimCurve = pNode->LclTranslation.GetCurve<FbxAnimCurve>(pAnimLayer, FBXSDK_CURVENODE_COMPONENT_Z);
            if (lAnimCurve)
            {
                FBXSDK_printf("        TZ\n");
                DisplayCurve(lAnimCurve);
            }

            lAnimCurve = pNode->LclRotation.GetCurve<FbxAnimCurve>(pAnimLayer, FBXSDK_CURVENODE_COMPONENT_X);
            if (lAnimCurve)
            {
                FBXSDK_printf("        RX\n");
                DisplayCurve(lAnimCurve);
            }
            lAnimCurve = pNode->LclRotation.GetCurve<FbxAnimCurve>(pAnimLayer, FBXSDK_CURVENODE_COMPONENT_Y);
            if (lAnimCurve)
            {
                FBXSDK_printf("        RY\n");
                DisplayCurve(lAnimCurve);
            }
            lAnimCurve = pNode->LclRotation.GetCurve<FbxAnimCurve>(pAnimLayer, FBXSDK_CURVENODE_COMPONENT_Z);
            if (lAnimCurve)
            {
                FBXSDK_printf("        RZ\n");
                DisplayCurve(lAnimCurve);
            }

            lAnimCurve = pNode->LclScaling.GetCurve<FbxAnimCurve>(pAnimLayer, FBXSDK_CURVENODE_COMPONENT_X);
            if (lAnimCurve)
            {
                FBXSDK_printf("        SX\n");
                DisplayCurve(lAnimCurve);
            }
            lAnimCurve = pNode->LclScaling.GetCurve<FbxAnimCurve>(pAnimLayer, FBXSDK_CURVENODE_COMPONENT_Y);
            if (lAnimCurve)
            {
                FBXSDK_printf("        SY\n");
                DisplayCurve(lAnimCurve);
            }
            lAnimCurve = pNode->LclScaling.GetCurve<FbxAnimCurve>(pAnimLayer, FBXSDK_CURVENODE_COMPONENT_Z);
            if (lAnimCurve)
            {
                FBXSDK_printf("        SZ\n");
                DisplayCurve(lAnimCurve);
            }
        }

        // Display curves specific to a light or marker.
        FbxNodeAttribute* lNodeAttribute = pNode->GetNodeAttribute();

        if (lNodeAttribute)
        {
            lAnimCurve = lNodeAttribute->Color.GetCurve<FbxAnimCurve>(pAnimLayer, FBXSDK_CURVENODE_COLOR_RED);
            if (lAnimCurve)
            {
                FBXSDK_printf("        Red\n");
                DisplayCurve(lAnimCurve);
            }
            lAnimCurve = lNodeAttribute->Color.GetCurve<FbxAnimCurve>(pAnimLayer, FBXSDK_CURVENODE_COLOR_GREEN);
            if (lAnimCurve)
            {
                FBXSDK_printf("        Green\n");
                DisplayCurve(lAnimCurve);
            }
            lAnimCurve = lNodeAttribute->Color.GetCurve<FbxAnimCurve>(pAnimLayer, FBXSDK_CURVENODE_COLOR_BLUE);
            if (lAnimCurve)
            {
                FBXSDK_printf("        Blue\n");
                DisplayCurve(lAnimCurve);
            }

            // Display curves specific to a light.
            FbxLight* light = pNode->GetLight();
            if (light)
            {
                lAnimCurve = light->Intensity.GetCurve<FbxAnimCurve>(pAnimLayer);
                if (lAnimCurve)
                {
                    FBXSDK_printf("        Intensity\n");
                    DisplayCurve(lAnimCurve);
                }

                lAnimCurve = light->OuterAngle.GetCurve<FbxAnimCurve>(pAnimLayer);
                if (lAnimCurve)
                {
                    FBXSDK_printf("        Outer Angle\n");
                    DisplayCurve(lAnimCurve);
                }

                lAnimCurve = light->Fog.GetCurve<FbxAnimCurve>(pAnimLayer);
                if (lAnimCurve)
                {
                    FBXSDK_printf("        Fog\n");
                    DisplayCurve(lAnimCurve);
                }
            }

            // Display curves specific to a camera.
            FbxCamera* camera = pNode->GetCamera();
            if (camera)
            {
                lAnimCurve = camera->FieldOfView.GetCurve<FbxAnimCurve>(pAnimLayer);
                if (lAnimCurve)
                {
                    FBXSDK_printf("        Field of View\n");
                    DisplayCurve(lAnimCurve);
                }

                lAnimCurve = camera->FieldOfViewX.GetCurve<FbxAnimCurve>(pAnimLayer);
                if (lAnimCurve)
                {
                    FBXSDK_printf("        Field of View X\n");
                    DisplayCurve(lAnimCurve);
                }

                lAnimCurve = camera->FieldOfViewY.GetCurve<FbxAnimCurve>(pAnimLayer);
                if (lAnimCurve)
                {
                    FBXSDK_printf("        Field of View Y\n");
                    DisplayCurve(lAnimCurve);
                }

                lAnimCurve = camera->OpticalCenterX.GetCurve<FbxAnimCurve>(pAnimLayer);
                if (lAnimCurve)
                {
                    FBXSDK_printf("        Optical Center X\n");
                    DisplayCurve(lAnimCurve);
                }

                lAnimCurve = camera->OpticalCenterY.GetCurve<FbxAnimCurve>(pAnimLayer);
                if(lAnimCurve)
                {
                    FBXSDK_printf("        Optical Center Y\n");
                    DisplayCurve(lAnimCurve);
                }

                lAnimCurve = camera->Roll.GetCurve<FbxAnimCurve>(pAnimLayer);
                if(lAnimCurve)
                {
                    FBXSDK_printf("        Roll\n");
                    DisplayCurve(lAnimCurve);
                }
            }

            // Display curves specific to a geometry.
            if (lNodeAttribute->GetAttributeType() == FbxNodeAttribute::eMesh ||
                lNodeAttribute->GetAttributeType() == FbxNodeAttribute::eNurbs ||
                lNodeAttribute->GetAttributeType() == FbxNodeAttribute::ePatch)
            {
                FbxGeometry* lGeometry = (FbxGeometry*) lNodeAttribute;

                int lBlendShapeDeformerCount = lGeometry->GetDeformerCount(FbxDeformer::eBlendShape);
                for(int lBlendShapeIndex = 0; lBlendShapeIndex<lBlendShapeDeformerCount; ++lBlendShapeIndex)
                {
                    FbxBlendShape* lBlendShape = (FbxBlendShape*)lGeometry->GetDeformer(lBlendShapeIndex, FbxDeformer::eBlendShape);

                    int lBlendShapeChannelCount = lBlendShape->GetBlendShapeChannelCount();
                    for(int lChannelIndex = 0; lChannelIndex<lBlendShapeChannelCount; ++lChannelIndex)
                    {
                        FbxBlendShapeChannel* lChannel = lBlendShape->GetBlendShapeChannel(lChannelIndex);
                        const char* lChannelName = lChannel->GetName();

                        lAnimCurve = lGeometry->GetShapeChannel(lBlendShapeIndex, lChannelIndex, pAnimLayer, true);
                        if(lAnimCurve)
                        {
                            FBXSDK_printf("        Shape %s\n", lChannelName);
                            DisplayCurve(lAnimCurve);
                        }
                    }
                }
            }
        }

        // Display curves specific to properties
        FbxProperty lProperty = pNode->GetFirstProperty();
        while (lProperty.IsValid())
        {
            if (lProperty.GetFlag(FbxPropertyAttr::eUser))
            {
                FbxString lFbxFCurveNodeName  = lProperty.GetName();
                FbxAnimCurveNode* lCurveNode = lProperty.GetCurveNode(pAnimLayer);

                if (!lCurveNode){
                    lProperty = pNode->GetNextProperty(lProperty);
                    continue;
                }

                FbxDataType lDataType = lProperty.GetPropertyDataType();
                if (lDataType.GetType() == eFbxBool || lDataType.GetType() == eFbxDouble || lDataType.GetType() == eFbxFloat || lDataType.GetType() == eFbxInt)
                {
                    FbxString lMessage;

                    lMessage =  "        Property ";
                    lMessage += lProperty.GetName();
                    if (lProperty.GetLabel().GetLen() > 0)
                    {
                        lMessage += " (Label: ";
                        lMessage += lProperty.GetLabel();
                        lMessage += ")";
                    };

                    DisplayString(lMessage.Buffer());

                    for( int c = 0; c < lCurveNode->GetCurveCount(0U); c++ )
                    {
                        lAnimCurve = lCurveNode->GetCurve(0U, c);
                        if (lAnimCurve)
                            DisplayCurve(lAnimCurve);
                    }
                }
                else if(lDataType.GetType() == eFbxDouble3 || lDataType.GetType() == eFbxDouble4 || lDataType.Is(FbxColor3DT) || lDataType.Is(FbxColor4DT))
                {
                    char* lComponentName1 = (lDataType.Is(FbxColor3DT) ||lDataType.Is(FbxColor4DT)) ? (char*)FBXSDK_CURVENODE_COLOR_RED : (char*)"X";
                    char* lComponentName2 = (lDataType.Is(FbxColor3DT) ||lDataType.Is(FbxColor4DT)) ? (char*)FBXSDK_CURVENODE_COLOR_GREEN : (char*)"Y";
                    char* lComponentName3 = (lDataType.Is(FbxColor3DT) ||lDataType.Is(FbxColor4DT)) ? (char*)FBXSDK_CURVENODE_COLOR_BLUE  : (char*)"Z";
                    FbxString      lMessage;

                    lMessage =  "        Property ";
                    lMessage += lProperty.GetName();
                    if (lProperty.GetLabel().GetLen() > 0)
                    {
                        lMessage += " (Label: ";
                        lMessage += lProperty.GetLabel();
                        lMessage += ")";
                    }
                    DisplayString(lMessage.Buffer());

                    for( int c = 0; c < lCurveNode->GetCurveCount(0U); c++ )
                    {
                        lAnimCurve = lCurveNode->GetCurve(0U, c);
                        if (lAnimCurve)
                        {
                            DisplayString("        Component ", lComponentName1);
                            DisplayCurve(lAnimCurve);
                        }
                    }

                    for( int c = 0; c < lCurveNode->GetCurveCount(1U); c++ )
                    {
                        lAnimCurve = lCurveNode->GetCurve(1U, c);
                        if (lAnimCurve)
                        {
                            DisplayString("        Component ", lComponentName2);
                            DisplayCurve(lAnimCurve);
                        }
                    }

                    for( int c = 0; c < lCurveNode->GetCurveCount(2U); c++ )
                    {
                        lAnimCurve = lCurveNode->GetCurve(2U, c);
                        if (lAnimCurve)
                        {
                            DisplayString("        Component ", lComponentName3);
                            DisplayCurve(lAnimCurve);
                        }
                    }
                }
                else if (lDataType.GetType() == eFbxEnum)
                {
                    FbxString lMessage;

                    lMessage =  "        Property ";
                    lMessage += lProperty.GetName();
                    if (lProperty.GetLabel().GetLen() > 0)
                    {
                        lMessage += " (Label: ";
                        lMessage += lProperty.GetLabel();
                        lMessage += ")";
                    };
                    DisplayString(lMessage.Buffer());

                    for( int c = 0; c < lCurveNode->GetCurveCount(0U); c++ )
                    {
                        lAnimCurve = lCurveNode->GetCurve(0U, c);
                        if (lAnimCurve)
                            DisplayListCurve(lAnimCurve, &lProperty);
                    }
                }
            }

            lProperty = pNode->GetNextProperty(lProperty);
        } // while

    }

    static int InterpolationFlagToIndex(int flags)
    {
        if( (flags & FbxAnimCurveDef::eInterpolationConstant) == FbxAnimCurveDef::eInterpolationConstant ) return 1;
        if( (flags & FbxAnimCurveDef::eInterpolationLinear) == FbxAnimCurveDef::eInterpolationLinear ) return 2;
        if( (flags & FbxAnimCurveDef::eInterpolationCubic) == FbxAnimCurveDef::eInterpolationCubic ) return 3;
        return 0;
    }

    static int ConstantmodeFlagToIndex(int flags)
    {
        if( (flags & FbxAnimCurveDef::eConstantStandard) == FbxAnimCurveDef::eConstantStandard ) return 1;
        if( (flags & FbxAnimCurveDef::eConstantNext) == FbxAnimCurveDef::eConstantNext ) return 2;
        return 0;
    }

    static int TangentmodeFlagToIndex(int flags)
    {
        if( (flags & FbxAnimCurveDef::eTangentAuto) == FbxAnimCurveDef::eTangentAuto ) return 1;
        if( (flags & FbxAnimCurveDef::eTangentAutoBreak)== FbxAnimCurveDef::eTangentAutoBreak ) return 2;
        if( (flags & FbxAnimCurveDef::eTangentTCB) == FbxAnimCurveDef::eTangentTCB ) return 3;
        if( (flags & FbxAnimCurveDef::eTangentUser) == FbxAnimCurveDef::eTangentUser ) return 4;
        if( (flags & FbxAnimCurveDef::eTangentGenericBreak) == FbxAnimCurveDef::eTangentGenericBreak ) return 5;
        if( (flags & FbxAnimCurveDef::eTangentBreak) == FbxAnimCurveDef::eTangentBreak ) return 6;
        return 0;
    }

    static int TangentweightFlagToIndex(int flags)
    {
        if( (flags & FbxAnimCurveDef::eWeightedNone) == FbxAnimCurveDef::eWeightedNone ) return 1;
        if( (flags & FbxAnimCurveDef::eWeightedRight) == FbxAnimCurveDef::eWeightedRight ) return 2;
        if( (flags & FbxAnimCurveDef::eWeightedNextLeft) == FbxAnimCurveDef::eWeightedNextLeft ) return 3;
        return 0;
    }

    static int TangentVelocityFlagToIndex(int flags)
    {
        if( (flags & FbxAnimCurveDef::eVelocityNone) == FbxAnimCurveDef::eVelocityNone ) return 1;
        if( (flags & FbxAnimCurveDef::eVelocityRight) == FbxAnimCurveDef::eVelocityRight ) return 2;
        if( (flags & FbxAnimCurveDef::eVelocityNextLeft) == FbxAnimCurveDef::eVelocityNextLeft ) return 3;
        return 0;
    }

    void DisplayCurveKeys(FbxAnimCurve* pCurve)
    {
        static char* interpolation[] = { "?", "constant", "linear", "cubic"};
        static char* constantMode[] =  { "?", "Standard", "Next" };
        static char* cubicMode[] =     { "?", "Auto", "Auto break", "Tcb", "User", "Break", "User break" };
        static char* tangentWVMode[] = { "?", "None", "Right", "Next left" };

        FbxTime   lKeyTime;
        float   lKeyValue;
        char    lTimeString[256];
        FbxString lOutputString;
        int     lCount;

        int lKeyCount = pCurve->KeyGetCount();

        for(lCount = 0; lCount < lKeyCount; lCount++)
        {
            lKeyValue = static_cast<float>(pCurve->KeyGetValue(lCount));
            lKeyTime  = pCurve->KeyGetTime(lCount);

            lOutputString = "            Key Time: ";
            lOutputString += lKeyTime.GetTimeString(lTimeString, FbxUShort(256));
            lOutputString += ".... Key Value: ";
            lOutputString += lKeyValue;
            lOutputString += " [ ";
            lOutputString += interpolation[ InterpolationFlagToIndex(pCurve->KeyGetInterpolation(lCount)) ];
            if ((pCurve->KeyGetInterpolation(lCount)&FbxAnimCurveDef::eInterpolationConstant) == FbxAnimCurveDef::eInterpolationConstant)
            {
                lOutputString += " | ";
                lOutputString += constantMode[ ConstantmodeFlagToIndex(pCurve->KeyGetConstantMode(lCount)) ];
            }
            else if ((pCurve->KeyGetInterpolation(lCount)&FbxAnimCurveDef::eInterpolationCubic) == FbxAnimCurveDef::eInterpolationCubic)
            {
                lOutputString += " | ";
                lOutputString += cubicMode[ TangentmodeFlagToIndex(pCurve->KeyGetTangentMode(lCount)) ];
                lOutputString += " | ";
                lOutputString += tangentWVMode[ TangentweightFlagToIndex(pCurve->KeyGet(lCount).GetTangentWeightMode()) ];
                lOutputString += " | ";
                lOutputString += tangentWVMode[ TangentVelocityFlagToIndex(pCurve->KeyGet(lCount).GetTangentVelocityMode()) ];
            }
            lOutputString += " ]";
            lOutputString += "\n";
            FBXSDK_printf (lOutputString);
        }
    }

    void DisplayListCurveKeys(FbxAnimCurve* pCurve, FbxProperty* pProperty)
    {
        FbxTime   lKeyTime;
        int     lKeyValue;
        char    lTimeString[256];
        FbxString lListValue;
        FbxString lOutputString;
        int     lCount;

        int lKeyCount = pCurve->KeyGetCount();

        for(lCount = 0; lCount < lKeyCount; lCount++)
        {
            lKeyValue = static_cast<int>(pCurve->KeyGetValue(lCount));
            lKeyTime  = pCurve->KeyGetTime(lCount);

            lOutputString = "            Key Time: ";
            lOutputString += lKeyTime.GetTimeString(lTimeString, FbxUShort(256));
            lOutputString += ".... Key Value: ";
            lOutputString += lKeyValue;
            lOutputString += " (";
            lOutputString += pProperty->GetEnumValue(lKeyValue);
            lOutputString += ")";

            lOutputString += "\n";
            FBXSDK_printf (lOutputString);
        }
    }