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?

Project: http://murplyx.net/sss - Move with WAD and draw lines with mouse

Source Code: http://murplyx.net/sss/js/main.js and http://murplyx.net/sss/js/vec.js

\$\endgroup\$
  • \$\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 Feb 4 '15 at 19:45
  • \$\begingroup\$ @Peethor please click the project link, you can move with WASD \$\endgroup\$ – super Feb 4 '15 at 19:57
  • 1
    \$\begingroup\$ @davidvanbrink I want the player to stop, and not fall through the bottom line. Test it at murplyx.net/sss \$\endgroup\$ – super Feb 6 '15 at 5:59
  • 1
    \$\begingroup\$ Sometimes the diagonal line "loses", if you keep pressing 'D' the box goes through the diagonal instead. \$\endgroup\$ – bornander Feb 6 '15 at 8:55
  • 1
    \$\begingroup\$ Yep, that's what I mean, how do I fix it and what's the problem? \$\endgroup\$ – super Feb 6 '15 at 9:30
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\$
  • \$\begingroup\$ Dude, that's just genious, now I wonder, is my calculations correct about doing facTime -= col.time; each time there is a collision under the frame? \$\endgroup\$ – super Feb 6 '15 at 19:45
  • \$\begingroup\$ What do you mean by: "only addressing the fall-through-the-floor part, not the go-across-ceiling part which seems something different", it actually works for both or am I wrong? \$\endgroup\$ – super Feb 6 '15 at 19:55
  • \$\begingroup\$ It's all fixed by simply: if (col.time > 0.001) b.pos.add(vec.mul(b.vel, delta * (col.time == 1 ? 1 : col.time - 0.001) * facTime)); Uploaded and updated the code, murplyx.net/sss \$\endgroup\$ – super Feb 6 '15 at 19:57
  • \$\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 supports Monica Feb 6 '15 at 20:02
  • \$\begingroup\$ Thaaanks alooot, what do you mean by other corner cases, like what would that be, I can only see that all my problems are fixed. \$\endgroup\$ – super Feb 6 '15 at 20:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.