-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSphere.cpp
More file actions
40 lines (26 loc) · 1.74 KB
/
Copy pathSphere.cpp
File metadata and controls
40 lines (26 loc) · 1.74 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include "Sphere.h"
namespace RayTracer {
Sphere::Sphere() : Sphere({0, 0, 0}, 1) {}
Sphere::Sphere(const glm::vec3& center, const float radius) : Sphere(center, radius, {0.3, 0.3, 0.3}, 0) {}
Sphere::Sphere(const glm::vec3& center, const float radius, const glm::vec3& color, const float metalness) : Geometry(color, metalness), center(center), radius(radius) {}
Intersection Sphere::intersect(const Ray& ray) const
{
// https://en.wikipedia.org/wiki/Line%E2%80%93sphere_intersection
const float uoc = glm::dot(ray.getDirection(), ray.getOrigin() - center);
const float ocLength = glm::length(ray.getOrigin() - center);
const float delta = (uoc * uoc) - ((ocLength * ocLength) - (radius * radius));
if (delta < 0) return {false, {}, std::numeric_limits<float>::infinity(), this};
const float deltaSqrt = std::sqrt(delta);
const float d1 = -uoc + deltaSqrt;
if (delta == 0) return {true, ray.getOrigin() + d1 * ray.getDirection(), d1, this};
const float d2 = -uoc - deltaSqrt;
if (d1 < 0 && d2 < 0) return {false, {}, std::numeric_limits<float>::infinity(), this};
else if (d1 < 0) return {true, ray.getOrigin() + d2 * ray.getDirection(), d2, this};
else if (d2 < 0) return {true, ray.getOrigin() + d1 * ray.getDirection(), d1, this};
return (d1 - d2 <= 0) ? Intersection{true, ray.getOrigin() + d1 * ray.getDirection(), d1, this} : Intersection{true, ray.getOrigin() + d2 * ray.getDirection(), d2, this};
}
Ray Sphere::reflectRay(const Ray& ray, const Intersection& intersection) const
{
return {intersection.position, glm::reflect(ray.getDirection(), glm::normalize(intersection.position - center))};
}
} // RayTracer