Merge pull request #11613 from Wu-Hao/v3.6

updated SpritePolygon
This commit is contained in:
minggo 2015-04-27 17:59:59 +08:00
commit 6b13505d1d
7 changed files with 76 additions and 64 deletions

View File

@ -343,4 +343,12 @@ void MarchingSquare::optimize(float level)
return; return;
epsilon = level; epsilon = level;
points = rdp(points); points = rdp(points);
auto last = points.back();
if(last.y > points.front().y)
points.front().y = last.y;
points.pop_back();
//delete the last point, because its almost the same as the starting point
// CCLOG("%.1f, %.1f, %.1f, %.1f", points[0].x, points[0].y, points.back().x, points.back().y);
} }

View File

@ -49,7 +49,6 @@ public:
void printPoints(); void printPoints();
//using RamerDouglasPeucker algorithm //using RamerDouglasPeucker algorithm
void optimize(float level = 0); void optimize(float level = 0);
protected: protected:
unsigned int findFirstNoneTransparentPixel(); unsigned int findFirstNoneTransparentPixel();
void marchSquare(int startx, int starty); void marchSquare(int startx, int starty);
@ -70,6 +69,8 @@ protected:
std::vector<cocos2d::Vec2> rdp(std::vector<cocos2d::Vec2> v); std::vector<cocos2d::Vec2> rdp(std::vector<cocos2d::Vec2> v);
float perpendicularDistance(cocos2d::Vec2 i, cocos2d::Vec2 start, cocos2d::Vec2 end); float perpendicularDistance(cocos2d::Vec2 i, cocos2d::Vec2 start, cocos2d::Vec2 end);
float scaleFactor; float scaleFactor;
}; };
NS_CC_END NS_CC_END

View File

