Hi I am new to 3D and I'm trying to create a sphere triangle collision detection. I want to use this method because I have an airplane flying above a plane which is not flat. What I would want to check is if the airplane is crashing on one of the triangles of my plane. I have been researching all around and recapping my vector math a bit, and came up with this implementation. The problem of this implementation is that the dot product with the vertices gives me a negative number ( (pointB - pointA).Dot(pointA) > 0 && (pointC - pointA).Dot(pointA) > 0) which is smaller than 0, so it returns as a hit, which is not. But the distance to the faces works fine, and the distance to the vertices too. But it actually only finds a hit on one specific point on my plane which is strange. If someone could give me some suggestions what is wrong with this implementation I would be glad.
Below I have the implementation. I load in an obj model and then push all the vertices in the vertex list which is a std vector, and all the triangles in the triangle list. the vertex list is a list of vector3 and the triangle list is a list of triangles which are compound out of three int indices. Thanks in advance.
I got this implementation from this site:
http://realtimecolli...net/blog/?p=103
// sphere - plane collision. face, edge, vertex acurate
bool Game::isColliding(MeshObject* object, float radius, MeshObject* plane)
{
for(int f = 0; f < plane->mesh->triangleList.size(); f++)
{
vector3 spherePos = object->position;
vector3 vertex0 = plane->mesh->verticeList.at(plane->mesh->triangleList[f].m_Indices[0]);
vector3 vertex1 = plane->mesh->verticeList.at(plane->mesh->triangleList[f].m_Indices[1]);
vector3 vertex2 = plane->mesh->verticeList.at(plane->mesh->triangleList[f].m_Indices[2]);
vector3 pointA = vertex0 - spherePos;
vector3 pointB = vertex1 - spherePos;
vector3 pointC = vertex2 - spherePos;
// -------------*** Face checks ***------------
// facedistance check
float distanceFace = abs(pointA.Dot(plane->mesh->triangleList[f].m_Normal));
// face separation check
float separatedf;
if(distanceFace > radius)
{ separatedf = 1;}else {separatedf = 0;}
// ----------*** end face checks ***------------
// ----------*** Vertex checks ***-------------
// vertexdistance check
float distanceVertex0 = sqrt(pointA.Dot(pointA));
float distanceVertex1 = sqrt(pointB.Dot(pointB));
float distanceVertex2 = sqrt(pointC.Dot(pointC));
// vertex separation checks
float separatedv0;
if(distanceVertex0 > radius && (pointB - pointA).Dot(pointA) > 0 && (pointC - pointA).Dot(pointA) > 0)
{separatedv0 = 1;}else{separatedv0 = 0;}
float separatedv1;
if(distanceVertex1 > radius && (pointB - pointA).Dot(pointB) > 0 && (pointC - pointB).Dot(pointB) > 0)
{separatedv1 = 1;}else{separatedv1 =0;}
float separatedv2;
if(distanceVertex2 > radius && (pointC - pointA).Dot(pointC) > 0 && (pointC - pointB).Dot(pointC) > 0)
{separatedv2 = 1;}else{separatedv2 =0;}
float separatedv = separatedv0 || separatedv1 || separatedv2;
// --------*** end vertex check ***-------------
// ----------*** Edges checks ***--------------
// B - A
vector3 ABEdge = vertex1 - vertex0;
float ABT = ((spherePos - pointA).Dot(ABEdge)) / (ABEdge.Dot(ABEdge));
vector3 projA = pointA + ABT * ABEdge; // projection center sphere onto plane edge A
vector3 SphereProjA = spherePos - projA;
vector3 v2Proj = pointC - projA;
float separatedEdgeA;
if(sqrt(SphereProjA.Dot(v2Proj)) > radius && SphereProjA.Dot(v2Proj))
{separatedEdgeA = 1;}else{separatedEdgeA = 0;}
// C - B
vector3 BCEdge = vertex2 - vertex1;
float BCT = ((spherePos - pointB).Dot(BCEdge)) / (BCEdge.Dot(BCEdge));
vector3 projB = pointB + BCT * BCEdge; // projection center sphere onto plane edge B
vector3 SphereProjB = spherePos - projB;
vector3 v0Proj = pointA - projB;
float separatedEdgeB;
if(sqrt(SphereProjB.Dot(v0Proj)) > radius && SphereProjB.Dot(v0Proj))
{separatedEdgeB = 1;}else{separatedEdgeB = 0;}
// A - C
vector3 CAEdge = vertex0 - vertex2;
float CAT = ((spherePos - pointC).Dot(CAEdge)) / (CAEdge.Dot(CAEdge));
vector3 projC = pointC + CAT * CAEdge; // projection center sphere onto plane edge C
vector3 SphereProjC = spherePos - projC;
vector3 v1Proj = pointB - projC;
float separatedEdgeC;
if(sqrt(SphereProjC.Dot(v1Proj)) > radius && SphereProjC.Dot(v1Proj))
{separatedEdgeC = 1;}else{separatedEdgeC = 0;}
// edge separation check
float separatede = separatedEdgeA || separatedEdgeB || separatedEdgeC;
// ----------*** end edge check ***-------------------
if(separatedf || separatedv || separatede)
{
return false;
}
else
{
return true;
}
}
}