00001 #ifndef OPENTISSUE_COLLISION_GJK_GJK_REDUCE_TRIANGLE_H
00002 #define OPENTISSUE_COLLISION_GJK_GJK_REDUCE_TRIANGLE_H
00003
00004
00005
00006
00007
00008
00009
00010 #include <OpenTissue/configuration.h>
00011
00012 #include <OpenTissue/core/geometry/geometry_barycentric.h>
00013
00014 #include <OpenTissue/collision/gjk/gjk_simplex.h>
00015 #include <OpenTissue/collision/gjk/gjk_outside_vertex_edge_voronoi_plane.h>
00016 #include <OpenTissue/collision/gjk/gjk_outside_edge_face_voronoi_plane.h>
00017
00018 namespace OpenTissue
00019 {
00020 namespace gjk
00021 {
00022
00023 namespace detail
00024 {
00037 template< typename V >
00038 inline void reduce_triangle( V const & p, Simplex<V> & S)
00039 {
00040 typedef typename V::value_type T;
00041 typedef typename V::value_traits value_traits;
00042
00043 int bit_A = 0;
00044 int bit_B = 0;
00045 int bit_C = 0;
00046 size_t idx_A = 0;
00047 size_t idx_B = 0;
00048 size_t idx_C = 0;
00049
00050 get_used_indices( S.m_bitmask, idx_A, bit_A, idx_B, bit_B, idx_C, bit_C );
00051
00052 V const & A = S.m_v[idx_A];
00053 V const & B = S.m_v[idx_B];
00054 V const & C = S.m_v[idx_C];
00055
00056 bool const outside_AB = outside_vertex_edge_voronoi_plane(p, A, B);
00057 bool const outside_AC = outside_vertex_edge_voronoi_plane(p, A, C);
00058 bool const outside_BC = outside_vertex_edge_voronoi_plane(p, B, C);
00059 bool const outside_BA = outside_vertex_edge_voronoi_plane(p, B, A);
00060 bool const outside_CA = outside_vertex_edge_voronoi_plane(p, C, A);
00061 bool const outside_CB = outside_vertex_edge_voronoi_plane(p, C, B);
00062 bool const outside_ABC = outside_edge_face_voronoi_plane( p, A, B, C);
00063 bool const outside_BCA = outside_edge_face_voronoi_plane( p, B, C, A);
00064 bool const outside_CAB = outside_edge_face_voronoi_plane( p, C, A, B);
00065
00066
00067 if( outside_AB && outside_AC )
00068 {
00069 S.m_bitmask = bit_A;
00070 S.m_v[idx_B].clear();
00071 S.m_v[idx_C].clear();
00072 S.m_a[idx_B].clear();
00073 S.m_a[idx_C].clear();
00074 S.m_b[idx_B].clear();
00075 S.m_b[idx_C].clear();
00076 S.m_w[idx_A] = value_traits::one();
00077 S.m_w[idx_B] = value_traits::zero();
00078 S.m_w[idx_C] = value_traits::zero();
00079 return;
00080 }
00081 if( outside_BA && outside_BC )
00082 {
00083 S.m_bitmask = bit_B;
00084 S.m_v[idx_A].clear();
00085 S.m_v[idx_C].clear();
00086 S.m_a[idx_A].clear();
00087 S.m_a[idx_C].clear();
00088 S.m_b[idx_A].clear();
00089 S.m_b[idx_C].clear();
00090 S.m_w[idx_A] = value_traits::zero();
00091 S.m_w[idx_B] = value_traits::one();
00092 S.m_w[idx_C] = value_traits::zero();
00093 return;
00094 }
00095 if( outside_CA && outside_CB )
00096 {
00097 S.m_bitmask = bit_C;
00098 S.m_v[idx_A].clear();
00099 S.m_v[idx_B].clear();
00100 S.m_a[idx_A].clear();
00101 S.m_a[idx_B].clear();
00102 S.m_b[idx_A].clear();
00103 S.m_b[idx_B].clear();
00104 S.m_w[idx_A] = value_traits::zero();
00105 S.m_w[idx_B] = value_traits::zero();
00106 S.m_w[idx_C] = value_traits::one();
00107 return;
00108 }
00109
00110 if( outside_ABC && !outside_AB && !outside_BA )
00111 {
00112 S.m_bitmask = bit_A | bit_B;
00113 S.m_v[idx_C].clear();
00114 S.m_a[idx_C].clear();
00115 S.m_b[idx_C].clear();
00116 S.m_w[idx_C] = value_traits::zero();
00117 OpenTissue::geometry::barycentric_geometric(A,B,p,S.m_w[idx_A],S.m_w[idx_B]);
00118 return;
00119 }
00120 if( outside_BCA && !outside_BC && !outside_CB )
00121 {
00122 S.m_bitmask = bit_B | bit_C;
00123 S.m_v[idx_A].clear();
00124 S.m_a[idx_A].clear();
00125 S.m_b[idx_A].clear();
00126 S.m_w[idx_A] = value_traits::zero();
00127 OpenTissue::geometry::barycentric_geometric(B,C,p,S.m_w[idx_B],S.m_w[idx_C]);
00128 return;
00129 }
00130 if( outside_CAB && !outside_AC && !outside_CA )
00131 {
00132 S.m_bitmask = bit_A | bit_C;
00133 S.m_v[idx_B].clear();
00134 S.m_a[idx_B].clear();
00135 S.m_b[idx_B].clear();
00136 S.m_w[idx_B] = value_traits::zero();
00137 OpenTissue::geometry::barycentric_geometric(A,C,p,S.m_w[idx_A],S.m_w[idx_C]);
00138 return;
00139 }
00140
00141 if(!outside_ABC && !outside_BCA && !outside_CAB)
00142 {
00143 OpenTissue::geometry::barycentric_geometric( A, B, C, p, S.m_w[idx_A], S.m_w[idx_B], S.m_w[idx_C]);
00144 return;
00145 }
00146 }
00147
00148
00149 }
00150 }
00151 }
00152
00153
00154 #endif