@ -222,19 +222,24 @@ TrianglesCommand::Triangles SpritePolygon::triangulate(std::vector<cocos2d::Vec2
delete cdt; delete cdt;
return TrianglesCommand::Triangles{&(*_verts)[0], &(*_indices)[0], (ssize_t)_verts->size(), (ssize_t)_indices->size()}; return TrianglesCommand::Triangles{&(*_verts)[0], &(*_indices)[0], (ssize_t)_verts->size(), (ssize_t)_indices->size()};
} }
bool SpritePolygon::initWithCache(const std::string &file, const SpritePolygonInfo *info) bool SpritePolygon::initWithCache(const std::string &file, SpritePolygonInfo *info)
{ {
CCASSERT(file.size()>0, "Invalid filename for sprite"); CCASSERT(file.size()>0, "Invalid filename for sprite");
Texture2D *texture = Director::getInstance()->getTextureCache()->addImage(file); Texture2D *texture = Director::getInstance()->getTextureCache()->addImage(file);
if (texture) CCASSERT(texture, "texture was not loaded properly");
{ _polygonInfo = info;
initWithTexture(texture); initWithTexture(texture);
if(_polygonInfo->_rect.equals(Rect::ZERO))
{
setContentSize(Size(texture->getPixelsWide(), texture->getPixelsHigh())/Director::getInstance()->getContentScaleFactor());
} }
else{ else
throw "some error"; {
setContentSize(_polygonInfo->_rect.size);
} }
// _textureRect = info->_textureRect;
// _triangles = info->_triangles;
setAnchorPoint(Vec2(0.5,0.5));
return true; return true;
} }
bool SpritePolygon::initWithMarching(const std::string &file, const cocos2d::Rect &rect, float optimization) bool SpritePolygon::initWithMarching(const std::string &file, const cocos2d::Rect &rect, float optimization)
@ -249,17 +254,17 @@ bool SpritePolygon::initWithMarching(const std::string &file, const cocos2d::Rec
auto marcher = new MarchingSquare(file); auto marcher = new MarchingSquare(file);
marcher->trace(); marcher->trace();
marcher->optimize(optimization); marcher->optimize(optimization);
// marcher->test();
auto p = marcher->getPoints(); auto p = marcher->getPoints();
auto _triangles = triangulate(p); auto triangles = triangulate(p);
delete marcher; delete marcher;
//save result to cache //save result to cache
SpritePolygonInfo info; _polygonInfo = SpritePolygonCache::getInstance()->addSpritePolygonCache(file, rect, triangles);
info._rect = rect; setAnchorPoint(Vec2(0.5,0.5));
info._triangles = _triangles;
_polygonInfo = SpritePolygonCache::getInstance()->addSpritePolygonCache(file, info);
calculateUVandContentSize(); calculateUVandContentSize();
// SpritePolygonCache::printInfo(*_polygonInfo); // SpritePolygonCache::printInfo(*_polygonInfo);
#if CC_SPRITE_DEBUG_DRAW #if CC_SPRITE_DEBUG_DRAW
debugDraw(); debugDraw();
@ -270,15 +275,10 @@ bool SpritePolygon::initWithPoly2tri(const std::string &filename, std::vector<co
{ {
CCASSERT(filename.size()>0, "Invalid filename for sprite"); CCASSERT(filename.size()>0, "Invalid filename for sprite");
Texture2D *texture = Director::getInstance()->getTextureCache()->addImage(filename); Texture2D *texture = Director::getInstance()->getTextureCache()->addImage(filename);
if (texture) CCASSERT(texture, "texture was not loaded properly");
{
initWithTexture(texture); initWithTexture(texture);
} _polygonInfo = SpritePolygonCache::getInstance()->addSpritePolygonCache(filename, Rect, triangulate(verts));
else{ setAnchorPoint(Vec2(0.5,0.5));
throw "some error";
}
SpritePolygonInfo info = SpritePolygonInfo{Rect, triangulate(verts)};
_polygonInfo = SpritePolygonCache::getInstance()->addSpritePolygonCache(filename, info);
calculateUVandContentSize(); calculateUVandContentSize();
#if CC_SPRITE_DEBUG_DRAW #if CC_SPRITE_DEBUG_DRAW
debugDraw(); debugDraw();
@ -328,11 +328,12 @@ bool SpritePolygon::initWithVerts(const std::string& filename,std::vector<cocos2
initWithTexture(texture); initWithTexture(texture);
auto _textureRect = getTextRectFromTriangles(verts); auto _textureRect = getTextRectFromTriangles(verts);
setContentSize(_textureRect.size); setContentSize(_textureRect.size/Director::getInstance()->getContentScaleFactor());
setAnchorPoint(Vec2(0.5,0.5));
_transformDirty = true; _transformDirty = true;
auto _triangles = TrianglesCommand::Triangles{&verts[0], &indices[0], (ssize_t)verts.size(), (ssize_t)indices.size()}; auto _triangles = TrianglesCommand::Triangles{&verts[0], &indices[0], (ssize_t)verts.size(), (ssize_t)indices.size()};
SpritePolygonInfo info = SpritePolygonInfo{_textureRect, _triangles}; _polygonInfo = SpritePolygonCache::getInstance()->addSpritePolygonCache(filename, _textureRect, _triangles);
_polygonInfo = SpritePolygonCache::getInstance()->addSpritePolygonCache(filename, info);
#if CC_SPRITE_DEBUG_DRAW #if CC_SPRITE_DEBUG_DRAW
debugDraw(); debugDraw();
#endif #endif
@ -352,13 +353,12 @@ bool SpritePolygon::initWithRect(const std::string& filename, std::vector<cocos2
auto c4b = Color4B::WHITE; auto c4b = Color4B::WHITE;
auto t2f = Tex2F(0,0); auto t2f = Tex2F(0,0);
_verts.push_back(V3F_C4B_T2F{v3,c4b,t2f}); _verts.push_back(V3F_C4B_T2F{v3,c4b,t2f});
// _indices.push_back(idx);
} }
auto _triangles = TrianglesCommand::Triangles{&_verts[0], &indices[0], (ssize_t)_verts.size(), (ssize_t)indices.size()}; auto _triangles = TrianglesCommand::Triangles{&_verts[0], &indices[0], (ssize_t)_verts.size(), (ssize_t)indices.size()};
SpritePolygonInfo info = SpritePolygonInfo{rect, _triangles}; _polygonInfo = SpritePolygonCache::getInstance()->addSpritePolygonCache(filename, rect, _triangles);
_polygonInfo = SpritePolygonCache::getInstance()->addSpritePolygonCache(filename, info);
calculateUVandContentSize(); calculateUVandContentSize();
setAnchorPoint(Vec2(0.5,0.5));
#if CC_SPRITE_DEBUG_DRAW #if CC_SPRITE_DEBUG_DRAW
debugDraw(); debugDraw();
#endif #endif
@ -370,24 +370,14 @@ bool SpritePolygon::initWithTexture(Texture2D *texture)
Node::init(); Node::init();
//init the triangles command //init the triangles command
setGLProgramState(GLProgramState::getOrCreateWithGLProgramName(GLProgram::SHADER_NAME_POSITION_TEXTURE_COLOR_NO_MVP)); setGLProgramState(GLProgramState::getOrCreateWithGLProgramName(GLProgram::SHADER_NAME_POSITION_TEXTURE_COLOR_NO_MVP));
_blendFunc = BlendFunc::ALPHA_PREMULTIPLIED; _blendFunc = BlendFunc::ALPHA_PREMULTIPLIED;
setTexture(texture); setTexture(texture);
// _textureRect = (rect.equals(Rect::ZERO))? Rect(0,0,texture->getPixelsWide(), texture->getPixelsHigh()) : rect;
setAnchorPoint(Vec2(0.5,0.5));
return true; return true;
} }
void SpritePolygon::setTexture(const std::string &filename) void SpritePolygon::setTexture(const std::string &filename)
{ {
Texture2D *texture = Director::getInstance()->getTextureCache()->addImage(filename); Texture2D *texture = Director::getInstance()->getTextureCache()->addImage(filename);
setTexture(texture); setTexture(texture);
// Rect rect = Rect::ZERO;
// if (texture)
// rect.size = texture->getContentSize();
// setTextureRect(rect);
} }
static unsigned char cc_2x2_white_image[] = { static unsigned char cc_2x2_white_image[] = {
// RGBA8888 // RGBA8888
@ -425,7 +415,6 @@ void SpritePolygon::setTexture(Texture2D *texture)
CC_SAFE_RETAIN(texture); CC_SAFE_RETAIN(texture);
CC_SAFE_RELEASE(_texture); CC_SAFE_RELEASE(_texture);
_texture = texture; _texture = texture;
// updateBlendFunc();
} }
} }
const float SpritePolygon::getArea(){ const float SpritePolygon::getArea(){
@ -454,6 +443,9 @@ void SpritePolygon::debugDraw()
_debugDrawNode = DrawNode::create(); _debugDrawNode = DrawNode::create();
addChild(_debugDrawNode); addChild(_debugDrawNode);
} }
else{
_debugDrawNode->clear();
}
//draw all points //draw all points
auto positions = new (std::nothrow) Vec2[_polygonInfo->_triangles.vertCount]; auto positions = new (std::nothrow) Vec2[_polygonInfo->_triangles.vertCount];
Vec2 *pos = &positions[0]; Vec2 *pos = &positions[0];

