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)); } }
// 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); } }
// 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)); } }
void FbxUtil::LoadLight(const SceneNode::Ptr &ntNode, FbxNode *fbxNode) { FbxLight *fbxLight = static_cast<FbxLight*>(fbxNode->GetNodeAttribute()); LightType type; switch (fbxLight->LightType.Get()) { case FbxLight::EType::eDirectional: type = LightType::DIRECTIONAL; break; case FbxLight::EType::ePoint: type = LightType::POINT; break; case FbxLight::EType::eSpot: type = LightType::SPOT; break; default: LOGW << "Unsupported light type!"; return; } Light::Ptr light = Light::Create(); FbxDouble3 color = fbxLight->Color.Get(); light->SetType(type); light->SetColor(Color((float)color.mData[0], (float)color.mData[1], (float)color.mData[2])); light->SetIntensity((float)fbxLight->Intensity.Get() * m_ScaleFactor); light->SetInnerAngle(Angle::DegToRad * (float)fbxLight->InnerAngle.Get()); light->SetOutterAngle(Angle::DegToRad * (float)fbxLight->OuterAngle.Get()); light->SetFalloff((float)fbxLight->FarAttenuationEnd.Get() * m_ScaleFactor); light->SetRadius((float)fbxLight->DecayStart.Get() * m_ScaleFactor); light->CalculateAABB(); LOGD << fbxLight->GetName(); ntNode->AddComponent(light); }
void gltfWriter::AdditionalTechniqueParameters (FbxNode *pNode, web::json::value &techniqueParameters, bool bHasNormals /*=false*/) { if ( bHasNormals ) { techniqueParameters [U("normalMatrix")] =web::json::value::object ({ // normal matrix { U("semantic"), web::json::value::string (U("MODELVIEWINVERSETRANSPOSE")) }, { U("type"), web::json::value::number ((int)IOglTF::FLOAT_MAT3) } }) ; } techniqueParameters [U("modelViewMatrix")] =web::json::value::object ({ // modeliew matrix { U("semantic"), web::json::value::string (U("MODELVIEW")) }, { U("type"), web::json::value::number ((int)IOglTF::FLOAT_MAT4) } }) ; techniqueParameters [U("projectionMatrix")] =web::json::value::object ({ // projection matrix { U("semantic"), web::json::value::string (U("PROJECTION")) }, { U("type"), web::json::value::number ((int)IOglTF::FLOAT_MAT4) } }) ; //d:\projects\gltf\converter\collada2gltf\shaders\commonprofileshaders.cpp #905 //if ( hasSkinning ) { // addSemantic ("vs", "attribute", // "JOINT", "joint", 1, false); // addSemantic ("vs", "attribute", // "WEIGHT", "weight", 1, false); // assert (techniqueExtras != nullptr); // addSemantic ("vs", "uniform", // JOINTMATRIX, "jointMat", jointsCount, false, true /* force as an array */); //} // We ignore lighting if the only light we have is ambient int lightCount =pNode->GetScene ()->RootProperty.GetSrcObjectCount<FbxLight> () ; for ( int i =0 ; i < lightCount ; i++ ) { FbxLight *pLight =pNode->GetScene ()->RootProperty.GetSrcObject<FbxLight> (i) ; if ( lightCount == 1 && pLight->LightType.Get () == FbxLight::EType::ePoint ) return ; //utility::string_t name =nodeId (pLight->GetNode ()) ; utility::string_t name =utility::conversions::to_string_t (pLight->GetTypeName ()) ; std::transform (name.begin (), name.end (), name.begin (), ::tolower) ; if ( pLight->LightType.Get () == FbxLight::EType::ePoint ) { techniqueParameters [name + utility::conversions::to_string_t (i) + U("Color")] =web::json::value::object ({ // Color { U("type"), web::json::value::number ((int)IOglTF::FLOAT_VEC3) }, { U("value"), web::json::value::array ({{ pLight->Color.Get () [0], pLight->Color.Get () [1], pLight->Color.Get () [2] }}) } }) ; } else { techniqueParameters [name + utility::conversions::to_string_t (i) + U("Color")] =web::json::value::object ({ // Color { U("type"), web::json::value::number ((int)IOglTF::FLOAT_VEC3) }, { U("value"), web::json::value::array ({{ pLight->Color.Get () [0], pLight->Color.Get () [1], pLight->Color.Get () [2] }}) } }) ; techniqueParameters [name + utility::conversions::to_string_t (i) + U("Transform")] =web::json::value::object ({ // Transform { U("semantic"), web::json::value::string (U("MODELVIEW")) }, { U("source"), web::json::value::string (utility::conversions::to_string_t (pLight->GetNode ()->GetName ())) }, { U("type"), web::json::value::number ((int)IOglTF::FLOAT_MAT4) } }) ; if ( pLight->LightType.Get () == FbxLight::EType::eDirectional ) { web::json::value lightDef =web::json::value::object () ; lightAttenuation (pLight, lightDef) ; if ( !lightDef [U("constantAttenuation")].is_null () ) techniqueParameters [name + utility::conversions::to_string_t (i) + U("ConstantAttenuation")] =web::json::value::object ({ { U("type"), web::json::value::number ((int)IOglTF::FLOAT) }, { U("value"), lightDef [U("constantAttenuation")] } }) ; if ( !lightDef [U("linearAttenuation")].is_null () ) techniqueParameters [name + utility::conversions::to_string_t (i) + U("LinearAttenuation")] =web::json::value::object ({ { U("type"), web::json::value::number ((int)IOglTF::FLOAT) }, { U("value"), lightDef [U("linearAttenuation")] } }) ; if ( !lightDef [U("quadraticAttenuation")].is_null () ) techniqueParameters [name + utility::conversions::to_string_t (i) + U("QuadraticAttenuation")] =web::json::value::object ({ { U("type"), web::json::value::number ((int)IOglTF::FLOAT) }, { U("value"), lightDef [U("quadraticAttenuation")] } }) ; } if ( pLight->LightType.Get () == FbxLight::EType::eSpot ) { techniqueParameters [name + utility::conversions::to_string_t (i) + U("InverseTransform")] =web::json::value::object ({ { U("semantic"), web::json::value::string (U("MODELVIEWINVERSE")) }, { U("source"), web::json::value::string (utility::conversions::to_string_t (pLight->GetNode ()->GetName ())) }, { U("type"), web::json::value::number ((int)IOglTF::FLOAT_MAT4) } }) ; techniqueParameters [name + utility::conversions::to_string_t (i) + U("FallOffAngle")] =web::json::value::object ({ { U("type"), web::json::value::number ((int)IOglTF::FLOAT) }, { U("value"), web::json::value::number (DEG2RAD (pLight->OuterAngle)) } }) ; techniqueParameters [name + utility::conversions::to_string_t (i) + U("FallOffExponent")] =web::json::value::object ({ { U("type"), web::json::value::number ((int)IOglTF::FLOAT) }, { U("value"), web::json::value::number ((double)0.) } }) ; } } } }