Softbody Verlet Integration Deformation

Started by
5 comments, last by miqvp22 4 years, 3 months ago

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

Advertisement

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.

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!
 

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.

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

@SFSpoto I wrote this link in my first post, hope it's useful: http://web.archive.org/web/20080410171619/http://www.teknikus.dk/tj/gdc2001.htm

This topic is closed to new replies.

Advertisement