void getMaterialAndTextureFileNames(FbxGeometry* fbxGeometry, std::vector<std::string>* out_textureFileNames,
																		Material* out_material) {

	if (fbxGeometry->GetNode() == nullptr) {
		return;
	}

	int numMaterials = fbxGeometry->GetNode()->GetSrcObjectCount(FbxSurfaceMaterial::ClassId);
	for (int midx = 0; midx < numMaterials; ++midx){

		FbxSurfaceMaterial *fbxMaterial = (FbxSurfaceMaterial *)fbxGeometry->GetNode()->GetSrcObject(FbxSurfaceMaterial::ClassId, midx);

		if (fbxMaterial) {

			getMaterialData(fbxMaterial, out_material);

			// Go through all the possible textures
			int tidx;
			FBXSDK_FOR_EACH_TEXTURE(tidx) {
				FbxProperty fbxTextureProperty = fbxMaterial->FindProperty(FbxLayerElement::sTextureChannelNames[tidx]);
				std::vector<std::string>* tempTextureFileNames = findAndGetTextureInfoByProperty(fbxTextureProperty, midx);
				for (int t = 0; t < tempTextureFileNames->size(); ++t) {
					out_textureFileNames->push_back(tempTextureFileNames->at(t));
				}
			}

		}//end if(fbxMaterial)

	}// end for materialIndex

	return;
}
Example #2
0
void FBXMesh::Builder::unloadCacheRecursive(FbxNode * pNode)
{
	// Unload the material cache
	const int lMaterialCount = pNode->GetMaterialCount();
	for (int lMaterialIndex = 0; lMaterialIndex < lMaterialCount; ++lMaterialIndex)
	{
		FbxSurfaceMaterial * lMaterial = pNode->GetMaterial(lMaterialIndex);
		if (lMaterial && lMaterial->GetUserDataPtr())
		{
			FBXMaterialCache* lMaterialCache = static_cast<FBXMaterialCache*>(lMaterial->GetUserDataPtr());
			lMaterial->SetUserDataPtr(NULL);
			delete lMaterialCache;
		}
	}

	FbxNodeAttribute* lNodeAttribute = pNode->GetNodeAttribute();
	if (lNodeAttribute)
	{
		// Unload the mesh cache
		if (lNodeAttribute->GetAttributeType() == FbxNodeAttribute::eMesh)
		{
			FbxMesh * lMesh = pNode->GetMesh();
			if (lMesh && lMesh->GetUserDataPtr())
			{

#ifndef USE_META_DATA
			VBOMesh * lMeshCache = static_cast<VBOMesh *>(lMesh->GetUserDataPtr());
			lMesh->SetUserDataPtr(NULL);
			delete lMeshCache;
#else
			FbxMetaData * fbxMetaData = static_cast<FbxMetaData*>(lMesh->GetUserDataPtr());
			lMesh->SetUserDataPtr(NULL);
			delete fbxMetaData;
#endif
			}
		}
		// Unload the light cache
		else if (lNodeAttribute->GetAttributeType() == FbxNodeAttribute::eLight)
		{
			FbxLight * lLight = pNode->GetLight();
			if (lLight && lLight->GetUserDataPtr())
			{
				FBXLightCache* lLightCache = static_cast<FBXLightCache*>(lLight->GetUserDataPtr());
				lLight->SetUserDataPtr(NULL);
				delete lLightCache;
			}
		}
	}

	const int lChildCount = pNode->GetChildCount();
	for (int lChildIndex = 0; lChildIndex < lChildCount; ++lChildIndex)
	{
		unloadCacheRecursive(pNode->GetChild(lChildIndex));
	}
}
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);
				}

			}
		}


	}


}
Example #4
0
    // Bake node attributes and materials under this node recursively.
    // Currently only mesh, light and material.
    void LoadCacheRecursive(SceneContext* pSceneCtx, FbxNode * pNode, FbxAnimLayer * pAnimLayer, bool pSupportVBO)
    {
        // Bake material and hook as user data.
        const int lMaterialCount = pNode->GetMaterialCount();
        for (int lMaterialIndex = 0; lMaterialIndex < lMaterialCount; ++lMaterialIndex)
        {
            FbxSurfaceMaterial * lMaterial = pNode->GetMaterial(lMaterialIndex);
            if (lMaterial && !lMaterial->GetUserDataPtr())
            {
                FbxAutoPtr<MaterialCache> lMaterialCache(new MaterialCache);
                if (lMaterialCache->Initialize(lMaterial))
                {
                    lMaterial->SetUserDataPtr(lMaterialCache.Release());
                }
            }
        }

        FbxNodeAttribute* lNodeAttribute = pNode->GetNodeAttribute();
        if (lNodeAttribute)
        {
            // Bake mesh as VBO(vertex buffer object) into GPU.
            if (lNodeAttribute->GetAttributeType() == FbxNodeAttribute::eMesh)
            {
                FbxMesh * lMesh = pNode->GetMesh();
                if (pSupportVBO && lMesh && !lMesh->GetUserDataPtr())
                {
                    FbxAutoPtr<VBOMesh> lMeshCache(new VBOMesh);
                    if (lMeshCache->Initialize(pSceneCtx, lMesh))
                    {
                        lMesh->SetUserDataPtr(lMeshCache.Release());
                    }
                }
            }
            // Bake light properties.
            else if (lNodeAttribute->GetAttributeType() == FbxNodeAttribute::eLight)
            {
                FbxLight * lLight = pNode->GetLight();
                if (lLight && !lLight->GetUserDataPtr())
                {
                    FbxAutoPtr<LightCache> lLightCache(new LightCache);
                    if (lLightCache->Initialize(lLight, pAnimLayer))
                    {
                        lLight->SetUserDataPtr(lLightCache.Release());
                    }
                }
            }
        }

        const int lChildCount = pNode->GetChildCount();
        for (int lChildIndex = 0; lChildIndex < lChildCount; ++lChildIndex)
        {
            LoadCacheRecursive(pSceneCtx, pNode->GetChild(lChildIndex), pAnimLayer, pSupportVBO);
        }
    }
Example #5
0
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 FBXSceneEncoder::loadMaterial(FbxNode* fbxNode)
{
    Node* node = findNode(fbxNode);
    Model* model = (node) ? node->getModel() : NULL;

    const int materialCount = fbxNode->GetMaterialCount();
    for (int index = 0; index < materialCount; ++index)
    {
        FbxSurfaceMaterial* fbxMaterial = fbxNode->GetMaterial(index);
        string materialName(fbxMaterial->GetName());
        fixMaterialName(materialName);
        Material* material = NULL;
        map<string, Material*>::iterator it = _materials.find(materialName);
        if (it != _materials.end())
        {
            // This material was already loaded so don't load it again
            material = it->second;
        }
        else
        {
            if (EncoderArguments::getInstance()->outputMaterialEnabled())
            {
                material = createMaterial(materialName, fbxMaterial, node);
            }
            else
            {
                // If outputMaterialEnabled() is not enabled then only create the materials for the purpose of writing 
                // the material name in the GPB file. There is no need to load uniforms and samplers for the material.
                material = new Material(materialName);
            }
            _materials[materialName] = material;
        }

        if (materialCount == 1 && material && model)
        {
            model->setMaterial(material); // TODO: add support for materials per mesh part
        }
        else if (materialCount > 1 && material && model)
        {
            model->setMaterial(material, index);
        }
    }

    const int childCount = fbxNode->GetChildCount();
    for (int i = 0; i < childCount; ++i)
    {
        FbxNode* childNode = fbxNode->GetChild(i);
        if (childNode)
        {
            loadMaterial(childNode);
        }
    }
}
Example #7
0
		void FbxLoader::BindMaterial(FbxNode* node, Node& meshNode)
		{
			const int materialCount = node->GetMaterialCount();
			meshNode.materialNames.resize(materialCount);

			for(int i = 0; i < materialCount; i++) {
				FbxSurfaceMaterial* surfaceMaterial = node->GetMaterial(i);
				auto name = surfaceMaterial->GetName();
				meshNode.materialNames[i] = name;
				if(materials[name].normalMapName != "")
					meshNode.useNormalMap = true;
			}
		}
