Go to the documentation of this file.00001 #ifndef OPENTISSUE_DYNAMICS_MBD_COLLISION_DETECTION_MBD_SPATIAL_HASHING_H
00002 #define OPENTISSUE_DYNAMICS_MBD_COLLISION_DETECTION_MBD_SPATIAL_HASHING_H
00003
00004
00005
00006
00007
00008
00009
00010 #include <OpenTissue/configuration.h>
00011
00012 #include <OpenTissue/core/geometry/geometry_aabb.h>
00013 #include <OpenTissue/collision/intersect/intersect_aabb_aabb.h>
00014 #include <OpenTissue/collision/spatial_hashing/spatial_hashing.h>
00015
00016 namespace OpenTissue
00017 {
00018 namespace mbd
00019 {
00023 template <typename types>
00024 class SpatialHashing
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::matrix3x3_type matrix3x3_type;
00032 typedef typename types::configuration_type configuration_type;
00033 typedef typename types::body_type body_type;
00034 typedef typename types::edge_type edge_type;
00035 typedef typename types::edge_ptr_container edge_ptr_container;
00036
00037 protected:
00038
00039 class collision_policy
00040 {
00041 public:
00042
00043 typedef typename types::math_policy::index_type size_type;
00044 typedef typename types::math_policy::real_type real_type;
00045 typedef body_type data_type;
00046 typedef body_type query_type;
00047 typedef edge_type result_type;
00048 typedef edge_ptr_container result_container;
00049
00050 typedef OpenTissue::spatial_hashing::PrimeNumberHashFunction hash_function;
00051
00052
00053
00054 typedef OpenTissue::spatial_hashing::Grid< OpenTissue::math::Vector3<real_type>, OpenTissue::math::Vector3<int>, data_type, hash_function> hash_grid;
00055
00056 public:
00057
00058 size_type m_policy_time_stamp;
00059 configuration_type * m_configuration;
00060
00061 public:
00062
00063 collision_policy()
00064 : m_policy_time_stamp(0)
00065 {}
00066
00067 vector3_type min_coord(body_type const & body) const { return body.min();};
00068 vector3_type max_coord(body_type const & body) const { return body.max();};
00069
00070 void reset(result_container & results)
00071 {
00072 results.clear();
00073 ++m_policy_time_stamp;
00074 };
00075
00076 void report(data_type const & data, query_type const & query,result_container & results)
00077 {
00078 body_type * body1 = const_cast<body_type*>(&data);
00079 body_type * body2 = const_cast<body_type*>(&query);
00080
00081 if(body1==body2)
00082 return;
00083
00084 if(body1->get_index() > body2->get_index())
00085 return;
00086
00087 edge_type * edge = m_configuration->get_edge( body1, body2 );
00088 if ( edge && edge->m_sh_time_stamp == m_policy_time_stamp )
00089 return;
00090
00091 if(OpenTissue::intersect::aabb_aabb(body1->m_aabb,body2->m_aabb))
00092 {
00093 if ( !edge )
00094 edge = m_configuration->add( body1, body2 );
00095 edge->m_sh_time_stamp = m_policy_time_stamp;
00096 results.push_back( edge );
00097 }
00098 }
00099 };
00100
00101 typedef OpenTissue::spatial_hashing::AABBDataQuery< typename collision_policy::hash_grid, collision_policy > query_algorithm;
00102
00103 public:
00104
00105 class node_traits
00106 {
00107 public:
00108
00109 geometry::AABB<typename types::math_policy> m_aabb;
00110
00111 vector3_type min(void) const { return m_aabb.min();};
00112 vector3_type max(void) const { return m_aabb.max();};
00113
00114 void updateAABB( body_type * self, real_type const & envelope )
00115 {
00116 vector3_type r;
00117 self->get_position( r );
00118 matrix3x3_type R;
00119 self->get_orientation( R );
00120 self->compute_collision_aabb( r, R, m_aabb.m_min, m_aabb.m_max, envelope );
00121 }
00122 };
00123
00124 class edge_traits
00125 {
00126 public:
00127 edge_traits ( void ) : m_sh_time_stamp( 0 ) {};
00128 size_type m_sh_time_stamp;
00129 };
00130
00131 class constraint_traits { };
00132
00133 protected:
00134
00135 query_algorithm m_query;
00136
00137 public:
00138
00139 SpatialHashing( ){}
00140
00141 public:
00142
00143 void clear()
00144 {
00145 this->m_query.m_policy_time_stamp = 0;
00146 this->m_query.m_configuration = 0;
00147 }
00148
00149 void add( body_type * ) { };
00150 void remove( body_type * ) {};
00151
00152 void init( configuration_type & configuration )
00153 {
00154 clear();
00155 m_query.m_policy_time_stamp = 0;
00156 m_query.m_configuration = &configuration;
00157
00158 real_type envelope = m_query.m_configuration->get_collision_envelope();
00159
00160 typename configuration_type::body_iterator begin( m_query.m_configuration->body_begin() );
00161 typename configuration_type::body_iterator end( m_query.m_configuration->body_end() );
00162 typename configuration_type::body_iterator body;
00163
00164 for ( body = begin; body != end; ++body )
00165 body->updateAABB( &( *body ), envelope );
00166
00167 m_query.auto_init_settings(begin,end);
00168
00169 std::cout << "SpatialHashing::init(): |dx| = " << m_query.get_spacing() << std::endl;
00170 std::cout << "SpatialHashing::init(): |S| = " << m_query.size() << std::endl;
00171 }
00172
00173 void run( edge_ptr_container & edges )
00174 {
00175 real_type envelope = m_query.m_configuration->get_collision_envelope();
00176
00177 typename configuration_type::body_iterator begin( m_query.m_configuration->body_begin() );
00178 typename configuration_type::body_iterator end( m_query.m_configuration->body_end() );
00179 typename configuration_type::body_iterator body;
00180
00181 for ( body = begin; body!=end; ++body )
00182 body->updateAABB( &( *body ), envelope );
00183
00184
00185 m_query(begin, end, begin, end, edges, typename query_algorithm::all_tag() );
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208 };
00209
00210 };
00211
00212 }
00213 }
00214
00215
00216 #endif