Added the Solid 3.5 sources to the blender source tree.
[blender.git] / extern / solid / src / convex / DT_Sphere.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_Sphere.h"
25 #include "GEN_MinMax.h"
26
27 MT_Scalar DT_Sphere::supportH(const MT_Vector3& v) const 
28 {
29         return m_radius * v.length();
30 }
31
32 MT_Point3 DT_Sphere::support(const MT_Vector3& v) const 
33 {
34    MT_Scalar s = v.length();
35         
36         if (s > MT_Scalar(0.0))
37         {
38                 s = m_radius / s;
39                 return MT_Point3(v[0] * s, v[1] * s, v[2] * s);
40         }
41         else
42         {
43                 return MT_Point3(m_radius, MT_Scalar(0.0), MT_Scalar(0.0));
44         }
45 }
46
47 bool DT_Sphere::ray_cast(const MT_Point3& source, const MT_Point3& target,
48                                                  MT_Scalar& param, MT_Vector3& normal) const 
49 {
50         MT_Vector3 r = target - source;
51         MT_Scalar  delta = -source.dot(r);  
52         MT_Scalar  r_length2 = r.length2();
53         MT_Scalar  sigma = delta * delta - r_length2 * (source.length2() - m_radius * m_radius);
54
55         if (sigma >= MT_Scalar(0.0))
56                 // The line trough source and target intersects the sphere.
57         {
58                 MT_Scalar sqrt_sigma = MT_sqrt(sigma);
59                 // We need only the sign of lambda2, so the division by the positive 
60                 // r_length2 can be left out.
61                 MT_Scalar lambda2 = (delta + sqrt_sigma) /* / r_length2 */ ;
62                 if (lambda2 >= MT_Scalar(0.0))
63                         // The ray points at the sphere
64                 {
65                         MT_Scalar lambda1 = (delta - sqrt_sigma) / r_length2;
66                         if (lambda1 <= param)
67                                 // The ray hits the sphere, since 
68                                 // [lambda1, lambda2] overlaps [0, param]. 
69                         {
70                                 if (lambda1 > MT_Scalar(0.0))
71                                 {
72                                         param = lambda1;
73                                         normal = (source + r * lambda1) / m_radius;
74                                         // NB: division by m_radius to normalize the normal.
75                                 }
76                                 else
77                                 {
78                                         param = MT_Scalar(0.0);
79                                         normal.setValue(MT_Scalar(0.0), MT_Scalar(0.0), MT_Scalar(0.0));
80                                 }
81                                                 
82                                 return true;
83                         }
84                 }
85         }
86
87         return false;
88 }
89
90