Example #8
0
void Converter::getMaterials(FbxNode *n, std::vector<std::string> &textures, std::vector<PhongMaterial> &phongMats, std::vector<LambertMaterial> &lambertMats)
{
	for (int i = 0; i < n->GetMaterialCount(); ++i) {
		FbxSurfaceMaterial *material = n->GetMaterial(i);
		getDiffuseTextures(material, textures);
		if (material->GetClassId().Is(FbxSurfacePhong::ClassId)) {
			phongMats.push_back(getPhongMaterial(material));
		}
		else if (material->GetClassId().Is(FbxSurfaceLambert::ClassId)) {
			lambertMats.push_back(getLambertMaterial(material));
		}
	}
}
Example #9
0
void LoadMeshes(FbxNode* pFbxNode, packed_freelist<Mesh>& sceneMeshes)
{
    // Material
    const uint32_t materialCount = pFbxNode->GetMaterialCount();
    for (uint32_t i = 0; i < materialCount; ++i) {
        FbxSurfaceMaterial* pFbxMaterial = pFbxNode->GetMaterial(i);
        if (pFbxMaterial && !pFbxMaterial->GetUserDataPtr()) {
            FbxAutoPtr<Material> pMaterial(new Material);
            if (pMaterial->init(pFbxMaterial)) {
                pFbxMaterial->SetUserDataPtr(pMaterial.Release());
            }
        }
    }

    FbxNodeAttribute* nodeAttribute = pFbxNode->GetNodeAttribute();
    if (nodeAttribute) {
        // Mesh
        if (nodeAttribute->GetAttributeType() == FbxNodeAttribute::eMesh) {
            FbxMesh* pFbxMesh = pFbxNode->GetMesh();
            if (pFbxMesh && !pFbxMesh->GetUserDataPtr()) {
                Mesh mesh;
                if (mesh.init(pFbxMesh)) {
                    sceneMeshes.insert(mesh);
                }
                // TODO:
                FbxAutoPtr<Mesh> pMesh(new Mesh);
                if (pMesh->init(pFbxMesh)) {
                    pFbxMesh->SetUserDataPtr(pMesh.Release());
                }
            }
        }
        // Light
        else if (nodeAttribute->GetAttributeType() == FbxNodeAttribute::eLight) {
            FbxLight* pFbxLight = pFbxNode->GetLight();
            if (pFbxLight && !pFbxLight->GetUserDataPtr()) {
                FbxAutoPtr<Light> pLight(new Light);
                if (pLight->init(pFbxLight)) {
                    pFbxLight->SetUserDataPtr(pLight.Release());
                }
            }
        }
    }

    const int childCount = pFbxNode->GetChildCount();
    for (int i = 0; i < childCount; ++i) {
        LoadMeshes(pFbxNode->GetChild(i), sceneMeshes);
    }
}
Example #10
0
    // Unload the cache and release the memory under this node recursively.
    void UnloadCacheRecursive(FbxNode * pNode)
    {
        // Unload the material cache
        const int lMaterialCount = pNode->GetMaterialCount();
        for (int lMaterialIndex = 0; lMaterialIndex < lMaterialCount; ++lMaterialIndex)
        {
            FbxSurfaceMaterial * lMaterial = pNode->GetMaterial(lMaterialIndex);
            if (lMaterial && lMaterial->GetUserDataPtr())
            {
                MaterialCache * lMaterialCache = static_cast<MaterialCache *>(lMaterial->GetUserDataPtr());
                lMaterial->SetUserDataPtr(NULL);
                delete lMaterialCache;
            }
        }

        FbxNodeAttribute* lNodeAttribute = pNode->GetNodeAttribute();
        if (lNodeAttribute)
        {
            // Unload the mesh cache
            if (lNodeAttribute->GetAttributeType() == FbxNodeAttribute::eMesh)
            {
                FbxMesh * lMesh = pNode->GetMesh();
                if (lMesh && lMesh->GetUserDataPtr())
                {
                    VBOMesh * lMeshCache = static_cast<VBOMesh *>(lMesh->GetUserDataPtr());
                    lMesh->SetUserDataPtr(NULL);
                    delete lMeshCache;
                }
            }
            // Unload the light cache
            else if (lNodeAttribute->GetAttributeType() == FbxNodeAttribute::eLight)
            {
                FbxLight * lLight = pNode->GetLight();
                if (lLight && lLight->GetUserDataPtr())
                {
                    LightCache * lLightCache = static_cast<LightCache *>(lLight->GetUserDataPtr());
                    lLight->SetUserDataPtr(NULL);
                    delete lLightCache;
                }
            }
        }

        const int lChildCount = pNode->GetChildCount();
        for (int lChildIndex = 0; lChildIndex < lChildCount; ++lChildIndex)
        {
            UnloadCacheRecursive(pNode->GetChild(lChildIndex));
        }
    }
