GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: test/geometric_shapes.cpp Lines: 2782 2826 98.4 %
Date: 2024-02-09 12:57:42 Branches: 6968 14170 49.2 %

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
#define BOOST_TEST_MODULE FCL_GEOMETRIC_SHAPES
39
#include <boost/test/included/unit_test.hpp>
40
41
#include <hpp/fcl/narrowphase/narrowphase.h>
42
#include <hpp/fcl/collision.h>
43
#include <hpp/fcl/distance.h>
44
#include "utility.h"
45
#include <iostream>
46
#include <hpp/fcl/internal/tools.h>
47
#include <hpp/fcl/shape/geometric_shape_to_BVH_model.h>
48
49
using namespace hpp::fcl;
50
51
FCL_REAL extents[6] = {0, 0, 0, 10, 10, 10};
52
53
FCL_REAL tol_gjk = 0.01;
54
GJKSolver solver1;
55
GJKSolver solver2;
56
57
int line;
58
#define SET_LINE line = __LINE__
59
#define FCL_CHECK(cond) \
60
  BOOST_CHECK_MESSAGE(cond, "from line " << line << ": " #cond)
61
#define FCL_CHECK_EQUAL(a, b)                                                \
62
  BOOST_CHECK_MESSAGE((a) == (b), "from line " << line << ": " #a "[" << (a) \
63
                                               << "] != " #b "[" << (b)      \
64
                                               << "].")
65
#define BOOST_CHECK_FALSE(p) BOOST_CHECK(!(p))
66
67
namespace hpp {
68
namespace fcl {
69
std::ostream& operator<<(std::ostream& os, const ShapeBase&) {
70
  return os << "a_shape";
71
}
72
73
std::ostream& operator<<(std::ostream& os, const Box& b) {
74
  return os << "Box(" << 2 * b.halfSide.transpose() << ')';
75
}
76
}  // namespace fcl
77
}  // namespace hpp
78
79
template <typename S1, typename S2>
80
void printComparisonError(const std::string& comparison_type, const S1& s1,
81
                          const Transform3f& tf1, const S2& s2,
82
                          const Transform3f& tf2,
83
                          const Vec3f& contact_or_normal,
84
                          const Vec3f& expected_contact_or_normal,
85
                          bool check_opposite_normal, FCL_REAL tol) {
86
  std::cout << "Disagreement between " << comparison_type << " and expected_"
87
            << comparison_type << " for " << getNodeTypeName(s1.getNodeType())
88
            << " and " << getNodeTypeName(s2.getNodeType()) << ".\n"
89
            << "tf1.quaternion: " << tf1.getQuatRotation() << std::endl
90
            << "tf1.translation: " << tf1.getTranslation().transpose()
91
            << std::endl
92
            << "tf2.quaternion: " << tf2.getQuatRotation() << std::endl
93
            << "tf2.translation: " << tf2.getTranslation().transpose()
94
            << std::endl
95
            << comparison_type << ": " << contact_or_normal.transpose()
96
            << std::endl
97
            << "expected_" << comparison_type << ": "
98
            << expected_contact_or_normal.transpose();
99
100
  if (check_opposite_normal)
101
    std::cout << " or " << -expected_contact_or_normal.transpose();
102
103
  std::cout << std::endl
104
            << "difference: "
105
            << (contact_or_normal - expected_contact_or_normal).norm()
106
            << std::endl
107
            << "tolerance: " << tol << std::endl;
108
}
109
110
template <typename S1, typename S2>
111
void printComparisonError(const std::string& comparison_type, const S1& s1,
112
                          const Transform3f& tf1, const S2& s2,
113
                          const Transform3f& tf2, FCL_REAL depth,
114
                          FCL_REAL expected_depth, FCL_REAL tol) {
115
  std::cout << "Disagreement between " << comparison_type << " and expected_"
116
            << comparison_type << " for " << getNodeTypeName(s1.getNodeType())
117
            << " and " << getNodeTypeName(s2.getNodeType()) << ".\n"
118
            << "tf1.quaternion: " << tf1.getQuatRotation() << std::endl
119
            << "tf1.translation: " << tf1.getTranslation() << std::endl
120
            << "tf2.quaternion: " << tf2.getQuatRotation() << std::endl
121
            << "tf2.translation: " << tf2.getTranslation() << std::endl
122
            << "depth: " << depth << std::endl
123
            << "expected_depth: " << expected_depth << std::endl
124
            << "difference: " << std::fabs(depth - expected_depth) << std::endl
125
            << "tolerance: " << tol << std::endl;
126
}
127
128
template <typename S1, typename S2>
129
456
void compareContact(const S1& s1, const Transform3f& tf1, const S2& s2,
130
                    const Transform3f& tf2, const Vec3f& contact,
131
                    Vec3f* expected_point, FCL_REAL depth,
132
                    FCL_REAL* expected_depth, const Vec3f& normal,
133
                    Vec3f* expected_normal, bool check_opposite_normal,
134
                    FCL_REAL tol) {
135
✓✓
456
  if (expected_point) {
136
272
    bool contact_equal = isEqual(contact, *expected_point, tol);
137
✓✗✓✗
✓✗✓✗
✓✗✓✗
✗✓
272
    FCL_CHECK(contact_equal);
138
✗✓
272
    if (!contact_equal)
139
      printComparisonError("contact", s1, tf1, s2, tf2, contact,
140
                           *expected_point, false, tol);
141
  }
142
143
✓✓
456
  if (expected_depth) {
144
302
    bool depth_equal = std::fabs(depth - *expected_depth) < tol;
145
✓✗✓✗
✓✗✓✗
✓✗✓✗
✗✓
302
    FCL_CHECK(depth_equal);
146
✗✓
302
    if (!depth_equal)
147
      printComparisonError("depth", s1, tf1, s2, tf2, depth, *expected_depth,
148
                           tol);
149
  }
150
151
✓✓
456
  if (expected_normal) {
152
370
    bool normal_equal = isEqual(normal, *expected_normal, tol);
153
154
✓✓✓✗
370
    if (!normal_equal && check_opposite_normal)
155
✓✗
20
      normal_equal = isEqual(normal, -(*expected_normal), tol);
156
157
✓✗✓✗
✓✗✓✗
✓✗✓✗
✗✓
370
    FCL_CHECK(normal_equal);
158
✗✓
370
    if (!normal_equal)
159
      printComparisonError("normal", s1, tf1, s2, tf2, normal, *expected_normal,
160
                           check_opposite_normal, tol);
161
  }
162
456
}
163
164
template <typename S1, typename S2>
165
640
void testShapeIntersection(const S1& s1, const Transform3f& tf1, const S2& s2,
166
                           const Transform3f& tf2, bool expect_collision,
167
                           Vec3f* expected_point = NULL,
168
                           FCL_REAL* expected_depth = NULL,
169
                           Vec3f* expected_normal = NULL,
170
                           bool check_opposite_normal = false,
171
                           FCL_REAL tol = 1e-9) {
172
✓✗
640
  CollisionRequest request;
173
✓✗
1280
  CollisionResult result;
174
175
✓✗
640
  Vec3f contact;
176
✓✗
640
  Vec3f normal;  // normal direction should be from object 1 to object 2
177
  bool collision;
178
640
  bool check_failed = false;
179
180
640
  request.enable_contact = false;
181
640
  result.clear();
182
✓✗
640
  collision = (collide(&s1, tf1, &s2, tf2, request, result) > 0);
183
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✗✓
640
  FCL_CHECK_EQUAL(collision, expect_collision);
184
✓✗✗✓
640
  check_failed = check_failed || (collision != expect_collision);
185
186
640
  request.enable_contact = true;
187
640
  result.clear();
188
✓✗
640
  collision = (collide(&s1, tf1, &s2, tf2, request, result) > 0);
189
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✗✓
640
  FCL_CHECK_EQUAL(collision, expect_collision);
190
✓✗✗✓
640
  check_failed = check_failed || (collision != expect_collision);
191
192
✗✓
640
  if (check_failed) {
193
    BOOST_TEST_MESSAGE("Failure occured between " << s1 << " and " << s2
194
                                                  << " at transformations\n"
195
                                                  << tf1 << '\n'
196
                                                  << tf2);
197
  }
198
199
✓✓
640
  if (expect_collision) {
200
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✗✓
456
    FCL_CHECK_EQUAL(result.numContacts(), 1);
201
✓✗
456
    if (result.numContacts() == 1) {
202
✓✗✓✗
456
      Contact contact = result.getContact(0);
203
✓✗
456
      compareContact(s1, tf1, s2, tf2, contact.pos, expected_point,
204
                     contact.penetration_depth, expected_depth, contact.normal,
205
                     expected_normal, check_opposite_normal, tol);
206
    }
207
  }
208
640
}
209
210
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗
4
BOOST_AUTO_TEST_CASE(box_to_bvh) {
211
✓✗
4
  Box shape(1, 1, 1);
212
✓✗
2
  BVHModel<OBB> bvh;
213
✓✗✓✗
2
  generateBVHModel(bvh, shape, Transform3f());
214
2
}
215
216
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗
4
BOOST_AUTO_TEST_CASE(sphere_to_bvh) {
217
✓✗
4
  Sphere shape(1);
218
✓✗
2
  BVHModel<OBB> bvh;
219
✓✗✓✗
2
  generateBVHModel(bvh, shape, Transform3f(), 10, 10);
220
✓✗✓✗
2
  generateBVHModel(bvh, shape, Transform3f(), 50);
221
2
}
222
223
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗
4
BOOST_AUTO_TEST_CASE(cylinder_to_bvh) {
224
✓✗
4
  Cylinder shape(1, 1);
225
✓✗
2
  BVHModel<OBB> bvh;
226
✓✗✓✗
2
  generateBVHModel(bvh, shape, Transform3f(), 10, 10);
227
✓✗✓✗
2
  generateBVHModel(bvh, shape, Transform3f(), 50);
228
2
}
229
230
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗
4
BOOST_AUTO_TEST_CASE(cone_to_bvh) {
231
✓✗
4
  Cone shape(1, 1);
232
✓✗
2
  BVHModel<OBB> bvh;
233
✓✗✓✗
2
  generateBVHModel(bvh, shape, Transform3f(), 10, 10);
234
✓✗✓✗
2
  generateBVHModel(bvh, shape, Transform3f(), 50);
235
2
}
236
237
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗
4
BOOST_AUTO_TEST_CASE(shapeIntersection_cylinderbox) {
238
✓✗
4
  Cylinder s1(0.029, 0.1);
239
✓✗
2
  Box s2(1.6, 0.6, 0.025);
240
241
  Transform3f tf1(
242
      Quaternion3f(0.5279170511703305, -0.50981118132505521,
243
✓✗
2
                   -0.67596178682051911, 0.0668715876735793),
244
✓✗✓✗
4
      Vec3f(0.041218354748013122, 1.2022554710435607, 0.77338855025700015));
245
246
  Transform3f tf2(
247
✓✗
2
      Quaternion3f(0.70738826916719977, 0, 0, 0.70682518110536596),
248
✓✗✓✗
4
      Vec3f(-0.29936284351096382, 0.80023864435868775, 0.71750000000000003));
249
250
✓✗
2
  GJKSolver solver;
251
  FCL_REAL distance;
252
✓✗✓✗
✓✗
2
  Vec3f p1, p2, normal;
253
✓✗
2
  bool res = solver.shapeDistance(s1, tf1, s2, tf2, distance, p1, p2, normal);
254
✓✗✓✗
✓✗✓✗
✗✓✗✗
✗✗✓✗
✓✗✗✓
2
  BOOST_CHECK((res && distance > 0) || (!res && distance <= 0));
255
  // If objects are not colliding, p2 should be outside the cylinder and
256
  // p1 should be outside the box
257
✓✗✓✗
2
  Vec3f p2Loc(tf1.inverse().transform(p2));
258
✓✗✗✓
2
  bool p2_in_cylinder((fabs(p2Loc[2]) <= s1.halfLength) &&
259
                      (p2Loc[0] * p2Loc[0] + p2Loc[1] * p2Loc[1] <= s1.radius));
260
✓✗✓✗
2
  Vec3f p1Loc(tf2.inverse().transform(p1));
261
✓✗✓✗
✓✗✓✗
✓✗
2
  bool p1_in_box = (p1Loc.array().abs() <= s2.halfSide.array()).all();
262
✓✗✓✗
✓✗✓✗
✓✗
2
  std::cout << "p2 in cylinder = (" << p2Loc.transpose() << ")" << std::endl;
263
✓✗✓✗
✓✗✓✗
✓✗
2
  std::cout << "p1 in box = (" << p1Loc.transpose() << ")" << std::endl;
264
265
✓✗✓✗
✓✗✓✗
✓✗✗✓
✗✗✗✗
✗✗✓✗
✓✗✗✓
2
  BOOST_CHECK((res && !p2_in_cylinder && !p1_in_box) ||
266
              (!res && p2_in_cylinder && p1_in_box));
267
268
✓✗
2
  res = solver.shapeDistance(s2, tf2, s1, tf1, distance, p2, p1, normal);
269
✓✗✓✗
✓✗✓✗
✗✓✗✗
✗✗✓✗
✓✗✗✓
2
  BOOST_CHECK((res && distance > 0) || (!res && distance <= 0));
270
  // If objects are not colliding, p2 should be outside the cylinder and
271
  // p1 should be outside the box
272
273
✓✗✓✗
2
  p2Loc = tf1.inverse().transform(p2);
274
✓✗✗✓
2
  p2_in_cylinder = (fabs(p2Loc[2]) <= s1.halfLength) &&
275
                   (p2Loc[0] * p2Loc[0] + p2Loc[1] * p2Loc[1] <= s1.radius);
276
✓✗✓✗
2
  p1Loc = tf2.inverse().transform(p1);
277
✓✗✓✗
✓✗✓✗
✓✗
2
  p1_in_box = (p1Loc.array().abs() <= s2.halfSide.array()).all();
278
279
✓✗✓✗
✓✗✓✗
✓✗
2
  std::cout << "p2 in cylinder = (" << p2Loc.transpose() << ")" << std::endl;
280
✓✗✓✗
✓✗✓✗
✓✗
2
  std::cout << "p1 in box = (" << p1.transpose() << ")" << std::endl;
281
282
✓✗✓✗
✓✗✓✗
✓✗✗✓
✗✗✗✗
✗✗✓✗
✓✗✗✓
2
  BOOST_CHECK((res && !p2_in_cylinder && !p1_in_box) ||
283
              (!res && p2_in_cylinder && p1_in_box));
284
285
✓✗
2
  s1 = Cylinder(0.06, 0.1);
286
✓✗
2
  tf1.setTranslation(
287
✓✗
2
      Vec3f(-0.66734052046473924, 0.22219183277457269, 0.76825248755616293));
288
✓✗
2
  tf1.setQuatRotation(Quaternion3f(0.52613359459338371, 0.32189408354839893,
289
✓✗
2
                                   0.70415587451837913, -0.35175580165512249));
290
✓✗
2
  res = solver.shapeDistance(s1, tf1, s2, tf2, distance, p1, p2, normal);
291
2
}
292
293
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗
4
BOOST_AUTO_TEST_CASE(shapeIntersection_spheresphere) {
294
✓✗
4
  Sphere s1(20);
295
✓✗
4
  Sphere s2(10);
296
297
✓✗
2
  Transform3f tf1;
298
✓✗
2
  Transform3f tf2;
299
300
✓✗
2
  Transform3f transform;
301
✓✗
2
  generateRandomTransform(extents, transform);
302
303
  // Vec3f point;
304
  // FCL_REAL depth;
305
✓✗
2
  Vec3f normal;
306
307
✓✗✓✗
2
  tf1 = Transform3f();
308
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(40, 0, 0));
309
2
  SET_LINE;
310
✓✗
2
  testShapeIntersection(s1, tf1, s2, tf2, false);
311
312
✓✗
2
  tf1 = transform;
313
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(40, 0, 0));
314
2
  SET_LINE;
315
✓✗
2
  testShapeIntersection(s1, tf1, s2, tf2, false);
316
317
✓✗✓✗
2
  tf1 = Transform3f();
318
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(30, 0, 0));
319
✓✗✓✗
✓✗
2
  normal << 1, 0, 0;
320
2
  SET_LINE;
321
✓✗
2
  testShapeIntersection(s1, tf1, s2, tf2, true, NULL, NULL, &normal);
322
323
✓✗✓✗
2
  tf1 = Transform3f();
324
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(30.01, 0, 0));
325
2
  SET_LINE;
326
✓✗
2
  testShapeIntersection(s1, tf1, s2, tf2, false);
327
328
✓✗
2
  tf1 = transform;
329
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(30.01, 0, 0));
330
✓✗✓✗
✓✗
2
  normal = transform.getRotation() * Vec3f(1, 0, 0);
331
2
  SET_LINE;
332
✓✗
2
  testShapeIntersection(s1, tf1, s2, tf2, false);
333
334
✓✗✓✗
2
  tf1 = Transform3f();
335
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(29.9, 0, 0));
336
✓✗✓✗
✓✗
2
  normal << 1, 0, 0;
337
2
  SET_LINE;
338
✓✗
2
  testShapeIntersection(s1, tf1, s2, tf2, true, NULL, NULL, &normal);
339
340
✓✗
2
  tf1 = transform;
341
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(29.9, 0, 0));
342
✓✗✓✗
✓✗
2
  normal = transform.getRotation() * Vec3f(1, 0, 0);
343
2
  SET_LINE;
344
✓✗
2
  testShapeIntersection(s1, tf1, s2, tf2, true, NULL, NULL, &normal);
345
346
✓✗✓✗
2
  tf1 = Transform3f();
347
✓✗✓✗
2
  tf2 = Transform3f();
348
✓✗
2
  normal.setZero();  // If the centers of two sphere are at the same position,
349
                     // the normal is (0, 0, 0)
350
2
  SET_LINE;
351
✓✗
2
  testShapeIntersection(s1, tf1, s2, tf2, true, NULL, NULL, &normal);
352
353
✓✗
2
  tf1 = transform;
354
✓✗
2
  tf2 = transform;
355
✓✗
2
  normal.setZero();  // If the centers of two sphere are at the same position,
356
                     // the normal is (0, 0, 0)
357
2
  SET_LINE;
358
✓✗
2
  testShapeIntersection(s1, tf1, s2, tf2, true, NULL, NULL, &normal);
359
360
✓✗✓✗
2
  tf1 = Transform3f();
361
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(-29.9, 0, 0));
362
✓✗✓✗
✓✗
2
  normal << -1, 0, 0;
363
2
  SET_LINE;
364
✓✗
2
  testShapeIntersection(s1, tf1, s2, tf2, true, NULL, NULL, &normal);
365
366
✓✗
2
  tf1 = transform;
367
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(-29.9, 0, 0));
368
✓✗✓✗
✓✗
2
  normal = transform.getRotation() * Vec3f(-1, 0, 0);
369
2
  SET_LINE;
370
✓✗
2
  testShapeIntersection(s1, tf1, s2, tf2, true, NULL, NULL, &normal);
371
372
✓✗✓✗
2
  tf1 = Transform3f();
373
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(-30.0, 0, 0));
374
✓✗✓✗
✓✗
2
  normal << -1, 0, 0;
375
2
  SET_LINE;
376
✓✗
2
  testShapeIntersection(s1, tf1, s2, tf2, true, NULL, NULL, &normal);
377
378
✓✗✓✗
2
  tf1 = Transform3f();
379
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(-30.01, 0, 0));
380
✓✗✓✗
✓✗
2
  normal << -1, 0, 0;
381
2
  SET_LINE;
382
✓✗
2
  testShapeIntersection(s1, tf1, s2, tf2, false);
383
384
✓✗
2
  tf1 = transform;
385
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(-30.01, 0, 0));
386
2
  SET_LINE;
387
✓✗
2
  testShapeIntersection(s1, tf1, s2, tf2, false);
388
2
}
389
390
2075
bool compareContactPoints(const Vec3f& c1, const Vec3f& c2) {
391
2075
  return c1[2] < c2[2];
392
}  // Ascending order
393
394
100
void testBoxBoxContactPoints(const Matrix3f& R) {
395
✓✗
200
  Box s1(100, 100, 100);
396
✓✗
200
  Box s2(10, 20, 30);
397
398
  // Vertices of s2
399
✓✗
200
  std::vector<Vec3f> vertices(8);
400
✓✗✓✗
✓✗
100
  vertices[0] << 1, 1, 1;
401
✓✗✓✗
✓✗
100
  vertices[1] << 1, 1, -1;
402
✓✗✓✗
✓✗
100
  vertices[2] << 1, -1, 1;
403
✓✗✓✗
✓✗
100
  vertices[3] << 1, -1, -1;
404
✓✗✓✗
✓✗
100
  vertices[4] << -1, 1, 1;
405
✓✗✓✗
✓✗
100
  vertices[5] << -1, 1, -1;
406
✓✗✓✗
✓✗
100
  vertices[6] << -1, -1, 1;
407
✓✗✓✗
✓✗
100
  vertices[7] << -1, -1, -1;
408
409
✓✓
900
  for (std::size_t i = 0; i < 8; ++i) {
410
✓✗✓✗
✓✗
800
    vertices[i].array() *= s2.halfSide.array();
411
  }
412
413
✓✗✓✗
100
  Transform3f tf1 = Transform3f(Vec3f(0, 0, -50));
414
✓✗
100
  Transform3f tf2 = Transform3f(R);
415
416
✓✗
100
  Vec3f normal;
417
✓✗
100
  Vec3f point(0., 0., 0.);
418
  double distance;
419
420
  // Make sure the two boxes are colliding
421
100
  solver1.gjk_tolerance = 1e-5;
422
100
  solver1.epa_tolerance = 1e-5;
423
  bool res =
424
✓✗
100
      solver1.shapeIntersect(s1, tf1, s2, tf2, distance, true, &point, &normal);
425
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✗✓
100
  FCL_CHECK(res);
426
427
  // Compute global vertices
428
✓✓✓✗
900
  for (std::size_t i = 0; i < 8; ++i) vertices[i] = tf2.transform(vertices[i]);
429
430
  // Sort the vertices so that the lowest vertex along z-axis comes first
431
✓✗
100
  std::sort(vertices.begin(), vertices.end(), compareContactPoints);
432
433
  // The lowest vertex along z-axis should be the contact point
434
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✗✓
100
  FCL_CHECK(normal.isApprox(Vec3f(0, 0, 1), 1e-6));
435
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✗✓
100
  FCL_CHECK(vertices[0].head<2>().isApprox(point.head<2>(), 1e-6));
436
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✗✓
100
  FCL_CHECK(vertices[0][2] <= point[2] && point[2] < 0);
437
100
}
438
439
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗
4
BOOST_AUTO_TEST_CASE(shapeIntersection_boxbox) {
440
✓✗
4
  Box s1(20, 40, 50);
441
✓✗
4
  Box s2(10, 10, 10);
442
443
✓✗
2
  Transform3f tf1;
444
✓✗
2
  Transform3f tf2;
445
446
✓✗
2
  Transform3f transform;
447
✓✗
2
  generateRandomTransform(extents, transform);
448
449
  // Vec3f point;
450
  // FCL_REAL depth;
451
✓✗
2
  Vec3f normal;
452
453
✓✗
2
  Quaternion3f q;
454
✓✗✓✗
2
  q = AngleAxis((FCL_REAL)3.140 / 6, UnitZ);
455
456
✓✗✓✗
2
  tf1 = Transform3f();
457
✓✗✓✗
2
  tf2 = Transform3f();
458
  // TODO: Need convention for normal when the centers of two objects are at
459
  // same position. The current result is (1, 0, 0).
460
✓✗✓✗
✓✗
2
  normal << 1, 0, 0;
461
2
  SET_LINE;
462
✓✗
2
  testShapeIntersection(s1, tf1, s2, tf2, true, NULL, NULL, 0x0);
463
464
✓✗
2
  tf1 = transform;
465
✓✗
2
  tf2 = transform;
466
  // TODO: Need convention for normal when the centers of two objects are at
467
  // same position. The current result is (1, 0, 0).
468
✓✗✓✗
✓✗
2
  normal = transform.getRotation() * Vec3f(1, 0, 0);
469
2
  SET_LINE;
470
✓✗
2
  testShapeIntersection(s1, tf1, s2, tf2, true, NULL, NULL, 0x0);
471
472
✓✗✓✗
2
  tf1 = Transform3f();
473
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(15, 0, 0));
474
✓✗✓✗
✓✗
2
  normal << 1, 0, 0;
475
2
  SET_LINE;
476
✓✗
2
  testShapeIntersection(s1, tf1, s2, tf2, true, NULL, NULL, &normal, false,
477
                        1e-8);
478
479
✓✗✓✗
2
  tf1 = Transform3f();
480
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(15.01, 0, 0));
481
2
  SET_LINE;
482
✓✗
2
  testShapeIntersection(s1, tf1, s2, tf2, false);
483
484
✓✗✓✗
2
  tf1 = Transform3f();
485
✓✗✓✗
2
  tf2 = Transform3f(q);
486
✓✗✓✗
✓✗
2
  normal << 1, 0, 0;
487
2
  SET_LINE;
