Sphere-Cloth Collision

Started by
7 comments, last by oliii 14 years ago
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...

Indie Game Developer

Game Studio: Freakout Games

Advertisement
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 :-(

Indie Game Developer

Game Studio: Freakout Games

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.
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
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;}

Everything is better with Metal.

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));


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....

Indie Game Developer

Game Studio: Freakout Games

Have you tried your cloth with simulated wind and movement? Does it breaks up under tension and compression?

Everything is better with Metal.

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.

Indie Game Developer

Game Studio: Freakout Games

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));}

Everything is better with Metal.

This topic is closed to new replies.

Advertisement