#include "SceneDesignerFrameworkPCH.h" #include "MLightMapMaterialHelper.h" #include "NiLightMapMaterialHelper.h" #include "NiOptimize.h" //------------------------------------------------------------------------------ MLightMapMaterialHelper::sConvertResultInfo* MLightMapMaterialHelper::ConvertToLightMapMaterial(String* strFileName, String* strBackupDir) { if (strFileName == NULL) return NULL; if (strBackupDir != NULL) { // 确保备份路径存在 if (!IO::Directory::Exists(strBackupDir)) { try { IO::Directory::CreateDirectory(strBackupDir); } catch (Exception* e) { Forms::MessageBox::Show(e->ToString()); return NULL; } } } // 文件不存在 if (!File::Exists(strFileName)) { sConvertResultInfo* pInfo = new sConvertResultInfo(strFileName, false, "File does not exist."); return pInfo; } // 载入对应 nif NiStream kStream; const char* pszFileName = MStringToCharPointer(strFileName); char szFileName[256]; strcpy(szFileName, pszFileName); MFreeCharPointer(pszFileName); if (!kStream.Load(szFileName)) { sConvertResultInfo* pInfo = new sConvertResultInfo(strFileName, false, "Can not open file."); return pInfo; } NiNode* pkNode = NiDynamicCast(NiNode, kStream.GetObjectAt(0)); if (pkNode == NULL) { sConvertResultInfo* pInfo = new sConvertResultInfo(strFileName, false, "Root node does not exist."); return pInfo; } NiNode* pkOutputNode = NULL; String* strInfo = ""; bool bSucc = ConvertToLightMapMaterial(pkNode, pkOutputNode, strInfo); if (bSucc) { // 保存该文件 pkOutputNode->Update(0.0f); pkOutputNode->UpdateEffects(); pkOutputNode->UpdateProperties(); pkOutputNode->UpdateControllers(0.0f); pkOutputNode->UpdateNodeBound(); pkOutputNode->Update(0.0f); // 清除所有 texture 的 PersistentSrcRendererData 和 PixelData EmptyAllTextureDatas(pkOutputNode); if (strBackupDir != NULL) { // 备份源文件 String* strPureFileName = Path::GetFileName(strFileName); IO::File::Copy(strFileName, String::Concat(strBackupDir, "\\", strPureFileName), false); } NiStream kSaveStream; kSaveStream.InsertObject(pkOutputNode); if (!kSaveStream.Save(szFileName)) { Forms::MessageBox::Show(String::Concat("文件保存失败, ", strFileName)); } } sConvertResultInfo* pInfo = new sConvertResultInfo(strFileName, bSucc, strInfo); return pInfo; } //------------------------------------------------------------------------------ ArrayList* MLightMapMaterialHelper::ConvertToLightMapMaterial(ArrayList* arrFileList, String* strBackupDir) { if (arrFileList == NULL) return NULL; if (strBackupDir != NULL) { // 确保备份路径存在 if (!IO::Directory::Exists(strBackupDir)) { try { IO::Directory::CreateDirectory(strBackupDir); } catch (Exception* e) { Forms::MessageBox::Show(e->ToString()); return NULL; } } } ArrayList* arrConvertResult = new ArrayList(); // 遍历所有需要转换的文件 for (int i=0; iCount; i++) { String* strFileName = dynamic_cast(arrFileList->Item[i]); MLightMapMaterialHelper::sConvertResultInfo* pInfo = ConvertToLightMapMaterial(strFileName, strBackupDir); if (pInfo) arrConvertResult->Add(pInfo); } return arrConvertResult; } //------------------------------------------------------------------------------ void MLightMapMaterialHelper::EmptyAllTextureDatas(NiAVObject* pkAVObj) { if (pkAVObj == NULL) { return; } NiNode* pkNode = NiDynamicCast(NiNode, pkAVObj); if (pkNode != NULL) { pkNode->CompactChildArray(); int iChildCount = pkNode->GetChildCount(); for (int i=0; iGetChildCount(); i++) { NiAVObject* pkChild = pkNode->GetAt(i); EmptyAllTextureDatas(pkChild); } } NiTexturingProperty* pkTexProp = (NiTexturingProperty*)pkAVObj->GetProperty(NiProperty::TEXTURING); if (pkTexProp != NULL) { const NiTPrimitiveArray& kMaps = pkTexProp->GetMaps(); // register images for (unsigned int i = 0; i < kMaps.GetSize(); i++) { NiTexturingProperty::Map* pkMap = kMaps.GetAt(i); if ( pkMap) { EmptyTextureData(pkMap); } } for (unsigned int i = 0; i < pkTexProp->GetShaderMapCount(); i++) { NiTexturingProperty::ShaderMap* pkMap = pkTexProp->GetShaderMap(i); if (pkMap) { EmptyTextureData(pkMap); } } } } //------------------------------------------------------------------------------ void MLightMapMaterialHelper::EmptyTextureData(NiTexturingProperty::Map* pkMap) { if (pkMap == NULL) return; NiTexture* pkTex = pkMap->GetTexture(); if (pkTex != NULL) { if (NiIsKindOf(NiSourceTexture, pkTex)) { NiSourceTexture* pkSrcTex = NiDynamicCast(NiSourceTexture, pkTex); pkSrcTex->SetSourceRendererDataIsPersistent(false); pkSrcTex->DestroyAppPixelData(); } } } //------------------------------------------------------------------------------ bool MLightMapMaterialHelper::ConvertToLightMapMaterial(NiNode* pkInputNode, NiNode*& pkOutputNode, String*& strInfo) { if (pkInputNode==NULL) return false; NiOptimize::OptimizeTriShapes(pkInputNode); pkInputNode->Update(0.0f); vector arrInfo; int iNumGeomConv = 0; int iNumGeomFaile = 0; NiNode* pkNode = NiLightMapMaterialHelper::ConvertToLightMapMaterial(pkInputNode, iNumGeomConv, iNumGeomFaile, arrInfo); // 将转换信息拷贝到 strInfo for (int i=0; i 0) { pkOutputNode = pkNode; return true; } else { return false; } return true; } //------------------------------------------------------------------------------ void MLightMapMaterialHelper::Test() { //const char* pszNifPath = "E:\\mux\\Developer\\PlatformTools\\Bin\\scenedesigner\\Data\\Model\\SceneObj\\1101\\1101030080.nif"; //NiStream kStream; //kStream.Load(pszNifPath); //NiNodePtr pkNode = NiDynamicCast(NiNode, kStream.GetObjectAt(0)); //int iObjCount = kStream.GetObjectCount(); //pkNode->Update(0.0f); //NiLightMapMaterialHelper::ConvertToLightMapMaterial(pkNode); //pkNode->Update(0.0f); //pkNode->UpdateEffects(); //pkNode->UpdateProperties(); //pkNode->UpdateNodeBound(); //kStream.RemoveAllObjects(); //kStream.InsertObject(pkNode); //kStream.Save("_ConvertedLMM.nif"); }