-
Notifications
You must be signed in to change notification settings - Fork 0
/
aabb.cpp
122 lines (103 loc) · 2.8 KB
/
aabb.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
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
#include "aabb.hpp"
#include "vector3.hpp"
using namespace strangeloop;
AABB::AABB()
:center(0,0,0),size{0.0,0.0,0.0}
{
}
AABB::AABB(Point center, double size)
:center(center),size{size,size,size}
{
}
AABB::AABB(Point min, Point max)
:center((min[0] + max[0])/2,(min[1] + max[1])/2,(min[2] + max[2])/2),
size{fabs(min[0] - max[0])/2,fabs(min[1] - max[1])/2,fabs(min[2] - max[2])/2}
{
}
Point AABB::getMin() const
{
return Point(center[0] - size[0],center[1] - size[1],center[2] - size[2]);
}
Point AABB::getMax() const
{
return Point(center[0] + size[0],center[1] + size[1],center[2] + size[2]);
}
bool AABB::test(const AABB &target) const
{
return false;
}
bool AABB::test(const Ray &ray, Point &coord) const
{
const int NUMDIM = 3;
const int RIGHT = 0;
const int LEFT = 1;
const int MIDDLE = 2;
bool inside = true;
int whichPlane;
Vector3 maxT;
Vector3 quadrant;
Vector3 candidatePlane;
Point min = getMin();
Point max = getMax();
Point origin = ray.origin();
Vector3 direction = ray.direction();
// Find the candidate planes.
for (int i = 0; i < NUMDIM; i++) {
if (origin[i] < min[i]) {
quadrant[i] = LEFT;
candidatePlane[i] = min[i];
inside = false;
} else if (origin[i] > max[i]) {
quadrant[i] = RIGHT;
candidatePlane[i] = max[i];
inside = false;
} else {
quadrant[i] = MIDDLE;
}
}
// If the ray origin is inside the bounding box, return the origin as the coordinate
// and return the test as true.
if (inside) {
coord = origin;
return true;
}
// Calculate the T distances to the candidate planes.
for (int i = 0; i < NUMDIM; i++) {
if (quadrant[i] != MIDDLE && direction[i] != 0.0) {
maxT[i] = (candidatePlane[i] - origin[i]) / direction[i];
} else {
maxT[i] = -1.0;
}
}
// Get the largest of the T distances to get the actual intersection plane.
whichPlane = 0;
for (int i = 0; i < NUMDIM; i++) {
if (maxT[whichPlane] < maxT[i]) {
whichPlane = i;
}
}
if (maxT[whichPlane] < 0.0) {
return false;
}
for (int i = 0; i < NUMDIM; i++) {
if (whichPlane != i) {
coord[i] = origin[i] + maxT[whichPlane] * direction[i];
if (coord[i] < min[i] || coord[i] > max[i]) {
return false;
}
} else {
coord[i] = candidatePlane[i];
}
}
return true;
}
bool AABB::test(const Sphere &sphere) const
{
Point min = getMin();
Point max = getMax();
Point center = sphere.center();
double radius = sphere.radius();
double a, b, dmin, dmax;
double r2 = sqrt(radius);
return true;
}