Esempio n. 1
0
FbxDouble3 GetMaterialProperty(const FbxSurfaceMaterial * pMaterial,
	const char * pPropertyName,
	const char * pFactorPropertyName,
	std::string & pTextureName)
{
	FbxDouble3 lResult(0, 0, 0);
	const FbxProperty lProperty = pMaterial->FindProperty(pPropertyName);
	const FbxProperty lFactorProperty = pMaterial->FindProperty(pFactorPropertyName);
	if (lProperty.IsValid() && lFactorProperty.IsValid())
	{
		lResult = lProperty.Get<FbxDouble3>();
		double lFactor = lFactorProperty.Get<FbxDouble>();
		if (lFactor != 1)
		{
			lResult[0] *= lFactor;
			lResult[1] *= lFactor;
			lResult[2] *= lFactor;
		}
	}

	if (lProperty.IsValid())
	{
		const int lTextureCount = lProperty.GetSrcObjectCount<FbxFileTexture>();
		if (lTextureCount)
		{
			const FbxFileTexture* lTexture = lProperty.GetSrcObject<FbxFileTexture>();
			if (lTexture)
			{
				pTextureName = lTexture->GetFileName();
			}
		}
	}

	return lResult;
}
Esempio n. 2
0
// Bake material properties.
bool MaterialCache::Initialize(const FbxSurfaceMaterial * pMaterial)
{
	const FbxDouble3 lEmissive = GetMaterialProperty(pMaterial,
		FbxSurfaceMaterial::sEmissive, FbxSurfaceMaterial::sEmissiveFactor, mEmissive.mTextureName);
	mEmissive.mColor[0] = static_cast<GLfloat>(lEmissive[0]);
	mEmissive.mColor[1] = static_cast<GLfloat>(lEmissive[1]);
	mEmissive.mColor[2] = static_cast<GLfloat>(lEmissive[2]);

	const FbxDouble3 lAmbient = GetMaterialProperty(pMaterial,
		FbxSurfaceMaterial::sAmbient, FbxSurfaceMaterial::sAmbientFactor, mAmbient.mTextureName);
	mAmbient.mColor[0] = static_cast<GLfloat>(lAmbient[0]);
	mAmbient.mColor[1] = static_cast<GLfloat>(lAmbient[1]);
	mAmbient.mColor[2] = static_cast<GLfloat>(lAmbient[2]);

	const FbxDouble3 lDiffuse = GetMaterialProperty(pMaterial,
		FbxSurfaceMaterial::sDiffuse, FbxSurfaceMaterial::sDiffuseFactor, mDiffuse.mTextureName);
	mDiffuse.mColor[0] = static_cast<GLfloat>(lDiffuse[0]);
	mDiffuse.mColor[1] = static_cast<GLfloat>(lDiffuse[1]);
	mDiffuse.mColor[2] = static_cast<GLfloat>(lDiffuse[2]);

	const FbxDouble3 lSpecular = GetMaterialProperty(pMaterial,
		FbxSurfaceMaterial::sSpecular, FbxSurfaceMaterial::sSpecularFactor, mSpecular.mTextureName);
	mSpecular.mColor[0] = static_cast<GLfloat>(lSpecular[0]);
	mSpecular.mColor[1] = static_cast<GLfloat>(lSpecular[1]);
	mSpecular.mColor[2] = static_cast<GLfloat>(lSpecular[2]);

	FbxProperty lShininessProperty = pMaterial->FindProperty(FbxSurfaceMaterial::sShininess);
	if (lShininessProperty.IsValid())
	{
		double lShininess = lShininessProperty.Get<FbxDouble>();
		mShinness = static_cast<GLfloat>(lShininess);
	}

	return true;
}
Esempio n. 3
0
jdoubleArray getMaterialColorByProperty(JNIEnv *env, jint materialIndex, FbxDouble3 fbxColor, FbxDouble fbxColorFactor) {

	jdoubleArray color = env->NewDoubleArray(4);

	// Check memory could be allocated.
	if (color == NULL) { throwOutOfMemoryError(env); }

	FbxDouble transparencyFactor = ((FbxSurfaceLambert *) currentNode->GetMaterial(materialIndex))->TransparencyFactor;
	FbxDouble opacity;

	// Older FBX files may define the 'Opacity' property instead of 'TransparencyFactor'.
	FbxProperty opacityProperty = currentNode->GetMaterial(materialIndex)->FindProperty("Opacity");
	if (opacityProperty.IsValid()) {
		opacity = opacityProperty.Get<FbxDouble>();
	}
	else {
		opacity = 1-transparencyFactor;
	}

	double colorArray[4];
	for (int i=0; i<3; i++) {
		colorArray[i] = fbxColorFactor*fbxColor[i];
	}
	colorArray[3] = opacity;

	env->SetDoubleArrayRegion(color, 0, 4, colorArray);

	return color;
}
Esempio n. 4
0
void FBXImporter::LoadMaterialTexture(FBXMeshData* fbxMeshData, const char* textureType)
{
	FbxProperty property;

	// #NoteReference to DisplayMesh.cxx in FBX SDK samples.Note#
	property = fbxMeshData->mSurfaceMaterial->FindProperty(textureType);

	if (property.IsValid())
	{
		int textureCount = property.GetSrcObjectCount<FbxTexture>();

		for (int i = 0; i < textureCount; i++)
		{
			FbxTexture* texture = FbxCast<FbxTexture>(property.GetSrcObject<FbxTexture>(i));

			if (texture != nullptr)
			{
				FbxFileTexture* fileTexture = FbxCast<FbxFileTexture>(texture);

				string textureFileName = fileTexture->GetFileName();

				if (strcmp(textureType, FbxSurfaceMaterial::sDiffuse) == 0)
				{
					fbxMeshData->mMaterial->setDiffuseTexture(textureFileName);
				}
				else if (strcmp(textureType, FbxSurfaceMaterial::sBump) == 0)
				{
					fbxMeshData->mMaterial->setNormalMapTexture(textureFileName);
				}
			}
		}
	}
}
void CFBXLoader::CopyMatrialData(FbxSurfaceMaterial* mat, FBX_MATERIAL_NODE* destMat)
{
	if(!mat)
		return ;

	if ( mat->GetClassId().Is( FbxSurfaceLambert::ClassId ) ) 
	{
		destMat->type = FBX_MATERIAL_NODE::MATERIAL_LAMBERT;
	}
	else if ( mat->GetClassId().Is( FbxSurfacePhong::ClassId ) ) 
	{
		destMat->type = FBX_MATERIAL_NODE::MATERIAL_PHONG;
	}

	const FbxDouble3 lEmissive = GetMaterialProperty(mat,
		FbxSurfaceMaterial::sEmissive, FbxSurfaceMaterial::sEmissiveFactor, &destMat->emmisive);
	SetFbxColor(destMat->emmisive, lEmissive );

    const FbxDouble3 lAmbient = GetMaterialProperty(mat,
        FbxSurfaceMaterial::sAmbient, FbxSurfaceMaterial::sAmbientFactor, &destMat->ambient);
	SetFbxColor(destMat->ambient, lAmbient );

    const FbxDouble3 lDiffuse = GetMaterialProperty(mat,
        FbxSurfaceMaterial::sDiffuse, FbxSurfaceMaterial::sDiffuseFactor, &destMat->diffuse);
	SetFbxColor(destMat->diffuse, lDiffuse );

    const FbxDouble3 lSpecular = GetMaterialProperty(mat,
        FbxSurfaceMaterial::sSpecular, FbxSurfaceMaterial::sSpecularFactor, &destMat->specular);
	SetFbxColor(destMat->specular, lSpecular );

	//
	FbxProperty lTransparencyFactorProperty = mat->FindProperty(FbxSurfaceMaterial::sTransparencyFactor);
	if(lTransparencyFactorProperty.IsValid())
	{
		double lTransparencyFactor = lTransparencyFactorProperty.Get<FbxDouble>();
		destMat->TransparencyFactor = static_cast<float>(lTransparencyFactor);
	}

	// Specular Power
    FbxProperty lShininessProperty = mat->FindProperty(FbxSurfaceMaterial::sShininess);
    if (lShininessProperty.IsValid())
    {
        double lShininess = lShininessProperty.Get<FbxDouble>();
		destMat->shininess = static_cast<float>(lShininess);
	}
}
// マテリアル表示
void GetMatrialData(FbxSurfaceMaterial* mat)
{
	if(mat == nullptr)
	{
		return;
	}

	puts("");

	if(mat->GetClassId().Is(FbxSurfaceLambert::ClassId))
	{
		printf("ランバートタイプ\n");
	}
	else if(mat->GetClassId().Is(FbxSurfacePhong::ClassId))
	{
		printf("フォンタイプ\n");
	}

	const FbxDouble3 lEmissive = GetMaterialProperty(mat, FbxSurfaceMaterial::sEmissive, FbxSurfaceMaterial::sEmissiveFactor);
	printf("エミッシブカラー:r = %f, g = %f, b = %f\n", lEmissive.mData[0], lEmissive.mData[1], lEmissive.mData[2]);

	const FbxDouble3 lAmbient = GetMaterialProperty(mat, FbxSurfaceMaterial::sAmbient, FbxSurfaceMaterial::sAmbientFactor);
	printf("アンビエントカラー:r = %f, g = %f, b = %f\n", lAmbient.mData[0], lAmbient.mData[1], lAmbient.mData[2]);

	const FbxDouble3 lDiffuse = GetMaterialProperty(mat, FbxSurfaceMaterial::sDiffuse, FbxSurfaceMaterial::sDiffuseFactor);
	printf("ディフューズカラー:r = %f, g = %f, b = %f\n", lDiffuse.mData[0], lDiffuse.mData[1], lDiffuse.mData[2]);

	const FbxDouble3 lSpecular = GetMaterialProperty(mat, FbxSurfaceMaterial::sSpecular, FbxSurfaceMaterial::sSpecularFactor);
	printf("スペキュラカラー:r = %f, g = %f, b = %f\n", lSpecular.mData[0], lSpecular.mData[1], lSpecular.mData[2]);

	FbxProperty lTransparencyFactorProperty = mat->FindProperty(FbxSurfaceMaterial::sTransparencyFactor);
	if(lTransparencyFactorProperty.IsValid())
	{
		double lTransparencyFactor = lTransparencyFactorProperty.Get<FbxDouble>();
		printf("透明度 = %lf\n", lTransparencyFactor);
	}

	FbxProperty lShininessProperty = mat->FindProperty(FbxSurfaceMaterial::sShininess);
	if(lShininessProperty.IsValid())
	{
		double lShininess = lShininessProperty.Get<FbxDouble>();
		printf("スペキュラ = %lf\n", lShininess);
	}
}
Esempio n. 7
0
		void FbxLoader::FbxLoader::ProcessMaterialTexture2D(FbxSurfaceMaterial* mat, FMaterial& material)
		{
			int Texture2DIndex = 0;
			FbxProperty prop;

			FBXSDK_FOR_EACH_TEXTURE(Texture2DIndex)
			{
				prop = mat->FindProperty(FbxLayerElement::sTextureChannelNames[Texture2DIndex]);
				if(prop.IsValid()) {
					const int Texture2DCount = prop.GetSrcObjectCount<FbxTexture>();
					for(int i = 0; i < Texture2DCount; i++) {
						FbxTexture* texture = prop.GetSrcObject<FbxTexture>(i);
						if(texture) {
							std::string textureType = prop.GetNameAsCStr();
							FbxFileTexture* fileTexture = FbxCast<FbxFileTexture>(texture);
							if(fileTexture) {
								if(textureType == "DiffuseColor")
									material.diffuseMapName = fileTexture->GetRelativeFileName();
								else if(textureType == "SpecularColor")
									material.specularMapName = fileTexture->GetRelativeFileName();
								else if(textureType == "NormalMap") {
									material.normalMapName = fileTexture->GetRelativeFileName();
									useNormalMap = true;
								}
							}
						}
					}

					const int layeredTextureCount = prop.GetSrcObjectCount<FbxLayeredTexture>();
					for(int i = 0; i < layeredTextureCount; i++) {
						auto layeredTexture = prop.GetSrcObject<FbxLayeredTexture>(i);
						const int fileCount = layeredTexture->GetSrcObjectCount<FbxFileTexture>();
						for(int j = 0; j < fileCount; j++) {
							auto fileTexture = layeredTexture->GetSrcObject<FbxFileTexture>(j);
							std::string Texture2DType = prop.GetNameAsCStr();
							if(fileTexture) {
								if(Texture2DType == "DiffuseColor")
									material.diffuseMapName = fileTexture->GetRelativeFileName();
								else if(Texture2DType == "SpecularColor")
									material.specularMapName = fileTexture->GetRelativeFileName();
								else if(Texture2DType == "NormalMap") {
									material.normalMapName = fileTexture->GetRelativeFileName();
									useNormalMap = true;
								}
							}
						}
					}
				}
			}

			if(material.diffuseMapName != "") {
				std::string n = FbxPathUtils::GetFileName(material.diffuseMapName.c_str(), false).Buffer();
				material.name = n;
				mat->SetName(n.c_str());
			}
		}
