Go to the documentation of this file.00001 #ifndef OPENTISSUE_DYNAMICS_MBD_COLLISION_DETECTION_MBD_SINGLE_GROUP_ANALYSIS_H
00002 #define OPENTISSUE_DYNAMICS_MBD_COLLISION_DETECTION_MBD_SINGLE_GROUP_ANALYSIS_H
00003
00004
00005
00006
00007
00008
00009
00010 #include <OpenTissue/configuration.h>
00011
00012 #include <OpenTissue/core/math/math_precision.h>
00013 #include <OpenTissue/core/math/math_constants.h>
00014
00015
00016 namespace OpenTissue
00017 {
00018 namespace mbd
00019 {
00023 template<typename types>
00024 class SingleGroupAnalysis
00025 {
00026 protected:
00027
00028 typedef typename types::math_policy::index_type size_type;
00029 typedef typename types::math_policy::real_type real_type;
00030 typedef typename types::math_policy::vector3_type vector3_type;
00031 typedef typename types::math_policy::quaternion_type quaternion_type;
00032 typedef typename types::math_policy::coordsys_type coordsys_type;
00033
00034 typedef typename types::configuration_type configuration_type;
00035 typedef typename types::group_container group_container;
00036 typedef typename types::group_ptr_container group_ptr_container;
00037 typedef typename types::group_type group_type;
00038 typedef typename types::edge_ptr_container edge_ptr_container;
00039 typedef typename types::indirect_edge_iterator indirect_edge_iterator;
00040 typedef typename types::body_type body_type;
00041 typedef typename types::contact_type contact_type;
00042 typedef typename types::edge_type edge_type;
00043 typedef typename types::joint_type joint_type;
00044
00045 public:
00046
00047 class node_traits
00048 {
00049 public:
00050 node_traits()
00051 : m_sga_r_prev(0,0,0)
00052 , m_sga_Q_prev(0,1,0,0)
00053 , m_sga_absolute_resting(false)
00054 {}
00055
00056 public:
00057 vector3_type m_sga_r_prev;
00058 quaternion_type m_sga_Q_prev;
00059 bool m_sga_absolute_resting;
00060
00061
00062
00063
00064 };
00065
00066 class edge_traits
00067 {
00068 public:
00069
00070 typedef enum{
00071 undefined,
00072 separating,
00073 touching,
00074 penetrating
00075 } SGA_StateType;
00076
00077 public:
00078 edge_traits()
00079 : m_sga_time_stamp(0)
00080 {}
00081 public:
00082 coordsys_type m_sga_xformAtoB;
00083 coordsys_type m_sga_xformBtoA;
00084 coordsys_type m_sga_xformAtoB_prev;
00085 size_type m_sga_time_stamp;
00086 SGA_StateType m_sga_state;
00087 };
00088
00089 class constraint_traits { };
00090
00091
00092 protected:
00093
00094 configuration_type * m_configuration;
00095 group_type m_group;
00096 size_type m_time_stamp;
00097
00098 public:
00099
00100 SingleGroupAnalysis()
00101 : m_configuration(0)
00102 , m_time_stamp(0)
00103 {}
00104
00105 protected:
00106
00116 void do_absolute_resting_test()
00117 {
00118
00119 real_type accuracy = 0.001;
00120
00121 for(typename configuration_type::body_iterator body = m_configuration->body_begin();body!=m_configuration->body_end();++body)
00122 {
00123
00124 if(!body->is_active())
00125 continue;
00126
00127 vector3_type r;
00128 quaternion_type Q;
00129 body->get_position( r );
00130 body->get_orientation( Q );
00131 if(
00132 r.is_equal(body->m_sga_r_prev,accuracy)
00133 &&
00134 Q.is_equal(body->m_sga_Q_prev,accuracy)
00135 )
00136 {
00137 body->m_sga_absolute_resting = true;
00138 }
00139 else
00140 {
00141 body->m_sga_absolute_resting = false;
00142 body->m_sga_r_prev = r;
00143 body->m_sga_Q_prev = Q;
00144 }
00145 }
00146 }
00147
00148 public:
00149
00156 const bool post_broad_phase_analysis( edge_ptr_container & edges )
00157 {
00158 ++m_time_stamp;
00159 assert(m_configuration);
00160 bool penetration = false;
00161
00162 do_absolute_resting_test();
00163
00164
00165
00166
00167 indirect_edge_iterator begin(edges.begin());
00168 indirect_edge_iterator end(edges.end());
00169 for( indirect_edge_iterator edge = begin; edge!=end; ++edge )
00170 {
00171 edge->m_sga_time_stamp = m_time_stamp;
00172 edge->prunned() = true;
00173
00174 if(edge->get_body_A()->has_joint_to(edge->get_body_B()))
00175 continue;
00176 if(edge->get_body_A()->is_fixed() && edge->get_body_B()->is_fixed())
00177 continue;
00178 if(edge->get_body_A()->is_scripted() && edge->get_body_B()->is_scripted())
00179 continue;
00180 if(edge->get_body_A()->is_fixed() && edge->get_body_B()->is_scripted())
00181 continue;
00182 if(edge->get_body_A()->is_scripted() && edge->get_body_B()->is_fixed())
00183 continue;
00184 if(!edge->get_body_A()->is_active() || !edge->get_body_B()->is_active())
00185 continue;
00186 if(edge->get_body_A()->m_sga_absolute_resting && edge->get_body_B()->m_sga_absolute_resting )
00187 {
00188 edge->m_relative_resting = true;
00189 continue;
00190 }
00191 vector3_type r_a, r_b;
00192 quaternion_type Q_a, Q_b;
00193 edge->get_body_A()->get_position( r_a );
00194 edge->get_body_A()->get_orientation( Q_a );
00195 edge->get_body_B()->get_position( r_b );
00196 edge->get_body_B()->get_orientation( Q_b );
00197 edge->m_sga_xformAtoB = model_update(r_a, Q_a, r_b, Q_b );
00198
00199
00200 static real_type threshold = OpenTissue::math::working_precision<real_type>();
00201 if( edge->m_sga_xformAtoB.is_equal(edge->m_sga_xformAtoB_prev,threshold))
00202 {
00203
00204
00205
00206
00207 edge->m_relative_resting = true;
00208
00209
00210
00211
00212
00213
00214 }
00215 else
00216 {
00217
00218
00219
00220 edge->m_relative_resting = false;
00221 edge->m_sga_xformAtoB_prev = edge->m_sga_xformAtoB;
00222 edge->m_sga_xformBtoA = inverse(edge->m_sga_xformAtoB);
00223 }
00224 edge->prunned() = false;
00225 }
00226 return penetration;
00227 };
00228
00240 void post_narrow_phase_analysis(edge_ptr_container & edges )
00241 {
00242 using std::min;
00243
00244 assert(m_configuration);
00245 real_type envelope = m_configuration->get_collision_envelope();
00246 indirect_edge_iterator begin(edges.begin());
00247 indirect_edge_iterator end(edges.end());
00248 for(indirect_edge_iterator edge=begin;edge!=end;++edge)
00249 {
00250 if(edge->prunned())
00251 continue;
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266
00267
00268
00269
00270
00271
00272
00273
00274
00275
00276
00277
00278
00279 edge->m_sga_state = edge_type::undefined;
00280 real_type minimum = OpenTissue::math::detail::highest<real_type>();
00281 for(typename edge_type::contact_iterator contact = edge->contact_begin();contact != edge->contact_end();++contact)
00282 {
00283 minimum = min(contact->m_distance,minimum);
00284 }
00285 if(minimum > envelope)
00286 {
00287 edge->m_sga_state = edge_type::separating;
00288 edge->prunned() = true;
00289 continue;
00290 }
00291 if(minimum < -envelope)
00292 edge->m_sga_state = edge_type::penetrating;
00293 else
00294 edge->m_sga_state = edge_type::touching;
00295 }
00296 };
00297
00298 void post_contact_determination_analysis( edge_ptr_container & edges, group_ptr_container & groups)
00299 {
00300 groups.clear();
00301
00302 m_group.clear();
00303 for(typename configuration_type::body_iterator body = m_configuration->body_begin();body!=m_configuration->body_end();++body)
00304 {
00305 if(body->is_active())
00306 m_group.m_bodies.push_back( &(*body));
00307 }
00308 indirect_edge_iterator begin(edges.begin());
00309 indirect_edge_iterator end(edges.end());
00310 for(indirect_edge_iterator edge = begin;edge!=end;++edge )
00311 {
00312 for(typename edge_type::contact_iterator contact = edge->contact_begin();contact!=edge->contact_end();++contact)
00313 {
00314 m_group.m_contacts.push_back( &(*contact) );
00315 }
00316
00317 body_type * A = edge->get_body_A();
00318 body_type * B = edge->get_body_B();
00319 if(A->has_joint_to(B))
00320 {
00321 for(typename body_type::indirect_joint_iterator joint = A->joint_begin();joint!=A->joint_end();++joint)
00322 {
00323 if(joint->get_socket_A()->get_body()==B || joint->get_socket_B()->get_body()==B)
00324 {
00325 m_group.m_constraints.push_back( &(*joint) );
00326 }
00327 }
00328 }
00329 }
00330 groups.push_back(&m_group);
00331 };
00332
00333 public:
00334
00335 void clear()
00336 {
00337 this->m_time_stamp = 0;
00338 this->m_configuration = 0;
00339 this->m_group.clear();
00340 }
00341
00342 void add(body_type * ){};
00343 void remove(body_type * ){};
00344 void init(configuration_type & configuration)
00345 {
00346 clear();
00347 m_configuration = &configuration;
00348 m_time_stamp = 0;
00349 };
00350
00351 };
00352
00353 }
00354 }
00355
00356
00357 #endif