HardonCollider - resolving collision with a rotated rectangle

General discussion about LÖVE, Lua, game development, puns, and unicorns.
Post Reply
Newmski
Prole
Posts: 2
Joined: Sat Mar 25, 2023 12:16 pm

HardonCollider - resolving collision with a rotated rectangle

Post by Newmski »

Hi, I am attempting to integrate collision detection into my game using HardonCollider and I don’t think I am understanding how to correctly resolve the collisions.

In the attached sample I have a player and a platform. Gravity is constantly applied to the player which makes it fall until it collides with the platform This bit is working ok although I don’t understand why I have to negate the separating vector. The documentation says:
The separating vector points in the direction that shape has to move to clear the collision
If the separation vector points in the direction the player has to move shouldn’t it already be negative (to move it up the screen) rather than positive which would push it further into the platform?

Code: Select all

    for shape, delta in pairs(HC.collisions(platform)) do
        shape:move(-delta.x, -delta.y)
        shape.velocity.y = 0
        shape.grounded = true
    end   
My main issue though is that if I rotate the platform when the player is grounded it sticks to the platform. I can get to around 89 degrees before the player falls off. I would like the gravity to make the player slide down the platform as it rotates. I think this is due to my lack of knowledge of correctly resolving the collision – I think my collision resolution logic is pushing the player against the platform and making it stick.
Attachments
demo1.love
(18.9 KiB) Downloaded 47 times
User avatar
pgimeno
Party member
Posts: 3541
Joined: Sun Oct 18, 2015 2:58 pm

Re: HardonCollider - resolving collision with a rotated rectangle

Post by pgimeno »

Newmski wrote: Sat Mar 25, 2023 12:54 pm If the separation vector points in the direction the player has to move shouldn’t it already be negative (to move it up the screen) rather than positive which would push it further into the platform?

[...]

My main issue though is that if I rotate the platform when the player is grounded it sticks to the platform. I can get to around 89 degrees before the player falls off. I would like the gravity to make the player slide down the platform as it rotates. I think this is due to my lack of knowledge of correctly resolving the collision – I think my collision resolution logic is pushing the player against the platform and making it stick.
The answer to the first question is obvious. You're querying what collisions the platform has, hence you're getting a separating vector for the platform. This separating vector is correct for moving the platform so that it doesn't penetrate the player. Yet you want to move the player, hence the reversal of signs. If you query the player, you'll get the separating vector you expect. And in the end, it's probably better to query the player anyway, instead of each individual platform.

As for the second question, there are two parts to it. One is that while it is touching the platform, regardless of the touch direction, you're setting the vertical speed to 0, therefore when it's at the border but touching laterally, it still falls slowly. To solve that, you can query the Y of the separating vector before resetting the horizontal velocity. If the Y is very low or negative, it means that the separating vector does not impede the player from falling.

Code: Select all

        if delta.y > 0.01 then
            shape.velocity.y = 0
        end
And the second part is the bigger problem that the player does not accelerate when the platform is tilted, like a ramp should do. The best way to solve this is to use a Verlet integrator instead of the velocity vector approach you're using now.

The advantage of a Verlet integrator is that it doesn't use a velocity; instead, it uses the difference between the previous and the current position as an implicit velocity. That will be very useful in this case, because when you correct the position using the collision resolution, that will have an effect in the velocity. It may also complicate some aspects, but it gives great results nevertheless.

You may also give this a try without changing to a Verlet integrator: consider the separating vector as a force, and apply the horizontal component too, as follows:

Code: Select all

        player.velocity.x = player.velocity.x - delta.x * player.gravity * dt
I'm not sure that's physically correct, though, but it looks good. [Edit: definitely not physically correct]
Newmski
Prole
Posts: 2
Joined: Sat Mar 25, 2023 12:16 pm

Re: HardonCollider - resolving collision with a rotated rectangle

Post by Newmski »

Thanks to your suggestion I have got a solution that works much better than before.

This is a bit of a hack but it feels ok for now.

Code: Select all

    for shape, delta in pairs(HC.collisions(player)) do
        player:move(delta.x, delta.y)
        
        if delta.y > 0.01 then
            player.velocity.y = 0
        else
            player.velocity.y = player.gravity
        end

        player.grounded = true
    end  
I have attached the latest version for anybody that finds this post in the future..

Thanks again, I will now try to get my head around the Verlet integrator.
Attachments
demo1.love
(19.51 KiB) Downloaded 44 times
Post Reply

Who is online

Users browsing this forum: No registered users and 18 guests