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
++) {
48 } // else: do nothing, coordinate is inside the box
53 Box::Extend(const Box
& box
)
59 bool Box::OverlapsHelper(Box b
) const {
61 for(size_t i
= 0; i
< 3; i
++) {
63 (m_min
[i
] < b
.min()[i
] && b
.min()[i
] < m_max
[i
]) ||
64 (m_min
[i
] < b
.max()[i
] && b
.min()[i
] < m_max
[i
]) ||
65 (m_min
[i
] > b
.min()[i
] && b
.min()[i
] > m_max
[i
]) ||
66 (m_min
[i
] > b
.max()[i
] && b
.min()[i
] > m_max
[i
]);
72 Box::Overlaps(const Box
& b
) const
74 // Boxes overlap if b.m_min or b.m_max are between our m_max and m_min
76 bool overlaps
= OverlapsHelper(b
);
78 // if that is not enough, swap y coordinates, we could have the following
79 // (sample for 2-dimensional case):
81 // | | + denotes crossing,
82 // -----+----o | o denotes min/max point
90 Vec3f
new_min(min
[0], max
[1], min
[2]);
91 Vec3f
new_max(max
[0], min
[1], max
[2]);
92 Box
new_y_box(new_min
, new_max
);
93 overlaps
= OverlapsHelper(new_y_box
);
95 // and now for y and z coordinates also
97 min
= new_y_box
.min();
98 max
= new_y_box
.max();
99 new_min
= Vec3f(min
[0], min
[1], max
[2]);
100 new_max
= Vec3f(max
[0], max
[1], min
[2]);
101 Box
new_yz_box(new_min
, new_max
);
102 overlaps
= OverlapsHelper(new_yz_box
);
104 // and now for only z coordinates
106 min
= new_y_box
.min();
107 max
= new_y_box
.max();
108 new_min
= Vec3f(min
[0], max
[1], min
[2]);
109 new_max
= Vec3f(max
[0], min
[1], max
[2]);
110 Box
new_z_box(new_min
, new_max
);
111 overlaps
= OverlapsHelper(new_z_box
);
112 // at this point, we do not need to swap further, as either m_max or
113 // m_min has been tested inside b.
122 Box::Clip(const Ray
& ray
, float& tnear
, float& tfar
) const
124 // Note: equations here are the same as in InfinitePlane::Intersect()
125 // t = ((o-a)*n) / (d*n)
126 // o = ray.origin(), d = ray.direction(),
127 // n = surface normal of plane, a = anchor point of plane
128 Vec3f diff_min
= m_min
- ray
.origin(); // o-a
129 Vec3f diff_max
= m_max
- ray
.origin();
131 float cos_theta
, temp
;
132 float tx_near
= -Infinity
, tx_far
= Infinity
,
133 ty_near
= -Infinity
, ty_far
= Infinity
,
134 tz_near
= -Infinity
, tz_far
= Infinity
;
137 if((cos_theta
= ray
.direction().dot(Vec3f(1,0,0))) != 0) // if not parallel...
138 tx_near
= diff_min
.dot(Vec3f(1,0,0)) / cos_theta
;
139 if((cos_theta
= ray
.direction().dot(Vec3f(1,0,0))) != 0)
140 tx_far
= diff_max
.dot(Vec3f(1,0,0)) / cos_theta
;
142 // we don't know which is nearer, m_min or m_max, so swap them if neccessary
143 if(tx_near
> tx_far
) {
149 // do the same for y axis
150 if((cos_theta
= ray
.direction().dot(Vec3f(0,1,0))) != 0)
151 ty_near
= diff_min
.dot(Vec3f(0,1,0)) / cos_theta
;
152 if((cos_theta
= ray
.direction().dot(Vec3f(0,1,0))) != 0)
153 ty_far
= diff_max
.dot(Vec3f(0,1,0)) / cos_theta
;
154 if(ty_near
> ty_far
) {
161 if((cos_theta
= ray
.direction().dot(Vec3f(0,0,1))) != 0)
162 tz_near
= diff_min
.dot(Vec3f(0,0,1)) / cos_theta
;
163 if((cos_theta
= ray
.direction().dot(Vec3f(0,0,1))) != 0)
164 tz_far
= diff_max
.dot(Vec3f(0,0,1)) / cos_theta
;
165 if(tz_near
> tz_far
) {
171 // now the maximum of "near"s is the entry point of the ray, the minimum
172 // of "far"s is the ray's exit point. Visually speaking: the ray must cross
173 // all three "near" planes before it can be inside the box.
174 // Note: If t_near_max > t_far_min, the ray does not intersect the box
175 tnear
= fmax(fmax(tx_near
, ty_near
), tz_near
);
176 tfar
= fmin(fmin(tx_far
, ty_far
), tz_far
);
This page took 0.075177 seconds and 5 git commands to generate.