3
\$\begingroup\$

I'm trying to determine which side of my object a collision is happening. In all of my searching, I have found 2 different proposed solutions, but each one has a major issue. I'm hoping that someone here can explain what steps I am missing.

Attempt 1 : Sensors

The first solution I tried was using Sensors on the sides of a Dynamic body. Like this :

Sensor Setup

The issue with this solution is that multiple sensors can easily collide with a single obstacle, like this :

Multiple Sensors Colliding

Attempt 2 : Determine side of contact using the World Normal

My second solution was to get the Normal from the b2WorldManifold that is provided by the contact in BeginContact(). This works perfectly, but only for detecting the side when a collision begins, not when it ends. EndContact() doesn't have the ability to provide a World Normal. You can get the manifold, but the components of the Normal are undefined. The issue with this is that I have no way of knowing which collision just ended.

Hopefully someone knows enough about Box2D to see something simple that I am obviously missing. Thanks in advance for any input.

\$\endgroup\$
  • \$\begingroup\$ The issue of 'which side is colliding' is a little vague. Will you always have an entire side of your fixture overlapping? Couldn't you just have one point of the green fixture inside the black one? \$\endgroup\$ – NauticalMile Jan 15 '15 at 20:25
  • \$\begingroup\$ No. What I need to know is positionally, is the object I'm colliding with above, below, left, or right of my object? For example, if I'm colliding with a Wall to the Right, and I'm not on the ground, then I can walljump to the left. \$\endgroup\$ – Kreed Jan 15 '15 at 20:45
  • \$\begingroup\$ ahh, ok. That helps. For wall-jumping (according to this answer), you could calculate the direction vector between the center of mass of your character, and the point of contact. Whenever the jump button is pressed, apply an impulse away from the wall along that vector. Does that work for you? \$\endgroup\$ – NauticalMile Jan 15 '15 at 22:11
1
\$\begingroup\$

There exists a manifold from the time BeginContact is called just up until EndContact is called. When EndContact is called the manifold is no longer valid.

This means you can store the b2Contact pointer once BeginContact is called. For every game loop that EndContact is not called you can access the b2Contact pointer and query the manifold. This way you can update your world normal. Once EndContact is called you can just look at what your collision normal was last game loop.

\$\endgroup\$
0
\$\begingroup\$

enter image description here

  • Keep the point in the middle of the object before the movement;
  • Create a Vector with start in this point and end in the point in the middle of the rectangle result of the collision;
  • Check what side is in contact with that vector;
\$\endgroup\$
0
\$\begingroup\$

If you want to check which of your body sides collided with obstacles, you can create your box-shaped body consisting of four b2EdgeShape sides having independent fixtures instead of single b2PolygonShape (in case you are using b2PolygonShape). In this way, while your are checking for contacts, can easily determine which fixture of my body is currently in contact with. I hope it helps you out.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.