488
✓✗
2
  testShapeIntersection(s1, tf1, s2, tf2, true, NULL, NULL, 0x0);
489
490
✓✗
2
  tf1 = transform;
491
✓✗✓✗
✓✗
2
  tf2 = transform * Transform3f(q);
492
✓✗✓✗
✓✗
2
  normal = transform.getRotation() * Vec3f(1, 0, 0);
493
2
  SET_LINE;
494
✓✗
2
  testShapeIntersection(s1, tf1, s2, tf2, true, NULL, NULL, 0x0);
495
496
2
  int numTests = 100;
497
✓✓
202
  for (int i = 0; i < numTests; ++i) {
498
✓✗
200
    Transform3f tf;
499
✓✗
200
    generateRandomTransform(extents, tf);
500
200
    SET_LINE;
501
✓✗
200
    testBoxBoxContactPoints(tf.getRotation());
502
  }
503
2
}
504
505
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗
4
BOOST_AUTO_TEST_CASE(shapeIntersection_spherebox) {
506
✓✗
4
  Sphere s1(20);
507
✓✗
4
  Box s2(5, 5, 5);
508
509
✓✗
2
  Transform3f tf1;
510
✓✗
2
  Transform3f tf2;
511
512
✓✗
2
  Transform3f transform;
513
✓✗
2
  generateRandomTransform(extents, transform);
514
515
  // Vec3f point;
516
  // FCL_REAL depth;
517
✓✗
2
  Vec3f normal;
518
519
✓✗✓✗
2
  tf1 = Transform3f();
520
✓✗✓✗
2
  tf2 = Transform3f();
521
  // TODO: Need convention for normal when the centers of two objects are at
522
  // same position. The current result is (-1, 0, 0).
523
✓✗✓✗
✓✗
2
  normal << -1, 0, 0;
524
2
  SET_LINE;
525
✓✗
2
  testShapeIntersection(s1, tf1, s2, tf2, true, NULL, NULL, NULL);
526
527
✓✗
2
  tf1 = transform;
528
✓✗
2
  tf2 = transform;
529
  // TODO: Need convention for normal when the centers of two objects are at
530
  // same position.
531
2
  SET_LINE;
532
✓✗
2
  testShapeIntersection(s1, tf1, s2, tf2, true, NULL, NULL, NULL);
533
534
✓✗✓✗
2
  tf1 = Transform3f();
535
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(22.50001, 0, 0));
536
2
  SET_LINE;
537
✓✗
2
  testShapeIntersection(s1, tf1, s2, tf2, false);
538
539
✓✗
2
  tf1 = transform;
540
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(22.501, 0, 0));
541
2
  SET_LINE;
542
✓✗
2
  testShapeIntersection(s1, tf1, s2, tf2, false);
543
544
✓✗✓✗
2
  tf1 = Transform3f();
545
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(22.4, 0, 0));
546
✓✗✓✗
✓✗
2
  normal << 1, 0, 0;
547
2
  SET_LINE;
548
✓✗
2
  testShapeIntersection(s1, tf1, s2, tf2, true, NULL, NULL, &normal, false,
549
                        tol_gjk);
550
551
✓✗
2
  tf1 = transform;
552
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(22.4, 0, 0));
553
✓✗✓✗
✓✗
2
  normal = transform.getRotation() * Vec3f(1, 0, 0);
554
2
  SET_LINE;
555
✓✗
2
  testShapeIntersection(s1, tf1, s2, tf2, true, NULL, NULL, &normal, false,
556
                        tol_gjk);
557
2
}
558
559
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗
4
BOOST_AUTO_TEST_CASE(shapeDistance_spherebox) {
560
✓✗
2
  hpp::fcl::Matrix3f rotSphere;
561
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗
2
  rotSphere << 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0;
562
✓✗
2
  hpp::fcl::Vec3f trSphere(0.0, 0.0, 0.0);
563
564
✓✗
2
  hpp::fcl::Matrix3f rotBox;
565
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗
2
  rotBox << 1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0, 1.0;
566
✓✗
2
  hpp::fcl::Vec3f trBox(0.0, 5.0, 3.0);
567
568
✓✗
4
  hpp::fcl::Sphere sphere(1);
569
✓✗
4
  hpp::fcl::Box box(10, 2, 10);
570
571
✓✗
2
  hpp::fcl::DistanceResult result;
572
✓✗✓✗
2
  distance(&sphere, Transform3f(rotSphere, trSphere), &box,
573
✓✗✓✗
2
           Transform3f(rotBox, trBox), DistanceRequest(true), result);
574
575
2
  FCL_REAL eps = Eigen::NumTraits<FCL_REAL>::epsilon();
576
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK_CLOSE(result.min_distance, 3., eps);
577
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  EIGEN_VECTOR_IS_APPROX(result.nearest_points[0], Vec3f(0, 1, 0), eps);
578
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  EIGEN_VECTOR_IS_APPROX(result.nearest_points[1], Vec3f(0, 4, 0), eps);
579
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  EIGEN_VECTOR_IS_APPROX(result.normal, Vec3f(0, 1, 0), eps);
580
2
}
581
582
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗
4
BOOST_AUTO_TEST_CASE(shapeIntersection_spherecapsule) {
583
✓✗
4
  Sphere s1(20);
584
✓✗
4
  Capsule s2(5, 10);
585
586
✓✗
2
  Transform3f tf1;
587
✓✗
2
  Transform3f tf2;
588
589
✓✗
2
  Transform3f transform;
590
✓✗
2
  generateRandomTransform(extents, transform);
591
592
  // Vec3f point;
593
  // FCL_REAL depth;
594
✓✗
2
  Vec3f normal;
595
596
✓✗✓✗
2
  tf1 = Transform3f();
597
✓✗✓✗
2
  tf2 = Transform3f();
598
  // TODO: Need convention for normal when the centers of two objects are at
599
  // same position.
600
2
  SET_LINE;
601
✓✗
2
  testShapeIntersection(s1, tf1, s2, tf2, true, NULL, NULL, NULL);
602
603
✓✗
2
  tf1 = transform;
604
✓✗
2
  tf2 = transform;
605
  // TODO: Need convention for normal when the centers of two objects are at
606
  // same position.
607
2
  SET_LINE;
608
✓✗
2
  testShapeIntersection(s1, tf1, s2, tf2, true, NULL, NULL, NULL);
609
610
✓✗✓✗
2
  tf1 = Transform3f();
611
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(24.9, 0, 0));
612
✓✗✓✗
✓✗
2
  normal << 1, 0, 0;
613
2
  SET_LINE;
614
✓✗
2
  testShapeIntersection(s1, tf1, s2, tf2, true, NULL, NULL, &normal);
615
616
✓✗
2
  tf1 = transform;
617
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(24.9, 0, 0));
618
✓✗✓✗
✓✗
2
  normal = transform.getRotation() * Vec3f(1, 0, 0);
619
2
  SET_LINE;
620
✓✗
2
  testShapeIntersection(s1, tf1, s2, tf2, true, NULL, NULL, &normal);
621
622
✓✗✓✗
2
  tf1 = Transform3f();
623
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(25, 0, 0));
624
✓✗✓✗
✓✗
2
  normal << 1, 0, 0;
625
2
  SET_LINE;
626
✓✗
2
  testShapeIntersection(s1, tf1, s2, tf2, true, NULL, NULL, &normal);
627
628
✓✗
2
  tf1 = transform;
629
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(24.999999, 0, 0));
630
✓✗✓✗
✓✗
2
  normal = transform.getRotation() * Vec3f(1, 0, 0);
631
2
  SET_LINE;
632
✓✗
2
  testShapeIntersection(s1, tf1, s2, tf2, true, NULL, NULL, &normal);
633
634
✓✗✓✗
2
  tf1 = Transform3f();
635
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(25.1, 0, 0));
636
✓✗✓✗
✓✗
2
  normal << 1, 0, 0;
637
2
  SET_LINE;
638
✓✗
2
  testShapeIntersection(s1, tf1, s2, tf2, false);
639
640
✓✗
2
  tf1 = transform;
641
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(25.1, 0, 0));
642
✓✗✓✗
✓✗
2
  normal = transform.getRotation() * Vec3f(1, 0, 0);
643
2
  SET_LINE;
644
✓✗
2
  testShapeIntersection(s1, tf1, s2, tf2, false);
645
2
}
646
647
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗
4
BOOST_AUTO_TEST_CASE(shapeIntersection_cylindercylinder) {
648
✓✗
4
  Cylinder s1(5, 15);
649
✓✗
4
  Cylinder s2(5, 15);
650
651
✓✗
2
  Transform3f tf1;
652
✓✗
2
  Transform3f tf2;
653
654
✓✗
2
  Transform3f transform;
655
✓✗
2
  generateRandomTransform(extents, transform);
656
657
  // Vec3f point;
658
  // FCL_REAL depth;
659
✓✗
2
  Vec3f normal;
660
661
✓✗✓✗
2
  tf1 = Transform3f();
662
✓✗✓✗
2
  tf2 = Transform3f();
663
  // TODO: Need convention for normal when the centers of two objects are at
664
  // same position.
665
2
  SET_LINE;
666
✓✗
2
  testShapeIntersection(s1, tf1, s2, tf2, true, NULL, NULL, NULL);
667
668
✓✗
2
  tf1 = transform;
669
✓✗
2
  tf2 = transform;
670
  // TODO: Need convention for normal when the centers of two objects are at
671
  // same position.
672
2
  SET_LINE;
673
✓✗
2
  testShapeIntersection(s1, tf1, s2, tf2, true, NULL, NULL, NULL);
674
675
✓✗✓✗
2
  tf1 = Transform3f();
676
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(0, 9.9, 0));
677
✓✗✓✗
✓✗
2
  normal << 0, 1, 0;
678
2
  SET_LINE;
679
✓✗
2
  testShapeIntersection(s1, tf1, s2, tf2, true, NULL, NULL, &normal, false,
680
                        tol_gjk);
681
682
✓✗✓✗
2
  tf1 = Transform3f();
683
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(9.9, 0, 0));
684
✓✗✓✗
✓✗
2
  normal << 1, 0, 0;
685
2
  SET_LINE;
686
✓✗
2
  testShapeIntersection(s1, tf1, s2, tf2, true, NULL, NULL, &normal, false,
687
                        tol_gjk);
688
689
✓✗
2
  tf1 = transform;
690
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(9.9, 0, 0));
691
✓✗✓✗
✓✗
2
  normal = transform.getRotation() * Vec3f(1, 0, 0);
692
2
  SET_LINE;
693
✓✗
2
  testShapeIntersection(s1, tf1, s2, tf2, true, NULL, NULL, &normal, false,
694
                        tol_gjk);
695
696
✓✗✓✗
2
  tf1 = Transform3f();
697
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(10.01, 0, 0));
698
2
  SET_LINE;
699
✓✗
2
  testShapeIntersection(s1, tf1, s2, tf2, false);
700
701
✓✗
2
  tf1 = transform;
702
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(10.01, 0, 0));
703
2
  SET_LINE;
704
✓✗
2
  testShapeIntersection(s1, tf1, s2, tf2, false);
705
2
}
706
707
/*
708
BOOST_AUTO_TEST_CASE(shapeIntersection_conecone)
709
{
710
  Cone s1(5, 10);
711
  Cone s2(5, 10);
712
713
  Transform3f tf1;
714
  Transform3f tf2;
715
716
  Transform3f transform;
717
  generateRandomTransform(extents, transform);
718
719
  // Vec3f point;
720
  // FCL_REAL depth;
721
  Vec3f normal;
722
723
  tf1 = Transform3f();
724
  tf2 = Transform3f();
725
  // TODO: Need convention for normal when the centers of two objects are at
726
same position. SET_LINE; testShapeIntersection(s1, tf1, s2, tf2, true, NULL,
727
NULL, NULL);
728
729
  tf1 = transform;
730
  tf2 = transform;
731
  // TODO: Need convention for normal when the centers of two objects are at
732
same position. SET_LINE; testShapeIntersection(s1, tf1, s2, tf2, true, NULL,
733
NULL, NULL);
734
735
  tf1 = Transform3f();
736
  tf2 = Transform3f(Vec3f(9.9, 0, 0));
737
  normal << 1, 0, 0;
738
  SET_LINE; testShapeIntersection(s1, tf1, s2, tf2, true, NULL, NULL, &normal,
739
false, tol_gjk);
740
741
  tf1 = transform;
742
  tf2 = transform * Transform3f(Vec3f(9.9, 0, 0));
743
  normal = transform.getRotation() * Vec3f(1, 0, 0);
744
  SET_LINE; testShapeIntersection(s1, tf1, s2, tf2, true, NULL, NULL, &normal,
745
false, tol_gjk);
746
747
  tf1 = Transform3f();
748
  tf2 = Transform3f(Vec3f(10.001, 0, 0));
749
  SET_LINE; testShapeIntersection(s1, tf1, s2, tf2, false);
750
751
  tf1 = transform;
752
  tf2 = transform * Transform3f(Vec3f(10.001, 0, 0));
753
  SET_LINE; testShapeIntersection(s1, tf1, s2, tf2, false);
754
755
  tf1 = Transform3f();
756
  tf2 = Transform3f(Vec3f(0, 0, 9.9));
757
  normal << 0, 0, 1;
758
  SET_LINE; testShapeIntersection(s1, tf1, s2, tf2, true, NULL, NULL, &normal);
759
760
  tf1 = transform;
761
  tf2 = transform * Transform3f(Vec3f(0, 0, 9.9));
762
  normal = transform.getRotation() * Vec3f(0, 0, 1);
763
  SET_LINE; testShapeIntersection(s1, tf1, s2, tf2, true, NULL, NULL, &normal);
764
}
765
*/
766
767
/*
768
BOOST_AUTO_TEST_CASE(shapeIntersection_conecylinder)
769
{
770
  Cylinder s1(5, 10);
771
  Cone s2(5, 10);
772
773
  Transform3f tf1;
774
  Transform3f tf2;
775
776
  Transform3f transform;
777
  generateRandomTransform(extents, transform);
778
779
  // Vec3f point;
780
  // FCL_REAL depth;
781
  Vec3f normal;
782
783
  tf1 = Transform3f();
784
  tf2 = Transform3f();
785
  // TODO: Need convention for normal when the centers of two objects are at
786
same position. SET_LINE; testShapeIntersection(s1, tf1, s2, tf2, true, NULL,
787
NULL, NULL);
788
789
  tf1 = transform;
790
  tf2 = transform;
791
  // TODO: Need convention for normal when the centers of two objects are at
792
same position. SET_LINE; testShapeIntersection(s1, tf1, s2, tf2, true, NULL,
793
NULL, NULL);
794
795
  tf1 = Transform3f();
796
  tf2 = Transform3f(Vec3f(9.9, 0, 0));
797
  normal << 1, 0, 0;
798
  SET_LINE; testShapeIntersection(s1, tf1, s2, tf2, true, NULL, NULL, &normal,
799
false, 0.061);
800
801
  tf1 = transform;
802
  tf2 = transform * Transform3f(Vec3f(9.9, 0, 0));
803
  normal = transform.getRotation() * Vec3f(1, 0, 0);
804
  SET_LINE; testShapeIntersection(s1, tf1, s2, tf2, true, NULL, NULL, &normal,
805
false, 0.46);
806
807
  tf1 = Transform3f();
808
  tf2 = Transform3f(Vec3f(10.01, 0, 0));
809
  SET_LINE; testShapeIntersection(s1, tf1, s2, tf2, false);
810
811
  tf1 = transform;
812
  tf2 = transform * Transform3f(Vec3f(10.01, 0, 0));
813
  SET_LINE; testShapeIntersection(s1, tf1, s2, tf2, false);
814
815
  tf1 = Transform3f();
816
  tf2 = Transform3f(Vec3f(0, 0, 9.9));
817
  normal << 0, 0, 1;
818
  SET_LINE; testShapeIntersection(s1, tf1, s2, tf2, true, NULL, NULL, &normal);
819
820
  tf1 = transform;
821
  tf2 = transform * Transform3f(Vec3f(0, 0, 9.9));
822
  normal = transform.getRotation() * Vec3f(0, 0, 1);
823
  SET_LINE; testShapeIntersection(s1, tf1, s2, tf2, true, NULL, NULL, &normal);
824
825
  tf1 = Transform3f();
826
  tf2 = Transform3f(Vec3f(0, 0, 10.01));
827
  SET_LINE; testShapeIntersection(s1, tf1, s2, tf2, false);
828
829
  tf1 = transform;
830
  tf2 = transform * Transform3f(Vec3f(0, 0, 10.01));
831
  SET_LINE; testShapeIntersection(s1, tf1, s2, tf2, false);
832
}
833
*/
834
835
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗
4
BOOST_AUTO_TEST_CASE(shapeIntersection_spheretriangle) {
836
✓✗
4
  Sphere s(10);
837
✓✓✓✗
8
  Vec3f t[3];
838
✓✗✓✗
✓✗
2
  t[0] << 20, 0, 0;
839
✓✗✓✗
✓✗
2
  t[1] << -20, 0, 0;
840
✓✗✓✗
✓✗
2
  t[2] << 0, 20, 0;
841
842
✓✗
2
  Transform3f transform;
843
✓✗
2
  generateRandomTransform(extents, transform);
844
845
✓✗✓✗
✓✗
2
  Vec3f c1, c2, normal;
846
  FCL_REAL distance;
847
  bool res;
848
849
  res =
850
✓✗✓✗
2
      solver1.shapeTriangleInteraction(s, Transform3f(), t[0], t[1], t[2],
851
✓✗
4
                                       Transform3f(), distance, c1, c2, normal);
852
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(res);
853
854
✓✗
2
  res = solver1.shapeTriangleInteraction(s, transform, t[0], t[1], t[2],
855
                                         transform, distance, c1, c2, normal);
856
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(res);
857
858
✓✗✓✗
✓✗
2
  t[0] << 30, 0, 0;
859
✓✗✓✗
✓✗
2
  t[1] << 9.9, -20, 0;
860
✓✗✓✗
✓✗
2
  t[2] << 9.9, 20, 0;
861
  res =
862
✓✗✓✗
2
      solver1.shapeTriangleInteraction(s, Transform3f(), t[0], t[1], t[2],
863
✓✗
4
                                       Transform3f(), distance, c1, c2, normal);
864
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(res);
865
866
✓✗
2
  res = solver1.shapeTriangleInteraction(s, transform, t[0], t[1], t[2],
867
                                         transform, distance, c1, c2, normal);
868
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(res);
869
870
  res =
871
✓✗✓✗
2
      solver1.shapeTriangleInteraction(s, Transform3f(), t[0], t[1], t[2],
872
✓✗
4
                                       Transform3f(), distance, c1, c2, normal);
873
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(res);
874
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(isEqual(normal, Vec3f(1, 0, 0), 1e-9));
875
876
✓✗
2
  res = solver1.shapeTriangleInteraction(s, transform, t[0], t[1], t[2],
877
                                         transform, distance, c1, c2, normal);
878
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(res);
879
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✗✓
2
  BOOST_CHECK(isEqual(normal, transform.getRotation() * Vec3f(1, 0, 0), 1e-9));
880
2
}
881
882
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗
4
BOOST_AUTO_TEST_CASE(shapeIntersection_halfspacetriangle) {
883
✓✗✓✗
4
  Halfspace hs(Vec3f(1, 0, 0), 0);
884
✓✓✓✗
8
  Vec3f t[3];
885
✓✗✓✗
✓✗
2
  t[0] << 20, 0, 0;
886
✓✗✓✗
✓✗
2
  t[1] << -20, 0, 0;
887
✓✗✓✗
✓✗
2
  t[2] << 0, 20, 0;
888
889
✓✗
2
  Transform3f transform;
890
✓✗
2
  generateRandomTransform(extents, transform);
891
892
✓✗✓✗
2
  Vec3f c1, c2;
893
  FCL_REAL distance;
894
✓✗
2
  Vec3f normal;
895
  bool res;
896
897
  res =
898
✓✗✓✗
2
      solver1.shapeTriangleInteraction(hs, Transform3f(), t[0], t[1], t[2],
899
✓✗
4
                                       Transform3f(), distance, c1, c2, normal);
900
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(res);
901
902
✓✗
2
  res = solver1.shapeTriangleInteraction(hs, transform, t[0], t[1], t[2],
903
                                         transform, distance, c1, c2, normal);
904
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(res);
905
906
✓✗✓✗
✓✗
2
  t[0] << 20, 0, 0;
907
✓✗✓✗
✓✗
2
  t[1] << 0, -20, 0;
908
✓✗✓✗
✓✗
2
  t[2] << 0, 20, 0;
909
  res =
910
✓✗✓✗
2
      solver1.shapeTriangleInteraction(hs, Transform3f(), t[0], t[1], t[2],
911
✓✗
4
                                       Transform3f(), distance, c1, c2, normal);
912
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(res);
913
914
  // These tests fail because of numerical precision errors. The points t[1] and
915
  // t[2] lies on the border of the half-space. The normals should be good, when
916
  // computed (i.e. res == true)
917
✓✗
2
  res = solver1.shapeTriangleInteraction(hs, transform, t[0], t[1], t[2],
918
                                         transform, distance, c1, c2, normal);
919
  // BOOST_CHECK(res);
920
✗✓
2
  if (res)
921
    BOOST_CHECK(
922
        isEqual(normal, transform.getRotation() * Vec3f(1, 0, 0), 1e-9));
923
924
  res =
925
✓✗✓✗
2
      solver1.shapeTriangleInteraction(hs, Transform3f(), t[0], t[1], t[2],
926
✓✗
2
                                       Transform3f(), distance, c1, c2, normal);
927
  // BOOST_CHECK(res);
928
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✗✓
2
  if (res) BOOST_CHECK(isEqual(normal, Vec3f(1, 0, 0), 1e-9));
929
930
✓✗
2
  res = solver1.shapeTriangleInteraction(hs, transform, t[0], t[1], t[2],
931
                                         transform, distance, c1, c2, normal);
932
  // BOOST_CHECK(res);
933
✗✓
2
  if (res)
934
    BOOST_CHECK(
935
        isEqual(normal, transform.getRotation() * Vec3f(1, 0, 0), 1e-9));
936
2
}
937
938
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗
4
BOOST_AUTO_TEST_CASE(shapeIntersection_planetriangle) {
939
✓✗✓✗
4
  Plane hs(Vec3f(1, 0, 0), 0);
940
✓✓✓✗
8
  Vec3f t[3];
941
✓✗✓✗
✓✗
2
  t[0] << 20, 0, 0;
942
✓✗✓✗
✓✗
2
  t[1] << -20, 0, 0;
943
✓✗✓✗
✓✗
2
  t[2] << 0, 20, 0;
944
945
✓✗
2
  Transform3f transform;
946
✓✗
2
  generateRandomTransform(extents, transform);
947
948
✓✗✓✗
2
  Vec3f c1, c2;
949
  FCL_REAL distance;
950
✓✗
2
  Vec3f normal;
951
  bool res;
952
953
  res =
954
✓✗✓✗
2
      solver1.shapeTriangleInteraction(hs, Transform3f(), t[0], t[1], t[2],
955
✓✗
4
                                       Transform3f(), distance, c1, c2, normal);
956
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(res);
957
958
✓✗
2
  res = solver1.shapeTriangleInteraction(hs, transform, t[0], t[1], t[2],
959
                                         transform, distance, c1, c2, normal);
960
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(res);
961
962
✓✗✓✗
✓✗
2
  t[0] << 20, 0, 0;
963
✓✗✓✗
✓✗
2
  t[1] << -0.1, -20, 0;
964
✓✗✓✗
✓✗
2
  t[2] << -0.1, 20, 0;
965
966
✓✗
2
  res = solver1.shapeTriangleInteraction(hs, transform, t[0], t[1], t[2],
967
                                         transform, distance, c1, c2, normal);
968
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(res);
969
970
  res =
971
✓✗✓✗
2
      solver1.shapeTriangleInteraction(hs, Transform3f(), t[0], t[1], t[2],
972
✓✗
4
                                       Transform3f(), distance, c1, c2, normal);
973
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(res);
974
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(isEqual(normal, Vec3f(1, 0, 0), 1e-9));
975
976
✓✗
2
  res = solver1.shapeTriangleInteraction(hs, transform, t[0], t[1], t[2],
977
                                         transform, distance, c1, c2, normal);
978
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(res);
979
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✗✓
2
  BOOST_CHECK(isEqual(normal, transform.getRotation() * Vec3f(1, 0, 0), 1e-9));
980
2
}
981
982
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗
4
BOOST_AUTO_TEST_CASE(shapeIntersection_halfspacesphere) {
983
✓✗
4
  Sphere s(10);
984
✓✗✓✗
4
  Halfspace hs(Vec3f(1, 0, 0), 0);
985
986
✓✗
2
  Transform3f tf1;
987
✓✗
2
  Transform3f tf2;
988
989
✓✗
2
  Transform3f transform;
990
✓✗
2
  generateRandomTransform(extents, transform);
991
992
✓✗
2
  Vec3f contact;
993
  FCL_REAL depth;
994
✓✗
2
  Vec3f normal;
995
996
✓✗✓✗
2
  tf1 = Transform3f();
997
✓✗✓✗
2
  tf2 = Transform3f();
998
✓✗✓✗
✓✗
2
  contact << -5, 0, 0;
999
2
  depth = 10;
1000
✓✗✓✗
✓✗
2
  normal << -1, 0, 0;
1001
2
  SET_LINE;
1002
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
1003
1004
✓✗
2
  tf1 = transform;
1005
✓✗
2
  tf2 = transform;
1006
✓✗✓✗
2
  contact = transform.transform(Vec3f(-5, 0, 0));
1007
2
  depth = 10;
1008
✓✗✓✗
✓✗
2
  normal = transform.getRotation() * Vec3f(-1, 0, 0);
1009
2
  SET_LINE;
1010
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
1011
1012
✓✗✓✗
2
  tf1 = Transform3f();
1013
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(5, 0, 0));
1014
✓✗✓✗
✓✗
2
  contact << -2.5, 0, 0;
