Collision Checker
boost_collision_queries.cc
Go to the documentation of this file.
3 
4 #include <boost/foreach.hpp>
5 #include <boost/geometry.hpp>
6 #include <boost/geometry/geometries/multi_polygon.hpp>
7 
11 
12 namespace collision {
13 
14 using namespace detail::accelerators;
15 
16 namespace solvers {
17 namespace solverBoost {
18 
19 #define BOOST_EPS (0)
20 
21 typedef boost::geometry::model::multi_polygon<bg_polygon_type> bg_mpolygon_type;
22 
28 bool boost_within(const BoostPolygon& polyg1, const BoostPolygon& polyg2) {
29  return polyg1.within(polyg2);
30 }
31 
46 int boost_poly_poly_convex_hull(const Polygon& pos1, const Polygon& pos2,
47  collision::PolygonConstPtr& resPoly) {
48  BoostPolygon bp1(&pos1);
49  BoostPolygon bp2(&pos2);
50  std::vector<bg_polygon_type> output;
51  bg_polygon_type* boostp_1 = bp1.getInternal();
52  bg_polygon_type* boostp_2 = bp2.getInternal();
53 
54  {
55  // STACK_TIMER timer_union(TIMER_union);
56  boost::geometry::union_(*boostp_1, *boostp_2, output);
57  }
58  if (output.size() != 1) {
59  return -1;
60  }
61 
62  // convex Hull
63  {
64  // STACK_TIMER timer_chull(TIMER_chull_polygon);
65  resPoly = BoostPolygon(output[0]).convexHull()->toPolygon();
66  }
67  return 0;
68 }
69 
70 inline int boost_obb_obb_convex_hull(const RectangleOBB& pos1,
71  const RectangleOBB& pos2,
72  collision::PolygonConstPtr& resPoly) {
73  BoostPolygon bp1(&pos1);
74  BoostPolygon bp2(&pos2);
75  std::vector<bg_polygon_type> output;
76  bg_polygon_type* boostp_1 = bp1.getInternal();
77  bg_polygon_type* boostp_2 = bp2.getInternal();
78 
79  {
80  // STACK_TIMER timer_union(TIMER_union);
81  boost::geometry::union_(*boostp_1, *boostp_2, output);
82  }
83  if (output.size() != 1) {
84  return -1;
85  }
86 
87  // convex Hull
88  {
89  // STACK_TIMER timer_chull(TIMER_chull_polygon);
90  resPoly = BoostPolygon(output[0]).convexHull()->toPolygon();
91  }
92  return 0;
93 }
94 
113  const RectangleOBB& pos1,
114  const RectangleOBB& pos2, bool& res) {
116  int err = boost_obb_obb_convex_hull(pos1, pos2, resPoly);
117  if (err) return err;
118  {
119  // STACK_TIMER timer_collide(TIMER_collide_3);
120  res = sg.collide(*resPoly);
121  }
122  return 0;
123 }
124 
126  const RectangleOBB& pos2, bool& res) {
129  {
130  // STACK_TIMER timer_collide(TIMER_collide_3);
131  res = sg.collide(*resOBB);
132  }
133  return 0;
134 }
135 
137  const ShapeGroup& sg, const Shape& shape,
138  std::vector<bg_polygon_type>& mpoly) {
139  bg_mpolygon_type mpoly_res;
140  bg_mpolygon_type tmp_union;
141 
142  for (auto obj : sg.unpack()) {
143  if (obj->getCollisionObjectType() !=
145  return -1;
146  }
147  const collision::Polygon* obj_poly =
148  static_cast<const collision::Polygon*>(obj.get());
149  if (obj_poly->getAABB()->collide(shape)) {
150  BoostPolygon bp(obj_poly);
151  bg_polygon_type poly_tmp = *(bp.getInternal());
152 
153  mpoly.push_back(poly_tmp);
154  }
155  }
156  return 0;
157 }
158 
160  bool& res) {
161  BoostPolygon bp1(&obb);
162  std::vector<bg_polygon_type> poly_vec;
163  int err = 0;
164  {
165  // STACK_TIMER timer_get_cand(TIMER_get_cand);
166  err = boost_get_candidate_polygons_no_merge(sg, obb, poly_vec);
167  if (err) return err;
168  }
169 
170  bg_mpolygon_type output;
171  bg_polygon_type cur_poly = *(bp1.getInternal());
172  output.push_back(cur_poly);
173  bg_polygon_type polygon;
174  bg_mpolygon_type tmp_union;
175  {
176  // STACK_TIMER timer_difference(TIMER_difference);
177  BOOST_FOREACH (polygon, poly_vec) {
178  boost::geometry::clear(tmp_union);
179  boost::geometry::difference(output, polygon, tmp_union);
180  output = tmp_union;
181  }
182  }
183  if (boost::geometry::is_empty(output) ||
184  ((BOOST_EPS > 0) && boost::geometry::area(output) < BOOST_EPS)) {
185  res = true;
186  } else {
187  res = false;
188  }
189  return 0;
190 }
191 
192 template <typename T>
193 int boost_polygon_enclosure_grid(T& grid, std::vector<BoostPolygon*> polygons,
194  AABB& aabb, const BoostPolygon* obj_poly,
195  bool& res) {
197  aligned_vector<int> candidates;
198  std::vector<bg_polygon_type> poly_vec;
199 
200  detail::accelerators::windowQuery(grid, aabb, candidates);
201 
202  for (auto el : candidates) {
203  poly_vec.push_back(*(polygons[el]->getInternal()));
204  }
205 
206  bg_mpolygon_type output;
207  bg_polygon_type cur_poly = *(obj_poly->getInternal());
208  output.push_back(cur_poly);
209  bg_polygon_type polygon;
210  bg_mpolygon_type tmp_union;
211  {
212  STACK_TIMER timer_difference(TIMER_difference);
213  BOOST_FOREACH (polygon, poly_vec) {
214  boost::geometry::clear(tmp_union);
215  boost::geometry::difference(output, polygon, tmp_union);
216  output = tmp_union;
217  }
218  }
219  if (boost::geometry::is_empty(output) ||
220  ((BOOST_EPS > 0) && boost::geometry::area(output) < BOOST_EPS)) {
221  res = true;
222  } else {
223  res = false;
224  }
225 
226  return 0;
227 }
228 
229 template int boost_polygon_enclosure_grid<ContainerGrid<HorizontalGrid>>(
230  ContainerGrid<HorizontalGrid>& grid, std::vector<BoostPolygon*> polygons,
231  AABB& aabb, const BoostPolygon* obj_poly, bool& res);
232 template int boost_polygon_enclosure_grid<ContainerGrid<VerticalGrid>>(
233  ContainerGrid<VerticalGrid>& grid, std::vector<BoostPolygon*> polygons,
234  AABB& aabb, const BoostPolygon* obj_poly, bool& res);
235 
237  const RectangleOBB& pos1,
238  const RectangleOBB& pos2,
239  bool& res) {
240  std::vector<bg_polygon_type> poly_vec;
241 
242  int err = 0;
243 
245 
246  {
247  // STACK_TIMER timer_chull(TIMER_boost_obb_obb_convex_hull);
248 
249  err = boost_obb_obb_convex_hull(pos1, pos2, resPoly);
250  }
251  if (err) return err;
253 
254  {
255  // STACK_TIMER timer_get_cand(TIMER_get_cand);
256  aabb = resPoly->getAABB();
257  const collision::RectangleAABB* aabb_ptr = aabb.get();
258  err = boost_get_candidate_polygons_no_merge(sg, *aabb_ptr, poly_vec);
259  if (err) return err;
260  }
261 
262  bg_mpolygon_type output;
263  bg_polygon_type cur_poly = *(BoostPolygon(resPoly.get()).getInternal());
264  output.push_back(cur_poly);
265  bg_polygon_type polygon;
266  bg_mpolygon_type tmp_union;
267  {
268  // STACK_TIMER timer_difference(TIMER_difference);
269  BOOST_FOREACH (polygon, poly_vec) {
270  boost::geometry::clear(tmp_union);
271  boost::geometry::difference(output, polygon, tmp_union);
272  output = tmp_union;
273  }
274  }
275  if (boost::geometry::is_empty(output) ||
276  ((BOOST_EPS > 0) && boost::geometry::area(output) < BOOST_EPS)) {
277  res = true;
278  } else {
279  // std::cout << boost::geometry::area(output) << std::endl;
280  res = false;
281  }
282  return 0;
283 }
284 
286  const RectangleOBB& pos1,
287  const RectangleOBB& pos2, bool& res) {
288  std::vector<bg_polygon_type> poly_vec;
289 
292 
293  return boost_polygon_enclosure(sg, *resOBB, res);
294 }
295 
296 } // namespace solverBoost
297 } // namespace solvers
298 } // namespace collision
Oriented rectangle.
Definition: rectangle_obb.h:19
std::vector< T, boost::alignment::aligned_allocator< T, 16 > > aligned_vector
Definition: declarations.h:9
int boost_ccd_obb_sum_collision(const ShapeGroup &sg, const RectangleOBB &pos1, const RectangleOBB &pos2, bool &res)
int boost_ccd_convex_hull_polygon_enclosure(const ShapeGroup &sg, const RectangleOBB &pos1, const RectangleOBB &pos2, bool &res)
int boost_polygon_enclosure(const ShapeGroup &sg, const RectangleOBB &obb, bool &res)
std::vector< ShapeConstPtr > unpack() const
Returns Vector of all shapes contained inside the ShapeGroup.
Definition: shape_group.cc:187
int windowQuery(ContainerGrid< DIRECTION > &container, AABB &aabb, aligned_vector< int > &candidates)
std::shared_ptr< const RectangleAABB > RectangleAABBConstPtr
boost::geometry::model::multi_polygon< bg_polygon_type > bg_mpolygon_type
BoostPolygonConstPtr convexHull(void) const
Computes a convex hull of the given BoostPolygon.
ShapeGroup can contain simple shapes.
Definition: shape_group.h:33
RectangleOBBConstPtr ccd_merge_entities(const RectangleOBB *first, const RectangleOBB *second)
std::shared_ptr< const RectangleOBB > RectangleOBBConstPtr
int boost_ccd_convex_hull_collision(const ShapeGroup &sg, const RectangleOBB &pos1, const RectangleOBB &pos2, bool &res)
Checks if the convex hull of the Boolean union of two given OBB boxes collides with any of the ShapeG...
boost::geometry::model::polygon< bg_point_type > bg_polygon_type
std::shared_ptr< const Polygon > PolygonConstPtr
Definition: polygon.h:23
int boost_polygon_enclosure_grid(T &grid, std::vector< BoostPolygon *> polygons, AABB &aabb, const BoostPolygon *obj_poly, bool &res)
bool within(const BoostPolygon &other) const
Returns true if the BoostPolygon is completely contained within another BoostPolygon object...
virtual std::shared_ptr< const collision::RectangleAABB > getAABB() const
virtual bool collide(const CollisionObject &c, const collision::CollisionRequest &req=CollisionRequest()) const
int boost_ccd_obb_sum_polygon_enclosure(const ShapeGroup &sg, const RectangleOBB &pos1, const RectangleOBB &pos2, bool &res)
bg_polygon_type * getInternal(void) const
Returns the contained boost.Geometry polygon object.
Axis-aligned rectangle.
int boost_get_candidate_polygons_no_merge(const ShapeGroup &sg, const Shape &shape, std::vector< bg_polygon_type > &mpoly)
Base prototype for the shape of an obstacle.
Definition: shape.h:25
#define TIMER_difference
Definition: application.h:32
int boost_poly_poly_convex_hull(const Polygon &pos1, const Polygon &pos2, collision::PolygonConstPtr &resPoly)
Creates a collision Polygon of two RectangleOBB objects. The convex hull of the boolean union of the ...
int boost_obb_obb_convex_hull(const RectangleOBB &pos1, const RectangleOBB &pos2, collision::PolygonConstPtr &resPoly)
#define BOOST_EPS
Polygon contains Triangles and Vertices.
Definition: polygon.h:29
bool boost_within(const BoostPolygon &polyg1, const BoostPolygon &polyg2)
Returns true if the BoostPolygon polyg1 is completely contained within the other BoostPolygon object ...
BoostPolygon allows to use boost.Geometry functions for Polygon objects.
#define TIMER_polygon_enclosure
Definition: application.h:41
#define STACK_TIMER
Definition: application.h:11