Material* FBXScene::GetMaterialLinkedWithPolygon(FbxMesh* pFBXMesh, int nLayerIndex, int nPolygonIndex, int nPolygonVertexIndex, int nVertexIndex) { if( nLayerIndex < 0 || nLayerIndex > pFBXMesh->GetLayerCount() ) return NULL; FbxNode* pNode = pFBXMesh->GetNode(); if( !pNode ) return NULL; FbxLayerElementMaterial* pFBXMaterial = pFBXMesh->GetLayer(nLayerIndex)->GetMaterials(); if( pFBXMaterial ) { int nMappingIndex = GetMappingIndex( pFBXMaterial->GetMappingMode(), nPolygonIndex, 0, nVertexIndex ); if( nMappingIndex < 0 ) return NULL; FbxLayerElement::EReferenceMode referenceMode = pFBXMaterial->GetReferenceMode(); if( referenceMode == FbxLayerElement::EReferenceMode::eDirect ) { if( nMappingIndex < pNode->GetMaterialCount() ) { return GetMaterial(pNode->GetMaterial(nMappingIndex)); } } else if( referenceMode == FbxLayerElement::EReferenceMode::eIndexToDirect ) { const FbxLayerElementArrayTemplate<int>& pMaterialIndexArray = pFBXMaterial->GetIndexArray(); if( nMappingIndex < pMaterialIndexArray.GetCount() ) { int nIndex = pMaterialIndexArray.GetAt(nMappingIndex); if( nIndex < pNode->GetMaterialCount() ) { return GetMaterial(pNode->GetMaterial(nIndex)); } } } } return NULL; }
void MaterialHandler::MapMaterials(FbxNode * pNode, SceneMap * sceneMap) { //Recursively extract the children for (int j = 0; j < pNode->GetChildCount(); j++) MapMaterials(pNode->GetChild(j), sceneMap); FbxGeometry* pGeometry = pNode->GetGeometry(); int materialCount = 0; FbxNode* node = NULL; if (pGeometry) { node = pGeometry->GetNode(); if (node) materialCount = pNode->GetMaterialCount(); if (materialCount > 0) { for (int i = 0; i < materialCount; i++) { if (pNode->GetMaterial(i)) { FbxSurfaceMaterial *pMaterial = node->GetMaterial(i); std::cout << pMaterial->GetName() << "\n"; if (sceneMap->materialHash.find(pMaterial->GetName()) == sceneMap->materialHash.end()) { // not found std::cout << "New material found! mapping..\n"; sceneMap->materialHash[pMaterial->GetName()] = sceneMap->materialID; sceneMap->materialID += 1; } else { // found std::cout << "Material " << pMaterial->GetName() << " already exist .. skipping mapping of material" << std::endl; } //ProcessData(pMaterial, materialCount, outputMat); } } } } }
// メッシュ情報処理(再帰関数) void GetMeshData(FbxNode *parent, VertexDataArray& outVertexData) { // メッシュだけ処理 int numKids = parent->GetChildCount(); for(int i = 0; i < numKids; i++) { FbxNode *child = parent->GetChild(i); // メッシュを見つけたら if(child->GetMesh()) { FbxMesh* pMesh = child->GetMesh();// static_cast<FbxMesh*>(child->GetNodeAttribute()); printf("メッシュ発見\n"); printf("名前:%s\n", pMesh->GetName()); printf("ポリゴン数:%d\n", pMesh->GetPolygonCount()); printf("マテリアル数:%d\n", pMesh->GetElementMaterialCount()); printf("コントロールポイント数(頂点座標):%d\n", pMesh->GetControlPointsCount()); printf("UV数:%d\n", pMesh->GetTextureUVCount()); FbxArray<FbxVector4> normals; pMesh->GetPolygonVertexNormals(normals); printf("法線数:%d\n", normals.GetCount()); // 頂点情報取得 GetFBXVertexData(pMesh, outVertexData); } // マテリアル int numMat = child->GetMaterialCount(); for(int j = 0; j < numMat; ++j) { FbxSurfaceMaterial* mat = child->GetMaterial(j); if(mat) { GetMatrialData(mat); } } if(numMat == 0) { printf("マテリアルなし\n"); } child->GetChild(0); // 更に子を処理 GetMeshData(child, outVertexData); } }
void MaterialHandler::GetMaterialData(FbxNode * pNode, MaterialExport* outputMat, SceneMap* sceneMap) { //Recursively extract the children for (int j = 0; j < pNode->GetChildCount(); j++) GetMaterialData(pNode->GetChild(j),outputMat,sceneMap); if (outputMat == nullptr) //If the first material is processed. create a new MaterialExport object { outputMat = new MaterialExport; } FbxGeometry* pGeometry = pNode->GetGeometry(); int materialCount = 0; FbxNode* node = NULL; if (pGeometry) { //If the node has any geometry node = pGeometry->GetNode(); if (node) materialCount = pNode->GetMaterialCount(); //Get the amount of materials the geometry has if (materialCount > 0) { for (int i = 0; i < materialCount; i++) { if (pNode->GetMaterial(i)) { FbxSurfaceMaterial *pMaterial = node->GetMaterial(i); //Get the material ProcessData(pMaterial, materialCount, outputMat,sceneMap); //process the data! } } } } }
//------------------------------------------------------------------------------------------------------------------------------------------- void transferMaterials(FbxGeometry* fbxMesh, Mesh* mesh){ int numMaterials = 0; if (fbxMesh == NULL){ throw new Exception("fbxMesh can not be NULL !"); } FbxNode* fbxNode = NULL; fbxNode = fbxMesh->GetNode(); if (fbxNode){ numMaterials = fbxNode->GetMaterialCount(); } LOG_DEBUG << " Number of materials: " << numMaterials; if (numMaterials > 0) { FbxPropertyT<FbxDouble3> lKFbxDouble3; FbxPropertyT<FbxDouble> lKFbxDouble1; FbxColor theColor; for (int matId = 0; matId < numMaterials; matId++){ Material* material = new Material(); FbxSurfaceMaterial* fbxMaterial = fbxNode->GetMaterial(matId); // Get the implementation to see f it's a hardware shader const FbxImplementation* fbxImplementation = GetImplementation(fbxMaterial, FBXSDK_IMPLEMENTATION_HLSL); string fbxImplementationType = "HLSL"; if (fbxImplementation != NULL){ fbxImplementation = GetImplementation(fbxMaterial, FBXSDK_IMPLEMENTATION_CGFX); fbxImplementationType = "CFGX"; } if (fbxImplementation) { // Handle hardware shader // TODO: transfer material using hardware shader } else if (fbxMaterial->GetClassId().Is(FbxSurfacePhong::ClassId)) { // Handle phong shader // Transfer Ambient color lKFbxDouble3 = ((FbxSurfacePhong*)fbxMaterial)->Ambient; material->Ambient = Vector4s(lKFbxDouble3.Get()[0], lKFbxDouble3.Get()[1], lKFbxDouble3.Get()[2], 1); // Transfer Diffuse color lKFbxDouble3 = ((FbxSurfacePhong*)fbxMaterial)->Diffuse; material->Diffuse = Vector4s(lKFbxDouble3.Get()[0], lKFbxDouble3.Get()[1], lKFbxDouble3.Get()[2], 1); // Transfer Specular color lKFbxDouble3 = ((FbxSurfacePhong*)fbxMaterial)->Specular; material->Specular = Vector4s(lKFbxDouble3.Get()[0], lKFbxDouble3.Get()[1], lKFbxDouble3.Get()[2], 1); // Transfer Emissive color lKFbxDouble3 = ((FbxSurfacePhong*)fbxMaterial)->Emissive; material->Emissive = Vector4s(lKFbxDouble3.Get()[0], lKFbxDouble3.Get()[1], lKFbxDouble3.Get()[2], 1); // Transfer Transperency factor lKFbxDouble1 = ((FbxSurfacePhong*)fbxMaterial)->TransparencyFactor; material->Opacity = 1.0 - lKFbxDouble1.Get(); // Transfer Shininess lKFbxDouble3 = ((FbxSurfacePhong*)fbxMaterial)->Shininess; material->Shininess = lKFbxDouble1.Get(); // Transfer Reflectivity lKFbxDouble3 = ((FbxSurfacePhong*)fbxMaterial)->ReflectionFactor; material->Reflectivity = lKFbxDouble1.Get(); } else if (fbxMaterial->GetClassId().Is(FbxSurfaceLambert::ClassId)) { // Handle Lambert shader lKFbxDouble3 = ((FbxSurfaceLambert *)fbxMaterial)->Ambient; material->Ambient = Vector4s(lKFbxDouble3.Get()[0], lKFbxDouble3.Get()[1], lKFbxDouble3.Get()[2], 1); // Display the Diffuse Color lKFbxDouble3 = ((FbxSurfaceLambert *)fbxMaterial)->Diffuse; material->Diffuse = Vector4s(lKFbxDouble3.Get()[0], lKFbxDouble3.Get()[1], lKFbxDouble3.Get()[2], 1); // Display the Emissive lKFbxDouble3 = ((FbxSurfaceLambert *)fbxMaterial)->Emissive; material->Emissive = Vector4s(lKFbxDouble3.Get()[0], lKFbxDouble3.Get()[1], lKFbxDouble3.Get()[2], 1); // Display the Opacity lKFbxDouble1 = ((FbxSurfaceLambert *)fbxMaterial)->TransparencyFactor; material->Opacity = 1.0 - lKFbxDouble1.Get(); } else { LOG_WARNING << "Unknown type of Material !"; } FbxPropertyT<FbxString> fbxString; fbxString = fbxMaterial->ShadingModel; material->ShadingMode = fbxString.Get(); mesh->Materials.push_back(material); } } LOG_DEBUG << "Transfer materials successfully! "; }
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() ); } } }
//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())); } }