1015
2
  depth = 15;
1016
✓✗✓✗
✓✗
2
  normal << -1, 0, 0;
1017
2
  SET_LINE;
1018
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
1019
1020
✓✗
2
  tf1 = transform;
1021
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(5, 0, 0));
1022
✓✗✓✗
2
  contact = transform.transform(Vec3f(-2.5, 0, 0));
1023
2
  depth = 15;
1024
✓✗✓✗
✓✗
2
  normal = transform.getRotation() * Vec3f(-1, 0, 0);
1025
2
  SET_LINE;
1026
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
1027
1028
✓✗✓✗
2
  tf1 = Transform3f();
1029
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(-5, 0, 0));
1030
✓✗✓✗
✓✗
2
  contact << -7.5, 0, 0;
1031
2
  depth = 5;
1032
✓✗✓✗
✓✗
2
  normal << -1, 0, 0;
1033
2
  SET_LINE;
1034
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
1035
1036
✓✗
2
  tf1 = transform;
1037
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(-5, 0, 0));
1038
✓✗✓✗
2
  contact = transform.transform(Vec3f(-7.5, 0, 0));
1039
2
  depth = 5;
1040
✓✗✓✗
✓✗
2
  normal = transform.getRotation() * Vec3f(-1, 0, 0);
1041
2
  SET_LINE;
1042
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
1043
1044
✓✗✓✗
2
  tf1 = Transform3f();
1045
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(-10.1, 0, 0));
1046
2
  SET_LINE;
1047
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, false);
1048
1049
✓✗
2
  tf1 = transform;
1050
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(-10.1, 0, 0));
1051
2
  SET_LINE;
1052
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, false);
1053
1054
✓✗✓✗
2
  tf1 = Transform3f();
1055
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(10.1, 0, 0));
1056
✓✗✓✗
✓✗
2
  contact << 0.05, 0, 0;
1057
2
  depth = 20.1;
1058
✓✗✓✗
✓✗
2
  normal << -1, 0, 0;
1059
2
  SET_LINE;
1060
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
1061
1062
✓✗
2
  tf1 = transform;
1063
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(10.1, 0, 0));
1064
✓✗✓✗
2
  contact = transform.transform(Vec3f(0.05, 0, 0));
1065
2
  depth = 20.1;
1066
✓✗✓✗
✓✗
2
  normal = transform.getRotation() * Vec3f(-1, 0, 0);
1067
2
  SET_LINE;
1068
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
1069
2
}
1070
1071
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗
4
BOOST_AUTO_TEST_CASE(shapeIntersection_planesphere) {
1072
✓✗
4
  Sphere s(10);
1073
✓✗✓✗
4
  Plane hs(Vec3f(1, 0, 0), 0);
1074
1075
✓✗
2
  Transform3f tf1;
1076
✓✗
2
  Transform3f tf2;
1077
1078
✓✗
2
  Transform3f transform;
1079
✓✗
2
  generateRandomTransform(extents, transform);
1080
1081
✓✗
2
  Vec3f contact;
1082
  FCL_REAL depth;
1083
✓✗
2
  Vec3f normal;
1084
1085
✓✗✓✗
2
  tf1 = Transform3f();
1086
✓✗✓✗
2
  tf2 = Transform3f();
1087
✓✗
2
  contact.setZero();
1088
2
  depth = 10;
1089
✓✗✓✗
✓✗
2
  normal << 1, 0, 0;  // (1, 0, 0) or (-1, 0, 0)
1090
2
  SET_LINE;
1091
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
1092
1093
✓✗
2
  tf1 = transform;
1094
✓✗
2
  tf2 = transform;
1095
✓✗✓✗
2
  contact = transform.transform(Vec3f(0, 0, 0));
1096
2
  depth = 10;
1097
✓✗✓✗
✓✗
2
  normal = transform.getRotation() * Vec3f(1, 0, 0);  // (1, 0, 0) or (-1, 0, 0)
1098
2
  SET_LINE;
1099
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal, true);
1100
1101
✓✗✓✗
2
  tf1 = Transform3f();
1102
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(5, 0, 0));
1103
✓✗✓✗
✓✗
2
  contact << 5, 0, 0;
1104
2
  depth = 5;
1105
✓✗✓✗
✓✗
2
  normal << 1, 0, 0;
1106
2
  SET_LINE;
1107
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
1108
1109
✓✗
2
  tf1 = transform;
1110
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(5, 0, 0));
1111
✓✗✓✗
2
  contact = transform.transform(Vec3f(5, 0, 0));
1112
2
  depth = 5;
1113
✓✗✓✗
✓✗
2
  normal = transform.getRotation() * Vec3f(1, 0, 0);
1114
2
  SET_LINE;
1115
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
1116
1117
✓✗✓✗
2
  tf1 = Transform3f();
1118
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(-5, 0, 0));
1119
✓✗✓✗
✓✗
2
  contact << -5, 0, 0;
1120
2
  depth = 5;
1121
✓✗✓✗
✓✗
2
  normal << -1, 0, 0;
1122
2
  SET_LINE;
1123
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
1124
1125
✓✗
2
  tf1 = transform;
1126
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(-5, 0, 0));
1127
✓✗✓✗
2
  contact = transform.transform(Vec3f(-5, 0, 0));
1128
2
  depth = 5;
1129
✓✗✓✗
✓✗
2
  normal = transform.getRotation() * Vec3f(-1, 0, 0);
1130
2
  SET_LINE;
1131
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
1132
1133
✓✗✓✗
2
  tf1 = Transform3f();
1134
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(-10.1, 0, 0));
1135
2
  SET_LINE;
1136
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, false);
1137
1138
✓✗
2
  tf1 = transform;
1139
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(-10.1, 0, 0));
1140
2
  SET_LINE;
1141
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, false);
1142
1143
✓✗✓✗
2
  tf1 = Transform3f();
1144
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(10.1, 0, 0));
1145
2
  SET_LINE;
1146
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, false);
1147
1148
✓✗
2
  tf1 = transform;
1149
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(10.1, 0, 0));
1150
2
  SET_LINE;
1151
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, false);
1152
2
}
1153
1154
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗
4
BOOST_AUTO_TEST_CASE(shapeIntersection_halfspacebox) {
1155
✓✗
4
  Box s(5, 10, 20);
1156
✓✗✓✗
4
  Halfspace hs(Vec3f(1, 0, 0), 0);
1157
1158
✓✗
2
  Transform3f tf1;
1159
✓✗
2
  Transform3f tf2;
1160
1161
✓✗
2
  Transform3f transform;
1162
✓✗
2
  generateRandomTransform(extents, transform);
1163
1164
✓✗
2
  Vec3f contact;
1165
  FCL_REAL depth;
1166
✓✗
2
  Vec3f normal;
1167
1168
✓✗✓✗
2
  tf1 = Transform3f();
1169
✓✗✓✗
2
  tf2 = Transform3f();
1170
✓✗✓✗
✓✗
2
  contact << -1.25, 0, 0;
1171
2
  depth = 2.5;
1172
✓✗✓✗
✓✗
2
  normal << -1, 0, 0;
1173
2
  SET_LINE;
1174
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
1175
1176
✓✗
2
  tf1 = transform;
1177
✓✗
2
  tf2 = transform;
1178
✓✗✓✗
2
  contact = transform.transform(Vec3f(-1.25, 0, 0));
1179
2
  depth = 2.5;
1180
✓✗✓✗
✓✗
2
  normal = transform.getRotation() * Vec3f(-1, 0, 0);
1181
2
  SET_LINE;
1182
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
1183
1184
✓✗✓✗
2
  tf1 = Transform3f();
1185
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(1.25, 0, 0));
1186
✓✗✓✗
✓✗
2
  contact << -0.625, 0, 0;
1187
2
  depth = 3.75;
1188
✓✗✓✗
✓✗
2
  normal << -1, 0, 0;
1189
2
  SET_LINE;
1190
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
1191
1192
✓✗
2
  tf1 = transform;
1193
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(1.25, 0, 0));
1194
✓✗✓✗
2
  contact = transform.transform(Vec3f(-0.625, 0, 0));
1195
2
  depth = 3.75;
1196
✓✗✓✗
✓✗
2
  normal = transform.getRotation() * Vec3f(-1, 0, 0);
1197
2
  SET_LINE;
1198
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
1199
1200
✓✗✓✗
2
  tf1 = Transform3f();
1201
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(-1.25, 0, 0));
1202
✓✗✓✗
✓✗
2
  contact << -1.875, 0, 0;
1203
2
  depth = 1.25;
1204
✓✗✓✗
✓✗
2
  normal << -1, 0, 0;
1205
2
  SET_LINE;
1206
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
1207
1208
✓✗
2
  tf1 = transform;
1209
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(-1.25, 0, 0));
1210
✓✗✓✗
2
  contact = transform.transform(Vec3f(-1.875, 0, 0));
1211
2
  depth = 1.25;
1212
✓✗✓✗
✓✗
2
  normal = transform.getRotation() * Vec3f(-1, 0, 0);
1213
2
  SET_LINE;
1214
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
1215
1216
✓✗✓✗
2
  tf1 = Transform3f();
1217
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(2.51, 0, 0));
1218
✓✗✓✗
✓✗
2
  contact << 0.005, 0, 0;
1219
2
  depth = 5.01;
1220
✓✗✓✗
✓✗
2
  normal << -1, 0, 0;
1221
2
  SET_LINE;
1222
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
1223
1224
✓✗
2
  tf1 = transform;
1225
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(2.51, 0, 0));
1226
✓✗✓✗
2
  contact = transform.transform(Vec3f(0.005, 0, 0));
1227
2
  depth = 5.01;
1228
✓✗✓✗
✓✗
2
  normal = transform.getRotation() * Vec3f(-1, 0, 0);
1229
2
  SET_LINE;
1230
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
1231
1232
✓✗✓✗
2
  tf1 = Transform3f();
1233
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(-2.51, 0, 0));
1234
2
  SET_LINE;
1235
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, false);
1236
1237
✓✗
2
  tf1 = transform;
1238
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(-2.51, 0, 0));
1239
2
  SET_LINE;
1240
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, false);
1241
1242
✓✗✓✗
2
  tf1 = Transform3f(transform.getRotation());
1243
✓✗✓✗
2
  tf2 = Transform3f();
1244
2
  SET_LINE;
1245
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true);
1246
2
}
1247
1248
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗
4
BOOST_AUTO_TEST_CASE(shapeIntersection_planebox) {
1249
✓✗
4
  Box s(5, 10, 20);
1250
✓✗✓✗
4
  Plane hs(Vec3f(1, 0, 0), 0);
1251
1252
✓✗
2
  Transform3f tf1;
1253
✓✗
2
  Transform3f tf2;
1254
1255
✓✗
2
  Transform3f transform;
1256
✓✗
2
  generateRandomTransform(extents, transform);
1257
1258
✓✗
2
  Vec3f contact;
1259
  FCL_REAL depth;
1260
✓✗
2
  Vec3f normal;
1261
1262
✓✗✓✗
2
  tf1 = Transform3f();
1263
✓✗✓✗
2
  tf2 = Transform3f();
1264
✓✗✓✗
✓✗
2
  contact << 0, 0, 0;
1265
2
  depth = 2.5;
1266
✓✗✓✗
✓✗
2
  normal << 1, 0, 0;  // (1, 0, 0) or (-1, 0, 0)
1267
2
  SET_LINE;
1268
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
1269
1270
✓✗
2
  tf1 = transform;
1271
✓✗
2
  tf2 = transform;
1272
✓✗✓✗
2
  contact = transform.transform(Vec3f(0, 0, 0));
1273
2
  depth = 2.5;
1274
✓✗✓✗
✓✗
2
  normal = transform.getRotation() * Vec3f(1, 0, 0);  // (1, 0, 0) or (-1, 0, 0)
1275
2
  SET_LINE;
1276
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
1277
1278
✓✗✓✗
2
  tf1 = Transform3f();
1279
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(1.25, 0, 0));
1280
✓✗✓✗
✓✗
2
  contact << 1.25, 0, 0;
1281
2
  depth = 1.25;
1282
✓✗✓✗
✓✗
2
  normal << 1, 0, 0;
1283
2
  SET_LINE;
1284
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
1285
1286
✓✗
2
  tf1 = transform;
1287
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(1.25, 0, 0));
1288
✓✗✓✗
2
  contact = transform.transform(Vec3f(1.25, 0, 0));
1289
2
  depth = 1.25;
1290
✓✗✓✗
✓✗
2
  normal = transform.getRotation() * Vec3f(1, 0, 0);
1291
2
  SET_LINE;
1292
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
1293
1294
✓✗✓✗
2
  tf1 = Transform3f();
1295
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(-1.25, 0, 0));
1296
✓✗✓✗
✓✗
2
  contact << -1.25, 0, 0;
1297
2
  depth = 1.25;
1298
✓✗✓✗
✓✗
2
  normal << -1, 0, 0;
1299
2
  SET_LINE;
1300
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
1301
1302
✓✗
2
  tf1 = transform;
1303
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(-1.25, 0, 0));
1304
✓✗✓✗
2
  contact = transform.transform(Vec3f(-1.25, 0, 0));
1305
2
  depth = 1.25;
1306
✓✗✓✗
✓✗
2
  normal = transform.getRotation() * Vec3f(-1, 0, 0);
1307
2
  SET_LINE;
1308
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
1309
1310
✓✗✓✗
2
  tf1 = Transform3f();
1311
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(2.51, 0, 0));
1312
2
  SET_LINE;
1313
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, false);
1314
1315
✓✗
2
  tf1 = transform;
1316
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(2.51, 0, 0));
1317
2
  SET_LINE;
1318
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, false);
1319
1320
✓✗✓✗
2
  tf1 = Transform3f();
1321
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(-2.51, 0, 0));
1322
2
  SET_LINE;
1323
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, false);
1324
1325
✓✗
2
  tf1 = transform;
1326
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(-2.51, 0, 0));
1327
2
  SET_LINE;
1328
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, false);
1329
1330
✓✗✓✗
2
  tf1 = Transform3f(transform.getRotation());
1331
✓✗✓✗
2
  tf2 = Transform3f();
1332
2
  SET_LINE;
1333
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true);
1334
2
}
1335
1336
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗
4
BOOST_AUTO_TEST_CASE(shapeIntersection_halfspacecapsule) {
1337
✓✗
4
  Capsule s(5, 10);
1338
✓✗✓✗
4
  Halfspace hs(Vec3f(1, 0, 0), 0);
1339
1340
✓✗
2
  Transform3f tf1;
1341
✓✗
2
  Transform3f tf2;
1342
1343
✓✗
2
  Transform3f transform;
1344
✓✗
2
  generateRandomTransform(extents, transform);
1345
1346
✓✗
2
  Vec3f contact;
1347
  FCL_REAL depth;
1348
✓✗
2
  Vec3f normal;
1349
1350
✓✗✓✗
2
  tf1 = Transform3f();
1351
✓✗✓✗
2
  tf2 = Transform3f();
1352
✓✗✓✗
✓✗
2
  contact << -2.5, 0, 0;
1353
2
  depth = 5;
1354
✓✗✓✗
✓✗
2
  normal << -1, 0, 0;
1355
2
  SET_LINE;
1356
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
1357
1358
✓✗
2
  tf1 = transform;
1359
✓✗
2
  tf2 = transform;
1360
✓✗✓✗
2
  contact = transform.transform(Vec3f(-2.5, 0, 0));
1361
2
  depth = 5;
1362
✓✗✓✗
✓✗
2
  normal = transform.getRotation() * Vec3f(-1, 0, 0);
1363
2
  SET_LINE;
1364
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
1365
1366
✓✗✓✗
2
  tf1 = Transform3f();
1367
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(2.5, 0, 0));
1368
✓✗✓✗
✓✗
2
  contact << -1.25, 0, 0;
1369
2
  depth = 7.5;
1370
✓✗✓✗
✓✗
2
  normal << -1, 0, 0;
1371
2
  SET_LINE;
1372
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
1373
1374
✓✗
2
  tf1 = transform;
1375
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(2.5, 0, 0));
1376
✓✗✓✗
2
  contact = transform.transform(Vec3f(-1.25, 0, 0));
1377
2
  depth = 7.5;
1378
✓✗✓✗
✓✗
2
  normal = transform.getRotation() * Vec3f(-1, 0, 0);
1379
2
  SET_LINE;
1380
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
1381
1382
✓✗✓✗
2
  tf1 = Transform3f();
1383
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(-2.5, 0, 0));
1384
✓✗✓✗
✓✗
2
  contact << -3.75, 0, 0;
1385
2
  depth = 2.5;
1386
✓✗✓✗
✓✗
2
  normal << -1, 0, 0;
1387
2
  SET_LINE;
1388
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
1389
1390
✓✗
2
  tf1 = transform;
1391
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(-2.5, 0, 0));
1392
✓✗✓✗
2
  contact = transform.transform(Vec3f(-3.75, 0, 0));
1393
2
  depth = 2.5;
1394
✓✗✓✗
✓✗
2
  normal = transform.getRotation() * Vec3f(-1, 0, 0);
1395
2
  SET_LINE;
1396
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
1397
1398
✓✗✓✗
2
  tf1 = Transform3f();
1399
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(5.1, 0, 0));
1400
✓✗✓✗
✓✗
2
  contact << 0.05, 0, 0;
1401
2
  depth = 10.1;
1402
✓✗✓✗
✓✗
2
  normal << -1, 0, 0;
1403
2
  SET_LINE;
1404
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
1405
1406
✓✗
2
  tf1 = transform;
1407
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(5.1, 0, 0));
1408
✓✗✓✗
2
  contact = transform.transform(Vec3f(0.05, 0, 0));
1409
2
  depth = 10.1;
1410
✓✗✓✗
✓✗
2
  normal = transform.getRotation() * Vec3f(-1, 0, 0);
1411
2
  SET_LINE;
1412
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
1413
1414
✓✗✓✗
2
  tf1 = Transform3f();
1415
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(-5.1, 0, 0));
1416
2
  SET_LINE;
1417
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, false);
1418
1419
✓✗
2
  tf1 = transform;
1420
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(-5.1, 0, 0));
1421
2
  SET_LINE;
1422
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, false);
1423
1424
✓✗✓✗
✓✗
2
  hs = Halfspace(Vec3f(0, 1, 0), 0);
1425
1426
✓✗✓✗
2
  tf1 = Transform3f();
1427
✓✗✓✗
2
  tf2 = Transform3f();
1428
✓✗✓✗
✓✗
2
  contact << 0, -2.5, 0;
1429
2
  depth = 5;
1430
✓✗✓✗
✓✗
2
  normal << 0, -1, 0;
1431
2
  SET_LINE;
1432
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
1433
1434
✓✗
2
  tf1 = transform;
1435
✓✗
2
  tf2 = transform;
1436
✓✗✓✗
2
  contact = transform.transform(Vec3f(0, -2.5, 0));
1437
2
  depth = 5;
1438
✓✗✓✗
✓✗
2
  normal = transform.getRotation() * Vec3f(0, -1, 0);
1439
2
  SET_LINE;
1440
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
1441
1442
✓✗✓✗
2
  tf1 = Transform3f();
1443
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(0, 2.5, 0));
1444
✓✗✓✗
✓✗
2
  contact << 0, -1.25, 0;
1445
2
  depth = 7.5;
1446
✓✗✓✗
✓✗
2
  normal << 0, -1, 0;
1447
2
  SET_LINE;
1448
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
1449
1450
✓✗
2
  tf1 = transform;
1451
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(0, 2.5, 0));
1452
✓✗✓✗
2
  contact = transform.transform(Vec3f(0, -1.25, 0));
1453
2
  depth = 7.5;
1454
✓✗✓✗
✓✗
2
  normal = transform.getRotation() * Vec3f(0, -1, 0);
1455
2
  SET_LINE;
1456
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
1457
1458
✓✗✓✗
2
  tf1 = Transform3f();
1459
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(0, -2.5, 0));
1460
✓✗✓✗
✓✗
2
  contact << 0, -3.75, 0;
1461
2
  depth = 2.5;
1462
✓✗✓✗
✓✗
2
  normal << 0, -1, 0;
1463
2
  SET_LINE;
1464
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
1465
1466
✓✗
2
  tf1 = transform;
1467
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(0, -2.5, 0));
1468
✓✗✓✗
2
  contact = transform.transform(Vec3f(0, -3.75, 0));
1469
2
  depth = 2.5;
1470
✓✗✓✗
✓✗
2
  normal = transform.getRotation() * Vec3f(0, -1, 0);
1471
2
  SET_LINE;
1472
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
1473
1474
✓✗✓✗
2
  tf1 = Transform3f();
1475
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(0, 5.1, 0));
1476
✓✗✓✗
✓✗
2
  contact << 0, 0.05, 0;
1477
2
  depth = 10.1;
1478
✓✗✓✗
✓✗
2
  normal << 0, -1, 0;
1479
2
  SET_LINE;
1480
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
1481
1482
✓✗
2
  tf1 = transform;
1483
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(0, 5.1, 0));
1484
✓✗✓✗
2
  contact = transform.transform(Vec3f(0, 0.05, 0));
1485
2
  depth = 10.1;
1486
✓✗✓✗
✓✗
2
  normal = transform.getRotation() * Vec3f(0, -1, 0);
1487
2
  SET_LINE;
1488
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
1489
1490
✓✗✓✗
2
  tf1 = Transform3f();
1491
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(0, -5.1, 0));
1492
2
  SET_LINE;
1493
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, false);
1494
1495
✓✗
2
  tf1 = transform;
1496
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(0, -5.1, 0));
1497
2
  SET_LINE;
1498
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, false);
1499
1500
✓✗✓✗
✓✗
2
  hs = Halfspace(Vec3f(0, 0, 1), 0);
1501
1502
✓✗✓✗
2
  tf1 = Transform3f();
1503
✓✗✓✗
2
  tf2 = Transform3f();
1504
✓✗✓✗
✓✗
2
  contact << 0, 0, -5;
1505
2
  depth = 10;
1506
✓✗✓✗
✓✗
2
  normal << 0, 0, -1;
1507
2
  SET_LINE;
1508
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
1509
1510
✓✗
2
  tf1 = transform;
1511
✓✗
2
  tf2 = transform;
1512
✓✗✓✗
2
  contact = transform.transform(Vec3f(0, 0, -5));
1513
2
  depth = 10;
1514
✓✗✓✗
✓✗
2
  normal = transform.getRotation() * Vec3f(0, 0, -1);
1515
2
  SET_LINE;
1516
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
1517
1518
✓✗✓✗
2
  tf1 = Transform3f();
1519
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(0, 0, 2.5));
1520
✓✗✓✗
✓✗
2
  contact << 0, 0, -3.75;
1521
2
  depth = 12.5;
1522
✓✗✓✗
✓✗
2
  normal << 0, 0, -1;
1523
2
  SET_LINE;
1524
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
1525
1526
✓✗
2
  tf1 = transform;
1527
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(0, 0, 2.5));
1528
✓✗✓✗
2
  contact = transform.transform(Vec3f(0, 0, -3.75));
1529
2
  depth = 12.5;
1530
✓✗✓✗
✓✗
2
  normal = transform.getRotation() * Vec3f(0, 0, -1);
1531
2
  SET_LINE;
1532
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
1533
1534
✓✗✓✗
2
  tf1 = Transform3f();
1535
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(0, 0, -2.5));
1536
✓✗✓✗
✓✗
2
  contact << 0, 0, -6.25;
1537
2
  depth = 7.5;
1538
✓✗✓✗
✓✗
2
  normal << 0, 0, -1;
1539
2
  SET_LINE;
1540
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
1541
1542
✓✗
2
  tf1 = transform;
1543
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(0, 0, -2.5));
1544
✓✗✓✗
2
  contact = transform.transform(Vec3f(0, 0, -6.25));
1545
2
  depth = 7.5;
1546
✓✗✓✗
✓✗
2
  normal = transform.getRotation() * Vec3f(0, 0, -1);
1547
2
  SET_LINE;
1548
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
1549
1550
✓✗✓✗
2
  tf1 = Transform3f();
1551
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(0, 0, 10.1));
1552
✓✗✓✗
✓✗
2
  contact << 0, 0, 0.05;
1553
2
  depth = 20.1;
1554
✓✗✓✗
✓✗
2
  normal << 0, 0, -1;
