| Directory: | ./ |
|---|---|
| File: | include/pinocchio/collision/broadphase-manager.hxx |
| Date: | 2025-02-12 21:03:38 |
| Exec | Total | Coverage | |
|---|---|---|---|
| Lines: | 103 | 128 | 80.5% |
| Branches: | 69 | 134 | 51.5% |
| Line | Branch | Exec | Source |
|---|---|---|---|
| 1 | // | ||
| 2 | // Copyright (c) 2022 INRIA | ||
| 3 | // | ||
| 4 | |||
| 5 | #ifndef __pinocchio_collision_broadphase_manager_hxx__ | ||
| 6 | #define __pinocchio_collision_broadphase_manager_hxx__ | ||
| 7 | |||
| 8 | namespace pinocchio | ||
| 9 | { | ||
| 10 | |||
| 11 | template<typename Manager> | ||
| 12 | 34069 | void BroadPhaseManagerTpl<Manager>::update(bool compute_local_aabb) | |
| 13 | { | ||
| 14 | 34069 | const GeometryModel & geom_model = getGeometryModel(); | |
| 15 |
1/2✗ Branch 2 not taken.
✓ Branch 3 taken 34069 times.
|
34069 | assert(selected_geometry_objects.size() == size_t(collision_object_inflation.size())); |
| 16 | |||
| 17 | 34069 | GeometryData & geom_data = getGeometryData(); | |
| 18 | |||
| 19 | // Pass 1: check the new active geometries and list the new deactive geometries | ||
| 20 | 34069 | std::vector<size_t> new_active, new_inactive; | |
| 21 |
2/2✓ Branch 1 taken 40082 times.
✓ Branch 2 taken 34069 times.
|
74151 | for (size_t k = 0; k < selected_geometry_objects.size(); ++k) |
| 22 | { | ||
| 23 | 40082 | const size_t geometry_object_id = selected_geometry_objects[k]; | |
| 24 | 40082 | const GeometryObject & geom_object = geom_model.geometryObjects[geometry_object_id]; | |
| 25 | |||
| 26 |
2/4✓ Branch 2 taken 40082 times.
✗ Branch 3 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 40082 times.
|
40082 | if (geom_object.geometry->aabb_local.volume() <= 0.) // degenerated geometry, we should not |
| 27 | // consider it as an active object. | ||
| 28 | { | ||
| 29 | ✗ | if (collision_object_is_active[k]) | |
| 30 | { | ||
| 31 | ✗ | collision_object_is_active[k] = false; | |
| 32 | ✗ | new_inactive.push_back(k); | |
| 33 | } | ||
| 34 | |||
| 35 | ✗ | continue; // don't go further and checks the next objects | |
| 36 | } | ||
| 37 | |||
| 38 |
2/4✓ Branch 1 taken 40082 times.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 40082 times.
|
40082 | if (collision_object_is_active[k] != !geom_object.disableCollision) // change state |
| 39 | { | ||
| 40 | ✗ | collision_object_is_active[k] = !geom_object.disableCollision; | |
| 41 | ✗ | if (geom_object.disableCollision) | |
| 42 | ✗ | new_inactive.push_back(k); | |
| 43 | else | ||
| 44 | ✗ | new_active.push_back(k); | |
| 45 | } | ||
| 46 | } | ||
| 47 | |||
| 48 | // The pass should be done over all the geometry objects composing the collision tree. | ||
| 49 |
1/2✓ Branch 1 taken 34069 times.
✗ Branch 2 not taken.
|
34069 | collision_object_inflation.setZero(); |
| 50 |
2/2✓ Branch 1 taken 2384760 times.
✓ Branch 2 taken 34069 times.
|
2418829 | for (size_t pair_id = 0; pair_id < geom_model.collisionPairs.size(); ++pair_id) |
| 51 | { | ||
| 52 | // TODO(jcarpent): enhance the performances by collecting only the collision pairs related to | ||
| 53 | // the selected_geometry_objects | ||
| 54 | 2384760 | const CollisionPair & pair = geom_model.collisionPairs[pair_id]; | |
| 55 | 2384760 | const GeomIndex geom1_id = pair.first; | |
| 56 | 2384760 | const GeomIndex geom2_id = pair.second; | |
| 57 | |||
| 58 | 2384760 | const bool geom1_is_selected = | |
| 59 | 2384760 | geometry_to_collision_index[geom1_id] != (std::numeric_limits<size_t>::max)(); | |
| 60 | 2384760 | const bool geom2_is_selected = | |
| 61 | 2384760 | geometry_to_collision_index[geom2_id] != (std::numeric_limits<size_t>::max)(); | |
| 62 |
4/4✓ Branch 0 taken 2244480 times.
✓ Branch 1 taken 140280 times.
✓ Branch 2 taken 2174340 times.
✓ Branch 3 taken 70140 times.
|
2384760 | if (!(geom1_is_selected || geom2_is_selected)) |
| 63 | 2174340 | continue; | |
| 64 | |||
| 65 | 210420 | const bool check_collision = geom_data.activeCollisionPairs[pair_id] | |
| 66 |
2/4✓ Branch 1 taken 210420 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 210420 times.
✗ Branch 5 not taken.
|
420840 | && !( |
| 67 |
1/2✓ Branch 1 taken 210420 times.
✗ Branch 2 not taken.
|
210420 | geom_model.geometryObjects[geom1_id].disableCollision |
| 68 |
1/2✓ Branch 1 taken 210420 times.
✗ Branch 2 not taken.
|
210420 | || geom_model.geometryObjects[geom2_id].disableCollision); |
| 69 | |||
| 70 |
1/2✗ Branch 0 not taken.
✓ Branch 1 taken 210420 times.
|
210420 | if (!check_collision) |
| 71 | ✗ | continue; | |
| 72 | |||
| 73 | 210420 | const ::hpp::fcl::CollisionRequest & cr = geom_data.collisionRequests[pair_id]; | |
| 74 | 210420 | const double inflation = (cr.break_distance + cr.security_margin) * 0.5; | |
| 75 | |||
| 76 |
2/2✓ Branch 0 taken 140280 times.
✓ Branch 1 taken 70140 times.
|
210420 | if (geom1_is_selected) |
| 77 | { | ||
| 78 | 140280 | const Eigen::DenseIndex geom1_id_local = | |
| 79 | 140280 | static_cast<Eigen::DenseIndex>(geometry_to_collision_index[geom1_id]); | |
| 80 |
1/2✓ Branch 1 taken 140280 times.
✗ Branch 2 not taken.
|
140280 | collision_object_inflation[geom1_id_local] = |
| 81 |
1/2✓ Branch 1 taken 140280 times.
✗ Branch 2 not taken.
|
140280 | (std::max)(inflation, collision_object_inflation[geom1_id_local]); |
| 82 | } | ||
| 83 | |||
| 84 |
2/2✓ Branch 0 taken 140280 times.
✓ Branch 1 taken 70140 times.
|
210420 | if (geom2_is_selected) |
| 85 | { | ||
| 86 | 140280 | const Eigen::DenseIndex geom2_id_local = | |
| 87 | 140280 | static_cast<Eigen::DenseIndex>(geometry_to_collision_index[geom2_id]); | |
| 88 |
1/2✓ Branch 1 taken 140280 times.
✗ Branch 2 not taken.
|
140280 | collision_object_inflation[geom2_id_local] = |
| 89 |
1/2✓ Branch 1 taken 140280 times.
✗ Branch 2 not taken.
|
140280 | (std::max)(inflation, collision_object_inflation[geom2_id_local]); |
| 90 | } | ||
| 91 | } | ||
| 92 | |||
| 93 |
2/2✓ Branch 3 taken 40082 times.
✓ Branch 4 taken 34069 times.
|
114233 | for (size_t k = 0; k < selected_geometry_objects.size(); ++k) |
| 94 | { | ||
| 95 |
2/4✓ Branch 1 taken 40082 times.
✗ Branch 2 not taken.
✗ Branch 4 not taken.
✓ Branch 5 taken 40082 times.
|
40082 | if (!collision_object_is_active[k]) |
| 96 | ✗ | continue; | |
| 97 | |||
| 98 | 40082 | const size_t geometry_object_id = selected_geometry_objects[k]; | |
| 99 | |||
| 100 | 40082 | const GeometryObject & geom_obj = geom_model.geometryObjects[geometry_object_id]; | |
| 101 | 40082 | hpp::fcl::CollisionGeometryPtr_t new_geometry = geom_obj.geometry; | |
| 102 | |||
| 103 | 40082 | CollisionObject & collision_obj = collision_objects[k]; | |
| 104 | 40082 | hpp::fcl::CollisionGeometryPtr_t geometry = collision_obj.collisionGeometry(); | |
| 105 | |||
| 106 |
2/4✓ Branch 2 taken 40082 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 40082 times.
✗ Branch 6 not taken.
|
40082 | collision_obj.setTransform(toFclTransform3f(geom_data.oMg[geometry_object_id])); |
| 107 | |||
| 108 |
2/2✓ Branch 2 taken 1 times.
✓ Branch 3 taken 40081 times.
|
40082 | if (new_geometry.get() != geometry.get()) |
| 109 |
1/2✓ Branch 1 taken 1 times.
✗ Branch 2 not taken.
|
1 | collision_obj.setCollisionGeometry(new_geometry, compute_local_aabb); |
| 110 | |||
| 111 |
1/2✓ Branch 1 taken 40082 times.
✗ Branch 2 not taken.
|
40082 | collision_obj.computeAABB(); |
| 112 |
2/4✓ Branch 2 taken 40082 times.
✗ Branch 3 not taken.
✓ Branch 5 taken 40082 times.
✗ Branch 6 not taken.
|
40082 | collision_obj.getAABB().expand(collision_object_inflation[static_cast<Eigen::DenseIndex>(k)]); |
| 113 | } | ||
| 114 | |||
| 115 | // Remove deactivated collision objects | ||
| 116 |
1/2✗ Branch 5 not taken.
✓ Branch 6 taken 34069 times.
|
34069 | for (size_t k : new_inactive) |
| 117 | ✗ | manager.unregisterObject(&collision_objects[k]); | |
| 118 | |||
| 119 | // Add deactivated collision objects | ||
| 120 |
1/2✗ Branch 5 not taken.
✓ Branch 6 taken 34069 times.
|
34069 | for (size_t k : new_active) |
| 121 | ✗ | manager.registerObject(&collision_objects[k]); | |
| 122 | |||
| 123 |
1/2✓ Branch 1 taken 34069 times.
✗ Branch 2 not taken.
|
34069 | manager.update(); // because the position has changed. |
| 124 |
2/4✓ Branch 1 taken 34069 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 34069 times.
✗ Branch 4 not taken.
|
34069 | assert(check() && "The status of the BroadPhaseManager is not valid"); |
| 125 | 34069 | } | |
| 126 | |||
| 127 | template<typename Manager> | ||
| 128 | ✗ | void BroadPhaseManagerTpl<Manager>::update(GeometryData * geom_data_ptr_new) | |
| 129 | { | ||
| 130 | ✗ | Base::geometry_data_ptr = geom_data_ptr_new; | |
| 131 | ✗ | update(false); | |
| 132 | } | ||
| 133 | |||
| 134 | template<typename Manager> | ||
| 135 | 104 | BroadPhaseManagerTpl<Manager>::~BroadPhaseManagerTpl() | |
| 136 | { | ||
| 137 | 104 | } | |
| 138 | |||
| 139 | template<typename Manager> | ||
| 140 | 34107 | bool BroadPhaseManagerTpl<Manager>::check() const | |
| 141 | { | ||
| 142 |
1/2✓ Branch 1 taken 34107 times.
✗ Branch 2 not taken.
|
34107 | std::vector<hpp::fcl::CollisionObject *> collision_objects_ptr = manager.getObjects(); |
| 143 |
1/2✗ Branch 2 not taken.
✓ Branch 3 taken 34107 times.
|
34107 | if (collision_objects_ptr.size() > collision_objects.size()) |
| 144 | ✗ | return false; | |
| 145 | |||
| 146 | 34107 | size_t count_active_objects = 0; | |
| 147 |
2/2✓ Branch 4 taken 40108 times.
✓ Branch 5 taken 34107 times.
|
74215 | for (auto active : collision_object_is_active) |
| 148 | 40108 | count_active_objects += active; | |
| 149 | |||
| 150 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 34107 times.
|
34107 | if (count_active_objects != collision_objects_ptr.size()) |
| 151 | ✗ | return false; | |
| 152 | |||
| 153 | 34107 | const GeometryModel & geom_model = getGeometryModel(); | |
| 154 |
4/4✓ Branch 1 taken 40106 times.
✓ Branch 2 taken 1 times.
✓ Branch 4 taken 40107 times.
✓ Branch 5 taken 34106 times.
|
114320 | for (size_t k = 0; k < selected_geometry_objects.size(); ++k) |
| 155 | { | ||
| 156 | 40107 | const size_t geometry_id = selected_geometry_objects[k]; | |
| 157 | |||
| 158 | 40107 | const hpp::fcl::CollisionObject & collision_obj = collision_objects[k]; | |
| 159 | 40107 | hpp::fcl::CollisionGeometryConstPtr_t geometry = collision_obj.collisionGeometry(); | |
| 160 | |||
| 161 |
2/4✓ Branch 1 taken 40107 times.
✗ Branch 2 not taken.
✓ Branch 3 taken 40107 times.
✗ Branch 4 not taken.
|
40107 | if (collision_object_is_active[k]) // The collision object is active |
| 162 | { | ||
| 163 | 40107 | if ( | |
| 164 |
1/2✓ Branch 3 taken 40107 times.
✗ Branch 4 not taken.
|
40107 | std::find(collision_objects_ptr.begin(), collision_objects_ptr.end(), &collision_obj) |
| 165 |
1/2✗ Branch 2 not taken.
✓ Branch 3 taken 40107 times.
|
80214 | == collision_objects_ptr.end()) |
| 166 | 1 | return false; | |
| 167 | |||
| 168 | 40107 | if ( | |
| 169 |
1/2✓ Branch 2 taken 40107 times.
✗ Branch 3 not taken.
|
40107 | geometry.get()->aabb_local.volume() |
| 170 |
1/2✗ Branch 1 not taken.
✓ Branch 2 taken 40107 times.
|
40107 | == -(std::numeric_limits<hpp::fcl::FCL_REAL>::infinity)()) |
| 171 | ✗ | return false; | |
| 172 | |||
| 173 | 40107 | const GeometryObject & geom_obj = geom_model.geometryObjects[geometry_id]; | |
| 174 | 40107 | hpp::fcl::CollisionGeometryConstPtr_t geometry_of_geom_obj = geom_obj.geometry; | |
| 175 | |||
| 176 |
2/2✓ Branch 2 taken 1 times.
✓ Branch 3 taken 40106 times.
|
40107 | if (geometry.get() != geometry_of_geom_obj.get()) |
| 177 | 1 | return false; | |
| 178 |
2/2✓ Branch 1 taken 40106 times.
✓ Branch 2 taken 1 times.
|
40107 | } |
| 179 | else | ||
| 180 | { | ||
| 181 | ✗ | if ( | |
| 182 | ✗ | std::find(collision_objects_ptr.begin(), collision_objects_ptr.end(), &collision_obj) | |
| 183 | ✗ | != collision_objects_ptr.end()) | |
| 184 | ✗ | return false; | |
| 185 | } | ||
| 186 | } | ||
| 187 | |||
| 188 | 34106 | return true; | |
| 189 | 34107 | } | |
| 190 | |||
| 191 | template<typename Manager> | ||
| 192 | 34136 | bool BroadPhaseManagerTpl<Manager>::check(CollisionCallBackBase * callback) const | |
| 193 | { | ||
| 194 | 34136 | return &callback->getGeometryModel() == &getGeometryModel() | |
| 195 |
2/4✓ Branch 0 taken 34136 times.
✗ Branch 1 not taken.
✓ Branch 4 taken 34136 times.
✗ Branch 5 not taken.
|
34136 | && &callback->getGeometryData() == &getGeometryData(); |
| 196 | } | ||
| 197 | |||
| 198 | template<typename Manager> | ||
| 199 | 104 | void BroadPhaseManagerTpl<Manager>::init() | |
| 200 | { | ||
| 201 | 104 | const GeometryModel & geom_model = getGeometryModel(); | |
| 202 | 104 | collision_objects.reserve(selected_geometry_objects.size()); | |
| 203 |
2/2✓ Branch 1 taken 82 times.
✓ Branch 2 taken 104 times.
|
186 | for (size_t k = 0; k < selected_geometry_objects.size(); ++k) |
| 204 | { | ||
| 205 | 82 | const size_t geometry_id = selected_geometry_objects[k]; | |
| 206 | GeometryObject & geom_obj = | ||
| 207 | 82 | const_cast<GeometryObject &>(geom_model.geometryObjects[geometry_id]); | |
| 208 |
1/2✓ Branch 2 taken 82 times.
✗ Branch 3 not taken.
|
82 | collision_objects.push_back(CollisionObject(geom_obj.geometry, geometry_id)); |
| 209 | |||
| 210 | // Feed the base broadphase manager | ||
| 211 |
1/2✓ Branch 2 taken 82 times.
✗ Branch 3 not taken.
|
82 | if (collision_object_is_active[k]) |
| 212 | 82 | manager.registerObject(&collision_objects.back()); | |
| 213 | } | ||
| 214 | 104 | } | |
| 215 | |||
| 216 | template<typename Manager> | ||
| 217 | ✗ | bool BroadPhaseManagerTpl<Manager>::collide( | |
| 218 | CollisionObject & obj, CollisionCallBackBase * callback) const | ||
| 219 | { | ||
| 220 | ✗ | manager.collide(&obj, callback); | |
| 221 | ✗ | return callback->collision; | |
| 222 | } | ||
| 223 | |||
| 224 | template<typename Manager> | ||
| 225 | 1004 | bool BroadPhaseManagerTpl<Manager>::collide(CollisionCallBackBase * callback) const | |
| 226 | { | ||
| 227 | 1004 | manager.collide(callback); | |
| 228 | 1004 | return callback->collision; | |
| 229 | } | ||
| 230 | |||
| 231 | template<typename Manager> | ||
| 232 | 530112 | bool BroadPhaseManagerTpl<Manager>::collide( | |
| 233 | BroadPhaseManagerTpl & other_manager, CollisionCallBackBase * callback) const | ||
| 234 | { | ||
| 235 | 530112 | manager.collide(&other_manager.manager, callback); | |
| 236 | 530112 | return callback->collision; | |
| 237 | } | ||
| 238 | |||
| 239 | } // namespace pinocchio | ||
| 240 | |||
| 241 | #endif // ifndef __pinocchio_collision_broadphase_manager_hxx__ | ||
| 242 |