//-------------------------------------------------------------------------
//
//-------------------------------------------------------------------------
void UnFbx::FFbxImporter::FixupMaterial( FbxSurfaceMaterial& FbxMaterial, UMaterial* UnrealMaterial )
{
	// add a basic diffuse color if no texture is linked to diffuse
	if (UnrealMaterial->BaseColor.Expression == NULL)
	{
		FbxDouble3 DiffuseColor;
		
		UMaterialExpressionVectorParameter* MyColorExpression = ConstructObject<UMaterialExpressionVectorParameter>( UMaterialExpressionVectorParameter::StaticClass(), UnrealMaterial );
		UnrealMaterial->Expressions.Add( MyColorExpression );
		UnrealMaterial->BaseColor.Expression = MyColorExpression;

		bool bFoundDiffuseColor = true;
		if( FbxMaterial.GetClassId().Is(FbxSurfacePhong::ClassId) )
		{
			DiffuseColor = ((FbxSurfacePhong&)(FbxMaterial)).Diffuse.Get();
		}
		else if( FbxMaterial.GetClassId().Is(FbxSurfaceLambert::ClassId) )
		{
			DiffuseColor = ((FbxSurfaceLambert&)(FbxMaterial)).Diffuse.Get();
		}
		else
		{
			bFoundDiffuseColor = false;
		}

		if( bFoundDiffuseColor )
		{
			MyColorExpression->DefaultValue.R = (float)(DiffuseColor[0]);
			MyColorExpression->DefaultValue.G = (float)(DiffuseColor[1]);
			MyColorExpression->DefaultValue.B = (float)(DiffuseColor[2]);
		}
		else
		{
			// use random color because there may be multiple materials, then they can be different 
			MyColorExpression->DefaultValue.R = 0.5f+(0.5f*FMath::Rand())/RAND_MAX;
			MyColorExpression->DefaultValue.G = 0.5f+(0.5f*FMath::Rand())/RAND_MAX;
			MyColorExpression->DefaultValue.B = 0.5f+(0.5f*FMath::Rand())/RAND_MAX;
		}

		TArray<FExpressionOutput> Outputs = UnrealMaterial->BaseColor.Expression->GetOutputs();
		FExpressionOutput* Output = Outputs.GetTypedData();
		UnrealMaterial->BaseColor.Mask = Output->Mask;
		UnrealMaterial->BaseColor.MaskR = Output->MaskR;
		UnrealMaterial->BaseColor.MaskG = Output->MaskG;
		UnrealMaterial->BaseColor.MaskB = Output->MaskB;
		UnrealMaterial->BaseColor.MaskA = Output->MaskA;
	}
}
Example #12
0
void FBXImporter::LoadMaterialAttributes(FBXMeshData* fbxMeshData)
{
	// Get the name of material.
	FbxSurfaceMaterial* surfaceMaterial = fbxMeshData->mSurfaceMaterial;
	const char* materialName = surfaceMaterial->GetName();

	// Phong material
	if (surfaceMaterial->GetClassId().Is(FbxSurfacePhong::ClassId))
	{
		// Ambient color.
		FbxDouble3 ambient = ((FbxSurfacePhong*)surfaceMaterial)->Ambient;

		// Diffuse color.
		FbxDouble3 diffuse = ((FbxSurfacePhong*)surfaceMaterial)->Diffuse;

		// Specular color.
		FbxDouble3 specular = ((FbxSurfacePhong*)surfaceMaterial)->Specular;

		// Emissive color.
		FbxDouble3 emissive = ((FbxSurfacePhong*)surfaceMaterial)->Emissive;

		// Opacity.
		FbxDouble opacity = ((FbxSurfacePhong*)surfaceMaterial)->TransparencyFactor;

		// Shininess.
		FbxDouble shininess = ((FbxSurfacePhong*)surfaceMaterial)->Shininess;

		// Reflectivety.
		FbxDouble reflectiveity = ((FbxSurfacePhong*)surfaceMaterial)->ReflectionFactor;
	}

	// Lambert material.
	if (surfaceMaterial->GetClassId().Is(FbxSurfaceLambert::ClassId))
	{
		// Ambient color.
		FbxDouble3 ambient = ((FbxSurfaceLambert*)surfaceMaterial)->Ambient;

		// Diffuse color.
		FbxDouble3 diffuse = ((FbxSurfaceLambert*)surfaceMaterial)->Diffuse;

		// Emissive color.
		FbxDouble3 emissive = ((FbxSurfaceLambert*)surfaceMaterial)->Emissive;

		// Opacity.
		FbxDouble opacity = ((FbxSurfaceLambert*)surfaceMaterial)->TransparencyFactor;
	}
}
Example #13
0
//-------------------------------------------------------------------------------------------------------------------------------------------
void transferTextures(FbxGeometry* fbxMesh, Mesh* mesh)
{
    FbxNode* fbxNode = fbxMesh->GetNode();
    FbxProperty fbxProperty;
    int numMaterials = fbxNode->GetSrcObjectCount<FbxSurfaceMaterial>();
    for (int matId = 0; matId < numMaterials; matId++){
        FbxSurfaceMaterial* fbxMaterial = fbxNode->GetSrcObject<FbxSurfaceMaterial>(matId);
        Material* modelMaterial = mesh->Materials[matId];

        if (fbxMaterial){
            // Go through all the possible textures
            for (int layerId = 0; layerId < FbxLayerElement::sTypeTextureCount; layerId++){
                fbxProperty = fbxMaterial->FindProperty(FbxLayerElement::sTextureChannelNames[layerId]);
                transferTextureByProperty(fbxProperty, matId, modelMaterial);
            }
        }
    }


    LOG_DEBUG << "Transfer materials successfully! ";
}
Example #14
0
	void FbxUtil::LoadMaterial(const SceneNode::Ptr &ntNode, FbxNode *fbxNode)
	{
		if (fbxNode->GetMaterialCount() > 0)
		{
			FbxSurfaceMaterial *fbxMaterial = fbxNode->GetMaterial(0);

			// only supports phong material
			if (fbxMaterial->GetClassId().Is(FbxSurfacePhong::ClassId))
			{
				Material::Ptr material = EntityUtil::Instance()->FindEntity<Material>(fbxMaterial->GetName());

				if (material == nullptr)
				{
					material = CreateMaterial(fbxMaterial);
					EntityUtil::Instance()->AddEntity(material);
				}

				if (auto ptr = ntNode->GetComponent<MeshRender>())
					ptr->SetMaterial(material);
			}
		}
	}
Example #15
0
//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()));
			}
		}