1555
2
  SET_LINE;
1556
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
1557
1558
✓✗
2
  tf1 = transform;
1559
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(0, 0, 10.1));
1560
✓✗✓✗
2
  contact = transform.transform(Vec3f(0, 0, 0.05));
1561
2
  depth = 20.1;
1562
✓✗✓✗
✓✗
2
  normal = transform.getRotation() * Vec3f(0, 0, -1);
1563
2
  SET_LINE;
1564
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
1565
1566
✓✗✓✗
2
  tf1 = Transform3f();
1567
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(0, 0, -10.1));
1568
2
  SET_LINE;
1569
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, false);
1570
1571
✓✗
2
  tf1 = transform;
1572
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(0, 0, -10.1));
1573
2
  SET_LINE;
1574
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, false);
1575
2
}
1576
1577
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗
4
BOOST_AUTO_TEST_CASE(shapeIntersection_planecapsule) {
1578
✓✗
4
  Capsule s(5, 10);
1579
✓✗✓✗
4
  Plane hs(Vec3f(1, 0, 0), 0);
1580
1581
✓✗
2
  Transform3f tf1;
1582
✓✗
2
  Transform3f tf2;
1583
1584
✓✗
2
  Transform3f transform;
1585
✓✗
2
  generateRandomTransform(extents, transform);
1586
1587
✓✗
2
  Vec3f contact;
1588
  FCL_REAL depth;
1589
✓✗
2
  Vec3f normal;
1590
1591
✓✗✓✗
2
  tf1 = Transform3f();
1592
✓✗✓✗
2
  tf2 = Transform3f();
1593
✓✗✓✗
✓✗
2
  contact << 0, 0, 0;
1594
2
  depth = 5;
1595
✓✗✓✗
✓✗
2
  normal << 1, 0, 0;  // (1, 0, 0) or (-1, 0, 0)
1596
2
  SET_LINE;
1597
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, 0x0, 0x0, 0x0, true);
1598
1599
✓✗
2
  tf1 = transform;
1600
✓✗
2
  tf2 = transform;
1601
✓✗✓✗
2
  contact = transform.transform(Vec3f(0, 0, 0));
1602
2
  depth = 5;
1603
✓✗✓✗
✓✗
2
  normal = transform.getRotation() * Vec3f(1, 0, 0);  // (1, 0, 0) or (-1, 0, 0)
1604
2
  SET_LINE;
1605
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, 0x0, 0x0, 0x0, true);
1606
1607
✓✗✓✗
2
  tf1 = Transform3f();
1608
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(2.5, 0, 0));
1609
✓✗✓✗
✓✗
2
  contact << 2.5, 0, 0;
1610
2
  depth = 2.5;
1611
✓✗✓✗
✓✗
2
  normal << 1, 0, 0;
1612
2
  SET_LINE;
1613
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, 0x0, &depth, &normal);
1614
1615
✓✗
2
  tf1 = transform;
1616
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(2.5, 0, 0));
1617
✓✗✓✗
2
  contact = transform.transform(Vec3f(2.5, 0, 0));
1618
2
  depth = 2.5;
1619
✓✗✓✗
✓✗
2
  normal = transform.getRotation() * Vec3f(1, 0, 0);
1620
2
  SET_LINE;
1621
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, 0x0, &depth, &normal);
1622
1623
✓✗✓✗
2
  tf1 = Transform3f();
1624
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(-2.5, 0, 0));
1625
✓✗✓✗
✓✗
2
  contact << -2.5, 0, 0;
1626
2
  depth = 2.5;
1627
✓✗✓✗
✓✗
2
  normal << -1, 0, 0;
1628
2
  SET_LINE;
1629
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, 0x0, &depth, &normal);
1630
1631
✓✗
2
  tf1 = transform;
1632
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(-2.5, 0, 0));
1633
✓✗✓✗
2
  contact = transform.transform(Vec3f(-2.5, 0, 0));
1634
2
  depth = 2.5;
1635
✓✗✓✗
✓✗
2
  normal = transform.getRotation() * Vec3f(-1, 0, 0);
1636
2
  SET_LINE;
1637
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, 0x0, &depth, &normal);
1638
1639
✓✗✓✗
2
  tf1 = Transform3f();
1640
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(5.1, 0, 0));
1641
2
  SET_LINE;
1642
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, false);
1643
1644
✓✗
2
  tf1 = transform;
1645
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(5.1, 0, 0));
1646
2
  SET_LINE;
1647
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, false);
1648
1649
✓✗✓✗
2
  tf1 = Transform3f();
1650
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(-5.1, 0, 0));
1651
2
  SET_LINE;
1652
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, false);
1653
1654
✓✗
2
  tf1 = transform;
1655
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(-5.1, 0, 0));
1656
2
  SET_LINE;
1657
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, false);
1658
1659
✓✗✓✗
✓✗
2
  hs = Plane(Vec3f(0, 1, 0), 0);
1660
1661
✓✗✓✗
2
  tf1 = Transform3f();
1662
✓✗✓✗
2
  tf2 = Transform3f();
1663
✓✗✓✗
✓✗
2
  contact << 0, 0, 0;
1664
2
  depth = 5;
1665
✓✗✓✗
✓✗
2
  normal << 0, 1, 0;  // (0, 1, 0) or (0, -1, 0)
1666
2
  SET_LINE;
1667
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, 0x0, &depth, 0x0, true);
1668
1669
✓✗
2
  tf1 = transform;
1670
✓✗
2
  tf2 = transform;
1671
✓✗✓✗
2
  contact = transform.transform(Vec3f(0, 0, 0));
1672
2
  depth = 5;
1673
✓✗✓✗
✓✗
2
  normal = transform.getRotation() * Vec3f(0, 1, 0);  // (0, 1, 0) or (0, -1, 0)
1674
2
  SET_LINE;
1675
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, 0x0, &depth, &normal, true);
1676
1677
✓✗✓✗
2
  tf1 = Transform3f();
1678
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(0, 2.5, 0));
1679
✓✗✓✗
✓✗
2
  contact << 0, 2.5, 0;
1680
2
  depth = 2.5;
1681
✓✗✓✗
✓✗
2
  normal << 0, 1, 0;
1682
2
  SET_LINE;
1683
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, 0x0, &depth, 0x0);
1684
1685
✓✗
2
  tf1 = transform;
1686
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(0, 2.5, 0));
1687
✓✗✓✗
2
  contact = transform.transform(Vec3f(0, 2.5, 0));
1688
2
  depth = 2.5;
1689
✓✗✓✗
✓✗
2
  normal = transform.getRotation() * Vec3f(0, 1, 0);
1690
2
  SET_LINE;
1691
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, 0x0, &depth, 0x0);
1692
1693
✓✗✓✗
2
  tf1 = Transform3f();
1694
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(0, -2.5, 0));
1695
✓✗✓✗
✓✗
2
  contact << 0, -2.5, 0;
1696
2
  depth = 2.5;
1697
✓✗✓✗
✓✗
2
  normal << 0, -1, 0;
1698
2
  SET_LINE;
1699
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, 0x0, &depth, &normal);
1700
1701
✓✗
2
  tf1 = transform;
1702
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(0, -2.5, 0));
1703
✓✗✓✗
2
  contact = transform.transform(Vec3f(0, -2.5, 0));
1704
2
  depth = 2.5;
1705
✓✗✓✗
✓✗
2
  normal = transform.getRotation() * Vec3f(0, -1, 0);
1706
2
  SET_LINE;
1707
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, 0x0, &depth, &normal);
1708
1709
✓✗✓✗
2
  tf1 = Transform3f();
1710
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(0, 5.1, 0));
1711
2
  SET_LINE;
1712
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, false);
1713
1714
✓✗
2
  tf1 = transform;
1715
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(0, 5.1, 0));
1716
2
  SET_LINE;
1717
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, false);
1718
1719
✓✗✓✗
2
  tf1 = Transform3f();
1720
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(0, -5.1, 0));
1721
2
  SET_LINE;
1722
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, false);
1723
1724
✓✗
2
  tf1 = transform;
1725
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(0, -5.1, 0));
1726
2
  SET_LINE;
1727
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, false);
1728
1729
✓✗✓✗
✓✗
2
  hs = Plane(Vec3f(0, 0, 1), 0);
1730
1731
✓✗✓✗
2
  tf1 = Transform3f();
1732
✓✗✓✗
2
  tf2 = Transform3f();
1733
✓✗✓✗
✓✗
2
  contact << 0, 0, 0;
1734
2
  depth = 10;
1735
✓✗✓✗
✓✗
2
  normal << 0, 0, 1;  // (0, 0, 1) or (0, 0, -1)
1736
2
  SET_LINE;
1737
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, 0x0, 0x0, 0x0, true);
1738
1739
✓✗
2
  tf1 = transform;
1740
✓✗
2
  tf2 = transform;
1741
✓✗✓✗
2
  contact = transform.transform(Vec3f(0, 0, 0));
1742
2
  depth = 10;
1743
✓✗✓✗
✓✗
2
  normal = transform.getRotation() * Vec3f(0, 0, 1);  // (0, 0, 1) or (0, 0, -1)
1744
2
  SET_LINE;
1745
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, 0x0, &depth, 0x0, true);
1746
1747
✓✗✓✗
2
  tf1 = Transform3f();
1748
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(0, 0, 2.5));
1749
✓✗✓✗
✓✗
2
  contact << 0, 0, 2.5;
1750
2
  depth = 7.5;
1751
✓✗✓✗
✓✗
2
  normal << 0, 0, 1;
1752
2
  SET_LINE;
1753
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, 0x0, &depth, 0x0);
1754
1755
✓✗
2
  tf1 = transform;
1756
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(0, 0, 2.5));
1757
✓✗✓✗
2
  contact = transform.transform(Vec3f(0, 0, 2.5));
1758
2
  depth = 7.5;
1759
✓✗✓✗
✓✗
2
  normal = transform.getRotation() * Vec3f(0, 0, 1);
1760
2
  SET_LINE;
1761
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, 0x0, &depth, 0x0);
1762
1763
✓✗✓✗
2
  tf1 = Transform3f();
1764
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(0, 0, -2.5));
1765
✓✗✓✗
✓✗
2
  contact << 0, 0, -2.5;
1766
2
  depth = 7.5;
1767
✓✗✓✗
✓✗
2
  normal << 0, 0, -1;
1768
2
  SET_LINE;
1769
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, 0x0, &depth, 0x0);
1770
1771
✓✗
2
  tf1 = transform;
1772
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(0, 0, -2.5));
1773
✓✗✓✗
2
  contact = transform.transform(Vec3f(0, 0, -2.5));
1774
2
  depth = 7.5;
1775
✓✗✓✗
✓✗
2
  normal = transform.getRotation() * Vec3f(0, 0, -1);
1776
2
  SET_LINE;
1777
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, 0x0, &depth, 0x0);
1778
1779
✓✗✓✗
2
  tf1 = Transform3f();
1780
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(0, 0, 10.1));
1781
2
  SET_LINE;
1782
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, false);
1783
1784
✓✗
2
  tf1 = transform;
1785
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(0, 0, 10.1));
1786
2
  SET_LINE;
1787
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, false);
1788
1789
✓✗✓✗
2
  tf1 = Transform3f();
1790
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(0, 0, -10.1));
1791
2
  SET_LINE;
1792
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, false);
1793
1794
✓✗
2
  tf1 = transform;
1795
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(0, 0, -10.1));
1796
2
  SET_LINE;
1797
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, false);
1798
2
}
1799
1800
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗
4
BOOST_AUTO_TEST_CASE(shapeIntersection_halfspacecylinder) {
1801
✓✗
4
  Cylinder s(5, 10);
1802
✓✗✓✗
4
  Halfspace hs(Vec3f(1, 0, 0), 0);
1803
1804
✓✗
2
  Transform3f tf1;
1805
✓✗
2
  Transform3f tf2;
1806
1807
✓✗
2
  Transform3f transform;
1808
✓✗
2
  generateRandomTransform(extents, transform);
1809
1810
✓✗
2
  Vec3f contact;
1811
  FCL_REAL depth;
1812
✓✗
2
  Vec3f normal;
1813
1814
✓✗✓✗
2
  tf1 = Transform3f();
1815
✓✗✓✗
2
  tf2 = Transform3f();
1816
✓✗✓✗
✓✗
2
  contact << -2.5, 0, 0;
1817
2
  depth = 5;
1818
✓✗✓✗
✓✗
2
  normal << -1, 0, 0;
1819
2
  SET_LINE;
1820
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
1821
1822
✓✗
2
  tf1 = transform;
1823
✓✗
2
  tf2 = transform;
1824
✓✗✓✗
2
  contact = transform.transform(Vec3f(-2.5, 0, 0));
1825
2
  depth = 5;
1826
✓✗✓✗
✓✗
2
  normal = transform.getRotation() * Vec3f(-1, 0, 0);
1827
2
  SET_LINE;
1828
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
1829
1830
✓✗✓✗
2
  tf1 = Transform3f();
1831
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(2.5, 0, 0));
1832
✓✗✓✗
✓✗
2
  contact << -1.25, 0, 0;
1833
2
  depth = 7.5;
1834
✓✗✓✗
✓✗
2
  normal << -1, 0, 0;
1835
2
  SET_LINE;
1836
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
1837
1838
✓✗
2
  tf1 = transform;
1839
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(2.5, 0, 0));
1840
✓✗✓✗
2
  contact = transform.transform(Vec3f(-1.25, 0, 0));
1841
2
  depth = 7.5;
1842
✓✗✓✗
✓✗
2
  normal = transform.getRotation() * Vec3f(-1, 0, 0);
1843
2
  SET_LINE;
1844
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
1845
1846
✓✗✓✗
2
  tf1 = Transform3f();
1847
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(-2.5, 0, 0));
1848
✓✗✓✗
✓✗
2
  contact << -3.75, 0, 0;
1849
2
  depth = 2.5;
1850
✓✗✓✗
✓✗
2
  normal << -1, 0, 0;
1851
2
  SET_LINE;
1852
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
1853
1854
✓✗
2
  tf1 = transform;
1855
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(-2.5, 0, 0));
1856
✓✗✓✗
2
  contact = transform.transform(Vec3f(-3.75, 0, 0));
1857
2
  depth = 2.5;
1858
✓✗✓✗
✓✗
2
  normal = transform.getRotation() * Vec3f(-1, 0, 0);
1859
2
  SET_LINE;
1860
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
1861
1862
✓✗✓✗
2
  tf1 = Transform3f();
1863
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(5.1, 0, 0));
1864
✓✗✓✗
✓✗
2
  contact << 0.05, 0, 0;
1865
2
  depth = 10.1;
1866
✓✗✓✗
✓✗
2
  normal << -1, 0, 0;
1867
2
  SET_LINE;
1868
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
1869
1870
✓✗
2
  tf1 = transform;
1871
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(5.1, 0, 0));
1872
✓✗✓✗
2
  contact = transform.transform(Vec3f(0.05, 0, 0));
1873
2
  depth = 10.1;
1874
✓✗✓✗
✓✗
2
  normal = transform.getRotation() * Vec3f(-1, 0, 0);
1875
2
  SET_LINE;
1876
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
1877
1878
✓✗✓✗
2
  tf1 = Transform3f();
1879
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(-5.1, 0, 0));
1880
2
  SET_LINE;
1881
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, false);
1882
1883
✓✗
2
  tf1 = transform;
1884
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(-5.1, 0, 0));
1885
2
  SET_LINE;
1886
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, false);
1887
1888
✓✗✓✗
✓✗
2
  hs = Halfspace(Vec3f(0, 1, 0), 0);
1889
1890
✓✗✓✗
2
  tf1 = Transform3f();
1891
✓✗✓✗
2
  tf2 = Transform3f();
1892
✓✗✓✗
✓✗
2
  contact << 0, -2.5, 0;
1893
2
  depth = 5;
1894
✓✗✓✗
✓✗
2
  normal << 0, -1, 0;
1895
2
  SET_LINE;
1896
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
1897
1898
✓✗
2
  tf1 = transform;
1899
✓✗
2
  tf2 = transform;
1900
✓✗✓✗
2
  contact = transform.transform(Vec3f(0, -2.5, 0));
1901
2
  depth = 5;
1902
✓✗✓✗
✓✗
2
  normal = transform.getRotation() * Vec3f(0, -1, 0);
1903
2
  SET_LINE;
1904
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
1905
1906
✓✗✓✗
2
  tf1 = Transform3f();
1907
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(0, 2.5, 0));
1908
✓✗✓✗
✓✗
2
  contact << 0, -1.25, 0;
1909
2
  depth = 7.5;
1910
✓✗✓✗
✓✗
2
  normal << 0, -1, 0;
1911
2
  SET_LINE;
1912
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
1913
1914
✓✗
2
  tf1 = transform;
1915
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(0, 2.5, 0));
1916
✓✗✓✗
2
  contact = transform.transform(Vec3f(0, -1.25, 0));
1917
2
  depth = 7.5;
1918
✓✗✓✗
✓✗
2
  normal = transform.getRotation() * Vec3f(0, -1, 0);
1919
2
  SET_LINE;
1920
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
1921
1922
✓✗✓✗
2
  tf1 = Transform3f();
1923
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(0, -2.5, 0));
1924
✓✗✓✗
✓✗
2
  contact << 0, -3.75, 0;
1925
2
  depth = 2.5;
1926
✓✗✓✗
✓✗
2
  normal << 0, -1, 0;
1927
2
  SET_LINE;
1928
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
1929
1930
✓✗
2
  tf1 = transform;
1931
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(0, -2.5, 0));
1932
✓✗✓✗
2
  contact = transform.transform(Vec3f(0, -3.75, 0));
1933
2
  depth = 2.5;
1934
✓✗✓✗
✓✗
2
  normal = transform.getRotation() * Vec3f(0, -1, 0);
1935
2
  SET_LINE;
1936
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
1937
1938
✓✗✓✗
2
  tf1 = Transform3f();
1939
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(0, 5.1, 0));
1940
✓✗✓✗
✓✗
2
  contact << 0, 0.05, 0;
1941
2
  depth = 10.1;
1942
✓✗✓✗
✓✗
2
  normal << 0, -1, 0;
1943
2
  SET_LINE;
1944
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
1945
1946
✓✗
2
  tf1 = transform;
1947
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(0, 5.1, 0));
1948
✓✗✓✗
2
  contact = transform.transform(Vec3f(0, 0.05, 0));
1949
2
  depth = 10.1;
1950
✓✗✓✗
✓✗
2
  normal = transform.getRotation() * Vec3f(0, -1, 0);
1951
2
  SET_LINE;
1952
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
1953
1954
✓✗✓✗
2
  tf1 = Transform3f();
1955
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(0, -5.1, 0));
1956
2
  SET_LINE;
1957
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, false);
1958
1959
✓✗
2
  tf1 = transform;
1960
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(0, -5.1, 0));
1961
2
  SET_LINE;
1962
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, false);
1963
1964
✓✗✓✗
✓✗
2
  hs = Halfspace(Vec3f(0, 0, 1), 0);
1965
1966
✓✗✓✗
2
  tf1 = Transform3f();
1967
✓✗✓✗
2
  tf2 = Transform3f();
1968
✓✗✓✗
✓✗
2
  contact << 0, 0, -2.5;
1969
2
  depth = 5;
1970
✓✗✓✗
✓✗
2
  normal << 0, 0, -1;
1971
2
  SET_LINE;
1972
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
1973
1974
✓✗
2
  tf1 = transform;
1975
✓✗
2
  tf2 = transform;
1976
✓✗✓✗
2
  contact = transform.transform(Vec3f(0, 0, -2.5));
1977
2
  depth = 5;
1978
✓✗✓✗
✓✗
2
  normal = transform.getRotation() * Vec3f(0, 0, -1);
1979
2
  SET_LINE;
1980
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
1981
1982
✓✗✓✗
2
  tf1 = Transform3f();
1983
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(0, 0, 2.5));
1984
✓✗✓✗
✓✗
2
  contact << 0, 0, -1.25;
1985
2
  depth = 7.5;
1986
✓✗✓✗
✓✗
2
  normal << 0, 0, -1;
1987
2
  SET_LINE;
1988
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
1989
1990
✓✗
2
  tf1 = transform;
1991
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(0, 0, 2.5));
1992
✓✗✓✗
2
  contact = transform.transform(Vec3f(0, 0, -1.25));
1993
2
  depth = 7.5;
1994
✓✗✓✗
✓✗
2
  normal = transform.getRotation() * Vec3f(0, 0, -1);
1995
2
  SET_LINE;
1996
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
1997
1998
✓✗✓✗
2
  tf1 = Transform3f();
1999
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(0, 0, -2.5));
2000
✓✗✓✗
✓✗
2
  contact << 0, 0, -3.75;
2001
2
  depth = 2.5;
2002
✓✗✓✗
✓✗
2
  normal << 0, 0, -1;
2003
2
  SET_LINE;
2004
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
2005
2006
✓✗
2
  tf1 = transform;
2007
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(0, 0, -2.5));
2008
✓✗✓✗
2
  contact = transform.transform(Vec3f(0, 0, -3.75));
2009
2
  depth = 2.5;
2010
✓✗✓✗
✓✗
2
  normal = transform.getRotation() * Vec3f(0, 0, -1);
2011
2
  SET_LINE;
2012
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
2013
2014
✓✗✓✗
2
  tf1 = Transform3f();
2015
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(0, 0, 5.1));
2016
✓✗✓✗
✓✗
2
  contact << 0, 0, 0.05;
2017
2
  depth = 10.1;
2018
✓✗✓✗
✓✗
2
  normal << 0, 0, -1;
2019
2
  SET_LINE;
2020
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
2021
2022
✓✗
2
  tf1 = transform;
2023
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(0, 0, 5.1));
2024
✓✗✓✗
2
  contact = transform.transform(Vec3f(0, 0, 0.05));
2025
2
  depth = 10.1;
2026
✓✗✓✗
✓✗
2
  normal = transform.getRotation() * Vec3f(0, 0, -1);
2027
2
  SET_LINE;
2028
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
2029
2030
✓✗✓✗
2
  tf1 = Transform3f();
2031
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(0, 0, -5.1));
2032
2
  SET_LINE;
2033
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, false);
2034
2035
✓✗
2
  tf1 = transform;
2036
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(0, 0, -5.1));
2037
2
  SET_LINE;
2038
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, false);
2039
2
}
2040
2041
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗
4
BOOST_AUTO_TEST_CASE(shapeIntersection_planecylinder) {
2042
✓✗
4
  Cylinder s(5, 10);
2043
✓✗✓✗
4
  Plane hs(Vec3f(1, 0, 0), 0);
2044
2045
✓✗
2
  Transform3f tf1;
2046
✓✗
2
  Transform3f tf2;
2047
2048
✓✗
2
  Transform3f transform;
2049
✓✗
2
  generateRandomTransform(extents, transform);
2050
2051
✓✗
2
  Vec3f contact;
2052
  FCL_REAL depth;
2053
✓✗
2
  Vec3f normal;
2054
2055
✓✗✓✗
2
  tf1 = Transform3f();
2056
✓✗✓✗
2
  tf2 = Transform3f();
2057
✓✗✓✗
✓✗
2
  contact << 0, 0, 0;
2058
2
  depth = 5;
2059
✓✗✓✗
✓✗
2
  normal << 1, 0, 0;  // (1, 0, 0) or (-1, 0, 0)
2060
2
  SET_LINE;
2061
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal, true);
2062
2063
✓✗
2
  tf1 = transform;
2064
✓✗
2
  tf2 = transform;
2065
✓✗✓✗
2
  contact = transform.transform(Vec3f(0, 0, 0));
2066
2
  depth = 5;
2067
✓✗✓✗
✓✗
2
  normal = transform.getRotation() * Vec3f(1, 0, 0);  // (1, 0, 0) or (-1, 0, 0)
2068
2
  SET_LINE;
2069
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal, true);
2070
2071
✓✗✓✗
2
  tf1 = Transform3f();
2072
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(2.5, 0, 0));
2073
✓✗✓✗
✓✗
2
  contact << 2.5, 0, 0;
2074
2
  depth = 2.5;
2075
✓✗✓✗
✓✗
2
  normal << 1, 0, 0;
2076
2
  SET_LINE;
2077
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
2078
2079
✓✗
2
  tf1 = transform;
2080
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(2.5, 0, 0));
2081
✓✗✓✗
2
  contact = transform.transform(Vec3f(2.5, 0, 0));
2082
2
  depth = 2.5;
2083
✓✗✓✗
✓✗
2
  normal = transform.getRotation() * Vec3f(1, 0, 0);
2084
2
  SET_LINE;
2085
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
2086
2087
✓✗✓✗
2
  tf1 = Transform3f();
2088
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(-2.5, 0, 0));
2089
✓✗✓✗
✓✗
2
  contact << -2.5, 0, 0;
2090
2
  depth = 2.5;
2091
✓✗✓✗
✓✗
2
  normal << -1, 0, 0;
2092
2
  SET_LINE;
2093
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
2094
2095
✓✗
2
  tf1 = transform;
2096
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(-2.5, 0, 0));
2097
✓✗✓✗
2
  contact = transform.transform(Vec3f(-2.5, 0, 0));
