Added the Solid 3.5 sources to the blender source tree.
[blender.git] / extern / solid / src / convex / DT_Box.cpp
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 #include "DT_Box.h"
25
26 MT_Scalar DT_Box::supportH(const MT_Vector3& v) const 
27 {
28     return v.absolute().dot(m_extent);
29 }
30
31 MT_Point3 DT_Box::support(const MT_Vector3& v) const 
32 {
33     return MT_Point3(v[0] < MT_Scalar(0.0) ? -m_extent[0] : m_extent[0],
34                      v[1] < MT_Scalar(0.0) ? -m_extent[1] : m_extent[1],
35                      v[2] < MT_Scalar(0.0) ? -m_extent[2] : m_extent[2]); 
36     
37 }
38
39
40 bool DT_Box::ray_cast(const MT_Point3& source, const MT_Point3& target,
41                                           MT_Scalar& param, MT_Vector3& normal) const 
42 {
43         T_Outcode source_bits = outcode(source);
44         T_Outcode target_bits = outcode(target);
45
46         if ((source_bits & target_bits) == 0x0)
47                 // None of the side planes separate the ray from the box.
48         {
49                 MT_Scalar lambda_enter = MT_Scalar(0.0);
50                 MT_Scalar lambda_exit  = param;
51                 MT_Vector3 r = target - source;
52                 T_Outcode normal_bit = 0x0; // Indicates the axis that is returned as normal.
53                 T_Outcode bit = 0x01;
54                 int i;
55                 for (i = 0; i != 3; ++i)
56                 {
57                         if (source_bits & bit)
58                                 // Point of intersection is entering
59                         {
60                                 MT_Scalar lambda = (-source[i] - m_extent[i]) / r[i];
61                                 if (lambda_enter < lambda)
62                                 {
63                                         lambda_enter = lambda;
64                                         normal_bit = bit;
65                                 }
66                         }
67                         else if (target_bits & bit) 
68                                 // Point of intersection is exiting
69                         {
70                                 MT_Scalar lambda = (-source[i] - m_extent[i]) / r[i];
71                                 GEN_set_min(lambda_exit, lambda);
72                         }
73                         bit <<=1;
74                         if (source_bits & bit)
75                                 // Point of intersection is entering
76                         {
77                                 MT_Scalar lambda =  (-source[i] + m_extent[i]) / r[i];
78                                 if (lambda_enter < lambda)
79                                 {
80                                         lambda_enter = lambda;
81                                         normal_bit = bit;
82                                 }
83                         }
84                         else if (target_bits & bit) 
85                                 // Point of intersection is exiting
86                         {
87                                 MT_Scalar lambda =  (-source[i] + m_extent[i]) / r[i];
88                                 GEN_set_min(lambda_exit, lambda);
89                         }
90                         bit <<=1;
91                 }
92                 if (lambda_enter <= lambda_exit)
93                         // The ray intersects the box
94                 {
95                         param = lambda_enter;
96                         normal.setValue(normal_bit == 0x01 ? -MT_Scalar(1.0) : 
97                                                         normal_bit == 0x02 ?  MT_Scalar(1.0) : 
98                                                         MT_Scalar(0.0),
99                                                         normal_bit == 0x04 ? -MT_Scalar(1.0) : 
100                                                         normal_bit == 0x08 ?  MT_Scalar(1.0) : 
101                                                         MT_Scalar(0.0),
102                                                         normal_bit == 0x10 ? -MT_Scalar(1.0) : 
103                                                         normal_bit == 0x20 ?  MT_Scalar(1.0) : 
104                                                         MT_Scalar(0.0));
105                         return true;
106                 }
107         }
108
109         return false;
110 }
111
112