inifinite mass and a jitter problem

Started by
15 comments, last by _WeirdCat_ 8 years, 11 months ago

Hi guys,

I have a small issue with impulse based physics. After loading a 2d array of inifinite mass "bricks" (32x32) into a game level and dropping a character with finite mass on top of the bricks everything works fine until the character spans two bricks. That's when the jitter starts.

Code is pairwise AABB vs AABB testing like so


for(unsigned int i=0;i<entities.size();i++){
		for(unsigned int j=i+1;j<entities.size();j++){
			if(entities[i]->rigid->i_mass==0.0f && entities[j]->rigid->i_mass==0.0f)
				continue;
			//check collisions here
					
		}
	}

I don't quite understand what's going on here. All the collision and physics works fine until a third finite mass entity is in contact with two infinate mass entities, whether the two inifinate mass entities are in contact or not.

I did not test this on other shapes, just AABBs.

Could this have something to do with floating point errors perhaps?

Thanks,

Mike

Advertisement

Need more specifics.

What do you mean by 'jitter'?

Post the collision detection/response code as well (or describe it carefully).

o3o

Could it simply be that while the corrective impulse from interacting with brick #1 is exactly enough to counter the finite mass objects perp velocity vector due to movement and gravity, the the impulse caused by interaction with brick #2 does not take this into account and applies the same impulse, resulting in overshoot? I've experienced similar behaviour in some of my innumerable physics experiments.

Cheers,

Mike

Thanks for the responses guys, but I found the problem. It had to do with my SAT test and the penetration distance.

@Mike-How exactly did you solve your problem if you don't mind me asking?

Thanks,

Mike

In my opinion the most robust solution is always to only apply some fraction of the total needed impulse, and then iterate through the velocity-part of the constraint until it reaches an equilibrium.

@h4tt3n could you please be more specific? Do have perhaps any links where I can learn more about this technique?

Thanks,

Mike

If you would post your collision response code I or someone else might be able to tell you specifically how to improve it. Basically what you do is for each loop (1) pre-compute all object distances, normalized vectors, overlaps, and the exact impulse needed to move colliding objects apart. (2) Apply a fraction of that impulse + a velocity dependant damping impulse, resulting in new object velocities, but do *not* update object position. Repeat (2), recycling all data computed in (1) but with re-computed damping impulses until an acceptable global equilibrium is reached. Depending on the setup and your expectations this could be done in perhaps 4 - 16 iterations. (3) Update position and go back to (1).

Cheers,

Mike

Inside the main update loop


		for(ui i=0;i<bodies.size();i++)
			bodies[i]->integrate(1.0f/(float)FPS);
		
	
		for(ui i=0;i<bodies.size();i++){
			for(ui j=i+1;j<bodies.size();j++){
				if(bodies[i]->i_mass==0.0f && bodies[j]->i_mass==0.0f)
					continue;
				ContactInfo ci;
				
				collisionTest collide=coll_matrix[bodies[i]->type][bodies[j]->type];
				if(collide(bodies[i],bodies[j],ci)){
					Contact contact(bodies[i],bodies[j],ci);
					contacts.push_back(contact);

					
				}
				
			}		
		}
		
		for(ui i=0;i<contacts.size();i++)
			contacts[i].solvePenetration();

		for(ui iter=0;iter<iterations;iter++)
			for(ui i=0;i<contacts.size();i++)
				contacts[i].solveImpulse();

Penetration method


void Contact::solvePenetration(){
	float tot_i_mass=b1->i_mass+b2->i_mass;

	b1->center-=ci.normal*b1->i_mass/(tot_i_mass)*ci.pen;
	b2->center+=ci.normal*b2->i_mass/(tot_i_mass)*ci.pen;
	
}

and the impulse solve method


void Contact::solveImpulse(){
	Vec2 rel_vel=b2->vel-b1->vel;
	float sep_vel=rel_vel.dot(ci.normal);;
	if(sep_vel>0.0f)
		return;
	float tot_i_mass=b1->i_mass+b2->i_mass;

	b1->vel+=ci.normal*sep_vel*((b1->i_mass/(tot_i_mass))*(1+ci.e));
	b2->vel-=ci.normal*sep_vel*((b2->i_mass/(tot_i_mass))*(1+ci.e));

}

Okay, I'll give it a try. Just please don't expect me to deliver a ready-made code snippet that can be pasted directly into your program. First, I'd like to know a little more about the iterations going on here:


for(ui iter=0;iter<iterations;iter++)
			for(ui i=0;i<contacts.size();i++)
				contacts[i].solveImpulse();

This seems to be doing exactly the kind of velocity-level iteration that I recommended earlier. What change in behaviour do you experience when changing the number of iterations? Especially, what happens when you have a lot of interacting bodies either stacked or pulling each other via constraints?

Cheers,

Mike

Hi Mike,

What change in behaviour do you experience when changing the number of iterations?

Visibly none

what happens when you have a lot of interacting bodies either stacked or pulling each other via constraints?

That depends.

When I have an AABB with finite mass, resting (more specifically after falling, ie due to gravity) onto 2 or more infinetly massed AABBs, the finite mass AABB starts to jitter.

Now, if I have an AABB with finite mass resting on one infinitelly massed AABB, there's no jitter and the object is settled.

If I have many objects resting on top of each other, especially ones with bigger masses resting on smaller masses I get jitters, but that's usually if there's more than 3 or 4. For my game purposes this is not a concern as I am not attempting to do a physical simulation.

I strongly suspect that the issue is what you told me about earlier,

Could it simply be that while the corrective impulse from interacting with brick #1 is exactly enough to counter the finite mass objects perp velocity vector due to movement and gravity, the the impulse caused by interaction with brick #2 does not take this into account and applies the same impulse, resulting in overshoot?

However, I am not exactly sure how to solve this problem. I tried two different SAT algos, and one works better than the other, but the issue persists.

Thanks,

Mike

This topic is closed to new replies.

Advertisement