1 #ifndef CPP_COLLISION_INCLUDE_COLLISION_GRID_FCL_H_ 2 #define CPP_COLLISION_INCLUDE_COLLISION_GRID_FCL_H_ 6 #include <fcl/broadphase/broadphase_SSaP.h> 7 #include <fcl/broadphase/broadphase_SaP.h> 8 #include <fcl/broadphase/broadphase_collision_manager.h> 9 #include <fcl/broadphase/broadphase_dynamic_AABB_tree.h> 10 #include <fcl/broadphase/broadphase_interval_tree.h> 11 #include <fcl/broadphase/broadphase_spatialhash.h> 13 #include <boost/align/aligned_allocator.hpp> 17 #include <fcl/narrowphase/collision_object.h> 31 namespace accelerators {
46 if (o1->getUserData()) {
47 cdata->
candidates_->push_back(*((
int*)o1->getUserData()));
48 }
else if (o2->getUserData()) {
49 cdata->candidates_->push_back(*((
int*)o2->getUserData()));
62 typedef Eigen::Matrix<uint64_t, Eigen::Dynamic, 1>
VectorXi64;
66 EIGEN_MAKE_ALIGNED_OPERATOR_NEW
72 for (
auto obj : objects_in) {
75 double min_x = std::numeric_limits<double>::max();
76 double max_x = std::numeric_limits<double>::min();
77 double min_y = std::numeric_limits<double>::max();
78 double max_y = std::numeric_limits<double>::min();
79 for (
auto obj : objects_in) {
82 min_x = std::min(min_x, aabb.
x_min);
83 min_y = std::min(min_y, aabb.
y_min);
84 max_x = std::max(max_x, aabb.
x_max);
85 max_y = std::max(max_y, aabb.
y_max);
88 double gridlen = max_x - min_x;
89 double cell_size = gridlen / sett.
num_cells;
93 broadphase_manager_ =
new fcl::DynamicAABBTreeCollisionManager<double>;
97 broadphase_manager_ =
new fcl::SpatialHashingCollisionManager<double>(
98 cell_size, fcl::Vector3<double>(min_x, min_y, -
FCL_HEIGHT),
99 fcl::Vector3<double>(max_x, max_y,
FCL_HEIGHT),
104 broadphase_manager_ =
new fcl::IntervalTreeCollisionManager<double>;
109 broadphase_manager_ =
new fcl::SaPCollisionManager<double>;
114 broadphase_manager_ =
new fcl::SSaPCollisionManager<double>;
118 throw std::invalid_argument(
"Invalid FCL broadphase manager ID");
125 for (
auto obj : sg_ptr->
unpack()) {
126 addObject(obj.get());
129 auto sg_aabb = sg_ptr->
getAABB();
130 double min_x = sg_aabb->min()(0);
131 double min_y = sg_aabb->min()(1);
132 double max_x = sg_aabb->max()(0);
133 double max_y = sg_aabb->max()(1);
135 double gridlen = max_x - min_x;
136 double cell_size = gridlen / sett.
num_cells;
140 broadphase_manager_ =
new fcl::DynamicAABBTreeCollisionManager<double>;
144 broadphase_manager_ =
new fcl::SpatialHashingCollisionManager<double>(
145 cell_size, fcl::Vector3<double>(min_x, min_y, -
FCL_HEIGHT),
146 fcl::Vector3<double>(max_x, max_y,
FCL_HEIGHT),
151 broadphase_manager_ =
new fcl::IntervalTreeCollisionManager<double>;
156 broadphase_manager_ =
new fcl::SaPCollisionManager<double>;
161 broadphase_manager_ =
new fcl::SSaPCollisionManager<double>;
165 throw std::invalid_argument(
"Invalid FCL broadphase manager ID");
172 if (broadphase_manager_)
delete broadphase_manager_;
179 registerObjectId(obj);
180 aabbs_.push_back(aabb);
181 ObjectProxy proxy = CreateProxy(obj, aabbs_.back());
182 objects_.push_back(proxy);
201 numchecks_ += objects_.size();
202 getCandidates(proxy, collision_candidates);
207 for (
int i = 0; i < objects_optimized_id_.size(); i++) {
212 collision_candidates2.push_back(objects_optimized_id_[i]);
217 std::sort(collision_candidates2.begin(), collision_candidates2.end());
218 std::set<int> collision_candidates_set;
219 for (
auto el : collision_candidates) {
220 collision_candidates_set.insert(el);
222 std::sort(collision_candidates.begin(), collision_candidates.end());
223 int found_count = std::unique(collision_candidates.begin(),
224 collision_candidates.end()) -
225 collision_candidates.begin();
226 int real_count = std::unique(collision_candidates2.begin(),
227 collision_candidates2.end()) -
228 collision_candidates2.begin();
230 volatile int missed = real_count - found_count;
232 bool bMissed =
false;
234 for (
auto el : collision_candidates2) {
235 if (collision_candidates_set.find(el) ==
236 collision_candidates_set.end()) {
242 if (missed > 0 || bMissed) {
243 std::cout <<
"broadphase verification: miss\n";
244 throw std::exception();
250 collision_checked_id_.fill(0);
251 int numcands_local = 0;
254 std::vector<OBB_SAT2D, Eigen::aligned_allocator<OBB_SAT2D>>
256 obb1_fast_container.emplace_back(obb1->
center(), obb1->
r_x() * 2,
260 for (
auto el : collision_candidates) {
261 if ((el < 0) || (el >= fast_obbs_.size())) {
262 std::cout <<
"internal error";
263 throw std::exception();
265 if (!collision_checked_id_(el)) {
267 collision_checked_id_(el) = 1;
268 if (fast_obbs_[el].
overlaps(*(obb1_fast_container.begin())))
271 numcands_ += numcands_local;
277 for (
auto el : collision_candidates) {
278 if (!collision_checked_id_(el)) {
280 collision_checked_id_(el) = 1;
282 if (object_by_id_[el]->collide(*obj)) {
283 numcands_ += numcands_local;
289 numcands_ += numcands_local;
299 inline int finalizeCreation(
void) {
300 int total_objects = 0;
301 total_objects += objects_.size();
303 objects_optimized_id_.clear();
304 object_by_id_.clear();
305 object_by_id_.resize(object_ids_.size());
306 collision_checked_id_ = Eigen::VectorXi::Zero(object_ids_.size());
308 masks_optimized_ = VectorXi64::Zero(total_objects);
309 res_mask_optimized_ = Eigen::VectorXi::Zero(total_objects);
312 for (
auto el : objects_) {
318 objects_optimized_id_.push_back(getObjectId(el.obj_ptr));
319 object_by_id_[objects_optimized_id_.back()] = el.obj_ptr;
320 masks_optimized_[objects_optimized_id_.size() - 1] = el.mask;
321 auto curAABB = &aabbs_[objects_optimized_id_.back()];
323 (curAABB->x_max - curAABB->x_min) / 2,
324 (curAABB->y_max - curAABB->y_min) / 2,
325 Eigen::Vector2d((curAABB->x_max + curAABB->x_min) / 2,
326 (curAABB->y_max + curAABB->y_min) / 2)));
327 fcl_object_geometries_.emplace_back(rect->createFCLCollisionGeometry());
328 fcl_objects_.emplace_back(
329 fcl_object_geometries_.back(),
333 for (
auto id : objects_optimized_id_) {
334 fcl_objects_[id].setUserData(&objects_optimized_id_[
id]);
335 broadphase_manager_->registerObject(&fcl_objects_[
id]);
338 broadphase_manager_->setup();
348 Eigen::Vector2d((curAABB.
x_max + curAABB.
x_min) / 2,
350 auto cur_geom = std::shared_ptr<fcl::CollisionGeometry<FCL_PRECISION>>(
356 cur_obj.setUserData(0);
358 broadphase_manager_->collide(
359 &cur_obj, &reqData, ContainerFunctionWindowQueryFCL<FCL_PRECISION>);
364 auto search = object_ids_.find(obj);
365 if (search != object_ids_.end()) {
366 return search->second;
368 throw std::exception();
371 inline uint64_t get_mask(
const AABB& obj) {
return 0; }
375 uint64_t mask = get_mask(aabb);
381 object_ids_.insert(std::make_pair(obj, (
int)object_ids_.size()));
386 fast_obbs_.emplace_back(obb_in->
center(), obb_in->
r_x() * 2,
398 auto aabb_fcl = obj->
getAABB();
399 return AABB(*aabb_fcl);
403 fcl::BroadPhaseCollisionManagerd* broadphase_manager_;
405 std::vector<AABB> aabbs_;
406 std::vector<ObjectProxy> objects_;
408 std::vector<std::shared_ptr<fcl::CollisionGeometry<FCL_PRECISION>>>
409 fcl_object_geometries_;
410 std::vector<fcl::CollisionObject<FCL_PRECISION>> fcl_objects_;
412 VectorXi64 masks_optimized_;
413 Eigen::VectorXi res_mask_optimized_;
416 std::vector<OBB_SAT2D, Eigen::aligned_allocator<OBB_SAT2D>> fast_obbs_;
417 Eigen::VectorXi collision_checked_id_;
419 std::map<const CollisionObject*, int> object_ids_;
426 void constructHelper(
void) {
429 broadphase_manager_ = 0;
Eigen::Vector2d local_y_axis() const
std::vector< T, boost::alignment::aligned_allocator< T, 16 > > aligned_vector
#define TIMER_grid_narrowphase
virtual CollisionObjectClass getCollisionObjectClass() const
std::vector< ShapeConstPtr > unpack() const
Returns Vector of all shapes contained inside the ShapeGroup.
std::shared_ptr< const RectangleAABB > RectangleAABBConstPtr
Eigen::Matrix< uint64_t, Eigen::Dynamic, 1 > VectorXi64
std::shared_ptr< const collision::RectangleAABB > getAABB() const
bool collides_eps(const AABB_SAT2D &other, double eps)
ShapeGroup can contain simple shapes.
#define TIMER_grid_hashing
ContainerCollisionRequestDataFCL(aligned_vector< int > &candidates)
AABB getAABB(const CollisionObject *obj)
FCLContainerBroadphaseType
fcl::CollisionGeometry< FCL_PRECISION > * createFCLCollisionGeometry(void) const override
CollisionObject * obj_ptr
aligned_vector< int > * candidates_
EIGEN_MAKE_ALIGNED_OPERATOR_NEW ContainerFCL(aligned_vector< collision::CollisionObject *> objects_in, const ContainerSettings &sett)
virtual CollisionObjectType getCollisionObjectType() const
int addObject(const CollisionObject *obj)
virtual std::shared_ptr< const collision::RectangleAABB > getAABB() const =0
bool ContainerFunctionWindowQueryFCL(fcl::CollisionObject< S > *o1, fcl::CollisionObject< S > *o2, void *cdata_)
int checkCollision(const CollisionObject *obj, const ContainerCollisionRequest &req)
Base class for CollisionObjects and some of their groups.
Eigen::Vector2d local_x_axis() const
bool overlaps(const Triangle_SAT2D &tri, const OBB_SAT2D &obb)
#define TIMER_grid_candidates
Eigen::Vector2d center() const
Get geometric center of shape.
ContainerFCL(const ShapeGroup *sg_ptr, const ContainerSettings &sett)