• Advertisement
Sign in to follow this  

Cloth Physics

This topic is 3821 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

I've been working on cloth physics for some time now and I can't seem to get it to look right. I'm using the spring-ball approach where I'm loading a mesh, creating a ball at everything vertice and putting a spring through all edges and one past it (as long as the dot product of those vectors are close to 1). I'm also calculating using Hooke's look and a spring constant, but I can't seem to find the right values to make it look right, the cloth seems to stretch too much and look very rubbery. I want to be able to set a maximum (and maybe minimum) percent each spring can stretch and have the cloth stay intact. Here's an image of what i'm seeing:

Share this post


Link to post
Share on other sites
Advertisement
Can you post the code you use?
I remember that there's a very good article linked from here about cloth sim, I use it sometimes ago.
The real problem with cloth sim is that it's hatd to make it "rigid". Springs/mass are great for very soft cloth, but you can't really make a "rigid" cloth without a very good integration scheme, or small time step etc. (which mean more computation time).
Increase the spring constant to get something harder, but maybe you will have to fight against oscillations, which can be decrease with damping...

I think another way to create cloth is to use the fast LSM (which was posted here 1 or 2 month ago), which could lead, I think, to very hard and stable cloth.

Share this post


Link to post
Share on other sites

void cWCloth::_Update(WcrFLOAT dt)
{
float springLen;
float extension;
sWVector3D force, acc, vel;
sWVector3D tension;

for (WuLONG i=0 ; i<m_Springs.GetNetItems() ; ++i)
{
springLen = ((*m_pCurrent)[m_Springs->m_BallIndex[0]]->m_Position -
(*m_pCurrent)[m_Springs->m_BallIndex[1]]->m_Position).Length();
extension = springLen - m_Springs->m_fNaturalLength;
m_Springs->m_fExtension = springLen / m_Springs->m_fNaturalLength;
m_Springs->m_fTension = m_fSpringConstant * extension / m_Springs->m_fNaturalLength;
}

for (WuLONG i=0 ; i<m_Balls[0].GetNetItems() ; ++i)
{
force = m_v3Gravity + m_v3ExternalForce;
vel = sWVector3D();
for (WuLONG j=0 ; j<m_Springs.GetNetItems() ; ++j)
{
// if the the current ball is the first ball of the spring
if (m_Springs[j]->m_BallIndex[0] == i)
{
tension = (*m_pCurrent)[m_Springs[j]->m_BallIndex[1]]->m_Position -
(*m_pCurrent)->m_Position;
tension.Normalize();

force += tension * m_Springs[j]->m_fTension;
/*if (m_Springs[j]->m_fExtension > m_fMaxExtension)
{
vel += (tension *
((m_Springs[j]->m_fExtension - m_fMaxExtension)
* (m_Springs[j]->m_fNaturalLength)));
} else
if (m_Springs[j]->m_fExtension < m_fMinExtension)
{
vel += (tension *
((m_Springs[j]->m_fExtension - m_fMinExtension)
* (m_Springs[j]->m_fNaturalLength)));
}*/

}
else
// if the current ball is the second ball of the spring
if (m_Springs[j]->m_BallIndex[1] == i)
{
tension = (*m_pCurrent)[m_Springs[j]->m_BallIndex[0]]->m_Position -
(*m_pCurrent)->m_Position;
tension.Normalize();

force += tension * m_Springs[j]->m_fTension;
}
}

// Calculate where the ball is going to be
acc = force / m_fBallMass;
(*m_pNext)->m_Velocity = (*m_pCurrent)->m_Velocity + (acc * dt) + vel;
(*m_pNext)->m_Velocity *= 0.75f;
if (i != 0 && i != 110)
(*m_pNext)->m_Position = (*m_pCurrent)->m_Position +
((*m_pCurrent)->m_Velocity + (*m_pNext)->m_Velocity) * dt/2.0f;

// Position the vertice at the next ball
if (i != 0 && i != 110)
m_pModel->Objects[0]->Verts->Vertex = (*m_pNext)->m_Position;
}

// Swap the lists
tWVectorList<sWBall> * temp = m_pCurrent;
m_pCurrent = m_pNext;
m_pNext = temp;
}



