I realize this topic is covered extensively, but I've looked at dozens of academic presentations and I can't seem to make any of them work.
I am attempting to detect a) whether a ray (poiint/direction) intersects with a given triangle and b) where (in world coordinates). I adapted the following code from the lighthouse 3D article:
[source lang="cpp"]int isx3d(Line3D line, Plane3D plane, Number3D *where) { Number3D e1 = vec3d(plane.v0, plane.v1); Number3D e2 = vec3d(plane.v0, plane.v2); Number3D h = cross3d(line.p1, e2); float a = dot3d(e1, h); if (a > -0.00001 && a < 0.00001) //(close_enough(a, 0.0f)) return FALSE; float f = 1.0f/a; Number3D s = vec3d(plane.v0, line.p0); float u = f*dot3d(s,h); if (u < 0.0f || u > 1.0f) return FALSE; Number3D q = cross3d(s, e1); float v = f*dot3d(line.p1,q); if (v < 0.0f || u+v > 1.0f) return FALSE; float t = f*dot3d(e2, q); if (t > 0.00001) { float w = 1.0f-(u+v); Number3D ww; ww.x = w*plane.v0.x+u*plane.v1.x+v*plane.v2.x; ww.y = w*plane.v0.y+u*plane.v1.y+v*plane.v2.y; ww.z = w*plane.v0.z+u*plane.v1.z+v*plane.v2.z; *where = ww; return TRUE; } return FALSE;}[/source]
This code seems very similar to other examples, but it has a couple of problems:
First, it works when the point of origin is on the negative side of the triangle, but when the point of origin is on the positive side, it can trigger a false positive result (as if it is considering the ray being cast negatively from the point of origin as well).
Second, the resulting point is wrong. I have tried transforming this every way I can think of, but it either walks across the face of the triangle in a diagonal line (instead of horizontally if I just moving the point of of origin on the X/Y plane) or it moves along a curve(?).
Show differencesHistory of post edits
#1kmx
Posted 21 July 2012 - 07:30 PM
I realize this topic is covered extensively, but I've looked at dozens of academic presentations and I can't seem to make any of them work.
I am attempting to detect a) whether a ray (poiint/direction) intersects with a given triangle. I adapted the following code from the lighthouse 3D article:
[source lang="cpp"]int isx3d(Line3D line, Plane3D plane, Number3D *where) { Number3D e1 = vec3d(plane.v0, plane.v1); Number3D e2 = vec3d(plane.v0, plane.v2); Number3D h = cross3d(line.p1, e2); float a = dot3d(e1, h); if (a > -0.00001 && a < 0.00001) //(close_enough(a, 0.0f)) return FALSE; float f = 1.0f/a; Number3D s = vec3d(plane.v0, line.p0); float u = f*dot3d(s,h); if (u < 0.0f || u > 1.0f) return FALSE; Number3D q = cross3d(s, e1); float v = f*dot3d(line.p1,q); if (v < 0.0f || u+v > 1.0f) return FALSE; float t = f*dot3d(e2, q); if (t > 0.00001) { float w = 1.0f-(u+v); Number3D ww; ww.x = w*plane.v0.x+u*plane.v1.x+v*plane.v2.x; ww.y = w*plane.v0.y+u*plane.v1.y+v*plane.v2.y; ww.z = w*plane.v0.z+u*plane.v1.z+v*plane.v2.z; *where = ww; return TRUE; } return FALSE;}[/source]
This code seems very similar to other examples, but it has a couple of problems:
First, it works when the point of origin is on the negative side of the triangle, but when the point of origin is on the positive side, it can trigger a false positive result (as if it is considering the ray being cast negatively from the point of origin as well).
Second, the resulting point is wrong. I have tried transforming this every way I can think of, but it either walks across the face of the triangle in a diagonal line (instead of horizontally if I just moving the point of of origin on the X/Y plane) or it moves along a curve(?).
I am attempting to detect a) whether a ray (poiint/direction) intersects with a given triangle. I adapted the following code from the lighthouse 3D article:
[source lang="cpp"]int isx3d(Line3D line, Plane3D plane, Number3D *where) { Number3D e1 = vec3d(plane.v0, plane.v1); Number3D e2 = vec3d(plane.v0, plane.v2); Number3D h = cross3d(line.p1, e2); float a = dot3d(e1, h); if (a > -0.00001 && a < 0.00001) //(close_enough(a, 0.0f)) return FALSE; float f = 1.0f/a; Number3D s = vec3d(plane.v0, line.p0); float u = f*dot3d(s,h); if (u < 0.0f || u > 1.0f) return FALSE; Number3D q = cross3d(s, e1); float v = f*dot3d(line.p1,q); if (v < 0.0f || u+v > 1.0f) return FALSE; float t = f*dot3d(e2, q); if (t > 0.00001) { float w = 1.0f-(u+v); Number3D ww; ww.x = w*plane.v0.x+u*plane.v1.x+v*plane.v2.x; ww.y = w*plane.v0.y+u*plane.v1.y+v*plane.v2.y; ww.z = w*plane.v0.z+u*plane.v1.z+v*plane.v2.z; *where = ww; return TRUE; } return FALSE;}[/source]
This code seems very similar to other examples, but it has a couple of problems:
First, it works when the point of origin is on the negative side of the triangle, but when the point of origin is on the positive side, it can trigger a false positive result (as if it is considering the ray being cast negatively from the point of origin as well).
Second, the resulting point is wrong. I have tried transforming this every way I can think of, but it either walks across the face of the triangle in a diagonal line (instead of horizontally if I just moving the point of of origin on the X/Y plane) or it moves along a curve(?).