Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: LineStrip VertexArray and ConvexShape problem  (Read 4403 times)

0 Members and 1 Guest are viewing this topic.

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: LineStrip VertexArray and ConvexShape problem
« Reply #15 on: February 14, 2024, 04:32:55 pm »
I'm glad you've at least tried Selba Ward; it is there for people to use!

I mentioned Spline only as a simple and easy way to draw a polygon's outline. Simply export Polygon's positions and set all Spline's positions from that export. Remember to close the Spline. You can also use a thickness for Spline so the outline is no longer infinitely thin (and drawn as a pixel thickness). You can also round the corners. Note that Spline creates the entire polyline as a single object and draws it with a single draw call whereas drawing multiple sf::RectangleShapes (one for each edge) is one draw per edge. FYI, Selba Ward's Line can also draw a simple line with or without thickness and also used to use sf::RectangleShape internally but was replaced by custom vertex array. Still, Spline's better ;)

Another thing to note is that if anything in Selba Ward isn't generic enough to be useful in multiple scenarios, I'd like to consider updates and improvements, and if anything is completely missing from Selba Ward, I consider adding it.
Selba Ward is still improving and Polygon is actually pretty new so somethings are yet to come.

My responses were to help with the creation of the object that you were having trouble with. Hope you at least got that shape made! Note that I didn't mention Selba Ward at first and tried to explain how to create the object yourself. :)

My point about any complex being able to be represented by triangles still stands. However, this is separate from being able to triangulate from a given set of points. Does the "butterfly shape" have holes? Polygon can handle holes but must be informed where they are; hole vertices must also be in opposite (clockwise) direction. In addition, the triangulation method must be set to "EarClip" rather than the more simple "BasicEarClip" to be able to handle the holes. Note that Polygon can only handle "simple polygons"; that is, a polygon that never crosses itself. Holes are technically not part of a "simple polygon" but Polygon converts it into a simple polygon first (as a bonus!).

If you could provide the vertices for the "butterfly shape" and an image of what it should look like, I'd like to do some tests.

It's worth noting that Polygon is designed to be a way to provide a filled polygonal area from a set of points representing its boundary. It's not, however, designed to have visual effects that manipulate those points (such as corner rounding). Those effects should be done separately and given to Polygon to create the shape. In fact, Spline can do this; it can handle Bezier curves and can export its interpolated position so a curved boundary could be created in Spline and then passed to Polygon to create the shape.
It was considered to have a base for both Spline and Polygon as they have similar concepts but decided against so that each Selba Ward drawable can be used independently.

Reading what you wrote about the "butterfly shape" again, I realise that you are creating a polygon where edges cross. This is not a simple polygon and cannot be handled automatically by Polygon. It breaks the rule that vertices must be passed in the same direction. The "butterfly" has vertices in both clockwise and anti-clockwise directions.
Probably better to not have allowed a polygon definition to do this than to try to fix it when the mistake is made.
This could be considered "ill-formed" as it has a "twisted" and not flat face. In fact, if that shape (like a bow-tie, I'm imagining) is required, it can be created; the point in the centre should be included since it exists. It would basically be 6 vertices (5 different ones) which would be the rectangle (in anti-clockwise direction) with the centre vertex between the two vertices of each opposing edge (either top and bottom or left and right).
It could be thought of this way: why is a shape with 2 triangles trying be defined without giving one of the points of each triangle?

Pre-processing can "fix" this. It can already be done before giving the points to Polygon (by specifying them correctly) but features that check and/or adjust for this could be included in Polygon at a later time.

As an aside, Polygon should, in the future, also be able to use monotone triangulation (uses scanline).

I hope I've addressed your questions and helped with your issues. If I missed anything, feel free to let me know.
Also, I'm open to ideas for Polygon and also, more generally, Selba Ward.


EDIT (2024/02/15):
Selba Ward's Polygon can now (as of v1.4), in fact, also work points that are in a clockwise order!
And more!
For more info, see this: https://github.com/Hapaxia/SelbaWard/pull/46
« Last Edit: February 15, 2024, 04:41:20 pm by Hapax »
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

kojack

  • Sr. Member
  • ****
  • Posts: 343
  • C++/C# game dev teacher.
    • View Profile
Re: LineStrip VertexArray and ConvexShape problem
« Reply #16 on: February 15, 2024, 01:08:51 pm »
I'm a little hesitant to mention it (since it is barely documented and you'll be on your own getting it to work), but another way to go for vector art is to use NanoVG. It's kind of like a real time version of SVG using OpenGL.
Here's a pic of your data (the points vector) rendered using this code (in an SFML project):
        nvgBeginFrame(vg, 1920, 1080, 1);
        nvgBeginPath(vg);
        nvgFillColor(vg, nvgRGBA(255, 0, 0, 255));
        nvgStrokeColor(vg, nvgRGBA(255, 255, 0, 255));
        nvgStrokeWidth(vg, 2);
        nvgTranslate(vg, 100,100);
        nvgBeginPath(vg);
        nvgMoveTo(vg, points[0].x, points[0].y);
        for (int i=1; i<points.size(); ++i)
        {
                nvgLineTo(vg, points[i].x, points[i].y);
        }
        nvgClosePath(vg);
        nvgFill(vg);
        nvgStroke(vg);
        nvgEndFrame(vg);
 