2098
2
  depth = 2.5;
2099
✓✗✓✗
✓✗
2
  normal = transform.getRotation() * Vec3f(-1, 0, 0);
2100
2
  SET_LINE;
2101
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
2102
2103
✓✗✓✗
2
  tf1 = Transform3f();
2104
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(5.1, 0, 0));
2105
2
  SET_LINE;
2106
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, false);
2107
2108
✓✗
2
  tf1 = transform;
2109
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(5.1, 0, 0));
2110
2
  SET_LINE;
2111
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, false);
2112
2113
✓✗✓✗
2
  tf1 = Transform3f();
2114
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(-5.1, 0, 0));
2115
2
  SET_LINE;
2116
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, false);
2117
2118
✓✗
2
  tf1 = transform;
2119
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(-5.1, 0, 0));
2120
2
  SET_LINE;
2121
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, false);
2122
2123
✓✗✓✗
✓✗
2
  hs = Plane(Vec3f(0, 1, 0), 0);
2124
2125
✓✗✓✗
2
  tf1 = Transform3f();
2126
✓✗✓✗
2
  tf2 = Transform3f();
2127
✓✗✓✗
✓✗
2
  contact << 0, 0, 0;
2128
2
  depth = 5;
2129
✓✗✓✗
✓✗
2
  normal << 0, 1, 0;  // (1, 0, 0) or (-1, 0, 0)
2130
2
  SET_LINE;
2131
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal, true);
2132
2133
✓✗
2
  tf1 = transform;
2134
✓✗
2
  tf2 = transform;
2135
✓✗✓✗
2
  contact = transform.transform(Vec3f(0, 0, 0));
2136
2
  depth = 5;
2137
✓✗✓✗
✓✗
2
  normal = transform.getRotation() * Vec3f(0, 1, 0);  // (1, 0, 0) or (-1, 0, 0)
2138
2
  SET_LINE;
2139
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal, true);
2140
2141
✓✗✓✗
2
  tf1 = Transform3f();
2142
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(0, 2.5, 0));
2143
✓✗✓✗
✓✗
2
  contact << 0, 2.5, 0;
2144
2
  depth = 2.5;
2145
✓✗✓✗
✓✗
2
  normal << 0, 1, 0;
2146
2
  SET_LINE;
2147
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
2148
2149
✓✗
2
  tf1 = transform;
2150
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(0, 2.5, 0));
2151
✓✗✓✗
2
  contact = transform.transform(Vec3f(0, 2.5, 0));
2152
2
  depth = 2.5;
2153
✓✗✓✗
✓✗
2
  normal = transform.getRotation() * Vec3f(0, 1, 0);
2154
2
  SET_LINE;
2155
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
2156
2157
✓✗✓✗
2
  tf1 = Transform3f();
2158
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(0, -2.5, 0));
2159
✓✗✓✗
✓✗
2
  contact << 0, -2.5, 0;
2160
2
  depth = 2.5;
2161
✓✗✓✗
✓✗
2
  normal << 0, -1, 0;
2162
2
  SET_LINE;
2163
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
2164
2165
✓✗
2
  tf1 = transform;
2166
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(0, -2.5, 0));
2167
✓✗✓✗
2
  contact = transform.transform(Vec3f(0, -2.5, 0));
2168
2
  depth = 2.5;
2169
✓✗✓✗
✓✗
2
  normal = transform.getRotation() * Vec3f(0, -1, 0);
2170
2
  SET_LINE;
2171
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
2172
2173
✓✗✓✗
2
  tf1 = Transform3f();
2174
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(0, 5.1, 0));
2175
2
  SET_LINE;
2176
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, false);
2177
2178
✓✗
2
  tf1 = transform;
2179
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(0, 5.1, 0));
2180
2
  SET_LINE;
2181
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, false);
2182
2183
✓✗✓✗
2
  tf1 = Transform3f();
2184
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(0, -5.1, 0));
2185
2
  SET_LINE;
2186
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, false);
2187
2188
✓✗
2
  tf1 = transform;
2189
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(0, -5.1, 0));
2190
2
  SET_LINE;
2191
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, false);
2192
2193
✓✗✓✗
✓✗
2
  hs = Plane(Vec3f(0, 0, 1), 0);
2194
2195
✓✗✓✗
2
  tf1 = Transform3f();
2196
✓✗✓✗
2
  tf2 = Transform3f();
2197
✓✗✓✗
✓✗
2
  contact << 0, 0, 0;
2198
2
  depth = 5;
2199
✓✗✓✗
✓✗
2
  normal << 0, 0, 1;  // (1, 0, 0) or (-1, 0, 0)
2200
2
  SET_LINE;
2201
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal, true);
2202
2203
✓✗
2
  tf1 = transform;
2204
✓✗
2
  tf2 = transform;
2205
✓✗✓✗
2
  contact = transform.transform(Vec3f(0, 0, 0));
2206
2
  depth = 5;
2207
✓✗✓✗
✓✗
2
  normal = transform.getRotation() * Vec3f(0, 0, 1);  // (1, 0, 0) or (-1, 0, 0)
2208
2
  SET_LINE;
2209
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal, true);
2210
2211
✓✗✓✗
2
  tf1 = Transform3f();
2212
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(0, 0, 2.5));
2213
✓✗✓✗
✓✗
2
  contact << 0, 0, 2.5;
2214
2
  depth = 2.5;
2215
✓✗✓✗
✓✗
2
  normal << 0, 0, 1;
2216
2
  SET_LINE;
2217
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
2218
2219
✓✗
2
  tf1 = transform;
2220
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(0, 0, 2.5));
2221
✓✗✓✗
2
  contact = transform.transform(Vec3f(0, 0, 2.5));
2222
2
  depth = 2.5;
2223
✓✗✓✗
✓✗
2
  normal = transform.getRotation() * Vec3f(0, 0, 1);
2224
2
  SET_LINE;
2225
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
2226
2227
✓✗✓✗
2
  tf1 = Transform3f();
2228
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(0, 0, -2.5));
2229
✓✗✓✗
✓✗
2
  contact << 0, 0, -2.5;
2230
2
  depth = 2.5;
2231
✓✗✓✗
✓✗
2
  normal << 0, 0, -1;
2232
2
  SET_LINE;
2233
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
2234
2235
✓✗
2
  tf1 = transform;
2236
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(0, 0, -2.5));
2237
✓✗✓✗
2
  contact = transform.transform(Vec3f(0, 0, -2.5));
2238
2
  depth = 2.5;
2239
✓✗✓✗
✓✗
2
  normal = transform.getRotation() * Vec3f(0, 0, -1);
2240
2
  SET_LINE;
2241
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
2242
2243
✓✗✓✗
2
  tf1 = Transform3f();
2244
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(0, 0, 10.1));
2245
2
  SET_LINE;
2246
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, false);
2247
2248
✓✗
2
  tf1 = transform;
2249
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(0, 0, 10.1));
2250
2
  SET_LINE;
2251
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, false);
2252
2253
✓✗✓✗
2
  tf1 = Transform3f();
2254
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(0, 0, -10.1));
2255
2
  SET_LINE;
2256
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, false);
2257
2258
✓✗
2
  tf1 = transform;
2259
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(0, 0, -10.1));
2260
2
  SET_LINE;
2261
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, false);
2262
2
}
2263
2264
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗
4
BOOST_AUTO_TEST_CASE(shapeIntersection_halfspacecone) {
2265
✓✗
4
  Cone s(5, 10);
2266
✓✗✓✗
4
  Halfspace hs(Vec3f(1, 0, 0), 0);
2267
2268
✓✗
2
  Transform3f tf1;
2269
✓✗
2
  Transform3f tf2;
2270
2271
✓✗
2
  Transform3f transform;
2272
✓✗
2
  generateRandomTransform(extents, transform);
2273
2274
✓✗
2
  Vec3f contact;
2275
  FCL_REAL depth;
2276
✓✗
2
  Vec3f normal;
2277
2278
✓✗✓✗
2
  tf1 = Transform3f();
2279
✓✗✓✗
2
  tf2 = Transform3f();
2280
✓✗✓✗
✓✗
2
  contact << -2.5, 0, -5;
2281
2
  depth = 5;
2282
✓✗✓✗
✓✗
2
  normal << -1, 0, 0;
2283
2
  SET_LINE;
2284
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
2285
2286
✓✗
2
  tf1 = transform;
2287
✓✗
2
  tf2 = transform;
2288
✓✗✓✗
2
  contact = transform.transform(Vec3f(-2.5, 0, -5));
2289
2
  depth = 5;
2290
✓✗✓✗
✓✗
2
  normal = transform.getRotation() * Vec3f(-1, 0, 0);
2291
2
  SET_LINE;
2292
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
2293
2294
✓✗✓✗
2
  tf1 = Transform3f();
2295
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(2.5, 0, 0));
2296
✓✗✓✗
✓✗
2
  contact << -1.25, 0, -5;
2297
2
  depth = 7.5;
2298
✓✗✓✗
✓✗
2
  normal << -1, 0, 0;
2299
2
  SET_LINE;
2300
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
2301
2302
✓✗
2
  tf1 = transform;
2303
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(2.5, 0, 0));
2304
✓✗✓✗
2
  contact = transform.transform(Vec3f(-1.25, 0, -5));
2305
2
  depth = 7.5;
2306
✓✗✓✗
✓✗
2
  normal = transform.getRotation() * Vec3f(-1, 0, 0);
2307
2
  SET_LINE;
2308
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
2309
2310
✓✗✓✗
2
  tf1 = Transform3f();
2311
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(-2.5, 0, 0));
2312
✓✗✓✗
✓✗
2
  contact << -3.75, 0, -5;
2313
2
  depth = 2.5;
2314
✓✗✓✗
✓✗
2
  normal << -1, 0, 0;
2315
2
  SET_LINE;
2316
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
2317
2318
✓✗
2
  tf1 = transform;
2319
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(-2.5, 0, 0));
2320
✓✗✓✗
2
  contact = transform.transform(Vec3f(-3.75, 0, -5));
2321
2
  depth = 2.5;
2322
✓✗✓✗
✓✗
2
  normal = transform.getRotation() * Vec3f(-1, 0, 0);
2323
2
  SET_LINE;
2324
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
2325
2326
✓✗✓✗
2
  tf1 = Transform3f();
2327
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(5.1, 0, 0));
2328
✓✗✓✗
✓✗
2
  contact << 0.05, 0, -5;
2329
2
  depth = 10.1;
2330
✓✗✓✗
✓✗
2
  normal << -1, 0, 0;
2331
2
  SET_LINE;
2332
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
2333
2334
✓✗
2
  tf1 = transform;
2335
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(5.1, 0, 0));
2336
✓✗✓✗
2
  contact = transform.transform(Vec3f(0.05, 0, -5));
2337
2
  depth = 10.1;
2338
✓✗✓✗
✓✗
2
  normal = transform.getRotation() * Vec3f(-1, 0, 0);
2339
2
  SET_LINE;
2340
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
2341
2342
✓✗✓✗
2
  tf1 = Transform3f();
2343
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(-5.1, 0, 0));
2344
2
  SET_LINE;
2345
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, false);
2346
2347
✓✗
2
  tf1 = transform;
2348
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(-5.1, 0, 0));
2349
2
  SET_LINE;
2350
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, false);
2351
2352
✓✗✓✗
✓✗
2
  hs = Halfspace(Vec3f(0, 1, 0), 0);
2353
2354
✓✗✓✗
2
  tf1 = Transform3f();
2355
✓✗✓✗
2
  tf2 = Transform3f();
2356
✓✗✓✗
✓✗
2
  contact << 0, -2.5, -5;
2357
2
  depth = 5;
2358
✓✗✓✗
✓✗
2
  normal << 0, -1, 0;
2359
2
  SET_LINE;
2360
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
2361
2362
✓✗
2
  tf1 = transform;
2363
✓✗
2
  tf2 = transform;
2364
✓✗✓✗
2
  contact = transform.transform(Vec3f(0, -2.5, -5));
2365
2
  depth = 5;
2366
✓✗✓✗
✓✗
2
  normal = transform.getRotation() * Vec3f(0, -1, 0);
2367
2
  SET_LINE;
2368
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
2369
2370
✓✗✓✗
2
  tf1 = Transform3f();
2371
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(0, 2.5, 0));
2372
✓✗✓✗
✓✗
2
  contact << 0, -1.25, -5;
2373
2
  depth = 7.5;
2374
✓✗✓✗
✓✗
2
  normal << 0, -1, 0;
2375
2
  SET_LINE;
2376
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
2377
2378
✓✗
2
  tf1 = transform;
2379
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(0, 2.5, 0));
2380
✓✗✓✗
2
  contact = transform.transform(Vec3f(0, -1.25, -5));
2381
2
  depth = 7.5;
2382
✓✗✓✗
✓✗
2
  normal = transform.getRotation() * Vec3f(0, -1, 0);
2383
2
  SET_LINE;
2384
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
2385
2386
✓✗✓✗
2
  tf1 = Transform3f();
2387
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(0, -2.5, 0));
2388
✓✗✓✗
✓✗
2
  contact << 0, -3.75, -5;
2389
2
  depth = 2.5;
2390
✓✗✓✗
✓✗
2
  normal << 0, -1, 0;
2391
2
  SET_LINE;
2392
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
2393
2394
✓✗
2
  tf1 = transform;
2395
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(0, -2.5, 0));
2396
✓✗✓✗
2
  contact = transform.transform(Vec3f(0, -3.75, -5));
2397
2
  depth = 2.5;
2398
✓✗✓✗
✓✗
2
  normal = transform.getRotation() * Vec3f(0, -1, 0);
2399
2
  SET_LINE;
2400
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
2401
2402
✓✗✓✗
2
  tf1 = Transform3f();
2403
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(0, 5.1, 0));
2404
✓✗✓✗
✓✗
2
  contact << 0, 0.05, -5;
2405
2
  depth = 10.1;
2406
✓✗✓✗
✓✗
2
  normal << 0, -1, 0;
2407
2
  SET_LINE;
2408
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
2409
2410
✓✗
2
  tf1 = transform;
2411
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(0, 5.1, 0));
2412
✓✗✓✗
2
  contact = transform.transform(Vec3f(0, 0.05, -5));
2413
2
  depth = 10.1;
2414
✓✗✓✗
✓✗
2
  normal = transform.getRotation() * Vec3f(0, -1, 0);
2415
2
  SET_LINE;
2416
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
2417
2418
✓✗✓✗
2
  tf1 = Transform3f();
2419
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(0, -5.1, 0));
2420
2
  SET_LINE;
2421
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, false);
2422
2423
✓✗
2
  tf1 = transform;
2424
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(0, -5.1, 0));
2425
2
  SET_LINE;
2426
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, false);
2427
2428
✓✗✓✗
✓✗
2
  hs = Halfspace(Vec3f(0, 0, 1), 0);
2429
2430
✓✗✓✗
2
  tf1 = Transform3f();
2431
✓✗✓✗
2
  tf2 = Transform3f();
2432
✓✗✓✗
✓✗
2
  contact << 0, 0, -2.5;
2433
2
  depth = 5;
2434
✓✗✓✗
✓✗
2
  normal << 0, 0, -1;
2435
2
  SET_LINE;
2436
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
2437
2438
✓✗
2
  tf1 = transform;
2439
✓✗
2
  tf2 = transform;
2440
✓✗✓✗
2
  contact = transform.transform(Vec3f(0, 0, -2.5));
2441
2
  depth = 5;
2442
✓✗✓✗
✓✗
2
  normal = transform.getRotation() * Vec3f(0, 0, -1);
2443
2
  SET_LINE;
2444
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
2445
2446
✓✗✓✗
2
  tf1 = Transform3f();
2447
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(0, 0, 2.5));
2448
✓✗✓✗
✓✗
2
  contact << 0, 0, -1.25;
2449
2
  depth = 7.5;
2450
✓✗✓✗
✓✗
2
  normal << 0, 0, -1;
2451
2
  SET_LINE;
2452
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
2453
2454
✓✗
2
  tf1 = transform;
2455
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(0, 0, 2.5));
2456
✓✗✓✗
2
  contact = transform.transform(Vec3f(0, 0, -1.25));
2457
2
  depth = 7.5;
2458
✓✗✓✗
✓✗
2
  normal = transform.getRotation() * Vec3f(0, 0, -1);
2459
2
  SET_LINE;
2460
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
2461
2462
✓✗✓✗
2
  tf1 = Transform3f();
2463
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(0, 0, -2.5));
2464
✓✗✓✗
✓✗
2
  contact << 0, 0, -3.75;
2465
2
  depth = 2.5;
2466
✓✗✓✗
✓✗
2
  normal << 0, 0, -1;
2467
2
  SET_LINE;
2468
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
2469
2470
✓✗
2
  tf1 = transform;
2471
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(0, 0, -2.5));
2472
✓✗✓✗
2
  contact = transform.transform(Vec3f(0, 0, -3.75));
2473
2
  depth = 2.5;
2474
✓✗✓✗
✓✗
2
  normal = transform.getRotation() * Vec3f(0, 0, -1);
2475
2
  SET_LINE;
2476
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
2477
2478
✓✗✓✗
2
  tf1 = Transform3f();
2479
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(0, 0, 5.1));
2480
✓✗✓✗
✓✗
2
  contact << 0, 0, 0.05;
2481
2
  depth = 10.1;
2482
✓✗✓✗
✓✗
2
  normal << 0, 0, -1;
2483
2
  SET_LINE;
2484
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
2485
2486
✓✗
2
  tf1 = transform;
2487
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(0, 0, 5.1));
2488
✓✗✓✗
2
  contact = transform.transform(Vec3f(0, 0, 0.05));
2489
2
  depth = 10.1;
2490
✓✗✓✗
✓✗
2
  normal = transform.getRotation() * Vec3f(0, 0, -1);
2491
2
  SET_LINE;
2492
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
2493
2494
✓✗✓✗
2
  tf1 = Transform3f();
2495
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(0, 0, -5.1));
2496
2
  SET_LINE;
2497
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, false);
2498
2499
✓✗
2
  tf1 = transform;
2500
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(0, 0, -5.1));
2501
2
  SET_LINE;
2502
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, false);
2503
2
}
2504
2505
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗
4
BOOST_AUTO_TEST_CASE(shapeIntersection_planecone) {
2506
✓✗
4
  Cone s(5, 10);
2507
✓✗✓✗
4
  Plane hs(Vec3f(1, 0, 0), 0);
2508
2509
✓✗
2
  Transform3f tf1;
2510
✓✗
2
  Transform3f tf2;
2511
2512
✓✗
2
  Transform3f transform;
2513
✓✗
2
  generateRandomTransform(extents, transform);
2514
2515
✓✗
2
  Vec3f contact;
2516
  FCL_REAL depth;
2517
✓✗
2
  Vec3f normal;
2518
2519
✓✗✓✗
2
  tf1 = Transform3f();
2520
✓✗✓✗
2
  tf2 = Transform3f();
2521
✓✗✓✗
✓✗
2
  contact << 0, 0, 0;
2522
2
  depth = 5;
2523
✓✗✓✗
✓✗
2
  normal << 1, 0, 0;  // (1, 0, 0) or (-1, 0, 0)
2524
2
  SET_LINE;
2525
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal, true);
2526
2527
✓✗
2
  tf1 = transform;
2528
✓✗
2
  tf2 = transform;
2529
✓✗✓✗
2
  contact = transform.transform(Vec3f(0, 0, 0));
2530
2
  depth = 5;
2531
  normal =
2532
✓✗✓✗
✓✗
2
      transform.getRotation() * Vec3f(-1, 0, 0);  // (1, 0, 0) or (-1, 0, 0)
2533
2
  SET_LINE;
2534
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal, true);
2535
2536
✓✗✓✗
2
  tf1 = Transform3f();
2537
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(2.5, 0, 0));
2538
✓✗✓✗
✓✗
2
  contact << 2.5, 0, -2.5;
2539
2
  depth = 2.5;
2540
✓✗✓✗
✓✗
2
  normal << 1, 0, 0;
2541
2
  SET_LINE;
2542
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
2543
2544
✓✗
2
  tf1 = transform;
2545
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(2.5, 0, 0));
2546
✓✗✓✗
2
  contact = transform.transform(Vec3f(2.5, 0, -2.5));
2547
2
  depth = 2.5;
2548
✓✗✓✗
✓✗
2
  normal = transform.getRotation() * Vec3f(1, 0, 0);
2549
2
  SET_LINE;
2550
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
2551
2552
✓✗✓✗
2
  tf1 = Transform3f();
2553
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(-2.5, 0, 0));
2554
✓✗✓✗
✓✗
2
  contact << -2.5, 0, -2.5;
2555
2
  depth = 2.5;
2556
✓✗✓✗
✓✗
2
  normal << -1, 0, 0;
2557
2
  SET_LINE;
2558
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
2559
2560
✓✗
2
  tf1 = transform;
2561
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(-2.5, 0, 0));
2562
✓✗✓✗
2
  contact = transform.transform(Vec3f(-2.5, 0, -2.5));
2563
2
  depth = 2.5;
2564
✓✗✓✗
✓✗
2
  normal = transform.getRotation() * Vec3f(-1, 0, 0);
2565
2
  SET_LINE;
2566
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
2567
2568
✓✗✓✗
2
  tf1 = Transform3f();
2569
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(5.1, 0, 0));
2570
2
  SET_LINE;
2571
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, false);
2572
2573
✓✗
2
  tf1 = transform;
2574
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(5.1, 0, 0));
2575
2
  SET_LINE;
2576
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, false);
2577
2578
✓✗✓✗
2
  tf1 = Transform3f();
2579
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(-5.1, 0, 0));
2580
2
  SET_LINE;
2581
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, false);
2582
2583
✓✗
2
  tf1 = transform;
2584
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(-5.1, 0, 0));
2585
2
  SET_LINE;
2586
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, false);
2587
2588
✓✗✓✗
✓✗
2
  hs = Plane(Vec3f(0, 1, 0), 0);
2589
2590
✓✗✓✗
2
  tf1 = Transform3f();
2591
✓✗✓✗
2
  tf2 = Transform3f();
2592
✓✗✓✗
✓✗
2
  contact << 0, 0, 0;
2593
2
  depth = 5;
2594
✓✗✓✗
✓✗
2
  normal << 0, 1, 0;  // (1, 0, 0) or (-1, 0, 0)
2595
2
  SET_LINE;
2596
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal, true);
2597
2598
✓✗
2
  tf1 = transform;
2599
✓✗
2
  tf2 = transform;
2600
✓✗✓✗
2
  contact = transform.transform(Vec3f(0, 0, 0));
2601
2
  depth = 5;
2602
✓✗✓✗
✓✗
2
  normal = transform.getRotation() * Vec3f(0, 1, 0);  // (1, 0, 0) or (-1, 0, 0)
2603
2
  SET_LINE;
2604
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal, true);
2605
2606
✓✗✓✗
2
  tf1 = Transform3f();
2607
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(0, 2.5, 0));
2608
✓✗✓✗
✓✗
2
  contact << 0, 2.5, -2.5;
2609
2
  depth = 2.5;
2610
✓✗✓✗
✓✗
2
  normal << 0, 1, 0;
2611
2
  SET_LINE;
2612
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
2613
2614
✓✗
2
  tf1 = transform;
2615
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(0, 2.5, 0));
2616
✓✗✓✗
2
  contact = transform.transform(Vec3f(0, 2.5, -2.5));
2617
2
  depth = 2.5;
2618
✓✗✓✗
✓✗
2
  normal = transform.getRotation() * Vec3f(0, 1, 0);
2619
2
  SET_LINE;
2620
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
2621
2622
✓✗✓✗
2
  tf1 = Transform3f();
2623
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(0, -2.5, 0));
2624
✓✗✓✗
✓✗
2
  contact << 0, -2.5, -2.5;
2625
2
  depth = 2.5;
2626
✓✗✓✗
✓✗
2
  normal << 0, -1, 0;
2627
2
  SET_LINE;
2628
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
2629
2630
✓✗
2
  tf1 = transform;
2631
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(0, -2.5, 0));
2632
✓✗✓✗
2
  contact = transform.transform(Vec3f(0, -2.5, -2.5));
2633
2
  depth = 2.5;
2634
✓✗✓✗
✓✗
2
  normal = transform.getRotation() * Vec3f(0, -1, 0);
2635
2
  SET_LINE;
2636
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
2637
2638
✓✗✓✗
2
  tf1 = Transform3f();
2639
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(0, 5.1, 0));
2640
2
  SET_LINE;
2641
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, false);
2642
2643
✓✗
2
  tf1 = transform;
2644
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(0, 5.1, 0));
2645
2
  SET_LINE;
2646
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, false);
2647
2648
✓✗✓✗
2
  tf1 = Transform3f();
2649
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(0, -5.1, 0));
2650
2
  SET_LINE;
2651
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, false);
2652
2653
✓✗
2
  tf1 = transform;
2654
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(0, -5.1, 0));
2655
2
  SET_LINE;
2656
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, false);
2657
2658
✓✗✓✗
✓✗
2
  hs = Plane(Vec3f(0, 0, 1), 0);
2659
2660
✓✗✓✗
2
  tf1 = Transform3f();