//-------------------------------------------------------------------------
//
//-------------------------------------------------------------------------
bool UnFbx::FFbxImporter::CreateAndLinkExpressionForMaterialProperty(
							FbxSurfaceMaterial& FbxMaterial,
							UMaterial* UnrealMaterial,
							const char* MaterialProperty ,
							FExpressionInput& MaterialInput, 
							bool bSetupAsNormalMap,
							TArray<FString>& UVSet )
{
	bool bCreated = false;
	FbxProperty FbxProperty = FbxMaterial.FindProperty( MaterialProperty );
	if( FbxProperty.IsValid() )
	{
		int32 LayeredTextureCount = FbxProperty.GetSrcObjectCount(FbxLayeredTexture::ClassId);
		if (LayeredTextureCount>0)
		{
			UE_LOG(LogFbxMaterialImport, Warning,TEXT("Layered TEXTures are not supported (material %s)"),ANSI_TO_TCHAR(FbxMaterial.GetName()));
		}
		else
		{
			int32 TextureCount = FbxProperty.GetSrcObjectCount(FbxTexture::ClassId);
			if (TextureCount>0)
			{
				for(int32 TextureIndex =0; TextureIndex<TextureCount; ++TextureIndex)
				{
					FbxFileTexture* FbxTexture = FbxProperty.GetSrcObject(FBX_TYPE(FbxFileTexture), TextureIndex);

					// create an unreal texture asset
					UTexture* UnrealTexture = ImportTexture(FbxTexture, bSetupAsNormalMap);
				
					if (UnrealTexture)
					{
						// and link it to the material 
						UMaterialExpressionTextureSample* UnrealTextureExpression = ConstructObject<UMaterialExpressionTextureSample>( UMaterialExpressionTextureSample::StaticClass(), UnrealMaterial );
						UnrealMaterial->Expressions.Add( UnrealTextureExpression );
						MaterialInput.Expression = UnrealTextureExpression;
						UnrealTextureExpression->Texture = UnrealTexture;
						UnrealTextureExpression->SamplerType = bSetupAsNormalMap ? SAMPLERTYPE_Normal : SAMPLERTYPE_Color;
						
						// add/find UVSet and set it to the texture
						FbxString UVSetName = FbxTexture->UVSet.Get();
						FString LocalUVSetName = ANSI_TO_TCHAR(UVSetName.Buffer());
						int32 SetIndex = UVSet.Find(LocalUVSetName);
						UMaterialExpressionTextureCoordinate* MyCoordExpression = ConstructObject<UMaterialExpressionTextureCoordinate>( UMaterialExpressionTextureCoordinate::StaticClass(), UnrealMaterial );
						UnrealMaterial->Expressions.Add( MyCoordExpression );
						MyCoordExpression->CoordinateIndex = (SetIndex >= 0)? SetIndex: 0;
						UnrealTextureExpression->Coordinates.Expression = MyCoordExpression;

						if ( !bSetupAsNormalMap )
						{
							UnrealMaterial->BaseColor.Expression = UnrealTextureExpression;
						}
						else
						{
							UnrealMaterial->Normal.Expression = UnrealTextureExpression;
						}

						bCreated = true;
					}		
				}
			}

			if (MaterialInput.Expression)
			{
				TArray<FExpressionOutput> Outputs = MaterialInput.Expression->GetOutputs();
				FExpressionOutput* Output = Outputs.GetTypedData();
				MaterialInput.Mask = Output->Mask;
				MaterialInput.MaskR = Output->MaskR;
				MaterialInput.MaskG = Output->MaskG;
				MaterialInput.MaskB = Output->MaskB;
				MaterialInput.MaskA = Output->MaskA;
			}
		}
	}

	return bCreated;
}
void UnFbx::FFbxImporter::ImportTexturesFromNode(FbxNode* Node)
{
	FbxProperty Property;
	int32 NbMat = Node->GetMaterialCount();

	// visit all materials
	int32 MaterialIndex;
	for (MaterialIndex = 0; MaterialIndex < NbMat; MaterialIndex++)
	{
		FbxSurfaceMaterial *Material = Node->GetMaterial(MaterialIndex);

		//go through all the possible textures
		if(Material)
		{
			int32 TextureIndex;
			FBXSDK_FOR_EACH_TEXTURE(TextureIndex)
			{
				Property = Material->FindProperty(FbxLayerElement::sTextureChannelNames[TextureIndex]);

				if( Property.IsValid() )
				{
					FbxTexture * lTexture= NULL;

					//Here we have to check if it's layered textures, or just textures:
					int32 LayeredTextureCount = Property.GetSrcObjectCount(FbxLayeredTexture::ClassId);
					FbxString PropertyName = Property.GetName();
					if(LayeredTextureCount > 0)
					{
						for(int32 LayerIndex=0; LayerIndex<LayeredTextureCount; ++LayerIndex)
						{
							FbxLayeredTexture *lLayeredTexture = FbxCast <FbxLayeredTexture>(Property.GetSrcObject(FbxLayeredTexture::ClassId, LayerIndex));
							int32 NbTextures = lLayeredTexture->GetSrcObjectCount(FbxTexture::ClassId);
							for(int32 TexIndex =0; TexIndex<NbTextures; ++TexIndex)
							{
								FbxFileTexture* Texture = FbxCast <FbxFileTexture> (lLayeredTexture->GetSrcObject(FbxFileTexture::ClassId,TexIndex));
								if(Texture)
								{
									ImportTexture(Texture, PropertyName == FbxSurfaceMaterial::sNormalMap || PropertyName == FbxSurfaceMaterial::sBump);
								}
							}
						}
					}
					else
					{
						//no layered texture simply get on the property
						int32 NbTextures = Property.GetSrcObjectCount(FbxTexture::ClassId);
						for(int32 TexIndex =0; TexIndex<NbTextures; ++TexIndex)
						{

							FbxFileTexture* Texture = FbxCast <FbxFileTexture> (Property.GetSrcObject(FbxFileTexture::ClassId,TexIndex));
							if(Texture)
							{
								ImportTexture(Texture, PropertyName == FbxSurfaceMaterial::sNormalMap || PropertyName == FbxSurfaceMaterial::sBump);
							}
						}
					}
				}
			}

		}//end if(Material)

	}// end for MaterialIndex
}
Example #18
0
//--------------------------------------------------------------------------------------
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);
	}
}
Example #19
0
//-------------------------------------------------------------------------------------------------------------------------------------------
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 MeshImporter::LoadMaterials(FbxNode* node, MeshEntry* mesh, ID3D11Device3* device,
	ID3D11DeviceContext3* context)
{
	int mcount = node->GetSrcObjectCount<FbxSurfaceMaterial>();

	for (int index = 0; index < mcount; index++)
	{
		FbxSurfaceMaterial *material =
			(FbxSurfaceMaterial*)node->GetSrcObject<FbxSurfaceMaterial>(index);

		if (material)
		{
			// 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 layered_texture_count = prop.GetSrcObjectCount<FbxLayeredTexture>();

			if (layered_texture_count > 0)
			{
				for (int j = 0; j < layered_texture_count; j++)
				{
					FbxLayeredTexture* layered_texture = FbxCast<FbxLayeredTexture>(prop.GetSrcObject<FbxLayeredTexture>(j));
					int lcount = layered_texture->GetSrcObjectCount<FbxTexture>();

					for (int k = 0; k < lcount; k++)
					{
						FbxTexture* texture =
							FbxCast<FbxTexture>(layered_texture->GetSrcObject<FbxTexture>(k));
						// Then, you can get all the properties of the texture, include its name
						const char* texture_name = texture->GetName();

						// Load files
						LoadTexture(texture_name, mesh, device, context);

						PrintTab(to_string(layered_texture_count) + " Layered textures loaded!" +
							"Number of layers: " + to_string(lcount));
					}
				}
			}
			else
			{
				// Directly get textures
				int texture_count = prop.GetSrcObjectCount<FbxTexture>();

				for (int j = 0; j < texture_count; j++)
				{
					const FbxTexture* texture =
						FbxCast<FbxTexture>(prop.GetSrcObject<FbxTexture>(j));
					// Then, you can get all the properties of the texture, include its name
					const char* texture_name = texture->GetName();

					// Load file
					LoadTexture(texture_name, mesh, device, context);

					PrintTab(to_string(texture_count) + " Single texture loaded!");
				}
			}
		}
	}
}
Example #21
0
    //THIS MUST HAPPEN AFTER IMPORTING SKELETONS.
    //-----------------------------------------------------------------------------------
    static void ImportMesh(SceneImport* import, FbxMesh* mesh, MatrixStack4x4& matrixStack, std::map<int, FbxNode*>& nodeToJointIndex)
    {
        MeshBuilder builder = MeshBuilder();
        ASSERT_OR_DIE(mesh->IsTriangleMesh(), "Was unable to load the mesh, it's not a triangle mesh!");
        Matrix4x4 geoTransform = GetGeometricTransform(mesh);
        matrixStack.Push(geoTransform);

        int controlPointCount = mesh->GetControlPointsCount();

        //Figure out our weighs for all verts before importing any of them
        std::vector<SkinWeight> skinWeights;
        if (HasSkinWeights(mesh))
        {
            skinWeights.resize(controlPointCount);
            GetSkinWeights(import, skinWeights, mesh, nodeToJointIndex);
        }
        else
        {
            FbxNode* node = mesh->GetNode();
            //Walk tree up till you reach the node associated with that joint.
            //Find the first parent node that has a joint associated with it
            //All vertices (fully weighted)
            //All Skin Weights = indices{jointINdex, 0, 0, 0 } weights{1.0f, 0.0f, 0.0f, 0.0f};

            int jointIndex = Skeleton::INVALID_JOINT_INDEX;
            for (auto iter = nodeToJointIndex.begin(); iter != nodeToJointIndex.end(); ++iter)
            {
                if (iter->second == node)
                {
                    jointIndex = iter->first;
                    break;
                }
            }

            if (jointIndex == Skeleton::INVALID_JOINT_INDEX)
            {
                for (unsigned int i = 0; i < skinWeights.size(); ++i)
                {
                    skinWeights[i].indices = Vector4Int::ZERO;
                    skinWeights[i].weights = Vector4::UNIT_X;
                }
            }
            else
            {
                for (unsigned int i = 0; i < skinWeights.size(); ++i)
                {
                    skinWeights[i].indices = Vector4Int(jointIndex, 0, 0, 0);
                    skinWeights[i].weights = Vector4::UNIT_X;
                }
            }
        }

        builder.Begin();
        {
            Matrix4x4 transform = matrixStack.GetTop();
            int polyCount = mesh->GetPolygonCount();
            for (int polyIndex = 0; polyIndex < polyCount; ++polyIndex)
            {
                int vertCount = mesh->GetPolygonSize(polyIndex);
                ASSERT_OR_DIE(vertCount == 3, "Vertex count was not 3");
                for (int vertIndex = 0; vertIndex < vertCount; ++vertIndex)
                {
                    ImportVertex(builder, transform, mesh, polyIndex, vertIndex, skinWeights);
                }
            }
        }
        builder.End();

        FbxSurfaceMaterial* material = mesh->GetNode()->GetMaterial(0);
        builder.SetMaterialName(material->GetName());

        matrixStack.Pop();

        import->meshes.push_back(builder);
    }
