btPersistentManifold.h

Go to the documentation of this file.
00001 /*
00002 Bullet Continuous Collision Detection and Physics Library
00003 Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
00004 
00005 This software is provided 'as-is', without any express or implied warranty.
00006 In no event will the authors be held liable for any damages arising from the use of this software.
00007 Permission is granted to anyone to use this software for any purpose, 
00008 including commercial applications, and to alter it and redistribute it freely, 
00009 subject to the following restrictions:
00010 
00011 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.
00012 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
00013 3. This notice may not be removed or altered from any source distribution.
00014 */
00015 
00016 #ifndef BT_PERSISTENT_MANIFOLD_H
00017 #define BT_PERSISTENT_MANIFOLD_H
00018 
00019 
00020 #include "LinearMath/btVector3.h"
00021 #include "LinearMath/btTransform.h"
00022 #include "btManifoldPoint.h"
00023 class btCollisionObject;
00024 #include "LinearMath/btAlignedAllocator.h"
00025 
00026 struct btCollisionResult;
00027 
00029 extern btScalar gContactBreakingThreshold;
00030 
00031 typedef bool (*ContactDestroyedCallback)(void* userPersistentData);
00032 typedef bool (*ContactProcessedCallback)(btManifoldPoint& cp,void* body0,void* body1);
00033 extern ContactDestroyedCallback gContactDestroyedCallback;
00034 extern ContactProcessedCallback gContactProcessedCallback;
00035 
00036 //the enum starts at 1024 to avoid type conflicts with btTypedConstraint
00037 enum btContactManifoldTypes
00038 {
00039         MIN_CONTACT_MANIFOLD_TYPE = 1024,
00040         BT_PERSISTENT_MANIFOLD_TYPE
00041 };
00042 
00043 #define MANIFOLD_CACHE_SIZE 4
00044 
00052 
00053 
00054 ATTRIBUTE_ALIGNED128( class) btPersistentManifold : public btTypedObject
00055 //ATTRIBUTE_ALIGNED16( class) btPersistentManifold : public btTypedObject
00056 {
00057 
00058         btManifoldPoint m_pointCache[MANIFOLD_CACHE_SIZE];
00059 
00061         const btCollisionObject* m_body0;
00062         const btCollisionObject* m_body1;
00063 
00064         int     m_cachedPoints;
00065 
00066         btScalar        m_contactBreakingThreshold;
00067         btScalar        m_contactProcessingThreshold;
00068 
00069         
00071         int     sortCachedPoints(const btManifoldPoint& pt);
00072 
00073         int             findContactPoint(const btManifoldPoint* unUsed, int numUnused,const btManifoldPoint& pt);
00074 
00075 public:
00076 
00077         BT_DECLARE_ALIGNED_ALLOCATOR();
00078 
00079         int     m_companionIdA;
00080         int     m_companionIdB;
00081 
00082         int m_index1a;
00083 
00084         btPersistentManifold();
00085 
00086         btPersistentManifold(const btCollisionObject* body0,const btCollisionObject* body1,int , btScalar contactBreakingThreshold,btScalar contactProcessingThreshold)
00087                 : btTypedObject(BT_PERSISTENT_MANIFOLD_TYPE),
00088         m_body0(body0),m_body1(body1),m_cachedPoints(0),
00089                 m_contactBreakingThreshold(contactBreakingThreshold),
00090                 m_contactProcessingThreshold(contactProcessingThreshold)
00091         {
00092         }
00093 
00094         SIMD_FORCE_INLINE const btCollisionObject* getBody0() const { return m_body0;}
00095         SIMD_FORCE_INLINE const btCollisionObject* getBody1() const { return m_body1;}
00096 
00097         void    setBodies(const btCollisionObject* body0,const btCollisionObject* body1)
00098         {
00099                 m_body0 = body0;
00100                 m_body1 = body1;
00101         }
00102 
00103         void clearUserCache(btManifoldPoint& pt);
00104 
00105 #ifdef DEBUG_PERSISTENCY
00106         void    DebugPersistency();
00107 #endif //
00108         
00109         SIMD_FORCE_INLINE int   getNumContacts() const { return m_cachedPoints;}
00111         void setNumContacts(int cachedPoints)
00112         {
00113                 m_cachedPoints = cachedPoints;
00114         }
00115 
00116 
00117         SIMD_FORCE_INLINE const btManifoldPoint& getContactPoint(int index) const
00118         {
00119                 btAssert(index < m_cachedPoints);
00120                 return m_pointCache[index];
00121         }
00122 
00123         SIMD_FORCE_INLINE btManifoldPoint& getContactPoint(int index)
00124         {
00125                 btAssert(index < m_cachedPoints);
00126                 return m_pointCache[index];
00127         }
00128 
00130         btScalar        getContactBreakingThreshold() const;
00131 
00132         btScalar        getContactProcessingThreshold() const
00133         {
00134                 return m_contactProcessingThreshold;
00135         }
00136         
00137         void setContactBreakingThreshold(btScalar contactBreakingThreshold)
00138         {
00139                 m_contactBreakingThreshold = contactBreakingThreshold;
00140         }
00141 
00142         void setContactProcessingThreshold(btScalar     contactProcessingThreshold)
00143         {
00144                 m_contactProcessingThreshold = contactProcessingThreshold;
00145         }
00146         
00147         
00148 
00149 
00150         int getCacheEntry(const btManifoldPoint& newPoint) const;
00151 
00152         int addManifoldPoint( const btManifoldPoint& newPoint, bool isPredictive=false);
00153 
00154         void removeContactPoint (int index)
00155         {
00156                 clearUserCache(m_pointCache[index]);
00157 
00158                 int lastUsedIndex = getNumContacts() - 1;
00159 //              m_pointCache[index] = m_pointCache[lastUsedIndex];
00160                 if(index != lastUsedIndex) 
00161                 {
00162                         m_pointCache[index] = m_pointCache[lastUsedIndex]; 
00163                         //get rid of duplicated userPersistentData pointer
00164                         m_pointCache[lastUsedIndex].m_userPersistentData = 0;
00165                         m_pointCache[lastUsedIndex].m_appliedImpulse = 0.f;
00166                         m_pointCache[lastUsedIndex].m_lateralFrictionInitialized = false;
00167                         m_pointCache[lastUsedIndex].m_appliedImpulseLateral1 = 0.f;
00168                         m_pointCache[lastUsedIndex].m_appliedImpulseLateral2 = 0.f;
00169                         m_pointCache[lastUsedIndex].m_lifeTime = 0;
00170                 }
00171 
00172                 btAssert(m_pointCache[lastUsedIndex].m_userPersistentData==0);
00173                 m_cachedPoints--;
00174         }
00175         void replaceContactPoint(const btManifoldPoint& newPoint,int insertIndex)
00176         {
00177                 btAssert(validContactDistance(newPoint));
00178 
00179 #define MAINTAIN_PERSISTENCY 1
00180 #ifdef MAINTAIN_PERSISTENCY
00181                 int     lifeTime = m_pointCache[insertIndex].getLifeTime();
00182                 btScalar        appliedImpulse = m_pointCache[insertIndex].m_appliedImpulse;
00183                 btScalar        appliedLateralImpulse1 = m_pointCache[insertIndex].m_appliedImpulseLateral1;
00184                 btScalar        appliedLateralImpulse2 = m_pointCache[insertIndex].m_appliedImpulseLateral2;
00185 //              bool isLateralFrictionInitialized = m_pointCache[insertIndex].m_lateralFrictionInitialized;
00186                 
00187                 
00188                         
00189                 btAssert(lifeTime>=0);
00190                 void* cache = m_pointCache[insertIndex].m_userPersistentData;
00191                 
00192                 m_pointCache[insertIndex] = newPoint;
00193 
00194                 m_pointCache[insertIndex].m_userPersistentData = cache;
00195                 m_pointCache[insertIndex].m_appliedImpulse = appliedImpulse;
00196                 m_pointCache[insertIndex].m_appliedImpulseLateral1 = appliedLateralImpulse1;
00197                 m_pointCache[insertIndex].m_appliedImpulseLateral2 = appliedLateralImpulse2;
00198                 
00199                 m_pointCache[insertIndex].m_appliedImpulse =  appliedImpulse;
00200                 m_pointCache[insertIndex].m_appliedImpulseLateral1 = appliedLateralImpulse1;
00201                 m_pointCache[insertIndex].m_appliedImpulseLateral2 = appliedLateralImpulse2;
00202 
00203 
00204                 m_pointCache[insertIndex].m_lifeTime = lifeTime;
00205 #else
00206                 clearUserCache(m_pointCache[insertIndex]);
00207                 m_pointCache[insertIndex] = newPoint;
00208         
00209 #endif
00210         }
00211 
00212         
00213         bool validContactDistance(const btManifoldPoint& pt) const
00214         {
00215                 return pt.m_distance1 <= getContactBreakingThreshold();
00216         }
00218         void    refreshContactPoints(  const btTransform& trA,const btTransform& trB);
00219 
00220         
00221         SIMD_FORCE_INLINE       void    clearManifold()
00222         {
00223                 int i;
00224                 for (i=0;i<m_cachedPoints;i++)
00225                 {
00226                         clearUserCache(m_pointCache[i]);
00227                 }
00228                 m_cachedPoints = 0;
00229         }
00230 
00231 
00232 
00233 }
00234 ;
00235 
00236 
00237 
00238 
00239 
00240 #endif //BT_PERSISTENT_MANIFOLD_H