| [2431] | 1 | #ifndef BT_BOX_COLLISION_H_INCLUDED | 
|---|
 | 2 | #define BT_BOX_COLLISION_H_INCLUDED | 
|---|
 | 3 |  | 
|---|
 | 4 | /*! \file gim_box_collision.h | 
|---|
 | 5 | \author Francisco Len Nßjera | 
|---|
 | 6 | */ | 
|---|
 | 7 | /* | 
|---|
 | 8 | This source file is part of GIMPACT Library. | 
|---|
 | 9 |  | 
|---|
 | 10 | For the latest info, see http://gimpact.sourceforge.net/ | 
|---|
 | 11 |  | 
|---|
 | 12 | Copyright (c) 2007 Francisco Leon Najera. C.C. 80087371. | 
|---|
 | 13 | email: projectileman@yahoo.com | 
|---|
 | 14 |  | 
|---|
 | 15 |  | 
|---|
 | 16 | This software is provided 'as-is', without any express or implied warranty. | 
|---|
 | 17 | In no event will the authors be held liable for any damages arising from the use of this software. | 
|---|
 | 18 | Permission is granted to anyone to use this software for any purpose, | 
|---|
 | 19 | including commercial applications, and to alter it and redistribute it freely, | 
|---|
 | 20 | subject to the following restrictions: | 
|---|
 | 21 |  | 
|---|
 | 22 | 1. The origin of this software must not be misrepresented; you must not claim that you wrote the original software. If you use this software in a product, an acknowledgment in the product documentation would be appreciated but is not required. | 
|---|
 | 23 | 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software. | 
|---|
 | 24 | 3. This notice may not be removed or altered from any source distribution. | 
|---|
 | 25 | */ | 
|---|
 | 26 |  | 
|---|
 | 27 | #include "LinearMath/btTransform.h" | 
|---|
 | 28 |  | 
|---|
 | 29 |  | 
|---|
 | 30 | ///Swap numbers | 
|---|
 | 31 | #define BT_SWAP_NUMBERS(a,b){ \ | 
|---|
 | 32 |     a = a+b; \ | 
|---|
 | 33 |     b = a-b; \ | 
|---|
 | 34 |     a = a-b; \ | 
|---|
 | 35 | }\ | 
|---|
 | 36 |  | 
|---|
 | 37 |  | 
|---|
 | 38 | #define BT_MAX(a,b) (a<b?b:a) | 
|---|
 | 39 | #define BT_MIN(a,b) (a>b?b:a) | 
|---|
 | 40 |  | 
|---|
 | 41 | #define BT_GREATER(x, y)        btFabs(x) > (y) | 
|---|
 | 42 |  | 
|---|
 | 43 | #define BT_MAX3(a,b,c) BT_MAX(a,BT_MAX(b,c)) | 
|---|
 | 44 | #define BT_MIN3(a,b,c) BT_MIN(a,BT_MIN(b,c)) | 
|---|
 | 45 |  | 
|---|
 | 46 |  | 
|---|
 | 47 |  | 
|---|
 | 48 |  | 
|---|
 | 49 |  | 
|---|
 | 50 |  | 
|---|
 | 51 | enum eBT_PLANE_INTERSECTION_TYPE | 
|---|
 | 52 | { | 
|---|
 | 53 |         BT_CONST_BACK_PLANE = 0, | 
|---|
 | 54 |         BT_CONST_COLLIDE_PLANE, | 
|---|
 | 55 |         BT_CONST_FRONT_PLANE | 
|---|
 | 56 | }; | 
|---|
 | 57 |  | 
|---|
 | 58 | //SIMD_FORCE_INLINE bool test_cross_edge_box( | 
|---|
 | 59 | //      const btVector3 & edge, | 
|---|
 | 60 | //      const btVector3 & absolute_edge, | 
|---|
 | 61 | //      const btVector3 & pointa, | 
|---|
 | 62 | //      const btVector3 & pointb, const btVector3 & extend, | 
|---|
 | 63 | //      int dir_index0, | 
|---|
 | 64 | //      int dir_index1 | 
|---|
 | 65 | //      int component_index0, | 
|---|
 | 66 | //      int component_index1) | 
|---|
 | 67 | //{ | 
|---|
 | 68 | //      // dir coords are -z and y | 
|---|
 | 69 | // | 
|---|
 | 70 | //      const btScalar dir0 = -edge[dir_index0]; | 
|---|
 | 71 | //      const btScalar dir1 = edge[dir_index1]; | 
|---|
 | 72 | //      btScalar pmin = pointa[component_index0]*dir0 + pointa[component_index1]*dir1; | 
|---|
 | 73 | //      btScalar pmax = pointb[component_index0]*dir0 + pointb[component_index1]*dir1; | 
|---|
 | 74 | //      //find minmax | 
|---|
 | 75 | //      if(pmin>pmax) | 
|---|
 | 76 | //      { | 
|---|
 | 77 | //              BT_SWAP_NUMBERS(pmin,pmax); | 
|---|
 | 78 | //      } | 
|---|
 | 79 | //      //find extends | 
|---|
 | 80 | //      const btScalar rad = extend[component_index0] * absolute_edge[dir_index0] + | 
|---|
 | 81 | //                                      extend[component_index1] * absolute_edge[dir_index1]; | 
|---|
 | 82 | // | 
|---|
 | 83 | //      if(pmin>rad || -rad>pmax) return false; | 
|---|
 | 84 | //      return true; | 
|---|
 | 85 | //} | 
|---|
 | 86 | // | 
|---|
 | 87 | //SIMD_FORCE_INLINE bool test_cross_edge_box_X_axis( | 
|---|
 | 88 | //      const btVector3 & edge, | 
|---|
 | 89 | //      const btVector3 & absolute_edge, | 
