2015-04-23 14:34:56 +08:00
|
|
|
/****************************************************************************
|
|
|
|
Copyright (c) 2008-2010 Ricardo Quesada
|
|
|
|
Copyright (c) 2010-2012 cocos2d-x.org
|
|
|
|
Copyright (c) 2011 Zynga Inc.
|
|
|
|
Copyright (c) 2013-2014 Chukong Technologies Inc.
|
|
|
|
|
|
|
|
http://www.cocos2d-x.org
|
|
|
|
|
|
|
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
|
|
of this software and associated documentation files (the "Software"), to deal
|
|
|
|
in the Software without restriction, including without limitation the rights
|
|
|
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
|
|
copies of the Software, and to permit persons to whom the Software is
|
|
|
|
furnished to do so, subject to the following conditions:
|
|
|
|
|
|
|
|
The above copyright notice and this permission notice shall be included in
|
|
|
|
all copies or substantial portions of the Software.
|
|
|
|
|
|
|
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
|
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|
|
|
THE SOFTWARE.
|
|
|
|
****************************************************************************/
|
|
|
|
|
|
|
|
#include "SpritePolygonCache.h"
|
2015-05-20 06:07:50 +08:00
|
|
|
#include "AutoPolygon.h"
|
2015-04-23 14:34:56 +08:00
|
|
|
#include "platform/CCFileUtils.h"
|
2015-05-19 11:25:53 +08:00
|
|
|
#include "base/CCDirector.h"
|
|
|
|
#include "renderer/CCTextureCache.h"
|
2015-05-20 06:07:50 +08:00
|
|
|
#include "poly2tri/poly2tri.h"
|
2015-04-23 14:34:56 +08:00
|
|
|
USING_NS_CC;
|
|
|
|
|
2015-05-15 17:18:19 +08:00
|
|
|
SpritePolygonCache* SpritePolygonCache::s_spritePolygonCache = nullptr;
|
2015-04-23 14:34:56 +08:00
|
|
|
|
|
|
|
SpritePolygonCache::SpritePolygonCache()
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
SpritePolygonCache::~SpritePolygonCache()
|
|
|
|
{
|
2015-05-18 15:52:46 +08:00
|
|
|
removeAllSpritePolygonCache();
|
2015-04-23 14:34:56 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
SpritePolygonCache* SpritePolygonCache::getInstance()
|
|
|
|
{
|
2015-05-15 17:18:19 +08:00
|
|
|
if (nullptr == s_spritePolygonCache)
|
2015-04-23 14:34:56 +08:00
|
|
|
{
|
2015-05-15 17:18:19 +08:00
|
|
|
s_spritePolygonCache = new (std::nothrow) SpritePolygonCache();
|
|
|
|
s_spritePolygonCache->init();
|
2015-04-23 14:34:56 +08:00
|
|
|
}
|
2015-05-15 17:18:19 +08:00
|
|
|
return s_spritePolygonCache;
|
2015-04-23 14:34:56 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void SpritePolygonCache::destroyInstance()
|
|
|
|
{
|
2015-05-15 17:18:19 +08:00
|
|
|
CC_SAFE_DELETE(s_spritePolygonCache);
|
2015-04-23 14:34:56 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
void SpritePolygonCache::init()
|
|
|
|
{
|
2015-05-15 17:18:19 +08:00
|
|
|
_spritePolygonCacheMap.reserve(20);
|
2015-04-23 14:34:56 +08:00
|
|
|
}
|
|
|
|
|
2015-05-20 06:07:50 +08:00
|
|
|
SpritePolygonInfo* SpritePolygonCache::addSpritePolygonCache(const std::string& filePath, const cocos2d::Rect& rect, const cocos2d::TrianglesCommand::Triangles& triangles)
|
2015-04-23 14:34:56 +08:00
|
|
|
{
|
2015-05-15 17:18:19 +08:00
|
|
|
auto fullpath = FileUtils::getInstance()->fullPathForFilename(filePath);;
|
2015-04-23 14:34:56 +08:00
|
|
|
|
2015-05-15 17:18:19 +08:00
|
|
|
auto it = _spritePolygonCacheMap.find(fullpath);
|
|
|
|
if (_spritePolygonCacheMap.end() != it)
|
2015-04-23 14:34:56 +08:00
|
|
|
{
|
|
|
|
VecSpritePolygonInfo vecInfo = it->second;
|
|
|
|
|
|
|
|
auto infoIt = vecInfo.begin();
|
|
|
|
for (; infoIt != vecInfo.end(); infoIt++)
|
|
|
|
{
|
2015-04-27 15:19:26 +08:00
|
|
|
if ((*infoIt)->_rect.equals(rect))
|
2015-04-23 14:34:56 +08:00
|
|
|
{
|
2015-05-18 15:10:41 +08:00
|
|
|
CC_SAFE_DELETE_ARRAY((*infoIt)->_triangles.verts);
|
|
|
|
CC_SAFE_DELETE_ARRAY((*infoIt)->_triangles.indices);
|
2015-05-20 06:07:50 +08:00
|
|
|
(*infoIt)->_triangles.verts = new V3F_C4B_T2F[triangles.vertCount];
|
|
|
|
(*infoIt)->_triangles.indices = new unsigned short[triangles.indexCount];
|
|
|
|
(*infoIt)->_triangles.vertCount = triangles.vertCount;
|
|
|
|
(*infoIt)->_triangles.indexCount = triangles.indexCount;
|
|
|
|
memcpy((*infoIt)->_triangles.verts, triangles.verts, triangles.vertCount*sizeof(V3F_C4B_T2F));
|
|
|
|
memcpy((*infoIt)->_triangles.indices, triangles.indices, triangles.indexCount*sizeof(unsigned short));
|
2015-04-27 15:19:26 +08:00
|
|
|
return *infoIt;
|
2015-04-23 14:34:56 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-04-27 15:19:26 +08:00
|
|
|
VecSpritePolygonInfo vecInfo;
|
2015-04-23 14:34:56 +08:00
|
|
|
vecInfo.clear();
|
2015-05-15 17:18:19 +08:00
|
|
|
if (it != _spritePolygonCacheMap.end())
|
2015-04-27 11:57:36 +08:00
|
|
|
{
|
|
|
|
vecInfo = it->second;
|
|
|
|
}
|
2015-04-27 10:44:23 +08:00
|
|
|
SpritePolygonInfo* info = new SpritePolygonInfo;
|
2015-04-23 14:34:56 +08:00
|
|
|
if (nullptr != info)
|
|
|
|
{
|
2015-04-27 15:19:26 +08:00
|
|
|
info->_rect = rect;
|
2015-05-20 06:07:50 +08:00
|
|
|
info->_triangles.verts = new V3F_C4B_T2F[triangles.vertCount];
|
|
|
|
info->_triangles.indices = new unsigned short[triangles.indexCount];
|
|
|
|
info->_triangles.vertCount = triangles.vertCount;
|
|
|
|
info->_triangles.indexCount = triangles.indexCount;
|
|
|
|
memcpy(info->_triangles.verts, triangles.verts, triangles.vertCount*sizeof(V3F_C4B_T2F));
|
|
|
|
memcpy(info->_triangles.indices, triangles.indices, triangles.indexCount*sizeof(unsigned short));
|
2015-04-23 14:34:56 +08:00
|
|
|
|
|
|
|
vecInfo.push_back(info);
|
2015-05-15 17:18:19 +08:00
|
|
|
_spritePolygonCacheMap[filePath] = vecInfo;
|
2015-04-23 14:34:56 +08:00
|
|
|
}
|
|
|
|
return info;
|
|
|
|
}
|
|
|
|
|
2015-05-19 11:25:53 +08:00
|
|
|
SpritePolygonInfo* SpritePolygonCache::getSpritePolygonCache(const std::string& filePath, const cocos2d::Rect& rect, float optimization)
|
2015-04-23 14:34:56 +08:00
|
|
|
{
|
2015-05-19 11:25:53 +08:00
|
|
|
SpritePolygonInfo* spritePolygonInfo = nullptr;
|
|
|
|
bool isFound = false;
|
|
|
|
|
|
|
|
auto fullpath = FileUtils::getInstance()->fullPathForFilename(filePath);
|
|
|
|
if(fullpath.size() == 0)
|
|
|
|
{
|
2015-04-23 14:34:56 +08:00
|
|
|
return nullptr;
|
2015-05-19 11:25:53 +08:00
|
|
|
}
|
2015-04-23 14:34:56 +08:00
|
|
|
|
2015-05-19 11:25:53 +08:00
|
|
|
auto it = _spritePolygonCacheMap.find(fullpath);
|
|
|
|
if (_spritePolygonCacheMap.end() != it)
|
2015-04-23 14:34:56 +08:00
|
|
|
{
|
2015-05-19 11:25:53 +08:00
|
|
|
auto infoIter = it->second.begin();
|
|
|
|
for (; infoIter != it->second.end(); infoIter++)
|
|
|
|
{
|
|
|
|
if ((*infoIter)->_rect.equals(rect))
|
|
|
|
{
|
|
|
|
spritePolygonInfo = *infoIter;
|
|
|
|
isFound = true;
|
|
|
|
}
|
|
|
|
}
|
2015-04-23 14:34:56 +08:00
|
|
|
}
|
|
|
|
|
2015-05-20 06:07:50 +08:00
|
|
|
if(!isFound)
|
2015-05-19 11:25:53 +08:00
|
|
|
{
|
2015-05-20 06:07:50 +08:00
|
|
|
//we need 5 steps to get cocos2d::TrianglesCommand::Triangles for cache.
|
|
|
|
//1.trace 2.optimize 3.expand 4.triangulate 5.calculateuv
|
2015-05-19 11:25:53 +08:00
|
|
|
if(-1 == optimization) optimization = 1.169;
|
2015-05-20 06:07:50 +08:00
|
|
|
AutoPolygon autopolygon(fullpath);
|
|
|
|
autopolygon.generateTriangles(rect, optimization);
|
|
|
|
spritePolygonInfo = addSpritePolygonCache(fullpath, rect, autopolygon.getTriangles());
|
2015-05-19 11:25:53 +08:00
|
|
|
}
|
|
|
|
return spritePolygonInfo;
|
2015-04-23 14:34:56 +08:00
|
|
|
}
|
|
|
|
|
2015-05-15 17:18:19 +08:00
|
|
|
void SpritePolygonCache::removeSpritePolygonCache(const std::string& filePath, const cocos2d::Rect* rect)
|
2015-04-23 14:34:56 +08:00
|
|
|
{
|
|
|
|
std::string fullpath = FileUtils::getInstance()->fullPathForFilename(filePath);
|
|
|
|
if (fullpath.size() == 0)
|
|
|
|
return;
|
|
|
|
|
2015-05-15 17:18:19 +08:00
|
|
|
auto it = _spritePolygonCacheMap.find(fullpath);
|
|
|
|
if (_spritePolygonCacheMap.end() == it)
|
2015-04-23 14:34:56 +08:00
|
|
|
return;
|
|
|
|
|
|
|
|
if (nullptr == rect)
|
2015-04-27 11:01:47 +08:00
|
|
|
return;
|
2015-04-23 14:34:56 +08:00
|
|
|
|
|
|
|
auto infoIter = it->second.begin();
|
|
|
|
for (; infoIter != it->second.end(); infoIter++)
|
|
|
|
{
|
2015-04-27 11:01:47 +08:00
|
|
|
if((*infoIter)->_rect.equals(*rect))
|
|
|
|
{
|
2015-04-27 15:19:26 +08:00
|
|
|
CC_SAFE_DELETE(*infoIter);
|
2015-04-27 11:57:36 +08:00
|
|
|
it->second.erase(infoIter);
|
2015-04-27 11:01:47 +08:00
|
|
|
break;
|
|
|
|
}
|
2015-04-23 14:34:56 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2015-04-24 18:17:12 +08:00
|
|
|
void SpritePolygonCache::removeAllSpritePolygonCache()
|
2015-04-23 14:34:56 +08:00
|
|
|
{
|
2015-05-15 17:18:19 +08:00
|
|
|
for (std::unordered_map<std::string, VecSpritePolygonInfo>::iterator it = _spritePolygonCacheMap.begin(); it != _spritePolygonCacheMap.end(); ++it)
|
2015-04-24 18:17:12 +08:00
|
|
|
{
|
2015-04-27 15:19:26 +08:00
|
|
|
for (auto infoIter = it->second.begin(); infoIter != it->second.end(); infoIter++)
|
|
|
|
{
|
|
|
|
CC_SAFE_DELETE(*infoIter);
|
|
|
|
}
|
2015-04-24 18:17:12 +08:00
|
|
|
it->second.clear();
|
|
|
|
}
|
2015-05-15 17:18:19 +08:00
|
|
|
_spritePolygonCacheMap.clear();
|
2015-04-23 14:34:56 +08:00
|
|
|
}
|
|
|
|
|
2015-05-15 17:18:19 +08:00
|
|
|
bool SpritePolygonCache::isSpritePolygonCacheExist(const std::string& filePath, const cocos2d::Rect& rect)
|
2015-04-23 14:34:56 +08:00
|
|
|
{
|
|
|
|
std::string fullpath = FileUtils::getInstance()->fullPathForFilename(filePath);
|
|
|
|
if (fullpath.size() == 0)
|
|
|
|
return false;
|
|
|
|
|
2015-05-15 17:18:19 +08:00
|
|
|
auto it = _spritePolygonCacheMap.find(fullpath);
|
|
|
|
if (_spritePolygonCacheMap.end() == it)
|
2015-04-23 14:34:56 +08:00
|
|
|
return false;
|
|
|
|
|
|
|
|
auto infoIter = it->second.begin();
|
|
|
|
for (; infoIter != it->second.end(); infoIter++)
|
|
|
|
{
|
|
|
|
if ((*infoIter)->_rect.equals(rect))
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void SpritePolygonCache::printInfo(SpritePolygonInfo &info){
|
|
|
|
CCLOG("========================");
|
|
|
|
CCLOG("%zd, %zd", info._triangles.vertCount, info._triangles.indexCount);
|
|
|
|
|
|
|
|
auto vertEnd = &info._triangles.verts[info._triangles.vertCount];
|
|
|
|
for(auto v = info._triangles.verts; v < vertEnd; v++)
|
|
|
|
{
|
2015-04-27 10:44:23 +08:00
|
|
|
CCLOG("%f, %f", v->vertices.x, v->vertices.y);
|
2015-04-23 14:34:56 +08:00
|
|
|
}
|
|
|
|
auto indEnd = &info._triangles.indices[info._triangles.indexCount];
|
|
|
|
for(auto i = info._triangles.indices; i < indEnd; i+=3)
|
|
|
|
{
|
2015-04-27 13:34:47 +08:00
|
|
|
CCLOG("%d, %d, %d,", *i,*(i+1), *(i+2));
|
|
|
|
}
|
|
|
|
|
|
|
|
auto uvEnd = &info._triangles.verts[info._triangles.vertCount];
|
|
|
|
for(auto v = info._triangles.verts; v < uvEnd; v++)
|
|
|
|
{
|
|
|
|
CCLOG("%f, %f", v->texCoords.u, v->texCoords.v);
|
2015-04-23 14:34:56 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
USING_NS_CC;
|