Go to the documentation of this file.00001 #ifndef OPENTISSUE_DYNAMICS_MBD_COLLISION_DETECTION_MBD_COLLISION_DETECTION_H
00002 #define OPENTISSUE_DYNAMICS_MBD_COLLISION_DETECTION_MBD_COLLISION_DETECTION_H
00003
00004
00005
00006
00007
00008
00009
00010 #include <OpenTissue/configuration.h>
00011
00012 namespace OpenTissue
00013 {
00014 namespace mbd
00015 {
00024 template<
00025 typename types,
00026 template<typename types> class BroadPhasePolicy,
00027 template<typename types> class NarrowPhasePolicy,
00028 template<typename types> class AnalyzerPolicy
00029 >
00030 class CollisionDetection
00031 {
00032 protected:
00033
00034 typedef typename types::math_policy::index_type size_type;
00035 typedef typename types::configuration_type configuration_type;
00036 typedef typename types::body_type body_type;
00037 typedef typename types::edge_type edge_type;
00038 typedef typename types::group_ptr_container group_ptr_container;
00039 typedef typename types::group_type group_type;
00040 typedef typename types::edge_ptr_container edge_ptr_container;
00041 typedef typename types::indirect_edge_iterator indirect_edge_iterator;
00042
00043 typedef BroadPhasePolicy<types> broad_phase_type;
00044 typedef NarrowPhasePolicy<types> narrow_phase_type;
00045 typedef AnalyzerPolicy<types> analyzer_type;
00046
00047 public:
00048
00049 class node_traits
00050 : public broad_phase_type::node_traits
00051 , public narrow_phase_type::node_traits
00052 , public analyzer_type::node_traits
00053 {};
00054
00055 class edge_traits
00056 : public broad_phase_type::edge_traits
00057 , public narrow_phase_type::edge_traits
00058 , public analyzer_type::edge_traits
00059 {};
00060
00061 class constraint_traits
00062 : public broad_phase_type::constraint_traits
00063 , public narrow_phase_type::constraint_traits
00064 , public analyzer_type::constraint_traits
00065 {};
00066
00067 protected:
00068
00069 configuration_type * m_configuration;
00070 broad_phase_type m_broad_phase;
00071 narrow_phase_type m_narrow_phase;
00072 analyzer_type m_analyzer;
00073 bool m_short_circuit;
00074 size_type m_time_stamp;
00075
00076 public:
00077
00078 CollisionDetection()
00079 : m_configuration(0)
00080 , m_short_circuit(false)
00081 , m_time_stamp(0)
00082 {}
00083
00084 public:
00085
00091 broad_phase_type * get_broad_phase() { return &m_broad_phase; }
00092 broad_phase_type const * get_broad_phase() const { return &m_broad_phase; }
00093
00099 narrow_phase_type * get_narrow_phase() { return &m_narrow_phase; }
00100 narrow_phase_type const * get_narrow_phase() const { return &m_narrow_phase; }
00101
00107 analyzer_type * get_analyzer() { return &m_analyzer; }
00108 analyzer_type const * get_analyzer() const { return &m_analyzer; }
00109
00110
00111 public:
00112
00120 bool run(group_ptr_container & groups)
00121 {
00122 ++m_time_stamp;
00123
00124 assert(m_configuration || !"CollisionDetection::run(): missing configuration");
00125
00126 edge_ptr_container edges;
00127 bool penetration = false;
00128 m_broad_phase.run(edges);
00129
00130
00131 indirect_edge_iterator begin(edges.begin());
00132 indirect_edge_iterator end(edges.end());
00133
00134 for(indirect_edge_iterator edge = begin;edge!=end;++edge)
00135 {
00136 edge->m_updated_time_stamp = m_time_stamp;
00137 }
00138
00139
00140 {
00141
00142
00143
00144
00145 typename configuration_type::joint_iterator joint = m_configuration->joint_begin();
00146 typename configuration_type::joint_iterator end = m_configuration->joint_end();
00147 for(;joint!=end;++joint)
00148 {
00149 body_type * A = joint->get_socket_A()->get_body();
00150 body_type * B = joint->get_socket_B()->get_body();
00151 edge_type * edge = m_configuration->get_edge(A,B);
00152 if(!edge)
00153 edge = m_configuration->add(A,B);
00154 if(edge->m_updated_time_stamp != m_time_stamp)
00155 {
00156 edge->m_updated_time_stamp = m_time_stamp;
00157 edges.push_back( &(*edge) );
00158 }
00159 }
00160 }
00161
00162 penetration |= m_analyzer.post_broad_phase_analysis(edges);
00163
00164 if(m_short_circuit && penetration)
00165 return penetration;
00166
00167 for(indirect_edge_iterator edge = begin;edge!=end;++edge)
00168 {
00169 if(edge->prunned())
00170 continue;
00171
00172 penetration |= m_narrow_phase.run(&(*edge));
00173
00174 if(m_short_circuit && penetration)
00175 return penetration;
00176 }
00177 m_analyzer.post_narrow_phase_analysis(edges);
00178
00179 m_analyzer.post_contact_determination_analysis(edges,groups);
00180 return penetration;
00181 }
00182
00188 void init(configuration_type & configuration)
00189 {
00190 m_time_stamp = 0;
00191 m_configuration = &configuration;
00192 m_broad_phase.init(configuration);
00193 m_narrow_phase.init(configuration);
00194 m_analyzer.init(configuration);
00195 }
00196
00200 void clear()
00201 {
00202 m_time_stamp = 0;
00203 m_broad_phase.clear();
00204 m_narrow_phase.clear();
00205 m_analyzer.clear();
00206 }
00207
00215 bool add(body_type * body)
00216 {
00217 assert(body || !"CollisionDetection::add(): body was null");
00218 assert(m_configuration || !"CollisionDetection::add(): missing configuration");
00219 m_broad_phase.add(body);
00220 m_narrow_phase.add(body);
00221 m_analyzer.add(body);
00222 return true;
00223 }
00224
00232 bool remove(body_type * body)
00233 {
00234 assert(body || !"CollisionDetection::remove(): body was null");
00235 assert(m_configuration || !"CollisionDetection::remove(): missing configuration");
00236 m_broad_phase.remove(body);
00237 m_narrow_phase.remove(body);
00238 m_analyzer.remove(body);
00239 return true;
00240 }
00241
00242
00250 void set_short_circuiting(bool const & value)
00251 {
00252 m_short_circuit = value;
00253 }
00254
00260 bool is_short_circuiting() const {return m_short_circuit;}
00261
00268 size_type get_time_stamp() const {return m_time_stamp;}
00269
00270 };
00271
00272 }
00273 }
00274
00275
00276 #endif