Squirrely dynamic bodies resting on flat static surface (video)

User avatar
goosesensor
Posts: 11
Joined: Tue Jul 17, 2018 3:50 am
Location: Santa Cruz, CA

Squirrely dynamic bodies resting on flat static surface (video)

Post by goosesensor » Wed Jul 18, 2018 12:59 am

I'm having some issues with squirrely dynamic bodies attempting to rest on a flat static body.

I have a static "ground plane," 40x40 units, that I've tried constructing a number of different ways:

- btBoxShape of varying thickness
- btConvexHullShape created from a plane geometry
- btBvhTriangleMeshShape created from a plane geometry with varying number of subdivisions.

In my test, I create a number of small dynamic bodies (.5 - 1.5 units on longest axis) using btConvexHullShape, reduced via btShapeHull, and drop them from the air onto the static ground body.

The simulation seems to act normally until it's time for the dynamic bodies to come to rest on the ground. They often do not lie flat on the surface and do strange things like spinning indefinitely on their corners. See gifs below.

Image
Image


I've done a lot of tweaking with friction, restitution, sleeping thresholds, damping, etc on the dynamic objects and on the static ground. Some combinations can somewhat mitigate the issues, but all have undesirable tradeoffs. The closest I've found to making things behave correctly is setting the mass of the dynamic objects to something very high (500+), but this too has undesirable side effects.

Mass == 2000:

Image


What am I doing wrong?


Some other info:

The small grid marks on the ground are 1 unit increments
Timestep is 1.0/120.0 — have tried much smaller
Gravity is -9.8
Using btBoxShape instead of btConvexHullShape for the dynamic objects exhibits the same behavior, only to a lesser severity.

PcChip
Posts: 33
Joined: Sun May 20, 2018 3:09 pm

Re: Squirrely dynamic bodies resting on flat static surface (video)

Post by PcChip » Thu Jul 19, 2018 2:23 am

try this:

ground:
restitution = 0.0
friction = 1.0

objects:
restitution = 0.3
friction = 0.5

make sure you don't have sleeping disabled for the objects (make sure you did not myRigidBody->setActivationState(DISABLE_DEACTIVATION); )

User avatar
goosesensor
Posts: 11
Joined: Tue Jul 17, 2018 3:50 am
Location: Santa Cruz, CA

Re: Squirrely dynamic bodies resting on flat static surface (video)

Post by goosesensor » Thu Jul 19, 2018 3:47 am

Thanks chip.

Generally activiationState gets set to ACTIVE_TAG when the rigid body is created in my code -- I disabled it to leave it as Bullet's default, then changed the friction and restitution settings as you recommended. Here is the result:

Image

Mwni
Posts: 9
Joined: Thu Jul 12, 2018 4:43 pm

Re: Squirrely dynamic bodies resting on flat static surface (video)

Post by Mwni » Thu Jul 19, 2018 3:09 pm

I had the same problem with cylinders that were inexplicably rolling around once on the floor.
Have you tried increasing the solver iteration count to something higher than the default of 10?

Code: Select all

world->getSolverInfo()->m_numIterations = 30

User avatar
goosesensor
Posts: 11
Joined: Tue Jul 17, 2018 3:50 am
Location: Santa Cruz, CA

Re: Squirrely dynamic bodies resting on flat static surface (video)

Post by goosesensor » Thu Jul 19, 2018 11:49 pm

Hi Mwni,

I played around with m_numIterations a bit. Setting to 0 results in no dynamic<->static interaction as expected, but anything larger seems to have no effect.

m_numIterations = 0:

Image

m_numIterations = 10:

Image

m_numIterations = 100:

Image

User avatar
goosesensor
Posts: 11
Joined: Tue Jul 17, 2018 3:50 am
Location: Santa Cruz, CA

Re: Squirrely dynamic bodies resting on flat static surface (video)

Post by goosesensor » Fri Jul 20, 2018 12:37 am

Another example using boxes. The spinning phenomenon is a lot less common, but boxes often don't lay flat on the ground. btBoxShape, mass=1

Image

PcChip
Posts: 33
Joined: Sun May 20, 2018 3:09 pm

Re: Squirrely dynamic bodies resting on flat static surface (video)

