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

505 lines
No EOL
20 KiB
C++

#include "stdafx.h"
#include "engine/precompiled_engine.h"
#ifndef _ITF_ANIMATIONLOADER_H_
#include "AnimTexPacker/AnimationLoader.h"
#endif
#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_XMLALL_H_
#include "engine/XML/XML_All.h"
#endif //_ITF_XMLALL_H_
#ifndef _ITF_ANIMATIONTRACK_H_
#include "engine/animation/AnimationTrack.h"
#endif //_ITF_ANIMATIONTRACK_H_
#ifndef _ITF_ANIMATIONSKELETON_H_
#include "engine/animation/AnimationSkeleton.h"
#endif // _ITF_ANIMATIONSKELETON_H_
#ifndef _ITF_ANIMATIONPATCHBANK_H_
#include "engine/animation/AnimationPatchBank.h"
#endif // _ITF_ANIMATIONPATCHBANK_H_
#ifndef _ITF_FILESERVER_H_
#include "core/file/FileServer.h"
#endif //_ITF_FILESERVER_H_
#ifndef _ITF_ANIMATIONRES_H_
#include "engine/animation/AnimationRes.h"
#endif //_ITF_ANIMATIONRES_H_
#ifndef _ITF_ANIMATIONLOADPATCHBANK_H_
#include "tools/plugins/CookerPlugin/AnimLoader/AnimationLoadPatchBank.h"
#endif //_ITF_ANIMATIONLOADPATCHBANK_H_
#ifndef _ITF_ANIMATIONLOADTRACK_H_
#include "tools/plugins/CookerPlugin/AnimLoader/AnimationLoadTrack.h"
#endif //_ITF_ANIMATIONLOADTRACK_H_
#ifndef _ITF_FILEMANAGER_ITF_H_
#include "adapters/FileManager_ITF/FileManager_ITF.h"
#endif //_ITF_FILEMANAGER_ITF_H_
#ifndef _ITF_SOURCECONTROLADAPTER_H_
#include "engine/AdaptersInterfaces/SourceControlAdapter.h"
#endif // _ITF_SOURCECONTROLADAPTER_H_
#ifndef _ITF_ANIMATION_H_
#include "engine/animation/Animation.h"
#endif //_ITF_ANIMATION_H_
#ifndef _ITF_XMLALL_H_
#include "engine/XML/XML_All.h"
#endif //_ITF_XMLALL_H_
//#define _DONT_RESIZE_SUBTEXTURES
#ifndef ITF_GFX_MATERIAL_H_
#include "engine/display/material/GFXMaterial.h"
#endif //ITF_GFX_MATERIAL_H_
#include "TexturePacker\PackerLog.h"
namespace ITF
{
namespace AnimTexPacker
{
///////////////////////////////////////////////////////////////////////////////////////////
AnimationLoader::AnimationLoader()
{
LOG("-------------AnimTexPacker : CURRENTLY, TEXTURES ARE LOADED TOO");
}
///////////////////////////////////////////////////////////////////////////////////////////
AnimationLoader::~AnimationLoader()
{
}
///////////////////////////////////////////////////////////////////////////////////////////
void AnimationLoader::mayUpdateBoneCount(u32 _boneCount)
{
while(_boneCount>m_boneMaxSizes.size())
{
BoneMaxSize s;
m_boneMaxSizes.push_back(s);
}
}
#if !defined(ITF_FINAL) && defined(ITF_WIN32) && defined(ITF_DEBUG_STRINGID)
///////////////////////////////////////////////////////////////////////////////////////////
void AnimationLoader::exportAnimations(const Path& _directory)
{
for (u32 index=0; index<m_loadedAnimations.size(); index++)
{
AnimTrack *track = m_loadedAnimations[index];
if (!track)
continue;
Path filePath = _directory.copyAndChangeBasename(m_loadedAnimationPathes[index].getBasename());
AnimationLoadTrack::writeAnimTrack(&m_subAnimSet, track, filePath);
}
}
#endif
///////////////////////////////////////////////////////////////////////////////////////////
void AnimationLoader::cookAnimations(const Path& _directory, const Platform& _platform)
{
for (u32 index=0; index<m_loadedAnimations.size(); index++)
{
AnimTrack *track = m_loadedAnimations[index];
if (!track)
continue;
Path filePath = _directory.copyAndChangeBasename(m_loadedAnimationPathes[index].getBasename());
Path cookFile = FILESERVER->getCookedNamePlatform(filePath,_platform);
track->saveBinary(cookFile);
}
}
///////////////////////////////////////////////////////////////////////////////////////////
void AnimationLoader::modifyAnimations(const AnimPackerConfiguration &_config)
{
for (u32 index=0; index<m_loadedAnimations.size(); index++)
{
AnimTrack *track = m_loadedAnimations[index];
if (!track)
continue;
ITF_SET<String8> patchBanks;
//patch BML (Bitmap match list)
for (u32 bmlIndex=0; bmlIndex<track->m_bmlList.size(); bmlIndex++)
{
AnimTrackBML &bml = track->m_bmlList[bmlIndex];
for (u32 templateIndex=0; templateIndex<bml.m_templateRefs.size(); templateIndex++)
{
TemplateRef &templte = bml.m_templateRefs[templateIndex];
PbkMerger *merger = m_mergerList.getPbkMergerFromTemplateID(templte.m_patchName);
if (merger)
{
const String8 &patchBankName = merger->getCompositeName();
patchBanks.insert(patchBankName);
templte.m_bankName = StringID(patchBankName);
}
else
{
templte.m_bankName = StringID::Invalid;
}
}
}
//modify patchbankList
track->m_patchBankPathList.clear();
for (ITF_SET<String8>::const_iterator pbkNameIter=patchBanks.begin();
pbkNameIter!=patchBanks.end();
pbkNameIter++)
{
const String8 &name=*pbkNameIter;
Path patchBankPath(_config.m_mainPath.copyAndChangeBasename(name));
track->m_patchBankPathList.push_back(patchBankPath.getStringID());
}
}
}
///////////////////////////////////////////////////////////////////////////////////////////
StringID AnimationLoader::findSeedBone(const StringID &_boneID)
{
for (PatchDepot::iterator iter=m_patchDepot.begin();
iter!=m_patchDepot.end();
iter++)
{
//For each patch
PatchList &patchList = *iter;
for (ITF_LIST<Patch*>::iterator patchIter = patchList.m_patches.begin();
patchIter!=patchList.m_patches.end();
patchIter++)
{
Patch *patch = *patchIter;
//find ID in bone IDs
if (find(patch->getBoneIDs().begin(), patch->getBoneIDs().end(), _boneID)!=patch->getBoneIDs().end())
{
return patch->getBoneIDs()[0];
}
}
}
ITF_ASSERT_MSG(bfalse, "could not find bone");
return _boneID;
}
struct PatchBankTemplate {
AnimPatchBank * m_bank;
const GFX_MATERIAL * m_material;
StringID m_pachBankId;
ITF_VECTOR<StringID> m_templateUsed;
};
///////////////////////////////////////////////////////////////////////////////////////////
AnimTrack * AnimationLoader::parseAnimation(SubAnimSet *_subAnimSet, u32 _subIdx, u32 _hdDownscaleMask)
{
AnimMeshScene animMeshScene;
AnimInfo &animInfo = animMeshScene.m_AnimInfo;
animInfo.m_Pos = Vec3d::Zero;
animInfo.m_Scale = Vec2d::One;
ITF_VECTOR<AnimFrameInfo> frameInfoList;
AnimFrameInfo animFrame;
animFrame.m_fFrame = 0;
animFrame.m_subAnimIdx = _subIdx;
animFrame.m_percent = 1.f;
animFrame.m_useVisuals = btrue;
animInfo.m_subAnimSet = &m_subAnimSet;
frameInfoList.push_back(animFrame);
animInfo.m_frameInfo = frameInfoList;
animInfo.m_useRootRotation = bfalse;
AnimTrack *track = _subAnimSet->getSubAnim(_subIdx) ? _subAnimSet->getSubAnim(_subIdx)->getTrack() : NULL;
if (!track)
return NULL;
AnimSkeleton *skeletonPtr = _subAnimSet->getSkeleton();
u32 boneCount = skeletonPtr->m_BonesCurFrame.size();
mayUpdateBoneCount(boneCount);
//Iterate for each patch bank (actually to each patch bank image)
ITF_VECTOR<PatchBankTemplate> trackPatches;
VectorAnim<AnimTrackBML>::iterator bmlIter = track->m_bmlList.begin();
for (; bmlIter != track->m_bmlList.end(); ++bmlIter)
{
AnimTrackBML & bml = *bmlIter;
VectorAnim<TemplateRef>::iterator tempRefIter = bml.m_templateRefs.begin();
for (; tempRefIter != bml.m_templateRefs.end(); ++tempRefIter)
{
TemplateRef & templateRef = *tempRefIter;
AnimTemplate * animTemplate;
AnimPatchBank * bank;
const GFX_MATERIAL * material = NULL;
if (m_subAnimSet.getAnimTemplateAndMaterialAndBank(templateRef, animTemplate, material, bank))
{
PatchBankTemplate *trackPatche = NULL;
for (ITF_VECTOR<PatchBankTemplate>::iterator it = trackPatches.begin();
it != trackPatches.end(); it++)
{
if (it->m_bank == bank)
{
trackPatche = &(*it);
break;
}
}
if (!trackPatche)
{
trackPatches.resize(trackPatches.size()+1);
trackPatche = &trackPatches[trackPatches.size()-1];
trackPatche->m_bank = bank;
trackPatche->m_material = material;
trackPatche->m_pachBankId = (*tempRefIter).m_bankName;
}
bbool templateAlreadyUsed = bfalse;
for (ITF_VECTOR<StringID>::iterator itt = trackPatche->m_templateUsed.begin();
itt != trackPatche->m_templateUsed.end(); itt++)
{
if (*itt == templateRef.m_patchName)
{
templateAlreadyUsed = btrue;
break;
}
}
if (!templateAlreadyUsed)
trackPatche->m_templateUsed.push_back(templateRef.m_patchName);
}
}
}
for (ITF_VECTOR<PatchBankTemplate>::iterator it = trackPatches.begin();
it != trackPatches.end(); it++)
{
PatchBankTemplate & trackPatche =(*it);
if (trackPatche.m_material)
{
m_patchDepot.addToPatchBankToPatchDepot(trackPatche.m_material, trackPatche.m_bank, trackPatche.m_pachBankId, skeletonPtr, &trackPatche.m_templateUsed, _hdDownscaleMask);
}
}
return track;
}
///////////////////////////////////////////////////////////////////////////////////////////
void AnimationLoader::loadAnimations(const ITF_VECTOR<Path> &animPathList, const ITF_VECTOR<TextureBankPath> * _textureBank, u32 _hdDownscaleMask)
{
if (!m_subAnimSet.getTemplate())
m_subAnimSet.setTemplate( new SubAnimSet_Template() );
RESOURCE_MANAGER->registerResourceContainer(&m_resourceContainer,"AnimationsLoader");
TexturePacker::PackerLog::s_main->setLabel("Step-1/2 : Loading Animations (1/3)");
TexturePacker::PackerLog::s_main->resetProgressbar(animPathList.size());
AnimResourcePackage emptyTemplate;
for (ITF_VECTOR<Path>::const_iterator iter=animPathList.begin();
iter!=animPathList.end();
iter++)
{
XMLAll::addTrackToAnimResourcePackage(*iter, m_subAnimSet.getAnimResourcePackagePtr(), &emptyTemplate);
TexturePacker::PackerLog::s_main->progressbarStep();
}
AnimResourcePackage * package = m_subAnimSet.getAnimResourcePackagePtr();
const ITF_VECTOR<AnimPathAABB> & animPathAABB = package->getAnimPathAABB();
for (ITF_VECTOR<AnimPathAABB>::const_iterator animIter = animPathAABB.begin();
animIter != animPathAABB.end(); ++animIter)
{
m_subAnimSet.addSubAnimByPath(animIter->m_path, animIter->m_name, -1, -1);
}
if (_textureBank)
package->addTextureBankPath(*_textureBank);
m_subAnimSet.linkSubAnimToTrack(&m_resourceContainer);
const ResourceContainer::ResourceList & resList = m_resourceContainer.getResourcesList();
TexturePacker::PackerLog::s_main->setLabel("Step-1/2 : Loading Animations (2/3)");
TexturePacker::PackerLog::s_main->resetProgressbar(resList.size());
for (u32 i=0; i<resList.size(); i++)
{
const ResourceID & resID = resList[i];
if (!resID.getResource()->forceLoadFile())
{
String8 msg;
String8 resName;
resID.getResource()->getPath().toString8(resName);
msg.setTextFormat("Error loading resource %s", resName.cStr());
SYSTEM_ADAPTER->messageBox(String8("Texture Packer"), msg, 64, ITF_IDYES);
exit(0);
}
TexturePacker::PackerLog::s_main->progressbarStep();
}
// Check duplicate Ids
StringID duplicate;
Path file1, file2;
if (m_subAnimSet.isTherePatchesWithSameNameInDifferentBanks(duplicate, file1, file2))
{
String8 imgI, imgJ;
file1.toString8(imgI);
file2.toString8(imgJ);
String8 tmpName = duplicate.getDebugString();
String8 msg;
msg.setTextFormat("Error !!\nTwo different patch banks:\n-%s\n%s\nhave same patch name %s",
imgI.cStr(), imgJ.cStr(), tmpName.cStr());
SYSTEM_ADAPTER->messageBox(String8("Texture Packer"), msg, 64, ITF_IDYES);
exit(0);
}
String8 errorStr;
if (!m_subAnimSet.isResolveMarkersOk())
m_subAnimSet.resolveMarkers(errorStr, &m_resourceContainer, &m_resourceContainer);
m_subAnimSet.computePatchBankBoneInMainSkeleton();
TexturePacker::PackerLog::s_main->setLabel("Step-1/2 : Loading Animations (3/3)");
TexturePacker::PackerLog::s_main->resetProgressbar(animPathList.size());
for (u32 i=0; i<animPathList.size(); i++)
{
AnimTrack *track = parseAnimation(&m_subAnimSet, i, _hdDownscaleMask);
if (track)
{
m_loadedAnimationPathes.push_back(animPathList[i]);
m_loadedAnimations.push_back(track);
}
TexturePacker::PackerLog::s_main->progressbarStep();
}
//Match bone sizes with patches
for (PatchDepot::iterator iter=m_patchDepot.begin();
iter!=m_patchDepot.end();
iter++)
{
//For each patch
PatchList &patchList = *iter;
for (ITF_LIST<Patch*>::iterator patchIter = patchList.m_patches.begin();
patchIter!=patchList.m_patches.end();
patchIter++)
{
Patch *patch = *patchIter;
//Iterate each of its bones
for (u32 patchBoneIndex=0; patchBoneIndex<patch->getBoneIndices().size(); patchBoneIndex++)
{
u32 patchBone = patch->getBoneIndices()[patchBoneIndex];
//And grow the patch with the bone size
if (patchBone<m_boneMaxSizes.size())
{
Patch *patchToGrow = patch->getSourceOfAlias();
if (patchToGrow==NULL)
patchToGrow = patch;
patchToGrow->growPatchMaxSize(m_boneMaxSizes[patchBone]);
}
}
}
}
m_resourceContainer.clear();
RESOURCE_MANAGER->unregisterResourceContainer(&m_resourceContainer);
}
///////////////////////////////////////////////////////////////////////////////////////////
bbool AnimationLoader::buildPackedMap(const AnimPackerConfiguration &_config, const Platform& _platform)
{
int serialMergerIndex = 0;
PbkMergerList::buildPbkMergerList(serialMergerIndex, _config, m_mergerList, m_patchDepot);
AnimSkeleton * skl;
if (m_patchDepot.size() && m_patchDepot.front().m_patches.size())
{
skl = m_patchDepot.front().m_patches.front()->getAnimSkeleton();
} else
{
skl = m_subAnimSet.getAnimResourcePackage().getSkeleton();
if (!skl && !m_subAnimSet.getTemplate())
return bfalse;
skl = m_subAnimSet.getSkeleton();
}
u32 stepIdx = 1;
String8 logStr;
for (PbkMergerList::iterator iter=m_mergerList.begin();
iter!=m_mergerList.end();
iter++, stepIdx++)
{
PbkMerger &merger = *iter;
logStr.setTextFormat("Step-2/2 : Creating merged files (%u/%u)", stepIdx, m_mergerList.size());
TexturePacker::PackerLog::s_main->setLabel(logStr.cStr());
logStr.setTextFormat("------>> Creating merged files (%u/%u)", stepIdx, m_mergerList.size());
TexturePacker::PackerLog::s_main->addText(logStr.cStr());
bbool isOk = merger.buildPackedMap(_config);
if (!isOk)
{
ITF_ERROR("Could not build packed map");
return bfalse;
}
merger.createCompositePatchBank(&m_patchDepot);
#if !defined(ITF_FINAL) && defined(ITF_WIN32) && defined(ITF_DEBUG_STRINGID)
Path imagePath = _config.m_mainPath.copyAndChangeBasename(iter->getCompositeName()+".pbk");
if (SOURCECONTROL_ADAPTER)
SOURCECONTROL_ADAPTER->checkout(imagePath);
AnimationLoadPatchBank::writeAnimPatchBank(iter->m_compositeAnimPatchBank, skl, imagePath);
if (SOURCECONTROL_ADAPTER)
SOURCECONTROL_ADAPTER->add(imagePath);
#endif
}
return btrue;
}
void AnimationLoader::fillUnion( ITF_VECTOR<AnimationLoader> & _loaderList )
{
ITF_VECTOR<PatchDepot *> patchList;
for (ITF_VECTOR<AnimationLoader>::iterator loaderIter = _loaderList.begin();
loaderIter != _loaderList.end(); ++loaderIter)
{
patchList.push_back(&loaderIter->m_patchDepot);
}
PatchDepot::fillUnionPatchDepot( m_patchDepot, patchList );
}
ITF_LIST<PbkMerger*> AnimationLoader::getMergeListPtr()
{
ITF_LIST<PbkMerger*> lst;
for (ITF_LIST<PbkMerger>::iterator mIter = m_mergerList.begin();
mIter != m_mergerList.end(); ++mIter)
{
lst.push_back(&(*mIter));
}
return lst;
}
}
}