1 /*
2  * Software License Agreement (BSD License)
3  *
4  *  Copyright (c) 2011-2014, Willow Garage, Inc.
5  *  Copyright (c) 2014-2016, Open Source Robotics Foundation
6  *  All rights reserved.
7  *
8  *  Redistribution and use in source and binary forms, with or without
9  *  modification, are permitted provided that the following conditions
10  *  are met:
11  *
12  *   * Redistributions of source code must retain the above copyright
13  *     notice, this list of conditions and the following disclaimer.
14  *   * Redistributions in binary form must reproduce the above
15  *     copyright notice, this list of conditions and the following
16  *     disclaimer in the documentation and/or other materials provided
17  *     with the distribution.
18  *   * Neither the name of Open Source Robotics Foundation nor the names of its
19  *     contributors may be used to endorse or promote products derived
20  *     from this software without specific prior written permission.
21  *
22  *  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23  *  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24  *  LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25  *  FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26  *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
28  *  BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29  *  LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
30  *  CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31  *  LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
32  *  ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33  *  POSSIBILITY OF SUCH DAMAGE.
34  */
35 
36 /** \author Jia Pan */
37 
38 #include "fcl/BV/kIOS.h"
39 #include "fcl/BVH/BVH_utility.h"
40 #include "fcl/math/transform.h"
41 
42 #include <iostream>
43 #include <limits>
44 
45 namespace fcl
46 {
47 
overlap(const kIOS & other) const48 bool kIOS::overlap(const kIOS& other) const
49 {
50   for(unsigned int i = 0; i < num_spheres; ++i)
51   {
52     for(unsigned int j = 0; j < other.num_spheres; ++j)
53     {
54       FCL_REAL o_dist = (spheres[i].o - other.spheres[j].o).sqrLength();
55       FCL_REAL sum_r = spheres[i].r + other.spheres[j].r;
56       if(o_dist > sum_r * sum_r)
57         return false;
58     }
59   }
60 
61   return obb.overlap(other.obb);
62 
63   return true;
64 }
65 
66 
contain(const Vec3f & p) const67 bool kIOS::contain(const Vec3f& p) const
68 {
69   for(unsigned int i = 0; i < num_spheres; ++i)
70   {
71     FCL_REAL r = spheres[i].r;
72     if((spheres[i].o - p).sqrLength() > r * r)
73       return false;
74   }
75 
76   return true;
77 }
78 
operator +=(const Vec3f & p)79 kIOS& kIOS::operator += (const Vec3f& p)
80 {
81   for(unsigned int i = 0; i < num_spheres; ++i)
82   {
83     FCL_REAL r = spheres[i].r;
84     FCL_REAL new_r_sqr = (p - spheres[i].o).sqrLength();
85     if(new_r_sqr > r * r)
86     {
87       spheres[i].r = sqrt(new_r_sqr);
88     }
89   }
90 
91   obb += p;
92   return *this;
93 }
94 
operator +(const kIOS & other) const95 kIOS kIOS::operator + (const kIOS& other) const
96 {
97   kIOS result;
98   unsigned int new_num_spheres = std::min(num_spheres, other.num_spheres);
99   for(unsigned int i = 0; i < new_num_spheres; ++i)
100   {
101     result.spheres[i] = encloseSphere(spheres[i], other.spheres[i]);
102   }
103 
104   result.num_spheres = new_num_spheres;
105 
106   result.obb = obb + other.obb;
107 
108   return result;
109 }
110 
width() const111 FCL_REAL kIOS::width() const
112 {
113   return obb.width();
114 }
115 
height() const116 FCL_REAL kIOS::height() const
117 {
118   return obb.height();
119 }
120 
depth() const121 FCL_REAL kIOS::depth() const
122 {
123   return obb.depth();
124 }
125 
volume() const126 FCL_REAL kIOS::volume() const
127 {
128   return obb.volume();
129 }
130 
size() const131 FCL_REAL kIOS::size() const
132 {
133   return volume();
134 }
135 
distance(const kIOS & other,Vec3f * P,Vec3f * Q) const136 FCL_REAL kIOS::distance(const kIOS& other, Vec3f* P, Vec3f* Q) const
137 {
138   FCL_REAL d_max = 0;
139   int id_a = -1, id_b = -1;
140   for(unsigned int i = 0; i < num_spheres; ++i)
141   {
142     for(unsigned int j = 0; j < other.num_spheres; ++j)
143     {
144       FCL_REAL d = (spheres[i].o - other.spheres[j].o).length() - (spheres[i].r + other.spheres[j].r);
145       if(d_max < d)
146       {
147         d_max = d;
148         if(P && Q)
149         {
150           id_a = i; id_b = j;
151         }
152       }
153     }
154   }
155 
156   if(P && Q)
157   {
158     if(id_a != -1 && id_b != -1)
159     {
160       Vec3f v = spheres[id_a].o - spheres[id_b].o;
161       FCL_REAL len_v = v.length();
162       *P = spheres[id_a].o - v * (spheres[id_a].r / len_v);
163       *Q = spheres[id_b].o + v * (spheres[id_b].r / len_v);
164     }
165   }
166 
167   return d_max;
168 }
169 
170 
overlap(const Matrix3f & R0,const Vec3f & T0,const kIOS & b1,const kIOS & b2)171 bool overlap(const Matrix3f& R0, const Vec3f& T0, const kIOS& b1, const kIOS& b2)
172 {
173   kIOS b2_temp = b2;
174   for(unsigned int i = 0; i < b2_temp.num_spheres; ++i)
175   {
176     b2_temp.spheres[i].o = R0 * b2_temp.spheres[i].o + T0;
177   }
178 
179 
180   b2_temp.obb.To = R0 * b2_temp.obb.To + T0;
181   b2_temp.obb.axis[0] = R0 * b2_temp.obb.axis[0];
182   b2_temp.obb.axis[1] = R0 * b2_temp.obb.axis[1];
183   b2_temp.obb.axis[2] = R0 * b2_temp.obb.axis[2];
184 
185   return b1.overlap(b2_temp);
186 }
187 
distance(const Matrix3f & R0,const Vec3f & T0,const kIOS & b1,const kIOS & b2,Vec3f * P,Vec3f * Q)188 FCL_REAL distance(const Matrix3f& R0, const Vec3f& T0, const kIOS& b1, const kIOS& b2, Vec3f* P, Vec3f* Q)
189 {
190   kIOS b2_temp = b2;
191   for(unsigned int i = 0; i < b2_temp.num_spheres; ++i)
192   {
193     b2_temp.spheres[i].o = R0 * b2_temp.spheres[i].o + T0;
194   }
195 
196   return b1.distance(b2_temp, P, Q);
197 }
198 
199 
translate(const kIOS & bv,const Vec3f & t)200 kIOS translate(const kIOS& bv, const Vec3f& t)
201 {
202   kIOS res(bv);
203   for(size_t i = 0; i < res.num_spheres; ++i)
204   {
205     res.spheres[i].o += t;
206   }
207 
208   translate(res.obb, t);
209   return res;
210 }
211 
212 
213 }
214