NickHardeman / ofxFBX

FBX SDK addon for OpenFrameworks
MIT License
111 stars 34 forks source link

Removing models from a scene? #6

Closed Bentleyj closed 5 years ago

Bentleyj commented 8 years ago

Hey Nick,

Loving your work!

I'd like to use one ofxFBXScene object and one ofxFBXManager object to dynamically load .fbx files. The problem I'm experiencing is that as I load new models and add the to the scene by calling scene.load(filePath, settings) and then manager.setup( &scene ) they just stack up on top of each other.

How would you recommend doing this? I was thinking of adding something like an "unload" method to the scene class, or perhaps the best way is to use multiple scene objects. Do you have a recommendation? I'm currently working on the unload method route trying to get to something that works. Let me know!

Bentleyj commented 8 years ago

I've added this method:

//-------------------------------------------------------------- void ofxFBXScene::unloadModels() { bones.clear(); meshes.clear(); clusters.clear(); skeletons.clear(); animations.clear(); fbxFilePath = ""; }

And it seems to be working fine, can you comment on whether or not this will cause some problems with memory?

Bentleyj commented 8 years ago

I have now ammended to this because I don't think that vector::clear deleted the resources pointed to by the pointers, now it looks like this:

//-------------------------------------------------------------- void ofxFBXScene::unloadModels() { for(auto it = bones.begin(); it != bones.end(); it++) { it->reset(); } for(auto it = meshes.begin(); it != meshes.end(); it++) { it->reset(); } for(auto it = clusters.begin(); it != clusters.end(); it++) { it->reset(); } for(auto it = skeletons.begin(); it != skeletons.end(); it++) { it->reset(); } bones.clear(); meshes.clear(); clusters.clear(); skeletons.clear(); animations.clear(); fbxFilePath = ""; }

NickHardeman commented 8 years ago

Hi @Bentleyj,

I made the ofxFBXScene class with the idea that it holds all of the resources. The ofxFBXManager has pointers to all of the resources in the ofxFBXScene class. That way the resources only take up memory once (in the scene class). The draw calls are faster because all of the resources are uploaded to the GPU already in the ofxFBXScene class. I usually have a single ofxFBXScene class and many instances of the ofxFBXManager class if you want to have many of the same 3d models.

Is there a reason that you want to use only one ofxFBXScene for loading and unloading resources?

Remember that the ofxFBXManager needs the ofxFBXScene to function properly. So make sure to delete all of the ofxFBXManagers first before deleting the ofxFBXScene, since it references the resources in ofxFBXScene. Or put a check in the ofxFBXManager class to determine if the scene is NULL.

Best, Nick

Bentleyj commented 8 years ago

Thanks a million for the insight Nick,

The only reason I wanted to do it that way was I have inherited a project that just loads a single model and I wanted it to load and unload models. It made it easier for me to keep the original architecture and just load and unload the model whenever I like.

So your advice is: 1 ofxFBXScene per model and one ofxFBXManager per draw instance of the scene? So the best way in your eyes is to just load multiple ofxFBXScenes and give them each a manager and then reference the correct one for each different model? If I've understood that correctly I may indeed implement it if I have the time!

Thanks again for the speedy reply!

NickHardeman commented 8 years ago

"So your advice is: 1 ofxFBXScene per model and one ofxFBXManager per draw instance of the scene?" Correct, a different ofxFBXScene for each unique model and one ofxFBXManager per draw instance. You could implement a caching system if you didn't want to restructure the code that would store the ofxFBXScene instances so they wouldn't have to be persistent and it shouldn't change the structure too much.