Hey let's switch away from bullet to anything else (discussion)
Posted: 28 Aug 2018, 09:09
After spending several hours figuring out how to write the most basic possible wrapper function for bullet's discrete collision testing function, btCollisionWorld::contactTest, I tested whether the actor ended up in the world after the movement solver ran, and much to my surprise, it often did! Why, how weird. Let's add tons of printf debugging to see where it happens:
Wait, what? Why did I write that? Surely that print statement can't actually get triggered. I mean, I'm instantly teleporting to mEndPos, which should be exactly the location that bullet is spitting out, right?
...Weird. Okay, maybe there's some weird numerical instability happening somewhere.
So if I add a safety margin to the original block it should go away, right?
Whyyyy? Hooow? Okay, okay, I'll turn the safety margin up to like 0.5, okay? That should get rid of the problem for sure, right? So I did that and tried to reproduce it, and it was less likely, but after not even a minute of running into funny-shaped walls...
┻━┻ ︵ ¯\(ツ)/¯ ︵ ┻━┻
Nope, not doing this anymore.
----------
It's entirely possible that, somewhere, in some obscure place in the code I'm working on, bullet is being used incorrectly. But if it's THAT hard to use right, OpenMW shouldn't be using it. And if the code I'm working with right now is using it correctly, then it's wrong, and we shouldn't use it if it's wrong.
It's also possible that OpenMW, or at least my development environment, is using an outdated version of bullet, but if it is, it's not THAT outdated, and having problems like this at such a mature stage of development is extremely dirty.
Code: Select all
// get tracing information between the current and desired position
tracer.doTrace(colobj, newPosition, nextpos, collisionWorld);
// if there is no obstruction, move to the new position and break
if(!tracer.mHitObject)
{
bool startTouch = contactTest(physicActor, newPosition, collisionWorld);
newPosition = tracer.mEndPos; // mEndPos is exactly equal to nextpos if tracer.mHitObject is null
bool endTouch = contactTest(physicActor, newPosition, collisionWorld);
if(endTouch && !startTouch)
std::cerr << "entered world A\n";
break;
}
...Weird. Okay, maybe there's some weird numerical instability happening somewhere.
So if I add a safety margin to the original block it should go away, right?
Code: Select all
// earlier in the code: osg::Vec3f nextpos = newPosition + velocity * remainingTime;
auto direction = velocity;
direction.normalize();
// get tracing information between the current and desired position
tracer.doTrace(colobj, newPosition, nextpos + direction*sSafetyMargin, collisionWorld);
// if there is no obstruction, move to the new position and break
if(!tracer.mHitObject)
{
bool startTouch = contactTest(physicActor, newPosition, collisionWorld);
newPosition = tracer.mEndPos - direction*sSafetyMargin;
bool endTouch = contactTest(physicActor, newPosition, collisionWorld);
if(endTouch && !startTouch)
std::cerr << "entered world A\n";
break;
}
Whyyyy? Hooow? Okay, okay, I'll turn the safety margin up to like 0.5, okay? That should get rid of the problem for sure, right? So I did that and tried to reproduce it, and it was less likely, but after not even a minute of running into funny-shaped walls...
Code: Select all
static const float sSafetyMargin = 0.5f; // How far to stay away from any geometry we collide with (so that we don't go slightly inside of it and end up with bad collision tracing data)
┻━┻ ︵ ¯\(ツ)/¯ ︵ ┻━┻
Nope, not doing this anymore.
----------
It's entirely possible that, somewhere, in some obscure place in the code I'm working on, bullet is being used incorrectly. But if it's THAT hard to use right, OpenMW shouldn't be using it. And if the code I'm working with right now is using it correctly, then it's wrong, and we shouldn't use it if it's wrong.
It's also possible that OpenMW, or at least my development environment, is using an outdated version of bullet, but if it is, it's not THAT outdated, and having problems like this at such a mature stage of development is extremely dirty.