RigidBodys remain asleep when ground static body is removed

Post Reply
Slight0
Posts: 11
Joined: Wed Nov 19, 2014 12:42 am

RigidBodys remain asleep when ground static body is removed

Post by Slight0 »

I'm integrating bullet physics into Unity.

In my test, I create some simple rigidbody cubes that are launched ontop of a static BvhTriangleMeshShape rigidbody. When the cubes come to rest and become inactive, removing the underlying triangle mesh static body causes them to float. I figured bullet should automatically wake those objects on top of the removed object?

Any ideas what's going on? Is this something I'm supposed to handle explicitly? I'm using the latest trunk source.
Flix
Posts: 456
Joined: Tue Dec 25, 2007 1:06 pm

Re: RigidBodys remain asleep when ground static body is remo

Post by Flix »

Slight0 wrote:Is this something I'm supposed to handle explicitly?
In short, yes.
Slight0
Posts: 11
Joined: Wed Nov 19, 2014 12:42 am

Re: RigidBodys remain asleep when ground static body is remo

Post by Slight0 »

Flix wrote:
Slight0 wrote:Is this something I'm supposed to handle explicitly?
In short, yes.
Why? Is there ever a case when you want objects to float when the bottom object is removed?

If what you say is true, and this is not a bug, what's the ideal way to awaken these objects?
c6burns
Posts: 149
Joined: Fri May 24, 2013 6:08 am

Re: RigidBodys remain asleep when ground static body is remo

Post by c6burns »

You are expecting a dynamic reaction from a static object. I am assuming there is no check in the broadphase for changes that require waking up bodies in contact with such an object. That does not surprise me. It's not often the earth disappears from under my feet.

The typical scenario is sleeping non-static bodies getting woken up by active non-static bodies (eg. a soccer ball at rest suddenly being kicked by my foot). That will be handled for you automatically, and there's even a comment to that effect in btRigidBody.h.
Slight0
Posts: 11
Joined: Wed Nov 19, 2014 12:42 am

Re: RigidBodys remain asleep when ground static body is remo

Post by Slight0 »

c6burns wrote:You are expecting a dynamic reaction from a static object.
Huh? I'm expecting that, after calling CollisionWorld->RemoveCollisionObject() that, yes, it iterates over collision pairs it has with non-static rigidbodys and awakens them. Be that directly as I call RemoveCollisionObject or during the next simulation step.

How is this an outlandish expectation?
c6burns wrote:I am assuming there is no check in the broadphase for changes that require waking up bodies in contact with such an object. That does not surprise me. It's not often the earth disappears from under my feet.
That's because you don't live in a video game.
c6burns wrote:The typical scenario is sleeping non-static bodies getting woken up by active non-static bodies (eg. a soccer ball at rest suddenly being kicked by my foot). That will be handled for you automatically, and there's even a comment to that effect in btRigidBody.h.
I'm fairly certain if you remove a sleeping non-static rigidbody, it will not awaken sleeping rigidbodys stacked on top of it. I will test this in a moment.

Edit: Yep, if I stack some rigidbody cubes with mass 1 on top of eachother then remove the bottom one, they all just float in the air until acted on... This seems like an obvious oversight.
c6burns
Posts: 149
Joined: Fri May 24, 2013 6:08 am

Re: RigidBodys remain asleep when ground static body is remo

Post by c6burns »

You can win the argument, but you're not going to be closer to the behaviour you require for your simulation :lol:

EDIT: Ehhh OK I'll admit re-reading this I look kinda like a jerk. I didn't mean to be a jerk. My point was that removing sleeping bodies from the world is likely not a common use case. It's not one that came up in any of my simulations.

