Blender V2.61 - r43446
|
00001 #ifndef GIM_BOX_COLLISION_H_INCLUDED 00002 #define GIM_BOX_COLLISION_H_INCLUDED 00003 00007 /* 00008 ----------------------------------------------------------------------------- 00009 This source file is part of GIMPACT Library. 00010 00011 For the latest info, see http://gimpact.sourceforge.net/ 00012 00013 Copyright (c) 2006 Francisco Leon Najera. C.C. 80087371. 00014 email: projectileman@yahoo.com 00015 00016 This library is free software; you can redistribute it and/or 00017 modify it under the terms of EITHER: 00018 (1) The GNU Lesser General Public License as published by the Free 00019 Software Foundation; either version 2.1 of the License, or (at 00020 your option) any later version. The text of the GNU Lesser 00021 General Public License is included with this library in the 00022 file GIMPACT-LICENSE-LGPL.TXT. 00023 (2) The BSD-style license that is included with this library in 00024 the file GIMPACT-LICENSE-BSD.TXT. 00025 (3) The zlib/libpng license that is included with this library in 00026 the file GIMPACT-LICENSE-ZLIB.TXT. 00027 00028 This library is distributed in the hope that it will be useful, 00029 but WITHOUT ANY WARRANTY; without even the implied warranty of 00030 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the files 00031 GIMPACT-LICENSE-LGPL.TXT, GIMPACT-LICENSE-ZLIB.TXT and GIMPACT-LICENSE-BSD.TXT for more details. 00032 00033 ----------------------------------------------------------------------------- 00034 */ 00035 #include "gim_basic_geometry_operations.h" 00036 #include "LinearMath/btTransform.h" 00037 00038 00039 00040 //SIMD_FORCE_INLINE bool test_cross_edge_box( 00041 // const btVector3 & edge, 00042 // const btVector3 & absolute_edge, 00043 // const btVector3 & pointa, 00044 // const btVector3 & pointb, const btVector3 & extend, 00045 // int dir_index0, 00046 // int dir_index1 00047 // int component_index0, 00048 // int component_index1) 00049 //{ 00050 // // dir coords are -z and y 00051 // 00052 // const btScalar dir0 = -edge[dir_index0]; 00053 // const btScalar dir1 = edge[dir_index1]; 00054 // btScalar pmin = pointa[component_index0]*dir0 + pointa[component_index1]*dir1; 00055 // btScalar pmax = pointb[component_index0]*dir0 + pointb[component_index1]*dir1; 00056 // //find minmax 00057 // if(pmin>pmax) 00058 // { 00059 // GIM_SWAP_NUMBERS(pmin,pmax); 00060 // } 00061 // //find extends 00062 // const btScalar rad = extend[component_index0] * absolute_edge[dir_index0] + 00063 // extend[component_index1] * absolute_edge[dir_index1]; 00064 // 00065 // if(pmin>rad || -rad>pmax) return false; 00066 // return true; 00067 //} 00068 // 00069 //SIMD_FORCE_INLINE bool test_cross_edge_box_X_axis( 00070 // const btVector3 & edge, 00071 // const btVector3 & absolute_edge, 00072 // const btVector3 & pointa, 00073 // const btVector3 & pointb, btVector3 & extend) 00074 //{ 00075 // 00076 // return test_cross_edge_box(edge,absolute_edge,pointa,pointb,extend,2,1,1,2); 00077 //} 00078 // 00079 // 00080 //SIMD_FORCE_INLINE bool test_cross_edge_box_Y_axis( 00081 // const btVector3 & edge, 00082 // const btVector3 & absolute_edge, 00083 // const btVector3 & pointa, 00084 // const btVector3 & pointb, btVector3 & extend) 00085 //{ 00086 // 00087 // return test_cross_edge_box(edge,absolute_edge,pointa,pointb,extend,0,2,2,0); 00088 //} 00089 // 00090 //SIMD_FORCE_INLINE bool test_cross_edge_box_Z_axis( 00091 // const btVector3 & edge, 00092 // const btVector3 & absolute_edge, 00093 // const btVector3 & pointa, 00094 // const btVector3 & pointb, btVector3 & extend) 00095 //{ 00096 // 00097 // return test_cross_edge_box(edge,absolute_edge,pointa,pointb,extend,1,0,0,1); 00098 //} 00099 00100 #define TEST_CROSS_EDGE_BOX_MCR(edge,absolute_edge,pointa,pointb,_extend,i_dir_0,i_dir_1,i_comp_0,i_comp_1)\ 00101 {\ 00102 const btScalar dir0 = -edge[i_dir_0];\ 00103 const btScalar dir1 = edge[i_dir_1];\ 00104 btScalar pmin = pointa[i_comp_0]*dir0 + pointa[i_comp_1]*dir1;\ 00105 btScalar pmax = pointb[i_comp_0]*dir0 + pointb[i_comp_1]*dir1;\ 00106 if(pmin>pmax)\ 00107 {\ 00108 GIM_SWAP_NUMBERS(pmin,pmax); \ 00109 }\ 00110 const btScalar abs_dir0 = absolute_edge[i_dir_0];\ 00111 const btScalar abs_dir1 = absolute_edge[i_dir_1];\ 00112 const btScalar rad = _extend[i_comp_0] * abs_dir0 + _extend[i_comp_1] * abs_dir1;\ 00113 if(pmin>rad || -rad>pmax) return false;\ 00114 }\ 00115 00116 00117 #define TEST_CROSS_EDGE_BOX_X_AXIS_MCR(edge,absolute_edge,pointa,pointb,_extend)\ 00118 {\ 00119 TEST_CROSS_EDGE_BOX_MCR(edge,absolute_edge,pointa,pointb,_extend,2,1,1,2);\ 00120 }\ 00121 00122 #define TEST_CROSS_EDGE_BOX_Y_AXIS_MCR(edge,absolute_edge,pointa,pointb,_extend)\ 00123 {\ 00124 TEST_CROSS_EDGE_BOX_MCR(edge,absolute_edge,pointa,pointb,_extend,0,2,2,0);\ 00125 }\ 00126 00127 #define TEST_CROSS_EDGE_BOX_Z_AXIS_MCR(edge,absolute_edge,pointa,pointb,_extend)\ 00128 {\ 00129 TEST_CROSS_EDGE_BOX_MCR(edge,absolute_edge,pointa,pointb,_extend,1,0,0,1);\ 00130 }\ 00131 00132 00133 00135 class GIM_BOX_BOX_TRANSFORM_CACHE 00136 { 00137 public: 00138 btVector3 m_T1to0; 00139 btMatrix3x3 m_R1to0; 00140 btMatrix3x3 m_AR; 00141 00142 SIMD_FORCE_INLINE void calc_absolute_matrix() 00143 { 00144 static const btVector3 vepsi(1e-6f,1e-6f,1e-6f); 00145 m_AR[0] = vepsi + m_R1to0[0].absolute(); 00146 m_AR[1] = vepsi + m_R1to0[1].absolute(); 00147 m_AR[2] = vepsi + m_R1to0[2].absolute(); 00148 } 00149 00150 GIM_BOX_BOX_TRANSFORM_CACHE() 00151 { 00152 } 00153 00154 00155 GIM_BOX_BOX_TRANSFORM_CACHE(mat4f trans1_to_0) 00156 { 00157 COPY_MATRIX_3X3(m_R1to0,trans1_to_0) 00158 MAT_GET_TRANSLATION(trans1_to_0,m_T1to0) 00159 calc_absolute_matrix(); 00160 } 00161 00163 SIMD_FORCE_INLINE void calc_from_homogenic(const btTransform & trans0,const btTransform & trans1) 00164 { 00165 00166 m_R1to0 = trans0.getBasis().transpose(); 00167 m_T1to0 = m_R1to0 * (-trans0.getOrigin()); 00168 00169 m_T1to0 += m_R1to0*trans1.getOrigin(); 00170 m_R1to0 *= trans1.getBasis(); 00171 00172 calc_absolute_matrix(); 00173 } 00174 00176 SIMD_FORCE_INLINE void calc_from_full_invert(const btTransform & trans0,const btTransform & trans1) 00177 { 00178 m_R1to0 = trans0.getBasis().inverse(); 00179 m_T1to0 = m_R1to0 * (-trans0.getOrigin()); 00180 00181 m_T1to0 += m_R1to0*trans1.getOrigin(); 00182 m_R1to0 *= trans1.getBasis(); 00183 00184 calc_absolute_matrix(); 00185 } 00186 00187 SIMD_FORCE_INLINE btVector3 transform(const btVector3 & point) 00188 { 00189 return btVector3(m_R1to0[0].dot(point) + m_T1to0.x(), 00190 m_R1to0[1].dot(point) + m_T1to0.y(), 00191 m_R1to0[2].dot(point) + m_T1to0.z()); 00192 } 00193 }; 00194 00195 00196 #define BOX_PLANE_EPSILON 0.000001f 00197 00199 class GIM_AABB 00200 { 00201 public: 00202 btVector3 m_min; 00203 btVector3 m_max; 00204 00205 GIM_AABB() 00206 {} 00207 00208 00209 GIM_AABB(const btVector3 & V1, 00210 const btVector3 & V2, 00211 const btVector3 & V3) 00212 { 00213 m_min[0] = GIM_MIN3(V1[0],V2[0],V3[0]); 00214 m_min[1] = GIM_MIN3(V1[1],V2[1],V3[1]); 00215 m_min[2] = GIM_MIN3(V1[2],V2[2],V3[2]); 00216 00217 m_max[0] = GIM_MAX3(V1[0],V2[0],V3[0]); 00218 m_max[1] = GIM_MAX3(V1[1],V2[1],V3[1]); 00219 m_max[2] = GIM_MAX3(V1[2],V2[2],V3[2]); 00220 } 00221 00222 GIM_AABB(const btVector3 & V1, 00223 const btVector3 & V2, 00224 const btVector3 & V3, 00225 GREAL margin) 00226 { 00227 m_min[0] = GIM_MIN3(V1[0],V2[0],V3[0]); 00228 m_min[1] = GIM_MIN3(V1[1],V2[1],V3[1]); 00229 m_min[2] = GIM_MIN3(V1[2],V2[2],V3[2]); 00230 00231 m_max[0] = GIM_MAX3(V1[0],V2[0],V3[0]); 00232 m_max[1] = GIM_MAX3(V1[1],V2[1],V3[1]); 00233 m_max[2] = GIM_MAX3(V1[2],V2[2],V3[2]); 00234 00235 m_min[0] -= margin; 00236 m_min[1] -= margin; 00237 m_min[2] -= margin; 00238 m_max[0] += margin; 00239 m_max[1] += margin; 00240 m_max[2] += margin; 00241 } 00242 00243 GIM_AABB(const GIM_AABB &other): 00244 m_min(other.m_min),m_max(other.m_max) 00245 { 00246 } 00247 00248 GIM_AABB(const GIM_AABB &other,btScalar margin ): 00249 m_min(other.m_min),m_max(other.m_max) 00250 { 00251 m_min[0] -= margin; 00252 m_min[1] -= margin; 00253 m_min[2] -= margin; 00254 m_max[0] += margin; 00255 m_max[1] += margin; 00256 m_max[2] += margin; 00257 } 00258 00259 SIMD_FORCE_INLINE void invalidate() 00260 { 00261 m_min[0] = G_REAL_INFINITY; 00262 m_min[1] = G_REAL_INFINITY; 00263 m_min[2] = G_REAL_INFINITY; 00264 m_max[0] = -G_REAL_INFINITY; 00265 m_max[1] = -G_REAL_INFINITY; 00266 m_max[2] = -G_REAL_INFINITY; 00267 } 00268 00269 SIMD_FORCE_INLINE void increment_margin(btScalar margin) 00270 { 00271 m_min[0] -= margin; 00272 m_min[1] -= margin; 00273 m_min[2] -= margin; 00274 m_max[0] += margin; 00275 m_max[1] += margin; 00276 m_max[2] += margin; 00277 } 00278 00279 SIMD_FORCE_INLINE void copy_with_margin(const GIM_AABB &other, btScalar margin) 00280 { 00281 m_min[0] = other.m_min[0] - margin; 00282 m_min[1] = other.m_min[1] - margin; 00283 m_min[2] = other.m_min[2] - margin; 00284 00285 m_max[0] = other.m_max[0] + margin; 00286 m_max[1] = other.m_max[1] + margin; 00287 m_max[2] = other.m_max[2] + margin; 00288 } 00289 00290 template<typename CLASS_POINT> 00291 SIMD_FORCE_INLINE void calc_from_triangle( 00292 const CLASS_POINT & V1, 00293 const CLASS_POINT & V2, 00294 const CLASS_POINT & V3) 00295 { 00296 m_min[0] = GIM_MIN3(V1[0],V2[0],V3[0]); 00297 m_min[1] = GIM_MIN3(V1[1],V2[1],V3[1]); 00298 m_min[2] = GIM_MIN3(V1[2],V2[2],V3[2]); 00299 00300 m_max[0] = GIM_MAX3(V1[0],V2[0],V3[0]); 00301 m_max[1] = GIM_MAX3(V1[1],V2[1],V3[1]); 00302 m_max[2] = GIM_MAX3(V1[2],V2[2],V3[2]); 00303 } 00304 00305 template<typename CLASS_POINT> 00306 SIMD_FORCE_INLINE void calc_from_triangle_margin( 00307 const CLASS_POINT & V1, 00308 const CLASS_POINT & V2, 00309 const CLASS_POINT & V3, btScalar margin) 00310 { 00311 m_min[0] = GIM_MIN3(V1[0],V2[0],V3[0]); 00312 m_min[1] = GIM_MIN3(V1[1],V2[1],V3[1]); 00313 m_min[2] = GIM_MIN3(V1[2],V2[2],V3[2]); 00314 00315 m_max[0] = GIM_MAX3(V1[0],V2[0],V3[0]); 00316 m_max[1] = GIM_MAX3(V1[1],V2[1],V3[1]); 00317 m_max[2] = GIM_MAX3(V1[2],V2[2],V3[2]); 00318 00319 m_min[0] -= margin; 00320 m_min[1] -= margin; 00321 m_min[2] -= margin; 00322 m_max[0] += margin; 00323 m_max[1] += margin; 00324 m_max[2] += margin; 00325 } 00326 00328 SIMD_FORCE_INLINE void appy_transform(const btTransform & trans) 00329 { 00330 btVector3 center = (m_max+m_min)*0.5f; 00331 btVector3 extends = m_max - center; 00332 // Compute new center 00333 center = trans(center); 00334 00335 btVector3 textends(extends.dot(trans.getBasis().getRow(0).absolute()), 00336 extends.dot(trans.getBasis().getRow(1).absolute()), 00337 extends.dot(trans.getBasis().getRow(2).absolute())); 00338 00339 m_min = center - textends; 00340 m_max = center + textends; 00341 } 00342 00344 SIMD_FORCE_INLINE void merge(const GIM_AABB & box) 00345 { 00346 m_min[0] = GIM_MIN(m_min[0],box.m_min[0]); 00347 m_min[1] = GIM_MIN(m_min[1],box.m_min[1]); 00348 m_min[2] = GIM_MIN(m_min[2],box.m_min[2]); 00349 00350 m_max[0] = GIM_MAX(m_max[0],box.m_max[0]); 00351 m_max[1] = GIM_MAX(m_max[1],box.m_max[1]); 00352 m_max[2] = GIM_MAX(m_max[2],box.m_max[2]); 00353 } 00354 00356 template<typename CLASS_POINT> 00357 SIMD_FORCE_INLINE void merge_point(const CLASS_POINT & point) 00358 { 00359 m_min[0] = GIM_MIN(m_min[0],point[0]); 00360 m_min[1] = GIM_MIN(m_min[1],point[1]); 00361 m_min[2] = GIM_MIN(m_min[2],point[2]); 00362 00363 m_max[0] = GIM_MAX(m_max[0],point[0]); 00364 m_max[1] = GIM_MAX(m_max[1],point[1]); 00365 m_max[2] = GIM_MAX(m_max[2],point[2]); 00366 } 00367 00369 SIMD_FORCE_INLINE void get_center_extend(btVector3 & center,btVector3 & extend) const 00370 { 00371 center = (m_max+m_min)*0.5f; 00372 extend = m_max - center; 00373 } 00374 00376 SIMD_FORCE_INLINE void find_intersection(const GIM_AABB & other, GIM_AABB & intersection) const 00377 { 00378 intersection.m_min[0] = GIM_MAX(other.m_min[0],m_min[0]); 00379 intersection.m_min[1] = GIM_MAX(other.m_min[1],m_min[1]); 00380 intersection.m_min[2] = GIM_MAX(other.m_min[2],m_min[2]); 00381 00382 intersection.m_max[0] = GIM_MIN(other.m_max[0],m_max[0]); 00383 intersection.m_max[1] = GIM_MIN(other.m_max[1],m_max[1]); 00384 intersection.m_max[2] = GIM_MIN(other.m_max[2],m_max[2]); 00385 } 00386 00387 00388 SIMD_FORCE_INLINE bool has_collision(const GIM_AABB & other) const 00389 { 00390 if(m_min[0] > other.m_max[0] || 00391 m_max[0] < other.m_min[0] || 00392 m_min[1] > other.m_max[1] || 00393 m_max[1] < other.m_min[1] || 00394 m_min[2] > other.m_max[2] || 00395 m_max[2] < other.m_min[2]) 00396 { 00397 return false; 00398 } 00399 return true; 00400 } 00401 00407 SIMD_FORCE_INLINE bool collide_ray(const btVector3 & vorigin,const btVector3 & vdir) 00408 { 00409 btVector3 extents,center; 00410 this->get_center_extend(center,extents);; 00411 00412 btScalar Dx = vorigin[0] - center[0]; 00413 if(GIM_GREATER(Dx, extents[0]) && Dx*vdir[0]>=0.0f) return false; 00414 btScalar Dy = vorigin[1] - center[1]; 00415 if(GIM_GREATER(Dy, extents[1]) && Dy*vdir[1]>=0.0f) return false; 00416 btScalar Dz = vorigin[2] - center[2]; 00417 if(GIM_GREATER(Dz, extents[2]) && Dz*vdir[2]>=0.0f) return false; 00418 00419 00420 btScalar f = vdir[1] * Dz - vdir[2] * Dy; 00421 if(btFabs(f) > extents[1]*btFabs(vdir[2]) + extents[2]*btFabs(vdir[1])) return false; 00422 f = vdir[2] * Dx - vdir[0] * Dz; 00423 if(btFabs(f) > extents[0]*btFabs(vdir[2]) + extents[2]*btFabs(vdir[0]))return false; 00424 f = vdir[0] * Dy - vdir[1] * Dx; 00425 if(btFabs(f) > extents[0]*btFabs(vdir[1]) + extents[1]*btFabs(vdir[0]))return false; 00426 return true; 00427 } 00428 00429 00430 SIMD_FORCE_INLINE void projection_interval(const btVector3 & direction, btScalar &vmin, btScalar &vmax) const 00431 { 00432 btVector3 center = (m_max+m_min)*0.5f; 00433 btVector3 extend = m_max-center; 00434 00435 btScalar _fOrigin = direction.dot(center); 00436 btScalar _fMaximumExtent = extend.dot(direction.absolute()); 00437 vmin = _fOrigin - _fMaximumExtent; 00438 vmax = _fOrigin + _fMaximumExtent; 00439 } 00440 00441 SIMD_FORCE_INLINE ePLANE_INTERSECTION_TYPE plane_classify(const btVector4 &plane) const 00442 { 00443 btScalar _fmin,_fmax; 00444 this->projection_interval(plane,_fmin,_fmax); 00445 00446 if(plane[3] > _fmax + BOX_PLANE_EPSILON) 00447 { 00448 return G_BACK_PLANE; // 0 00449 } 00450 00451 if(plane[3]+BOX_PLANE_EPSILON >=_fmin) 00452 { 00453 return G_COLLIDE_PLANE; //1 00454 } 00455 return G_FRONT_PLANE;//2 00456 } 00457 00458 SIMD_FORCE_INLINE bool overlapping_trans_conservative(const GIM_AABB & box, btTransform & trans1_to_0) 00459 { 00460 GIM_AABB tbox = box; 00461 tbox.appy_transform(trans1_to_0); 00462 return has_collision(tbox); 00463 } 00464 00466 SIMD_FORCE_INLINE bool overlapping_trans_cache( 00467 const GIM_AABB & box,const GIM_BOX_BOX_TRANSFORM_CACHE & transcache, bool fulltest) 00468 { 00469 00470 //Taken from OPCODE 00471 btVector3 ea,eb;//extends 00472 btVector3 ca,cb;//extends 00473 get_center_extend(ca,ea); 00474 box.get_center_extend(cb,eb); 00475 00476 00477 btVector3 T; 00478 btScalar t,t2; 00479 int i; 00480 00481 // Class I : A's basis vectors 00482 for(i=0;i<3;i++) 00483 { 00484 T[i] = transcache.m_R1to0[i].dot(cb) + transcache.m_T1to0[i] - ca[i]; 00485 t = transcache.m_AR[i].dot(eb) + ea[i]; 00486 if(GIM_GREATER(T[i], t)) return false; 00487 } 00488 // Class II : B's basis vectors 00489 for(i=0;i<3;i++) 00490 { 00491 t = MAT_DOT_COL(transcache.m_R1to0,T,i); 00492 t2 = MAT_DOT_COL(transcache.m_AR,ea,i) + eb[i]; 00493 if(GIM_GREATER(t,t2)) return false; 00494 } 00495 // Class III : 9 cross products 00496 if(fulltest) 00497 { 00498 int j,m,n,o,p,q,r; 00499 for(i=0;i<3;i++) 00500 { 00501 m = (i+1)%3; 00502 n = (i+2)%3; 00503 o = i==0?1:0; 00504 p = i==2?1:2; 00505 for(j=0;j<3;j++) 00506 { 00507 q = j==2?1:2; 00508 r = j==0?1:0; 00509 t = T[n]*transcache.m_R1to0[m][j] - T[m]*transcache.m_R1to0[n][j]; 00510 t2 = ea[o]*transcache.m_AR[p][j] + ea[p]*transcache.m_AR[o][j] + 00511 eb[r]*transcache.m_AR[i][q] + eb[q]*transcache.m_AR[i][r]; 00512 if(GIM_GREATER(t,t2)) return false; 00513 } 00514 } 00515 } 00516 return true; 00517 } 00518 00520 SIMD_FORCE_INLINE bool collide_plane( 00521 const btVector4 & plane) 00522 { 00523 ePLANE_INTERSECTION_TYPE classify = plane_classify(plane); 00524 return (classify == G_COLLIDE_PLANE); 00525 } 00526 00528 SIMD_FORCE_INLINE bool collide_triangle_exact( 00529 const btVector3 & p1, 00530 const btVector3 & p2, 00531 const btVector3 & p3, 00532 const btVector4 & triangle_plane) 00533 { 00534 if(!collide_plane(triangle_plane)) return false; 00535 00536 btVector3 center,extends; 00537 this->get_center_extend(center,extends); 00538 00539 const btVector3 v1(p1 - center); 00540 const btVector3 v2(p2 - center); 00541 const btVector3 v3(p3 - center); 00542 00543 //First axis 00544 btVector3 diff(v2 - v1); 00545 btVector3 abs_diff = diff.absolute(); 00546 //Test With X axis 00547 TEST_CROSS_EDGE_BOX_X_AXIS_MCR(diff,abs_diff,v1,v3,extends); 00548 //Test With Y axis 00549 TEST_CROSS_EDGE_BOX_Y_AXIS_MCR(diff,abs_diff,v1,v3,extends); 00550 //Test With Z axis 00551 TEST_CROSS_EDGE_BOX_Z_AXIS_MCR(diff,abs_diff,v1,v3,extends); 00552 00553 00554 diff = v3 - v2; 00555 abs_diff = diff.absolute(); 00556 //Test With X axis 00557 TEST_CROSS_EDGE_BOX_X_AXIS_MCR(diff,abs_diff,v2,v1,extends); 00558 //Test With Y axis 00559 TEST_CROSS_EDGE_BOX_Y_AXIS_MCR(diff,abs_diff,v2,v1,extends); 00560 //Test With Z axis 00561 TEST_CROSS_EDGE_BOX_Z_AXIS_MCR(diff,abs_diff,v2,v1,extends); 00562 00563 diff = v1 - v3; 00564 abs_diff = diff.absolute(); 00565 //Test With X axis 00566 TEST_CROSS_EDGE_BOX_X_AXIS_MCR(diff,abs_diff,v3,v2,extends); 00567 //Test With Y axis 00568 TEST_CROSS_EDGE_BOX_Y_AXIS_MCR(diff,abs_diff,v3,v2,extends); 00569 //Test With Z axis 00570 TEST_CROSS_EDGE_BOX_Z_AXIS_MCR(diff,abs_diff,v3,v2,extends); 00571 00572 return true; 00573 } 00574 }; 00575 00576 00578 SIMD_FORCE_INLINE bool btCompareTransformsEqual(const btTransform & t1,const btTransform & t2) 00579 { 00580 if(!(t1.getOrigin() == t2.getOrigin()) ) return false; 00581 00582 if(!(t1.getBasis().getRow(0) == t2.getBasis().getRow(0)) ) return false; 00583 if(!(t1.getBasis().getRow(1) == t2.getBasis().getRow(1)) ) return false; 00584 if(!(t1.getBasis().getRow(2) == t2.getBasis().getRow(2)) ) return false; 00585 return true; 00586 } 00587 00588 00589 00590 #endif // GIM_BOX_COLLISION_H_INCLUDED