3
\$\begingroup\$

So I have set up a Swept test for AABB vs Line Collision that works fine, now the problem is that I have to deal with acute corners, where this happens:

Acute Corner

As you can see the AABB just falls through the bottom Line, when it should stop.

I have been trying to do this for a month now, and I can't find any solution at all.

Why does this happen and how do I fix it?

\$\endgroup\$
5
  • \$\begingroup\$ Maybe it's just me, but I find this question a little confusing. What exactly is happening, and what do you want to have happening? Does the example you showed trigger a collision? \$\endgroup\$
    – Peethor
    Commented Feb 4, 2015 at 19:45
  • \$\begingroup\$ Thanks for the edit. Can you clarify just a little further: What are the conditions, and what is the desired behavior? (Like every bug report, "Steps taken, expected behavior, actual behavior.) \$\endgroup\$ Commented Feb 5, 2015 at 17:37
  • \$\begingroup\$ In the example you show, what do you "want" to happen instead? \$\endgroup\$ Commented Feb 5, 2015 at 22:23
  • \$\begingroup\$ For some reason, the diagonal line "wins" on the shove, and the bottom line is ignored? \$\endgroup\$ Commented Feb 6, 2015 at 6:10
  • 1
    \$\begingroup\$ Sometimes the diagonal line "loses", if you keep pressing 'D' the box goes through the diagonal instead. \$\endgroup\$
    – bornander
    Commented Feb 6, 2015 at 8:55

1 Answer 1

5
+100
\$\begingroup\$

(only addressing the fall-through-the-floor part, not the go-across-ceiling part which seems something different) If I understand your algorithm correctly, you do the following:

  • Take your box current position t=0
  • Take the target position t=1
  • For all lines, find the collision time, and take the smallest one, tc.
  • If tc < 1, move the box ahead by tc times displacement vector.

What happens is that through numerical error when you move your box one of the sides moves slightly aside and passes a line (typically the ground). From there it doesn't hit anymore and can fall through.

My advice would be to keep a safety margin. Don't let your object move by col.time, in :

b.pos.add(vec.mul(b.vel, delta * col.time * facTime));

Move by (col.time - 0.01). Adjust 0.01 as needed. Don't move if col.time < 0.01.

I'm used to doing this kind of stuff in C++, not .js, so I'm not quite ready to test it in your framework, but I'll try later and check that it works. If you can try it, just le me know whether it helps.

I'm not sure how your velocity changes as you near the object, there might still be an issue if velocity approaches zero.

\$\endgroup\$
4
  • \$\begingroup\$ Great. I was trying to look up your .js and I'm all confused, not my language :-p. If you get into other corner cases, consider: as long a there's a collision, reduce the stepping distance and test again until you step a distance that doesn't colide. That is usually the most robust (more costly) solution. \$\endgroup\$
    – Jeffrey
    Commented Feb 6, 2015 at 20:02
  • \$\begingroup\$ Test nearly parallel lines, like a very high funnel just a bit tighter than your box. Does it fall through ? Test your object with a much higher velocity. \$\endgroup\$
    – Jeffrey
    Commented Feb 6, 2015 at 20:26
  • \$\begingroup\$ You're done :-). One little issue. Go right a bit, then up, then left so that the 'side' of the box applies against an edge end. Keep 'A' pressed. The box doesn't slide. Rather it holds in the air. Solving this would be more involved. You'd have to project the remaining part of your move vector against the side of the box, so you get a downward vector. Then the box would move down, but it gets tricky if there's a second intersection. Is you game ok with the box able to stick to side edges ? \$\endgroup\$
    – Jeffrey
    Commented Feb 6, 2015 at 21:18
  • \$\begingroup\$ Let us continue this discussion in chat. \$\endgroup\$
    – Jeffrey
    Commented Feb 6, 2015 at 22:09

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .