Finished AutoPolygon and Sprite

This commit is contained in:
WuHao 2015-06-04 15:43:31 +08:00
parent 3c5326ba1f
commit 0a51c9bd27
9 changed files with 573 additions and 472 deletions

View File

@ -4273,6 +4273,11 @@
isa = PBXProject;
attributes = {
LastUpgradeCheck = 0600;
TargetAttributes = {
A07A517F1783A1D20073F6A7 = {
DevelopmentTeam = NQ596S94Q5;
};
};
};
buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "cocos2d_tests" */;
compatibilityVersion = "Xcode 3.2";
@ -5894,6 +5899,7 @@
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_IDENTITY = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "../tests/cpp-tests/proj.ios/Prefix.pch";
GCC_PREPROCESSOR_DEFINITIONS = (
@ -5907,6 +5913,7 @@
"$(inherited)",
"$(SRCROOT)/../external/curl/prebuilt/ios",
);
PROVISIONING_PROFILE = "";
SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
USER_HEADER_SEARCH_PATHS = "$(inherited) $(SRCROOT)/../cocos/platform/ios $(SRCROOT)/../cocos/platform/ios/Simulation $(SRCROOT)/../external/curl/include/ios";
@ -5918,6 +5925,7 @@
isa = XCBuildConfiguration;
buildSettings = {
CODE_SIGN_IDENTITY = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
GCC_PRECOMPILE_PREFIX_HEADER = YES;
GCC_PREFIX_HEADER = "../tests/cpp-tests/proj.ios/Prefix.pch";
GCC_PREPROCESSOR_DEFINITIONS = (
@ -5931,6 +5939,7 @@
"$(inherited)",
"$(SRCROOT)/../external/curl/prebuilt/ios",
);
PROVISIONING_PROFILE = "";
SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
USER_HEADER_SEARCH_PATHS = "$(inherited) $(SRCROOT)/../cocos/platform/ios $(SRCROOT)/../cocos/platform/ios/Simulation $(SRCROOT)/../external/curl/include/ios";

View File

@ -37,8 +37,11 @@ USING_NS_CC;
PolygonInfo::PolygonInfo(const PolygonInfo& other):
triangles(),
isVertsOwner(true)
isVertsOwner(true),
rect()
{
filename = other.filename;
rect = other.rect;
triangles.verts = new V3F_C4B_T2F[other.triangles.vertCount];
triangles.indices = new unsigned short[other.triangles.indexCount];
triangles.vertCount = other.triangles.vertCount;
@ -48,7 +51,8 @@ isVertsOwner(true)
};
PolygonInfo::PolygonInfo(V3F_C4B_T2F_Quad *quad):
triangles(),
isVertsOwner(true)
isVertsOwner(true),
rect()
{
isVertsOwner = false;
unsigned short *indices = new unsigned short[6]{0,1,2, 3,2,1};
@ -58,6 +62,21 @@ isVertsOwner(true)
triangles.verts = (V3F_C4B_T2F*)quad;
}
PolygonInfo& PolygonInfo::operator= (const PolygonInfo& other)
{
if(this != &other)
{
filename = other.filename;
rect = other.rect;
triangles.verts = new V3F_C4B_T2F[other.triangles.vertCount];
triangles.indices = new unsigned short[other.triangles.indexCount];
triangles.vertCount = other.triangles.vertCount;
triangles.indexCount = other.triangles.indexCount;
memcpy(triangles.verts, other.triangles.verts, other.triangles.vertCount*sizeof(V3F_C4B_T2F));
memcpy(triangles.indices, other.triangles.indices, other.triangles.indexCount*sizeof(unsigned short));
}
return *this;
}
PolygonInfo::~PolygonInfo()
{
if(nullptr != triangles.verts && isVertsOwner)
@ -70,6 +89,25 @@ PolygonInfo::~PolygonInfo()
CC_SAFE_DELETE_ARRAY(triangles.indices);
}
}
const unsigned int PolygonInfo::getVertCount() const
{
return (unsigned int)triangles.vertCount;
}
const float PolygonInfo::getArea() const
{
float area = 0;
V3F_C4B_T2F *verts = triangles.verts;
unsigned short *indices = triangles.indices;
for(int i = 0; i < triangles.indexCount; i+=3)
{
auto A = verts[indices[i]].vertices;
auto B = verts[indices[i+1]].vertices;
auto C = verts[indices[i+2]].vertices;
area += (A.x*(B.y-C.y) + B.x*(C.y-A.y) + C.x*(A.y - B.y))/2;
}
return area;
}
@ -98,20 +136,23 @@ AutoPolygon::~AutoPolygon()
std::vector<Vec2> AutoPolygon::trace(const Rect& rect, const float& threshold)
{
Vec2 first = findFirstNoneTransparentPixel(rect);
// Rect realRect = getRealRect(rect);
Vec2 first = findFirstNoneTransparentPixel(rect, threshold);
return marchSquare(rect, first, threshold);
}
Vec2 AutoPolygon::findFirstNoneTransparentPixel(const Rect& rect)
Vec2 AutoPolygon::findFirstNoneTransparentPixel(const Rect& rect, const float& threshold)
{
Vec2 first;
bool found;
Vec2 i;
for(i.y = rect.origin.y; i.y < rect.origin.y+rect.size.height; i.y++)
{
for(i.x = rect.origin.x; i.x < rect.origin.x+rect.size.height; i.x++)
if(found)break;
for(i.x = rect.origin.x; i.x < rect.origin.x+rect.size.width; i.x++)
{
if(getAlphaByPos(i))
auto alpha = getAlphaByPos(i);
if(alpha>threshold)
{
found = true;
break;
@ -155,15 +196,21 @@ unsigned int AutoPolygon::getSquareValue(const unsigned int& x, const unsigned i
+---+---+
*/
unsigned int sv = 0;
/* because the rect is from bottom left, while the texure if from left top */
Vec2 tl = Vec2(x-1, _height-(y-1));
sv += (rect.containsPoint(tl) && getAlphaByPos(tl) > threshold)? 1 : 0;
Vec2 tr = Vec2(x, _height-(y-1));
sv += (rect.containsPoint(tr) && getAlphaByPos(tr) > threshold)? 2 : 0;
Vec2 bl = Vec2(x-1, _height-y);
sv += (rect.containsPoint(bl) && getAlphaByPos(bl) > threshold)? 4 : 0;
Vec2 br = Vec2(x, _height-y);
sv += (rect.containsPoint(br) && getAlphaByPos(br) > threshold)? 8 : 0;
//NOTE: due to the way we pick points from texture, rect needs to be smaller, otherwise it goes outside 1 pixel
auto fixedRect = Rect(rect.origin, rect.size-Size(2,2));
Vec2 tl = Vec2(x-1, y-1);
sv += (fixedRect.containsPoint(tl) && getAlphaByPos(tl) > threshold)? 1 : 0;
Vec2 tr = Vec2(x, y-1);
sv += (fixedRect.containsPoint(tr) && getAlphaByPos(tr) > threshold)? 2 : 0;
Vec2 bl = Vec2(x-1, y);
sv += (fixedRect.containsPoint(bl) && getAlphaByPos(bl) > threshold)? 4 : 0;
Vec2 br = Vec2(x, y);
sv += (fixedRect.containsPoint(br) && getAlphaByPos(br) > threshold)? 8 : 0;
CCASSERT(sv != 0 && sv != 15, "square value should not be 0, or 15");
return sv;
}
@ -316,19 +363,19 @@ std::vector<cocos2d::Vec2> AutoPolygon::marchSquare(const Rect& rect, const Vec2
cury += stepy;
if(stepx == prevx && stepy == prevy)
{
_points.back().x = (float)(curx) / _scaleFactor;
_points.back().y = (float)(_height-cury) / _scaleFactor;
_points.back().x = (float)(curx-rect.origin.x) / _scaleFactor;
_points.back().y = (float)(rect.size.height - cury + rect.origin.y) / _scaleFactor;
}
else if(problem)
{
//TODO: we triangulation cannot work collineer points, so we need to modify same point a little
//TODO: maybe we can detect if we go into a hole and coming back the hole, we should extract those points and remove them
_points.back().x -= 0.00001;
_points.back().y -= 0.00001;
_points.push_back(Vec2((float)curx, (float)_height-cury)/ _scaleFactor);
// _points.back().x -= 0.00001;
// _points.back().y -= 0.00001;
_points.push_back(Vec2((float)(curx- rect.origin.x) / _scaleFactor, (float)(rect.size.height - cury + rect.origin.y) / _scaleFactor));
}
else{
_points.push_back(Vec2((float)curx, (float)_height-cury)/ _scaleFactor);
_points.push_back(Vec2((float)(curx-rect.origin.x) / _scaleFactor, (float)(rect.size.height - cury + rect.origin.y) / _scaleFactor));
}
count++;
@ -406,25 +453,48 @@ std::vector<cocos2d::Vec2> AutoPolygon::rdp(std::vector<cocos2d::Vec2> v, const
return ret;
}
}
std::vector<Vec2> AutoPolygon::reduce(const std::vector<Vec2>& points, const float& epsilon)
std::vector<Vec2> AutoPolygon::reduce(const std::vector<Vec2>& points, const Rect& rect , const float& epsilon)
{
CCASSERT(points.size()>3, "points are just a triangle, no need further reduction");
if(epsilon <= 0)
auto size = points.size();
// if there are less than 3 points, then we have nothing
if(size<3)
{
log("AUTOPOLYGON: cannot reduce points for %s that has less than 3 points in input, e: %f", _filename.c_str(), epsilon);
return std::vector<Vec2>();
}
// if there are less than 9 points (but more than 3), then we don't need to reduce it
else if (size < 9)
{
log("AUTOPOLYGON: cannot reduce points for %s e: %f",_filename.c_str(), epsilon);
return points;
std::vector<Vec2> result = rdp(points, epsilon);
auto last = result.back();
}
float maxEp = MIN(rect.size.width, rect.size.height);
float ep = clampf(epsilon, 0.0, maxEp/_scaleFactor/2);
std::vector<Vec2> result = rdp(points, ep);
if(last.y > result.front().y)
// auto resSize = result.size();
auto last = result.back();
if(last.y > result.front().y && last.getDistance(result.front()) < ep*0.5)
{
result.front().y = last.y;
result.pop_back();
result.pop_back();
}
return result;
}
std::vector<Vec2> AutoPolygon::expand(const std::vector<Vec2>& points, const cocos2d::Rect &rect, const float& epsilon)
{
auto size = points.size();
// if there are less than 3 points, then we have nothig
if(size<3)
{
log("AUTOPOLYGON: cannot expand points for %s with less than 3 points, e: %f", _filename.c_str(), epsilon);
return std::vector<Vec2>();
}
ClipperLib::Path subj;
ClipperLib::PolyTree solution;
ClipperLib::Paths out;
// ClipperLib::Paths simple;
ClipperLib::PolyTree out;
for(std::vector<Vec2>::const_iterator it = points.begin(); it<points.end(); it++)
{
subj << ClipperLib::IntPoint(it->x, it->y);
@ -432,12 +502,35 @@ std::vector<Vec2> AutoPolygon::expand(const std::vector<Vec2>& points, const coc
ClipperLib::ClipperOffset co;
co.AddPath(subj, ClipperLib::jtMiter, ClipperLib::etClosedPolygon);
co.Execute(solution, epsilon);
ClipperLib::PolyNode* p = solution.GetFirst();
while(p->IsHole()){
p = p->GetNext();
}
//turn the result into simply polygon (AKA, fix overlap)
ClipperLib::SimplifyPolygon(solution.Childs[0]->Contour, out);
// //turn the result into simply polygon (AKA, fix overlap)
// ClipperLib::SimplifyPolygon(p->Contour, simple);
//clamp into the specified rect
ClipperLib::Clipper cl= ClipperLib::Clipper();
cl.StrictlySimple(true);
cl.AddPath(p->Contour, ClipperLib::ptSubject, true);
//create the clipping rect
ClipperLib::Path clamp;
clamp.push_back(ClipperLib::IntPoint(0, 0));
clamp.push_back(ClipperLib::IntPoint(rect.size.width/_scaleFactor, 0));
clamp.push_back(ClipperLib::IntPoint(rect.size.width/_scaleFactor, rect.size.height/_scaleFactor));
clamp.push_back(ClipperLib::IntPoint(0, rect.size.height/_scaleFactor));
cl.AddPath(clamp, ClipperLib::ptClip, true);
cl.Execute(ClipperLib::ctIntersection, out);
std::vector<Vec2> outPoints;
auto end = out[0].end();
for(std::vector<ClipperLib::IntPoint>::const_iterator pt = out[0].begin(); pt < end; pt++)
ClipperLib::PolyNode* p2 = out.GetFirst();
while(p2->IsHole()){
p2 = p2->GetNext();
}
auto end = p2->Contour.end();
for(std::vector<ClipperLib::IntPoint>::const_iterator pt = p2->Contour.begin(); pt < end; pt++)
{
outPoints.push_back(Vec2(pt->X, pt->Y));
}
@ -451,7 +544,12 @@ bool AutoPolygon::isAConvexPoint(const cocos2d::Vec2& p1, const cocos2d::Vec2& p
TrianglesCommand::Triangles AutoPolygon::triangulate(const std::vector<Vec2>& points)
{
CCASSERT(points.size()>=3, "the points size is less than 3.");
// if there are less than 3 points, then we can't triangulate
if(points.size()<3)
{
log("AUTOPOLYGON: cannot triangulate %s with less than 3 points", _filename.c_str());
return TrianglesCommand::Triangles();
}
std::vector<p2t::Point*> p2points;
for(std::vector<Vec2>::const_iterator it = points.begin(); it<points.end(); it++)
{
@ -511,7 +609,7 @@ TrianglesCommand::Triangles AutoPolygon::triangulate(const std::vector<Vec2>& po
return triangles;
}
void AutoPolygon::calculateUV(V3F_C4B_T2F* verts, const ssize_t& count)
void AutoPolygon::calculateUV(const Rect& rect, V3F_C4B_T2F* verts, const ssize_t& count)
{
/*
whole texture UV coordination
@ -528,36 +626,60 @@ void AutoPolygon::calculateUV(V3F_C4B_T2F* verts, const ssize_t& count)
| |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);
CCASSERT(_width && _height, "please specify width and height for this AutoPolygon instance");
float texWidth = _width/_scaleFactor;
float texHeight = _height/_scaleFactor;
float texWidth = _width;
float texHeight = _height;
auto end = &verts[count];
for(auto i = verts; i != end; i++)
{
// for every point, offset with the centerpoint
float u = i->vertices.x / texWidth;
float v = (texHeight - i->vertices.y) / texHeight;
// for every point, offcset with the centerpoint
float u = (i->vertices.x*_scaleFactor + rect.origin.x) / texWidth;
float v = (rect.origin.y+rect.size.height - i->vertices.y*_scaleFactor) / texHeight;
i->texCoords.u = u;
i->texCoords.v = v;
}
}
Rect AutoPolygon::getRealRect(const Rect& rect)
{
Rect realRect = rect;
//check rect to see if its zero
if(realRect.equals(Rect::ZERO))
{
//if the instance doesn't have width and height, then the whole operation is kaput
CCASSERT(_height && _width, "Please specify a width and height for this instance before using its functions");
realRect = Rect(0,0, _width, _height);
}
else{
//rect is specified, so convert to real rect
auto scale = Director::getInstance()->getContentScaleFactor();
realRect = Rect(rect.origin*scale, rect.size*scale);
}
return realRect;
}
PolygonInfo AutoPolygon::generateTriangles(const Rect& rect, const float& epsilon, const float& threshold)
{
auto p = trace(rect, threshold);
p = reduce(p, epsilon);
p = expand(p, rect, epsilon);
Rect realRect = getRealRect(rect);
auto p = trace(realRect, threshold);
p = reduce(p, realRect, epsilon);
p = expand(p, realRect, epsilon);
auto tri = triangulate(p);
calculateUV(tri.verts, tri.vertCount);
calculateUV(realRect, tri.verts, tri.vertCount);
PolygonInfo ret = PolygonInfo();
ret.triangles = tri;
ret.filename = _filename;
ret.rect = realRect;
return ret;
}
}
PolygonInfo AutoPolygon::generatePolygon(const std::string& filename, const Rect& rect, const float epsilon, const float threshold)
{
auto AP = new AutoPolygon(filename);
auto ret = AP->generateTriangles(rect, epsilon, threshold);
delete AP;
return ret;
}

View File

@ -40,15 +40,23 @@ class CC_DLL PolygonInfo
public:
PolygonInfo():
triangles(),
isVertsOwner(true)
isVertsOwner(true),
rect()
{
};
PolygonInfo(const PolygonInfo& other);
PolygonInfo(V3F_C4B_T2F_Quad *quad);
PolygonInfo& operator= (const PolygonInfo &other);
~PolygonInfo();
Rect rect;
std::string filename;
TrianglesCommand::Triangles triangles;
const unsigned int getVertCount() const;
const float getArea() const;
protected:
bool isVertsOwner;
};
@ -62,15 +70,15 @@ public:
//using RamerDouglasPeucker algorithm
std::vector<Vec2> trace(const cocos2d::Rect& rect, const float& threshold = 0.0);
std::vector<Vec2> reduce(const std::vector<Vec2>& points, const float& epsilon = 2.0);
std::vector<Vec2> expand(const std::vector<Vec2>& points, const cocos2d::Rect& rect, const float& epsilon);
std::vector<Vec2> reduce(const std::vector<Vec2>& points, const Rect& rect, const float& epsilon = 2.0);
std::vector<Vec2> expand(const std::vector<Vec2>& points, const Rect& rect, const float& epsilon);
TrianglesCommand::Triangles triangulate(const std::vector<Vec2>& points);
void calculateUV(V3F_C4B_T2F* verts, const unsigned int& count);
void calculateUV(const Rect& rect, V3F_C4B_T2F* verts, const ssize_t& count);
PolygonInfo generateTriangles(const Rect& rect, const float& epsilon, const float& threshold = 0);
PolygonInfo generateTriangles(const Rect& rect = Rect::ZERO, const float& epsilon = 2.0, const float& threshold = 0.05);
static PolygonInfo generatePolygon(const std::string& filename, const Rect& rect = Rect::ZERO, const float epsilon = 2.0, const float threshold = 0.05);
protected:
Vec2 findFirstNoneTransparentPixel(const Rect& rect);
Vec2 findFirstNoneTransparentPixel(const Rect& rect, const float& threshold);
std::vector<cocos2d::Vec2> marchSquare(const Rect& rect, const Vec2& first, const float& threshold);
unsigned int getSquareValue(const unsigned int& x, const unsigned int& y, const Rect& rect, const float& threshold);
@ -84,6 +92,8 @@ protected:
float perpendicularDistance(const cocos2d::Vec2& i, const cocos2d::Vec2& start, const cocos2d::Vec2& end);
bool isAConvexPoint(const cocos2d::Vec2& p1, const cocos2d::Vec2& p2);
//real rect is the size that is in scale with the texture file
Rect getRealRect(const Rect& rect);
Image* _image;
unsigned char * _data;

View File

@ -92,6 +92,8 @@ Sprite* Sprite::create(const PolygonInfo& info)
if(sprite && sprite->initWithPolygon(info))
{
sprite->autorelease();
// auto clamp = Texture2D::TexParams{GL_LINEAR,GL_LINEAR,GL_CLAMP_TO_BORDER, GL_CLAMP_TO_BORDER};
// sprite->getTexture()->setTexParameters(clamp);
return sprite;
}
CC_SAFE_DELETE(sprite);
@ -222,8 +224,14 @@ bool Sprite::initWithSpriteFrame(SpriteFrame *spriteFrame)
bool Sprite::initWithPolygon(const cocos2d::PolygonInfo &info)
{
Texture2D *texture = Director::getInstance()->getTextureCache()->addImage(info.filename);
initWithTexture(texture);
_polyInfo = new PolygonInfo(info);
bool res = false;
if(initWithTexture(texture));
{
_polyInfo = new PolygonInfo(info);
setContentSize(_polyInfo->rect.size/Director::getInstance()->getContentScaleFactor());
res = true;
}
return res;
}
// designated initializer
@ -258,7 +266,7 @@ bool Sprite::initWithTexture(Texture2D *texture, const Rect& rect, bool rotated)
_quad.tl.colors = Color4B::WHITE;
_quad.tr.colors = Color4B::WHITE;
_polyInfo = new PolygonInfo(&_quad);
// shader state
setGLProgramState(GLProgramState::getOrCreateWithGLProgramName(GLProgram::SHADER_NAME_POSITION_TEXTURE_COLOR_NO_MVP));
@ -267,6 +275,7 @@ bool Sprite::initWithTexture(Texture2D *texture, const Rect& rect, bool rotated)
setTexture(texture);
setTextureRect(rect, rotated, rect.size);
_polyInfo = new PolygonInfo(&_quad);
// by default use "Self Render".
// if the sprite is added to a batchnode, then it will automatically switch to "batchnode Render"
setBatchNode(nullptr);
@ -289,8 +298,7 @@ Sprite::Sprite(void)
, _insideBounds(true)
{
#if CC_SPRITE_DEBUG_DRAW
_debugDrawNode = DrawNode::create();
addChild(_debugDrawNode);
debugDraw(true)
#endif //CC_SPRITE_DEBUG_DRAW
}
@ -429,6 +437,59 @@ void Sprite::setTextureRect(const Rect& rect, bool rotated, const Size& untrimme
}
}
void Sprite::debugDraw(bool on)
{
DrawNode* draw = getChildByName<DrawNode*>("debugDraw");
if(on)
{
if(!draw)
{
draw = DrawNode::create();
draw->setName("debugDraw");
addChild(draw);
}
draw->setVisible(true);
draw->clear();
//draw all points
auto positions = new (std::nothrow) Vec2[_polyInfo->triangles.vertCount];
Vec2 *pos = &positions[0];
auto verts = _polyInfo->triangles.verts;
auto end = &verts[_polyInfo->triangles.vertCount];
for(V3F_C4B_T2F *v = verts; v != end; pos++, v++)
{
pos->x = v->vertices.x;
pos->y = v->vertices.y;
}
draw->drawPoints(positions, (unsigned int)_polyInfo->triangles.vertCount, 8, Color4F(0.0f, 1.0f, 1.0f, 1.0f));
//draw lines
auto last = _polyInfo->triangles.indexCount/3;
auto _indices = _polyInfo->triangles.indices;
auto _verts = _polyInfo->triangles.verts;
for(unsigned int i = 0; i < last; i++)
{
//draw 3 lines
Vec3 from =_verts[_indices[i*3]].vertices;
Vec3 to = _verts[_indices[i*3+1]].vertices;
draw->drawLine(Vec2(from.x, from.y), Vec2(to.x,to.y), Color4F::GREEN);
from =_verts[_indices[i*3+1]].vertices;
to = _verts[_indices[i*3+2]].vertices;
draw->drawLine(Vec2(from.x, from.y), Vec2(to.x,to.y), Color4F::GREEN);
from =_verts[_indices[i*3+2]].vertices;
to = _verts[_indices[i*3]].vertices;
draw->drawLine(Vec2(from.x, from.y), Vec2(to.x,to.y), Color4F::GREEN);
}
CC_SAFE_DELETE_ARRAY(positions);
}
else
{
if(draw)
draw->setVisible(false);
}
}
// override this method to generate "double scale" sprites
void Sprite::setVertexRect(const Rect& rect)
{
@ -622,17 +683,6 @@ void Sprite::draw(Renderer *renderer, const Mat4 &transform, uint32_t flags)
{
_trianglesCommand.init(_globalZOrder, _texture->getName(), getGLProgramState(), _blendFunc, _polyInfo->triangles, transform, flags);
renderer->addCommand(&_trianglesCommand);
#if CC_SPRITE_DEBUG_DRAW
_debugDrawNode->clear();
Vec2 vertices[4] = {
Vec2( _quad.bl.vertices.x, _quad.bl.vertices.y ),
Vec2( _quad.br.vertices.x, _quad.br.vertices.y ),
Vec2( _quad.tr.vertices.x, _quad.tr.vertices.y ),
Vec2( _quad.tl.vertices.x, _quad.tl.vertices.y ),
};
_debugDrawNode->drawPoly(vertices, 4, true, Color4F(1.0, 1.0, 1.0, 1.0));
#endif //CC_SPRITE_DEBUG_DRAW
}
}
@ -1088,4 +1138,15 @@ std::string Sprite::getDescription() const
return StringUtils::format("<Sprite | Tag = %d, TextureID = %d>", _tag, texture_id );
}
PolygonInfo Sprite::getPolygonInfo() const
{
return PolygonInfo(*_polyInfo);
}
void Sprite::setPolygonInfo(const PolygonInfo& info)
{
delete _polyInfo;
_polyInfo = new PolygonInfo(info);
}
NS_CC_END

View File

@ -554,6 +554,22 @@ CC_CONSTRUCTOR_ACCESS:
*/
virtual bool initWithFile(const std::string& filename, const Rect& rect);
void debugDraw(bool on);
/**
* returns a copy of the polygon information associated with this sprite
* because this is a copy process it is slower than getting the reference, so use wisely
*
* @return a copy of PolygonInfo
*/
PolygonInfo getPolygonInfo() const;
/**
* set the sprite to use this new PolygonInfo
*
* @param PolygonInfo the polygon information object
*/
void setPolygonInfo(const PolygonInfo& info);
protected:
void updateColor() override;
@ -562,6 +578,8 @@ protected:
virtual void setReorderChildDirtyRecursively();
virtual void setDirtyRecursively(bool value);
//
// Data used when the sprite is rendered using a SpriteSheet
//
@ -581,9 +599,10 @@ protected:
Texture2D* _texture; /// Texture2D object that is used to render the sprite
SpriteFrame* _spriteFrame;
TrianglesCommand _trianglesCommand; ///
#if CC_SPRITE_DEBUG_DRAW
DrawNode *_debugDrawNode;
#endif //CC_SPRITE_DEBUG_DRAW
// DrawNode *_debugDrawNode;
//
// Shared data
//

View File

@ -107,6 +107,10 @@ Rect::Rect(float x, float y, float width, float height)
{
setRect(x, y, width, height);
}
Rect::Rect(const Vec2& pos, const Size& dimension)
{
setRect(pos.x, pos.y, dimension.width, dimension.height);
}
Rect::Rect(const Rect& other)
{

View File

@ -133,6 +133,11 @@ public:
* @js NA
*/
Rect(float x, float y, float width, float height);
/**
Constructor a rect.
* @js NA
*/
Rect(const Vec2& pos, const Size& dimension);
/**
Copy constructor.
* @js NA

View File

@ -8,23 +8,126 @@
#include "SpritePolygonTest.h"
#include "../testResource.h"
#include "ui/CocosGUI.h"
USING_NS_CC;
SpritePolygonTest::SpritePolygonTest()
{
ADD_TEST_CASE(SpritePolygonTest1);
// ADD_TEST_CASE(SpritePolygonTest2);
// ADD_TEST_CASE(SpritePolygonTest3);
// ADD_TEST_CASE(SpritePolygonTest4);
ADD_TEST_CASE(SpritePolygonPerformanceTestStatic);
ADD_TEST_CASE(SpritePerformanceTestStatic);
ADD_TEST_CASE(SpritePolygonTest2);
ADD_TEST_CASE(SpritePolygonTest3);
ADD_TEST_CASE(SpritePolygonTest4);
ADD_TEST_CASE(SpritePolygonPerformanceTestDynamic);
ADD_TEST_CASE(SpritePerformanceTestDynamic);
}
void SpritePolygonTestCase::onBackCallback(cocos2d::Ref *sender)
{
TestCase::onBackCallback(sender);
Director::getInstance()->setClearColor(Color4F::BLACK);
}
void SpritePolygonTestDemo::initTouchDebugDraw()
{
auto touchListener = EventListenerTouchOneByOne::create();
touchListener->onTouchBegan = [&](Touch* touch, Event* event){
sp->debugDraw(true);
spp->debugDraw(true);
return true;
};
touchListener->onTouchMoved = [&](Touch* touch, Event* event){
auto pos = touch->getDelta();
float newScale = clampf(spp->getScale() + pos.x * 0.01f, 0.1f, 2.f);
spp->setScale(newScale);
sp->setScale(newScale);
};
touchListener->onTouchEnded = [&](Touch* touch, Event* event){
spp->debugDraw(false);
sp->debugDraw(false);
};
_eventDispatcher->addEventListenerWithSceneGraphPriority(touchListener, this);
}
void SpritePolygonTest1::make2Sprites()
{
Director::getInstance()->setClearColor(Color4F(102.f/255, 184.f/255, 204.f/255, 255.f));
auto filename = s_pathGrossini;
auto pinfo = AutoPolygon::generatePolygon(filename);
spp = Sprite::create(pinfo);
addChild(spp);
auto s = Director::getInstance()->getWinSize();
auto offset = Vec2(0.15*s.width,0);
spp->setPosition(Vec2(s)/2 + offset);
sp = Sprite::create(filename);
addChild(sp);
sp->setPosition(Vec2(s)/2 - offset);
TTFConfig ttfConfig("fonts/arial.ttf", 8);
std::string temp = "Sprite:\nPixels drawn: ";
auto spSize = sp->getContentSize();
auto spArea = Label::createWithTTF(ttfConfig, temp+Value((int)spSize.width*(int)spSize.height).asString());
sp->addChild(spArea);
spArea->setAnchorPoint(Vec2(0,1));
temp = "SpritePolygon:\nPixels drawn: ";
auto vertCount = "\nverts:"+Value((int)pinfo.getVertCount()).asString();
auto sppArea = Label::createWithTTF(ttfConfig, temp+Value((int)pinfo.getArea()).asString()+vertCount);
spp->addChild(sppArea);
sppArea->setAnchorPoint(Vec2(0,1));
initTouchDebugDraw();
}
SpritePolygonTest1::SpritePolygonTest1()
{
_title = "SpritePolygon Creation";
_subtitle = "Sprite::create(AutoPolygon::generatePolygon(filename))";
make2Sprites();
}
SpritePolygonTest2::SpritePolygonTest2()
{
_title = "SpritePolygon Creation with a rect";
_subtitle = "Sprite::create(AutoPolygon::generatePolygon(filename, rect))";
make2Sprites();
}
void SpritePolygonTest2::make2Sprites()
{
Director::getInstance()->setClearColor(Color4F(102.f/255, 184.f/255, 204.f/255, 255.f));
auto filename = s_pathGrossini;
Rect head = Rect(30,25,25,25);
auto pinfo = AutoPolygon::generatePolygon(filename, head);
spp = Sprite::create(pinfo);
addChild(spp);
auto s = Director::getInstance()->getWinSize();
auto offset = Vec2(0.15*s.width,0);
spp->setPosition(Vec2(s)/2 + offset);
sp = Sprite::create(filename,head);
addChild(sp);
sp->setPosition(Vec2(s)/2 - offset);
TTFConfig ttfConfig("fonts/arial.ttf", 8);
std::string temp = "Sprite:\nPixels drawn: ";
auto spSize = sp->getContentSize();
auto spArea = Label::createWithTTF(ttfConfig, temp+Value((int)spSize.width*(int)spSize.height).asString());
sp->addChild(spArea);
spArea->setAnchorPoint(Vec2(0,1));
temp = "SpritePolygon:\nPixels drawn: ";
auto vertCount = "\nverts:"+Value((int)pinfo.getVertCount()).asString();
auto sppArea = Label::createWithTTF(ttfConfig, temp+Value((int)pinfo.getArea()).asString()+vertCount);
spp->addChild(sppArea);
sppArea->setAnchorPoint(Vec2(0,1));
initTouchDebugDraw();
}
SpritePolygonPerformance::SpritePolygonPerformance()
{
SpritePolygonCache::getInstance()->removeAllSpritePolygonCache();
Director::getInstance()->setClearColor(Color4F(102.f/255, 184.f/255, 204.f/255, 255.f));
TTFConfig ttfConfig("fonts/arial.ttf", 10);
perfLabel = Label::createWithTTF(ttfConfig, "performance test");
@ -43,10 +146,12 @@ SpritePolygonPerformance::SpritePolygonPerformance()
scheduleUpdate();
continuousHighDtTime = 0.0;
waitingTime = 0.0;
// _pinfo = PolygonInfo(AutoPolygon::generatePolygon(s_pathGrossini));
}
void SpritePolygonPerformance::updateLabel()
{
// std::string temp = "Nodes: " + Value(spriteCount).asString() + " Triangles: " + Value(triCount).asString() + "\nPixels: " + Value(pixelCount).asString() + " Vertices: " + Value(vertCount).asString();
std::string temp = "Nodes: " + Value(spriteCount).asString() + " Triangles: " + Value(triCount).asString() + "\nPixels: " + Value(pixelCount).asString() + " Vertices: " + Value(vertCount).asString();
if(!ended)
perfLabel->setString("Nodes: " + Value(spriteCount).asString() + " Triangles: " + Value(triCount).asString() + "\nPixels: " + Value(pixelCount).asString() + " Vertices: " + Value(vertCount).asString());
}
@ -114,386 +219,153 @@ void SpritePolygonPerformance::incrementStats()
triCount += _incTri;
pixelCount += _incPix;
}
SpritePolygonPerformanceTestStatic::SpritePolygonPerformanceTestStatic()
void SpritePolygonPerformanceTestDynamic::initIncrementStats()
{
_title = "Static SpritePolygon Performance";
_subtitle = "Test running, please wait until it ends";
initIncrementStats();
}
experimental::SpritePolygon* SpritePolygonPerformanceTestStatic::makeSprite()
{
return experimental::SpritePolygon::create(s_pathGrossini);
}
void SpritePolygonPerformanceTestStatic::initIncrementStats()
{
auto t = experimental::SpritePolygon::create(s_pathGrossini);
_incVert = (int)t->getVertCount();
_incTri = (int)t->getTrianglesCount();
_incPix = (int)t->getArea();
_incVert = (int)_pinfo.getVertCount();
_incTri = (int)_pinfo.triangles.indexCount/3;
_incPix = (int)_pinfo.getArea();
}
SpritePolygonPerformanceTestDynamic::SpritePolygonPerformanceTestDynamic()
{
_pinfo = AutoPolygon::generatePolygon(s_pathGrossini);
_title = "Dynamic SpritePolygon Performance";
_subtitle = "Test running, please wait until it ends";
initIncrementStats();
}
experimental::SpritePolygon* SpritePolygonPerformanceTestDynamic::makeSprite()
Sprite* SpritePolygonPerformanceTestDynamic::makeSprite()
{
auto ret = experimental::SpritePolygon::create(s_pathGrossini);
auto ret = Sprite::create(_pinfo);
ret->runAction(RepeatForever::create(RotateBy::create(1.0,360.0)));
return ret;
}
SpritePerformanceTestStatic::SpritePerformanceTestStatic()
{
_title = "Static Sprite Performance";
_subtitle = "Test running, please wait until it ends";
initIncrementStats();
}
Sprite* SpritePerformanceTestStatic::makeSprite()
{
return Sprite::create(s_pathGrossini);
}
void SpritePerformanceTestStatic::initIncrementStats()
{
auto t = Sprite::create(s_pathGrossini);
_incVert = 4;
_incTri = 2;
_incPix = t->getContentSize().width * t->getContentSize().height;
}
SpritePerformanceTestDynamic::SpritePerformanceTestDynamic()
{
_title = "Dynamic Sprite Performance";
_subtitle = "Test running, please wait until it ends";
initIncrementStats();
}
void SpritePerformanceTestDynamic::initIncrementStats()
{
auto t = Sprite::create(s_pathGrossini);
_incVert = 4;
_incTri = 2;
_incPix = t->getContentSize().width * t->getContentSize().height;
}
Sprite* SpritePerformanceTestDynamic::makeSprite()
{
auto ret = Sprite::create(s_pathGrossini);
auto ret = Sprite::create(s_pathGrossini);
ret->runAction(RepeatForever::create(RotateBy::create(1.0,360.0)));
return ret;
}
void SpritePolygonTestDemo::initDefaultSprite(const std::string &filename, cocos2d::Node * inst)
SpritePolygonTestSlider::SpritePolygonTestSlider()
{
Director::getInstance()->setClearColor(Color4F(102.f/255, 184.f/255, 204.f/255, 255.f));
_ttfConfig = TTFConfig("fonts/arial.ttf", 8);
_title = "Optimization Value (default:2.0)";
_subtitle = "";
spp = inst;
addChild(spp);
auto s = Director::getInstance()->getWinSize();
auto offset = Vec2(0.15*s.width,0);
spp->setPosition(Vec2(s)/2 + offset);
auto vsize =Director::getInstance()->getVisibleSize();
cocos2d::ui::Slider* slider = cocos2d::ui::Slider::create();
slider->loadBarTexture("cocosui/sliderTrack.png");
slider->loadSlidBallTextures("cocosui/sliderThumb.png", "cocosui/sliderThumb.png", "");
slider->loadProgressBarTexture("cocosui/sliderProgress.png");
slider->setPosition(Vec2(vsize.width/2, vsize.height/4/* + slider->getSize().height * 2.0f*/));
slider->addEventListener(CC_CALLBACK_2(SpritePolygonTestSlider::changeEpsilon, this));
slider->setPercent(10);
addChild(slider);
}
void SpritePolygonTestSlider::makeSprites(const std::string* list, const int count, const float y)
{
auto vsize =Director::getInstance()->getVisibleSize();
float offset = (vsize.width-100)/(count-1);
// float y = vsize.height/2;
for(int i = 0; i < count; i++)
{
auto sp = makeSprite(list[i], Vec2(50+offset*i, y));
addChild(sp);
sp->debugDraw(true);
}
}
void SpritePolygonTestSlider::changeEpsilon(cocos2d::Ref *pSender, cocos2d::ui::Slider::EventType type)
{
if (type == cocos2d::ui::Slider::EventType::ON_PERCENTAGE_CHANGED)
{
cocos2d::ui::Slider* slider = dynamic_cast<cocos2d::ui::Slider*>(pSender);
float epsilon = powf(slider->getPercent()/100.0,2)*20.0;
for(auto child : _children)
{
if(child->getName().size())
{
Sprite *sp = (Sprite*)child;
auto file = sp->getName();
auto pinfo = AutoPolygon::generatePolygon(file, Rect::ZERO, epsilon);
sp->setPolygonInfo(pinfo);
sp->debugDraw(true);
updateLabel(sp, pinfo);
}
}
}
}
void SpritePolygonTestSlider::updateLabel(const cocos2d::Sprite *sp, const PolygonInfo &pinfo)
{
Label *label = (Label*)(sp->getChildren().at(0));
auto filename = sp->getName();
auto size = pinfo.rect.size/Director::getInstance()->getContentScaleFactor();
label->setString(filename+"\nVerts: "+Value((int)pinfo.getVertCount()).asString()+ "\nPixels: "+Value((int)(pinfo.getArea()/(size.width*size.height)*100)).asString()+"%");
}
Sprite* SpritePolygonTestSlider::makeSprite(const std::string &filename, const Vec2 &pos)
{
auto quadSize = Sprite::create(filename)->getContentSize();
int originalSize = quadSize.width * quadSize.height;
auto pinfo = AutoPolygon::generatePolygon(filename);
auto ret = Sprite::create(pinfo);
ret->setPosition(pos);
sp = Sprite::create(filename);
addChild(sp);
sp->setPosition(Vec2(s)/2 - offset);
auto touchListener = EventListenerTouchOneByOne::create();
touchListener->onTouchBegan = [&](Touch* touch, Event* event){
// spp->showDebug(true);
debugForNormalSprite->setVisible(true);
return true;
};
touchListener->onTouchMoved = [&](Touch* touch, Event* event){
auto pos = touch->getDelta();
float newScale = clampf(spp->getScale() + pos.x * 0.01f, 0.1f, 2.f);
spp->setScale(newScale);
sp->setScale(newScale);
};
touchListener->onTouchEnded = [&](Touch* touch, Event* event){
// spp->showDebug(false);
debugForNormalSprite->setVisible(false);
};
_eventDispatcher->addEventListenerWithSceneGraphPriority(touchListener, this);
debugForNormalSprite = DrawNode::create();
sp->addChild(debugForNormalSprite);
auto positions = new Vec2[4];
auto spSize = sp->getContentSize();
positions[0] = Vec2(0, spSize.height);
positions[1] = Vec2(spSize);
positions[2] = Vec2(spSize.width, 0);
positions[3] = Vec2(0,0);
debugForNormalSprite->drawPoints(positions, 4, 8, Color4F(0.0,1.0,1.0,1.0));
debugForNormalSprite->drawLine(positions[0], positions[1], Color4F::GREEN);
debugForNormalSprite->drawLine(positions[1], positions[2], Color4F::GREEN);
debugForNormalSprite->drawLine(positions[2], positions[3], Color4F::GREEN);
debugForNormalSprite->drawLine(positions[3], positions[0], Color4F::GREEN);
debugForNormalSprite->drawLine(positions[0], positions[2], Color4F::GREEN);
debugForNormalSprite->setVisible(false);
delete [] positions;
TTFConfig ttfConfig("fonts/arial.ttf", 8);
std::string temp = "Sprite:\nPixels drawn: ";
auto spArea = Label::createWithTTF(ttfConfig, temp+Value((int)spSize.width*(int)spSize.height).asString());
sp->addChild(spArea);
auto spArea = Label::createWithTTF(_ttfConfig, filename+"\nVerts: "+Value((int)pinfo.getVertCount()).asString()+ "\nPixels: "+Value((int)(pinfo.getArea()/originalSize*100)).asString()+"%");
ret->addChild(spArea);
spArea->setAnchorPoint(Vec2(0,1));
temp = "SpritePolygon:\nPixels drawn: ";
// auto vertCount = "\nverts:"+Value((int)spp->getVertCount()).asString();
// auto sppArea = Label::createWithTTF(ttfConfig, temp+Value((int)spp->getArea()).asString()+vertCount);
// spp->addChild(sppArea);
// sppArea->setAnchorPoint(Vec2(0,1));
ret->setName(filename);
ret->setAnchorPoint(Vec2(0.5, 0));
return ret;
}
void SpritePolygonTestCase::onBackCallback(cocos2d::Ref *sender)
SpritePolygonTest3::SpritePolygonTest3()
{
TestCase::onBackCallback(sender);
Director::getInstance()->setClearColor(Color4F::BLACK);
_ttfConfig = TTFConfig("fonts/arial.ttf", 8);
_title = "Optimization Value (default:2.0)";
_subtitle = "";
auto vsize =Director::getInstance()->getVisibleSize();
std::string list[] = {
"Images/arrows.png",
"Images/CyanTriangle.png",
s_pathB2,
"Images/elephant1_Diffuse.png",
"Images/stars2.png"
};
int count = 5;
makeSprites(list, count, vsize.height/2);
}
SpritePolygonTest1::SpritePolygonTest1()
SpritePolygonTest4::SpritePolygonTest4()
{
SpritePolygonCache::getInstance()->removeAllSpritePolygonCache();
_title = "SpritePolygon Creation";
_subtitle = "SpritePolygon::create(\"Images/grossini.png\")";
cocos2d::experimental::SpritePolygon *s;
for(int i = 0; i < 10; i ++)
{
s= experimental::SpritePolygon::create(s_pathGrossini);
}
initDefaultSprite(s_pathGrossini, s);
}
//SpritePolygonTest2::SpritePolygonTest2()
//{
// /*
// 36.5 128.5
// 27.5 133.5
// 24.5 145.5
// 26.5 161.5
// 33.5 168.5
// 27.5 168.5
// 16.5 179.5
// 30.5 197.5
// 28.5 237.5
// 56.5 237.5
// 54.5 197.5
// 68.5 184.5
// 57.5 168.5
// 51.5 168.5
// 60.5 154.5
// 57.5 133.5
// 48.5 127.5
// 36.5 127.5
// */
// std::vector<Vec2> verts;
// verts.push_back(Vec2(36.5, 242.0-128.5));
// verts.push_back(Vec2(27.5, 242.0-133.5));
// verts.push_back(Vec2(24.5, 242.0-145.5));
// verts.push_back(Vec2(26.5, 242.0-161.5));
// verts.push_back(Vec2(33.5, 242.0-168.5));
// verts.push_back(Vec2(27.5, 242.0-168.5));
// verts.push_back(Vec2(16.5, 242.0-179.5));
// verts.push_back(Vec2(30.5, 242.0-197.5));
// verts.push_back(Vec2(28.5, 242.0-237.5));
// verts.push_back(Vec2(56.5, 242.0-237.5));
// verts.push_back(Vec2(54.5, 242.0-197.5));
// verts.push_back(Vec2(68.5, 242.0-184.5));
// verts.push_back(Vec2(57.5, 242.0-168.5));
// verts.push_back(Vec2(51.5, 242.0-168.5));
// verts.push_back(Vec2(60.5, 242.0-154.5));
// verts.push_back(Vec2(57.5, 242.0-133.5));
// verts.push_back(Vec2(48.5, 242.0-127.5));
// verts.push_back(Vec2(36.5, 242.0-127.5));
//
// SpritePolygonCache::getInstance()->removeAllSpritePolygonCache();
// _title = "SpritePolygon Creation";
// _subtitle = "SpritePolygon::create(\"Images/grossini.png\", verts)";
// auto s = experimental::SpritePolygon::create(s_pathGrossini, verts);
// initDefaultSprite(s_pathGrossini, s);
//}
//
//SpritePolygonTest3::SpritePolygonTest3()
//{
// /*
// 18, 48
// 33.500000, 73.500000
// 27.500000, 73.500000
// 16.500000, 62.500000
// 30.500000, 44.500000
// 54.500000, 44.500000
// 51.500000, 73.500000
// 60.500000, 87.500000
// 26.500000, 80.500000
// 24.500000, 96.500000
// 57.500000, 108.500000
// 36.500000, 113.500000
// 48.500000, 114.500000
// 36.500000, 114.500000
// 27.500000, 108.500000
// 68.500000, 57.500000
// 57.500000, 73.500000
// 56.500000, 4.500000
// 28.500000, 4.500000
// 0, 1, 2
// 3, 0, 2
// 4, 0, 3
// 5, 0, 4
// 5, 6, 0
// 0, 6, 7
// 8, 7, 6
// 6, 9, 8
// 9, 10, 8
// 9, 11, 10
// 11, 12, 10
// 8, 10, 13
// 14, 5, 4
// 15, 5, 14
// 4, 3, 16
// 3, 17, 16
// */
// std::vector<Vec2> verts;
// verts.push_back(Vec2(33.500000, 73.500000));
// verts.push_back(Vec2(27.500000, 73.500000));
// verts.push_back(Vec2(16.500000, 62.500000));
// verts.push_back(Vec2(30.500000, 44.500000));
// verts.push_back(Vec2(54.500000, 44.500000));
// verts.push_back(Vec2(51.500000, 73.500000));
// verts.push_back(Vec2(60.500000, 87.500000));
// verts.push_back(Vec2(26.500000, 80.500000));
// verts.push_back(Vec2(24.500000, 96.500000));
// verts.push_back(Vec2(57.500000, 108.500000));
// verts.push_back(Vec2(36.500000, 113.500000));
// verts.push_back(Vec2(48.500000, 114.500000));
// verts.push_back(Vec2(36.500000, 114.500000));
// verts.push_back(Vec2(27.500000, 108.500000));
// verts.push_back(Vec2(68.500000, 57.500000));
// verts.push_back(Vec2(57.500000, 73.500000));
// verts.push_back(Vec2(56.500000, 4.500000));
// verts.push_back(Vec2(28.500000, 4.500000));
// unsigned short indicesArr[] = {0, 1, 2, 3, 0, 2, 4, 0, 3, 5, 0, 4, 5, 6, 0, 0, 6, 7, 8, 7, 6, 6, 9, 8, 9, 10, 8, 9, 11, 10, 11, 12, 10, 8, 10, 13, 14, 5, 4, 15, 5, 14, 4, 3, 16, 3, 17, 16};
// std::vector<unsigned short> indices(indicesArr, indicesArr + sizeof indicesArr / sizeof indicesArr[0]);
//
// SpritePolygonCache::getInstance()->removeAllSpritePolygonCache();
// _title = "SpritePolygon Creation";
// _subtitle = "SpritePolygon::create(\"Images/grossini.png\", verts, indices)";
// auto s = experimental::SpritePolygon::create(s_pathGrossini, verts, indices);
// initDefaultSprite(s_pathGrossini, s);
//}
//
SpritePolygonTest4::SpritePolygonTest4(){
/*
18, 48
33.500000, 73.500000
27.500000, 73.500000
16.500000, 62.500000
30.500000, 44.500000
54.500000, 44.500000
51.500000, 73.500000
60.500000, 87.500000
26.500000, 80.500000
24.500000, 96.500000
57.500000, 108.500000
36.500000, 113.500000
48.500000, 114.500000
36.500000, 114.500000
27.500000, 108.500000
68.500000, 57.500000
57.500000, 73.500000
56.500000, 4.500000
28.500000, 4.500000
0, 1, 2,
3, 0, 2,
4, 0, 3,
5, 0, 4,
5, 6, 0,
0, 6, 7,
8, 7, 6,
6, 9, 8,
9, 10, 8,
9, 11, 10,
11, 12, 10,
8, 10, 13,
14, 5, 4,
15, 5, 14,
4, 3, 16,
3, 17, 16,
0.394118, 0.392562
0.323529, 0.392562
0.194118, 0.483471
0.358824, 0.632231
0.641176, 0.632231
0.605882, 0.392562
0.711765, 0.276859
0.311765, 0.334711
0.288235, 0.202479
0.676471, 0.103306
0.429412, 0.061983
0.570588, 0.053719
0.429412, 0.053719
0.323529, 0.103306
0.805882, 0.524793
0.676471, 0.392562
0.664706, 0.962810
0.335294, 0.962810
*/
Vec3 poss[] = {Vec3(33.500000, 73.500000,0),
Vec3(27.500000, 73.500000,0),
Vec3(16.500000, 62.500000,0),
Vec3(30.500000, 44.500000,0),
Vec3(54.500000, 44.500000,0),
Vec3(51.500000, 73.500000,0),
Vec3(60.500000, 87.500000,0),
Vec3(26.500000, 80.500000,0),
Vec3(24.500000, 96.500000,0),
Vec3(57.500000, 108.500000,0),
Vec3(36.500000, 113.500000,0),
Vec3(48.500000, 114.500000,0),
Vec3(36.500000, 114.500000,0),
Vec3(27.500000, 108.500000,0),
Vec3(68.500000, 57.500000,0),
Vec3(57.500000, 73.500000,0),
Vec3(56.500000, 4.500000,0),
Vec3(28.500000, 4.50000, 0)
};
unsigned short idxs[] = {0, 1, 2, 3, 0, 2, 4, 0, 3, 5, 0, 4, 5, 6, 0, 0, 6, 7, 8, 7, 6, 6, 9, 8, 9, 10, 8, 9, 11, 10, 11, 12, 10, 8, 10, 13, 14, 5, 4, 15, 5, 14, 4, 3, 16, 3, 17, 16};
std::vector<unsigned short> indices(idxs, idxs + sizeof idxs / sizeof idxs[0]);
Tex2F t2f[] = {
Tex2F(0.394118f, 0.392562f),
Tex2F(0.323529f, 0.392562f),
Tex2F(0.194118f, 0.483471f),
Tex2F(0.358824f, 0.632231f),
Tex2F(0.641176f, 0.632231f),
Tex2F(0.605882f, 0.392562f),
Tex2F(0.711765f, 0.276859f),
Tex2F(0.311765f, 0.334711f),
Tex2F(0.288235f, 0.202479f),
Tex2F(0.676471f, 0.103306f),
Tex2F(0.429412f, 0.061983f),
Tex2F(0.570588f, 0.053719f),
Tex2F(0.429412f, 0.053719f),
Tex2F(0.323529f, 0.103306f),
Tex2F(0.805882f, 0.524793f),
Tex2F(0.676471f, 0.392562f),
Tex2F(0.664706f, 0.962810f),
Tex2F(0.335294f, 0.962810f)
};
std::vector<V3F_C4B_T2F> vs;
for(int i = 0; i < 18; i++)
{
V3F_C4B_T2F t = {poss[i],Color4B::WHITE, t2f[i]};
vs.push_back(t);
}
_ttfConfig = TTFConfig("fonts/arial.ttf", 8);
_title = "Optimization Value (default:2.0)";
_subtitle = "";
auto vsize =Director::getInstance()->getVisibleSize();
SpritePolygonCache::getInstance()->removeAllSpritePolygonCache();
_title = "SpritePolygon Creation";
_subtitle = "SpritePolygon::create(\"Images/grossini.png\", vector<V3F_C4B_T2F> v, vector<unsigned short> indices)";
// auto s = experimental::SpritePolygon::create(s_pathGrossini, vs, indices);
auto pinfo = new PolygonInfo();
pinfo->triangles.verts = &vs[0];
pinfo->triangles.indices = idxs;
pinfo->triangles.vertCount = vs.size();
pinfo->triangles.indexCount = 18;
auto s = Sprite::create(*pinfo);
initDefaultSprite(s_pathGrossini, s);
int count = 3;
std::string list[] = {
s_pathGrossini,
// "TileMaps/fixed-ortho-test2.png",
"Images/grossinis_sister1.png",
"Images/grossinis_sister2.png"
};
makeSprites(list, count, vsize.height/5*2);
}

View File

@ -1,9 +1,11 @@
#ifndef __cocos2d_tests__SpritePolygonTest__
#include "../testBasic.h"
#include "../BaseTest.h"
#include "2d/CCSpritePolygon.h"
#include "ui/CocosGUI.h"
DEFINE_TEST_SUITE(SpritePolygonTest);
class SpritePolygonTestCase : public TestCase
{
protected:
@ -16,14 +18,29 @@ protected:
class SpritePolygonTestDemo : public SpritePolygonTestCase
{
public:
void initDefaultSprite(const std::string &filename, cocos2d::Node *inst);
protected:
cocos2d::Node* spp;
void initTouchDebugDraw();
cocos2d::Sprite* spp;
cocos2d::Sprite* sp;
cocos2d::DrawNode *debugForNormalSprite;
};
class SpritePolygonTest1 : public SpritePolygonTestDemo
{
public:
CREATE_FUNC(SpritePolygonTest1);
SpritePolygonTest1();
void make2Sprites();
};
class SpritePolygonTest2 : public SpritePolygonTestDemo
{
public:
CREATE_FUNC(SpritePolygonTest2);
SpritePolygonTest2();
void make2Sprites();
};
class SpritePolygonPerformance : public SpritePolygonTestCase
{
public:
@ -41,6 +58,7 @@ protected:
int continuousLowDt;
float continuousHighDtTime;
float waitingTime;
int _posX;
int _posY;
@ -60,71 +78,52 @@ protected:
int _incPix;
};
class SpritePolygonPerformanceTestStatic : public SpritePolygonPerformance
{
public:
CREATE_FUNC(SpritePolygonPerformanceTestStatic);
SpritePolygonPerformanceTestStatic();
protected:
cocos2d::experimental::SpritePolygon* makeSprite();
void initIncrementStats();
};
class SpritePerformanceTestStatic : public SpritePolygonPerformance
{
public:
CREATE_FUNC(SpritePerformanceTestStatic);
SpritePerformanceTestStatic();
protected:
cocos2d::Sprite* makeSprite();
void initIncrementStats();
};
class SpritePolygonPerformanceTestDynamic : public SpritePolygonPerformanceTestStatic
class SpritePolygonPerformanceTestDynamic : public SpritePolygonPerformance
{
public:
CREATE_FUNC(SpritePolygonPerformanceTestDynamic);
SpritePolygonPerformanceTestDynamic();
protected:
cocos2d::experimental::SpritePolygon* makeSprite();
cocos2d::Sprite* makeSprite();
cocos2d::PolygonInfo _pinfo;
void initIncrementStats();
};
class SpritePerformanceTestDynamic : public SpritePerformanceTestStatic
class SpritePerformanceTestDynamic : public SpritePolygonPerformance
{
public:
CREATE_FUNC(SpritePerformanceTestDynamic);
SpritePerformanceTestDynamic();
protected:
cocos2d::Sprite* makeSprite();
void initIncrementStats();
};
class SpritePolygonTest1 : public SpritePolygonTestDemo
class SpritePolygonTestSlider : public SpritePolygonTestCase
{
public:
CREATE_FUNC(SpritePolygonTest1);
SpritePolygonTest1();
CREATE_FUNC(SpritePolygonTestSlider);
SpritePolygonTestSlider();
protected:
cocos2d::Sprite* makeSprite(const std::string& filename, const cocos2d::Vec2& pos);
void makeSprites(const std::string* list, const int count, const float y);
cocos2d::TTFConfig _ttfConfig;
void changeEpsilon(Ref *pSender, cocos2d::ui::Slider::EventType type);
void updateLabel(const cocos2d::Sprite* sp, const cocos2d::PolygonInfo &pinfo);
};
//class SpritePolygonTest2 : public SpritePolygonTestDemo
//{
//public:
// CREATE_FUNC(SpritePolygonTest2);
// SpritePolygonTest2();
//};
//
//class SpritePolygonTest3 : public SpritePolygonTestDemo
//{
//public:
// CREATE_FUNC(SpritePolygonTest3);
// SpritePolygonTest3();
//};
class SpritePolygonTest4 : public SpritePolygonTestDemo
class SpritePolygonTest3 : public SpritePolygonTestSlider
{
public:
CREATE_FUNC(SpritePolygonTest3);
SpritePolygonTest3();
};
class SpritePolygonTest4 : public SpritePolygonTestSlider
{
public:
CREATE_FUNC(SpritePolygonTest4);
SpritePolygonTest4();
};
#endif /* defined(__cocos2d_tests__SpritePolygonTest__) */