#include <fbxsdk/scene/animation/fbxanimcurve.h>
#include <fbxsdk/scene/animation/fbxanimcurvenode.h>
#include <fbxsdk/scene/animation/fbxanimlayer.h>
#include <fbxsdk/scene/fbxscene.h>
#include <fbxsdk/core/fbxmanager.h>
#include <fbxsdk/core/fbxpropertydef.h>
#include <fbxsdk/fileio/fbximporter.h>
#include <fbxsdk/fileio/fbxexporter.h>
#include "ortool_fcurveeditor_tool.h"
#define ORTOOLTEMPLATE__CLASS ORTOOLTEMPLATE__CLASSNAME
#define ORTOOLTEMPLATE__LABEL "FCurveEditor"
#define ORTOOLTEMPLATE__DESC "FBSDK - Tool FCurve Editor Description"
ORTOOLTEMPLATE__LABEL,
ORTOOLTEMPLATE__DESC,
bool ORTool_FCurveEditor::FBCreate()
{
mPropertyFromFBSDKFromProperty =
NULL;
mPropertyFromFBSDKFromANode =
NULL;
mPropertyFromFBSDKOutsideEditor =
NULL;
mPropertyFromFBXSDKProperty =
NULL;
StartSize[0] = 800;
StartSize[1] = 500;
int lB = 10;
int lW = 200;
int lH = 18;
AddRegion( "Label", "Label",
SetControl( "Label", mLabel );
mLabel.Caption = "Custom curve shown in FCurveEditor";
AddRegion( "Delete", "Delete",
SetControl( "Delete", mExternalFCurveButton );
mExternalFCurveButton.Caption = "Add new property";
mExternalFCurveButton.OnClick.Add(
this, (
FBCallback) &ORTool_FCurveEditor::EventExternalFCurveClick);
mExternalFCurveButtonState = 0;
AddRegion( "FCurveInteractionButton", "FCurveInteractionButton",
SetControl( "FCurveInteractionButton", mPropertyAndKeyButton );
mPropertyAndKeyButton.Caption = "Frame All";
mPropertyAndKeyButton.OnClick.Add(
this, (
FBCallback) &ORTool_FCurveEditor::EventPropertyAndKeyClick);
mPropertyAndKeyButtonButtonState = 0;
mEditor = new FBFCurveEditor();
AddRegion("FCurveEditor","FCurveEditor",
SetControl("FCurveEditor",mEditor);
mNull = new FBModelNull("Source Object for curve");
mNull->Show = true;
FBTime lTime = FBTime(0);
mNull->Translation.SetAnimated(true);
mNull->Translation.GetAnimationNode()->KeyAdd(lTime, lPos.mValue);
mNull->Rotation.SetAnimated(true);
mNull->Rotation.GetAnimationNode()->KeyAdd(lTime, lR.mValue);
FBAnimationLayer* lLayer = FBSystem().CurrentTake->GetLayer(1);
if(!lLayer)
{
FBSystem().CurrentTake->CreateNewLayer();
lLayer = FBSystem().CurrentTake->GetLayer(1);
}
FBSystem().CurrentTake->SetCurrentLayer(1);
mNull->Translation.SetAnimated(true);
mNull->Translation.GetAnimationNode()->KeyAdd(lTime, lPosLayer1.mValue);
lTime.SetSecondDouble(5.0);
mNull->Translation.GetAnimationNode()->KeyAdd(lTime, lPosLayer2.mValue);
mNull->Rotation.SetAnimated(true);
mNull->Rotation.GetAnimationNode()->KeyAdd(lTime, lRLayer1.mValue);
mPropertyFromFBSDKFromANode = FBFCurveEditorUtility::TheOne().AddExternalCurves(
"FCurveDummyNode",
"TestProp",
kFBPT_Vector3D, mNull->Translation.GetAnimationNode());
mPropertyFromFBSDKFromProperty = FBFCurveEditorUtility::TheOne().AddExternalCurves("FCurveDummyNode", "TestPropFromProp", (FBProperty*)&mNull->Translation);
mPropertyFromFBSDKOutsideEditor = FBFCurveEditorUtility::TheOne().AddExternalCurves(
"FCurveDummyNode",
"TestPropInOutsideEditor",
kFBPT_Vector3D, mNull->Translation.GetAnimationNode(), mEditor);
FbxManager *lSdkManager = FBXSDK_NAMESPACE::FbxManager::Create();
FbxIOSettings * ios = FbxIOSettings::Create(lSdkManager, IOSROOT );
mScene = FBXSDK_NAMESPACE::FbxScene::Create(lSdkManager,"");
FbxImporter* lImporter = FbxImporter::Create(lSdkManager, "");
#ifdef KARCH_ENV_WIN
lImporter->Initialize("C:\\cube.fbx", -1, ios);
#else
lImporter->Initialize("/var/tmp/cube.fbx", -1, ios);
#endif
lImporter->Import(mScene);
lImporter->Destroy();
FbxNode* lObject = mScene->FindNodeByName("Cube");
if(lObject)
{
mPropertyFromFBXSDKProperty = FBFCurveEditorUtility::TheOne().AddExternalCurves(lObject->GetName(), "Lcl Translation", &lObject->LclTranslation, mScene->GetCurrentAnimationStack());
}
mNull->Selected = true;
mNull->Translation.SetFocus(true);
mNull->Translation.GetAnimationNode()->Nodes[0]->FCurve->KeySetSelected(0, true);
FBFCurveEditorUtility::TheOne().RegisterToFCurveEditorEvent(
this, (
FBCallback)&ORTool_FCurveEditor::EventFCurveEditorEvent);
return true;
}
void ORTool_FCurveEditor::FBDestroy()
{
FBFCurveEditorUtility::TheOne().UnregisterToFCurveEditorEvent(
this, (
FBCallback)&ORTool_FCurveEditor::EventFCurveEditorEvent);
}
{
FBFCurveEditorEvent lEvent(pEvent);
{
FBTrace(
"FBFCurveEditorEvent received: kFBGhostKeep\n" );
}
{
FBTrace(
"FBFCurveEditorEvent received: kFBGhostSwap\n" );
}
{
FBTrace(
"FBFCurveEditorEvent received: kFBGhostClear\n" );
}
else
{
FBTrace(
"FBFCurveEditorEvent received: kFBUnspecified\n" );
}
}
void ORTool_FCurveEditor::EventPropertyAndKeyClick(
HISender pSender,
HKEvent pEvent )
{
mPropertyAndKeyButtonButtonState++;
switch(mPropertyAndKeyButtonButtonState)
{
case 0:
break;
case 1:
{
FBFCurveEditorUtility::TheOne().Frame(false);
mPropertyAndKeyButton.Caption = "Get the time span";
}
break;
case 2:
{
FBTimeSpan lTS = FBFCurveEditorUtility::TheOne().GetTimeSpan();
FBTrace(
"Time span retrieved:\n - Start time: %s\n - Stop time: %s\n", lTS.GetStart().GetTimeString(), lTS.GetStop().GetTimeString() );
mPropertyAndKeyButton.Caption = "Set the time span from 0 to 8 seconds";
}
break;
case 3:
{
FBTime lEightSeconds;
lEightSeconds.SetSecondDouble(8);
FBTimeSpan lNewTS(0, lEightSeconds);
FBFCurveEditorUtility::TheOne().SetTimeSpan(lNewTS);
mPropertyAndKeyButton.Caption = "Get the selected properties";
}
break;
case 4:
{
FBArrayTemplate<FBProperty *> lPropArray;
FBFCurveEditorUtility::TheOne().GetProperties(lPropArray, true);
int lNbProps = lPropArray.GetCount();
FBTrace(
"Selected Properties Count: %d\n", lNbProps );
for(
int i = 0;
i < lNbProps;
i++ )
FBTrace(
" - %s\n", lPropArray[
i ]->GetName() );
mPropertyAndKeyButton.Caption = "Get the objects";
}
break;
case 5:
{
FBArrayTemplate<FBComponent *> lObjectArray;
FBFCurveEditorUtility::TheOne().GetObjects(lObjectArray);
int lNbObjects = lObjectArray.GetCount();
FBTrace(
"Objects Count: %d\n", lNbObjects );
for(
int i = 0;
i < lNbObjects;
i++ )
FBTrace(
" - %s\n", lObjectArray[
i ]->GetFullName() );
mPropertyAndKeyButton.Caption = "Get the selected curve components";
}
break;
case 6:
{
FBArrayTemplate<FBProperty *> lPropArray;
FBFCurveEditorUtility::TheOne().GetProperties(lPropArray, true);
FBArrayTemplate<FBFCurve *> lFBFCurveArray;
FBStringList lFCurvesNames;
for(
int i = 0;
i < lPropArray.GetCount();
i++)
{
FBPropertyAnimatable* lAnimProp = (FBPropertyAnimatable*)lPropArray.GetAt(
i);
if( lAnimProp->GetAnimationNode() )
{
if(lAnimProp->GetAnimationNode()->FCurve && lAnimProp->IsFocused())
{
lFBFCurveArray.Add(lAnimProp->GetAnimationNode()->FCurve);
lFCurvesNames.Add(lAnimProp->GetName());
}
else
{
int lNodeCount = lAnimProp->GetAnimationNode()->Nodes.GetCount();
for(int lCurveIter = 0; lCurveIter < lNodeCount; lCurveIter++)
{
if(lAnimProp->IsFocused() || lAnimProp->IsFocusedChild(lCurveIter))
{
lFBFCurveArray.Add(lAnimProp->GetAnimationNode()->Nodes[lCurveIter]->FCurve);
char lCurveName[ 1024 ];
sprintf_s( lCurveName,
"%s (child %d)", lAnimProp->GetName(), lCurveIter );
lFCurvesNames.Add( lCurveName );
}
}
}
}
}
int lNbCurves = lFBFCurveArray.GetCount();
FBTrace(
"Curves Count: %d\n", lNbCurves );
for(
int i = 0;
i < lNbCurves;
i++ )
FBTrace(
" - %s\n", lFCurvesNames[
i ]);
mPropertyAndKeyButton.Caption = "Select the first property/component";
}
break;
case 7:
{
FBArrayTemplate<FBProperty *> lPropArray;
FBFCurveEditorUtility::TheOne().GetProperties(lPropArray, true);
for(
int i = 0;
i < lPropArray.GetCount();
i++)
{
FBPropertyAnimatable* lAnimProp = (FBPropertyAnimatable*)lPropArray.GetAt(
i);
lAnimProp->SetFocus( false );
}
FBFCurveEditorUtility::TheOne().GetProperties(lPropArray, false);
if(lPropArray.GetCount())
{
FBPropertyAnimatable* lAnimProp = (FBPropertyAnimatable*)lPropArray.GetAt(0);
lAnimProp->SetFocusChild(0, true);
}
mPropertyAndKeyButton.Caption = "Key the first property/component";
}
break;
case 8:
{
FBArrayTemplate<FBProperty *> lPropArray;
FBFCurveEditorUtility::TheOne().GetProperties(lPropArray, false);
if(lPropArray.GetCount())
{
FBPropertyAnimatable* lAnimProp = (FBPropertyAnimatable*)lPropArray.GetAt(0);
lAnimProp->KeyAt( FBTime(0,0,0,0) );
lAnimProp->KeyAt( FBTime(0,0,0,5) );
if(lAnimProp->GetAnimationNode()->FCurve)
{
lAnimProp->GetAnimationNode()->FCurve->KeySetSelected(0, true);
lAnimProp->GetAnimationNode()->FCurve->KeySetSelected(1, true);
}
else
{
if(lAnimProp->GetAnimationNode()->Nodes.GetCount())
{
lAnimProp->GetAnimationNode()->Nodes[0]->FCurve->KeySetSelected(0, true);
lAnimProp->GetAnimationNode()->Nodes[0]->FCurve->KeySetSelected(1, true);
}
}
}
mPropertyAndKeyButton.Caption = "Frame selected keys";
}
break;
case 9:
{
FBFCurveEditorUtility::TheOne().Frame( true );
mPropertyAndKeyButton.Caption = "Done";
}
break;
}
}
void ORTool_FCurveEditor::EventExternalFCurveClick(
HISender pSender,
HKEvent pEvent )
{
mExternalFCurveButtonState++;
switch(mExternalFCurveButtonState)
{
case 0:
break;
case 1:
mPropertyFromFBSDKAddedAfter = FBFCurveEditorUtility::TheOne().AddExternalCurves(
"FCurveDummyNode",
"TestPropRotation",
kFBPT_Vector3D, mNull->Rotation.GetAnimationNode());
mExternalFCurveButton.Caption = "Update Custom Curves";
break;
case 2:
{
FBFCurveEditorUtility::TheOne().UpdateCurves(mPropertyFromFBSDKAddedAfter, mNull->Rotation.GetAnimationNode());
FbxNode* lObject = mScene->FindNodeByName("Cube");
if(lObject)
{
FbxTime lTime;
lTime.SetSecondDouble(5.0);
lObject->LclTranslation.GetCurveNode(false)->GetCurve(0)->KeyAdd(lTime);
FBFCurveEditorUtility::TheOne().UpdateCurves(mPropertyFromFBXSDKProperty, &lObject->LclTranslation,
NULL);
}
mExternalFCurveButton.Caption = "Get Custom Curves";
}
break;
case 3:
{
FBFCurveEditorUtility::TheOne().GetCurves(mPropertyFromFBSDKAddedAfter, mNull->Translation.GetAnimationNode());
FbxNode* lObject = mScene->FindNodeByName("Cube");
if(lObject)
{
FBSystem().CurrentTake->SetCurrentLayer(0);
FBTime lTime;
lTime.SetFrame(70);
FBPropertyAnimatable* lAnimProp = (FBPropertyAnimatable*)mPropertyFromFBXSDKProperty;
if( lAnimProp->GetAnimationNode() )
lAnimProp->GetAnimationNode()->KeyAdd(lTime, lPos.mValue);
FBSystem().CurrentTake->SetCurrentLayer(1);
lTime.SetFrame(50);
lAnimProp = (FBPropertyAnimatable*)mPropertyFromFBXSDKProperty;
if( lAnimProp->GetAnimationNode() )
lAnimProp->GetAnimationNode()->KeyAdd(lTime, lPos.mValue);
FBFCurveEditorUtility::TheOne().GetCurves(mPropertyFromFBXSDKProperty, &lObject->LclTranslation, mScene->GetCurrentAnimationStack());
FbxManager *lSdkManager = FBXSDK_NAMESPACE::FbxManager::Create();
FbxIOSettings * ios = FbxIOSettings::Create(lSdkManager, IOSROOT );
FbxExporter* lExporter = FbxExporter::Create(lSdkManager, "FBXExporter");
#ifdef KARCH_ENV_WIN
lExporter->Initialize("C:\\Exported_cube.fbx", -1, ios);
#else
lExporter->Initialize("/var/tmp/Exported_cube.fbx", -1, ios);
#endif
lExporter->Export(mScene);
lExporter->Destroy();
}
mExternalFCurveButton.Caption = "Delete Custom Object";
}
break;
case 4:
if(mPropertyFromFBSDKFromProperty)
{
FBFCurveEditorUtility::TheOne().RemoveExternalCurves(mPropertyFromFBSDKFromProperty);
mPropertyFromFBSDKFromProperty =
NULL;
}
if(mPropertyFromFBSDKFromANode)
{
FBFCurveEditorUtility::TheOne().RemoveExternalCurves(mPropertyFromFBSDKFromANode);
mPropertyFromFBSDKFromANode =
NULL;
}
if(mPropertyFromFBSDKOutsideEditor)
{
FBFCurveEditorUtility::TheOne().RemoveExternalCurves(mPropertyFromFBSDKOutsideEditor);
mPropertyFromFBSDKOutsideEditor =
NULL;
}
if(mPropertyFromFBSDKAddedAfter)
{
FBFCurveEditorUtility::TheOne().RemoveExternalCurves(mPropertyFromFBSDKAddedAfter);
mPropertyFromFBSDKAddedAfter =
NULL;
}
if(mPropertyFromFBXSDKProperty)
{
FBFCurveEditorUtility::TheOne().RemoveExternalCurves(mPropertyFromFBXSDKProperty);
mPropertyFromFBXSDKProperty =
NULL;
}
mExternalFCurveButton.Caption = "Done";
break;
}
}