mirror of https://github.com/axmolengine/axmol.git
skincache
This commit is contained in:
parent
2c6f7b63d1
commit
531f8998a1
|
@ -259,59 +259,60 @@ 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);
|
||||||
|
std::string key = fullPath + "#" + name;
|
||||||
|
const auto skindata = MeshSkinDataCache::getInstance()->getMeshSkinData(key);
|
||||||
|
if (skindata)
|
||||||
|
{
|
||||||
|
auto skin = new MeshSkin();
|
||||||
|
skin->initFromSkinData(*skindata);
|
||||||
|
skin->autorelease();
|
||||||
|
return skin;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
auto instance = Bundle3D::getInstance();
|
auto instance = Bundle3D::getInstance();
|
||||||
bool ret = instance->load(fullPath);
|
bool ret = instance->load(fullPath);
|
||||||
if (ret)
|
if (ret)
|
||||||
{
|
{
|
||||||
SkinData skindata;
|
SkinData data;
|
||||||
if (instance->loadSkinData(name, &skindata))
|
if (instance->loadSkinData(name, &data))
|
||||||
{
|
{
|
||||||
auto skin = new MeshSkin();
|
auto skin = new MeshSkin();
|
||||||
skin->_bindShape = skindata.bindShape;
|
skin->initFromSkinData(data);
|
||||||
skin->setBoneCount((int)skindata.boneNames.size());
|
skin->autorelease();
|
||||||
|
return skin;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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++) {
|
for (size_t i = 0; i < skindata.boneNames.size(); i++) {
|
||||||
auto bone = Bone::create(skindata.boneNames[i]);
|
auto bone = Bone::create(skindata.boneNames[i]);
|
||||||
bone->_bindPose = skindata.inverseBindPoseMatrices[i];
|
bone->_bindPose = skindata.inverseBindPoseMatrices[i];
|
||||||
skin->addBone(bone);
|
addBone(bone);
|
||||||
}
|
}
|
||||||
for (auto it : skindata.boneChild) {
|
for (auto it : skindata.boneChild) {
|
||||||
auto parent = skin->getBoneByIndex(it.first);
|
auto parent = getBoneByIndex(it.first);
|
||||||
for (auto childIt : it.second) {
|
for (auto childIt : it.second) {
|
||||||
auto child = skin->getBoneByIndex(childIt);
|
auto child = getBoneByIndex(childIt);
|
||||||
child->_parent = parent;
|
child->_parent = parent;
|
||||||
parent->_children.pushBack(child);
|
parent->_children.pushBack(child);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
skin->setRootBone(skin->getBoneByIndex(skindata.rootBoneIndex));
|
setRootBone(getBoneByIndex(skindata.rootBoneIndex));
|
||||||
|
return true;
|
||||||
skin->autorelease();
|
|
||||||
return skin;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
return nullptr;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//get & set bind shape matrix
|
//get & set bind shape matrix
|
||||||
|
@ -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()
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in New Issue