void FBXSceneEncoder::loadMaterialTextures(FbxSurfaceMaterial* fbxMaterial, Material* material)
{
    FbxProperty fbxProperty;
    int textureIndex;
    FBXSDK_FOR_EACH_TEXTURE(textureIndex)
    {
        fbxProperty = fbxMaterial->FindProperty(FbxLayerElement::sTextureChannelNames[textureIndex]);
        //FindAndDisplayTextureInfoByProperty(fbxProperty, lDisplayHeader, lMaterialIndex);
        if ( fbxProperty.IsValid() )
        {
            int textureCount = fbxProperty.GetSrcObjectCount<FbxTexture>();
            for (int j = 0; j < textureCount; ++j)
            {
                FbxLayeredTexture *layeredTexture = fbxProperty.GetSrcObject<FbxLayeredTexture>(j);
                if (layeredTexture)
                {
                    //DisplayInt("    Layered Texture: ", j);
                    FbxLayeredTexture *layeredTexture = fbxProperty.GetSrcObject<FbxLayeredTexture>(j);
                    int lNbTextures = layeredTexture->GetSrcObjectCount<FbxTexture>();
                    for (int k = 0; k<lNbTextures; ++k)
                    {
                        FbxTexture* fbxTexture = layeredTexture->GetSrcObject<FbxTexture>(k);
                        if (fbxTexture)
                        {
                            /*
                            if (pDisplayHeader){
                                DisplayInt("    Textures connected to Material ", pMaterialIndex);
                                pDisplayHeader = false;
                            }
                            */

                            //NOTE the blend mode is ALWAYS on the LayeredTexture and NOT the one on the texture.
                            //Why is that?  because one texture can be shared on different layered textures and might
                            //have different blend modes.

                            FbxLayeredTexture::EBlendMode lBlendMode;
                            layeredTexture->GetTextureBlendMode(k, lBlendMode);
                            //DisplayString("    Textures for ", pProperty.GetName());
                            //DisplayInt("        Texture ", k);
                            //DisplayTextureInfo(fbxTexture, (int) lBlendMode);
                        }

                    }
                }
                else if (FbxTexture* fbxTexture = fbxProperty.GetSrcObject<FbxTexture>(j))
                {
                    //no layered texture simply get on the property
                    if (FbxFileTexture* fileTexture = FbxCast<FbxFileTexture>(fbxTexture))
                    {
                        loadMaterialFileTexture(fileTexture, material);
                    }
                }
            }
        }
    }
}
Esempio n. 9
0
static void GetCustomVisionData(FbxNode* fbxNode, hkStringPtr& userPropertiesStr)
{
	userPropertiesStr = "";
	for(FbxProperty prop = fbxNode->GetFirstProperty(); prop.IsValid(); prop = fbxNode->GetNextProperty(prop))
	{
		EFbxType type = prop.GetPropertyDataType().GetType();
		if (type == eFbxString)
		{
			FbxString propertyData = prop.Get<FbxString>();
			const char* text = propertyData.Buffer();
			if (!hkString::strNcasecmp(text, "vision", 6))
			{
				userPropertiesStr = text;
				break;
			}
		}
	}
}
Esempio n. 10
0
void Converter::getDiffuseTextures(FbxSurfaceMaterial *material, std::vector<std::string> &textures)
{
	FbxProperty property = material->FindProperty(FbxLayerElement::sTextureChannelNames[0]);
	if (property.IsValid()) {
		for (int j = 0; j < property.GetSrcObjectCount<FbxTexture>(); ++j) {
			if (!property.GetSrcObject<FbxLayeredTexture>(j)) {
				FbxTexture* texture = property.GetSrcObject<FbxTexture>(j);
				if (texture) {
					std::string textureType = property.GetNameAsCStr();
					FbxFileTexture* fileTexture = FbxCast<FbxFileTexture>(texture);
					if (fileTexture) {
						if (textureType == "DiffuseColor") {
							//std::cout << fileTexture->GetRelativeFileName() << "\n";
							textures.push_back(fileTexture->GetRelativeFileName());
						}
					}
				}
			}
		}
	}
}
Esempio n. 11
0
	Material *FBX::buildMaterialFromFBX(FbxSurfaceMaterial *lMaterial) {
		Material *material=new Material(lMaterial->GetName());

		material->setShader("Common_d");
		material->addParameter(new Parameter("diffuse", Color(1.0, 1.0, 1.0, 0.0)));
		material->addParameter(new Parameter("ambient", Color(1.0, 1.0, 1.0, 0.0)));
		material->addParameter(new Parameter("specular", Color(0.9, 0.9, 0.9, 0.0)));
		material->addParameter(new Parameter("emissive", Color(0.0, 0.0, 0.0, 0.0)));
		material->addParameter(new Parameter("power_gloss_level", Color(50.0, 0.1, 0.0, 0.0)));
		material->addParameter(new Parameter("opacity_reflection_refraction_spectype", Color(1.0, 0.0, 1.0, 0.0)));
		material->addParameter(new Parameter("", Color(0.0, 0.0, 0.0, 0.0)));
		material->addParameter(new Parameter("", Color(0.0, 0.0, 0.0, 0.0)));
		material->addParameter(new Parameter("", Color(0.0, 0.0, 0.0, 0.0)));
		material->addParameter(new Parameter("", Color(0.0, 0.0, 0.0, 0.0)));

		FbxProperty lProperty = lMaterial->FindProperty(FbxSurfaceMaterial::sDiffuse);
		if (lProperty.IsValid()) {
			const int lTextureCount = lProperty.GetSrcObjectCount<FbxFileTexture>();
			if (lTextureCount) {
				const FbxFileTexture* lTexture = lProperty.GetSrcObject<FbxFileTexture>();
				if (lTexture) {
					string path=ToString(lTexture->GetFileName());

					size_t sep = path.find_last_of("\\/");
					if (sep != std::string::npos) {
						path = path.substr(sep + 1, path.size() - sep - 1);
					}
	
					size_t dot = path.find_last_of(".");
					if (dot != string::npos) {
						path = path.substr(0, dot);
					}

					Texture *texture=new Texture(ToString(lMaterial->GetName())+"-0000", "diffuse", path);
					material->addTextureUnit(texture);
				}
			}
		}
		return material;
	}
