505 lines
No EOL
20 KiB
C++
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;
|
|
}
|
|
|
|
}
|
|
} |