Blender  V2.93
util_boundbox.h
Go to the documentation of this file.
1 /*
2  * Copyright 2011-2013 Blender Foundation
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #ifndef __UTIL_BOUNDBOX_H__
18 #define __UTIL_BOUNDBOX_H__
19 
20 #include <float.h>
21 #include <math.h>
22 
23 #include "util/util_math.h"
24 #include "util/util_string.h"
25 #include "util/util_transform.h"
26 #include "util/util_types.h"
27 
29 
30 /* 3D BoundBox */
31 
32 class BoundBox {
33  public:
35 
37  {
38  }
39 
40  __forceinline BoundBox(const float3 &pt) : min(pt), max(pt)
41  {
42  }
43 
44  __forceinline BoundBox(const float3 &min_, const float3 &max_) : min(min_), max(max_)
45  {
46  }
47 
48  enum empty_t { empty = 0 };
49 
51  : min(make_float3(FLT_MAX, FLT_MAX, FLT_MAX)), max(make_float3(-FLT_MAX, -FLT_MAX, -FLT_MAX))
52  {
53  }
54 
55  __forceinline void grow(const float3 &pt)
56  {
57  /* the order of arguments to min is such that if pt is nan, it will not
58  * influence the resulting bounding box */
59  min = ccl::min(pt, min);
60  max = ccl::max(pt, max);
61  }
62 
63  __forceinline void grow(const float3 &pt, float border)
64  {
66  min = ccl::min(pt - shift, min);
67  max = ccl::max(pt + shift, max);
68  }
69 
70  __forceinline void grow(const BoundBox &bbox)
71  {
72  grow(bbox.min);
73  grow(bbox.max);
74  }
75 
76  __forceinline void grow_safe(const float3 &pt)
77  {
78  /* the order of arguments to min is such that if pt is nan, it will not
79  * influence the resulting bounding box */
80  if (isfinite(pt.x) && isfinite(pt.y) && isfinite(pt.z)) {
81  min = ccl::min(pt, min);
82  max = ccl::max(pt, max);
83  }
84  }
85 
86  __forceinline void grow_safe(const float3 &pt, float border)
87  {
88  if (isfinite(pt.x) && isfinite(pt.y) && isfinite(pt.z) && isfinite(border)) {
90  min = ccl::min(pt - shift, min);
91  max = ccl::max(pt + shift, max);
92  }
93  }
94 
95  __forceinline void grow_safe(const BoundBox &bbox)
96  {
97  grow_safe(bbox.min);
98  grow_safe(bbox.max);
99  }
100 
101  __forceinline void intersect(const BoundBox &bbox)
102  {
103  min = ccl::max(min, bbox.min);
104  max = ccl::min(max, bbox.max);
105  }
106 
107  /* todo: avoid using this */
108  __forceinline float safe_area() const
109  {
110  if (!((min.x <= max.x) && (min.y <= max.y) && (min.z <= max.z)))
111  return 0.0f;
112 
113  return area();
114  }
115 
116  __forceinline float area() const
117  {
118  return half_area() * 2.0f;
119  }
120 
121  __forceinline float half_area() const
122  {
123  float3 d = max - min;
124  return (d.x * d.z + d.y * d.z + d.x * d.y);
125  }
126 
128  {
129  return 0.5f * (min + max);
130  }
131 
133  {
134  return min + max;
135  }
136 
138  {
139  return max - min;
140  }
141 
142  __forceinline bool valid() const
143  {
144  return (min.x <= max.x) && (min.y <= max.y) && (min.z <= max.z) &&
145  (isfinite(min.x) && isfinite(min.y) && isfinite(min.z)) &&
146  (isfinite(max.x) && isfinite(max.y) && isfinite(max.z));
147  }
148 
149  BoundBox transformed(const Transform *tfm) const
150  {
152 
153  for (int i = 0; i < 8; i++) {
154  float3 p;
155 
156  p.x = (i & 1) ? min.x : max.x;
157  p.y = (i & 2) ? min.y : max.y;
158  p.z = (i & 4) ? min.z : max.z;
159 
160  result.grow(transform_point(tfm, p));
161  }
162 
163  return result;
164  }
165 
166  __forceinline bool intersects(const BoundBox &other)
167  {
168  float3 center_diff = center() - other.center(), total_size = (size() + other.size()) * 0.5f;
169  return fabsf(center_diff.x) <= total_size.x && fabsf(center_diff.y) <= total_size.y &&
170  fabsf(center_diff.z) <= total_size.z;
171  }
172 };
173 
174 __forceinline BoundBox merge(const BoundBox &bbox, const float3 &pt)
175 {
176  return BoundBox(min(bbox.min, pt), max(bbox.max, pt));
177 }
178 
180 {
181  return BoundBox(min(a.min, b.min), max(a.max, b.max));
182 }
183 
185  const BoundBox &b,
186  const BoundBox &c,
187  const BoundBox &d)
188 {
189  return merge(merge(a, b), merge(c, d));
190 }
191 
193 {
194  return BoundBox(max(a.min, b.min), min(a.max, b.max));
195 }
196 
198 {
199  return intersect(a, intersect(b, c));
200 }
201 
202 /* 2D BoundBox */
203 
204 class BoundBox2D {
205  public:
206  float left;
207  float right;
208  float bottom;
209  float top;
210 
211  BoundBox2D() : left(0.0f), right(1.0f), bottom(0.0f), top(1.0f)
212  {
213  }
214 
215  bool operator==(const BoundBox2D &other) const
216  {
217  return (left == other.left && right == other.right && bottom == other.bottom &&
218  top == other.top);
219  }
220 
221  float width()
222  {
223  return right - left;
224  }
225 
226  float height()
227  {
228  return top - bottom;
229  }
230 
231  BoundBox2D operator*(float f) const
232  {
234 
235  result.left = left * f;
236  result.right = right * f;
237  result.bottom = bottom * f;
238  result.top = top * f;
239 
240  return result;
241  }
242 
243  BoundBox2D subset(const BoundBox2D &other) const
244  {
246 
247  subset.left = left + other.left * (right - left);
248  subset.right = left + other.right * (right - left);
249  subset.bottom = bottom + other.bottom * (top - bottom);
250  subset.top = bottom + other.top * (top - bottom);
251 
252  return subset;
253  }
254 
256  {
258 
259  result.left = ((left - other.left) / (other.right - other.left));
260  result.right = ((right - other.left) / (other.right - other.left));
261  result.bottom = ((bottom - other.bottom) / (other.top - other.bottom));
262  result.top = ((top - other.bottom) / (other.top - other.bottom));
263 
264  return result;
265  }
266 
267  BoundBox2D clamp(float mn = 0.0f, float mx = 1.0f)
268  {
270 
271  result.left = ccl::clamp(left, mn, mx);
272  result.right = ccl::clamp(right, mn, mx);
273  result.bottom = ccl::clamp(bottom, mn, mx);
274  result.top = ccl::clamp(top, mn, mx);
275 
276  return result;
277  }
278 };
279 
281 
282 #endif /* __UTIL_BOUNDBOX_H__ */
struct BoundBox BoundBox
BoundBox2D clamp(float mn=0.0f, float mx=1.0f)
BoundBox2D make_relative_to(const BoundBox2D &other) const
float width()
BoundBox2D operator*(float f) const
float height()
BoundBox2D subset(const BoundBox2D &other) const
bool operator==(const BoundBox2D &other) const
IconTextureDrawCall border
#define CCL_NAMESPACE_END
#define fabsf(x)
#define make_float3(x, y, z)
bool isfinite(uchar)
Definition: image.cpp:44
static unsigned c
Definition: RandGen.cpp:97
static unsigned a[3]
Definition: RandGen.cpp:92
#define min(a, b)
Definition: sort.c:51
__forceinline void grow(const BoundBox &bbox)
Definition: util_boundbox.h:70
__forceinline float half_area() const
__forceinline BoundBox(empty_t)
Definition: util_boundbox.h:50
__forceinline void grow_safe(const BoundBox &bbox)
Definition: util_boundbox.h:95
__forceinline BoundBox(const float3 &pt)
Definition: util_boundbox.h:40
BoundBox transformed(const Transform *tfm) const
__forceinline bool valid() const
__forceinline float3 center() const
__forceinline BoundBox(const float3 &min_, const float3 &max_)
Definition: util_boundbox.h:44
float3 max
Definition: util_boundbox.h:34
__forceinline float3 size() const
__forceinline BoundBox()
Definition: util_boundbox.h:36
__forceinline void intersect(const BoundBox &bbox)
__forceinline void grow_safe(const float3 &pt)
Definition: util_boundbox.h:76
__forceinline float safe_area() const
__forceinline bool intersects(const BoundBox &other)
__forceinline void grow(const float3 &pt)
Definition: util_boundbox.h:55
__forceinline float area() const
__forceinline void grow(const float3 &pt, float border)
Definition: util_boundbox.h:63
float3 min
Definition: util_boundbox.h:34
__forceinline void grow_safe(const float3 &pt, float border)
Definition: util_boundbox.h:86
__forceinline float3 center2() const
float z
Definition: sky_float3.h:35
float y
Definition: sky_float3.h:35
float x
Definition: sky_float3.h:35
float max
__forceinline BoundBox merge(const BoundBox &bbox, const float3 &pt)
__forceinline BoundBox intersect(const BoundBox &a, const BoundBox &b)
#define __forceinline
Definition: util_defines.h:71
ccl_device_inline int clamp(int a, int mn, int mx)
Definition: util_math.h:283
ccl_device_inline float3 transform_point(const Transform *t, const float3 a)