Beding/warping Sprites by bezier

Hi!
I want to create a subclass of Sprite (or something similar) which I can bend based on a bezier curve. Something like the image

My plan is to have a Constructor with:

  • Bezier curve (s)
  • of subdivisions (triangles to subdivide)

  • boolean . TRUE to define if the Sprite should be repeated if the bezier curve is bigger than the Sprite, or false in case I wan to auto-scale to the size of the curve.

I have searched everywhere in cocos2dx but cant find anything, I found this thread which gives me some idea, but I dont totally know how to achieve the desired result.

Does anyone have created something similar?
Does anyone have an idea of how to achieve this result?

Related:

(from PM - for community)

For this bend effect you’ll need to generate custom geometry. I do this in my Textured Ring example using vectors of vertices and texture coords, but you might want to consider using PolygonInfo instead so you can support batching - See CCSprite implementation for use.

As for the actual solution, I would start with simplifying a sprite to a line of fixed width and two points (center left & center right for example). Then by sampling a bezier equation along the line, insert new points. Finally converting the line back into geometry as two vertices per line point, extended perpendicular to the curve by half the line width, in both directions.

I drew you a picture in paint :smiley:

The X texture coordinate will be the same in each vertex pair generated from the line, which is simply the normalised linear position along the line. The Y texture coordinate will be the same across pairs, with the pair.first=0 and pair.second=1.

Hope this helps :smiley:

I have been working on the spline definition, now im tryign to distort the image,
this is a preliminar result:

but soon ill integrate it using a spline of unlimited points and other stuff…
Ill post it here once I finish this.

Just… one question:
If i Want to deform an animation, is it possible to keep the coordinates distort?
what else do I need to do in order to keep an animation running on a distorted sprite?

Look like some great progress!

Yeah animations should be relatively trivial for a given sprite frame rect.

Once you’ve generated your UVs, for each: multiply by rect size (uwidth, vheight) and then add the origin.

This will scale and translate your normalised UV to the atlas sprite frame area, or do nothing if the Frame represents a full texture, where rect=(0,0,1,1).

You could inherit from cocos2d::Sprite so you can make use of the cocos2d-x Animate action but I’d recommend implementing your own action or animate functionality in class. Definitely make use of cocos2d::SpriteFrame and cocos2d::Animation though!

Hope this helps.

So far this is what I have achieved:

but there are a lot of things that im not sure what to do about it:
1-[quote=“almax27, post:3, topic:33758”]
but you might want to consider using PolygonInfo instead so you can support batching - See CCSprite implementation for use.
[/quote]

  • I still have to check how to use this for batching (pending)

2- [quote=“almax27, post:5, topic:33758”]
Once you’ve generated your UVs, for each: multiply by rect size (uwidth, vheight) and then add the origin.
[/quote]

  • this is in case I want the sprite to not to change the size, but just the shape, right?

3- [quote=“almax27, post:5, topic:33758”]
This will scale and translate your normalised UV to the atlas sprite frame area, or do nothing if the Frame represents a full texture, where rect=(0,0,1,1).
[/quote]

I totally do not understand this part :frowning:

And the animation part… well… i will start tomorrow when after I sleep hahaha.

Thank you a lot for the help :slight_smile:
I will add the code here once I clean it up :frowning:

Basically a sprite frame usually represents a sub section of a texture. i.e. rect(0.2, 0.6, 0.2, 0.2)

This calculation is required to animate your curve using a sprite sheet. Although you could just use separate textures, it would not be as efficient.

OK, its not the best, there are a lot of improvements could be done (like batching or inherit from CCSprite, using linear creates not nice results, etc) but so far this is what I have.
If anyone wants to improve the class or tell me what could be implemented or extended, please tell me, I will try to help.

extras:

  • setTexture - replaces texture
  • setStrokeScale - keeps the size and position of nodes, but the texture size is scaled

TexturedSpline parameters:
- a vector of Vec2 points ( the path)
- the amount of subdivisions between point and point
- the texture or texture name
- the type of spline (Linear, catmull-rom**, b-qubic) (** = default)

And this is an expample of usage

if(auto spline = TexturedSpline::create(path, 10, "brick.jpg")
{
    addChild(spline);
    spline->setPosition(center);
}

TexturedSpline.cpp (11.0 KB)
TexturedSpline.h (2.6 KB)

notes:
the path must contain 4 POINTS or more
If the points distance is bigger than the sprite size then it repeats the sprite.

  • This requires the texture’s dimensions to be pow of 2.
  • so: If u want to just distort any image, remove that requiremente from code and texture will not be repeated, by doing this the texture wont repeat (AFAIK, I actually havent tried)
4 Likes