// Source http://geomalgorithms.com/a06-_intersect-2.html#intersect3D_RayTriangle%28%29 RayHit Triangle3d::CalculateCollision(Line3d line) { float r, a, b; // params to calc ray-plane intersect Vector3d dir = line.direction; // ray direction vector Vector3d w0 = Vector3d(line.position, this->a); a = -Vector3d::dotProduct(normal, w0); b = Vector3d::dotProduct(normal, dir); if(abs(b) < 0.000001f) { // ray is parallel to triangle plane return RayHit(); // Disjoint. no intersect } // get intersect point of ray with triangle plane r = a / b; if(r < 0.0) // ray points away from triangle return RayHit(); // => no intersect // for a segment, also test if (r > 1.0) => no intersect Point3d I = line.getPositionAlongLine(r); // intersect point of ray and plane // is I inside T? float uu, uv, vv, wu, wv, D; uu = Vector3d::dotProduct(u, u); uv = Vector3d::dotProduct(u, v); vv = Vector3d::dotProduct(v, v); Vector3d w = Vector3d(I, this->a); wu = Vector3d::dotProduct(w, u); wv = Vector3d::dotProduct(w, v); D = uv * uv - uu * vv; // get and test parametric coords float s, t; s = (uv * wv - vv * wu) / D; if(s < 0.0 || s > 1.0) // I is outside T return RayHit(); t = (uv * wu - uu * wv) / D; if(t < 0.0 || (s + t) > 1.0) // I is outside T return RayHit(); return RayHit(I,normal); // I is in T }
Color Trace(Ray& R, int lev) // trace a ray { RayHit hit = RayHit(MISS, 0, Vector(0, 0, 0), false); if (lev > MAX_RECURSION_LEVEL) return defColor; int hitObj = -1; for (int i = 0; i < nObjs; i++) { RayHit h = theShapes[i]->intersect(R); if (h.status != MISS && h.tValue < R.tValue) { hitObj = i; hit = h; R.tValue = h.tValue; } } if (hitObj < 0) return defColor; else return Shade(hitObj, R, hit, lev); }