GCC Code Coverage Report


Directory: ./
File: include/pinocchio/collision/broadphase-manager.hxx
Date: 2024-08-27 18:20:05
Exec Total Coverage
Lines: 0 123 0.0%
Branches: 0 134 0.0%

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 void BroadPhaseManagerTpl<Manager>::update(bool compute_local_aabb)
13 {
14 const GeometryModel & geom_model = getGeometryModel();
15 assert(selected_geometry_objects.size() == size_t(collision_object_inflation.size()));
16
17 GeometryData & geom_data = getGeometryData();
18
19 // Pass 1: check the new active geometries and list the new deactive geometries
20 std::vector<size_t> new_active, new_inactive;
21 for (size_t k = 0; k < selected_geometry_objects.size(); ++k)
22 {
23 const size_t geometry_object_id = selected_geometry_objects[k];
24 const GeometryObject & geom_object = geom_model.geometryObjects[geometry_object_id];
25
26 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 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 collision_object_inflation.setZero();
50 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 const CollisionPair & pair = geom_model.collisionPairs[pair_id];
55 const GeomIndex geom1_id = pair.first;
56 const GeomIndex geom2_id = pair.second;
57
58 const bool geom1_is_selected =
59 geometry_to_collision_index[geom1_id] != (std::numeric_limits<size_t>::max)();
60 const bool geom2_is_selected =
61 geometry_to_collision_index[geom2_id] != (std::numeric_limits<size_t>::max)();
62 if (!(geom1_is_selected || geom2_is_selected))
63 continue;
64
65 const bool check_collision = geom_data.activeCollisionPairs[pair_id]
66 && !(
67 geom_model.geometryObjects[geom1_id].disableCollision
68 || geom_model.geometryObjects[geom2_id].disableCollision);
69
70 if (!check_collision)
71 continue;
72
73 const ::hpp::fcl::CollisionRequest & cr = geom_data.collisionRequests[pair_id];
74 const double inflation = (cr.break_distance + cr.security_margin) * 0.5;
75
76 if (geom1_is_selected)
77 {
78 const Eigen::DenseIndex geom1_id_local =
79 static_cast<Eigen::DenseIndex>(geometry_to_collision_index[geom1_id]);
80 collision_object_inflation[geom1_id_local] =
81 (std::max)(inflation, collision_object_inflation[geom1_id_local]);
82 }
83
84 if (geom2_is_selected)
85 {
86 const Eigen::DenseIndex geom2_id_local =
87 static_cast<Eigen::DenseIndex>(geometry_to_collision_index[geom2_id]);
88 collision_object_inflation[geom2_id_local] =
89 (std::max)(inflation, collision_object_inflation[geom2_id_local]);
90 }
91 }
92
93 for (size_t k = 0; k < selected_geometry_objects.size(); ++k)
94 {
95 if (!collision_object_is_active[k])
96 continue;
97
98 const size_t geometry_object_id = selected_geometry_objects[k];
99
100 const GeometryObject & geom_obj = geom_model.geometryObjects[geometry_object_id];
101 hpp::fcl::CollisionGeometryPtr_t new_geometry = geom_obj.geometry;
102
103 CollisionObject & collision_obj = collision_objects[k];
104 hpp::fcl::CollisionGeometryPtr_t geometry = collision_obj.collisionGeometry();
105
106 collision_obj.setTransform(toFclTransform3f(geom_data.oMg[geometry_object_id]));
107
108 if (new_geometry.get() != geometry.get())
109 collision_obj.setCollisionGeometry(new_geometry, compute_local_aabb);
110
111 collision_obj.computeAABB();
112 collision_obj.getAABB().expand(collision_object_inflation[static_cast<Eigen::DenseIndex>(k)]);
113 }
114
115 // Remove deactivated collision objects
116 for (size_t k : new_inactive)
117 manager.unregisterObject(&collision_objects[k]);
118
119 // Add deactivated collision objects
120 for (size_t k : new_active)
121 manager.registerObject(&collision_objects[k]);
122
123 manager.update(); // because the position has changed.
124 assert(check() && "The status of the BroadPhaseManager is not valid");
125 }
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 BroadPhaseManagerTpl<Manager>::~BroadPhaseManagerTpl()
136 {
137 }
138
139 template<typename Manager>
140 bool BroadPhaseManagerTpl<Manager>::check() const
141 {
142 std::vector<hpp::fcl::CollisionObject *> collision_objects_ptr = manager.getObjects();
143 if (collision_objects_ptr.size() > collision_objects.size())
144 return false;
145
146 size_t count_active_objects = 0;
147 for (auto active : collision_object_is_active)
148 count_active_objects += active;
149
150 if (count_active_objects != collision_objects_ptr.size())
151 return false;
152
153 const GeometryModel & geom_model = getGeometryModel();
154 for (size_t k = 0; k < selected_geometry_objects.size(); ++k)
155 {
156 const size_t geometry_id = selected_geometry_objects[k];
157
158 const hpp::fcl::CollisionObject & collision_obj = collision_objects[k];
159 hpp::fcl::CollisionGeometryConstPtr_t geometry = collision_obj.collisionGeometry();
160
161 if (collision_object_is_active[k]) // The collision object is active
162 {
163 if (
164 std::find(collision_objects_ptr.begin(), collision_objects_ptr.end(), &collision_obj)
165 == collision_objects_ptr.end())
166 return false;
167
168 if (
169 geometry.get()->aabb_local.volume()
170 == -(std::numeric_limits<hpp::fcl::FCL_REAL>::infinity)())
171 return false;
172
173 const GeometryObject & geom_obj = geom_model.geometryObjects[geometry_id];
174 hpp::fcl::CollisionGeometryConstPtr_t geometry_of_geom_obj = geom_obj.geometry;
175
176 if (geometry.get() != geometry_of_geom_obj.get())
177 return false;
178 }
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 return true;
189 }
190
191 template<typename Manager>
192 bool BroadPhaseManagerTpl<Manager>::check(CollisionCallBackBase * callback) const
193 {
194 return &callback->getGeometryModel() == &getGeometryModel()
195 && &callback->getGeometryData() == &getGeometryData();
196 }
197
198 template<typename Manager>
199 void BroadPhaseManagerTpl<Manager>::init()
200 {
201 const GeometryModel & geom_model = getGeometryModel();
202 collision_objects.reserve(selected_geometry_objects.size());
203 for (size_t k = 0; k < selected_geometry_objects.size(); ++k)
204 {
205 const size_t geometry_id = selected_geometry_objects[k];
206 GeometryObject & geom_obj =
207 const_cast<GeometryObject &>(geom_model.geometryObjects[geometry_id]);
208 collision_objects.push_back(CollisionObject(geom_obj.geometry, geometry_id));
209
210 // Feed the base broadphase manager
211 if (collision_object_is_active[k])
212 manager.registerObject(&collision_objects.back());
213 }
214 }
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 bool BroadPhaseManagerTpl<Manager>::collide(CollisionCallBackBase * callback) const
226 {
227 manager.collide(callback);
228 return callback->collision;
229 }
230
231 template<typename Manager>
232 bool BroadPhaseManagerTpl<Manager>::collide(
233 BroadPhaseManagerTpl & other_manager, CollisionCallBackBase * callback) const
234 {
235 manager.collide(&other_manager.manager, callback);
236 return callback->collision;
237 }
238
239 } // namespace pinocchio
240
241 #endif // ifndef __pinocchio_collision_broadphase_manager_hxx__
242