Help me solve the last 5% in my collision response

Started by
10 comments, last by Kurt-olsson 9 years, 7 months ago

i will base the sliding based on where the player wants to go.

Yes, this is exactly what I tried to explain before: it would be better if your function took the destination point as input instead of the velocity. Also, when generating the slide-to position, you should use your existing function ClosestPointOnLine, instead of the new ProjectPointOnLine I used, so that the sphere stops sliding at the end of the line. Otherwise, if the projection of the destination point is outside of the line segment, the player sphere will slide too far, possibly missing other collisions.

Also in my example, during the slide-response, you should call ResolveCollissions repeatedly, each time using the returned x and y values as the new source position (set them as the new px and py values which will be passed to the next ResolveCollissions call), and calculating a new slide-to position based on the existing destination position. You stop calling ResolveCollissions when the position it returns is "almost" identical to the last (px, py) position. By "identical" I mean: when the distance from the currently returned x and y position to the last returned position (which you saved in (px, py)) is smaller than 1.0 (one pixel) for example. I think this will also solve the problem of sliding against the convex corners, but it would probably still be better if you could handle that case by using your algorithm - in the example I attached, this is handled by just pushing the player away from the corner point by 20.0 pixels - I don't like that. This should be used instead of the "slide" boolean parameter I added before.

Also, I think it would be best if you separate the collision response from the collision detection, like you did with the GetClosestCollision function, except GetClosestCollision should always re-calculate and return the closest line & point instead of returning the closest line based on the cached "line.overlap" values. GetClosestCollision should also differentiate between lines and line-endpoints (like in my example), and it should return the closest point on the line, pushed-out along the normal of the line in case of a line collision, or pushed-away along the radius from the line-endpoint in case of a line-endpoint collision. Then, in the collision-response code (which remains in the ResolveCollissions function), you just call GetClosestCollision (the collision-detection code), initially with the source and destination points passed to ResolveCollissions, and then repeatedly with the destination position returned by GetClosestCollision, until GetClosestCollision returns a position that is "almost" identical to the last position like I explained above. Also, GetClosestCollision should return the destination point directly in case there's no collision (it currently returns 0, meaning there was a collision with the line at position 0?).

Advertisement

Update!

i have followed this document a little bit and also tried to implement the things you pointed on, seperate detection and response.

I now have a function that returns data that we need when solving response.

http://www.peroxide.dk/papers/collision/collision.pdf

I think the key to the good routine my first version compared to my latest is to not just "push-out". Instead, calculate time of impact from a velocity.

Then get new velocity and run checks again.

And my pseudo code works like this now:.

Before movement, see if the player is free: 1.0 = free < 1.0 = we hit something and return the time t of impact.

If we dont hit anything, just move player

If we hit we check:
If player is not very very close, move the player close to the impact line - a little value
Now take the new velocity and run the function again recursivly.

This works now brilliant on edges corners, but have some problems in the vertex edges.

My next update will be to add checks for "edges" first and handle them seperatly.

I have uploaded a new document Version 4.

This topic is closed to new replies.

Advertisement