Moby
CCD.h
1 /****************************************************************************
2  * Copyright 2009 Evan Drumwright
3  * This library is distributed under the terms of the Apache V2.0
4  * License (obtainable from http://www.apache.org/licenses/LICENSE-2.0).
5  ****************************************************************************/
6 
7 #ifndef _CCD_H
8 #define _CCD_H
9 
10 #include <list>
11 #include <set>
12 #include <map>
13 #include <boost/shared_ptr.hpp>
14 #include <Ravelin/sorted_pair>
15 #include <Moby/Log.h>
16 #include <Moby/SpherePrimitive.h>
17 #include <Moby/TorusPrimitive.h>
18 #include <Moby/PolyhedralPrimitive.h>
19 #include <Moby/PairwiseDistInfo.h>
20 #include <Moby/HeightmapPrimitive.h>
21 #include <Moby/PlanePrimitive.h>
22 #include <Moby/BoxPrimitive.h>
23 #include <Moby/CylinderPrimitive.h>
24 #include <Moby/CollisionDetection.h>
25 #include <Moby/BV.h>
26 #include <Moby/GJK.h>
27 #include <Moby/Polyhedron.h>
28 
29 namespace Moby {
30 
31 class RigidBody;
32 class ArticulatedBody;
33 class CollisionGeometry;
34 
36 class CCD : public CollisionDetection
37 {
38  public:
39  CCD();
40  virtual ~CCD() {}
41  virtual void load_from_xml(boost::shared_ptr<const XMLTree> node, std::map<std::string, BasePtr>& id_map);
42  virtual void save_to_xml(XMLTreePtr node, std::list<boost::shared_ptr<const Base> >& shared_objects) const;
43  virtual void broad_phase(double dt, const std::vector<ControlledBodyPtr>& bodies, std::vector<std::pair<CollisionGeometryPtr, CollisionGeometryPtr> >& to_check);
44  virtual double calc_CA_Euler_step(const PairwiseDistInfo& pdi);
45  virtual void find_contacts(CollisionGeometryPtr cgA, CollisionGeometryPtr cgB, std::vector<UnilateralConstraint>& contacts, double TOL = NEAR_ZERO)
46  {
47  find_contacts(cgA, cgB, std::back_inserter(contacts), TOL);
48  }
49  static unsigned constrain_unsigned(int ii, int maxi){
50  return (unsigned) std::min(std::max(ii,0),maxi);
51  }
52 
53  template <class OutputIterator>
54  OutputIterator find_contacts(CollisionGeometryPtr cgA, CollisionGeometryPtr cgB, OutputIterator output_begin, double TOL = NEAR_ZERO);
55 
57 
62  std::set<Ravelin::sorted_pair<CollisionGeometryPtr> > disabled_pairs;
63 
64  protected:
65  virtual double calc_next_CA_Euler_step(const PairwiseDistInfo& pdi) { return calc_next_CA_Euler_step_generic(pdi); }
66 
67  private:
68  // the 3 axes
69  enum AxisType { eXAxis, eYAxis, eZAxis };
70 
71  static double sqr(double x) { return x*x; }
72  double calc_next_CA_Euler_step_polyhedron_plane(boost::shared_ptr<PolyhedralPrimitive> p, const Ravelin::SVelocityd& rv, boost::shared_ptr<const Ravelin::Pose3d> P, const Ravelin::Vector3d& normal, double offset);
73  double calc_next_CA_Euler_step_polyhedron_polyhedron(boost::shared_ptr<PolyhedralPrimitive> pA, boost::shared_ptr<PolyhedralPrimitive> pB, boost::shared_ptr<const Ravelin::Pose3d> poseA, boost::shared_ptr<const Ravelin::Pose3d> poseB, const Ravelin::SVelocityd& rvA, const Ravelin::SVelocityd& rvB, const Ravelin::Vector3d& n0, double offset);
74  virtual double calc_next_CA_Euler_step_generic(const PairwiseDistInfo& pdi);
75  virtual double calc_CA_Euler_step_generic(const PairwiseDistInfo& pdi);
76  virtual double calc_CA_Euler_step_sphere(const PairwiseDistInfo& pdi);
77  static double calc_max_dist(ArticulatedBodyPtr ab, RigidBodyPtr rb, const Ravelin::Vector3d& n, double rmax);
78  static double calc_max_dist(RigidBodyPtr rb, const Ravelin::Vector3d& n, double rmax);
79  static double calc_max_step(RigidBodyPtr rbA, RigidBodyPtr rbB, const Ravelin::Vector3d& n, double rmaxA, double rmaxB, double dist);
80 
81  // structure for doing broad phase collision detection
82  struct BoundsStruct
83  {
84  bool end; // bounds is for start or end
85  CollisionGeometryPtr geom; // the geometry
86  BVPtr bv; // the unexpanded bounding volume
87  bool operator<(const BoundsStruct& bs) const { return (!end && bs.end); }
88  };
89 
90  // gets the distance on farthest points
91  std::map<CollisionGeometryPtr, double> _rmax;
92 
93  // see whether the bounds vectors need to be rebuilt
94  bool _rebuild_bounds_vecs;
95 
96  // the bounding spheres
97  std::map<CollisionGeometryPtr, BVPtr> _bounding_spheres;
98 
100  std::vector<std::pair<double, BoundsStruct> > _x_bounds;
101 
103  std::vector<std::pair<double, BoundsStruct> > _y_bounds;
104 
106  std::vector<std::pair<double, BoundsStruct> > _z_bounds;
107 
109  std::map<CollisionGeometryPtr, BVPtr> _swept_BVs;
110 
112  std::map<Ravelin::sorted_pair<CollisionGeometryPtr>, double> _min_dist_observed;
113 
114  static BVPtr construct_bounding_sphere(CollisionGeometryPtr cg);
115  void sort_AABBs(const std::vector<RigidBodyPtr>& rigid_bodies, double dt);
116  void update_bounds_vector(std::vector<std::pair<double, BoundsStruct> >& bounds, AxisType axis, double dt, bool recreate_bvs);
117  void build_bv_vector(const std::vector<RigidBodyPtr>& rigid_bodies, std::vector<std::pair<double, BoundsStruct> >& bounds);
118  BVPtr get_swept_BV(CollisionGeometryPtr geom, BVPtr bv, double dt);
119 
120  bool intersect_BV_trees(boost::shared_ptr<BV> a, boost::shared_ptr<BV> b, const Ravelin::Transform3d& aTb, CollisionGeometryPtr geom_a, CollisionGeometryPtr geom_b);
121 
122  template <class OutputIterator>
123  OutputIterator find_contacts_polyhedron_polyhedron(CollisionGeometryPtr cgA, CollisionGeometryPtr cgB, OutputIterator output_begin, double TOL);
124 
125  template <class OutputIterator>
126  OutputIterator intersect_BV_leafs(BVPtr a, BVPtr b, const Ravelin::Transform3d& aTb, CollisionGeometryPtr geom_a, CollisionGeometryPtr geom_b, OutputIterator output_begin) const;
127 
128  template <class OutputIterator>
129  OutputIterator find_contacts_generic(CollisionGeometryPtr cgA, CollisionGeometryPtr cgB, OutputIterator output_begin, double TOL);
130 
131  template <class OutputIterator>
132  OutputIterator find_contacts_plane_generic(CollisionGeometryPtr cgA, CollisionGeometryPtr cgB, OutputIterator output_begin, double TOL);
133 
134  template <class OutputIterator>
135  OutputIterator find_contacts_torus_plane(CollisionGeometryPtr cgA, CollisionGeometryPtr cgB, OutputIterator output_begin, double TOL);
136 
137  template <class OutputIterator>
138  OutputIterator find_contacts_sphere_plane(CollisionGeometryPtr cgA, CollisionGeometryPtr cgB, OutputIterator output_begin, double TOL);
139 
140  template <class OutputIterator>
141  OutputIterator find_contacts_cylinder_plane(CollisionGeometryPtr cgA, CollisionGeometryPtr cgB, OutputIterator output_begin, double TOL);
142 
143  template <class OutputIterator>
144  OutputIterator find_contacts_heightmap_generic(CollisionGeometryPtr cgA, CollisionGeometryPtr cgB, OutputIterator output_begin, double TOL);
145 
146  template <class OutputIterator>
147  OutputIterator find_contacts_sphere_sphere(CollisionGeometryPtr cgA, CollisionGeometryPtr cgB, OutputIterator output_begin, double TOL);
148 
149  template <class OutputIterator>
150  OutputIterator find_contacts_sphere_heightmap(CollisionGeometryPtr cgA, CollisionGeometryPtr cgB, OutputIterator output_begin, double TOL);
151 
152  template <class OutputIterator>
153  OutputIterator find_contacts_convex_heightmap(CollisionGeometryPtr cgA, CollisionGeometryPtr cgB, OutputIterator output_begin, double TOL);
154 
155  template <class OutputIterator>
156  OutputIterator find_contacts_box_sphere(CollisionGeometryPtr cgA, CollisionGeometryPtr cgB, OutputIterator output_begin, double TOL);
157 
158  template <class RandomAccessIterator>
159  void insertion_sort(RandomAccessIterator begin, RandomAccessIterator end);
160 
161  template <class OutputIterator>
162  OutputIterator find_contacts_vertex_vertex(CollisionGeometryPtr cgA, CollisionGeometryPtr cgB, boost::shared_ptr<Polyhedron::Vertex> v1, boost::shared_ptr<Polyhedron::Vertex> v2, double signed_dist, OutputIterator output_begin);
163 
164  template <class OutputIterator>
165  OutputIterator find_contacts_vertex_edge(CollisionGeometryPtr cgA, CollisionGeometryPtr cgB, boost::shared_ptr<Polyhedron::Vertex> v, boost::shared_ptr<Polyhedron::Edge> e, double signed_dist, OutputIterator output_begin);
166 
167  template <class OutputIterator>
168  OutputIterator find_contacts_vertex_face(CollisionGeometryPtr cgA, CollisionGeometryPtr cgB, boost::shared_ptr<Polyhedron::Vertex> vA, boost::shared_ptr<Polyhedron::Face> fB, double signed_dist, OutputIterator output_begin);
169 
170  template <class OutputIterator>
171  OutputIterator find_contacts_edge_edge(CollisionGeometryPtr cgA, CollisionGeometryPtr cgB, boost::shared_ptr<Polyhedron::Edge> e1, boost::shared_ptr<Polyhedron::Edge> e2, double signed_dist, OutputIterator output_begin);
172 
173  template <class OutputIterator>
174  OutputIterator find_contacts_edge_face(CollisionGeometryPtr cgA, CollisionGeometryPtr cgB, boost::shared_ptr<Polyhedron::Edge> eA, boost::shared_ptr<Polyhedron::Face> fB, double signed_dist, OutputIterator output_begin);
175 
176  template <class OutputIterator>
177  OutputIterator find_contacts_face_face(CollisionGeometryPtr cgA, CollisionGeometryPtr cgB, boost::shared_ptr<Polyhedron::Face> fA, boost::shared_ptr<Polyhedron::Face> fB, double signed_dist, OutputIterator output_begin);
178 
179 }; // end class
180 
181 #include "CCD.inl"
182 
183 } // end namespace
184 
185 #endif
186 
Defines an abstract collision detection mechanism.
Definition: CollisionDetection.h:38
Abstract class for articulated bodies.
Definition: ArticulatedBody.h:26
boost::shared_ptr< BV > BVPtr
Bounding volume (BV) smart pointer.
Definition: Types.h:92
std::set< Ravelin::sorted_pair< CollisionGeometryPtr > > disabled_pairs
Pairs of collision geometries that aren't checked for contact/collision.
Definition: CCD.h:62
virtual void broad_phase(double dt, const std::vector< ControlledBodyPtr > &bodies, std::vector< std::pair< CollisionGeometryPtr, CollisionGeometryPtr > > &to_check)
Default broad phase function (checks everything)
Definition: CCD.cpp:702
Represents a single rigid body.
Definition: RigidBody.h:43
virtual double calc_CA_Euler_step(const PairwiseDistInfo &pdi)
Computes a conservative advancement step between two collision geometries assuming that velocity is c...
Definition: CCD.cpp:122
boost::shared_ptr< RigidBody > RigidBodyPtr
Rigid body smart pointer.
Definition: Types.h:62
boost::shared_ptr< CollisionGeometry > CollisionGeometryPtr
Collision geometry smart pointer.
Definition: Types.h:77
Defines collision geometry that may be used (in principle) many ways: for rigid bodies, non-rigid bodies, ...
Definition: CollisionGeometry.h:36
boost::shared_ptr< XMLTree > XMLTreePtr
XML tree smart pointer.
Definition: Types.h:104
virtual void load_from_xml(boost::shared_ptr< const XMLTree > node, std::map< std::string, BasePtr > &id_map)
Implements Base::load_from_xml()
Definition: CCD.cpp:674
Implements the CollisionDetection abstract class to perform exact contact finding using abstract shap...
Definition: CCD.h:36
virtual void save_to_xml(XMLTreePtr node, std::list< boost::shared_ptr< const Base > > &shared_objects) const
Implements Base::save_to_xml()
Definition: CCD.cpp:690
boost::shared_ptr< ArticulatedBody > ArticulatedBodyPtr
Articulated body smart pointer.
Definition: Types.h:65
CCD()
Constructs a collision detector with default tolerances.
Definition: CCD.cpp:55
Structure for storing the pairwise distance between pointers to two CollisionGeometry objects...
Definition: PairwiseDistInfo.h:15