2661
✓✗✓✗
2
  tf2 = Transform3f();
2662
✓✗✓✗
✓✗
2
  contact << 0, 0, 0;
2663
2
  depth = 5;
2664
✓✗✓✗
✓✗
2
  normal << 0, 0, 1;  // (1, 0, 0) or (-1, 0, 0)
2665
2
  SET_LINE;
2666
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal, true);
2667
2668
✓✗
2
  tf1 = transform;
2669
✓✗
2
  tf2 = transform;
2670
✓✗✓✗
2
  contact = transform.transform(Vec3f(0, 0, 0));
2671
2
  depth = 5;
2672
✓✗✓✗
✓✗
2
  normal = transform.getRotation() * Vec3f(0, 0, 1);  // (1, 0, 0) or (-1, 0, 0)
2673
2
  SET_LINE;
2674
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal, true);
2675
2676
✓✗✓✗
2
  tf1 = Transform3f();
2677
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(0, 0, 2.5));
2678
✓✗✓✗
✓✗
2
  contact << 0, 0, 2.5;
2679
2
  depth = 2.5;
2680
✓✗✓✗
✓✗
2
  normal << 0, 0, 1;
2681
2
  SET_LINE;
2682
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
2683
2684
✓✗
2
  tf1 = transform;
2685
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(0, 0, 2.5));
2686
✓✗✓✗
2
  contact = transform.transform(Vec3f(0, 0, 2.5));
2687
2
  depth = 2.5;
2688
✓✗✓✗
✓✗
2
  normal = transform.getRotation() * Vec3f(0, 0, 1);
2689
2
  SET_LINE;
2690
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
2691
2692
✓✗✓✗
2
  tf1 = Transform3f();
2693
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(0, 0, -2.5));
2694
✓✗✓✗
✓✗
2
  contact << 0, 0, -2.5;
2695
2
  depth = 2.5;
2696
✓✗✓✗
✓✗
2
  normal << 0, 0, -1;
2697
2
  SET_LINE;
2698
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
2699
2700
✓✗
2
  tf1 = transform;
2701
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(0, 0, -2.5));
2702
✓✗✓✗
2
  contact = transform.transform(Vec3f(0, 0, -2.5));
2703
2
  depth = 2.5;
2704
✓✗✓✗
✓✗
2
  normal = transform.getRotation() * Vec3f(0, 0, -1);
2705
2
  SET_LINE;
2706
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, true, &contact, &depth, &normal);
2707
2708
✓✗✓✗
2
  tf1 = Transform3f();
2709
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(0, 0, 10.1));
2710
2
  SET_LINE;
2711
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, false);
2712
2713
✓✗
2
  tf1 = transform;
2714
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(0, 0, 10.1));
2715
2
  SET_LINE;
2716
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, false);
2717
2718
✓✗✓✗
2
  tf1 = Transform3f();
2719
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(0, 0, -10.1));
2720
2
  SET_LINE;
2721
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, false);
2722
2723
✓✗
2
  tf1 = transform;
2724
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(0, 0, -10.1));
2725
2
  SET_LINE;
2726
✓✗
2
  testShapeIntersection(s, tf1, hs, tf2, false);
2727
2
}
2728
2729
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗
4
BOOST_AUTO_TEST_CASE(shapeDistance_spheresphere) {
2730
✓✗
4
  Sphere s1(20);
2731
✓✗
4
  Sphere s2(10);
2732
2733
✓✗
2
  Transform3f transform;
2734
  // generateRandomTransform(extents, transform);
2735
2736
  bool res;
2737
2
  FCL_REAL dist = -1;
2738
✓✗✓✗
✓✗
2
  Vec3f closest_p1, closest_p2, normal;
2739
  res =
2740
✓✗✓✗
✓✗✓✗
2
      solver1.shapeDistance(s1, Transform3f(), s2, Transform3f(Vec3f(0, 40, 0)),
2741
                            dist, closest_p1, closest_p2, normal);
2742
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(fabs(dist - 10) < 0.001);
2743
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(res);
2744
2745
✓✗✓✗
2
  res = solver1.shapeDistance(s1, Transform3f(), s2,
2746
✓✗✓✗
4
                              Transform3f(Vec3f(30.1, 0, 0)), dist, closest_p1,
2747
                              closest_p2, normal);
2748
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(fabs(dist - 0.1) < 0.001);
2749
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(res);
2750
2751
✓✗✓✗
2
  res = solver1.shapeDistance(s1, Transform3f(), s2,
2752
✓✗✓✗
4
                              Transform3f(Vec3f(29.9, 0, 0)), dist, closest_p1,
2753
                              closest_p2, normal);
2754
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(dist < 0);
2755
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK_FALSE(res);
2756
2757
  res =
2758
✓✗✓✗
✓✗✓✗
2
      solver1.shapeDistance(s1, Transform3f(Vec3f(40, 0, 0)), s2, Transform3f(),
2759
                            dist, closest_p1, closest_p2, normal);
2760
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(fabs(dist - 10) < 0.001);
2761
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(res);
2762
2763
✓✗✓✗
✓✗
2
  res = solver1.shapeDistance(s1, Transform3f(Vec3f(30.1, 0, 0)), s2,
2764
✓✗
4
                              Transform3f(), dist, closest_p1, closest_p2,
2765
                              normal);
2766
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(fabs(dist - 0.1) < 0.001);
2767
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(res);
2768
2769
✓✗✓✗
✓✗
2
  res = solver1.shapeDistance(s1, Transform3f(Vec3f(29.9, 0, 0)), s2,
2770
✓✗
4
                              Transform3f(), dist, closest_p1, closest_p2,
2771
                              normal);
2772
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(dist < 0);
2773
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK_FALSE(res);
2774
2775
✓✗
2
  res = solver1.shapeDistance(s1, transform, s2,
2776
✓✗✓✗
✓✗
4
                              transform * Transform3f(Vec3f(40, 0, 0)), dist,
2777
                              closest_p1, closest_p2, normal);
2778
  // this is one problem: the precise is low sometimes
2779
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(fabs(dist - 10) < 0.1);
2780
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(res);
2781
2782
✓✗
2
  res = solver1.shapeDistance(s1, transform, s2,
2783
✓✗✓✗
✓✗
4
                              transform * Transform3f(Vec3f(30.1, 0, 0)), dist,
2784
                              closest_p1, closest_p2, normal);
2785
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(fabs(dist - 0.1) < 0.06);
2786
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(res);
2787
2788
✓✗
2
  res = solver1.shapeDistance(s1, transform, s2,
2789
✓✗✓✗
✓✗
4
                              transform * Transform3f(Vec3f(29.9, 0, 0)), dist,
2790
                              closest_p1, closest_p2, normal);
2791
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(dist < 0);
2792
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK_FALSE(res);
2793
2794
✓✗✓✗
✓✗✓✗
2
  res = solver1.shapeDistance(s1, transform * Transform3f(Vec3f(40, 0, 0)), s2,
2795
                              transform, dist, closest_p1, closest_p2, normal);
2796
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(fabs(dist - 10) < 0.1);
2797
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(res);
2798
2799
  res =
2800
✓✗✓✗
✓✗✓✗
2
      solver1.shapeDistance(s1, transform * Transform3f(Vec3f(30.1, 0, 0)), s2,
2801
                            transform, dist, closest_p1, closest_p2, normal);
2802
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(fabs(dist - 0.1) < 0.1);
2803
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(res);
2804
2805
  res =
2806
✓✗✓✗
✓✗✓✗
2
      solver1.shapeDistance(s1, transform * Transform3f(Vec3f(29.9, 0, 0)), s2,
2807
                            transform, dist, closest_p1, closest_p2, normal);
2808
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(dist < 0);
2809
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK_FALSE(res);
2810
2
}
2811
2812
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗
4
BOOST_AUTO_TEST_CASE(shapeDistance_boxbox) {
2813
✓✗
4
  Box s1(20, 40, 50);
2814
✓✗
4
  Box s2(10, 10, 10);
2815
✓✗✓✗
✓✗
2
  Vec3f closest_p1, closest_p2, normal;
2816
2817
✓✗
2
  Transform3f transform;
2818
  // generateRandomTransform(extents, transform);
2819
2820
  bool res;
2821
  FCL_REAL dist;
2822
2823
✓✗✓✗
✓✗
2
  res = solver1.shapeDistance(s1, Transform3f(), s2, Transform3f(), dist,
2824
                              closest_p1, closest_p2, normal);
2825
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(dist <= 0);
2826
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK_FALSE(res);
2827
2828
✓✗
2
  res = solver1.shapeDistance(s1, transform, s2, transform, dist, closest_p1,
2829
                              closest_p2, normal);
2830
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(dist <= 0);
2831
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK_FALSE(res);
2832
2833
✓✗✓✗
2
  res = solver1.shapeDistance(s2, Transform3f(), s2,
2834
✓✗✓✗
4
                              Transform3f(Vec3f(10.1, 0, 0)), dist, closest_p1,
2835
                              closest_p2, normal);
2836
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(fabs(dist - 0.1) < 0.001);
2837
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(res);
2838
2839
✓✗✓✗
2
  res = solver1.shapeDistance(s2, Transform3f(), s2,
2840
✓✗✓✗
4
                              Transform3f(Vec3f(20.1, 0, 0)), dist, closest_p1,
2841
                              closest_p2, normal);
2842
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(fabs(dist - 10.1) < 0.001);
2843
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(res);
2844
2845
✓✗✓✗
2
  res = solver1.shapeDistance(s2, Transform3f(), s2,
2846
✓✗✓✗
4
                              Transform3f(Vec3f(0, 20.2, 0)), dist, closest_p1,
2847
                              closest_p2, normal);
2848
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(fabs(dist - 10.2) < 0.001);
2849
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(res);
2850
2851
✓✗✓✗
2
  res = solver1.shapeDistance(s2, Transform3f(), s2,
2852
✓✗✓✗
4
                              Transform3f(Vec3f(10.1, 10.1, 0)), dist,
2853
                              closest_p1, closest_p2, normal);
2854
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(fabs(dist - 0.1 * 1.414) < 0.001);
2855
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(res);
2856
2857
✓✗✓✗
2
  res = solver2.shapeDistance(s2, Transform3f(), s2,
2858
✓✗✓✗
4
                              Transform3f(Vec3f(10.1, 0, 0)), dist, closest_p1,
2859
                              closest_p2, normal);
2860
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(fabs(dist - 0.1) < 0.001);
2861
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(res);
2862
2863
✓✗✓✗
2
  res = solver2.shapeDistance(s2, Transform3f(), s2,
2864
✓✗✓✗
4
                              Transform3f(Vec3f(20.1, 0, 0)), dist, closest_p1,
2865
                              closest_p2, normal);
2866
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(fabs(dist - 10.1) < 0.001);
2867
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(res);
2868
2869
✓✗✓✗
2
  res = solver2.shapeDistance(s2, Transform3f(), s2,
2870
✓✗✓✗
4
                              Transform3f(Vec3f(0, 20.1, 0)), dist, closest_p1,
2871
                              closest_p2, normal);
2872
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(fabs(dist - 10.1) < 0.001);
2873
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(res);
2874
2875
✓✗✓✗
2
  res = solver2.shapeDistance(s2, Transform3f(), s2,
2876
✓✗✓✗
4
                              Transform3f(Vec3f(10.1, 10.1, 0)), dist,
2877
                              closest_p1, closest_p2, normal);
2878
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(fabs(dist - 0.1 * 1.414) < 0.001);
2879
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(res);
2880
2881
✓✗
2
  res = solver1.shapeDistance(s1, transform, s2,
2882
✓✗✓✗
✓✗
4
                              transform * Transform3f(Vec3f(15.1, 0, 0)), dist,
2883
                              closest_p1, closest_p2, normal);
2884
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(fabs(dist - 0.1) < 0.001);
2885
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(res);
2886
2887
  res =
2888
✓✗✓✗
✓✗✓✗
2
      solver1.shapeDistance(s1, Transform3f(), s2, Transform3f(Vec3f(20, 0, 0)),
2889
                            dist, closest_p1, closest_p2, normal);
2890
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(fabs(dist - 5) < 0.001);
2891
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(res);
2892
2893
✓✗
2
  res = solver1.shapeDistance(s1, transform, s2,
2894
✓✗✓✗
✓✗
4
                              transform * Transform3f(Vec3f(20, 0, 0)), dist,
2895
                              closest_p1, closest_p2, normal);
2896
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(fabs(dist - 5) < 0.001);
2897
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(res);
2898
2
}
2899
2900
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗
4
BOOST_AUTO_TEST_CASE(shapeDistance_boxsphere) {
2901
✓✗
4
  Sphere s1(20);
2902
✓✗
4
  Box s2(5, 5, 5);
2903
✓✗✓✗
✓✗
2
  Vec3f closest_p1, closest_p2, normal;
2904
2905
✓✗
2
  Transform3f transform;
2906
✓✗
2
  generateRandomTransform(extents, transform);
2907
2908
  bool res;
2909
  FCL_REAL dist;
2910
2911
2
  int N = 10;
2912
✓✓
24
  for (int i = 0; i < N + 1; ++i) {
2913
✓✗
22
    FCL_REAL dbox = 0.0001 + (s1.radius + s2.halfSide(0)) * i * 4 / (3 * N);
2914
✓✗✓✗
✓✗
22
    res = solver1.shapeDistance(s1, Transform3f(Vec3f(dbox, 0., 0.)), s2,
2915
✓✗
44
                                Transform3f(), dist, closest_p1, closest_p2,
2916
                                normal);
2917
✓✗✓✗
✓✗✓✗
✓✗✓✗
✗✓
22
    BOOST_CHECK_CLOSE(dist, (dbox - s1.radius - s2.halfSide(0)), 1e-6);
2918
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✗✓
22
    EIGEN_VECTOR_IS_APPROX(normal, -Vec3f(1, 0, 0), 1e-6);
2919
2920
✓✗
22
    res = solver1.shapeDistance(s1, transform, s2, transform, dist, closest_p1,
2921
                                closest_p2, normal);
2922
✓✗
22
    res = solver1.shapeDistance(
2923
✓✗✓✗
✓✗
44
        s1, transform * Transform3f(Vec3f(dbox, 0., 0.)), s2, transform, dist,
2924
        closest_p1, closest_p2, normal);
2925
✓✗✓✗
✓✗✓✗
✓✗✓✗
✗✓
22
    BOOST_CHECK_CLOSE(dist, (dbox - s1.radius - s2.halfSide(0)), 1e-6);
2926
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✗✓
22
    EIGEN_VECTOR_IS_APPROX(normal, -transform.getRotation().col(0), 1e-6);
2927
  }
2928
2929
✓✗✓✗
✓✗
2
  res = solver1.shapeDistance(s1, Transform3f(), s2, Transform3f(), dist,
2930
                              closest_p1, closest_p2, normal);
2931
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(dist <= 0);
2932
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK_FALSE(res);
2933
2934
✓✗
2
  res = solver1.shapeDistance(s1, transform, s2, transform, dist, closest_p1,
2935
                              closest_p2, normal);
2936
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(dist <= 0);
2937
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK_FALSE(res);
2938
2939
✓✗✓✗
2
  res = solver1.shapeDistance(s1, Transform3f(), s2,
2940
✓✗✓✗
4
                              Transform3f(Vec3f(22.6, 0, 0)), dist, closest_p1,
2941
                              closest_p2, normal);
2942
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(fabs(dist - 0.1) < 0.001);
2943
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(res);
2944
2945
✓✗
2
  res = solver1.shapeDistance(s1, transform, s2,
2946
✓✗✓✗
✓✗
4
                              transform * Transform3f(Vec3f(22.6, 0, 0)), dist,
2947
                              closest_p1, closest_p2, normal);
2948
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(fabs(dist - 0.1) < 0.05);
2949
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(res);
2950
2951
  res =
2952
✓✗✓✗
✓✗✓✗
2
      solver1.shapeDistance(s1, Transform3f(), s2, Transform3f(Vec3f(40, 0, 0)),
2953
                            dist, closest_p1, closest_p2, normal);
2954
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(fabs(dist - 17.5) < 0.001);
2955
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(res);
2956
2957
✓✗
2
  res = solver1.shapeDistance(s1, transform, s2,
2958
✓✗✓✗
✓✗
4
                              transform * Transform3f(Vec3f(40, 0, 0)), dist,
2959
                              closest_p1, closest_p2, normal);
2960
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(fabs(dist - 17.5) < 0.001);
2961
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(res);
2962
2
}
2963
2964
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗
4
BOOST_AUTO_TEST_CASE(shapeDistance_cylindercylinder) {
2965
✓✗
4
  Cylinder s1(5, 10);
2966
✓✗
4
  Cylinder s2(5, 10);
2967
✓✗✓✗
✓✗
2
  Vec3f closest_p1, closest_p2, normal;
2968
2969
✓✗
2
  Transform3f transform;
2970
✓✗
2
  generateRandomTransform(extents, transform);
2971
2972
  bool res;
2973
  FCL_REAL dist;
2974
2975
✓✗✓✗
✓✗
2
  res = solver1.shapeDistance(s1, Transform3f(), s2, Transform3f(), dist,
2976
                              closest_p1, closest_p2, normal);
2977
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(dist <= 0);
2978
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK_FALSE(res);
2979
2980
✓✗
2
  res = solver1.shapeDistance(s1, transform, s2, transform, dist, closest_p1,
2981
                              closest_p2, normal);
2982
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(dist <= 0);
2983
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK_FALSE(res);
2984
2985
✓✗✓✗
2
  res = solver1.shapeDistance(s1, Transform3f(), s2,
2986
✓✗✓✗
4
                              Transform3f(Vec3f(10.1, 0, 0)), dist, closest_p1,
2987
                              closest_p2, normal);
2988
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(fabs(dist - 0.1) < 0.001);
2989
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(res);
2990
2991
✓✗
2
  res = solver1.shapeDistance(s1, transform, s2,
2992
✓✗✓✗
✓✗
4
                              transform * Transform3f(Vec3f(10.1, 0, 0)), dist,
2993
                              closest_p1, closest_p2, normal);
2994
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(fabs(dist - 0.1) < 0.001);
2995
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(res);
2996
2997
  res =
2998
✓✗✓✗
✓✗✓✗
2
      solver1.shapeDistance(s1, Transform3f(), s2, Transform3f(Vec3f(40, 0, 0)),
2999
                            dist, closest_p1, closest_p2, normal);
3000
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(fabs(dist - 30) < 0.001);
3001
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(res);
3002
3003
✓✗
2
  res = solver1.shapeDistance(s1, transform, s2,
3004
✓✗✓✗
✓✗
4
                              transform * Transform3f(Vec3f(40, 0, 0)), dist,
3005
                              closest_p1, closest_p2, normal);
3006
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(fabs(dist - 30) < 0.001);
3007
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(res);
3008
2
}
3009
3010
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗
4
BOOST_AUTO_TEST_CASE(shapeDistance_conecone) {
3011
✓✗
4
  Cone s1(5, 10);
3012
✓✗
4
  Cone s2(5, 10);
3013
✓✗✓✗
✓✗
2
  Vec3f closest_p1, closest_p2, normal;
3014
3015
✓✗
2
  Transform3f transform;
3016
✓✗
2
  generateRandomTransform(extents, transform);
3017
3018
  bool res;
3019
  FCL_REAL dist;
3020
3021
✓✗✓✗
✓✗
2
  res = solver1.shapeDistance(s1, Transform3f(), s2, Transform3f(), dist,
3022
                              closest_p1, closest_p2, normal);
3023
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(dist <= 0);
3024
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK_FALSE(res);
3025
3026
✓✗
2
  res = solver1.shapeDistance(s1, transform, s2, transform, dist, closest_p1,
3027
                              closest_p2, normal);
3028
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(dist <= 0);
3029
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK_FALSE(res);
3030
3031
✓✗✓✗
2
  res = solver1.shapeDistance(s1, Transform3f(), s2,
3032
✓✗✓✗
4
                              Transform3f(Vec3f(10.1, 0, 0)), dist, closest_p1,
3033
                              closest_p2, normal);
3034
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(fabs(dist - 0.1) < 0.001);
3035
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(res);
3036
3037
✓✗
2
  res = solver1.shapeDistance(s1, transform, s2,
3038
✓✗✓✗
✓✗
4
                              transform * Transform3f(Vec3f(10.1, 0, 0)), dist,
3039
                              closest_p1, closest_p2, normal);
3040
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(fabs(dist - 0.1) < 0.001);
3041
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(res);
3042
3043
  res =
3044
✓✗✓✗
✓✗✓✗
2
      solver1.shapeDistance(s1, Transform3f(), s2, Transform3f(Vec3f(0, 0, 40)),
3045
                            dist, closest_p1, closest_p2, normal);
3046
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(fabs(dist - 30) < 1);
3047
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(res);
3048
3049
✓✗
2
  res = solver1.shapeDistance(s1, transform, s2,
3050
✓✗✓✗
✓✗
4
                              transform * Transform3f(Vec3f(0, 0, 40)), dist,
3051
                              closest_p1, closest_p2, normal);
3052
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(fabs(dist - 30) < 1);
3053
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(res);
3054
2
}
3055
3056
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗
4
BOOST_AUTO_TEST_CASE(shapeDistance_conecylinder) {
3057
✓✗
4
  Cylinder s1(5, 10);
3058
✓✗
4
  Cone s2(5, 10);
3059
✓✗✓✗
✓✗
2
  Vec3f closest_p1, closest_p2, normal;
3060
3061
✓✗
2
  Transform3f transform;
3062
✓✗
2
  generateRandomTransform(extents, transform);
3063
3064
  bool res;
3065
  FCL_REAL dist;
3066
3067
✓✗✓✗
✓✗
2
  res = solver1.shapeDistance(s1, Transform3f(), s2, Transform3f(), dist,
3068
                              closest_p1, closest_p2, normal);
3069
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(dist <= 0);
3070
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK_FALSE(res);
3071
3072
✓✗
2
  res = solver1.shapeDistance(s1, transform, s2, transform, dist, closest_p1,
3073
                              closest_p2, normal);
3074
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(dist <= 0);
3075
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK_FALSE(res);
3076
3077
✓✗✓✗
2
  res = solver1.shapeDistance(s1, Transform3f(), s2,
3078
✓✗✓✗
4
                              Transform3f(Vec3f(10.1, 0, 0)), dist, closest_p1,
3079
                              closest_p2, normal);
3080
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(fabs(dist - 0.1) < 0.01);
3081
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(res);
3082
3083
✓✗
2
  res = solver1.shapeDistance(s1, transform, s2,
3084
✓✗✓✗
✓✗
4
                              transform * Transform3f(Vec3f(10.1, 0, 0)), dist,
3085
                              closest_p1, closest_p2, normal);
3086
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(fabs(dist - 0.1) < 0.02);
3087
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(res);
3088
3089
  res =
3090
✓✗✓✗
✓✗✓✗
2
      solver1.shapeDistance(s1, Transform3f(), s2, Transform3f(Vec3f(40, 0, 0)),
3091
                            dist, closest_p1, closest_p2, normal);
3092
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(fabs(dist - 30) < 0.01);
3093
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(res);
3094
3095
✓✗
2
  res = solver1.shapeDistance(s1, transform, s2,
3096
✓✗✓✗
✓✗
4
                              transform * Transform3f(Vec3f(40, 0, 0)), dist,
3097
                              closest_p1, closest_p2, normal);
3098
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(fabs(dist - 30) < 0.1);
3099
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(res);
3100
2
}
3101
3102
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗
4
BOOST_AUTO_TEST_CASE(shapeIntersectionGJK_spheresphere) {
3103
✓✗
4
  Sphere s1(20);
3104
✓✗
4
  Sphere s2(10);
3105
3106
✓✗
2
  Transform3f tf1;
3107
✓✗
2
  Transform3f tf2;
3108
3109
✓✗
2
  Transform3f transform;
3110
✓✗
2
  generateRandomTransform(extents, transform);
3111
3112
  //  Vec3f contact;
3113
  //  FCL_REAL depth;
3114
✓✗
2
  Vec3f normal;
3115
3116
✓✗✓✗
2
  tf1 = Transform3f();
3117
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(40, 0, 0));
3118
2
  SET_LINE;
3119
✓✗
2
  testShapeIntersection(s1, tf1, s2, tf2, false);
3120
3121
✓✗
2
  tf1 = transform;
3122
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(40, 0, 0));
3123
2
  SET_LINE;
3124
✓✗
2
  testShapeIntersection(s1, tf1, s2, tf2, false);
3125
3126
✓✗✓✗
2
  tf1 = Transform3f();
3127
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(30, 0, 0));
3128
✓✗✓✗
✓✗
2
  normal << 1, 0, 0;
3129
2
  SET_LINE;
3130
✓✗
2
  testShapeIntersection(s1, tf1, s2, tf2, true, NULL, NULL, &normal);
3131
3132
✓✗✓✗
2
  tf1 = Transform3f();
3133
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(30.01, 0, 0));
3134
2
  SET_LINE;
3135
✓✗
2
  testShapeIntersection(s1, tf1, s2, tf2, false);
3136
3137
✓✗
2
  tf1 = transform;
