|
Tell us what you think of the site.
|
Autodesk Media & Entertainment User Community
|
Autodesk® 3ds Max®
|
|
Autodesk® Maya®
|
|
Autodesk® Softimage®
|
|
Autodesk® MotionBuilder®
|
|
Autodesk® Mudbox™
|
|
Autodesk® ImageModeler™
|
|
Autodesk® Sketchbook® Pro
|
|
Autodesk® Smoke on Mac®
|
| Problems with pNode->GetGlobalFromCurrentTake
|
|
|
I recently updated our fbx importer at work from using the 2006.11 SDK to now using the 2010.2 SDK.
After so mstruggle with the redesign way to get textures I got everything to work, or at least so I thought.
After doing some more testing I found out that the first time I load an FBX with animations everything looks fine. But if I load the same fbx a second time pNode->GetGlobalFromCurrentTake doesnt return the same matrix. The rotation part for each node is identical, but the translation of the matrix is totally different.
Whats even more weird is that i tried to make sure that the entire SDK is shut down and restarted between loading those 2 models, but the positions still come out wrong. This also applies if the models are 2 different models. The first one loads fine while the second one gets its matrices correclty rotated but with wrong translation. This was not happeneing in the old 2006.11 SDK and my code for grabbing the matrices have not changed.
I also tried using pNode->GetLocalTFromCurrentTake and that also gives the wrong translations the second time an fbx is loaded.
I am gonna do some more research into this but it only seems to apply to grabbing matrices from a take. Any of my hierarchial but not animated models seem to work just fine.
All this is used in our model viewing / conversion tool that converts from fbx to our game engine model format so its kinda important for us to get this working. If all else fails I guess i’ll have to go back to the 2006.11 SDK where everything worked ( and revert all my changes regarding texture fetching )
I could try all the SDK’s inbetween in an attempt to see if any of them works as expected.
// Edit
Tested against the 2009.3 SDK and there it works as it should. That is with me altering only 1 line of code and that was that the Initialize on the SDK Importer only takes a filename in the 2009.3 and takes filename + fileformat in 2010.2.
This makes me believe that the “error” is either something in the 2010.2 SDK or something that was previously destroyed automatically in older SDK’s but not in the 2010.2 SDK
I also did some more investigation using information in another post on how to grab the local position matrices for a node using the curves.
KFCurve* pCurveX = pNode->LclTranslation.GetKFCurve( KFCURVENODE_T_X, lCurrentTakeNodeName )
When comparing what this gives for my first node both times i get these differences:
First run:
mValue -0.11108135
mUpdateId 119
mFCurveKeysList fbxsdk_20102::KFCurveKey *
mValue -0.11108135
mLastSearchIndex 107
mCandidateValue -0.11108135
Second run:
mValue -0.035425175
mUpdateId 6
mFCurveKeysList fbxsdk_20102::KFCurveKey *
mValue -0.035425175
mLastSearchIndex 0
mCandidateValue -0.035425175
As one can clearly see the curve value is different teh second run, whats also interesting is that the updateID and the LastSearchIndex is also different the second run.
I compared it to the 2009.3 SDK and there all 3 of those was always identical the second, third, fouth run and so.
Does anyone have any idea what I might be doing wrong / fogetting or if this is actually some kind of bug in the SDK?
At least the 2009.3 SDK works so I’ll stick to that for now even if using the latest would have been prefeared since Tangents and Binormals was introduced in that one.
|
|
|
|
Hi Tomas,
I tested it by 2010.2 ImportScene sample.
Unfortunately, I can’t reproduce your problem:(
As far as I know, we really modified something around SDK manager and destroy behavior. As a result, the old code may need to be refactored.
I tested ImportScene with the following code, is it similar to your way?
I hope it can help you out.
KFbxSdkManager* lSdkManager = NULL;
KFbxScene* lScene = NULL;
//first run
// Prepare the FBX SDK.
InitializeSdkObjects(lSdkManager, lScene)
// Load the scene.
lResult = LoadScene(lSdkManager, lScene, argv[1])
DisplayAnimation(lScene)
// Destroy all objects created by the FBX SDK.
DestroySdkObjects(lSdkManager)
//once again
// Prepare the FBX SDK.
InitializeSdkObjects(lSdkManager, lScene)
// Load the scene.
lResult = LoadScene(lSdkManager, lScene, argv[1])
DisplayAnimation(lScene)
// Destroy all objects created by the FBX SDK.
DestroySdkObjects(lSdkManager)
Zhihao, Data Platform - Autodesk
|
|
|
|
I am doing alot of other stuff inbetween, but I can try to narrow down my code to the minimum ( while still having ot break ) hopefully I’ll be able to see what triggers the breaking. We temporarily solved it by using the 2009.3 SDK.
|
|
|
|
Done more indepth investigation and found the probable cause.
Ill paste my code down here for all to see
The first code is my code that starts up the SDK, grabs a KFCurve then shuts down the SDK again
I made a loop so it does this twice ( this is just test code to find the “bug” )
for( tgUInt32 i=0; i<2; ++i ) {
if( g_pApp->GetPluginFbx()->GetFbxScene()->Init( m_FilePath ) )
{
KFbxNode* pNode = g_ptgPluginFbx->GetFbxScene()->GetRootNode()->GetChild( 0 )
if( pNode )
{
KFCurve* pCurveX = pNode->LclTranslation.GetKFCurve( KFCURVENODE_T_X, g_ptgPluginFbx->GetFbxScene()->GetScene()->GetCurrentTakeName() )
if( pCurveX )
{
KTime Frame;
Frame.SetTime( 0, 0, 0, 0, 0, KTime::eCINEMA )
if( pCurveX )
tgLogPrint( "%f\n", ( tgFloat )pCurveX->Evaluate( Frame ) )
}
}
g_pApp->GetPluginFbx()->GetFbxScene()->Shutdown()
}
}
The rest of the code here is my init and shutdown functions for the FBX SDK
/*
====
Init
====
*/
tgBool tgCPluginFbxScene::Init( const tgChar* pFileName )
{
// Create the SDK manager
m_pSdkManager = KFbxSdkManager::Create()
if( m_pSdkManager )
{
tgSInt32 FileFormat = -1;
// Create the importer
m_pImporter = KFbxImporter::Create( m_pSdkManager, "" )
// Check which fileformat we are trying to load
if( !m_pSdkManager->GetIOPluginRegistry()->DetectFileFormat( pFileName, ( tgInt32& )FileFormat ) )
{
tgLogError( "Unknown file format\n" )
FileFormat = m_pSdkManager->GetIOPluginRegistry()->FindReaderIDByDescription( "FBX binary ( *.fbx )" )
}
// Create the scene
m_pScene = KFbxScene::Create( m_pSdkManager, "" )
// Set time mode to 24 fps
KTime::SetGlobalTimeMode( KTime::eCINEMA )
// Initialize the importer and set the desired fileformat
if( m_pImporter->Initialize( pFileName, FileFormat ) == TRUE )
{
// Import the scene
if( m_pImporter->Import( m_pScene ) == TRUE )
{
// Grab the root node and the pose
m_pRootNode = m_pScene->GetRootNode()
m_pPose = m_pScene->GetPoseCount() > 0 ? m_pScene->GetPose( 0 ) : NULL;
if( m_pRootNode )
{
// Convert model animations to use 24 fps
m_pRootNode->ResetPivotSetAndConvertAnimation( 24 )
// Grab all the takes
m_pScene->FillTakeNameArray( m_TakeNameArray )
// If there are more than 1 take we just grab the second one
if( m_TakeNameArray.GetCount() > 1 ) m_pScene->SetCurrentTake( m_TakeNameArray[ 1 ]->Buffer() )
else m_pScene->SetCurrentTake( m_TakeNameArray[ 0 ]->Buffer() )
return TRUE;
}
}
}
else
{
tgLogError( "Unable to open file %s\n", pFileName )
tgLogError( "Error reported: %s\n", m_pImporter->GetLastErrorString() )
}
}
else
{
tgLogError( "Unable to create the FBX SDK manager, the license may be expired\n" )
}
return FALSE; }
/*
========
Shutdown
========
*/ void tgCPluginFbxScene::Shutdown( void )
{
if( m_pSdkManager )
{
if( m_pScene )
{
m_pScene->Destroy()
m_pScene = NULL;
}
if( m_pImporter )
{
m_pImporter->Destroy()
m_pImporter = NULL;
}
m_pSdkManager->Destroy()
m_pSdkManager = NULL;
}
Clear()
}
Now here comes the fun part
What I DID find out is that if i DONT run this line of code:
m_pRootNode->ResetPivotSetAndConvertAnimation( 24 )
Then I get the wrong result both runs, with that line in there, its correct on first run, wrong on second. So if I were to GUESS whats wrong my first guess would be that the Animations actually isnt converted at all the second run. Actually, i tried changing the 24 to something else, but since I grab the info at Time 0 the I get the correct result the first run no matter what.
So to continue my first guess, it seems as if the PivotSet isnt Reset the second run.
Now I’d like someone from AutoDesk to speak their opinion on this.
|
|
|
|
Hi Tomas,
I tried your code. With my test scene, the results are always same:( with or without ResetPivotSetAndConvertAnimation.
I wonder your test scene are special, or more complicated than mine (at least).
would you please attach your sample FBX scene? Thank you.
Zhihao, Data Platform - Autodesk
|
|
|
|
I tested again with several of my animated models using the ImportScene sample with the code you pasted except i didnt call DisplayAnimation because i found something interesting before that was ran.
What I found was this:
First run:
FBX version number for this FBX SDK is 6.1.0
FBX version number for file fighter2.fbx is 6.1.0
Take Information
Number of takes: 1
Current take: "Take 001"
Take 0
Name: "Take 001"
Description: ""
Import Name: "Take 001"
Import State: true
Second run:
FBX version number for this FBX SDK is 6.1.0
FBX version number for file fighter2.fbx is 6.1.0
Take Information
Number of takes: 1
Current take: ""
Take 0
Name: "Take 001"
Description: ""
Import Name: "Take 001"
Import State: true
As you can see the second run did not get a default take. This is using the ImportScene sample with the code you pasted, so clearly the error is somewhere in the SDK.
I solved this now in our code by running this before calling ResetPivotSetAndConvertAnimation:
// Grab all the takes
m_pScene->FillTakeNameArray( m_TakeNameArray )
// If there are more than 1 take we just grab the second one if( m_TakeNameArray.GetCount() > 1 ) m_pScene->SetCurrentTake( m_TakeNameArray[ 1 ]->Buffer() ) else m_pScene->SetCurrentTake( m_TakeNameArray[ 0 ]->Buffer() )
But as I have stated earlier, this was not a problem in any of the previous SDK’s, and I assume that since the SDK does fill in a default take the first run, it should also do so on second, third, fourth run and so on.
-------------
Another thing I noticed thats an entirely different matter. In the 2006.11.1 SDK any nodes with identical names got renamed. One of the 3D artists had 2 joints in a scene named “joint27” and in the 2006.11.1 SDK the second got renamed to “joint27_cln1_1” or something like that. This did not happen in the 2010.2 SDK which caused us some trouble ( and took some time to figure out what the problem was ), now I solved it myself by checking all node names against eachother and renameing any duplicates, but is this feature still in there just that I need to call a function? Or was it removed entirely?
|
|
|
|
|
Hi, Tomas,
Yes I can reproduce the first problem by 2010.2 SDK, run twice, default take will be blank in the second time.
Good news is this bug is already fixed, but have to wait for next release for it.
Another thing is about renaming, sure SDK can handle it. It sounds like before the reader will rename duplicated names, but new reader does not do this job any more, so it need to be handled somewhere else. But I did not dig into very old code of 2006.11.1 yet, I will do more investigation and inform you if I get any news, , and it would be very helpful if you could describe more details on how you import FBX files.
Oh, by the way, you may also try this function KFbxSceneRenamer::ResolveNameClashing.
Thanks!
Author: Jiayang Xu
|
| Replied: 26 September 2009 03:43 PM
|
|
|
|
|
|
tgBool tgCPluginFbxScene::Init( const tgChar* pFileName )
{
// Create the SDK manager
m_pSdkManager = KFbxSdkManager::Create()
if( m_pSdkManager )
{
tgSInt32 FileFormat = -1;
// Create the importer
m_pImporter = KFbxImporter::Create( m_pSdkManager, "" )
// Check which fileformat we are trying to load
if( !m_pSdkManager->GetIOPluginRegistry()->DetectFileFormat( pFileName, ( tgInt32& )FileFormat ) )
{
tgLogError( "Unknown file format\n" )
FileFormat = m_pSdkManager->GetIOPluginRegistry()->FindReaderIDByDescription( "FBX binary ( *.fbx )" )
}
// Set the file format
m_pImporter->SetFileFormat( FileFormat )
// Create the scene
m_pScene = KFbxScene::Create( m_pSdkManager, "" )
// Set time mode to 24 fps
KTime::SetGlobalTimeMode( KTime::eCINEMA )
// Initialize the importer and set the desired fileformat
if( m_pImporter->Initialize( pFileName ) == TRUE )
{
// Import the scene
if( m_pImporter->Import( m_pScene ) == TRUE )
{
// Grab the root node and the pose
m_pRootNode = m_pScene->GetRootNode()
m_pPose = m_pScene->GetPoseCount() > 0 ? m_pScene->GetPose( 0 ) : NULL;
if( m_pRootNode )
{
tgUInt32 NumZeroSizeTriangles;
// Grab all the takes
m_pScene->FillTakeNameArray( m_TakeNameArray )
// If there are more than 1 take we just grab the second one
if( m_TakeNameArray.GetCount() > 1 ) m_pScene->SetCurrentTake( m_TakeNameArray[ 1 ]->Buffer() )
else m_pScene->SetCurrentTake( m_TakeNameArray[ 0 ]->Buffer() )
// Convert model animations to use 24 fps
m_pRootNode->ResetPivotSetAndConvertAnimation( 24 )
return TRUE;
}
}
}
else
{
tgLogError( "Unable to open file %s\n", pFileName )
tgLogError( "Error reported: %s\n", m_pImporter->GetLastErrorString() )
}
}
else
{
tgLogError( "Unable to create the FBX SDK manager, the license may be expired\n" )
}
return FALSE; }
That is how I setup and import the fbx, in previous SDK the nodes would have been renamed here already ( I think )
I tried that KFbxSceneRenamer::ResolveNameClashing but I found no information on how to use it or what each setting meant. The documentation only said “set to TRUE to enable this flag” .....
I did a rough guess on what was needed to be set but that failed, When importing a scene that usually takes about 40mb of memory to load I had to cancel the importing after 5 minutes because then it was up to 2Gb of memory usage, all due to that KFbxSceneRenamer::ResolveNameClashing thing.
So I wont use that again until there is information on how to use it.
Author: Tomas Jakobsson
|
| Replied: 29 September 2009 03:58 AM
|
|
|
|
|
Noone in the FBX SDK dev team know why this happends?
|
|
|
|
| Settings
| Choose Theme color:
|
|
|
|
|
|
|