Back to index

supertuxkart  0.5+dfsg1
btAabbUtil2.h
Go to the documentation of this file.
00001 /*
00002 Copyright (c) 2003-2006 Gino van den Bergen / Erwin Coumans  http://continuousphysics.com/Bullet/
00003 
00004 This software is provided 'as-is', without any express or implied warranty.
00005 In no event will the authors be held liable for any damages arising from the use of this software.
00006 Permission is granted to anyone to use this software for any purpose, 
00007 including commercial applications, and to alter it and redistribute it freely, 
00008 subject to the following restrictions:
00009 
00010 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.
00011 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
00012 3. This notice may not be removed or altered from any source distribution.
00013 */
00014 
00015 
00016 
00017 #ifndef AABB_UTIL2
00018 #define AABB_UTIL2
00019 
00020 #include "btVector3.h"
00021 #include "btMinMax.h"
00022 
00023 SIMD_FORCE_INLINE void AabbExpand (btVector3& aabbMin,
00024                                                            btVector3& aabbMax,
00025                                                            const btVector3& expansionMin,
00026                                                            const btVector3& expansionMax)
00027 {
00028        aabbMin = aabbMin + expansionMin;
00029        aabbMax = aabbMax + expansionMax;
00030 }
00031 
00032 
00034 SIMD_FORCE_INLINE bool TestAabbAgainstAabb2(const btVector3 &aabbMin1, const btVector3 &aabbMax1,
00035                                                         const btVector3 &aabbMin2, const btVector3 &aabbMax2)
00036 {
00037        bool overlap = true;
00038        overlap = (aabbMin1[0] > aabbMax2[0] || aabbMax1[0] < aabbMin2[0]) ? false : overlap;
00039        overlap = (aabbMin1[2] > aabbMax2[2] || aabbMax1[2] < aabbMin2[2]) ? false : overlap;
00040        overlap = (aabbMin1[1] > aabbMax2[1] || aabbMax1[1] < aabbMin2[1]) ? false : overlap;
00041        return overlap;
00042 }
00043 
00045 SIMD_FORCE_INLINE bool TestTriangleAgainstAabb2(const btVector3 *vertices,
00046                                                                const btVector3 &aabbMin, const btVector3 &aabbMax)
00047 {
00048        const btVector3 &p1 = vertices[0];
00049        const btVector3 &p2 = vertices[1];
00050        const btVector3 &p3 = vertices[2];
00051 
00052        if (btMin(btMin(p1[0], p2[0]), p3[0]) > aabbMax[0]) return false;
00053        if (btMax(btMax(p1[0], p2[0]), p3[0]) < aabbMin[0]) return false;
00054 
00055        if (btMin(btMin(p1[2], p2[2]), p3[2]) > aabbMax[2]) return false;
00056        if (btMax(btMax(p1[2], p2[2]), p3[2]) < aabbMin[2]) return false;
00057   
00058        if (btMin(btMin(p1[1], p2[1]), p3[1]) > aabbMax[1]) return false;
00059        if (btMax(btMax(p1[1], p2[1]), p3[1]) < aabbMin[1]) return false;
00060        return true;
00061 }
00062 
00063 
00064 SIMD_FORCE_INLINE int       btOutcode(const btVector3& p,const btVector3& halfExtent) 
00065 {
00066        return (p.getX()  < -halfExtent.getX() ? 0x01 : 0x0) |    
00067                  (p.getX() >  halfExtent.getX() ? 0x08 : 0x0) |
00068                  (p.getY() < -halfExtent.getY() ? 0x02 : 0x0) |    
00069                  (p.getY() >  halfExtent.getY() ? 0x10 : 0x0) |
00070                  (p.getZ() < -halfExtent.getZ() ? 0x4 : 0x0) |    
00071                  (p.getZ() >  halfExtent.getZ() ? 0x20 : 0x0);
00072 }
00073 
00074 
00075 SIMD_FORCE_INLINE bool btRayAabb2(const btVector3& rayFrom,
00076                                                           const btVector3& rayInvDirection,
00077                                                           const unsigned int raySign[3],
00078                                                           const btVector3 bounds[2],
00079                                                           btScalar& tmin,
00080                                                           btScalar lambda_min,
00081                                                           btScalar lambda_max)
00082 {
00083        btScalar tmax, tymin, tymax, tzmin, tzmax;
00084        tmin = (bounds[raySign[0]][0] - rayFrom[0]) * rayInvDirection[0];
00085        tmax = (bounds[1-raySign[0]][0] - rayFrom[0]) * rayInvDirection[0];
00086        tymin = (bounds[raySign[1]][1] - rayFrom[1]) * rayInvDirection[1];
00087        tymax = (bounds[1-raySign[1]][1] - rayFrom[1]) * rayInvDirection[1];
00088 
00089        if ( (tmin > tymax) || (tymin > tmax) )
00090               return false;
00091 
00092        if (tymin > tmin)
00093               tmin = tymin;
00094 
00095        if (tymax < tmax)
00096               tmax = tymax;
00097 
00098        tzmin = (bounds[raySign[2]][2] - rayFrom[2]) * rayInvDirection[2];
00099        tzmax = (bounds[1-raySign[2]][2] - rayFrom[2]) * rayInvDirection[2];
00100 
00101        if ( (tmin > tzmax) || (tzmin > tmax) )
00102               return false;
00103        if (tzmin > tmin)
00104               tmin = tzmin;
00105        if (tzmax < tmax)
00106               tmax = tzmax;
00107        return ( (tmin < lambda_max) && (tmax > lambda_min) );
00108 }
00109 
00110 SIMD_FORCE_INLINE bool btRayAabb(const btVector3& rayFrom, 
00111                                                          const btVector3& rayTo, 
00112                                                          const btVector3& aabbMin, 
00113                                                          const btVector3& aabbMax,
00114                                      btScalar& param, btVector3& normal) 
00115 {
00116        btVector3 aabbHalfExtent = (aabbMax-aabbMin)* btScalar(0.5);
00117        btVector3 aabbCenter = (aabbMax+aabbMin)* btScalar(0.5);
00118        btVector3     source = rayFrom - aabbCenter;
00119        btVector3     target = rayTo - aabbCenter;
00120        int    sourceOutcode = btOutcode(source,aabbHalfExtent);
00121        int targetOutcode = btOutcode(target,aabbHalfExtent);
00122        if ((sourceOutcode & targetOutcode) == 0x0)
00123        {
00124               btScalar lambda_enter = btScalar(0.0);
00125               btScalar lambda_exit  = param;
00126               btVector3 r = target - source;
00127               int i;
00128               btScalar      normSign = 1;
00129               btVector3     hitNormal(0,0,0);
00130               int bit=1;
00131 
00132               for (int j=0;j<2;j++)
00133               {
00134                      for (i = 0; i != 3; ++i)
00135                      {
00136                             if (sourceOutcode & bit)
00137                             {
00138                                    btScalar lambda = (-source[i] - aabbHalfExtent[i]*normSign) / r[i];
00139                                    if (lambda_enter <= lambda)
00140                                    {
00141                                           lambda_enter = lambda;
00142                                           hitNormal.setValue(0,0,0);
00143                                           hitNormal[i] = normSign;
00144                                    }
00145                             }
00146                             else if (targetOutcode & bit) 
00147                             {
00148                                    btScalar lambda = (-source[i] - aabbHalfExtent[i]*normSign) / r[i];
00149                                    btSetMin(lambda_exit, lambda);
00150                             }
00151                             bit<<=1;
00152                      }
00153                      normSign = btScalar(-1.);
00154               }
00155               if (lambda_enter <= lambda_exit)
00156               {
00157                      param = lambda_enter;
00158                      normal = hitNormal;
00159                      return true;
00160               }
00161        }
00162        return false;
00163 }
00164 
00165 
00166 #endif
00167 
00168