aabb.hh 5.2 KB
Newer Older
1
2
3
4
5
6
7
8
/*
 * File:   aabb.hh
 * Author: Jordan P. Lefebvre
 *
 * Created on August 13, 2012, 8:23 PM
 */

#ifndef RADIX_RADIXGEOMETRY_AABB_HH_
9
#define RADIX_RADIXGEOMETRY_AABB_HH_
10
11

#include <string>
12
#include <vector>
13

14
15
#include "radixmath/constants.hh"
#include "radixmath/matrix.hh"
16
17
#include "radixmath/point3d.hh"
#include "radixmath/ray.hh"
18

19
#include "radixcore/visibility.hh"
20
21
namespace radix
{
22
/**
23
24
25
 * @class AABB
 * @brief Axis Aligned Bounding Box
 */
26
27
class RADIX_PUBLIC AABB
{
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
 public:
  Real x0, x1, y0, y1, z0, z1;

  /**
   * Constructor
   */
  AABB(void);

  /**
   * Convenience Constructor
   * @param x0 x origin
   * @param x1
   * @param y0 y origin
   * @param y1
   * @param z0 z origin
   * @param z1
   */
  AABB(const Real x0, const Real x1, const Real y0, const Real y1,
       const Real z0, const Real z1);

  /**
   * Constructor
   * @param p0
   * @param p1
   */
  AABB(const Point3D p0, const Point3D p1);

  /**
   * Copy constructor
   * @param bbox
   */
  AABB(const AABB &aabb);

  /**
   * Assignment operator
   * @param rhs
   * @return
   */
  AABB &operator=(const AABB &rhs);

  AABB operator*(const Matrix &matrix) const;

70
71
  bool operator==(const AABB &rhs) const
  {
72
73
74
75
76
77
78
79
80
    return x0 == rhs.x0 && x1 == rhs.x1 && y0 == rhs.y0 && y1 == rhs.y1 &&
           z0 == rhs.z0 && z1 == rhs.z1;
  }
  /**
   * @brief determine if this AABB has volume
   * Volume is defined as anything but a point
   * @return bool - true if and only if this AABB does not define a point
   */
  bool hasVolume() const { return !(x0 == x1 && y0 == y1 && z0 == z1); }
81
82
  bool isInfinite() const
  {
83
84
85
    return x0 == -infinity || x1 == infinity || y0 == -infinity ||
           y1 == infinity || z0 == -infinity || z1 == infinity;
  }
86
87
  bool isMaxReal() const
  {
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
    return x0 == -maxReal || x1 == maxReal || y0 == -maxReal || y1 == maxReal ||
           z0 == -maxReal || z1 == maxReal;
  }
  static bool isNull(const AABB &aabb);
  /**
       * @brief Add two aabbs together
       * This is used for calculating the bounding box of two geometries
       * @param rhs
       * @return AABB(std::min(rhs.x0,this->x0), std::max(rhs.x1,this->x1)
                      ,std::min(rhs.y0,this->y0), std::max(rhs.y1,this->y1)
                      std::min(rhs.z0,this->z0), std::max(rhs.z1,this->z1))
       */
  AABB operator+(const AABB &rhs);
  /**
   * @brief intersects determine if an intersection exists between this and the
   * other aabb
   * @param o - other aabb to determine intersection with
   * @return true, only if these overlap, false otherwise
   */
  bool intersects(const AABB &o) const;
  /**
   * @brief creates the aabb bounding the intersection of the two
   * @param rhs
   * @return AABB
   */
  AABB operator&(const AABB &rhs);
  /**
   * Determine if the given AABB is contained inside this AABB
   * Containment is determined if the given AABB is equal or
   * smaller than this AABB
   * @param a - the AABB to determine containment in this AABB
   * @return true - iff the given AABB is contained
   */
121
122
  inline bool contains(const AABB &a) const
  {
123
124
125
    return x0 <= a.x0 && x1 >= a.x1 && y0 <= a.y0 && y1 >= a.y1 && z0 <= a.z0 &&
           z1 >= a.z1;
  }
126
127
  AABB &invert()
  {
128
129
130
131
132
133
134
135
136
137
138
139
140
    bool x0Edge;
    bool x1Edge;
    bool y0Edge;
    bool y1Edge;
    bool z0Edge;
    bool z1Edge;
    x0Edge = x0 == -maxReal || x0 == maxReal;
    x1Edge = x1 == -maxReal || x1 == maxReal;
    y0Edge = y0 == -maxReal || y0 == maxReal;
    y1Edge = y1 == -maxReal || y1 == maxReal;
    z0Edge = z0 == -maxReal || z0 == maxReal;
    z1Edge = z1 == -maxReal || z1 == maxReal;

141
142
    if (!x0Edge && x1Edge && y0Edge && y1Edge && z0Edge && z1Edge)
    {
143
144
      x1 = x0;
      x0 = -maxReal;
145
146
147
    }
    else if (x0Edge && !x1Edge && y0Edge && y1Edge && z0Edge && z1Edge)
    {
148
149
      x0 = x1;
      x1 = maxReal;
150
151
152
    }
    else if (x0Edge && x1Edge && !y0Edge && y1Edge && z0Edge && z1Edge)
    {
153
154
      y1 = y0;
      y0 = -maxReal;
155
156
157
    }
    else if (x0Edge && x1Edge && y0Edge && !y1Edge && z0Edge && z1Edge)
    {
158
159
      y0 = y1;
      y1 = maxReal;
160
161
162
    }
    else if (x0Edge && x1Edge && y0Edge && y1Edge && !z0Edge && z1Edge)
    {
163
164
      z1 = z0;
      z0 = -maxReal;
165
166
167
    }
    else if (x0Edge && x1Edge && y0Edge && y1Edge && z0Edge && !z1Edge)
    {
168
169
      z0 = z1;
      z1 = maxReal;
170
171
172
    }
    else
    {
173
174
175
176
177
178
      x0 = -maxReal;
      x1 = maxReal;
      y0 = -maxReal;
      y1 = maxReal;
      z0 = -maxReal;
      z1 = maxReal;
179
    }
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
    return *this;
  }
  /**
   * Destructor
   */
  ~AABB(void);

  /**
       * Hit
       * @brief Based on Kay and Kayjia method based on "slabs"

       * @param ray ray to intersect
       * @param t track length to populate on collision
       * @return true on collision, false otherwise
       */
  virtual bool hit(const Ray &ray, Real &t) const;

  /**
   * checks if {@code p} is inside this aabb
   * @param p Point3D
   * @return true if inside, false otherwise
   */
  virtual bool inside(const Point3D &p) const;
  virtual bool on(const Point3D &p) const;
  std::string toString() const;
  Point3D origin() const;
  std::vector<Point3D> vertices() const;
  Real height() const { return std::abs(z0 - z1); }
  Real width() const { return std::abs(x0 - x1); }
  Real depth() const { return std::abs(y0 - y1); }
210
211
};

212
}  // namespace radix
213

214
#endif /* ATLAS_AABB_H */