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