Skip to content

Commit bb1d826

Browse files
committed
Hfield-Shape: use ShapeShapeDistance instead of GJKSolver
1 parent 70fa396 commit bb1d826

File tree

1 file changed

+51
-37
lines changed

1 file changed

+51
-37
lines changed

include/hpp/fcl/internal/traversal_node_hfield_shape.h

+51-37
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
#include <hpp/fcl/shape/geometric_shapes.h>
4444
#include <hpp/fcl/narrowphase/narrowphase.h>
4545
#include <hpp/fcl/shape/geometric_shapes_utility.h>
46+
#include <hpp/fcl/internal/shape_shape_func.h>
4647
#include <hpp/fcl/internal/traversal_node_base.h>
4748
#include <hpp/fcl/internal/traversal.h>
4849
#include <hpp/fcl/internal/intersect.h>
@@ -410,40 +411,50 @@ bool shapeDistance(const GJKSolver* nsolver, const CollisionRequest& request,
410411
enum { RTIsIdentity = Options & RelativeTransformationIsIdentity };
411412

412413
const Transform3f Id;
413-
Vec3f contact1_1, contact1_2, normal1, normal1_top;
414-
Vec3f contact2_1, contact2_2, normal2, normal2_top;
415-
FCL_REAL distance1, distance2;
416-
bool collision1, collision2;
417-
bool hfield_witness_is_on_bin_side1, hfield_witness_is_on_bin_side2;
418-
// Because we do bin comparison and correction, we always compute penetration
419-
// information.
414+
// The solver `nsolver` has already been set up by the collision request
415+
// `request`. If GJK early stopping is enabled through `request`, it will be
416+
// used.
417+
// The only thing we need to make sure is that in case of collision, the
418+
// penetration information is computed (as we do bins comparison).
420419
bool compute_penetration = true;
421-
if (RTIsIdentity)
422-
nsolver->shapeDistance(convex1, Id, shape, tf2, distance1,
423-
compute_penetration, contact1_1, contact1_2,
424-
normal1);
425-
else
426-
nsolver->shapeDistance(convex1, tf1, shape, tf2, distance1,
427-
compute_penetration, contact1_1, contact1_2,
428-
normal1);
429-
collision1 = (distance1 - request.security_margin <=
430-
request.collision_distance_threshold);
431-
432-
hfield_witness_is_on_bin_side1 =
420+
DistanceRequest drequest(compute_penetration, compute_penetration);
421+
DistanceResult dresult1;
422+
DistanceResult dresult2;
423+
FCL_REAL distance1, distance2;
424+
425+
if (RTIsIdentity) {
426+
distance1 = ShapeShapeDistance<Convex<Polygone>, Shape>(
427+
&convex1, Id, &shape, tf2, nsolver, drequest, dresult1);
428+
} else {
429+
distance1 = ShapeShapeDistance<Convex<Polygone>, Shape>(
430+
&convex1, tf1, &shape, tf2, nsolver, drequest, dresult1);
431+
}
432+
bool collision1 = (distance1 - request.security_margin <=
433+
request.collision_distance_threshold);
434+
435+
Vec3f& contact1_1 = dresult1.nearest_points[0];
436+
Vec3f& contact1_2 = dresult1.nearest_points[1];
437+
Vec3f& normal1 = dresult1.normal;
438+
Vec3f normal1_top;
439+
bool hfield_witness_is_on_bin_side1 =
433440
binCorrection(convex1, convex1_active_faces, shape, tf2, distance1,
434441
contact1_1, contact1_2, normal1, normal1_top, collision1);
435442

436-
if (RTIsIdentity)
437-
nsolver->shapeDistance(convex2, Id, shape, tf2, distance2,
438-
compute_penetration, contact2_1, contact2_2, normal);
439-
else
440-
nsolver->shapeDistance(convex2, tf1, shape, tf2, distance2,
441-
compute_penetration, contact2_1, contact2_2,
442-
normal2);
443-
collision2 = (distance2 - request.security_margin <=
444-
request.collision_distance_threshold);
445-
446-
hfield_witness_is_on_bin_side2 =
443+
if (RTIsIdentity) {
444+
distance2 = ShapeShapeDistance<Convex<Polygone>, Shape>(
445+
&convex2, Id, &shape, tf2, nsolver, drequest, dresult2);
446+
} else {
447+
distance2 = ShapeShapeDistance<Convex<Polygone>, Shape>(
448+
&convex2, tf1, &shape, tf2, nsolver, drequest, dresult2);
449+
}
450+
Vec3f& contact2_1 = dresult2.nearest_points[0];
451+
Vec3f& contact2_2 = dresult2.nearest_points[1];
452+
Vec3f& normal2 = dresult2.normal;
453+
Vec3f normal2_top;
454+
bool collision2 = (distance2 - request.security_margin <=
455+
request.collision_distance_threshold);
456+
457+
bool hfield_witness_is_on_bin_side2 =
447458
binCorrection(convex2, convex2_active_faces, shape, tf2, distance2,
448459
contact2_1, contact2_2, normal2, normal2_top, collision2);
449460

@@ -701,6 +712,8 @@ class HeightFieldShapeDistanceTraversalNode : public DistanceTraversalNodeBase {
701712

702713
/// @brief Distance testing between leaves (one bin of the height field and
703714
/// one shape)
715+
/// TODO(louis): deal with Hfield-Shape distance just like in Hfield-Shape
716+
/// collision (bin correction etc).
704717
void leafComputeDistance(unsigned int b1, unsigned int /*b2*/) const {
705718
if (this->enable_statistics) this->num_leaf_tests++;
706719

@@ -710,14 +723,15 @@ class HeightFieldShapeDistanceTraversalNode : public DistanceTraversalNodeBase {
710723
const ConvexQuadrilateral convex =
711724
details::buildConvexQuadrilateral(node, *this->model1);
712725

713-
FCL_REAL d;
714-
Vec3f closest_p1, closest_p2, normal;
715-
716-
nsolver->shapeDistance(convex, this->tf1, *(this->model2), this->tf2, d,
717-
closest_p1, closest_p2, normal);
726+
DistanceResult distanceResult;
727+
const FCL_REAL distance = ShapeShapeDistance<ConvexQuadrilateral, S>(
728+
&convex, this->tf1, this->model2, this->tf2, this->nsolver,
729+
this->request, distanceResult);
718730

719-
this->result->update(d, this->model1, this->model2, b1,
720-
DistanceResult::NONE, closest_p1, closest_p2, normal);
731+
this->result->update(distance, this->model1, this->model2, b1,
732+
DistanceResult::NONE, distanceResult.nearest_points[0],
733+
distanceResult.nearest_points[1],
734+
distanceResult.normal);
721735
}
722736

723737
/// @brief Whether the traversal process can stop early

0 commit comments

Comments
 (0)