GCC Code Coverage Report


Directory: ./
File: include/coal/internal/traversal_node_bvhs.h
Date: 2025-04-01 09:23:31
Exec Total Coverage
Lines: 179 184 97.3%
Branches: 76 124 61.3%

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 #ifndef COAL_TRAVERSAL_NODE_MESHES_H
39 #define COAL_TRAVERSAL_NODE_MESHES_H
40
41 /// @cond INTERNAL
42
43 #include "coal/collision_data.h"
44 #include "coal/internal/traversal_node_base.h"
45 #include "coal/BV/BV_node.h"
46 #include "coal/BV/BV.h"
47 #include "coal/BVH/BVH_model.h"
48 #include "coal/internal/intersect.h"
49 #include "coal/shape/geometric_shapes.h"
50 #include "coal/narrowphase/narrowphase.h"
51 #include "coal/internal/traversal.h"
52 #include "coal/internal/shape_shape_func.h"
53
54 #include <cassert>
55
56 namespace coal {
57
58 /// @addtogroup Traversal_For_Collision
59 /// @{
60
61 /// @brief Traversal node for collision between BVH models
62 template <typename BV>
63 class BVHCollisionTraversalNode : public CollisionTraversalNodeBase {
64 public:
65 21595 BVHCollisionTraversalNode(const CollisionRequest& request)
66 21595 : CollisionTraversalNodeBase(request) {
67 21595 model1 = NULL;
68 21595 model2 = NULL;
69
70 21595 num_bv_tests = 0;
71 21595 num_leaf_tests = 0;
72 21595 query_time_seconds = 0.0;
73 21595 }
74
75 /// @brief Whether the BV node in the first BVH tree is leaf
76 116998931 bool isFirstNodeLeaf(unsigned int b) const {
77
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 58499498 times.
116998931 assert(model1 != NULL && "model1 is NULL");
78 116998931 return model1->getBV(b).isLeaf();
79 }
80
81 /// @brief Whether the BV node in the second BVH tree is leaf
82 116998931 bool isSecondNodeLeaf(unsigned int b) const {
83
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 58499498 times.
116998931 assert(model2 != NULL && "model2 is NULL");
84 116998931 return model2->getBV(b).isLeaf();
85 }
86
87 /// @brief Determine the traversal order, is the first BVTT subtree better
88 41583777 bool firstOverSecond(unsigned int b1, unsigned int b2) const {
89 41583777 Scalar sz1 = model1->getBV(b1).bv.size();
90 41583777 Scalar sz2 = model2->getBV(b2).bv.size();
91
92 41583777 bool l1 = model1->getBV(b1).isLeaf();
93 41583777 bool l2 = model2->getBV(b2).isLeaf();
94
95
6/6
✓ Branch 0 taken 9579863 times.
✓ Branch 1 taken 11212045 times.
✓ Branch 2 taken 3851809 times.
✓ Branch 3 taken 5728054 times.
✓ Branch 4 taken 1543658 times.
✓ Branch 5 taken 2308151 times.
41583777 if (l2 || (!l1 && (sz1 > sz2))) return true;
96 16072382 return false;
97 }
98
99 /// @brief Obtain the left child of BV node in the first BVH
100 25511395 int getFirstLeftChild(unsigned int b) const {
101 25511395 return model1->getBV(b).leftChild();
102 }
103
104 /// @brief Obtain the right child of BV node in the first BVH
105 25511395 int getFirstRightChild(unsigned int b) const {
106 25511395 return model1->getBV(b).rightChild();
107 }
108
109 /// @brief Obtain the left child of BV node in the second BVH
110 16072382 int getSecondLeftChild(unsigned int b) const {
111 16072382 return model2->getBV(b).leftChild();
112 }
113
114 /// @brief Obtain the right child of BV node in the second BVH
115 16072382 int getSecondRightChild(unsigned int b) const {
116 16072382 return model2->getBV(b).rightChild();
117 }
118
119 /// @brief The first BVH model
120 const BVHModel<BV>* model1;
121 /// @brief The second BVH model
122 const BVHModel<BV>* model2;
123
124 /// @brief statistical information
125 mutable int num_bv_tests;
126 mutable int num_leaf_tests;
127 mutable Scalar query_time_seconds;
128 };
129
130 /// @brief Traversal node for collision between two meshes
131 template <typename BV, int _Options = RelativeTransformationIsIdentity>
132 class MeshCollisionTraversalNode : public BVHCollisionTraversalNode<BV> {
133 public:
134 enum {
135 Options = _Options,
136 RTIsIdentity = _Options & RelativeTransformationIsIdentity
137 };
138
139 21595 MeshCollisionTraversalNode(const CollisionRequest& request)
140
1/2
✓ Branch 2 taken 10697 times.
✗ Branch 3 not taken.
21595 : BVHCollisionTraversalNode<BV>(request) {
141 21595 vertices1 = NULL;
142 21595 vertices2 = NULL;
143 21595 tri_indices1 = NULL;
144 21595 tri_indices2 = NULL;
145 21595 }
146
147 /// BV test between b1 and b2
148 /// @param b1, b2 Bounding volumes to test,
149 /// @retval sqrDistLowerBound square of a lower bound of the minimal
150 /// distance between bounding volumes.
151 41745725 bool BVDisjoints(unsigned int b1, unsigned int b2,
152 Scalar& sqrDistLowerBound) const {
153
2/2
✓ Branch 0 taken 3869604 times.
✓ Branch 1 taken 17003287 times.
41745725 if (this->enable_statistics) this->num_bv_tests++;
154 bool disjoint;
155 if (RTIsIdentity)
156 83175980 disjoint = !this->model1->getBV(b1).overlap(
157 41587990 this->model2->getBV(b2), this->request, sqrDistLowerBound);
158 else {
159 157735 disjoint = !overlap(RT._R(), RT._T(), this->model2->getBV(b2).bv,
160 157735 this->model1->getBV(b1).bv, this->request,
161 sqrDistLowerBound);
162 }
163
2/2
✓ Branch 0 taken 80983 times.
✓ Branch 1 taken 20791908 times.
41745725 if (disjoint)
164 161948 internal::updateDistanceLowerBoundFromBV(this->request, *this->result,
165 sqrDistLowerBound);
166 41745725 return disjoint;
167 }
168
169 /// Intersection testing between leaves (two triangles)
170 ///
171 /// @param b1, b2 id of primitive in bounding volume hierarchy
172 /// @retval sqrDistLowerBound squared lower bound of distance between
173 /// primitives if they are not in collision.
174 ///
175 /// This method supports a security margin. If the distance between
176 /// the primitives is less than the security margin, the objects are
177 /// considered as in collision. in this case a contact point is
178 /// returned in the CollisionResult.
179 ///
180 /// @note If the distance between objects is less than the security margin,
181 /// and the object are not colliding, the penetration depth is
182 /// negative.
183 58359872 void leafCollides(unsigned int b1, unsigned int b2,
184 Scalar& sqrDistLowerBound) const {
185
2/2
✓ Branch 0 taken 3846921 times.
✓ Branch 1 taken 25333019 times.
58359872 if (this->enable_statistics) this->num_leaf_tests++;
186
187 58359872 const BVNode<BV>& node1 = this->model1->getBV(b1);
188 58359872 const BVNode<BV>& node2 = this->model2->getBV(b2);
189
190 58359872 int primitive_id1 = node1.primitiveId();
191 58359872 int primitive_id2 = node2.primitiveId();
192
193 58359872 const Triangle& tri_id1 = tri_indices1[primitive_id1];
194 58359872 const Triangle& tri_id2 = tri_indices2[primitive_id2];
195
196 58359872 const Vec3s& P1 = vertices1[tri_id1[0]];
197 58359872 const Vec3s& P2 = vertices1[tri_id1[1]];
198 58359872 const Vec3s& P3 = vertices1[tri_id1[2]];
199 58359872 const Vec3s& Q1 = vertices2[tri_id2[0]];
200 58359872 const Vec3s& Q2 = vertices2[tri_id2[1]];
201 58359872 const Vec3s& Q3 = vertices2[tri_id2[2]];
202
203
1/2
✓ Branch 1 taken 29179940 times.
✗ Branch 2 not taken.
58359872 TriangleP tri1(P1, P2, P3);
204
1/2
✓ Branch 1 taken 29179940 times.
✗ Branch 2 not taken.
58359872 TriangleP tri2(Q1, Q2, Q3);
205
206 // TODO(louis): MeshCollisionTraversalNode should have its own GJKSolver.
207
1/2
✓ Branch 1 taken 29179940 times.
✗ Branch 2 not taken.
58359872 GJKSolver solver(this->request);
208
209 58359872 const bool compute_penetration =
210
3/4
✓ Branch 0 taken 25329507 times.
✓ Branch 1 taken 3850433 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 25329507 times.
58359872 this->request.enable_contact || (this->request.security_margin < 0);
211
3/6
✓ Branch 1 taken 29179940 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 29179940 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 29179940 times.
✗ Branch 8 not taken.
58359872 Vec3s p1, p2, normal;
212
1/2
✓ Branch 2 taken 29179940 times.
✗ Branch 3 not taken.
58359872 DistanceResult distanceResult;
213 116719744 Scalar distance = internal::ShapeShapeDistance<TriangleP, TriangleP>(
214
1/2
✓ Branch 1 taken 29179940 times.
✗ Branch 2 not taken.
58359872 &tri1, this->tf1, &tri2, this->tf2, &solver, compute_penetration, p1,
215 p2, normal);
216
217 58359872 const Scalar distToCollision = distance - this->request.security_margin;
218
219
1/2
✓ Branch 1 taken 29179940 times.
✗ Branch 2 not taken.
58359872 internal::updateDistanceLowerBoundFromLeaf(this->request, *(this->result),
220 distToCollision, p1, p2, normal);
221
222 58359872 if (distToCollision <=
223
2/2
✓ Branch 0 taken 15561 times.
✓ Branch 1 taken 29164379 times.
58359872 this->request.collision_distance_threshold) { // collision
224 31121 sqrDistLowerBound = 0;
225
1/2
✓ Branch 1 taken 15561 times.
✗ Branch 2 not taken.
31121 if (this->result->numContacts() < this->request.num_max_contacts) {
226
2/4
✓ Branch 1 taken 15561 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 15561 times.
✗ Branch 5 not taken.
31121 this->result->addContact(Contact(this->model1, this->model2,
227 primitive_id1, primitive_id2, p1, p2,
228 normal, distance));
229 }
230 } else
231 58328751 sqrDistLowerBound = distToCollision * distToCollision;
232 58359872 }
233
234 Vec3s* vertices1;
235 Vec3s* vertices2;
236
237 Triangle* tri_indices1;
238 Triangle* tri_indices2;
239
240 details::RelativeTransformation<!bool(RTIsIdentity)> RT;
241 };
242
243 /// @brief Traversal node for collision between two meshes if their underlying
244 /// BVH node is oriented node (OBB, RSS, OBBRSS, kIOS)
245 typedef MeshCollisionTraversalNode<OBB, 0> MeshCollisionTraversalNodeOBB;
246 typedef MeshCollisionTraversalNode<RSS, 0> MeshCollisionTraversalNodeRSS;
247 typedef MeshCollisionTraversalNode<kIOS, 0> MeshCollisionTraversalNodekIOS;
248 typedef MeshCollisionTraversalNode<OBBRSS, 0> MeshCollisionTraversalNodeOBBRSS;
249
250 /// @}
251
252 namespace details {
253 template <typename BV>
254 struct DistanceTraversalBVDistanceLowerBound_impl {
255 5556 static Scalar run(const BVNode<BV>& b1, const BVNode<BV>& b2) {
256 5556 return b1.distance(b2);
257 }
258 3175686 static Scalar run(const Matrix3s& R, const Vec3s& T, const BVNode<BV>& b1,
259 const BVNode<BV>& b2) {
260 3178280 return distance(R, T, b1.bv, b2.bv);
261 }
262 };
263
264 template <>
265 struct DistanceTraversalBVDistanceLowerBound_impl<OBB> {
266 15564 static Scalar run(const BVNode<OBB>& b1, const BVNode<OBB>& b2) {
267 Scalar sqrDistLowerBound;
268
1/2
✓ Branch 1 taken 15564 times.
✗ Branch 2 not taken.
15564 CollisionRequest request(DISTANCE_LOWER_BOUND, 0);
269 // request.break_distance = ?
270
3/4
✓ Branch 1 taken 15564 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 10494 times.
✓ Branch 4 taken 5070 times.
15564 if (b1.overlap(b2, request, sqrDistLowerBound)) {
271 // TODO A penetration upper bound should be computed.
272 10494 return -1;
273 }
274 5070 return std::sqrt(sqrDistLowerBound);
275 }
276 static Scalar run(const Matrix3s& R, const Vec3s& T, const BVNode<OBB>& b1,
277 const BVNode<OBB>& b2) {
278 Scalar sqrDistLowerBound;
279 CollisionRequest request(DISTANCE_LOWER_BOUND, 0);
280 // request.break_distance = ?
281 if (overlap(R, T, b1.bv, b2.bv, request, sqrDistLowerBound)) {
282 // TODO A penetration upper bound should be computed.
283 return -1;
284 }
285 return std::sqrt(sqrDistLowerBound);
286 }
287 };
288
289 template <>
290 struct DistanceTraversalBVDistanceLowerBound_impl<AABB> {
291 static Scalar run(const BVNode<AABB>& b1, const BVNode<AABB>& b2) {
292 Scalar sqrDistLowerBound;
293 CollisionRequest request(DISTANCE_LOWER_BOUND, 0);
294 // request.break_distance = ?
295 if (b1.overlap(b2, request, sqrDistLowerBound)) {
296 // TODO A penetration upper bound should be computed.
297 return -1;
298 }
299 return std::sqrt(sqrDistLowerBound);
300 }
301 static Scalar run(const Matrix3s& R, const Vec3s& T, const BVNode<AABB>& b1,
302 const BVNode<AABB>& b2) {
303 Scalar sqrDistLowerBound;
304 CollisionRequest request(DISTANCE_LOWER_BOUND, 0);
305 // request.break_distance = ?
306 if (overlap(R, T, b1.bv, b2.bv, request, sqrDistLowerBound)) {
307 // TODO A penetration upper bound should be computed.
308 return -1;
309 }
310 return std::sqrt(sqrDistLowerBound);
311 }
312 };
313 } // namespace details
314
315 /// @addtogroup Traversal_For_Distance
316 /// @{
317
318 /// @brief Traversal node for distance computation between BVH models
319 template <typename BV>
320 class BVHDistanceTraversalNode : public DistanceTraversalNodeBase {
321 public:
322 14374 BVHDistanceTraversalNode() : DistanceTraversalNodeBase() {
323 14374 model1 = NULL;
324 14374 model2 = NULL;
325
326 14374 num_bv_tests = 0;
327 14374 num_leaf_tests = 0;
328 14374 query_time_seconds = 0.0;
329 14374 }
330
331 /// @brief Whether the BV node in the first BVH tree is leaf
332 2274508 bool isFirstNodeLeaf(unsigned int b) const {
333 2274508 return model1->getBV(b).isLeaf();
334 }
335
336 /// @brief Whether the BV node in the second BVH tree is leaf
337 2274508 bool isSecondNodeLeaf(unsigned int b) const {
338 2274508 return model2->getBV(b).isLeaf();
339 }
340
341 /// @brief Determine the traversal order, is the first BVTT subtree better
342 1607482 bool firstOverSecond(unsigned int b1, unsigned int b2) const {
343 1607482 Scalar sz1 = model1->getBV(b1).bv.size();
344 1607482 Scalar sz2 = model2->getBV(b2).bv.size();
345
346 1607482 bool l1 = model1->getBV(b1).isLeaf();
347 1607482 bool l2 = model2->getBV(b2).isLeaf();
348
349
6/6
✓ Branch 0 taken 352537 times.
✓ Branch 1 taken 451204 times.
✓ Branch 2 taken 279090 times.
✓ Branch 3 taken 73447 times.
✓ Branch 4 taken 112308 times.
✓ Branch 5 taken 166782 times.
1607482 if (l2 || (!l1 && (sz1 > sz2))) return true;
350 480458 return false;
351 }
352
353 /// @brief Obtain the left child of BV node in the first BVH
354 1127024 int getFirstLeftChild(unsigned int b) const {
355 1127024 return model1->getBV(b).leftChild();
356 }
357
358 /// @brief Obtain the right child of BV node in the first BVH
359 1127024 int getFirstRightChild(unsigned int b) const {
360 1127024 return model1->getBV(b).rightChild();
361 }
362
363 /// @brief Obtain the left child of BV node in the second BVH
364 480458 int getSecondLeftChild(unsigned int b) const {
365 480458 return model2->getBV(b).leftChild();
366 }
367
368 /// @brief Obtain the right child of BV node in the second BVH
369 480458 int getSecondRightChild(unsigned int b) const {
370 480458 return model2->getBV(b).rightChild();
371 }
372
373 /// @brief The first BVH model
374 const BVHModel<BV>* model1;
375 /// @brief The second BVH model
376 const BVHModel<BV>* model2;
377
378 /// @brief statistical information
379 mutable int num_bv_tests;
380 mutable int num_leaf_tests;
381 mutable Scalar query_time_seconds;
382 };
383
384 /// @brief Traversal node for distance computation between two meshes
385 template <typename BV, int _Options = RelativeTransformationIsIdentity>
386 class MeshDistanceTraversalNode : public BVHDistanceTraversalNode<BV> {
387 public:
388 enum {
389 Options = _Options,
390 RTIsIdentity = _Options & RelativeTransformationIsIdentity
391 };
392
393 using BVHDistanceTraversalNode<BV>::enable_statistics;
394 using BVHDistanceTraversalNode<BV>::request;
395 using BVHDistanceTraversalNode<BV>::result;
396 using BVHDistanceTraversalNode<BV>::tf1;
397 using BVHDistanceTraversalNode<BV>::model1;
398 using BVHDistanceTraversalNode<BV>::model2;
399 using BVHDistanceTraversalNode<BV>::num_bv_tests;
400 using BVHDistanceTraversalNode<BV>::num_leaf_tests;
401
402
1/2
✓ Branch 2 taken 7163 times.
✗ Branch 3 not taken.
14374 MeshDistanceTraversalNode() : BVHDistanceTraversalNode<BV>() {
403 14374 vertices1 = NULL;
404 14374 vertices2 = NULL;
405 14374 tri_indices1 = NULL;
406 14374 tri_indices2 = NULL;
407
408 14374 rel_err = this->request.rel_err;
409 14374 abs_err = this->request.abs_err;
410 14374 }
411
412 14374 void preprocess() {
413 14326 if (!RTIsIdentity) preprocessOrientedNode();
414 14374 }
415
416 14374 void postprocess() {
417 14326 if (!RTIsIdentity) postprocessOrientedNode();
418 14374 }
419
420 /// @brief BV culling test in one BVTT node
421 3214964 Scalar BVDistanceLowerBound(unsigned int b1, unsigned int b2) const {
422
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 1607482 times.
3214964 if (enable_statistics) num_bv_tests++;
423 if (RTIsIdentity)
424 36684 return details::DistanceTraversalBVDistanceLowerBound_impl<BV>::run(
425 73368 model1->getBV(b1), model2->getBV(b2));
426 else
427 3178280 return details::DistanceTraversalBVDistanceLowerBound_impl<BV>::run(
428 6356560 RT._R(), RT._T(), model1->getBV(b1), model2->getBV(b2));
429 }
430
431 /// @brief Distance testing between leaves (two triangles)
432 665850 void leafComputeDistance(unsigned int b1, unsigned int b2) const {
433
1/2
✗ Branch 0 not taken.
✓ Branch 1 taken 332925 times.
665850 if (this->enable_statistics) this->num_leaf_tests++;
434
435 665850 const BVNode<BV>& node1 = this->model1->getBV(b1);
436 665850 const BVNode<BV>& node2 = this->model2->getBV(b2);
437
438 665850 int primitive_id1 = node1.primitiveId();
439 665850 int primitive_id2 = node2.primitiveId();
440
441 665850 const Triangle& tri_id1 = tri_indices1[primitive_id1];
442 665850 const Triangle& tri_id2 = tri_indices2[primitive_id2];
443
444 665850 const Vec3s& t11 = vertices1[tri_id1[0]];
445 665850 const Vec3s& t12 = vertices1[tri_id1[1]];
446 665850 const Vec3s& t13 = vertices1[tri_id1[2]];
447
448 665850 const Vec3s& t21 = vertices2[tri_id2[0]];
449 665850 const Vec3s& t22 = vertices2[tri_id2[1]];
450 665850 const Vec3s& t23 = vertices2[tri_id2[2]];
451
452 // nearest point pair
453
3/6
✓ Branch 1 taken 332925 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 332925 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 332925 times.
✗ Branch 8 not taken.
665850 Vec3s P1, P2, normal;
454
455 Scalar d2;
456 if (RTIsIdentity)
457
1/2
✓ Branch 1 taken 3601 times.
✗ Branch 2 not taken.
7202 d2 = TriangleDistance::sqrTriDistance(t11, t12, t13, t21, t22, t23, P1,
458 P2);
459 else
460
1/2
✓ Branch 3 taken 329324 times.
✗ Branch 4 not taken.
658648 d2 = TriangleDistance::sqrTriDistance(t11, t12, t13, t21, t22, t23,
461 RT._R(), RT._T(), P1, P2);
462 665850 Scalar d = sqrt(d2);
463
464
1/2
✓ Branch 1 taken 332925 times.
✗ Branch 2 not taken.
665850 this->result->update(d, this->model1, this->model2, primitive_id1,
465 primitive_id2, P1, P2, normal);
466 665850 }
467
468 /// @brief Whether the traversal process can stop early
469 3208866 bool canStop(Scalar c) const {
470
2/2
✓ Branch 0 taken 474954 times.
✓ Branch 1 taken 1129479 times.
3208866 if ((c >= this->result->min_distance - abs_err) &&
471
1/2
✓ Branch 0 taken 474954 times.
✗ Branch 1 not taken.
949908 (c * (1 + rel_err) >= this->result->min_distance))
472 949908 return true;
473 2258958 return false;
474 }
475
476 Vec3s* vertices1;
477 Vec3s* vertices2;
478
479 Triangle* tri_indices1;
480 Triangle* tri_indices2;
481
482 /// @brief relative and absolute error, default value is 0.01 for both terms
483 Scalar rel_err;
484 Scalar abs_err;
485
486 details::RelativeTransformation<!bool(RTIsIdentity)> RT;
487
488 private:
489 14326 void preprocessOrientedNode() {
490 14326 const int init_tri_id1 = 0, init_tri_id2 = 0;
491 14326 const Triangle& init_tri1 = tri_indices1[init_tri_id1];
492 14326 const Triangle& init_tri2 = tri_indices2[init_tri_id2];
493
494
3/4
✓ Branch 1 taken 21489 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 21489 times.
✓ Branch 4 taken 7163 times.
57304 Vec3s init_tri1_points[3];
495
3/4
✓ Branch 1 taken 21489 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 21489 times.
✓ Branch 4 taken 7163 times.
57304 Vec3s init_tri2_points[3];
496
497
1/2
✓ Branch 2 taken 7163 times.
✗ Branch 3 not taken.
14326 init_tri1_points[0] = vertices1[init_tri1[0]];
498
1/2
✓ Branch 2 taken 7163 times.
✗ Branch 3 not taken.
14326 init_tri1_points[1] = vertices1[init_tri1[1]];
499
1/2
✓ Branch 2 taken 7163 times.
✗ Branch 3 not taken.
14326 init_tri1_points[2] = vertices1[init_tri1[2]];
500
501
1/2
✓ Branch 2 taken 7163 times.
✗ Branch 3 not taken.
14326 init_tri2_points[0] = vertices2[init_tri2[0]];
502
1/2
✓ Branch 2 taken 7163 times.
✗ Branch 3 not taken.
14326 init_tri2_points[1] = vertices2[init_tri2[1]];
503
1/2
✓ Branch 2 taken 7163 times.
✗ Branch 3 not taken.
14326 init_tri2_points[2] = vertices2[init_tri2[2]];
504
505
3/6
✓ Branch 1 taken 7163 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 7163 times.
✗ Branch 5 not taken.
✓ Branch 7 taken 7163 times.
✗ Branch 8 not taken.
14326 Vec3s p1, p2, normal;
506
1/2
✓ Branch 3 taken 7163 times.
✗ Branch 4 not taken.
14326 Scalar distance = sqrt(TriangleDistance::sqrTriDistance(
507 init_tri1_points[0], init_tri1_points[1], init_tri1_points[2],
508 init_tri2_points[0], init_tri2_points[1], init_tri2_points[2], RT._R(),
509 RT._T(), p1, p2));
510
511
1/2
✓ Branch 1 taken 7163 times.
✗ Branch 2 not taken.
14326 result->update(distance, model1, model2, init_tri_id1, init_tri_id2, p1, p2,
512 normal);
513 14326 }
514 7163 void postprocessOrientedNode() {
515 /// the points obtained by triDistance are not in world space: both are in
516 /// object1's local coordinate system, so we need to convert them into the
517 /// world space.
518
3/4
✓ Branch 0 taken 7163 times.
✗ Branch 1 not taken.
✓ Branch 2 taken 1901 times.
✓ Branch 3 taken 5262 times.
14326 if (request.enable_nearest_points && (result->o1 == model1) &&
519
2/2
✓ Branch 0 taken 1673 times.
✓ Branch 1 taken 228 times.
3802 (result->o2 == model2)) {
520 3346 result->nearest_points[0] = tf1.transform(result->nearest_points[0]);
521 3346 result->nearest_points[1] = tf1.transform(result->nearest_points[1]);
522 }
523 14326 }
524 };
525
526 /// @brief Traversal node for distance computation between two meshes if their
527 /// underlying BVH node is oriented node (RSS, OBBRSS, kIOS)
528 typedef MeshDistanceTraversalNode<RSS, 0> MeshDistanceTraversalNodeRSS;
529 typedef MeshDistanceTraversalNode<kIOS, 0> MeshDistanceTraversalNodekIOS;
530 typedef MeshDistanceTraversalNode<OBBRSS, 0> MeshDistanceTraversalNodeOBBRSS;
531
532 /// @}
533
534 /// @brief for OBB and RSS, there is local coordinate of BV, so normal need to
535 /// be transformed
536 namespace details {
537
538 template <typename BV>
539 inline const Matrix3s& getBVAxes(const BV& bv) {
540 return bv.axes;
541 }
542
543 template <>
544 inline const Matrix3s& getBVAxes<OBBRSS>(const OBBRSS& bv) {
545 return bv.obb.axes;
546 }
547
548 } // namespace details
549
550 } // namespace coal
551
552 /// @endcond
553
554 #endif
555