Sorry your browser is not supported!

You are using an outdated browser that does not support modern web technologies, in order to use this site please update to a new browser.

Browsers supported include Chrome, FireFox, Safari, Opera, Internet Explorer 10+ or Microsoft Edge.

Geek Culture / How does sliding collision response work?

Author
Message
_Pauli_
AGK Developer
15
Years of Service
User Offline
Joined: 13th Aug 2009
Location: Germany
Posted: 14th Jan 2013 16:31
Hello,

can anyone explain to me how sliding collision (like in Sparky's Collision DLL) works?
I'm interested in the inner workings regarding vectors and movement in 3D space. The actual collision detection (ray vs. polygon) is not of interest here. Just assume I can get a collision point and face normal from a ray-to-wall intersection. Also I'm working with simple velocity movement here (I apply a velocity vector to the current position to move to a new position).

Usage example:
You control a FPS camera that runs into a wall at an angle. Instead of the camera sticking to the closest point of collision at the wall, it slides along the wall surface.

My ideas so far:
I think I have to do something like these steps:
1) Check collision from old position to new position.
2) If collision occurs, calculate how much of the velocity is "left over" (how much the velocity vector penetrates the polygon).
3) Transform the point of intersection by the penetration amount somehow (maybe along the polygons tangent?).

Would be great if someone could help me out with this!

Fluffy Rabbit
User Banned
Posted: 14th Jan 2013 17:09
Usually it's axial. Rays and all that aren't even necessary if you're just doing a few collision checks with a box. Actually, I'm having a hard time remembering the exact steps, and frankly I can't understand how some of the more complex procedures work. You say you want to use rays, huh? Well, the minimum number of rays you have to cast is 6 (in 3-dimensional space). Each one extends in its own direction on its respective axis. You can cast 4 additional rays to represent an 8-ray plane. When you actually hit the wall, how deep your rays intersect determines how far away from the wall you are pushed back in that direction, and the game "eats" your velocity on that axis. So, if your X velocity is 5 and your Y velocity is 5, after you hit on the Y axis your Y velocity is 0 and your X velocity is still 5.

Also, shouldn't this be posted in Game Design Theory?
Matty H
16
Years of Service
User Offline
Joined: 7th Oct 2008
Location: England
Posted: 14th Jan 2013 17:42 Edited at: 14th Jan 2013 17:42
I think you could do it like this.

Move object along its x component only and check for collision, put it back.
Move object along its y component only and check for collision, put it back.
Move object along its z component only and check for collision, put it back.

Then which ever components did not return a collision then the object is free to move in that direction. Obviously you don't have to move backward and forward, just thought that helps explain the process.

I tried it in 2D and it works great, I presume 3D is no different.

Zotoaster
20
Years of Service
User Offline
Joined: 20th Dec 2004
Location: Scotland
Posted: 14th Jan 2013 19:10
I imagine you could take the reflection vector of the incoming ray, and project it against the plane of the polygon.

"everyone forgets a semi-colon sometimes." - Phaelax
_Pauli_
AGK Developer
15
Years of Service
User Offline
Joined: 13th Aug 2009
Location: Germany
Posted: 15th Jan 2013 09:11 Edited at: 15th Jan 2013 09:34
Thanks for the replies so far!

@Fluffy Rabbit & Matty H:
I think those are some pretty straight forward approaches, that could indeed work well. But they both have to do multiple collision checks. I hope there is some way to do this only with the data (intersection point, normal) gathered from a single collision check. But if that is not possible I will get back to a multi-check approach so thanks for the hints!

Quote: "shouldn't this be posted in Game Design Theory?"

If this is the case, then a moderator should feel free to move this thread. Thanks.

@Zotoaster:
Could you explain this a bit more in detail? I'm not so good at vector maths. I know I could reflect the velocity vector against the hit face normal. And then how should I project that against the plane?

After some more research I found this nice article:
General Collision Detection for Games using Ellipsoids

At about two third down the page there is a section called "Sliding" which explains the process I'm aiming for:
Quote: "First, a collision is detected, and the velocity vector [...] is cut short at the point where it collides with the plane. The remainder (the leftover energy – everything behind the plane) is not thrown away. Rather, the destination point is projected onto the plane along the plane’s normal. This new point, subtracted from our collision point results in a new velocity vector that can be used for sliding."


