// Ray Plane Collision - returns true if collsion exists bool Collision::RayPlane(const float& normalX, const float& normalY, const float& normalZ, float pointOnPlaneX, float pointOnPlaneY, float pointOnPlaneZ, float initialX, float initialY, float initialZ, float directionX, float directionY, float directionZ, Vector3d p1, Vector3d p2, Vector3d p3, Vector3d p4, float* distance, Vector3d* collisionPoint){ // if the dot product == 0 then there is no collision if((directionX * normalX + directionY * normalY + directionZ * normalZ) == 0){ return false; } float t = ((pointOnPlaneX * normalX + pointOnPlaneY * normalY + pointOnPlaneZ * normalZ - normalX * initialX - normalY * initialY - normalZ * initialZ) / (directionX * normalX + directionY * normalY + directionZ * normalZ)); // if t is a negative.....or (in this case) < 0 the intersection point // is in the opposite direction... this indicates there is no collision // i like to think as t representing scalar time here....since time is directed // along a negative axis (which cant be)...it would denote no collision and evaluate to false. if(t < 0){ return false; } // intialize a point that is used for testing the collision of the ray and a triangle of the plane. float x = initialX + t * directionX; float y = initialY + t * directionY; float z = initialZ + t * directionZ; Vector3d rayPoint(x, y, z); float precision = 0.3; // test to see if the sum of the three sub triangles equals the triangle from which they // are derived...precision is used here in case the subtraction of the triangles are off by say like .0000000001 // exgerated i know, but used to illustrate the point. p1, p2, p3, and p4 are the vertices of the plane. // the first test in the if statement is for the first triangle after the quad was subdivided // simularly the second test in the if statement is for the other triangle. if(std::abs(triangleArea(p1, p2, p3) - (triangleArea(p1, p2, rayPoint) + triangleArea(p2, p3, rayPoint) + triangleArea(p1, p3, rayPoint))) < precision || std::abs(triangleArea(p1, p3, p4) - (triangleArea(p1, p3, rayPoint) + triangleArea(p3, p4, rayPoint) + triangleArea(p1, p4, rayPoint))) < precision){ if(distance != NULL){ (*distance) = t; if(collisionPoint != NULL){ collisionPoint->setX(x); collisionPoint->setY(y); collisionPoint->setZ(z); } } return true; } return false; }
int main() { Vec3 rayPoint(0,0,20); Vec3 rayDirn(0,0,-1); Vec3 triA(-1,-1,0); Vec3 triB(1,-1,0); Vec3 triC(2,1,0); if(CalcRayTriIntersection(rayPoint,rayDirn, triA,triB,triC)) { std::cout << "Ray intersects triangle!\n"; } else { std::cout << "Ray misses triangle!\n"; } return 0; }