/
dynsphere.cpp
84 lines (66 loc) · 2.29 KB
/
dynsphere.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
72
73
74
75
76
77
78
79
80
81
82
83
84
// DynSphere.cpp
#include "dynsphere.h"
DynSphere::DynSphere(const Vector3& pos, float r, const rgb& col, float mintime, float maxtime)
: center (pos)
, radius (r)
, color (col)
, min_time (mintime)
, max_time (maxtime)
{ /* DO_NOTHING */ }
bool DynSphere::hit(const Ray& ray, float tmin, float tmax, float time, HitRecord& record) const
{
auto new_center = getCenter(time);
auto temp = ray.origin() - new_center;
double a = dot(ray.direction(), ray.direction());
double b = 2 * dot(ray.direction(), temp);
double c = dot(temp, temp) - radius * radius;
double discriminant = b * b - 4 * a * c;
// first check to see if ray intersects sphere
if (discriminant > 0)
{
discriminant = sqrt(discriminant);
double t = (-b - discriminant) / (2 * a);
// now check for valid interval
if (t < tmin)
{ t = (-b + discriminant) / (2 * a); }
if (t < tmin || t > tmax)
{ return false; }
// we have a valid hit
record.t = float(t);
record.normal = unitVector(ray.origin() + float(t) * ray.direction() - new_center);
record.color = color;
return true;
}
return false;
}
bool DynSphere::shadowHit(const Ray& ray, float tmin, float tmax, float time) const
{
auto new_center = getCenter(time);
auto temp = ray.origin() - new_center;
double a = dot(ray.direction(), ray.direction());
double b = 2 * dot(ray.direction(), temp);
double c = dot(temp, temp) - radius * radius;
double discriminant = b * b - 4 * a * c;
// first check to see if ray intersects sphere
if (discriminant > 0)
{
discriminant = sqrt(discriminant);
double t = (-b - discriminant) / (2 * a);
// now check for valid interval
if (t < tmin)
{ t = (-b + discriminant) / (2 * a); }
if (t < tmin || t > tmax)
{ return false; }
// we have a valid hit
return true;
}
return false;
}
Vector3 DynSphere::getCenter(float time) const
{
auto real_time = time * max_time + (1.0f - time) * min_time;
return Vector3(
center.x() + real_time,
center.y() + real_time,
center.z() + real_time);
}