Contact.h

00001 /****************************************************************************
00002  * Copyright 2006 Evan Drumwright
00003  * This library is distributed under the terms of the GNU General Public 
00004  * License (found in COPYING).
00005  ****************************************************************************/
00006 
00007 #ifndef _CONTACT_H
00008 #define _CONTACT_H
00009 
00010 #include <iostream>
00011 #include <list>
00012 #include <boost/shared_ptr.hpp>
00013 #include <Physsim/Vector3.h>
00014 #include <Physsim/ContactData.h>
00015 
00016 class SoNode;
00017 
00018 namespace Physsim {
00019 
00020 class Polyhedron;
00021 class CollisionGeometry;
00022 
00024 
00028 class Contact : public Base
00029 {
00030         public:
00031                 enum ContactPhaseType { eNoContact, eImpacting, eImpactResponse, eRestingStart, eResting };
00032                 enum ContactType { eNone, eVertex, eEdge, ePoints, ePolygon, ePolyhedron };
00033                 Contact() { _contact_type = eNone; }
00034                 Contact(const Contact& c) { *this = c; }
00035                 virtual ~Contact() {}
00036                 void operator=(const Contact& c);               
00037                 virtual bool is_struct_identical(BaseConstPtr object) const;
00038                 virtual void clone(BasePtr& cloned, bimap<BasePtr, BasePtr>* obj_map = NULL) const;
00039                 virtual void load_state(BaseConstPtr object, bimap<BasePtr, BasePtr>* correspondence = NULL);
00040                 virtual void save_state(BasePtr object, bimap<BasePtr, BasePtr>* correspondence = NULL) const;
00041                 boost::shared_ptr<std::list<Vector3> > get_vertices() const;
00042                 void set_contact_data(boost::shared_ptr<ContactData> cdata);
00043                 void apply_contact_forces() const;
00044                 static void det_connected_contacts(const std::list<ContactPtr>& contacts, std::list<std::list<ContactPtr> >& sets);
00045 
00047                 boost::shared_ptr<ContactData> get_contact_data() const { return _cdata; }
00048 
00049                 template <class ForwardIterator>
00050                 static boost::shared_ptr<std::list<ContactPtr> > form_singletons(ForwardIterator first, ForwardIterator last);
00051                 
00053                 ContactType _contact_type;
00054 
00056                 Real _d;
00057                 
00059                 Vector3 _vertex;
00060                 
00062                 std::list<Vector3> _points;
00063 
00065                 std::pair<Vector3, Vector3> _edge;
00066                 
00068                 std::list<Vector3> _surface;
00069                 
00071                 PolyhedronPtr _volume;
00072 
00074                 Vector3 _normal;        
00075 
00077                 Vector3 _normal_dot;
00078 
00080                 std::list<std::pair<Vector3, Real> > _normal_forces;
00081 
00083                 std::list<std::pair<Vector3, Vector3> > _tangent_forces;
00084 
00086                 CollisionGeometryPtr _geom1, _geom2;
00087 
00089                 ContactPhaseType _phase;
00090 
00091                 boost::shared_ptr<std::list<Vector3> > generate_samples() const;        
00092                 boost::shared_ptr<std::list<Vector3> > generate_samples(unsigned n) const;
00093                 SoNode* to_visualization_data() const;
00094                 void write_vrml(const std::string& filename) const;
00095 
00096         private:
00097                 static std::pair<Real, Real> sample_Halton_2D(unsigned n);
00098                 static Real sample_Halton_1D(unsigned n);       
00099 
00101                 boost::shared_ptr<ContactData> _cdata;
00102 }; // end class
00103 
00104 std::ostream& operator<<(std::ostream& o, const Contact& c);
00105 
00107 template <class ForwardIterator>
00108 boost::shared_ptr<std::list<ContactPtr> > Contact::form_singletons(ForwardIterator first, ForwardIterator last)
00109 {
00110         boost::shared_ptr<std::list<ContactPtr> > singletons(new std::list<ContactPtr>());
00111 
00112         // iterate over all contacts
00113         for (ForwardIterator i = first; i != last; i++)
00114         {
00115                 // if the contact type is a vertex, copy *i to the list of discrete contacts
00116                 if ((*i)->_contact_type == Contact::eVertex)
00117                         singletons->push_back(*i);
00118                 else if ((*i)->_contact_type == Contact::ePoints)
00119                 {                       
00120                         // create a contact for every vertex
00121                         for (std::list<Vector3>::const_iterator j = (*i)->_points.begin(); j != (*i)->_points.end(); j++)
00122                         {
00123                                 // create a new contacts
00124                                 ContactPtr c(new Contact(**i));
00125                                 c->_contact_type = Contact::eVertex;
00126                                 c->_vertex = *j;
00127                                 singletons->push_back(c);
00128                         }                               
00129                 }
00130                 else if ((*i)->_contact_type == Contact::eEdge)
00131                 {
00132                         // create two new contacts
00133                         ContactPtr c1(new Contact(**i));
00134                         ContactPtr c2(new Contact(**i));
00135                         c1->_contact_type = c2->_contact_type = Contact::eVertex;
00136                         c1->_vertex = (*i)->_edge.first;
00137                         c2->_vertex = (*i)->_edge.second;
00138                         singletons->push_back(c1);
00139                         singletons->push_back(c2);
00140                 }
00141                 else if ((*i)->_contact_type == Contact::ePolygon)
00142                 {
00143                         // create a contact for every vertex
00144                         for (std::list<Vector3>::const_iterator j = (*i)->_surface.begin(); j != (*i)->_surface.end(); j++)
00145                         {
00146                                 // create a new contacts
00147                                 ContactPtr c(new Contact(**i));
00148                                 c->_contact_type = Contact::eVertex;
00149                                 c->_vertex = *j;
00150                                 singletons->push_back(c);
00151                         }                               
00152                 }
00153                 else
00154                 {
00155                         // get the vertices for the polyhedron of contact
00156                         const std::vector<Vector3ConstPtr>& vertices = (*i)->_volume->get_vertices();
00157                         
00158                         // turn the list of n contact points into n separate contacts of one point each
00159                         for (unsigned j=0; j< vertices.size(); j++)
00160                         {
00161                                 ContactPtr c(new Contact(**i));
00162                                 c->_contact_type = Contact::eVertex;
00163                                 c->_vertex = *vertices[j];
00164                                 singletons->push_back(c);
00165                         }
00166                 }
00167         }
00168 
00169         return singletons;                      
00170 }
00171 
00172 } // end namespace Physsim
00173 
00174 #endif
00175 

Generated on Wed Oct 24 14:54:21 2007 for Physsim by  doxygen 1.5.1