Planet
navi homePPSaboutscreenshotsdownloaddevelopmentforum

source: code/trunk/src/bullet/BulletCollision/NarrowPhaseCollision/btPersistentManifold.h @ 2985

Last change on this file since 2985 was 2882, checked in by rgrieder, 16 years ago

Update from Bullet 2.73 to 2.74.

  • Property svn:eol-style set to native
File size: 6.5 KB
Line 
1/*
2Bullet Continuous Collision Detection and Physics Library
3Copyright (c) 2003-2006 Erwin Coumans  http://continuousphysics.com/Bullet/
4
5This software is provided 'as-is', without any express or implied warranty.
6In no event will the authors be held liable for any damages arising from the use of this software.
7Permission is granted to anyone to use this software for any purpose,
8including commercial applications, and to alter it and redistribute it freely,
9subject to the following restrictions:
10
111. 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.
122. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
133. This notice may not be removed or altered from any source distribution.
14*/
15
16#ifndef PERSISTENT_MANIFOLD_H
17#define PERSISTENT_MANIFOLD_H
18
19
20#include "LinearMath/btVector3.h"
21#include "LinearMath/btTransform.h"
22#include "btManifoldPoint.h"
23#include "LinearMath/btAlignedAllocator.h"
24
25struct btCollisionResult;
26
27///maximum contact breaking and merging threshold
28extern btScalar gContactBreakingThreshold;
29
30typedef bool (*ContactDestroyedCallback)(void* userPersistentData);
31typedef bool (*ContactProcessedCallback)(btManifoldPoint& cp,void* body0,void* body1);
32extern ContactDestroyedCallback gContactDestroyedCallback;
33
34
35
36
37#define MANIFOLD_CACHE_SIZE 4
38
39///btPersistentManifold is a contact point cache, it stays persistent as long as objects are overlapping in the broadphase.
40///Those contact points are created by the collision narrow phase.
41///The cache can be empty, or hold 1,2,3 or 4 points. Some collision algorithms (GJK) might only add one point at a time.
42///updates/refreshes old contact points, and throw them away if necessary (distance becomes too large)
43///reduces the cache to 4 points, when more then 4 points are added, using following rules:
44///the contact point with deepest penetration is always kept, and it tries to maximuze the area covered by the points
45///note that some pairs of objects might have more then one contact manifold.
46ATTRIBUTE_ALIGNED16( class) btPersistentManifold
47{
48
49        btManifoldPoint m_pointCache[MANIFOLD_CACHE_SIZE];
50
51        /// this two body pointers can point to the physics rigidbody class.
52        /// void* will allow any rigidbody class
53        void* m_body0;
54        void* m_body1;
55        int     m_cachedPoints;
56
57        btScalar        m_contactBreakingThreshold;
58        btScalar        m_contactProcessingThreshold;
59
60       
61        /// sort cached points so most isolated points come first
62        int     sortCachedPoints(const btManifoldPoint& pt);
63
64        int             findContactPoint(const btManifoldPoint* unUsed, int numUnused,const btManifoldPoint& pt);
65
66public:
67
68        BT_DECLARE_ALIGNED_ALLOCATOR();
69
70        int m_index1a;
71
72        btPersistentManifold();
73
74        btPersistentManifold(void* body0,void* body1,int , btScalar contactBreakingThreshold,btScalar contactProcessingThreshold)
75                : m_body0(body0),m_body1(body1),m_cachedPoints(0),
76                m_contactBreakingThreshold(contactBreakingThreshold),
77                m_contactProcessingThreshold(contactProcessingThreshold)
78        {
79               
80        }
81
82        SIMD_FORCE_INLINE void* getBody0() { return m_body0;}
83        SIMD_FORCE_INLINE void* getBody1() { return m_body1;}
84
85        SIMD_FORCE_INLINE const void* getBody0() const { return m_body0;}
86        SIMD_FORCE_INLINE const void* getBody1() const { return m_body1;}
87
88        void    setBodies(void* body0,void* body1)
89        {
90                m_body0 = body0;
91                m_body1 = body1;
92        }
93
94        void clearUserCache(btManifoldPoint& pt);
95
96#ifdef DEBUG_PERSISTENCY
97        void    DebugPersistency();
98#endif //
99       
100        SIMD_FORCE_INLINE int   getNumContacts() const { return m_cachedPoints;}
101
102        SIMD_FORCE_INLINE const btManifoldPoint& getContactPoint(int index) const
103        {
104                btAssert(index < m_cachedPoints);
105                return m_pointCache[index];
106        }
107
108        SIMD_FORCE_INLINE btManifoldPoint& getContactPoint(int index)
109        {
110                btAssert(index < m_cachedPoints);
111                return m_pointCache[index];
112        }
113
114        ///@todo: get this margin from the current physics / collision environment
115        btScalar        getContactBreakingThreshold() const;
116
117        btScalar        getContactProcessingThreshold() const
118        {
119                return m_contactProcessingThreshold;
120        }
121       
122        int getCacheEntry(const btManifoldPoint& newPoint) const;
123
124        int addManifoldPoint( const btManifoldPoint& newPoint);
125
126        void removeContactPoint (int index)
127        {
128                clearUserCache(m_pointCache[index]);
129
130                int lastUsedIndex = getNumContacts() - 1;
131//              m_pointCache[index] = m_pointCache[lastUsedIndex];
132                if(index != lastUsedIndex) 
133                {
134                        m_pointCache[index] = m_pointCache[lastUsedIndex]; 
135                        //get rid of duplicated userPersistentData pointer
136                        m_pointCache[lastUsedIndex].m_userPersistentData = 0;
137                        m_pointCache[lastUsedIndex].m_appliedImpulse = 0.f;
138                        m_pointCache[lastUsedIndex].m_lateralFrictionInitialized = false;
139                        m_pointCache[lastUsedIndex].m_appliedImpulseLateral1 = 0.f;
140                        m_pointCache[lastUsedIndex].m_appliedImpulseLateral2 = 0.f;
141                        m_pointCache[lastUsedIndex].m_lifeTime = 0;
142                }
143
144                btAssert(m_pointCache[lastUsedIndex].m_userPersistentData==0);
145                m_cachedPoints--;
146        }
147        void replaceContactPoint(const btManifoldPoint& newPoint,int insertIndex)
148        {
149                btAssert(validContactDistance(newPoint));
150
151#define MAINTAIN_PERSISTENCY 1
152#ifdef MAINTAIN_PERSISTENCY
153                int     lifeTime = m_pointCache[insertIndex].getLifeTime();
154                btScalar        appliedImpulse = m_pointCache[insertIndex].m_appliedImpulse;
155                btScalar        appliedLateralImpulse1 = m_pointCache[insertIndex].m_appliedImpulseLateral1;
156                btScalar        appliedLateralImpulse2 = m_pointCache[insertIndex].m_appliedImpulseLateral2;
157                               
158                btAssert(lifeTime>=0);
159                void* cache = m_pointCache[insertIndex].m_userPersistentData;
160               
161                m_pointCache[insertIndex] = newPoint;
162
163                m_pointCache[insertIndex].m_userPersistentData = cache;
164                m_pointCache[insertIndex].m_appliedImpulse = appliedImpulse;
165                m_pointCache[insertIndex].m_appliedImpulseLateral1 = appliedLateralImpulse1;
166                m_pointCache[insertIndex].m_appliedImpulseLateral2 = appliedLateralImpulse2;
167               
168                m_pointCache[insertIndex].m_lifeTime = lifeTime;
169#else
170                clearUserCache(m_pointCache[insertIndex]);
171                m_pointCache[insertIndex] = newPoint;
172       
173#endif
174        }
175
176        bool validContactDistance(const btManifoldPoint& pt) const
177        {
178                return pt.m_distance1 <= getContactBreakingThreshold();
179        }
180        /// calculated new worldspace coordinates and depth, and reject points that exceed the collision margin
181        void    refreshContactPoints(  const btTransform& trA,const btTransform& trB);
182
183       
184        SIMD_FORCE_INLINE       void    clearManifold()
185        {
186                int i;
187                for (i=0;i<m_cachedPoints;i++)
188                {
189                        clearUserCache(m_pointCache[i]);
190                }
191                m_cachedPoints = 0;
192        }
193
194
195
196}
197;
198
199
200
201
202
203#endif //PERSISTENT_MANIFOLD_H
Note: See TracBrowser for help on using the repository browser.