fixed memory leakage, remove unused header, fixed reference args.

This commit is contained in:
Jacky 2015-05-18 15:10:41 +08:00
parent 19c5d2dc84
commit d21f85787e
6 changed files with 70 additions and 103 deletions

View File

@ -28,12 +28,12 @@ THE SOFTWARE.
#include "MarchingSquare.h"
#include <algorithm>
#include <math.h>
#include <stdio.h>
USING_NS_CC;
MarchingSquare::MarchingSquare(const std::string &filename, const unsigned int threshold)
:_image(nullptr)
,_data(nullptr)
,_filename("")
,_threshold(0)
,_width(0)
@ -58,6 +58,7 @@ MarchingSquare::~MarchingSquare()
delete _image;
_image = nullptr;
}
_points.clear();
}
void MarchingSquare::trace()
@ -69,28 +70,31 @@ void MarchingSquare::trace()
unsigned int MarchingSquare::findFirstNoneTransparentPixel()
{
unsigned int first = -1;
for(unsigned int i = 0; i < _width*_height; i++)
{
if(getAlphaAt(i) > _threshold)
if(getAlphaByIndex(i) > _threshold)
{
return i;
first = i;
break;
}
}
throw "image is all transparent!";
CCASSERT(-1 != first, "image is all transparent!");
return first;
}
unsigned char MarchingSquare::getAlphaAt(const unsigned int i)
unsigned char MarchingSquare::getAlphaByIndex(const unsigned int& i)
{
CCASSERT(i < _width*_height, "coordinate is out of range.");
return *(_data+i*4+3);
}
unsigned char MarchingSquare::getAlphaAt(const int x, const int y)
unsigned char MarchingSquare::getAlphaByPos(const unsigned int& x, const unsigned int& y)
{
if(x < 0 || y < 0 || x > _width-1 || y > _height-1)
return 0;
CCASSERT(x < _width-1 && y < _height-1, "coordinate is out of range.");
return *(_data+(y*_width+x)*4+3);
}
unsigned int MarchingSquare::getSquareValue(int x, int y)
unsigned int MarchingSquare::getSquareValue(const unsigned int& x, const unsigned int& y)
{
/*
checking the 2x2 pixel grid, assigning these values to each pixel, if not transparent
@ -101,18 +105,18 @@ unsigned int MarchingSquare::getSquareValue(int x, int y)
+---+---+
*/
unsigned int sv = 0;
if(getAlphaAt(x-1, y-1) > _threshold)
if(getAlphaByPos(x-1, y-1) > _threshold)
sv += 1;
if(getAlphaAt(x,y-1) > _threshold)
if(getAlphaByPos(x,y-1) > _threshold)
sv += 2;
if(getAlphaAt(x-1, y) > _threshold)
if(getAlphaByPos(x-1, y) > _threshold)
sv += 4;
if(getAlphaAt(x, y) > _threshold)
if(getAlphaByPos(x, y) > _threshold)
sv += 8;
return sv;
}
void MarchingSquare::marchSquare(int startx, int starty)
void MarchingSquare::marchSquare(const unsigned int& startx, const unsigned int& starty)
{
int stepx = 0;
int stepy = 0;
@ -248,12 +252,8 @@ void MarchingSquare::marchSquare(int startx, int starty)
case6s.push_back(i);
}
break;
case 0:
CCLOG("case 0 at x:%d, y:%d, coming from %d, %d", curx, cury, prevx, prevy);
throw "this shoudln't happen";
case 15:
CCLOG("case 15 at x:%d, y:%d, coming from %d, %d", curx, cury, prevx, prevy);
throw "this shoudln't happen";
default:
CCLOG("this shouldn't happen.");
}
//little optimization
// if previous direction is same as current direction,
@ -281,8 +281,7 @@ void MarchingSquare::marchSquare(int startx, int starty)
prevx = stepx;
prevy = stepy;
problem = false;
if(count > totalPixel)
throw "oh no, marching square cannot find starting position";
CCASSERT(count <= totalPixel, "oh no, marching square cannot find starting position");
} while(curx != startx || cury != starty);
}
@ -294,24 +293,24 @@ void MarchingSquare::printPoints()
}
}
float MarchingSquare::perpendicularDistance(cocos2d::Vec2 ii, cocos2d::Vec2 ss, cocos2d::Vec2 ee)
float MarchingSquare::perpendicularDistance(const cocos2d::Vec2& i, const cocos2d::Vec2& start, const cocos2d::Vec2& end)
{
float res;
float slope;
float intercept;
if(ss.x == ee.x)
if(start.x == end.x)
{
res = fabsf(ii.x- ee.x);
res = fabsf(i.x- end.x);
}
else if (ss.y == ee.y)
else if (start.y == end.y)
{
res = fabsf(ii.y - ee.y);
res = fabsf(i.y - end.y);
}
else{
slope = (ee.y - ss.y) / (ee.x - ss.x);
intercept = ss.y - (slope*ss.x);
res = fabsf(slope * ii.x - ii.y + intercept) / sqrtf(powf(slope, 2)+1);
slope = (end.y - start.y) / (end.x - start.x);
intercept = start.y - (slope*start.x);
res = fabsf(slope * i.x - i.y + intercept) / sqrtf(powf(slope, 2)+1);
}
return res;
}
@ -352,7 +351,7 @@ std::vector<cocos2d::Vec2> MarchingSquare::rdp(std::vector<cocos2d::Vec2> v)
return ret;
}
}
void MarchingSquare::optimize(const cocos2d::Rect &rect, float level)
void MarchingSquare::optimize(const cocos2d::Rect &rect, const float level)
{
if(level <= 0 || _points.size()<4)
return;
@ -364,38 +363,36 @@ void MarchingSquare::optimize(const cocos2d::Rect &rect, float level)
_points.front().y = last.y;
_points.pop_back();
printPoints();
expand(rect, level);
}
void MarchingSquare::expand(const cocos2d::Rect &rect, float level)
void MarchingSquare::expand(const cocos2d::Rect &rect, const float& level)
{
std::vector<cocos2d::Vec2> offsets;
size_t length = _points.size();
Vec2 v1,v2,v3;
for (int i=0; i<length; i++) {
Vec2 v1;
Vec2 v2;
if (i == 0) {
v1 = _points[i]-_points[length-1];
v2 = _points[i]-_points[i+1];
v1.set(_points[i]-_points[length-1]);
v2.set(_points[i]-_points[i+1]);
}
else if(i == length-1){
v1 = _points[i]-_points[i-1];
v2 = _points[i]-_points[0];
v1.set(_points[i]-_points[i-1]);
v2.set(_points[i]-_points[0]);
}
else{
v1 = _points[i]-_points[i-1];
v2 = _points[i]-_points[i+1];
v1.set(_points[i]-_points[i-1]);
v2.set(_points[i]-_points[i+1]);
}
v1.normalize();
v2.normalize();
Vec2 v3 = isAConvexPoint(v1, -v2)? (v1 + v2) : (-v1-v2);
v3 = isAConvexPoint(v1, -v2)? (v1 + v2) : (-v1-v2);
v3.normalize();
offsets.push_back(v3);
}
for (int i=0; i<length; i++) {
_points[i].x = _points[i].x + offsets[i].x * level*2;
_points[i].y = _points[i].y + offsets[i].y * level*2;
_points[i].x = _points[i].x + offsets[i].x * level;
_points[i].y = _points[i].y + offsets[i].y * level;
_points[i].clamp(rect.origin, rect.origin+rect.size);
}
}

