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

Author Topic: AABB collision resolution not working as expected  (Read 1964 times)

0 Members and 1 Guest are viewing this topic.

Nortski

  • Newbie
  • *
  • Posts: 7
    • View Profile
AABB collision resolution not working as expected
« on: April 28, 2024, 04:19:39 pm »
I am a beginner trying to implement some AABB collision detection. I'm following along with the excellent COMP4300 Game Programming lecture series on Youtube by Professor Dave Churchill but I'm now stuck.

After watching his lecture on collision detection and resolution I believe I have implemented everything as instructed. The collision detection works fine but the resolution of detecting how much overlap there is and pushing back the sprite by the amount of overlap is not working as expected.

As you can see in the linked video, the resolution only works against the tiles at the very top of the screen. Note that I'm only testing for horizontal collision.

According to the lecture I had to create two helper functions: getOverlap and getPreviousOverlap, which is just a copy and paste of getOverlap but uses the entity's previous frame's position.

If getOverlap x and y are both greater than 0 then there's a collision. This part works.

To see if it was horizontal collision I use the formula if(prevOverlap.y > 0) {}

However; apart from the tiles at the top, this condition is not being met.

Link to demo video https://streamable.com/mj9o61

// Collision system in Scene_Play.cpp
void Scene_Play::sCollision()
{
    auto& playerTransform = m_player->getComponent<CTransform>();
    auto& playerBoundingBox = m_player->getComponent<CBoundingBox>();
    auto& playerState = m_player->getComponent<CState>().state;

    for (auto& e : m_entityManager.getEntities("tile"))
    {
        Vec2 overlap = Physics::getOverlap(m_player, e);
        Vec2 prevOverlap = Physics::getPreviousOverlap(m_player, e);
        auto& entityTransform = e->getComponent<CTransform>();

        if(overlap.x > 0 && overlap.y > 0)
        {
            std::cout << "Collision detected" << std::endl;          
           
            if (prevOverlap.y > 0) {

                std::cout << "Horizontal collision" << std::endl;
                // Calcualte if from left or right collision occurred
                playerTransform.pos.x = (playerTransform.pos.x < entityTransform.pos.x) ? playerTransform.pos.x -= overlap.x : playerTransform.pos.x += overlap.x;
            }
        }
    }
}

//Helper functions in Physics.cpp
Vec2 Physics::getOverlap(std::shared_ptr<Entity> player, std::shared_ptr<Entity> entity)
{
    auto& playerTransform = player->getComponent<CTransform>();
    auto& playerBoundingBox = player->getComponent<CBoundingBox>();
    auto& entityTransform = entity->getComponent<CTransform>();
    auto& entityBoundingBox = entity->getComponent<CBoundingBox>();

    Vec2 delta = { abs(entityTransform.pos.x - playerTransform.pos.x), abs(entityTransform.pos.y - playerTransform.pos.y) };

    float ox = (entityBoundingBox.halfSize.x + playerBoundingBox.halfSize.x) - delta.x;
    float oy = (entityBoundingBox.halfSize.y + playerBoundingBox.halfSize.y) - delta.y;

    if (ox > 0 && oy > 0) return Vec2(ox, oy);

    return Vec2(0.0f, 0.0f);
}

Vec2 Physics::getPreviousOverlap(std::shared_ptr<Entity> player, std::shared_ptr<Entity> entity)
{
    auto& playerTransform = player->getComponent<CTransform>();
    auto& playerBoundingBox = player->getComponent<CBoundingBox>();
    auto& entityTransform = entity->getComponent<CTransform>();
    auto& entityBoundingBox = entity->getComponent<CBoundingBox>();

    Vec2 delta = { abs(entityTransform.prevPos.x - playerTransform.prevPos.x), abs(entityTransform.prevPos.y - playerTransform.prevPos.y) };

    float ox = (entityBoundingBox.halfSize.x + playerBoundingBox.halfSize.x) - delta.x;
    float oy = (entityBoundingBox.halfSize.y + playerBoundingBox.halfSize.y) - delta.y;

    if (ox > 0 && oy > 0) return Vec2(ox, oy);

    return Vec2(0.0f, 0.0f);
}
 

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11030
    • View Profile
    • development blog
    • Email
Re: AABB collision resolution not working as expected
« Reply #1 on: April 28, 2024, 05:31:31 pm »
Can you check that your BoundingBox and Transform component actually updated correctly, so you aren't just getting the same information for all the entities?

I recommend getting out the debugger and stepping through the collision resolution code, to see what values you're working on and where the values aren't as expected.
« Last Edit: April 29, 2024, 08:59:46 pm by eXpl0it3r »
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Nortski

  • Newbie
  • *
  • Posts: 7
    • View Profile
Re: AABB collision resolution not working as expected
« Reply #2 on: April 29, 2024, 06:02:29 pm »
I recommend getting out the debugger and stepping through the collision resolution code, so see what values you're working on and where the values aren't as expected.

It appears that the prevPos.x and PrevPos.y components of the entity objects are returning 0.0. I don't know why as they update correctly in the movement system.

Nortski

  • Newbie
  • *
  • Posts: 7
    • View Profile
Re: AABB collision resolution not working as expected
« Reply #3 on: April 29, 2024, 06:16:31 pm »
Oh my word! Thank you internet stranger for giving my a kick up the backside to use the debugger for once in my life. Turns out I was only ever updating the players previous position whereas all other enitites had defaulted to 0 as per the constructor.

What an idiot #face palm#

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11030
    • View Profile
    • development blog
    • Email
Re: AABB collision resolution not working as expected
« Reply #4 on: April 29, 2024, 09:00:16 pm »
Hehe ;D

The debugger can be a valuable tool for finding our own mistakes :D
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/