Bullet Collision Detection & Physics Library
btHashedSimplePairCache.cpp
Go to the documentation of this file.
1 /*
2 Bullet Continuous Collision Detection and Physics Library
3 Copyright (c) 2003-2006 Erwin Coumans http://continuousphysics.com/Bullet/
4 
5 This software is provided 'as-is', without any express or implied warranty.
6 In no event will the authors be held liable for any damages arising from the use of this software.
7 Permission is granted to anyone to use this software for any purpose,
8 including commercial applications, and to alter it and redistribute it freely,
9 subject to the following restrictions:
10 
11 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.
12 2. Altered source versions must be plainly marked as such, and must not be misrepresented as being the original software.
13 3. This notice may not be removed or altered from any source distribution.
14 */
15 
16 
17 
19 
20 
21 #include <stdio.h>
22 
23 #ifdef BT_DEBUG_COLLISION_PAIRS
24 int gOverlappingSimplePairs = 0;
25 int gRemoveSimplePairs =0;
26 int gAddedSimplePairs =0;
27 int gFindSimplePairs =0;
28 #endif //BT_DEBUG_COLLISION_PAIRS
29 
30 
31 
33  int initialAllocatedSize= 2;
34  m_overlappingPairArray.reserve(initialAllocatedSize);
35  growTables();
36 }
37 
38 
39 
40 
42 {
43 }
44 
45 
46 
47 
48 
49 
51 {
54  m_next.clear();
55 
56  int initialAllocatedSize= 2;
57  m_overlappingPairArray.reserve(initialAllocatedSize);
58  growTables();
59 }
60 
61 
62 
64 {
65 #ifdef BT_DEBUG_COLLISION_PAIRS
66  gFindSimplePairs++;
67 #endif
68 
69 
70  /*if (indexA > indexB)
71  btSwap(indexA, indexB);*/
72 
73  int hash = static_cast<int>(getHash(static_cast<unsigned int>(indexA), static_cast<unsigned int>(indexB)) & (m_overlappingPairArray.capacity()-1));
74 
75  if (hash >= m_hashTable.size())
76  {
77  return NULL;
78  }
79 
80  int index = m_hashTable[hash];
81  while (index != BT_SIMPLE_NULL_PAIR && equalsPair(m_overlappingPairArray[index], indexA, indexB) == false)
82  {
83  index = m_next[index];
84  }
85 
86  if (index == BT_SIMPLE_NULL_PAIR)
87  {
88  return NULL;
89  }
90 
92 
93  return &m_overlappingPairArray[index];
94 }
95 
96 //#include <stdio.h>
97 
99 {
100 
101  int newCapacity = m_overlappingPairArray.capacity();
102 
103  if (m_hashTable.size() < newCapacity)
104  {
105  //grow hashtable and next table
106  int curHashtableSize = m_hashTable.size();
107 
108  m_hashTable.resize(newCapacity);
109  m_next.resize(newCapacity);
110 
111 
112  int i;
113 
114  for (i= 0; i < newCapacity; ++i)
115  {
117  }
118  for (i = 0; i < newCapacity; ++i)
119  {
121  }
122 
123  for(i=0;i<curHashtableSize;i++)
124  {
125 
126  const btSimplePair& pair = m_overlappingPairArray[i];
127  int indexA = pair.m_indexA;
128  int indexB = pair.m_indexB;
129 
130  int hashValue = static_cast<int>(getHash(static_cast<unsigned int>(indexA),static_cast<unsigned int>(indexB)) & (m_overlappingPairArray.capacity()-1)); // New hash value with new mask
131  m_next[i] = m_hashTable[hashValue];
132  m_hashTable[hashValue] = i;
133  }
134 
135 
136  }
137 }
138 
140 {
141 
142  int hash = static_cast<int>(getHash(static_cast<unsigned int>(indexA),static_cast<unsigned int>(indexB)) & (m_overlappingPairArray.capacity()-1)); // New hash value with new mask
143 
144 
145  btSimplePair* pair = internalFindPair(indexA, indexB, hash);
146  if (pair != NULL)
147  {
148  return pair;
149  }
150 
151  int count = m_overlappingPairArray.size();
152  int oldCapacity = m_overlappingPairArray.capacity();
154 
155  int newCapacity = m_overlappingPairArray.capacity();
156 
157  if (oldCapacity < newCapacity)
158  {
159  growTables();
160  //hash with new capacity
161  hash = static_cast<int>(getHash(static_cast<unsigned int>(indexA),static_cast<unsigned int>(indexB)) & (m_overlappingPairArray.capacity()-1));
162  }
163 
164  pair = new (mem) btSimplePair(indexA,indexB);
165 
166  pair->m_userPointer = 0;
167 
168  m_next[count] = m_hashTable[hash];
169  m_hashTable[hash] = count;
170 
171  return pair;
172 }
173 
174 
175 
177 {
178 #ifdef BT_DEBUG_COLLISION_PAIRS
179  gRemoveSimplePairs++;
180 #endif
181 
182 
183  /*if (indexA > indexB)
184  btSwap(indexA, indexB);*/
185 
186  int hash = static_cast<int>(getHash(static_cast<unsigned int>(indexA),static_cast<unsigned int>(indexB)) & (m_overlappingPairArray.capacity()-1));
187 
188  btSimplePair* pair = internalFindPair(indexA, indexB, hash);
189  if (pair == NULL)
190  {
191  return 0;
192  }
193 
194 
195  void* userData = pair->m_userPointer;
196 
197 
198  int pairIndex = int(pair - &m_overlappingPairArray[0]);
199  btAssert(pairIndex < m_overlappingPairArray.size());
200 
201  // Remove the pair from the hash table.
202  int index = m_hashTable[hash];
203  btAssert(index != BT_SIMPLE_NULL_PAIR);
204 
205  int previous = BT_SIMPLE_NULL_PAIR;
206  while (index != pairIndex)
207  {
208  previous = index;
209  index = m_next[index];
210  }
211 
212  if (previous != BT_SIMPLE_NULL_PAIR)
213  {
214  btAssert(m_next[previous] == pairIndex);
215  m_next[previous] = m_next[pairIndex];
216  }
217  else
218  {
219  m_hashTable[hash] = m_next[pairIndex];
220  }
221 
222  // We now move the last pair into spot of the
223  // pair being removed. We need to fix the hash
224  // table indices to support the move.
225 
226  int lastPairIndex = m_overlappingPairArray.size() - 1;
227 
228  // If the removed pair is the last pair, we are done.
229  if (lastPairIndex == pairIndex)
230  {
232  return userData;
233  }
234 
235  // Remove the last pair from the hash table.
236  const btSimplePair* last = &m_overlappingPairArray[lastPairIndex];
237  /* missing swap here too, Nat. */
238  int lastHash = static_cast<int>(getHash(static_cast<unsigned int>(last->m_indexA), static_cast<unsigned int>(last->m_indexB)) & (m_overlappingPairArray.capacity()-1));
239 
240  index = m_hashTable[lastHash];
241  btAssert(index != BT_SIMPLE_NULL_PAIR);
242 
243  previous = BT_SIMPLE_NULL_PAIR;
244  while (index != lastPairIndex)
245  {
246  previous = index;
247  index = m_next[index];
248  }
249 
250  if (previous != BT_SIMPLE_NULL_PAIR)
251  {
252  btAssert(m_next[previous] == lastPairIndex);
253  m_next[previous] = m_next[lastPairIndex];
254  }
255  else
256  {
257  m_hashTable[lastHash] = m_next[lastPairIndex];
258  }
259 
260  // Copy the last pair into the remove pair's spot.
261  m_overlappingPairArray[pairIndex] = m_overlappingPairArray[lastPairIndex];
262 
263  // Insert the last pair into the hash table
264  m_next[pairIndex] = m_hashTable[lastHash];
265  m_hashTable[lastHash] = pairIndex;
266 
268 
269  return userData;
270 }
271 //#include <stdio.h>
272 
273 
274 
275 
276 
277 
278 
279 
280 
281 
unsigned int getHash(unsigned int indexA, unsigned int indexB)
btSimplePair * internalFindPair(int proxyIdA, int proxyIdB, int hash)
#define btAssert(x)
Definition: btScalar.h:131
void clear()
clear the array, deallocated memory. Generally it is better to use array.resize(0), to reduce performance overhead of run-time memory (de)allocations.
const int BT_SIMPLE_NULL_PAIR
int size() const
return the number of elements in the array
btAlignedObjectArray< int > m_hashTable
int capacity() const
return the pre-allocated (reserved) elements, this is at least as large as the total number of elemen...
bool equalsPair(const btSimplePair &pair, int indexA, int indexB)
void resize(int newsize, const T &fillData=T())
btSimplePair * findPair(int indexA, int indexB)
btAlignedObjectArray< int > m_next
virtual void * removeOverlappingPair(int indexA, int indexB)
btSimplePairArray m_overlappingPairArray
btSimplePair * internalAddPair(int indexA, int indexB)