Strange problem with Möller ray/triangle intersection test

Started by
3 comments, last by ZiM 20 years, 6 months ago
Möller's ray/tri intersection test indicates an intersection when certain values are used, although in reality there shouldn't be any (drew it on paper to verify this); Ray origin is (48, 32, 64) Ray direction is (-48, 32, 0) Triangles vertices, counter-clockwise: (128, 64, 128), (64, 64, 108.8), (64, 64, 0) Debugging reveals that the determinant value from first dot product seems to be wrong. When I place breakpoint right after it debugger says det=222822. and calculating it by hand with calculator gives 301465.6 - could it be that this is too big value for floating point representation?

static bool RayTriIntersect(Vector &o, Vector &d, Vector &v1, Vector &v2, Vector &v3, Vector &ptHit)
{
	// Computes the intersection point of given ray and triangle if there is one.
	// Returns: true  if there is intersection and stores the isect point in ptHit
	//          false if given ray and triangle do not intersect
	Vector s, p, q, e1, e2;
	float  u, v, t, det, detInv;

	e1 = v2 - v1;
	e2 = v3 - v1;

	p = Vector::CrossProduct(d, e2);
	det = Vector::DotProduct(e1, p);

	if(det < M_EPSILON)
		return false;

	detInv = 1.0/det;

	s = o - v1;	
	u = detInv * Vector::DotProduct(s, p);

	if(u < 0 || u > det)
		return false;

	q = Vector::CrossProduct(s, e1);
	v = detInv * Vector::DotProduct(d, q);

	if(v < 0 || u+v > det)
		return false;

	t = detInv * Vector::DotProduct(e2, q);

	if(t > 1) // Make sure it's not longer than the original ray
		return false;

	ptHit = v1*(1 - u - v) + v2*u + v3*v;
	return true;
}
   
[edited by - ZiM on October 14, 2003 5:28:12 AM]
Advertisement
I've got the same result as the computer. det = 222822.4f

so I guess YOU are wrong

e1 = (-64, 0, -19.2)e2 = (-64, 0, -128)d  = (-48, 32, 0)p.x = 32 * -128   -   0p.y =    0        -   (-48 * -128)p.z =    0        -   ( 32 * -64)p   = (-4096, -6144, 2048)det = -4096 * -64 +   0   +   -19.2 * 2048det = 222822.4


[edited by - oliii on October 14, 2003 12:12:54 PM]

Everything is better with Metal.

Seems like you were right. I get the same result now.

I managed to fix the problem by replacing
if(u < 0 || u > det) 
with
if(u < 0 || u > 1.0) 
, same for the u+v.

I wonder why the original code at http://www.acm.org/jgt/papers/MollerTrumbore97/code.html have these...
maybe because they assumed the ray direction was normalised. I'll check the algorithm later, as I use it myself, but I always use it with normalised ray. If you are right, good find. You may want to check your changes with a non-orthogonal triangle.

[edited by - oliii on October 14, 2003 12:58:36 PM]

Everything is better with Metal.

if you assume that the ray direction is normalized then
ASSERT it using assert() or any other method.
That will save you a lot of pain in general.
Act of War - EugenSystems/Atari

This topic is closed to new replies.

Advertisement