FCL  0.6.0
Flexible Collision Library
convex-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_SHAPE_CONVEX_INL_H
39 #define FCL_SHAPE_CONVEX_INL_H
40 
41 #include "fcl/geometry/shape/convex.h"
42 
43 namespace fcl
44 {
45 
46 //==============================================================================
47 extern template
48 class Convex<double>;
49 
50 //==============================================================================
51 template <typename S>
53  Vector3<S>* plane_normals, S* plane_dis, int num_planes_,
54  Vector3<S>* points, int num_points_, int* polygons_)
55  : ShapeBase<S>()
56 {
57  plane_normals = plane_normals;
58  plane_dis = plane_dis;
59  num_planes = num_planes_;
60  points = points;
61  num_points = num_points_;
62  polygons = polygons_;
63  edges = nullptr;
64 
65  Vector3<S> sum = Vector3<S>::Zero();
66  for(int i = 0; i < num_points; ++i)
67  {
68  sum += points[i];
69  }
70 
71  center = sum * (S)(1.0 / num_points);
72 
73  fillEdges();
74 }
75 
76 //==============================================================================
77 template <typename S>
79  : ShapeBase<S>(other)
80 {
81  plane_normals = other.plane_normals;
82  plane_dis = other.plane_dis;
83  num_planes = other.num_planes;
84  points = other.points;
85  polygons = other.polygons;
86  edges = new Edge[other.num_edges];
87  memcpy(edges, other.edges, sizeof(Edge) * num_edges);
88 }
89 
90 //==============================================================================
91 template <typename S>
93 {
94  delete [] edges;
95 }
96 
97 //==============================================================================
98 template <typename S>
100 {
101  this->aabb_local.min_.setConstant(-std::numeric_limits<S>::max());
102  this->aabb_local.max_.setConstant(std::numeric_limits<S>::max());
103  for(int i = 0; i < num_points; ++i)
104  this->aabb_local += points[i];
105 
106  this->aabb_center = this->aabb_local.center();
107  this->aabb_radius = (this->aabb_local.min_ - this->aabb_center).norm();
108 }
109 
110 //==============================================================================
111 template <typename S>
113 {
114  return GEOM_CONVEX;
115 }
116 
117 //==============================================================================
118 template <typename S>
120 {
121  Matrix3<S> C = Matrix3<S>::Zero();
122 
123  Matrix3<S> C_canonical;
124  C_canonical << 1/ 60.0, 1/120.0, 1/120.0,
125  1/120.0, 1/ 60.0, 1/120.0,
126  1/120.0, 1/120.0, 1/ 60.0;
127 
128  int* points_in_poly = polygons;
129  int* index = polygons + 1;
130  for(int i = 0; i < num_planes; ++i)
131  {
132  Vector3<S> plane_center = Vector3<S>::Zero();
133 
134  // compute the center of the polygon
135  for(int j = 0; j < *points_in_poly; ++j)
136  plane_center += points[index[j]];
137  plane_center = plane_center * (1.0 / *points_in_poly);
138 
139  // compute the volume of tetrahedron making by neighboring two points, the plane center and the reference point (zero) of the convex shape
140  const Vector3<S>& v3 = plane_center;
141  for(int j = 0; j < *points_in_poly; ++j)
142  {
143  int e_first = index[j];
144  int e_second = index[(j+1)%*points_in_poly];
145  const Vector3<S>& v1 = points[e_first];
146  const Vector3<S>& v2 = points[e_second];
147  S d_six_vol = (v1.cross(v2)).dot(v3);
148  Matrix3<S> A; // this is A' in the original document
149  A.row(0) = v1;
150  A.row(1) = v2;
151  A.row(2) = v3;
152  C += A.transpose() * C_canonical * A * d_six_vol; // change accordingly
153  }
154 
155  points_in_poly += (*points_in_poly + 1);
156  index = points_in_poly + 1;
157  }
158 
159  S trace_C = C(0, 0) + C(1, 1) + C(2, 2);
160 
161  Matrix3<S> m;
162  m << trace_C - C(0, 0), -C(0, 1), -C(0, 2),
163  -C(1, 0), trace_C - C(1, 1), -C(1, 2),
164  -C(2, 0), -C(2, 1), trace_C - C(2, 2);
165 
166  return m;
167 }
168 
169 //==============================================================================
170 template <typename S>
171 Vector3<S> Convex<S>::computeCOM() const
172 {
173  Vector3<S> com = Vector3<S>::Zero();
174  S vol = 0;
175  int* points_in_poly = polygons;
176  int* index = polygons + 1;
177  for(int i = 0; i < num_planes; ++i)
178  {
179  Vector3<S> plane_center = Vector3<S>::Zero();
180 
181  // compute the center of the polygon
182  for(int j = 0; j < *points_in_poly; ++j)
183  plane_center += points[index[j]];
184  plane_center = plane_center * (1.0 / *points_in_poly);
185 
186  // compute the volume of tetrahedron making by neighboring two points, the plane center and the reference point (zero) of the convex shape
187  const Vector3<S>& v3 = plane_center;
188  for(int j = 0; j < *points_in_poly; ++j)
189  {
190  int e_first = index[j];
191  int e_second = index[(j+1)%*points_in_poly];
192  const Vector3<S>& v1 = points[e_first];
193  const Vector3<S>& v2 = points[e_second];
194  S d_six_vol = (v1.cross(v2)).dot(v3);
195  vol += d_six_vol;
196  com += (points[e_first] + points[e_second] + plane_center) * d_six_vol;
197  }
198 
199  points_in_poly += (*points_in_poly + 1);
200  index = points_in_poly + 1;
201  }
202 
203  return com / (vol * 4); // here we choose zero as the reference
204 }
205 
206 //==============================================================================
207 template <typename S>
209 {
210  S vol = 0;
211  int* points_in_poly = polygons;
212  int* index = polygons + 1;
213  for(int i = 0; i < num_planes; ++i)
214  {
215  Vector3<S> plane_center = Vector3<S>::Zero();
216 
217  // compute the center of the polygon
218  for(int j = 0; j < *points_in_poly; ++j)
219  plane_center += points[index[j]];
220  plane_center = plane_center * (1.0 / *points_in_poly);
221 
222  // compute the volume of tetrahedron making by neighboring two points, the plane center and the reference point (zero point) of the convex shape
223  const Vector3<S>& v3 = plane_center;
224  for(int j = 0; j < *points_in_poly; ++j)
225  {
226  int e_first = index[j];
227  int e_second = index[(j+1)%*points_in_poly];
228  const Vector3<S>& v1 = points[e_first];
229  const Vector3<S>& v2 = points[e_second];
230  S d_six_vol = (v1.cross(v2)).dot(v3);
231  vol += d_six_vol;
232  }
233 
234  points_in_poly += (*points_in_poly + 1);
235  index = points_in_poly + 1;
236  }
237 
238  return vol / 6;
239 }
240 
241 //==============================================================================
242 template <typename S>
244 {
245  int* points_in_poly = polygons;
246  if(edges) delete [] edges;
247 
248  int num_edges_alloc = 0;
249  for(int i = 0; i < num_planes; ++i)
250  {
251  num_edges_alloc += *points_in_poly;
252  points_in_poly += (*points_in_poly + 1);
253  }
254 
255  edges = new Edge[num_edges_alloc];
256 
257  points_in_poly = polygons;
258  int* index = polygons + 1;
259  num_edges = 0;
260  Edge e;
261  bool isinset;
262  for(int i = 0; i < num_planes; ++i)
263  {
264  for(int j = 0; j < *points_in_poly; ++j)
265  {
266  e.first = std::min(index[j], index[(j+1)%*points_in_poly]);
267  e.second = std::max(index[j], index[(j+1)%*points_in_poly]);
268  isinset = false;
269  for(int k = 0; k < num_edges; ++k)
270  {
271  if((edges[k].first == e.first) && (edges[k].second == e.second))
272  {
273  isinset = true;
274  break;
275  }
276  }
277 
278  if(!isinset)
279  {
280  edges[num_edges].first = e.first;
281  edges[num_edges].second = e.second;
282  ++num_edges;
283  }
284  }
285 
286  points_in_poly += (*points_in_poly + 1);
287  index = points_in_poly + 1;
288  }
289 
290  if(num_edges < num_edges_alloc)
291  {
292  Edge* tmp = new Edge[num_edges];
293  memcpy(tmp, edges, num_edges * sizeof(Edge));
294  delete [] edges;
295  edges = tmp;
296  }
297 }
298 
299 //==============================================================================
300 template <typename S>
301 std::vector<Vector3<S>> Convex<S>::getBoundVertices(
302  const Transform3<S>& tf) const
303 {
304  std::vector<Vector3<S>> result(num_points);
305  for(int i = 0; i < num_points; ++i)
306  {
307  result[i] = tf * points[i];
308  }
309 
310  return result;
311 }
312 
313 } // namespace fcl
314 
315 #endif
Vector3< S_ > aabb_center
AABB center in local coordinate.
Definition: collision_geometry.h:91
NODE_TYPE
traversal node type: bounding volume (AABB, OBB, RSS, kIOS, OBBRSS, KDOP16, KDOP18, kDOP24), basic shape (box, sphere, ellipsoid, capsule, cone, cylinder, convex, plane, halfspace, triangle), and octree
Definition: collision_geometry.h:54
Main namespace.
Definition: broadphase_bruteforce-inl.h:45
Base class for all basic geometric shapes.
Definition: shape_base.h:48
S_ aabb_radius
AABB radius.
Definition: collision_geometry.h:94
void computeLocalAABB() override
Compute AABB<S>
Definition: convex-inl.h:99
Vector3< S > center
center of the convex polytope, this is used for collision: center is guaranteed in the internal of th...
Definition: convex.h:94
Matrix3< S > computeMomentofInertia() const override
based on http://number-none.com/blow/inertia/bb_inertia.doc
Definition: convex-inl.h:119
void fillEdges()
Get edge information.
Definition: convex-inl.h:243
Vector3< S > computeCOM() const override
compute center of mass
Definition: convex-inl.h:171
Definition: convex.h:86
std::vector< Vector3< S > > getBoundVertices(const Transform3< S > &tf) const
get the vertices of some convex shape which can bound this shape in a specific configuration ...
Definition: convex-inl.h:301
Convex(Vector3< S > *plane_normals, S *plane_dis, int num_planes, Vector3< S > *points, int num_points, int *polygons)
Constructing a convex, providing normal and offset of each polytype surface, and the points and shape...
Definition: convex-inl.h:52
AABB< S_ > aabb_local
AABB in local coordinate, used for tight AABB when only translation transform.
Definition: collision_geometry.h:97
S computeVolume() const override
compute the volume
Definition: convex-inl.h:208
Convex polytope.
Definition: convex.h:48
int * polygons
An array of indices to the points of each polygon, it should be the number of vertices followed by th...
Definition: convex.h:79
NODE_TYPE getNodeType() const override
Get node type: a conex polytope.
Definition: convex-inl.h:112