00001
00002
00003
00004
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 };
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
00113 for (ForwardIterator i = first; i != last; i++)
00114 {
00115
00116 if ((*i)->_contact_type == Contact::eVertex)
00117 singletons->push_back(*i);
00118 else if ((*i)->_contact_type == Contact::ePoints)
00119 {
00120
00121 for (std::list<Vector3>::const_iterator j = (*i)->_points.begin(); j != (*i)->_points.end(); j++)
00122 {
00123
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
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
00144 for (std::list<Vector3>::const_iterator j = (*i)->_surface.begin(); j != (*i)->_surface.end(); j++)
00145 {
00146
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
00156 const std::vector<Vector3ConstPtr>& vertices = (*i)->_volume->get_vertices();
00157
00158
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 }
00173
00174 #endif
00175