Collision Response Jerky

Started by
1 comment, last by BlueSpud 10 years, 5 months ago

I've been implementing the collision detection and response detailed in this paper:http://www.peroxide.dk/papers/collision/collision.pdf I've got it mostly working now, but the collision response is a bit jumpy. I've only implemented collision inside the triangle but for what I've testing it against, it doesn't make a difference. Here is my code:


bool physicsObject::onSameSide(glm::vec3 point, glm::vec3 p1, glm::vec3 p2, glm::vec3 p3)
{
glm::vec3 cross1 = glm::cross(p3-p2, point-p2);
glm::vec3 cross2 = glm::cross(p3-p2, p1-p2);
if (glm::dot(cross1, cross2) >= 0.0)
return true;
else return false;

}

collisionResponsePacket physicsObject::checkTriangle(unsigned int i)
{
collisionResponsePacket packetToReturn;
glm::vec3 velocity = playerESpace.vecInElipsoidSpace( glm::vec3(-camx,-camy,-camz)-glm::vec3(-lcamx,-lcamy,-lcamz));
glm::vec3 basePos = playerESpace.vecInElipsoidSpace(glm::vec3(-lcamx,-lcamy,-lcamz));

//for now, we're just going to check the one triangle.
//.obj stores vertexes in counter-clockwise order, so we're going to swap the positions.
glm::vec3 p1 =playerESpace.vecInElipsoidSpace( (glm::vec3(ModelRegistry.models[model].m.obj[i].x3,ModelRegistry.models[model].m.obj[i].y3,ModelRegistry.models[model].m.obj[i].z3)));
glm::vec3 p2 = playerESpace.vecInElipsoidSpace((glm::vec3(ModelRegistry.models[model].m.obj[i].x2,ModelRegistry.models[model].m.obj[i].y2,ModelRegistry.models[model].m.obj[i].z2)));
glm::vec3 p3 = playerESpace.vecInElipsoidSpace((glm::vec3(ModelRegistry.models[model].m.obj[i].x1,ModelRegistry.models[model].m.obj[i].y1,ModelRegistry.models[model].m.obj[i].z1)));

//get the normal
glm::vec3 normal = glm::normalize(glm::cross(p2-p1, p3-p1));

//get signed distance
float distance = glm::dot(normal, basePos) - ((normal.x*p1.x)+(normal.y*p1.y)+(normal.z*p1.z));
//normal dot velocity
float ndv = glm::dot(normal, velocity);
//times of intersection
float time1 = (1.0 - distance)/ndv;
float time2 = (-1.0 - distance)/ndv;

if (time1 > time2)
{
float temp = time2;
time2 = time1;
time1 = temp;
}
if (time1 > 1.0 || time2 < 0.0)
{
//do something to say there wasn't a collision here
}
else
{
if (time2 > 10)
time2 = 0;
if (time1 < 0.0)
time1 = 0;

//get the point where we think that the sphere is going to collide
glm::vec3 intersectionPoint = (basePos + (time1*velocity*(float)0.95)) - normal;

//now we need to check if this collided
if (onSameSide(intersectionPoint, p1, p2, p3) && onSameSide(intersectionPoint, p2, p1, p3) && onSameSide(intersectionPoint, p3, p1, p2))
{
//there was a collision inside the triangle, so wer're done here.
packetToReturn.intersectionPoint = intersectionPoint;
packetToReturn.time0 = time1;
packetToReturn.time1 = time2;
packetToReturn.collided = true;
}
else
{
//temp, I just want to be able to check more complex meshes
return packetToReturn;
//there wasn't a collision inside the triangle so now for the fin stuff, we get to check the collision for the edges and points.
//this is also called the sweep test

//first we check collisions with the vertexes
}
}

return packetToReturn;
}


void physicsObject::testCollisionMeshWithElipsoid(double time)
{
//some of the vectors we require for the response
glm::vec3 velocity = playerESpace.vecInElipsoidSpace( glm::vec3(-camx,-camy,-camz)-glm::vec3(-lcamx,-lcamy,-lcamz));
glm::vec3 basePos = playerESpace.vecInElipsoidSpace(glm::vec3(-lcamx,-lcamy,-lcamz));
glm::vec3 destination = playerESpace.vecInElipsoidSpace(glm::vec3(-camx,-camy,-camz));

std::vector<collisionResponsePacket>results;
for (int i = 0; i < ModelRegistry.models[model].m.obj.size(); i++)
//we chech each triangle
results.push_back(checkTriangle(i));

//now we find which one we are going to respond against, then do it
for (int i = 0; i < results.size(); i++)
{
if (results[i].collided == true)
{

//we found the droids we are looking for ;)
glm::vec3 newPosition = basePos + (velocity*results[i].time0*0.9f);
glm::vec3 intersectionPoint = results[i].intersectionPoint - (velocity*results[i].time0*0.9f);
glm::vec3 slingingPlaneOrigin = intersectionPoint;
glm::vec3 slidingPlaneNormal = glm::normalize(newPosition - intersectionPoint);
float distance = glm::dot(slidingPlaneNormal, destination) - ((slidingPlaneNormal.x*slingingPlaneOrigin.x)+(slidingPlaneNormal.y*slingingPlaneOrigin.y)+(slidingPlaneNormal.z*slingingPlaneOrigin.z));
destination = destination - (distance)*slidingPlaneNormal;


//convert the new point back into what the camera will take
// lcamx = results[i].intersectionPoint.x;
//lcamy = results[i].intersectionPoint.y;
//lcamz = results[i].intersectionPoint.z;
//now we can update everything
camx = -destination.x*ELIPSE_X;
camz = -destination.z*ELIPSE_Z;
camy = -destination.y*ELIPSE_Y;

break;
}
}
results.clear();
}

I know its very inefficient, but I want the functionality there first. I've looked at the sample code in the paper but I haven't been able to work out whats wrong. I'm not recursing, but when I do, the camera warps to different places. What I want to know what is wrong with the length of the velocities, etc that would cause this kind of problem. Any help or information would be appreciated.

EDIT:

I've tried dividing the distance variable, this one: "destination - (distance)*slidingPlaneNormal;" and that seems to smooth it out but it seems to cause inaccuracies in the response and causing the camera to clip through the world.

Advertisement

Formatting of your code is messed up there?

Anyway, this looks bad

if (time2 > 10)
time2 = 0;
if (time1 < 0.0)
time1 = 0;

Dunno why 10 turns up there do you mean 1.0? And if it's bigger than 10 (or 1.0) don't set it to zero set it to 1.0 or 10.

"Most people think, great God will come from the sky, take away everything, and make everybody feel high" - Bob Marley

Formatting of your code is messed up there?

Anyway, this looks bad

if (time2 > 10)
time2 = 0;
if (time1 < 0.0)
time1 = 0;

Dunno why 10 turns up there do you mean 1.0? And if it's bigger than 10 (or 1.0) don't set it to zero set it to 1.0 or 10.

Thanks for pointing that out. I'm pretty sure that that shouldn't matter because, after that line nothing is being done with time2 because the collision is not fully implemented.

This topic is closed to new replies.

Advertisement