From a77ea28fa709d9a9fa778cccc7f81bc539d4e63f Mon Sep 17 00:00:00 2001 From: LinYing Date: Fri, 26 Apr 2019 17:38:32 +0800 Subject: [PATCH 1/4] add concave polygon support to DrawNode --- cocos/2d/CCDrawNode.cpp | 125 ++++++++++++++++-- cocos/2d/CCDrawNode.h | 22 +++ .../DrawPrimitivesTest/DrawPrimitivesTest.cpp | 4 + 3 files changed, 141 insertions(+), 10 deletions(-) diff --git a/cocos/2d/CCDrawNode.cpp b/cocos/2d/CCDrawNode.cpp index d7420bde17fc..34485da32dde 100644 --- a/cocos/2d/CCDrawNode.cpp +++ b/cocos/2d/CCDrawNode.cpp @@ -98,6 +98,120 @@ static inline Tex2F __t(const Vec2 &v) return *(Tex2F*)&v; } +static const float EPSILON=0.0000000001f; +float Triangulate::Area(const Vec2 *verts,int n) +{ + float A=0.0f; + for(int p=n-1,q=0; q= 0.0f) && (bCROSScp >= 0.0f) && (cCROSSap >= 0.0f)); +}; + +bool Triangulate::Snip(const Vec2 *verts,int u,int v,int w,int n,int *V) +{ + int p; + float Ax, Ay, Bx, By, Cx, Cy, Px, Py; + + Ax = verts[V[u]].x; + Ay = verts[V[u]].y; + + Bx = verts[V[v]].x; + By = verts[V[v]].y; + + Cx = verts[V[w]].x; + Cy = verts[V[w]].y; + + if ( EPSILON > (((Bx-Ax)*(Cy-Ay)) - ((By-Ay)*(Cx-Ax))) ) return false; + + for (p=0;p2; ) + { + /* if we loop, it is probably a non-simple polygon */ + if (0 >= (count--)) + { + //** Triangulate: ERROR - probable bad polygon! + return triangles; + } + /* three consecutive vertices in current polygon, */ + int u = v ; if (nv <= u) u = 0; /* previous */ + v = u+1; if (nv <= v) v = 0; /* new v */ + int w = v+1; if (nv <= w) w = 0; /* next */ + + if ( Snip(verts,u,v,w,nv,V) ) + { + int a,b,c,s,t; + /* true names of the vertices */ + a = V[u]; b = V[v]; c = V[w]; + + V2F_C4B_T2F_Triangle tmp = { + {verts[a], Color4B(fillColor), __t(v2fzero)}, + {verts[b], Color4B(fillColor), __t(v2fzero)}, + {verts[c], Color4B(fillColor), __t(v2fzero)}, + }; + *triangles++ = tmp; + m++; + /* remove v from remaining polygon */ + for(s=v,t=v+1;tdrawPolygon(points, sizeof(points)/sizeof(points[0]), Color4F(1,0,0,0.5), 4, Color4F(0,0,1,0.5)); + // Draw concave polygons + Vec2 concavePoints[] = { Vec2(0,130), Vec2(140,130), Vec2(140,160),Vec2(120,145),Vec2(30,145),Vec2(0,160) }; + draw->drawPolygon(concavePoints, sizeof(concavePoints)/sizeof(concavePoints[0]), Color4F(1,0,0,0.5), 4, Color4F(0,0,1,0.5)); + // star poly (triggers buggs) { const float o=80; From 85ecbcde74269efad4cd8ac5ab050a5586798dc9 Mon Sep 17 00:00:00 2001 From: LinYing Date: Sun, 28 Apr 2019 11:21:51 +0800 Subject: [PATCH 2/4] change to cocos2d-x coding style --- cocos/2d/CCDrawNode.cpp | 18 +++++++++--------- cocos/2d/CCDrawNode.h | 8 ++++---- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/cocos/2d/CCDrawNode.cpp b/cocos/2d/CCDrawNode.cpp index 34485da32dde..3658312c98e4 100644 --- a/cocos/2d/CCDrawNode.cpp +++ b/cocos/2d/CCDrawNode.cpp @@ -99,7 +99,7 @@ static inline Tex2F __t(const Vec2 &v) } static const float EPSILON=0.0000000001f; -float Triangulate::Area(const Vec2 *verts,int n) +float Triangulate::computeArea(const Vec2 *verts,int n) { float A=0.0f; for(int p=n-1,q=0; q= 0.0f) && (bCROSScp >= 0.0f) && (cCROSSap >= 0.0f)); }; -bool Triangulate::Snip(const Vec2 *verts,int u,int v,int w,int n,int *V) +bool Triangulate::checkSnip(const Vec2 *verts,int u,int v,int w,int n,int *V) { int p; float Ax, Ay, Bx, By, Cx, Cy, Px, Py; @@ -156,19 +156,19 @@ bool Triangulate::Snip(const Vec2 *verts,int u,int v,int w,int n,int *V) if( (p == u) || (p == v) || (p == w) ) continue; Px = verts[V[p]].x; Py = verts[V[p]].y; - if (InsideTriangle(Ax,Ay,Bx,By,Cx,Cy,Px,Py)) return false; + if (isInsideTriangle(Ax,Ay,Bx,By,Cx,Cy,Px,Py)) return false; } return true; } -V2F_C4B_T2F_Triangle * Triangulate::Process(const Vec2 *verts,V2F_C4B_T2F_Triangle * triangles,int n,const Color4F &fillColor) +V2F_C4B_T2F_Triangle * Triangulate::processTriangles(const Vec2 *verts,V2F_C4B_T2F_Triangle * triangles,int n,const Color4F &fillColor) { if ( n < 3 ) return triangles; int *V = new int[n]; /* we want a counter-clockwise polygon in V */ - if ( 0.0f < Area(verts,n) ) + if ( 0.0f < computeArea(verts,n) ) for (int v=0; v Date: Mon, 6 May 2019 09:51:51 +0800 Subject: [PATCH 3/4] add the url of the code comes from --- cocos/2d/CCDrawNode.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/cocos/2d/CCDrawNode.h b/cocos/2d/CCDrawNode.h index 80fc941cc367..1607719ac8b1 100644 --- a/cocos/2d/CCDrawNode.h +++ b/cocos/2d/CCDrawNode.h @@ -41,6 +41,10 @@ NS_CC_BEGIN static const int DEFAULT_LINE_WIDTH = 2; +/* + * Code of Triangulate copied & pasted from http://www.flipcode.com/archives/Efficient_Polygon_Triangulation.shtml, + * Added some changes for cocos2d + */ class Triangulate { public: From 1309e8f9dd8fc280d255789fd5c764fa24e1862f Mon Sep 17 00:00:00 2001 From: LinYing Date: Tue, 7 May 2019 17:26:11 +0800 Subject: [PATCH 4/4] move test code to a seperate class --- .../DrawPrimitivesTest/DrawPrimitivesTest.cpp | 29 ++++++++++++++++--- .../DrawPrimitivesTest/DrawPrimitivesTest.h | 12 ++++++++ 2 files changed, 37 insertions(+), 4 deletions(-) diff --git a/tests/cpp-tests/Classes/DrawPrimitivesTest/DrawPrimitivesTest.cpp b/tests/cpp-tests/Classes/DrawPrimitivesTest/DrawPrimitivesTest.cpp index e16b195bb3aa..7d6f40bbe24e 100644 --- a/tests/cpp-tests/Classes/DrawPrimitivesTest/DrawPrimitivesTest.cpp +++ b/tests/cpp-tests/Classes/DrawPrimitivesTest/DrawPrimitivesTest.cpp @@ -43,6 +43,7 @@ DrawPrimitivesTests::DrawPrimitivesTests() ADD_TEST_CASE(DrawNodeTest); ADD_TEST_CASE(PrimitivesCommandTest); ADD_TEST_CASE(Issue11942Test); + ADD_TEST_CASE(Issue19641Test); } string DrawPrimitivesBaseTest::title() const @@ -265,10 +266,6 @@ DrawNodeTest::DrawNodeTest() Vec2 points[] = { Vec2(s.height/4,0), Vec2(s.width,s.height/5), Vec2(s.width/3*2,s.height) }; draw->drawPolygon(points, sizeof(points)/sizeof(points[0]), Color4F(1,0,0,0.5), 4, Color4F(0,0,1,0.5)); - // Draw concave polygons - Vec2 concavePoints[] = { Vec2(0,130), Vec2(140,130), Vec2(140,160),Vec2(120,145),Vec2(30,145),Vec2(0,160) }; - draw->drawPolygon(concavePoints, sizeof(concavePoints)/sizeof(concavePoints[0]), Color4F(1,0,0,0.5), 4, Color4F(0,0,1,0.5)); - // star poly (triggers buggs) { const float o=80; @@ -440,6 +437,30 @@ string Issue11942Test::subtitle() const return "drawCircle() with width"; } +// +// Issue19641Tes +// Test draw a concave polygon +// +Issue19641Test::Issue19641Test() +{ + auto draw = DrawNode::create(); + addChild(draw, 10); + + auto s = Director::getInstance()->getWinSize(); + Vec2 concavePoints[] = { Vec2(s.width/2-70,130), Vec2(s.width/2+70,130), Vec2(s.width/2+70,160), Vec2(s.width/2+50,145), Vec2(s.width/2-40,145), Vec2(s.width/2-70,160) }; + draw->drawPolygon(concavePoints, sizeof(concavePoints)/sizeof(concavePoints[0]), Color4F(1,0,0,0.5), 4, Color4F(0,1,0,0.5)); +} + +string Issue19641Test::title() const +{ + return "GitHub Issue #19641"; +} + +string Issue19641Test::subtitle() const +{ + return "draw a concave polygon"; +} + #if defined(__GNUC__) && ((__GNUC__ >= 4) || ((__GNUC__ == 3) && (__GNUC_MINOR__ >= 1))) #pragma GCC diagnostic warning "-Wdeprecated-declarations" diff --git a/tests/cpp-tests/Classes/DrawPrimitivesTest/DrawPrimitivesTest.h b/tests/cpp-tests/Classes/DrawPrimitivesTest/DrawPrimitivesTest.h index ccbf03e5db40..91a79920d6dc 100644 --- a/tests/cpp-tests/Classes/DrawPrimitivesTest/DrawPrimitivesTest.h +++ b/tests/cpp-tests/Classes/DrawPrimitivesTest/DrawPrimitivesTest.h @@ -96,4 +96,16 @@ class Issue11942Test : public DrawPrimitivesBaseTest }; +class Issue19641Test : public DrawPrimitivesBaseTest +{ +public: + CREATE_FUNC(Issue19641Test); + + Issue19641Test(); + + virtual std::string title() const override; + virtual std::string subtitle() const override; + +}; + #endif