Esempio n. 12
0
//-------------------------------------------------------------------------------------------------------------------------------------------
void transferTextureByProperty(FbxProperty fbxProperty, int matId, Material* modelMaterial){
    if (fbxProperty.IsValid()){
        int textureCount = fbxProperty.GetSrcObjectCount<FbxTexture>();

        for (int texId = 0; texId < textureCount; texId++){
            FbxLayeredTexture* layeredTexture = fbxProperty.GetSrcObject<FbxLayeredTexture>(texId);
            if (layeredTexture){
                int numTexture = layeredTexture->GetSrcObjectCount<FbxTexture>();
                for (int k = 0; k < numTexture; k++){
                    FbxTexture* texture = layeredTexture->GetSrcObject<FbxTexture>(k);
                    if (texture){
                        LOG_DEBUG << "   Textures connected to material " << matId;

                        Texture* modelTexture = new Texture();
                        FbxLayeredTexture::EBlendMode blendMode;
                        layeredTexture->GetTextureBlendMode(k, blendMode);
                        transferTextureInfo(texture, (int)blendMode, modelTexture);
                        modelMaterial->Textures.push_back(modelTexture);
                    }
                }
            }
            else
            {
                // There is no layered texture
                FbxTexture* texture = fbxProperty.GetSrcObject<FbxTexture>(texId);
                if (texture){
                    LOG_DEBUG << "   Textures connected to material " << matId;

                    Texture* modelTexture = new Texture();
                    transferTextureInfo(texture, -1, modelTexture);
                    modelMaterial->Textures.push_back(modelTexture);
                }
            }
        }
    }
}
StateSetContent FbxMaterialToOsgStateSet::convert(const FbxSurfaceMaterial* pFbxMat)
{
    FbxMaterialMap::const_iterator it = _fbxMaterialMap.find(pFbxMat);
    if (it != _fbxMaterialMap.end())
        return it->second;

    osg::ref_ptr<osg::Material> pOsgMat = new osg::Material;
    pOsgMat->setName(pFbxMat->GetName());

    StateSetContent result;

    result.material = pOsgMat;

    FbxString shadingModel = pFbxMat->ShadingModel.Get();

    const FbxSurfaceLambert* pFbxLambert = FbxCast<FbxSurfaceLambert>(pFbxMat);

    // diffuse map...
    result.diffuse = selectTextureDetails(pFbxMat->FindProperty(FbxSurfaceMaterial::sDiffuse));

    // opacity map...
    double transparencyColorFactor = 1.0;
    bool useTransparencyColorFactor = false;

    const FbxProperty lOpacityProperty = pFbxMat->FindProperty(FbxSurfaceMaterial::sTransparentColor);
    if (lOpacityProperty.IsValid())
    {
        FbxDouble3 transparentColor = lOpacityProperty.Get<FbxDouble3>();
        // If transparent color is defined set the transparentFactor to gray scale value of transparentColor
        if (transparentColor[0] < 1.0 || transparentColor[1] < 1.0 || transparentColor[2] < 1.0) {
            transparencyColorFactor = transparentColor[0]*0.30 + transparentColor[1]*0.59 + transparentColor[2]*0.11;
            useTransparencyColorFactor = true;
        }

        result.opacity = selectTextureDetails(lOpacityProperty);
    }

    // reflection map...
    result.reflection = selectTextureDetails(pFbxMat->FindProperty(FbxSurfaceMaterial::sReflection));

    // emissive map...
    result.emissive = selectTextureDetails(pFbxMat->FindProperty(FbxSurfaceMaterial::sEmissive));

    // ambient map...
    result.ambient = selectTextureDetails(pFbxMat->FindProperty(FbxSurfaceMaterial::sAmbient));

    // normal map...
    result.normalMap = selectTextureDetails(pFbxMat->FindProperty(FbxSurfaceMaterial::sNormalMap));

    // specular map...
    result.specular = selectTextureDetails(pFbxMat->FindProperty(FbxSurfaceMaterial::sSpecular));

    // shininess map...
    result.shininess = selectTextureDetails(pFbxMat->FindProperty(FbxSurfaceMaterial::sShininess));


    if (pFbxLambert)
    {
        FbxDouble3 color = pFbxLambert->Diffuse.Get();
        double factor = pFbxLambert->DiffuseFactor.Get();
        double transparencyFactor = useTransparencyColorFactor ? transparencyColorFactor : pFbxLambert->TransparencyFactor.Get();
        pOsgMat->setDiffuse(osg::Material::FRONT_AND_BACK, osg::Vec4(
            static_cast<float>(color[0] * factor),
            static_cast<float>(color[1] * factor),
            static_cast<float>(color[2] * factor),
            static_cast<float>(1.0 - transparencyFactor)));

        color = pFbxLambert->Ambient.Get();
        factor = pFbxLambert->AmbientFactor.Get();
        pOsgMat->setAmbient(osg::Material::FRONT_AND_BACK, osg::Vec4(
            static_cast<float>(color[0] * factor),
            static_cast<float>(color[1] * factor),
            static_cast<float>(color[2] * factor),
            1.0f));

        color = pFbxLambert->Emissive.Get();
        factor = pFbxLambert->EmissiveFactor.Get();
        pOsgMat->setEmission(osg::Material::FRONT_AND_BACK, osg::Vec4(
            static_cast<float>(color[0] * factor),
            static_cast<float>(color[1] * factor),
            static_cast<float>(color[2] * factor),
            1.0f));

        // get maps factors...
        if (result.diffuse.valid()) result.diffuse->factor = pFbxLambert->DiffuseFactor.Get();
        if (result.emissive.valid()) result.emissive->factor = pFbxLambert->EmissiveFactor.Get();
        if (result.ambient.valid()) result.ambient->factor = pFbxLambert->AmbientFactor.Get();
        if (result.normalMap.valid()) result.normalMap->factor = pFbxLambert->BumpFactor.Get();

        if (const FbxSurfacePhong* pFbxPhong = FbxCast<FbxSurfacePhong>(pFbxLambert))
        {
            color = pFbxPhong->Specular.Get();
            factor = pFbxPhong->SpecularFactor.Get();
            pOsgMat->setSpecular(osg::Material::FRONT_AND_BACK, osg::Vec4(
                static_cast<float>(color[0] * factor),
                static_cast<float>(color[1] * factor),
                static_cast<float>(color[2] * factor),
                1.0f));
            // Since Maya and 3D studio Max stores their glossiness values in exponential format (2^(log2(x))
            // We need to linearize to values between 0-100 and then scale to values between 0-128.
            // Glossiness values above 100 will result in shininess larger than 128.0 and will be clamped
            double shininess = (64.0 * log (pFbxPhong->Shininess.Get())) / (5.0 * log(2.0));
            pOsgMat->setShininess(osg::Material::FRONT_AND_BACK,
                static_cast<float>(shininess));

            // get maps factors...
            if (result.reflection.valid()) result.reflection->factor = pFbxPhong->ReflectionFactor.Get();
            if (result.specular.valid()) result.specular->factor = pFbxPhong->SpecularFactor.Get();
            // get more factors here...
        }
    }

    if (_lightmapTextures)
    {
        // if using an emission map then adjust material properties accordingly...
        if (result.emissive.valid())
        {
            osg::Vec4 diffuse = pOsgMat->getDiffuse(osg::Material::FRONT_AND_BACK);
            pOsgMat->setEmission(osg::Material::FRONT_AND_BACK, diffuse);
            pOsgMat->setDiffuse(osg::Material::FRONT_AND_BACK, osg::Vec4(0,0,0,diffuse.a()));
            pOsgMat->setAmbient(osg::Material::FRONT_AND_BACK, osg::Vec4(0,0,0,diffuse.a()));
        }
    }

    _fbxMaterialMap.insert(FbxMaterialMap::value_type(pFbxMat, result));
    return result;
}
Esempio n. 14
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() );
		}
	}
}
Esempio n. 15
0
void Tools::DisplayGenericInfo::DisplayProperties( FbxObject *i_object )
{
	DisplayCommon::DisplayString( "Name: ", (char *)i_object->GetName() );

	// Display all the properties
	int i, count = 0;
	FbxProperty lProperty = i_object->GetFirstProperty();
	while( lProperty.IsValid() )
	{
		count++;
		lProperty = i_object->GetNextProperty( lProperty );
	}

	FbxString lTitleStr = "    Property Count: ";

	if( count == 0 )
		return; // there are no properties to display

	DisplayCommon::DisplayInt( lTitleStr.Buffer(), count );

	i = 0;
	lProperty = i_object->GetFirstProperty();
	while( lProperty.IsValid() )
	{
		// exclude user properties
		FbxString string;
		DisplayCommon::DisplayInt( "        Property ", i );
		string = lProperty.GetLabel();
		DisplayCommon::DisplayString( "            Display Name: ", string );
		string = lProperty.GetName();
		DisplayCommon::DisplayString( "            Internal Name: ", string.Buffer() );
		string = lProperty.GetPropertyDataType().GetName();
		DisplayCommon::DisplayString( "            Type: ",string.Buffer() );
		if (lProperty.HasMinLimit())
			DisplayCommon::DisplayDouble( "            Min Limit: ", lProperty.GetMinLimit() );
		if (lProperty.HasMaxLimit())
			DisplayCommon::DisplayDouble( "            Max Limit: ", lProperty.GetMaxLimit() );
		DisplayCommon::DisplayBool( "            Is Animatable: ", lProperty.GetFlag(FbxPropertyAttr::eAnimatable) );

		switch( lProperty.GetPropertyDataType().GetType() )
		{
		case eFbxBool:
			DisplayCommon::DisplayBool( "            Default Value: ", lProperty.Get<FbxBool>() );
			break;

		case eFbxDouble:
			DisplayCommon::DisplayDouble( "            Default Value: ", lProperty.Get<FbxDouble>() );
			break;

		case eFbxDouble4:
			{
				FbxColor lDefault;
				char buffer[64];

				lDefault = lProperty.Get<FbxColor>();
				FBXSDK_sprintf( buffer, 64, "R=%f, G=%f, B=%f, A=%f", lDefault.mRed, lDefault.mGreen, lDefault.mBlue, lDefault.mAlpha );
				DisplayCommon::DisplayString( "            Default Value: ", buffer );
			}
			break;

		case eFbxInt:
			DisplayCommon::DisplayInt( "            Default Value: ", lProperty.Get<FbxInt>() );
			break;

		case eFbxDouble3:
			{
				FbxDouble3 lDefault;
				char buffer[64];

				lDefault = lProperty.Get<FbxDouble3>();
				FBXSDK_sprintf( buffer, 64, "X=%f, Y=%f, Z=%f", lDefault[0], lDefault[1], lDefault[2] );
				DisplayCommon::DisplayString( "            Default Value: ", buffer );
			}
			break;

			//case FbxEnumDT:
			//    DisplayInt("            Default Value: ", lProperty.Get<FbxEnum>());
			//    break;

		case eFbxFloat:
			DisplayCommon::DisplayDouble( "            Default Value: ", lProperty.Get<FbxFloat>() );
			break;

		case eFbxString:
			string = lProperty.Get<FbxString>();
			DisplayCommon::DisplayString( "            Default Value: ", string.Buffer() );
			break;

		default:
			DisplayCommon::DisplayString( "            Default Value: UNIDENTIFIED" );
			break;
		}
		i++;
		lProperty = i_object->GetNextProperty( lProperty );
	}
}
Esempio n. 16
0
void FbxMaterial::AddProperty(const FbxProperty &property,
                           const FbxProperty &factor_property)
{




    /**
    *If we are dealing with an invalid properties, abort
    */
    if (!property.IsValid() || !factor_property.IsValid())
        return;




    /**
     *Get the name of the property
     */
    QString property_name = property.GetNameAsCStr();


    /**
    *Based on the property's name, load required stuff
    */
    if (property_name == FbxSurfaceMaterial::sDiffuse)
    {



        /**
         *Get the diffuse color and intensity
         */
        FbxDouble3 diffuse_color = property.Get<FbxDouble3>();
        FbxDouble diffuse_intensity = factor_property.Get<FbxDouble>();



        /**
         *Set diffuse color and intensity
         */
        SetDiffuseColor(aae::mesh_util::QVector3DFromFbxVector3D(diffuse_color));
        SetDiffuseIntensity(diffuse_intensity);




        /**
        *If there are no textures attached to the property, return
        */
        if(!property.GetSrcObjectCount<FbxFileTexture>() > 0)
            return;



        /**
         *Get the texture handler
         */
        FbxFileTexture * texture = property.GetSrcObject<FbxFileTexture>();
        if (!texture)
            return;



        /**
        *Add the diffuse texture name of the material
        */
        AddTexture(diffuse, texture->GetFileName());


    }
    else if (property_name == FbxSurfaceMaterial::sNormalMap)
    {


        /**
        *If there are no textures attached to the property, return
        */
        if(!property.GetSrcObjectCount<FbxFileTexture>() > 0)
            return;


        /**
         *Get the texture handler
         */
        FbxFileTexture * texture = property.GetSrcObject<FbxFileTexture>();
        if (!texture)
            return;


        /**
        *Set normal map texture of the material
        */
        AddTexture(normal, texture->GetFileName());


    }
    else if (property_name == FbxSurfaceMaterial::sSpecular)
    {


        /**
         *Get the specular color and intensity
         */
        FbxDouble3 specular_color = property.Get<FbxDouble3>();
        FbxDouble specular_intensity = factor_property.Get<FbxDouble>();



        /**
        *Set the specular color and intensity
        */
        SetSpecularColor(aae::mesh_util::QVector3DFromFbxVector3D(specular_color));
        SetSpecularIntensity(specular_intensity);



    }
    else if (property_name == FbxSurfaceMaterial::sShininess)
    {


        /**
         *Get and set specular hardness
         */
        FbxDouble specular_hardness = property.Get<FbxDouble>();
        SetSpecularHardness(specular_hardness);


    }





}
Esempio n. 17
0
StateSetContent
FbxMaterialToOsgStateSet::convert(const FbxSurfaceMaterial* pFbxMat)
{
    FbxMaterialMap::const_iterator it = _fbxMaterialMap.find(pFbxMat);
    if (it != _fbxMaterialMap.end())
        return it->second;

    osg::ref_ptr<osg::Material> pOsgMat = new osg::Material;
    pOsgMat->setName(pFbxMat->GetName());

    StateSetContent result;

    result.material = pOsgMat;

    FbxString shadingModel = pFbxMat->ShadingModel.Get();

    const FbxSurfaceLambert* pFbxLambert = FbxCast<FbxSurfaceLambert>(pFbxMat);

    // diffuse map...
    const FbxProperty lProperty = pFbxMat->FindProperty(FbxSurfaceMaterial::sDiffuse);
    if (lProperty.IsValid())
    {
        int lNbTex = lProperty.GetSrcObjectCount<FbxFileTexture>();
        for (int lTextureIndex = 0; lTextureIndex < lNbTex; lTextureIndex++)
        {
            FbxFileTexture* lTexture = FbxCast<FbxFileTexture>(lProperty.GetSrcObject<FbxFileTexture>(lTextureIndex));
            if (lTexture)
            {
                result.diffuseTexture = fbxTextureToOsgTexture(lTexture);
                result.diffuseChannel = lTexture->UVSet.Get();
                result.diffuseScaleU = lTexture->GetScaleU();
                result.diffuseScaleV = lTexture->GetScaleV();
            }

            //For now only allow 1 texture
            break;
        }
    }

    double transparencyColorFactor = 1.0;
    bool useTransparencyColorFactor = false;

    // opacity map...
    const FbxProperty lOpacityProperty = pFbxMat->FindProperty(FbxSurfaceMaterial::sTransparentColor);
    if (lOpacityProperty.IsValid())
    {
        FbxDouble3 transparentColor = lOpacityProperty.Get<FbxDouble3>();
        // If transparent color is defined set the transparentFactor to gray scale value of transparentColor
        if (transparentColor[0] < 1.0 || transparentColor[1] < 1.0 || transparentColor[2] < 1.0) {
            transparencyColorFactor = transparentColor[0]*0.30 + transparentColor[1]*0.59 + transparentColor[2]*0.11;
            useTransparencyColorFactor = true;
        }         

        int lNbTex = lOpacityProperty.GetSrcObjectCount<FbxFileTexture>();
        for (int lTextureIndex = 0; lTextureIndex < lNbTex; lTextureIndex++)
        {
            FbxFileTexture* lTexture = FbxCast<FbxFileTexture>(lOpacityProperty.GetSrcObject<FbxFileTexture>(lTextureIndex));
            if (lTexture)
            {
                // TODO: if texture image does NOT have an alpha channel, should it be added?

                result.opacityTexture = fbxTextureToOsgTexture(lTexture);
                result.opacityChannel = lTexture->UVSet.Get();
                result.opacityScaleU = lTexture->GetScaleU();
                result.opacityScaleV = lTexture->GetScaleV();
            }

            //For now only allow 1 texture
            break;
        }
    }

    // reflection map...
    const FbxProperty lReflectionProperty = pFbxMat->FindProperty(FbxSurfaceMaterial::sReflection);
    if (lReflectionProperty.IsValid())
    {
        int lNbTex = lReflectionProperty.GetSrcObjectCount<FbxFileTexture>();
        for (int lTextureIndex = 0; lTextureIndex < lNbTex; lTextureIndex++)
        {
            FbxFileTexture* lTexture = FbxCast<FbxFileTexture>(lReflectionProperty.GetSrcObject<FbxFileTexture>(lTextureIndex));
            if (lTexture)
            {
                // support only spherical reflection maps...
                if (FbxFileTexture::eUMT_ENVIRONMENT == lTexture->CurrentMappingType.Get())
                {
                    result.reflectionTexture = fbxTextureToOsgTexture(lTexture);
                    result.reflectionChannel = lTexture->UVSet.Get();
                }
            }

            //For now only allow 1 texture
            break;
        }
    }

    // emissive map...
    const FbxProperty lEmissiveProperty = pFbxMat->FindProperty(FbxSurfaceMaterial::sEmissive);
    if (lEmissiveProperty.IsValid())
    {
        int lNbTex = lEmissiveProperty.GetSrcObjectCount<FbxFileTexture>();
        for (int lTextureIndex = 0; lTextureIndex < lNbTex; lTextureIndex++)
        {
            FbxFileTexture* lTexture = FbxCast<FbxFileTexture>(lEmissiveProperty.GetSrcObject<FbxFileTexture>(lTextureIndex));
            if (lTexture)
            {
                result.emissiveTexture = fbxTextureToOsgTexture(lTexture);
                result.emissiveChannel = lTexture->UVSet.Get();
                result.emissiveScaleU = lTexture->GetScaleU();
                result.emissiveScaleV = lTexture->GetScaleV();
            }

            //For now only allow 1 texture
            break;
        }
    }

    // ambient map...
    const FbxProperty lAmbientProperty = pFbxMat->FindProperty(FbxSurfaceMaterial::sAmbient);
    if (lAmbientProperty.IsValid())
    {
        int lNbTex = lAmbientProperty.GetSrcObjectCount<FbxFileTexture>();
        for (int lTextureIndex = 0; lTextureIndex < lNbTex; lTextureIndex++)
        {
            FbxFileTexture* lTexture = FbxCast<FbxFileTexture>(lAmbientProperty.GetSrcObject<FbxFileTexture>(lTextureIndex));
            if (lTexture)
            {
                result.ambientTexture = fbxTextureToOsgTexture(lTexture);
                result.ambientChannel = lTexture->UVSet.Get();
                result.ambientScaleU = lTexture->GetScaleU();
                result.ambientScaleV = lTexture->GetScaleV();
            }

            //For now only allow 1 texture
            break;
        }
    }

    if (pFbxLambert)
    {
        FbxDouble3 color = pFbxLambert->Diffuse.Get();
        double factor = pFbxLambert->DiffuseFactor.Get();
        double transparencyFactor = useTransparencyColorFactor ? transparencyColorFactor : pFbxLambert->TransparencyFactor.Get();
        pOsgMat->setDiffuse(osg::Material::FRONT_AND_BACK, osg::Vec4(
            static_cast<float>(color[0] * factor),
            static_cast<float>(color[1] * factor),
            static_cast<float>(color[2] * factor),
            static_cast<float>(1.0 - transparencyFactor)));

        color = pFbxLambert->Ambient.Get();
        factor = pFbxLambert->AmbientFactor.Get();
        pOsgMat->setAmbient(osg::Material::FRONT_AND_BACK, osg::Vec4(
            static_cast<float>(color[0] * factor),
            static_cast<float>(color[1] * factor),
            static_cast<float>(color[2] * factor),
            1.0f));

        color = pFbxLambert->Emissive.Get();
        factor = pFbxLambert->EmissiveFactor.Get();
        pOsgMat->setEmission(osg::Material::FRONT_AND_BACK, osg::Vec4(
            static_cast<float>(color[0] * factor),
            static_cast<float>(color[1] * factor),
            static_cast<float>(color[2] * factor),
            1.0f));

        // get maps factors...
        result.diffuseFactor = pFbxLambert->DiffuseFactor.Get();

        if (const FbxSurfacePhong* pFbxPhong = FbxCast<FbxSurfacePhong>(pFbxLambert))
        {
            color = pFbxPhong->Specular.Get();
            factor = pFbxPhong->SpecularFactor.Get();
            pOsgMat->setSpecular(osg::Material::FRONT_AND_BACK, osg::Vec4(
                static_cast<float>(color[0] * factor),
                static_cast<float>(color[1] * factor),
                static_cast<float>(color[2] * factor),
                1.0f));
            // Since Maya and 3D studio Max stores their glossiness values in exponential format (2^(log2(x)) 
            // We need to linearize to values between 0-100 and then scale to values between 0-128.
            // Glossiness values above 100 will result in shininess larger than 128.0 and will be clamped
            double shininess = (64.0 * log (pFbxPhong->Shininess.Get())) / (5.0 * log(2.0));
            pOsgMat->setShininess(osg::Material::FRONT_AND_BACK,
                static_cast<float>(shininess));

            // get maps factors...
            result.reflectionFactor = pFbxPhong->ReflectionFactor.Get();
            // get more factors here...
        }
    }

    if (_lightmapTextures)
    {
        // if using an emission map then adjust material properties accordingly...
        if (result.emissiveTexture)
        {
            osg::Vec4 diffuse = pOsgMat->getDiffuse(osg::Material::FRONT_AND_BACK);
            pOsgMat->setEmission(osg::Material::FRONT_AND_BACK, diffuse);
            pOsgMat->setDiffuse(osg::Material::FRONT_AND_BACK, osg::Vec4(0,0,0,diffuse.a()));
            pOsgMat->setAmbient(osg::Material::FRONT_AND_BACK, osg::Vec4(0,0,0,diffuse.a()));
        }
    }

    _fbxMaterialMap.insert(FbxMaterialMap::value_type(pFbxMat, result));
    return result;
}
void 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
}
Esempio n. 19
0
bool UnFbx::FFbxImporter::ImportAnimation(USkeleton* Skeleton, UAnimSequence * DestSeq, const FString& FileName, TArray<FbxNode*>& SortedLinks, TArray<FbxNode*>& NodeArray, FbxAnimStack* CurAnimStack, const int32 ResampleRate, const FbxTimeSpan AnimTimeSpan)
{
	// @todo : the length might need to change w.r.t. sampling keys
	FbxTime SequenceLength = AnimTimeSpan.GetDuration();
	float PreviousSequenceLength = DestSeq->SequenceLength;

	// if you have one pose(thus 0.f duration), it still contains animation, so we'll need to consider that as MINIMUM_ANIMATION_LENGTH time length
	DestSeq->SequenceLength = FGenericPlatformMath::Max<float>(SequenceLength.GetSecondDouble(), MINIMUM_ANIMATION_LENGTH);

	if(PreviousSequenceLength > MINIMUM_ANIMATION_LENGTH && DestSeq->RawCurveData.FloatCurves.Num() > 0)
	{
		// The sequence already existed when we began the import. We need to scale the key times for all curves to match the new 
		// duration before importing over them. This is to catch any user-added curves
		float ScaleFactor = DestSeq->SequenceLength / PreviousSequenceLength;
		for(FFloatCurve& Curve : DestSeq->RawCurveData.FloatCurves)
		{
			Curve.FloatCurve.ScaleCurve(0.0f, ScaleFactor);
		}
	}

	if (ImportOptions->bDeleteExistingMorphTargetCurves)
	{
		for (int32 CurveIdx=0; CurveIdx<DestSeq->RawCurveData.FloatCurves.Num(); ++CurveIdx)
		{
			auto& Curve = DestSeq->RawCurveData.FloatCurves[CurveIdx];
			if (Curve.GetCurveTypeFlag(ACF_DrivesMorphTarget))
			{
				DestSeq->RawCurveData.FloatCurves.RemoveAt(CurveIdx, 1, false);
				--CurveIdx;
			}
		}

		DestSeq->RawCurveData.FloatCurves.Shrink();
	}

	//
	// import blend shape curves
	//
	{
		GWarn->BeginSlowTask( LOCTEXT("BeginImportMorphTargetCurves", "Importing Morph Target Curves"), true);
		for ( int32 NodeIndex = 0; NodeIndex < NodeArray.Num(); NodeIndex++ )
		{
			// consider blendshape animation curve
			FbxGeometry* Geometry = (FbxGeometry*)NodeArray[NodeIndex]->GetNodeAttribute();
			if (Geometry)
			{
				int32 BlendShapeDeformerCount = Geometry->GetDeformerCount(FbxDeformer::eBlendShape);
				for(int32 BlendShapeIndex = 0; BlendShapeIndex<BlendShapeDeformerCount; ++BlendShapeIndex)
				{
					FbxBlendShape* BlendShape = (FbxBlendShape*)Geometry->GetDeformer(BlendShapeIndex, FbxDeformer::eBlendShape);

					const int32 BlendShapeChannelCount = BlendShape->GetBlendShapeChannelCount();

					FString BlendShapeName = UTF8_TO_TCHAR(MakeName(BlendShape->GetName()));

					for(int32 ChannelIndex = 0; ChannelIndex<BlendShapeChannelCount; ++ChannelIndex)
					{
						FbxBlendShapeChannel* Channel = BlendShape->GetBlendShapeChannel(ChannelIndex);

						if(Channel)
						{
							FString ChannelName = UTF8_TO_TCHAR(MakeName(Channel->GetName()));

							// Maya adds the name of the blendshape and an underscore to the front of the channel name, so remove it
							if(ChannelName.StartsWith(BlendShapeName))
							{
								ChannelName = ChannelName.Right(ChannelName.Len() - (BlendShapeName.Len()+1));
							}

							FbxAnimCurve* Curve = Geometry->GetShapeChannel(BlendShapeIndex, ChannelIndex, (FbxAnimLayer*)CurAnimStack->GetMember(0));
							if (Curve && Curve->KeyGetCount() > 0)
							{
								FFormatNamedArguments Args;
								Args.Add(TEXT("BlendShape"), FText::FromString(ChannelName));
								const FText StatusUpate = FText::Format(LOCTEXT("ImportingMorphTargetCurvesDetail", "Importing Morph Target Curves [{BlendShape}]"), Args);
								GWarn->StatusUpdate(NodeIndex + 1, NodeArray.Num(), StatusUpate);
								// now see if we have one already exists. If so, just overwrite that. if not, add new one. 
								ImportCurveToAnimSequence(DestSeq, *ChannelName, Curve,  ACF_DrivesMorphTarget | ACF_TriggerEvent, AnimTimeSpan, 0.01f /** for some reason blend shape values are coming as 100 scaled **/);
							}
						}
					}
				}
			}
		}
		GWarn->EndSlowTask();
	}

	// 
	// importing custom attribute START
	//
	if (ImportOptions->bImportCustomAttribute)
	{
		GWarn->BeginSlowTask( LOCTEXT("BeginImportMorphTargetCurves", "Importing Custom Attirubte Curves"), true);
		const int32 TotalLinks = SortedLinks.Num();
		int32 CurLinkIndex=0;
		for(auto Node: SortedLinks)
		{
			FbxProperty Property = Node->GetFirstProperty();
			while (Property.IsValid())
			{
				FbxAnimCurveNode* CurveNode = Property.GetCurveNode();
				// do this if user defined and animated and leaf node
				if( CurveNode && Property.GetFlag(FbxPropertyAttr::eUserDefined) && 
					CurveNode->IsAnimated() && IsSupportedCurveDataType(Property.GetPropertyDataType().GetType()) )
				{
					FString CurveName = UTF8_TO_TCHAR(CurveNode->GetName());
					UE_LOG(LogFbx, Log, TEXT("CurveName : %s"), *CurveName );

					int32 TotalCount = CurveNode->GetChannelsCount();
					for (int32 ChannelIndex=0; ChannelIndex<TotalCount; ++ChannelIndex)
					{
						FbxAnimCurve * AnimCurve = CurveNode->GetCurve(ChannelIndex);
						FString ChannelName = CurveNode->GetChannelName(ChannelIndex).Buffer();

						if (AnimCurve)
						{
							FString FinalCurveName;
							if (TotalCount == 1)
							{
								FinalCurveName = CurveName;
							}
							else
							{
								FinalCurveName = CurveName + "_" + ChannelName;
							}

							FFormatNamedArguments Args;
							Args.Add(TEXT("CurveName"), FText::FromString(FinalCurveName));
							const FText StatusUpate = FText::Format(LOCTEXT("ImportingCustomAttributeCurvesDetail", "Importing Custom Attribute [{CurveName}]"), Args);
							GWarn->StatusUpdate(CurLinkIndex + 1, TotalLinks, StatusUpate);

							ImportCurveToAnimSequence(DestSeq, FinalCurveName, AnimCurve,  ACF_DefaultCurve, AnimTimeSpan);
						}
											
					}
				}

				Property = Node->GetNextProperty(Property); 
			}

			CurLinkIndex++;
		}

		GWarn->EndSlowTask();
	}

	// importing custom attribute END

	const bool bSourceDataExists = (DestSeq->SourceRawAnimationData.Num() > 0);
	TArray<AnimationTransformDebug::FAnimationTransformDebugData> TransformDebugData;
	int32 TotalNumKeys = 0;
	const FReferenceSkeleton& RefSkeleton = Skeleton->GetReferenceSkeleton();

	// import animation
	{
		GWarn->BeginSlowTask( LOCTEXT("BeginImportAnimation", "Importing Animation"), true);

		TArray<struct FRawAnimSequenceTrack>& RawAnimationData = bSourceDataExists? DestSeq->SourceRawAnimationData : DestSeq->RawAnimationData;
		DestSeq->TrackToSkeletonMapTable.Empty();
		DestSeq->AnimationTrackNames.Empty();
		RawAnimationData.Empty();

		TArray<FName> FbxRawBoneNames;
		FillAndVerifyBoneNames(Skeleton, SortedLinks, FbxRawBoneNames, FileName);

		UnFbx::FFbxImporter* FbxImporter = UnFbx::FFbxImporter::GetInstance();

		const bool bPreserveLocalTransform = FbxImporter->GetImportOptions()->bPreserveLocalTransform;

		// Build additional transform matrix
		UFbxAnimSequenceImportData* TemplateData = Cast<UFbxAnimSequenceImportData>(DestSeq->AssetImportData);
		FbxAMatrix FbxAddedMatrix;
		BuildFbxMatrixForImportTransform(FbxAddedMatrix, TemplateData);
		FMatrix AddedMatrix = Converter.ConvertMatrix(FbxAddedMatrix);

		const int32 NumSamplingKeys = FMath::FloorToInt(AnimTimeSpan.GetDuration().GetSecondDouble() * ResampleRate);
		const FbxTime TimeIncrement = (NumSamplingKeys > 1)? AnimTimeSpan.GetDuration() / (NumSamplingKeys - 1) : AnimTimeSpan.GetDuration();
		for(int32 SourceTrackIdx = 0; SourceTrackIdx < FbxRawBoneNames.Num(); ++SourceTrackIdx)
		{
			int32 NumKeysForTrack = 0;

			// see if it's found in Skeleton
			FName BoneName = FbxRawBoneNames[SourceTrackIdx];
			int32 BoneTreeIndex = RefSkeleton.FindBoneIndex(BoneName);

			// update status
			FFormatNamedArguments Args;
			Args.Add(TEXT("TrackName"), FText::FromName(BoneName));
			Args.Add(TEXT("TotalKey"), FText::AsNumber(NumSamplingKeys));
			Args.Add(TEXT("TrackIndex"), FText::AsNumber(SourceTrackIdx+1));
			Args.Add(TEXT("TotalTracks"), FText::AsNumber(FbxRawBoneNames.Num()));
			const FText StatusUpate = FText::Format(LOCTEXT("ImportingAnimTrackDetail", "Importing Animation Track [{TrackName}] ({TrackIndex}/{TotalTracks}) - TotalKey {TotalKey}"), Args);
			GWarn->StatusForceUpdate(SourceTrackIdx + 1, FbxRawBoneNames.Num(), StatusUpate);

			if (BoneTreeIndex!=INDEX_NONE)
			{
				bool bSuccess = true;

				FRawAnimSequenceTrack RawTrack;
				RawTrack.PosKeys.Empty();
				RawTrack.RotKeys.Empty();
				RawTrack.ScaleKeys.Empty();

				AnimationTransformDebug::FAnimationTransformDebugData NewDebugData;

				FbxNode* Link = SortedLinks[SourceTrackIdx];
				FbxNode * LinkParent = Link->GetParent();
			
				for(FbxTime CurTime = AnimTimeSpan.GetStart(); CurTime <= AnimTimeSpan.GetStop(); CurTime += TimeIncrement)
				{
					// save global trasnform
					FbxAMatrix GlobalMatrix = Link->EvaluateGlobalTransform(CurTime);
					// we'd like to verify this before going to Transform. 
					// currently transform has tons of NaN check, so it will crash there
					FMatrix GlobalUEMatrix = Converter.ConvertMatrix(GlobalMatrix);
					if (GlobalUEMatrix.ContainsNaN())
					{
						bSuccess = false;
						AddTokenizedErrorMessage(FTokenizedMessage::Create(EMessageSeverity::Error, FText::Format(LOCTEXT("Error_InvalidTransform",
							"Track {0} contains invalid transform. Could not import the track."), FText::FromName(BoneName))), FFbxErrors::Animation_TransformError);
						break;
					}

					FTransform GlobalTransform =  Converter.ConvertTransform(GlobalMatrix);
					if (GlobalTransform.ContainsNaN())
					{
						bSuccess = false;
						AddTokenizedErrorMessage(FTokenizedMessage::Create(EMessageSeverity::Error, FText::Format(LOCTEXT("Error_InvalidUnrealTransform",
											"Track {0} did not yeild valid transform. Please report this to animation team."), FText::FromName(BoneName))), FFbxErrors::Animation_TransformError);
						break;
					}

					// debug data, including import transformation
					FTransform AddedTransform(AddedMatrix);
					NewDebugData.SourceGlobalTransform.Add(GlobalTransform * AddedTransform);

					FTransform LocalTransform;
					if( !bPreserveLocalTransform && LinkParent)
					{
						// I can't rely on LocalMatrix. I need to recalculate quaternion/scale based on global transform if Parent exists
						FbxAMatrix ParentGlobalMatrix = Link->GetParent()->EvaluateGlobalTransform(CurTime);
						FTransform ParentGlobalTransform =  Converter.ConvertTransform(ParentGlobalMatrix);

						LocalTransform = GlobalTransform.GetRelativeTransform(ParentGlobalTransform);
						NewDebugData.SourceParentGlobalTransform.Add(ParentGlobalTransform);
					} 
					else
					{
						FbxAMatrix& LocalMatrix = Link->EvaluateLocalTransform(CurTime); 
						FbxVector4 NewLocalT = LocalMatrix.GetT();
						FbxVector4 NewLocalS = LocalMatrix.GetS();
						FbxQuaternion NewLocalQ = LocalMatrix.GetQ();

						LocalTransform.SetTranslation(Converter.ConvertPos(NewLocalT));
						LocalTransform.SetScale3D(Converter.ConvertScale(NewLocalS));
						LocalTransform.SetRotation(Converter.ConvertRotToQuat(NewLocalQ));

						NewDebugData.SourceParentGlobalTransform.Add(FTransform::Identity);
					}

					if(TemplateData && BoneTreeIndex == 0)
					{
						// If we found template data earlier, apply the import transform matrix to
						// the root track.
						LocalTransform.SetFromMatrix(LocalTransform.ToMatrixWithScale() * AddedMatrix);
					}

					if (LocalTransform.ContainsNaN())
					{
						bSuccess = false;
						AddTokenizedErrorMessage(FTokenizedMessage::Create(EMessageSeverity::Error, FText::Format(LOCTEXT("Error_InvalidUnrealLocalTransform",
											"Track {0} did not yeild valid local transform. Please report this to animation team."), FText::FromName(BoneName))), FFbxErrors::Animation_TransformError);
						break;
					}

					RawTrack.ScaleKeys.Add(LocalTransform.GetScale3D());
					RawTrack.PosKeys.Add(LocalTransform.GetTranslation());
					RawTrack.RotKeys.Add(LocalTransform.GetRotation());

					NewDebugData.RecalculatedLocalTransform.Add(LocalTransform);
					++NumKeysForTrack;
				}

				if (bSuccess)
				{
					//add new track
					int32 NewTrackIdx = RawAnimationData.Add(RawTrack);
					DestSeq->AnimationTrackNames.Add(BoneName);

					NewDebugData.SetTrackData(NewTrackIdx, BoneTreeIndex, BoneName);

					// add mapping to skeleton bone track
					DestSeq->TrackToSkeletonMapTable.Add(FTrackToSkeletonMap(BoneTreeIndex));
					TransformDebugData.Add(NewDebugData);
				}
			}

			TotalNumKeys = FMath::Max( TotalNumKeys, NumKeysForTrack );
		}

		DestSeq->NumFrames = TotalNumKeys;
		GWarn->EndSlowTask();
	}

	// compress animation
	{
		GWarn->BeginSlowTask( LOCTEXT("BeginCompressAnimation", "Compress Animation"), true);
		GWarn->StatusForceUpdate(1, 1, LOCTEXT("CompressAnimation", "Compressing Animation"));
		// if source data exists, you should bake it to Raw to apply
		if(bSourceDataExists)
		{
			DestSeq->BakeTrackCurvesToRawAnimation();
		}
		else
		{
			// otherwise just compress
			DestSeq->PostProcessSequence();
		}

		// run debug mode
		AnimationTransformDebug::OutputAnimationTransformDebugData(TransformDebugData, TotalNumKeys, RefSkeleton);
		GWarn->EndSlowTask();
	}

	return true;
}
Esempio n. 20
0
void Resource::FBX::FBXMaterial::InitMaterial(const FbxSurfaceMaterial *pFbxMaterial, Resource::ResourceManager& rm) {
//	Logger::Debug(pFbxMaterial->GetName());

	Render::MaterialElement& material = AddElement();

	const FbxImplementation *lImplementation = pFbxMaterial->GetDefaultImplementation();
	FbxPropertyT<FbxDouble3> lKFbxDouble3;
	FbxPropertyT<FbxDouble> lKFbxDouble1;
	FbxColor theColor;

	if(lImplementation){
		const FbxBindingTable *lTable = lImplementation->GetRootTable();
		size_t lEntryNum = lTable->GetEntryCount();

		for (int i = 0; i < (int) lEntryNum; ++i) {
			const FbxBindingTableEntry &lEntry = lTable->GetEntry(i);
			const char *lEntrySrcType = lEntry.GetEntryType(true);
			FbxProperty lFbxProp;


			FbxString lTest = lEntry.GetSource();
			FBXSDK_printf("            Entry: %s\n", lTest.Buffer());


			if (strcmp(FbxPropertyEntryView::sEntryType, lEntrySrcType) == 0) {
				lFbxProp = pFbxMaterial->FindPropertyHierarchical(lEntry.GetSource());
				if (!lFbxProp.IsValid()) {
					lFbxProp = pFbxMaterial->RootProperty.FindHierarchical(lEntry.GetSource());
				}


			}
			else if (strcmp(FbxConstantEntryView::sEntryType, lEntrySrcType) == 0) {
				lFbxProp = lImplementation->GetConstants().FindHierarchical(lEntry.GetSource());
			}
		}
	}
	else if (pFbxMaterial->GetClassId().Is(FbxSurfacePhong::ClassId))
	{
		// We found a Phong material.  Display its properties.

		// Display the Ambient Color
		lKFbxDouble3 =((FbxSurfacePhong *) pFbxMaterial)->Ambient;
		theColor.Set(lKFbxDouble3.Get()[0], lKFbxDouble3.Get()[1], lKFbxDouble3.Get()[2]);

		// Display the Diffuse Color
		lKFbxDouble3 =((FbxSurfacePhong *) pFbxMaterial)->Diffuse;
		theColor.Set(lKFbxDouble3.Get()[0], lKFbxDouble3.Get()[1], lKFbxDouble3.Get()[2]);

		// Display the Specular Color (unique to Phong materials)
		lKFbxDouble3 =((FbxSurfacePhong *) pFbxMaterial)->Specular;
		theColor.Set(lKFbxDouble3.Get()[0], lKFbxDouble3.Get()[1], lKFbxDouble3.Get()[2]);

		// Display the Emissive Color
		lKFbxDouble3 =((FbxSurfacePhong *) pFbxMaterial)->Emissive;
		theColor.Set(lKFbxDouble3.Get()[0], lKFbxDouble3.Get()[1], lKFbxDouble3.Get()[2]);

		//Opacity is Transparency factor now
		lKFbxDouble1 =((FbxSurfacePhong *) pFbxMaterial)->TransparencyFactor;

		// Display the Shininess
		lKFbxDouble1 =((FbxSurfacePhong *) pFbxMaterial)->Shininess;
		double dShininess = lKFbxDouble1.Get();

		lKFbxDouble1 =((FbxSurfacePhong *) pFbxMaterial)->Specular;
		double dSpecular = lKFbxDouble1.Get();

		lKFbxDouble1 =((FbxSurfacePhong *) pFbxMaterial)->SpecularFactor;
		double dSpecularFactor = lKFbxDouble1.Get();

		material.m_fShininess = dShininess;
		material.m_fSpecular = dSpecular * dSpecularFactor;

		// Display the Reflectivity
		lKFbxDouble1 =((FbxSurfacePhong *) pFbxMaterial)->ReflectionFactor;
		material.m_fReflectionFactor = lKFbxDouble1.Get();
	}
	else if(pFbxMaterial->GetClassId().Is(FbxSurfaceLambert::ClassId) )
	{
		// We found a Lambert material. Display its properties.
		// Display the Ambient Color
		lKFbxDouble3=((FbxSurfaceLambert *)pFbxMaterial)->Ambient;
		theColor.Set(lKFbxDouble3.Get()[0], lKFbxDouble3.Get()[1], lKFbxDouble3.Get()[2]);

		// Display the Diffuse Color
		lKFbxDouble3 =((FbxSurfaceLambert *)pFbxMaterial)->Diffuse;
		theColor.Set(lKFbxDouble3.Get()[0], lKFbxDouble3.Get()[1], lKFbxDouble3.Get()[2]);

		// Display the Emissive
		lKFbxDouble3 =((FbxSurfaceLambert *)pFbxMaterial)->Emissive;
		theColor.Set(lKFbxDouble3.Get()[0], lKFbxDouble3.Get()[1], lKFbxDouble3.Get()[2]);

		// Display the Opacity
		lKFbxDouble1 =((FbxSurfaceLambert *)pFbxMaterial)->TransparencyFactor;
	}
	else
		Logger::Debug("Unknown type of Material");



	FbxProperty prop = pFbxMaterial->FindProperty(FbxSurfaceMaterial::sDiffuse);
	// Check if it's layeredtextures
	int layeredTextureCount = prop.GetSrcObjectCount<FbxLayeredTexture>();
	for (int j = 0; j < layeredTextureCount; j++)
	{
		FbxLayeredTexture* layered_texture = FbxCast<FbxLayeredTexture>(prop.GetSrcObject<FbxLayeredTexture>(j));
		int lcount = layered_texture->GetSrcObjectCount<FbxFileTexture>();

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

			material.AddTexture(rm.LoadImageFromFile(textureName));
		}
	}

	int textureCount = prop.GetSrcObjectCount<FbxFileTexture>();
	for(int i=0; i<textureCount; ++i){
		FbxFileTexture* texture = FbxCast<FbxFileTexture>(prop.GetSrcObject<FbxFileTexture>(i));
		const char* textureName = texture->GetFileName();

		material.AddTexture(rm.LoadImageFromFile(textureName));
	}

	FbxPropertyT<FbxString> lString;
	lString = pFbxMaterial->ShadingModel;
}
Esempio n. 21
0
//===============================================================================================================================
void FBXLoader::LoadMaterialTexture(FbxSurfaceMaterial* inMaterial, ZShadeSandboxLighting::ShaderMaterial*& ioMaterial)
{
	uint32 textureIndex = 0;
	FbxProperty property;
	
	FBXSDK_FOR_EACH_TEXTURE(textureIndex)
	{
		property = inMaterial->FindProperty(FbxLayerElement::sTextureChannelNames[textureIndex]);
		if (property.IsValid())
		{
			uint32 textureCount = property.GetSrcObjectCount<FbxTexture>();
			for (uint32 i = 0; i < textureCount; ++i)
			{
				FbxLayeredTexture* layeredTexture = property.GetSrcObject<FbxLayeredTexture>(i);
				if(layeredTexture)
				{
					throw std::exception("Layered Texture is currently unsupported\n");
				}
				else
				{
					FbxTexture* texture = property.GetSrcObject<FbxTexture>(i);
					if (texture)
					{
						std::string textureType = property.GetNameAsCStr();
						FbxFileTexture* fileTexture = FbxCast<FbxFileTexture>(texture);

						if (fileTexture)
						{
							string str_filename(fileTexture->GetFileName());
							std::size_t index = str_filename.find_last_of('/\\');
							if (index != string::npos)
							{
								BetterString str(fileTexture->GetFileName());
								int dot_index = str.get_index('.');
								BetterString pathName = str.substring(index + 1, dot_index);
								BetterString ext = str.substring(dot_index + 1);
								BetterString filename = pathName + "." + ext;
								str_filename = filename.toString();
							}

							if (textureType == "DiffuseColor")
							{
								ioMaterial->sDiffuseTextureName = str_filename;
								ioMaterial->bHasDiffuseTexture = true;
							}
							else if (textureType == "SpecularColor")
							{
								ioMaterial->sSpecularTextureName = str_filename;
								ioMaterial->bHasSpecularTexture = true;
							}
							else if (textureType == "Bump")
							{
								ioMaterial->sNormalMapTextureName = str_filename;
								ioMaterial->bHasNormalMapTexture = true;
							}
						}
					}
				}
			}
		}
	}
	
	ioMaterial->SetD3D(m_pD3DSystem);
	
	bool addToMM = false;
	
	if (ioMaterial->bHasDiffuseTexture)
	{
		ZShadeSandboxLighting::ShaderMaterial* material;
		if (material = MaterialManager::Instance()->GetMaterial(ioMaterial->sMaterialName))
		{
			// The texture has already been loaded
			ioMaterial->SetMaterialDiffuseTexture(material->DiffuseTexture());
		}
		else
		{
			// Need to load new texture
			ioMaterial->AddDiffuseTexture(m_pGD3D->m_textures_path, ioMaterial->sDiffuseTextureName);
			
			addToMM = true;
		}
	}
	
	if (ioMaterial->bHasSpecularTexture)
	{
		ZShadeSandboxLighting::ShaderMaterial* material;
		if (material = MaterialManager::Instance()->GetMaterial(ioMaterial->sMaterialName))
		{
			// The texture has already been loaded
			ioMaterial->SetMaterialSpecularTexture(material->SpecularTexture());
		}
		else
		{
			// Need to load new texture
			ioMaterial->AddDiffuseTexture(m_pGD3D->m_textures_path, ioMaterial->sSpecularTextureName);
			
			addToMM = true;
		}
	}
	
	if (ioMaterial->bHasNormalMapTexture)
	{
		ZShadeSandboxLighting::ShaderMaterial* material;
		if (material = MaterialManager::Instance()->GetMaterial(ioMaterial->sMaterialName))
		{
			// The texture has already been loaded
			ioMaterial->SetMaterialNormalMapTexture(material->NormalMapTexture());
		}
		else
		{
			// Need to load new texture
			ioMaterial->AddDiffuseTexture(m_pGD3D->m_textures_path, ioMaterial->sNormalMapTextureName);
			
			addToMM = true;
		}
	}
	
	if (addToMM)
	{
		MaterialManager::Instance()->Add(ioMaterial);
	}
}
StateSetContent
FbxMaterialToOsgStateSet::convert(const FbxSurfaceMaterial* pFbxMat)
{
    FbxMaterialMap::const_iterator it = _fbxMaterialMap.find(pFbxMat);
    if (it != _fbxMaterialMap.end())
        return it->second;

    osg::ref_ptr<osg::Material> pOsgMat = new osg::Material;
    pOsgMat->setName(pFbxMat->GetName());

    StateSetContent result;

    result.material = pOsgMat;

    FbxString shadingModel = pFbxMat->ShadingModel.Get();

    const FbxSurfaceLambert* pFbxLambert = FbxCast<FbxSurfaceLambert>(pFbxMat);

    // diffuse map...
    const FbxProperty lProperty = pFbxMat->FindProperty(FbxSurfaceMaterial::sDiffuse);
    if (lProperty.IsValid())
    {
        int lNbTex = lProperty.GetSrcObjectCount<FbxFileTexture>();
        for (int lTextureIndex = 0; lTextureIndex < lNbTex; lTextureIndex++)
        {
            FbxFileTexture* lTexture = FbxCast<FbxFileTexture>(lProperty.GetSrcObject<FbxFileTexture>(lTextureIndex));
            if (lTexture)
            {
                result.diffuseTexture = fbxTextureToOsgTexture(lTexture);
                result.diffuseChannel = lTexture->UVSet.Get();
                result.diffuseScaleU = lTexture->GetScaleU();
                result.diffuseScaleV = lTexture->GetScaleV();
            }

            //For now only allow 1 texture
            break;
        }
    }

    // opacity map...
    const FbxProperty lOpacityProperty = pFbxMat->FindProperty(FbxSurfaceMaterial::sTransparentColor);
    if (lOpacityProperty.IsValid())
    {
        int lNbTex = lOpacityProperty.GetSrcObjectCount<FbxFileTexture>();
        for (int lTextureIndex = 0; lTextureIndex < lNbTex; lTextureIndex++)
        {
            FbxFileTexture* lTexture = FbxCast<FbxFileTexture>(lOpacityProperty.GetSrcObject<FbxFileTexture>(lTextureIndex));
            if (lTexture)
            {
                // TODO: if texture image does NOT have an alpha channel, should it be added?

                result.opacityTexture = fbxTextureToOsgTexture(lTexture);
                result.opacityChannel = lTexture->UVSet.Get();
                result.opacityScaleU = lTexture->GetScaleU();
                result.opacityScaleV = lTexture->GetScaleV();
            }

            //For now only allow 1 texture
            break;
        }
    }

    // reflection map...
    const FbxProperty lReflectionProperty = pFbxMat->FindProperty(FbxSurfaceMaterial::sReflection);
    if (lReflectionProperty.IsValid())
    {
        int lNbTex = lReflectionProperty.GetSrcObjectCount<FbxFileTexture>();
        for (int lTextureIndex = 0; lTextureIndex < lNbTex; lTextureIndex++)
        {
            FbxFileTexture* lTexture = FbxCast<FbxFileTexture>(lReflectionProperty.GetSrcObject<FbxFileTexture>(lTextureIndex));
            if (lTexture)
            {
                // support only spherical reflection maps...
                if (FbxFileTexture::eUMT_ENVIRONMENT == lTexture->CurrentMappingType.Get())
                {
                    result.reflectionTexture = fbxTextureToOsgTexture(lTexture);
                    result.reflectionChannel = lTexture->UVSet.Get();
                }
            }

            //For now only allow 1 texture
            break;
        }
    }

    // emissive map...
    const FbxProperty lEmissiveProperty = pFbxMat->FindProperty(FbxSurfaceMaterial::sEmissive);
    if (lEmissiveProperty.IsValid())
    {
        int lNbTex = lEmissiveProperty.GetSrcObjectCount<FbxFileTexture>();
        for (int lTextureIndex = 0; lTextureIndex < lNbTex; lTextureIndex++)
        {
            FbxFileTexture* lTexture = FbxCast<FbxFileTexture>(lEmissiveProperty.GetSrcObject<FbxFileTexture>(lTextureIndex));
            if (lTexture)
            {
                result.emissiveTexture = fbxTextureToOsgTexture(lTexture);
                result.emissiveChannel = lTexture->UVSet.Get();
                result.emissiveScaleU = lTexture->GetScaleU();
                result.emissiveScaleV = lTexture->GetScaleV();
            }

            //For now only allow 1 texture
            break;
        }
    }

    if (pFbxLambert)
    {
        FbxDouble3 color = pFbxLambert->Diffuse.Get();
        double factor = pFbxLambert->DiffuseFactor.Get();
        pOsgMat->setDiffuse(osg::Material::FRONT_AND_BACK, osg::Vec4(
            static_cast<float>(color[0] * factor),
            static_cast<float>(color[1] * factor),
            static_cast<float>(color[2] * factor),
            static_cast<float>(1.0 - pFbxLambert->TransparencyFactor.Get())));

        color = pFbxLambert->Ambient.Get();
        factor = pFbxLambert->AmbientFactor.Get();
        pOsgMat->setAmbient(osg::Material::FRONT_AND_BACK, osg::Vec4(
            static_cast<float>(color[0] * factor),
            static_cast<float>(color[1] * factor),
            static_cast<float>(color[2] * factor),
            1.0f));

        color = pFbxLambert->Emissive.Get();
        factor = pFbxLambert->EmissiveFactor.Get();
        pOsgMat->setEmission(osg::Material::FRONT_AND_BACK, osg::Vec4(
            static_cast<float>(color[0] * factor),
            static_cast<float>(color[1] * factor),
            static_cast<float>(color[2] * factor),
            1.0f));

        // get maps factors...
        result.diffuseFactor = pFbxLambert->DiffuseFactor.Get();

        if (const FbxSurfacePhong* pFbxPhong = FbxCast<FbxSurfacePhong>(pFbxLambert))
        {
            color = pFbxPhong->Specular.Get();
            factor = pFbxPhong->SpecularFactor.Get();
            pOsgMat->setSpecular(osg::Material::FRONT_AND_BACK, osg::Vec4(
                static_cast<float>(color[0] * factor),
                static_cast<float>(color[1] * factor),
                static_cast<float>(color[2] * factor),
                1.0f));

            pOsgMat->setShininess(osg::Material::FRONT_AND_BACK,
                static_cast<float>(pFbxPhong->Shininess.Get()));

            // get maps factors...
            result.reflectionFactor = pFbxPhong->ReflectionFactor.Get();
            // get more factors here...
        }
    }

    if (_lightmapTextures)
    {
        // if using an emission map then adjust material properties accordingly...
        if (result.emissiveTexture)
        {
            osg::Vec4 diffuse = pOsgMat->getDiffuse(osg::Material::FRONT_AND_BACK);
            pOsgMat->setEmission(osg::Material::FRONT_AND_BACK, diffuse);
            pOsgMat->setDiffuse(osg::Material::FRONT_AND_BACK, osg::Vec4(0,0,0,diffuse.a()));
            pOsgMat->setAmbient(osg::Material::FRONT_AND_BACK, osg::Vec4(0,0,0,diffuse.a()));
        }
    }

    _fbxMaterialMap.insert(FbxMaterialMap::value_type(pFbxMat, result));
    return result;
}
Esempio n. 23
0
FbxDouble3 CFBXLoader::GetMaterialProperty(
		const FbxSurfaceMaterial * pMaterial,
		const char * pPropertyName,
        const char * pFactorPropertyName,
        FBX_MATRIAL_ELEMENT*			pElement)
{
	pElement->type = FBX_MATRIAL_ELEMENT::ELEMENT_NONE;

    FbxDouble3 lResult(0, 0, 0);
    const FbxProperty lProperty = pMaterial->FindProperty(pPropertyName);
    const FbxProperty lFactorProperty = pMaterial->FindProperty(pFactorPropertyName);
    if (lProperty.IsValid() && lFactorProperty.IsValid())
    {
        lResult = lProperty.Get<FbxDouble3>();
        double lFactor = lFactorProperty.Get<FbxDouble>();
        if (lFactor != 1)
        {
            lResult[0] *= lFactor;
            lResult[1] *= lFactor;
            lResult[2] *= lFactor;
        }

		pElement->type = FBX_MATRIAL_ELEMENT::ELEMENT_COLOR;
    }

    if (lProperty.IsValid())
    {
		int existTextureCount = 0;
        const int lTextureCount = lProperty.GetSrcObjectCount<FbxFileTexture>();

		for(int i=0;i<lTextureCount;i++)
		{
			FbxFileTexture* lFileTexture = lProperty.GetSrcObject<FbxFileTexture>(i);
			if(!lFileTexture)
				continue;

			FbxString uvsetName = lFileTexture->UVSet.Get();
			std::string uvSetString = uvsetName.Buffer();
			std::string filepath = lFileTexture->GetFileName();

			pElement->textureSetArray[uvSetString].push_back(filepath);
			existTextureCount++;
		}
	
		const int lLayeredTextureCount = lProperty.GetSrcObjectCount<FbxLayeredTexture>();

		for(int i=0;i<lLayeredTextureCount;i++)
		{
			FbxLayeredTexture* lLayeredTexture = lProperty.GetSrcObject<FbxLayeredTexture>(i);

			const int lTextureFileCount = lLayeredTexture->GetSrcObjectCount<FbxFileTexture>();

			for(int j=0;j<lTextureFileCount;j++)
			{
				FbxFileTexture* lFileTexture = lLayeredTexture->GetSrcObject<FbxFileTexture>(j);
				if(!lFileTexture)
					continue;

				FbxString uvsetName = lFileTexture->UVSet.Get();
				std::string uvSetString = uvsetName.Buffer();
				std::string filepath = lFileTexture->GetFileName();

				pElement->textureSetArray[uvSetString].push_back(filepath);
				existTextureCount++;
			}
		}

		if(existTextureCount > 0)
		{
			if(pElement->type == FBX_MATRIAL_ELEMENT::ELEMENT_COLOR)
				pElement->type = FBX_MATRIAL_ELEMENT::ELEMENT_BOTH;
			else
				pElement->type = FBX_MATRIAL_ELEMENT::ELEMENT_TEXTURE;
		}
     }

    return lResult;
}
Esempio n. 24
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()));
			}
		}
