FCL  0.6.0
Flexible Collision Library
shape_mesh_collision_traversal_node-inl.h
1 /*
2  * Software License Agreement (BSD License)
3  *
4  * Copyright (c) 2011-2014, Willow Garage, Inc.
5  * Copyright (c) 2014-2016, Open Source Robotics Foundation
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * * Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  * * Redistributions in binary form must reproduce the above
15  * copyright notice, this list of conditions and the following
16  * disclaimer in the documentation and/or other materials provided
17  * with the distribution.
18  * * Neither the name of Open Source Robotics Foundation nor the names of its
19  * contributors may be used to endorse or promote products derived
20  * from this software without specific prior written permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
28  * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
29  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
30  * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
31  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
32  * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33  * POSSIBILITY OF SUCH DAMAGE.
34  */
35 
38 #ifndef FCL_TRAVERSAL_SHAPEMESHCOLLISIONTRAVERSALNODE_INL_H
39 #define FCL_TRAVERSAL_SHAPEMESHCOLLISIONTRAVERSALNODE_INL_H
40 
41 #include "fcl/narrowphase/detail/traversal/collision/shape_mesh_collision_traversal_node.h"
42 
43 namespace fcl
44 {
45 
46 namespace detail
47 {
48 
49 //==============================================================================
50 template <typename Shape, typename BV, typename NarrowPhaseSolver>
51 ShapeMeshCollisionTraversalNode<Shape, BV, NarrowPhaseSolver>::ShapeMeshCollisionTraversalNode()
52  : ShapeBVHCollisionTraversalNode<Shape, BV>()
53 {
54  vertices = nullptr;
55  tri_indices = nullptr;
56 
57  nsolver = nullptr;
58 }
59 
60 //==============================================================================
61 template <typename Shape, typename BV, typename NarrowPhaseSolver>
63 {
64  using S = typename BV::S;
65 
66  if(this->enable_statistics) this->num_leaf_tests++;
67  const BVNode<BV>& node = this->model2->getBV(b2);
68 
69  int primitive_id = node.primitiveId();
70 
71  const Triangle& tri_id = tri_indices[primitive_id];
72 
73  const Vector3<S>& p1 = vertices[tri_id[0]];
74  const Vector3<S>& p2 = vertices[tri_id[1]];
75  const Vector3<S>& p3 = vertices[tri_id[2]];
76 
77  if(this->model1->isOccupied() && this->model2->isOccupied())
78  {
79  bool is_intersect = false;
80 
81  if(!this->request.enable_contact)
82  {
83  if(nsolver->shapeTriangleIntersect(*(this->model1), this->tf1, p1, p2, p3, nullptr, nullptr, nullptr))
84  {
85  is_intersect = true;
86  if(this->request.num_max_contacts > this->result->numContacts())
87  this->result->addContact(Contact<S>(this->model1, this->model2, Contact<S>::NONE, primitive_id));
88  }
89  }
90  else
91  {
92  S penetration;
93  Vector3<S> normal;
94  Vector3<S> contactp;
95 
96  if(nsolver->shapeTriangleIntersect(*(this->model1), this->tf1, p1, p2, p3, &contactp, &penetration, &normal))
97  {
98  is_intersect = true;
99  if(this->request.num_max_contacts > this->result->numContacts())
100  this->result->addContact(Contact<S>(this->model1, this->model2, Contact<S>::NONE, primitive_id, contactp, normal, penetration));
101  }
102  }
103 
104  if(is_intersect && this->request.enable_cost)
105  {
106  AABB<S> overlap_part;
107  AABB<S> shape_aabb;
108  computeBV(*(this->model1), this->tf1, shape_aabb);
109  AABB<S>(p1, p2, p3).overlap(shape_aabb, overlap_part);
110  this->result->addCostSource(CostSource<S>(overlap_part, cost_density), this->request.num_max_cost_sources);
111  }
112  }
113  else if((!this->model1->isFree() && !this->model2->isFree()) && this->request.enable_cost)
114  {
115  if(nsolver->shapeTriangleIntersect(*(this->model1), this->tf1, p1, p2, p3, nullptr, nullptr, nullptr))
116  {
117  AABB<S> overlap_part;
118  AABB<S> shape_aabb;
119  computeBV(*(this->model1), this->tf1, shape_aabb);
120  AABB<S>(p1, p2, p3).overlap(shape_aabb, overlap_part);
121  this->result->addCostSource(CostSource<S>(overlap_part, cost_density), this->request.num_max_cost_sources);
122  }
123  }
124 }
125 
126 //==============================================================================
127 template <typename Shape, typename BV, typename NarrowPhaseSolver>
129 {
130  return this->request.isSatisfied(*(this->result));
131 }
132 
133 //==============================================================================
134 template <typename Shape, typename BV, typename NarrowPhaseSolver>
135 bool initialize(
137  const Shape& model1,
138  const Transform3<typename BV::S>& tf1,
139  BVHModel<BV>& model2,
140  Transform3<typename BV::S>& tf2,
141  const NarrowPhaseSolver* nsolver,
144  bool use_refit,
145  bool refit_bottomup)
146 {
147  using S = typename BV::S;
148 
149  if(model2.getModelType() != BVH_MODEL_TRIANGLES)
150  return false;
151 
152  if(!tf2.matrix().isIdentity())
153  {
154  std::vector<Vector3<S>> vertices_transformed(model2.num_vertices);
155  for(int i = 0; i < model2.num_vertices; ++i)
156  {
157  Vector3<S>& p = model2.vertices[i];
158  Vector3<S> new_v = tf2 * p;
159  vertices_transformed[i] = new_v;
160  }
161 
162  model2.beginReplaceModel();
163  model2.replaceSubModel(vertices_transformed);
164  model2.endReplaceModel(use_refit, refit_bottomup);
165 
166  tf2.setIdentity();
167  }
168 
169  node.model1 = &model1;
170  node.tf1 = tf1;
171  node.model2 = &model2;
172  node.tf2 = tf2;
173  node.nsolver = nsolver;
174 
175  computeBV(model1, tf1, node.model1_bv);
176 
177  node.vertices = model2.vertices;
178  node.tri_indices = model2.tri_indices;
179 
180  node.request = request;
181  node.result = &result;
182 
183  node.cost_density = model1.cost_density * model2.cost_density;
184 
185  return true;
186 }
187 
188 //==============================================================================
189 template <typename Shape, typename NarrowPhaseSolver>
191 {
192 }
193 
194 //==============================================================================
195 template <typename Shape, typename NarrowPhaseSolver>
197 {
198  if(this->enable_statistics) this->num_bv_tests++;
199  return !overlap(this->tf2.linear(), this->tf2.translation(), this->model1_bv, this->model2->getBV(b2).bv);
200 }
201 
202 //==============================================================================
203 template <typename Shape, typename NarrowPhaseSolver>
205 {
206  detail::meshShapeCollisionOrientedNodeLeafTesting(b2, b1, *(this->model2), this->model1, this->vertices, this->tri_indices,
207  this->tf2, this->tf1, this->nsolver, this->enable_statistics, this->cost_density, this->num_leaf_tests, this->request, *(this->request));
208 
209  // may need to change the order in pairs
210 }
211 
212 //==============================================================================
213 template <typename Shape, typename NarrowPhaseSolver>
215 {
216 }
217 
218 //==============================================================================
219 template <typename Shape, typename NarrowPhaseSolver>
221 {
222  if(this->enable_statistics) this->num_bv_tests++;
223  return !overlap(this->tf2.linear(), this->tf2.translation(), this->model1_bv, this->model2->getBV(b2).bv);
224 }
225 
226 //==============================================================================
227 template <typename Shape, typename NarrowPhaseSolver>
229 {
230  detail::meshShapeCollisionOrientedNodeLeafTesting(b2, b1, *(this->model2), this->model1, this->vertices, this->tri_indices,
231  this->tf2, this->tf1, this->nsolver, this->enable_statistics, this->cost_density, this->num_leaf_tests, this->request, *(this->request));
232 
233  // may need to change the order in pairs
234 }
235 
236 //==============================================================================
237 template <typename Shape, typename NarrowPhaseSolver>
239 {
240 }
241 
242 //==============================================================================
243 template <typename Shape, typename NarrowPhaseSolver>
245 {
246  if(this->enable_statistics) this->num_bv_tests++;
247  return !overlap(this->tf2.linear(), this->tf2.translation(), this->model1_bv, this->model2->getBV(b2).bv);
248 }
249 
250 //==============================================================================
251 template <typename Shape, typename NarrowPhaseSolver>
253 {
254  detail::meshShapeCollisionOrientedNodeLeafTesting(b2, b1, *(this->model2), this->model1, this->vertices, this->tri_indices,
255  this->tf2, this->tf1, this->nsolver, this->enable_statistics, this->cost_density, this->num_leaf_tests, this->request, *(this->request));
256 
257  // may need to change the order in pairs
258 }
259 
260 //==============================================================================
261 template <typename Shape, typename NarrowPhaseSolver>
263 {
264 }
265 
266 //==============================================================================
267 template <typename Shape, typename NarrowPhaseSolver>
269 {
270  if(this->enable_statistics) this->num_bv_tests++;
271  return !overlap(this->tf2.linear(), this->tf2.translation(), this->model1_bv, this->model2->getBV(b2).bv);
272 }
273 
274 //==============================================================================
275 template <typename Shape, typename NarrowPhaseSolver>
277 {
278  detail::meshShapeCollisionOrientedNodeLeafTesting(b2, b1, *(this->model2), this->model1, this->vertices, this->tri_indices,
279  this->tf2, this->tf1, this->nsolver, this->enable_statistics, this->cost_density, this->num_leaf_tests, this->request, *(this->request));
280 
281  // may need to change the order in pairs
282 }
283 
284 template <typename Shape, typename BV, typename NarrowPhaseSolver, template <typename, typename> class OrientedNode>
285 static bool setupShapeMeshCollisionOrientedNode(OrientedNode<Shape, NarrowPhaseSolver>& node,
286  const Shape& model1, const Transform3<typename BV::S>& tf1,
287  const BVHModel<BV>& model2, const Transform3<typename BV::S>& tf2,
288  const NarrowPhaseSolver* nsolver,
289  const CollisionRequest<typename BV::S>& request,
291 {
292  if(model2.getModelType() != BVH_MODEL_TRIANGLES)
293  return false;
294 
295  node.model1 = &model1;
296  node.tf1 = tf1;
297  node.model2 = &model2;
298  node.tf2 = tf2;
299  node.nsolver = nsolver;
300 
301  computeBV(model1, tf1, node.model1_bv);
302 
303  node.vertices = model2.vertices;
304  node.tri_indices = model2.tri_indices;
305 
306  node.request = request;
307  node.result = &result;
308 
309  node.cost_density = model1.cost_density * model2.cost_density;
310 
311  return true;
312 }
313 
314 //==============================================================================
315 template <typename Shape, typename NarrowPhaseSolver>
316 bool initialize(
318  const Shape& model1,
319  const Transform3<typename Shape::S>& tf1,
320  const BVHModel<OBB<typename Shape::S>>& model2,
321  const Transform3<typename Shape::S>& tf2,
322  const NarrowPhaseSolver* nsolver,
325 {
326  return detail::setupShapeMeshCollisionOrientedNode(
327  node, model1, tf1, model2, tf2, nsolver, request, result);
328 }
329 
330 //==============================================================================
331 template <typename Shape, typename NarrowPhaseSolver>
332 bool initialize(
334  const Shape& model1,
335  const Transform3<typename Shape::S>& tf1,
336  const BVHModel<RSS<typename Shape::S>>& model2,
337  const Transform3<typename Shape::S>& tf2,
338  const NarrowPhaseSolver* nsolver,
341 {
342  return detail::setupShapeMeshCollisionOrientedNode(
343  node, model1, tf1, model2, tf2, nsolver, request, result);
344 }
345 
346 //==============================================================================
347 template <typename Shape, typename NarrowPhaseSolver>
348 bool initialize(
350  const Shape& model1,
351  const Transform3<typename Shape::S>& tf1,
352  const BVHModel<kIOS<typename Shape::S>>& model2,
353  const Transform3<typename Shape::S>& tf2,
354  const NarrowPhaseSolver* nsolver,
357 {
358  return detail::setupShapeMeshCollisionOrientedNode(
359  node, model1, tf1, model2, tf2, nsolver, request, result);
360 }
361 
362 //==============================================================================
363 template <typename Shape, typename NarrowPhaseSolver>
364 bool initialize(
366  const Shape& model1,
367  const Transform3<typename Shape::S>& tf1,
368  const BVHModel<OBBRSS<typename Shape::S>>& model2,
369  const Transform3<typename Shape::S>& tf2,
370  const NarrowPhaseSolver* nsolver,
373 {
374  return detail::setupShapeMeshCollisionOrientedNode(
375  node, model1, tf1, model2, tf2, nsolver, request, result);
376 }
377 
378 } // namespace detail
379 } // namespace fcl
380 
381 #endif
bool enable_cost
whether the cost sources will be computed
Definition: collision_request.h:64
bool enable_statistics
Whether stores statistics.
Definition: collision_traversal_node_base.h:78
void addCostSource(const CostSource< S > &c, std::size_t num_max_cost_sources)
add one cost source into result structure
Definition: collision_result-inl.h:66
size_t num_max_contacts
The maximum number of contacts will return.
Definition: collision_request.h:55
Main namespace.
Definition: broadphase_bruteforce-inl.h:45
int replaceSubModel(const std::vector< Vector3< S >> &ps)
Replace a set of points in the old BVH model.
Definition: BVH_model-inl.h:559
collision result
Definition: collision_request.h:48
A class for rectangle sphere-swept bounding volume.
Definition: RSS.h:49
int beginReplaceModel()
Replace the geometry information of current frame (i.e. should have the same mesh topology with the p...
Definition: BVH_model-inl.h:508
BVHModelType getModelType() const
Model type described by the instance.
Definition: BVH_model-inl.h:48
bool overlap(const Eigen::MatrixBase< DerivedA > &R0, const Eigen::MatrixBase< DerivedB > &T0, const kIOS< S > &b1, const kIOS< S > &b2)
Check collision between two kIOSs, b1 is in configuration (R0, T0) and b2 is in identity.
Definition: kIOS-inl.h:249
const BVNode< BV > & getBV(int id) const
We provide getBV() and getNumBVs() because BVH may be compressed (in future), so we must provide some...
Definition: BVH_model-inl.h:160
Definition: shape_mesh_collision_traversal_node.h:116
Transform3< Shape1::S > tf2
configuration of second object
Definition: traversal_node_base.h:88
void leafTesting(int b1, int b2) const
Intersection testing between leaves (one shape and one triangle)
Definition: shape_mesh_collision_traversal_node-inl.h:62
Contact information returned by collision.
Definition: contact.h:48
bool BVTesting(int b1, int b2) const
BV test between b1 and b2.
Definition: shape_mesh_collision_traversal_node-inl.h:268
Vector3< S > * vertices
Geometry point data.
Definition: BVH_model.h:162
void leafTesting(int b1, int b2) const
Leaf test between node b1 and b2, if they are both leafs.
Definition: shape_mesh_collision_traversal_node-inl.h:252
bool BVTesting(int b1, int b2) const
BV test between b1 and b2.
Definition: shape_mesh_collision_traversal_node-inl.h:220
int num_vertices
Number of points.
Definition: BVH_model.h:174
CollisionRequest< Shape1::S > request
request setting for collision
Definition: collision_traversal_node_base.h:72
int primitiveId() const
Return the primitive index. The index is referred to the original data (i.e. vertices or tri_indices)...
Definition: BV_node_base.cpp:50
Triangle * tri_indices
Geometry triangle index data, will be nullptr for point clouds.
Definition: BVH_model.h:165
Triangle with 3 indices for points.
Definition: triangle.h:47
unknown model type
Definition: BVH_internal.h:78
bool enable_contact
whether the contact information (normal, penetration depth and contact position) will return ...
Definition: collision_request.h:58
Traversal node for collision between shape and mesh.
Definition: shape_mesh_collision_traversal_node.h:52
request to the collision algorithm
Definition: collision_request.h:52
size_t num_max_cost_sources
The maximum number of cost sources will return.
Definition: collision_request.h:61
void leafTesting(int b1, int b2) const
Leaf test between node b1 and b2, if they are both leafs.
Definition: shape_mesh_collision_traversal_node-inl.h:228
void computeBV(const Shape &s, const Transform3< typename BV::S > &tf, BV &bv)
calculate a bounding volume for a shape in a specific configuration
Definition: utility-inl.h:1049
bool BVTesting(int b1, int b2) const
BV test between b1 and b2.
Definition: shape_mesh_collision_traversal_node-inl.h:196
A class describing the bounding hierarchy of a mesh model or a point cloud model (which is viewed as ...
Definition: BVH_model.h:57
BV::S cost_density
collision cost for unit volume
Definition: collision_geometry.h:103
CollisionResult< Shape1::S > * result
collision result kept during the traversal iteration
Definition: collision_traversal_node_base.h:75
A class describing a bounding volume node. It includes the tree structure providing in BVNodeBase and...
Definition: BV_node.h:52
Transform3< Shape1::S > tf1
configuation of first object
Definition: traversal_node_base.h:85
Cost source describes an area with a cost. The area is described by an AABB<S> region.
Definition: cost_source.h:49
void leafTesting(int b1, int b2) const
Leaf test between node b1 and b2, if they are both leafs.
Definition: shape_mesh_collision_traversal_node-inl.h:204
Definition: shape_mesh_collision_traversal_node.h:168
bool canStop() const
Whether the traversal process can stop early.
Definition: shape_mesh_collision_traversal_node-inl.h:128
Definition: shape_mesh_collision_traversal_node.h:142
Class merging the OBB and RSS, can handle collision and distance simultaneously.
Definition: OBBRSS.h:50
int endReplaceModel(bool refit=true, bool bottomup=true)
End BVH model replacement, will also refit or rebuild the bounding volume hierarchy.
Definition: BVH_model-inl.h:577
bool BVTesting(int b1, int b2) const
BV test between b1 and b2.
Definition: shape_mesh_collision_traversal_node-inl.h:244
A class describing the kIOS collision structure, which is a set of spheres.
Definition: kIOS.h:48
Oriented bounding box class.
Definition: OBB.h:51
void leafTesting(int b1, int b2) const
Leaf test between node b1 and b2, if they are both leafs.
Definition: shape_mesh_collision_traversal_node-inl.h:276
void addContact(const Contact< S > &c)
add one contact into result structure
Definition: collision_result-inl.h:59
Traversal node for shape and mesh, when mesh BVH is one of the oriented node (OBB, RSS, OBBRSS, kIOS)
Definition: shape_mesh_collision_traversal_node.h:90