View File

@ -28,12 +28,9 @@ THE SOFTWARE.
#ifndef COCOS_2D_MARCHINGSQUARE_H__
#define COCOS_2D_MARCHINGSQUARE_H__
#include "cocos2d.h"
#include <string>
#include <vector>
#include "base/CCConsole.h"
#include "platform/CCPlatformMacros.h"
#include "math/Vec2.h"
#include "cocos2d.h"
NS_CC_BEGIN
@ -42,32 +39,35 @@ class CC_DLL MarchingSquare
public:
MarchingSquare(const std::string &filename, const unsigned int threshold = 0);
~MarchingSquare();
//TODO: should return list of vec2s
void trace();
void setThreshold(unsigned int threshold){_threshold = threshold;};
unsigned int getThreshold(){return _threshold;};
const unsigned int getThreshold(){return _threshold;};
ssize_t getVecCount(){return _points.size();};
std::vector<cocos2d::Vec2> getPoints(){return _points;};
const std::vector<cocos2d::Vec2> getPoints(){return _points;};
void printPoints();
//using RamerDouglasPeucker algorithm
void optimize(const cocos2d::Rect &rect, float level = 0);
void expand(const cocos2d::Rect &rect, float level = 0);
void trace();
void optimize(const cocos2d::Rect &rect, const float level = 0);
protected:
unsigned int findFirstNoneTransparentPixel();
void marchSquare(int startx, int starty);
unsigned int getSquareValue(int x, int y);
void marchSquare(const unsigned int& startx, const unsigned int& starty);
unsigned int getSquareValue(const unsigned int& x, const unsigned int& y);
unsigned char getAlphaAt(const unsigned int i);
unsigned char getAlphaAt(const int x, const int y);
unsigned char getAlphaByIndex(const unsigned int& i);
unsigned char getAlphaByPos(const unsigned int& x, const unsigned int& y);
int getIndexFromPos(int x, int y){return y*_width+x;};
cocos2d::Vec2 getPosFromIndex(int i){return cocos2d::Vec2(i%_width, i/_width);};
int getIndexFromPos(const unsigned int& x, const unsigned int& y){return y*_width+x;};
cocos2d::Vec2 getPosFromIndex(const unsigned int& i){return cocos2d::Vec2(i%_width, i/_width);};
std::vector<cocos2d::Vec2> rdp(std::vector<cocos2d::Vec2> v);
float perpendicularDistance(cocos2d::Vec2 i, cocos2d::Vec2 start, cocos2d::Vec2 end);
float perpendicularDistance(const cocos2d::Vec2& i, const cocos2d::Vec2& start, const cocos2d::Vec2& end);
bool isAConvexPoint(const cocos2d::Vec2& p1, const cocos2d::Vec2& p2);
void expand(const cocos2d::Rect &rect, const float& level = 0);
cocos2d::Image* _image;
unsigned char * _data;