3138
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(30.01, 0, 0));
3139
✓✗✓✗
✓✗
2
  normal = transform.getRotation() * Vec3f(1, 0, 0);
3140
2
  SET_LINE;
3141
✓✗
2
  testShapeIntersection(s1, tf1, s2, tf2, false);
3142
3143
✓✗✓✗
2
  tf1 = Transform3f();
3144
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(29.9, 0, 0));
3145
✓✗✓✗
✓✗
2
  normal << 1, 0, 0;
3146
2
  SET_LINE;
3147
✓✗
2
  testShapeIntersection(s1, tf1, s2, tf2, true, NULL, NULL, &normal);
3148
3149
✓✗
2
  tf1 = transform;
3150
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(29.9, 0, 0));
3151
✓✗✓✗
✓✗
2
  normal = transform.getRotation() * Vec3f(1, 0, 0);
3152
2
  SET_LINE;
3153
✓✗
2
  testShapeIntersection(s1, tf1, s2, tf2, true, NULL, NULL, &normal);
3154
3155
✓✗✓✗
2
  tf1 = Transform3f();
3156
✓✗✓✗
2
  tf2 = Transform3f();
3157
✓✗
2
  normal.setZero();  // If the centers of two sphere are at the same position,
3158
                     // the normal is (0, 0, 0)
3159
2
  SET_LINE;
3160
✓✗
2
  testShapeIntersection(s1, tf1, s2, tf2, true, NULL, NULL, &normal);
3161
3162
✓✗
2
  tf1 = transform;
3163
✓✗
2
  tf2 = transform;
3164
✓✗
2
  normal.setZero();  // If the centers of two sphere are at the same position,
3165
                     // the normal is (0, 0, 0)
3166
2
  SET_LINE;
3167
✓✗
2
  testShapeIntersection(s1, tf1, s2, tf2, true, NULL, NULL, &normal);
3168
3169
✓✗✓✗
2
  tf1 = Transform3f();
3170
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(-29.9, 0, 0));
3171
✓✗✓✗
✓✗
2
  normal << -1, 0, 0;
3172
2
  SET_LINE;
3173
✓✗
2
  testShapeIntersection(s1, tf1, s2, tf2, true, NULL, NULL, &normal);
3174
3175
✓✗
2
  tf1 = transform;
3176
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(-29.9, 0, 0));
3177
✓✗✓✗
✓✗
2
  normal = transform.getRotation() * Vec3f(-1, 0, 0);
3178
2
  SET_LINE;
3179
✓✗
2
  testShapeIntersection(s1, tf1, s2, tf2, true, NULL, NULL, &normal);
3180
3181
✓✗✓✗
2
  tf1 = Transform3f();
3182
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(-30.0, 0, 0));
3183
✓✗✓✗
✓✗
2
  normal << -1, 0, 0;
3184
2
  SET_LINE;
3185
✓✗
2
  testShapeIntersection(s1, tf1, s2, tf2, true, NULL, NULL, &normal);
3186
3187
✓✗✓✗
2
  tf1 = Transform3f();
3188
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(-30.01, 0, 0));
3189
✓✗✓✗
✓✗
2
  normal << -1, 0, 0;
3190
2
  SET_LINE;
3191
✓✗
2
  testShapeIntersection(s1, tf1, s2, tf2, false);
3192
3193
✓✗
2
  tf1 = transform;
3194
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(-30.01, 0, 0));
3195
2
  SET_LINE;
3196
✓✗
2
  testShapeIntersection(s1, tf1, s2, tf2, false);
3197
2
}
3198
3199
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗
4
BOOST_AUTO_TEST_CASE(shapeIntersectionGJK_boxbox) {
3200
✓✗
4
  Box s1(20, 40, 50);
3201
✓✗
4
  Box s2(10, 10, 10);
3202
3203
✓✗
2
  Transform3f tf1;
3204
✓✗
2
  Transform3f tf2;
3205
3206
✓✗
2
  Transform3f transform;
3207
✓✗
2
  generateRandomTransform(extents, transform);
3208
3209
  // Vec3f point;
3210
  // FCL_REAL depth;
3211
✓✗
2
  Vec3f normal;
3212
3213
✓✗
2
  Quaternion3f q;
3214
✓✗✓✗
2
  q = AngleAxis((FCL_REAL)3.140 / 6, UnitZ);
3215
3216
✓✗✓✗
2
  tf1 = Transform3f();
3217
✓✗✓✗
2
  tf2 = Transform3f();
3218
  // TODO: Need convention for normal when the centers of two objects are at
3219
  // same position. The current result is (1, 0, 0).
3220
✓✗✓✗
✓✗
2
  normal << 1, 0, 0;
3221
2
  SET_LINE;
3222
✓✗
2
  testShapeIntersection(s1, tf1, s2, tf2, true, NULL, NULL, 0x0);
3223
3224
✓✗
2
  tf1 = transform;
3225
✓✗
2
  tf2 = transform;
3226
  // TODO: Need convention for normal when the centers of two objects are at
3227
  // same position. The current result is (1, 0, 0).
3228
✓✗✓✗
✓✗
2
  normal = transform.getRotation() * Vec3f(1, 0, 0);
3229
2
  SET_LINE;
3230
✓✗
2
  testShapeIntersection(s1, tf1, s2, tf2, true, NULL, NULL, 0x0);
3231
3232
✓✗✓✗
2
  tf1 = Transform3f();
3233
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(15, 0, 0));
3234
✓✗✓✗
✓✗
2
  normal << 1, 0, 0;
3235
2
  SET_LINE;
3236
✓✗
2
  testShapeIntersection(s1, tf1, s2, tf2, true, NULL, NULL, &normal, false,
3237
                        1e-8);
3238
3239
✓✗
2
  tf1 = transform;
3240
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(15.01, 0, 0));
3241
2
  SET_LINE;
3242
✓✗
2
  testShapeIntersection(s1, tf1, s2, tf2, false);
3243
3244
✓✗✓✗
2
  tf1 = Transform3f();
3245
✓✗✓✗
2
  tf2 = Transform3f(q);
3246
✓✗✓✗
✓✗
2
  normal << 1, 0, 0;
3247
2
  SET_LINE;
3248
✓✗
2
  testShapeIntersection(s1, tf1, s2, tf2, true, NULL, NULL, 0x0);
3249
3250
✓✗
2
  tf1 = transform;
3251
✓✗✓✗
✓✗
2
  tf2 = transform * Transform3f(q);
3252
✓✗✓✗
✓✗
2
  normal = transform.getRotation() * Vec3f(1, 0, 0);
3253
2
  SET_LINE;
3254
✓✗
2
  testShapeIntersection(s1, tf1, s2, tf2, true, NULL, NULL, 0x0);
3255
2
}
3256
3257
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗
4
BOOST_AUTO_TEST_CASE(shapeIntersectionGJK_spherebox) {
3258
✓✗
4
  Sphere s1(20);
3259
✓✗
4
  Box s2(5, 5, 5);
3260
3261
✓✗
2
  Transform3f tf1;
3262
✓✗
2
  Transform3f tf2;
3263
3264
✓✗
2
  Transform3f transform;
3265
✓✗
2
  generateRandomTransform(extents, transform);
3266
3267
  // Vec3f point;
3268
  // FCL_REAL depth;
3269
✓✗
2
  Vec3f normal;
3270
3271
✓✗✓✗
2
  tf1 = Transform3f();
3272
✓✗✓✗
2
  tf2 = Transform3f();
3273
  // TODO: Need convention for normal when the centers of two objects are at
3274
  // same position.
3275
2
  SET_LINE;
3276
✓✗
2
  testShapeIntersection(s1, tf1, s2, tf2, true, NULL, NULL, NULL);
3277
3278
✓✗
2
  tf1 = transform;
3279
✓✗
2
  tf2 = transform;
3280
  // TODO: Need convention for normal when the centers of two objects are at
3281
  // same position.
3282
2
  SET_LINE;
3283
✓✗
2
  testShapeIntersection(s1, tf1, s2, tf2, true, NULL, NULL, NULL);
3284
3285
✓✗✓✗
2
  tf1 = Transform3f();
3286
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(22.5, 0, 0));
3287
✓✗✓✗
✓✗
2
  normal << 1, 0, 0;
3288
2
  SET_LINE;
3289
✓✗
2
  testShapeIntersection(
3290
      s1, tf1, s2, tf2, true, NULL, NULL, &normal, false,
3291
      1e-7);  // built-in GJK solver requires larger tolerance than libccd
3292
3293
✓✗
2
  tf1 = transform;
3294
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(22.51, 0, 0));
3295
2
  SET_LINE;
3296
✓✗
2
  testShapeIntersection(s1, tf1, s2, tf2, false);
3297
3298
✓✗✓✗
2
  tf1 = Transform3f();
3299
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(22.4, 0, 0));
3300
✓✗✓✗
✓✗
2
  normal << 1, 0, 0;
3301
2
  SET_LINE;
3302
✓✗
2
  testShapeIntersection(
3303
      s1, tf1, s2, tf2, true, NULL, NULL, &normal, false,
3304
      1e-2);  // built-in GJK solver requires larger tolerance than libccd
3305
3306
✓✗
2
  tf1 = transform;
3307
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(22.4, 0, 0));
3308
✓✗✓✗
✓✗
2
  normal = transform.getRotation() * Vec3f(1, 0, 0);
3309
2
  SET_LINE;
3310
✓✗
2
  testShapeIntersection(s1, tf1, s2, tf2, true, NULL, NULL, NULL);
3311
  // built-in GJK solver returns incorrect normal.
3312
  // testShapeIntersection(s1, tf1, s2, tf2, true, NULL, NULL, &normal);
3313
2
}
3314
3315
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗
4
BOOST_AUTO_TEST_CASE(shapeIntersectionGJK_spherecapsule) {
3316
✓✗
4
  Sphere s1(20);
3317
✓✗
4
  Capsule s2(5, 10);
3318
3319
✓✗
2
  Transform3f tf1;
3320
✓✗
2
  Transform3f tf2;
3321
3322
✓✗
2
  Transform3f transform;
3323
✓✗
2
  generateRandomTransform(extents, transform);
3324
3325
  // Vec3f point;
3326
  // FCL_REAL depth;
3327
✓✗
2
  Vec3f normal;
3328
3329
✓✗✓✗
2
  tf1 = Transform3f();
3330
✓✗✓✗
2
  tf2 = Transform3f();
3331
  // TODO: Need convention for normal when the centers of two objects are at
3332
  // same position.
3333
2
  SET_LINE;
3334
✓✗
2
  testShapeIntersection(s1, tf1, s2, tf2, true, NULL, NULL, NULL);
3335
3336
✓✗
2
  tf1 = transform;
3337
✓✗
2
  tf2 = transform;
3338
  // TODO: Need convention for normal when the centers of two objects are at
3339
  // same position.
3340
2
  SET_LINE;
3341
✓✗
2
  testShapeIntersection(s1, tf1, s2, tf2, true, NULL, NULL, NULL);
3342
3343
✓✗✓✗
2
  tf1 = Transform3f();
3344
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(24.9, 0, 0));
3345
✓✗✓✗
✓✗
2
  normal << 1, 0, 0;
3346
2
  SET_LINE;
3347
✓✗
2
  testShapeIntersection(s1, tf1, s2, tf2, true, NULL, NULL, &normal);
3348
3349
✓✗
2
  tf1 = transform;
3350
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(24.9, 0, 0));
3351
✓✗✓✗
✓✗
2
  normal = transform.getRotation() * Vec3f(1, 0, 0);
3352
2
  SET_LINE;
3353
✓✗
2
  testShapeIntersection(s1, tf1, s2, tf2, true, NULL, NULL, &normal);
3354
3355
✓✗✓✗
2
  tf1 = Transform3f();
3356
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(25, 0, 0));
3357
✓✗✓✗
✓✗
2
  normal << 1, 0, 0;
3358
2
  SET_LINE;
3359
✓✗
2
  testShapeIntersection(s1, tf1, s2, tf2, true, NULL, NULL, &normal);
3360
3361
✓✗
2
  tf1 = transform;
3362
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(25.1, 0, 0));
3363
✓✗✓✗
✓✗
2
  normal = transform.getRotation() * Vec3f(1, 0, 0);
3364
2
  SET_LINE;
3365
✓✗
2
  testShapeIntersection(s1, tf1, s2, tf2, false);
3366
2
}
3367
3368
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗
4
BOOST_AUTO_TEST_CASE(shapeIntersectionGJK_cylindercylinder) {
3369
✓✗
4
  Cylinder s1(5, 10);
3370
✓✗
4
  Cylinder s2(5, 10);
3371
3372
✓✗
2
  Transform3f tf1;
3373
✓✗
2
  Transform3f tf2;
3374
3375
✓✗
2
  Transform3f transform;
3376
✓✗
2
  generateRandomTransform(extents, transform);
3377
3378
  // Vec3f point;
3379
  // FCL_REAL depth;
3380
✓✗
2
  Vec3f normal;
3381
3382
✓✗✓✗
2
  tf1 = Transform3f();
3383
✓✗✓✗
2
  tf2 = Transform3f();
3384
  // TODO: Need convention for normal when the centers of two objects are at
3385
  // same position.
3386
2
  SET_LINE;
3387
✓✗
2
  testShapeIntersection(s1, tf1, s2, tf2, true, NULL, NULL, NULL);
3388
3389
✓✗
2
  tf1 = transform;
3390
✓✗
2
  tf2 = transform;
3391
  // TODO: Need convention for normal when the centers of two objects are at
3392
  // same position.
3393
2
  SET_LINE;
3394
✓✗
2
  testShapeIntersection(s1, tf1, s2, tf2, true, NULL, NULL, NULL);
3395
3396
✓✗✓✗
2
  tf1 = Transform3f();
3397
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(9.9, 0, 0));
3398
✓✗✓✗
✓✗
2
  normal << 1, 0, 0;
3399
2
  SET_LINE;
3400
✓✗
2
  testShapeIntersection(s1, tf1, s2, tf2, true, NULL, NULL, &normal, false,
3401
                        tol_gjk);
3402
3403
✓✗
2
  tf1 = transform;
3404
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(9.9, 0, 0));
3405
✓✗✓✗
✓✗
2
  normal = transform.getRotation() * Vec3f(1, 0, 0);
3406
2
  SET_LINE;
3407
✓✗
2
  testShapeIntersection(s1, tf1, s2, tf2, true);
3408
2
  SET_LINE;
3409
✓✗
2
  testShapeIntersection(s1, tf1, s2, tf2, true, NULL, NULL, &normal, false,
3410
                        tol_gjk);
3411
3412
✓✗✓✗
2
  tf1 = Transform3f();
3413
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(10, 0, 0));
3414
✓✗✓✗
✓✗
2
  normal << 1, 0, 0;
3415
2
  SET_LINE;
3416
✓✗
2
  testShapeIntersection(s1, tf1, s2, tf2, true, NULL, NULL, &normal, false,
3417
                        tol_gjk);
3418
3419
✓✗
2
  tf1 = transform;
3420
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(10.01, 0, 0));
3421
2
  SET_LINE;
3422
✓✗
2
  testShapeIntersection(s1, tf1, s2, tf2, false);
3423
2
}
3424
3425
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗
4
BOOST_AUTO_TEST_CASE(shapeIntersectionGJK_conecone) {
3426
✓✗
4
  Cone s1(5, 10);
3427
✓✗
4
  Cone s2(5, 10);
3428
3429
✓✗
2
  Transform3f tf1;
3430
✓✗
2
  Transform3f tf2;
3431
3432
✓✗
2
  Transform3f transform;
3433
✓✗
2
  generateRandomTransform(extents, transform);
3434
3435
  // Vec3f point;
3436
  // FCL_REAL depth;
3437
✓✗
2
  Vec3f normal;
3438
3439
✓✗✓✗
2
  tf1 = Transform3f();
3440
✓✗✓✗
2
  tf2 = Transform3f();
3441
  // TODO: Need convention for normal when the centers of two objects are at
3442
  // same position.
3443
2
  SET_LINE;
3444
✓✗
2
  testShapeIntersection(s1, tf1, s2, tf2, true, NULL, NULL, NULL);
3445
3446
✓✗
2
  tf1 = transform;
3447
✓✗
2
  tf2 = transform;
3448
  // TODO: Need convention for normal when the centers of two objects are at
3449
  // same position.
3450
2
  SET_LINE;
3451
✓✗
2
  testShapeIntersection(s1, tf1, s2, tf2, true, NULL, NULL, NULL);
3452
3453
✓✗✓✗
2
  tf1 = Transform3f();
3454
  // z=0 is a singular points. Two normals could be returned.
3455
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(9.9, 0, 0.00001));
3456
✓✗
2
  normal = Vec3f(2 * (s1.halfLength + s2.halfLength), 0, s1.radius + s2.radius)
3457
✓✗✓✗
2
               .normalized();
3458
2
  SET_LINE;
3459
✓✗
2
  testShapeIntersection(s1, tf1, s2, tf2, true, NULL, NULL, &normal, false,
3460
                        tol_gjk);
3461
3462
✓✗✓✗
2
  tf1 = transform * tf1;
3463
✓✗✓✗
2
  tf2 = transform * tf2;
3464
✓✗✓✗
2
  normal = transform.getRotation() * normal;
3465
2
  SET_LINE;
3466
✓✗
2
  testShapeIntersection(s1, tf1, s2, tf2, true, NULL, NULL, &normal, false,
3467
                        tol_gjk);
3468
3469
✓✗✓✗
2
  tf1 = Transform3f();
3470
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(10.1, 0, 0));
3471
2
  SET_LINE;
3472
✓✗
2
  testShapeIntersection(s1, tf1, s2, tf2, false);
3473
3474
✓✗
2
  tf1 = transform;
3475
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(10.1, 0, 0));
3476
2
  SET_LINE;
3477
✓✗
2
  testShapeIntersection(s1, tf1, s2, tf2, false);
3478
3479
✓✗✓✗
2
  tf1 = Transform3f();
3480
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(0, 0, 9.9));
3481
✓✗✓✗
✓✗
2
  normal << 0, 0, 1;
3482
2
  SET_LINE;
3483
✓✗
2
  testShapeIntersection(s1, tf1, s2, tf2, true, NULL, NULL, &normal, false,
3484
                        tol_gjk);
3485
3486
✓✗
2
  tf1 = transform;
3487
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(0, 0, 9.9));
3488
✓✗✓✗
✓✗
2
  normal = transform.getRotation() * Vec3f(0, 0, 1);
3489
2
  SET_LINE;
3490
✓✗
2
  testShapeIntersection(s1, tf1, s2, tf2, true, NULL, NULL, &normal, false,
3491
                        tol_gjk);
3492
2
}
3493
3494
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗
4
BOOST_AUTO_TEST_CASE(shapeIntersectionGJK_conecylinder) {
3495
✓✗
4
  Cylinder s1(5, 10);
3496
✓✗
4
  Cone s2(5, 10);
3497
3498
✓✗
2
  Transform3f tf1;
3499
✓✗
2
  Transform3f tf2;
3500
3501
✓✗
2
  Transform3f transform;
3502
✓✗
2
  generateRandomTransform(extents, transform);
3503
3504
  // Vec3f point;
3505
  // FCL_REAL depth;
3506
✓✗
2
  Vec3f normal;
3507
3508
✓✗✓✗
2
  tf1 = Transform3f();
3509
✓✗✓✗
2
  tf2 = Transform3f();
3510
  // TODO: Need convention for normal when the centers of two objects are at
3511
  // same position.
3512
2
  SET_LINE;
3513
✓✗
2
  testShapeIntersection(s1, tf1, s2, tf2, true, NULL, NULL, NULL);
3514
3515
✓✗
2
  tf1 = transform;
3516
✓✗
2
  tf2 = transform;
3517
  // TODO: Need convention for normal when the centers of two objects are at
3518
  // same position.
3519
2
  SET_LINE;
3520
✓✗
2
  testShapeIntersection(s1, tf1, s2, tf2, true, NULL, NULL, NULL);
3521
3522
✓✗✓✗
2
  tf1 = Transform3f();
3523
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(9.9, 0, 0));
3524
2
  SET_LINE;
3525
✓✗
2
  testShapeIntersection(s1, tf1, s2, tf2, true, NULL, NULL, NULL);
3526
3527
✓✗
2
  tf1 = transform;
3528
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(9.9, 0, 0));
3529
2
  SET_LINE;
3530
✓✗
2
  testShapeIntersection(s1, tf1, s2, tf2, true, NULL, NULL, NULL);
3531
3532
✓✗✓✗
2
  tf1 = Transform3f();
3533
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(10, 0, 0));
3534
2
  SET_LINE;
3535
✓✗
2
  testShapeIntersection(s1, tf1, s2, tf2, true, NULL, NULL, NULL);
3536
3537
✓✗
2
  tf1 = transform;
3538
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(10, 0, 0));
3539
2
  SET_LINE;
3540
✓✗
2
  testShapeIntersection(s1, tf1, s2, tf2, true, NULL, NULL, NULL);
3541
3542
✓✗✓✗
2
  tf1 = Transform3f();
3543
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(0, 0, 9.9));
3544
✓✗✓✗
✓✗
2
  normal << 0, 0, 1;
3545
2
  SET_LINE;
3546
✓✗
2
  testShapeIntersection(s1, tf1, s2, tf2, true, NULL, NULL, &normal, false,
3547
                        tol_gjk);
3548
3549
✓✗
2
  tf1 = transform;
3550
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(0, 0, 9.9));
3551
✓✗✓✗
✓✗
2
  normal = transform.getRotation() * Vec3f(0, 0, 1);
3552
2
  SET_LINE;
3553
✓✗
2
  testShapeIntersection(s1, tf1, s2, tf2, true, NULL, NULL, &normal, false,
3554
                        tol_gjk);
3555
3556
✓✗✓✗
2
  tf1 = Transform3f();
3557
✓✗✓✗
✓✗
2
  tf2 = Transform3f(Vec3f(0, 0, 10));
3558
✓✗✓✗
✓✗
2
  normal << 0, 0, 1;
3559
2
  SET_LINE;
3560
✓✗
2
  testShapeIntersection(s1, tf1, s2, tf2, true, NULL, NULL, &normal, false,
3561
                        tol_gjk);
3562
3563
✓✗
2
  tf1 = transform;
3564
✓✗✓✗
✓✗✓✗
2
  tf2 = transform * Transform3f(Vec3f(0, 0, 10.1));
3565
2
  SET_LINE;
3566
✓✗
2
  testShapeIntersection(s1, tf1, s2, tf2, false);