Post by PcChip » Fri Jul 20, 2018 1:39 am

I have an "opengl / bullet physics playground" project in visual studio that I try new things in, so the code is very hacky and ugly, but this is what works normally for me:

Code: Select all

	// Build the broadphase
	//btBroadphaseInterface* broadphase = new btAxisSweep3(btVector3(0,-3,0), btVector3(TERRAIN_SIZE,5,TERRAIN_SIZE));
	btBroadphaseInterface* broadphase = new btDbvtBroadphase();
	// Set up the collision configuration and dispatcher
	btDefaultCollisionConfiguration* collisionConfiguration = new btDefaultCollisionConfiguration();
	btCollisionDispatcher* dispatcher = new btCollisionDispatcher(collisionConfiguration);

	// The actual physics solver
	btSequentialImpulseConstraintSolver* solver = new btSequentialImpulseConstraintSolver;

	// The world.
	dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher, broadphase, solver, collisionConfiguration);
	dynamicsWorld->setGravity(btVector3(0, -9.8, 0));

	PhysicsDebugDraw* m_debugDraw = new PhysicsDebugDraw();
	dynamicsWorld->setDebugDrawer(m_debugDraw);


	btContactSolverInfo& info = dynamicsWorld->getSolverInfo();
	info.m_numIterations = 4;

Code: Select all

	for (int i = 0; i < 20; i++)
	{

		btScalar mass = 1;
		btVector3 fallInertia((rand() % 4)-1, (rand() % 3)-2, (rand() % 6)-3);
		fallShape->calculateLocalInertia(mass, fallInertia);
		fallMotionStates.emplace_back(new btDefaultMotionState(btTransform(btQuaternion(rand()%3, rand() % 3, rand() % 3, 1), btVector3(rand()%20+2, rand() % 5 + 10, rand() % 20+2))));
		btRigidBody::btRigidBodyConstructionInfo fallRigidBodyCI(mass, fallMotionStates[i], fallShape, fallInertia);
		fallRigidBodyCI.m_restitution = 0.2;
		fallRigidBodyCI.m_friction = 1;
		fallingRigidBodies.emplace_back(new btRigidBody(fallRigidBodyCI));
		fallingRigidBodies[i]->setUserPointer((void*)i);
		dynamicsWorld->addRigidBody(fallingRigidBodies[i]);
		//fallingRigidBodies[i]->setCcdMotionThreshold(0.1);
	}

User avatar
goosesensor
Posts: 11
Joined: Tue Jul 17, 2018 3:50 am
Location: Santa Cruz, CA

Re: Squirrely dynamic bodies resting on flat static surface (video)

Post by goosesensor » Fri Jul 20, 2018 2:38 am

Chip, my code appears to do essentially all the same things as yours, except that I calculate localInertia like this:

btVector3 localInertia = {0, 0, 0}
collisionShape->calculateLocalInertia(mass, localInertia);

Note sure if that's correct...


If I try it with your random method of calculating localInertia, I get boxes that lay nice and flat, but don't rotate, and fruit that never loses the small amount of angular velocity I assign to it when it first enters the world.

Image

Mwni
Posts: 9
Joined: Thu Jul 12, 2018 4:43 pm

Re: Squirrely dynamic bodies resting on flat static surface (video)

Post by Mwni » Fri Jul 20, 2018 7:20 am

Now, this is really strange. Box shapes atleast have always worked very well for me...

The last guess I could make is to increase the substeps for the simulation steps.

Code: Select all

world->stepSimulation(1/60, 5, 1/300)
This for example subdivides 60 Hz steps into 5 substeps. I found this has drastically improved the stability of constraints. Drawback is that it most likely increases performance cost alot.

User avatar
goosesensor
Posts: 11
Joined: Tue Jul 17, 2018 3:50 am
Location: Santa Cruz, CA

Re: Squirrely dynamic bodies resting on flat static surface (video)

Post by goosesensor » Fri Jul 20, 2018 8:56 pm

Hi Mwni,

Unfortunately timestep & number of substeps don't appear to be the issue.

Since the simulation appears to run much more stably with very high masses (10,000x scale) I'm tempted to just move forward with that.

I'm wondering what types unforeseen issues scaling the mass for all my objects may present in the future. Obviously applied forces and torques need to be adjusted. Perhaps restitution will need tweaking as well. What adjustments might need to be made?

