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
)
37 Box::Extend(const Vec3f
& a
)
39 // for all three coordinates, move m_max or m_min to the point
40 for(size_t i
= 0; i
< 3; i
++) {
43 } else if(a
[i
] < m_min
[i
]) {
45 } // else: do nothing, coordinate is inside the box
50 Box::Extend(const Box
& box
)
54 bool Box::OverlapsHelper(Box b
) const {
56 for(size_t i
= 0; i
< 3; i
++) {
58 (m_min
[i
] < b
.min()[i
] && b
.min()[i
] < m_max
[i
]) ||
59 (m_min
[i
] < b
.max()[i
] && b
.min()[i
] < m_max
[i
]) ||
60 (m_min
[i
] > b
.min()[i
] && b
.min()[i
] > m_max
[i
]) ||
61 (m_min
[i
] > b
.max()[i
] && b
.min()[i
] > m_max
[i
]);
67 Box::Overlaps(const Box
& b
) const
69 // Boxes overlap if b.m_min or b.m_max are between our m_max and m_min
71 bool overlaps
= OverlapsHelper(b
);
73 // if that is not enough, swap y coordinates, we could have the following
74 // (sample for 2-dimensional case):
76 // | | + denotes crossing,
77 // -----+----o | o denotes min/max point
85 Vec3f
new_min(min
[0], max
[1], min
[2]);
86 Vec3f
new_max(max
[0], min
[1], max
[2]);
87 Box
new_y_box(new_min
, new_max
);
88 overlaps
= OverlapsHelper(new_y_box
);
90 // and now for y and z coordinates also
92 min
= new_y_box
.min();
93 max
= new_y_box
.max();
94 new_min
= Vec3f(min
[0], min
[1], max
[2]);
95 new_max
= Vec3f(max
[0], max
[1], min
[2]);
96 Box
new_yz_box(new_min
, new_max
);
97 overlaps
= OverlapsHelper(new_yz_box
);
99 // and now for only z coordinates
101 min
= new_y_box
.min();
102 max
= new_y_box
.max();
103 new_min
= Vec3f(min
[0], max
[1], min
[2]);
104 new_max
= Vec3f(max
[0], min
[1], max
[2]);
105 Box
new_z_box(new_min
, new_max
);
106 overlaps
= OverlapsHelper(new_z_box
);
107 // at this point, we do not need to swap further, as either m_max or
108 // m_min has been tested inside b.
117 Box::Clip(const Ray
& ray
, float& tnear
, float& tfar
) const
119 // Note: equations here are the same as in InfinitePlane::Intersect()
120 // t = ((o-a)*n) / (d*n)
121 // o = ray.origin(), d = ray.direction(),
122 // n = surface normal of plane, a = anchor point of plane
123 Vec3f diff_min
= m_min
- ray
.origin(); // o-a
124 Vec3f diff_max
= m_max
- ray
.origin();
126 float cos_theta
, temp
;
127 float tx_near
= -Infinity
, tx_far
= Infinity
,
128 ty_near
= -Infinity
, ty_far
= Infinity
,
129 tz_near
= -Infinity
, tz_far
= Infinity
;
132 if((cos_theta
= ray
.direction().dot(Vec3f(1,0,0))) != 0) // if not parallel...
133 tx_near
= diff_min
.dot(Vec3f(1,0,0)) / cos_theta
;
134 if((cos_theta
= ray
.direction().dot(Vec3f(1,0,0))) != 0)
135 tx_far
= diff_max
.dot(Vec3f(1,0,0)) / cos_theta
;
137 // we don't know which is nearer, m_min or m_max, so swap them if neccessary
138 if(tx_near
> tx_far
) {
144 // do the same for y axis
145 if((cos_theta
= ray
.direction().dot(Vec3f(0,1,0))) != 0)
146 ty_near
= diff_min
.dot(Vec3f(0,1,0)) / cos_theta
;
147 if((cos_theta
= ray
.direction().dot(Vec3f(0,1,0))) != 0)
148 ty_far
= diff_max
.dot(Vec3f(0,1,0)) / cos_theta
;
149 if(ty_near
> ty_far
) {
156 if((cos_theta
= ray
.direction().dot(Vec3f(0,0,1))) != 0)
157 tz_near
= diff_min
.dot(Vec3f(0,0,1)) / cos_theta
;
158 if((cos_theta
= ray
.direction().dot(Vec3f(0,0,1))) != 0)
159 tz_far
= diff_max
.dot(Vec3f(0,0,1)) / cos_theta
;
160 if(tz_near
> tz_far
) {
166 // now the maximum of "near"s is the entry point of the ray, the minimum
167 // of "far"s is the ray's exit point. Visually speaking: the ray must cross
168 // all three "near" planes before it can be inside the box.
169 // Note: If t_near_max > t_far_min, the ray does not intersect the box
170 tnear
= fmax(fmax(tx_near
, ty_near
), tz_near
);
171 tfar
= fmin(fmin(tx_far
, ty_far
), tz_far
);
This page took 0.061591 seconds and 5 git commands to generate.