|---|
 | 90 | //      const btVector3 & pointa, | 
|---|
 | 91 | //      const btVector3 & pointb, btVector3 & extend) | 
|---|
 | 92 | //{ | 
|---|
 | 93 | // | 
|---|
 | 94 | //      return test_cross_edge_box(edge,absolute_edge,pointa,pointb,extend,2,1,1,2); | 
|---|
 | 95 | //} | 
|---|
 | 96 | // | 
|---|
 | 97 | // | 
|---|
 | 98 | //SIMD_FORCE_INLINE bool test_cross_edge_box_Y_axis( | 
|---|
 | 99 | //      const btVector3 & edge, | 
|---|
 | 100 | //      const btVector3 & absolute_edge, | 
|---|
 | 101 | //      const btVector3 & pointa, | 
|---|
 | 102 | //      const btVector3 & pointb, btVector3 & extend) | 
|---|
 | 103 | //{ | 
|---|
 | 104 | // | 
|---|
 | 105 | //      return test_cross_edge_box(edge,absolute_edge,pointa,pointb,extend,0,2,2,0); | 
|---|
 | 106 | //} | 
|---|
 | 107 | // | 
|---|
 | 108 | //SIMD_FORCE_INLINE bool test_cross_edge_box_Z_axis( | 
|---|
 | 109 | //      const btVector3 & edge, | 
|---|
 | 110 | //      const btVector3 & absolute_edge, | 
|---|
 | 111 | //      const btVector3 & pointa, | 
|---|
 | 112 | //      const btVector3 & pointb, btVector3 & extend) | 
|---|
 | 113 | //{ | 
|---|
 | 114 | // | 
|---|
 | 115 | //      return test_cross_edge_box(edge,absolute_edge,pointa,pointb,extend,1,0,0,1); | 
|---|
 | 116 | //} | 
|---|
 | 117 |  | 
|---|
 | 118 |  | 
|---|
 | 119 | #define TEST_CROSS_EDGE_BOX_MCR(edge,absolute_edge,pointa,pointb,_extend,i_dir_0,i_dir_1,i_comp_0,i_comp_1)\ | 
|---|
 | 120 | {\ | 
|---|
 | 121 |         const btScalar dir0 = -edge[i_dir_0];\ | 
|---|
 | 122 |         const btScalar dir1 = edge[i_dir_1];\ | 
|---|
 | 123 |         btScalar pmin = pointa[i_comp_0]*dir0 + pointa[i_comp_1]*dir1;\ | 
|---|
 | 124 |         btScalar pmax = pointb[i_comp_0]*dir0 + pointb[i_comp_1]*dir1;\ | 
|---|
 | 125 |         if(pmin>pmax)\ | 
|---|
 | 126 |         {\ | 
|---|
 | 127 |                 BT_SWAP_NUMBERS(pmin,pmax); \ | 
|---|
 | 128 |         }\ | 
|---|
 | 129 |         const btScalar abs_dir0 = absolute_edge[i_dir_0];\ | 
|---|
 | 130 |         const btScalar abs_dir1 = absolute_edge[i_dir_1];\ | 
|---|
 | 131 |         const btScalar rad = _extend[i_comp_0] * abs_dir0 + _extend[i_comp_1] * abs_dir1;\ | 
|---|
 | 132 |         if(pmin>rad || -rad>pmax) return false;\ | 
|---|
 | 133 | }\ | 
|---|
 | 134 |  | 
|---|
 | 135 |  | 
|---|
 | 136 | #define TEST_CROSS_EDGE_BOX_X_AXIS_MCR(edge,absolute_edge,pointa,pointb,_extend)\ | 
|---|
 | 137 | {\ | 
|---|
 | 138 |         TEST_CROSS_EDGE_BOX_MCR(edge,absolute_edge,pointa,pointb,_extend,2,1,1,2);\ | 
|---|
 | 139 | }\ | 
|---|
 | 140 |  | 
|---|
 | 141 | #define TEST_CROSS_EDGE_BOX_Y_AXIS_MCR(edge,absolute_edge,pointa,pointb,_extend)\ | 
|---|
 | 142 | {\ | 
|---|
 | 143 |         TEST_CROSS_EDGE_BOX_MCR(edge,absolute_edge,pointa,pointb,_extend,0,2,2,0);\ | 
|---|
 | 144 | }\ | 
|---|
 | 145 |  | 
|---|
 | 146 | #define TEST_CROSS_EDGE_BOX_Z_AXIS_MCR(edge,absolute_edge,pointa,pointb,_extend)\ | 
|---|
 | 147 | {\ | 
|---|
 | 148 |         TEST_CROSS_EDGE_BOX_MCR(edge,absolute_edge,pointa,pointb,_extend,1,0,0,1);\ | 
|---|
 | 149 | }\ | 
|---|
 | 150 |  | 
|---|
 | 151 |  | 
|---|
 | 152 | //! Returns the dot product between a vec3f and the col of a matrix | 
|---|
 | 153 | SIMD_FORCE_INLINE btScalar bt_mat3_dot_col( | 
|---|
 | 154 | const btMatrix3x3 & mat, const btVector3 & vec3, int colindex) | 
|---|
 | 155 | { | 
|---|
 | 156 |         return vec3[0]*mat[0][colindex] + vec3[1]*mat[1][colindex] + vec3[2]*mat[2][colindex]; | 
|---|
 | 157 | } | 
|---|
 | 158 |  | 
|---|
 | 159 |  | 
|---|
 | 160 | //!  Class for transforming a model1 to the space of model0 | 
|---|
 | 161 | ATTRIBUTE_ALIGNED16     (class) BT_BOX_BOX_TRANSFORM_CACHE | 
