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

## Recommended Posts

##### Share on other sites
What I don't get is that you had it working in the original thread right?
All the methods we discussed until now do work and provide acceptable friction.

I think that you should really double-check all you math code and trace values around because you may very well have a nasty bug hidden somewhere. Displaying forces and impulses at the contact point would also help the lisibility but visual debugging only goes so far so checking hard values is certainly required now.

There's not much more I can tell. It's working in my code, the math are the same, it should work in yours... really! ;)
Just come to think of it but Oliii must have done and released that a hundred times already so did you check his code? How is he doing it?

Courage!

edit: The Physics for Game Developer friction example has a typo in its sample code. The friction component is applied positively to both bodies, you don't want that :). But even with that modified I could never get his approach to work with stacks. Single objects kind of work but stacks badly blew up.

[Edited by - b34r on July 30, 2005 8:40:36 AM]

##### Share on other sites
"What I don't get is that you had it working in the original thread right?
All the methods we discussed until now do work and provide acceptable friction."

That's what I thought, too. But I realised that it was not working in many cases, so there had to be a big bug in it.
Then I gave up trying around and startet to think about the problem (coding something you don't understand isn't a very good idea)... I also looked at example code (oliii) but until now I didnt get the point ;-)

##### Share on other sites
I finally managed to put friction in. here's the demo: Friction demo

s = start/stop
r = reset
t = single step

i had no time to make several tests yet. The friction is based on the formula's on a slide from Bridson. I think it's the one on MrRowls page but it could also be a newer slide.

##### Share on other sites
Hi Airo!
Sure that's working correctly? At the beginning the blocks do a strange slide-hop ;-)

Here's what mine is currently looking like: (press SPACE to go)
Click me!
In this scene eveything's fine...but sadly in other scenes everything's still screwed up :-(
(I hate friction) :P

##### Share on other sites
could you post the time at which the hop occurs? i didn;t see anything strange but i'm biased, i so badly want it to look good after all the failed attempts ;)

edit: it appears your right, i'm gaining energy there.

Updated friction demo

the slides are from here http://www.rowlhouse.co.uk and then the jiglib thing, there's a link to a slide. I printed out the slides so I don;t have another direct link.

I've seen that demo. It looks nice. Can you stop the blob from rolling/sliding?

[Edited by - Airo on August 4, 2005 2:41:32 AM]

##### Share on other sites
Ahh :-) Your new demo works fine! Respect!
I'll have a look at those papers...(my implementation is worse than I thought) ;-)

Good luck!

##### Share on other sites
ok I had a lot of trouble with friction as well when I first did this so I thought id help you out a bit more.

