-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathSphere.cpp
71 lines (66 loc) · 2.42 KB
/
Sphere.cpp
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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
//
// Sphere.cpp
// Curvature
//
// Created by Simon Demeule on 2019-03-30.
// Copyright © 2019 Simon Demeule. All rights reserved.
//
#include "Sphere.hpp"
#include <algorithm>
Sphere::Sphere(glm::vec3 originNew, float radiusNew, ShadableAttributes* shadableAttributesNew) :
ShadableObject(shadableAttributesNew),
origin(originNew),
radius(radiusNew)
{
boundingBox.setPointPositive(glm::vec3(radiusNew) + originNew);
boundingBox.setPointNegative(- glm::vec3(radiusNew) + originNew);
primitiveCount = 1;
}
ShadableObjectIntersection Sphere::intersection(Ray ray) {
ShadableObjectIntersection intersection;
// code based on class notes
glm::vec3 delta = ray.origin - origin;
float b = 2.0 * glm::dot(ray.direction, delta);
float c = glm::dot(delta, delta) - radius * radius;
float n = b * b - 4.0 * c;
if(n < 0) {
// root doesn't exist
// exit calculation
intersection.exists = false;
return intersection;
}
float r = std::sqrt(n);
float t = (- b - r) / 2.0;
// the intersection with smallest distance is
// tmin = (- b - r) / 2.0
//
// the intersection with largest distance is
// tmax (- b + r) / 2.0
//
// in all cases, tmax geometrically corresponds to a backface intersection.
// this means we are only interested in tmin.
//
// if the ray is a camera ray, positive bias prevents intersection if the camera is at the surface of the sphere.
// if the ray is not a camera ray, negative bias ensures that objects which spawn a shadow ray on their surface will generate an intersection.
if(t < (ray.isCameraRay ? 1e-2 : -1e-2)) {
// the intersection is behind the ray's origin
// exit calculation
intersection.exists = false;
return intersection;
}
intersection.origin = ray.origin + ray.direction * t;
intersection.normal = (intersection.origin - origin) * (float)(1.0 / radius);
intersection.exists = true;
intersection.incident = ray.direction;
intersection.distance = t;
intersection.object = this;
intersection.objectIntersectionDepth = 1;
return intersection;
}
DistanceMeasure Sphere::distance(glm::vec3 point) {
DistanceMeasure distanceMeasure;
distanceMeasure.origin = point;
distanceMeasure.objectDistanceDepth = 1;
distanceMeasure.distance = std::max<float>(0, glm::length(point - origin) - radius);
return distanceMeasure;
}