HitRecord Plane::intersect(Ray ray) const { float d = -QVector3D::dotProduct(ray.getDirection(), planeVector.toVector3D()); float u = QVector4D::dotProduct(QVector4D(ray.getOrigin(), 1), planeVector); float t = u / d; if(ray.inRange(t)) { return HitRecord(t, ray, material, planeVector.toVector3D()); } else { return HitRecord(); } }
HitRecord AreaLight::intersect(Ray ray) const { QVector3D ad = ray.getOrigin() - origin; QVector3D abxac = QVector3D::crossProduct(uDirection, vDirection); float w = -QVector3D::dotProduct(abxac, ray.getDirection()); if(w == 0) return HitRecord(); float t = QVector3D::dotProduct(abxac, ad) / w; if(!ray.inRange(t)) return HitRecord(); QVector3D adxde = QVector3D::crossProduct(ad, ray.getDirection()); float u = QVector3D::dotProduct(adxde, vDirection) / w; if(u < 0 || u > 1) return HitRecord(); float v = -QVector3D::dotProduct(adxde, uDirection) / w; if(v < 0 || v > 1) return HitRecord(); return HitRecord(t, ray, this, normal); }
HitRecord BezierCurve::intersect(const Ray &ray, const double dist, const double time) const { HitRecord hit = HitRecord(dist); //These are the endpoints of the line segment double t = findIntersection(0.0, 1.0, ray); if (t != 0.0){ hit.hit(t, this, matl, ray, n); } return hit; }
std::pair<boost::optional<double>,HitRecord> Scene::hit(Ray r) { auto hit = std::make_pair(boost::optional<double>(), HitRecord()); // std::cout << r.depth << std::endl; if(bbox.hit(r)){ for(auto& s:shapes) { auto cHit = s->hit(r); auto m = min(hit.first,cHit.first); if(m != hit.first) { hit = cHit; } } } return hit; }
bool Disc::hit(const Ray& ray, const float& tmin, const float& tmax, const float& time, HitRecord& hitRecord) const { // o => origin of ray // d => direction of ray // p = o + t.d => equation of ray // // p => point on disc // c => center of disc // n => normal of disc // r => radius of disc // (p - c).n = 0 => equation of plane containing disc // // (o + t.d - c).n = 0 // o.n + t.d.n - c.n = 0 // t = (c - o).n / d.n // // p = o + t.d // (p - c).(p - c) < r.r float rdMultiplyDn = dot(ray.direction, normal); if (rdMultiplyDn != 0.0f) // TODO Epsilon { float t = dot((center - ray.origin), normal) / rdMultiplyDn; if (t >= tmin && t <= tmax) { Vec3 cp = ray.pointAtParameter(t) - center; if (dot(cp, cp) < radiusSquare) { hitRecord = HitRecord(t, normal, color); return true; } } } return false; }
bool Sphere::hit(const Ray& ray, const float& tmin, const float& tmax, const float& time, HitRecord& hitRecord) const { // Fast Ray Sphere Intersection - Jeff Hultquist // Graphics Gems I - Andrew S. Glassner - Page 388 Vec3 scSubtractRo = center - ray.origin; float scSubtractRoSquare = dot(scSubtractRo, scSubtractRo); float projection = dot(scSubtractRo, ray.direction); float discriminant = radiusSquare - (scSubtractRoSquare - (projection * projection)); if (discriminant > 0.0f) { // TODO Switch tmin tmax if required //tmin = projection - sqrt(discriminant); //tmax = projection + sqrt(discriminant); float discriminantSqrt = sqrtf(discriminant); float t = projection - discriminantSqrt; if (t < tmin) { t = projection + discriminantSqrt; } if (t >= tmin && t <= tmax) { // valid hit hitRecord = HitRecord(t, (ray.direction * t - scSubtractRo).normal(), color); return true; } } return false; }