void FBXMesh::Builder::unloadCacheRecursive(FbxNode * pNode) { // Unload the material cache const int lMaterialCount = pNode->GetMaterialCount(); for (int lMaterialIndex = 0; lMaterialIndex < lMaterialCount; ++lMaterialIndex) { FbxSurfaceMaterial * lMaterial = pNode->GetMaterial(lMaterialIndex); if (lMaterial && lMaterial->GetUserDataPtr()) { FBXMaterialCache* lMaterialCache = static_cast<FBXMaterialCache*>(lMaterial->GetUserDataPtr()); lMaterial->SetUserDataPtr(NULL); delete lMaterialCache; } } FbxNodeAttribute* lNodeAttribute = pNode->GetNodeAttribute(); if (lNodeAttribute) { // Unload the mesh cache if (lNodeAttribute->GetAttributeType() == FbxNodeAttribute::eMesh) { FbxMesh * lMesh = pNode->GetMesh(); if (lMesh && lMesh->GetUserDataPtr()) { #ifndef USE_META_DATA VBOMesh * lMeshCache = static_cast<VBOMesh *>(lMesh->GetUserDataPtr()); lMesh->SetUserDataPtr(NULL); delete lMeshCache; #else FbxMetaData * fbxMetaData = static_cast<FbxMetaData*>(lMesh->GetUserDataPtr()); lMesh->SetUserDataPtr(NULL); delete fbxMetaData; #endif } } // Unload the light cache else if (lNodeAttribute->GetAttributeType() == FbxNodeAttribute::eLight) { FbxLight * lLight = pNode->GetLight(); if (lLight && lLight->GetUserDataPtr()) { FBXLightCache* lLightCache = static_cast<FBXLightCache*>(lLight->GetUserDataPtr()); lLight->SetUserDataPtr(NULL); delete lLightCache; } } } const int lChildCount = pNode->GetChildCount(); for (int lChildIndex = 0; lChildIndex < lChildCount; ++lChildIndex) { unloadCacheRecursive(pNode->GetChild(lChildIndex)); } }
// Unload the cache and release the memory under this node recursively. void UnloadCacheRecursive(FbxNode * pNode) { // Unload the material cache const int lMaterialCount = pNode->GetMaterialCount(); for (int lMaterialIndex = 0; lMaterialIndex < lMaterialCount; ++lMaterialIndex) { FbxSurfaceMaterial * lMaterial = pNode->GetMaterial(lMaterialIndex); if (lMaterial && lMaterial->GetUserDataPtr()) { MaterialCache * lMaterialCache = static_cast<MaterialCache *>(lMaterial->GetUserDataPtr()); lMaterial->SetUserDataPtr(NULL); delete lMaterialCache; } } FbxNodeAttribute* lNodeAttribute = pNode->GetNodeAttribute(); if (lNodeAttribute) { // Unload the mesh cache if (lNodeAttribute->GetAttributeType() == FbxNodeAttribute::eMesh) { FbxMesh * lMesh = pNode->GetMesh(); if (lMesh && lMesh->GetUserDataPtr()) { VBOMesh * lMeshCache = static_cast<VBOMesh *>(lMesh->GetUserDataPtr()); lMesh->SetUserDataPtr(NULL); delete lMeshCache; } } // Unload the light cache else if (lNodeAttribute->GetAttributeType() == FbxNodeAttribute::eLight) { FbxLight * lLight = pNode->GetLight(); if (lLight && lLight->GetUserDataPtr()) { LightCache * lLightCache = static_cast<LightCache *>(lLight->GetUserDataPtr()); lLight->SetUserDataPtr(NULL); delete lLightCache; } } } const int lChildCount = pNode->GetChildCount(); for (int lChildIndex = 0; lChildIndex < lChildCount; ++lChildIndex) { UnloadCacheRecursive(pNode->GetChild(lChildIndex)); } }
// Bake node attributes and materials under this node recursively. // Currently only mesh, light and material. void LoadCacheRecursive(SceneContext* pSceneCtx, FbxNode * pNode, FbxAnimLayer * pAnimLayer, bool pSupportVBO) { // Bake material and hook as user data. const int lMaterialCount = pNode->GetMaterialCount(); for (int lMaterialIndex = 0; lMaterialIndex < lMaterialCount; ++lMaterialIndex) { FbxSurfaceMaterial * lMaterial = pNode->GetMaterial(lMaterialIndex); if (lMaterial && !lMaterial->GetUserDataPtr()) { FbxAutoPtr<MaterialCache> lMaterialCache(new MaterialCache); if (lMaterialCache->Initialize(lMaterial)) { lMaterial->SetUserDataPtr(lMaterialCache.Release()); } } } FbxNodeAttribute* lNodeAttribute = pNode->GetNodeAttribute(); if (lNodeAttribute) { // Bake mesh as VBO(vertex buffer object) into GPU. if (lNodeAttribute->GetAttributeType() == FbxNodeAttribute::eMesh) { FbxMesh * lMesh = pNode->GetMesh(); if (pSupportVBO && lMesh && !lMesh->GetUserDataPtr()) { FbxAutoPtr<VBOMesh> lMeshCache(new VBOMesh); if (lMeshCache->Initialize(pSceneCtx, lMesh)) { lMesh->SetUserDataPtr(lMeshCache.Release()); } } } // Bake light properties. else if (lNodeAttribute->GetAttributeType() == FbxNodeAttribute::eLight) { FbxLight * lLight = pNode->GetLight(); if (lLight && !lLight->GetUserDataPtr()) { FbxAutoPtr<LightCache> lLightCache(new LightCache); if (lLightCache->Initialize(lLight, pAnimLayer)) { lLight->SetUserDataPtr(lLightCache.Release()); } } } } const int lChildCount = pNode->GetChildCount(); for (int lChildIndex = 0; lChildIndex < lChildCount; ++lChildIndex) { LoadCacheRecursive(pSceneCtx, pNode->GetChild(lChildIndex), pAnimLayer, pSupportVBO); } }
void LoadMeshes(FbxNode* pFbxNode, packed_freelist<Mesh>& sceneMeshes) { // Material const uint32_t materialCount = pFbxNode->GetMaterialCount(); for (uint32_t i = 0; i < materialCount; ++i) { FbxSurfaceMaterial* pFbxMaterial = pFbxNode->GetMaterial(i); if (pFbxMaterial && !pFbxMaterial->GetUserDataPtr()) { FbxAutoPtr<Material> pMaterial(new Material); if (pMaterial->init(pFbxMaterial)) { pFbxMaterial->SetUserDataPtr(pMaterial.Release()); } } } FbxNodeAttribute* nodeAttribute = pFbxNode->GetNodeAttribute(); if (nodeAttribute) { // Mesh if (nodeAttribute->GetAttributeType() == FbxNodeAttribute::eMesh) { FbxMesh* pFbxMesh = pFbxNode->GetMesh(); if (pFbxMesh && !pFbxMesh->GetUserDataPtr()) { Mesh mesh; if (mesh.init(pFbxMesh)) { sceneMeshes.insert(mesh); } // TODO: FbxAutoPtr<Mesh> pMesh(new Mesh); if (pMesh->init(pFbxMesh)) { pFbxMesh->SetUserDataPtr(pMesh.Release()); } } } // Light else if (nodeAttribute->GetAttributeType() == FbxNodeAttribute::eLight) { FbxLight* pFbxLight = pFbxNode->GetLight(); if (pFbxLight && !pFbxLight->GetUserDataPtr()) { FbxAutoPtr<Light> pLight(new Light); if (pLight->init(pFbxLight)) { pFbxLight->SetUserDataPtr(pLight.Release()); } } } } const int childCount = pFbxNode->GetChildCount(); for (int i = 0; i < childCount; ++i) { LoadMeshes(pFbxNode->GetChild(i), sceneMeshes); } }