1 // This code is in the public domain -- castanyo@yahoo.es 2 3 #ifndef NV_MATH_BOX_H 4 #define NV_MATH_BOX_H 5 6 #include <nvmath/Vector.h> 7 8 #include <float.h> // FLT_MAX 9 10 namespace nv 11 { 12 13 /// Axis Aligned Bounding Box. 14 class Box 15 { 16 public: 17 18 /// Default ctor. Box()19 Box() { }; 20 21 /// Copy ctor. Box(const Box & b)22 Box( const Box & b ) : m_mins(b.m_mins), m_maxs(b.m_maxs) { } 23 24 /// Init ctor. Box(Vector3::Arg mins,Vector3::Arg maxs)25 Box( Vector3::Arg mins, Vector3::Arg maxs ) : m_mins(mins), m_maxs(maxs) { } 26 27 // Cast operators. 28 operator const float * () const { return reinterpret_cast<const float *>(this); } 29 30 /// Min corner of the box. mins()31 Vector3 mins() const { return m_mins; } 32 33 /// Max corner of the box. maxs()34 Vector3 maxs() const { return m_maxs; } 35 36 /// Clear the bounds. clearBounds()37 void clearBounds() 38 { 39 m_mins.set(FLT_MAX, FLT_MAX, FLT_MAX); 40 m_maxs.set(-FLT_MAX, -FLT_MAX, -FLT_MAX); 41 } 42 43 /// Build a cube centered on center and with edge = 2*dist cube(Vector3::Arg center,float dist)44 void cube(Vector3::Arg center, float dist) 45 { 46 setCenterExtents(center, Vector3(dist, dist, dist)); 47 } 48 49 /// Build a box, given center and extents. setCenterExtents(Vector3::Arg center,Vector3::Arg extents)50 void setCenterExtents(Vector3::Arg center, Vector3::Arg extents) 51 { 52 m_mins = center - extents; 53 m_maxs = center + extents; 54 } 55 56 /// Get box center. center()57 Vector3 center() const 58 { 59 return (m_mins + m_maxs) * 0.5f; 60 } 61 62 /// Return extents of the box. extents()63 Vector3 extents() const 64 { 65 return (m_maxs - m_mins) * 0.5f; 66 } 67 68 /// Return extents of the box. extents(uint axis)69 scalar extents(uint axis) const 70 { 71 nvDebugCheck(axis < 3); 72 if (axis == 0) return (m_maxs.x() - m_mins.x()) * 0.5f; 73 if (axis == 1) return (m_maxs.y() - m_mins.y()) * 0.5f; 74 if (axis == 2) return (m_maxs.z() - m_mins.z()) * 0.5f; 75 nvAssume(false); 76 return 0.0f; 77 } 78 79 /// Add a point to this box. addPointToBounds(Vector3::Arg p)80 void addPointToBounds(Vector3::Arg p) 81 { 82 m_mins = min(m_mins, p); 83 m_maxs = max(m_maxs, p); 84 } 85 86 /// Add a box to this box. addBoxToBounds(const Box & b)87 void addBoxToBounds(const Box & b) 88 { 89 m_mins = min(m_mins, b.m_mins); 90 m_maxs = max(m_maxs, b.m_maxs); 91 } 92 93 /// Translate box. translate(Vector3::Arg v)94 void translate(Vector3::Arg v) 95 { 96 m_mins += v; 97 m_maxs += v; 98 } 99 100 /// Scale the box. scale(float s)101 void scale(float s) 102 { 103 m_mins *= s; 104 m_maxs *= s; 105 } 106 107 /// Get the area of the box. area()108 float area() const 109 { 110 const Vector3 d = extents(); 111 return 8.0f * (d.x()*d.y() + d.x()*d.z() + d.y()*d.z()); 112 } 113 114 /// Get the volume of the box. volume()115 float volume() const 116 { 117 Vector3 d = extents(); 118 return 8.0f * (d.x() * d.y() * d.z()); 119 } 120 121 /// Return true if the box contains the given point. contains(Vector3::Arg p)122 bool contains(Vector3::Arg p) const 123 { 124 return 125 m_mins.x() < p.x() && m_mins.y() < p.y() && m_mins.z() < p.z() && 126 m_maxs.x() > p.x() && m_maxs.y() > p.y() && m_maxs.z() > p.z(); 127 } 128 129 private: 130 131 Vector3 m_mins; 132 Vector3 m_maxs; 133 }; 134 135 136 137 } // nv namespace 138 139 140 #endif // NV_MATH_BOX_H 141