//----------------------------------------------------------------------------
void SceneBuilder::ConvertMaterials ()
{
	int quantity = mMtls.GetQuantity();

	mMtlTreeList.resize(quantity);
	for (int i=0; i<quantity; i++)
	{
		Mtl *mtl = mMtls.GetMtl(i);
		if (mtl)
		{
			ConvertMaterial(*mtl, mMtlTreeList[i]);
		}
	}
}
void LeftHandConvertor::ProcessScene()
{
  ConvertNode( mAssimpScene->mRootNode );

  for( std::size_t i=0; i < mAssimpScene->mNumMeshes; ++i )
  {
    ConvertMesh( mAssimpScene->mMeshes[i] );
  }

  for( std::size_t i=0; i < mAssimpScene->mNumMaterials; ++i )
  {
    ConvertMaterial( mAssimpScene->mMaterials[i] );
  }

  for ( std::size_t i=0; i < mAssimpScene->mNumAnimations; ++i )
  {
    aiAnimation* animation = mAssimpScene->mAnimations[i];
    for( std::size_t j=0; j < animation->mNumChannels; ++j )
    {
      aiNodeAnim* nodeAnimation = animation->mChannels[j];
      ConvertAnimation( nodeAnimation );
    }
  }
}
//----------------------------------------------------------------------------
void SceneBuilder::ConvertMaterial (Mtl &mtl, MtlTree &mtlTree)
{
	// 光照属性
	PX2::Shine *shine = new0 PX2::Shine;
	Color color = mtl.GetAmbient();
	float alpha = 1.0f - mtl.GetXParency();
	shine->Ambient = PX2::Float4(color.r, color.g, color.b, 1.0f);
	color = mtl.GetDiffuse();
	shine->Diffuse = PX2::Float4(color.r, color.g, color.b, alpha);
	color = mtl.GetSpecular();
	float shininess = mtl.GetShininess()*2.0f;
	shine->Specular = PX2::Float4(color.r, color.g, color.b, shininess);

	const char *name = (const char*)mtl.GetName();
	shine->SetName(name);

	mtlTree.SetShine(shine);

	bool IsDirect9Shader = false;

	if (mtl.ClassID() == Class_ID(CMTL_CLASS_ID, 0)
		|| mtl.ClassID() == Class_ID(DMTL_CLASS_ID, 0))
	{
		StdMat2 *stdMat2 = (StdMat2*)(&mtl);
		Interval valid = FOREVER;
		stdMat2->Update(mTimeStart, valid);

		std::string strName(stdMat2->GetName());
		bool doubleSide = (stdMat2->GetTwoSided()==1);

		char strBitMapName[256];
		memset(strBitMapName, 0, 256*sizeof(char));
		std::string resourcePath;

		PX2::Shader::SamplerFilter filter = PX2::Shader::SF_LINEAR_LINEAR;
		PX2::Shader::SamplerCoordinate uvCoord = PX2::Shader::SC_REPEAT;
		PX2_UNUSED(uvCoord);

		if (stdMat2->MapEnabled(ID_DI))
		{
			BitmapTex *tex = (BitmapTex*)stdMat2->GetSubTexmap(ID_DI);

			BitmapInfo bI;
			const char *mapName = tex->GetMapName();
			TheManager->GetImageInfo(&bI, mapName);
			strcpy(strBitMapName, bI.Name());

			std::string fullName = std::string(strBitMapName);
			std::string::size_type sizeT = fullName.find_first_not_of(mSettings->SrcRootDir);
			resourcePath = std::string(strBitMapName).substr(sizeT);

			StdUVGen* uvGen = tex->GetUVGen();
			PX2_UNUSED(uvGen);
			int filType = tex->GetFilterType();
			switch (filType)
			{
				case FILTER_PYR:
					filter = PX2::Shader::SF_LINEAR_LINEAR;
					break;
				case FILTER_SAT:
					filter = PX2::Shader::SF_NEAREST;
					break;
				default:
					break;
			}
		}
		else
		{
			sprintf(strBitMapName, "%s/%s", mSettings->SrcRootDir, PX2_DEFAULT_TEXTURE);
			resourcePath = PX2_DEFAULT_TEXTURE;
		}

		PX2::Texture2D *tex2d = PX2::DynamicCast<PX2::Texture2D>(
			PX2::ResourceManager::GetSingleton().BlockLoad(strBitMapName));
		tex2d->SetResourcePath(resourcePath);

		if (tex2d)
		{
			PX2::Texture2DMaterial *tex2dMtl = new0 PX2::Texture2DMaterial(filter, 
				uvCoord, uvCoord);
			if (doubleSide)
			{
				tex2dMtl->GetCullProperty(0, 0)->Enabled = false;
			}

			PX2::MaterialInstance *instance = tex2dMtl->CreateInstance(tex2d);

			mtlTree.SetMaterialInstance(instance);
		}
		else
		{
			PX2::VertexColor4Material *vcMtl = new0 PX2::VertexColor4Material();
			PX2::MaterialInstance *instance = vcMtl->CreateInstance();
			mtlTree.SetMaterialInstance(instance);
		}
	}
	else if (mtl.ClassID() == Class_ID(MULTI_CLASS_ID, 0))
	{
	}
	else if (mtl.ClassID() == DIRECTX_9_SHADER_CLASS_ID)
	{
		IsDirect9Shader = true;

		IDxMaterial* dxMtl = (IDxMaterial*)mtl.GetInterface(IDXMATERIAL_INTERFACE);
		char *effectName = dxMtl->GetEffectFilename();
		IParamBlock2 *paramBlock = mtl.GetParamBlock(0);

		std::string outPath;
		std::string outBaseName;
		std::string outExtention;
		PX2::StringHelp::SplitFullFilename(effectName, outPath, outBaseName,
			outExtention);

		PX2::ShinePtr shineStandard = new0 PX2::Shine();
		bool alphaVertex = false;
		PX2::Texture2DPtr diffTex;
		bool normalEnable = false;
		PX2::Texture2DPtr normalTex;
		float normalScale = 0.0f;
		bool specEnable = false;
		PX2::Texture2DPtr specTex;
		float specPower = 0.0f;
		bool reflectEnable = false;
		PX2::TextureCubePtr reflectTex;
		float reflectPower = 0.0f;
		bool doubleSide = false;
		int blendMode = 2;

		ParamBlockDesc2 *paramDesc = 0;
		int numParam = 0;
		if (paramBlock)
		{
			paramDesc = paramBlock->GetDesc();
			numParam = paramBlock->NumParams();

			ParamType2 paramType;
			for (int i=0; i<numParam; i++)
			{
				std::string parmName;
				PX2::Float4 color4 = PX2::Float4(0.0f, 0.0f, 0.0f, 0.0f);
				PX2::Float3 color3 = PX2::Float3(0.0f, 0.0f, 0.0f);
				float floatValue = 0.0f;
				bool boolValue = false;
				float *floatTable = 0;
				int intValue = 0;
				std::string str;
				PX2::Texture2D *tex2d = 0;

				paramType = paramBlock->GetParameterType((ParamID)i);

				if (TYPE_STRING == paramType)
					ConvertStringAttrib(paramBlock, i, parmName, str);
				else if (TYPE_FLOAT == paramType)
					ConvertFloatAttrib(paramBlock, i, parmName, floatValue);
				else if (TYPE_INT == paramType)
					ConvertIntAttrib(paramBlock, i, parmName, intValue);
				else if (TYPE_RGBA == paramType)
					ConvertColorAttrib(paramBlock, i, parmName, color4, i);
				else if (TYPE_POINT3 == paramType)
					ConvertPoint3Attrib(paramBlock, i, parmName, color3);
				else if (TYPE_POINT4 == paramType)
					ConvertPoint4Attrib(paramBlock, i, parmName, color4);
				else if (TYPE_BOOL == paramType)
					ConvertBoolAttrib(paramBlock, i, parmName, boolValue);
				else if (TYPE_FLOAT_TAB == paramType)
					ConvertFloatTabAttrib(paramBlock, i, parmName, floatTable);
				else if (TYPE_BITMAP == paramType)
					ConvertBitMapAttrib(paramBlock, i, parmName, tex2d);
				else if (TYPE_FRGBA ==paramType)
					ConvertFRGBAAttrib(paramBlock, i, parmName, color4);

				// shine
				if (parmName == "gBlendMode")
				{
					blendMode = intValue;
				}
				else if (parmName == "gShineEmissive")
				{
					shineStandard->Emissive = color4;
				}
				else if (parmName == "gShineAmbient")
				{
					shineStandard->Ambient = color4;
				}
				else if (parmName == "gShineDiffuse")
				{
					shineStandard->Diffuse = color4;
				}
				// alpha vertex
				else if (parmName == "gAlphaVertex")
				{
					alphaVertex = boolValue;
				}
				// diffuse
				else if (parmName == "gDiffuseTexture")
				{
					diffTex = tex2d;
				}
				// normal
				else if (parmName == "gNormalEnable")
				{
					normalEnable = boolValue;
				}
				else if (parmName == "gNormalTexture")
				{
					normalTex = tex2d;
				}
				else if (parmName == "gNormalScale")
				{
					normalScale = floatValue;
				}
				// specular
				else if (parmName == "gSpecularEnable")
				{
					specEnable = boolValue;
				}
				else if (parmName == "gSpecularTexture")
				{
					specTex = tex2d;
				}
				else if (parmName == "gSpecularPower")
				{
					specPower = floatValue;
				}
				// reflect
				else if (parmName == "gReflectionEnable")
				{
					reflectEnable = boolValue;
				}
				else if (parmName == "gReflectTexture")
				{
					//reflectTex = tex2d;
				}
				else if (parmName == "gReflectPower")
				{
					reflectPower = floatValue;
				}
				// other
				else if (parmName == "gDoubleSide")
				{
					doubleSide = boolValue;
				}
			}
		}

		PX2::MaterialInstance *inst = 0;
		PX2::StandardMaterial *standardMtl = 0;
		PX2::StandardESMaterial_Default *standardESMtl_D = 0;
		PX2::StandardESMaterial_Specular *standardESMtl_S = 0;
		if (outBaseName == "Standard")
		{
			char mtlName[256];
			memset(mtlName, 0, 256*sizeof(char));
			sprintf(mtlName, "%s/%s", mSettings->DstRootDir, 
				"Data/mtls/Standard.pxfx");
			standardMtl = new0 PX2::StandardMaterial(mtlName);
		}
		else if (outBaseName == "StandardES")
		{
			if (false == specEnable)
			{
				standardESMtl_D = new0 PX2::StandardESMaterial_Default();

				if (0 == blendMode)
				{
					standardESMtl_D->GetAlphaProperty(0, 0)->BlendEnabled = false;
					standardESMtl_D->GetAlphaProperty(0, 0)->CompareEnabled = false;
				}
				else if (1 == blendMode)
				{
					standardESMtl_D->GetAlphaProperty(0, 0)->BlendEnabled = true;
				}
				else if (2 == blendMode)
				{
					standardESMtl_D->GetAlphaProperty(0, 0)->BlendEnabled = false;
					standardESMtl_D->GetAlphaProperty(0, 0)->CompareEnabled = true;
					standardESMtl_D->GetAlphaProperty(0, 0)->Compare = PX2::AlphaProperty::CM_GEQUAL;
					standardESMtl_D->GetAlphaProperty(0, 0)->Reference = 0.2f;
				}
			}
			else
			{
				char mtlName[256];
				memset(mtlName, 0, 256*sizeof(char));
				sprintf(mtlName, "%s/%s", mSettings->DstRootDir, 
					"Data/mtls/StandardES_Specular.pxfx");
				standardESMtl_S = new0 PX2::StandardESMaterial_Specular(mtlName);
			}
		}

		if (standardMtl && diffTex)
		{
			if (doubleSide)
			{
				standardMtl->GetCullProperty(0, 0)->Enabled = false;
			}

			inst = standardMtl->CreateInstance(diffTex, alphaVertex, 
				normalEnable, normalTex, normalScale, specEnable, specTex,
				specPower, 0, shineStandard);
		}
		else if (standardESMtl_D && diffTex)
		{
			if (doubleSide)
			{
				standardESMtl_D->GetCullProperty(0, 0)->Enabled = false;
			}

			inst = standardESMtl_D->CreateInstance(diffTex, 0, shineStandard);
		}
		else if (standardESMtl_S && diffTex && specTex)
		{
			if (doubleSide)
			{
				standardESMtl_S->GetCullProperty(0, 0)->Enabled = false;
			}

			inst = standardESMtl_S->CreateInstance(diffTex, specTex, specPower,
				0, shineStandard);
		}

		if (inst)
		{
			mtlTree.SetMaterialInstance(inst);
		}
		else
		{
			PX2::MaterialInstance *instance = 
				PX2::VertexColor4Material::CreateUniqueInstance();
			mtlTree.SetMaterialInstance(instance);
		}
	}
	else
	{
		PX2::VertexColor4Material *vcMtl = new0 PX2::VertexColor4Material();
		PX2::MaterialInstance *instance = vcMtl->CreateInstance();
		mtlTree.SetMaterialInstance(instance);
	}

	// 对子材质进行处理
	if (IsDirect9Shader)
		return;

	int mQuantity = mtl.NumSubMtls(); // Class_ID(MULTI_CLASS_ID, 0)
	if (mQuantity > 0)
	{
		mtlTree.SetMChildQuantity(mQuantity);
		for (int i=0; i<mQuantity; i++)
		{
			Mtl *subMtl = 0;
			subMtl = mtl.GetSubMtl(i);
			if (subMtl)
			{
				ConvertMaterial(*subMtl, mtlTree.GetMChild(i));
			}
		}
	}
}