1 // Copyright (C) 2000  Sean Cavanaugh
2 // This file is licensed under the terms of the Lesser GNU Public License
3 // (see LPGL.txt, or http://www.gnu.org/copyleft/lesser.txt)
4 
5 // AJM:
6 #pragma warning(disable: 4305)                             // truncation from 'const double' to 'float'
7 
8 
9 #ifndef BOUNDINGBOX_H__
10 #define BOUNDINGBOX_H__
11 
12 #if _MSC_VER >= 1000
13 #pragma once
14 #endif
15 
16 class BoundingBox
17 {
18 public:
19     typedef enum
20     {
21         eDisjoint,      // neither boxes touch
22         eUnion,         // this box intersects with the other box
23         eSubset,        // this box is inside the other box
24         eSuperset       // this box is completly envelops the other box
25     } eBoundingState;
26 
27     // Tests if other box is completely outside of this box
testDisjoint(const BoundingBox & other)28     bool testDisjoint(const BoundingBox& other) const
29     {
30         if ((m_Mins[0] > other.m_Maxs[0]) ||
31             (m_Mins[1] > other.m_Maxs[1]) ||
32             (m_Mins[2] > other.m_Maxs[2]) ||
33             (m_Maxs[0] < other.m_Mins[0]) ||
34             (m_Maxs[1] < other.m_Mins[1]) ||
35             (m_Maxs[2] < other.m_Mins[2]))
36         {
37             return true;
38         }
39         return false;
40     }
41     // returns true if this box is completely inside other box
testSubset(const BoundingBox & other)42     bool testSubset(const BoundingBox& other) const
43     {
44         if (
45                 (m_Mins[0] >= other.m_Mins[0]) &&
46                 (m_Maxs[0] <= other.m_Maxs[0]) &&
47                 (m_Mins[1] >= other.m_Mins[1]) &&
48                 (m_Maxs[1] <= other.m_Maxs[1]) &&
49                 (m_Mins[2] >= other.m_Mins[2]) &&
50                 (m_Maxs[2] <= other.m_Maxs[2])
51            )
52         {
53             return true;
54         }
55         return false;
56     }
57     // returns true if this box contains the other box completely
testSuperset(const BoundingBox & other)58     bool testSuperset(const BoundingBox& other) const
59     {
60         return other.testSubset(*this);
61     }
62     // returns true if this box partially intersects the other box
testUnion(const BoundingBox & other)63     bool testUnion(const BoundingBox& other) const
64     {
65         BoundingBox tmpBox;
66         tmpBox.m_Mins[0] = std::max(m_Mins[0], other.m_Mins[0]);
67         tmpBox.m_Mins[1] = std::max(m_Mins[1], other.m_Mins[1]);
68         tmpBox.m_Mins[2] = std::max(m_Mins[2], other.m_Mins[2]);
69         tmpBox.m_Maxs[0] = std::min(m_Maxs[0], other.m_Maxs[0]);
70         tmpBox.m_Maxs[1] = std::min(m_Maxs[1], other.m_Maxs[1]);
71         tmpBox.m_Maxs[2] = std::min(m_Maxs[2], other.m_Maxs[2]);
72 
73         if ((tmpBox.m_Mins[0] > tmpBox.m_Maxs[0]) ||
74             (tmpBox.m_Mins[1] > tmpBox.m_Maxs[1]) ||
75             (tmpBox.m_Mins[2] > tmpBox.m_Maxs[2]))
76         {
77             return false;
78         }
79         return true;
80     }
test(const BoundingBox & other)81     eBoundingState test(const BoundingBox& other) const
82     {
83         eBoundingState rval;
84         if (testDisjoint(other))
85         {
86             rval = eDisjoint;
87         }
88         else if (testSubset(other))
89         {
90             rval = eSubset;
91         }
92         else if (testSuperset(other))
93         {
94             rval = eSuperset;
95         }
96         else
97         {
98             rval = eUnion;
99         }
100         return rval;
101     }
102 
set(const vec3_t mins,const vec3_t maxs)103     void set(const vec3_t mins, const vec3_t maxs)
104     {
105         VectorCopy(mins, m_Mins);
106         VectorCopy(maxs, m_Maxs);
107     }
reset()108     void reset()
109     {
110         VectorFill(m_Mins,  999999999.999);
111         VectorFill(m_Maxs, -999999999.999);
112     }
add(const vec3_t point)113     void add(const vec3_t point)
114     {
115         m_Mins[0] = std::min(m_Mins[0], point[0]);
116         m_Maxs[0] = std::max(m_Maxs[0], point[0]);
117         m_Mins[1] = std::min(m_Mins[1], point[1]);
118         m_Maxs[1] = std::max(m_Maxs[1], point[1]);
119         m_Mins[2] = std::min(m_Mins[2], point[2]);
120         m_Maxs[2] = std::max(m_Maxs[2], point[2]);
121     }
add(const BoundingBox & other)122     void add(const BoundingBox& other)
123     {
124         add(other.m_Mins);
125         add(other.m_Maxs);
126     }
127 
128 public:
129     // BoundingBox(const BoundingBox& other) // Default copy constructor ok
130     // BoundingBox& operator=(const BoundingBox& other); // Default copy operator ok
BoundingBox()131     BoundingBox()
132     {
133         reset();
134     }
BoundingBox(const vec3_t & mins,const vec3_t & maxs)135     BoundingBox(const vec3_t& mins, const vec3_t& maxs)
136     {
137         VectorCopy(mins, m_Mins);
138         VectorCopy(maxs, m_Maxs);
139     }
~BoundingBox()140     ~BoundingBox() {}
141 
142 public:
143     // Bounding box
144     vec3_t m_Mins;
145     vec3_t m_Maxs;
146 };
147 
148 #endif//BOUNDINGBOX_H__