FCL  0.6.0
Flexible Collision Library
shape_mesh_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_SHAPEMESHCONSERVATIVEADVANCEMENTTRAVERSALNODE_INL_H
39 #define FCL_TRAVERSAL_SHAPEMESHCONSERVATIVEADVANCEMENTTRAVERSALNODE_INL_H
40 
41 #include "fcl/narrowphase/detail/traversal/distance/shape_mesh_conservative_advancement_traversal_node.h"
42 
43 namespace fcl
44 {
45 
46 namespace detail
47 {
48 
49 //==============================================================================
50 template <typename Shape, typename BV, typename NarrowPhaseSolver>
51 ShapeMeshConservativeAdvancementTraversalNode<Shape, BV, NarrowPhaseSolver>::
52 ShapeMeshConservativeAdvancementTraversalNode(S w_)
53  : ShapeMeshDistanceTraversalNode<Shape, BV, 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 Shape, typename BV, 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->model1_bv.distance(this->model2->getBV(b2).bv, &P1, &P2);
74 
75  stack.emplace_back(P1, P2, b1, b2, d);
76 
77  return d;
78 }
79 
80 //==============================================================================
81 template <typename Shape, typename BV, typename NarrowPhaseSolver>
83 {
84  if(this->enable_statistics) this->num_leaf_tests++;
85 
86  const BVNode<BV>& node = this->model2->getBV(b2);
87 
88  int primitive_id = node.primitiveId();
89 
90  const Triangle& tri_id = this->tri_indices[primitive_id];
91 
92  const Vector3<S>& p1 = this->vertices[tri_id[0]];
93  const Vector3<S>& p2 = this->vertices[tri_id[1]];
94  const Vector3<S>& p3 = this->vertices[tri_id[2]];
95 
96  S d;
97  Vector3<S> P1, P2;
98  this->nsolver->shapeTriangleDistance(*(this->model1), this->tf1, p1, p2, p3, &d, &P1, &P2);
99 
100  if(d < this->min_distance)
101  {
102  this->min_distance = d;
103 
104  closest_p1 = P1;
105  closest_p2 = P2;
106 
107  last_tri_id = primitive_id;
108  }
109 
110  Vector3<S> n = P2 - this->tf1 * p1; n.normalize();
111  // here n should be in global frame
112  TBVMotionBoundVisitor<BV> mb_visitor1(this->model1_bv, n);
113  TriangleMotionBoundVisitor<S> mb_visitor2(p1, p2, p3, -n);
114  S bound1 = motion1->computeMotionBound(mb_visitor1);
115  S bound2 = motion2->computeMotionBound(mb_visitor2);
116 
117  S bound = bound1 + bound2;
118 
119  S cur_delta_t;
120  if(bound <= d) cur_delta_t = 1;
121  else cur_delta_t = d / bound;
122 
123  if(cur_delta_t < delta_t)
124  delta_t = cur_delta_t;
125 }
126 
127 //==============================================================================
128 template <typename Shape, typename BV, typename NarrowPhaseSolver>
130 canStop(S c) const
131 {
132  if((c >= w * (this->min_distance - this->abs_err)) && (c * (1 + this->rel_err) >= w * this->min_distance))
133  {
134  const auto& data = stack.back();
135 
136  Vector3<S> n = data.P2 - this->tf1 * data.P1; n.normalize();
137  int c2 = data.c2;
138 
139  TBVMotionBoundVisitor<BV> mb_visitor1(this->model1_bv, n);
140  TBVMotionBoundVisitor<BV> mb_visitor2(this->model2->getBV(c2).bv, -n);
141  S bound1 = motion1->computeMotionBound(mb_visitor1);
142  S bound2 = motion2->computeMotionBound(mb_visitor2);
143 
144  S bound = bound1 + bound2;
145 
146  S cur_delta_t;
147  if(bound < c) cur_delta_t = 1;
148  else cur_delta_t = c / bound;
149 
150  if(cur_delta_t < delta_t)
151  delta_t = cur_delta_t;
152 
153  stack.pop_back();
154 
155  return true;
156  }
157  else
158  {
159  stack.pop_back();
160 
161  return false;
162  }
163 }
164 
165 //==============================================================================
166 template <typename Shape, typename BV, typename NarrowPhaseSolver>
167 bool initialize(
169  const Shape& model1,
170  const Transform3<typename BV::S>& tf1,
171  BVHModel<BV>& model2,
172  const Transform3<typename BV::S>& tf2,
173  const NarrowPhaseSolver* nsolver,
174  typename BV::S w,
175  bool use_refit,
176  bool refit_bottomup)
177 {
178  using S = typename BV::S;
179 
180  std::vector<Vector3<S>> vertices_transformed(model2.num_vertices);
181  for(int i = 0; i < model2.num_vertices; ++i)
182  {
183  Vector3<S>& p = model2.vertices[i];
184  Vector3<S> new_v = tf2 * p;
185  vertices_transformed[i] = new_v;
186  }
187 
188  model2.beginReplaceModel();
189  model2.replaceSubModel(vertices_transformed);
190  model2.endReplaceModel(use_refit, refit_bottomup);
191 
192  node.model1 = &model1;
193  node.model2 = &model2;
194 
195  node.vertices = model2.vertices;
196  node.tri_indices = model2.tri_indices;
197 
198  node.tf1 = tf1;
199  node.tf2 = tf2;
200 
201  node.nsolver = nsolver;
202  node.w = w;
203 
204  computeBV(model1, Transform3<S>::Identity(), node.model1_bv);
205 
206  return true;
207 }
208 
209 //==============================================================================
210 template <typename Shape, typename NarrowPhaseSolver>
213  typename Shape::S w_)
215  Shape, RSS<typename Shape::S>, NarrowPhaseSolver>(w_)
216 {
217  // Do nothing
218 }
219 
220 //==============================================================================
221 template <typename Shape, typename NarrowPhaseSolver>
222 typename Shape::S
224 BVTesting(int b1, int b2) const
225 {
226  using S = typename Shape::S;
227 
228  if(this->enable_statistics) this->num_bv_tests++;
229  Vector3<S> P1, P2;
230  S d = distance(this->tf2.linear(), this->tf2.translation(), this->model2->getBV(b2).bv, this->model1_bv, &P2, &P1);
231 
232  this->stack.emplace_back(P1, P2, b1, b2, d);
233 
234  return d;
235 }
236 
237 //==============================================================================
238 template <typename Shape, typename NarrowPhaseSolver>
240 leafTesting(int b1, int b2) const
241 {
242  detail::meshShapeConservativeAdvancementOrientedNodeLeafTesting(
243  b2,
244  b1,
245  this->model2,
246  *(this->model1),
247  this->model1_bv,
248  this->vertices,
249  this->tri_indices,
250  this->tf2,
251  this->tf1,
252  this->motion2,
253  this->motion1,
254  this->nsolver,
255  this->enable_statistics,
256  this->min_distance,
257  this->closest_p2,
258  this->closest_p1,
259  this->last_tri_id,
260  this->delta_t,
261  this->num_leaf_tests);
262 }
263 
264 //==============================================================================
265 template <typename Shape, typename NarrowPhaseSolver>
267 canStop(typename Shape::S c) const
268 {
269  return detail::meshShapeConservativeAdvancementOrientedNodeCanStop(
270  c,
271  this->min_distance,
272  this->abs_err,
273  this->rel_err,
274  this->w,
275  this->model2,
276  *(this->model1),
277  this->model1_bv,
278  this->motion2,
279  this->motion1,
280  this->stack,
281  this->delta_t);
282 }
283 
284 //==============================================================================
285 template <typename Shape, typename NarrowPhaseSolver>
286 bool initialize(
288  const Shape& model1,
289  const Transform3<typename Shape::S>& tf1,
290  const BVHModel<RSS<typename Shape::S>>& model2,
291  const Transform3<typename Shape::S>& tf2,
292  const NarrowPhaseSolver* nsolver,
293  typename Shape::S w)
294 {
295  using S = typename Shape::S;
296 
297  node.model1 = &model1;
298  node.tf1 = tf1;
299  node.model2 = &model2;
300  node.tf2 = tf2;
301  node.nsolver = nsolver;
302 
303  node.w = w;
304 
305  computeBV(model1, Transform3<S>::Identity(), node.model1_bv);
306 
307  return true;
308 }
309 
310 //==============================================================================
311 template <typename Shape, typename NarrowPhaseSolver>
314  typename Shape::S w_)
316  Shape, OBBRSS<typename Shape::S>, NarrowPhaseSolver>(w_)
317 {
318 }
319 
320 //==============================================================================
321 template <typename Shape, typename NarrowPhaseSolver>
322 typename Shape::S
324 BVTesting(int b1, int b2) const
325 {
326  using S = typename Shape::S;
327 
328  if(this->enable_statistics) this->num_bv_tests++;
329  Vector3<S> P1, P2;
330  S d = distance(this->tf2.linear(), this->tf2.translation(), this->model2->getBV(b2).bv, this->model1_bv, &P2, &P1);
331 
332  this->stack.emplace_back(P1, P2, b1, b2, d);
333 
334  return d;
335 }
336 
337 //==============================================================================
338 template <typename Shape, typename NarrowPhaseSolver>
340 leafTesting(int b1, int b2) const
341 {
342  detail::meshShapeConservativeAdvancementOrientedNodeLeafTesting(
343  b2,
344  b1,
345  this->model2,
346  *(this->model1),
347  this->model1_bv,
348  this->vertices,
349  this->tri_indices,
350  this->tf2,
351  this->tf1,
352  this->motion2,
353  this->motion1,
354  this->nsolver,
355  this->enable_statistics,
356  this->min_distance,
357  this->closest_p2,
358  this->closest_p1,
359  this->last_tri_id,
360  this->delta_t,
361  this->num_leaf_tests);
362 }
363 
364 //==============================================================================
365 template <typename Shape, typename NarrowPhaseSolver>
367 canStop(typename Shape::S c) const
368 {
369  return detail::meshShapeConservativeAdvancementOrientedNodeCanStop(
370  c,
371  this->min_distance,
372  this->abs_err,
373  this->rel_err,
374  this->w,
375  this->model2,
376  *(this->model1),
377  this->model1_bv,
378  this->motion2,
379  this->motion1,
380  this->stack,
381  this->delta_t);
382 }
383 
384 //==============================================================================
385 template <typename Shape, typename NarrowPhaseSolver>
386 bool initialize(
388  const Shape& model1,
389  const Transform3<typename Shape::S>& tf1,
390  const BVHModel<OBBRSS<typename Shape::S>>& model2,
391  const Transform3<typename Shape::S>& tf2,
392  const NarrowPhaseSolver* nsolver,
393  typename Shape::S w)
394 {
395  using S = typename Shape::S;
396 
397  node.model1 = &model1;
398  node.tf1 = tf1;
399  node.model2 = &model2;
400  node.tf2 = tf2;
401  node.nsolver = nsolver;
402 
403  node.w = w;
404 
405  computeBV(model1, Transform3<S>::Identity(), node.model1_bv);
406 
407  return true;
408 }
409 
410 } // namespace detail
411 } // namespace fcl
412 
413 #endif
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
bool canStop(S c) const
Whether the traversal process can stop early.
Definition: shape_mesh_conservative_advancement_traversal_node-inl.h:130
A class for rectangle sphere-swept bounding volume.
Definition: RSS.h:49
void leafTesting(int b1, int b2) const
Leaf test between node b1 and b2, if they are both leafs.
Definition: shape_mesh_conservative_advancement_traversal_node-inl.h:340
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
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< Shape1::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
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
S BVTesting(int b1, int b2) const
BV culling test in one BVTT node.
Definition: shape_mesh_conservative_advancement_traversal_node-inl.h:69
Definition: shape_mesh_conservative_advancement_traversal_node.h:106
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
void leafTesting(int b1, int b2) const
Conservative advancement testing between leaves (one triangle and one shape)
Definition: shape_mesh_conservative_advancement_traversal_node-inl.h:82
void leafTesting(int b1, int b2) const
Leaf test between node b1 and b2, if they are both leafs.
Definition: shape_mesh_conservative_advancement_traversal_node-inl.h:240
A class describing the bounding hierarchy of a mesh model or a point cloud model (which is viewed as ...
Definition: BVH_model.h:57
S w
CA controlling variable: early stop for the early iterations of CA.
Definition: shape_mesh_conservative_advancement_traversal_node.h:77
S BVTesting(int b1, int b2) const
BV test between b1 and b2.
Definition: shape_mesh_conservative_advancement_traversal_node-inl.h:224
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
Definition: shape_mesh_conservative_advancement_traversal_node.h:133
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
Definition: shape_mesh_conservative_advancement_traversal_node.h:52
S BVTesting(int b1, int b2) const
BV test between b1 and b2.
Definition: shape_mesh_conservative_advancement_traversal_node-inl.h:324
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 enable_statistics
Whether stores statistics.
Definition: distance_traversal_node_base.h:79