Below is the code I came up with to register the side of a body that a collision occurred. I only have experience with Box2d in a javascript version: box2dweb. I am assuming this code doesn't work for your target platform, but I would guess that there is a similar solution using any Box2D implementation.
var listener = new b2ContactListener;
listener.BeginContact = function (contact) {
//placeholder for contact point
var manifold = new b2WorldManifold();
//fill placeholder with contact "world" contact points
contact.GetWorldManifold(manifold);
//NOTE: m_pointCount is compared and not "m_points.length"
//basically the b2WorldManifold starts with 2 points
//but does not necessarily solve them
var point_count = contact.GetManifold().m_pointCount;
//add up midpoint intermediate values
for (var i=0;i<point_count;i++){
midpoint.x += manifold.m_points[i].x;
midpoint.y += manifold.m_points[i].y;
}
//gets the midpoint of the contact points
if (!(point_count <= 1)) {
midpoint.x = midpoint.x / point_count;
midpoint.y = midpoint.y / point_count;
//only 1 point
} else {
midpoint.x = manifold.m_points[0].x;
midpoint.y = manifold.m_points[0].y;
}
//use the Box2d user data field to map back to game object (ent)
var bA = contact.GetFixtureA().GetBody().GetUserData();
var bB = contact.GetFixtureB().GetBody().GetUserData();
if (!bA || !bB) return;
var A = bA.ent, B = bB.ent;
//call each entities collision function with the midpoint of the collision
A.onCollide(B,midpoint.x,midpoint.y);
B.onCollide(A,midpoint.x,midpoint.y);
}
Entity.prototype.onCollide = function (other_ent,cx,cy) {
var pos = this.body.GetPosition();
//careful - gotcha here is that height of SetAsBox is in halves!
var top = pos.y - this.h / 2;
var side;
// unless you are using "bullet" option for a fixture the
// collision points are typically crossing into the body
// thus .. adding minor amount of buffer to the top
if (cy < (top + 0.01) ) {
side = "top";
} else {
side = "not-top";
}
}
//Box2d World object
world.SetContactListener(listener);
eg
This question was the closest that I could find to one I asked. I really wanted to answer your question with my own findings, but I was stumped, and had to ask my own question :)
There are a couple ways to solve this problem, but if you wanted to use collision information this should be somewhat viable.