PcChip
Posts: 33
Joined: Sun May 20, 2018 3:09 pm

Re: Squirrely dynamic bodies resting on flat static surface (video)

Post by PcChip » Sat Jul 21, 2018 2:04 am

this is how I call stepSimulation (in both my hacky playground project, and my actual hobby game project)

Code: Select all

	
		simTime = glfwGetTime();
		dynamicsWorld->stepSimulation(deltaTime, 20, 1./100);
		dynamicsWorld->synchronizeMotionStates();  //if I remember correctly this was for the btRaycastVehicle's wheels
		if (drawDebug)
		{
			dynamicsWorld->debugDrawWorld();
		}
		simTime = (glfwGetTime() - simTime);


I would suggest starting a new project, compiling a fresh version of Bullet from github, and testing there with a basic bare-bones approach

User avatar
goosesensor
Posts: 11
Joined: Tue Jul 17, 2018 3:50 am
Location: Santa Cruz, CA

Re: Squirrely dynamic bodies resting on flat static surface (video)

Post by goosesensor » Sat Jul 21, 2018 2:13 am

A little more info...

Everything with configuring the world, creating shapes and rigid bodies, and configuring those objects all seems to be by the book...

There are only two things that I am somewhat concerned about:

1. For resource management and scene graph synchronization purposes, I'm storing bt objects (btRigiBody, bt...Shape, etc) in std::maps, which map them to their associated higher-level game objects/nodes. I am not making any use of btAlignedObjectArray. It's my understanding that this is okay as long as I don't use SSE (I'm not -- I was getting crashes every once in a while in a Bullet SSE-enabled function when converting OpenGL matrices to BT matrices and vise-versa. Commenting out the SSE code to enable the regular user code seemed to fix the issue.)

2. I can't say why, but my simulation stepping seems a little smelly. It essentially looks like this:

btWorld->stepSimulation(deltaSeconds, 10, 1.0/120.0);

My test (gifs posted above) is running somewhere in the neighborhood of 300-400fps, so deltaSeconds is between 0.0025 and 0.0033 for any given step.

User avatar
goosesensor
Posts: 11
Joined: Tue Jul 17, 2018 3:50 am
Location: Santa Cruz, CA

Re: Squirrely dynamic bodies resting on flat static surface (video)

Post by goosesensor » Sat Jul 21, 2018 2:15 am

Thanks Chip. Probably a good idea.

I think I will try managing the physics simulation from the "client side" of my framework (as opposed to opaquely through a wrapper) first, then start from scratch. Weird stuff.
Last edited by goosesensor on Sat Jul 21, 2018 2:42 am, edited 1 time in total.

PcChip
Posts: 33
Joined: Sun May 20, 2018 3:09 pm

Re: Squirrely dynamic bodies resting on flat static surface (video)

Post by PcChip » Sat Jul 21, 2018 2:34 am

regarding bullet to opengl, I stole this from a forum somewhere

Code: Select all

glm::mat4 bulletToGlm(const btTransform& t)
{
glm::mat4 m(0);
const btMatrix3x3& basis = t.getBasis();
// rotation
for (int r = 0; r < 3; r++)
{
for (int c = 0; c < 3; c++)
{
m[c][r] = basis[r][c];
}
}
// traslation
btVector3 origin = t.getOrigin();
m[3][0] = origin.getX();
m[3][1] = origin.getY();
m[3][2] = origin.getZ();
// unit scale
m[0][3] = 0.0f;
m[1][3] = 0.0f;
m[2][3] = 0.0f;
m[3][3] = 1.0f;
return m;
}

User avatar
goosesensor
Posts: 11
Joined: Tue Jul 17, 2018 3:50 am
Location: Santa Cruz, CA

Re: Squirrely dynamic bodies resting on flat static surface (video)

Post by goosesensor » Sat Jul 21, 2018 2:45 am

Thanks... plugged that in to replace my existing function:

mat4 GLMMat4FromBTTransform(const btTransform& from) {
mat4 glmMat;
from.getOpenGLMatrix(value_ptr(glmMat));
return glmMat;
}

Exacto-el-same-o. :roll:

Post Reply