Page 1 of 9

Hey let's switch away from bullet to anything else (discussion)

Posted: 28 Aug 2018, 09:09
by wareya
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:

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;
                    }
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?

Image

...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;
                    }
Image

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)
Image

┻━┻ ︵ ¯\(ツ)/¯ ︵ ┻━┻

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.

Re: Hey let's switch away from bullet to anything else

Posted: 28 Aug 2018, 09:21
by Chris
Hey let's switch away from bullet to anything else
Good luck. I've had nothing but problems with Bullet too, but everything else we've looked at is worse (lacking features, bad performance, isn't updated anymore, or has an incompatible license, or some combination thereof). The only alternative I've seen to Bullet is doing it ourselves, but the headaches involved with that are massive too (especially if we want to add rigid body support, or have scalable performance).
It's entirely possible that, somewhere, in some obscure place in the code I'm working on, bullet is being used incorrectly.
Given my interaction with the Bullet devs, there doesn't seem to be a definition for Bullet "being used [in]correctly". Whenever I asked if something was the right way to do something, they basically said if it works, that's how you do it. And when asking for examples on how to do something, I was just told there is no set way to do something, to find our own way that works.

Re: Hey let's switch away from bullet to anything else

Posted: 28 Aug 2018, 09:28
by wareya
I found a good-looking alternative to Bullet once, but it's written in and for Rust. No idea if there are C or C++ bindings.

https://github.com/sebcrozet/ncollide

Going full custom is an option, but doing collisions with matrix-transformed meshes is a huge pain, and it would be really annoying to figure out how to do continuous cylinder-mesh collisions correctly (I barely figured out how to do continuous sphere-sphere collisions, and I never actually implemented it).

Re: Hey let's switch away from bullet to anything else

Posted: 28 Aug 2018, 09:41
by Ace (SWE)
I've heard good things about Newton (Game) Dynamics; http://newtondynamics.com/forum/newton.php
Zlib licensed so it should be GPL compatible.

Used in - for instance - Frictional Games HPL engine (Penumbra, Amnesia, Soma)

Re: Hey let's switch away from bullet to anything else

Posted: 29 Aug 2018, 00:40
by AnyOldName3
Many mainstream game studios manage to trick Bullet into behaving, so it is possible to make it work. In commercial engines, I only recall ever seeing Havok (which is proprietary, fast, and supposedly less accurate than Bullet), Bullet (which we know is Bullet) or something fully custom (which would be a lot of development effort, potentially better spent submitting patches to Bullet).

Re: Hey let's switch away from bullet to anything else

Posted: 29 Aug 2018, 13:00
by charlieg
Ace (SWE) wrote:
28 Aug 2018, 09:41
I've heard good things about Newton (Game) Dynamics; http://newtondynamics.com/forum/newton.php
Zlib licensed so it should be GPL compatible.

Used in - for instance - Frictional Games HPL engine (Penumbra, Amnesia, Soma)
So the obvious questions:

1) How ingrained is bullet in OpenMW? Is there any attempt at abstraction? How widely used is it?

2) Does the API for Newton Dynamics provide the necessary equivalence to bullet?

3) Is anybody interested in attempting to swap out bullet for Newton Dynamics?

(Or another alternative if there is one.)

Re: Hey let's switch away from bullet to anything else

Posted: 29 Aug 2018, 14:30
by raven
Bullet (and other physics engines) work by resolving collisions, not avoiding them.

You would have to switch away from all the ray/convex casting and use rigid bodies. Zero out angular velocity to keep characters bodies upright (or use a constraint).

Re: Hey let's switch away from bullet to anything else

Posted: 29 Aug 2018, 16:46
by Thunderforge
Ace (SWE) wrote:
28 Aug 2018, 09:41
Zlib licensed so it should be GPL compatible.
Bullet is also zlib, so there is no problem on a license front for using Newton Game Dynamics.

Re: Hey let's switch away from bullet to anything else

Posted: 30 Aug 2018, 13:56
by gus
1) How ingrained is bullet in OpenMW? Is there any attempt at abstraction? How widely used is it?

2) Does the API for Newton Dynamics provide the necessary equivalence to bullet?

3) Is anybody interested in attempting to swap out bullet for Newton Dynamics?
1) it should be abstracted away. At least it was when I wrote it, might have changed though. It is used only for the NPC ccharacter controller and maybe raycasting (I think it was moved to raycasting with the 3d engine instead though, as the collision shape do not match visual shapes).

2) it should. Honestly, the feature used in openmw are really basic and most physics engine should have them. Actually, it might be possible to use Newton character controller directly ( bullet character controller is/was garbage)

3) I guess I could do it if it is seen as worth it? A big chunk of the work was extracting the relevant informations from the NIF files, and that's done, so it shouldn't be too painfull. However, in my experience, all the physics engine I used have their weird quircks. But I must say that bullet documentation is well, inexistant, and Bullet was really annoying to work with. A lot of guesswork, and no information on who is the owner of memory. Had some nice memory leak too :p

Re: Hey let's switch away from bullet to anything else

Posted: 30 Aug 2018, 14:05
by lysol
Now this discussion became interesting suddenly.