Skip to main content
GameDev.net gamedev.net
🔒 Locked

Softbody Verlet Integration Deformation

Started by miqvp22 May 4, 2019 at 1:08 PM 5 replies 13.3k views
Original Post
miqvp22
miqvp22

Hello,

I have implemented a structure based in Node (particles) and Beams (edges), to perform a cloth simulation. ( like BeamNG does to perform deformation physics )

image.png.62e87da959cce69745a53260443e835d.pngimage.png.c251c90f0e023537488ac29f4207b92e.png

I'm wondering to know how could I stop constraint relaxation dynamically after some crash, to simulate a car chassis crash and avoid a complete recovery due to constraint solving.

(this is my current constraint solve code, more in http://web.archive.org/web/20080410171619/http://www.teknikus.dk/tj/gdc2001.htm )

image.png.47a9d3b95d2e469d4e4608ffdeb41a49.png


Thanks

Irlan Robson
Irlan Robson

Definitely not the way I would simulate a car crash but I would try to decrease the streching stiffness after detecting such a crash in order to make the car more soft for a couple of seconds, then would restore the stiffness value to bring back the car to the undeformed configuration.

It seems that the streching stiffness in your code is 0.005, but it could be a relaxation factor, so I don't know. Anyway your position-based solver loop would look something like this:


void b3Cloth::Step(float32 h, u32 iterations)
{
	if (h == 0.0f)
	{
		return;
	}
  
	// Damping 
	float32 d = exp(-h * m_kd);

	// Integrate using semi-implicit Euler
	for (u32 i = 0; i < m_pCount; ++i)
	{
		b3Particle* p = m_ps + i;

		p->v += h * p->im * m_gravity;
		p->v *= d;

		p->p0 = p->p;
		p->p += h * p->v;
	}

	// Solve position constraints
	for (u32 i = 0; i < iterations; ++i)
	{
		SolveC1();
	}

	// Estimate current velocity
	float32 inv_h = 1.0f / h;
	for (u32 i = 0; i < m_pCount; ++i)
	{
		b3Particle* p = m_ps + i;
		p->v = inv_h * (p->p - p->p0);
	}
  
	// Solve velocity constraints (e.g. friction, etc)...
}
      
void b3Cloth::SolveC1()
{
	for (u32 i = 0; i < m_c1Count; ++i)
	{
		b3C1* c = m_c1s + i;
		
		b3Particle* p1 = m_ps + c->i1;
		b3Particle* p2 = m_ps + c->i2;

		float32 m1 = p1->im;
		float32 m2 = p2->im;

		float32 mass = m1 + m2;
		if (mass == 0.0f)
		{
			continue;
		}

		mass = 1.0f / mass;

		b3Vec3 J2 = p2->p - p1->p;
		float32 L = b3Length(J2);
		if (L > B3_EPSILON)
		{
			J2 /= L;
		}

		b3Vec3 J1 = -J2;

		// m_k1 is the streching stiffness in [0, 1]  
		float32 C = L - c->L;
		float32 impulse = -m_k1 * mass * C;

		p1->p += (m1 * impulse) * J1;
		p2->p += (m2 * impulse) * J2;
	}
}

Hope it helps.

miqvp22
miqvp22
2 minutes ago, Irlan Robson said:

Definitely not the way I would simulate a car crash but I would try to decrease the streching stiffness after detecting such a crash in order to make the car more soft for a couple of seconds, then would restore the stiffness value to bring back the car to the undeformed configuration.

It seems that the streching stiffness in your code is 0.005, but it could be a relaxation factor, so I don't know. Anyway your constraint solver loop would be like this:



void b3Cloth::Step(float32 h, u32 iterations)
{
	if (h == 0.0f)
	{
		return;
	}
  
	// Damping 
	float32 d = exp(-h * m_kd);

	// Integrate using semi-implicit Euler
	for (u32 i = 0; i < m_pCount; ++i)
	{
		b3Particle* p = m_ps + i;

		p->v += h * p->im * m_gravity;
		p->v *= d;

		p->p0 = p->p;
		p->p += h * p->v;
	}

	// Solve position constraints
	for (u32 i = 0; i < iterations; ++i)
	{
		SolveC1();
	}

	// Estimate current velocity
	float32 inv_h = 1.0f / h;
	for (u32 i = 0; i < m_pCount; ++i)
	{
		b3Particle* p = m_ps + i;
		p->v = inv_h * (p->p - p->p0);
	}
  
	// Solve velocity constraints (e.g. friction, etc)...
}
      
void b3Cloth::SolveC1()
{
	for (u32 i = 0; i < m_c1Count; ++i)
	{
		b3C1* c = m_c1s + i;
		
		b3Particle* p1 = m_ps + c->i1;
		b3Particle* p2 = m_ps + c->i2;

		float32 m1 = p1->im;
		float32 m2 = p2->im;

		float32 mass = m1 + m2;
		if (mass == 0.0f)
		{
			continue;
		}

		mass = 1.0f / mass;

		b3Vec3 J2 = p2->p - p1->p;
		float32 L = b3Length(J2);
		if (L > B3_EPSILON)
		{
			J2 /= L;
		}

		b3Vec3 J1 = -J2;

		// m_k1 is the streching stiffness in [0, 1]  
		float32 C = L - c->L;
		float32 impulse = -m_k1 * mass * C;

		p1->p += (m1 * impulse) * J1;
		p2->p += (m2 * impulse) * J2;
	}
}

Hope it helps.

I solved it by adding this line to my code:

if(difference > 0.1f) stick.length = deltaLength;

It is working like a mass-spring elastic limit. So, If the deformation difference is higher than the beam default relaxed length, I set ‘restitution’ its default length. Like a metal chassis would.

But thanks for this other solution!

Randy Gaul
Randy Gaul

You should add in code to adjust rest length of your springs if they are stretched or compressed too far.

You can also adjust rest length if a particle receives am impulse above a threshold.

SFSpoto
SFSpoto

Hi all,

I'm interested in this kind of system. Do you have any references that explains how such model of a deformable car could be implemented ?

Thank you

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.