Jump to content
  • Advertisement
Sign in to follow this  
barzorx

FBXSDK (C++) Animation from multiple files, Texturizing...

This topic is 986 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hello everyone! I am new to FBXSDK, and I asked over their forums about how to properly use their SDK to learn, with no success. Most times I search online, I cant find information I need. I have a lot of things I want to learn, specifically texturizing a model and animating a 3D model, but for now I'd like to focus on just animating.

 

I currently managed to load, and display a mesh, its bones, and scroll through the animations within one FBX files successfuly. That is, in one single fbx file (for example, in their sample humanoid.fbx file), I can load it, and scroll through its animations, display everything, etc. The way I do this is by switching the TakeInfo. as such:

 

FbxAnimStack * lCurrentAnimationStack = modelScene->FindMember<FbxAnimStack>(mAnimStackArray[currentAnimation]->Buffer());
 
mCurrentAnimLayer = lCurrentAnimationStack->GetMember<FbxAnimLayer>();
 
modelScene->SetCurrentAnimationStack(lCurrentAnimationStack);
 
FbxTakeInfo* lCurrentTakeInfo = modelScene->GetTakeInfo(*(mAnimStackArray[currentAnimation]));
 
 
if (lCurrentTakeInfo)
{
mStart = lCurrentTakeInfo->mLocalTimeSpan.GetStart();
mStop = lCurrentTakeInfo->mLocalTimeSpan.GetStop();
}
else
{
// Take the time line value
FbxTimeSpan lTimeLineTimeSpan;
modelScene->GetGlobalSettings().GetTimelineDefaultTimeSpan(lTimeLineTimeSpan);
 
mStart = lTimeLineTimeSpan.GetStart();
mStop = lTimeLineTimeSpan.GetStop();
}
 
mCurrentTime = mStart;

 

 

Which works nicely. No textures yet, but one step at a time.

 

Now, I am trying to get one FBX file which only contains the bind pose (mesh, skeleton, etc), to use the animations found throughout a bunch of other FBX files. That is in file A I have just the bind pose, fileB has walk, file C has run, fileD has attack, and so on.

 

The way I thought to do it was by merging scenes, but I couldn't quite get it. A friend suggested me to make my own class to hold all of the nodes per animation, and then use that to draw, etc. I believe my friend's approach to be the best (since I can then control if i want a certain animation, pose, or w/e in or out) but maybe a little bit too complicated at the point I am in right now when it comes to understanding FBXSDK.

 

Right now I have modelScene as "FileA" - the bind pose. Then, I load tempScene as "FileB" - the next animation. I import the animations with 

modelScene = FbxScene::Create(manager,"model")

importer->Import(modelScene)

and

tempScene = FbxScene::Create(manager, "temp");

importer->Import(tempScene)

 

 

 

My first attempt at merging them was with this code:

 

/*
int lNumSceneObjects = tempScene->GetSrcObjectCount();
for (int i = 0; i < lNumSceneObjects; i++) {
FbxObject* lObj = tempScene->GetSrcObject(i);
if (lObj == tempScene->GetRootNode() || *lObj == tempScene->GetGlobalSettings()){
continue;
}
lObj->ConnectDstObject(modelScene);
}
tempScene->DisconnectAllSrcObject();
*/

 

 

But, no success.  My second attempt had me creating manually the AnimStack, AnimLayer in modelScene, and then go through tempScene's nodes and when a node had a translation, rotation, or scaling in one of those, copy that curve into modelScene.

 

FbxString lAnimStackName = "Take002";
FbxAnimStack* lAnimStack = FbxAnimStack::Create(modelScene, lAnimStackName);
FbxAnimLayer* lAnimLayer = FbxAnimLayer::Create(modelScene, "Base Layer");
lAnimStack->AddMember(lAnimLayer);
 
CopyAnimationCurvesFrom(lAnimLayer, tempScene);
 
....
 