Now the task is to understand all of it and put it into code form...

Edit:
This article seems to have some very useful information too (at about four fifths down the page under "Collision response"):
Collision detection & Response

Phaelax
DBPro Master
22
Years of Service
User Offline
Joined: 16th Apr 2003
Location: Metropia
Posted: 16th Jan 2013 02:37 Edited at: 16th Jan 2013 02:37
The last link Pauli posted was what I was going to post. It's the tutorial I learned from. Good in depth explanations of the topic.


Quote: "Move object along its x component only and check for collision, put it back.
Move object along its y component only and check for collision, put it back.
Move object along its z component only and check for collision, put it back."

I don't think you'd slide very well doing that.

Basically, you project a line segment from your current position to your destination. If that line intersects a poly, first calculate the point of impact. Move there. Now determine how much of line (it's really your velocity vector) remains after travelling to the point of impact. Project that remaining vector onto the surface of the plane and move to that new point.
This will allow you to slide along walls, varying your speed based on the angle you hit the wall at.

"You're not going crazy. You're going sane in a crazy world!" ~Tick
_Pauli_
AGK Developer
15
Years of Service
User Offline
Joined: 13th Aug 2009
Location: Germany
Posted: 16th Jan 2013 09:01 Edited at: 16th Jan 2013 14:28
Right, that's exactly the process I was aiming for! The second tutorial I linked to is pretty good and covers lots of stuff. I can really recommend this for everyone interested in doing their own collision and response.

Quote: "Project that remaining vector onto the surface"


This is the bit I'm still struggling with, but should be doable.

Matty H
16
Years of Service
User Offline
Joined: 7th Oct 2008
Location: England
Posted: 16th Jan 2013 14:14
Quote: "I don't think you'd slide very well doing that."


You're probably right, it was a quick solution I used once for a 2D game and seemed to work ok. But it's not very elegant anyway

Phaelax
DBPro Master
22
Years of Service
User Offline
Joined: 16th Apr 2003
Location: Metropia
Posted: 17th Jan 2013 01:35
When positioning the player near a surface after collision, be sure not to place them directly at the point of impact. This will place them on the poly itself and you could potentially end up moving through the object.

"You're not going crazy. You're going sane in a crazy world!" ~Tick
_Pauli_
AGK Developer
15
Years of Service
User Offline
Joined: 13th Aug 2009
Location: Germany
Posted: 18th Jan 2013 09:41 Edited at: 18th Jan 2013 12:43
This is remotely related to this subject:

How do I get the downhill pointing vector (in 3D) of a heightfield terrain (or any shape maybe) if I just have the normal of the surface?

I guess this vector would be a tangent of the surface.
Off the top of my head I'd say this is calculated by taking the cross product of the global up axis (0, 1, 0) and the face normal:



I can't try it right now because I'm at work. Can somebody verify or correct this?

Edit:
Ok, had a second thought on this. The above will give me the sideways direction (as opposed to downhill) of the surface. I guess that's the binormal/bitangent. Now I think I should calculate a second cross product of the normal and this vector to get the downhill vector!

Like this:



Any thoughts? (Still can't test it yet...)

Phaelax
DBPro Master
22
Years of Service
User Offline
Joined: 16th Apr 2003
Location: Metropia
Posted: 19th Jan 2013 17:38
Quote: "
[quote]Project that remaining vector onto the surface"


This is the bit I'm still struggling with, but should be doable.[/quote]

I *believe* to project one vector onto another the formula is:

(A dot B)*B

B in this case would be a normalized line lying on the surface of the plane. Basically, subtract any two verts from the poly and normalize it. It's been awhile since I read the peroxide paper, so you'd want to double check this.


Quote: "How do I get the downhill pointing vector (in 3D) of a heightfield terrain (or any shape maybe) if I just have the normal of the surface?"

You mean a vector showing the direction of the hill's slope? I think what I just mentioned might help you there.

But you shouldn't need to calculate "downhill". The collision system will handle that for you if you have gravity. Add a gravity constant to your velocity vector when you move then check collision. Gravity will pull you down the hill all on its own.

"You're not going crazy. You're going sane in a crazy world!" ~Tick

Login to post a reply

Server time is: 2025-05-20 17:25:29
Your offset time is: 2025-05-20 17:25:29