00001 #ifndef OPENTISSUE_COLLISION_GJK_GJK_VORONOI_SIMPLEX_SOLVER_POLICY_H 00002 #define OPENTISSUE_COLLISION_GJK_GJK_VORONOI_SIMPLEX_SOLVER_POLICY_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/collision/gjk/gjk_simplex.h> 00013 #include <OpenTissue/collision/gjk/gjk_reduce_edge.h> 00014 #include <OpenTissue/collision/gjk/gjk_reduce_triangle.h> 00015 #include <OpenTissue/collision/gjk/gjk_reduce_tetrahedron.h> 00016 00017 #include <cmath> 00018 #include <cassert> 00019 00020 namespace OpenTissue 00021 { 00022 namespace gjk 00023 { 00024 00033 class VoronoiSimplexSolverPolicy 00034 { 00035 public: 00036 00055 template<typename V> 00056 static V reduce_simplex( Simplex<V> & S, V & a, V & b ) 00057 { 00058 typedef typename V::value_traits value_traits; 00059 00060 V const p = V( value_traits::zero(), value_traits::zero(), value_traits::zero() ); 00061 00062 switch( dimension( S ) ) 00063 { 00064 case 1: 00065 { 00066 // Nothing to do, a vertex can not be reduced! 00067 int bit_A = 0; 00068 size_t idx_A = 0; 00069 00070 get_used_indices( S.m_bitmask, idx_A, bit_A ); 00071 00072 S.m_bitmask = bit_A; 00073 S.m_w[idx_A] = value_traits::one(); 00074 } 00075 break; 00076 case 2: 00077 detail::reduce_edge(p, S); 00078 break; 00079 case 3: 00080 detail::reduce_triangle(p, S); 00081 break; 00082 case 4: 00083 detail::reduce_tetrahedron(p, S); 00084 break; 00085 default: 00086 assert(false || !"reduce_simplex(): can not reduce simplex of that size"); 00087 break; 00088 }; 00089 00090 // Now compute the actual closest points based on the bary-centric coordinates. 00091 a.clear(); 00092 b.clear(); 00093 int used_bit = 1; 00094 for(size_t i=0u; i<4u; ++i) 00095 { 00096 if(S.m_bitmask & used_bit) 00097 { 00098 a += S.m_w[i]*S.m_a[i]; 00099 b += S.m_w[i]*S.m_b[i]; 00100 } 00101 used_bit <<= 1; 00102 } 00103 return (a-b); 00104 } 00105 00106 }; 00107 00108 } // namespace gjk 00109 00110 } // namespace OpenTissue 00111 00112 // OPENTISSUE_COLLISION_GJK_GJK_VORONOI_SIMPLEX_SOLVER_POLICY_H 00113 #endif