FBXModel::MaterialCollection FBXModel::getMaterials(const GraphicsDevice& device, KFbxNode* node)
{		
	MaterialCollection materials;

	for (int i = 0; i < node->GetMaterialCount(); ++i)
	{
		FBXMaterial material;

		KFbxSurfaceMaterial* surfaceMaterial = node->GetMaterial(i);

		KFbxProperty prop = surfaceMaterial->FindProperty(KFbxSurfaceMaterial::sDiffuse);

		if	(prop.IsValid())
		{
			int textureCount = prop.GetSrcObjectCount(KFbxFileTexture::ClassId);

			if (textureCount)
			{
				KFbxFileTexture* fbxTexture = prop.GetSrcObject(FBX_TYPE(KFbxFileTexture), 0);

				if (fbxTexture)
					material.texture = Texture::createFromFile(device, fbxTexture->GetFileName());
			}
		}

		if (!material.texture)
			material.texture = defaultTexture;
						
		if	(surfaceMaterial->GetClassId().Is(KFbxSurfacePhong::ClassId))
		{
			Material& mat = material.material;

			KFbxSurfacePhong* phong = (KFbxSurfacePhong*)surfaceMaterial;

			mat.Ambient = convert(phong->Diffuse.Get());
			mat.Diffuse = mat.Ambient;
			mat.Specular = convert(phong->Specular.Get());
			mat.Emissive = convert(phong->Emissive.Get());
			mat.Power = (float)phong->SpecularFactor.Get();
		}

		materials.push_back(material);
	}

	return materials;
}
Example #2
0
void ShadingManager::SetMaterial(const KFbxNode * pNode, int pMaterialIndex) const
{
	const KFbxSurfaceMaterial * lSurfaceMaterial = pNode->GetMaterial(pMaterialIndex);
	if (!lSurfaceMaterial)
		return;

	if (lSurfaceMaterial == mLastMaterial)
		return;

	mLastMaterial = lSurfaceMaterial;

	SetMaterialProperty(lSurfaceMaterial, KFbxSurfaceMaterial::sEmissive, KFbxSurfaceMaterial::sEmissiveFactor, GL_EMISSION);

	SetMaterialProperty(lSurfaceMaterial, KFbxSurfaceMaterial::sAmbient, KFbxSurfaceMaterial::sAmbientFactor, GL_AMBIENT);

	const TextureObjectsForMaterialType::RecordType * lRecord = mTextureObjectsForMaterial.Find(lSurfaceMaterial);
	if (lRecord)
	{
		glBindTexture(GL_TEXTURE_2D, lRecord->GetValue());
		mLastTextureObject = lRecord->GetValue();
	}
	else
	{
		mLastTextureObject = 0;
	}

	if (!mLastTextureObject)
	{
		SetMaterialProperty(lSurfaceMaterial, KFbxSurfaceMaterial::sDiffuse, KFbxSurfaceMaterial::sDiffuseFactor, GL_DIFFUSE);
	}

	SetMaterialProperty(lSurfaceMaterial, KFbxSurfaceMaterial::sSpecular, KFbxSurfaceMaterial::sSpecularFactor, GL_SPECULAR);
	KFbxProperty lShininessProperty = lSurfaceMaterial->FindProperty(KFbxSurfaceMaterial::sShininess);
	if (lShininessProperty.IsValid())
	{
		double lShininess = 0;
		lShininess = lShininessProperty.Get(&lShininess);
		glMaterialf(GL_FRONT, GL_SHININESS, (GLfloat)lShininess);
	}
}
Example #3
0
void ShadingManager::Initialize(const KFbxNode* pNode)
{
	if (!pNode)
		return;

	if (pNode->GetNodeAttribute())
	{
		const int lMaterialCount = pNode->GetMaterialCount();
		for (int lMaterialIndex = 0; lMaterialIndex < lMaterialCount; ++lMaterialIndex)
		{
			const KFbxSurfaceMaterial * lMaterial = pNode->GetMaterial(lMaterialIndex);
			if (lMaterial)
			{
				const KFbxProperty lProperty = lMaterial->FindProperty(KFbxSurfaceMaterial::sDiffuse);
				if (lProperty.IsValid())
				{
					const int lTextureCount = lProperty.GetSrcObjectCount(KFbxFileTexture::ClassId);
					if (lTextureCount)
					{
						const KFbxFileTexture* lTexture = lProperty.GetSrcObject(FBX_TYPE(KFbxFileTexture), 0);
						if (lTexture)
						{
							unsigned int lTextureObject;
							mTextureManager->LoadTexture(lTexture, &lTextureObject);
							mTextureObjectsForMaterial.Insert(lMaterial, lTextureObject);
						}
					}
				}
			}
		}
	}

	const int lChildCount = pNode->GetChildCount();
	for (int lChildIndex = 0; lChildIndex < lChildCount; ++lChildIndex)
	{
		Initialize(pNode->GetChild(lChildIndex));
	}
}
Example #4
0
bool	FBXLoader::DisplayTextureNames( KFbxProperty &pProperty, KString& pConnectionString)
{
	int lLayeredTextureCount = pProperty.GetSrcObjectCount(KFbxLayeredTexture::ClassId);
	if (lLayeredTextureCount > 0)
	{
		for (int j=0; j<lLayeredTextureCount; ++j)
		{
			KFbxLayeredTexture *lLayeredTexture = KFbxCast <KFbxLayeredTexture>(pProperty.GetSrcObject(KFbxLayeredTexture::ClassId, j));
			int lNbTextures = lLayeredTexture->GetSrcObjectCount(KFbxTexture::ClassId);
			pConnectionString += " Texture ";

			for (int k =0; k<lNbTextures; ++k)
			{
				pConnectionString += "\"";
				pConnectionString += (char*)lLayeredTexture->GetName();
				pConnectionString += "\"";
				pConnectionString += " ";
			}
			pConnectionString += "of ";
			pConnectionString += pProperty.GetName();
			pConnectionString += " on layer ";
			pConnectionString += j;
		}
		pConnectionString += " |";
		return true;
	}
	else
	{
		int lNbTextures = pProperty.GetSrcObjectCount(KFbxTexture::ClassId);

		if (lNbTextures > 0)
		{
			pConnectionString += " Texture ";
			pConnectionString += " ";

			for (int j =0; j<lNbTextures; ++j)
			{
				KFbxTexture* lTexture = KFbxCast <KFbxTexture> (pProperty.GetSrcObject(KFbxTexture::ClassId,j));
				if (lTexture)
				{
					pConnectionString += "\"";
					pConnectionString += (char*)lTexture->GetName();
					pConnectionString += "\"";
					pConnectionString += " ";
				}
			}
			pConnectionString += "of ";
			pConnectionString += pProperty.GetName();
			pConnectionString += " |";
			return true;
		}
		return false;
	}
}
Example #5
0
void ShadingManager::SetMaterialProperty(const KFbxSurfaceMaterial * pMaterial,
		const char * pPropertyName,
		const char * pFactorPropertyName,
		unsigned int pOGLProperty) const
{
	const KFbxProperty lProperty = pMaterial->FindProperty(pPropertyName);
	const KFbxProperty lFactorProperty = pMaterial->FindProperty(pFactorPropertyName);
	if (lProperty.IsValid() && lFactorProperty.IsValid())
	{
		fbxDouble3 lColor = fbxDouble3(0, 0, 0);
		lColor = lProperty.Get(&lColor);
		double lFactor = 1;
		lFactor = lFactorProperty.Get(&lFactor);
		if (lFactor != 1)
		{
			lColor[0] *= lFactor;
			lColor[1] *= lFactor;
			lColor[2] *= lFactor;
		}

		const GLfloat lMaterial[] = {(GLfloat)lColor[0], (GLfloat)lColor[1], (GLfloat)lColor[2], 1.0f};
		glMaterialfv(GL_FRONT, pOGLProperty, lMaterial);
	}
}
Example #6
0
bool	FBXLoader::FindTextureInfo(KFbxProperty prop, bool& disp, int mat_i, Object* o)
{
	if (prop.IsValid())
	{
		Texture*	t;

		t = new (std::nothrow) Texture;
		if (t == NULL)
		{
			std::cout << "[FbxLoader]{__FindTextureInfo} Error: Can not allocate memory\n";
			return (false);
		}
		int	t_count;
		int	i;

		t_count = prop.GetSrcObjectCount(KFbxTexture::ClassId);
		i = 0;
		while (i < t_count)
		{
			KFbxLayeredTexture*	lay_t;

			lay_t = KFbxCast <KFbxLayeredTexture>(prop.GetSrcObject(KFbxLayeredTexture::ClassId, i));
			if (lay_t)
			{
				KFbxLayeredTexture*	lay_t2;
				int			nb_text;
				int			j;

				lay_t2 = KFbxCast <KFbxLayeredTexture>(prop.GetSrcObject(KFbxLayeredTexture::ClassId, i));
				nb_text = lay_t2->GetSrcObjectCount(KFbxTexture::ClassId);
				j = 0;
				while (j < nb_text)
				{
					KFbxTexture*	_t;

					_t = KFbxCast <KFbxTexture> (lay_t2->GetSrcObject(KFbxTexture::ClassId, j));
					if (_t)
					{
						KFbxLayeredTexture::EBlendMode blend_mode;

						if (disp)
							disp = false;
						lay_t2->GetTextureBlendMode(j, blend_mode);
						this->TextureInfoFinded(_t, (int)blend_mode, t);
						o->GetMatList()->at(mat_i)->AddTexture(t);
					}
					++j;
				}
			}
			else
			{
				KFbxTexture*	_t;

				_t = KFbxCast <KFbxTexture> (prop.GetSrcObject(KFbxTexture::ClassId, i));
				if (_t)
				{
					if (disp)
						disp = false;
					if (strcmp(prop.GetName(), "DiffuseColor") == 0)
						t->SetTXTChanel(0);
					else if (strcmp(prop.GetName(), "SpecularColor") == 0)
						t->SetTXTChanel(3);
					this->TextureInfoFinded(_t, -1, t);
					o->GetMatList()->at(mat_i)->AddTexture(t);
				}
			}
			++i;
		}
	}
	return (true);
}
Example #7
0
StateSetContent
FbxMaterialToOsgStateSet::convert(const KFbxSurfaceMaterial* 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 KFbxSurfaceLambert* pFbxLambert = KFbxCast<KFbxSurfaceLambert>(pFbxMat);

    // diffuse map...
    const KFbxProperty lProperty = pFbxMat->FindProperty(KFbxSurfaceMaterial::sDiffuse);
    if (lProperty.IsValid())
    {
        int lNbTex = lProperty.GetSrcObjectCount(KFbxFileTexture::ClassId);
        for (int lTextureIndex = 0; lTextureIndex < lNbTex; lTextureIndex++)
        {
            KFbxFileTexture* lTexture = KFbxCast<KFbxFileTexture>(lProperty.GetSrcObject(KFbxFileTexture::ClassId, 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 KFbxProperty lOpacityProperty = pFbxMat->FindProperty(KFbxSurfaceMaterial::sTransparentColor);
    if (lOpacityProperty.IsValid())
    {
        int lNbTex = lOpacityProperty.GetSrcObjectCount(KFbxFileTexture::ClassId);
        for (int lTextureIndex = 0; lTextureIndex < lNbTex; lTextureIndex++)
        {
            KFbxFileTexture* lTexture = KFbxCast<KFbxFileTexture>(lOpacityProperty.GetSrcObject(KFbxFileTexture::ClassId, 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 KFbxProperty lReflectionProperty = pFbxMat->FindProperty(KFbxSurfaceMaterial::sReflection);
    if (lReflectionProperty.IsValid())
    {
        int lNbTex = lReflectionProperty.GetSrcObjectCount(KFbxFileTexture::ClassId);
        for (int lTextureIndex = 0; lTextureIndex < lNbTex; lTextureIndex++)
        {
            KFbxFileTexture* lTexture = KFbxCast<KFbxFileTexture>(lReflectionProperty.GetSrcObject(KFbxFileTexture::ClassId, lTextureIndex));
            if (lTexture)
            {
                // support only spherical reflection maps...
                if (KFbxFileTexture::eUMT_ENVIRONMENT == lTexture->CurrentMappingType.Get())
                {
                    result.reflectionTexture = fbxTextureToOsgTexture(lTexture);
                    result.reflectionChannel = lTexture->UVSet.Get();
                }
            }

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

    // emissive map...
    const KFbxProperty lEmissiveProperty = pFbxMat->FindProperty(KFbxSurfaceMaterial::sEmissive);
    if (lEmissiveProperty.IsValid())
    {
        int lNbTex = lEmissiveProperty.GetSrcObjectCount(KFbxFileTexture::ClassId);
        for (int lTextureIndex = 0; lTextureIndex < lNbTex; lTextureIndex++)
        {
            KFbxFileTexture* lTexture = KFbxCast<KFbxFileTexture>(lEmissiveProperty.GetSrcObject(KFbxFileTexture::ClassId, 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 KFbxSurfacePhong* pFbxPhong = KFbxCast<KFbxSurfacePhong>(pFbxLambert))
        {
            color = pFbxPhong->Specular.Get();
            factor = pFbxPhong->SpecularFactor.Get();
            pOsgMat->setSpecular(osg::Material::FRONT_AND_BACK, osg::Vec4(
                static_cast<float>(color[0] * factor),
                static_cast<float>(color[1] * factor),
                static_cast<float>(color[2] * factor),
                1.0f));

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

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

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

    _fbxMaterialMap.insert(FbxMaterialMap::value_type(pFbxMat, result));
    return result;
}
void FBXJSONSerializer::recurse_over_model(fbxsdk_2012_1::KFbxNode *fbx_node, json::Array& meshes_array) {
  KFbxMesh* old_mesh = fbx_node->GetMesh();
  if (old_mesh) {
    KFbxGeometryConverter converter(fbx_node->GetFbxSdkManager());
    KFbxMesh* mesh = converter.TriangulateMesh(old_mesh);
    mesh->ComputeBBox();
    mesh->ComputeVertexNormals();
    
    Object json_mesh;
    {
      KFbxLayerElementUV* uvs = mesh->GetLayer(0)->GetUVs();
      KFbxLayerElementNormal* normals = mesh->GetLayer(0, KFbxLayerElement::eNORMAL)->GetNormals();
      Array json_mesh_normals;        
      Array json_mesh_uvs;
      Array json_mesh_vertices;
      int polygon_count = mesh->GetPolygonCount();
      for (int poly_index = 0; poly_index < polygon_count; poly_index++) {
        for (int vertex_index = 0; vertex_index < mesh->GetPolygonSize(poly_index); vertex_index++) {
          int vertex_position = mesh->GetPolygonVertex(poly_index, vertex_index);
          
          KFbxVector4 vertex = mesh->GetControlPoints()[vertex_position];
          Number vertex_x = vertex.GetAt(0); json_mesh_vertices.Insert(vertex_x);
          Number vertex_y = vertex.GetAt(1); json_mesh_vertices.Insert(vertex_y);
          Number vertex_z = vertex.GetAt(2); json_mesh_vertices.Insert(vertex_z);

          KFbxVector4 normal = normals->GetDirectArray()[vertex_position];

          Number normal_x = normal.GetAt(0); json_mesh_normals.Insert(normal_x);
          Number normal_y = normal.GetAt(1); json_mesh_normals.Insert(normal_y);
          Number normal_z = normal.GetAt(2); json_mesh_normals.Insert(normal_z); 

          if (uvs) {            
            int mesh_index = mesh->GetTextureUVIndex(poly_index, vertex_index);
            KFbxVector2 uv = uvs->GetDirectArray().GetAt(mesh_index);  
            Number uv_x = 1.0f-uv[0]; json_mesh_uvs.Insert(uv_x); // these are flipped
            Number uv_y = 1.0f-uv[1]; json_mesh_uvs.Insert(uv_y);
          }
        }
      }
      json_mesh["vertices"] = json_mesh_vertices;
      json_mesh["normals"] = json_mesh_normals;
      json_mesh["uvs"] = json_mesh_uvs;

    }
    {
      fbxDouble3 scale = fbx_node->LclScaling.Get();
      Object json_mesh_scale;
      json_mesh_scale["x"] = Number(scale[0]);
      json_mesh_scale["y"] = Number(scale[1]);
      json_mesh_scale["z"] = Number(scale[2]);
      json_mesh["scale"] = json_mesh_scale;
    }
    {
      fbxDouble3 translation = fbx_node->LclTranslation.Get();
      Object json_mesh_translation;
      json_mesh_translation["x"] = Number(translation[0]);
      json_mesh_translation["y"] = Number(translation[1]);
      json_mesh_translation["z"] = Number(translation[2]);
      json_mesh["translation"] = json_mesh_translation;
    }
    {
      fbxDouble3 rotation = fbx_node->LclRotation.Get();
      Object json_mesh_rotation;
      json_mesh_rotation["x"] = Number(rotation[0]);
      json_mesh_rotation["y"] = Number(rotation[1]);
      json_mesh_rotation["z"] = Number(rotation[2]);
      json_mesh["rotation"] = json_mesh_rotation;
    }
    {
      int material_count = fbx_node->GetMaterialCount(); 
      Array json_mesh_materials;
      
      for (int material_index = 0; material_index < material_count; material_index++) {
        KFbxSurfaceMaterial* surface_material = fbx_node->GetMaterial(material_index);
        
        Object json_material;
        
        Array json_textures;
        int textureIndex = 0;
        FOR_EACH_TEXTURE(textureIndex) {
          KFbxProperty property = surface_material->FindProperty(KFbxLayerElement::TEXTURE_CHANNEL_NAMES[textureIndex]);
          int layered_texture_count = property.GetSrcObjectCount(KFbxTexture::ClassId);
          for (int layered_texture_index = 0; layered_texture_index < layered_texture_count; ++layered_texture_index) {
            KFbxTexture* texture = KFbxCast <KFbxTexture> (property.GetSrcObject(KFbxTexture::ClassId, layered_texture_index));
            if(texture) {
              KFbxFileTexture *file_texture = KFbxCast<KFbxFileTexture>(texture);
              if (file_texture) {
                Object json_texture;
                json_texture["filename"] = String(file_texture->GetFileName());
                json_textures.Insert(json_texture);
              }               
            }
          }
        }
        json_material["textures"] = json_textures;
        
        KFbxSurfaceLambert* lambert_material = KFbxCast<KFbxSurfaceLambert>(surface_material);
        
        if (lambert_material) {
          Object diffuse;
          double diffuse_r = lambert_material->Diffuse.Get()[0];
          diffuse["r"] = Number(diffuse_r);
          double diffuse_g = lambert_material->Diffuse.Get()[1];
          diffuse["g"] = Number(diffuse_g);
          double diffuse_b = lambert_material->Diffuse.Get()[2];
          diffuse["b"] = Number(diffuse_b);
          json_material["diffuse"] = diffuse;

          Object ambient;
          double ambient_r = lambert_material->Ambient.Get()[0];
          ambient["r"] = Number(ambient_r);
          double ambient_g = lambert_material->Ambient.Get()[1];
          ambient["g"] = Number(ambient_g);
          double ambient_b = lambert_material->Ambient.Get()[2];
          ambient["b"] = Number(ambient_b);
          json_material["ambient"] = ambient;
          
          KFbxProperty specular_property = lambert_material->FindProperty("SpecularColor");
          fbxDouble3 specular_data;
          specular_property.Get(&specular_data, eDOUBLE3);
          Object specular;
          float specular_r = specular_data[0];
          specular["r"] = Number(specular_r);
          float specular_g = specular_data[1];
          specular["g"] = Number(specular_g);
          float specular_b = specular_data[2];
          specular["b"] = Number(specular_b);
          json_material["specular"] = specular;            
        }
        
        json_mesh_materials.Insert(json_material);
      }
      json_mesh["materials"] = json_mesh_materials;
    }
    json_mesh["uv_stride"] = Number(2);
    json_mesh["vertex_stride"] = Number(3);
    json_mesh["normal_stride"] = Number(3);
    meshes_array.Insert(json_mesh);
  }
  
  for(int j = 0; j < fbx_node->GetChildCount(); j++) {
    recurse_over_model(fbx_node->GetChild(j), meshes_array);
  }
}