#ifndef SPHERE_H #define SPHERE_H #include "hittable.hpp" #include "vec3.hpp" struct sphere : hittable { /* Attributes */ point3 center; double radius; std::shared_ptr mat_ptr; /* Contructor */ sphere(point3 c, double r, std::shared_ptr m) { center = c; radius = r; mat_ptr = m; } /* Virtual methods declaration */ virtual bool hit(const ray& r, double t_min, double t_max, hit_record& rec) const override; }; /* Virtual method implementations */ bool sphere::hit(const ray& r, double t_min, double t_max, hit_record& rec) const { rmt_ScopedCPUSample(Sphere_Hit, RMTSF_Aggregate); // Part 1 vec3 oc = r.origin - center; double a = r.direction.length_squared(); double half_b = dot(oc, r.direction); double c = oc.length_squared() - radius*radius; // Part 2 double discriminant = half_b*half_b - a*c; if (discriminant < 0) return false; double sqrtd = sqrt(discriminant); // Find the nearest root that lies in the acceptable range // Part 3 double root = (-half_b - sqrtd) / a; if (root < t_min || t_max < root) { root = (-half_b + sqrtd) / a; if (root < t_min || t_max < root) return false; } // Part 4 rec.t = root; rec.p = r.at(rec.t); vec3 outward_normal = (rec.p - center) / radius; rec.set_face_normal(r, outward_normal); rec.mat_ptr = mat_ptr; return true; } #endif