Jump to content
  • Advertisement
Sign in to follow this  
too_many_stars

inifinite mass and a jitter problem

This topic is 1328 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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

Share this post


Link to post
Share on other sites
Advertisement

Need more specifics.

 

What do you mean by 'jitter'?

 

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

Share this post


Link to post
Share on other sites

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

Edited by h4tt3n

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

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. 

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

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

}

Share this post


Link to post
Share on other sites

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

Edited by h4tt3n

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

GameDev.net is your game development community. Create an account for your GameDev Portfolio and participate in the largest developer community in the games industry.

Sign me up!