View File

@ -58,7 +58,7 @@ public:
//not recommended for production, its better to use the vec2 list for better performance //not recommended for production, its better to use the vec2 list for better performance
static SpritePolygon *create(const std::string&, const cocos2d::Rect& rect = cocos2d::Rect::ZERO, float optimization = -1); static SpritePolygon *create(const std::string&, const cocos2d::Rect& rect = cocos2d::Rect::ZERO, float optimization = -1);
bool initWithMarching(const std::string &file, const cocos2d::Rect &rect, float optimization); bool initWithMarching(const std::string &file, const cocos2d::Rect &rect, float optimization);
bool initWithCache(const std::string &file, const SpritePolygonInfo *info); bool initWithCache(const std::string &file, SpritePolygonInfo *info);
bool initWithTexture(cocos2d::Texture2D *texture); bool initWithTexture(cocos2d::Texture2D *texture);
@ -78,14 +78,9 @@ protected:
void calculateUVandContentSize(); void calculateUVandContentSize();
bool _triangleDirty; //if triangle is dirty, then it needs to be recalculated from verts and indices
// std::vector<cocos2d::V3F_C4B_T2F> _verts;
// std::vector<unsigned short> _indices;
cocos2d::TrianglesCommand _tcmd; cocos2d::TrianglesCommand _tcmd;
cocos2d::BlendFunc _blendFunc; cocos2d::BlendFunc _blendFunc;
// cocos2d::TrianglesCommand::Triangles _triangles;
cocos2d::Texture2D *_texture; cocos2d::Texture2D *_texture;
// cocos2d::Rect _textureRect;
SpritePolygonInfo *_polygonInfo; SpritePolygonInfo *_polygonInfo;
virtual void draw(cocos2d::Renderer *renderer, const cocos2d::Mat4 &transform, uint32_t flags); virtual void draw(cocos2d::Renderer *renderer, const cocos2d::Mat4 &transform, uint32_t flags);

