| #ifndef SPHERE_H |
| #define SPHERE_H |
| //============================================================================================== |
| // Originally written in 2016 by Peter Shirley <ptrshrl@gmail.com> |
| // |
| // To the extent possible under law, the author(s) have dedicated all copyright |
| // and related and neighboring rights to this software to the public domain |
| // worldwide. This software is distributed without any warranty. |
| // |
| // You should have received a copy (see file COPYING.txt) of the CC0 Public |
| // Domain Dedication along with this software. If not, see |
| // <http://creativecommons.org/publicdomain/zero/1.0/>. |
| // |
| // The original source code is from |
| // https://github.com/RayTracing/raytracing.github.io/tree/release/src/InOneWeekend |
| // |
| // Changes to the original code follow the following license. |
| // |
| // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
| // See https://llvm.org/LICENSE.txt for license information. |
| // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
| //============================================================================================== |
| |
| #include "rtweekend.h" |
| |
| #include "hittable.h" |
| |
| class sphere : public hittable { |
| public: |
| __host__ __device__ sphere(point3 _center, double _radius, |
| SharedPtr<material> _material) |
| : center(_center), radius(_radius), mat(_material) {} |
| |
| __host__ __device__ bool hit(const ray &r, interval ray_t, |
| hit_record &rec) const override { |
| vec3 oc = r.origin() - center; |
| auto a = r.direction().length_squared(); |
| auto half_b = dot(oc, r.direction()); |
| auto c = oc.length_squared() - radius * radius; |
| |
| auto discriminant = half_b * half_b - a * c; |
| if (discriminant < 0) |
| return false; |
| |
| // Find the nearest root that lies in the acceptable range. |
| auto sqrtd = sqrt(discriminant); |
| auto root = (-half_b - sqrtd) / a; |
| if (!ray_t.surrounds(root)) { |
| root = (-half_b + sqrtd) / a; |
| if (!ray_t.surrounds(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 = mat; |
| |
| return true; |
| } |
| |
| private: |
| point3 center; |
| double radius; |
| SharedPtr<material> mat; |
| }; |
| |
| #endif |