#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;
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);
}
}
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);
}
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);
}
}
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);
}
}
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);
}
}
}
}
}
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);
}
}
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);
}
}