-
Notifications
You must be signed in to change notification settings - Fork 22
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
BetterCharacterControl hops across seams #18
Comments
Note that the test app relies on the app's tick listener being added before the BCC's tick listener! The first anomaly detected is in
This is highly reproducible. The character's post-tick location with During |
On a hunch, I replaced the Before implementing this workaround, try to pin down the root cause, since it presumably affects non-BCC rigid bodies as well. |
Today the |
Shortening the physics timestep slightly (from 0.0166667 to 0.013) resolves the issue, at least for |
Another symptom of this issue is that when
Need to look into how the impulse is calculated. |
With
|
The |
By adding The mysterious 7.674518 impulse is set at line 95:
7.674517 is an abnormally large value for |
It's set in if (!infoGlobal.m_splitImpulse || (penetration > infoGlobal.m_splitImpulsePenetrationThreshold))
{
//combine position and velocity into rhs
solverConstraint.m_rhs = penetrationImpulse + velocityImpulse; //-solverConstraint.m_contactNormal1.dot(bodyA->m_externalForce*bodyA->m_invMass-bodyB->m_externalForce/bodyB->m_invMass)*solverConstraint.m_jacDiagABInv; |
Step 10 had:
whereas step 11 has:
That partly explains why the issue is more pronounced at high speeds. |
On both step 10 and step 11,
|
btManifoldPoint& cp = manifold->getContactPoint(j); in Now to figure out where that |
It's the 4-arg constructor invoked at btManifoldResult.cpp:131. Here's the call stack:
|
Looks like it comes from normalInB = m_cachedSeparatingAxis; and btScalar rlen = btScalar(1.) / btSqrt(lenSqr);
normalInB *= rlen; //normalize There oughta be a law against functions that are 500 lines long! |
Here are the
Compare with step 10:
So now looking for where |
There's an ominous comment at line 735: //note, for large differences in shapes, use double precision build! I tried using double-precision, and it didn't seem to help. The history of
The code iterates, in a loop extending from line 839 to line 969, with 8 possible exits from the loop. (There oughta be a law!) I wonder which exit is taken here... The main exits seem to be the first 2, which I've designated A and B. The one leading to (-0.081573 1.036597 -0.081604) is exit B: //exit 0: the new point is already in the simplex, or we didn't come any closer
if (m_simplexSolver->inSimplex(w))
{
m_degenerateSimplex = 1;
checkSimplex = true;
break;
} Exit B was also taken on the previous timestep, only there the loop went around 3 times:
Perhaps the loop terminated too soon. |
Despite comments about the Johnson algorithm and alternative approaches, the only implementation of In Adding "<stdio.h>" to "btVoronoiSimplexSolver.cpp" broke raycasting, so I stepped through in GDB. On the 2nd iteration of step 11, GDB sees:
The function returns GJK seems to believe that the contact point lies exactly on the edge of the mesh triangle, so the normal is undefined. I need to study the code some more. |
I think what goes on in step 11 is, there are 2 contact points calculated, one for each triangle, and the SI solver sets up a contact constraint for each point. But only one of the constraints is really valid. For the triangle with index=0, |
I now understand this issue well enough to contemplate solving it. Some approaches I'm considering:
1 and 3 seem straightforward to implement, but introduce approximations and might break assumptions made elsewhere. |
Found btInternalEdgeUtility.h which pointed me to http://code.google.com/p/bullet/issues/detail?id=27 which pointed me to https://pybullet.org/Bullet/phpBB3/viewtopic.php?f=9&t=1814 |
The intent of |
Pursuing approach 2, we can use |
The plan is to modify
|
Solved in Libbulletjme for |
There was a bug when the capsule rests exactly on the seam, in which case both contacts get filtered out. That was solved by reducing the tolerance by 0.1%, for "less aggressive" filtering. Now there's another bug, which seems to affect sphere shapes only---it shows up in |
An easy solution to the latest bug would be to avoid |
Apparently |
The I have concerns about the performance impact of contact filtering and also the likelihood that these changes to Bullet might expose more bugs, or introduce new ones. Due to these concerns, the fix will appear in a test release (Minie v4.5.0-test1) before being put into production. |
Consider this issue solved with the release of Minie v4.5.0-test1. Future work may include adding contact filtering to compound and GImpact shapes. |
I added contact filtering for Gimpact shapes to Libbulletjme at af2752b033a34a76b38336b173a3ae12858af04b. That fix should be included in the stable release of Minie v4.5 . Contact filtering for compound shapes will require a lot of work, and I don't foresee it happening in 2021. |
Another issue related to contact filtering: #40 |
When a
BetterCharacterController
moves back and forth across the seam between 2 triangles in a flatMeshCollisionShape
, it sometimes makes an unexpected vertical hop.This issue was reported (in JMonkeyEngine) as long ago as December 2013: https://hub.jmonkeyengine.org/t/bettercharactercontrol-acts-like-trampoline/28186 and also as recently as October 2021: https://hub.jmonkeyengine.org/t/bettercharactercontroller-bouncing-off-of-the-ground-while-moving/44991.
Thanks to @jcfandino, we now have a simple test that reproduces the issue. Note that the pauses (
desiredVelocity.zero()
) are necessary to reproduce the issue.The text was updated successfully, but these errors were encountered: