This commit is contained in:
yangxiao 2014-06-16 19:17:07 +08:00
Родитель 2c6f7b63d1
Коммит 531f8998a1
2 изменённых файлов: 69 добавлений и 81 удалений

Просмотреть файл

@ -259,61 +259,62 @@ MeshSkin::~MeshSkin()
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
MeshSkin* MeshSkin::create(const std::string& filename, const std::string& name)
{
//load skin here;
std::string fullPath = FileUtils::getInstance()->fullPathForFilename(filename);
auto instance = Bundle3D::getInstance();
bool ret = instance->load(fullPath);
if (ret)
std::string key = fullPath + "#" + name;
const auto skindata = MeshSkinDataCache::getInstance()->getMeshSkinData(key);
if (skindata)
{
SkinData skindata;
if (instance->loadSkinData(name, &skindata))
auto skin = new MeshSkin();
skin->initFromSkinData(*skindata);
skin->autorelease();
return skin;
}
else
{
auto instance = Bundle3D::getInstance();
bool ret = instance->load(fullPath);
if (ret)
{
auto skin = new MeshSkin();
skin->_bindShape = skindata.bindShape;
skin->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];
skin->addBone(bone);
SkinData data;
if (instance->loadSkinData(name, &data))
{
auto skin = new MeshSkin();
skin->initFromSkinData(data);
skin->autorelease();
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;
}
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
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)
_cacheInstance = new MeshSkinCache();
_cacheInstance = new MeshSkinDataCache();
return _cacheInstance;
}
void MeshSkinCache::purgeMeshSkinCache()
void MeshSkinDataCache::purgeMeshSkinCache()
{
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);
if (it != _skins.end())
return it->second;
auto it = _skinDatas.find(key);
if (it != _skinDatas.end())
return &it->second;
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
_skins[key] = skin;
skin->retain();
_skinDatas[key] = skin;
return true;
}
void MeshSkinCache::removeAllMeshSkin()
void MeshSkinDataCache::removeAllMeshSkin()
{
for (auto itr = _skins.begin(); itr != _skins.end(); itr++) {
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;
}
}
_skinDatas.clear();
}
MeshSkinCache::MeshSkinCache()
MeshSkinDataCache::MeshSkinDataCache()
{
}
MeshSkinCache::~MeshSkinCache()
MeshSkinDataCache::~MeshSkinDataCache()
{
}

Просмотреть файл

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