Jump to content
  • Advertisement
Sign in to follow this  

Help requested on Ray Triangle Collision

This topic is 2296 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

(Sorry if the post says Ray triangle, I was first trying with a ray first, but that wouldn't work with my airplane, so I'm trying sphere triangle now.)

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:

// 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;
return true;
Edited by Veer.

Share this post

Link to post
Share on other sites
Your implementation resembles more of a "is a point in front of or behind a plane?" test.

If you need ray-triangle intersection testing, I recommend taking using a published and tested method. The Möller-Trumbore test is a good one I prefer. An implementation of that can be found from MathGeoLib (code).

If you are actually looking for a point behind/infrontof test, then try the Plane::SignedDistance function.

Share this post

Link to post
Share on other sites
I just can't seem to get this implementation right.. does anyone have some other great example of sphere triangle collision? or maybe point out what is wrong with this implementation. Thanks

Share this post

Link to post
Share on other sites
Christer Ericson has a triangle-sphere collision routine in his book Real-Time Collision detection. The algorithm is implemented in MathGeoLib here.

Share this post

Link to post
Share on other sites
Sign in to follow this  

  • Advertisement

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!