FCL  0.6.0
Flexible Collision Library
mesh_shape_conservative_advancement_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_MESHSHAPECONSERVATIVEADVANCEMENTTRAVERSALNODE_INL_H
39 #define FCL_TRAVERSAL_MESHSHAPECONSERVATIVEADVANCEMENTTRAVERSALNODE_INL_H
40 
41 #include "fcl/narrowphase/detail/traversal/distance/mesh_shape_conservative_advancement_traversal_node.h"
42 
43 namespace fcl
44 {
45 
46 namespace detail
47 {
48 
49 //==============================================================================
50 template <typename BV, typename Shape, typename NarrowPhaseSolver>
51 MeshShapeConservativeAdvancementTraversalNode<BV, Shape, NarrowPhaseSolver>::
52 MeshShapeConservativeAdvancementTraversalNode(S w_) :
53  MeshShapeDistanceTraversalNode<BV, Shape, NarrowPhaseSolver>()
54 {
55  delta_t = 1;
56  toc = 0;
57  t_err = (S)0.0001;
58 
59  w = w_;
60 
61  motion1 = nullptr;
62  motion2 = nullptr;
63 }
64 
65 //==============================================================================
66 template <typename BV, typename Shape, typename NarrowPhaseSolver>
67 typename BV::S
69 BVTesting(int b1, int b2) const
70 {
71  if(this->enable_statistics) this->num_bv_tests++;
72  Vector3<S> P1, P2;
73  S d = this->model2_bv.distance(this->model1->getBV(b1).bv, &P2, &P1);
74 
75  stack.emplace_back(P1, P2, b1, b2, d);
76 
77  return d;
78 }
79 
80 //==============================================================================
81 template <typename BV, typename Shape, typename NarrowPhaseSolver>
83 leafTesting(int b1, int b2) const
84 {
85  if(this->enable_statistics) this->num_leaf_tests++;
86 
87  const BVNode<BV>& node = this->model1->getBV(b1);
88 
89  int primitive_id = node.primitiveId();
90 
91  const Triangle& tri_id = this->tri_indices[primitive_id];
92 
93  const Vector3<S>& p1 = this->vertices[tri_id[0]];
94  const Vector3<S>& p2 = this->vertices[tri_id[1]];
95  const Vector3<S>& p3 = this->vertices[tri_id[2]];
96 
97  S d;
98  Vector3<S> P1, P2;
99  this->nsolver->shapeTriangleDistance(*(this->model2), this->tf2, p1, p2, p3, &d, &P2, &P1);
100 
101  if(d < this->min_distance)
102  {
103  this->min_distance = d;
104 
105  closest_p1 = P1;
106  closest_p2 = P2;
107 
108  last_tri_id = primitive_id;
109  }
110 
111  Vector3<S> n = this->tf2 * p2 - P1; n.normalize();
112  // here n should be in global frame
113  TriangleMotionBoundVisitor<S> mb_visitor1(p1, p2, p3, n);
114  TBVMotionBoundVisitor<BV> mb_visitor2(this->model2_bv, -n);
115  S bound1 = motion1->computeMotionBound(mb_visitor1);
116  S bound2 = motion2->computeMotionBound(mb_visitor2);
117 
118  S bound = bound1 + bound2;
119 
120  S cur_delta_t;
121  if(bound <= d) cur_delta_t = 1;
122  else cur_delta_t = d / bound;
123 
124  if(cur_delta_t < delta_t)
125  delta_t = cur_delta_t;
126 }
127 
128 //==============================================================================
129 template <typename BV, typename Shape, typename NarrowPhaseSolver>
131 canStop(S c) const
132 {
133  if((c >= w * (this->min_distance - this->abs_err))
134  && (c * (1 + this->rel_err) >= w * this->min_distance))
135  {
136  const auto& data = stack.back();
137 
138  Vector3<S> n = this->tf2 * data.P2 - data.P1; n.normalize();
139  int c1 = data.c1;
140 
141  TBVMotionBoundVisitor<BV> mb_visitor1(this->model1->getBV(c1).bv, n);
142  TBVMotionBoundVisitor<BV> mb_visitor2(this->model2_bv, -n);
143  S bound1 = motion1->computeMotionBound(mb_visitor1);
144  S bound2 = motion2->computeMotionBound(mb_visitor2);
145 
146  S bound = bound1 + bound2;
147 
148  S cur_delta_t;
149  if(bound < c) cur_delta_t = 1;
150  else cur_delta_t = c / bound;
151 
152  if(cur_delta_t < delta_t)
153  delta_t = cur_delta_t;
154 
155  stack.pop_back();
156 
157  return true;
158  }
159  else
160  {
161  stack.pop_back();
162 
163  return false;
164  }
165 }
166 
167 //==============================================================================
168 template <typename BV, typename Shape, typename NarrowPhaseSolver>
169 bool initialize(
172  const Transform3<typename BV::S>& tf1,
173  const Shape& model2,
174  const Transform3<typename BV::S>& tf2,
175  const NarrowPhaseSolver* nsolver,
176  typename BV::S w,
177  bool use_refit,
178  bool refit_bottomup)
179 {
180  using S = typename BV::S;
181 
182  std::vector<Vector3<S>> vertices_transformed(model1.num_vertices);
183  for(int i = 0; i < model1.num_vertices; ++i)
184  {
185  Vector3<S>& p = model1.vertices[i];
186  Vector3<S> new_v = tf1 * p;
187  vertices_transformed[i] = new_v;
188  }
189 
190  model1.beginReplaceModel();
191  model1.replaceSubModel(vertices_transformed);
192  model1.endReplaceModel(use_refit, refit_bottomup);
193 
194  node.model1 = &model1;
195  node.model2 = &model2;
196 
197  node.vertices = model1.vertices;
198  node.tri_indices = model1.tri_indices;
199 
200  node.tf1 = tf1;
201  node.tf2 = tf2;
202 
203  node.nsolver = nsolver;
204  node.w = w;
205 
206  computeBV(model2, Transform3<S>::Identity(), node.model2_bv);
207 
208  return true;
209 }
210 
211 //==============================================================================
212 template <typename BV, typename Shape, typename NarrowPhaseSolver>
213 void meshShapeConservativeAdvancementOrientedNodeLeafTesting(
214  int b1,
215  int /* b2 */,
216  const BVHModel<BV>* model1,
217  const Shape& model2,
218  const BV& model2_bv,
219  Vector3<typename BV::S>* vertices,
220  Triangle* tri_indices,
221  const Transform3<typename BV::S>& tf1,
222  const Transform3<typename BV::S>& tf2,
223  const MotionBase<typename BV::S>* motion1,
224  const MotionBase<typename BV::S>* motion2,
225  const NarrowPhaseSolver* nsolver,
226  bool enable_statistics,
227  typename BV::S& min_distance,
228  Vector3<typename BV::S>& p1,
229  Vector3<typename BV::S>& p2,
230  int& last_tri_id,
231  typename BV::S& delta_t,
232  int& num_leaf_tests)
233 {
234  using S = typename BV::S;
235 
236  if(enable_statistics) num_leaf_tests++;
237 
238  const BVNode<BV>& node = model1->getBV(b1);
239  int primitive_id = node.primitiveId();
240 
241  const Triangle& tri_id = tri_indices[primitive_id];
242  const Vector3<S>& t1 = vertices[tri_id[0]];
243  const Vector3<S>& t2 = vertices[tri_id[1]];
244  const Vector3<S>& t3 = vertices[tri_id[2]];
245 
246  S distance;
247  Vector3<S> P1 = Vector3<S>::Zero();
248  Vector3<S> P2 = Vector3<S>::Zero();
249  nsolver->shapeTriangleDistance(model2, tf2, t1, t2, t3, tf1, &distance, &P2, &P1);
250 
251  if(distance < min_distance)
252  {
253  min_distance = distance;
254 
255  p1 = P1;
256  p2 = P2;
257 
258  last_tri_id = primitive_id;
259  }
260 
261  // n is in global frame
262  Vector3<S> n = P2 - P1; n.normalize();
263 
264  TriangleMotionBoundVisitor<S> mb_visitor1(t1, t2, t3, n);
265  TBVMotionBoundVisitor<BV> mb_visitor2(model2_bv, -n);
266  S bound1 = motion1->computeMotionBound(mb_visitor1);
267  S bound2 = motion2->computeMotionBound(mb_visitor2);
268 
269  S bound = bound1 + bound2;
270 
271  S cur_delta_t;
272  if(bound <= distance) cur_delta_t = 1;
273  else cur_delta_t = distance / bound;
274 
275  if(cur_delta_t < delta_t)
276  delta_t = cur_delta_t;
277 }
278 
279 //==============================================================================
280 template <typename BV, typename Shape>
281 bool meshShapeConservativeAdvancementOrientedNodeCanStop(
282  typename BV::S c,
283  typename BV::S min_distance,
284  typename BV::S abs_err,
285  typename BV::S rel_err,
286  typename BV::S w,
287  const BVHModel<BV>* model1,
288  const Shape& model2,
289  const BV& model2_bv,
290  const MotionBase<typename BV::S>* motion1,
291  const MotionBase<typename BV::S>* motion2,
293  typename BV::S& delta_t)
294 {
295  using S = typename BV::S;
296 
297  if((c >= w * (min_distance - abs_err)) && (c * (1 + rel_err) >= w * min_distance))
298  {
299  const auto& data = stack.back();
300  Vector3<S> n = data.P2 - data.P1; n.normalize();
301  int c1 = data.c1;
302 
303  TBVMotionBoundVisitor<BV> mb_visitor1(model1->getBV(c1).bv, n);
304  TBVMotionBoundVisitor<BV> mb_visitor2(model2_bv, -n);
305 
306  S bound1 = motion1->computeMotionBound(mb_visitor1);
307  S bound2 = motion2->computeMotionBound(mb_visitor2);
308 
309  S bound = bound1 + bound2;
310 
311  S cur_delta_t;
312  if(bound <= c) cur_delta_t = 1;
313  else cur_delta_t = c / bound;
314 
315  if(cur_delta_t < delta_t)
316  delta_t = cur_delta_t;
317 
318  stack.pop_back();
319 
320  return true;
321  }
322  else
323  {
324  stack.pop_back();
325  return false;
326  }
327 }
328 
329 //==============================================================================
330 template <typename Shape, typename NarrowPhaseSolver>
334  RSS<S>, Shape, NarrowPhaseSolver>(w_)
335 {
336  // Do nothing
337 }
338 
339 //==============================================================================
340 template <typename Shape, typename NarrowPhaseSolver>
341 typename Shape::S
343 BVTesting(int b1, int b2) const
344 {
345  if(this->enable_statistics) this->num_bv_tests++;
346  Vector3<S> P1, P2;
347  S d = distance(this->tf1.linear(), this->tf1.translation(), this->model1->getBV(b1).bv, this->model2_bv, &P1, &P2);
348 
349  this->stack.emplace_back(P1, P2, b1, b2, d);
350 
351  return d;
352 }
353 
354 //==============================================================================
355 template <typename Shape, typename NarrowPhaseSolver>
356 void
358 leafTesting(int b1, int b2) const
359 {
360  detail::meshShapeConservativeAdvancementOrientedNodeLeafTesting(
361  b1,
362  b2,
363  this->model1,
364  *(this->model2),
365  this->model2_bv,
366  this->vertices,
367  this->tri_indices,
368  this->tf1,
369  this->tf2,
370  this->motion1,
371  this->motion2,
372  this->nsolver,
373  this->enable_statistics,
374  this->min_distance,
375  this->closest_p1,
376  this->closest_p2,
377  this->last_tri_id,
378  this->delta_t,
379  this->num_leaf_tests);
380 }
381 
382 //==============================================================================
383 template <typename Shape, typename NarrowPhaseSolver>
384 bool
386 canStop(typename Shape::S c) const
387 {
388  return detail::meshShapeConservativeAdvancementOrientedNodeCanStop(
389  c,
390  this->min_distance,
391  this->abs_err,
392  this->rel_err,
393  this->w,
394  this->model1,
395  *(this->model2),
396  this->model2_bv,
397  this->motion1,
398  this->motion2,
399  this->stack,
400  this->delta_t);
401 }
402 
403 //==============================================================================
404 template <typename Shape, typename NarrowPhaseSolver>
405 bool initialize(
407  const BVHModel<RSS<typename Shape::S>>& model1,
408  const Transform3<typename Shape::S>& tf1,
409  const Shape& model2,
410  const Transform3<typename Shape::S>& tf2,
411  const NarrowPhaseSolver* nsolver,
412  typename Shape::S w)
413 {
414  using S = typename Shape::S;
415 
416  node.model1 = &model1;
417  node.tf1 = tf1;
418  node.model2 = &model2;
419  node.tf2 = tf2;
420  node.nsolver = nsolver;
421 
422  node.w = w;
423 
424  computeBV(model2, Transform3<S>::Identity(), node.model2_bv);
425 
426  return true;
427 }
428 
429 //==============================================================================
430 template <typename Shape, typename NarrowPhaseSolver>
433  typename Shape::S w_)
435  OBBRSS<S>, Shape, NarrowPhaseSolver>(w_)
436 {
437  // Do nothing
438 }
439 
440 //==============================================================================
441 template <typename Shape, typename NarrowPhaseSolver>
442 typename Shape::S
444 BVTesting(int b1, int b2) const
445 {
446  if(this->enable_statistics) this->num_bv_tests++;
447  Vector3<S> P1, P2;
448  S d = distance(this->tf1.linear(), this->tf1.translation(), this->model1->getBV(b1).bv, this->model2_bv, &P1, &P2);
449 
450  this->stack.emplace_back(P1, P2, b1, b2, d);
451 
452  return d;
453 }
454 
455 //==============================================================================
456 template <typename Shape, typename NarrowPhaseSolver>
457 void
459 leafTesting(int b1, int b2) const
460 {
461  detail::meshShapeConservativeAdvancementOrientedNodeLeafTesting(
462  b1,
463  b2,
464  this->model1,
465  *(this->model2),
466  this->model2_bv,
467  this->vertices,
468  this->tri_indices,
469  this->tf1,
470  this->tf2,
471  this->motion1,
472  this->motion2,
473  this->nsolver,
474  this->enable_statistics,
475  this->min_distance,
476  this->closest_p1,
477  this->closest_p2,
478  this->last_tri_id,
479  this->delta_t,
480  this->num_leaf_tests);
481 }
482 
483 //==============================================================================
484 template <typename Shape, typename NarrowPhaseSolver>
485 bool
487 canStop(typename Shape::S c) const
488 {
489  return detail::meshShapeConservativeAdvancementOrientedNodeCanStop(
490  c,
491  this->min_distance,
492  this->abs_err,
493  this->rel_err,
494  this->w,
495  this->model1,
496  *(this->model2),
497  this->model2_bv,
498  this->motion1,
499  this->motion2,
500  this->stack,
501  this->delta_t);
502 }
503 
504 //==============================================================================
505 template <typename Shape, typename NarrowPhaseSolver>
506 bool initialize(
508  const BVHModel<OBBRSS<typename Shape::S>>& model1,
509  const Transform3<typename Shape::S>& tf1,
510  const Shape& model2,
511  const Transform3<typename Shape::S>& tf2,
512  const NarrowPhaseSolver* nsolver,
513  typename Shape::S w)
514 {
515  using S = typename Shape::S;
516 
517  node.model1 = &model1;
518  node.tf1 = tf1;
519  node.model2 = &model2;
520  node.tf2 = tf2;
521  node.nsolver = nsolver;
522 
523  node.w = w;
524 
525  computeBV(model2, Transform3<S>::Identity(), node.model2_bv);
526 
527  return true;
528 }
529 
530 } // namespace detail
531 } // namespace fcl
532 
533 #endif
void leafTesting(int b1, int b2) const
Leaf test between node b1 and b2, if they are both leafs.
Definition: mesh_shape_conservative_advancement_traversal_node-inl.h:358
const BVHModel< OBBRSS< S > > * model1
The first BVH model.
Definition: bvh_distance_traversal_node.h:87
Definition: motion_base.h:52
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
S rel_err
relative and absolute error, default value is 0.01 for both terms
Definition: mesh_distance_traversal_node.h:76
Definition: mesh_shape_conservative_advancement_traversal_node.h:171
S BVTesting(int b1, int b2) const
BV test between b1 and b2.
Definition: mesh_shape_conservative_advancement_traversal_node-inl.h:444
virtual S computeMotionBound(const BVMotionBoundVisitor< S > &mb_visitor) const =0
Compute the motion bound for a bounding volume, given the closest direction n between two query objec...
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
S BVTesting(int b1, int b2) const
BV culling test in one BVTT node.
Definition: mesh_shape_conservative_advancement_traversal_node-inl.h:69
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
Transform3< OBBRSS< S >::S > tf2
configuration of second object
Definition: traversal_node_base.h:88
Vector3< S > * vertices
Geometry point data.
Definition: BVH_model.h:162
int num_vertices
Number of points.
Definition: BVH_model.h:174
Traversal node for conservative advancement computation between BVH and shape.
Definition: mesh_shape_conservative_advancement_traversal_node.h:52
Definition: tbv_motion_bound_visitor.h:65
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
int num_bv_tests
statistical information
Definition: bvh_distance_traversal_node.h:92
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 canStop(S c) const
Whether the traversal process can stop early.
Definition: mesh_shape_conservative_advancement_traversal_node-inl.h:131
void leafTesting(int b1, int b2) const
Conservative advancement testing between leaves (one triangle and one shape)
Definition: mesh_shape_conservative_advancement_traversal_node-inl.h:83
Definition: bv_motion_bound_visitor.h:45
Definition: conservative_advancement_stack_data.h:50
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 bv
bounding volume storing the geometry
Definition: BV_node.h:57
const BVHModel< OBBRSS< S > > * model2
The second BVH model.
Definition: bvh_distance_traversal_node.h:89
void leafTesting(int b1, int b2) const
Leaf test between node b1 and b2, if they are both leafs.
Definition: mesh_shape_conservative_advancement_traversal_node-inl.h:459
A class describing a bounding volume node. It includes the tree structure providing in BVNodeBase and...
Definition: BV_node.h:52
Transform3< OBBRSS< S >::S > tf1
configuation of first object
Definition: traversal_node_base.h:85
S distance(const Eigen::MatrixBase< DerivedA > &R0, const Eigen::MatrixBase< DerivedB > &T0, const kIOS< S > &b1, const kIOS< S > &b2, Vector3< S > *P, Vector3< S > *Q)
Approximate distance between two kIOS bounding volumes.
Definition: kIOS-inl.h:266
S w
CA controlling variable: early stop for the early iterations of CA.
Definition: mesh_shape_conservative_advancement_traversal_node.h:77
Definition: mesh_shape_conservative_advancement_traversal_node.h:143
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
S BVTesting(int b1, int b2) const
BV test between b1 and b2.
Definition: mesh_shape_conservative_advancement_traversal_node-inl.h:343
bool enable_statistics
Whether stores statistics.
Definition: distance_traversal_node_base.h:79