It works within SFML fine, but you have to be a little careful. To get concave shapes it needs a stencil buffer, so you need to set the SFML window context to 8 bit stencil. You also need to call resetGLStates() on the SFML window after any NanoVG rendering, because NanoVG messes with opengl states that SFML expects to not be changed.
Performance won't be as good (since its more dynamic remaking the shape every frame, not just a vertex array generated once), but there's a lot of features in it.
https://github.com/memononen/nanovg

z7x

  • Newbie
  • *
  • Posts: 10
    • View Profile
Re: LineStrip VertexArray and ConvexShape problem
« Reply #17 on: February 16, 2024, 06:30:36 pm »


I have almost finished my polygon class. Actually, when I first looked at the ear clipping code in SelbaWard, I didn't understand anything. However, after watching the video in the link above, I realized how simple it actually is, and I tried to code it myself. The result was quite successful, and now I can draw shapes using both ear clipping and scanline algorithms. However, when the edges of the polygon overlap, the expected result is not achieved when drawn with ear clipping. In such cases, I have a few shapes where I compare the results of drawing with ear clipping and scanline algorithms. For example, when I try to draw some shapes with ear clipping, due to the overlapping edges, I exit the loop without fully filling the shape. I also checked if overlapping edges can be drawn with the scanline algorithm, but even though the scanline fills the interior most of the time, there can still be minor glitches. Additionally, I thought it would be silly to draw a simple square with the scanline, so adding ear clipping seemed quite logical, and now both of them work (except for the exceptions I mentioned). Furthermore, I have shared some visuals below regarding this matter. For instance, when you want to draw a crescent shape, you don't need to send 30-40 points to the polygon. I achieved this with just 3 points. To explain how it works, only 3 key points are sent, which determine the real identity of the polygon. Between these points, arcs are drawn at the angle you specify, and by sending only 3 points, we can draw based on the angles of the arcs between these 3 points. Features like this can be added, and instead of asking the user to reverse the corners based on whether they are clockwise or not, the polygon should calculate it based on the points sent. For example, if your calculations work counterclockwise, then let there be a function that calculates this, and if your calculations work counterclockwise and the polygon is calculated clockwise, then you can reverse the corners. Allowing the user to do this might result in a runtime error for novice coders like me. Other than that, that's all I have to say. I'll be closely following your developments.

https://drive.google.com/file/d/1FdalzQlJhhzCmc5OnFjEc7UAzxvsNkfg/view?usp=sharing

"Here is the visual representation. The shapes in the top row are drawn with the ear clipping algorithm, while the shapes in the bottom row are drawn with the scanline algorithm. The shapes are exactly the same; the only difference is the drawing methods. Take a close look at the differences between them."

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: LineStrip VertexArray and ConvexShape problem
« Reply #18 on: March 06, 2024, 05:41:31 pm »
Glad you got what you need working and thank you for the suggestions.

Selba Ward's Polygon has already been recently upgraded to allow either direction as well as multiple other features. However, I would strongly suggest against automatically calculating the direction of the vertices as this would entail processing every edge/angle before even beginning and this can be extremely time-consuming as larger shapes are involved. Personally, I think that insisting that the provider of the vertices knows in which direction they are in is preferred over unnecessary work during the triangulation. Of course, if the direction needs to be calculated 'automatically', it could be done 'before' triangulation if the provider is unable to know the direction. This, at least, can be done just once if they keep consistent.

Providing control points instead of actual points is adding another step. Again, one that can be skipped without the ability but, since Selba Ward's Spline already does that work, Polygon doesn't need it as well as it can simply take the actual points exported from Spline.

You've done a lot of work in this area and probably learnt a lot, which is admirable! I must admit, though, that considering you only had a single specific problem and that problem was already provided for, it seems like you got caught in a rabbit hole (I do that too!). I suppose, then, I'm asking if you got your actual initial problem solved (whether using Selba Ward, your own triangulator, or a simple vertex array as I initially suggested) and can move on with that project?
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*