1

So, I had this code working for AABB collision until I decided to make a sprite bigger on Y axis than in X axis. I tried to fix the code but now it just doubles the collision size than the actual sprite size. ex. size of sprite 1 iVec2(50,100), size of sprite 2 iVec2(30,30).

CollisionData Collision::DoCollision(GameObject &object1, GameObject &object2) {

iVec2 center(object1.Position.x + object1.Size.x / 2, object1.Position.y + object1.Size.y / 2);

iVec2 half_extents(object2.Size.x / 2, object2.Size.y / 2);
iVec2 aabb_center(object2.Position.x + half_extents.x, object2.Position.y + half_extents.y);

iVec2 difference = center - aabb_center;
iVec2 difference2 = center - aabb_center;

iVec2 clamped = glm::clamp(difference, -half_extents, half_extents);
iVec2 clamped2 = glm::clamp(difference2, -iVec2(object1.Size.x / 2, object1.Size.y / 2), iVec2(object1.Size.x / 2, object1.Size.y / 2));

iVec2 closest = aabb_center + clamped;
iVec2 closest2 = aabb_center + clamped2;

difference = closest - center;
difference2 = closest2 - center;

if (glm::length(difference) <= object1.Size.x / 2 || glm::length(difference2) <= object1.Size.y / 2)
    return std::make_tuple(GL_TRUE, VectorDirection(difference), difference);
else return std::make_tuple(GL_FALSE, UP, glm::vec2(0, 0));

}
HalloweenJack
  • 281
  • 2
  • 15

1 Answers1

1

I recommend to do a simple overlap check.

If 2 segments are overlapping, can be checked by:

overlap = (x1+w1) > x2 && (x2+w2) > x1

where x1 is the start and w1 the width of the first segment. x2 is the start and w2 the width of the 2n segment.

If you want to check if to axis aligned bounding boxes are overlapping, then ypu have to do the test for both dimensions

bool overlap = 
    (object1.Position.x + object1.Size.x) > object2.Position.x) &&
    (object2.Position.x + object2.Size.x) > object1.Position.x) &&
    (object1.Position.y + object1.Size.y) > object2.Position.y) &&
    (object2.Position.y + object2.Size.y) > object1.Position.y);

If you want to know the amount of the overlapping, the you have to calculate the center points of the boxes and to compare the distance of the center points, to common half size of the boxes:

CollisionData Collision::DoCollision(GameObject &object1, GameObject &object2) {

    iVec2 center1(
        object1.Position.x + object1.Size.x / 2,
        object1.Position.y + object1.Size.y / 2);
    iVec2 center2(
        object2.Position.x + object2.Size.x / 2,
         object2.Position.y + object2.Size.y / 2);

    iVec2 dist = center1 - center2;
    iVec2 size((object1.Size.x + object2.Size.x) / 2, (object1.Size.y + object2.Size.y) / 2);


    iVec2 difference = size - iVec2(abs(dist.x), abs(dist.y));

    bool overlap = difference.x > 0 && difference.y > 0;

    if ( overlap )
    {
        iVec2 min1 = object1.Position;
        iVec2 min2 = object2.Position;
        iVec2 max1 = object1.Position + object1.Size;
        iVec2 max2 = object2.Position + object2.Size;

        bool horizontal = difference.x > difference.y;
        if ( min2.x > min1.x && max1.x < max2.x || min1.x > min2.x && max2.x < max1.x )
             horizontal = false;
        else if ( min2.y > min1.y && max1.y < max2.y || min1.y > min2.y && max2.y < max1.y )
             horizontal = true;

        return std::make_tuple(
            GL_TRUE, !horizontal ? (dist.x < 0 ? LEFT: RIGHT) : (dist.y < 0 ? UP : DOWN), difference );
    }

    return std::make_tuple(GL_FALSE, UP, glm::vec2(0, 0));
}
HalloweenJack
  • 281
  • 2
  • 15
Rabbid76
  • 202,892
  • 27
  • 131
  • 174
  • I used to use that code, but I need to push back the object on collision, so I check with VectorDifference() where it landed, Up, Down, Left, Right... Otherwise I would not know here to pushback the object, and using the last key isn't useful. – HalloweenJack Aug 31 '18 at 17:36
  • @Aether Yes, I see. But if the object is *left*, *right*, *up* or *down* is encoded in `dist`. If `dist.x` is less than 0, then `object1` is left of `object2` ... – Rabbid76 Aug 31 '18 at 17:40
  • Wow, got that working, thanks a lot, but there is still one small problem...It doesn't know when to use dist.x and dist.y. – HalloweenJack Sep 01 '18 at 01:38
  • @Aether If `difference.x > difference.y then you have to use `dist.x`. See the answer. May be you have to swap `UP` and `DOWN`, this depends on your coordinate system, which i don't know. – Rabbid76 Sep 01 '18 at 07:43
  • Actually, I already tried that, but still fall on a similar mistake, if the object 2 x size is bigger than the y size or viceversa then if an object laans, lets say on the left it would still be moved to the top since the difference is greate... – HalloweenJack Sep 01 '18 at 21:01
  • @Ather I think I understand your issue. See the changes to the answer. – Rabbid76 Sep 01 '18 at 21:16