Basically this is my implantation of MrRawl’s friction idea, its ripped out of other code so sorry if its hard to follow:

 /*Friction - At each collision point the normal impulse has been calculated.Applying friction at each point is treated like a collision - calculate the impulse required to prevent the two points on the two objects diverging.Now compare this tangential friction impulse to staticFriction*normalImpulse. If it's greater, then friction won't be able to stop the objects, so apply dynamicFriction*normalImpulse in the tangential direction. If it's less then apply the originally calculated tangential friction.*/CRigidBody* m_pBodyA;CRigidBody* m_pBodyB;BOOL m_bMovable[2];Vector2 m_vPointA[2]; //collision points Vector2 m_vPointB[2];BOOL CCollisionSolver::_SolvePoint(float CoR, I32 n)	{		Vector2 resVelocity = Vector2(0,0);		Vector2 cp1;		Vector2 cp1Perp;		if(m_bMovable[0])		{			cp1 =   m_vPointA[n] - m_pBodyA->m_vPosition;			cp1Perp = Vector2(-cp1.y(), cp1.x());			resVelocity = m_pBodyA->m_vVelocity-(cp1Perp*m_pBodyA->m_fRotaionalVelocity);		}		Vector2 cp2;		Vector2 cp2Perp;		if(m_bMovable[1])		{			cp2 =  m_vPointB[n] - m_pBodyB->m_vPosition;			cp2Perp = Vector2(-cp2.y(), cp2.x());			resVelocity -= m_pBodyB->m_vVelocity-(cp2Perp*m_pBodyB->m_fRotaionalVelocity);		}		float surfaceReletive = resVelocity*m_vCollisionNormal;		if(surfaceReletive > 0) //moving apart			return false;		float top = (-CoR * surfaceReletive) - surfaceReletive;		float botA;				if(m_bMovable[0])		{			botA = m_pBodyA->m_fInvMass;			float rAPdotN = cp1^m_vCollisionNormal;			botA += ((rAPdotN*rAPdotN)*m_pBodyA->m_fInvInertia);		}		else			botA = 0;		float botB;				if(m_bMovable[1])		{			botB = m_pBodyB->m_fInvMass;			float rBPdotN = cp2^m_vCollisionNormal;			botB += ((rBPdotN*rBPdotN)*m_pBodyB->m_fInvInertia);		}		else			botB = 0;		float j = (top/(botA+botB));		//Friction - At each collision point the normal impulse has been calculated.		Vector2 jN = m_vCollisionNormal*j;		if(m_bMovable[0])		{			m_pBodyA->m_vVelocity += jN*m_pBodyA->m_fInvMass;			m_pBodyA->m_fRotaionalVelocity -= ((cp1^jN)*m_pBodyA->m_fInvInertia);		}		if(m_bMovable[1])		{			m_pBodyB->m_vVelocity -= jN*m_pBodyB->m_fInvMass;			m_pBodyB->m_fRotaionalVelocity += ((cp2^jN)*m_pBodyB->m_fInvInertia);		}		//friction		if(m_fCoefficientOfFriction <= 0 ) 			return true;				resVelocity = Vector2(0,0);				if(m_bMovable[0])		{			resVelocity = m_pBodyA->m_vVelocity-(cp1Perp*m_pBodyA->m_fRotaionalVelocity);		}			if(m_bMovable[1])		{			resVelocity -= m_pBodyB->m_vVelocity-(cp2Perp*m_pBodyB->m_fRotaionalVelocity);		}		//Applying friction at each point is treated like a collision - 		Vector2 tangent_vel = resVelocity - (m_vCollisionNormal*(resVelocity* m_vCollisionNormal));		float tangent_speed = tangent_vel.Length(); //TODO: change this		if (tangent_speed < 0.0f) 			return true;			Vector2 T = -tangent_vel / tangent_speed;				top = tangent_speed;		if(m_bMovable[0])		{			botA = m_pBodyA->m_fInvMass;			float rAPdotN = cp1^T;			botA +=  ((rAPdotN*rAPdotN)*m_pBodyA->m_fInvInertia);		}		else			botA = 0;		if(m_bMovable[1])		{			botB = m_pBodyB->m_fInvMass;			float rBPdotN = cp2^T;			botB +=  ((rBPdotN*rBPdotN)*m_pBodyB->m_fInvInertia);		}		else			botB = 0;		float denominator = botA+botB;		if (denominator > 0)		{							//calculate the impulse required to prevent the two points on the two objects diverging.			float impulse_to_reverse = top / denominator;			float static_friction = m_fCoefficientOfFriction;			float dynamic_friction = m_fCoefficientOfFriction*0.8;			float impulse_from_normal_impulse = static_friction * j;			float friction_impulse;    			//Now compare this tangential friction impulse to staticFriction*normalImpulse			if (impulse_to_reverse < impulse_from_normal_impulse)								//If it's less then apply the originally calculated tangential friction.				friction_impulse = impulse_to_reverse;			else				//If it's greater, then friction won't be able to stop the objects, 				//so apply dynamicFriction*normalImpulse in the tangential direction. 				friction_impulse = dynamic_friction * j;			Vector2 jT = T*friction_impulse;			if(m_bMovable[0])			{				m_pBodyA->m_vVelocity += jT*m_pBodyA->m_fInvMass;				m_pBodyA->m_fRotaionalVelocity -= ((cp1^jT)*m_pBodyA->m_fInvInertia);			}			if(m_bMovable[1])			{				m_pBodyB->m_vVelocity -=  jT*m_pBodyB->m_fInvMass;				m_pBodyB->m_fRotaionalVelocity += ((cp2^jT)*m_pBodyB->m_fInvInertia);				}		}		return true;	}

