JD2022-TU1/main/tools/legacy/TexturePacker/AnimTexPacker/PatchDepot.cpp

398 lines
17 KiB
C++

#include "stdafx.h"
#ifndef _ITF_PATCHDEPOT_H_
#include "AnimTexPacker/PatchDepot.h"
#endif
#ifndef _ITF_ANIMATIONPATCHBANK_H_
#include "engine/animation/AnimationPatchBank.h"
#endif // _ITF_ANIMATIONPATCHBANK_H_
#ifndef _ITF_ERRORHANDLER_H_
#include "core/error/ErrorHandler.h"
#endif //_ITF_ERRORHANDLER_H_
#ifndef _ITF_ASSERTMANAGER_H_
#include "core/AssertManager.h"
#endif //_ITF_ASSERTMANAGER_H_
#ifndef _ITF_FILEMANAGER_ITF_H_
#include "adapters/FileManager_ITF/FileManager_ITF.h"
#endif //_ITF_FILEMANAGER_ITF_H_
#ifndef _ITF_FILESERVER_H_
#include "core/file/FileServer.h"
#endif //_ITF_FILESERVER_H_
#ifndef ITF_GFX_MATERIAL_H_
#include "engine/display/material/GFXMaterial.h"
#endif //ITF_GFX_MATERIAL_H_
namespace ITF
{
namespace AnimTexPacker
{
///////////////////////////////////////////////////////////////////////////////////////////
///Destructor
PatchDepot::~PatchDepot()
{
for (iterator iter=begin();
iter!=end();
iter++)
{
iter->destroy();
}
}
///////////////////////////////////////////////////////////////////////////////////////////
const PatchList * PatchDepot::getInPatchDepot(const Path &_patchImagePath)
{
for (const_iterator iter=begin();
iter!=end();
iter++)
{
if (iter->m_patchImagePath == _patchImagePath)
return &(*iter);
}
return NULL;
}
///////////////////////////////////////////////////////////////////////////////////////////
void PatchDepot::processTemplate(PatchList *_patchList, AnimPatchBank *_patchBank, StringID & _bankID, ITF_VECTOR<ImageTextureMode> &imageTab, const Path &imagePath, AnimSkeleton *_skeleton, const ITF_VECTOR<StringID> * templateUsed)
{
int PatchIndex=0;
VectorAnim<AnimTemplate*> templateList;
if (!templateUsed)
{
templateList = _patchBank->m_templateList;
} else
{
ITF_VECTOR<StringID>::const_iterator tIt = templateUsed->begin();
for (; tIt != templateUsed->end(); tIt++)
{
NamesMap::Iterator ntt(_patchBank->m_NameToTemplate);
ntt.findKey(*tIt);
if (!ntt.isEnd())
{
templateList.push_back(_patchBank->m_templateList[ntt.second()]);
}
}
}
VectorAnim<AnimTemplate*>::const_iterator patchIter;
for (patchIter=templateList.begin();
patchIter!=templateList.end();
patchIter++, PatchIndex++)
{
AnimTemplate *animtemplate = *patchIter;
animtemplate->ComputeBonesGlobalPos();
StringID templateID;
NamesMap::Iterator nameIter(_patchBank->m_NameToTemplate);
for (;!nameIter.isEnd(); nameIter.increment())
{
if (_patchBank->m_templateList[nameIter.second()]==animtemplate)
templateID = nameIter.first();
}
if (find(_patchList->m_usedPatches.begin(), _patchList->m_usedPatches.end(), templateID ) == _patchList->m_usedPatches.end())
{
_patchList->m_usedPatches.push_back(templateID);
//Find linked items from each animTemplate
ITF_LIST<ChainedBones> _chainedBoneList;
BuildChainedBoneList(_chainedBoneList, animtemplate);
//animtemplate->m_Patch[patchIndex].m_AnimPatchPoints->m_mainRefs.m_BonePtr
ITF_LIST<ChainedBones>::iterator chainIter;
for (chainIter=_chainedBoneList.begin(); chainIter!=_chainedBoneList.end(); chainIter++)
{
ChainedBones &chain = *chainIter;
Patch *newPatch = newAlloc(mId_Temporary, Patch);
newPatch->initialize(_bankID, templateID, animtemplate, chain, imageTab, imagePath, _skeleton);
//Patch *sourceOfAlias = NULL;
//ITF_LIST<Patch*>::const_iterator existingIter;
//for (existingIter=_patchList->m_patches.begin();
// existingIter!=_patchList->m_patches.end();
// existingIter++)
//{
// if (newPatch->isEqual(*existingIter))
// {
// sourceOfAlias = *existingIter;
// break;
// }
//}
//if (existingIter!=_patchList->m_patches.end())
// newPatch->setAliasOf(sourceOfAlias);
_patchList->m_patches.push_back(newPatch);
}
}
}
}
///////////////////////////////////////////////////////////////////////////////////////////
bbool PatchDepot::isVisuallyRootBone(AnimBone *_bone)
{
if (_bone->m_BoneParent==NULL)
return btrue;
if (_bone->m_PatchFlags & BONE_PARENT_CUT)
return btrue;
return bfalse;
}
///////////////////////////////////////////////////////////////////////////////////////////
bbool PatchDepot::BuildChainedBoneList(ITF_LIST<ChainedBones> &_chainedBoneList, AnimTemplate *_template)
{
VectorAnim<AnimBone*> remainingBones;
remainingBones.reserve(_template->m_BonesCurFrame.size());
for (u32 i=0;i<_template->m_BonesCurFrame.size(); i++)
remainingBones.push_back(&_template->m_BonesCurFrame[i]);
//Initialize list with seeds (root bones)
for (int index=0; index<(int)remainingBones.size(); index++)
{
AnimBone *bone = remainingBones[index];
bbool isRoot = isVisuallyRootBone(bone);
if (isRoot)
{
ChainedBones seed;
seed.m_AnimBones.push_back(bone);
remainingBones.erase(remainingBones.begin()+index);
index--;
_chainedBoneList.push_back(seed);
}
}
//Add other bones
while(remainingBones.size())
{
bbool somethingFound=bfalse;
for (int boneToAddIndex=0; boneToAddIndex<(int)remainingBones.size(); boneToAddIndex++)
{
AnimBone *boneToAdd = remainingBones[boneToAddIndex];
bbool boneWasFound=bfalse;
//Find already registered bone in _chainedBoneList
ITF_LIST<ChainedBones>::iterator iter;
for (iter =_chainedBoneList.begin(); iter!=_chainedBoneList.end(); iter++)
{
if (iter->m_AnimBones.find(boneToAdd->m_BoneParent)>=0)
{
somethingFound=btrue;
boneWasFound = btrue;
iter->m_AnimBones.push_back(boneToAdd);
}
}
if (boneWasFound)
{
remainingBones.erase(remainingBones.begin()+boneToAddIndex);
boneToAddIndex--;
}
}
if (!somethingFound)
{
ITF_FATAL_ERROR("Inconsistent skeleton found when trying to pack an animation");
return bfalse;
}
}
return btrue;
}
///////////////////////////////////////////////////////////////////////////////////////////
void PatchDepot::addToPatchBankToPatchDepot(
const GFX_MATERIAL * _material,
AnimPatchBank *patchBank,
StringID & _bankName,
AnimSkeleton *skeleton,
const ITF_VECTOR<StringID> * templateUsed,
u32 _hdDownscaleMask)
{
const Path & imagePath = _material->getTextureResID().getResource()->getPath();
PatchList * newPatchList = (PatchList *)getInPatchDepot(imagePath);
if (!newPatchList)
{
PatchList tmpNewPatchList;
this->push_back(tmpNewPatchList);
newPatchList = &this->back();
newPatchList->m_patchImagePath = imagePath;
newPatchList->m_patchBank = patchBank;
newPatchList->m_bankName = _bankName;
newPatchList->m_imgMask = 0;
newPatchList->m_hdDownscaleMask = _hdDownscaleMask;
newPatchList->m_imgUseAlphaMask = 0;
} else if (!templateUsed)
return;
LOG("---Loading bank %s", imagePath.toString8().cStr());
if (patchBank)
{
ITF_VECTOR<ImageTextureMode> imageTab;
ITF_VECTOR<String8> imageTabStr;
for (u32 textIdx=0; textIdx<(u32)TEXSET_ID_COUNT; textIdx++)
{
Resource * res = _material->getTextureResID((TextureSetSubID)textIdx).getResource();
if (res)
{
imageTab.resize(imageTab.size()+1);
ImageTextureMode & currentItm = imageTab[imageTab.size()-1];
currentItm.m_mode = (TextureSetSubID)textIdx;
Path imagePathMode = res->getPath();
if (_hdDownscaleMask & (1<<textIdx))
{
String8 strName = imagePathMode.getBasenameWithoutExtension();
strName += "_hd.";
strName += imagePathMode.getExtension();
imagePathMode.changeBasename(strName);
}
bbool isImageOk = FILEMANAGER->fileExists(imagePathMode);
if (isImageOk)
{
String8 translated = FILESERVER->platformString8FromPath(imagePathMode);
isImageOk = currentItm.m_image.load(translated.cStr());
nv::Image::Format format = currentItm.m_image.format();
if (format == nv::Image::Format_ARGB)
newPatchList->m_imgUseAlphaMask |= 1<<textIdx;
imageTabStr.push_back(translated);
}
if (!isImageOk)
{
LOG("Image %s was not found", imagePath.toString8().cStr());
imageTab.resize(imageTab.size()-1);
}
newPatchList->m_imgMask |= 1<<textIdx;
}
}
if (imageTab.size())
{
u32 firstWidth = imageTab[0].m_image.width();
u32 firstHeight = imageTab[0].m_image.height();
for (u32 imgIdx=1; imgIdx < imageTab.size(); imgIdx++)
{
if (imageTab[imgIdx].m_image.width() != firstWidth ||
imageTab[imgIdx].m_image.height() != firstHeight)
{
String8 msg;
msg.setTextFormat("Invalid texture Set: \n%s (%ix%i) and\n%s (%ix%i)\nare incompatible, please check files size",
imageTabStr[0].cStr(), firstWidth, firstHeight,
imageTabStr[imgIdx].cStr(), imageTab[imgIdx].m_image.width(), imageTab[imgIdx].m_image.height());
SYSTEM_ADAPTER->messageBox(String8("Texture Packer"), msg, 64, ITF_IDYES);
exit(0);
}
}
processTemplate(newPatchList, patchBank, _bankName, imageTab, imagePath, skeleton, templateUsed);
}
}
}
void PatchDepot::fillUnionPatchDepot( PatchDepot & _dst, ITF_VECTOR< PatchDepot * > & _srcList )
{
ITF_VECTOR< PatchDepot * >::iterator srcIter = _srcList.begin();
ITF_VECTOR< Path > fusionPath;
for (; srcIter != _srcList.end(); ++srcIter)
{
const PatchDepot & depot = *(*srcIter);
PatchDepot::const_iterator patchIter = depot.begin();
for (; patchIter != depot.end(); ++patchIter)
{
const Path & path = patchIter->m_patchImagePath;
if (std::find(fusionPath.begin(), fusionPath.end(), path) != fusionPath.end())
continue;
ITF_VECTOR< PatchDepot * >::const_iterator src2Iter = srcIter+1;
for (; src2Iter != _srcList.end(); ++src2Iter)
{
const PatchDepot & depot2 = *(*src2Iter);
PatchDepot::const_iterator patch2Iter = depot2.begin();
for (; patch2Iter != depot2.end(); ++patch2Iter)
{
const Path & path2 = patch2Iter->m_patchImagePath;
if (std::find(fusionPath.begin(), fusionPath.end(), path2) != fusionPath.end())
continue;
if (path2 == path)
{
ITF_LIST<Patch*>::const_iterator pathPtrIter = patchIter->m_patches.begin();
for (; pathPtrIter != patchIter->m_patches.end(); ++pathPtrIter)
{
const StringID & animTpl = (*pathPtrIter)->getTemplateID();
ITF_LIST<Patch*>::const_iterator path2PtrIter = patch2Iter->m_patches.begin();
for (; path2PtrIter != patch2Iter->m_patches.end(); ++path2PtrIter)
{
if (animTpl == (*path2PtrIter)->getTemplateID())
break;
}
if (path2PtrIter != patch2Iter->m_patches.end())
{
fusionPath.push_back(path);
break;
}
}
break;
}
}
}
}
}
ITF_VECTOR< Path >::const_iterator pathIter = fusionPath.begin();
for (; pathIter != fusionPath.end(); ++pathIter)
{
const Path & path = *pathIter;
bbool pathAdded = bfalse;
srcIter = _srcList.begin();
for (; srcIter != _srcList.end(); ++srcIter)
{
PatchDepot & depot = *(*srcIter);
PatchDepot::iterator patchIter = depot.begin();
for (; patchIter != depot.end(); ++patchIter)
{
const Path & pathIn = patchIter->m_patchImagePath;
if (pathIn == path)
{
if (!pathAdded)
{
_dst.push_back(*patchIter);
pathAdded = btrue;
} else
{
PatchList & curPatch = _dst.back();
for (ITF_VECTOR<StringID>::iterator usedIter = patchIter->m_usedPatches.begin()
; usedIter != patchIter->m_usedPatches.end(); ++usedIter)
{
if (std::find(curPatch.m_usedPatches.begin(), curPatch.m_usedPatches.end(), *usedIter) == curPatch.m_usedPatches.end())
curPatch.m_usedPatches.push_back(*usedIter);
}
for (ITF_LIST<Patch*>::iterator pIter = patchIter->m_patches.begin()
; pIter != patchIter->m_patches.end(); ++pIter)
{
if (std::find(curPatch.m_patches.begin(), curPatch.m_patches.end(), *pIter) == curPatch.m_patches.end())
curPatch.m_patches.push_back(*pIter);
}
}
depot.erase(patchIter);
break;
}
}
}
}
}
}
}