Added the Solid 3.5 sources to the blender source tree.
[blender.git] / extern / solid / src / complex / DT_CBox.h
1 /*
2  * SOLID - Software Library for Interference Detection
3  * 
4  * Copyright (C) 2001-2003  Dtecta.  All rights reserved.
5  *
6  * This library may be distributed under the terms of the Q Public License
7  * (QPL) as defined by Trolltech AS of Norway and appearing in the file
8  * LICENSE.QPL included in the packaging of this file.
9  *
10  * This library may be distributed and/or modified under the terms of the
11  * GNU General Public License (GPL) version 2 as published by the Free Software
12  * Foundation and appearing in the file LICENSE.GPL included in the
13  * packaging of this file.
14  *
15  * This library is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
16  * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
17  *
18  * Commercial use or any other use of this library not covered by either 
19  * the QPL or the GPL requires an additional license from Dtecta. 
20  * Please contact info@dtecta.com for enquiries about the terms of commercial
21  * use of this library.
22  */
23
24 #ifndef DT_CBOX_H
25 #define DT_CBOX_H
26
27 #include "MT_BBox.h"
28
29 struct DT_CBox {
30     DT_CBox() {}
31     DT_CBox(const MT_Point3& center, const MT_Vector3& extent) 
32       : m_center(center),
33         m_extent(extent)
34     {}
35
36     explicit DT_CBox(const MT_BBox& bbox) { set(bbox); }
37
38     const MT_Point3& getCenter() const { return m_center; }
39     const MT_Vector3& getExtent() const { return m_extent; }
40
41     void set(const MT_BBox& bbox)
42     {
43         m_center = bbox.getCenter();
44         m_extent = bbox.getExtent();
45     }
46  
47     MT_BBox get() const
48     {
49         return MT_BBox(m_center - m_extent, m_center + m_extent);
50     }
51
52     MT_Scalar size() const  
53     {
54         return GEN_max(GEN_max(m_extent[0], m_extent[1]), m_extent[2]);
55     }
56
57
58     DT_CBox& operator+=(const DT_CBox& box)
59     {
60         m_center += box.getCenter();
61         m_extent += box.getExtent();
62         return *this;
63     }
64     
65     int longestAxis() const { return m_extent.closestAxis(); }
66         
67     DT_CBox hull(const DT_CBox& b) const 
68     {
69         return DT_CBox(this->get().hull(b.get()));
70     }
71
72     bool overlaps(const DT_CBox& b) const 
73     {
74         return MT_abs(m_center[0] - b.m_center[0]) <= m_extent[0] + b.m_extent[0] &&
75                MT_abs(m_center[1] - b.m_center[1]) <= m_extent[1] + b.m_extent[1] &&
76                MT_abs(m_center[2] - b.m_center[2]) <= m_extent[2] + b.m_extent[2];
77     }
78     
79     bool overlapsLineSegment(const MT_Point3& p, const MT_Point3& q) const 
80     {
81         MT_Vector3 r = q - p;   
82         MT_Vector3 r_abs = r.absolute();
83         
84         if (!overlaps(DT_CBox(p + r * MT_Scalar(0.5), r_abs * MT_Scalar(0.5))))
85         {
86             return false;
87         }
88         
89         MT_Vector3 s = p - m_center;
90
91         if (MT_abs(r[2] * s[1] - r[1] * s[2]) > r_abs[2] * m_extent[1] + r_abs[1] * m_extent[2])
92         {
93             return false;
94         }
95                     
96         if (MT_abs(r[0] * s[2] - r[2] * s[0]) > r_abs[0] * m_extent[2] + r_abs[2] * m_extent[0])
97         {
98             return false;
99         }
100                     
101         if (MT_abs(r[1] * s[0] - r[0] * s[1]) > r_abs[1] * m_extent[0] + r_abs[0] * m_extent[1])
102         {
103             return false;
104         }
105             
106         return true;
107     }
108     
109     MT_Point3 support(const MT_Vector3& v) const 
110     {
111         return m_center + MT_Vector3(v[0] < MT_Scalar(0.0) ? -m_extent[0] : m_extent[0],
112                                      v[1] < MT_Scalar(0.0) ? -m_extent[1] : m_extent[1],
113                                      v[2] < MT_Scalar(0.0) ? -m_extent[2] : m_extent[2]); 
114     
115     }
116
117 private:
118     MT_Point3  m_center;
119     MT_Vector3 m_extent;
120 };
121
122 inline DT_CBox operator+(const DT_CBox& b1, const DT_CBox& b2) 
123 {
124     return DT_CBox(b1.getCenter() + b2.getCenter(), 
125                    b1.getExtent() + b2.getExtent());
126 }
127
128 inline DT_CBox operator-(const DT_CBox& b1, const DT_CBox& b2) 
129 {
130     return DT_CBox(b1.getCenter() - b2.getCenter(), 
131                    b1.getExtent() + b2.getExtent());
132 }
133
134 #endif