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
}