void FBXImporter::LoadMaterialTexture(FBXMeshData* fbxMeshData, const char* textureType) { FbxProperty property; // #NoteReference to DisplayMesh.cxx in FBX SDK samples.Note# property = fbxMeshData->mSurfaceMaterial->FindProperty(textureType); if (property.IsValid()) { int textureCount = property.GetSrcObjectCount<FbxTexture>(); for (int i = 0; i < textureCount; i++) { FbxTexture* texture = FbxCast<FbxTexture>(property.GetSrcObject<FbxTexture>(i)); if (texture != nullptr) { FbxFileTexture* fileTexture = FbxCast<FbxFileTexture>(texture); string textureFileName = fileTexture->GetFileName(); if (strcmp(textureType, FbxSurfaceMaterial::sDiffuse) == 0) { fbxMeshData->mMaterial->setDiffuseTexture(textureFileName); } else if (strcmp(textureType, FbxSurfaceMaterial::sBump) == 0) { fbxMeshData->mMaterial->setNormalMapTexture(textureFileName); } } } } }
// Bake node attributes and materials for this scene and load the textures. void LoadCacheRecursive(SceneContext* pSceneCtx, FbxScene * pScene, FbxAnimLayer * pAnimLayer, GXLPCWSTR pFbxFileName, bool pSupportVBO) { // Load the textures into GPU, only for file texture now const int lTextureCount = pScene->GetTextureCount(); for (int lTextureIndex = 0; lTextureIndex < lTextureCount; ++lTextureIndex) { FbxTexture * lTexture = pScene->GetTexture(lTextureIndex); FbxFileTexture * lFileTexture = FbxCast<FbxFileTexture>(lTexture); if (lFileTexture && !lFileTexture->GetUserDataPtr()) { // Try to load the texture from absolute path const FbxString lFileName = lFileTexture->GetFileName(); // Only TGA textures are supported now. //if (lFileName.Right(3).Upper() != "TGA") //{ // FBXSDK_printf("Only TGA textures are supported now: %s\n", lFileName.Buffer()); // continue; //} //unsigned int lTextureObject = 0; //bool lStatus = LoadTextureFromFile(lFileName, lTextureObject); //const FbxString lAbsFbxFileName = FbxPathUtils::Resolve(pFbxFileName); //const FbxString lAbsFolderName = FbxPathUtils::GetFolderName(lAbsFbxFileName); //if (!lStatus) //{ // // Load texture from relative file name (relative to FBX file) // const FbxString lResolvedFileName = FbxPathUtils::Bind(lAbsFolderName, lFileTexture->GetRelativeFileName()); // lStatus = LoadTextureFromFile(lResolvedFileName, lTextureObject); //} //if (!lStatus) //{ // // Load texture from file name only (relative to FBX file) // const FbxString lTextureFileName = FbxPathUtils::GetFileName(lFileName); // const FbxString lResolvedFileName = FbxPathUtils::Bind(lAbsFolderName, lTextureFileName); // lStatus = LoadTextureFromFile(lResolvedFileName, lTextureObject); //} //if (!lStatus) //{ // FBXSDK_printf("Failed to load texture file: %s\n", lFileName.Buffer()); // continue; //} //if (lStatus) //{ // int * lTextureName = new int(lTextureObject); // lFileTexture->SetUserDataPtr(lTextureName); //} } } LoadCacheRecursive(pSceneCtx, pScene->GetRootNode(), pAnimLayer, pSupportVBO); }
void FbxLoader::FbxLoader::ProcessMaterialTexture2D(FbxSurfaceMaterial* mat, FMaterial& material) { int Texture2DIndex = 0; FbxProperty prop; FBXSDK_FOR_EACH_TEXTURE(Texture2DIndex) { prop = mat->FindProperty(FbxLayerElement::sTextureChannelNames[Texture2DIndex]); if(prop.IsValid()) { const int Texture2DCount = prop.GetSrcObjectCount<FbxTexture>(); for(int i = 0; i < Texture2DCount; i++) { FbxTexture* texture = prop.GetSrcObject<FbxTexture>(i); if(texture) { std::string textureType = prop.GetNameAsCStr(); FbxFileTexture* fileTexture = FbxCast<FbxFileTexture>(texture); if(fileTexture) { if(textureType == "DiffuseColor") material.diffuseMapName = fileTexture->GetRelativeFileName(); else if(textureType == "SpecularColor") material.specularMapName = fileTexture->GetRelativeFileName(); else if(textureType == "NormalMap") { material.normalMapName = fileTexture->GetRelativeFileName(); useNormalMap = true; } } } } const int layeredTextureCount = prop.GetSrcObjectCount<FbxLayeredTexture>(); for(int i = 0; i < layeredTextureCount; i++) { auto layeredTexture = prop.GetSrcObject<FbxLayeredTexture>(i); const int fileCount = layeredTexture->GetSrcObjectCount<FbxFileTexture>(); for(int j = 0; j < fileCount; j++) { auto fileTexture = layeredTexture->GetSrcObject<FbxFileTexture>(j); std::string Texture2DType = prop.GetNameAsCStr(); if(fileTexture) { if(Texture2DType == "DiffuseColor") material.diffuseMapName = fileTexture->GetRelativeFileName(); else if(Texture2DType == "SpecularColor") material.specularMapName = fileTexture->GetRelativeFileName(); else if(Texture2DType == "NormalMap") { material.normalMapName = fileTexture->GetRelativeFileName(); useNormalMap = true; } } } } } } if(material.diffuseMapName != "") { std::string n = FbxPathUtils::GetFileName(material.diffuseMapName.c_str(), false).Buffer(); material.name = n; mat->SetName(n.c_str()); } }
reMaterial* reFBXAsset::getMaterial( FbxMesh* fmesh, int i, reMaterialSet& set) { reMaterial* mat = NULL; for (int l = 0; l < fmesh->GetElementMaterialCount(); l++) { FbxGeometryElementMaterial* lMaterialElement = fmesh->GetElementMaterial(l); int lMatId = lMaterialElement->GetIndexArray().GetAt(i); if(lMatId >= 0) { if (mat = set.materialById(lMatId)) return mat; mat = new reMaterial; mat->id = lMatId; set.addMetarial(mat); FbxSurfaceMaterial* lMaterial = fmesh->GetNode()->GetMaterial(lMaterialElement->GetIndexArray().GetAt(i)); if (!lMaterial) { continue; } ////////////////////////////////////////////////////////////////////////// FbxProperty lProperty = lMaterial->FindProperty(FbxSurfaceMaterial::sDiffuse); if (lMaterial->GetClassId().Is(FbxSurfacePhong::ClassId)) { FbxDouble3 lFbxDouble3; lFbxDouble3 =((FbxSurfacePhong *)lMaterial)->Diffuse; mat->diffuseColor = reColor4(lFbxDouble3[0], lFbxDouble3[1], lFbxDouble3[2], 1); } if (lMaterial->GetClassId().Is(FbxSurfaceLambert::ClassId)) { FbxDouble3 lFbxDouble3; lFbxDouble3 =((FbxSurfaceLambert *)lMaterial)->Diffuse; mat->diffuseColor = reColor4(lFbxDouble3[0], lFbxDouble3[1], lFbxDouble3[2], 1); } ////////////////////////////////////////////////////////////////////////// read texture int lNbTextures = lProperty.GetSrcObjectCount(FbxTexture::ClassId); if (lNbTextures) { mat->diffuseTexture = new reTexture; FbxTexture* lTexture = FbxCast <FbxTexture> (lProperty.GetSrcObject(FbxTexture::ClassId,0)); qDebug() << "map: " << lTexture->GetName(); FbxFileTexture *lFileTexture = FbxCast<FbxFileTexture>(lTexture); if (lFileTexture) { mat->diffuseTexture->fileName(lFileTexture->GetFileName()); } } ////////////////////////////////////////////////////////////////////////// } } return mat; }
//------------------------------------------------------------------------------------------------------------------------------------------- void transferTextureInfo(FbxTexture* texture, int blendMode, Texture* modelTexture){ FbxFileTexture* fileTexture = FbxCast<FbxFileTexture>(texture); FbxProceduralTexture* proceduralTexture = FbxCast<FbxProceduralTexture>(texture); modelTexture->TextureName = texture->GetName(); if (fileTexture){ Image* image = loadImage(fileTexture->GetFileName(), &Texture::Images); modelTexture->Image = image; } else if (proceduralTexture){ LOG_WARNING << "Procedural texture ! " << "Texture name: " << modelTexture->TextureName; } modelTexture->ScaleU = texture->GetScaleU(); modelTexture->ScaleV = texture->GetScaleV(); modelTexture->TranslateU = texture->GetTranslationU(); modelTexture->TranslateV = texture->GetTranslationV(); modelTexture->IsSwapUV = texture->GetSwapUV(); modelTexture->RotateU = texture->GetRotationU(); modelTexture->RotateV = texture->GetRotationV(); modelTexture->RotateW = texture->GetRotationW(); const char* lAlphaSources[] = { "None", "RGB Intensity", "Black" }; modelTexture->AlphaSource = lAlphaSources[texture->GetAlphaSource()]; modelTexture->CropLeft = texture->GetCroppingLeft(); modelTexture->CropRight = texture->GetCroppingRight(); modelTexture->CropTop = texture->GetCroppingTop(); modelTexture->CropBottom = texture->GetCroppingBottom(); const char* lMappingTypes[] = { "Null", "Planar", "Spherical", "Cylindrical", "Box", "Face", "UV", "Environment" }; modelTexture->MappingType = lMappingTypes[texture->GetMappingType()]; const char* lBlendModes[] = { "Translucent", "Add", "Modulate", "Modulate2" }; if (blendMode >= 0){ modelTexture->BlendMode = lBlendModes[blendMode]; } modelTexture->Alpha = texture->GetDefaultAlpha(); if (fileTexture){ const char* lMaterialUses[] = { "Model Material", "Default Material" }; modelTexture->MaterialUsed = lMaterialUses[fileTexture->GetMaterialUse()]; } const char* pTextureUses[] = { "Standard", "Shadow Map", "Light Map", "Spherical Reflexion Map", "Sphere Reflexion Map", "Bump Normal Map" }; modelTexture->TextureUsed = pTextureUses[texture->GetTextureUse()]; LOG_INFO << "Texture information: \n" << modelTexture->ToString(); LOG_DEBUG << "Read texture successfully!"; }
jstring getMaterialMapByProperty(JNIEnv *env, jint materialIndex, const char *property) { FbxTexture *texture = currentNode->GetMaterial(materialIndex)->FindProperty(property).GetSrcObject<FbxTexture>(); if (texture) { FbxFileTexture *fileTexture = FbxCast<FbxFileTexture>(texture); if (fileTexture) { return env->NewStringUTF(fileTexture->GetFileName()); } } return NULL; }
TextureDetails* FbxMaterialToOsgStateSet::selectTextureDetails(const FbxProperty& lProperty) { if (lProperty.IsValid()) { FbxFileTexture* fileTexture = selectFbxFileTexture(lProperty); if (fileTexture) { TextureDetails* textureDetails = new TextureDetails(); textureDetails->texture = fbxTextureToOsgTexture(fileTexture); textureDetails->channel = fileTexture->UVSet.Get(); textureDetails->scale.set(fileTexture->GetScaleU(), fileTexture->GetScaleV()); return textureDetails; } } return 0; }
std::string getTextureFileName(FbxTexture* fbxTexture) { std::string returnString = ""; FbxFileTexture *fbxFileTexture = FbxCast<FbxFileTexture>(fbxTexture); FbxProceduralTexture *fbxProceduralTexture = FbxCast<FbxProceduralTexture>(fbxTexture); if (fbxFileTexture != nullptr) { const char* textureFileName = fbxFileTexture->GetFileName(); returnString = textureFileName; printf("\nFound texture filename: %s", returnString.c_str()); } if (fbxProceduralTexture != nullptr) { printf("\nWARNING : Procedural textures found"); } return returnString; }
// Unload the cache and release the memory fro this scene and release the textures in GPU void UnloadCacheRecursive(FbxScene * pScene) { const int lTextureCount = pScene->GetTextureCount(); for (int lTextureIndex = 0; lTextureIndex < lTextureCount; ++lTextureIndex) { FbxTexture * lTexture = pScene->GetTexture(lTextureIndex); FbxFileTexture * lFileTexture = FbxCast<FbxFileTexture>(lTexture); if (lFileTexture && lFileTexture->GetUserDataPtr()) { int * lTextureName = static_cast<int *>(lFileTexture->GetUserDataPtr()); lFileTexture->SetUserDataPtr(NULL); //glDeleteTextures(1, lTextureName); delete lTextureName; } } UnloadCacheRecursive(pScene->GetRootNode()); }
void Converter::getDiffuseTextures(FbxSurfaceMaterial *material, std::vector<std::string> &textures) { FbxProperty property = material->FindProperty(FbxLayerElement::sTextureChannelNames[0]); if (property.IsValid()) { for (int j = 0; j < property.GetSrcObjectCount<FbxTexture>(); ++j) { if (!property.GetSrcObject<FbxLayeredTexture>(j)) { FbxTexture* texture = property.GetSrcObject<FbxTexture>(j); if (texture) { std::string textureType = property.GetNameAsCStr(); FbxFileTexture* fileTexture = FbxCast<FbxFileTexture>(texture); if (fileTexture) { if (textureType == "DiffuseColor") { //std::cout << fileTexture->GetRelativeFileName() << "\n"; textures.push_back(fileTexture->GetRelativeFileName()); } } } } } } }
void FbxMaterial::AddProperty(const FbxProperty &property, const FbxProperty &factor_property) { /** *If we are dealing with an invalid properties, abort */ if (!property.IsValid() || !factor_property.IsValid()) return; /** *Get the name of the property */ QString property_name = property.GetNameAsCStr(); /** *Based on the property's name, load required stuff */ if (property_name == FbxSurfaceMaterial::sDiffuse) { /** *Get the diffuse color and intensity */ FbxDouble3 diffuse_color = property.Get<FbxDouble3>(); FbxDouble diffuse_intensity = factor_property.Get<FbxDouble>(); /** *Set diffuse color and intensity */ SetDiffuseColor(aae::mesh_util::QVector3DFromFbxVector3D(diffuse_color)); SetDiffuseIntensity(diffuse_intensity); /** *If there are no textures attached to the property, return */ if(!property.GetSrcObjectCount<FbxFileTexture>() > 0) return; /** *Get the texture handler */ FbxFileTexture * texture = property.GetSrcObject<FbxFileTexture>(); if (!texture) return; /** *Add the diffuse texture name of the material */ AddTexture(diffuse, texture->GetFileName()); } else if (property_name == FbxSurfaceMaterial::sNormalMap) { /** *If there are no textures attached to the property, return */ if(!property.GetSrcObjectCount<FbxFileTexture>() > 0) return; /** *Get the texture handler */ FbxFileTexture * texture = property.GetSrcObject<FbxFileTexture>(); if (!texture) return; /** *Set normal map texture of the material */ AddTexture(normal, texture->GetFileName()); } else if (property_name == FbxSurfaceMaterial::sSpecular) { /** *Get the specular color and intensity */ FbxDouble3 specular_color = property.Get<FbxDouble3>(); FbxDouble specular_intensity = factor_property.Get<FbxDouble>(); /** *Set the specular color and intensity */ SetSpecularColor(aae::mesh_util::QVector3DFromFbxVector3D(specular_color)); SetSpecularIntensity(specular_intensity); } else if (property_name == FbxSurfaceMaterial::sShininess) { /** *Get and set specular hardness */ FbxDouble specular_hardness = property.Get<FbxDouble>(); SetSpecularHardness(specular_hardness); } }
StateSetContent FbxMaterialToOsgStateSet::convert(const FbxSurfaceMaterial* pFbxMat) { FbxMaterialMap::const_iterator it = _fbxMaterialMap.find(pFbxMat); if (it != _fbxMaterialMap.end()) return it->second; osg::ref_ptr<osg::Material> pOsgMat = new osg::Material; pOsgMat->setName(pFbxMat->GetName()); StateSetContent result; result.material = pOsgMat; FbxString shadingModel = pFbxMat->ShadingModel.Get(); const FbxSurfaceLambert* pFbxLambert = FbxCast<FbxSurfaceLambert>(pFbxMat); // diffuse map... const FbxProperty lProperty = pFbxMat->FindProperty(FbxSurfaceMaterial::sDiffuse); if (lProperty.IsValid()) { int lNbTex = lProperty.GetSrcObjectCount<FbxFileTexture>(); for (int lTextureIndex = 0; lTextureIndex < lNbTex; lTextureIndex++) { FbxFileTexture* lTexture = FbxCast<FbxFileTexture>(lProperty.GetSrcObject<FbxFileTexture>(lTextureIndex)); if (lTexture) { result.diffuseTexture = fbxTextureToOsgTexture(lTexture); result.diffuseChannel = lTexture->UVSet.Get(); result.diffuseScaleU = lTexture->GetScaleU(); result.diffuseScaleV = lTexture->GetScaleV(); } //For now only allow 1 texture break; } } // opacity map... const FbxProperty lOpacityProperty = pFbxMat->FindProperty(FbxSurfaceMaterial::sTransparentColor); if (lOpacityProperty.IsValid()) { int lNbTex = lOpacityProperty.GetSrcObjectCount<FbxFileTexture>(); for (int lTextureIndex = 0; lTextureIndex < lNbTex; lTextureIndex++) { FbxFileTexture* lTexture = FbxCast<FbxFileTexture>(lOpacityProperty.GetSrcObject<FbxFileTexture>(lTextureIndex)); if (lTexture) { // TODO: if texture image does NOT have an alpha channel, should it be added? result.opacityTexture = fbxTextureToOsgTexture(lTexture); result.opacityChannel = lTexture->UVSet.Get(); result.opacityScaleU = lTexture->GetScaleU(); result.opacityScaleV = lTexture->GetScaleV(); } //For now only allow 1 texture break; } } // reflection map... const FbxProperty lReflectionProperty = pFbxMat->FindProperty(FbxSurfaceMaterial::sReflection); if (lReflectionProperty.IsValid()) { int lNbTex = lReflectionProperty.GetSrcObjectCount<FbxFileTexture>(); for (int lTextureIndex = 0; lTextureIndex < lNbTex; lTextureIndex++) { FbxFileTexture* lTexture = FbxCast<FbxFileTexture>(lReflectionProperty.GetSrcObject<FbxFileTexture>(lTextureIndex)); if (lTexture) { // support only spherical reflection maps... if (FbxFileTexture::eUMT_ENVIRONMENT == lTexture->CurrentMappingType.Get()) { result.reflectionTexture = fbxTextureToOsgTexture(lTexture); result.reflectionChannel = lTexture->UVSet.Get(); } } //For now only allow 1 texture break; } } // emissive map... const FbxProperty lEmissiveProperty = pFbxMat->FindProperty(FbxSurfaceMaterial::sEmissive); if (lEmissiveProperty.IsValid()) { int lNbTex = lEmissiveProperty.GetSrcObjectCount<FbxFileTexture>(); for (int lTextureIndex = 0; lTextureIndex < lNbTex; lTextureIndex++) { FbxFileTexture* lTexture = FbxCast<FbxFileTexture>(lEmissiveProperty.GetSrcObject<FbxFileTexture>(lTextureIndex)); if (lTexture) { result.emissiveTexture = fbxTextureToOsgTexture(lTexture); result.emissiveChannel = lTexture->UVSet.Get(); result.emissiveScaleU = lTexture->GetScaleU(); result.emissiveScaleV = lTexture->GetScaleV(); } //For now only allow 1 texture break; } } if (pFbxLambert) { FbxDouble3 color = pFbxLambert->Diffuse.Get(); double factor = pFbxLambert->DiffuseFactor.Get(); pOsgMat->setDiffuse(osg::Material::FRONT_AND_BACK, osg::Vec4( static_cast<float>(color[0] * factor), static_cast<float>(color[1] * factor), static_cast<float>(color[2] * factor), static_cast<float>(1.0 - pFbxLambert->TransparencyFactor.Get()))); color = pFbxLambert->Ambient.Get(); factor = pFbxLambert->AmbientFactor.Get(); pOsgMat->setAmbient(osg::Material::FRONT_AND_BACK, osg::Vec4( static_cast<float>(color[0] * factor), static_cast<float>(color[1] * factor), static_cast<float>(color[2] * factor), 1.0f)); color = pFbxLambert->Emissive.Get(); factor = pFbxLambert->EmissiveFactor.Get(); pOsgMat->setEmission(osg::Material::FRONT_AND_BACK, osg::Vec4( static_cast<float>(color[0] * factor), static_cast<float>(color[1] * factor), static_cast<float>(color[2] * factor), 1.0f)); // get maps factors... result.diffuseFactor = pFbxLambert->DiffuseFactor.Get(); if (const FbxSurfacePhong* pFbxPhong = FbxCast<FbxSurfacePhong>(pFbxLambert)) { color = pFbxPhong->Specular.Get(); factor = pFbxPhong->SpecularFactor.Get(); pOsgMat->setSpecular(osg::Material::FRONT_AND_BACK, osg::Vec4( static_cast<float>(color[0] * factor), static_cast<float>(color[1] * factor), static_cast<float>(color[2] * factor), 1.0f)); pOsgMat->setShininess(osg::Material::FRONT_AND_BACK, static_cast<float>(pFbxPhong->Shininess.Get())); // get maps factors... result.reflectionFactor = pFbxPhong->ReflectionFactor.Get(); // get more factors here... } } if (_lightmapTextures) { // if using an emission map then adjust material properties accordingly... if (result.emissiveTexture) { osg::Vec4 diffuse = pOsgMat->getDiffuse(osg::Material::FRONT_AND_BACK); pOsgMat->setEmission(osg::Material::FRONT_AND_BACK, diffuse); pOsgMat->setDiffuse(osg::Material::FRONT_AND_BACK, osg::Vec4(0,0,0,diffuse.a())); pOsgMat->setAmbient(osg::Material::FRONT_AND_BACK, osg::Vec4(0,0,0,diffuse.a())); } } _fbxMaterialMap.insert(FbxMaterialMap::value_type(pFbxMat, result)); return result; }
void Tools::DisplayMaterial::DisplayMaterial( FbxGeometry *i_geometry ) { DisplayCommon::DisplayString( "\n\n--------------------\nMaterial\n--------------------" ); int materialCount = 0; FbxNode *node = NULL; if( i_geometry ) { node = i_geometry->GetNode(); if( node ) materialCount = node->GetMaterialCount(); } if( materialCount > 0 ) { FbxPropertyT<FbxDouble3> double3; FbxPropertyT<FbxDouble> double1; FbxColor theColor; for( int ctr = 0; ctr < materialCount; ctr++ ) { DisplayCommon::DisplayInt( " Material ", ctr ); FbxSurfaceMaterial *material = node->GetMaterial( ctr ); DisplayCommon::DisplayString( " Name: \"", (char *) material->GetName(), "\"" ); #ifdef DISPLAY_HARDWARE_SHADER_INFORMATION //Get the implementation to see if it's a hardware shader. // Note:: this cause memory leak const FbxImplementation* implementation = GetImplementation( material, FBXSDK_IMPLEMENTATION_HLSL ); FbxString implementationType = "HLSL"; if( !implementation ) { implementation = GetImplementation( material, FBXSDK_IMPLEMENTATION_CGFX ); implementationType = "CGFX"; } if( implementation ) { //Now we have a hardware shader, let's read it FBXSDK_printf( " Hardware Shader Type: %s\n", implemenationType.Buffer() ); DisplayCommon::DisplayString( " Hardware Shader Type: ", implemenationType ); const FbxBindingTable* rootTable = implementation->GetRootTable(); FbxString fileName = rootTable->DescAbsoluteURL.Get(); FbxString techniqueName = rootTable->DescTAG.Get(); const FbxBindingTable* table = implementation->GetRootTable(); size_t entryNum = table->GetEntryCount(); for( int i = 0; i < (int)entryNum; i++ ) { const FbxBindingTableEntry& entry = table->GetEntry( i ); const char *entrySrcType = entry.GetEntryType( true ); FbxProperty fbxProp; FbxString test = entry.GetSource(); FBXSDK_printf( " Entry: %s\n", test.Buffer() ); DisplayCommon::DisplayString( " Entry: %s\n", test ); if ( strcmp( FbxPropertyEntryView::sEntryType, entrySrcType ) == 0 ) { fbxProp = material->FindPropertyHierarchical(entry.GetSource()); if( !fbxProp.IsValid() ) { fbxProp = material->RootProperty.FindHierarchical( entry.GetSource() ); } } else if( strcmp( FbxConstantEntryView::sEntryType, entrySrcType ) == 0 ) { fbxProp = implementation->GetConstants().FindHierarchical( entry.GetSource() ); } if( fbxProp.IsValid() ) { if( fbxProp.GetSrcObjectCount<FbxTexture>() > 0 ) { //do what you want with the textures for( int j = 0; j < fbxProp.GetSrcObjectCount<FbxFileTexture>(); j++ ) { FbxFileTexture *tex = fbxProp.GetSrcObject<FbxFileTexture>( j ); FBXSDK_printf( " File Texture: %s\n", tex->GetFileName() ); DisplayCommon::DisplayString( " File Texture: %s\n", tex->GetFileName() ); } for( int j = 0; j < fbxProp.GetSrcObjectCount<FbxLayeredTexture>(); j++ ) { FbxLayeredTexture *tex = fbxProp.GetSrcObject<FbxLayeredTexture>( j ); FBXSDK_printf( " Layered Texture: %s\n", tex->GetName() ); DisplayCommon::DisplayString( " Layered Texture: %s\n", tex->GetName() ); } for( int j = 0; j < fbxProp.GetSrcObjectCount<FbxProceduralTexture>(); j++ ) { FbxProceduralTexture *tex = fbxProp.GetSrcObject<FbxProceduralTexture>( j ); FBXSDK_printf( " Procedural Texture: %s\n", tex->GetName() ); DisplayCommon::DisplayString( " Procedural Texture: %s\n", tex->GetName() ); } } else { FbxDataType fbxType = fbxProp.GetPropertyDataType(); FbxString fbxName = fbxType.GetName(); if( FbxBoolDT == fbxType ) { DisplayCommon::DisplayBool( " Bool: ", fbxProp.Get<FbxBool>() ); } else if( FbxIntDT == fbxType || FbxEnumDT == fbxType ) { DisplayCommon::DisplayInt( " Int: ", fbxProp.Get<FbxInt>() ); } else if( FbxFloatDT == fbxType ) { DisplayCommon::DisplayDouble( " Float: ", fbxProp.Get<FbxFloat>() ); } else if( FbxDoubleDT == fbxType ) { DisplayCommon::DisplayDouble( " Double: ", fbxProp.Get<FbxDouble>() ); } else if( FbxStringDT == fbxType || FbxUrlDT == fbxType || FbxXRefUrlDT == fbxType ) { DisplayCommon::DisplayString( " String: ", fbxProp.Get<FbxString>().Buffer() ); } else if( FbxDouble2DT == fbxType ) { FbxDouble2 double2 = fbxProp.Get<FbxDouble2>(); FbxVector2 vector; vector[0] = double2[0]; vector[1] = double2[1]; DisplayCommon::Display2DVector( " 2D vector: ", vector ); } else if( (FbxDouble3DT == fbxType) || (FbxColor3DT == fbxType) ) { FbxDouble3 double3 = fbxProp.Get<FbxDouble3>(); FbxVector4 vector; vector[0] = double3[0]; vector[1] = double3[1]; vector[2] = double3[2]; DisplayCommon::Display3DVector( " 3D vector: ", vector ); } else if( (FbxDouble4DT == fbxType) || (FbxColor4DT == fbxType) ) { FbxDouble4 double4 = fbxProp.Get<FbxDouble4>(); FbxVector4 vector; vector[0] = double4[0]; vector[1] = double4[1]; vector[2] = double4[2]; vector[3] = double4[3]; DisplayCommon::Display4DVector( " 4D vector: ", vector ); } else if( FbxDouble4x4DT == fbxType ) { FbxDouble4x4 double44 = fbxProp.Get<FbxDouble4x4>(); for( int j = 0; j < 4; j++ ) { FbxVector4 vector; vector[0] = double44[j][0]; vector[1] = double44[j][1]; vector[2] = double44[j][2]; vector[3] = double44[j][3]; DisplayCommon::Display4DVector( " 4x4D vector: ", vector ); } } } } } } else #endif // #ifdef DISPLAY_HARDWARE_SHADER_INFORMATION if( material->GetClassId().Is(FbxSurfacePhong::ClassId) ) { // We found a Phong material. Display its properties. // Display the Ambient Color double3 = ((FbxSurfacePhong *) material)->Ambient; theColor.Set( double3.Get()[0], double3.Get()[1], double3.Get()[2] ); DisplayCommon::DisplayColor( " Ambient: ", theColor ); // Display the Diffuse Color double3 = ((FbxSurfacePhong *) material)->Diffuse; theColor.Set( double3.Get()[0], double3.Get()[1], double3.Get()[2] ); DisplayCommon::DisplayColor( " Diffuse: ", theColor ); // Display the Specular Color (unique to Phong materials) double3 = ((FbxSurfacePhong *) material)->Specular; theColor.Set( double3.Get()[0], double3.Get()[1], double3.Get()[2] ); DisplayCommon::DisplayColor( " Specular: ", theColor ); // Display the Emissive Color double3 = ((FbxSurfacePhong *) material)->Emissive; theColor.Set( double3.Get()[0], double3.Get()[1], double3.Get()[2] ); DisplayCommon::DisplayColor( " Emissive: ", theColor ); //Opacity is Transparency factor now double1 = ((FbxSurfacePhong *) material)->TransparencyFactor; DisplayCommon::DisplayDouble( " Opacity: ", 1.0-double1.Get() ); // Display the Shininess double1 = ((FbxSurfacePhong *) material)->Shininess; DisplayCommon::DisplayDouble( " Shininess: ", double1.Get() ); // Display the Reflectivity double1 = ((FbxSurfacePhong *) material)->ReflectionFactor; DisplayCommon::DisplayDouble( " Reflectivity: ", double1.Get() ); } else if( material->GetClassId().Is(FbxSurfaceLambert::ClassId) ) { // We found a Lambert material. Display its properties. // Display the Ambient Color double3 = ((FbxSurfaceLambert *)material)->Ambient; theColor.Set( double3.Get()[0], double3.Get()[1], double3.Get()[2] ); DisplayCommon::DisplayColor( " Ambient: ", theColor ); // Display the Diffuse Color double3 = ((FbxSurfaceLambert *)material)->Diffuse; theColor.Set( double3.Get()[0], double3.Get()[1], double3.Get()[2] ); DisplayCommon::DisplayColor( " Diffuse: ", theColor ); // Display the Emissive double3 = ((FbxSurfaceLambert *)material)->Emissive; theColor.Set( double3.Get()[0], double3.Get()[1], double3.Get()[2] ); DisplayCommon::DisplayColor( " Emissive: ", theColor ); // Display the Opacity double1 = ((FbxSurfaceLambert *)material)->TransparencyFactor; DisplayCommon::DisplayDouble( " Opacity: ", 1.0-double1.Get() ); } else DisplayCommon::DisplayString( "Unknown type of Material" ); FbxPropertyT<FbxString> string; string = material->ShadingModel; DisplayCommon::DisplayString( " Shading Model: ", string.Get() ); } } }
FbxModelData* FBXLoader::loadModel( const char* aFile ) { FBX_LOG("FBXLoader Creating ModelData..."); myLoadingModel = new FbxModelData; FBX_LOG("Success!"); FBX_LOG("FBXLoader Creating TextureData..."); myLoadingModel->myTextureData = new TextureData(); FBX_LOG("Success!"); FBX_LOG("FBXLoader Loading Scene..."); auto scene = LoadScene(aFile); FBX_LOG("Successfully loaded scene!"); FBX_LOG("FBXLoader Loading Textures..."); //TextureData const int lTextureCount = scene->GetTextureCount(); for (int lTextureIndex = 0; lTextureIndex < lTextureCount; ++lTextureIndex) { FbxTexture * lTexture = scene->GetTexture(lTextureIndex); FbxFileTexture * lFileTexture = reinterpret_cast<FbxFileTexture*>(lTexture); if (lFileTexture && !lFileTexture->GetUserDataPtr()) { const FbxString lFileName = lFileTexture->GetFileName(); unsigned int lTextureObject = 0; lTextureObject; bool lStatus = false; lStatus; const FbxString lAbsFbxFileName = FbxPathUtils::Resolve(aFile); const FbxString lAbsFolderName = FbxPathUtils::GetFolderName(lAbsFbxFileName); const FbxString lTextureFileName = lAbsFolderName + "\\" + lFileTexture->GetRelativeFileName();// FbxPathUtils::GetFileName(lFileName); const FbxString lResolvedFileName = lAbsFolderName + "\\" + FbxPathUtils::GetFileName(lFileName);// lFileTexture->GetRelativeFileName();;// FbxPathUtils::Bind(lAbsFolderName, lTextureFileName); TextureInfo info; info.myFileName = lResolvedFileName; //info.myFileName += "\\"; info.myFileName = lFileTexture->GetRelativeFileName(); myLoadingModel->myTextureData->myTextures.push_back(info); lFileTexture->SetFileName(lResolvedFileName); } } FBX_LOG("Success!"); FBX_LOG("FBXLoader Loading Animations..."); FbxArray<FbxString*> animationNames; FbxArray<FbxPose*> poses; scene->FillAnimStackNameArray(animationNames); scene->FillPoseArray(poses); FbxAnimStack * lCurrentAnimationStack = nullptr; FbxAnimLayer* lCurrentAnimLayer = nullptr; if(animationNames.GetCount() > 0) { lCurrentAnimationStack = scene->FindMember<FbxAnimStack>(animationNames[0]->Buffer()); if (lCurrentAnimationStack != NULL) { lCurrentAnimLayer = lCurrentAnimationStack->GetMember<FbxAnimLayer>(); } } //lCurrentAnimLayer->IsR myLoadingModel->myAnimation = new AnimationData(); FbxPose* pose = nullptr; if(poses.GetCount() > 0) { pose = poses[0]; } LoadAnimation(*myLoadingModel->myAnimation,scene->GetRootNode(),FbxAMatrix(),pose, lCurrentAnimLayer,-1); LoadNodeRecursive(myLoadingModel, *myLoadingModel->myAnimation, scene->GetRootNode(), FbxAMatrix(), pose, lCurrentAnimLayer, -1); FBX_LOG("Success!"); return myLoadingModel; }
// マテリアルプロパティ獲得 FbxDouble3 GetMaterialProperty( const FbxSurfaceMaterial * pMaterial, const char * pPropertyName, const char * pFactorPropertyName) { FbxDouble3 lResult(0, 0, 0); const FbxProperty lProperty = pMaterial->FindProperty(pPropertyName); const FbxProperty lFactorProperty = pMaterial->FindProperty(pFactorPropertyName); if(lProperty.IsValid() && lFactorProperty.IsValid()) { lResult = lProperty.Get<FbxDouble3>(); double lFactor = lFactorProperty.Get<FbxDouble>(); if(lFactor != 1) { lResult[0] *= lFactor; lResult[1] *= lFactor; lResult[2] *= lFactor; } } if(lProperty.IsValid()) { printf("テクスチャ\n"); const int lTextureCount = lProperty.GetSrcObjectCount<FbxFileTexture>(); for(int i = 0; i<lTextureCount; i++) { FbxFileTexture* lFileTexture = lProperty.GetSrcObject<FbxFileTexture>(i); if(lFileTexture) { FbxString uvsetName = lFileTexture->UVSet.Get(); std::string uvSetString = uvsetName.Buffer(); std::string filepath = lFileTexture->GetFileName(); printf("UVSet名=%s\n", uvSetString.c_str()); printf("テクスチャ名=%s\n", filepath.c_str()); } } puts(""); printf("レイヤードテクスチャ\n"); const int lLayeredTextureCount = lProperty.GetSrcObjectCount<FbxLayeredTexture>(); for(int i = 0; i<lLayeredTextureCount; i++) { FbxLayeredTexture* lLayeredTexture = lProperty.GetSrcObject<FbxLayeredTexture>(i); const int lTextureFileCount = lLayeredTexture->GetSrcObjectCount<FbxFileTexture>(); for(int j = 0; j<lTextureFileCount; j++) { FbxFileTexture* lFileTexture = lLayeredTexture->GetSrcObject<FbxFileTexture>(j); if(lFileTexture) { FbxString uvsetName = lFileTexture->UVSet.Get(); std::string uvSetString = uvsetName.Buffer(); std::string filepath = lFileTexture->GetFileName(); printf("UVSet名=%s\n", uvSetString.c_str()); printf("テクスチャ名=%s\n", filepath.c_str()); } } } puts(""); } return lResult; }
void LoadMeshes(Scene* pScene, std::vector<uint32_t>* loadedMeshIDs) { FbxManager* fbxManager = FbxManager::Create(); FbxIOSettings* pFbxIOSettings = FbxIOSettings::Create(fbxManager, IOSROOT); fbxManager->SetIOSettings(pFbxIOSettings); (*(fbxManager->GetIOSettings())).SetBoolProp(IMP_FBX_MATERIAL, true); (*(fbxManager->GetIOSettings())).SetBoolProp(IMP_FBX_TEXTURE, true); (*(fbxManager->GetIOSettings())).SetBoolProp(IMP_FBX_LINK, false); (*(fbxManager->GetIOSettings())).SetBoolProp(IMP_FBX_SHAPE, false); (*(fbxManager->GetIOSettings())).SetBoolProp(IMP_FBX_GOBO, false); (*(fbxManager->GetIOSettings())).SetBoolProp(IMP_FBX_ANIMATION, true); (*(fbxManager->GetIOSettings())).SetBoolProp(IMP_FBX_GLOBAL_SETTINGS, true); bool bEmbedMedia = true; (*(fbxManager->GetIOSettings())).SetBoolProp(EXP_FBX_MATERIAL, true); (*(fbxManager->GetIOSettings())).SetBoolProp(EXP_FBX_TEXTURE, true); (*(fbxManager->GetIOSettings())).SetBoolProp(EXP_FBX_EMBEDDED, bEmbedMedia); (*(fbxManager->GetIOSettings())).SetBoolProp(EXP_FBX_SHAPE, true); (*(fbxManager->GetIOSettings())).SetBoolProp(EXP_FBX_GOBO, true); (*(fbxManager->GetIOSettings())).SetBoolProp(EXP_FBX_ANIMATION, true); (*(fbxManager->GetIOSettings())).SetBoolProp(EXP_FBX_GLOBAL_SETTINGS, true); FbxImporter* pFbxImporter = FbxImporter::Create(fbxManager, ""); // Initialize the importer. bool result = pFbxImporter->Initialize(pScene->loadPath.c_str(), -1, fbxManager->GetIOSettings()); if (!result) { printf("Get error when init FBX Importer: %s\n\n", pFbxImporter->GetStatus().GetErrorString()); exit(-1); } // fbx version number int major, minor, revision; pFbxImporter->GetFileVersion(major, minor, revision); // import pFbxScene FbxScene* pFbxScene = FbxScene::Create(fbxManager, "myScene"); pFbxImporter->Import(pFbxScene); pFbxImporter->Destroy(); pFbxImporter = nullptr; // check axis system FbxAxisSystem axisSystem = pFbxScene->GetGlobalSettings().GetAxisSystem(); FbxAxisSystem vulkanAxisSystem(FbxAxisSystem::eYAxis, FbxAxisSystem::eParityOdd, FbxAxisSystem::eRightHanded); if (axisSystem != vulkanAxisSystem) { axisSystem.ConvertScene(pFbxScene); } // check unit system FbxSystemUnit systemUnit = pFbxScene->GetGlobalSettings().GetSystemUnit(); if (systemUnit.GetScaleFactor() != 1.0) { FbxSystemUnit::cm.ConvertScene(pFbxScene); } // Triangulate Mesh FbxGeometryConverter fbxGeometryConverter(fbxManager); fbxGeometryConverter.Triangulate(pFbxScene, true); // Load Texture int textureCount = pFbxScene->GetTextureCount(); for (int i = 0; i < textureCount; ++i) { FbxTexture* pFbxTexture = pFbxScene->GetTexture(i); FbxFileTexture* pFbxFileTexture = FbxCast<FbxFileTexture>(pFbxTexture); if (pFbxTexture && pFbxFileTexture->GetUserDataPtr()) { } } LoadMeshes(pFbxScene->GetRootNode(), pScene->meshes); }
void Resource::FBX::FBXMaterial::InitMaterial(const FbxSurfaceMaterial *pFbxMaterial, Resource::ResourceManager& rm) { // Logger::Debug(pFbxMaterial->GetName()); Render::MaterialElement& material = AddElement(); const FbxImplementation *lImplementation = pFbxMaterial->GetDefaultImplementation(); FbxPropertyT<FbxDouble3> lKFbxDouble3; FbxPropertyT<FbxDouble> lKFbxDouble1; FbxColor theColor; if(lImplementation){ const FbxBindingTable *lTable = lImplementation->GetRootTable(); size_t lEntryNum = lTable->GetEntryCount(); for (int i = 0; i < (int) lEntryNum; ++i) { const FbxBindingTableEntry &lEntry = lTable->GetEntry(i); const char *lEntrySrcType = lEntry.GetEntryType(true); FbxProperty lFbxProp; FbxString lTest = lEntry.GetSource(); FBXSDK_printf(" Entry: %s\n", lTest.Buffer()); if (strcmp(FbxPropertyEntryView::sEntryType, lEntrySrcType) == 0) { lFbxProp = pFbxMaterial->FindPropertyHierarchical(lEntry.GetSource()); if (!lFbxProp.IsValid()) { lFbxProp = pFbxMaterial->RootProperty.FindHierarchical(lEntry.GetSource()); } } else if (strcmp(FbxConstantEntryView::sEntryType, lEntrySrcType) == 0) { lFbxProp = lImplementation->GetConstants().FindHierarchical(lEntry.GetSource()); } } } else if (pFbxMaterial->GetClassId().Is(FbxSurfacePhong::ClassId)) { // We found a Phong material. Display its properties. // Display the Ambient Color lKFbxDouble3 =((FbxSurfacePhong *) pFbxMaterial)->Ambient; theColor.Set(lKFbxDouble3.Get()[0], lKFbxDouble3.Get()[1], lKFbxDouble3.Get()[2]); // Display the Diffuse Color lKFbxDouble3 =((FbxSurfacePhong *) pFbxMaterial)->Diffuse; theColor.Set(lKFbxDouble3.Get()[0], lKFbxDouble3.Get()[1], lKFbxDouble3.Get()[2]); // Display the Specular Color (unique to Phong materials) lKFbxDouble3 =((FbxSurfacePhong *) pFbxMaterial)->Specular; theColor.Set(lKFbxDouble3.Get()[0], lKFbxDouble3.Get()[1], lKFbxDouble3.Get()[2]); // Display the Emissive Color lKFbxDouble3 =((FbxSurfacePhong *) pFbxMaterial)->Emissive; theColor.Set(lKFbxDouble3.Get()[0], lKFbxDouble3.Get()[1], lKFbxDouble3.Get()[2]); //Opacity is Transparency factor now lKFbxDouble1 =((FbxSurfacePhong *) pFbxMaterial)->TransparencyFactor; // Display the Shininess lKFbxDouble1 =((FbxSurfacePhong *) pFbxMaterial)->Shininess; double dShininess = lKFbxDouble1.Get(); lKFbxDouble1 =((FbxSurfacePhong *) pFbxMaterial)->Specular; double dSpecular = lKFbxDouble1.Get(); lKFbxDouble1 =((FbxSurfacePhong *) pFbxMaterial)->SpecularFactor; double dSpecularFactor = lKFbxDouble1.Get(); material.m_fShininess = dShininess; material.m_fSpecular = dSpecular * dSpecularFactor; // Display the Reflectivity lKFbxDouble1 =((FbxSurfacePhong *) pFbxMaterial)->ReflectionFactor; material.m_fReflectionFactor = lKFbxDouble1.Get(); } else if(pFbxMaterial->GetClassId().Is(FbxSurfaceLambert::ClassId) ) { // We found a Lambert material. Display its properties. // Display the Ambient Color lKFbxDouble3=((FbxSurfaceLambert *)pFbxMaterial)->Ambient; theColor.Set(lKFbxDouble3.Get()[0], lKFbxDouble3.Get()[1], lKFbxDouble3.Get()[2]); // Display the Diffuse Color lKFbxDouble3 =((FbxSurfaceLambert *)pFbxMaterial)->Diffuse; theColor.Set(lKFbxDouble3.Get()[0], lKFbxDouble3.Get()[1], lKFbxDouble3.Get()[2]); // Display the Emissive lKFbxDouble3 =((FbxSurfaceLambert *)pFbxMaterial)->Emissive; theColor.Set(lKFbxDouble3.Get()[0], lKFbxDouble3.Get()[1], lKFbxDouble3.Get()[2]); // Display the Opacity lKFbxDouble1 =((FbxSurfaceLambert *)pFbxMaterial)->TransparencyFactor; } else Logger::Debug("Unknown type of Material"); FbxProperty prop = pFbxMaterial->FindProperty(FbxSurfaceMaterial::sDiffuse); // Check if it's layeredtextures int layeredTextureCount = prop.GetSrcObjectCount<FbxLayeredTexture>(); for (int j = 0; j < layeredTextureCount; j++) { FbxLayeredTexture* layered_texture = FbxCast<FbxLayeredTexture>(prop.GetSrcObject<FbxLayeredTexture>(j)); int lcount = layered_texture->GetSrcObjectCount<FbxFileTexture>(); for (int k = 0; k < lcount; k++) { FbxFileTexture* texture = FbxCast<FbxFileTexture>(layered_texture->GetSrcObject<FbxFileTexture>(k)); // Then, you can get all the properties of the texture, include its name const char* textureName = texture->GetFileName(); material.AddTexture(rm.LoadImageFromFile(textureName)); } } int textureCount = prop.GetSrcObjectCount<FbxFileTexture>(); for(int i=0; i<textureCount; ++i){ FbxFileTexture* texture = FbxCast<FbxFileTexture>(prop.GetSrcObject<FbxFileTexture>(i)); const char* textureName = texture->GetFileName(); material.AddTexture(rm.LoadImageFromFile(textureName)); } FbxPropertyT<FbxString> lString; lString = pFbxMaterial->ShadingModel; }
void Material::ExportMaterials(FbxScene* scene, FbxMesh* mesh, const ImporterMesh& importedMesh, const ImporterMaterial* importedMaterials) { for (int i = 0; i < importedMesh.material_count; i++) { FbxNode* node = mesh->GetNode(); FbxString materialName = importedMaterials[importedMesh.material_Id[i]].name; FbxString shadingName; FbxDouble3 diffuseColor(importedMaterials[importedMesh.material_Id[i]].diffuse[0], importedMaterials[importedMesh.material_Id[i]].diffuse[1], importedMaterials[importedMesh.material_Id[i]].diffuse[2]); FbxDouble3 ambientColor(importedMaterials[importedMesh.material_Id[i]].ambient[0], importedMaterials[importedMesh.material_Id[i]].ambient[1], importedMaterials[importedMesh.material_Id[i]].ambient[2]); FbxDouble3 emissiveColor(importedMaterials[importedMesh.material_Id[i]].incandescence[0], importedMaterials[importedMesh.material_Id[i]].incandescence[1], importedMaterials[importedMesh.material_Id[i]].incandescence[2]); FbxDouble3 transparencyColor(importedMaterials[importedMesh.material_Id[i]].transparency_color[0], importedMaterials[importedMesh.material_Id[i]].transparency_color[1], importedMaterials[importedMesh.material_Id[i]].transparency_color[2]); FbxDouble3 specularColor(importedMaterials[importedMesh.material_Id[i]].specular[0], importedMaterials[importedMesh.material_Id[i]].specular[1] , importedMaterials[importedMesh.material_Id[i]].specular[2]); const char* pathName = "C://Users/Litet/Documents/GitHub/SmallGameProject/FBX Export/FBX Export/"; // Lambert if (importedMaterials[importedMesh.material_Id[i]].mtrl_type == 0) { shadingName = "Lambert"; FbxSurfaceLambert* material = NULL; material= node->GetSrcObject<FbxSurfaceLambert>(0); material = FbxSurfaceLambert::Create(scene, materialName.Buffer()); materialName += i; material->Emissive.Set(emissiveColor); material->Ambient.Set(ambientColor); material->Diffuse.Set(diffuseColor); material->DiffuseFactor.Set(importedMaterials[importedMesh.material_Id[i]].diffuse_factor); material->TransparentColor.Set(transparencyColor); FbxNode* node = mesh->GetNode(); if (node) { node->AddMaterial(material); } // Diffuse Texture FbxFileTexture* texture = FbxFileTexture::Create(scene, "Diffuse Texture"); std::cout << "DAFUSE MAP LENGTH: " << importedMaterials[importedMesh.material_Id[i]].duffuse_map_length << std::endl; if (importedMaterials[importedMesh.material_Id[i]].duffuse_map_length > 0) { std::string tmp(pathName); tmp += importedMaterials[importedMesh.material_Id[i]].diffuse_map; texture->SetFileName(tmp.c_str()); texture->SetTextureUse(FbxTexture::eStandard); texture->SetMappingType(FbxTexture::eUV); texture->SetMaterialUse(FbxFileTexture::eModelMaterial); texture->SetSwapUV(false); texture->SetTranslation(0.0, 0.0); texture->SetScale(1.0, 1.0); texture->SetRotation(0.0, 0.0); if (material) material->Diffuse.ConnectSrcObject(texture); } // Normal Texture texture = FbxFileTexture::Create(scene, "Normal Texture"); if (importedMaterials[importedMesh.material_Id[i]].normal_map_length > 0) { texture->SetFileName(importedMaterials[importedMesh.material_Id[i]].normal_map); texture->SetTextureUse(FbxTexture::eStandard); texture->SetMappingType(FbxTexture::eUV); texture->SetMaterialUse(FbxFileTexture::eModelMaterial); texture->SetSwapUV(false); texture->SetTranslation(0.0, 0.0); texture->SetScale(1.0, 1.0); texture->SetRotation(0.0, 0.0); if (material) material->NormalMap.ConnectSrcObject(texture); } } // Phong else { shadingName = "Phong"; FbxSurfacePhong* material = NULL; material = node->GetSrcObject<FbxSurfacePhong>(0); material = FbxSurfacePhong::Create(scene, materialName.Buffer()); materialName += i; material->Emissive.Set(emissiveColor); material->Ambient.Set(ambientColor); material->Diffuse.Set(diffuseColor); material->DiffuseFactor.Set(importedMaterials[importedMesh.material_Id[i]].diffuse_factor); material->TransparentColor.Set(transparencyColor); material->Specular.Set(specularColor); // No need... super boost? //material->SpecularFactor.Set(importedMaterials[importedMesh.material_Id[i]].specular_factor * 100); material->Shininess.Set(importedMaterials[importedMesh.material_Id[i]].specular_factor); material->Reflection.Set(FbxDouble3(importedMaterials[importedMesh.material_Id[i]].reflection[0], importedMaterials[importedMesh.material_Id[i]].reflection[1], importedMaterials[importedMesh.material_Id[i]].reflection[2])); // Bugged...? material->ReflectionFactor.Set(FbxDouble(importedMaterials[importedMesh.material_Id[i]].reflection_factor)); cout << importedMaterials[importedMesh.material_Id[i]].shininess << endl; FbxNode* node = mesh->GetNode(); if (node) { node->AddMaterial(material); } // Diffuse Texture FbxFileTexture* texture = FbxFileTexture::Create(scene, "Diffuse Texture"); if (importedMaterials[importedMesh.material_Id[i]].duffuse_map_length > 0) { texture->SetFileName(importedMaterials[importedMesh.material_Id[i]].diffuse_map); texture->SetTextureUse(FbxTexture::eStandard); texture->SetMappingType(FbxTexture::eUV); texture->SetMaterialUse(FbxFileTexture::eModelMaterial); texture->SetSwapUV(false); texture->SetTranslation(0.0, 0.0); texture->SetScale(1.0, 1.0); texture->SetRotation(0.0, 0.0); if (material) material->Diffuse.ConnectSrcObject(texture); } // Specular Texture texture = FbxFileTexture::Create(scene, "Specular Texture"); if (importedMaterials[importedMesh.material_Id[i]].specular_map_length > 0) { texture->SetFileName(importedMaterials[importedMesh.material_Id[i]].specular_map); texture->SetTextureUse(FbxTexture::eStandard); texture->SetMappingType(FbxTexture::eUV); texture->SetMaterialUse(FbxFileTexture::eModelMaterial); texture->SetSwapUV(false); texture->SetTranslation(0.0, 0.0); texture->SetScale(1.0, 1.0); texture->SetRotation(0.0, 0.0); if (material) material->Specular.ConnectSrcObject(texture); } // Normal Texture texture = FbxFileTexture::Create(scene, "Normal Texture"); if (importedMaterials[importedMesh.material_Id[i]].normal_map_length > 0) { texture->SetFileName(importedMaterials[importedMesh.material_Id[i]].normal_map); texture->SetTextureUse(FbxTexture::eStandard); texture->SetMappingType(FbxTexture::eUV); texture->SetMaterialUse(FbxFileTexture::eModelMaterial); texture->SetSwapUV(false); texture->SetTranslation(0.0, 0.0); texture->SetScale(1.0, 1.0); texture->SetRotation(0.0, 0.0); if (material) material->NormalMap.ConnectSrcObject(texture); } } } }
//converts a FBX mesh to a CC mesh static ccMesh* FromFbxMesh(FbxMesh* fbxMesh, FileIOFilter::LoadParameters& parameters) { if (!fbxMesh) return 0; int polyCount = fbxMesh->GetPolygonCount(); //fbxMesh->GetLayer( unsigned triCount = 0; unsigned polyVertCount = 0; //different from vertCount (vertices can be counted multiple times here!) //as we can't load all polygons (yet ;) we already look if we can load any! { unsigned skipped = 0; for (int i=0; i<polyCount; ++i) { int pSize = fbxMesh->GetPolygonSize(i); if (pSize == 3) { ++triCount; polyVertCount += 3; } else if (pSize == 4) { triCount += 2; polyVertCount += 4; } else { ++skipped; } } if (triCount == 0) { ccLog::Warning(QString("[FBX] No triangle or quad found in mesh '%1'! (polygons with more than 4 vertices are not supported for the moment)").arg(fbxMesh->GetName())); return 0; } else if (skipped != 0) { ccLog::Warning(QString("[FBX] Some polygons in mesh '%1' were ignored (%2): polygons with more than 4 vertices are not supported for the moment)").arg(fbxMesh->GetName()).arg(skipped)); return 0; } } int vertCount = fbxMesh->GetControlPointsCount(); if (vertCount <= 0) { ccLog::Warning(QString("[FBX] Mesh '%1' has no vetex or no polygon?!").arg(fbxMesh->GetName())); return 0; } ccPointCloud* vertices = new ccPointCloud("vertices"); ccMesh* mesh = new ccMesh(vertices); mesh->setName(fbxMesh->GetName()); mesh->addChild(vertices); vertices->setEnabled(false); if (!mesh->reserve(static_cast<unsigned>(triCount)) || !vertices->reserve(vertCount)) { ccLog::Warning(QString("[FBX] Not enough memory to load mesh '%1'!").arg(fbxMesh->GetName())); delete mesh; return 0; } //colors { for (int l=0; l<fbxMesh->GetElementVertexColorCount(); l++) { FbxGeometryElementVertexColor* vertColor = fbxMesh->GetElementVertexColor(l); //CC can only handle per-vertex colors if (vertColor->GetMappingMode() == FbxGeometryElement::eByControlPoint) { if (vertColor->GetReferenceMode() == FbxGeometryElement::eDirect || vertColor->GetReferenceMode() == FbxGeometryElement::eIndexToDirect) { if (vertices->reserveTheRGBTable()) { switch (vertColor->GetReferenceMode()) { case FbxGeometryElement::eDirect: { for (int i=0; i<vertCount; ++i) { FbxColor c = vertColor->GetDirectArray().GetAt(i); vertices->addRGBColor( static_cast<colorType>(c.mRed * ccColor::MAX), static_cast<colorType>(c.mGreen * ccColor::MAX), static_cast<colorType>(c.mBlue * ccColor::MAX) ); } } break; case FbxGeometryElement::eIndexToDirect: { for (int i=0; i<vertCount; ++i) { int id = vertColor->GetIndexArray().GetAt(i); FbxColor c = vertColor->GetDirectArray().GetAt(id); vertices->addRGBColor( static_cast<colorType>(c.mRed * ccColor::MAX), static_cast<colorType>(c.mGreen * ccColor::MAX), static_cast<colorType>(c.mBlue * ccColor::MAX) ); } } break; default: assert(false); break; } vertices->showColors(true); mesh->showColors(true); break; //no need to look for other color fields (we won't be able to handle them! } else { ccLog::Warning(QString("[FBX] Not enough memory to load mesh '%1' colors!").arg(fbxMesh->GetName())); } } else { ccLog::Warning(QString("[FBX] Color field #%i of mesh '%1' will be ignored (unhandled type)").arg(l).arg(fbxMesh->GetName())); } } else { ccLog::Warning(QString("[FBX] Color field #%i of mesh '%1' will be ignored (unhandled type)").arg(l).arg(fbxMesh->GetName())); } } } //normals can be per vertices or per-triangle int perPointNormals = -1; int perVertexNormals = -1; int perPolygonNormals = -1; { for (int j=0; j<fbxMesh->GetElementNormalCount(); j++) { FbxGeometryElementNormal* leNormals = fbxMesh->GetElementNormal(j); switch(leNormals->GetMappingMode()) { case FbxGeometryElement::eByControlPoint: perPointNormals = j; break; case FbxGeometryElement::eByPolygonVertex: perVertexNormals = j; break; case FbxGeometryElement::eByPolygon: perPolygonNormals = j; break; default: //not handled break; } } } //per-point normals if (perPointNormals >= 0) { FbxGeometryElementNormal* leNormals = fbxMesh->GetElementNormal(perPointNormals); FbxLayerElement::EReferenceMode refMode = leNormals->GetReferenceMode(); const FbxLayerElementArrayTemplate<FbxVector4>& normals = leNormals->GetDirectArray(); assert(normals.GetCount() == vertCount); if (normals.GetCount() != vertCount) { ccLog::Warning(QString("[FBX] Wrong number of normals on mesh '%1'!").arg(fbxMesh->GetName())); perPointNormals = -1; } else if (!vertices->reserveTheNormsTable()) { ccLog::Warning(QString("[FBX] Not enough memory to load mesh '%1' normals!").arg(fbxMesh->GetName())); perPointNormals = -1; } else { //import normals for (int i=0; i<vertCount; ++i) { int id = refMode != FbxGeometryElement::eDirect ? leNormals->GetIndexArray().GetAt(i) : i; FbxVector4 N = normals.GetAt(id); //convert to CC-structure CCVector3 Npc( static_cast<PointCoordinateType>(N.Buffer()[0]), static_cast<PointCoordinateType>(N.Buffer()[1]), static_cast<PointCoordinateType>(N.Buffer()[2]) ); vertices->addNorm(Npc); } vertices->showNormals(true); mesh->showNormals(true); //no need to import the other normals (if any) perVertexNormals = -1; perPolygonNormals = -1; } } //per-triangle normals NormsIndexesTableType* normsTable = 0; if (perVertexNormals >= 0 || perPolygonNormals >= 0) { normsTable = new NormsIndexesTableType(); if (!normsTable->reserve(polyVertCount) || !mesh->reservePerTriangleNormalIndexes()) { ccLog::Warning(QString("[FBX] Not enough memory to load mesh '%1' normals!").arg(fbxMesh->GetName())); normsTable->release(); normsTable = 0; } else { mesh->setTriNormsTable(normsTable); vertices->showNormals(true); mesh->showNormals(true); } } //materials ccMaterialSet* materials = 0; { FbxNode* lNode = fbxMesh->GetNode(); int lMaterialCount = lNode ? lNode->GetMaterialCount() : 0; for (int i=0; i<lMaterialCount; i++) { FbxSurfaceMaterial *lBaseMaterial = lNode->GetMaterial(i); bool isLambert = lBaseMaterial->GetClassId().Is(FbxSurfaceLambert::ClassId); bool isPhong = lBaseMaterial->GetClassId().Is(FbxSurfacePhong::ClassId); if (isLambert || isPhong) { ccMaterial::Shared mat(new ccMaterial(lBaseMaterial->GetName())); FbxSurfaceLambert* lLambertMat = static_cast<FbxSurfaceLambert*>(lBaseMaterial); float ambient[4]; float diffuse[4]; float emission[4]; float specular[4]; FbxSurfacePhong* lPhongMat = isPhong ? static_cast<FbxSurfacePhong*>(lBaseMaterial) : 0; for (int k=0; k<3; ++k) { ambient[k] = static_cast<float>(lLambertMat->Ambient.Get()[k]); diffuse[k] = static_cast<float>(lLambertMat->Diffuse.Get()[k]); emission[k] = static_cast<float>(lLambertMat->Emissive.Get()[k]); if (lPhongMat) { specular[k] = static_cast<float>(lPhongMat->Specular.Get()[k]); } } mat->setAmbient(ambient); mat->setDiffuse(diffuse); mat->setEmission(emission); if (isPhong) { mat->setSpecular(specular); assert(lPhongMat); mat->setShininess(static_cast<float>(lPhongMat->Shininess)); } //import associated texture (if any) { int lTextureIndex; FBXSDK_FOR_EACH_TEXTURE(lTextureIndex) { FbxProperty lProperty = lBaseMaterial->FindProperty(FbxLayerElement::sTextureChannelNames[lTextureIndex]); if( lProperty.IsValid() ) { int lTextureCount = lProperty.GetSrcObjectCount<FbxTexture>(); FbxTexture* texture = 0; //we can handle only one texture per material! We'll take the non layered one by default (if any) for (int j = 0; j < lTextureCount; ++j) { //Here we have to check if it's layeredtextures, or just textures: FbxLayeredTexture *lLayeredTexture = lProperty.GetSrcObject<FbxLayeredTexture>(j); if (lLayeredTexture) { //we don't handle layered textures! /*int lNbTextures = lLayeredTexture->GetSrcObjectCount<FbxTexture>(); for (int k=0; k<lNbTextures; ++k) { FbxTexture* lTexture = lLayeredTexture->GetSrcObject<FbxTexture>(k); if(lTexture) { } } //*/ } else { //non-layered texture FbxTexture* lTexture = lProperty.GetSrcObject<FbxTexture>(j); if(lTexture) { //we take the first non layered texture by default texture = lTexture; break; } } } if (texture) { FbxFileTexture *lFileTexture = FbxCast<FbxFileTexture>(texture); if (lFileTexture) { const char* texAbsoluteFilename = lFileTexture->GetFileName(); ccLog::PrintDebug(QString("[FBX] Texture absolue filename: %1").arg(texAbsoluteFilename)); if (texAbsoluteFilename != 0 && texAbsoluteFilename[0] != 0) { if (!mat->loadAndSetTexture(texAbsoluteFilename)) { ccLog::Warning(QString("[FBX] Failed to load texture file: %1").arg(texAbsoluteFilename)); } } } } } } } if (!materials) { materials = new ccMaterialSet("materials"); mesh->addChild(materials); } materials->addMaterial(mat); } else { ccLog::Warning(QString("[FBX] Material '%1' has an unhandled type").arg(lBaseMaterial->GetName())); } }
FbxDouble3 CFBXLoader::GetMaterialProperty( const FbxSurfaceMaterial * pMaterial, const char * pPropertyName, const char * pFactorPropertyName, FBX_MATRIAL_ELEMENT* pElement) { pElement->type = FBX_MATRIAL_ELEMENT::ELEMENT_NONE; FbxDouble3 lResult(0, 0, 0); const FbxProperty lProperty = pMaterial->FindProperty(pPropertyName); const FbxProperty lFactorProperty = pMaterial->FindProperty(pFactorPropertyName); if (lProperty.IsValid() && lFactorProperty.IsValid()) { lResult = lProperty.Get<FbxDouble3>(); double lFactor = lFactorProperty.Get<FbxDouble>(); if (lFactor != 1) { lResult[0] *= lFactor; lResult[1] *= lFactor; lResult[2] *= lFactor; } pElement->type = FBX_MATRIAL_ELEMENT::ELEMENT_COLOR; } if (lProperty.IsValid()) { int existTextureCount = 0; const int lTextureCount = lProperty.GetSrcObjectCount<FbxFileTexture>(); for(int i=0;i<lTextureCount;i++) { FbxFileTexture* lFileTexture = lProperty.GetSrcObject<FbxFileTexture>(i); if(!lFileTexture) continue; FbxString uvsetName = lFileTexture->UVSet.Get(); std::string uvSetString = uvsetName.Buffer(); std::string filepath = lFileTexture->GetFileName(); pElement->textureSetArray[uvSetString].push_back(filepath); existTextureCount++; } const int lLayeredTextureCount = lProperty.GetSrcObjectCount<FbxLayeredTexture>(); for(int i=0;i<lLayeredTextureCount;i++) { FbxLayeredTexture* lLayeredTexture = lProperty.GetSrcObject<FbxLayeredTexture>(i); const int lTextureFileCount = lLayeredTexture->GetSrcObjectCount<FbxFileTexture>(); for(int j=0;j<lTextureFileCount;j++) { FbxFileTexture* lFileTexture = lLayeredTexture->GetSrcObject<FbxFileTexture>(j); if(!lFileTexture) continue; FbxString uvsetName = lFileTexture->UVSet.Get(); std::string uvSetString = uvsetName.Buffer(); std::string filepath = lFileTexture->GetFileName(); pElement->textureSetArray[uvSetString].push_back(filepath); existTextureCount++; } } if(existTextureCount > 0) { if(pElement->type == FBX_MATRIAL_ELEMENT::ELEMENT_COLOR) pElement->type = FBX_MATRIAL_ELEMENT::ELEMENT_BOTH; else pElement->type = FBX_MATRIAL_ELEMENT::ELEMENT_TEXTURE; } } return lResult; }
// Converts a CC mesh to an FBX mesh static FbxNode* ToFbxMesh(ccGenericMesh* mesh, FbxScene* pScene, QString filename, size_t meshIndex) { if (!mesh) return 0; FbxNode* lNode = FbxNode::Create(pScene,qPrintable(mesh->getName())); FbxMesh* lMesh = FbxMesh::Create(pScene, qPrintable(mesh->getName())); lNode->SetNodeAttribute(lMesh); ccGenericPointCloud* cloud = mesh->getAssociatedCloud(); if (!cloud) return 0; unsigned vertCount = cloud->size(); unsigned faceCount = mesh->size(); // Create control points. { lMesh->InitControlPoints(vertCount); FbxVector4* lControlPoints = lMesh->GetControlPoints(); for (unsigned i=0; i<vertCount; ++i) { const CCVector3* P = cloud->getPoint(i); lControlPoints[i] = FbxVector4(P->x,P->y,P->z); //lControlPoints[i] = FbxVector4(P->x,P->z,-P->y); //DGM: see loadFile (Y and Z are inverted) } } ccMesh* asCCMesh = 0; if (mesh->isA(CC_TYPES::MESH)) asCCMesh = static_cast<ccMesh*>(mesh); // normals if (mesh->hasNormals()) { FbxGeometryElementNormal* lGeometryElementNormal = lMesh->CreateElementNormal(); if (mesh->hasTriNormals()) { // We want to have one normal per vertex of each polygon, // so we set the mapping mode to eByPolygonVertex. lGeometryElementNormal->SetMappingMode(FbxGeometryElement::eByPolygonVertex); lGeometryElementNormal->SetReferenceMode(FbxGeometryElement::eIndexToDirect); lGeometryElementNormal->GetIndexArray().SetCount(faceCount*3); if (asCCMesh) { NormsIndexesTableType* triNorms = asCCMesh->getTriNormsTable(); assert(triNorms); for (unsigned i=0; i<triNorms->currentSize(); ++i) { const CCVector3& N = ccNormalVectors::GetNormal(triNorms->getValue(i)); FbxVector4 Nfbx(N.x,N.y,N.z); lGeometryElementNormal->GetDirectArray().Add(Nfbx); } for (unsigned j=0; j<faceCount; ++j) { int i1,i2,i3; asCCMesh->getTriangleNormalIndexes(j,i1,i2,i3); lGeometryElementNormal->GetIndexArray().SetAt(static_cast<int>(j)*3+0, i1); lGeometryElementNormal->GetIndexArray().SetAt(static_cast<int>(j)*3+1, i2); lGeometryElementNormal->GetIndexArray().SetAt(static_cast<int>(j)*3+2, i3); } } else { for (unsigned j=0; j<faceCount; ++j) { //we can't use the 'NormsIndexesTable' so we save all the normals of all the vertices CCVector3 Na,Nb,Nc; lGeometryElementNormal->GetDirectArray().Add(FbxVector4(Na.x,Na.y,Na.z)); lGeometryElementNormal->GetDirectArray().Add(FbxVector4(Nb.x,Nb.y,Nb.z)); lGeometryElementNormal->GetDirectArray().Add(FbxVector4(Nc.x,Nc.y,Nc.z)); mesh->getTriangleNormals(j,Na,Nb,Nc); lGeometryElementNormal->GetIndexArray().SetAt(static_cast<int>(j)*3+0, static_cast<int>(j)*3+0); lGeometryElementNormal->GetIndexArray().SetAt(static_cast<int>(j)*3+1, static_cast<int>(j)*3+1); lGeometryElementNormal->GetIndexArray().SetAt(static_cast<int>(j)*3+2, static_cast<int>(j)*3+2); } } } else { // We want to have one normal for each vertex (or control point), // so we set the mapping mode to eByControlPoint. lGeometryElementNormal->SetMappingMode(FbxGeometryElement::eByControlPoint); // The first method is to set the actual normal value // for every control point. lGeometryElementNormal->SetReferenceMode(FbxGeometryElement::eDirect); for (unsigned i=0; i<vertCount; ++i) { const CCVector3& N = cloud->getPointNormal(i); FbxVector4 Nfbx(N.x,N.y,N.z); lGeometryElementNormal->GetDirectArray().Add(Nfbx); } } } else { ccLog::Warning("[FBX] Mesh has no normal! You can manually compute them (select it then call \"Edit > Normals > Compute\")"); } // Set material mapping. bool hasMaterial = false; if (asCCMesh && asCCMesh->hasMaterials()) { const ccMaterialSet* matSet = asCCMesh->getMaterialSet(); size_t matCount = matSet->size(); //check if we have textures bool hasTextures = asCCMesh->hasTextures(); if (hasTextures) { //check that we actually have materials with textures as well! hasTextures = false; for (size_t i=0; i<matCount; ++i) { ccMaterial::CShared mat = matSet->at(i); if (mat->hasTexture()) { hasTextures = true; break; } } } static const char gDiffuseElementName[] = "DiffuseUV"; // Create UV for Diffuse channel if (hasTextures) { FbxGeometryElementUV* lUVDiffuseElement = lMesh->CreateElementUV(gDiffuseElementName); assert(lUVDiffuseElement != 0); lUVDiffuseElement->SetMappingMode(FbxGeometryElement::eByPolygonVertex); lUVDiffuseElement->SetReferenceMode(FbxGeometryElement::eIndexToDirect); //fill Direct Array const TextureCoordsContainer* texCoords = asCCMesh->getTexCoordinatesTable(); assert(texCoords); if (texCoords) { unsigned count = texCoords->currentSize(); lUVDiffuseElement->GetDirectArray().SetCount(static_cast<int>(count)); for (unsigned i=0; i<count; ++i) { const float* uv = texCoords->getValue(i); lUVDiffuseElement->GetDirectArray().SetAt(i,FbxVector2(uv[0],uv[1])); } } //fill Indexes Array assert(asCCMesh->hasPerTriangleTexCoordIndexes()); if (asCCMesh->hasPerTriangleTexCoordIndexes()) { unsigned triCount = asCCMesh->size(); lUVDiffuseElement->GetIndexArray().SetCount(static_cast<int>(3*triCount)); for (unsigned j=0; j<triCount; ++j) { int t1=0, t2=0, t3=0; asCCMesh->getTriangleTexCoordinatesIndexes(j, t1, t2, t3); lUVDiffuseElement->GetIndexArray().SetAt(j*3+0,t1); lUVDiffuseElement->GetIndexArray().SetAt(j*3+1,t2); lUVDiffuseElement->GetIndexArray().SetAt(j*3+2,t3); } } } //Textures used in this file QMap<QString,QString> texFilenames; //directory to save textures (if any) QFileInfo info(filename); QString textDirName = info.baseName() + QString(".fbm"); QDir baseDir = info.absoluteDir(); QDir texDir = QDir(baseDir.absolutePath() + QString("/") + textDirName); for (size_t i=0; i<matCount; ++i) { ccMaterial::CShared mat = matSet->at(i); FbxSurfacePhong *lMaterial = FbxSurfacePhong::Create(pScene, qPrintable(mat->getName())); const ccColor::Rgbaf& emission = mat->getEmission(); const ccColor::Rgbaf& ambient = mat->getAmbient(); const ccColor::Rgbaf& diffuse = mat->getDiffuseFront(); const ccColor::Rgbaf& specular = mat->getDiffuseFront(); lMaterial->Emissive.Set(FbxDouble3(emission.r,emission.g,emission.b)); lMaterial->Ambient .Set(FbxDouble3( ambient.r, ambient.g, ambient.b)); lMaterial->Diffuse .Set(FbxDouble3( diffuse.r, diffuse.g, diffuse.b)); lMaterial->Specular.Set(FbxDouble3(specular.r,specular.g,specular.b)); lMaterial->Shininess = mat->getShininessFront(); lMaterial->ShadingModel.Set("Phong"); if (hasTextures && mat->hasTexture()) { QString texFilename = mat->getTextureFilename(); //texture has not already been processed if (!texFilenames.contains(texFilename)) { //if necessary, we (try to) create a subfolder to store textures if (!texDir.exists()) { texDir = baseDir; if (texDir.mkdir(textDirName)) { texDir.cd(textDirName); } else { textDirName = QString(); ccLog::Warning("[FBX] Failed to create subfolder '%1' to store texture files (files will be stored next to the .fbx file)"); } } QFileInfo fileInfo(texFilename); QString baseTexName = fileInfo.fileName(); //add extension QString extension = QFileInfo(texFilename).suffix(); if (fileInfo.suffix().isEmpty()) baseTexName += QString(".png"); QString absoluteFilename = texDir.absolutePath() + QString("/") + baseTexName; ccLog::PrintDebug(QString("[FBX] Material '%1' texture: %2").arg(mat->getName()).arg(absoluteFilename)); texFilenames[texFilename] = absoluteFilename; } //mat.texture.save(absoluteFilename); // Set texture properties. FbxFileTexture* lTexture = FbxFileTexture::Create(pScene,"DiffuseTexture"); assert(!texFilenames[texFilename].isEmpty()); lTexture->SetFileName(qPrintable(texFilenames[texFilename])); lTexture->SetTextureUse(FbxTexture::eStandard); lTexture->SetMappingType(FbxTexture::eUV); lTexture->SetMaterialUse(FbxFileTexture::eModelMaterial); lTexture->SetSwapUV(false); lTexture->SetTranslation(0.0, 0.0); lTexture->SetScale(1.0, 1.0); lTexture->SetRotation(0.0, 0.0); lTexture->UVSet.Set(FbxString(gDiffuseElementName)); // Connect texture to the proper UV // don't forget to connect the texture to the corresponding property of the material lMaterial->Diffuse.ConnectSrcObject(lTexture); } int matIndex = lNode->AddMaterial(lMaterial); assert(matIndex == static_cast<int>(i)); } //don't forget to save the texture files { for (QMap<QString,QString>::ConstIterator it = texFilenames.begin(); it != texFilenames.end(); ++it) { const QImage image = ccMaterial::GetTexture(it.key()); image.mirrored().save(it.value()); } texFilenames.clear(); //don't need this anymore! } // Create 'triangle to material index' mapping { FbxGeometryElementMaterial* lMaterialElement = lMesh->CreateElementMaterial(); lMaterialElement->SetMappingMode(FbxGeometryElement::eByPolygon); lMaterialElement->SetReferenceMode(FbxGeometryElement::eIndexToDirect); } hasMaterial = true; } // colors if (cloud->hasColors()) { FbxGeometryElementVertexColor* lGeometryElementVertexColor = lMesh->CreateElementVertexColor(); lGeometryElementVertexColor->SetMappingMode(FbxGeometryElement::eByControlPoint); lGeometryElementVertexColor->SetReferenceMode(FbxGeometryElement::eDirect); lGeometryElementVertexColor->GetDirectArray().SetCount(vertCount); for (unsigned i=0; i<vertCount; ++i) { const colorType* C = cloud->getPointColor(i); FbxColor col( static_cast<double>(C[0])/ccColor::MAX, static_cast<double>(C[1])/ccColor::MAX, static_cast<double>(C[2])/ccColor::MAX ); lGeometryElementVertexColor->GetDirectArray().SetAt(i,col); } if (!hasMaterial) { //it seems that we have to create a fake material in order for the colors to be displayed (in Unity and FBX Review at least)! FbxSurfacePhong *lMaterial = FbxSurfacePhong::Create(pScene, "ColorMaterial"); lMaterial->Emissive.Set(FbxDouble3(0,0,0)); lMaterial->Ambient.Set(FbxDouble3(0,0,0)); lMaterial->Diffuse.Set(FbxDouble3(1,1,1)); lMaterial->Specular.Set(FbxDouble3(0,0,0)); lMaterial->Shininess = 0; lMaterial->ShadingModel.Set("Phong"); FbxGeometryElementMaterial* lMaterialElement = lMesh->CreateElementMaterial(); lMaterialElement->SetMappingMode(FbxGeometryElement::eAllSame); lMaterialElement->SetReferenceMode(FbxGeometryElement::eDirect); lNode->AddMaterial(lMaterial); } } // Create polygons { for (unsigned j=0; j<faceCount; ++j) { const CCLib::TriangleSummitsIndexes* tsi = mesh->getTriangleIndexes(j); int matIndex = hasMaterial ? asCCMesh->getTriangleMtlIndex(j) : -1; lMesh->BeginPolygon(matIndex); lMesh->AddPolygon(tsi->i1); lMesh->AddPolygon(tsi->i2); lMesh->AddPolygon(tsi->i3); lMesh->EndPolygon(); } } return lNode; }
G2::Entity FBXMesh::Builder::buildResource(bool importNormals, bool importTexCoords, bool importAnimations, bool flipTexU, bool flipTexV, TextureImporter* texImporte, G2::Entity* target) { // create mesh G2::Entity meshLocal; G2::Entity* mesh = &meshLocal; if (target != nullptr) { mesh = target; // in case the user gave a valid pointer, we don't write into the local mesh } if(isAnimated && importAnimations) { // prepare animationData FBXAnimationData animData(cacheStart, cacheStop, animStackNameArray, 24.0); // prepare animation state FBXAnimationState animState(poseIndex, initialAnimLayer, initialAnimationStack, start, stop, false); auto* fbxAnimationComponent = mesh->addComponent<FBXAnimationComponent>(fbxScene, animState, animData); } #ifdef USE_META_DATA // create a RenderComponent with the requested amount of VertexArrayObjects auto* renderComponent = mesh->addComponent<RenderComponent>(); renderComponent->allocateVertexArrays((unsigned int)meshMetaData.size()); // calculate the number of IndexArrayObjects we need unsigned int numIndexArrays = 0; for (unsigned int i = 0; i < meshMetaData.size() ; ++i) { MeshMetaData const& meshData = meshMetaData[i]; if(meshData.indices.size() > 0) { ++numIndexArrays; } } renderComponent->allocateIndexArrays(numIndexArrays); // init the VAO unsigned int totalVertices = 0; unsigned int currentIndexArrayIndex = 0; for (unsigned int i = 0; i < meshMetaData.size() ; ++i) { MeshMetaData const& meshData = meshMetaData[i]; renderComponent->getVertexArray(i).resizeElementCount((unsigned int)meshData.vertices.size()) .writeData(G2Core::Semantics::POSITION, &meshData.vertices[0]); totalVertices += (unsigned int)meshData.vertices.size(); if(meshData.hasNormals && importNormals) { renderComponent->getVertexArray(i).writeData(G2Core::Semantics::NORMAL, &meshData.normals[0]); } if(meshData.hasUvs && importTexCoords) { if (flipTexU || flipTexV) { std::vector<glm::vec2> uvCopy = meshData.uvs; // copy std::transform(uvCopy.begin(), uvCopy.end(), uvCopy.begin(), [flipTexU,flipTexV](glm::vec2& uv) { if (flipTexU) { uv.x = 1.0f - uv.x; } if (flipTexV) { uv.y = 1.0f - uv.y; } return uv; }); renderComponent->getVertexArray(i).writeData(G2Core::Semantics::TEXCOORD_0, &uvCopy[0]); } else { renderComponent->getVertexArray(i).writeData(G2Core::Semantics::TEXCOORD_0, &meshData.uvs[0]); } } if(meshData.indices.size() > 0) { IndexArrayObject& iao = renderComponent->getIndexArray(currentIndexArrayIndex); iao.writeIndices(&meshData.indices[0], (unsigned int)meshData.indices.size()); ++currentIndexArrayIndex; } // add a draw call renderComponent->addDrawCall(DrawCall() .setDrawMode(G2Core::DrawMode::TRIANGLES) .setEnabled(true) .setVaoIndex(i) .setModelSpaceAABB(meshData.modelSpaceAABB) .setIaoIndex(meshData.indices.size() > 0 ? currentIndexArrayIndex-1 : -1) .setAABBCalculationMode(AABBCalculationMode::MANUAL)); } G2::logger << "[FBXMesh] Name: " << name << "\n\tIAO: " << renderComponent->getNumIndexArrays() << "\n\tVAO: " << renderComponent->getNumVertexArrays() << "\n\tVertices: " << totalVertices << "\n\tDraw-Calls: " << renderComponent->getNumDrawCalls() << "\n\tTriangles: " << renderComponent->getNumTriangles() << G2::endl; #endif auto* nameComponent = mesh->addComponent<NameComponent>(); nameComponent->name = name; if (texImporte != nullptr && renderComponent != nullptr) { for (int i = 0; i < meshTextures.size(); ++i) { FbxFileTexture* fbxTex = meshTextures[i]; G2::Sampler::Name sampler = toSampler(fbxTex->GetTextureUse()); if (sampler != G2::Sampler::SAMPLER_INVALID && renderComponent->material.getTexture(sampler).get() == nullptr) { // sampler is valid and RenderComponent has not yet set a texture at that sampler const FbxString lAbsFolderName = FbxPathUtils::GetFolderName(FbxPathUtils::Resolve(meshFilePath.c_str())); const FbxString lResolvedFileName = FbxPathUtils::Bind(lAbsFolderName, fbxTex->GetRelativeFileName()); auto tex = texImporte->import( lResolvedFileName.Buffer(), G2Core::DataFormat::Internal::R32G32B32A32_F, G2Core::FilterMode::LINEAR, G2Core::FilterMode::LINEAR, false, toWrapMode(fbxTex->GetWrapModeU()), toWrapMode(fbxTex->GetWrapModeV()) ); if(tex.get() != nullptr) { renderComponent->material.setTexture(sampler, tex); } } } } return std::move(meshLocal); }
StateSetContent FbxMaterialToOsgStateSet::convert(const FbxSurfaceMaterial* pFbxMat) { FbxMaterialMap::const_iterator it = _fbxMaterialMap.find(pFbxMat); if (it != _fbxMaterialMap.end()) return it->second; osg::ref_ptr<osg::Material> pOsgMat = new osg::Material; pOsgMat->setName(pFbxMat->GetName()); StateSetContent result; result.material = pOsgMat; FbxString shadingModel = pFbxMat->ShadingModel.Get(); const FbxSurfaceLambert* pFbxLambert = FbxCast<FbxSurfaceLambert>(pFbxMat); // diffuse map... const FbxProperty lProperty = pFbxMat->FindProperty(FbxSurfaceMaterial::sDiffuse); if (lProperty.IsValid()) { int lNbTex = lProperty.GetSrcObjectCount<FbxFileTexture>(); for (int lTextureIndex = 0; lTextureIndex < lNbTex; lTextureIndex++) { FbxFileTexture* lTexture = FbxCast<FbxFileTexture>(lProperty.GetSrcObject<FbxFileTexture>(lTextureIndex)); if (lTexture) { result.diffuseTexture = fbxTextureToOsgTexture(lTexture); result.diffuseChannel = lTexture->UVSet.Get(); result.diffuseScaleU = lTexture->GetScaleU(); result.diffuseScaleV = lTexture->GetScaleV(); } //For now only allow 1 texture break; } } double transparencyColorFactor = 1.0; bool useTransparencyColorFactor = false; // opacity map... const FbxProperty lOpacityProperty = pFbxMat->FindProperty(FbxSurfaceMaterial::sTransparentColor); if (lOpacityProperty.IsValid()) { FbxDouble3 transparentColor = lOpacityProperty.Get<FbxDouble3>(); // If transparent color is defined set the transparentFactor to gray scale value of transparentColor if (transparentColor[0] < 1.0 || transparentColor[1] < 1.0 || transparentColor[2] < 1.0) { transparencyColorFactor = transparentColor[0]*0.30 + transparentColor[1]*0.59 + transparentColor[2]*0.11; useTransparencyColorFactor = true; } int lNbTex = lOpacityProperty.GetSrcObjectCount<FbxFileTexture>(); for (int lTextureIndex = 0; lTextureIndex < lNbTex; lTextureIndex++) { FbxFileTexture* lTexture = FbxCast<FbxFileTexture>(lOpacityProperty.GetSrcObject<FbxFileTexture>(lTextureIndex)); if (lTexture) { // TODO: if texture image does NOT have an alpha channel, should it be added? result.opacityTexture = fbxTextureToOsgTexture(lTexture); result.opacityChannel = lTexture->UVSet.Get(); result.opacityScaleU = lTexture->GetScaleU(); result.opacityScaleV = lTexture->GetScaleV(); } //For now only allow 1 texture break; } } // reflection map... const FbxProperty lReflectionProperty = pFbxMat->FindProperty(FbxSurfaceMaterial::sReflection); if (lReflectionProperty.IsValid()) { int lNbTex = lReflectionProperty.GetSrcObjectCount<FbxFileTexture>(); for (int lTextureIndex = 0; lTextureIndex < lNbTex; lTextureIndex++) { FbxFileTexture* lTexture = FbxCast<FbxFileTexture>(lReflectionProperty.GetSrcObject<FbxFileTexture>(lTextureIndex)); if (lTexture) { // support only spherical reflection maps... if (FbxFileTexture::eUMT_ENVIRONMENT == lTexture->CurrentMappingType.Get()) { result.reflectionTexture = fbxTextureToOsgTexture(lTexture); result.reflectionChannel = lTexture->UVSet.Get(); } } //For now only allow 1 texture break; } } // emissive map... const FbxProperty lEmissiveProperty = pFbxMat->FindProperty(FbxSurfaceMaterial::sEmissive); if (lEmissiveProperty.IsValid()) { int lNbTex = lEmissiveProperty.GetSrcObjectCount<FbxFileTexture>(); for (int lTextureIndex = 0; lTextureIndex < lNbTex; lTextureIndex++) { FbxFileTexture* lTexture = FbxCast<FbxFileTexture>(lEmissiveProperty.GetSrcObject<FbxFileTexture>(lTextureIndex)); if (lTexture) { result.emissiveTexture = fbxTextureToOsgTexture(lTexture); result.emissiveChannel = lTexture->UVSet.Get(); result.emissiveScaleU = lTexture->GetScaleU(); result.emissiveScaleV = lTexture->GetScaleV(); } //For now only allow 1 texture break; } } // ambient map... const FbxProperty lAmbientProperty = pFbxMat->FindProperty(FbxSurfaceMaterial::sAmbient); if (lAmbientProperty.IsValid()) { int lNbTex = lAmbientProperty.GetSrcObjectCount<FbxFileTexture>(); for (int lTextureIndex = 0; lTextureIndex < lNbTex; lTextureIndex++) { FbxFileTexture* lTexture = FbxCast<FbxFileTexture>(lAmbientProperty.GetSrcObject<FbxFileTexture>(lTextureIndex)); if (lTexture) { result.ambientTexture = fbxTextureToOsgTexture(lTexture); result.ambientChannel = lTexture->UVSet.Get(); result.ambientScaleU = lTexture->GetScaleU(); result.ambientScaleV = lTexture->GetScaleV(); } //For now only allow 1 texture break; } } if (pFbxLambert) { FbxDouble3 color = pFbxLambert->Diffuse.Get(); double factor = pFbxLambert->DiffuseFactor.Get(); double transparencyFactor = useTransparencyColorFactor ? transparencyColorFactor : pFbxLambert->TransparencyFactor.Get(); pOsgMat->setDiffuse(osg::Material::FRONT_AND_BACK, osg::Vec4( static_cast<float>(color[0] * factor), static_cast<float>(color[1] * factor), static_cast<float>(color[2] * factor), static_cast<float>(1.0 - transparencyFactor))); color = pFbxLambert->Ambient.Get(); factor = pFbxLambert->AmbientFactor.Get(); pOsgMat->setAmbient(osg::Material::FRONT_AND_BACK, osg::Vec4( static_cast<float>(color[0] * factor), static_cast<float>(color[1] * factor), static_cast<float>(color[2] * factor), 1.0f)); color = pFbxLambert->Emissive.Get(); factor = pFbxLambert->EmissiveFactor.Get(); pOsgMat->setEmission(osg::Material::FRONT_AND_BACK, osg::Vec4( static_cast<float>(color[0] * factor), static_cast<float>(color[1] * factor), static_cast<float>(color[2] * factor), 1.0f)); // get maps factors... result.diffuseFactor = pFbxLambert->DiffuseFactor.Get(); if (const FbxSurfacePhong* pFbxPhong = FbxCast<FbxSurfacePhong>(pFbxLambert)) { color = pFbxPhong->Specular.Get(); factor = pFbxPhong->SpecularFactor.Get(); pOsgMat->setSpecular(osg::Material::FRONT_AND_BACK, osg::Vec4( static_cast<float>(color[0] * factor), static_cast<float>(color[1] * factor), static_cast<float>(color[2] * factor), 1.0f)); // Since Maya and 3D studio Max stores their glossiness values in exponential format (2^(log2(x)) // We need to linearize to values between 0-100 and then scale to values between 0-128. // Glossiness values above 100 will result in shininess larger than 128.0 and will be clamped double shininess = (64.0 * log (pFbxPhong->Shininess.Get())) / (5.0 * log(2.0)); pOsgMat->setShininess(osg::Material::FRONT_AND_BACK, static_cast<float>(shininess)); // get maps factors... result.reflectionFactor = pFbxPhong->ReflectionFactor.Get(); // get more factors here... } } if (_lightmapTextures) { // if using an emission map then adjust material properties accordingly... if (result.emissiveTexture) { osg::Vec4 diffuse = pOsgMat->getDiffuse(osg::Material::FRONT_AND_BACK); pOsgMat->setEmission(osg::Material::FRONT_AND_BACK, diffuse); pOsgMat->setDiffuse(osg::Material::FRONT_AND_BACK, osg::Vec4(0,0,0,diffuse.a())); pOsgMat->setAmbient(osg::Material::FRONT_AND_BACK, osg::Vec4(0,0,0,diffuse.a())); } } _fbxMaterialMap.insert(FbxMaterialMap::value_type(pFbxMat, result)); return result; }
//-------------------------------------------------------------------------------------- void FBXScene::ProcessMaterials(FbxScene* pScene) { for( int i = 0; i < pScene->GetMaterialCount(); ++i ) { Material* pMaterial = new Material(i); FbxSurfaceMaterial* pFBXMaterial = pScene->GetMaterial(i); FbxProperty diffuseTextureProperty = pFBXMaterial->FindProperty(FbxSurfaceMaterial::sDiffuse); if( diffuseTextureProperty.IsValid() ) { FbxFileTexture* pDiffuseTexture = diffuseTextureProperty.GetSrcObject<FbxFileTexture>(0); if( pDiffuseTexture ) { std::string strFileName = pDiffuseTexture->GetFileName(); if( strFileName.length() == 0 ) strFileName = pDiffuseTexture->GetRelativeFileName(); strFileName = GetFileFromPath(strFileName); pMaterial->SetDiffuseTextureName(strFileName); } } FbxProperty normalTextureProperty = pFBXMaterial->FindProperty(FbxSurfaceMaterial::sNormalMap); if( normalTextureProperty.IsValid() ) { FbxFileTexture* pNormalTexture = normalTextureProperty.GetSrcObject<FbxFileTexture>(0); if( pNormalTexture ) { std::string strFileName = pNormalTexture->GetFileName(); if( strFileName.length() == 0 ) strFileName = pNormalTexture->GetRelativeFileName(); strFileName = GetFileFromPath(strFileName); pMaterial->SetNormalTextureName(strFileName); } } FbxSurfaceLambert* pLambert = FbxCast<FbxSurfaceLambert>(pFBXMaterial); FbxSurfacePhong* pPhong = FbxCast<FbxSurfacePhong>(pFBXMaterial); BTHFBX_VEC3 AmbientColor2; BTHFBX_VEC3 EmissiveColor2; BTHFBX_VEC3 DiffuseColor2; BTHFBX_VEC3 SpecularColor2; float fSpecularPower = 1.0f; float fTransparency = 1.0f; if( pLambert ) { AmbientColor2 = GetMaterialColor2(pLambert->Ambient, pLambert->AmbientFactor); EmissiveColor2 = GetMaterialColor2(pLambert->Emissive, pLambert->EmissiveFactor); DiffuseColor2 = GetMaterialColor2(pLambert->Diffuse, pLambert->DiffuseFactor); FbxPropertyT<FbxDouble> FBXTransparencyProperty = pLambert->TransparencyFactor; if( FBXTransparencyProperty.IsValid() ) fTransparency = (float)FBXTransparencyProperty.Get(); } if( pPhong ) { SpecularColor2 = GetMaterialColor2(pPhong->Specular, pPhong->SpecularFactor); FbxPropertyT<FbxDouble> FBXSpecularPowerProperty = pPhong->Shininess; if( FBXSpecularPowerProperty.IsValid() ) fSpecularPower = (float)FBXSpecularPowerProperty.Get(); } pMaterial->SetAmbientColor2(AmbientColor2); pMaterial->SetEmissiveColor2(EmissiveColor2); pMaterial->SetDiffuseColor2(DiffuseColor2); pMaterial->SetSpecularColor2(SpecularColor2); pMaterial->SetSpecularPower(fSpecularPower); pMaterial->SetTransparency(fTransparency); pMaterial->AddTexturePath( GetFilePath(this->mFilename) + "/" ); m_Materials.push_back(pMaterial); m_FBXMaterials.push_back(pFBXMaterial); } }
//=============================================================================================================================== void FBXLoader::LoadMaterialTexture(FbxSurfaceMaterial* inMaterial, ZShadeSandboxLighting::ShaderMaterial*& ioMaterial) { uint32 textureIndex = 0; FbxProperty property; FBXSDK_FOR_EACH_TEXTURE(textureIndex) { property = inMaterial->FindProperty(FbxLayerElement::sTextureChannelNames[textureIndex]); if (property.IsValid()) { uint32 textureCount = property.GetSrcObjectCount<FbxTexture>(); for (uint32 i = 0; i < textureCount; ++i) { FbxLayeredTexture* layeredTexture = property.GetSrcObject<FbxLayeredTexture>(i); if(layeredTexture) { throw std::exception("Layered Texture is currently unsupported\n"); } else { FbxTexture* texture = property.GetSrcObject<FbxTexture>(i); if (texture) { std::string textureType = property.GetNameAsCStr(); FbxFileTexture* fileTexture = FbxCast<FbxFileTexture>(texture); if (fileTexture) { string str_filename(fileTexture->GetFileName()); std::size_t index = str_filename.find_last_of('/\\'); if (index != string::npos) { BetterString str(fileTexture->GetFileName()); int dot_index = str.get_index('.'); BetterString pathName = str.substring(index + 1, dot_index); BetterString ext = str.substring(dot_index + 1); BetterString filename = pathName + "." + ext; str_filename = filename.toString(); } if (textureType == "DiffuseColor") { ioMaterial->sDiffuseTextureName = str_filename; ioMaterial->bHasDiffuseTexture = true; } else if (textureType == "SpecularColor") { ioMaterial->sSpecularTextureName = str_filename; ioMaterial->bHasSpecularTexture = true; } else if (textureType == "Bump") { ioMaterial->sNormalMapTextureName = str_filename; ioMaterial->bHasNormalMapTexture = true; } } } } } } } ioMaterial->SetD3D(m_pD3DSystem); bool addToMM = false; if (ioMaterial->bHasDiffuseTexture) { ZShadeSandboxLighting::ShaderMaterial* material; if (material = MaterialManager::Instance()->GetMaterial(ioMaterial->sMaterialName)) { // The texture has already been loaded ioMaterial->SetMaterialDiffuseTexture(material->DiffuseTexture()); } else { // Need to load new texture ioMaterial->AddDiffuseTexture(m_pGD3D->m_textures_path, ioMaterial->sDiffuseTextureName); addToMM = true; } } if (ioMaterial->bHasSpecularTexture) { ZShadeSandboxLighting::ShaderMaterial* material; if (material = MaterialManager::Instance()->GetMaterial(ioMaterial->sMaterialName)) { // The texture has already been loaded ioMaterial->SetMaterialSpecularTexture(material->SpecularTexture()); } else { // Need to load new texture ioMaterial->AddDiffuseTexture(m_pGD3D->m_textures_path, ioMaterial->sSpecularTextureName); addToMM = true; } } if (ioMaterial->bHasNormalMapTexture) { ZShadeSandboxLighting::ShaderMaterial* material; if (material = MaterialManager::Instance()->GetMaterial(ioMaterial->sMaterialName)) { // The texture has already been loaded ioMaterial->SetMaterialNormalMapTexture(material->NormalMapTexture()); } else { // Need to load new texture ioMaterial->AddDiffuseTexture(m_pGD3D->m_textures_path, ioMaterial->sNormalMapTextureName); addToMM = true; } } if (addToMM) { MaterialManager::Instance()->Add(ioMaterial); } }
std::shared_ptr<Material> FbxUtil::CreateMaterial(FbxSurfaceMaterial *fbxMaterial) { // a,d,s, Intensity(Factor), Shininess, Reflectivity, Transparency //GetImplementation(material, FBXSDK_IMP) FbxSurfacePhong *fbxPhong = static_cast<FbxSurfacePhong*>(fbxMaterial); Material::Ptr material = Material::Create(fbxPhong->GetName()); // read uniforms material->SetUniform(Material::SHININESS, Uniform1f::Create({ (float)fbxPhong->Shininess })); material->SetUniform(Material::AMBIENT_FACTOR, Uniform1f::Create({ (float)fbxPhong->AmbientFactor })); material->SetUniform(Material::DIFFUSE_FACTOR, Uniform1f::Create({ (float)fbxPhong->DiffuseFactor })); material->SetUniform(Material::SPECULAR_FACTOR, Uniform1f::Create({ (float)fbxPhong->SpecularFactor })); auto GetUniform3f = [](FbxPropertyT<FbxDouble3> &data) -> UniformBase::Ptr { return Uniform3f::Create({ (float)data.Get()[0], (float)data.Get()[1], (float)data.Get()[2] }); }; // read colors material->SetUniform(Material::AMBIENT_COLOR, GetUniform3f(fbxPhong->Ambient)); material->SetUniform(Material::DIFFUSE_COLOR, GetUniform3f(fbxPhong->Diffuse)); material->SetUniform(Material::SPECULAR_COLOR, GetUniform3f(fbxPhong->Specular)); material->SetUniform(Material::MATERIAL_ID, Uniform1ui::Create({ material->GetID() })); auto GetTexture = [&](FbxPropertyT<FbxDouble3> prop) -> Texture::Ptr { if (prop.IsValid() && prop.GetSrcObjectCount<FbxTexture>() > 0) { FbxTexture *fbxTexture = prop.GetSrcObject<FbxTexture>(0); FbxFileTexture *fileTexture = FbxCast<FbxFileTexture>(fbxTexture); if (fileTexture) { bool mipMap = (bool)fileTexture->UseMipMap; std::string filePath = FileUtil::Instance()->GetAbsPath(fileTexture->GetRelativeFileName(), true); auto texture = Texture::Create(fileTexture->GetName()); texture->SetFilterMode(mipMap ? FilterMode::LINEAR_MIPMAP_LINEAR : FilterMode::LINEAR); texture->CreateFromImage(filePath, mipMap); return texture; } else { LOGW << "FbxProceduralTexture not supported!"; } } return nullptr; }; // read tetxures. if(m_Options & Options::DIFFUSE_MAP) material->SetTexture(Material::DIFFUSE_TEXTURE, GetTexture(fbxPhong->Diffuse)); if(m_Options & Options::SPECULAR_MAP) material->SetTexture(Material::SPECULAR_TEXTURE, GetTexture(fbxPhong->Specular)); if(m_Options & Options::NORMAL_MAP) material->SetTexture(Material::NORMAL_TEXTURE, GetTexture(fbxPhong->NormalMap)); LOGD << fbxMaterial->GetName(); return material; }
SceneNode *SceneConverter::makeSceneNode(FbxNode *node) { SceneNode *sceneNode = new SceneNode(); if (node->GetParent() == NULL) // The root { // Type sceneNode->type = FbxString("root"); // Name sceneNode->attributes.push_back(std::make_pair(FbxString("name"), node->GetName())); // Transformation FbxAMatrix m = node->EvaluateGlobalTransform(); const FbxVector4 translation = m.GetT(); const FbxVector4 rotation = m.GetR(); const FbxVector4 scaling = m.GetS(); char buffer[1024]; FBXSDK_sprintf(buffer, 1024, "s:%8.5f,%8.5f,%8.5f,r:%8.5f,%8.5f,%8.5f,t:%8.5f,%8.5f,%8.5f", (float)scaling[0], (float)scaling[1], (float)scaling[2], (float)rotation[0], (float)rotation[1], (float)rotation[2], (float)translation[0], (float)translation[1], (float)translation[2]); sceneNode->attributes.push_back(std::make_pair(FbxString("transform"), FbxString(buffer))); } else { FbxCamera *camera = node->GetCamera(); if (camera != NULL) { sceneNode->type = FbxString("camera"); sceneNode->attributes.push_back(std::make_pair(FbxString("name"), node->GetName())); sceneNode->attributes.push_back(std::make_pair(FbxString("fixed"), FbxString("true"))); FbxVector4 position = camera->EvaluatePosition(); FbxVector4 center = camera->EvaluateLookAtPosition(); // FIXME: seems EvaluateUpDirection doesn't give correct result as it // is affected by its parent nodes' tranforms however we attach camera // to the root in paper3d's scene. // FbxVector4 up = camera->EvaluateUpDirection(position, center); FbxDouble3 up = camera->UpVector.Get(); char buffer[1024]; FBXSDK_sprintf(buffer, 1024, "eye:%8.5f,%8.5f,%8.5f,center:%8.5f,%8.5f,%8.5f,up:%8.5f,%8.5f,%8.5f", (float)position[0], (float)position[1], (float)position[2], (float)center[0], (float)center[1], (float)center[2], (float)up[0], (float)up[1], (float)up[2]); sceneNode->attributes.push_back(std::make_pair(FbxString("lookat"), FbxString(buffer))); float nearZ = (float)camera->GetNearPlane(); float farZ = (float)camera->GetFarPlane(); if (camera->ProjectionType.Get() == FbxCamera::ePerspective) { FbxCamera::EAspectRatioMode lCamAspectRatioMode = camera->GetAspectRatioMode(); double lAspectX = camera->AspectWidth.Get(); double lAspectY = camera->AspectHeight.Get(); double lAspectRatio = 1.333333; switch( lCamAspectRatioMode) { case FbxCamera::eWindowSize: lAspectRatio = lAspectX / lAspectY; break; case FbxCamera::eFixedRatio: lAspectRatio = lAspectX; break; case FbxCamera::eFixedResolution: lAspectRatio = lAspectX / lAspectY * camera->GetPixelRatio(); break; case FbxCamera::eFixedWidth: lAspectRatio = camera->GetPixelRatio() / lAspectY; break; case FbxCamera::eFixedHeight: lAspectRatio = camera->GetPixelRatio() * lAspectX; break; default: break; } //get the aperture ratio double lFilmHeight = camera->GetApertureHeight(); double lFilmWidth = camera->GetApertureWidth() * camera->GetSqueezeRatio(); //here we use Height : Width double lApertureRatio = lFilmHeight / lFilmWidth; //change the aspect ratio to Height : Width lAspectRatio = 1 / lAspectRatio; //revise the aspect ratio and aperture ratio FbxCamera::EGateFit lCameraGateFit = camera->GateFit.Get(); switch( lCameraGateFit ) { case FbxCamera::eFitFill: if( lApertureRatio > lAspectRatio) // the same as eHORIZONTAL_FIT { lFilmHeight = lFilmWidth * lAspectRatio; camera->SetApertureHeight( lFilmHeight); lApertureRatio = lFilmHeight / lFilmWidth; } else if( lApertureRatio < lAspectRatio) //the same as eVERTICAL_FIT { lFilmWidth = lFilmHeight / lAspectRatio; camera->SetApertureWidth( lFilmWidth); lApertureRatio = lFilmHeight / lFilmWidth; } break; case FbxCamera::eFitVertical: lFilmWidth = lFilmHeight / lAspectRatio; camera->SetApertureWidth( lFilmWidth); lApertureRatio = lFilmHeight / lFilmWidth; break; case FbxCamera::eFitHorizontal: lFilmHeight = lFilmWidth * lAspectRatio; camera->SetApertureHeight( lFilmHeight); lApertureRatio = lFilmHeight / lFilmWidth; break; case FbxCamera::eFitStretch: lAspectRatio = lApertureRatio; break; case FbxCamera::eFitOverscan: if( lFilmWidth > lFilmHeight) { lFilmHeight = lFilmWidth * lAspectRatio; } else { lFilmWidth = lFilmHeight / lAspectRatio; } lApertureRatio = lFilmHeight / lFilmWidth; break; case FbxCamera::eFitNone: default: break; } //change the aspect ratio to Width : Height lAspectRatio = 1 / lAspectRatio; #define HFOV2VFOV(h, ar) (2.0 * atan((ar) * tan( (h * FBXSDK_PI_DIV_180) * 0.5)) * FBXSDK_180_DIV_PI) //ar : aspectY / aspectX #define VFOV2HFOV(v, ar) (2.0 * atan((ar) * tan( (v * FBXSDK_PI_DIV_180) * 0.5)) * FBXSDK_180_DIV_PI) //ar : aspectX / aspectY double lFieldOfViewX = 0.0; double lFieldOfViewY = 0.0; if (camera->GetApertureMode() == FbxCamera::eVertical) { lFieldOfViewY = camera->FieldOfView.Get(); lFieldOfViewX = VFOV2HFOV( lFieldOfViewY, 1 / lApertureRatio); } else if (camera->GetApertureMode() == FbxCamera::eHorizontal) { lFieldOfViewX = camera->FieldOfView.Get(); //get HFOV lFieldOfViewY = HFOV2VFOV( lFieldOfViewX, lApertureRatio); } else if (camera->GetApertureMode() == FbxCamera::eFocalLength) { lFieldOfViewX = camera->ComputeFieldOfView(camera->FocalLength.Get()); //get HFOV lFieldOfViewY = HFOV2VFOV( lFieldOfViewX, lApertureRatio); } else if (camera->GetApertureMode() == FbxCamera::eHorizAndVert) { lFieldOfViewX = camera->FieldOfViewX.Get(); lFieldOfViewY = camera->FieldOfViewY.Get(); } #undef HFOV2VFOV #undef VFOV2HFOV FBXSDK_sprintf(buffer, 1024, "perspective,fov:%8.5f,aspect:-1,znear:%8.5f,zfar:%8.5f", (float)lFieldOfViewY, nearZ, farZ); sceneNode->attributes.push_back(std::make_pair(FbxString("projection"), FbxString(buffer))); } else { FBXSDK_sprintf(buffer, 1024, "orthogonal,aspect:-1,znear:%8.5f,zfar:%8.5f", nearZ, farZ); sceneNode->attributes.push_back(std::make_pair(FbxString("projection"), FbxString(buffer))); } m_numCameras++; } else { FbxLight *light = node->GetLight(); if (light != NULL) { m_numLights++; FBX_ASSERT(!"Not implemented!"); } else { // Type sceneNode->type = FbxString("drawable"); // Name sceneNode->attributes.push_back(std::make_pair(FbxString("name"), node->GetName())); // Transformation FbxAMatrix m = node->EvaluateLocalTransform(); //FbxAMatrix m1 = node->EvaluateGlobalTransform(); const FbxVector4 translation = m.GetT(); const FbxVector4 rotation = m.GetR(); const FbxVector4 scaling = m.GetS(); float s[3], r[3], t[3]; t[0] = (float)translation.mData[0]; t[1] = (float)translation.mData[1]; t[2] = (float)translation.mData[2]; r[0] = (float)(rotation[0] * FBXSDK_DEG_TO_RAD); r[1] = (float)(rotation[1] * FBXSDK_DEG_TO_RAD); r[2] = (float)(rotation[2] * FBXSDK_DEG_TO_RAD); s[0] = (float)scaling[0]; s[1] = (float)scaling[1]; s[2] = (float)scaling[2]; //const FbxVector4 translation1 = m1.GetT(); //const FbxVector4 rotation1 = m1.GetR(); //const FbxVector4 scaling1 = m1.GetS(); char buffer[1024]; FBXSDK_sprintf(buffer, 1024, "s:%8.5f,%8.5f,%8.5f,r:%8.5f,%8.5f,%8.5f,t:%8.5f,%8.5f,%8.5f", s[0], s[1], s[2], r[0], r[1], r[2], t[0], t[1], t[2]); sceneNode->attributes.push_back(std::make_pair(FbxString("transform"), FbxString(buffer))); // Mesh //if (node->GetNodeAttribute()->GetAttributeType() == FbxNodeAttribute::eCamera) //{ // FBXSDK_printf("f**k"); //} static FbxUInt32 i = 0; if (node->GetMesh() == NULL) { sceneNode->type = FbxString("node"); } else { const char *meshName = node->GetMesh()->GetName(); if (meshName == NULL || meshName[0] == 0) { meshName = node->GetName(); } FbxString prefix; if (meshName == NULL || meshName[0] == 0) { prefix = FbxString("mesh_") + FbxString(int(i++)); } else { prefix = FbxString(meshName); } sceneNode->geometry = prefix + FbxString(".") + m_arguments->meshFormat; // Material FbxSurfaceMaterial *material = node->GetMaterial(0); if (material != NULL) { // This only gets the material of type sDiffuse, you probably need to // traverse all Standard Material Property by its name to get all // possible textures. FbxProperty prop = material->FindProperty(FbxSurfaceMaterial::sDiffuse); // Check if it's layeredtextures int layeredTextureCount = prop.GetSrcObjectCount<FbxLayeredTexture>(); if (prop.GetSrcObjectCount<FbxTexture>() > 0) { FbxFileTexture *lTex = prop.GetSrcObject<FbxFileTexture>(0); FbxString filename = FbxPathUtils::GetFileName(lTex->GetFileName()); sceneNode->texture = filename.Lower(); m_textures.push_back(FbxString(lTex->GetFileName())); } // root node is not counted as a drawable. m_numDrawables++; } } } } } return sceneNode; }