OptiX  3.9
NVIDIA OptiX Acceleration Engine
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Macros Groups
optixu_aabb_namespace.h
Go to the documentation of this file.
1 
2 /*
3  * Copyright (c) 2008 - 2010 NVIDIA Corporation. All rights reserved.
4  *
5  * NVIDIA Corporation and its licensors retain all intellectual property and proprietary
6  * rights in and to this software, related documentation and any modifications thereto.
7  * Any use, reproduction, disclosure or distribution of this software and related
8  * documentation without an express license agreement from NVIDIA Corporation is strictly
9  * prohibited.
10  *
11  * TO THE MAXIMUM EXTENT PERMITTED BY APPLICABLE LAW, THIS SOFTWARE IS PROVIDED *AS IS*
12  * AND NVIDIA AND ITS SUPPLIERS DISCLAIM ALL WARRANTIES, EITHER EXPRESS OR IMPLIED,
13  * INCLUDING, BUT NOT LIMITED TO, IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
14  * PARTICULAR PURPOSE. IN NO EVENT SHALL NVIDIA OR ITS SUPPLIERS BE LIABLE FOR ANY
15  * SPECIAL, INCIDENTAL, INDIRECT, OR CONSEQUENTIAL DAMAGES WHATSOEVER (INCLUDING, WITHOUT
16  * LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS, BUSINESS INTERRUPTION, LOSS OF
17  * BUSINESS INFORMATION, OR ANY OTHER PECUNIARY LOSS) ARISING OUT OF THE USE OF OR
18  * INABILITY TO USE THIS SOFTWARE, EVEN IF NVIDIA HAS BEEN ADVISED OF THE POSSIBILITY OF
19  * SUCH DAMAGES
20  */
21 
30 #ifndef __optixu_optixu_aabb_namespace_h__
31 #define __optixu_optixu_aabb_namespace_h__
32 
33 #include "optixu_math_namespace.h"
34 
35 #ifndef __CUDACC__
36 # include <assert.h>
37 # define RT_AABB_ASSERT assert
38 #else
39 # define RT_AABB_ASSERT(x)
40 #endif
41 
42 // __forceinline__ works in cuda, VS, and with gcc. Leave it as macro in case
43 // we need to make this per-platform or we want to switch off inlining globally.
44 #ifndef OPTIXU_INLINE
45 # define OPTIXU_INLINE_DEFINED 1
46 # define OPTIXU_INLINE __forceinline__
47 #endif // OPTIXU_INLINE
48 
49 namespace optix {
50 
73  class Aabb
74  {
75  public:
76 
78  RT_HOSTDEVICE Aabb();
79 
81  RT_HOSTDEVICE Aabb( const float3& min, const float3& max );
82 
84  RT_HOSTDEVICE Aabb( const float3& v0, const float3& v1, const float3& v2 );
85 
87  RT_HOSTDEVICE bool operator==( const Aabb& other ) const;
88 
90  RT_HOSTDEVICE float3& operator[]( int i );
91 
93  RT_HOSTDEVICE const float3& operator[]( int i ) const;
94 
96  RT_HOSTDEVICE void set( const float3& min, const float3& max );
97 
99  RT_HOSTDEVICE void set( const float3& v0, const float3& v1, const float3& v2 );
100 
102  RT_HOSTDEVICE void invalidate();
103 
105  RT_HOSTDEVICE bool valid() const;
106 
108  RT_HOSTDEVICE bool contains( const float3& p ) const;
109 
111  RT_HOSTDEVICE bool contains( const Aabb& bb ) const;
112 
114  RT_HOSTDEVICE void include( const float3& p );
115 
117  RT_HOSTDEVICE void include( const Aabb& other );
118 
120  RT_HOSTDEVICE void include( const float3& min, const float3& max );
121 
123  RT_HOSTDEVICE float3 center() const;
124 
126  RT_HOSTDEVICE float center( int dim ) const;
127 
129  RT_HOSTDEVICE float3 extent() const;
130 
132  RT_HOSTDEVICE float extent( int dim ) const;
133 
135  RT_HOSTDEVICE float volume() const;
136 
138  RT_HOSTDEVICE float area() const;
139 
141  RT_HOSTDEVICE float halfArea() const;
142 
144  RT_HOSTDEVICE int longestAxis() const;
145 
147  RT_HOSTDEVICE float maxExtent() const;
148 
150  RT_HOSTDEVICE bool intersects( const Aabb& other ) const;
151 
153  RT_HOSTDEVICE void intersection( const Aabb& other );
154 
156  RT_HOSTDEVICE void enlarge( float amount );
157 
159  RT_HOSTDEVICE bool isFlat() const;
160 
163  RT_HOSTDEVICE float distance( const float3& x ) const;
164 
167  RT_HOSTDEVICE float distance2( const float3& x ) const;
168 
172  RT_HOSTDEVICE float signedDistance( const float3& x ) const;
173 
175  float3 m_min;
177  float3 m_max;
178  };
179 
180 
181  OPTIXU_INLINE RT_HOSTDEVICE Aabb::Aabb()
182  {
183  invalidate();
184  }
185 
186  OPTIXU_INLINE RT_HOSTDEVICE Aabb::Aabb( const float3& min, const float3& max )
187  {
188  set( min, max );
189  }
190 
191  OPTIXU_INLINE RT_HOSTDEVICE Aabb::Aabb( const float3& v0, const float3& v1, const float3& v2 )
192  {
193  set( v0, v1, v2 );
194  }
195 
196  OPTIXU_INLINE RT_HOSTDEVICE bool Aabb::operator==( const Aabb& other ) const
197  {
198  return m_min.x == other.m_min.x &&
199  m_min.y == other.m_min.y &&
200  m_min.z == other.m_min.z &&
201  m_max.x == other.m_max.x &&
202  m_max.y == other.m_max.y &&
203  m_max.z == other.m_max.z;
204  }
205 
206  OPTIXU_INLINE RT_HOSTDEVICE float3& Aabb::operator[]( int i )
207  {
208  RT_AABB_ASSERT( i>=0 && i<=1 );
209  return (&m_min)[i];
210  }
211 
212  OPTIXU_INLINE RT_HOSTDEVICE const float3& Aabb::operator[]( int i ) const
213  {
214  RT_AABB_ASSERT( i>=0 && i<=1 );
215  return (&m_min)[i];
216  }
217 
218  OPTIXU_INLINE RT_HOSTDEVICE void Aabb::set( const float3& min, const float3& max )
219  {
220  m_min = min;
221  m_max = max;
222  }
223 
224  OPTIXU_INLINE RT_HOSTDEVICE void Aabb::set( const float3& v0, const float3& v1, const float3& v2 )
225  {
226  m_min = fminf( v0, fminf(v1,v2) );
227  m_max = fmaxf( v0, fmaxf(v1,v2) );
228  }
229 
230  OPTIXU_INLINE RT_HOSTDEVICE void Aabb::invalidate()
231  {
232  m_min = make_float3( 1e37f );
233  m_max = make_float3( -1e37f );
234  }
235 
236  OPTIXU_INLINE RT_HOSTDEVICE bool Aabb::valid() const
237  {
238  return m_min.x <= m_max.x &&
239  m_min.y <= m_max.y &&
240  m_min.z <= m_max.z;
241  }
242 
243  OPTIXU_INLINE RT_HOSTDEVICE bool Aabb::contains( const float3& p ) const
244  {
245  return p.x >= m_min.x && p.x <= m_max.x &&
246  p.y >= m_min.y && p.y <= m_max.y &&
247  p.z >= m_min.z && p.z <= m_max.z;
248  }
249 
250  OPTIXU_INLINE RT_HOSTDEVICE bool Aabb::contains( const Aabb& bb ) const
251  {
252  return contains( bb.m_min ) && contains( bb.m_max );
253  }
254 
255  OPTIXU_INLINE RT_HOSTDEVICE void Aabb::include( const float3& p )
256  {
257  m_min = fminf( m_min, p );
258  m_max = fmaxf( m_max, p );
259  }
260 
261  OPTIXU_INLINE RT_HOSTDEVICE void Aabb::include( const Aabb& other )
262  {
263  m_min = fminf( m_min, other.m_min );
264  m_max = fmaxf( m_max, other.m_max );
265  }
266 
267  OPTIXU_INLINE RT_HOSTDEVICE void Aabb::include( const float3& min, const float3& max )
268  {
269  m_min = fminf( m_min, min );
270  m_max = fmaxf( m_max, max );
271  }
272 
273  OPTIXU_INLINE RT_HOSTDEVICE float3 Aabb::center() const
274  {
275  RT_AABB_ASSERT( valid() );
276  return (m_min+m_max) * 0.5f;
277  }
278 
279  OPTIXU_INLINE RT_HOSTDEVICE float Aabb::center( int dim ) const
280  {
281  RT_AABB_ASSERT( valid() );
282  RT_AABB_ASSERT( dim>=0 && dim<=2 );
283  return ( ((float*)(&m_min))[dim] + ((float*)(&m_max))[dim] ) * 0.5f;
284  }
285 
286  OPTIXU_INLINE RT_HOSTDEVICE float3 Aabb::extent() const
287  {
288  RT_AABB_ASSERT( valid() );
289  return m_max - m_min;
290  }
291 
292  OPTIXU_INLINE RT_HOSTDEVICE float Aabb::extent( int dim ) const
293  {
294  RT_AABB_ASSERT( valid() );
295  return ((float*)(&m_max))[dim] - ((float*)(&m_min))[dim];
296  }
297 
298  OPTIXU_INLINE RT_HOSTDEVICE float Aabb::volume() const
299  {
300  RT_AABB_ASSERT( valid() );
301  const float3 d = extent();
302  return d.x*d.y*d.z;
303  }
304 
305  OPTIXU_INLINE RT_HOSTDEVICE float Aabb::area() const
306  {
307  return 2.0f * halfArea();
308  }
309 
310  OPTIXU_INLINE RT_HOSTDEVICE float Aabb::halfArea() const
311  {
312  RT_AABB_ASSERT( valid() );
313  const float3 d = extent();
314  return d.x*d.y + d.y*d.z + d.z*d.x;
315  }
316 
317  OPTIXU_INLINE RT_HOSTDEVICE int Aabb::longestAxis() const
318  {
319  RT_AABB_ASSERT( valid() );
320  const float3 d = extent();
321 
322  if( d.x > d.y )
323  return d.x > d.z ? 0 : 2;
324  return d.y > d.z ? 1 : 2;
325  }
326 
327  OPTIXU_INLINE RT_HOSTDEVICE float Aabb::maxExtent() const
328  {
329  return extent( longestAxis() );
330  }
331 
332  OPTIXU_INLINE RT_HOSTDEVICE bool Aabb::intersects( const Aabb& other ) const
333  {
334  if( other.m_min.x > m_max.x || other.m_max.x < m_min.x ) return false;
335  if( other.m_min.y > m_max.y || other.m_max.y < m_min.y ) return false;
336  if( other.m_min.z > m_max.z || other.m_max.z < m_min.z ) return false;
337  return true;
338  }
339 
340  OPTIXU_INLINE RT_HOSTDEVICE void Aabb::intersection( const Aabb& other )
341  {
342  m_min.x = fmaxf( m_min.x, other.m_min.x );
343  m_min.y = fmaxf( m_min.y, other.m_min.y );
344  m_min.z = fmaxf( m_min.z, other.m_min.z );
345  m_max.x = fminf( m_max.x, other.m_max.x );
346  m_max.y = fminf( m_max.y, other.m_max.y );
347  m_max.z = fminf( m_max.z, other.m_max.z );
348  }
349 
350  OPTIXU_INLINE RT_HOSTDEVICE void Aabb::enlarge( float amount )
351  {
352  RT_AABB_ASSERT( valid() );
353  m_min -= make_float3( amount );
354  m_max += make_float3( amount );
355  }
356 
357  OPTIXU_INLINE RT_HOSTDEVICE bool Aabb::isFlat() const
358  {
359  return m_min.x == m_max.x ||
360  m_min.y == m_max.y ||
361  m_min.z == m_max.z;
362  }
363 
364  OPTIXU_INLINE RT_HOSTDEVICE float Aabb::distance( const float3& x ) const
365  {
366  return sqrtf(distance2(x));
367  }
368 
369  OPTIXU_INLINE RT_HOSTDEVICE float Aabb::signedDistance( const float3& x ) const
370  {
371  if( m_min.x <= x.x && x.x <= m_max.x &&
372  m_min.y <= x.y && x.y <= m_max.y &&
373  m_min.z <= x.z && x.z <= m_max.z) {
374  float distance_x = fminf( x.x - m_min.x, m_max.x - x.x);
375  float distance_y = fminf( x.y - m_min.y, m_max.y - x.y);
376  float distance_z = fminf( x.z - m_min.z, m_max.z - x.z);
377 
378  float min_distance = fminf(distance_x, fminf(distance_y, distance_z));
379  return -min_distance;
380  }
381 
382  return distance(x);
383  }
384 
385  OPTIXU_INLINE RT_HOSTDEVICE float Aabb::distance2( const float3& x ) const
386  {
387  float3 box_dims = m_max - m_min;
388 
389  // compute vector from min corner of box
390  float3 v = x - m_min;
391 
392  float dist2 = 0;
393  float excess;
394 
395  // project vector from box min to x on each axis,
396  // yielding distance to x along that axis, and count
397  // any excess distance outside box extents
398 
399  excess = 0;
400  if( v.x < 0 )
401  excess = v.x;
402  else if( v.x > box_dims.x )
403  excess = v.x - box_dims.x;
404  dist2 += excess * excess;
405 
406  excess = 0;
407  if( v.y < 0 )
408  excess = v.y;
409  else if( v.y > box_dims.y )
410  excess = v.y - box_dims.y;
411  dist2 += excess * excess;
412 
413  excess = 0;
414  if( v.z < 0 )
415  excess = v.z;
416  else if( v.z > box_dims.z )
417  excess = v.z - box_dims.z;
418  dist2 += excess * excess;
419 
420  return dist2;
421  }
422 
423 } // end namespace optix
424 
425 #ifdef OPTIXU_INLINE_DEFINED
426 # undef OPTIXU_INLINE_DEFINED
427 # undef OPTIXU_INLINE
428 #endif
429 
430 #undef RT_AABB_ASSERT
431 
432 #endif // #ifndef __optixu_optixu_aabb_namespace_h__
Axis-aligned bounding box.
Definition: optixu_aabb_namespace.h:73
RT_HOSTDEVICE bool isFlat() const
Definition: optixu_aabb_namespace.h:357
RT_HOSTDEVICE bool operator==(const Aabb &other) const
Definition: optixu_aabb_namespace.h:196
RT_HOSTDEVICE int longestAxis() const
Definition: optixu_aabb_namespace.h:317
RT_HOSTDEVICE float area() const
Definition: optixu_aabb_namespace.h:305
RT_HOSTDEVICE void include(const float3 &p)
Definition: optixu_aabb_namespace.h:255
RT_HOSTDEVICE void invalidate()
Definition: optixu_aabb_namespace.h:230
RT_HOSTDEVICE bool contains(const float3 &p) const
Definition: optixu_aabb_namespace.h:243
RT_HOSTDEVICE Aabb()
Definition: optixu_aabb_namespace.h:181
RT_HOSTDEVICE bool valid() const
Definition: optixu_aabb_namespace.h:236
RT_HOSTDEVICE float3 center() const
Definition: optixu_aabb_namespace.h:273
RT_HOSTDEVICE float signedDistance(const float3 &x) const
Definition: optixu_aabb_namespace.h:369
RT_HOSTDEVICE float3 extent() const
Definition: optixu_aabb_namespace.h:286
RT_HOSTDEVICE float halfArea() const
Definition: optixu_aabb_namespace.h:310
float3 m_min
Definition: optixu_aabb_namespace.h:175
RT_HOSTDEVICE float distance2(const float3 &x) const
Definition: optixu_aabb_namespace.h:385
RT_HOSTDEVICE float3 & operator[](int i)
Definition: optixu_aabb_namespace.h:206
RT_HOSTDEVICE void intersection(const Aabb &other)
Definition: optixu_aabb_namespace.h:340
OptiX public API.
RT_HOSTDEVICE float maxExtent() const
Definition: optixu_aabb_namespace.h:327
RT_HOSTDEVICE bool intersects(const Aabb &other) const
Definition: optixu_aabb_namespace.h:332
RT_HOSTDEVICE float volume() const
Definition: optixu_aabb_namespace.h:298
RT_HOSTDEVICE void set(const float3 &min, const float3 &max)
Definition: optixu_aabb_namespace.h:218
RT_HOSTDEVICE float distance(const float3 &x) const
Definition: optixu_aabb_namespace.h:364
RT_HOSTDEVICE void enlarge(float amount)
Definition: optixu_aabb_namespace.h:350
float3 m_max
Definition: optixu_aabb_namespace.h:177