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

Author Topic: Per-Pixel Collision Detection  (Read 12800 times)

0 Members and 1 Guest are viewing this topic.

Ruckamongus

  • Jr. Member
  • **
  • Posts: 70
    • View Profile
Per-Pixel Collision Detection
« on: September 18, 2012, 03:51:09 am »
First of all, I have ported the example over from the wiki. However, it was meant for SFML 1.6 which allowed direct access to pixel data without copying the image from the video card to memory. The ported system works, however to do a single collision it drops the FPS from 60 to 5! Of course this is not acceptable, so what would be the best way to accomplish per-pixel collision detection in SFML 2.0?

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11032
    • View Profile
    • development blog
    • Email
Re: Per-Pixel Collision Detection
« Reply #1 on: September 18, 2012, 07:13:53 am »
SFML is not great at pixel perfect collision detection, probably one of the fastest way is to have a copy of sf::Image and sf::Texture and then use the sprites position and the pixel data of sf::Image to check for collision. You can also reduce the needs for checking dramatically by using a quadtree or similar structures.
In many cases a pixel perfect collision can be replaced with a less precise test, without having that much influence on the game play.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Ruckamongus

  • Jr. Member
  • **
  • Posts: 70
    • View Profile
Re: Per-Pixel Collision Detection
« Reply #2 on: September 18, 2012, 08:49:41 pm »
You kind of restated my post lol. I understand what has to be done, but what is the best way to do it? Imagine if the sprite is rotated, I need to make a new copy of the image then get it's pixels, which is extremely slow. The only thing I can think of is to maybe store the pointer of pixels (the unrotated version) and try to figure out how to manipulate just the pointer data for rotations. That way I could create a sort of bitmask for each sprite. How though, would you go about rotating a huge list (the pointer) of pixels?

Also, the SFML documentation states NOT to keep the pixel pointer for very long.

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11032
    • View Profile
    • development blog
    • Email
Re: Per-Pixel Collision Detection
« Reply #3 on: September 18, 2012, 09:52:37 pm »
You kind of restated my post lol. I understand what has to be done, but what is the best way to do it?
Well you didn't give much information on what you're trying to do/how you handle sprites (i.e. rotation).
With my post I suggested what now posted as your second post. ;)
I also wanted to point out that you may want to use a diffrent check if that is possible (which I can't from your provided information).

As for 'the best way', keep in mind that for mostly all problems there isn't 'a best way', solutions depend highly on what one wants to achieve. So maybe you should tells us more what your intend is.
Other than that there aren't many solutions in SFML. As I already said SFML is not layed out for heavy pixel manipulation. If it's needed you may want to look at SDL.

Quote
Also, the SFML documentation states NOT to keep the pixel pointer for very long.
Well I didn't say anything about storing the pointer. ;)
Also the developer should know when the image data haas changed and can update it.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Ruckamongus

  • Jr. Member
  • **
  • Posts: 70
    • View Profile
Re: Per-Pixel Collision Detection
« Reply #4 on: September 18, 2012, 11:01:28 pm »
I do realize that I may have sounded rude, and I apologize for that, no hard feelings? :)

I actually switched from SDL to SFML for real time rotations and alpha blending. (Of course the C++ API and modern feel was definitely a plus as well. :P)

I do have bbox collisions working (super simple of course, SFML provides the functionality already) and circular collisions (via radius) work fine too. However I was just trying to come up with some way to get a collision (with alpha tolerance) between two rotates sprites. My current method draws two sprites to a white surface and if there is any overlap black pixels appear. This works fine, but then I have to get the pixel data which again is slow.

My code is fairly simple:
sf::RenderTexture Surface;
Surface.create(640, 480);
Surface.clear(sf::Color(255, 255, 255, 0));
Sprite1.setColor(sf::Color(0,0,0,255));
Sprite2.setColor(sf::Color(0,0,0,255));
Surface.draw(Sprite1, sf::BlendMode::BlendAdd);
Surface.draw(Sprite2, sf::BlendMode::BlendMultiply);
Surface.display();
 

Any overlap of Sprite1 with Sprite2 shows as non-white pixels. Is there a fast way to compare textures to have all the same color pixels?

If not what would be the best approximation method? Some sort of recursive rectangle or circle collision checking?

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11032
    • View Profile
    • development blog
    • Email
Re: Per-Pixel Collision Detection
« Reply #5 on: September 18, 2012, 11:42:46 pm »
I do realize that I may have sounded rude, and I apologize for that, no hard feelings? :)
No problem on my side. ;)

Is there a fast way to compare textures to have all the same color pixels?
SFML doesn't provide texture data manipulation, maybe you can find something in OpenGL although I guess Laurent would've worked on such feature if it actually is supported...

If not what would be the best approximation method? Some sort of recursive rectangle or circle collision checking?
I'm not an expert on collision detection but it mostly is just math and can be solved without the need of pixel data (note: it's always good to keep the logic (collision) and rendering (pixel information) separated).
You may find quite a bit of stuff by simply googling, other than that there are dedicated libraries like Box2D which can perform collision detection of rotated objects (rectangle/circle/polygons), if the simple way doesn't work, this way might. ;)
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Nexus

  • SFML Team
  • Hero Member
  • *****
  • Posts: 6287
  • Thor Developer
    • View Profile
    • Bromeon
Re: Per-Pixel Collision Detection
« Reply #6 on: September 18, 2012, 11:54:27 pm »
If not what would be the best approximation method? Some sort of recursive rectangle or circle collision checking?
You can take a look at the Separate Axis Theorem. There are also libraries like Boost.Geometry who provide functionality with respect to polygons and intersection.

In performance-critical applications, collision detection consists of at least two levels: The exact collision, and a simple one (like bounding-rect) which is applied first to exclude all the cases where it is not worth to compute the exact collision. Data structures like quadtress help further to reduce the amount of comparisons.
« Last Edit: September 18, 2012, 11:56:00 pm by Nexus »
Zloxx II: action platformer
Thor Library: particle systems, animations, dot products, ...
SFML Game Development:

 

anything