398 lines
17 KiB
C++
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;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|
|
}
|
|
}
|