Collision response - solver, penetration recovery
-
- Posts: 861
- Joined: Sun Jul 03, 2005 4:06 pm
- Location: Kirkland, WA
Re: Collision response - solver, penetration recovery
Hmm, against how many side planes are you clipping? It should be four not two.
-
- Posts: 10
- Joined: Fri Dec 04, 2015 2:48 am
Re: Collision response - solver, penetration recovery
Yes, it's against four.Dirk Gregorius wrote:Hmm, against how many side planes are you clipping? It should be four not two.
Should I clip the incident face vertices first, and then use the resulting points from the first clipping in the second clipping?
Code: Select all
std::vector<Contact> contacts;
this->ClipFaceToSidePlane(incident_face, -1 * normal1, neg_offset1, contacts);
this->ClipFaceToSidePlane(incident_face, normal1, pos_offset1, contacts);
this->ClipFaceToSidePlane(incident_face, -1 * normal2, neg_offset2, contacts);
this->ClipFaceToSidePlane(incident_face, normal2, pos_offset2, contacts);
Code: Select all
void RenderScene::ClipFaceToSidePlane(const Vector3* face, const Vector3& normal, float plane_offset, std::vector<Contact> &contacts)
{
Vector3 Vertex1 = face[3]; //start edge forms from endvertex->startvertex
float Distance1 = Vector3::Dot(Vertex1, normal) - plane_offset;
for (int i = 0; i < 4; i++)
{
Vector3 Vertex2 = face[i];
float Distance2 = Vector3::Dot(Vertex2, normal) - plane_offset;
if (Distance1 <= 0.0f && Distance2 <= 0.0f)
{
// Both vertices are behind the plane - keep vertex2
Contact contact1;
contact1.position = Vertex2;
contacts.push_back(contact1);
}
else if (Distance1 <= 0.0f && Distance2 > 0.0f)
{
// Vertex1 is behind the plane, vertex2 is in front -> intersection point
float Fraction = Distance1 / (Distance1 - Distance2);
Vector3 Position = Vertex1 + Fraction * (Vertex2 - Vertex1);
// Keep intersection point
Contact contact1;
contact1.position = Position;
contacts.push_back(contact1);
}
else if (Distance2 <= 0.0f && Distance1 > 0)
{
// Vertex2 is behind the plane, vertex1 is in front -> intersection point
float Fraction = Distance1 / (Distance1 - Distance2);
Vector3 Position = Vertex1 + Fraction * (Vertex2 - Vertex1);
// Keep intersection point
Contact contact1;
contact1.position = Position;
contacts.push_back(contact1);
// And also keep vertex2
Contact contact2;
contact2.position = Vertex2;
contacts.push_back(contact2);
}
// Keep vertex2 as starting vertex for next edge
Vertex1 = Vertex2;
Distance1 = Distance2;
}
}
-
- Posts: 10
- Joined: Fri Dec 04, 2015 2:48 am
Re: Collision response - solver, penetration recovery
Okay, so it looks pretty good now. I first clip the incident face vertices and then use the result from the first clipping in the second clipping. I do the same for the other side planes. This also makes sense to me. A point might be behind a sideplane but still needs to be tested on the others. Reminds me of broadphase collision test with sort and sweep.
I still can't stack cubes though. They are stacked for awhile before they slide off. When they start to slide off, I get 5-6 contact points.
This is my solver and I use baumgarte otherwise they will sink into the ground. I'm not sure how iterations(accumulating impulses) work so I have to research more there.
Is warmstart something I should look into as well?
Second picture is when the cubes are sliding off.


I still can't stack cubes though. They are stacked for awhile before they slide off. When they start to slide off, I get 5-6 contact points.
This is my solver and I use baumgarte otherwise they will sink into the ground. I'm not sure how iterations(accumulating impulses) work so I have to research more there.
Is warmstart something I should look into as well?
Second picture is when the cubes are sliding off.
Code: Select all
void RenderScene::ProcessContact(Contact* contact, float& Pn, Vector3&vel1, Vector3& ang_vel1, Vector3&vel2, Vector3& ang_vel2)
{
const float k_allowedPenetration = 0.01f;
float BAUMGARTE = 0.2f;
//BAUMGARTE
float bias = -BAUMGARTE * 1.f/this->physics_timestep * std::min(0.0f, -contact->penetration + k_allowedPenetration);
RigidBody* ent1 = contact->one;
RigidBody* ent2 = contact->two;
const float e = std::min(ent1->restitution, ent2->restitution);
Vector3 contactPoint = contact->position;
Vector3 contactNormal = contact->normal;
Vector3 rA = contactPoint - ent1->position;
Vector3 rB = contactPoint - ent2->position;
Vector3 kA = Vector3::Cross(rA, contactNormal);
Vector3 kB = Vector3::Cross(rB, contactNormal);
Vector3 uA = ent1->inverse_inertia_tensor_world_space*kA;
Vector3 uB = ent2->inverse_inertia_tensor_world_space*kB;
float normalMass = ent1->inverse_mass + ent2->inverse_mass;
if (!ent1->is_kinematic){
normalMass += Vector3::Dot(kA, uA);
}
if (!ent2->is_kinematic){
normalMass += Vector3::Dot(kB, uB);
}
// Relative velocity at contact
Vector3 relativeVel = (ent2->velocity + Vector3::Cross(ent2->angular_velocity, rB)) - (ent1->velocity + Vector3::Cross(ent1->angular_velocity, rA));
float numer = -(1 + e)*Vector3::Dot(relativeVel, contactNormal) + bias;
float f = numer / normalMass;
float Pn0 = contact->accumulated_impulse;
contact->accumulated_impulse = std::fmax(Pn0 + f, 0.0f);
f = contact->accumulated_impulse - Pn0;
Vector3 impulse = f*contactNormal;
contact->one->velocity -= impulse*ent1->inverse_mass;
contact->two->velocity += impulse*ent2->inverse_mass;
contact->one->angular_velocity -= f*uA;
contact->two->angular_velocity += f*uB;
}


-
- Posts: 861
- Joined: Sun Jul 03, 2005 4:06 pm
- Location: Kirkland, WA
Re: Collision response - solver, penetration recovery
Yes, you clip the clipped polygon with the next planes.
I am not sure about the last picture. Looks wrong to me, but again it is difficult to tell. Try a 45 degrees rotated box and if you get 8 vertices.
I am not sure about the last picture. Looks wrong to me, but again it is difficult to tell. Try a 45 degrees rotated box and if you get 8 vertices.
-
- Posts: 10
- Joined: Fri Dec 04, 2015 2:48 am
Re: Collision response - solver, penetration recovery
Yep, I get 8 vertices.Dirk Gregorius wrote:Yes, you clip the clipped polygon with the next planes.
I am not sure about the last picture. Looks wrong to me, but again it is difficult to tell. Try a 45 degrees rotated box and if you get 8 vertices.


-
- Posts: 861
- Joined: Sun Jul 03, 2005 4:06 pm
- Location: Kirkland, WA
Re: Collision response - solver, penetration recovery
Looks good! I would add friction next. 

-
- Posts: 10
- Joined: Fri Dec 04, 2015 2:48 am
Re: Collision response - solver, penetration recovery
I'll take a look at iterations(accumulating impulses), warmstart and friction.Dirk Gregorius wrote:Looks good! I would add friction next.
I can let go of the clipping part for now. Using the clipped polygon for the next clipping make sense to me, thanks Dirk.