diff --git a/cocos/3d/CCMeshSkin.cpp b/cocos/3d/CCMeshSkin.cpp index 5548f95c70..63623669d0 100644 --- a/cocos/3d/CCMeshSkin.cpp +++ b/cocos/3d/CCMeshSkin.cpp @@ -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() { } diff --git a/cocos/3d/CCMeshSkin.h b/cocos/3d/CCMeshSkin.h index ab838c4e8f..3a71ef9e16 100644 --- a/cocos/3d/CCMeshSkin.h +++ b/cocos/3d/CCMeshSkin.h @@ -27,6 +27,7 @@ #include +#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 _skins; + std::unordered_map _skinDatas; }; NS_CC_END diff --git a/cocos/renderer/ccShader_3D_PositionTex.vert b/cocos/renderer/ccShader_3D_PositionTex.vert index 67210c4caa..33e8e6040c 100644 --- a/cocos/renderer/ccShader_3D_PositionTex.vert +++ b/cocos/renderer/ccShader_3D_PositionTex.vert @@ -30,20 +30,9 @@ uniform vec4 u_matrixPalette[SKINNING_JOINT_COUNT * 3]; varying vec2 TextureCoordOut; vec4 _skinnedPosition; -vec4 tmp; - -void skinPosition(float blendWeight, int matrixIndex) -{ - tmp.x = dot(a_position, u_matrixPalette[matrixIndex]); - tmp.y = dot(a_position, u_matrixPalette[matrixIndex + 1]); - tmp.z = dot(a_position, u_matrixPalette[matrixIndex + 2]); - tmp.w = a_position.w; - _skinnedPosition += blendWeight * tmp; -} vec4 getPosition() { - _skinnedPosition = vec4(0.0); vec4 matrixPalette1 = vec4(0.0); vec4 matrixPalette2 = vec4(0.0); vec4 matrixPalette3 = vec4(0.0);