mirror of https://github.com/axmolengine/axmol.git
fixed memory leakage, remove unused header, fixed reference args.
This commit is contained in:
parent
19c5d2dc84
commit
d21f85787e
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 Ramer–Douglas–Peucker 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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
|
Loading…
Reference in New Issue