Esempio n. 25
0
void Tools::DisplayAnimation::DisplayChannels( FbxNode* i_node, FbxAnimLayer* i_animLayer, void (*DisplayCurve) (FbxAnimCurve* i_curve), void (*DisplayListCurve) (FbxAnimCurve* i_curve, FbxProperty* i_property), bool isSwitcher )
{
	FbxAnimCurve *animCurve = NULL;

	// Display general curves.
	if (!isSwitcher)
	{
		animCurve = i_node->LclTranslation.GetCurve( i_animLayer, FBXSDK_CURVENODE_COMPONENT_X );
		if( animCurve )
		{
			FBXSDK_printf( "        TX\n" );
			DisplayCommon::DisplayString( "        TX" );
			DisplayCurve( animCurve );
		}
		animCurve = i_node->LclTranslation.GetCurve( i_animLayer, FBXSDK_CURVENODE_COMPONENT_Y );
		if( animCurve )
		{
			FBXSDK_printf( "        TY\n" );
			DisplayCommon::DisplayString( "        TY" );
			DisplayCurve( animCurve );
		}
		animCurve = i_node->LclTranslation.GetCurve( i_animLayer, FBXSDK_CURVENODE_COMPONENT_Z );
		if( animCurve )
		{
			FBXSDK_printf( "        TZ\n" );
			DisplayCommon::DisplayString( "        TZ" );
			DisplayCurve( animCurve );
		}

		animCurve = i_node->LclRotation.GetCurve( i_animLayer, FBXSDK_CURVENODE_COMPONENT_X );
		if( animCurve )
		{
			FBXSDK_printf( "        RX\n" );
			DisplayCommon::DisplayString( "        RX" );
			DisplayCurve( animCurve );
		}
		animCurve = i_node->LclRotation.GetCurve( i_animLayer, FBXSDK_CURVENODE_COMPONENT_Y );
		if( animCurve )
		{
			FBXSDK_printf( "        RY\n" );
			DisplayCommon::DisplayString( "        RY" );
			DisplayCurve( animCurve );
		}
		animCurve = i_node->LclRotation.GetCurve( i_animLayer, FBXSDK_CURVENODE_COMPONENT_Z );
		if( animCurve )
		{
			FBXSDK_printf( "        RZ\n" );
			DisplayCommon::DisplayString( "        RZ" );
			DisplayCurve( animCurve );
		}

		animCurve = i_node->LclScaling.GetCurve( i_animLayer, FBXSDK_CURVENODE_COMPONENT_X );
		if( animCurve )
		{
			FBXSDK_printf( "        SX\n" );
			DisplayCommon::DisplayString( "        SX" );
			DisplayCurve( animCurve );
		}
		animCurve = i_node->LclScaling.GetCurve( i_animLayer, FBXSDK_CURVENODE_COMPONENT_Y );
		if( animCurve )
		{
			FBXSDK_printf( "        SY\n" );
			DisplayCommon::DisplayString( "        SY" );
			DisplayCurve( animCurve );
		}
		animCurve = i_node->LclScaling.GetCurve( i_animLayer, FBXSDK_CURVENODE_COMPONENT_Z );
		if( animCurve )
		{
			FBXSDK_printf( "        SZ\n" );
			DisplayCommon::DisplayString( "        SZ" );
			DisplayCurve( animCurve );
		}
	}

	// Display curves specific to a light or marker.
	FbxNodeAttribute *nodeAttribute = i_node->GetNodeAttribute();

	if( nodeAttribute )
	{
		animCurve = nodeAttribute->Color.GetCurve( i_animLayer, FBXSDK_CURVENODE_COLOR_RED );
		if( animCurve )
		{
			FBXSDK_printf( "        Red\n" );
			DisplayCommon::DisplayString( "        Red" );
			DisplayCurve( animCurve );
		}
		animCurve = nodeAttribute->Color.GetCurve( i_animLayer, FBXSDK_CURVENODE_COLOR_GREEN );
		if( animCurve )
		{
			FBXSDK_printf( "        Green\n" );
			DisplayCommon::DisplayString( "        Green" );
			DisplayCurve( animCurve );
		}
		animCurve = nodeAttribute->Color.GetCurve( i_animLayer, FBXSDK_CURVENODE_COLOR_BLUE );
		if( animCurve )
		{
			FBXSDK_printf( "        Blue\n" );
			DisplayCommon::DisplayString( "        Blue" );
			DisplayCurve( animCurve );
		}

		// Display curves specific to a light.
		FbxLight *light = i_node->GetLight();
		if( light )
		{
			animCurve = light->Intensity.GetCurve( i_animLayer );
			if( animCurve )
			{
				FBXSDK_printf( "        Intensity\n" );
				DisplayCommon::DisplayString( "        Intensity" );
				DisplayCurve( animCurve );
			}

			animCurve = light->OuterAngle.GetCurve( i_animLayer );
			if( animCurve )
			{
				FBXSDK_printf( "        Outer Angle\n" );
				DisplayCommon::DisplayString( "        Outer Angle" );
				DisplayCurve( animCurve );
			}

			animCurve = light->Fog.GetCurve( i_animLayer );
			if( animCurve )
			{
				FBXSDK_printf( "        Fog\n" );
				DisplayCommon::DisplayString( "        Fog" );
				DisplayCurve( animCurve );
			}
		}

		// Display curves specific to a camera.
		FbxCamera *camera = i_node->GetCamera();
		if( camera )
		{
			animCurve = camera->FieldOfView.GetCurve( i_animLayer );
			if( animCurve )
			{
				FBXSDK_printf( "        Field of View\n" );
				DisplayCommon::DisplayString( "        Field of View" );
				DisplayCurve( animCurve );
			}

			animCurve = camera->FieldOfViewX.GetCurve( i_animLayer );
			if( animCurve )
			{
				FBXSDK_printf( "        Field of View X\n" );
				DisplayCommon::DisplayString( "        Field of View X" );
				DisplayCurve( animCurve );
			}

			animCurve = camera->FieldOfViewY.GetCurve( i_animLayer );
			if( animCurve )
			{
				FBXSDK_printf( "        Field of View Y\n" );
				DisplayCommon::DisplayString( "        Field of View Y" );
				DisplayCurve( animCurve );
			}

			animCurve = camera->OpticalCenterX.GetCurve( i_animLayer );
			if( animCurve )
			{
				FBXSDK_printf( "        Optical Center X\n" );
				DisplayCommon::DisplayString( "        Optical Center X" );
				DisplayCurve( animCurve );
			}

			animCurve = camera->OpticalCenterY.GetCurve( i_animLayer );
			if( animCurve )
			{
				FBXSDK_printf( "        Optical Center Y\n" );
				DisplayCommon::DisplayString( "        Optical Center Y" );
				DisplayCurve( animCurve );
			}

			animCurve = camera->Roll.GetCurve( i_animLayer );
			if( animCurve )
			{
				FBXSDK_printf( "        Roll\n" );
				DisplayCommon::DisplayString( "        Roll" );
				DisplayCurve( animCurve );
			}
		}

		// Display curves specific to a geometry.
		if (nodeAttribute->GetAttributeType() == FbxNodeAttribute::eMesh ||
			nodeAttribute->GetAttributeType() == FbxNodeAttribute::eNurbs ||
			nodeAttribute->GetAttributeType() == FbxNodeAttribute::ePatch)
		{
			FbxGeometry *geometry = (FbxGeometry*) nodeAttribute;

			int blendShapeDeformerCount = geometry->GetDeformerCount( FbxDeformer::eBlendShape );
			for( int blendShapeIndex = 0; blendShapeIndex<blendShapeDeformerCount; blendShapeIndex++ )
			{
				FbxBlendShape *blendShape = (FbxBlendShape*)geometry->GetDeformer( blendShapeIndex, FbxDeformer::eBlendShape );

				int blendShapeChannelCount = blendShape->GetBlendShapeChannelCount();
				for( int channelIndex = 0; channelIndex<blendShapeChannelCount; channelIndex++ )
				{
					FbxBlendShapeChannel *channel = blendShape->GetBlendShapeChannel( channelIndex );
					const char *channelName = channel->GetName();

					animCurve = geometry->GetShapeChannel( blendShapeIndex, channelIndex, i_animLayer, true );
					if( animCurve )
					{
						FBXSDK_printf( "        Shape %s\n", channelName );
						DisplayCommon::DisplayString( "        Shape ", channelName );
						DisplayCurve( animCurve );
					}
				}
			}
		}
	}

	// Display curves specific to properties
	FbxProperty lProperty = i_node->GetFirstProperty();
	while( lProperty.IsValid() )
	{
		if( lProperty.GetFlag(FbxPropertyAttr::eUserDefined) )
		{
			FbxString lFbxFCurveNodeName  = lProperty.GetName();
			FbxAnimCurveNode* curveNode = lProperty.GetCurveNode( i_animLayer );

			if( !curveNode )
			{
				lProperty = i_node->GetNextProperty( lProperty );
				continue;
			}

			FbxDataType dataType = lProperty.GetPropertyDataType();
			if( dataType.GetType() == eFbxBool || dataType.GetType() == eFbxDouble || dataType.GetType() == eFbxFloat || dataType.GetType() == eFbxInt )
			{
				FbxString message;

				message =  "        Property ";
				message += lProperty.GetName();
				if( lProperty.GetLabel().GetLen() > 0 )
				{
					message += " (Label: ";
					message += lProperty.GetLabel();
					message += ")";
				};

				DisplayCommon::DisplayString( message );

				for( int c = 0; c < curveNode->GetCurveCount(0U); c++ )
				{
					animCurve = curveNode->GetCurve( 0U, c );
					if( animCurve )
						DisplayCurve( animCurve );
				}
			}
			else if( dataType.GetType() == eFbxDouble3 || dataType.GetType() == eFbxDouble4 || dataType.Is(FbxColor3DT) || dataType.Is(FbxColor4DT) )
			{
				char* componentName1 = (dataType.Is(FbxColor3DT) ||dataType.Is(FbxColor4DT)) ? (char*)FBXSDK_CURVENODE_COLOR_RED : (char*)"X";
				char* componentName2 = (dataType.Is(FbxColor3DT) ||dataType.Is(FbxColor4DT)) ? (char*)FBXSDK_CURVENODE_COLOR_GREEN : (char*)"Y";
				char* componentName3 = (dataType.Is(FbxColor3DT) ||dataType.Is(FbxColor4DT)) ? (char*)FBXSDK_CURVENODE_COLOR_BLUE  : (char*)"Z";
				FbxString message;

				message =  "        Property ";
				message += lProperty.GetName();
				if( lProperty.GetLabel().GetLen() > 0 )
				{
					message += " (Label: ";
					message += lProperty.GetLabel();
					message += ")";
				}
				DisplayCommon::DisplayString( message );

				for( int c = 0; c < curveNode->GetCurveCount(0U); c++ )
				{
					animCurve = curveNode->GetCurve( 0U, c );
					if( animCurve )
					{
						DisplayCommon::DisplayString( "        Component ", componentName1 );
						DisplayCurve( animCurve );
					}
				}

				for( int c = 0; c < curveNode->GetCurveCount(1U); c++ )
				{
					animCurve = curveNode->GetCurve(1U, c);
					if( animCurve )
					{
						DisplayCommon::DisplayString( "        Component ", componentName2 );
						DisplayCurve( animCurve );
					}
				}

				for( int c = 0; c < curveNode->GetCurveCount(2U); c++ )
				{
					animCurve = curveNode->GetCurve( 2U, c );
					if( animCurve )
					{
						DisplayCommon::DisplayString( "        Component ", componentName3 );
						DisplayCurve( animCurve );
					}
				}
			}
			else if( dataType.GetType() == eFbxEnum )
			{
				FbxString message;

				message =  "        Property ";
				message += lProperty.GetName();
				if( lProperty.GetLabel().GetLen() > 0 )
				{
					message += " (Label: ";
					message += lProperty.GetLabel();
					message += ")";
				};
				DisplayCommon::DisplayString( message );

				for( int c = 0; c < curveNode->GetCurveCount(0U); c++ )
				{
					animCurve = curveNode->GetCurve( 0U, c );
					if( animCurve )
						DisplayListCurve( animCurve, &lProperty );
				}
			}
		}

		lProperty = i_node->GetNextProperty( lProperty );
	} // while
}
Esempio n. 26
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);
	}
}
// マテリアルプロパティ獲得
FbxDouble3 GetMaterialProperty(
	const FbxSurfaceMaterial * pMaterial,
	const char * pPropertyName,
	const char * pFactorPropertyName)
{
	FbxDouble3 lResult(0, 0, 0);
	const FbxProperty lProperty = pMaterial->FindProperty(pPropertyName);
	const FbxProperty lFactorProperty = pMaterial->FindProperty(pFactorPropertyName);
	if(lProperty.IsValid() && lFactorProperty.IsValid())
	{
		lResult = lProperty.Get<FbxDouble3>();
		double lFactor = lFactorProperty.Get<FbxDouble>();
		if(lFactor != 1)
		{
			lResult[0] *= lFactor;
			lResult[1] *= lFactor;
			lResult[2] *= lFactor;
		}
	}

	if(lProperty.IsValid())
	{
		printf("テクスチャ\n");
		const int lTextureCount = lProperty.GetSrcObjectCount<FbxFileTexture>();
		for(int i = 0; i<lTextureCount; i++)
		{
			FbxFileTexture* lFileTexture = lProperty.GetSrcObject<FbxFileTexture>(i);
			if(lFileTexture)
			{
				FbxString uvsetName = lFileTexture->UVSet.Get();
				std::string uvSetString = uvsetName.Buffer();
				std::string filepath = lFileTexture->GetFileName();

				printf("UVSet名=%s\n", uvSetString.c_str());
				printf("テクスチャ名=%s\n", filepath.c_str());
			}
		}
		puts("");

		printf("レイヤードテクスチャ\n");
		const int lLayeredTextureCount = lProperty.GetSrcObjectCount<FbxLayeredTexture>();
		for(int i = 0; i<lLayeredTextureCount; i++)
		{
			FbxLayeredTexture* lLayeredTexture = lProperty.GetSrcObject<FbxLayeredTexture>(i);

			const int lTextureFileCount = lLayeredTexture->GetSrcObjectCount<FbxFileTexture>();

			for(int j = 0; j<lTextureFileCount; j++)
			{
				FbxFileTexture* lFileTexture = lLayeredTexture->GetSrcObject<FbxFileTexture>(j);
				if(lFileTexture)
				{
					FbxString uvsetName = lFileTexture->UVSet.Get();
					std::string uvSetString = uvsetName.Buffer();
					std::string filepath = lFileTexture->GetFileName();

					printf("UVSet名=%s\n", uvSetString.c_str());
					printf("テクスチャ名=%s\n", filepath.c_str());
				}
			}
		}
		puts("");
	}

	return lResult;
}
//-------------------------------------------------------------------------
//
//-------------------------------------------------------------------------
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;
}
Esempio n. 29
0
void FbxToHkxConverter::extractKeyFramesAndAnnotations(hkxScene *scene, FbxNode* fbxChildNode, hkxNode* newChildNode, int animStackIndex)
{
	FbxAMatrix bindPoseMatrix;
	FbxAnimStack* lAnimStack = NULL;
	int numAnimLayers = 0;
	FbxTimeSpan animTimeSpan;
	
	if (animStackIndex >= 0)
	{
		lAnimStack = m_curFbxScene->GetSrcObject<FbxAnimStack>(animStackIndex);
		numAnimLayers = lAnimStack->GetMemberCount<FbxAnimLayer>();
		animTimeSpan = lAnimStack->GetLocalTimeSpan();
	}

	// Find the time offset (in the "time space" of the FBX file) of the first animation frame
	FbxTime timePerFrame; timePerFrame.SetTime(0, 0, 0, 1, 0, m_curFbxScene->GetGlobalSettings().GetTimeMode());
	const FbxTime startTime = animTimeSpan.GetStart();
	const FbxTime endTime = animTimeSpan.GetStop();

	const hkReal startTimeSeconds = static_cast<hkReal>(startTime.GetSecondDouble());
	const hkReal endTimeSeconds = static_cast<hkReal>(endTime.GetSecondDouble());

	int numFrames = 0;
	bool staticNode = true;

	if (scene->m_sceneLength == 0)
	{
		bindPoseMatrix = fbxChildNode->EvaluateLocalTransform(startTime);
	}
	else
	{
		hkArray<hkStringOld> annotationStrings;
		hkArray<hkReal> annotationTimes;

		HK_ASSERT(0x0, newChildNode->m_keyFrames.getSize() == 0);

		// Sample each animation frame
		for (FbxTime time = startTime, priorSampleTime = endTime;
			 time < endTime;
			 priorSampleTime = time, time += timePerFrame, ++numFrames)
		{
			FbxAMatrix frameMatrix = fbxChildNode->EvaluateLocalTransform(time);
			staticNode = staticNode && (frameMatrix == bindPoseMatrix);

			hkMatrix4 mat;

			// Extract this frame's transform
			convertFbxXMatrixToMatrix4(frameMatrix, mat);
			newChildNode->m_keyFrames.pushBack(mat);

			// Extract all annotation strings for this frame using the deprecated
			// pipeline (new annotations are extracted when sampling attributes)
			if (m_options.m_exportAnnotations && numAnimLayers > 0)
			{
				FbxProperty prop = fbxChildNode->GetFirstProperty();
				while(prop.IsValid())
				{
					FbxString propName  = prop.GetName();
					FbxDataType lDataType = prop.GetPropertyDataType();
					hkStringOld name(propName.Buffer(), (int) propName.GetLen());
					if (name.asUpperCase().beginsWith("HK") && lDataType.GetType() == eFbxEnum)
					{
						FbxAnimLayer* lAnimLayer = lAnimStack->GetMember<FbxAnimLayer>(0);
						FbxAnimCurve* lAnimCurve = prop.GetCurve(lAnimLayer);

						int currentKeyIndex;
						const int keyIndex = (int) lAnimCurve->KeyFind(time, &currentKeyIndex);
						const int priorKeyIndex = (int) lAnimCurve->KeyFind(priorSampleTime);

						// Only store annotations on frames where they're explicitly keyframed, or if this is the first keyframe 
						if (priorKeyIndex != keyIndex)
						{
							const int currentEnumValueIndex = keyIndex < 0 ? (int) lAnimCurve->Evaluate(priorSampleTime) : (int) lAnimCurve->Evaluate(time);
							HK_ASSERT(0x0, currentEnumValueIndex < prop.GetEnumCount());
							const char* enumValue = prop.GetEnumValue(currentEnumValueIndex);
							hkxNode::AnnotationData& annotation = newChildNode->m_annotations.expandOne();
							annotation.m_time = (hkReal) (time - startTime).GetSecondDouble();
							annotation.m_description = (name + hkStringOld(enumValue, hkString::strLen(enumValue))).cString();
						}
					}
					prop = fbxChildNode->GetNextProperty(prop);
				}
			}
		}
	}

	// Replace animation key data for static nodes with just 1 or 2 frames of bind pose data
	if (staticNode)
	{
		// Static nodes in animated scene data are exported with two keys
		const bool exportTwoFramesForStaticNodes = (numFrames > 1);

		// replace transform
		newChildNode->m_keyFrames.setSize(exportTwoFramesForStaticNodes ? 2: 1);
		newChildNode->m_keyFrames.optimizeCapacity(0, true);

		// convert the bind pose transform to Havok format
		convertFbxXMatrixToMatrix4(bindPoseMatrix, newChildNode->m_keyFrames[0]);

		if (exportTwoFramesForStaticNodes)
		{
			newChildNode->m_keyFrames[1] = newChildNode->m_keyFrames[0];
		}
	}

	// Extract all times of actual keyframes for the current node... this can be used by Vision
	if ( m_options.m_storeKeyframeSamplePoints &&
		 newChildNode->m_keyFrames.getSize() > 2 &&
		 numAnimLayers > 0 )
	{
		FbxAnimLayer* lAnimLayer = lAnimStack->GetMember<FbxAnimLayer>(0);

		extractKeyTimes(fbxChildNode, lAnimLayer, FBXSDK_CURVENODE_TRANSLATION, newChildNode, startTimeSeconds, endTimeSeconds);
		extractKeyTimes(fbxChildNode, lAnimLayer, FBXSDK_CURVENODE_ROTATION, newChildNode, startTimeSeconds, endTimeSeconds);
		extractKeyTimes(fbxChildNode, lAnimLayer, FBXSDK_CURVENODE_SCALING, newChildNode, startTimeSeconds, endTimeSeconds);
		extractKeyTimes(fbxChildNode, lAnimLayer, FBXSDK_CURVENODE_COMPONENT_X, newChildNode, startTimeSeconds, endTimeSeconds);
		extractKeyTimes(fbxChildNode, lAnimLayer, FBXSDK_CURVENODE_COMPONENT_Y, newChildNode, startTimeSeconds, endTimeSeconds);
		extractKeyTimes(fbxChildNode, lAnimLayer, FBXSDK_CURVENODE_COMPONENT_Z, newChildNode, startTimeSeconds, endTimeSeconds);

		if (newChildNode->m_linearKeyFrameHints.getSize() > 1)
		{
			hkSort(newChildNode->m_linearKeyFrameHints.begin(), newChildNode->m_linearKeyFrameHints.getSize());
		}
	}
}