00001 #ifndef OPENTISSUE_COLLISION_INTERSECT_INTERSECT_OBB_OBB_SAT_H
00002 #define OPENTISSUE_COLLISION_INTERSECT_INTERSECT_OBB_OBB_SAT_H
00003
00004
00005
00006
00007
00008
00009
00010 #include <OpenTissue/configuration.h>
00011
00012 namespace OpenTissue
00013 {
00014 namespace intersect
00015 {
00016
00038 template<typename obb_type>
00039 bool obb_obb_sat(obb_type const & A, obb_type const & BinA )
00040 {
00041 using std::fabs;
00042
00043 typedef typename obb_type::real_type real_type;
00044 typedef typename obb_type::vector3_type vector3_type;
00045 typedef typename obb_type::matrix3x3_type matrix3x3_type;
00046
00047 matrix3x3_type const & R_ba = BinA.orientation();
00048 vector3_type const & p_ba = BinA.center();
00049 vector3_type const & b = BinA.eps();
00050 vector3_type const & a = A.eps();
00051
00052 static real_type threshold = math::working_precision<real_type>();
00053 real_type Q00 = fabs(R_ba(0,0))+threshold;
00054 real_type Q01 = fabs(R_ba(0,1))+threshold;
00055 real_type Q02 = fabs(R_ba(0,2))+threshold;
00056 real_type Q10 = fabs(R_ba(1,0))+threshold;
00057 real_type Q11 = fabs(R_ba(1,1))+threshold;
00058 real_type Q12 = fabs(R_ba(1,2))+threshold;
00059 real_type Q20 = fabs(R_ba(2,0))+threshold;
00060 real_type Q21 = fabs(R_ba(2,1))+threshold;
00061 real_type Q22 = fabs(R_ba(2,2))+threshold;
00062
00063 #define TST(expr1,expr2) if (fabs(expr1) - (expr2) > 0) return true;
00064 TST( p_ba(0), a(0) + b(0)*Q00 + b(1)*Q10 + b(2)*Q20 );
00065 TST( p_ba(1), a(1) + b(0)*Q01 + b(1)*Q11 + b(2)*Q21 );
00066 TST( p_ba(2), a(2) + b(0)*Q02 + b(1)*Q12 + b(2)*Q22 );
00067 TST( p_ba(0)*R_ba(0,0) + p_ba(1)*R_ba(1,0) + p_ba(2)*R_ba(2,0), b(0) + a(0)*Q00 + a(1)*Q10 + a(2)*Q20 );
00068 TST( p_ba(0)*R_ba(0,1) + p_ba(1)*R_ba(1,1) + p_ba(2)*R_ba(2,1), b(1) + a(0)*Q01 + a(1)*Q11 + a(2)*Q21 );
00069 TST( p_ba(0)*R_ba(0,2) + p_ba(1)*R_ba(1,2) + p_ba(2)*R_ba(2,2), b(2) + a(0)*Q02 + a(1)*Q12 + a(2)*Q22 );
00070 TST( p_ba(2)*R_ba(1,0) - p_ba(1)*R_ba(2,0), a(1)*Q20 + a(2)*Q10 + b(1)*Q02 + b(2)*Q01);
00071 TST( p_ba(2)*R_ba(1,1) - p_ba(1)*R_ba(2,1), a(1)*Q21 + a(2)*Q11 + b(2)*Q00 + b(0)*Q02);
00072 TST( p_ba(2)*R_ba(1,2) - p_ba(1)*R_ba(2,2), a(1)*Q22 + a(2)*Q12 + b(0)*Q01 + b(1)*Q00);
00073 TST( p_ba(0)*R_ba(2,0) - p_ba(2)*R_ba(0,0), a(2)*Q00 + a(0)*Q20 + b(1)*Q12 + b(2)*Q11);
00074 TST( p_ba(0)*R_ba(2,1) - p_ba(2)*R_ba(0,1), a(2)*Q01 + a(0)*Q21 + b(2)*Q10 + b(0)*Q12);
00075 TST( p_ba(0)*R_ba(2,2) - p_ba(2)*R_ba(0,2), a(2)*Q02 + a(0)*Q22 + b(0)*Q11 + b(1)*Q10);
00076 TST( p_ba(1)*R_ba(0,0) - p_ba(0)*R_ba(1,0), a(0)*Q10 + a(1)*Q00 + b(1)*Q22 + b(2)*Q21);
00077 TST( p_ba(1)*R_ba(0,1) - p_ba(0)*R_ba(1,1), a(0)*Q11 + a(1)*Q01 + b(2)*Q20 + b(0)*Q22);
00078 TST( p_ba(1)*R_ba(0,2) - p_ba(0)*R_ba(1,2), a(0)*Q12 + a(1)*Q02 + b(0)*Q21 + b(1)*Q20);
00079 #undef TST
00080 return false;
00081 }
00082
00083 }
00084
00085 }
00086
00087
00088 #endif