|---|
 | 162 | { | 
|---|
 | 163 | public: | 
|---|
 | 164 |     btVector3  m_T1to0;//!< Transforms translation of model1 to model 0 | 
|---|
 | 165 |         btMatrix3x3 m_R1to0;//!< Transforms Rotation of model1 to model 0, equal  to R0' * R1 | 
|---|
 | 166 |         btMatrix3x3 m_AR;//!< Absolute value of m_R1to0 | 
|---|
 | 167 |  | 
|---|
 | 168 |         SIMD_FORCE_INLINE void calc_absolute_matrix() | 
|---|
 | 169 |         { | 
|---|
 | 170 | //              static const btVector3 vepsi(1e-6f,1e-6f,1e-6f); | 
|---|
 | 171 | //              m_AR[0] = vepsi + m_R1to0[0].absolute(); | 
|---|
 | 172 | //              m_AR[1] = vepsi + m_R1to0[1].absolute(); | 
|---|
 | 173 | //              m_AR[2] = vepsi + m_R1to0[2].absolute(); | 
|---|
 | 174 |  | 
|---|
 | 175 |                 int i,j; | 
|---|
 | 176 |  | 
|---|
 | 177 |         for(i=0;i<3;i++) | 
|---|
 | 178 |         { | 
|---|
 | 179 |             for(j=0;j<3;j++ ) | 
|---|
 | 180 |             { | 
|---|
 | 181 |                 m_AR[i][j] = 1e-6f + btFabs(m_R1to0[i][j]); | 
|---|
 | 182 |             } | 
|---|
 | 183 |         } | 
|---|
 | 184 |  | 
|---|
 | 185 |         } | 
|---|
 | 186 |  | 
|---|
 | 187 |         BT_BOX_BOX_TRANSFORM_CACHE() | 
|---|
 | 188 |         { | 
|---|
 | 189 |         } | 
|---|
 | 190 |  | 
|---|
 | 191 |  | 
|---|
 | 192 |  | 
|---|
 | 193 |         //! Calc the transformation relative  1 to 0. Inverts matrics by transposing | 
|---|
 | 194 |         SIMD_FORCE_INLINE void calc_from_homogenic(const btTransform & trans0,const btTransform & trans1) | 
|---|
 | 195 |         { | 
|---|
 | 196 |  | 
|---|
 | 197 |                 btTransform temp_trans = trans0.inverse(); | 
|---|
 | 198 |                 temp_trans = temp_trans * trans1; | 
|---|
 | 199 |  | 
|---|
 | 200 |                 m_T1to0 = temp_trans.getOrigin(); | 
|---|
 | 201 |                 m_R1to0 = temp_trans.getBasis(); | 
|---|
 | 202 |  | 
|---|
 | 203 |  | 
|---|
 | 204 |                 calc_absolute_matrix(); | 
|---|
 | 205 |         } | 
|---|
 | 206 |  | 
|---|
 | 207 |         //! Calcs the full invertion of the matrices. Useful for scaling matrices | 
|---|
 | 208 |         SIMD_FORCE_INLINE void calc_from_full_invert(const btTransform & trans0,const btTransform & trans1) | 
|---|
 | 209 |         { | 
|---|
 | 210 |                 m_R1to0 = trans0.getBasis().inverse(); | 
|---|
 | 211 |                 m_T1to0 = m_R1to0 * (-trans0.getOrigin()); | 
|---|
 | 212 |  | 
|---|
 | 213 |                 m_T1to0 += m_R1to0*trans1.getOrigin(); | 
|---|
 | 214 |                 m_R1to0 *= trans1.getBasis(); | 
|---|
 | 215 |  | 
|---|
 | 216 |                 calc_absolute_matrix(); | 
|---|
 | 217 |         } | 
|---|
 | 218 |  | 
|---|
 | 219 |         SIMD_FORCE_INLINE btVector3 transform(const btVector3 & point) const | 
|---|
 | 220 |         { | 
|---|
 | 221 |                 return btVector3(m_R1to0[0].dot(point) + m_T1to0.x(), | 
|---|
 | 222 |                         m_R1to0[1].dot(point) + m_T1to0.y(), | 
|---|
 | 223 |                         m_R1to0[2].dot(point) + m_T1to0.z()); | 
|---|
 | 224 |         } | 
|---|
 | 225 | }; | 
|---|
 | 226 |  | 
|---|
 | 227 |  | 
|---|
 | 228 | #define BOX_PLANE_EPSILON 0.000001f | 
|---|
 | 229 |  | 
|---|
 | 230 | //! Axis aligned box | 
|---|
 | 231 | ATTRIBUTE_ALIGNED16     (class) btAABB | 
