Jump to content
  • Advertisement
miqvp22

Vehicles Softbody Verlet Integration Deformation

Recommended Posts

Posted (edited)

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

Edited by miqvp22

Share this post


Link to post
Share on other sites
Advertisement
Posted (edited)

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.

Edited by Irlan Robson

Share this post


Link to post
Share on other sites
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!
 

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

  • 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!