skincache

This commit is contained in:
yangxiao 2014-06-16 19:17:07 +08:00
parent 2c6f7b63d1
commit 531f8998a1
2 changed files with 69 additions and 81 deletions

View File

@ -259,61 +259,62 @@ MeshSkin::~MeshSkin()
removeAllBones(); removeAllBones();
} }
MeshSkin* MeshSkin::getOrCreate(const std::string& fileName, const std::string& name)
{
std::string fullPath = FileUtils::getInstance()->fullPathForFilename(fileName);
std::string key = fullPath + "#" + name;
auto skin = MeshSkinCache::getInstance()->getMeshSkin(key);
if (skin != nullptr)
return skin;
skin = create(fileName, name);
MeshSkinCache::getInstance()->addMeshSkin(key, skin);
return skin;
}
//create a new meshskin if do not want to share meshskin //create a new meshskin if do not want to share meshskin
MeshSkin* MeshSkin::create(const std::string& filename, const std::string& name) MeshSkin* MeshSkin::create(const std::string& filename, const std::string& name)
{ {
//load skin here; //load skin here;
std::string fullPath = FileUtils::getInstance()->fullPathForFilename(filename); std::string fullPath = FileUtils::getInstance()->fullPathForFilename(filename);
auto instance = Bundle3D::getInstance(); std::string key = fullPath + "#" + name;
bool ret = instance->load(fullPath); const auto skindata = MeshSkinDataCache::getInstance()->getMeshSkinData(key);
if (ret) if (skindata)
{ {
SkinData skindata; auto skin = new MeshSkin();
if (instance->loadSkinData(name, &skindata)) skin->initFromSkinData(*skindata);
skin->autorelease();
return skin;
}
else
{
auto instance = Bundle3D::getInstance();
bool ret = instance->load(fullPath);
if (ret)
{ {
auto skin = new MeshSkin(); SkinData data;
skin->_bindShape = skindata.bindShape; if (instance->loadSkinData(name, &data))
skin->setBoneCount((int)skindata.boneNames.size()); {
for (size_t i = 0; i < skindata.boneNames.size(); i++) { auto skin = new MeshSkin();
auto bone = Bone::create(skindata.boneNames[i]); skin->initFromSkinData(data);
bone->_bindPose = skindata.inverseBindPoseMatrices[i]; skin->autorelease();
skin->addBone(bone); return skin;
} }
for (auto it : skindata.boneChild) {
auto parent = skin->getBoneByIndex(it.first);
for (auto childIt : it.second) {
auto child = skin->getBoneByIndex(childIt);
child->_parent = parent;
parent->_children.pushBack(child);
}
}
skin->setRootBone(skin->getBoneByIndex(skindata.rootBoneIndex));
skin->autorelease();
return skin;
} }
} }
return nullptr; return nullptr;
} }
bool MeshSkin::initFromSkinData(const SkinData& skindata)
{
_bindShape = skindata.bindShape;
setBoneCount((int)skindata.boneNames.size());
for (size_t i = 0; i < skindata.boneNames.size(); i++) {
auto bone = Bone::create(skindata.boneNames[i]);
bone->_bindPose = skindata.inverseBindPoseMatrices[i];
addBone(bone);
}
for (auto it : skindata.boneChild) {
auto parent = getBoneByIndex(it.first);
for (auto childIt : it.second) {
auto child = getBoneByIndex(childIt);
child->_parent = parent;
parent->_children.pushBack(child);
}
}
setRootBone(getBoneByIndex(skindata.rootBoneIndex));
return true;
}
//get & set bind shape matrix //get & set bind shape matrix
const Mat4& MeshSkin::getBindShape() const const Mat4& MeshSkin::getBindShape() const
{ {
@ -430,15 +431,15 @@ void MeshSkin::addBone(Bone* bone)
} }
//////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////
MeshSkinCache* MeshSkinCache::_cacheInstance = nullptr; MeshSkinDataCache* MeshSkinDataCache::_cacheInstance = nullptr;
MeshSkinCache* MeshSkinCache::getInstance() MeshSkinDataCache* MeshSkinDataCache::getInstance()
{ {
if (_cacheInstance == nullptr) if (_cacheInstance == nullptr)
_cacheInstance = new MeshSkinCache(); _cacheInstance = new MeshSkinDataCache();
return _cacheInstance; return _cacheInstance;
} }
void MeshSkinCache::purgeMeshSkinCache() void MeshSkinDataCache::purgeMeshSkinCache()
{ {
if (_cacheInstance) if (_cacheInstance)
{ {
@ -446,50 +447,35 @@ void MeshSkinCache::purgeMeshSkinCache()
} }
} }
MeshSkin* MeshSkinCache::getMeshSkin(const std::string& key) const SkinData* MeshSkinDataCache::getMeshSkinData(const std::string& key) const
{ {
auto it = _skins.find(key); auto it = _skinDatas.find(key);
if (it != _skins.end()) if (it != _skinDatas.end())
return it->second; return &it->second;
return nullptr; return nullptr;
} }
bool MeshSkinCache::addMeshSkin(const std::string& key, MeshSkin* skin) bool MeshSkinDataCache::addMeshSkinData(const std::string& key, const SkinData& skin)
{ {
if (_skins.find(key) != _skins.end()) if (_skinDatas.find(key) != _skinDatas.end())
return false; // already have this key return false; // already have this key
_skins[key] = skin; _skinDatas[key] = skin;
skin->retain();
return true; return true;
} }
void MeshSkinCache::removeAllMeshSkin() void MeshSkinDataCache::removeAllMeshSkin()
{ {
for (auto itr = _skins.begin(); itr != _skins.end(); itr++) { _skinDatas.clear();
CC_SAFE_RELEASE_NULL(itr->second);
}
_skins.clear();
}
void MeshSkinCache::removeUnusedMeshSkin()
{
for( auto it=_skins.cbegin(); it!=_skins.cend(); /* nothing */) {
auto value = it->second;
if( value->getReferenceCount() == 1 ) {
CC_SAFE_RELEASE(value);
_skins.erase(it++);
} else {
++it;
}
}
} }
MeshSkinCache::MeshSkinCache() MeshSkinDataCache::MeshSkinDataCache()
{ {
} }
MeshSkinCache::~MeshSkinCache() MeshSkinDataCache::~MeshSkinDataCache()
{ {
} }

