Sorry, perhaps I should have mentioned I'm using the C# wrapper
BulletSharpPInvoke (repository link)
c6burns wrote:I don't understand where that OnDestroy method comes from. Are you using some bullet implementation for Unity where that exists? Also what does "dispose" mean? Free up the memory? Or perform all of the operations required to remove the btRigidBody from the world *and then* free up the memory? If the latter then no, that's not thread safe. You shouldn't change anything about the world while it is being stepped in another thread.
Anyway, what is actually happening inside those methods being called in OnDestroy is unclear.
I'm using my own implementation for Unity that uses BulletSharpPInvoke to call into the Bullet API. OnDestroy is a callback from Unity that is called when a GameObject is being destroyed and removed from memory; a destructor.
The first function that gets called is RemoveCollisionObject which is
defined here. That just calls
AlignedCollisionObjectArray.Remove (Upon further inspection this looks to be the culprit, I'm not sure if it's the brute force searching method they use or the actual API calls, but something here is taking over a millisecond to complete when there are over a thousand objects in the world.)
The second function is MotionState.Dispose
defined here.
The last is RigidBody.Dispose which is actually CollisionObject.Dipose
defined here.
In those links, you'll find calls to things like
btCollisionObject_delete and
btMotionState_delete which are really just C++ wrappers that call delete obj.
Basroil wrote:Deleting rigid bodies shouldn't take 1ms even on an old 386, there's definitely something going on that you can improve on. My personal guess is that your profiler is just mistaken (removing and deleting should be in the micro-second level rather than millisecond), though "destroy" function might be at fault if it's not the profiler.
Bodies must be removed only when the world is not being stepped, so that part must be done sequentially after stepping ends and before the next. After that you can take care of cleanup whenever/whereever you like.
I figured it shouldn't take more than a few microseconds. The profiler is just a basic wrapper for .NET's StopWatch class which is pretty accurate. It is very capable of measuring the microsecond level (those "ticks" are the number of elapsed hardware timer ticks since the start of the stopwatch). I've used StopWatch a lot to measure very minute tasks.
xexuxjy wrote:Out of interest , how have you integrated bullet into Unity, is it using Andres Traks wrapper, or a pure managed code version. Regardless, i'd be very surprised if it was thread safe. I would also suspect that SimpleProfiler really won't give you very good timings for such a small operation.
Yes, as I linked above, I'm using BulletSharpPInvoke by Andres Traks. Like I mentioned above, SimpleProfiler just wraps StopWatch which is capable of measuring below the millisecond level accurately. It rounds milliseconds down, not up. ~10,000 ticks = 1ms on my machine.
I did some more detailed profiling and found that World.RemoveCollisionObject is taking up the most time.
[11/19/2014] 5:37:26 PM BtRigidBody Destroy; World.RemoveCollisionObject: 1ms (15316 tick(s))
[11/19/2014] 5:37:26 PM BtRigidBody Destroy; MotionState.Dispose: 0ms (28 tick(s))
[11/19/2014] 5:37:26 PM BtRigidBody Destroy; RigidBody.Dispose: 0ms (28 tick(s))
[11/19/2014] 5:37:26 PM BtRigidBody Destroy; World.RemoveCollisionObject: 1ms (12782 tick(s))
[11/19/2014] 5:37:26 PM BtRigidBody Destroy; MotionState.Dispose: 0ms (28 tick(s))
[11/19/2014] 5:37:26 PM BtRigidBody Destroy; RigidBody.Dispose: 0ms (33 tick(s))
[11/19/2014] 5:37:26 PM BtRigidBody Destroy; World.RemoveCollisionObject: 1ms (13020 tick(s))
[11/19/2014] 5:37:26 PM BtRigidBody Destroy; MotionState.Dispose: 0ms (33 tick(s))
[11/19/2014] 5:37:26 PM BtRigidBody Destroy; RigidBody.Dispose: 0ms (28 tick(s))
[11/19/2014] 5:37:26 PM BtRigidBody Destroy; World.RemoveCollisionObject: 1ms (12647 tick(s))
[11/19/2014] 5:37:26 PM BtRigidBody Destroy; MotionState.Dispose: 0ms (28 tick(s))
[11/19/2014] 5:37:26 PM BtRigidBody Destroy; RigidBody.Dispose: 0ms (28 tick(s))
Is this typical? I'd like to note that I have about 1331 BvhTriangleMesh+RigidBody objects in the world all of which are static (mass = 0).