##### Share on other sites
Hey, thank's a lot! I desperately need some code to look at ;-)
I already implemented Oliii's code, but it somehow behaves wrong...oh well!
Maybe Airo want's to post his impulse code as well? :-D

##### Share on other sites
just so theres no confusion the first half of that code finds the collision impulse (as you usually would) and the second half adds the frictional impulse.

the function dosnt just do friction bit [attention] ok good [grin]

##### Share on other sites
I'm doing practically the same as structure. I'm willing to post the formula I've implemented if you couldn't find the slide.

##### Share on other sites
Quote:
 the function dosnt just do friction bit ok good

Huh? Could you rephrase that statement? I don't get it ;-)

##### Share on other sites
sorry :)

I mean that the function that I posted above is not just for adding the frictional part of the impulse collision response.

it finds the impulse for the collision response as your code prob already does then adds friction on to this.

the way I worded it above it could sound like this function just does the friction part.

##### Share on other sites
The idea of treating friction as a second collision is great :-D
My stuf is almost working now! (but still misbehaves in some situations)

(it isn't as unreadable as you thought) ;-)

What do you mean with this?
Quote:
 Applying friction at each point is treated like a collision - calculate the impulse required to prevent the two points on the two objects diverging.Now compare this tangential friction impulse to staticFriction*normalImpulse. If it's greater, then friction won't be able to stop the objects, so apply dynamicFriction*normalImpulse in the tangential direction. If it's less then apply the originally calculated tangential friction.

I don't get the point here :-(
(but I have a feeling that this somehow concerns my problem...)

##### Share on other sites
Hey together,
@Structure: you write:
float tangent_speed = tangent_vel.Length(); //TODO: change this
could you not do:

tangent=Vector2(m_vCollisionNormal.y,-m_vCollisionNormal.x);
tangent_speed=tangent*resVelocity;

??? That way you do not need the .Length() (and I guess that's the reason why you
write //TODO: change this).
I am also asking because I have implemented friction from your code (THANKS FOR YOUR CODE!!!) and did it this way.
Greetings,
Nathan

EDIT: You would also have to add
if(tangent_speed<0.0f)
{
tangent_speed=-tangent_speed;
tangent=-tangent;
}

I do not understand why you write:
if (tangent_speed < 0.0f)
return true;

tangent_speed can not be negativ in your case, can it?

[Edited by - LonelyStar on August 9, 2005 4:11:43 AM]

##### Share on other sites
hey LonelyStar,

this code is from an old project that was continuously being *cough* “upgraded” and thus never finished :)

I think the todo was there because of something to do with the length function being inefficient with the fixed point maths libs I was using (I converted it to floats to make it easer to read for the post)

im working at the mo, ao ill look at the code when I can and get back to you.

and yes the if(tangent_speed<0.0f) does seem a bit redundant, im sure there was a reason I had it there (prob something to do with me being stupid (likely) or fixed point precision problems)

##### Share on other sites
another friction test: mini domino

##### Share on other sites
Works freakin perfect! :-D Cool man!
(I hope to have some spare time soon to continue working on my (still not working) friction code...)

##### Share on other sites
i'm using this:

static friction:

Vrelative+ dot N = - e Vrelative- dot N

Vrelative+ dot T = 0

Solving for impulse J: J = -K^-1 ( (Vrelative- dot N)*N + Vrelative- )

if static friction check fails

J = j(N - u*T)

Solving for j gives

j = - (1 + e) Vrelative- dot N / (N dot (K*(N - uT)) )

This is from the slide I was talking about

##### Share on other sites
I don't quite get what you wrote there ;-)

What I'm trying right now is the following:
In my ApplyImpulse-function I copy'n'pasted the whole code (so that there are actually two collisions now) with these changes:

1) Relative velocity is now reduced to the component orthogonal to the collision normal

2)Every occurence of "collisionNormal" is changed to "collisionTangent" (which is the vector orthogonal to the collision normal)

The result isn't very satisfying... :-(