Reputation: 445
i want to implement the Moller & Trumbore algorithm, explained by
http://geomalgorithms.com/a06-_intersect-2.html
into my openframeworks project.
This is how my function looks
bool ofApp::intersectRayTriangle(Ray ray, Triangle triangle, ofVec3f* intersect) {
// u, v are triangle vectors - n is plane normal
ofVec3f u, v, n;
// ray vectors
ofVec3f w0, w;
// params to calc ray-plane intersect
float r, a, b;
u = triangle.v1 - triangle.v0;
u.normalize();
v = triangle.v2 - triangle.v0;
v.normalize();
n = u.cross(v);
n.normalize();
if(n == ofVec3f(0.0f, 0.0f, 0.0f)) // triangle is degenerate
return false;
w0 = ray.origin - triangle.v0;
a = -dot(n, w0);
b = dot(n, ray.direction);
if(fabs(b) < SMALL_NUM)
{
if(a == 0.0f)
return false; // ray lies in triangle plane
else
return false; // ray disjoint from plane
}
r = a / b;
if(r < 0.0f)
return false; // ray goes away from triangle
// intersect is the intersection point with the ray and the plane
*intersect = ray.origin + r * ray.direction;
// UNTIL HERE ITS ONLY PLANE INTERSECTION
//return true;
// Is plane intersection point inside the triangle?
float uu, uv, vv, wu, wv, D;
uu = dot(u,u);
uv = dot(u,v);
vv = dot(v,v);
w = *intersect - triangle.v0;
w.normalize();
wu = dot(w,u);
wv = dot(w,v);
D = uv * uv - uu * vv;
// get and test parametric coords
float s, t;
s = (uv * wv - vv * wu) / D;
if (s < 0.0f || s > 1.0f) // I is outside T
return false;
t = (uv * wu - uu * wv) / D;
if (t < 0.0f || (s + t) > 1.0f) // I is outside T
return false;
return true; // I is in T}
The first parts checks if the ray intersects the plane given by the triangle. The second part checks if the intersection points is inside the triangle to validate the triangle intersection.
My problem is, that the intersection point with the plane, which i get like
// intersect is the intersection point with the ray and the plane
*intersect = ray.origin + r * ray.direction;
is already wrong, while testing different plane intersecting rays bring me the right results with plane intersection if i return true right after...
I think about a normalize (or not normalize) error all the time, but im not sure about it.
The triangle has the coordinates:
triangle.v0 = ofVec3f(100.0, 50.0, 0.0);
triangle.v1 = ofVec3f(50.0, 150.0, 0.0);
triangle.v2 = ofVec3f(150.0, 150.0, 0.0);
and a ray, which should intersect
rayHit.origin = ofVec3f (100, 100, -100);
rayHit.direction = ofVec3f (1, 1, 1);
and a ray, which should NOT intersect
rayNoHit.origin = ofVec3f (200, 100, -100);
rayNoHit.direction = ofVec3f (1, 1, 1);
while a ray which not even goes through the plane validates me the functionality of intersecting the plane
rayNoPlaneHit.origin = ofVec3f(300, 100, -100);
rayNoPlaneHit.direction = ofVec3f(1, 1, 0);
I saw many different questions here about raycasting a triangle or plane, but i really think i got it already, only missing a little thing, which cost me hours already.
I would be so happy if somebody can help me. Thanks and best regards
Upvotes: 1
Views: 1242
Reputation: 445
Thank you cfh for the correct hint that my rayHit
intersects the z plane at (200,200,0)
. I did that wrong and rayHit
has now the right direction rayHit.direction = ofVec3f (0, 0, 1);
Therefore i can validate the functionality of intersecting the triangle plane now!
But my algorithm still returns the result that my (also corrected)
rayNoHit.origin = ofVec3f (200, 100, -100);
rayNoHit.direction = ofVec3f (0, 0, 1);
also is inside the triangle and i still have the problem that i can't validate that the point is inside the triangle the right way. Do i have a error in the barycentric coordinates solution or do i miss something else in the lower part of the algorithm?
Upvotes: 0
Reputation: 4666
There are two mistakes I can see: first, you specified the triangle in clockwise order, so its normal will point in negative z direction; the same direction that your ray points, so the hit will not register since the code checks for direction.
Second, your rayHit
intersects the z plane at (200, 200, 0)
, so your assumption that it intersects the triangle is wrong.
Upvotes: 0