void setup_lookat_transform(Transform M, Vect eye, Vect center, Vect up) { Vect n, u, v, t; int i; // rotational components VectSub(eye, center, n); // u = up x n VectCross(up, n, u); // v = n x u VectCross(n, u, v); // normalize n, u, v VectUnit(n); VectUnit(u); VectUnit(v); // translation t[X] = -VectDotProd(eye, u); t[Y] = -VectDotProd(eye, v); t[Z] = -VectDotProd(eye, n); // put it together for (i = 0; i < 3; i++) MATRC(M, 0, i) = u[i]; for (i = 0; i < 3; i++) MATRC(M, 1, i) = v[i]; for (i = 0; i < 3; i++) MATRC(M, 2, i) = n[i]; for (i = 0; i < 3; i++) MATRC(M, 3, i) = 0; for (i = 0; i < 3; i++) MATRC(M, i, 3) = t[i]; MATRC(M, 3, 3) = 1; // printf("lookat M = \n"); // TransformPrint(M); }
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 }
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; }