#ifndef SPHERE_H #define SPHERE_H #include "hittable.hpp" #include "vec3.hpp" struct sphere : hittable { /* Attributes */ point3 center; float radius; std::shared_ptr mat_ptr; /* Contructor */ sphere(point3 c, float r, std::shared_ptr m) { center = c; radius = r; mat_ptr = m; } /* Virtual methods declaration */ bool hit(const ray& r, float t_min, float t_max, hit_record& rec) const; }; /* Virtual method implementations */ bool sphere::hit(const ray& r, float t_min, float t_max, hit_record& rec) const { /* NOTE: This function is called too many times (and too fast) for it to be profiled in a usual way using Remotery. */ TIMED_BLOCK(); vec3 oc = r.origin - center; float a = r.direction.length_squared(); float half_b = dot(oc, r.direction); float c = oc.length_squared() - radius*radius; float discriminant = half_b*half_b - a*c; if (discriminant < 0) return false; float sqrtd = sqrt(discriminant); // Find the nearest root that lies in the acceptable range float 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; } 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