Sign in to follow this  
marcus12

Sphere-Cloth Collision

Recommended Posts

Hi, I am trying to simulate cloth and sphere collision. What I am trying to do is to calculate Vector3d offset = Cloth.Particle[] - ball; float len = offset.length(); if(len < radius_of_ball) { //collision is there //Since the shpere is moving along the z direction I tried to cut out the particle velocity around that direction //then the particle should be along the surface of the sphere Cloth.Particle[].velocity.z = 0.0; } But what happens is that, the sphere passes in and out of the cloth without any realistic behaviour. Is the approach right or what should I try and calculate to make it work. All suggestions are welcome...

Share this post


Link to post
Share on other sites
Quote:
Original post by marcus12
Hi,
I am trying to simulate cloth and sphere collision. What I am trying to do is
to calculate

Vector3d offset = Cloth.Particle[] - ball;
float len = offset.length();

if(len < radius_of_ball)
{
//collision is there
//Since the shpere is moving along the z direction I tried to cut out the
particle velocity around that direction
//then the particle should be along the surface of the sphere
Cloth.Particle[].velocity.z = 0.0;
}

But what happens is that, the sphere passes in and out of the cloth without any realistic behaviour.

Is the approach right or what should I try and calculate to make it work.

All suggestions are welcome...



Hi,

Its strange that no one replied :-(

Share this post


Link to post
Share on other sites
What you might try doing, if you don't already have this, is make it render the sphere and the points of the cloth.

From here you should be able to see if something is wrong with your code and it isn't working right (cloth balls are going into the sphere), or if something else is going on, such as the "holes" in your cloth (ie the places between your cloth points) are too big and the sphere goes through without much of a problem.

Something else you might try doing is instead of testing the sphere against the points in the cloth, instead test the sphere against the TRIANGLES of the cloth.

that will give you a more realistic result, at the cost of a little more computation time.

Share this post


Link to post
Share on other sites
oh also something else to try...

If the point on the cloth is less than the radius of the sphere, instead of just setting the z velocity to 0 what you should try doing is...

#1 - Get a vector from the center of the sphere to the cloth ball.
#2 - normalize that vector
#3 - multiply that vector by the sphere radius
#4 - move the ball to that position (ie sphere center + new vector)

That should give you a lot better results I think

Share this post


Link to post
Share on other sites
Finding if a point is inside a sphere is easy. I also assume that your cloth particles have a 'mass' associated with them.

Here's something you can try.

Quote:


bool particleInSphere(const Vector& particle, const Vector& centre, float radius, Vector& ncoll, float& dcoll)
{
Vector delta = (particle - centre);
float distance_squared = delta.dotProduct(delta);
if(distance_squared > (radius*radius)) return false;
float distance = sqrt(distance_squared);

ncoll = delta;
if(distance > 0.0001f) ncoll /= distance;
dcoll = (radius - distance);
return true;
}

bool collideParticleAndSphere(Vector& particle_pos,
Vector& particle_vel,
float particle_inverse_mass,
Vector& sphere_pos,
Vector& sphere_vel,
float sphere_radius,
float sphere_inverse_mass)
{
Vector ncoll;
float dcoll;
if(!particleInSphere(particle_pos, sphere_pos, sphere_radius, ncoll, dcoll))
return false;

// resolve intersection. push sphere and particle away from each other.
// the lighter of the two will be pushed more.
particle_pos += ncoll * (dcoll * particle_inverse_mass / (particle_inverse_mass + sphere_inverse_mass));

sphere_pos -= ncoll * (dcoll * sphere_inverse_mass / (particle_inverse_mass + sphere_inverse_mass));

// combined velocity
Vector v = (particle_vel - sphere_vel);

// impact velocity
float vn = v.dotProduct(ncoll);

// objects moving from each other already. add no impulse.
if(vn > 0.0f) return true;

// coefficient of restitution (how much bounce you want).
const float cor = 0.5f;

// collision impulse between the objects.
Vector impulse = ncoll * (-(1.0f + cor) * vn);

// apply impulse to change their velocity.
// the lighter of the two will have more of its momentum changed.
particle_vel += impulse * (particle_inverse_mass / (particle_inverse_mass + sphere_inverse_mass));

sphere_vel -= impulse * (sphere_inverse_mass / (particle_inverse_mass + sphere_inverse_mass));

return true;
}

Share this post


Link to post
Share on other sites
Quote:
Original post by oliii
Finding if a point is inside a sphere is easy. I also assume that your cloth particles have a 'mass' associated with them.

Here's something you can try.

Quote:


bool particleInSphere(const Vector& particle, const Vector& centre, float radius, Vector& ncoll, float& dcoll)
{
Vector delta = (particle - centre);
float distance_squared = delta.dotProduct(delta);
if(distance_squared > (radius*radius)) return false;
float distance = sqrt(distance_squared);

ncoll = delta;
if(distance > 0.0001f) ncoll /= distance;
dcoll = (radius - distance);
return true;
}

bool collideParticleAndSphere(Vector& particle_pos,
Vector& particle_vel,
float particle_inverse_mass,
Vector& sphere_pos,
Vector& sphere_vel,
float sphere_radius,
float sphere_inverse_mass)
{
Vector ncoll;
float dcoll;
if(!particleInSphere(particle_pos, sphere_pos, sphere_radius, ncoll, dcoll))
return false;

// resolve intersection. push sphere and particle away from each other.
// the lighter of the two will be pushed more.
particle_pos += ncoll * (dcoll * particle_inverse_mass / (particle_inverse_mass + sphere_inverse_mass));

sphere_pos -= ncoll * (dcoll * sphere_inverse_mass / (particle_inverse_mass + sphere_inverse_mass));

// combined velocity
Vector v = (particle_vel - sphere_vel);

// impact velocity
float vn = v.dotProduct(ncoll);

// objects moving from each other already. add no impulse.
if(vn > 0.0f) return true;

// coefficient of restitution (how much bounce you want).
const float cor = 0.5f;

// collision impulse between the objects.
Vector impulse = ncoll * (-(1.0f + cor) * vn);

// apply impulse to change their velocity.
// the lighter of the two will have more of its momentum changed.
particle_vel += impulse * (particle_inverse_mass / (particle_inverse_mass + sphere_inverse_mass));

sphere_vel -= impulse * (sphere_inverse_mass / (particle_inverse_mass + sphere_inverse_mass));

return true;
}


Hi,
Particles position should get updated with change in force, so is it right to move the particles by giving specific positions? like
Quote:

particle_pos += ncoll * (dcoll * particle_inverse_mass / (particle_inverse_mass + sphere_inverse_mass));
[/quote]

Also my cloth simulation seems to work properly like the cloth behaves properly under wind and gravity, but as soon as the cloth comes in contact with the rigid body it explodes.
I tested with the Oliii logic for collision it works properly around the edges nicely but not at the centre of clothes, also after couple of collision tests the cloth explodes.

Does it because the spring are not working properly? I have used Hooks law and given all the structural and sheer springs equal forces in the begining.

What are the things I should consider to test whether the springs are working correctly as the spring behaves unrealistic only under collision?

All suggestions are welcome....

Share this post


Link to post
Share on other sites
Have you tried your cloth with simulated wind and movement? Does it breaks up under tension and compression?

Share this post


Link to post
Share on other sites
Quote:
Original post by oliii
Have you tried your cloth with simulated wind and movement? Does it breaks up under tension and compression?



It does not break under the wind force and behaves quite normally, the problem only comes when it comes in touch with a rigid body then the whole particles tries to go in a zig zag pattern in any direction.

Share this post


Link to post
Share on other sites
try without the response.

Quote:



bool collideParticleAndSphere(Vector& particle_pos,
Vector& particle_vel,
float particle_inverse_mass,
Vector& sphere_pos,
Vector& sphere_vel,
float sphere_radius,
float sphere_inverse_mass)
{
Vector ncoll;
float dcoll;
if(!particleInSphere(particle_pos, sphere_pos, sphere_radius, ncoll, dcoll))
return false;

// resolve intersection. push sphere and particle away from each other.
// the lighter of the two will be pushed more.
particle_pos += ncoll * (dcoll * particle_inverse_mass / (particle_inverse_mass + sphere_inverse_mass));

sphere_pos -= ncoll * (dcoll * sphere_inverse_mass / (particle_inverse_mass + sphere_inverse_mass));
}

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

Sign in to follow this