00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #ifndef PERSISTENT_MANIFOLD_H
00017 #define PERSISTENT_MANIFOLD_H
00018
00019
00020 #include "LinearMath/btVector3.h"
00021 #include "LinearMath/btTransform.h"
00022 #include "btManifoldPoint.h"
00023 #include "LinearMath/btAlignedAllocator.h"
00024
00025 struct btCollisionResult;
00026
00028 extern btScalar gContactBreakingThreshold;
00029
00030 typedef bool (*ContactDestroyedCallback)(void* userPersistentData);
00031 typedef bool (*ContactProcessedCallback)(btManifoldPoint& cp,void* body0,void* body1);
00032 extern ContactDestroyedCallback gContactDestroyedCallback;
00033 extern ContactProcessedCallback gContactProcessedCallback;
00034
00035
00036 enum btContactManifoldTypes
00037 {
00038 BT_PERSISTENT_MANIFOLD_TYPE = 1,
00039 MAX_CONTACT_MANIFOLD_TYPE
00040 };
00041
00042 #define MANIFOLD_CACHE_SIZE 4
00043
00051 ATTRIBUTE_ALIGNED16( class) btPersistentManifold : public btTypedObject
00052 {
00053
00054 btManifoldPoint m_pointCache[MANIFOLD_CACHE_SIZE];
00055
00058 void* m_body0;
00059 void* m_body1;
00060 int m_cachedPoints;
00061
00062 btScalar m_contactBreakingThreshold;
00063 btScalar m_contactProcessingThreshold;
00064
00065
00067 int sortCachedPoints(const btManifoldPoint& pt);
00068
00069 int findContactPoint(const btManifoldPoint* unUsed, int numUnused,const btManifoldPoint& pt);
00070
00071 public:
00072
00073 BT_DECLARE_ALIGNED_ALLOCATOR();
00074
00075 int m_index1a;
00076
00077 btPersistentManifold();
00078
00079 btPersistentManifold(void* body0,void* body1,int , btScalar contactBreakingThreshold,btScalar contactProcessingThreshold)
00080 : btTypedObject(BT_PERSISTENT_MANIFOLD_TYPE),
00081 m_body0(body0),m_body1(body1),m_cachedPoints(0),
00082 m_contactBreakingThreshold(contactBreakingThreshold),
00083 m_contactProcessingThreshold(contactProcessingThreshold)
00084 {
00085 }
00086
00087 SIMD_FORCE_INLINE void* getBody0() { return m_body0;}
00088 SIMD_FORCE_INLINE void* getBody1() { return m_body1;}
00089
00090 SIMD_FORCE_INLINE const void* getBody0() const { return m_body0;}
00091 SIMD_FORCE_INLINE const void* getBody1() const { return m_body1;}
00092
00093 void setBodies(void* body0,void* body1)
00094 {
00095 m_body0 = body0;
00096 m_body1 = body1;
00097 }
00098
00099 void clearUserCache(btManifoldPoint& pt);
00100
00101 #ifdef DEBUG_PERSISTENCY
00102 void DebugPersistency();
00103 #endif //
00104
00105 SIMD_FORCE_INLINE int getNumContacts() const { return m_cachedPoints;}
00106
00107 SIMD_FORCE_INLINE const btManifoldPoint& getContactPoint(int index) const
00108 {
00109 btAssert(index < m_cachedPoints);
00110 return m_pointCache[index];
00111 }
00112
00113 SIMD_FORCE_INLINE btManifoldPoint& getContactPoint(int index)
00114 {
00115 btAssert(index < m_cachedPoints);
00116 return m_pointCache[index];
00117 }
00118
00120 btScalar getContactBreakingThreshold() const;
00121
00122 btScalar getContactProcessingThreshold() const
00123 {
00124 return m_contactProcessingThreshold;
00125 }
00126
00127 int getCacheEntry(const btManifoldPoint& newPoint) const;
00128
00129 int addManifoldPoint( const btManifoldPoint& newPoint);
00130
00131 void removeContactPoint (int index)
00132 {
00133 clearUserCache(m_pointCache[index]);
00134
00135 int lastUsedIndex = getNumContacts() - 1;
00136
00137 if(index != lastUsedIndex)
00138 {
00139 m_pointCache[index] = m_pointCache[lastUsedIndex];
00140
00141 m_pointCache[lastUsedIndex].m_userPersistentData = 0;
00142 m_pointCache[lastUsedIndex].m_appliedImpulse = 0.f;
00143 m_pointCache[lastUsedIndex].m_lateralFrictionInitialized = false;
00144 m_pointCache[lastUsedIndex].m_appliedImpulseLateral1 = 0.f;
00145 m_pointCache[lastUsedIndex].m_appliedImpulseLateral2 = 0.f;
00146 m_pointCache[lastUsedIndex].m_lifeTime = 0;
00147 }
00148
00149 btAssert(m_pointCache[lastUsedIndex].m_userPersistentData==0);
00150 m_cachedPoints--;
00151 }
00152 void replaceContactPoint(const btManifoldPoint& newPoint,int insertIndex)
00153 {
00154 btAssert(validContactDistance(newPoint));
00155
00156 #define MAINTAIN_PERSISTENCY 1
00157 #ifdef MAINTAIN_PERSISTENCY
00158 int lifeTime = m_pointCache[insertIndex].getLifeTime();
00159 btScalar appliedImpulse = m_pointCache[insertIndex].m_appliedImpulse;
00160 btScalar appliedLateralImpulse1 = m_pointCache[insertIndex].m_appliedImpulseLateral1;
00161 btScalar appliedLateralImpulse2 = m_pointCache[insertIndex].m_appliedImpulseLateral2;
00162
00163 btAssert(lifeTime>=0);
00164 void* cache = m_pointCache[insertIndex].m_userPersistentData;
00165
00166 m_pointCache[insertIndex] = newPoint;
00167
00168 m_pointCache[insertIndex].m_userPersistentData = cache;
00169 m_pointCache[insertIndex].m_appliedImpulse = appliedImpulse;
00170 m_pointCache[insertIndex].m_appliedImpulseLateral1 = appliedLateralImpulse1;
00171 m_pointCache[insertIndex].m_appliedImpulseLateral2 = appliedLateralImpulse2;
00172
00173 m_pointCache[insertIndex].m_lifeTime = lifeTime;
00174 #else
00175 clearUserCache(m_pointCache[insertIndex]);
00176 m_pointCache[insertIndex] = newPoint;
00177
00178 #endif
00179 }
00180
00181 bool validContactDistance(const btManifoldPoint& pt) const
00182 {
00183 return pt.m_distance1 <= getContactBreakingThreshold();
00184 }
00186 void refreshContactPoints( const btTransform& trA,const btTransform& trB);
00187
00188
00189 SIMD_FORCE_INLINE void clearManifold()
00190 {
00191 int i;
00192 for (i=0;i<m_cachedPoints;i++)
00193 {
00194 clearUserCache(m_pointCache[i]);
00195 }
00196 m_cachedPoints = 0;
00197 }
00198
00199
00200
00201 }
00202 ;
00203
00204
00205
00206
00207
00208 #endif //PERSISTENT_MANIFOLD_H