00001 #ifndef OPENTISSUE_DYNAMICS_MBD_UTIL_COLLISION_RESOLVERS_MBD_ITERATE_ONCE_COLLISION_RESOLVER_H 00002 #define OPENTISSUE_DYNAMICS_MBD_UTIL_COLLISION_RESOLVERS_MBD_ITERATE_ONCE_COLLISION_RESOLVER_H 00003 // 00004 // OpenTissue Template Library 00005 // - A generic toolbox for physics-based modeling and simulation. 00006 // Copyright (C) 2008 Department of Computer Science, University of Copenhagen. 00007 // 00008 // OTTL is licensed under zlib: http://opensource.org/licenses/zlib-license.php 00009 // 00010 #include <OpenTissue/configuration.h> 00011 00012 #include <OpenTissue/dynamics/mbd/interfaces/mbd_collision_resolver_interface.h> 00013 #include <OpenTissue/dynamics/mbd/mbd_apply_impulse.h> 00014 00015 namespace OpenTissue 00016 { 00017 namespace mbd 00018 { 00024 template< typename mbd_types, typename collision_law_policy > 00025 class IterateOnceCollisionResolver 00026 : public CollisionResolverInterface<mbd_types> 00027 , public collision_law_policy 00028 { 00029 public: 00030 00031 IterateOnceCollisionResolver() {} 00032 virtual ~IterateOnceCollisionResolver() {} 00033 00034 protected: 00035 00036 typedef typename mbd_types::math_policy::real_type real_type; 00037 typedef typename mbd_types::math_policy::vector3_type vector3_type; 00038 typedef typename mbd_types::group_type group_type; 00039 typedef typename mbd_types::body_type body_type; 00040 typedef typename mbd_types::contact_type contact_type; 00041 00042 public: 00043 00044 class node_traits{}; 00045 class edge_traits{}; 00046 class constraint_traits{ }; 00047 00048 protected: 00049 00054 struct ContactPointComparision 00055 { 00056 bool operator()(contact_type const * x, contact_type const * y) const 00057 { 00058 if(x->m_distance < y->m_distance) 00059 return true; 00060 return false; 00061 } 00062 }; 00063 00064 public: 00065 00066 void resolve_collisions(group_type & group) 00067 { 00068 if(group.size_contacts()==0) 00069 { 00070 return; 00071 } 00072 vector3_type J_a,J_b; 00073 group.m_contacts.sort(ContactPointComparision()); 00074 typename group_type::indirect_contact_iterator begin = group.contact_begin(); 00075 typename group_type::indirect_contact_iterator end = group.contact_end(); 00076 typename group_type::indirect_contact_iterator contact; 00077 for(contact=begin;contact!=end;++contact) 00078 { 00079 J_b = compute_impulse(&(*contact)); // from collision_law_policy 00080 J_a = - J_b; 00081 mbd::apply_impulse(contact->get_body_A(),contact->m_rA,J_a); 00082 mbd::apply_impulse(contact->get_body_B(),contact->m_rB,J_b); 00083 } 00084 } 00085 00086 }; 00087 00088 } // namespace mbd 00089 } // namespace OpenTissue 00090 // OPENTISSUE_DYNAMICS_MBD_UTIL_COLLISION_RESOLVERS_MBD_ITERATE_ONCE_COLLISION_RESOLVER_H 00091 #endif