Esempio n. 1
0
Intersection *intersect_ray_triangle(Ray *ray, Vect V0, Vect V1, Vect V2)
{
	Vect    u, v, n;        // triangle vectors
	Vect    w0, w;          // ray vectors
	float   a, b;           // params to calc ray-plane intersect
	float t;
	Vect I;
	Intersection *inter;

	// get triangle edge vectors and plane normal

	VectSub(V1, V0, u);
	VectSub(V2, V0, v);
	VectCross(u, v, n);  
	if (n[X] == 0 && n[Y] == 0 && n[Z] == 0)            // triangle is degenerate; do not deal with this case
		return NULL;               

	VectSub(ray->orig, V0, w0);
	a = -VectDotProd(n,w0);
	b = VectDotProd(n,ray->dir);

	if (fabs(b) < SMALL_NUM) {     // ray is parallel to triangle plane
		if (a == 0)                  // case 1: ray lies in triangle plane
			return NULL;
		else return NULL;               // case 2: ray disjoint from plane
	}

	// get intersect point of ray with triangle plane

	t = a / b;
	if (t < rayeps)                   // triangle is behind/too close to ray => no intersect
		return NULL;                 // for a segment, also test if (t > 1.0) => no intersect

	// intersect point of ray and plane

	VectAddS(t, ray->dir, ray->orig, I);        

	// is I inside T?

	float    uu, uv, vv, wu, wv, D;
	uu = VectDotProd(u,u);
	uv = VectDotProd(u,v);
	vv = VectDotProd(v,v);
	VectSub(I, V0, w);
	wu = VectDotProd(w,u);
	wv = VectDotProd(w,v);
	D = uv * uv - uu * vv;

	// get and test parametric (i.e., barycentric) coords

	float p, q;  // were s, t in original code
	p = (uv * wv - vv * wu) / D;
	if (p < 0.0 || p > 1.0)        // I is outside T
		return NULL;
	q = (uv * wu - uu * wv) / D;
	if (q < 0.0 || (p + q) > 1.0)  // I is outside T
		return NULL;

	inter = make_intersection();
	inter->t = t;
	VectCopy(inter->P, I);
	return inter;                      // I is in T
}
Esempio n. 2
0
void reflection_direction(Vect incoming, Vect norm, Vect outgoing)
{
	VectAddS(-2 * VectDotProd(incoming, norm), norm, incoming, outgoing);
}
Esempio n. 3
0
File: udray.cpp Progetto: ReeLiu/ray
Intersection *intersect_ray_triangle(Ray *ray, Vect V0, Vect V1, Vect V2)
{
	//Vect    u, v, n;        // triangle vectors
	//Vect    w0, w;          // ray vectors
	//float   a, b;           // params to calc ray-plane intersect
	//float t;
	//Vect I;
	//Intersection *inter;

	//// get triangle edge vectors and plane normal

	//VectSub(V1, V0, u);
	//VectSub(V2, V0, v);
	//VectCross(u, v, n);
	//if (n[X] == 0 && n[Y] == 0 && n[Z] == 0)            // triangle is degenerate; do not deal with this case
	//	return NULL;

	//VectSub(ray->orig, V0, w0);
	//a = -VectDotProd(n, w0);
	//b = VectDotProd(n, ray->dir);

	//if (fabs(b) < SMALL_NUM) {     // ray is parallel to triangle plane
	//	if (a == 0)                  // case 1: ray lies in triangle plane
	//		return NULL;
	//	else return NULL;               // case 2: ray disjoint from plane
	//}

	//// get intersect point of ray with triangle plane

	//t = a / b;
	//if (t < rayeps)                   // triangle is behind/too close to ray => no intersect
	//	return NULL;                 // for a segment, also test if (t > 1.0) => no intersect

	//								 // intersect point of ray and plane

	//VectAddS(t, ray->dir, ray->orig, I);

	//// is I inside T?

	//float    uu, uv, vv, wu, wv, D;
	//uu = VectDotProd(u, u);
	//uv = VectDotProd(u, v);
	//vv = VectDotProd(v, v);
	//VectSub(I, V0, w);
	//wu = VectDotProd(w, u);
	//wv = VectDotProd(w, v);
	//D = uv * uv - uu * vv;

	//// get and test parametric (i.e., barycentric) coords

	//float p, q;  // were s, t in original code
	//p = (uv * wv - vv * wu) / D;
	//if (p < 0.0 || p > 1.0)        // I is outside T
	//	return NULL;
	//q = (uv * wu - uu * wv) / D;
	//if (q < 0.0 || (p + q) > 1.0)  // I is outside T
	//	return NULL;

	//inter = make_intersection();
	//inter->t = t;
	//VectCopy(inter->P, I);
	//return inter;                      // I is in T

	Vect e1, e2, T, P, Q;
	double det, t, u1, v1;
	VectSub(V1, V0, e1);
	VectSub(V2, V0, e2);
	VectSub(ray->orig, V0, T);
	VectCross(ray->dir, e2, P);

	det = VectDotProd(P, e1);
	if (det < 0.0f)
	{
		VectNegate(T, T);
		det = -det;
	}

	// ray parallel to triangle plane
	if (det < SMALL_NUM)
		return NULL;

	u1 = VectDotProd(P, T);
	if (u1 < 0.0f || u1 > det)
		return NULL;

	VectCross(T, e1, Q);
	
	v1 = VectDotProd(Q, ray->dir);
	if (v1 < SMALL_NUM || v1 + u1 > det)
		return NULL;

	t = VectDotProd(Q, e2);

	if (t < 0.0f)
		return NULL;

	t /= det;

	Intersection* inter = make_intersection();
	VectAddS(t, ray->dir, ray->orig, inter->P);
	inter->t = t;

	return inter;
}