3567
2
}
3568
3569
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗
4
BOOST_AUTO_TEST_CASE(shapeIntersectionGJK_spheretriangle) {
3570
✓✗
4
  Sphere s(10);
3571
✓✓✓✗
8
  Vec3f t[3];
3572
✓✗✓✗
✓✗
2
  t[0] << 20, 0, 0;
3573
✓✗✓✗
✓✗
2
  t[1] << -20, 0, 0;
3574
✓✗✓✗
✓✗
2
  t[2] << 0, 20, 0;
3575
3576
✓✗
2
  Transform3f transform;
3577
✓✗
2
  generateRandomTransform(extents, transform);
3578
3579
✓✗✓✗
2
  Vec3f c1, c2;
3580
  FCL_REAL distance;
3581
✓✗
2
  Vec3f normal;
3582
  bool res;
3583
3584
  res =
3585
✓✗✓✗
2
      solver2.shapeTriangleInteraction(s, Transform3f(), t[0], t[1], t[2],
3586
✓✗
4
                                       Transform3f(), distance, c1, c2, normal);
3587
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(res);
3588
3589
✓✗
2
  res = solver2.shapeTriangleInteraction(s, transform, t[0], t[1], t[2],
3590
                                         transform, distance, c1, c2, normal);
3591
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(res);
3592
3593
✓✗✓✗
✓✗
2
  t[0] << 30, 0, 0;
3594
✓✗✓✗
✓✗
2
  t[1] << 9.9, -20, 0;
3595
✓✗✓✗
✓✗
2
  t[2] << 9.9, 20, 0;
3596
  res =
3597
✓✗✓✗
2
      solver2.shapeTriangleInteraction(s, Transform3f(), t[0], t[1], t[2],
3598
✓✗
4
                                       Transform3f(), distance, c1, c2, normal);
3599
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(res);
3600
3601
✓✗
2
  res = solver2.shapeTriangleInteraction(s, transform, t[0], t[1], t[2],
3602
                                         transform, distance, c1, c2, normal);
3603
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(res);
3604
3605
  res =
3606
✓✗✓✗
2
      solver2.shapeTriangleInteraction(s, Transform3f(), t[0], t[1], t[2],
3607
✓✗
4
                                       Transform3f(), distance, c1, c2, normal);
3608
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(res);
3609
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(isEqual(normal, Vec3f(1, 0, 0), 1e-9));
3610
3611
✓✗
2
  res = solver2.shapeTriangleInteraction(s, transform, t[0], t[1], t[2],
3612
                                         transform, distance, c1, c2, normal);
3613
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(res);
3614
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✗✓
2
  BOOST_CHECK(isEqual(normal, transform.getRotation() * Vec3f(1, 0, 0), 1e-9));
3615
2
}
3616
3617
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗
4
BOOST_AUTO_TEST_CASE(shapeIntersectionGJK_halfspacetriangle) {
3618
✓✗✓✗
4
  Halfspace hs(Vec3f(1, 0, 0), 0);
3619
✓✓✓✗
8
  Vec3f t[3];
3620
✓✗✓✗
✓✗
2
  t[0] << 20, 0, 0;
3621
✓✗✓✗
✓✗
2
  t[1] << -20, 0, 0;
3622
✓✗✓✗
✓✗
2
  t[2] << 0, 20, 0;
3623
3624
✓✗
2
  Transform3f transform;
3625
✓✗
2
  generateRandomTransform(extents, transform);
3626
3627
✓✗✓✗
2
  Vec3f c1, c2;
3628
  FCL_REAL distance;
3629
✓✗
2
  Vec3f normal;
3630
  bool res;
3631
3632
  res =
3633
✓✗✓✗
2
      solver2.shapeTriangleInteraction(hs, Transform3f(), t[0], t[1], t[2],
3634
✓✗
4
                                       Transform3f(), distance, c1, c2, normal);
3635
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(res);
3636
3637
✓✗
2
  res = solver2.shapeTriangleInteraction(hs, transform, t[0], t[1], t[2],
3638
                                         transform, distance, c1, c2, normal);
3639
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(res);
3640
3641
✓✗✓✗
✓✗
2
  t[0] << 20, 0, 0;
3642
✓✗✓✗
✓✗
2
  t[1] << 0, -20, 0;
3643
✓✗✓✗
✓✗
2
  t[2] << 0, 20, 0;
3644
  res =
3645
✓✗✓✗
2
      solver2.shapeTriangleInteraction(hs, Transform3f(), t[0], t[1], t[2],
3646
✓✗
4
                                       Transform3f(), distance, c1, c2, normal);
3647
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(res);
3648
3649
✓✗
2
  res = solver2.shapeTriangleInteraction(hs, transform, t[0], t[1], t[2],
3650
                                         transform, distance, c1, c2, normal);
3651
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(res);
3652
3653
  res =
3654
✓✗✓✗
2
      solver2.shapeTriangleInteraction(hs, Transform3f(), t[0], t[1], t[2],
3655
✓✗
4
                                       Transform3f(), distance, c1, c2, normal);
3656
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(res);
3657
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(isEqual(normal, Vec3f(1, 0, 0), 1e-9));
3658
3659
✓✗
2
  res = solver2.shapeTriangleInteraction(hs, transform, t[0], t[1], t[2],
3660
                                         transform, distance, c1, c2, normal);
3661
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(res);
3662
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✗✓
2
  BOOST_CHECK(isEqual(normal, transform.getRotation() * Vec3f(1, 0, 0), 1e-9));
3663
2
}
3664
3665
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗
4
BOOST_AUTO_TEST_CASE(shapeIntersectionGJK_planetriangle) {
3666
✓✗✓✗
4
  Plane hs(Vec3f(1, 0, 0), 0);
3667
✓✓✓✗
8
  Vec3f t[3];
3668
✓✗✓✗
✓✗
2
  t[0] << 20, 0, 0;
3669
✓✗✓✗
✓✗
2
  t[1] << -20, 0, 0;
3670
✓✗✓✗
✓✗
2
  t[2] << 0, 20, 0;
3671
3672
✓✗
2
  Transform3f transform;
3673
✓✗
2
  generateRandomTransform(extents, transform);
3674
3675
✓✗✓✗
2
  Vec3f c1, c2;
3676
  FCL_REAL distance;
3677
✓✗
2
  Vec3f normal;
3678
  bool res;
3679
3680
  res =
3681
✓✗✓✗
2
      solver1.shapeTriangleInteraction(hs, Transform3f(), t[0], t[1], t[2],
3682
✓✗
4
                                       Transform3f(), distance, c1, c2, normal);
3683
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(res);
3684
3685
✓✗
2
  res = solver1.shapeTriangleInteraction(hs, transform, t[0], t[1], t[2],
3686
                                         transform, distance, c1, c2, normal);
3687
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(res);
3688
3689
✓✗✓✗
✓✗
2
  t[0] << 20, 0, 0;
3690
✓✗✓✗
✓✗
2
  t[1] << -0.1, -20, 0;
3691
✓✗✓✗
✓✗
2
  t[2] << -0.1, 20, 0;
3692
  res =
3693
✓✗✓✗
2
      solver2.shapeTriangleInteraction(hs, Transform3f(), t[0], t[1], t[2],
3694
✓✗
4
                                       Transform3f(), distance, c1, c2, normal);
3695
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(res);
3696
3697
✓✗
2
  res = solver2.shapeTriangleInteraction(hs, transform, t[0], t[1], t[2],
3698
                                         transform, distance, c1, c2, normal);
3699
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(res);
3700
3701
  res =
3702
✓✗✓✗
2
      solver2.shapeTriangleInteraction(hs, Transform3f(), t[0], t[1], t[2],
3703
✓✗
4
                                       Transform3f(), distance, c1, c2, normal);
3704
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(res);
3705
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(isEqual(normal, Vec3f(1, 0, 0), 1e-9));
3706
3707
✓✗
2
  res = solver2.shapeTriangleInteraction(hs, transform, t[0], t[1], t[2],
3708
                                         transform, distance, c1, c2, normal);
3709
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(res);
3710
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✗✓
2
  BOOST_CHECK(isEqual(normal, transform.getRotation() * Vec3f(1, 0, 0), 1e-9));
3711
2
}
3712
3713
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗
4
BOOST_AUTO_TEST_CASE(spheresphere) {
3714
✓✗
4
  Sphere s1(20);
3715
✓✗
4
  Sphere s2(10);
3716
✓✗✓✗
✓✗
2
  Vec3f closest_p1, closest_p2, normal;
3717
3718
✓✗
2
  Transform3f transform;
3719
✓✗
2
  generateRandomTransform(extents, transform);
3720
3721
  bool res;
3722
2
  FCL_REAL dist = -1;
3723
3724
  res =
3725
✓✗✓✗
✓✗✓✗
2
      solver2.shapeDistance(s1, Transform3f(), s2, Transform3f(Vec3f(40, 0, 0)),
3726
                            dist, closest_p1, closest_p2, normal);
3727
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(fabs(dist - 10) < 0.001);
3728
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(res);
3729
3730
✓✗✓✗
2
  res = solver2.shapeDistance(s1, Transform3f(), s2,
3731
✓✗✓✗
4
                              Transform3f(Vec3f(30.1, 0, 0)), dist, closest_p1,
3732
                              closest_p2, normal);
3733
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(fabs(dist - 0.1) < 0.001);
3734
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(res);
3735
3736
✓✗✓✗
2
  res = solver2.shapeDistance(s1, Transform3f(), s2,
3737
✓✗✓✗
4
                              Transform3f(Vec3f(29.9, 0, 0)), dist, closest_p1,
3738
                              closest_p2, normal);
3739
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(dist <= 0);
3740
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK_FALSE(res);
3741
3742
  res =
3743
✓✗✓✗
✓✗✓✗
2
      solver2.shapeDistance(s1, Transform3f(Vec3f(40, 0, 0)), s2, Transform3f(),
3744
                            dist, closest_p1, closest_p2, normal);
3745
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(fabs(dist - 10) < 0.001);
3746
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(res);
3747
3748
✓✗✓✗
✓✗
2
  res = solver2.shapeDistance(s1, Transform3f(Vec3f(30.1, 0, 0)), s2,
3749
✓✗
4
                              Transform3f(), dist, closest_p1, closest_p2,
3750
                              normal);
3751
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(fabs(dist - 0.1) < 0.001);
3752
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(res);
3753
3754
✓✗✓✗
✓✗
2
  res = solver2.shapeDistance(s1, Transform3f(Vec3f(29.9, 0, 0)), s2,
3755
✓✗
4
                              Transform3f(), dist, closest_p1, closest_p2,
3756
                              normal);
3757
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(dist <= 0);
3758
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK_FALSE(res);
3759
3760
✓✗
2
  res = solver2.shapeDistance(s1, transform, s2,
3761
✓✗✓✗
✓✗
4
                              transform * Transform3f(Vec3f(40, 0, 0)), dist,
3762
                              closest_p1, closest_p2, normal);
3763
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(fabs(dist - 10) < 0.001);
3764
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(res);
3765
3766
✓✗
2
  res = solver2.shapeDistance(s1, transform, s2,
3767
✓✗✓✗
✓✗
4
                              transform * Transform3f(Vec3f(30.1, 0, 0)), dist,
3768
                              closest_p1, closest_p2, normal);
3769
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(fabs(dist - 0.1) < 0.001);
3770
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(res);
3771
3772
✓✗
2
  res = solver2.shapeDistance(s1, transform, s2,
3773
✓✗✓✗
✓✗
4
                              transform * Transform3f(Vec3f(29.9, 0, 0)), dist,
3774
                              closest_p1, closest_p2, normal);
3775
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(dist <= 0);
3776
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK_FALSE(res);
3777
3778
✓✗✓✗
✓✗✓✗
2
  res = solver2.shapeDistance(s1, transform * Transform3f(Vec3f(40, 0, 0)), s2,
3779
                              transform, dist, closest_p1, closest_p2, normal);
3780
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(fabs(dist - 10) < 0.001);
3781
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(res);
3782
3783
  res =
3784
✓✗✓✗
✓✗✓✗
2
      solver2.shapeDistance(s1, transform * Transform3f(Vec3f(30.1, 0, 0)), s2,
3785
                            transform, dist, closest_p1, closest_p2, normal);
3786
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(fabs(dist - 0.1) < 0.001);
3787
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(res);
3788
3789
  res =
3790
✓✗✓✗
✓✗✓✗
2
      solver2.shapeDistance(s1, transform * Transform3f(Vec3f(29.9, 0, 0)), s2,
3791
                            transform, dist, closest_p1, closest_p2, normal);
3792
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(dist <= 0);
3793
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK_FALSE(res);
3794
2
}
3795
3796
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗
4
BOOST_AUTO_TEST_CASE(boxbox) {
3797
✓✗
4
  Box s1(20, 40, 50);
3798
✓✗
4
  Box s2(10, 10, 10);
3799
✓✗✓✗
✓✗
2
  Vec3f closest_p1, closest_p2, normal;
3800
3801
✓✗
2
  Transform3f transform;
3802
✓✗
2
  generateRandomTransform(extents, transform);
3803
3804
  bool res;
3805
  FCL_REAL dist;
3806
3807
✓✗✓✗
✓✗
2
  res = solver2.shapeDistance(s1, Transform3f(), s2, Transform3f(), dist,
3808
                              closest_p1, closest_p2, normal);
3809
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(dist <= 0);
3810
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK_FALSE(res);
3811
3812
✓✗
2
  res = solver2.shapeDistance(s1, transform, s2, transform, dist, closest_p1,
3813
                              closest_p2, normal);
3814
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(dist <= 0);
3815
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK_FALSE(res);
3816
3817
✓✗✓✗
2
  res = solver2.shapeDistance(s1, Transform3f(), s2,
3818
✓✗✓✗
4
                              Transform3f(Vec3f(15.1, 0, 0)), dist, closest_p1,
3819
                              closest_p2, normal);
3820
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(fabs(dist - 0.1) < 0.001);
3821
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(res);
3822
3823
✓✗
2
  res = solver2.shapeDistance(s1, transform, s2,
3824
✓✗✓✗
✓✗
4
                              transform * Transform3f(Vec3f(15.1, 0, 0)), dist,
3825
                              closest_p1, closest_p2, normal);
3826
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(fabs(dist - 0.1) < 0.001);
3827
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(res);
3828
3829
  res =
3830
✓✗✓✗
✓✗✓✗
2
      solver2.shapeDistance(s1, Transform3f(), s2, Transform3f(Vec3f(20, 0, 0)),
3831
                            dist, closest_p1, closest_p2, normal);
3832
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(fabs(dist - 5) < 0.001);
3833
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(res);
3834
3835
✓✗
2
  res = solver2.shapeDistance(s1, transform, s2,
3836
✓✗✓✗
✓✗
4
                              transform * Transform3f(Vec3f(20, 0, 0)), dist,
3837
                              closest_p1, closest_p2, normal);
3838
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(fabs(dist - 5) < 0.001);
3839
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(res);
3840
2
}
3841
3842
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗
4
BOOST_AUTO_TEST_CASE(boxsphere) {
3843
✓✗
4
  Sphere s1(20);
3844
✓✗
4
  Box s2(5, 5, 5);
3845
✓✗✓✗
✓✗
2
  Vec3f closest_p1, closest_p2, normal;
3846
3847
✓✗
2
  Transform3f transform;
3848
✓✗
2
  generateRandomTransform(extents, transform);
3849
3850
  bool res;
3851
  FCL_REAL dist;
3852
3853
✓✗✓✗
✓✗
2
  res = solver2.shapeDistance(s1, Transform3f(), s2, Transform3f(), dist,
3854
                              closest_p1, closest_p2, normal);
3855
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(dist <= 0);
3856
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK_FALSE(res);
3857
3858
✓✗
2
  res = solver2.shapeDistance(s1, transform, s2, transform, dist, closest_p1,
3859
                              closest_p2, normal);
3860
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(dist <= 0);
3861
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK_FALSE(res);
3862
3863
✓✗✓✗
2
  res = solver2.shapeDistance(s1, Transform3f(), s2,
3864
✓✗✓✗
4
                              Transform3f(Vec3f(22.6, 0, 0)), dist, closest_p1,
3865
                              closest_p2, normal);
3866
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(fabs(dist - 0.1) < 0.01);
3867
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(res);
3868
3869
✓✗
2
  res = solver2.shapeDistance(s1, transform, s2,
3870
✓✗✓✗
✓✗
4
                              transform * Transform3f(Vec3f(22.6, 0, 0)), dist,
3871
                              closest_p1, closest_p2, normal);
3872
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(fabs(dist - 0.1) < 0.01);
3873
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(res);
3874
3875
  res =
3876
✓✗✓✗
✓✗✓✗
2
      solver2.shapeDistance(s1, Transform3f(), s2, Transform3f(Vec3f(40, 0, 0)),
3877
                            dist, closest_p1, closest_p2, normal);
3878
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(fabs(dist - 17.5) < 0.001);
3879
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(res);
3880
3881
✓✗
2
  res = solver2.shapeDistance(s1, transform, s2,
3882
✓✗✓✗
✓✗
4
                              transform * Transform3f(Vec3f(40, 0, 0)), dist,
3883
                              closest_p1, closest_p2, normal);
3884
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(fabs(dist - 17.5) < 0.001);
3885
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(res);
3886
2
}
3887
3888
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗
4
BOOST_AUTO_TEST_CASE(cylindercylinder) {
3889
✓✗
4
  Cylinder s1(5, 10);
3890
✓✗
4
  Cylinder s2(5, 10);
3891
✓✗✓✗
✓✗
2
  Vec3f closest_p1, closest_p2, normal;
3892
3893
✓✗
2
  Transform3f transform;
3894
✓✗
2
  generateRandomTransform(extents, transform);
3895
3896
  bool res;
3897
  FCL_REAL dist;
3898
3899
✓✗✓✗
✓✗
2
  res = solver2.shapeDistance(s1, Transform3f(), s2, Transform3f(), dist,
3900
                              closest_p1, closest_p2, normal);
3901
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(dist <= 0);
3902
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK_FALSE(res);
3903
3904
✓✗
2
  res = solver2.shapeDistance(s1, transform, s2, transform, dist, closest_p1,
3905
                              closest_p2, normal);
3906
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(dist <= 0);
3907
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK_FALSE(res);
3908
3909
✓✗✓✗
2
  res = solver2.shapeDistance(s1, Transform3f(), s2,
3910
✓✗✓✗
4
                              Transform3f(Vec3f(10.1, 0, 0)), dist, closest_p1,
3911
                              closest_p2, normal);
3912
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(fabs(dist - 0.1) < 0.001);
3913
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(res);
3914
3915
✓✗
2
  res = solver2.shapeDistance(s1, transform, s2,
3916
✓✗✓✗
✓✗
4
                              transform * Transform3f(Vec3f(10.1, 0, 0)), dist,
3917
                              closest_p1, closest_p2, normal);
3918
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(fabs(dist - 0.1) < 0.001);
3919
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(res);
3920
3921
  res =
3922
✓✗✓✗
✓✗✓✗
2
      solver2.shapeDistance(s1, Transform3f(), s2, Transform3f(Vec3f(40, 0, 0)),
3923
                            dist, closest_p1, closest_p2, normal);
3924
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(fabs(dist - 30) < 0.001);
3925
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(res);
3926
3927
✓✗
2
  res = solver2.shapeDistance(s1, transform, s2,
3928
✓✗✓✗
✓✗
4
                              transform * Transform3f(Vec3f(40, 0, 0)), dist,
3929
                              closest_p1, closest_p2, normal);
3930
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(fabs(dist - 30) < 0.001);
3931
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(res);
3932
2
}
3933
3934
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗
4
BOOST_AUTO_TEST_CASE(conecone) {
3935
✓✗
4
  Cone s1(5, 10);
3936
✓✗
4
  Cone s2(5, 10);
3937
✓✗✓✗
✓✗
2
  Vec3f closest_p1, closest_p2, normal;
3938
3939
✓✗
2
  Transform3f transform;
3940
✓✗
2
  generateRandomTransform(extents, transform);
3941
3942
  bool res;
3943
  FCL_REAL dist;
3944
3945
✓✗✓✗
✓✗
2
  res = solver2.shapeDistance(s1, Transform3f(), s2, Transform3f(), dist,
3946
                              closest_p1, closest_p2, normal);
3947
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(dist <= 0);
3948
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK_FALSE(res);
3949
3950
✓✗
2
  res = solver2.shapeDistance(s1, transform, s2, transform, dist, closest_p1,
3951
                              closest_p2, normal);
3952
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(dist <= 0);
3953
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK_FALSE(res);
3954
3955
✓✗✓✗
2
  res = solver2.shapeDistance(s1, Transform3f(), s2,
3956
✓✗✓✗
4
                              Transform3f(Vec3f(10.1, 0, 0)), dist, closest_p1,
3957
                              closest_p2, normal);
3958
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(fabs(dist - 0.1) < 0.001);
3959
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(res);
3960
3961
✓✗
2
  res = solver2.shapeDistance(s1, transform, s2,
3962
✓✗✓✗
✓✗
4
                              transform * Transform3f(Vec3f(10.1, 0, 0)), dist,
3963
                              closest_p1, closest_p2, normal);
3964
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(fabs(dist - 0.1) < 0.001);
3965
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(res);
3966
3967
  res =
3968
✓✗✓✗
✓✗✓✗
2
      solver2.shapeDistance(s1, Transform3f(), s2, Transform3f(Vec3f(0, 0, 40)),
3969
                            dist, closest_p1, closest_p2, normal);
3970
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(fabs(dist - 30) < 0.001);
3971
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(res);
3972
3973
✓✗
2
  res = solver2.shapeDistance(s1, transform, s2,
3974
✓✗✓✗
✓✗
4
                              transform * Transform3f(Vec3f(0, 0, 40)), dist,
3975
                              closest_p1, closest_p2, normal);
3976
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(fabs(dist - 30) < 0.001);
3977
✓✗✓✗
✓✗✓✗
✓✗✗✓
2
  BOOST_CHECK(res);
3978
2
}
3979
3980
template <typename S1, typename S2>
3981
1
void testReversibleShapeDistance(const S1& s1, const S2& s2,
3982
                                 FCL_REAL distance) {
3983
✓✗✓✗
1
  Transform3f tf1(Vec3f(-0.5 * distance, 0.0, 0.0));
3984
✓✗✓✗
1
  Transform3f tf2(Vec3f(+0.5 * distance, 0.0, 0.0));
3985
3986
  FCL_REAL distA;
3987
  FCL_REAL distB;
3988
✓✗
1
  Vec3f p1A;
3989
✓✗
1
  Vec3f p1B;
3990
✓✗
1
  Vec3f p2A;
3991
✓✗
1
  Vec3f p2B;
3992
✓✗✓✗
1
  Vec3f normalA, normalB;
3993
3994
  bool resA;
3995
  bool resB;
3996
3997
1
  const double tol = 1e-6;
3998
3999
✓✗
1
  resA = solver1.shapeDistance(s1, tf1, s2, tf2, distA, p1A, p2A, normalA);
4000
✓✗
1
  resB = solver1.shapeDistance(s2, tf2, s1, tf1, distB, p1B, p2B, normalB);
4001
4002
✓✗✓✗
✓✗✓✗
✓✗✗✓
1
  BOOST_CHECK(resA);
4003
✓✗✓✗
✓✗✓✗
✓✗✗✓
1
  BOOST_CHECK(resB);
4004
✓✗✓✗
✓✗✓✗
✓✗✗✓
1
  BOOST_CHECK_CLOSE(distA, distB, tol);  // distances should be same
4005
✓✗✓✗
✓✗✓✗
✓✗✓✗
✗✓
1
  BOOST_CHECK(
4006
      isEqual(p1A, p2B, tol));  // closest points should in reverse order
4007
✓✗✓✗
✓✗✓✗
✓✗✓✗
✗✓
1
  BOOST_CHECK(isEqual(p2A, p1B, tol));
4008
4009
✓✗
1
  resA = solver2.shapeDistance(s1, tf1, s2, tf2, distA, p1A, p2A, normalA);
4010
✓✗
1
  resB = solver2.shapeDistance(s2, tf2, s1, tf1, distB, p1B, p2B, normalB);
4011
4012
✓✗✓✗
✓✗✓✗
✓✗✗✓
1
  BOOST_CHECK(resA);
4013
✓✗✓✗
✓✗✓✗
✓✗✗✓
1
  BOOST_CHECK(resB);
4014
✓✗✓✗
✓✗✓✗
✓✗✗✓
1
  BOOST_CHECK_CLOSE(distA, distB, tol);
4015
✓✗✓✗
✓✗✓✗
✓✗✓✗
✗✓
1
  BOOST_CHECK(isEqual(p1A, p2B, tol));
4016
✓✗✓✗
✓✗✓✗
✓✗✓✗
✗✓
1
  BOOST_CHECK(isEqual(p2A, p1B, tol));
4017
1
}
4018
4019
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗✓✗
✓✗
4
BOOST_AUTO_TEST_CASE(reversibleShapeDistance_allshapes) {
4020
  // This test check whether a shape distance algorithm is called for the
4021
  // reverse case as well. For example, if FCL has sphere-capsule distance
4022
  // algorithm, then this algorithm should be called for capsule-sphere case.
4023
4024
  // Prepare all kinds of primitive shapes (7) -- box, sphere, capsule, cone,
4025
  // cylinder, plane, halfspace
4026
✓✗
4
  Box box(10, 10, 10);
4027
✓✗
4
  Sphere sphere(5);
4028
✓✗
4
  Capsule capsule(5, 10);
4029
✓✗
4
  Cone cone(5, 10);
4030
✓✗
4
  Cylinder cylinder(5, 10);
4031
✓✗✓✗
4
  Plane plane(Vec3f(0, 0, 0), 0.0);
4032
✓✗✓✗
4
  Halfspace halfspace(Vec3f(0, 0, 0), 0.0);
4033
4034
  // Use sufficiently long distance so that all the primitive shapes CANNOT
4035
  // intersect
4036
2
  FCL_REAL distance = 15.0;
4037
4038
  // If new shape distance algorithm is added for two distinct primitive
4039
  // shapes, uncomment associated lines. For example, box-sphere intersection
4040
  // algorithm is added, then uncomment box-sphere.
4041
4042
  //  testReversibleShapeDistance(box, sphere, distance);
4043
  //  testReversibleShapeDistance(box, capsule, distance);
4044
  //  testReversibleShapeDistance(box, cone, distance);
4045
  //  testReversibleShapeDistance(box, cylinder, distance);
4046
  //  testReversibleShapeDistance(box, plane, distance);
4047
  //  testReversibleShapeDistance(box, halfspace, distance);
4048
4049
2
  SET_LINE;
4050
✓✗
2
  testReversibleShapeDistance(sphere, capsule, distance);
4051
  //  testReversibleShapeDistance(sphere, cone, distance);
4052
  //  testReversibleShapeDistance(sphere, cylinder, distance);
4053
  //  testReversibleShapeDistance(sphere, plane, distance);
4054
  //  testReversibleShapeDistance(sphere, halfspace, distance);
4055
4056
  //  testReversibleShapeDistance(capsule, cone, distance);
4057
  //  testReversibleShapeDistance(capsule, cylinder, distance);
4058
  //  testReversibleShapeDistance(capsule, plane, distance);
4059
  //  testReversibleShapeDistance(capsule, halfspace, distance);
4060
4061
  //  testReversibleShapeDistance(cone, cylinder, distance);
4062
  //  testReversibleShapeDistance(cone, plane, distance);
4063
  //  testReversibleShapeDistance(cone, halfspace, distance);
4064
4065
  //  testReversibleShapeDistance(cylinder, plane, distance);
4066
  //  testReversibleShapeDistance(cylinder, halfspace, distance);
4067
4068
  //  testReversibleShapeDistance(plane, halfspace, distance);
4069
2
}