mirror of https://github.com/axmolengine/axmol.git
change to autopolygon.
This commit is contained in:
parent
514c8ae965
commit
bbaa60bbbb
|
@ -826,10 +826,10 @@
|
|||
15FB206F1AE7BE7400C31518 /* SpritePolygonCache.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 15FB20681AE7BE7400C31518 /* SpritePolygonCache.cpp */; };
|
||||
15FB20701AE7BE7400C31518 /* SpritePolygonCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 15FB20691AE7BE7400C31518 /* SpritePolygonCache.h */; };
|
||||
15FB20711AE7BE7400C31518 /* SpritePolygonCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 15FB20691AE7BE7400C31518 /* SpritePolygonCache.h */; };
|
||||
15FB20741AE7BF8600C31518 /* MarchingSquare.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 15FB20721AE7BF8600C31518 /* MarchingSquare.cpp */; };
|
||||
15FB20751AE7BF8600C31518 /* MarchingSquare.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 15FB20721AE7BF8600C31518 /* MarchingSquare.cpp */; };
|
||||
15FB20761AE7BF8600C31518 /* MarchingSquare.h in Headers */ = {isa = PBXBuildFile; fileRef = 15FB20731AE7BF8600C31518 /* MarchingSquare.h */; };
|
||||
15FB20771AE7BF8600C31518 /* MarchingSquare.h in Headers */ = {isa = PBXBuildFile; fileRef = 15FB20731AE7BF8600C31518 /* MarchingSquare.h */; };
|
||||
15FB20741AE7BF8600C31518 /* AutoPolygon.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 15FB20721AE7BF8600C31518 /* AutoPolygon.cpp */; };
|
||||
15FB20751AE7BF8600C31518 /* AutoPolygon.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 15FB20721AE7BF8600C31518 /* AutoPolygon.cpp */; };
|
||||
15FB20761AE7BF8600C31518 /* AutoPolygon.h in Headers */ = {isa = PBXBuildFile; fileRef = 15FB20731AE7BF8600C31518 /* AutoPolygon.h */; };
|
||||
15FB20771AE7BF8600C31518 /* AutoPolygon.h in Headers */ = {isa = PBXBuildFile; fileRef = 15FB20731AE7BF8600C31518 /* AutoPolygon.h */; };
|
||||
15FB20871AE7C57D00C31518 /* shapes.cc in Sources */ = {isa = PBXBuildFile; fileRef = 15FB207A1AE7C57D00C31518 /* shapes.cc */; };
|
||||
15FB20881AE7C57D00C31518 /* shapes.cc in Sources */ = {isa = PBXBuildFile; fileRef = 15FB207A1AE7C57D00C31518 /* shapes.cc */; };
|
||||
15FB20891AE7C57D00C31518 /* shapes.h in Headers */ = {isa = PBXBuildFile; fileRef = 15FB207B1AE7C57D00C31518 /* shapes.h */; };
|
||||
|
@ -2713,8 +2713,8 @@
|
|||
15FB20671AE7BE7400C31518 /* SpritePolygon.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SpritePolygon.h; sourceTree = "<group>"; };
|
||||
15FB20681AE7BE7400C31518 /* SpritePolygonCache.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = SpritePolygonCache.cpp; sourceTree = "<group>"; };
|
||||
15FB20691AE7BE7400C31518 /* SpritePolygonCache.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SpritePolygonCache.h; sourceTree = "<group>"; };
|
||||
15FB20721AE7BF8600C31518 /* MarchingSquare.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = MarchingSquare.cpp; sourceTree = "<group>"; };
|
||||
15FB20731AE7BF8600C31518 /* MarchingSquare.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MarchingSquare.h; sourceTree = "<group>"; };
|
||||
15FB20721AE7BF8600C31518 /* AutoPolygon.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = AutoPolygon.cpp; sourceTree = "<group>"; };
|
||||
15FB20731AE7BF8600C31518 /* AutoPolygon.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AutoPolygon.h; sourceTree = "<group>"; };
|
||||
15FB207A1AE7C57D00C31518 /* shapes.cc */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = shapes.cc; sourceTree = "<group>"; };
|
||||
15FB207B1AE7C57D00C31518 /* shapes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = shapes.h; sourceTree = "<group>"; };
|
||||
15FB207C1AE7C57D00C31518 /* utils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = utils.h; sourceTree = "<group>"; };
|
||||
|
@ -4575,8 +4575,8 @@
|
|||
1A570275180BCC840088DEC7 /* sprite-nodes */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
15FB20721AE7BF8600C31518 /* MarchingSquare.cpp */,
|
||||
15FB20731AE7BF8600C31518 /* MarchingSquare.h */,
|
||||
15FB20721AE7BF8600C31518 /* AutoPolygon.cpp */,
|
||||
15FB20731AE7BF8600C31518 /* AutoPolygon.h */,
|
||||
15FB20661AE7BE7400C31518 /* SpritePolygon.cpp */,
|
||||
15FB20671AE7BE7400C31518 /* SpritePolygon.h */,
|
||||
15FB20681AE7BE7400C31518 /* SpritePolygonCache.cpp */,
|
||||
|
@ -6726,7 +6726,7 @@
|
|||
3E2F27A719CFBFE400E7C490 /* AudioEngine.h in Headers */,
|
||||
15AE183A19AAD2F700C27E9E /* CCRay.h in Headers */,
|
||||
15AE18A319AAD33D00C27E9E /* CCParticleSystemQuadLoader.h in Headers */,
|
||||
15FB20761AE7BF8600C31518 /* MarchingSquare.h in Headers */,
|
||||
15FB20761AE7BF8600C31518 /* AutoPolygon.h in Headers */,
|
||||
B665E2C41AA80A6500DDB1C5 /* CCPUGeometryRotatorTranslator.h in Headers */,
|
||||
46A170F01807CECA005B8026 /* CCPhysicsWorld.h in Headers */,
|
||||
15AE199D19AAD39600C27E9E /* ScrollViewReader.h in Headers */,
|
||||
|
@ -7776,7 +7776,7 @@
|
|||
1A5702ED180BCE750088DEC7 /* CCTileMapAtlas.h in Headers */,
|
||||
15AE195E19AAD35100C27E9E /* CCSkin.h in Headers */,
|
||||
1A5702F1180BCE750088DEC7 /* CCTMXLayer.h in Headers */,
|
||||
15FB20771AE7BF8600C31518 /* MarchingSquare.h in Headers */,
|
||||
15FB20771AE7BF8600C31518 /* AutoPolygon.h in Headers */,
|
||||
15AE18AE19AAD33D00C27E9E /* CCBFileLoader.h in Headers */,
|
||||
15AE197819AAD35700C27E9E /* CCActionTimeline.h in Headers */,
|
||||
15FB206D1AE7BE7400C31518 /* SpritePolygon.h in Headers */,
|
||||
|
@ -8506,7 +8506,7 @@
|
|||
15AE199A19AAD39600C27E9E /* PageViewReader.cpp in Sources */,
|
||||
1A57030C180BCF190088DEC7 /* CCComponent.cpp in Sources */,
|
||||
382383F61A258FA7002C4610 /* idl_gen_fbs.cpp in Sources */,
|
||||
15FB20741AE7BF8600C31518 /* MarchingSquare.cpp in Sources */,
|
||||
15FB20741AE7BF8600C31518 /* AutoPolygon.cpp in Sources */,
|
||||
B665E2A61AA80A6500DDB1C5 /* CCPUEventHandlerTranslator.cpp in Sources */,
|
||||
15AE1A5919AAD40300C27E9E /* b2StackAllocator.cpp in Sources */,
|
||||
B29A7E3D19EE1B7700872B35 /* AnimationState.c in Sources */,
|
||||
|
@ -8981,7 +8981,7 @@
|
|||
15AE18AB19AAD33D00C27E9E /* CCBAnimationManager.cpp in Sources */,
|
||||
15AE1B7219AADA9A00C27E9E /* UIListView.cpp in Sources */,
|
||||
1A5701BE180BCB5A0088DEC7 /* CCLabelAtlas.cpp in Sources */,
|
||||
15FB20751AE7BF8600C31518 /* MarchingSquare.cpp in Sources */,
|
||||
15FB20751AE7BF8600C31518 /* AutoPolygon.cpp in Sources */,
|
||||
15AE1A3D19AAD3D500C27E9E /* b2CollideEdge.cpp in Sources */,
|
||||
1A5701C2180BCB5A0088DEC7 /* CCLabelBMFont.cpp in Sources */,
|
||||
1A087AE91860400400196EF5 /* edtaa3func.cpp in Sources */,
|
||||
|
|
|
@ -25,13 +25,14 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#include "MarchingSquare.h"
|
||||
#include "AutoPolygon.h"
|
||||
#include "poly2tri/poly2tri.h"
|
||||
#include <algorithm>
|
||||
#include <math.h>
|
||||
|
||||
USING_NS_CC;
|
||||
|
||||
MarchingSquare::MarchingSquare(const std::string &filename, const unsigned int threshold)
|
||||
AutoPolygon::AutoPolygon(const std::string &filename)
|
||||
:_image(nullptr)
|
||||
,_data(nullptr)
|
||||
,_filename("")
|
||||
|
@ -39,10 +40,8 @@ MarchingSquare::MarchingSquare(const std::string &filename, const unsigned int t
|
|||
,_width(0)
|
||||
,_height(0)
|
||||
,_scaleFactor(0)
|
||||
,_epsilon(0)
|
||||
{
|
||||
_filename = filename;
|
||||
_threshold = threshold;
|
||||
_image = new Image();
|
||||
_image->initWithImageFile(filename);
|
||||
CCASSERT(_image->getRenderFormat()==Texture2D::PixelFormat::RGBA8888, "unsupported format, currently only supports rgba8888");
|
||||
|
@ -50,25 +49,37 @@ MarchingSquare::MarchingSquare(const std::string &filename, const unsigned int t
|
|||
_width = _image->getWidth();
|
||||
_height = _image->getHeight();
|
||||
_scaleFactor = Director::getInstance()->getContentScaleFactor();
|
||||
_points.clear();
|
||||
_triangles = {nullptr, nullptr, 0, 0};
|
||||
}
|
||||
|
||||
MarchingSquare::~MarchingSquare()
|
||||
AutoPolygon::~AutoPolygon()
|
||||
{
|
||||
CC_SAFE_DELETE(_image);
|
||||
CC_SAFE_DELETE_ARRAY(_triangles.verts);
|
||||
CC_SAFE_DELETE_ARRAY(_triangles.indices);
|
||||
_points.clear();
|
||||
}
|
||||
|
||||
void MarchingSquare::trace(const Rect& rect)
|
||||
void AutoPolygon::trace(const Rect& rect, const unsigned int threshold)
|
||||
{
|
||||
_points.clear();
|
||||
CC_SAFE_DELETE_ARRAY(_triangles.verts);
|
||||
CC_SAFE_DELETE_ARRAY(_triangles.indices);
|
||||
_triangles.vertCount = 0;
|
||||
_triangles.indexCount = 0;
|
||||
_rect = rect;
|
||||
_threshold = threshold;
|
||||
|
||||
unsigned int first = findFirstNoneTransparentPixel();
|
||||
auto start = Vec2(first%_width, first/_width);
|
||||
marchSquare(start.x, start.y);
|
||||
}
|
||||
|
||||
unsigned int MarchingSquare::findFirstNoneTransparentPixel()
|
||||
unsigned int AutoPolygon::findFirstNoneTransparentPixel()
|
||||
{
|
||||
unsigned int first = -1;
|
||||
for(unsigned int i = 0; i < _width*_height; i++)
|
||||
for(unsigned int i = 0; i < _rect.size.width*_rect.size.height; i++)
|
||||
{
|
||||
if(getAlphaByIndex(i) > _threshold)
|
||||
{
|
||||
|
@ -80,18 +91,29 @@ unsigned int MarchingSquare::findFirstNoneTransparentPixel()
|
|||
return first;
|
||||
}
|
||||
|
||||
unsigned char MarchingSquare::getAlphaByIndex(const unsigned int& i)
|
||||
unsigned char AutoPolygon::getAlphaByIndex(const unsigned int& i)
|
||||
{
|
||||
CCASSERT(i < _width*_height, "coordinate is out of range.");
|
||||
// CCASSERT(i < _width*_height, "coordinate is out of range.");
|
||||
// unsigned int x = i % (int)_rect.size.width;
|
||||
// unsigned int y = i / (int)_rect.size.width;
|
||||
// CCLOG("i=%d, x=%d,y=%d",i,x,y);
|
||||
// x += _rect.origin.x;
|
||||
// y += _height - _rect.origin.y - _rect.size.height;
|
||||
// y = _height - _rect.origin.y -_rect.size.height + y;
|
||||
// return getAlphaByPos(x, y);
|
||||
return *(_data+i*4+3);
|
||||
}
|
||||
unsigned char MarchingSquare::getAlphaByPos(const unsigned int& x, const unsigned int& y)
|
||||
unsigned char AutoPolygon::getAlphaByPos(const unsigned int& x, const unsigned int& y)
|
||||
{
|
||||
CCASSERT(x < _width-1 && y < _height-1, "coordinate is out of range.");
|
||||
// CCASSERT(x <= _width-1 && y <= _height-1, "coordinate is out of range.");
|
||||
// if (x<_rect.origin.x || x>_rect.origin.x+_rect.size.width
|
||||
// || y<_rect.origin.y || y>_rect.origin.y+_rect.size.height) {
|
||||
// return 0;
|
||||
// }
|
||||
return *(_data+(y*_width+x)*4+3);
|
||||
}
|
||||
|
||||
unsigned int MarchingSquare::getSquareValue(const unsigned int& x, const unsigned int& y)
|
||||
unsigned int AutoPolygon::getSquareValue(const unsigned int& x, const unsigned int& y)
|
||||
{
|
||||
/*
|
||||
checking the 2x2 pixel grid, assigning these values to each pixel, if not transparent
|
||||
|
@ -113,7 +135,7 @@ unsigned int MarchingSquare::getSquareValue(const unsigned int& x, const unsigne
|
|||
return sv;
|
||||
}
|
||||
|
||||
void MarchingSquare::marchSquare(const unsigned int& startx, const unsigned int& starty)
|
||||
void AutoPolygon::marchSquare(const unsigned int& startx, const unsigned int& starty)
|
||||
{
|
||||
int stepx = 0;
|
||||
int stepy = 0;
|
||||
|
@ -282,7 +304,7 @@ void MarchingSquare::marchSquare(const unsigned int& startx, const unsigned int&
|
|||
} while(curx != startx || cury != starty);
|
||||
}
|
||||
|
||||
void MarchingSquare::printPoints()
|
||||
void AutoPolygon::printPoints()
|
||||
{
|
||||
for(auto p : _points)
|
||||
{
|
||||
|
@ -290,7 +312,7 @@ void MarchingSquare::printPoints()
|
|||
}
|
||||
}
|
||||
|
||||
float MarchingSquare::perpendicularDistance(const cocos2d::Vec2& i, const cocos2d::Vec2& start, const cocos2d::Vec2& end)
|
||||
float AutoPolygon::perpendicularDistance(const cocos2d::Vec2& i, const cocos2d::Vec2& start, const cocos2d::Vec2& end)
|
||||
{
|
||||
float res;
|
||||
float slope;
|
||||
|
@ -311,7 +333,7 @@ float MarchingSquare::perpendicularDistance(const cocos2d::Vec2& i, const cocos2
|
|||
}
|
||||
return res;
|
||||
}
|
||||
std::vector<cocos2d::Vec2> MarchingSquare::rdp(std::vector<cocos2d::Vec2> v)
|
||||
std::vector<cocos2d::Vec2> AutoPolygon::rdp(std::vector<cocos2d::Vec2> v, const float& optimization)
|
||||
{
|
||||
if(v.size() < 3)
|
||||
return v;
|
||||
|
@ -328,15 +350,15 @@ std::vector<cocos2d::Vec2> MarchingSquare::rdp(std::vector<cocos2d::Vec2> v)
|
|||
index = i;
|
||||
}
|
||||
}
|
||||
if (dist>_epsilon)
|
||||
if (dist>optimization)
|
||||
{
|
||||
std::vector<Vec2>::const_iterator begin = v.begin();
|
||||
std::vector<Vec2>::const_iterator end = v.end();
|
||||
std::vector<Vec2> l1(begin, begin+index+1);
|
||||
std::vector<Vec2> l2(begin+index, end);
|
||||
|
||||
std::vector<Vec2> r1 = rdp(l1);
|
||||
std::vector<Vec2> r2 = rdp(l2);
|
||||
std::vector<Vec2> r1 = rdp(l1, optimization);
|
||||
std::vector<Vec2> r2 = rdp(l2, optimization);
|
||||
|
||||
r1.insert(r1.end(), r2.begin()+1, r2.end());
|
||||
return r1;
|
||||
|
@ -348,12 +370,11 @@ std::vector<cocos2d::Vec2> MarchingSquare::rdp(std::vector<cocos2d::Vec2> v)
|
|||
return ret;
|
||||
}
|
||||
}
|
||||
void MarchingSquare::optimize(const float& optimization)
|
||||
void AutoPolygon::optimize(const float& optimization)
|
||||
{
|
||||
if(optimization <= 0 || _points.size()<4)
|
||||
return;
|
||||
_epsilon = optimization;
|
||||
_points = rdp(_points);
|
||||
_points = rdp(_points, optimization);
|
||||
auto last = _points.back();
|
||||
|
||||
if(last.y > _points.front().y)
|
||||
|
@ -361,7 +382,7 @@ void MarchingSquare::optimize(const float& optimization)
|
|||
_points.pop_back();
|
||||
}
|
||||
|
||||
void MarchingSquare::expand(const cocos2d::Rect &rect, const float& optimization)
|
||||
void AutoPolygon::expand(const cocos2d::Rect &rect, const float& optimization)
|
||||
{
|
||||
std::vector<cocos2d::Vec2> offsets;
|
||||
size_t length = _points.size();
|
||||
|
@ -392,10 +413,113 @@ void MarchingSquare::expand(const cocos2d::Rect &rect, const float& optimization
|
|||
}
|
||||
}
|
||||
|
||||
bool MarchingSquare::isAConvexPoint(const cocos2d::Vec2& p1, const cocos2d::Vec2& p2)
|
||||
bool AutoPolygon::isAConvexPoint(const cocos2d::Vec2& p1, const cocos2d::Vec2& p2)
|
||||
{
|
||||
if(p1.cross(p2)>0)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
return p1.cross(p2) >0 ? true : false;
|
||||
}
|
||||
|
||||
void AutoPolygon::triangulate()
|
||||
{
|
||||
CCASSERT(_points.size()>=3, "the points size is less than 3.");
|
||||
std::vector<p2t::Point*> points;
|
||||
for(std::vector<Vec2>::const_iterator it = _points.begin(); it<_points.end(); it++)
|
||||
{
|
||||
p2t::Point * p = new p2t::Point(it->x, it->y);
|
||||
points.push_back(p);
|
||||
}
|
||||
p2t::CDT cdt(points);
|
||||
cdt.Triangulate();
|
||||
std::vector<p2t::Triangle*> tris = cdt.GetTriangles();
|
||||
|
||||
V3F_C4B_T2F* verts= new V3F_C4B_T2F[_points.size()];
|
||||
unsigned short* indices = new unsigned short[tris.size()*3];
|
||||
unsigned short idx = 0;
|
||||
unsigned short vdx = 0;
|
||||
|
||||
for(std::vector<p2t::Triangle*>::const_iterator ite = tris.begin(); ite < tris.end(); ite++)
|
||||
{
|
||||
for(int i = 0; i < 3; i++)
|
||||
{
|
||||
auto p = (*ite)->GetPoint(i);
|
||||
auto v3 = Vec3(p->x, p->y, 0);
|
||||
bool found = false;
|
||||
int j;
|
||||
size_t length = vdx;
|
||||
for(j = 0; j < length; j++)
|
||||
{
|
||||
if(verts[j].vertices == v3)
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(found)
|
||||
{
|
||||
//if we found the same vertice, don't add to verts, but use the same vert with indices
|
||||
indices[idx] = j;
|
||||
idx++;
|
||||
}
|
||||
else
|
||||
{
|
||||
//vert does not exist yet, so we need to create a new one,
|
||||
auto c4b = Color4B::WHITE;
|
||||
auto t2f = Tex2F(0,0); // don't worry about tex coords now, we calculate that later
|
||||
V3F_C4B_T2F vert = {v3,c4b,t2f};
|
||||
verts[vdx] = vert;
|
||||
indices[idx] = vdx;
|
||||
idx++;
|
||||
vdx++;
|
||||
}
|
||||
}
|
||||
}
|
||||
for(auto j : points)
|
||||
{
|
||||
delete j;
|
||||
};
|
||||
_triangles = {verts, indices, vdx, idx};
|
||||
}
|
||||
|
||||
void AutoPolygon::calculateUV()
|
||||
{
|
||||
/*
|
||||
whole texture UV coordination
|
||||
0,0 1,0
|
||||
+---------------------+
|
||||
| |0.1
|
||||
| |0.2
|
||||
| +--------+ |0.3
|
||||
| |texRect | |0.4
|
||||
| | | |0.5
|
||||
| | | |0.6
|
||||
| +--------+ |0.7
|
||||
| |0.8
|
||||
| |0.9
|
||||
+---------------------+
|
||||
0,1 1,1
|
||||
|
||||
because when we scanned the image upside down, our uv is now upside down too
|
||||
*/
|
||||
|
||||
Texture2D* texture = Director::getInstance()->getTextureCache()->addImage(_filename);
|
||||
float texWidth = texture->getPixelsWide()/_scaleFactor;
|
||||
float texHeight = texture->getPixelsHigh()/_scaleFactor;
|
||||
|
||||
auto end = &_triangles.verts[_triangles.vertCount];
|
||||
for(auto i = _triangles.verts; i != end; i++)
|
||||
{
|
||||
// for every point, offset with the centerpoint
|
||||
float u = i->vertices.x / texWidth;
|
||||
float v = (texHeight - i->vertices.y) / texHeight;
|
||||
i->texCoords.u = u;
|
||||
i->texCoords.v = v;
|
||||
}
|
||||
}
|
||||
|
||||
void AutoPolygon::generateTriangles(const Rect& rect, const float& optimization, const unsigned int threshold)
|
||||
{
|
||||
trace(rect, threshold);
|
||||
optimize(optimization);
|
||||
expand(rect, optimization);
|
||||
triangulate();
|
||||
calculateUV();
|
||||
}
|
|
@ -25,8 +25,8 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
|||
THE SOFTWARE.
|
||||
****************************************************************************/
|
||||
|
||||
#ifndef COCOS_2D_MARCHINGSQUARE_H__
|
||||
#define COCOS_2D_MARCHINGSQUARE_H__
|
||||
#ifndef COCOS_2D_AUTOPOLYGON_H__
|
||||
#define COCOS_2D_AUTOPOLYGON_H__
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
@ -34,11 +34,11 @@ THE SOFTWARE.
|
|||
|
||||
NS_CC_BEGIN
|
||||
|
||||
class CC_DLL MarchingSquare
|
||||
class CC_DLL AutoPolygon
|
||||
{
|
||||
public:
|
||||
MarchingSquare(const std::string &filename, const unsigned int threshold = 0);
|
||||
~MarchingSquare();
|
||||
AutoPolygon(const std::string &filename);
|
||||
~AutoPolygon();
|
||||
|
||||
void setThreshold(unsigned int threshold){_threshold = threshold;};
|
||||
const unsigned int getThreshold(){return _threshold;};
|
||||
|
@ -46,12 +46,17 @@ public:
|
|||
ssize_t getVecCount(){return _points.size();};
|
||||
const std::vector<cocos2d::Vec2>& getPoints(){return _points;};
|
||||
|
||||
const TrianglesCommand::Triangles& getTriangles(){return _triangles;};
|
||||
void printPoints();
|
||||
|
||||
//using Ramer–Douglas–Peucker algorithm
|
||||
void trace(const cocos2d::Rect& rect);
|
||||
void trace(const cocos2d::Rect& rect, const unsigned int threshold = 0);
|
||||
void optimize(const float& optimization);
|
||||
void expand(const cocos2d::Rect& rect, const float& optimization);
|
||||
void triangulate();
|
||||
void calculateUV();
|
||||
|
||||
void generateTriangles(const cocos2d::Rect& rect, const float& optimization, const unsigned int threshold = 0);
|
||||
|
||||
protected:
|
||||
unsigned int findFirstNoneTransparentPixel();
|
||||
|
@ -64,7 +69,7 @@ protected:
|
|||
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);
|
||||
std::vector<cocos2d::Vec2> rdp(std::vector<cocos2d::Vec2> v, const float& optimization);
|
||||
float perpendicularDistance(const cocos2d::Vec2& i, const cocos2d::Vec2& start, const cocos2d::Vec2& end);
|
||||
|
||||
bool isAConvexPoint(const cocos2d::Vec2& p1, const cocos2d::Vec2& p2);
|
||||
|
@ -74,12 +79,13 @@ protected:
|
|||
std::string _filename;
|
||||
unsigned int _width;
|
||||
unsigned int _height;
|
||||
float _scaleFactor;
|
||||
cocos2d::Rect _rect;
|
||||
unsigned int _threshold;
|
||||
std::vector<cocos2d::Vec2> _points;
|
||||
float _epsilon;
|
||||
float _scaleFactor;
|
||||
TrianglesCommand::Triangles _triangles;
|
||||
};
|
||||
|
||||
NS_CC_END
|
||||
|
||||
#endif // #ifndef COCOS_2D_MARCHINGSQUARE_H__
|
||||
#endif // #ifndef COCOS_2D_AUTOPOLYGON_H__
|
|
@ -26,12 +26,11 @@
|
|||
****************************************************************************/
|
||||
|
||||
#include "SpritePolygonCache.h"
|
||||
#include "poly2tri/poly2tri.h"
|
||||
#include "MarchingSquare.h"
|
||||
#include "AutoPolygon.h"
|
||||
#include "platform/CCFileUtils.h"
|
||||
#include "base/CCDirector.h"
|
||||
#include "renderer/CCTextureCache.h"
|
||||
|
||||
#include "poly2tri/poly2tri.h"
|
||||
USING_NS_CC;
|
||||
|
||||
SpritePolygonCache* SpritePolygonCache::s_spritePolygonCache = nullptr;
|
||||
|
@ -66,7 +65,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& triangles)
|
||||
{
|
||||
auto fullpath = FileUtils::getInstance()->fullPathForFilename(filePath);;
|
||||
|
||||
|
@ -82,12 +81,12 @@ SpritePolygonInfo* SpritePolygonCache::addSpritePolygonCache(const std::string&
|
|||
{
|
||||
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;
|
||||
(*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));
|
||||
(*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));
|
||||
return *infoIt;
|
||||
}
|
||||
}
|
||||
|
@ -103,12 +102,12 @@ SpritePolygonInfo* SpritePolygonCache::addSpritePolygonCache(const std::string&
|
|||
if (nullptr != info)
|
||||
{
|
||||
info->_rect = rect;
|
||||
info->_triangles.verts = new V3F_C4B_T2F[trianglesCommand.vertCount];
|
||||
info->_triangles.indices = new unsigned short[trianglesCommand.indexCount];
|
||||
info->_triangles.vertCount = trianglesCommand.vertCount;
|
||||
info->_triangles.indexCount = trianglesCommand.indexCount;
|
||||
memcpy(info->_triangles.verts, trianglesCommand.verts, trianglesCommand.vertCount*sizeof(V3F_C4B_T2F));
|
||||
memcpy(info->_triangles.indices, trianglesCommand.indices, trianglesCommand.indexCount*sizeof(unsigned short));
|
||||
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));
|
||||
|
||||
vecInfo.push_back(info);
|
||||
_spritePolygonCacheMap[filePath] = vecInfo;
|
||||
|
@ -141,26 +140,14 @@ SpritePolygonInfo* SpritePolygonCache::getSpritePolygonCache(const std::string&
|
|||
}
|
||||
}
|
||||
|
||||
if(!isFound)//TODO:: for temp.
|
||||
if(!isFound)
|
||||
{
|
||||
//TODO:: can be removed.
|
||||
Texture2D *texture = Director::getInstance()->getTextureCache()->addImage(fullpath);
|
||||
CCASSERT(texture, "texture was not loaded properly");
|
||||
|
||||
//Marching Square
|
||||
//we need 5 steps to get cocos2d::TrianglesCommand::Triangles for cache.
|
||||
//1.trace 2.optimize 3.expand 4.triangulate 5.calculateuv
|
||||
if(-1 == optimization) optimization = 1.169;
|
||||
MarchingSquare marcher(fullpath);
|
||||
marcher.trace(rect);
|
||||
marcher.optimize(optimization);
|
||||
marcher.expand(rect, optimization);
|
||||
|
||||
marcher.printPoints();
|
||||
auto p = marcher.getPoints();
|
||||
SpritePolygonInfo* spi = triangulate(fullpath, rect, p);
|
||||
|
||||
calculateUV(spi, texture);//TODO:return spritepolygon and pass to calculateUV();
|
||||
spritePolygonInfo = spi;
|
||||
|
||||
AutoPolygon autopolygon(fullpath);
|
||||
autopolygon.generateTriangles(rect, optimization);
|
||||
spritePolygonInfo = addSpritePolygonCache(fullpath, rect, autopolygon.getTriangles());
|
||||
}
|
||||
return spritePolygonInfo;
|
||||
}
|
||||
|
@ -248,100 +235,4 @@ void SpritePolygonCache::printInfo(SpritePolygonInfo &info){
|
|||
}
|
||||
}
|
||||
|
||||
SpritePolygonInfo* SpritePolygonCache::triangulate(const std::string& file, const cocos2d::Rect& rect, std::vector<cocos2d::Vec2> & verts)
|
||||
{
|
||||
std::vector<p2t::Point*> points;
|
||||
for(std::vector<Vec2>::const_iterator it = verts.begin(); it<verts.end(); it++)
|
||||
{
|
||||
p2t::Point * p = new p2t::Point(it->x, it->y);
|
||||
points.push_back(p);
|
||||
}
|
||||
p2t::CDT cdt(points);
|
||||
cdt.Triangulate();
|
||||
std::vector<p2t::Triangle*> tris = cdt.GetTriangles();
|
||||
|
||||
std::vector<V3F_C4B_T2F> _verts;
|
||||
std::vector<unsigned short> _indices;
|
||||
unsigned short idx = 0;
|
||||
for(std::vector<p2t::Triangle*>::const_iterator ite = tris.begin(); ite < tris.end(); ite++)
|
||||
{
|
||||
for(int i = 0; i < 3; i++)
|
||||
{
|
||||
auto p = (*ite)->GetPoint(i);
|
||||
auto v3 = Vec3(p->x, p->y, 0);
|
||||
bool found = false;
|
||||
int j;
|
||||
for(j = 0; j < _verts.size(); j++)
|
||||
{
|
||||
if(_verts[j].vertices == v3)
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if(found)
|
||||
{
|
||||
//if we found the same vertice, don't add to verts, but use the same vert with indices
|
||||
_indices.push_back(j);
|
||||
}
|
||||
else
|
||||
{
|
||||
//vert does not exist yet, so we need to create a new one,
|
||||
auto c4b = Color4B::WHITE;
|
||||
auto t2f = Tex2F(0,0); // don't worry about tex coords now, we calculate that later
|
||||
V3F_C4B_T2F vert = {v3,c4b,t2f};
|
||||
_verts.push_back(vert);
|
||||
_indices.push_back(idx);
|
||||
idx++;
|
||||
}
|
||||
}
|
||||
}
|
||||
for(auto j : points)
|
||||
{
|
||||
delete j;
|
||||
}
|
||||
|
||||
TrianglesCommand::Triangles triangles = {&_verts[0], &_indices[0], (ssize_t)_verts.size(), (ssize_t)_indices.size()};
|
||||
return SpritePolygonCache::getInstance()->addSpritePolygonCache(file, rect, triangles);
|
||||
}
|
||||
|
||||
void SpritePolygonCache::calculateUV(SpritePolygonInfo* spritePolygonInfo, const cocos2d::Texture2D* texture2D)
|
||||
{
|
||||
/*
|
||||
whole texture UV coordination
|
||||
0,0 1,0
|
||||
+---------------------+
|
||||
| |0.1
|
||||
| |0.2
|
||||
| +--------+ |0.3
|
||||
| |texRect | |0.4
|
||||
| | | |0.5
|
||||
| | | |0.6
|
||||
| +--------+ |0.7
|
||||
| |0.8
|
||||
| |0.9
|
||||
+---------------------+
|
||||
0,1 1,1
|
||||
|
||||
because when we scanned the image upside down, our uv is now upside down too
|
||||
*/
|
||||
|
||||
float scaleFactor = Director::getInstance()->getContentScaleFactor();
|
||||
float texWidth = texture2D->getPixelsWide()/scaleFactor;
|
||||
float texHeight = texture2D->getPixelsHigh()/scaleFactor;
|
||||
|
||||
if(nullptr != spritePolygonInfo)
|
||||
{
|
||||
auto end = &spritePolygonInfo->_triangles.verts[spritePolygonInfo->_triangles.vertCount];
|
||||
for(auto i = spritePolygonInfo->_triangles.verts; i != end; i++)
|
||||
{
|
||||
// for every point, offset with the centerpoint
|
||||
float u = i->vertices.x / texWidth;
|
||||
float v = (texHeight - i->vertices.y) / texHeight;
|
||||
i->texCoords.u = u;
|
||||
i->texCoords.v = v;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
USING_NS_CC;
|
||||
|
|
|
@ -59,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& triangles);
|
||||
SpritePolygonInfo* getSpritePolygonCache(const std::string& filePath, const cocos2d::Rect& rect, float optimization);
|
||||
void removeSpritePolygonCache(const std::string& filePath, const cocos2d::Rect* rect = nullptr);
|
||||
void removeAllSpritePolygonCache();
|
||||
|
@ -69,8 +69,6 @@ public:
|
|||
protected:
|
||||
SpritePolygonCache();
|
||||
void init();
|
||||
void calculateUV(SpritePolygonInfo* spritePolygonInfo, const cocos2d::Texture2D* texture2D);
|
||||
SpritePolygonInfo* triangulate(const std::string& file, const cocos2d::Rect& rect, std::vector<cocos2d::Vec2> & verts);
|
||||
private:
|
||||
static SpritePolygonCache* s_spritePolygonCache;
|
||||
MapSpritePolygonInfo _spritePolygonCacheMap;
|
||||
|
|
Loading…
Reference in New Issue