diff --git a/cocos/2d/CCDrawNode.cpp b/cocos/2d/CCDrawNode.cpp index d7420bde17fc..3658312c98e4 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::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::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; + + 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 ( checkSnip(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;tgetWinSize(); + 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