• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • Examples
  • File List
  • File Members

/home/hauberg/Dokumenter/Capture/humim-tracker-0.1/src/OpenTissue/OpenTissue/collision/gjk/gjk_reduce_tetrahedron.h

Go to the documentation of this file.
00001 #ifndef OPENTISSUE_COLLISION_GJK_GJK_REDUCE_TETRAHEDRON_H
00002 #define OPENTISSUE_COLLISION_GJK_GJK_REDUCE_TETRAHEDRON_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/core/geometry/geometry_barycentric.h>
00013 
00014 #include <OpenTissue/collision/gjk/gjk_simplex.h>
00015 #include <OpenTissue/collision/gjk/gjk_outside_triangle.h>
00016 #include <OpenTissue/collision/gjk/gjk_outside_vertex_edge_voronoi_plane.h>
00017 #include <OpenTissue/collision/gjk/gjk_outside_edge_face_voronoi_plane.h>
00018 
00019 #include <cmath>
00020 
00021 namespace OpenTissue
00022 {
00023   namespace gjk
00024   {
00025 
00026     namespace detail
00027     {
00041       template< typename V >
00042       inline void reduce_tetrahedron( V const & p, Simplex<V> & S)
00043       {
00044         typedef typename V::value_type    T;
00045         typedef typename V::value_traits  value_traits;
00046 
00047         size_t const idx_A = 0u;
00048         size_t const idx_B = 1u;
00049         size_t const idx_C = 2u;
00050         size_t const idx_D = 3u;
00051 
00052         int const bit_A = 1;
00053         int const bit_B = 2;
00054         int const bit_C = 4;
00055         int const bit_D = 8;
00056 
00057         V const & A = S.m_v[idx_A];
00058         V const & B = S.m_v[idx_B];
00059         V const & C = S.m_v[idx_C];
00060         V const & D = S.m_v[idx_D];
00061 
00062         bool const outside_AB     = outside_vertex_edge_voronoi_plane(p, A, B);
00063         bool const outside_AC     = outside_vertex_edge_voronoi_plane(p, A, C);
00064         bool const outside_AD     = outside_vertex_edge_voronoi_plane(p, A, D);
00065         bool const outside_BA     = outside_vertex_edge_voronoi_plane(p, B, A);
00066         bool const outside_BC     = outside_vertex_edge_voronoi_plane(p, B, C);
00067         bool const outside_BD     = outside_vertex_edge_voronoi_plane(p, B, D);
00068         bool const outside_CA     = outside_vertex_edge_voronoi_plane(p, C, A);
00069         bool const outside_CB     = outside_vertex_edge_voronoi_plane(p, C, B);
00070         bool const outside_CD     = outside_vertex_edge_voronoi_plane(p, C, D);
00071         bool const outside_DA     = outside_vertex_edge_voronoi_plane(p, D, A);
00072         bool const outside_DB     = outside_vertex_edge_voronoi_plane(p, D, B);
00073         bool const outside_DC     = outside_vertex_edge_voronoi_plane(p, D, C);
00074         bool const outside_ABC_vp = outside_edge_face_voronoi_plane( p, A, B, C);
00075         bool const outside_ABD_vp = outside_edge_face_voronoi_plane( p, A, B, D);
00076         bool const outside_CAB_vp = outside_edge_face_voronoi_plane( p, C, A, B);
00077         bool const outside_CAD_vp = outside_edge_face_voronoi_plane( p, C, A, D);
00078         bool const outside_DAB_vp = outside_edge_face_voronoi_plane( p, D, A, B);
00079         bool const outside_ADC_vp = outside_edge_face_voronoi_plane( p, A, D, C);
00080         bool const outside_BCA_vp = outside_edge_face_voronoi_plane( p, B, C, A);
00081         bool const outside_BCD_vp = outside_edge_face_voronoi_plane( p, B, C, D);
00082         bool const outside_BDA_vp = outside_edge_face_voronoi_plane( p, B, D, A);
00083         bool const outside_DBC_vp = outside_edge_face_voronoi_plane( p, D, B, C);
00084         bool const outside_CDB_vp = outside_edge_face_voronoi_plane( p, C, D, B);
00085         bool const outside_DCA_vp = outside_edge_face_voronoi_plane( p, D, C, A);
00086         bool const outside_ABC    = outside_triangle( p, A, B, C, D);
00087         bool const outside_ABD    = outside_triangle( p, A, B, D, C);
00088         bool const outside_BCD    = outside_triangle( p, B, C, D, A);
00089         bool const outside_CAD    = outside_triangle( p, C, A, D, B);
00090 
00091         // Test Vertex Voronoi Regions
00092         if( outside_AB && outside_AC && outside_AD)
00093         {
00094           S.m_bitmask = bit_A;
00095           S.m_v[idx_B].clear();
00096           S.m_v[idx_C].clear();
00097           S.m_v[idx_D].clear();
00098           S.m_a[idx_B].clear();
00099           S.m_a[idx_C].clear();
00100           S.m_a[idx_D].clear();
00101           S.m_b[idx_B].clear();
00102           S.m_b[idx_C].clear();
00103           S.m_b[idx_D].clear();
00104           S.m_w[idx_A] = value_traits::one();
00105           S.m_w[idx_B] = value_traits::zero();
00106           S.m_w[idx_C] = value_traits::zero();
00107           S.m_w[idx_D] = value_traits::zero();    
00108           return;
00109         }
00110         if( outside_BA && outside_BC && outside_BD)
00111         {
00112           S.m_bitmask = bit_B;
00113           S.m_v[idx_A].clear();
00114           S.m_v[idx_C].clear();
00115           S.m_v[idx_D].clear();
00116           S.m_a[idx_A].clear();
00117           S.m_a[idx_C].clear();
00118           S.m_a[idx_D].clear();
00119           S.m_b[idx_A].clear();
00120           S.m_b[idx_C].clear();
00121           S.m_b[idx_D].clear();
00122           S.m_w[idx_A] = value_traits::zero();
00123           S.m_w[idx_B] = value_traits::one();
00124           S.m_w[idx_C] = value_traits::zero();
00125           S.m_w[idx_D] = value_traits::zero();    
00126           return;
00127         }
00128         if( outside_CA && outside_CB && outside_CD)
00129         {
00130           S.m_bitmask = bit_C;
00131           S.m_v[idx_A].clear();
00132           S.m_v[idx_B].clear();
00133           S.m_v[idx_D].clear();
00134           S.m_a[idx_A].clear();
00135           S.m_a[idx_B].clear();
00136           S.m_a[idx_D].clear();
00137           S.m_b[idx_A].clear();
00138           S.m_b[idx_B].clear();
00139           S.m_b[idx_D].clear();
00140           S.m_w[idx_A] = value_traits::zero();
00141           S.m_w[idx_B] = value_traits::zero();
00142           S.m_w[idx_C] = value_traits::one();
00143           S.m_w[idx_D] = value_traits::zero();    
00144           return;
00145         }
00146         if( outside_DA && outside_DB && outside_DC)
00147         {
00148           S.m_bitmask = bit_D;
00149           S.m_v[idx_A].clear();
00150           S.m_v[idx_B].clear();
00151           S.m_v[idx_C].clear();
00152           S.m_a[idx_A].clear();
00153           S.m_a[idx_B].clear();
00154           S.m_a[idx_C].clear();
00155           S.m_b[idx_A].clear();
00156           S.m_b[idx_B].clear();
00157           S.m_b[idx_C].clear();
00158           S.m_w[idx_A] = value_traits::zero();
00159           S.m_w[idx_B] = value_traits::zero();
00160           S.m_w[idx_C] = value_traits::zero();
00161           S.m_w[idx_D] = value_traits::one();
00162           return;
00163         }
00164 
00165         // Test Edge Voronoi Regions
00166         if(outside_ABC_vp && outside_ABD_vp && !outside_AB && !outside_BA)
00167         {
00168           S.m_bitmask = bit_A | bit_B;
00169           S.m_v[idx_C].clear();
00170           S.m_v[idx_D].clear();
00171           S.m_a[idx_C].clear();
00172           S.m_a[idx_D].clear();
00173           S.m_b[idx_C].clear();
00174           S.m_b[idx_D].clear();
00175           S.m_w[idx_C] = value_traits::zero();
00176           S.m_w[idx_D] = value_traits::zero();
00177           OpenTissue::geometry::barycentric_geometric(A,B,p,S.m_w[idx_A],S.m_w[idx_B]);
00178           return;
00179         }
00180         if(outside_CAB_vp && outside_CAD_vp && !outside_CA && !outside_AC)
00181         {
00182           S.m_bitmask = bit_A | bit_C;
00183           S.m_v[idx_B].clear();
00184           S.m_v[idx_D].clear();
00185           S.m_a[idx_B].clear();
00186           S.m_a[idx_D].clear();
00187           S.m_b[idx_B].clear();
00188           S.m_b[idx_D].clear();
00189           S.m_w[idx_B] = value_traits::zero();
00190           S.m_w[idx_D] = value_traits::zero();
00191           OpenTissue::geometry::barycentric_geometric(A,C,p,S.m_w[idx_A],S.m_w[idx_C]);
00192           return;
00193         }
00194         if(outside_DAB_vp && outside_ADC_vp && !outside_AD && !outside_DA)
00195         {
00196           S.m_bitmask = bit_A | bit_D;
00197           S.m_v[idx_B].clear();
00198           S.m_v[idx_C].clear();
00199           S.m_a[idx_B].clear();
00200           S.m_a[idx_C].clear();
00201           S.m_b[idx_B].clear();
00202           S.m_b[idx_C].clear();
00203           S.m_w[idx_B] = value_traits::zero();
00204           S.m_w[idx_C] = value_traits::zero();
00205           OpenTissue::geometry::barycentric_geometric(A,D,p,S.m_w[idx_A],S.m_w[idx_D]);
00206           return;
00207         }
00208         if(outside_BCA_vp && outside_BCD_vp && !outside_BC && !outside_CB)
00209         {
00210           S.m_bitmask = bit_B | bit_C;
00211           S.m_v[idx_A].clear();
00212           S.m_v[idx_D].clear();
00213           S.m_a[idx_A].clear();
00214           S.m_a[idx_D].clear();
00215           S.m_b[idx_A].clear();
00216           S.m_b[idx_D].clear();
00217           S.m_w[idx_A] = value_traits::zero();
00218           S.m_w[idx_D] = value_traits::zero();
00219           OpenTissue::geometry::barycentric_geometric(B,C,p,S.m_w[idx_B],S.m_w[idx_C]);
00220           return;
00221         }
00222         if(outside_BDA_vp && outside_DBC_vp && !outside_BD && !outside_DB)
00223         {
00224           S.m_bitmask = bit_B | bit_D;
00225           S.m_v[idx_A].clear();
00226           S.m_v[idx_C].clear();
00227           S.m_a[idx_A].clear();
00228           S.m_a[idx_C].clear();
00229           S.m_b[idx_A].clear();
00230           S.m_b[idx_C].clear();
00231           S.m_w[idx_A] = value_traits::zero();
00232           S.m_w[idx_C] = value_traits::zero();
00233           OpenTissue::geometry::barycentric_geometric(B,D,p,S.m_w[idx_B],S.m_w[idx_D]);
00234           return;
00235         }
00236         if(outside_CDB_vp && outside_DCA_vp && !outside_CD && !outside_DC)
00237         {
00238           S.m_bitmask = bit_C | bit_D;
00239           S.m_v[idx_A].clear();
00240           S.m_v[idx_B].clear();
00241           S.m_a[idx_A].clear();
00242           S.m_a[idx_B].clear();
00243           S.m_b[idx_A].clear();
00244           S.m_b[idx_B].clear();
00245           S.m_w[idx_A] = value_traits::zero();
00246           S.m_w[idx_B] = value_traits::zero();
00247           OpenTissue::geometry::barycentric_geometric(C,D,p,S.m_w[idx_C],S.m_w[idx_D]);
00248           return;
00249         }
00250 
00251         // Test Face Voronoi Regions
00252         if (outside_ABC && !outside_ABC_vp && !outside_BCA_vp && !outside_CAB_vp)
00253         {
00254           S.m_bitmask = bit_A | bit_B | bit_C;
00255           S.m_v[idx_D].clear();
00256           S.m_a[idx_D].clear();
00257           S.m_b[idx_D].clear();
00258           S.m_w[idx_D]  = value_traits::zero();          
00259           OpenTissue::geometry::barycentric_geometric( A, B, C, p, S.m_w[idx_A], S.m_w[idx_B], S.m_w[idx_C]);                    
00260           return;
00261         }
00262         if (outside_ABD && !outside_ABD_vp && !outside_BDA_vp && !outside_DAB_vp)
00263         {
00264           S.m_bitmask = bit_A | bit_B | bit_D;
00265           S.m_v[idx_C].clear();
00266           S.m_a[idx_C].clear();
00267           S.m_b[idx_C].clear();
00268           S.m_w[idx_C]  = value_traits::zero();
00269           OpenTissue::geometry::barycentric_geometric( A, B, D, p, S.m_w[idx_A], S.m_w[idx_B], S.m_w[idx_D]);
00270           return;
00271         }
00272         if (outside_BCD && !outside_BCD_vp && !outside_CDB_vp && !outside_DBC_vp)
00273         {
00274           S.m_bitmask = bit_B | bit_C | bit_D;
00275           S.m_v[idx_A].clear();
00276           S.m_a[idx_A].clear();
00277           S.m_b[idx_A].clear();
00278           S.m_w[idx_A] = value_traits::zero();
00279           OpenTissue::geometry::barycentric_geometric( B, C, D, p, S.m_w[idx_B], S.m_w[idx_C], S.m_w[idx_D]);
00280           return;
00281         }
00282         if (outside_CAD && !outside_CAD_vp && !outside_ADC_vp && !outside_DCA_vp)
00283         {
00284           S.m_bitmask = bit_C | bit_A | bit_D;
00285           S.m_v[idx_B].clear();
00286           S.m_a[idx_B].clear();
00287           S.m_b[idx_B].clear();
00288           S.m_w[idx_B] = value_traits::zero();
00289           OpenTissue::geometry::barycentric_geometric( C, A, D, p, S.m_w[idx_C], S.m_w[idx_A], S.m_w[idx_D]);
00290           return;
00291         }
00292 
00293         // Test tetrahedron internal region
00294         if( !outside_ABC  && !outside_ABD && !outside_BCD && !outside_CAD)
00295         {
00296           OpenTissue::geometry::barycentric_geometric( A, B, C, D, p, S.m_w[idx_A], S.m_w[idx_B], S.m_w[idx_C], S.m_w[idx_D]);
00297           return;
00298         }
00299       }
00300 
00301 
00302     } // namespace detail
00303 
00304   } // namespace gjk
00305 
00306 } // namespace OpenTissue
00307 
00308 // OPENTISSUE_COLLISION_GJK_GJK_REDUCE_TETRAHEDRON_H
00309 #endif

Generated on Thu Dec 1 2011 12:50:47 for HUMIM Tracker by  doxygen 1.7.1