I'm having issues running simple AABB vs AABB collision detection. I'm able to successfully detect collisions without checking with velocity. But for some reason my code keeps prematurely firing randomly or not at all at times when checking for collisions on "sweptAABB". I've already attempted to do Unit Tests, but I can't say I've gotten anything useful out of it.
bool phPhysics::sweptAABB(phPhysicsObject* sourceObject, phPhysicsObject* targetObject, phVector2D & outVelocity, phVector2D &collisionNormal)
{
const phAABB a = sourceObject->getAABBMinAndMax();
const phAABB b = targetObject->getAABBMinAndMax();
collisionNormal = phVector2D(0,0);
/* Are we already overlapping? */
if(isColliding(sourceObject, targetObject)) return false;
// Treat b as stationary, so invert v to get relative velocity
phVector2D v = -sourceObject->getVelocity();
float hitTime = 0.00f;
float outTime = 1.0f;
phVector2D overlapTime;
if( v.getX() < 0)
{
if( b.getMax().getX() < a.getMin().getX() )
return false;
if( b.getMax().getX() > a.getMin().getX() )
outTime = std::min( (a.getMin().getX() - b.getMax().getX()) / v.getX(), outTime );
if( a.getMax().getX() < b.getMin().getX() )
{
overlapTime.setX( (a.getMax().getX() - b.getMin().getX()) / v.getX() );
hitTime = std::max(overlapTime.getX(), hitTime);
}
}
else if( v.getX() > 0 )
{
if( b.getMin().getX() > a.getMax().getX() )
return false;
if( a.getMax().getX() > b.getMin().getX() )
outTime = std::min( (a.getMax().getX() - b.getMin().getX()) / v.getX(), outTime );
if( b.getMax().getX() < a.getMin().getX() )
{
overlapTime.setX((a.getMin().getX() - b.getMax().getX()) / v.getX());
hitTime = std::max(overlapTime.getX(), hitTime);
}
}
if( hitTime > outTime ) return false;
// Y axis overlap
if( v.getY() < 0 )
{
if( b.getMax().getY() < a.getMin().getY() )
return false;
if( b.getMax().getY() > a.getMin().getY() )
outTime = std::min( (a.getMin().getY() - b.getMax().getY()) / v.getY(), outTime );
if( a.getMax().getY() < b.getMin().getY() )
{
overlapTime.setY((a.getMax().getY() - b.getMin().getY()) / v.getY());
hitTime = std::max(overlapTime.getY(), hitTime);
}
}
else if( v.getY() > 0 )
{
if( b.getMin().getY() > a.getMax().getY() ) return false;
if( a.getMax().getY() > b.getMin().getY() ) outTime = std::min( (a.getMax().getY() - b.getMin().getY()) / v.getY(), outTime );
if( b.getMax().getY() < a.getMin().getY() )
{
overlapTime.setY((a.getMin().getY() - b.getMax().getY()) / v.getY());
hitTime = std::max(overlapTime.getY(), hitTime);
}
}
if( hitTime > outTime ) return false;
// Scale resulting velocity by normalized hit time
outVelocity = -v * hitTime;
// Hit normal is along axis with the highest overlap time
if( overlapTime.getX() > overlapTime.getY() )
{
collisionNormal = phVector2D(signbit(v.getX()), 0);
}
else
{
collisionNormal = phVector2D(0, signbit(v.getY()));
}
return true;
}
bool phPhysics::isColliding(phPhysicsObject* sourceObject, phPhysicsObject* targetObject)
{
const phAABB a = sourceObject->getAABBMinAndMax();
const phAABB b = targetObject->getAABBMinAndMax();
// Exit with no intersection if found separated along an axis
if(a.getMax().getX() < b.getMin().getX() || a.getMin().getX() > b.getMax().getX())
{
return false;
}
if(a.getMax().getY() < b.getMin().getY() || a.getMin().getY() > b.getMax().getY())
{
return false;
}
// No separating axis found, therefor there is at least one overlapping axis
return true;
}
I'm not sure if I'm simply missed a small critical detail or it's something I'm simply not understanding. Was hopping if someone can see if they spot the error or perhaps why I would experience odd intermittent collision detections w/ velocity.