void Model::CopyAnimationCurvesFrom(FbxAnimLayer* layer, FbxScene* scene)
{
for (int i = 0; i < scene->GetSrcObjectCount<FbxAnimStack>(); i++)
{
FbxAnimStack* lAnimStack = scene->GetSrcObject<FbxAnimStack>(i);
 
int nbAnimLayers = lAnimStack->GetMemberCount<FbxAnimLayer>();
 
for (int l = 0; l < nbAnimLayers; l++)
{
FbxAnimLayer* lAnimLayer = lAnimStack->GetMember<FbxAnimLayer>(l);
 
FbxAnimCurve* lAnimCurve = NULL;
 
int lChildCount = scene->GetRootNode()->GetChildCount();
for (int lChildNodes = 0; lChildNodes < lChildCount; lChildNodes++)
{
// All 3 produce same result: nothing
lAnimCurve = scene->GetRootNode()->GetChild(lChildNodes)->LclTranslation.GetCurve(lAnimLayer, false);
if (lAnimCurve)
{
FBXSDK_printf("        TRANSLATION\n");
//lAnimCurve = modelScene->GetRootNode()->GetChild(lChildNodes)->LclTranslation.GetCurve(layer, true);
//modelScene->GetRootNode()->GetChild(lChildNodes)->LclTranslation.ConnectSrcObject(lAnimCurve);
//lAnimCurve->ConnectDstObject(modelScene->GetRootNode()->GetChild(lChildNodes)->LclTranslation.GetCurve(layer,true));
}
lAnimCurve = scene->GetRootNode()->GetChild(lChildNodes)->LclScaling.GetCurve(lAnimLayer, false);
if (lAnimCurve)
{
FBXSDK_printf("        SCALING\n");
//lAnimCurve = modelScene->GetRootNode()->GetChild(lChildNodes)->LclScaling.GetCurve(layer, true);
//modelScene->GetRootNode()->GetChild(lChildNodes)->LclScaling.ConnectSrcObject(lAnimCurve);
//lAnimCurve->ConnectDstObject(modelScene->GetRootNode()->GetChild(lChildNodes)->LclScaling.GetCurve(layer, true));
}
lAnimCurve = scene->GetRootNode()->GetChild(lChildNodes)->LclRotation.GetCurve(lAnimLayer, false);
if (lAnimCurve)
{
FBXSDK_printf("        ROTATION\n");
//lAnimCurve = modelScene->GetRootNode()->GetChild(lChildNodes)->LclRotation.GetCurve(layer, true);
//modelScene->GetRootNode()->GetChild(lChildNodes)->LclRotation.ConnectSrcObject(lAnimCurve);
//lAnimCurve->ConnectDstObject(modelScene->GetRootNode()->GetChild(lChildNodes)->LclRotation.GetCurve(layer, true));
 
}
}
 
}
 
}
}
 

 

 

Can anyone guide me, just give me a hint towards the right thing to do? If required, I can post the entire code.

 

Thanks in advance

-Daniel

Share this post


Link to post
Share on other sites
Advertisement

I posted an FBX parser and viewer a while ago.   You can see how I did it here:  https://code.google.com/p/fbxviewer/

 

Thank you very much. I'll take a good look at it!

 

-Daniel

 

//edit

 

So, I've been reading your code for about an hour and, it's absolutely impressive. However, my problem is as I mentioned, I'm fairly new to FBXSDK, and the project itself is far far too much for me to digest at this point in time (I feel). I'll try to keep reading and see if I can understand it, but do or don't that's my problem, not yours. In the end, all I want to understand is how to properly merge two scenes so I can view animations. However what I meant by that is, its one character that holds multiple animations spread over multiple files. The way I'm doing things is fairly simple, importer loads the scene, I check for the animation array stack/take Info, and then recursively draw the mesh/bones (DrawMesh(pNode, pTime, pAnimLayer, lGlobalOffsetPosition, pPose);). When its all in one single file, I can scroll through the animations my switching the animation stack, layer, and take info, and that's about it. 

 

From what I can see here, you're importing every bone, mesh, etc, which is (i believe) the proper and best way to work with FBXSDK. But I don't feel I know enough to be able to just "jump into code" of this caliber and simply understand things. 

 

Again, thank you very much, and maybe with enough time this is the right way, but I think that right now this will just confuse me rather than teach me.

Edited by barzorx

Share this post


Link to post
Share on other sites

Alright, I'm still stumped. I keep trying things to merge scenes properly, but no success. Anyone knows where I could read or find more samples/documentation/tutorials other than the autodesk FBXSDKs?

Share this post


Link to post
Share on other sites
Why are you trying to merge this data into a single FBX scene?
If this is for a game, why aren’t you exporting both scenes to your own engine’s/game’s model/animation formats and loading them from there?