View File

@ -26,21 +26,8 @@
****************************************************************************/
#include "SpritePolygon.h"
#include "MarchingSquare.h"
#include "base/CCDirector.h"
#include "renderer/CCRenderer.h"
#include "renderer/CCTextureCache.h"
#include "renderer/CCGLProgramState.h"
#include "renderer/CCGLProgramCache.h"
#include <vector>
#include "poly2tri/poly2tri.h"
#include "SpritePolygonCache.h"
#include "platform/CCFileUtils.h"
using namespace std;
USING_NS_CC;
using namespace cocos2d::experimental;
@ -176,8 +163,8 @@ void SpritePolygon::triangulate(const std::string& file, const cocos2d::Rect& re
cdt->Triangulate();
std::vector<p2t::Triangle*> tris = cdt->GetTriangles();
vector<V3F_C4B_T2F> *_verts = new vector<V3F_C4B_T2F>();
vector<unsigned short> *_indices = new vector<unsigned short>;
std::vector<V3F_C4B_T2F> *_verts = new std::vector<V3F_C4B_T2F>();
std::vector<unsigned short> *_indices = new std::vector<unsigned short>;
unsigned short idx = 0;
for(std::vector<p2t::Triangle*>::const_iterator ite = tris.begin(); ite < tris.end(); ite++)
{
@ -253,7 +240,8 @@ bool SpritePolygon::initWithMarching(const std::string &file, const cocos2d::Rec
initWithTexture(texture);
//Marching Square
optimization = 1.169;
if(-1 == optimization)
optimization = 1.169;
auto newrect = rect;
auto marcher = new MarchingSquare(file);
marcher->trace();
@ -354,7 +342,7 @@ bool SpritePolygon::initWithRect(const std::string& file, std::vector<cocos2d::V
CCASSERT(texture, "texture was not loaded properly");
initWithTexture(texture);
//build v3f_c4b_t2f verts from vec2 vector
vector<V3F_C4B_T2F> _verts;
std::vector<V3F_C4B_T2F> _verts;
for(std::vector<Vec2>::const_iterator it = verts.begin(); it<verts.end(); it++)
{
auto v3 = Vec3(it->x, it->y, 0);
@ -436,7 +424,7 @@ const float SpritePolygon::getArea(){
float area = 0;
V3F_C4B_T2F *verts = _polygonInfo->_triangles.verts;
unsigned short *indices = _polygonInfo->_triangles.indices;
for(int i = 0; i < _polygonInfo->_triangles.indexCount; i=i+3)
for(int i = 0; i < _polygonInfo->_triangles.indexCount; i+=3)
{
auto A = verts[indices[i]].vertices;
auto B = verts[indices[i+1]].vertices;

View File

@ -28,10 +28,7 @@
#ifndef COCOS_2D_SpritePolygon_H__
#define COCOS_2D_SpritePolygon_H__
#include <vector>
#include "platform/CCPlatformMacros.h"
#include "2d/CCNode.h"
#include "renderer/CCTrianglesCommand.h"
#include "CCNode.h"
#include "CCDrawNode.h"
#include "SpritePolygonCache.h"
@ -57,7 +54,7 @@ public:
//create from a texture (rect), and automatically trace and optimize the points.
//not recommended for production, its better to use the vec2 list for better performance
static SpritePolygon *create(const std::string& file, 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 = -1);
bool initWithCache(const std::string &file, SpritePolygonInfo *info);
bool initWithTexture(cocos2d::Texture2D *texture);

View File

@ -26,19 +26,8 @@
****************************************************************************/
#include "SpritePolygonCache.h"
#include "3d/CCMesh.h"
#include "3d/CCMeshVertexIndexData.h"
#include "base/CCDirector.h"
#include "renderer/CCRenderer.h"
#include "renderer/CCTextureCache.h"
#include "renderer/CCGLProgramState.h"
#include "renderer/CCGLProgramCache.h"
#include <vector>
#include "poly2tri/poly2tri.h"
#include "platform/CCFileUtils.h"
using namespace std;
USING_NS_CC;
@ -73,7 +62,7 @@ void SpritePolygonCache::init()
_spritePolygonCacheMap.reserve(20);
}
SpritePolygonInfo* SpritePolygonCache::addSpritePolygonCache(const std::string& filePath, const cocos2d::Rect& rect, const cocos2d::TrianglesCommand::Triangles trianglesCommand)
SpritePolygonInfo* SpritePolygonCache::addSpritePolygonCache(const std::string& filePath, const cocos2d::Rect& rect, const cocos2d::TrianglesCommand::Triangles& trianglesCommand)
{
auto fullpath = FileUtils::getInstance()->fullPathForFilename(filePath);;
@ -87,8 +76,8 @@ SpritePolygonInfo* SpritePolygonCache::addSpritePolygonCache(const std::string&
{
if ((*infoIt)->_rect.equals(rect))
{
CC_SAFE_DELETE((*infoIt)->_triangles.verts);
CC_SAFE_DELETE((*infoIt)->_triangles.indices);
CC_SAFE_DELETE_ARRAY((*infoIt)->_triangles.verts);
CC_SAFE_DELETE_ARRAY((*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;

View File

@ -28,11 +28,7 @@
#ifndef COCOS_2D_SpritePolygonCACHE_H__
#define COCOS_2D_SpritePolygonCACHE_H__
#include <vector>
#include "platform/CCPlatformMacros.h"
#include "2d/CCNode.h"
#include "renderer/CCTrianglesCommand.h"
#include "CCDrawNode.h"
NS_CC_BEGIN
@ -63,7 +59,7 @@ public:
virtual ~SpritePolygonCache();
static SpritePolygonCache* getInstance();
static void destroyInstance();
SpritePolygonInfo* addSpritePolygonCache(const std::string& filePath, const cocos2d::Rect& rect, const cocos2d::TrianglesCommand::Triangles trianglesCommand);
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);
void removeSpritePolygonCache(const std::string& filePath, const cocos2d::Rect* rect = nullptr);
void removeAllSpritePolygonCache();