inside that comment, i tried to add implementation for what i was saying; having a maximum percent of extension and minimum extension. it worked a little bit, but not completely...

Share this post


Link to post
Share on other sites
If I understand correctly you apply a 0.75 damping on velocituy, this can be a too much (I think value between 0.99 and 0.95 are better, lower the system will loose to much energy).

Also I'm surprised about

m_Springs-&gt;m_fExtension = springLen / m_Springs-&gt;m_fNaturalLength;
m_Springs-&gt;m_fTension = m_fSpringConstant * extension / m_Springs-&gt;m_fNaturalLength


(maybe I just don't understand the code), but the force to apply to the particle are lineary dependant to the extension (in meter). For example if the spring has a rest length of L, and the distance between the 2 particles are X, then the force is X * constant.
The higher the constant value is, the harder the cloth will be.
You can also apply other forces, look at this article (this is the one I was talking in my previous post) :
http://www.intel.com/cd/ids/developer/asmo-na/eng/20413.htm

Share this post


Link to post
Share on other sites
Natural length is the length of the edge when i first loaded the mesh and created the balls.

The extension is the percentage from the current length divided by the natural length.

I remember now why i changed the damp from .95 to .75, because this happened

Share this post


Link to post
Share on other sites
That article is good and all; the code works and it looks like really good cloth, but the code is a bit big to try to break apart and figure out my specific problem... Is there maybe some tutorial or any other smaller projects that show how to do cloth physics?

Share this post


Link to post
Share on other sites
I would use infinitely stiff springs. Look at the Thomas Jakobsen character physics article. I think I have some code somewhere, but I achieved a very basic cloth animation demo like that very easily. Not sure about springs, especially when you need very stiff springs and you are performing a basic euler integration.

Share this post


Link to post
Share on other sites
I can second the Jakobsen recommendation, it is quite easy to come up with a stable implementation using this approach. You may also want to check out how Ageia did their cloth, it's described here (PDF). This has a nice approach for implementing bending constraints amongst other things.

Share this post


Link to post
Share on other sites
Ok, I have new implementation and it works A LOT better. The cloth is now intact but it waves WAY too much... it seems that the forces are too great for it.


void cWCloth::_Update(WcrFLOAT dt)
{
float springLen;
float extension;
//sWVector3D force, acc, vel;
//sWVector3D tension;

sWVector3D Force, relative, relVel;
float springForce, damp, force;

for (WuLONG i=0 ; i<m_Balls[0].GetNetItems() ; ++i)
{
if (i != 0 && i != 110)
{
m_Balls[0]->m_Velocity += (m_v3Gravity + m_v3ExternalForce) * dt;
m_Balls[0]->m_Position += m_Balls[0]->m_Velocity * dt;
m_pModel->Objects[0]->Verts->Vertex = m_Balls[0]->m_Position;
} else
{
m_Balls[0]->m_Velocity = sWVector3D();
}
}
for (WuLONG i=0 ; i<m_Springs.GetNetItems() ; ++i)
{
Force = m_Balls[0][m_Springs->m_BallIndex[1]]->m_Position - m_Balls[0][m_Springs->m_BallIndex[0]]->m_Position;
Force.Normalize();

relative = m_Balls[0][m_Springs->m_BallIndex[0]]->m_Position - m_Balls[0][m_Springs->m_BallIndex[1]]->m_Position;
relVel = m_Balls[0][m_Springs->m_BallIndex[0]]->m_Velocity - m_Balls[0][m_Springs->m_BallIndex[1]]->m_Velocity;
springForce = m_fSpringConstant * (relative.Length() - m_Springs->m_fNaturalLength);
damp = (m_fDamping * (relative * relVel)) / m_Springs->m_fNaturalLength;
force = (springForce + damp) / 2.0f;
Force *= force;

m_Balls[0][m_Springs->m_BallIndex[0]]->m_Velocity += Force * dt;
m_Balls[0][m_Springs->m_BallIndex[1]]->m_Velocity -= Force * dt;
}



The only way it looks decent is when:
m_fDamping = 1.4f
m_fSpringContant = 2000.0f
m_v3Gravity = vector(0, -100, 0)

Share this post


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

  • Advertisement