As for how you can solve this problem, as I have no interest in arguing whether or not I live in a video game (you can't prove I dont mannnnnnn). You can loop over the manifolds and wake up any bodies that are in contact with the one you are removing ... that's how I would do it. Someone else may have a better suggestion.

Example:

Code: Select all

int numManifolds = m_dynamicsWorld->getDispatcher()->getNumManifolds();

for (int i=0; i  < numManifolds; i++) {
	btPersistentManifold* manifold = getDynamicsWorld()->getDispatcher()->getManifoldByIndexInternal(i);
	if (!manifold->getNumContacts()) continue;

	float dist = 1;
	int minIndex = -1;
	for (int v=0;v<manifold->getNumContacts();v++) {
		if (dist > manifold->getContactPoint(v).getDistance()) {
			dist = manifold->getContactPoint(v).getDistance();
			minIndex = v;
		}
	}
	if (dist > 0.) continue;
		
	btCollisionObject* colObj0 = (btCollisionObject*)manifold->getBody0();
	btCollisionObject* colObj1 = (btCollisionObject*)manifold->getBody1();
	btRigidBody* body0 = btRigidBody::upcast(colObj0);
	btRigidBody* body1 = btRigidBody::upcast(colObj1);
	if (body0 == myGroundBody) {
		body1->activate();
	} else if (body1 == myGroundBody) {
		body0->activate();
	}
}
// remove myGroundBody now
The broadphase should handle activating the rest of the bodies which are now touching newly activated bodies (like if you have a stack of boxes on a ground which you just removed)

PS - Are you going to move to Unity 5 when it's released?
Slight0
Posts: 11
Joined: Wed Nov 19, 2014 12:42 am

Re: RigidBodys remain asleep when ground static body is remo

Post by Slight0 »

c6burns wrote: EDIT: Ehhh OK I'll admit re-reading this I look kinda like a jerk. I didn't mean to be a jerk.
Yeah, you big meanie! :wink:
c6burns wrote: My point was that removing sleeping bodies from the world is likely not a common use case. It's not one that came up in any of my simulations.
Well consider a laser weapon that is capable of instantly destroying a physics object for example. That's not my use case, just off the top. My case is that I need to regenerate the terrain.
c6burns wrote: As for how you can solve this problem, as I have no interest in arguing whether or not I live in a video game (you can't prove I dont mannnnnnn). You can loop over the manifolds and wake up any bodies that are in contact with the one you are removing ... that's how I would do it. Someone else may have a better suggestion.
I appreciate the example. I ended up solving it then by modifying RemoveCollisionObject and doing something similar.

Is it worth submitting a commit to the repository to include this behavior? In my mind it's a bug, but you say it's not a common use case so ¯\_(ツ)_/¯.
c6burns wrote: PS - Are you going to move to Unity 5 when it's released?
Yeah I'm pretty excited about it. A lot of great features including much needed graphics updates, a better shader pipeline, improved editor/profiler, and a more up to date audio solution. Plus, they're updating PhysX but, unless I can build meshes on a separate thread, it'll be useless to me. The thing I really want is an updated version of Mono that supports .Net 4.0 features and classes and also AOT compilation. However, there's been a lot of ambiguity surrounding this and if they are even going to continue using mono... I hope that gets sorted because the rest of Unity looks great.
c6burns
Posts: 149
Joined: Fri May 24, 2013 6:08 am

Re: RigidBodys remain asleep when ground static body is remo

Post by c6burns »

I don't see it as a bug, but that might just be me. You can always submit a patch, but I would make it an optional behaviour.

You definitely can do what you are doing with PhysX but in terms of Unity's implementation I couldn't say.
Slight0
Posts: 11
Joined: Wed Nov 19, 2014 12:42 am

Re: RigidBodys remain asleep when ground static body is remo

Post by Slight0 »

c6burns wrote:I don't see it as a bug, but that might just be me. You can always submit a patch, but I would make it an optional behaviour.
Well I'm curious as to what you thought of the laser destroying the box example. How would you handle such a case? For example in HL2, which uses Havok, some physics props are destructible. Upon destruction, props resting on the destroyed object are awakened and simulated as expected.
c6burns wrote:You definitely can do what you are doing with PhysX but in terms of Unity's implementation I couldn't say.
Yeah, Unity arbitrarily restricts every object derived from UnityEngine.Object to be inaccessible outside the main thread. I should also note that bullet is faster than Unity's current PhysX implementation for both physics simulation and collision mesh generation. Probably because PhysX is optimized for the GPU and CPU support was sort of retrofitted. Can't speak for the latest PhysX though.
Last edited by Slight0 on Fri Dec 05, 2014 1:43 am, edited 1 time in total.
c6burns
Posts: 149
Joined: Fri May 24, 2013 6:08 am

Re: RigidBodys remain asleep when ground static body is remo

Post by c6burns »

Actually, it's a common misconception that PhysX SDK is only optimized for hardware support ... though it is true that if we are talking about 2.8 it still contains the remnants of Ageia's code. I haven't really worked with 2.x so maybe it is true. 3.x represents a massive refactoring that is highly optimized for CPU and threading. Its major competitor among PhysX middleware would be Havok's Physics component. We are talking about middleware that gets licensed out for 5 figures, with a team of people working on it, and scores of big name studios integrating it. Those studios aren't just crossing their fingers that people without PhysX hardware don't notice any performance issues.

How Unity implements PhysX I honestly have no idea ... probably as a component since it's a component/entity engine ... and yeah you probably don't have an interface to really do anything with it except attach the component to an entity and choose some stuff in dropdowns. That's Unity for you :D

As far as waking up bodies that get removed, it's not a bad thing. All I am saying is if you make a patch, make it an optional behaviour because otherwise it could have unknown sideaffects on someone else's implementation. Just my 2 cents.
Post Reply