Go to the documentation of this file.00001 #ifndef OPENTISSUE_COLLISION_AABB_TREE_POLICIES_AABB_TREE_SINGLE_COLLISION_POLICY_H
00002 #define OPENTISSUE_COLLISION_AABB_TREE_POLICIES_AABB_TREE_SINGLE_COLLISION_POLICY_H
00003
00004
00005
00006
00007
00008
00009
00010 #include <OpenTissue/configuration.h>
00011
00012 #include <OpenTissue/collision/intersect/intersect_aabb_aabb.h>
00013
00014 namespace OpenTissue
00015 {
00016 namespace aabb_tree
00017 {
00018
00024 template<typename aabb_tree_geometry>
00025 class SingleCollisionPolicy
00026 {
00027 public:
00028
00029 typedef typename aabb_tree_geometry::bvh_type bvh_type;
00030 typedef typename bvh_type::volume_type volume_type;
00031 typedef typename bvh_type::geometry_type geometry_type;
00032 typedef typename bvh_type::geometry_iterator geometry_iterator;
00033 typedef typename bvh_type::bv_ptr bv_ptr;
00034 typedef typename bvh_type::annotated_bv_ptr annotated_bv_ptr;
00035 typedef typename bvh_type::annotated_bv_type annotated_bv_type;
00036
00037 typedef typename volume_type::math_types math_types;
00038 typedef typename math_types::real_type real_type;
00039 typedef typename math_types::vector3_type vector3_type;
00040
00041 public:
00042
00043 template<typename contact_point_container>
00044 void reset(contact_point_container & ) { }
00045
00046
00053 template<typename coord_transform,typename point_data_type>
00054 bool overlap(
00055 coord_transform const &
00056 , bv_ptr bv
00057 , point_data_type const & point
00058 )
00059 {
00060 vector3_type r = point.position();
00061 vector3_type r_old = point.old_position();
00062
00063 vector3_type m = vector3_type( math::detail::highest<real_type>() );
00064 vector3_type M = vector3_type( math::detail::lowest<real_type>() );
00065
00066 m = min(m,r);
00067 m = min(m,r_old);
00068 M = max(M,r);
00069 M = max(M,r_old);
00070
00071 volume_type sweeping(m,M);
00072
00073 return OpenTissue::intersect::aabb_aabb(sweeping, bv->volume());
00074 }
00075
00082 template<typename coord_transform,typename contact_point_container,typename point_data_type>
00083 void report(
00084 coord_transform const &
00085 , bv_ptr bv
00086 , point_data_type const & point
00087 , contact_point_container & contacts
00088 )
00089 {
00090 typedef typename contact_point_container::value_type contact_point_type;
00091
00092 using std::fabs;
00093
00094 vector3_type r = point.position();
00095 vector3_type r_old = point.old_position();
00096
00097 annotated_bv_ptr annotated_bv = boost::static_pointer_cast<annotated_bv_type>(bv);
00098
00099 geometry_type * triangle = &(*( annotated_bv->geometry_begin()));
00100 assert(triangle);
00101
00102 vector3_type x1 = triangle->m_p0->position();
00103 vector3_type x2 = triangle->m_p1->position();
00104 vector3_type x3 = triangle->m_p2->position();
00105
00106 geometry::Plane<math_types> plane;
00107 plane.set(x1,x2,x3);
00108
00109 real_type dO = plane.signed_distance(r_old);
00110 real_type dD = plane.signed_distance(r);
00111
00112 real_type t;
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122 t = dO/(dO-dD);
00123
00124 static real_type threshold = math::working_precision<real_type>();
00125 if((t<-threshold) || (t>(1.+threshold)))
00126 return;
00127
00128 vector3_type u;
00129 u = (r- r_old)*t + r_old;
00130
00131
00132
00133
00134
00135 real_type w1,w2,w3;
00136 OpenTissue::geometry::barycentric_algebraic(x1,x2,x3,u,w1,w2,w3);
00137
00138
00139
00140
00141
00142 real_type delta = 10e-5;
00143 real_type lower = - delta;
00144 real_type upper = 1.+ delta;
00145 if(
00146 (w1>lower)&&(w1<upper)
00147 &&
00148 (w2>lower)&&(w2<upper)
00149 &&
00150 (w3>lower)&&(w3<upper)
00151 )
00152 {
00153 contact_point_type cp;
00154
00155 cp.m_distance = fabs(dD);
00156 cp.m_n = plane.n();
00157 cp.m_p = u;
00158
00159 cp.m_A0 = const_cast<point_data_type*>(&point);
00160 cp.m_A1 = 0;
00161 cp.m_A2 = 0;
00162
00163 cp.m_B0 = triangle->m_p0;
00164 cp.m_B1 = triangle->m_p1;
00165 cp.m_B2 = triangle->m_p2;
00166
00167 cp.m_a0 = t;
00168 cp.m_a1 = 0;
00169 cp.m_a2 = 0;
00170
00171 cp.m_b0 = w1;
00172 cp.m_b1 = w2;
00173 cp.m_b2 = w3;
00174
00175 contacts.push_back( cp );
00176 }
00177
00178 }
00179
00180 };
00181
00182 }
00183
00184 }
00185
00186
00187 #endif