|---|
 | 232 | { | 
|---|
 | 233 | public: | 
|---|
 | 234 |         btVector3 m_min; | 
|---|
 | 235 |         btVector3 m_max; | 
|---|
 | 236 |  | 
|---|
 | 237 |         btAABB() | 
|---|
 | 238 |         {} | 
|---|
 | 239 |  | 
|---|
 | 240 |  | 
|---|
 | 241 |         btAABB(const btVector3 & V1, | 
|---|
 | 242 |                          const btVector3 & V2, | 
|---|
 | 243 |                          const btVector3 & V3) | 
|---|
 | 244 |         { | 
|---|
 | 245 |                 m_min[0] = BT_MIN3(V1[0],V2[0],V3[0]); | 
|---|
 | 246 |                 m_min[1] = BT_MIN3(V1[1],V2[1],V3[1]); | 
|---|
 | 247 |                 m_min[2] = BT_MIN3(V1[2],V2[2],V3[2]); | 
|---|
 | 248 |  | 
|---|
 | 249 |                 m_max[0] = BT_MAX3(V1[0],V2[0],V3[0]); | 
|---|
 | 250 |                 m_max[1] = BT_MAX3(V1[1],V2[1],V3[1]); | 
|---|
 | 251 |                 m_max[2] = BT_MAX3(V1[2],V2[2],V3[2]); | 
|---|
 | 252 |         } | 
|---|
 | 253 |  | 
|---|
 | 254 |         btAABB(const btVector3 & V1, | 
|---|
 | 255 |                          const btVector3 & V2, | 
|---|
 | 256 |                          const btVector3 & V3, | 
|---|
 | 257 |                          btScalar margin) | 
|---|
 | 258 |         { | 
|---|
 | 259 |                 m_min[0] = BT_MIN3(V1[0],V2[0],V3[0]); | 
|---|
 | 260 |                 m_min[1] = BT_MIN3(V1[1],V2[1],V3[1]); | 
|---|
 | 261 |                 m_min[2] = BT_MIN3(V1[2],V2[2],V3[2]); | 
|---|
 | 262 |  | 
|---|
 | 263 |                 m_max[0] = BT_MAX3(V1[0],V2[0],V3[0]); | 
|---|
 | 264 |                 m_max[1] = BT_MAX3(V1[1],V2[1],V3[1]); | 
|---|
 | 265 |                 m_max[2] = BT_MAX3(V1[2],V2[2],V3[2]); | 
|---|
 | 266 |  | 
|---|
 | 267 |                 m_min[0] -= margin; | 
|---|
 | 268 |                 m_min[1] -= margin; | 
|---|
 | 269 |                 m_min[2] -= margin; | 
|---|
 | 270 |                 m_max[0] += margin; | 
|---|
 | 271 |                 m_max[1] += margin; | 
|---|
 | 272 |                 m_max[2] += margin; | 
|---|
 | 273 |         } | 
|---|
 | 274 |  | 
|---|
 | 275 |         btAABB(const btAABB &other): | 
|---|
 | 276 |                 m_min(other.m_min),m_max(other.m_max) | 
|---|
 | 277 |         { | 
|---|
 | 278 |         } | 
|---|
 | 279 |  | 
|---|
 | 280 |         btAABB(const btAABB &other,btScalar margin ): | 
|---|
 | 281 |                 m_min(other.m_min),m_max(other.m_max) | 
|---|
 | 282 |         { | 
|---|
 | 283 |                 m_min[0] -= margin; | 
|---|
 | 284 |                 m_min[1] -= margin; | 
|---|
 | 285 |                 m_min[2] -= margin; | 
|---|
 | 286 |                 m_max[0] += margin; | 
|---|
 | 287 |                 m_max[1] += margin; | 
|---|
 | 288 |                 m_max[2] += margin; | 
|---|
 | 289 |         } | 
|---|
 | 290 |  | 
|---|
 | 291 |         SIMD_FORCE_INLINE void invalidate() | 
|---|
 | 292 |         { | 
|---|
 | 293 |                 m_min[0] = SIMD_INFINITY; | 
|---|
 | 294 |                 m_min[1] = SIMD_INFINITY; | 
|---|
 | 295 |                 m_min[2] = SIMD_INFINITY; | 
|---|
 | 296 |                 m_max[0] = -SIMD_INFINITY; | 
|---|
 | 297 |                 m_max[1] = -SIMD_INFINITY; | 
|---|
 | 298 |                 m_max[2] = -SIMD_INFINITY; | 
|---|
 | 299 |         } | 
|---|
 | 300 |  | 
|---|
 | 301 |         SIMD_FORCE_INLINE void increment_margin(btScalar margin) | 
|---|
 | 302 |         { | 
|---|
 | 303 |                 m_min[0] -= margin; | 
|---|
 | 304 |                 m_min[1] -= margin; | 
|---|
 | 305 |                 m_min[2] -= margin; | 
|---|
 | 306 |                 m_max[0] += margin; | 
|---|
 | 307 |                 m_max[1] += margin; | 
|---|
 | 308 |                 m_max[2] += margin; | 
|---|
 | 309 |         } | 
|---|
 | 310 |  | 
|---|
 | 311 |         SIMD_FORCE_INLINE void copy_with_margin(const btAABB &other, btScalar margin) | 
|---|
 | 312 |         { | 
|---|
 | 313 |                 m_min[0] = other.m_min[0] - margin; | 
|---|
 | 314 |                 m_min[1] = other.m_min[1] - margin; | 
|---|
 | 315 |                 m_min[2] = other.m_min[2] - margin; | 
|---|
 | 316 |  | 
|---|
 | 317 |                 m_max[0] = other.m_max[0] + margin; | 
|---|
 | 318 |                 m_max[1] = other.m_max[1] + margin; | 
|---|
 | 319 |                 m_max[2] = other.m_max[2] + margin; | 
|---|
 | 320 |         } | 
|---|
 | 321 |  | 
|---|
 | 322 |         template<typename CLASS_POINT> | 
|---|
 | 323 |         SIMD_FORCE_INLINE void calc_from_triangle( | 
|---|
 | 324 |                                                         const CLASS_POINT & V1, | 
|---|
 | 325 |                                                         const CLASS_POINT & V2, | 
|---|
 | 326 |                                                         const CLASS_POINT & V3) | 
|---|
 | 327 |         { | 
|---|
 | 328 |                 m_min[0] = BT_MIN3(V1[0],V2[0],V3[0]); | 
|---|
 | 329 |                 m_min[1] = BT_MIN3(V1[1],V2[1],V3[1]); | 
|---|
 | 330 |                 m_min[2] = BT_MIN3(V1[2],V2[2],V3[2]); | 
|---|
 | 331 |  | 
|---|
 | 332 |                 m_max[0] = BT_MAX3(V1[0],V2[0],V3[0]); | 
|---|
 | 333 |                 m_max[1] = BT_MAX3(V1[1],V2[1],V3[1]); | 
|---|
 | 334 |                 m_max[2] = BT_MAX3(V1[2],V2[2],V3[2]); | 
|---|
 | 335 |         } | 
|---|
 | 336 |  | 
|---|
 | 337 |         template<typename CLASS_POINT> | 
|---|
 | 338 |         SIMD_FORCE_INLINE void calc_from_triangle_margin( | 
|---|
 | 339 |                                                         const CLASS_POINT & V1, | 
|---|
 | 340 |                                                         const CLASS_POINT & V2, | 
|---|
 | 341 |                                                         const CLASS_POINT & V3, btScalar margin) | 
|---|
 | 342 |         { | 
|---|
 | 343 |                 m_min[0] = BT_MIN3(V1[0],V2[0],V3[0]); | 
|---|
 | 344 |                 m_min[1] = BT_MIN3(V1[1],V2[1],V3[1]); | 
|---|
 | 345 |                 m_min[2] = BT_MIN3(V1[2],V2[2],V3[2]); | 
|---|
 | 346 |  | 
|---|
 | 347 |                 m_max[0] = BT_MAX3(V1[0],V2[0],V3[0]); | 
|---|
 | 348 |                 m_max[1] = BT_MAX3(V1[1],V2[1],V3[1]); | 
|---|
 | 349 |                 m_max[2] = BT_MAX3(V1[2],V2[2],V3[2]); | 
|---|
 | 350 |  | 
|---|
 | 351 |                 m_min[0] -= margin; | 
|---|
 | 352 |                 m_min[1] -= margin; | 
|---|
 | 353 |                 m_min[2] -= margin; | 
|---|
 | 354 |                 m_max[0] += margin; | 
|---|
 | 355 |                 m_max[1] += margin; | 
|---|
 | 356 |                 m_max[2] += margin; | 
|---|
 | 357 |         } | 
|---|
 | 358 |  | 
|---|
 | 359 |         //! Apply a transform to an AABB | 
|---|
 | 360 |         SIMD_FORCE_INLINE void appy_transform(const btTransform & trans) | 
|---|
 | 361 |         { | 
|---|
 | 362 |                 btVector3 center = (m_max+m_min)*0.5f; | 
|---|
 | 363 |                 btVector3 extends = m_max - center; | 
|---|
 | 364 |                 // Compute new center | 
|---|
 | 365 |                 center = trans(center); | 
|---|
 | 366 |  | 
|---|
 | 367 |                 btVector3 textends(extends.dot(trans.getBasis().getRow(0).absolute()), | 
|---|
 | 368 |                                  extends.dot(trans.getBasis().getRow(1).absolute()), | 
|---|
 | 369 |                                  extends.dot(trans.getBasis().getRow(2).absolute())); | 
|---|
 | 370 |  | 
|---|
 | 371 |                 m_min = center - textends; | 
|---|
 | 372 |                 m_max = center + textends; | 
|---|
 | 373 |         } | 
|---|
 | 374 |  | 
|---|
 | 375 |  | 
|---|
 | 376 |         //! Apply a transform to an AABB | 
|---|
 | 377 |         SIMD_FORCE_INLINE void appy_transform_trans_cache(const BT_BOX_BOX_TRANSFORM_CACHE & trans) | 
|---|
 | 378 |         { | 
|---|
 | 379 |                 btVector3 center = (m_max+m_min)*0.5f; | 
|---|
 | 380 |                 btVector3 extends = m_max - center; | 
|---|
 | 381 |                 // Compute new center | 
|---|
 | 382 |                 center = trans.transform(center); | 
|---|
 | 383 |  | 
|---|
 | 384 |                 btVector3 textends(extends.dot(trans.m_R1to0.getRow(0).absolute()), | 
|---|
 | 385 |                                  extends.dot(trans.m_R1to0.getRow(1).absolute()), | 
|---|
 | 386 |                                  extends.dot(trans.m_R1to0.getRow(2).absolute())); | 
|---|
 | 387 |  | 
|---|
 | 388 |                 m_min = center - textends; | 
|---|
 | 389 |                 m_max = center + textends; | 
|---|
 | 390 |         } | 
|---|
 | 391 |  | 
|---|
 | 392 |         //! Merges a Box | 
|---|
 | 393 |         SIMD_FORCE_INLINE void merge(const btAABB & box) | 
|---|
 | 394 |         { | 
|---|
 | 395 |                 m_min[0] = BT_MIN(m_min[0],box.m_min[0]); | 
|---|
 | 396 |                 m_min[1] = BT_MIN(m_min[1],box.m_min[1]); | 
|---|
 | 397 |                 m_min[2] = BT_MIN(m_min[2],box.m_min[2]); | 
|---|
 | 398 |  | 
|---|
 | 399 |                 m_max[0] = BT_MAX(m_max[0],box.m_max[0]); | 
|---|
 | 400 |                 m_max[1] = BT_MAX(m_max[1],box.m_max[1]); | 
|---|
 | 401 |                 m_max[2] = BT_MAX(m_max[2],box.m_max[2]); | 
|---|
 | 402 |         } | 
|---|
 | 403 |  | 
|---|
 | 404 |         //! Merges a point | 
|---|
 | 405 |         template<typename CLASS_POINT> | 
|---|
 | 406 |         SIMD_FORCE_INLINE void merge_point(const CLASS_POINT & point) | 
|---|
 | 407 |         { | 
|---|
 | 408 |                 m_min[0] = BT_MIN(m_min[0],point[0]); | 
|---|
 | 409 |                 m_min[1] = BT_MIN(m_min[1],point[1]); | 
|---|
 | 410 |                 m_min[2] = BT_MIN(m_min[2],point[2]); | 
|---|
 | 411 |  | 
|---|
 | 412 |                 m_max[0] = BT_MAX(m_max[0],point[0]); | 
|---|
 | 413 |                 m_max[1] = BT_MAX(m_max[1],point[1]); | 
|---|
 | 414 |                 m_max[2] = BT_MAX(m_max[2],point[2]); | 
|---|
 | 415 |         } | 
|---|
 | 416 |  | 
|---|
 | 417 |         //! Gets the extend and center | 
|---|
 | 418 |         SIMD_FORCE_INLINE void get_center_extend(btVector3 & center,btVector3 & extend)  const | 
|---|
 | 419 |         { | 
|---|
 | 420 |                 center = (m_max+m_min)*0.5f; | 
|---|
 | 421 |                 extend = m_max - center; | 
|---|
 | 422 |         } | 
|---|
 | 423 |  | 
|---|
 | 424 |         //! Finds the intersecting box between this box and the other. | 
|---|
 | 425 |         SIMD_FORCE_INLINE void find_intersection(const btAABB & other, btAABB & intersection)  const | 
|---|
 | 426 |         { | 
|---|
 | 427 |                 intersection.m_min[0] = BT_MAX(other.m_min[0],m_min[0]); | 
|---|
 | 428 |                 intersection.m_min[1] = BT_MAX(other.m_min[1],m_min[1]); | 
|---|
 | 429 |                 intersection.m_min[2] = BT_MAX(other.m_min[2],m_min[2]); | 
|---|
 | 430 |  | 
|---|
 | 431 |                 intersection.m_max[0] = BT_MIN(other.m_max[0],m_max[0]); | 
|---|
 | 432 |                 intersection.m_max[1] = BT_MIN(other.m_max[1],m_max[1]); | 
|---|
 | 433 |                 intersection.m_max[2] = BT_MIN(other.m_max[2],m_max[2]); | 
|---|
 | 434 |         } | 
|---|
 | 435 |  | 
|---|
 | 436 |  | 
|---|
 | 437 |         SIMD_FORCE_INLINE bool has_collision(const btAABB & other) const | 
|---|
 | 438 |         { | 
|---|
 | 439 |                 if(m_min[0] > other.m_max[0] || | 
|---|
 | 440 |                    m_max[0] < other.m_min[0] || | 
|---|
 | 441 |                    m_min[1] > other.m_max[1] || | 
|---|
 | 442 |                    m_max[1] < other.m_min[1] || | 
|---|
 | 443 |                    m_min[2] > other.m_max[2] || | 
|---|
 | 444 |                    m_max[2] < other.m_min[2]) | 
|---|
 | 445 |                 { | 
|---|
 | 446 |                         return false; | 
|---|
 | 447 |                 } | 
|---|
 | 448 |                 return true; | 
|---|
 | 449 |         } | 
|---|
 | 450 |  | 
|---|
 | 451 |         /*! \brief Finds the Ray intersection parameter. | 
|---|
 | 452 |         \param aabb Aligned box | 
|---|
 | 453 |         \param vorigin A vec3f with the origin of the ray | 
|---|
 | 454 |         \param vdir A vec3f with the direction of the ray | 
|---|
 | 455 |         */ | 
|---|
 | 456 |         SIMD_FORCE_INLINE bool collide_ray(const btVector3 & vorigin,const btVector3 & vdir)  const | 
|---|
 | 457 |         { | 
|---|
 | 458 |                 btVector3 extents,center; | 
|---|
 | 459 |                 this->get_center_extend(center,extents);; | 
|---|
 | 460 |  | 
|---|
 | 461 |                 btScalar Dx = vorigin[0] - center[0]; | 
|---|
 | 462 |                 if(BT_GREATER(Dx, extents[0]) && Dx*vdir[0]>=0.0f)      return false; | 
|---|
 | 463 |                 btScalar Dy = vorigin[1] - center[1]; | 
|---|
 | 464 |                 if(BT_GREATER(Dy, extents[1]) && Dy*vdir[1]>=0.0f)      return false; | 
|---|
 | 465 |                 btScalar Dz = vorigin[2] - center[2]; | 
|---|
 | 466 |                 if(BT_GREATER(Dz, extents[2]) && Dz*vdir[2]>=0.0f)      return false; | 
|---|
 | 467 |  | 
|---|
 | 468 |  | 
|---|
 | 469 |                 btScalar f = vdir[1] * Dz - vdir[2] * Dy; | 
|---|
 | 470 |                 if(btFabs(f) > extents[1]*btFabs(vdir[2]) + extents[2]*btFabs(vdir[1])) return false; | 
|---|
 | 471 |                 f = vdir[2] * Dx - vdir[0] * Dz; | 
|---|
 | 472 |                 if(btFabs(f) > extents[0]*btFabs(vdir[2]) + extents[2]*btFabs(vdir[0]))return false; | 
|---|
 | 473 |                 f = vdir[0] * Dy - vdir[1] * Dx; | 
|---|
 | 474 |                 if(btFabs(f) > extents[0]*btFabs(vdir[1]) + extents[1]*btFabs(vdir[0]))return false; | 
|---|
 | 475 |                 return true; | 
|---|
 | 476 |         } | 
|---|
 | 477 |  | 
|---|
 | 478 |  | 
|---|
 | 479 |         SIMD_FORCE_INLINE void projection_interval(const btVector3 & direction, btScalar &vmin, btScalar &vmax) const | 
|---|
 | 480 |         { | 
|---|
 | 481 |                 btVector3 center = (m_max+m_min)*0.5f; | 
|---|
 | 482 |                 btVector3 extend = m_max-center; | 
|---|
 | 483 |  | 
|---|
 | 484 |                 btScalar _fOrigin =  direction.dot(center); | 
|---|
 | 485 |                 btScalar _fMaximumExtent = extend.dot(direction.absolute()); | 
|---|
 | 486 |                 vmin = _fOrigin - _fMaximumExtent; | 
|---|
 | 487 |                 vmax = _fOrigin + _fMaximumExtent; | 
|---|
 | 488 |         } | 
|---|
 | 489 |  | 
|---|
 | 490 |         SIMD_FORCE_INLINE eBT_PLANE_INTERSECTION_TYPE plane_classify(const btVector4 &plane) const | 
|---|
 | 491 |         { | 
|---|
 | 492 |                 btScalar _fmin,_fmax; | 
|---|
 | 493 |                 this->projection_interval(plane,_fmin,_fmax); | 
|---|
 | 494 |  | 
|---|
 | 495 |                 if(plane[3] > _fmax + BOX_PLANE_EPSILON) | 
|---|
 | 496 |                 { | 
|---|
 | 497 |                         return BT_CONST_BACK_PLANE; // 0 | 
|---|
 | 498 |                 } | 
|---|
 | 499 |  | 
|---|
 | 500 |                 if(plane[3]+BOX_PLANE_EPSILON >=_fmin) | 
|---|
 | 501 |                 { | 
|---|
 | 502 |                         return BT_CONST_COLLIDE_PLANE; //1 | 
|---|
 | 503 |                 } | 
|---|
 | 504 |                 return BT_CONST_FRONT_PLANE;//2 | 
|---|
 | 505 |         } | 
|---|
 | 506 |  | 
|---|
 | 507 |         SIMD_FORCE_INLINE bool overlapping_trans_conservative(const btAABB & box, btTransform & trans1_to_0) const | 
|---|
 | 508 |         { | 
|---|
 | 509 |                 btAABB tbox = box; | 
|---|
 | 510 |                 tbox.appy_transform(trans1_to_0); | 
|---|
 | 511 |                 return has_collision(tbox); | 
|---|
 | 512 |         } | 
|---|
 | 513 |  | 
|---|
 | 514 |         SIMD_FORCE_INLINE bool overlapping_trans_conservative2(const btAABB & box, | 
|---|
 | 515 |                 const BT_BOX_BOX_TRANSFORM_CACHE & trans1_to_0) const | 
|---|
 | 516 |         { | 
|---|
 | 517 |                 btAABB tbox = box; | 
|---|
 | 518 |                 tbox.appy_transform_trans_cache(trans1_to_0); | 
|---|
 | 519 |                 return has_collision(tbox); | 
|---|
 | 520 |         } | 
|---|
 | 521 |  | 
|---|
 | 522 |         //! transcache is the transformation cache from box to this AABB | 
|---|
 | 523 |         SIMD_FORCE_INLINE bool overlapping_trans_cache( | 
|---|
 | 524 |                 const btAABB & box,const BT_BOX_BOX_TRANSFORM_CACHE & transcache, bool fulltest) const | 
|---|
 | 525 |         { | 
|---|
 | 526 |  | 
|---|
 | 527 |                 //Taken from OPCODE | 
|---|
 | 528 |                 btVector3 ea,eb;//extends | 
|---|
 | 529 |                 btVector3 ca,cb;//extends | 
|---|
 | 530 |                 get_center_extend(ca,ea); | 
|---|
 | 531 |                 box.get_center_extend(cb,eb); | 
|---|
 | 532 |  | 
|---|
 | 533 |  | 
|---|
 | 534 |                 btVector3 T; | 
|---|
 | 535 |                 btScalar t,t2; | 
|---|
 | 536 |                 int i; | 
|---|
 | 537 |  | 
|---|
 | 538 |                 // Class I : A's basis vectors | 
|---|
 | 539 |                 for(i=0;i<3;i++) | 
|---|
 | 540 |                 { | 
|---|
 | 541 |                         T[i] =  transcache.m_R1to0[i].dot(cb) + transcache.m_T1to0[i] - ca[i]; | 
|---|
 | 542 |                         t = transcache.m_AR[i].dot(eb) + ea[i]; | 
|---|
 | 543 |                         if(BT_GREATER(T[i], t)) return false; | 
|---|
 | 544 |                 } | 
|---|
 | 545 |                 // Class II : B's basis vectors | 
|---|
 | 546 |                 for(i=0;i<3;i++) | 
|---|
 | 547 |                 { | 
|---|
 | 548 |                         t = bt_mat3_dot_col(transcache.m_R1to0,T,i); | 
|---|
 | 549 |                         t2 = bt_mat3_dot_col(transcache.m_AR,ea,i) + eb[i]; | 
|---|
 | 550 |                         if(BT_GREATER(t,t2))    return false; | 
|---|
 | 551 |                 } | 
|---|
 | 552 |                 // Class III : 9 cross products | 
|---|
 | 553 |                 if(fulltest) | 
|---|
 | 554 |                 { | 
|---|
 | 555 |                         int j,m,n,o,p,q,r; | 
|---|
 | 556 |                         for(i=0;i<3;i++) | 
|---|
 | 557 |                         { | 
|---|
 | 558 |                                 m = (i+1)%3; | 
|---|
 | 559 |                                 n = (i+2)%3; | 
|---|
 | 560 |                                 o = i==0?1:0; | 
|---|
 | 561 |                                 p = i==2?1:2; | 
|---|
 | 562 |                                 for(j=0;j<3;j++) | 
|---|
 | 563 |                                 { | 
|---|
 | 564 |                                         q = j==2?1:2; | 
|---|
 | 565 |                                         r = j==0?1:0; | 
|---|
 | 566 |                                         t = T[n]*transcache.m_R1to0[m][j] - T[m]*transcache.m_R1to0[n][j]; | 
|---|
 | 567 |                                         t2 = ea[o]*transcache.m_AR[p][j] + ea[p]*transcache.m_AR[o][j] + | 
|---|
 | 568 |                                                 eb[r]*transcache.m_AR[i][q] + eb[q]*transcache.m_AR[i][r]; | 
|---|
 | 569 |                                         if(BT_GREATER(t,t2))    return false; | 
|---|
 | 570 |                                 } | 
|---|
 | 571 |                         } | 
|---|
 | 572 |                 } | 
|---|
 | 573 |                 return true; | 
|---|
 | 574 |         } | 
|---|
 | 575 |  | 
|---|
 | 576 |         //! Simple test for planes. | 
|---|
 | 577 |         SIMD_FORCE_INLINE bool collide_plane( | 
|---|
 | 578 |                 const btVector4 & plane) const | 
|---|
 | 579 |         { | 
|---|
 | 580 |                 eBT_PLANE_INTERSECTION_TYPE classify = plane_classify(plane); | 
|---|
 | 581 |                 return (classify == BT_CONST_COLLIDE_PLANE); | 
|---|
 | 582 |         } | 
|---|
 | 583 |  | 
|---|
 | 584 |         //! test for a triangle, with edges | 
|---|
 | 585 |         SIMD_FORCE_INLINE bool collide_triangle_exact( | 
|---|
 | 586 |                 const btVector3 & p1, | 
|---|
 | 587 |                 const btVector3 & p2, | 
|---|
 | 588 |                 const btVector3 & p3, | 
|---|
 | 589 |                 const btVector4 & triangle_plane) const | 
|---|
 | 590 |         { | 
|---|
 | 591 |                 if(!collide_plane(triangle_plane)) return false; | 
|---|
 | 592 |  | 
|---|
 | 593 |                 btVector3 center,extends; | 
|---|
 | 594 |                 this->get_center_extend(center,extends); | 
|---|
 | 595 |  | 
|---|
 | 596 |                 const btVector3 v1(p1 - center); | 
|---|
 | 597 |                 const btVector3 v2(p2 - center); | 
|---|
 | 598 |                 const btVector3 v3(p3 - center); | 
|---|
 | 599 |  | 
|---|
 | 600 |                 //First axis | 
|---|
 | 601 |                 btVector3 diff(v2 - v1); | 
|---|
 | 602 |                 btVector3 abs_diff = diff.absolute(); | 
|---|
 | 603 |                 //Test With X axis | 
|---|
 | 604 |                 TEST_CROSS_EDGE_BOX_X_AXIS_MCR(diff,abs_diff,v1,v3,extends); | 
|---|
 | 605 |                 //Test With Y axis | 
|---|
 | 606 |                 TEST_CROSS_EDGE_BOX_Y_AXIS_MCR(diff,abs_diff,v1,v3,extends); | 
|---|
 | 607 |                 //Test With Z axis | 
|---|
 | 608 |                 TEST_CROSS_EDGE_BOX_Z_AXIS_MCR(diff,abs_diff,v1,v3,extends); | 
|---|
 | 609 |  | 
|---|
 | 610 |  | 
|---|
 | 611 |                 diff = v3 - v2; | 
|---|
 | 612 |                 abs_diff = diff.absolute(); | 
|---|
 | 613 |                 //Test With X axis | 
|---|
 | 614 |                 TEST_CROSS_EDGE_BOX_X_AXIS_MCR(diff,abs_diff,v2,v1,extends); | 
|---|
 | 615 |                 //Test With Y axis | 
|---|
 | 616 |                 TEST_CROSS_EDGE_BOX_Y_AXIS_MCR(diff,abs_diff,v2,v1,extends); | 
|---|
 | 617 |                 //Test With Z axis | 
|---|
 | 618 |                 TEST_CROSS_EDGE_BOX_Z_AXIS_MCR(diff,abs_diff,v2,v1,extends); | 
|---|
 | 619 |  | 
|---|
 | 620 |                 diff = v1 - v3; | 
|---|
 | 621 |                 abs_diff = diff.absolute(); | 
|---|
 | 622 |                 //Test With X axis | 
|---|
 | 623 |                 TEST_CROSS_EDGE_BOX_X_AXIS_MCR(diff,abs_diff,v3,v2,extends); | 
|---|
 | 624 |                 //Test With Y axis | 
|---|
 | 625 |                 TEST_CROSS_EDGE_BOX_Y_AXIS_MCR(diff,abs_diff,v3,v2,extends); | 
|---|
 | 626 |                 //Test With Z axis | 
|---|
 | 627 |                 TEST_CROSS_EDGE_BOX_Z_AXIS_MCR(diff,abs_diff,v3,v2,extends); | 
|---|
 | 628 |  | 
|---|
 | 629 |                 return true; | 
|---|
 | 630 |         } | 
|---|
 | 631 | }; | 
|---|
 | 632 |  | 
|---|
 | 633 |  | 
|---|
 | 634 | //! Compairison of transformation objects | 
|---|
 | 635 | SIMD_FORCE_INLINE bool btCompareTransformsEqual(const btTransform & t1,const btTransform & t2) | 
|---|
 | 636 | { | 
|---|
 | 637 |         if(!(t1.getOrigin() == t2.getOrigin()) ) return false; | 
|---|
 | 638 |  | 
|---|
 | 639 |         if(!(t1.getBasis().getRow(0) == t2.getBasis().getRow(0)) ) return false; | 
|---|
 | 640 |         if(!(t1.getBasis().getRow(1) == t2.getBasis().getRow(1)) ) return false; | 
|---|
 | 641 |         if(!(t1.getBasis().getRow(2) == t2.getBasis().getRow(2)) ) return false; | 
|---|
 | 642 |         return true; | 
|---|
 | 643 | } | 
|---|
 | 644 |  | 
|---|
 | 645 |  | 
|---|
 | 646 |  | 
|---|
 | 647 | #endif // GIM_BOX_COLLISION_H_INCLUDED | 
|---|