-
-
Notifications
You must be signed in to change notification settings - Fork 191
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
ArcadeSolver buggy collision resolution and ContactSolveBias #3135
Comments
Apologies if this should go in discussions- I realized it became more discussion than bug report midway through |
@kfalicov Thanks for the issue! This is very thorough! I think it should be an issue :)
Part of the problem is the discrete nature of the simulation, every update moves the colliders a fixed amount based on velocity/acceleration. If the jumping rectangle accelerating updates most of the way through the floor rectangle, overlap resolution will push it through the bottom to minimize overlap. What you suggest might help with this, we could explore this as well but might produce other artifacts if we ignore minimum overlap and rely on current pos/vel.
Totally agree on this, we should sort the contacts based on the distance to the collision features, not the centers of their geometry. This does cause some odd artifacts. We should definitely change this 100%
A lot of what you describe is part of a continuous collision solution. These are exactly the type of things we are thinking about, I've been doing a lot of research around approaches. This is definitely something we want.
Definitely, currently the (not very robust) continuous collision mechanism is raycasting when an object is moving faster than half it's size in a frame it starts a raycast from the center of (currently only in the DynamicTree spatial partition strategy). My plan is to do a separate phase in the solver for time of impact contacts. I'm currently leaning towards a technique known as speculative contacts as a v1 and perhaps something more robust in the future that can better handle fast rotation and multiple fast objects.
To summarize:
Workarounds:
|
I'm trying to avoid using the Realistic physics solver as I don't need the rest of its features, and it will get expensive with what I have planned for my project. But my requirements mean that I may end up having to write my own collision resolver, if only just for the player actor |
@kfalicov I'll dig in deeper this week, this is definitely something that should work |
@kfalicov Out of curiosity, what happens if you remove |
@kfalicov Sorry for the rapid fire responses! Could you send me your test code from the videos? |
Sure! The engine setup is in |
I got things to avoid teleporting by turning on a fairly high fixed update at 120fps (8ms steps guaranteed), it seems I can also go as low as 95. 120fps-platformer.mp4Another thing that was pointed out to me is we could implement substepping in excalibur to improve the fidelity of the simulation with low cost, I might also explore that in addition to continuous collision. |
The problem with any solution based on the fixed update is that it means this problem is concealed, not solved. All it takes is for the same object to be moving at about 1.5x speed in the new fixed update FPS in order to still experience the same incorrect collision behavior- the only condition to replicate this is that the vertical overlap is greater than the horizontal during any collision, which is likely to happen again on accident if I'm not extremely precise with the values I choose for acceleration and maximum velocity. If players walk all the way until just 1 pixel remains on the platform, and then they jump straight up, their falling speed is usually enough to make sure that they fall past the platform rather than landing back on it |
@kfalicov Fair point, I'll keep poking around for workaround. I do agree that a more robust solution is warranted probably continuous/substepping. I'm going to step through the arcade solver in this setup as well to see if there are any other oddities that we can fix easily (in addition to collision feature distance) |
I've got a promising experiment locally with substepping that seems to work without a fixed update, I'll post more when I have firmer results. The gist is it does multiple small integration steps, re-uses collision features, and solves incrementally every frame |
Related to #3135 ## Changes: - Adds collision sub-stepping to discretize each frame further to help with fast moving objects - Improves integration accuracy
This issue hasn't had any recent activity lately and is being marked as stale automatically. |
This issue hasn't had any recent activity lately and is being marked as stale automatically. |
Behavior
2024-07-21_19-19-19.mp4
My current parameters in-engine are:
version:
^0.30.0-alpha.964
Investigation
It seems to me like it's an issue with the resolution order of the solve, or the provided
contactSolveBias
not applying as expected. I investigated the ArcadeSolver code to try and find some evidence of the cause of the issue. I noted a few potential issues with the AABB solver:preSolve
computes the distance based onworldPos
of the objects, which is then used to sort thedistanceMap
so that the collisions can be solved by closest-first. This seems like an issue because theworldPos
difference between the colliders is based on the origin point of the colliders, which in this case is not indicative of the "embed" distance between the colliding objects. I would expect instead that for each "axis" of the collision, the distance between the relevant edges is used to determine the distance, rather than a vector from center -> centerExcalibur/src/engine/Collision/Solver/ArcadeSolver.ts
Line 84 in 1a13e28
In my attached video it does seem like this may have something to do with it, since the moving box is further away from the center of the "ground platform" than it is from the "wall platform" at the time of the buggy behavior
preSolve
when computing theSide
of the collision, rather than usingcontact.mtv
it should be dependent on the colliding object's most recent position/velocity vector, because otherwise the object may be pushed out in a way which doesn't make sense for the falling object. I believe the traditional term for this is "Swept AABB", and the direction checked first during the "sweep" should be based on thecontactSolveBias
Excalibur/src/engine/Collision/Solver/ArcadeSolver.ts
Line 81 in 1a13e28
My expectation would be that for all AABB collisions, we perform a sort of raycast to the earliest intersecting edge, and reverse the box's movement back along that ray until it is flush with the intersecting edge. Then, depending on whether the edge itself is a
horizontal
or avertical
, we can restore the opposite component of the velocity. For example:2. we compute this using the
Side.fromDirection
of the moving body's velocityIn the Multi Collision, the new location collides with two colliders (floor and wall). However, we don't need any sort of bias if we check the nearest collision first:
Is this a behavior that would be arriving in the "continuous" (marked as WIP) physics setting?
The text was updated successfully, but these errors were encountered: