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 
27 
28 
29 
30 
32  m_blockedForChanges(false)
33 {
34  int initialAllocatedSize= 2;
35  m_overlappingPairArray.reserve(initialAllocatedSize);
36  growTables();
37 }
38 
39 
40 
41 
43 {
44 }
45 
46 
47 
48 
49 
50 
52 {
55  m_next.clear();
56 
57  int initialAllocatedSize= 2;
58  m_overlappingPairArray.reserve(initialAllocatedSize);
59  growTables();
60 }
61 
62 
63 
65 {
67 
68 
69  /*if (indexA > indexB)
70  btSwap(indexA, indexB);*/
71 
72  int hash = static_cast<int>(getHash(static_cast<unsigned int>(indexA), static_cast<unsigned int>(indexB)) & (m_overlappingPairArray.capacity()-1));
73 
74  if (hash >= m_hashTable.size())
75  {
76  return NULL;
77  }
78 
79  int index = m_hashTable[hash];
80  while (index != BT_SIMPLE_NULL_PAIR && equalsPair(m_overlappingPairArray[index], indexA, indexB) == false)
81  {
82  index = m_next[index];
83  }
84 
85  if (index == BT_SIMPLE_NULL_PAIR)
86  {
87  return NULL;
88  }
89 
91 
92  return &m_overlappingPairArray[index];
93 }
94 
95 //#include <stdio.h>
96 
98 {
99 
100  int newCapacity = m_overlappingPairArray.capacity();
101 
102  if (m_hashTable.size() < newCapacity)
103  {
104  //grow hashtable and next table
105  int curHashtableSize = m_hashTable.size();
106 
107  m_hashTable.resize(newCapacity);
108  m_next.resize(newCapacity);
109 
110 
111  int i;
112 
113  for (i= 0; i < newCapacity; ++i)
114  {
116  }
117  for (i = 0; i < newCapacity; ++i)
118  {
120  }
121 
122  for(i=0;i<curHashtableSize;i++)
123  {
124 
125  const btSimplePair& pair = m_overlappingPairArray[i];
126  int indexA = pair.m_indexA;
127  int indexB = pair.m_indexB;
128 
129  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
130  m_next[i] = m_hashTable[hashValue];
131  m_hashTable[hashValue] = i;
132  }
133 
134 
135  }
136 }
137 
139 {
140 
141  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
142 
143 
144  btSimplePair* pair = internalFindPair(indexA, indexB, hash);
145  if (pair != NULL)
146  {
147  return pair;
148  }
149 
150  int count = m_overlappingPairArray.size();
151  int oldCapacity = m_overlappingPairArray.capacity();
153 
154  int newCapacity = m_overlappingPairArray.capacity();
155 
156  if (oldCapacity < newCapacity)
157  {
158  growTables();
159  //hash with new capacity
160  hash = static_cast<int>(getHash(static_cast<unsigned int>(indexA),static_cast<unsigned int>(indexB)) & (m_overlappingPairArray.capacity()-1));
161  }
162 
163  pair = new (mem) btSimplePair(indexA,indexB);
164 
165  pair->m_userPointer = 0;
166 
167  m_next[count] = m_hashTable[hash];
168  m_hashTable[hash] = count;
169 
170  return pair;
171 }
172 
173 
174 
176 {
178 
179 
180  /*if (indexA > indexB)
181  btSwap(indexA, indexB);*/
182 
183  int hash = static_cast<int>(getHash(static_cast<unsigned int>(indexA),static_cast<unsigned int>(indexB)) & (m_overlappingPairArray.capacity()-1));
184 
185  btSimplePair* pair = internalFindPair(indexA, indexB, hash);
186  if (pair == NULL)
187  {
188  return 0;
189  }
190 
191 
192  void* userData = pair->m_userPointer;
193 
194 
195  int pairIndex = int(pair - &m_overlappingPairArray[0]);
196  btAssert(pairIndex < m_overlappingPairArray.size());
197 
198  // Remove the pair from the hash table.
199  int index = m_hashTable[hash];
200  btAssert(index != BT_SIMPLE_NULL_PAIR);
201 
202  int previous = BT_SIMPLE_NULL_PAIR;
203  while (index != pairIndex)
204  {
205  previous = index;
206  index = m_next[index];
207  }
208 
209  if (previous != BT_SIMPLE_NULL_PAIR)
210  {
211  btAssert(m_next[previous] == pairIndex);
212  m_next[previous] = m_next[pairIndex];
213  }
214  else
215  {
216  m_hashTable[hash] = m_next[pairIndex];
217  }
218 
219  // We now move the last pair into spot of the
220  // pair being removed. We need to fix the hash
221  // table indices to support the move.
222 
223  int lastPairIndex = m_overlappingPairArray.size() - 1;
224 
225  // If the removed pair is the last pair, we are done.
226  if (lastPairIndex == pairIndex)
227  {
229  return userData;
230  }
231 
232  // Remove the last pair from the hash table.
233  const btSimplePair* last = &m_overlappingPairArray[lastPairIndex];
234  /* missing swap here too, Nat. */
235  int lastHash = static_cast<int>(getHash(static_cast<unsigned int>(last->m_indexA), static_cast<unsigned int>(last->m_indexB)) & (m_overlappingPairArray.capacity()-1));
236 
237  index = m_hashTable[lastHash];
238  btAssert(index != BT_SIMPLE_NULL_PAIR);
239 
240  previous = BT_SIMPLE_NULL_PAIR;
241  while (index != lastPairIndex)
242  {
243  previous = index;
244  index = m_next[index];
245  }
246 
247  if (previous != BT_SIMPLE_NULL_PAIR)
248  {
249  btAssert(m_next[previous] == lastPairIndex);
250  m_next[previous] = m_next[lastPairIndex];
251  }
252  else
253  {
254  m_hashTable[lastHash] = m_next[lastPairIndex];
255  }
256 
257  // Copy the last pair into the remove pair's spot.
258  m_overlappingPairArray[pairIndex] = m_overlappingPairArray[lastPairIndex];
259 
260  // Insert the last pair into the hash table
261  m_next[pairIndex] = m_hashTable[lastHash];
262  m_hashTable[lastHash] = pairIndex;
263 
265 
266  return userData;
267 }
268 //#include <stdio.h>
269 
270 
271 
272 
273 
274 
275 
276 
277 
278 
unsigned int getHash(unsigned int indexA, unsigned int indexB)
btSimplePair * internalFindPair(int proxyIdA, int proxyIdB, int hash)
#define btAssert(x)
Definition: btScalar.h:101
int gOverlappingSimplePairs
int gAddedSimplePairs
int gRemoveSimplePairs
int gFindSimplePairs
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)