StdMat2 *NifImporter::ImportMaterialAndTextures(ImpNode *node, NiAVObjectRef avObject)
{
   // Texture
   NiMaterialPropertyRef matRef = avObject->GetPropertyByType(NiMaterialProperty::TYPE);
   if (matRef != NULL){

		StdMat2 *m = NewDefaultStdMat();
		m->SetName(matRef->GetName().c_str());
		if (showTextures) {
			m->SetMtlFlag(MTL_DISPLAY_ENABLE_FLAGS, TRUE);
		}

		// try the civ4 shader first then default back to normal shaders
		if (ImportNiftoolsShader(node, avObject, m)) {
			return m;
		}

		NiTexturingPropertyRef texRef = avObject->GetPropertyByType(NiTexturingProperty::TYPE);
		NiWireframePropertyRef wireRef = avObject->GetPropertyByType(NiWireframeProperty::TYPE);
		NiAlphaPropertyRef alphaRef = avObject->GetPropertyByType(NiAlphaProperty::TYPE);
		NiStencilPropertyRef stencilRef = avObject->GetPropertyByType(NiStencilProperty::TYPE);
		NiShadePropertyRef shadeRef = avObject->GetPropertyByType(NiShadeProperty::TYPE);
		vector<NiPropertyRef> props = avObject->GetProperties();

		if (IsFallout3()) {
			m->SetAmbient(Color(0.588f, 0.588f, 0.588f),0);
			m->SetDiffuse(Color(0.588f, 0.588f, 0.588f),0);
			m->SetSpecular(Color(0.902f, 0.902f, 0.902f),0);
		} else {
			m->SetAmbient(TOCOLOR(matRef->GetAmbientColor()),0);
			m->SetDiffuse(TOCOLOR(matRef->GetDiffuseColor()),0);
			m->SetSpecular(TOCOLOR(matRef->GetSpecularColor()),0);
		}
      Color c = TOCOLOR(matRef->GetEmissiveColor());
      if (c.r != 0 || c.b != 0 || c.g != 0) {
         m->SetSelfIllumColorOn(TRUE);
         m->SetSelfIllumColor(c,0);
      }
      m->SetShinStr(0.0,0);
      m->SetShininess(matRef->GetGlossiness()/100.0,0);
      m->SetOpacity(matRef->GetTransparency(),0);

      bool hasShaderAttributes = (wireRef != NULL) || (stencilRef != NULL) || (shadeRef != NULL);
      if (m->SupportsShaders() && hasShaderAttributes) {
         if (Shader *s = m->GetShader()) {
            if (wireRef != NULL && (wireRef->GetFlags() & 1)) {
               BOOL value = TRUE;
               m->SetWire(value);
            }
            if (stencilRef != NULL) {
				if (stencilRef->GetFaceDrawMode() == DRAW_BOTH) {
                  BOOL value = TRUE;
                  m->SetTwoSided(value);
               }
            }
            if (shadeRef != NULL && shadeRef->GetFlags() & 1) {
               m->SetFaceted(TRUE);
            }
         }
      }

      if (NULL != texRef)
      {
         // Handle Base/Detail ???
         if (texRef->HasTexture(DECAL_0_MAP)){
            if (Texmap* tex = CreateTexture(texRef->GetTexture(DECAL_0_MAP)))
               m->SetSubTexmap(ID_DI, tex);
            if (texRef->HasTexture(BASE_MAP)){
               m->LockAmbDiffTex(FALSE);
               if (Texmap* tex = CreateTexture(texRef->GetTexture(BASE_MAP)))
                  m->SetSubTexmap(ID_AM, tex);
            }
         } else if (texRef->HasTexture(BASE_MAP)) {
			 if (Texmap* tex = CreateTexture(texRef->GetTexture(BASE_MAP))) {
               m->SetSubTexmap(ID_DI, tex);
			   if (showTextures) gi->ActivateTexture(tex,m);
			 }
         } 
         // Handle Bump map
         if (texRef->HasTexture(BUMP_MAP)) {
            if (Texmap* tex = CreateTexture(texRef->GetTexture(BUMP_MAP)))
               m->SetSubTexmap(ID_BU, CreateNormalBump(NULL, tex));
         }
         // Shiny map
         if (texRef->HasTexture(GLOSS_MAP)) {
            if (Texmap* tex = CreateTexture(texRef->GetTexture(GLOSS_MAP)))
               m->SetSubTexmap(ID_SS, tex);
         }
         // Self illumination
         if (texRef->HasTexture(GLOW_MAP)) {
            if (Texmap* tex = CreateTexture(texRef->GetTexture(GLOW_MAP)))
               m->SetSubTexmap(ID_SI, tex);
         }

         // Custom Shader Handling
         int nTex = texRef->GetShaderTextureCount();
         if (nTex > 0) {
            list<NiExtraDataRef> data = avObject->GetExtraData();
            NiGeometryRef trigeom = DynamicCast<NiGeometry>(avObject);
            if (trigeom->HasShader()) {
               for (list<NiExtraDataRef>::iterator itr = data.begin(); itr != data.end(); ++itr) {
                  if ( NiIntegerExtraDataRef idx = DynamicCast<NiIntegerExtraData>(*itr) ) {
                     string name = idx->GetName();
                     if ( wildmatch("*Index", name) ) {
                        int shader = idx->GetData();
                        if (shader < nTex) {
                           if ( name == "NormalMapIndex" ) {
                              if (Texmap* tex = CreateTexture(texRef->GetShaderTexture(shader)))
                                 m->SetSubTexmap(ID_BU, CreateNormalBump(NULL, tex));
                           } else if ( name == "SpecularIntensity" ) {
                              if (Texmap* tex = CreateTexture(texRef->GetShaderTexture(shader)))
                                 m->SetSubTexmap(ID_SP, CreateNormalBump(NULL, tex));
                           }
                        }
                     }
                  }
               }
            }
         }
      }
		if (NiTexturePropertyRef tex2Ref = avObject->GetPropertyByType(NiTextureProperty::TYPE)){
			// Handle Base/Detail ???
			if (Texmap* tex = CreateTexture(tex2Ref)) {
				m->SetSubTexmap(ID_DI, tex);
			} 
		}
		if (BSShaderNoLightingPropertyRef noLightShadeRef = SelectFirstObjectOfType<BSShaderNoLightingProperty>(props)) {
			if ( Texmap* tex = CreateTexture( noLightShadeRef->GetFileName() ) ) {
				m->SetSubTexmap(ID_DI, tex);
			}
		}
		if (BSShaderPPLightingPropertyRef ppLightShadeRef = SelectFirstObjectOfType<BSShaderPPLightingProperty>(props)) {
			if ( BSShaderTextureSetRef textures = ppLightShadeRef->GetTextureSet() ) {
				if ( Texmap* tex = CreateTexture( textures->GetTexture(0) ) )
					m->SetSubTexmap(ID_DI, tex);
            if ( Texmap* tex = CreateTexture( textures->GetTexture(1) ) )
               m->SetSubTexmap(ID_BU, CreateNormalBump(NULL, tex));
            if ( Texmap* tex = CreateTexture( textures->GetTexture(3) ) )
               m->SetSubTexmap(ID_SI, tex);
            if ( Texmap* tex = CreateTexture( textures->GetTexture(4) ) )
               m->SetSubTexmap(ID_RL, tex);
            if ( Texmap* tex = CreateTexture( textures->GetTexture(5) ) ) {
               if ( Texmap* mask = CreateTexture( textures->GetTexture(2) ) )
                  tex = CreateMask(NULL, tex, mask);
               m->SetSubTexmap(ID_SP, tex);
            }
			}
		}
		if (SkyShaderPropertyRef skyShadeRef = SelectFirstObjectOfType<SkyShaderProperty>(props)) {
			if ( Texmap* tex = CreateTexture( skyShadeRef->GetFileName() ) ) {
				m->SetSubTexmap(ID_DI, tex);
			}
		}
		if (TileShaderPropertyRef tileShadeRef = SelectFirstObjectOfType<TileShaderProperty>(props)) {
			if ( Texmap* tex = CreateTexture( tileShadeRef->GetFileName() ) ) {
				m->SetSubTexmap(ID_DI, tex);
			}
		}
		if (TallGrassShaderPropertyRef grassShadeRef = SelectFirstObjectOfType<TallGrassShaderProperty>(props)) {
			if ( Texmap* tex = CreateTexture( grassShadeRef->GetFileName() ) ) {
				m->SetSubTexmap(ID_DI, tex);
			}
		}
		if (Lighting30ShaderPropertyRef lighting30ShadeRef = SelectFirstObjectOfType<Lighting30ShaderProperty>(props)) {
         if ( BSShaderTextureSetRef textures = lighting30ShadeRef->GetTextureSet() ) {
            if ( Texmap* tex = CreateTexture( textures->GetTexture(0) ) )
               m->SetSubTexmap(ID_DI, tex);
            if ( Texmap* tex = CreateTexture( textures->GetTexture(1) ) )
               m->SetSubTexmap(ID_BU, CreateNormalBump(NULL, tex));
            if ( Texmap* tex = CreateTexture( textures->GetTexture(3) ) )
               m->SetSubTexmap(ID_SI, tex);
            if ( Texmap* tex = CreateTexture( textures->GetTexture(4) ) )
               m->SetSubTexmap(ID_RL, tex);
            if ( Texmap* tex = CreateTexture( textures->GetTexture(5) ) ) {
               if ( Texmap* mask = CreateTexture( textures->GetTexture(2) ) )
                  tex = CreateMask(NULL, tex, mask);
               m->SetSubTexmap(ID_SP, tex);
            }
         }
		}
		return m;
   }
   return NULL;
}
// --[  Method  ]---------------------------------------------------------------
//
//  - Class     : CStravaganzaMaxTools
//
//  - prototype : bool BuildShaders()
//
//  - Purpose   : Builds the shader list from MAX's materials.
//                Preview mode requires texture files to be stored with full
//                path in order to load them. When we export, we only store the
//                filename. Another thing is that in the export mode, we copy
//                all textures into the path specified by the user if that
//                option is checked.
//
// -----------------------------------------------------------------------------
bool CStravaganzaMaxTools::BuildShaders()
{
	std::vector<Mtl*>::iterator it;

	assert(m_vecShaders.empty());

	if(!m_bPreview && m_bCopyTextures && m_strTexturePath == "")
	{
		CLogger::NotifyWindow("Textures won't be copied\nSpecify a valid output texture path first");
	}

	LOG.Write("\n\n-Building shaders: ");

	for(it = m_vecMaterials.begin(); it != m_vecMaterials.end(); ++it)
	{
		Mtl* pMaxMaterial = *it;
		assert(pMaxMaterial);

		LOG.Write("\n    %s", pMaxMaterial->GetName().data());
		CShaderStandard* pShaderStd = new CShaderStandard;
		pShaderStd->SetName(pMaxMaterial->GetName().data());

		// Properties

		StdMat2 *pMaxStandardMtl = NULL;
		StdMat2 *pMaxBakedMtl    = NULL;

		float fAlpha;

		if(pMaxMaterial->ClassID() == Class_ID(DMTL_CLASS_ID, 0))
		{
			pMaxStandardMtl = (StdMat2 *)pMaxMaterial;
		}
		else if(pMaxMaterial->ClassID() == Class_ID(BAKE_SHELL_CLASS_ID, 0))
		{
			pMaxStandardMtl = (StdMat2 *)pMaxMaterial->GetSubMtl(0);
			pMaxBakedMtl    = (StdMat2 *)pMaxMaterial->GetSubMtl(1);
		}

		if(pMaxStandardMtl)
		{
			// Standard material

			fAlpha = pMaxStandardMtl->GetOpacity(0);

			Shader* pMaxShader = pMaxStandardMtl->GetShader();

			CVector4 v4Specular = ColorToVector4(pMaxStandardMtl->GetSpecular(0), 0.0f) * pMaxShader->GetSpecularLevel(0, 0);

			pShaderStd->SetAmbient  (ColorToVector4(pMaxStandardMtl->GetAmbient(0),  0.0f));
			pShaderStd->SetDiffuse  (ColorToVector4(pMaxStandardMtl->GetDiffuse(0),  fAlpha));
			pShaderStd->SetSpecular (v4Specular);
			pShaderStd->SetShininess(pMaxShader->GetGlossiness(0, 0) * 128.0f);

			if(pMaxStandardMtl->GetTwoSided() == TRUE)
			{
				pShaderStd->SetTwoSided(true);
			}

			// Need to cast to StdMat2 in order to get access to IsFaceted().
			// ¿Is StdMat2 always the interface for standard materials?
			if(((StdMat2*)pMaxStandardMtl)->IsFaceted())
			{
				pShaderStd->SetFaceted(true);
			}

			if(pMaxStandardMtl->GetWire() == TRUE)
			{
				pShaderStd->SetPostWire(true);
				pShaderStd->SetWireLineThickness(pMaxStandardMtl->GetWireSize(0));
			}
		}
		else
		{
			// Material != Standard

			fAlpha = 1.0f; // pMaxMaterial->GetXParency();

			pShaderStd->SetAmbient  (ColorToVector4(pMaxMaterial->GetAmbient(),  0.0f));
			pShaderStd->SetDiffuse  (ColorToVector4(pMaxMaterial->GetDiffuse(),  fAlpha));
			pShaderStd->SetSpecular (CVector4(0.0f, 0.0f, 0.0f, 0.0f));
			pShaderStd->SetShininess(0.0f);
		}

		// Layers

		if(!pMaxStandardMtl)
		{
			m_vecShaders.push_back(pShaderStd);
			continue;
		}

		bool bDiffuseMap32Bits = false;
		StdMat2 *pStandardMtl;

		for(int i = 0; i < 3; i++)
		{
			int nMap;

			pStandardMtl = pMaxStandardMtl;

			// 0 = diffuse, 1 == bump, 2 = lightmap (self illumination slot) or envmap (reflection slot)

			if(i == 0)
			{
				nMap = ID_DI;
			}
			else if(i == 1)
			{
				nMap = ID_BU;

				// If its a baked material, get the bump map from there

				if(pMaxBakedMtl)
				{
					pStandardMtl = pMaxBakedMtl;
				}
			}
			else if(i == 2)
			{
				bool bBaked = false;

				// If its a baked material, get the map2 (lightmap) from there

				if(pMaxBakedMtl)
				{
					if(pMaxBakedMtl->GetMapState(ID_SI) == MAXMAPSTATE_ENABLED)
					{
						bBaked       = true;
						nMap         = ID_SI;
						pStandardMtl = pMaxBakedMtl;
					}
				}

				if(!bBaked)
				{
					if(pStandardMtl->GetMapState(ID_SI) == MAXMAPSTATE_ENABLED)
					{
						nMap = ID_SI;
					}
					else
					{
						nMap = ID_RL;
					}
				}
			}

			// Check validity

			if(pStandardMtl->GetMapState(nMap) != MAXMAPSTATE_ENABLED)
			{
				if(i == 0)
				{
					LOG.Write("\n        No diffuse. Skipping.");
					break;
				}

				continue;
			}

			Texmap* pMaxTexmap = pStandardMtl->GetSubTexmap(nMap);

			if(!pMaxTexmap)
			{
				if(i == 0)
				{
					LOG.Write("\n        No diffuse. Skipping.");
					break;
				}

				continue;
			}

			// Get texmaps

			std::vector<std::string> vecTextures, vecPaths;

			CShaderStandard::SLayerInfo  layerInfo;
			CShaderStandard::SBitmapInfo bitmapInfo;

			if(pMaxTexmap->ClassID() == Class_ID(BMTEX_CLASS_ID, 0))
			{
				BitmapTex* pMaxBitmapTex = (BitmapTex*)pMaxTexmap;
				Bitmap*    pMaxBitmap    = pMaxBitmapTex->GetBitmap(SECONDS_TO_TICKS(m_fStartTime));
				StdUVGen*  pMaxUVGen     = pMaxBitmapTex->GetUVGen();

				if(!pMaxBitmap)
				{
					if(i == 0)
					{
						LOG.Write("\n        Invalid diffuse. Skipping.");
						break;
					}
					continue;
				}

				assert(pMaxUVGen);

				BitmapInfo bi = pMaxBitmap->Storage()->bi;

				// bi.Name() returns the full path
				// bi.Filename() returns just the filename

				vecTextures.push_back(bi.Filename());
				vecPaths.   push_back(bi.Name());

				LOG.Write("\n        Bitmap %s", vecTextures[0].data());

				// Check if diffuse texture has alpha channel

				if(i == 0)
				{
					CBitmap    bitmap;
					CInputFile bitmapFile;

					if(!bitmapFile.Open(bi.Name(), false))
					{
						CLogger::NotifyWindow("WARNING - CStravaganzaMaxTools::BuildShaders():\nUnable to load file %s", bi.Name());
					}
					else
					{
						if(!bitmap.Load(&bitmapFile, GetFileExt(bi.Name())))
						{
							CLogger::NotifyWindow("WARNING - CStravaganzaMaxTools::BuildShaders():\nUnable to load bitmap %s", bi.Name());
						}
						else
						{
							if(bitmap.GetBpp() == 32)
							{
								bDiffuseMap32Bits = true;
								LOG.Write(" (with alpha channel)");
							}
							bitmap.Free();
						}
						bitmapFile.Close();
					}
				}

				// Ok, copy properties

				layerInfo.texInfo.bLoop        = false;
				layerInfo.texInfo.eTextureType = UtilGL::Texturing::CTexture::TEXTURE2D;

				bitmapInfo.strFile         = m_bPreview ? bi.Name() : bi.Filename();
				bitmapInfo.bTile           = ((pMaxUVGen->GetTextureTiling() & (U_WRAP | V_WRAP)) == (U_WRAP | V_WRAP)) ? true : false;
				bitmapInfo.fSeconds        = 0.0f;
				bitmapInfo.bForceFiltering = false;
				bitmapInfo.eFilter         = UtilGL::Texturing::FILTER_TRILINEAR; // won't be used (forcefiltering = false)
				
				layerInfo.texInfo.m_vecBitmaps.push_back(bitmapInfo);

				layerInfo.eTexEnv          = nMap == ID_RL ? CShaderStandard::TEXENV_ADD : CShaderStandard::TEXENV_MODULATE;
				layerInfo.eUVGen           = pMaxUVGen->GetCoordMapping(0) == UVMAP_SPHERE_ENV ? CShaderStandard::UVGEN_ENVMAPPING : CShaderStandard::UVGEN_EXPLICITMAPPING;
				layerInfo.uMapChannel      = pMaxUVGen->GetMapChannel();
				layerInfo.v3ScrollSpeed    = CVector3(0.0f, 0.0f, 0.0f);
				layerInfo.v3RotationSpeed  = CVector3(0.0f, 0.0f, 0.0f);
				layerInfo.v3ScrollOffset   = CVector3(pMaxUVGen->GetUOffs(0), pMaxUVGen->GetVOffs(0), 0.0f);
				layerInfo.v3RotationOffset = CVector3(pMaxUVGen->GetUAng(0),  pMaxUVGen->GetVAng(0),  pMaxUVGen->GetWAng(0));
			}
			else if(pMaxTexmap->ClassID() == Class_ID(ACUBIC_CLASS_ID, 0))
			{
				ACubic*       pMaxCubic  = (ACubic*)pMaxTexmap;
				IParamBlock2* pBlock     = pMaxCubic->pblock;
				Interval      validRange = m_pMaxInterface->GetAnimRange();

				for(int nFace = 0; nFace < 6; nFace++)
				{
					int nMaxFace;

					switch(nFace)
					{
					case 0: nMaxFace = 3; break;
					case 1: nMaxFace = 2; break;
					case 2: nMaxFace = 1; break;
					case 3: nMaxFace = 0; break;
					case 4: nMaxFace = 5; break;
					case 5: nMaxFace = 4; break;
					}

					TCHAR *name;
					pBlock->GetValue(acubic_bitmap_names, TICKS_TO_SECONDS(m_fStartTime), name, validRange, nMaxFace);

					vecPaths.push_back(name);

					CStr path, file, ext;
					SplitFilename(CStr(name), &path, &file, &ext);

					std::string strFile = std::string(file.data()) + ext.data();

					vecTextures.push_back(strFile);

					bitmapInfo.strFile         = m_bPreview ? name : strFile;
					bitmapInfo.bTile           = false;
					bitmapInfo.fSeconds        = 0.0f;
					bitmapInfo.bForceFiltering = false;
					bitmapInfo.eFilter         = UtilGL::Texturing::FILTER_TRILINEAR;
					
					layerInfo.texInfo.m_vecBitmaps.push_back(bitmapInfo);
				}

				layerInfo.texInfo.bLoop        = false;
				layerInfo.texInfo.eTextureType = UtilGL::Texturing::CTexture::TEXTURECUBEMAP;

				layerInfo.eTexEnv          = nMap == ID_RL ? CShaderStandard::TEXENV_ADD : CShaderStandard::TEXENV_MODULATE;
				layerInfo.eUVGen           = CShaderStandard::UVGEN_ENVMAPPING;
				layerInfo.uMapChannel      = 0;
				layerInfo.v3ScrollSpeed    = CVector3(0.0f, 0.0f, 0.0f);
				layerInfo.v3RotationSpeed  = CVector3(0.0f, 0.0f, 0.0f);
				layerInfo.v3ScrollOffset   = CVector3(0.0f, 0.0f, 0.0f);
				layerInfo.v3RotationOffset = CVector3(0.0f, 0.0f, 0.0f);
			}
			else
			{
				if(i == 0)
				{
					LOG.Write("\n        No diffuse. Skipping.");
					break;
				}
				continue;
			}

			if(!m_bPreview && m_bCopyTextures && m_strTexturePath != "")
			{
				for(int nTex = 0; nTex != vecTextures.size(); nTex++)
				{
					// Copy textures into the specified folder

					std::string strDestPath = m_strTexturePath;

					if(strDestPath[strDestPath.length() - 1] != '\\')
					{
						strDestPath.append("\\", 1);
					}

					strDestPath.append(vecTextures[nTex]);

					if(!CopyFile(vecPaths[nTex].data(), strDestPath.data(), FALSE))
					{
						CLogger::NotifyWindow("Unable to copy %s to\n%s", vecPaths[i], strDestPath.data());
					}
				}
			}

			if(layerInfo.eUVGen == CShaderStandard::UVGEN_ENVMAPPING && i == 1)
			{
				CLogger::NotifyWindow("%s : Bump with spheremapping not supported", pShaderStd->GetName().data());
			}
			else
			{
				// Add layer

				switch(i)
				{
				case 0: pShaderStd->SetLayer(CShaderStandard::LAYER_DIFF, layerInfo); break;
				case 1: pShaderStd->SetLayer(CShaderStandard::LAYER_BUMP, layerInfo); break;
				case 2: pShaderStd->SetLayer(CShaderStandard::LAYER_MAP2, layerInfo); break;
				}
			}
		}

		// ¿Do we need blending?

		if(ARE_EQUAL(fAlpha, 1.0f) && !bDiffuseMap32Bits)
		{
			pShaderStd->SetBlendSrcFactor(UtilGL::States::BLEND_ONE);
			pShaderStd->SetBlendDstFactor(UtilGL::States::BLEND_ZERO);
		}
		else
		{
			pShaderStd->SetBlendSrcFactor(UtilGL::States::BLEND_SRCALPHA);
			pShaderStd->SetBlendDstFactor(UtilGL::States::BLEND_INVSRCALPHA);
		}

		// Add shader

		m_vecShaders.push_back(pShaderStd);
	}

	return true;
}
	//------------------------------
	StdMat2* MaterialCreator::createStandardMaterial( const COLLADAFW::EffectCommon& effectCommon, const String& name, const MaterialCreator::MaterialIdentifier& materialIdentifier )
	{
		StdMat2* material = NewDefaultStdMat();


		COLLADAFW::EffectCommon::ShaderType shaderType = effectCommon.getShaderType();
		switch ( shaderType )
		{
		case COLLADAFW::EffectCommon::SHADER_CONSTANT: 
			material->SetFaceted(true); // BUG393: Max actually does not support a constant shader!
		case COLLADAFW::EffectCommon::SHADER_BLINN: 
			material->SwitchShader(Class_ID(StandardMaterial::STD2_BLINN_SHADER_CLASS_ID, 0)); 
			break;
		case COLLADAFW::EffectCommon::SHADER_LAMBERT:
		case COLLADAFW::EffectCommon::SHADER_PHONG:
		case COLLADAFW::EffectCommon::SHADER_UNKNOWN:
		default: 
			material->SwitchShader(Class_ID(StandardMaterial::STD2_PHONG_CLASS_ID, 0)); 
			break;
		}


		// Retrieve the shader parameter blocks
		Shader* materialShader = material->GetShader();
		IParamBlock2* shaderParameters = (IParamBlock2*) materialShader->GetReference(0);
		IParamBlock2* extendedParameters = (IParamBlock2*) material->GetReference(StandardMaterial::EXTENDED_PB_REF);

		// Common material parameters
		material->SetName(name.c_str());
		const COLLADAFW::ColorOrTexture& diffuse = effectCommon.getDiffuse();

		if ( diffuse.isColor() )
			material->SetDiffuse( toMaxColor(diffuse), 0);

		const COLLADAFW::ColorOrTexture& emission = effectCommon.getEmission();
		if ( emission.isColor() )
		{
			material->SetSelfIllumColorOn(TRUE);
			material->SetSelfIllumColor( toMaxColor(emission), 0);
		}
		else
		{
			material->SetSelfIllumColorOn(FALSE);
			material->SetSelfIllum( 0, 0 );
		}

		float maxOpacity = 1;
		const COLLADAFW::ColorOrTexture& opacity = effectCommon.getOpacity();
		if ( opacity.isColor() )
		{
			const COLLADAFW::Color& opacityColor = opacity.getColor(); 
			float averageTransparent = (float)(opacityColor.getRed() + opacityColor.getGreen() + opacityColor.getBlue())/3; 
			maxOpacity = averageTransparent;
		}

		if ( getDocumentImporter()->getInvertTransparency() )
		{
			maxOpacity = 1 - maxOpacity;
		}

		// Max seems to like to have opacity 0 for opacity textures
		if ( opacity.isTexture() )
		{
			material->SetOpacity( 0, 0);
		}
		else
		{
			material->SetOpacity( maxOpacity, 0);
		}

		if (shaderType != COLLADAFW::EffectCommon::SHADER_CONSTANT && shaderType != COLLADAFW::EffectCommon::SHADER_UNKNOWN)
		{
			// Unlock the ambient and diffuse colors
			materialShader->SetLockAD(FALSE);
			materialShader->SetLockADTex(FALSE);
			material->LockAmbDiffTex(FALSE);
			material->SyncADTexLock(FALSE);

			// Lambert/Phong material parameters
			const COLLADAFW::ColorOrTexture& ambient = effectCommon.getAmbient();
			if ( ambient.isColor() )
				material->SetAmbient( toMaxColor(ambient), 0);
		}
		else
		{
			// Approximate constant shader, specular is the same color
			if ( diffuse.isColor() )
				material->SetSpecular( toMaxColor(diffuse), 0 );
		}

		const COLLADAFW::ColorOrTexture& specular = effectCommon.getSpecular();
		const COLLADAFW::FloatOrParam& shininessFloatOrParam = effectCommon.getShininess();
		float shininess = 1;
		if ( shininessFloatOrParam.getType() == COLLADAFW::FloatOrParam::FLOAT )
		{
			shininess = shininessFloatOrParam.getFloatValue();
		}
		if ( shaderType == COLLADAFW::EffectCommon::SHADER_PHONG || shaderType == COLLADAFW::EffectCommon::SHADER_BLINN)
		{
			// Phong material parameters
			if ( specular.isColor() )
				material->SetSpecular( toMaxColor(specular), 0 );

			material->SetShininess(ConversionFunctors::fromPercent(shininess), 0);
			material->SetShinStr(ConversionFunctors::fromPercent(shininess), 0);
		}

		//create and assign textures
		createAndAssignTexture( material, effectCommon, &COLLADAFW::EffectCommon::getAmbient, ID_AM, materialIdentifier.ambientMapChannel);
		createAndAssignTexture( material, effectCommon, &COLLADAFW::EffectCommon::getDiffuse, ID_DI, materialIdentifier.diffuseMapChannel);
		createAndAssignTexture( material, effectCommon, &COLLADAFW::EffectCommon::getSpecular, ID_SP, materialIdentifier.specularMapChannel);
		createAndAssignTexture( material, effectCommon, &COLLADAFW::EffectCommon::getEmission, ID_SI, materialIdentifier.emissionMapChannel);
		createAndAssignTexture( material, effectCommon, &COLLADAFW::EffectCommon::getOpacity, ID_OP, materialIdentifier.opacityMapChannel);

		return material;
	}