GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: src/BV/kDOP.cpp Lines: 65 111 58.6 %
Date: 2024-02-09 12:57:42 Branches: 35 152 23.0 %

Line Branch Exec Source
1
/*
2
 * Software License Agreement (BSD License)
3
 *
4
 *  Copyright (c) 2011-2014, Willow Garage, Inc.
5
 *  Copyright (c) 2014-2015, 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 <hpp/fcl/BV/kDOP.h>
39
#include <limits>
40
#include <iostream>
41
42
#include <hpp/fcl/collision_data.h>
43
44
namespace hpp {
45
namespace fcl {
46
47
/// @brief Find the smaller and larger one of two values
48
inline void minmax(FCL_REAL a, FCL_REAL b, FCL_REAL& minv, FCL_REAL& maxv) {
49
  if (a > b) {
50
    minv = b;
51
    maxv = a;
52
  } else {
53
    minv = a;
54
    maxv = b;
55
  }
56
}
57
/// @brief Merge the interval [minv, maxv] and value p/
58
90674648
inline void minmax(FCL_REAL p, FCL_REAL& minv, FCL_REAL& maxv) {
59
90674648
  if (p > maxv) maxv = p;
60
90674648
  if (p < minv) minv = p;
61
90674648
}
62
63
/// @brief Compute the distances to planes with normals from KDOP vectors except
64
/// those of AABB face planes
65
template <short N>
66
void getDistances(const Vec3f& /*p*/, FCL_REAL* /*d*/) {}
67
68
/// @brief Specification of getDistances
69
template <>
70
3126712
inline void getDistances<5>(const Vec3f& p, FCL_REAL* d) {
71
3126712
  d[0] = p[0] + p[1];
72
3126712
  d[1] = p[0] + p[2];
73
3126712
  d[2] = p[1] + p[2];
74
3126712
  d[3] = p[0] - p[1];
75
3126712
  d[4] = p[0] - p[2];
76
3126712
}
77
78
template <>
79
3126712
inline void getDistances<6>(const Vec3f& p, FCL_REAL* d) {
80
3126712
  d[0] = p[0] + p[1];
81
3126712
  d[1] = p[0] + p[2];
82
3126712
  d[2] = p[1] + p[2];
83
3126712
  d[3] = p[0] - p[1];
84
3126712
  d[4] = p[0] - p[2];
85
3126712
  d[5] = p[1] - p[2];
86
3126712
}
87
88
template <>
89
3126712
inline void getDistances<9>(const Vec3f& p, FCL_REAL* d) {
90
3126712
  d[0] = p[0] + p[1];
91
3126712
  d[1] = p[0] + p[2];
92
3126712
  d[2] = p[1] + p[2];
93
3126712
  d[3] = p[0] - p[1];
94
3126712
  d[4] = p[0] - p[2];
95
3126712
  d[5] = p[1] - p[2];
96
3126712
  d[6] = p[0] + p[1] - p[2];
97
3126712
  d[7] = p[0] + p[2] - p[1];
98
3126712
  d[8] = p[1] + p[2] - p[0];
99
3126712
}
100
101
template <short N>
102
1768152
KDOP<N>::KDOP() {
103
1768152
  FCL_REAL real_max = (std::numeric_limits<FCL_REAL>::max)();
104

1768152
  dist_.template head<N / 2>().setConstant(real_max);
105

1768152
  dist_.template tail<N / 2>().setConstant(-real_max);
106
1768152
}
107
108
template <short N>
109
KDOP<N>::KDOP(const Vec3f& v) {
110
  for (short i = 0; i < 3; ++i) {
111
    dist_[i] = dist_[N / 2 + i] = v[i];
112
  }
113
114
  FCL_REAL d[(N - 6) / 2];
115
  getDistances<(N - 6) / 2>(v, d);
116
  for (short i = 0; i < (N - 6) / 2; ++i) {
117
    dist_[3 + i] = dist_[3 + i + N / 2] = d[i];
118
  }
119
}
120
121
template <short N>
122
KDOP<N>::KDOP(const Vec3f& a, const Vec3f& b) {
123
  for (short i = 0; i < 3; ++i) {
124
    minmax(a[i], b[i], dist_[i], dist_[i + N / 2]);
125
  }
126
127
  FCL_REAL ad[(N - 6) / 2], bd[(N - 6) / 2];
128
  getDistances<(N - 6) / 2>(a, ad);
129
  getDistances<(N - 6) / 2>(b, bd);
130
  for (short i = 0; i < (N - 6) / 2; ++i) {
131
    minmax(ad[i], bd[i], dist_[3 + i], dist_[3 + i + N / 2]);
132
  }
133
}
134
135
template <short N>
136
bool KDOP<N>::overlap(const KDOP<N>& other) const {
137
  if ((dist_.template head<N / 2>() > other.dist_.template tail<N / 2>()).any())
138
    return false;
139
  if ((dist_.template tail<N / 2>() < other.dist_.template head<N / 2>()).any())
140
    return false;
141
  return true;
142
}
143
144
template <short N>
145
41454528
bool KDOP<N>::overlap(const KDOP<N>& other, const CollisionRequest& request,
146
                      FCL_REAL& sqrDistLowerBound) const {
147
41454528
  const FCL_REAL breakDistance(request.break_distance +
148
41454528
                               request.security_margin);
149
150

41454528
  FCL_REAL a =
151

41454528
      (dist_.template head<N / 2>() - other.dist_.template tail<N / 2>())
152
          .minCoeff();
153
41454528
  if (a > breakDistance) {
154
17488
    sqrDistLowerBound = a * a;
155
17488
    return false;
156
  }
157
158

41437040
  FCL_REAL b =
159

41437040
      (other.dist_.template head<N / 2>() - dist_.template tail<N / 2>())
160
          .minCoeff();
161
41437040
  if (b > breakDistance) {
162
32230
    sqrDistLowerBound = b * b;
163
32230
    return false;
164
  }
165
166
41404810
  sqrDistLowerBound = std::min(a, b);
167
41404810
  return true;
168
}
169
170
template <short N>
171
bool KDOP<N>::inside(const Vec3f& p) const {
172
  if ((p.array() < dist_.template head<3>()).any()) return false;
173
  if ((p.array() > dist_.template segment<3>(N / 2)).any()) return false;
174
175
  enum { P = ((N - 6) / 2) };
176
  Eigen::Array<FCL_REAL, P, 1> d;
177
  getDistances<P>(p, d.data());
178
179
  if ((d < dist_.template segment<P>(3)).any()) return false;
180
  if ((d > dist_.template segment<P>(3 + N / 2)).any()) return false;
181
182
  return true;
183
}
184
185
template <short N>
186
18760272
KDOP<N>& KDOP<N>::operator+=(const Vec3f& p) {
187
75041088
  for (short i = 0; i < 3; ++i) {
188

56280816
    minmax(p[i], dist_[i], dist_[N / 2 + i]);
189
  }
190
191
  FCL_REAL pd[(N - 6) / 2];
192
18760272
  getDistances<(N - 6) / 2>(p, pd);
193
143828752
  for (short i = 0; i < (N - 6) / 2; ++i) {
194

125068480
    minmax(pd[i], dist_[3 + i], dist_[3 + N / 2 + i]);
195
  }
196
197
18760272
  return *this;
198
}
199
200
template <short N>
201
39222
KDOP<N>& KDOP<N>::operator+=(const KDOP<N>& other) {
202
418368
  for (short i = 0; i < N / 2; ++i) {
203
379146
    dist_[i] = std::min(other.dist_[i], dist_[i]);
204
379146
    dist_[i + N / 2] = std::max(other.dist_[i + N / 2], dist_[i + N / 2]);
205
  }
206
39222
  return *this;
207
}
208
209
template <short N>
210
39222
KDOP<N> KDOP<N>::operator+(const KDOP<N>& other) const {
211
39222
  KDOP<N> res(*this);
212

78444
  return res += other;
213
}
214
215
template <short N>
216
FCL_REAL KDOP<N>::distance(const KDOP<N>& /*other*/, Vec3f* /*P*/,
217
                           Vec3f* /*Q*/) const {
218
  std::cerr << "KDOP distance not implemented!" << std::endl;
219
  return 0.0;
220
}
221
222
template <short N>
223
KDOP<N> translate(const KDOP<N>& bv, const Vec3f& t) {
224
  KDOP<N> res(bv);
225
  for (short i = 0; i < 3; ++i) {
226
    res.dist(i) += t[i];
227
    res.dist(short(N / 2 + i)) += t[i];
228
  }
229
230
  FCL_REAL d[(N - 6) / 2];
231
  getDistances<(N - 6) / 2>(t, d);
232
  for (short i = 0; i < (N - 6) / 2; ++i) {
233
    res.dist(short(3 + i)) += d[i];
234
    res.dist(short(3 + i + N / 2)) += d[i];
235
  }
236
237
  return res;
238
}
239
240
template class KDOP<16>;
241
template class KDOP<18>;
242
template class KDOP<24>;
243
244
template KDOP<16> translate<16>(const KDOP<16>&, const Vec3f&);
245
template KDOP<18> translate<18>(const KDOP<18>&, const Vec3f&);
246
template KDOP<24> translate<24>(const KDOP<24>&, const Vec3f&);
247
248
}  // namespace fcl
249
250
}  // namespace hpp