Example #22
0
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() );
		}
	}
}
Example #23
0
/**
 * 相対パスのファイル名をテクスチャのファイル名として再帰的に設定する
 *
 * @param node FbxNode
 */
void FbxFileLoader::set_relative_file_name_to_texture_file_name_recursive( FbxNode* node )
{
	if ( ! node )
	{
		return;
	}

	for ( int n = 0; n < node->GetMaterialCount(); n++ )
	{
		FbxSurfaceMaterial* material = node->GetMaterial( n );

		if ( ! material )
		{
			continue;
		}

		for ( auto p = material->GetFirstProperty(); p.IsValid(); p = material->GetNextProperty( p ) )
		{
			for ( int m = 0; m < p.GetSrcObjectCount< FbxTexture >(); m++ )
			{
				FbxLayeredTexture* layered_texture = p.GetSrcObject< FbxLayeredTexture >( m );
				FbxFileTexture* file_texture = nullptr;

				if ( layered_texture )
				{
					for ( int l = 0; l < layered_texture->GetSrcObjectCount< FbxTexture >(); l++ )
					{
						if ( ! layered_texture->GetSrcObject< FbxTexture >( l ) )
						{
							continue;
						}

						file_texture = FbxCast< FbxFileTexture >( layered_texture->GetSrcObject< FbxTexture >( l ) );
					}
				}
				else
				{
					if ( ! p.GetSrcObject< FbxTexture >( m ) )
					{
						continue;
					}

					file_texture = FbxCast< FbxFileTexture >( p.GetSrcObject< FbxTexture >( m ) );
				}

				if ( file_texture )
				{
					const string_t relative_file_name = file_texture->GetRelativeFileName();

					if ( ! file_texture->SetFileName( relative_file_name.c_str() ) )
					{
						COMMON_THROW_EXCEPTION_MESSAGE( string_t( "FbxFileTexture::SetFileName failed : " ) + relative_file_name );
					}
					/*
					if ( ! file_texture->SetRelativeFileName( relative_file_name.c_str() ) )
					{
						COMMON_THROW_EXCEPTION_MESSAGE( string_t( "FbxFileTexture::SetRelativeFileName failed : " ) + relative_file_name );
					}
					*/
				}
			}
		}
	}

	for ( int n = 0; n < node->GetChildCount(); n++ )
	{
		set_relative_file_name_to_texture_file_name_recursive( node->GetChild( n ) );
	}
}
Example #24
0
bool FillData(ModelData* someData,FbxNode* aNode, AnimationData* aAnimation)
{
	FbxMesh* mesh = aNode->GetMesh();
	if (mesh == nullptr || !aNode)
		return false;

	const int lPolygonCount = mesh->GetPolygonCount();

	// Count the polygon count of each material
	FbxLayerElementArrayTemplate<int>* lMaterialIndice = NULL;
	FbxGeometryElement::EMappingMode lMaterialMappingMode = FbxGeometryElement::eNone;
	if (mesh->GetElementMaterial())
	{
		lMaterialIndice = &mesh->GetElementMaterial()->GetIndexArray();
		lMaterialMappingMode = mesh->GetElementMaterial()->GetMappingMode();
		if (lMaterialIndice && lMaterialMappingMode == FbxGeometryElement::eByPolygon)
		{
			FBX_ASSERT(lMaterialIndice->GetCount() == lPolygonCount);
			if (lMaterialIndice->GetCount() == lPolygonCount)
			{
				// Count the faces of each material
				for (int lPolygonIndex = 0; lPolygonIndex < lPolygonCount; ++lPolygonIndex)
				{
					const int lMaterialIndex = lMaterialIndice->GetAt(lPolygonIndex);
					lMaterialIndex;
					/*if (someData->mSubMeshes[lMaterialIndex] == NULL)
					{
						someData->mSubMeshes[lMaterialIndex] = new ModelData::SubMesh;
					}
					someData->mSubMeshes[lMaterialIndex]->TriangleCount += 1;*/
				}

				// Make sure we have no "holes" (NULL) in the mSubMeshes table. This can happen
				// if, in the loop above, we resized the mSubMeshes by more than one slot.
					
				/*for (int i = 0; i < someData->mSubMeshes.Count(); i++)
				{
					if (someData->mSubMeshes[i] == NULL)
						someData->mSubMeshes[i] = new ModelData::SubMesh;
				}*/

				// Record the offset (how many vertex)
				const int lMaterialCount = someData->mSubMeshes.Size();
				lMaterialCount;
				int lOffset = 0;
				/*for (int lIndex = 0; lIndex < lMaterialCount; ++lIndex)
				{
					someData->mSubMeshes[lIndex]->IndexOffset = lOffset;
					lOffset += someData->mSubMeshes[lIndex]->TriangleCount * 3;
					// This will be used as counter in the following procedures, reset to zero
					someData->mSubMeshes[lIndex]->TriangleCount = 0;
				}*/
				FBX_ASSERT(lOffset == lPolygonCount * 3);
			}
		}
	}

	// All faces will use the same material.
	if (someData->mSubMeshes.Size() == 0)
	{
		if (someData->mSubMeshes.GetCapacity() == 0)
		{
			someData->mSubMeshes.Init(1);
		}
		someData->mSubMeshes.RemoveAll();
		someData->mSubMeshes.AddEmptyObject();
		someData->mSubMeshes[0] = new ModelData::SubMesh();
	}

		

	bool hasNormalMap = false;

	const int lMaterialCount = aNode->GetMaterialCount();
	for (int lMaterialIndex = 0; lMaterialIndex < lMaterialCount; ++lMaterialIndex)
	{
		FbxSurfaceMaterial * lMaterial = aNode->GetMaterial(lMaterialIndex);
		if (lMaterial && !lMaterial->GetUserDataPtr())
		{
			TextureInfo diffuseInfo;
			GetMaterialProperty(lMaterial,FbxSurfaceMaterial::sDiffuse,FbxSurfaceMaterial::sDiffuseFactor,diffuseInfo.myFileName);
			diffuseInfo.myType = DIFFUSE;
			if(diffuseInfo.myFileName.empty() == false)
			{
				someData->myTextures.push_back(diffuseInfo);
			}

			TextureInfo normalInfo;
			GetMaterialProperty(lMaterial,FbxSurfaceMaterial::sNormalMap,FbxSurfaceMaterial::sBumpFactor,normalInfo.myFileName);
			hasNormalMap = normalInfo.myFileName.empty() == false;
			normalInfo.myType = NORMALMAP;
			if(normalInfo.myFileName.empty() == false)
			{
				someData->myTextures.push_back(normalInfo);
				hasNormalMap = true;
			}

			TextureInfo roughnessInfo;
			GetMaterialProperty(lMaterial,FbxSurfaceMaterial::sSpecular,FbxSurfaceMaterial::sSpecularFactor,roughnessInfo.myFileName);
			roughnessInfo.myType = ROUGHNESS;
			if(roughnessInfo.myFileName.empty() == false)
			{
				someData->myTextures.push_back(roughnessInfo);
			}

			TextureInfo substanceInfo;
			GetMaterialProperty(lMaterial,FbxSurfaceMaterial::sReflection,FbxSurfaceMaterial::sReflectionFactor,substanceInfo.myFileName);
			substanceInfo.myType = SUBSTANCE;
			if(substanceInfo.myFileName.empty() == false)
			{
				someData->myTextures.push_back(substanceInfo);
			}

			TextureInfo ambientInfo;
			GetMaterialProperty(lMaterial, FbxSurfaceMaterial::sAmbient, FbxSurfaceMaterial::sAmbientFactor, ambientInfo.myFileName);
			ambientInfo.myType = AO;
			if (substanceInfo.myFileName.empty() == false)
			{
				someData->myTextures.push_back(ambientInfo);
			}
		}
	}

	// Congregate all the data of a mesh to be cached in VBOs.
	// If normal or UV is by polygon vertex, record all vertex attributes by polygon vertex.'
		
	someData->mHasNormal = mesh->GetElementNormalCount() > 0;
	someData->mHasUV = mesh->GetElementUVCount() > 0;
	someData->myHasBiNormal = mesh->GetElementBinormalCount() > 0;

	FbxSkin * lSkinDeformer = (FbxSkin *)mesh->GetDeformer(0, FbxDeformer::eSkin);
	someData->myHasSkinweights = lSkinDeformer != nullptr;

	if(hasNormalMap && someData->myHasBiNormal == false)
	{
		mesh->GenerateTangentsDataForAllUVSets();
		someData->myHasBiNormal = mesh->GetElementBinormalCount() > 0;
	}
	someData->myHasTangents = mesh->GetElementTangentCount() > 0;
		
	FbxGeometryElement::EMappingMode lNormalMappingMode = FbxGeometryElement::eNone;
	FbxGeometryElement::EMappingMode lUVMappingMode = FbxGeometryElement::eNone;
	if (someData->mHasNormal)
	{
		lNormalMappingMode = mesh->GetElementNormal(0)->GetMappingMode();
		if (lNormalMappingMode == FbxGeometryElement::eNone)
		{
			someData->mHasNormal = false;
		}
		if (someData->mHasNormal && lNormalMappingMode != FbxGeometryElement::eByControlPoint)
		{
			someData->mAllByControlPoint = false;
		}
	}
	if (someData->mHasUV)
	{
		lUVMappingMode = mesh->GetElementUV(0)->GetMappingMode();
		if (lUVMappingMode == FbxGeometryElement::eNone)
		{
			someData->mHasUV = false;
		}
		if (someData->mHasUV && lUVMappingMode != FbxGeometryElement::eByControlPoint)
		{
			someData->mAllByControlPoint = false;
		}
	}

	// Allocate the array memory, by control point or by polygon vertex.
	int lPolygonVertexCount = mesh->GetControlPointsCount();
	//if (!someData->my)
	{
		ModelData::Layout newLayout;
		newLayout.myType = ModelData::VERTEX_POS;
		newLayout.mySize = VERTEX_STRIDE;
		newLayout.myOffset = 0;
		someData->myLayout.Add(newLayout);
		lPolygonVertexCount = lPolygonCount * TRIANGLE_VERTEX_COUNT;
	}
	int stride = VERTEX_STRIDE;
	size_t size = lPolygonVertexCount * VERTEX_STRIDE;
	//float * lVertices = new float[lPolygonVertexCount * VERTEX_STRIDE];
	unsigned int * lIndices = new unsigned int[lPolygonCount * TRIANGLE_VERTEX_COUNT];
	someData->myIndexCount = lPolygonCount * TRIANGLE_VERTEX_COUNT;
	//float * lNormals = NULL;
	if (someData->mHasNormal)
	{
		ModelData::Layout newLayout;
		newLayout.myType = ModelData::VERTEX_NORMAL;
		newLayout.mySize = NORMAL_STRIDE;
		newLayout.myOffset = stride*4;
		someData->myLayout.Add(newLayout);

		stride += NORMAL_STRIDE;
		size += lPolygonVertexCount * NORMAL_STRIDE;
		//lNormals = new float[lPolygonVertexCount * NORMAL_STRIDE];
	}
	//float * lUVs = NULL;
	FbxStringList lUVNames;
	mesh->GetUVSetNames(lUVNames);
	const char * lUVName = NULL;
	if (someData->mHasUV && lUVNames.GetCount())
	{
		ModelData::Layout newLayout;
		newLayout.myType = ModelData::VERTEX_UV;
		newLayout.mySize = UV_STRIDE;
		newLayout.myOffset = stride*4;
		someData->myLayout.Add(newLayout);

		stride += UV_STRIDE;
		size += lPolygonVertexCount * UV_STRIDE;
		//lUVs = new float[lPolygonVertexCount * UV_STRIDE];
		lUVName = lUVNames[0];
	}

	if (someData->myHasBiNormal)
	{
		ModelData::Layout newLayout;
		newLayout.myType = ModelData::VERTEX_BINORMAL;
		newLayout.mySize = BINORMAL_STRIDE;
		newLayout.myOffset = stride*4;
		someData->myLayout.Add(newLayout);

		stride += BINORMAL_STRIDE;
		size += lPolygonVertexCount * BINORMAL_STRIDE;
		//lUVs = new float[lPolygonVertexCount * UV_STRIDE];
	}

	if (someData->myHasTangents)
	{
		ModelData::Layout newLayout;
		newLayout.myType = ModelData::VERTEX_TANGENT;
		newLayout.mySize = TANGENT_STRIDE;
		newLayout.myOffset = stride*4;
		someData->myLayout.Add(newLayout);

		stride += TANGENT_STRIDE;
		size += lPolygonVertexCount * TANGENT_STRIDE;
		//lUVs = new float[lPolygonVertexCount * UV_STRIDE];
	}

	if (someData->myHasSkinweights)
	{
		ModelData::Layout newLayout;
		newLayout.myType = ModelData::VERTEX_SKINWEIGHTS;
		newLayout.mySize = SKINWEIGHT_STRIDE;
		newLayout.myOffset = stride*4;
		someData->myLayout.Add(newLayout);

		stride += SKINWEIGHT_STRIDE;
		size += lPolygonVertexCount * SKINWEIGHT_STRIDE;

		newLayout.myType = ModelData::VERTEX_BONEID;
		newLayout.mySize = BONEID_STRIDE;
		newLayout.myOffset = stride*4;
		someData->myLayout.Add(newLayout);

		stride += BONEID_STRIDE;
		size += lPolygonVertexCount * BONEID_STRIDE;
		//lUVs = new float[lPolygonVertexCount * UV_STRIDE];
	}

	float * lVertices = new float[size];

	FbxAMatrix globalPos;
	FbxVector4* weights = nullptr;
	FbxVectorTemplate4<int>* bones = nullptr;
	FbxTime time = static_cast<FbxTime>(0.0f);
	if(someData->myHasSkinweights)
	{
		weights = new FbxVector4[mesh->GetControlPointsCount()];
		bones = new FbxVectorTemplate4<int>[mesh->GetControlPointsCount()];
		ComputeLinearDeformation(globalPos,mesh,weights,bones,aAnimation);
	}

	const FbxGeometryElementBinormal * lBiNormalElement = NULL;
	const FbxGeometryElementTangent * lTangentElement = NULL;

	if (someData->myHasBiNormal)
	{
		lBiNormalElement = mesh->GetElementBinormal(0);
	}
	if (someData->myHasTangents)
	{
		lTangentElement = mesh->GetElementTangent(0);
	}

	// Populate the array with vertex attribute, if by control point.
	const FbxVector4 * lControlPoints = mesh->GetControlPoints();
	FbxVector4 lCurrentVertex;
	FbxVector4 lCurrentNormal;
	FbxVector4 lCurrentBiNormal;
	FbxVector4 lCurrentTangent;
	FbxVector2 lCurrentUV;
	if (someData->mAllByControlPoint)
	{
		const FbxGeometryElementNormal * lNormalElement = NULL;
		const FbxGeometryElementUV * lUVElement = NULL;
		if (someData->mHasNormal)
		{
			lNormalElement = mesh->GetElementNormal(0);
		}
		if (someData->mHasUV)
		{
			lUVElement = mesh->GetElementUV(0);
		}

		for (int lIndex = 0; lIndex < lPolygonVertexCount; ++lIndex)
		{
			int currentIndex = lIndex * stride;
			int addedSize = VERTEX_STRIDE;
			// Save the vertex position.
			lCurrentVertex = lControlPoints[lIndex];
				
			CU::Vector4f position(static_cast<float>(lCurrentVertex[0]),
					static_cast<float>(lCurrentVertex[1]),
					static_cast<float>(lCurrentVertex[2]),
					1);

			CU::Matrix44f fixMatrix;
			fixMatrix = CU::Matrix44<float>::CreateReflectionMatrixAboutAxis(CU::Vector3f(1,0,0));
			position = position*fixMatrix;

			lVertices[currentIndex] = position.x;
			lVertices[currentIndex + 1] = position.y;
			lVertices[currentIndex + 2] = position.z;
			lVertices[currentIndex + 3] = 1;


			// Save the normal.
			if (someData->mHasNormal)
			{
				int lNormalIndex = lIndex;
				if (lNormalElement->GetReferenceMode() == FbxLayerElement::eIndexToDirect)
				{
					lNormalIndex = lNormalElement->GetIndexArray().GetAt(lIndex);
				}
				lCurrentNormal = lNormalElement->GetDirectArray().GetAt(lNormalIndex);

				CU::Vector3f normal( static_cast<float>(lCurrentNormal[0]), static_cast<float>(lCurrentNormal[1]), static_cast<float>(lCurrentNormal[2]));
				normal = normal*CU::Matrix33<float>::CreateReflectionMatrixAboutAxis(CU::Vector3f(1, 0, 0));

				lVertices[currentIndex + addedSize] = normal.x;
				lVertices[currentIndex + addedSize + 1] = normal.y;
				lVertices[currentIndex + addedSize + 2] = normal.z;
				lVertices[currentIndex + addedSize + 3] = 0;
				addedSize += NORMAL_STRIDE;
			}

			// Save the UV.
			if (someData->mHasUV)
			{
				int lUVIndex = lIndex;
				if (lUVElement->GetReferenceMode() == FbxLayerElement::eIndexToDirect)
				{
					lUVIndex = lUVElement->GetIndexArray().GetAt(lIndex);
				}
				lCurrentUV = lUVElement->GetDirectArray().GetAt(lUVIndex);
				lVertices[currentIndex + addedSize] = static_cast<float>(lCurrentUV[0]);
				lVertices[currentIndex + addedSize + 1] = static_cast<float>(lCurrentUV[1])*-1.0f;
				addedSize += 2;
			}

			if (someData->myHasBiNormal)
				{
					int lBinormIndexIndex = lIndex;
					if (lBiNormalElement->GetReferenceMode() == FbxLayerElement::eIndexToDirect)
					{
						lBinormIndexIndex = lBiNormalElement->GetIndexArray().GetAt(lIndex);
					}

					lCurrentBiNormal = lBiNormalElement->GetDirectArray().GetAt(lBinormIndexIndex);
					//mesh->GetElementBinormal(lPolygonIndex, lVerticeIndex, lCurrentNormal);
					//lCurrentNormal = lCurrentNormal
					CU::Vector3f normal( static_cast<float>(lCurrentBiNormal[0]), static_cast<float>(lCurrentBiNormal[1]), static_cast<float>(lCurrentBiNormal[2]));
					normal = normal*CU::Matrix33<float>::CreateReflectionMatrixAboutAxis(CU::Vector3f(1, 0, 0));
					if (CU::Length(normal) != 0.f)
						CU::Normalize(normal);
					lVertices[currentIndex + addedSize] = normal.x;
					lVertices[currentIndex + addedSize + 1] = normal.y;
					lVertices[currentIndex + addedSize + 2] = normal.z;
					lVertices[currentIndex + addedSize + 3] = 0;
					addedSize += BINORMAL_STRIDE;
				}

				if (someData->myHasTangents)
				{
					int lBinormIndexIndex = lIndex;
					if (lTangentElement->GetReferenceMode() == FbxLayerElement::eIndexToDirect)
					{
						lBinormIndexIndex = lTangentElement->GetIndexArray().GetAt(lIndex);
					}

					lCurrentTangent = lTangentElement->GetDirectArray().GetAt(lBinormIndexIndex);

					//lCurrentNormal = lCurrentNormal
					CU::Vector3f normal( static_cast<float>(lCurrentTangent[0]), static_cast<float>(lCurrentTangent[1]), static_cast<float>(lCurrentTangent[2]));
					normal = normal*CU::Matrix33<float>::CreateReflectionMatrixAboutAxis(CU::Vector3f(1, 0, 0));
					if (CU::Length(normal) != 0.f)
						CU::Normalize(normal);
					lVertices[currentIndex + addedSize] = normal.x;
					lVertices[currentIndex + addedSize + 1] = normal.y;
					lVertices[currentIndex + addedSize + 2] = normal.z;
					lVertices[currentIndex + addedSize + 3] = 0;
					addedSize += TANGENT_STRIDE;
				}

				if(someData->myHasSkinweights)
				{
					FbxVector4 currentWeights = weights[lIndex];
					//currentWeights.Normalize();

					lVertices[currentIndex + addedSize] = static_cast<float>(currentWeights[0]);
					lVertices[currentIndex + addedSize + 1] = static_cast<float>(currentWeights[1]);
					lVertices[currentIndex + addedSize + 2] = static_cast<float>(currentWeights[2]);
					lVertices[currentIndex + addedSize + 3] = static_cast<float>(currentWeights[3]);
					addedSize += SKINWEIGHT_STRIDE;

					FbxVectorTemplate4<int> currentBones = bones[lIndex];

					lVertices[currentIndex + addedSize] = static_cast<float>(currentBones[0]);
					lVertices[currentIndex + addedSize + 1] = static_cast<float>(currentBones[1]);
					lVertices[currentIndex + addedSize + 2] = static_cast<float>(currentBones[2]);
					lVertices[currentIndex + addedSize + 3] = static_cast<float>(currentBones[3]);
					addedSize += BONEID_STRIDE;
				}
		}

	}

	int lVertexCount = 0;
	for (int lPolygonIndex = 0; lPolygonIndex < lPolygonCount; ++lPolygonIndex)
	{
		// The material for current face.
		int lMaterialIndex = 0;
		if (lMaterialIndice && lMaterialMappingMode == FbxGeometryElement::eByPolygon)
		{
			lMaterialIndex = lMaterialIndice->GetAt(lPolygonIndex);
		}

		// Where should I save the vertex attribute index, according to the material
		const int lIndexOffset = someData->mSubMeshes[lMaterialIndex]->IndexOffset +
			someData->mSubMeshes[lMaterialIndex]->TriangleCount * 3;
		for (int lVerticeIndex = TRIANGLE_VERTEX_COUNT-1; lVerticeIndex > -1; --lVerticeIndex)
		{
			const int lControlPointIndex = mesh->GetPolygonVertex(lPolygonIndex, lVerticeIndex);
				
			int vertexIndex = lIndexOffset + (TRIANGLE_VERTEX_COUNT-1) - lVerticeIndex;
			if (someData->mAllByControlPoint)
			{
				lIndices[vertexIndex] = static_cast<unsigned int>(lControlPointIndex);
			}
			// Populate the array with vertex attribute, if by polygon vertex.
			else
			{
				lIndices[vertexIndex] = static_cast<unsigned int>(lVertexCount);

				lCurrentVertex = lControlPoints[lControlPointIndex];
				int addedSize = VERTEX_STRIDE;
				int currentIndex = lVertexCount * stride;

				CU::Vector4f position(static_cast<float>(lCurrentVertex[0]),
					static_cast<float>(lCurrentVertex[1]),
					static_cast<float>(lCurrentVertex[2]),
					1);

				//fixMatrix
				CU::Matrix44f fixMatrix;
				fixMatrix = CU::Matrix44<float>::CreateReflectionMatrixAboutAxis(CU::Vector3f(1, 0, 0));
				position = position*fixMatrix;

				lVertices[currentIndex] = position.x;
				lVertices[currentIndex + 1] = position.y;
				lVertices[currentIndex + 2] = position.z;
				lVertices[currentIndex + 3] = 0;

				if (someData->mHasNormal)
				{
					mesh->GetPolygonVertexNormal(lPolygonIndex, lVerticeIndex, lCurrentNormal);
					CU::Vector3f normal( static_cast<float>(lCurrentNormal[0]), static_cast<float>(lCurrentNormal[1]), static_cast<float>(lCurrentNormal[2]));
					normal = normal*CU::Matrix33<float>::CreateReflectionMatrixAboutAxis(CU::Vector3f(1, 0, 0));
					if (CU::Length(normal) != 0.f)
						CU::Normalize(normal);

					lVertices[currentIndex + addedSize] = normal.x;
					lVertices[currentIndex + addedSize + 1] = normal.y;
					lVertices[currentIndex + addedSize + 2] = normal.z;
					lVertices[currentIndex + addedSize + 3] = 0;
					addedSize += NORMAL_STRIDE;
				}

				if (someData->mHasUV)
				{
					bool lUnmappedUV;
					mesh->GetPolygonVertexUV(lPolygonIndex, lVerticeIndex, lUVName, lCurrentUV, lUnmappedUV);
					lVertices[currentIndex + addedSize] = static_cast<float>(lCurrentUV[0]);
					lVertices[currentIndex + addedSize + 1] = static_cast<float>(lCurrentUV[1])*-1.0f;
					addedSize += UV_STRIDE;
				}
					
				if (someData->myHasBiNormal)
				{
					int lBinormIndexIndex = lVerticeIndex;
					if (lBiNormalElement->GetReferenceMode() == FbxLayerElement::eIndexToDirect)
					{
						lBinormIndexIndex = lBiNormalElement->GetIndexArray().GetAt(lVerticeIndex);
					}

					lCurrentBiNormal = lBiNormalElement->GetDirectArray().GetAt(lBinormIndexIndex);

					CU::Vector3f normal( static_cast<float>(lCurrentBiNormal[0]), static_cast<float>(lCurrentBiNormal[1]), static_cast<float>(lCurrentBiNormal[2]));
					normal = normal*CU::Matrix33<float>::CreateReflectionMatrixAboutAxis(CU::Vector3f(1, 0, 0));
					if (CU::Length(normal) != 0.f)
						CU::Normalize(normal);
					lVertices[currentIndex + addedSize] = normal.x;
					lVertices[currentIndex + addedSize + 1] = normal.y;
					lVertices[currentIndex + addedSize + 2] = normal.z;
					lVertices[currentIndex + addedSize + 3] = 0;
					addedSize += BINORMAL_STRIDE;
				}

				if (someData->myHasTangents)
				{
					int lBinormIndexIndex = lVerticeIndex;
					if (lTangentElement->GetReferenceMode() == FbxLayerElement::eIndexToDirect)
					{
						lBinormIndexIndex = lTangentElement->GetIndexArray().GetAt(lVerticeIndex);
					}

					lCurrentTangent = lTangentElement->GetDirectArray().GetAt(lBinormIndexIndex);

					mesh->GetPolygonVertexNormal(lPolygonIndex, lVerticeIndex, lCurrentNormal);

					CU::Vector3f normal( static_cast<float>(lCurrentTangent[0]), static_cast<float>(lCurrentTangent[1]), static_cast<float>(lCurrentTangent[2]));
					normal = normal*CU::Matrix33<float>::CreateReflectionMatrixAboutAxis(CU::Vector3f(1, 0, 0));
					if (CU::Length(normal) != 0.f)
						CU::Normalize(normal);
					lVertices[currentIndex + addedSize] = normal.x;
					lVertices[currentIndex + addedSize + 1] = normal.y;
					lVertices[currentIndex + addedSize + 2] = normal.z;
					lVertices[currentIndex + addedSize + 3] = 0;
					addedSize += TANGENT_STRIDE;
				}

				if(someData->myHasSkinweights)
				{
					FbxVector4 currentWeights = weights[lControlPointIndex];
					FbxVectorTemplate4<int> currentBones = bones[lControlPointIndex];
					for(int l = 0;l < 4;++l)
					{
						if(currentBones[l] == -1)
						{
							currentWeights[l] = 0.0f;
						}
					}
					currentWeights.Normalize();

					lVertices[currentIndex + addedSize] = static_cast<float>(currentWeights[0]);
					lVertices[currentIndex + addedSize + 1] = static_cast<float>(currentWeights[1]);
					lVertices[currentIndex + addedSize + 2] = static_cast<float>(currentWeights[2]);
					lVertices[currentIndex + addedSize + 3] = static_cast<float>(currentWeights[3]);
					addedSize += SKINWEIGHT_STRIDE;

						

					lVertices[currentIndex + addedSize] = *(float*)&currentBones[0];
					lVertices[currentIndex + addedSize + 1] = *(float*)&currentBones[1];
					lVertices[currentIndex + addedSize + 2] = *(float*)&currentBones[2];
					lVertices[currentIndex + addedSize + 3] = *(float*)&currentBones[3];
					addedSize += BONEID_STRIDE;
				}
			}
			++lVertexCount;
		}
		someData->mSubMeshes[lMaterialIndex]->TriangleCount += 1;
	}

	someData->myVertexCount = lVertexCount;
	someData->myVertexStride = stride;

	someData->myVertexBuffer = lVertices;
	someData->myIndicies = lIndices;

	if(weights)
	{
		delete [] weights;
		delete [] bones;
	}

	return true;
}
Example #25
0
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;
}