Collision Checker
geometry_queries.cc
Go to the documentation of this file.
1 #include <fcl/math/bv/OBB.h>
7 
9 
10 namespace collision {
11 
12 namespace detail {
13 namespace geometry_queries {
15  fcl::OBB<FCL_PRECISION>* fcl_obb) {
16  fcl_obb->axis = fcl::Matrix3<FCL_PRECISION>::Zero();
17  fcl_obb->To = fcl::Vector3<FCL_PRECISION>::Zero();
18  fcl_obb->extent = fcl::Vector3<FCL_PRECISION>::Zero();
19 
20  fcl_obb->To.topRows(2) = obb->center().cast<double>();
21 
22  if (obb->r_x() > obb->r_y())
23 
24  {
25  fcl_obb->axis.block<2, 1>(0, 0) = obb->local_x_axis();
26  fcl_obb->axis.block<2, 1>(0, 1) = obb->local_y_axis();
27  fcl_obb->axis(2, 2) = 1;
28 
29  fcl_obb->extent(0) = obb->r_x();
30  fcl_obb->extent(1) = obb->r_y();
31 
32  } else {
33  fcl_obb->axis.block<2, 1>(0, 0) = obb->local_y_axis();
34  fcl_obb->axis.block<2, 1>(0, 1) = obb->local_x_axis();
35  fcl_obb->axis(2, 2) = 1;
36  fcl_obb->extent(0) = obb->r_x();
37  fcl_obb->extent(1) = obb->r_y();
38  }
39 
40  return 0;
41 }
42 
43 int fillFclOBBHelper(const OBB* obb, fcl::OBB<FCL_PRECISION>* fcl_obb) {
44  fcl_obb->axis = fcl::Matrix3<FCL_PRECISION>::Zero();
45  fcl_obb->To = fcl::Vector3<FCL_PRECISION>::Zero();
46  fcl_obb->extent = fcl::Vector3<FCL_PRECISION>::Zero();
47  fcl_obb->To.topRows(2) = obb->center().cast<double>();
48 
49  if (obb->r_x() > obb->r_y())
50 
51  {
52  fcl_obb->axis.block<2, 1>(0, 0) = obb->local_x_axis();
53  fcl_obb->axis.block<2, 1>(0, 1) = obb->local_y_axis();
54  fcl_obb->axis(2, 2) = 1;
55 
56  fcl_obb->extent(0) = obb->r_x();
57  fcl_obb->extent(1) = obb->r_y();
58 
59  } else {
60  fcl_obb->axis.block<2, 1>(0, 0) = obb->local_y_axis();
61  fcl_obb->axis.block<2, 1>(0, 1) = obb->local_x_axis();
62  fcl_obb->axis(2, 2) = 1;
63  fcl_obb->extent(0) = obb->r_x();
64  fcl_obb->extent(1) = obb->r_y();
65  }
66 
67  return 0;
68 }
69 
70 // todo: add AABB handling
71 
73  const RectangleOBB* second) {
74  fcl::OBB<FCL_PRECISION> this_obb;
75  fcl::OBB<FCL_PRECISION> other_obb;
76 
77  fillFclOBBHelper(first, &this_obb);
78  fillFclOBBHelper(second, &other_obb);
79 
80  fcl::OBB<FCL_PRECISION> merged_obb = this_obb + other_obb;
81 
82  Eigen::Matrix2d local_ax;
83 
84  local_ax = merged_obb.axis.block<2, 2>(0, 0).cast<double>();
85  double rx = merged_obb.extent(0);
86  double ry = merged_obb.extent(1);
87  Eigen::Vector2d cent = merged_obb.To.topRows(2).cast<double>();
88 
89  RectangleOBBConstPtr ret(new collision::RectangleOBB(rx, ry, local_ax, cent));
90 
91  return (ret);
92 }
93 
94 bool cmpd(double A, double B, double epsilon = 1e-7)
95 {
96  return (fabs(A - B) < epsilon);
97 }
98 
99 int ccd_merge_entities(const Sphere* first,
100  const Sphere* second, ShapeGroupPtr ret)
101 {
102  if(!cmpd(first->radius(),second->radius(), 1e-7))
103  {
104  return -1;
105  }
106  ret->addToGroup(std::static_pointer_cast<const collision::Shape>(first->shared_from_this()));
107  ret->addToGroup(std::static_pointer_cast<const collision::Shape>(second->shared_from_this()));
108 
109  auto rect=collision::geometry_queries::create_rectangle_obb_from_points(first->center(), second->center(),first->radius()*2);
110  ret->addToGroup(rect);
111 
112  return 0;
113 }
114 
115 
116 OBB merge_obbs(const OBB& first, const OBB& second) {
117  OBB obb_merged;
118 
119  fcl::OBB<FCL_PRECISION> this_obb;
120  fcl::OBB<FCL_PRECISION> other_obb;
121 
122  fillFclOBBHelper(&first, &this_obb);
123  fillFclOBBHelper(&second, &other_obb);
124 
125  fcl::OBB<FCL_PRECISION> merged_obb = this_obb + other_obb;
126 
127  Eigen::Matrix2d local_ax;
128 
129  local_ax = merged_obb.axis.block<2, 2>(0, 0).cast<double>();
130  Eigen::Vector2d r(merged_obb.extent(0), merged_obb.extent(1));
131 
132  Eigen::Vector2d cent = merged_obb.To.topRows(2).cast<double>();
133 
134  return OBB(local_ax, r, cent);
135 }
136 
138  return std::make_shared<const RectangleOBB>(aabb->r_x(), aabb->r_y(), 0,
139  aabb->center());
140 }
141 
142 } // namespace geometry_queries
143 } // namespace detail
144 
145 
146 namespace geometry_queries {
148  const CollisionObject* second) {
149  if ((first->getCollisionObjectType() == OBJ_TYPE_AABB_BOX) ||
150  (second->getCollisionObjectType() == OBJ_TYPE_AABB_BOX)) {
151  RectangleOBBConstPtr old_rect1;
152  RectangleOBBConstPtr old_rect2;
153  if (first->getCollisionObjectType() == OBJ_TYPE_AABB_BOX) {
155  static_cast<const RectangleAABB*>(first));
156  first = old_rect1.get();
157  }
158  if (second->getCollisionObjectType() == OBJ_TYPE_AABB_BOX) {
160  static_cast<const RectangleAABB*>(second));
161  second = old_rect2.get();
162  }
164  static_cast<const RectangleOBB*>(first),
165  static_cast<const RectangleOBB*>(second));
166  }
167 
168  if (first->getCollisionObjectType() == OBJ_TYPE_OBB_BOX &&
171  static_cast<const RectangleOBB*>(first),
172  static_cast<const RectangleOBB*>(second));
173  }
174  else if(first->getCollisionObjectType()==OBJ_TYPE_SPHERE &&
176  {
177  ShapeGroupPtr sg_merge_res(new ShapeGroup());
179  static_cast<const Sphere*>(first),
180  static_cast<const Sphere*>(second),sg_merge_res);
181  if(ret_merge)
182  return nullptr;
183  else
184  return sg_merge_res;
185  }
186 
187  /*
188  else if(first->getCollisionObjectType()==OBJ_TYPE_POLYGON &&
189  second->getCollisionObjectType()==OBJ_TYPE_POLYGON)
190  {
191  PolygonConstPtr new_poly;
192  int res=boost_poly_poly_convex_hull(*(static_cast<const
193  Polygon*>(first.get())),*(static_cast<const
194  Polygon*>(second.get())),new_poly); if(res) return nullptr; return
195  new_poly;
196  }
197  */
198  else
199  return nullptr;
200 }
201 
202 std::size_t test_polygon_enclosure(const ShapeGroup& sg,
203  const RectangleOBB& obb, bool& res) {
204  if (boost_polygon_enclosure(sg, obb, res)) {
205  return 1;
206  } else
207  return 0;
208 }
209 
211  Eigen::Vector2d pt2,
212  double rect_width) {
213  Eigen::Matrix2d local_axes;
214 
215  Eigen::Vector2d v = pt2 - pt1;
216 
217  Eigen::Vector2d center = (pt1 + pt2) / 2;
218 
219  double length = v.norm();
220 
221  if (length < 1e-10) return 0;
222 
223  v = v / length;
224 
225  local_axes.col(0) = v;
226  local_axes.col(1) = Eigen::Vector2d(-v(1), v(0));
227  return std::make_shared<const RectangleOBB>(length / 2, rect_width / 2,
228  local_axes, center);
229 }
230 
231 int create_rectangles_obb_from_vertex_list(std::vector<Eigen::Vector2d>& verts,
232  collision::ShapeGroup* sg_rects_ptr,
233  double rect_width) {
234  for (auto vert = verts.begin(); vert < verts.end() - 1; vert++) {
236  create_rectangle_obb_from_points(*vert, *(vert + 1), rect_width);
237  if (rect_new) sg_rects_ptr->addToGroup(rect_new);
238  }
239  if (verts.size() > 1) {
241  *(verts.end() - 1), *(verts.begin()), rect_width);
242  if (rect_new) sg_rects_ptr->addToGroup(rect_new);
243  }
244  return 0;
245 }
246 
247 } // namespace geometry_queries
248 } // namespace collision
Eigen::Vector2d local_y_axis() const
Oriented rectangle.
Definition: rectangle_obb.h:19
double r_x() const
Definition: obb.h:76
int boost_polygon_enclosure(const ShapeGroup &sg, const RectangleOBB &obb, bool &res)
bool cmpd(double A, double B, double epsilon=1e-7)
RectangleOBBConstPtr obb_from_aabb(const RectangleAABB *aabb)
Eigen::Vector2d local_x_axis() const
Definition: obb.h:41
OBB merge_obbs(const OBB &obb1, const OBB &obb2)
ShapeGroup can contain simple shapes.
Definition: shape_group.h:33
RectangleOBBConstPtr ccd_merge_entities(const RectangleOBB *first, const RectangleOBB *second)
RectangleOBBConstPtr create_rectangle_obb_from_points(Eigen::Vector2d pt1, Eigen::Vector2d pt2, double rect_width)
std::shared_ptr< const RectangleOBB > RectangleOBBConstPtr
int create_rectangles_obb_from_vertex_list(std::vector< Eigen::Vector2d > &verts, collision::ShapeGroup *sg_rects_ptr, double rect_width)
std::shared_ptr< const CollisionObject > CollisionObjectConstPtr
Eigen::Vector2d center(void) const
Definition: obb.h:39
Eigen::Vector2d local_y_axis() const
Definition: obb.h:43
double r_y() const
Definition: obb.h:78
Circle.
Definition: sphere.h:14
std::shared_ptr< ShapeGroup > ShapeGroupPtr
Definition: polygon.h:17
virtual CollisionObjectType getCollisionObjectType() const
Axis-aligned rectangle.
std::size_t test_polygon_enclosure(const ShapeGroup &sg_polygons, const RectangleOBB &obb, bool &res)
Base class for CollisionObjects and some of their groups.
void addToGroup(ShapeConstPtr shape)
Adds a simple shape to the ShapeGroup.
Definition: shape_group.cc:176
Eigen::Vector2d local_x_axis() const
double radius() const
Definition: sphere.h:48
Eigen::Vector2d center() const
Get geometric center of shape.
Definition: shape.cc:16
int fillFclOBBHelper(const RectangleOBB *obb, fcl::OBB< FCL_PRECISION > *fcl_obb)