Circle collision mask
With this, when you delete points from the mask leaving only 2, the first point will be the center and the other will determine the radius. Super backward and forward compatible, as it just uses raw points data, very solid. I've already implemented the detection-response functions for polygon-circle and circle-circle cases, for both native and web, and here is an example to test them: CircleCollision.zip
Awesome! That looks nice! Great job :) I wonder if we could set up a few tests, to automatically check that the collision are working properly for a few polygons? (Let me know if you need help to launch tests, you can look at how it's done in the CI: https://github.com/4ian/GD/blob/master/.travis.yml#L39)
Also, do you think this could impact performances when doing a lot of collisions tests?
OK, I'll take a look into those tests :)
About the performance, if I did it right, there should be not problem at all:
- For polygon-polygon collisions the only check added is if one of the "polygons" is a circle (vertices.size() == 2), if so it maps the right function.
- For circle-circle it's super straightforward as you may guess, and maybe I can make it even faster.
- For polygon-circle it uses SAT, but the circle adds only one extra axis to check (if it where another polygon it would add one axis per edge), and for each axis the circle has to project only one point (if it where a polygon it should project every vertex). So it should be faster ⚡️
Thinking about it, I've forgotten to implement the isPointInsidePolygon functions for circles, but it's super easy.
I've added some tests for GDJS and a benchmark for circle collisions, the circle-polygon has almost the same performance than poly-poly (sometimes slightly slower), and the circle-circle is a bit faster. Maybe they are not much faster because multiple radius calculations.
Anyway, what draws my attention is the C++ vs JS performance. For my circle collision benchmarks (and the other collision benchmark out there) in C++ I have ~15 fps (yeah I have a shoes box as computer), but in JS everything seems so smooth, I'm sure it's around ~60 fps. Are you doing some dirty tricks in JS?, ignoring checks or something? 🤔
One way to increase the performance could be storing the radius as a polygon member, the radius would be calculated only once here: Direction.cpp#L149, and it should be scaled with the sprite scale here: RuntimeSpriteObject.cpp#L383 if I'm right.
Currently you can decide how the circle mask will be scaled if you do a non-homogeneous scale, for example if you put the point that determines the radius at the right of the center, then when you scale the object horizontally the circle will be a big bounding circle (bigger than the height) but if you scale it vertically the circle will keep the original radius. This will be lost with the performance "hack" above.
Thanks for the JS tests and the benchmarks :) I'm sure what to do because it's a bit frightening to have such a performance difference between C++ and JS 🤔
Maybe the handling of the object lists in the generated code? I don't know how C++ manages the memory so I can't do much anyway 😐
Sorry I did not take the time to dig to see why there was such performance issues. Could you tell me how I can run the benchmark to see if I can find anything to fix? :)
I just ran the collision benchmark located at "GDJS/tests/games/Collision benchmark.gdg", if your PC has the power to run it in native preview at 60 fps maybe you can add more copies of the objects until your fps are low, then try the web preview, hopefully (or not) JS will be faster.
I hope I will be able to add the collision masks editor soon to GD5. I'll make sure to add support for circles so that we could merge this!
(Oops misclick on "Close" button, sorry!)
Any eta on when this might get merged, circle's are very useful 😁