L. Spiro

Share this post


Link to post
Share on other sites

Hi Spiro,

 

First of all thanks for replying. Although currently this is not for a game, or an engine, eventually i'd like to build something like that. However, currently I do not understand nearly enough on how to work with FBX to simply "start building my own structures, and exporting them into there". I understand so far what the (poor) FBXSDK documentation has. I can load the scene, I can draw it by going recursively through its nodes, detecting if its a bone/mesh, and in case of meshes recursively draw, calculate deformations/skinning, and then i can play the animations by simply switching the animation stack/take.

 

Right now, I still can't texturize. And to make things worse, if the animation of a character is spread through multiple files, I don't understand how to play them from different files. That's why first I wanted to try and learn how to merge the scenes - I thought somehow by merging only the animations, I could achieve what I already achieved when all animations are in one single file (like with humanoid.fbx, which comes with the sample).

 

If making my own structure and exporting to it is the best way to achieve this, then I'll do that. However, I still do not know nearly enough about FBX to properly do this. By that I mean, I understand there are kinds of nodes, there is a structure that holds all nodes, and I suppose I'd have to create a high level container (model, perhaps) which contains a set of nodes for mesh, skeleton... animation maybe? light... but I still don't know enough to be able to confidently start writing this high level container (and its inner containers).

 

If you know of any page I could read on how to do this properly I'd appreciate it, very much. I really want to learn how to properly do this, but there aren't many resources online.

 

Thanks

Daniel

Share this post


Link to post
Share on other sites
A proper pipeline is:
Maya -> FBX -> Your Own Format -> Game
 
At no point is it ever useful to learn how to build FBX files with the SDK; always let Maya or 3DS Max do that for you during export.
Merging FBX files is as simple as loading them into Maya or 3DS Max and exporting them as a single scene.  If your goal is to make games etc. then you are wasting a significant amount of time on this obviously non-trivial problem, only to scrap it all once you begin your actual game project.
 
I primarily use FBX files in my pipeline and at the company where I work we have used them for major tech demos, and at no point has any of us ever modified an FBX scene through the SDK.
In the world of games, FBX files are read-only and for the purpose of creating your own file format.
 
 

If making my own structure and exporting to it is the best way to achieve this, then I'll do that. However, I still do not know nearly enough about FBX to properly do this. By that I mean, I understand there are kinds of nodes, there is a structure that holds all nodes, and I suppose I'd have to create a high level container (model, perhaps) which contains a set of nodes for mesh, skeleton... animation maybe? light... but I still don't know enough to be able to confidently start writing this high level container (and its inner containers).

But at least you will be able to ask questions and you will be going down a fruitful road.
I can’t help you merge FBX files via the SDK. No one can. No one does that.
Besides that, you seem equally (or more) unprepared to handle merging of FBX scenes. If both tasks are daunting then you may as well pick the relevant one.


L. Spiro

Share this post


Link to post
Share on other sites

Thank you again for replying so quickly.

 

It is clear now that bothering with learning how to merge scenes, etc, is going to be useless and that I should instead focus in extracting information and then using it from there.

 

I hope I am not being a bother then by asking, how would I go about extracting relevant information from the FBX files? I am of course assuming that loading scene>going through the nodes is still very much required, but what would be the proper way to create a struct (or well, class[es])? I realize this is a very complex question - not one you can just write in one answer, but any guidance on this matter would be really appreciated. 

 

I can only -guess- to an extent some details. For example a struct/class that would hold bone information, another one for mesh, light, etc, and then a higher level struct/class to keep everything tidy. I've never tackled this with FBX - though I did simply stuff with .obj (which we can agree is much more simplified specially without animations etc), so any advice, or if you know links where I could read about would be great.

 

If you think it's too much to tackle though I'll understand.

 

-Daniel

Share this post


Link to post
Share on other sites
You should start a new thread for asking new questions.

My flow, which is typical, is to extract all the information from the FBX file via the SDK, store it all in your own custom structures, and then export those structures. There are no rules. Your classes can take inspiration from the FBX SDK. Have a mesh class, then a mesh instance, then a model (or scene) class which contains all of those mesh instances, plus classes for lights, cameras, etc. Same with animations. A track class, etc.


L. Spiro

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!