2 #include "InfinitePlane.hxx"
4 Box::Box() : m_min(Infinity
, Infinity
, Infinity
),
5 m_max(-Infinity
, -Infinity
, -Infinity
)
9 Box::Box(Vec3f min
, Vec3f max
) : m_min(min
), m_max(max
)
17 Box::Box(const Box
& b
)
24 Box::operator=(const Box
& b
)
34 m_min
= Vec3f(Infinity
, Infinity
, Infinity
);
35 m_max
= Vec3f(-Infinity
, -Infinity
, -Infinity
);
39 Box::Extend(const Vec3f
& a
)
41 // for all three coordinates, move m_max or m_min to the point
42 for(size_t i
= 0; i
< 3; i
++) {
45 } else if(a
[i
] < m_min
[i
]) {
47 } // else: do nothing, coordinate is inside the box
52 Box::Extend(const Box
& box
)
58 bool Box::OverlapsHelper(Box b
) const {
60 for(size_t i
= 0; i
< 3; i
++) {
62 (m_min
[i
] < b
.min()[i
] && b
.min()[i
] < m_max
[i
]) ||
63 (m_min
[i
] < b
.max()[i
] && b
.min()[i
] < m_max
[i
]) ||
64 (m_min
[i
] > b
.min()[i
] && b
.min()[i
] > m_max
[i
]) ||
65 (m_min
[i
] > b
.max()[i
] && b
.min()[i
] > m_max
[i
]);
71 Box::Overlaps(const Box
& b
) const
73 // Boxes overlap if b.m_min or b.m_max are between our m_max and m_min
75 bool overlaps
= OverlapsHelper(b
);
77 // if that is not enough, swap y coordinates, we could have the following
78 // (sample for 2-dimensional case):
80 // | | + denotes crossing,
81 // -----+----o | o denotes min/max point
89 Vec3f
new_min(min
[0], max
[1], min
[2]);
90 Vec3f
new_max(max
[0], min
[1], max
[2]);
91 Box
new_y_box(new_min
, new_max
);
92 overlaps
= OverlapsHelper(new_y_box
);
94 // and now for y and z coordinates also
96 min
= new_y_box
.min();
97 max
= new_y_box
.max();
98 new_min
= Vec3f(min
[0], min
[1], max
[2]);
99 new_max
= Vec3f(max
[0], max
[1], min
[2]);
100 Box
new_yz_box(new_min
, new_max
);
101 overlaps
= OverlapsHelper(new_yz_box
);
103 // and now for only z coordinates
105 min
= new_y_box
.min();
106 max
= new_y_box
.max();
107 new_min
= Vec3f(min
[0], max
[1], min
[2]);
108 new_max
= Vec3f(max
[0], min
[1], max
[2]);
109 Box
new_z_box(new_min
, new_max
);
110 overlaps
= OverlapsHelper(new_z_box
);
111 // at this point, we do not need to swap further, as either m_max or
112 // m_min has been tested inside b.
121 Box::Clip(const Ray
& ray
, float& tnear
, float& tfar
) const
123 // Note: equations here are the same as in InfinitePlane::Intersect()
124 // t = ((o-a)*n) / (d*n)
125 // o = ray.origin(), d = ray.direction(),
126 // n = surface normal of plane, a = anchor point of plane
127 Vec3f diff_min
= m_min
- ray
.origin(); // o-a
128 Vec3f diff_max
= m_max
- ray
.origin();
130 float cos_theta
, temp
;
131 float tx_near
= -Infinity
, tx_far
= Infinity
,
132 ty_near
= -Infinity
, ty_far
= Infinity
,
133 tz_near
= -Infinity
, tz_far
= Infinity
;
136 if((cos_theta
= ray
.direction().dot(Vec3f(1,0,0))) != 0) // if not parallel...
137 tx_near
= diff_min
.dot(Vec3f(1,0,0)) / cos_theta
;
138 if((cos_theta
= ray
.direction().dot(Vec3f(1,0,0))) != 0)
139 tx_far
= diff_max
.dot(Vec3f(1,0,0)) / cos_theta
;
141 // we don't know which is nearer, m_min or m_max, so swap them if neccessary
142 if(tx_near
> tx_far
) {
148 // do the same for y axis
149 if((cos_theta
= ray
.direction().dot(Vec3f(0,1,0))) != 0)
150 ty_near
= diff_min
.dot(Vec3f(0,1,0)) / cos_theta
;
151 if((cos_theta
= ray
.direction().dot(Vec3f(0,1,0))) != 0)
152 ty_far
= diff_max
.dot(Vec3f(0,1,0)) / cos_theta
;
153 if(ty_near
> ty_far
) {
160 if((cos_theta
= ray
.direction().dot(Vec3f(0,0,1))) != 0)
161 tz_near
= diff_min
.dot(Vec3f(0,0,1)) / cos_theta
;
162 if((cos_theta
= ray
.direction().dot(Vec3f(0,0,1))) != 0)
163 tz_far
= diff_max
.dot(Vec3f(0,0,1)) / cos_theta
;
164 if(tz_near
> tz_far
) {
170 // now the maximum of "near"s is the entry point of the ray, the minimum
171 // of "far"s is the ray's exit point. Visually speaking: the ray must cross
172 // all three "near" planes before it can be inside the box.
173 // Note: If t_near_max > t_far_min, the ray does not intersect the box
174 tnear
= fmax(fmax(tx_near
, ty_near
), tz_near
);
175 tfar
= fmin(fmin(tx_far
, ty_far
), tz_far
);
This page took 0.058683 seconds and 5 git commands to generate.