View File

@ -73,7 +73,7 @@ void SpritePolygonCache::init()
} }
SpritePolygonInfo* SpritePolygonCache::addSpritePolygonCache(const std::string& filePath, const SpritePolygonInfo& spritePolygonInfo) SpritePolygonInfo* SpritePolygonCache::addSpritePolygonCache(const std::string& filePath, const cocos2d::Rect& rect, const cocos2d::TrianglesCommand::Triangles trianglesCommand)
{ {
auto fullpath = filePath; auto fullpath = filePath;
@ -85,11 +85,18 @@ SpritePolygonInfo* SpritePolygonCache::addSpritePolygonCache(const std::string&
auto infoIt = vecInfo.begin(); auto infoIt = vecInfo.begin();
for (; infoIt != vecInfo.end(); infoIt++) for (; infoIt != vecInfo.end(); infoIt++)
{ {
if ((*infoIt)->_rect.equals(spritePolygonInfo._rect)) if ((*infoIt)->_rect.equals(rect))
{ {
(*infoIt)->_triangles = spritePolygonInfo._triangles; //Update
// (*infoIt)->_textureRect = SpritePolygonInfo._textureRect; CC_SAFE_DELETE((*infoIt)->_triangles.verts);
return nullptr; CC_SAFE_DELETE((*infoIt)->_triangles.indices);
(*infoIt)->_triangles.verts = new V3F_C4B_T2F[trianglesCommand.vertCount];
(*infoIt)->_triangles.indices = new unsigned short[trianglesCommand.indexCount];
(*infoIt)->_triangles.vertCount = trianglesCommand.vertCount;
(*infoIt)->_triangles.indexCount = trianglesCommand.indexCount;
memcpy((*infoIt)->_triangles.verts, trianglesCommand.verts, trianglesCommand.vertCount*sizeof(V3F_C4B_T2F));
memcpy((*infoIt)->_triangles.indices, trianglesCommand.indices, trianglesCommand.indexCount*sizeof(unsigned short));
return *infoIt;
} }
} }
} }
@ -103,16 +110,16 @@ SpritePolygonInfo* SpritePolygonCache::addSpritePolygonCache(const std::string&
SpritePolygonInfo* info = new SpritePolygonInfo; SpritePolygonInfo* info = new SpritePolygonInfo;
if (nullptr != info) if (nullptr != info)
{ {
info->_rect = spritePolygonInfo._rect; info->_rect = rect;
info->_triangles.verts = new V3F_C4B_T2F[spritePolygonInfo._triangles.vertCount]; info->_triangles.verts = new V3F_C4B_T2F[trianglesCommand.vertCount];
info->_triangles.indices = new unsigned short[spritePolygonInfo._triangles.indexCount]; info->_triangles.indices = new unsigned short[trianglesCommand.indexCount];
info->_triangles.vertCount = spritePolygonInfo._triangles.vertCount; info->_triangles.vertCount = trianglesCommand.vertCount;
info->_triangles.indexCount = spritePolygonInfo._triangles.indexCount; info->_triangles.indexCount = trianglesCommand.indexCount;
memcpy(info->_triangles.verts, spritePolygonInfo._triangles.verts, spritePolygonInfo._triangles.vertCount*sizeof(V3F_C4B_T2F));
memcpy(info->_triangles.indices, spritePolygonInfo._triangles.indices, spritePolygonInfo._triangles.indexCount*sizeof(unsigned short)); memcpy(info->_triangles.verts, trianglesCommand.verts, trianglesCommand.vertCount*sizeof(V3F_C4B_T2F));
// info->_textureRect = SpritePolygonInfo._textureRect; memcpy(info->_triangles.indices, trianglesCommand.indices, trianglesCommand.indexCount*sizeof(unsigned short));
vecInfo.push_back(info); vecInfo.push_back(info);
_SpritePolygonCacheMap[filePath] = vecInfo; _SpritePolygonCacheMap[filePath] = vecInfo;
@ -156,6 +163,7 @@ void SpritePolygonCache::removeSpritePolygonCache(const std::string& filePath,
{ {
if((*infoIter)->_rect.equals(*rect)) if((*infoIter)->_rect.equals(*rect))
{ {
CC_SAFE_DELETE(*infoIter);
it->second.erase(infoIter); it->second.erase(infoIter);
break; break;
} }
@ -168,6 +176,10 @@ void SpritePolygonCache::removeAllSpritePolygonCache()
{ {
for (std::unordered_map<std::string, VecSpritePolygonInfo>::iterator it = _SpritePolygonCacheMap.begin(); it != _SpritePolygonCacheMap.end(); ++it) for (std::unordered_map<std::string, VecSpritePolygonInfo>::iterator it = _SpritePolygonCacheMap.begin(); it != _SpritePolygonCacheMap.end(); ++it)
{ {
for (auto infoIter = it->second.begin(); infoIter != it->second.end(); infoIter++)
{
CC_SAFE_DELETE(*infoIter);
}
it->second.clear(); it->second.clear();
} }
_SpritePolygonCacheMap.clear(); _SpritePolygonCacheMap.clear();

View File

@ -44,12 +44,12 @@ typedef struct CC_DLL _SpritePolygonInfo
{ {
if(nullptr != _triangles.verts) if(nullptr != _triangles.verts)
{ {
CC_SAFE_DELETE(_triangles.verts); CC_SAFE_DELETE_ARRAY(_triangles.verts);
} }
if(nullptr != _triangles.indices) if(nullptr != _triangles.indices)
{ {
CC_SAFE_DELETE(_triangles.indices); CC_SAFE_DELETE_ARRAY(_triangles.indices);
} }
} }
} SpritePolygonInfo; } SpritePolygonInfo;
@ -63,7 +63,7 @@ public:
virtual ~SpritePolygonCache(); virtual ~SpritePolygonCache();
static SpritePolygonCache* getInstance(); static SpritePolygonCache* getInstance();
static void destroyInstance(); static void destroyInstance();
SpritePolygonInfo* addSpritePolygonCache(const std::string& filePath, const SpritePolygonInfo& SpritePolygonInfo); SpritePolygonInfo* addSpritePolygonCache(const std::string& filePath, const cocos2d::Rect& rect, const cocos2d::TrianglesCommand::Triangles trianglesCommand);
SpritePolygonInfo* getSpritePolygonCache(const std::string& filePath, const cocos2d::Rect& rect); SpritePolygonInfo* getSpritePolygonCache(const std::string& filePath, const cocos2d::Rect& rect);
void removeSpritePolygonCache(const std::string& filePath, const cocos2d::Rect* rect = nullptr); void removeSpritePolygonCache(const std::string& filePath, const cocos2d::Rect* rect = nullptr);
void removeAllSpritePolygonCache(); void removeAllSpritePolygonCache();

View File

@ -94,7 +94,11 @@ SpritePolygonTest1::SpritePolygonTest1()
SpritePolygonCache::getInstance()->removeAllSpritePolygonCache(); SpritePolygonCache::getInstance()->removeAllSpritePolygonCache();
_title = "SpritePolygon Creation"; _title = "SpritePolygon Creation";
_subtitle = "SpritePolygon::create(\"Images/grossini.png\")"; _subtitle = "SpritePolygon::create(\"Images/grossini.png\")";
auto s = experimental::SpritePolygon::create(s_pathGrossini); cocos2d::experimental::SpritePolygon *s;
for(int i = 0; i < 10; i ++)
{
s= experimental::SpritePolygon::create(s_pathGrossini);
}
initDefaultSprite(s_pathGrossini, s); initDefaultSprite(s_pathGrossini, s);
} }