View File

@ -27,6 +27,7 @@
#include <unordered_map> #include <unordered_map>
#include "CCBundle3DData.h"
#include "base/ccMacros.h" #include "base/ccMacros.h"
#include "base/CCRef.h" #include "base/CCRef.h"
#include "base/CCVector.h" #include "base/CCVector.h"
@ -148,7 +149,6 @@ protected:
class MeshSkin: public Ref class MeshSkin: public Ref
{ {
public: public:
static MeshSkin* getOrCreate(const std::string& filename, const std::string& name);
//create a new meshskin if do not want to share meshskin //create a new meshskin if do not want to share meshskin
static MeshSkin* create(const std::string& filename, const std::string& name); static MeshSkin* create(const std::string& filename, const std::string& name);
@ -185,6 +185,8 @@ protected:
~MeshSkin(); ~MeshSkin();
bool initFromSkinData(const SkinData& skindata);
void removeAllBones(); void removeAllBones();
void addBone(Bone* bone); void addBone(Bone* bone);
@ -200,26 +202,26 @@ protected:
Vec4* _matrixPalette; Vec4* _matrixPalette;
}; };
class MeshSkinCache class MeshSkinDataCache
{ {
public: public:
static MeshSkinCache* getInstance(); static MeshSkinDataCache* getInstance();
static void purgeMeshSkinCache(); static void purgeMeshSkinCache();
MeshSkin* getMeshSkin(const std::string& key); const SkinData* getMeshSkinData(const std::string& key) const;
bool addMeshSkin(const std::string& key, MeshSkin* skin); bool addMeshSkinData(const std::string& key, const SkinData& skinData);
void removeAllMeshSkin(); void removeAllMeshSkin();
void removeUnusedMeshSkin(); void removeUnusedMeshSkin();
protected: protected:
MeshSkinCache(); MeshSkinDataCache();
~MeshSkinCache(); ~MeshSkinDataCache();
static MeshSkinCache* _cacheInstance; static MeshSkinDataCache* _cacheInstance;
std::unordered_map<std::string, MeshSkin*> _skins; std::unordered_map<std::string, SkinData> _skinDatas;
}; };
NS_CC_END NS_CC_END