Blender V2.61 - r43446
|
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 00017 #ifndef BT_OBJECT_ARRAY__ 00018 #define BT_OBJECT_ARRAY__ 00019 00020 #include "btScalar.h" // has definitions like SIMD_FORCE_INLINE 00021 #include "btAlignedAllocator.h" 00022 00028 00029 #define BT_USE_PLACEMENT_NEW 1 00030 //#define BT_USE_MEMCPY 1 //disable, because it is cumbersome to find out for each platform where memcpy is defined. It can be in <memory.h> or <string.h> or otherwise... 00031 00032 #ifdef BT_USE_MEMCPY 00033 #include <memory.h> 00034 #include <string.h> 00035 #endif //BT_USE_MEMCPY 00036 00037 #ifdef BT_USE_PLACEMENT_NEW 00038 #include <new> //for placement new 00039 #endif //BT_USE_PLACEMENT_NEW 00040 00041 00044 template <typename T> 00045 //template <class T> 00046 class btAlignedObjectArray 00047 { 00048 btAlignedAllocator<T , 16> m_allocator; 00049 00050 int m_size; 00051 int m_capacity; 00052 T* m_data; 00053 //PCK: added this line 00054 bool m_ownsMemory; 00055 00056 protected: 00057 SIMD_FORCE_INLINE int allocSize(int size) 00058 { 00059 return (size ? size*2 : 1); 00060 } 00061 SIMD_FORCE_INLINE void copy(int start,int end, T* dest) const 00062 { 00063 int i; 00064 for (i=start;i<end;++i) 00065 #ifdef BT_USE_PLACEMENT_NEW 00066 new (&dest[i]) T(m_data[i]); 00067 #else 00068 dest[i] = m_data[i]; 00069 #endif //BT_USE_PLACEMENT_NEW 00070 } 00071 00072 SIMD_FORCE_INLINE void init() 00073 { 00074 //PCK: added this line 00075 m_ownsMemory = true; 00076 m_data = 0; 00077 m_size = 0; 00078 m_capacity = 0; 00079 } 00080 SIMD_FORCE_INLINE void destroy(int first,int last) 00081 { 00082 int i; 00083 for (i=first; i<last;i++) 00084 { 00085 m_data[i].~T(); 00086 } 00087 } 00088 00089 SIMD_FORCE_INLINE void* allocate(int size) 00090 { 00091 if (size) 00092 return m_allocator.allocate(size); 00093 return 0; 00094 } 00095 00096 SIMD_FORCE_INLINE void deallocate() 00097 { 00098 if(m_data) { 00099 //PCK: enclosed the deallocation in this block 00100 if (m_ownsMemory) 00101 { 00102 m_allocator.deallocate(m_data); 00103 } 00104 m_data = 0; 00105 } 00106 } 00107 00108 00109 00110 00111 public: 00112 00113 btAlignedObjectArray() 00114 { 00115 init(); 00116 } 00117 00118 ~btAlignedObjectArray() 00119 { 00120 clear(); 00121 } 00122 00124 btAlignedObjectArray(const btAlignedObjectArray& otherArray) 00125 { 00126 init(); 00127 00128 int otherSize = otherArray.size(); 00129 resize (otherSize); 00130 otherArray.copy(0, otherSize, m_data); 00131 } 00132 00133 00134 00136 SIMD_FORCE_INLINE int size() const 00137 { 00138 return m_size; 00139 } 00140 00141 SIMD_FORCE_INLINE const T& at(int n) const 00142 { 00143 return m_data[n]; 00144 } 00145 00146 SIMD_FORCE_INLINE T& at(int n) 00147 { 00148 return m_data[n]; 00149 } 00150 00151 SIMD_FORCE_INLINE const T& operator[](int n) const 00152 { 00153 return m_data[n]; 00154 } 00155 00156 SIMD_FORCE_INLINE T& operator[](int n) 00157 { 00158 return m_data[n]; 00159 } 00160 00161 00163 SIMD_FORCE_INLINE void clear() 00164 { 00165 destroy(0,size()); 00166 00167 deallocate(); 00168 00169 init(); 00170 } 00171 00172 SIMD_FORCE_INLINE void pop_back() 00173 { 00174 m_size--; 00175 m_data[m_size].~T(); 00176 } 00177 00180 SIMD_FORCE_INLINE void resize(int newsize, const T& fillData=T()) 00181 { 00182 int curSize = size(); 00183 00184 if (newsize < curSize) 00185 { 00186 for(int i = newsize; i < curSize; i++) 00187 { 00188 m_data[i].~T(); 00189 } 00190 } else 00191 { 00192 if (newsize > size()) 00193 { 00194 reserve(newsize); 00195 } 00196 #ifdef BT_USE_PLACEMENT_NEW 00197 for (int i=curSize;i<newsize;i++) 00198 { 00199 new ( &m_data[i]) T(fillData); 00200 } 00201 #endif //BT_USE_PLACEMENT_NEW 00202 00203 } 00204 00205 m_size = newsize; 00206 } 00207 00208 SIMD_FORCE_INLINE T& expandNonInitializing( ) 00209 { 00210 int sz = size(); 00211 if( sz == capacity() ) 00212 { 00213 reserve( allocSize(size()) ); 00214 } 00215 m_size++; 00216 00217 return m_data[sz]; 00218 } 00219 00220 00221 SIMD_FORCE_INLINE T& expand( const T& fillValue=T()) 00222 { 00223 int sz = size(); 00224 if( sz == capacity() ) 00225 { 00226 reserve( allocSize(size()) ); 00227 } 00228 m_size++; 00229 #ifdef BT_USE_PLACEMENT_NEW 00230 new (&m_data[sz]) T(fillValue); //use the in-place new (not really allocating heap memory) 00231 #endif 00232 00233 return m_data[sz]; 00234 } 00235 00236 00237 SIMD_FORCE_INLINE void push_back(const T& _Val) 00238 { 00239 int sz = size(); 00240 if( sz == capacity() ) 00241 { 00242 reserve( allocSize(size()) ); 00243 } 00244 00245 #ifdef BT_USE_PLACEMENT_NEW 00246 new ( &m_data[m_size] ) T(_Val); 00247 #else 00248 m_data[size()] = _Val; 00249 #endif //BT_USE_PLACEMENT_NEW 00250 00251 m_size++; 00252 } 00253 00254 00256 SIMD_FORCE_INLINE int capacity() const 00257 { 00258 return m_capacity; 00259 } 00260 00261 SIMD_FORCE_INLINE void reserve(int _Count) 00262 { // determine new minimum length of allocated storage 00263 if (capacity() < _Count) 00264 { // not enough room, reallocate 00265 T* s = (T*)allocate(_Count); 00266 00267 copy(0, size(), s); 00268 00269 destroy(0,size()); 00270 00271 deallocate(); 00272 00273 //PCK: added this line 00274 m_ownsMemory = true; 00275 00276 m_data = s; 00277 00278 m_capacity = _Count; 00279 00280 } 00281 } 00282 00283 00284 class less 00285 { 00286 public: 00287 00288 bool operator() ( const T& a, const T& b ) 00289 { 00290 return ( a < b ); 00291 } 00292 }; 00293 00294 template <typename L> 00295 void quickSortInternal(L CompareFunc,int lo, int hi) 00296 { 00297 // lo is the lower index, hi is the upper index 00298 // of the region of array a that is to be sorted 00299 int i=lo, j=hi; 00300 T x=m_data[(lo+hi)/2]; 00301 00302 // partition 00303 do 00304 { 00305 while (CompareFunc(m_data[i],x)) 00306 i++; 00307 while (CompareFunc(x,m_data[j])) 00308 j--; 00309 if (i<=j) 00310 { 00311 swap(i,j); 00312 i++; j--; 00313 } 00314 } while (i<=j); 00315 00316 // recursion 00317 if (lo<j) 00318 quickSortInternal( CompareFunc, lo, j); 00319 if (i<hi) 00320 quickSortInternal( CompareFunc, i, hi); 00321 } 00322 00323 00324 template <typename L> 00325 void quickSort(L CompareFunc) 00326 { 00327 //don't sort 0 or 1 elements 00328 if (size()>1) 00329 { 00330 quickSortInternal(CompareFunc,0,size()-1); 00331 } 00332 } 00333 00334 00336 template <typename L> 00337 void downHeap(T *pArr, int k, int n,L CompareFunc) 00338 { 00339 /* PRE: a[k+1..N] is a heap */ 00340 /* POST: a[k..N] is a heap */ 00341 00342 T temp = pArr[k - 1]; 00343 /* k has child(s) */ 00344 while (k <= n/2) 00345 { 00346 int child = 2*k; 00347 00348 if ((child < n) && CompareFunc(pArr[child - 1] , pArr[child])) 00349 { 00350 child++; 00351 } 00352 /* pick larger child */ 00353 if (CompareFunc(temp , pArr[child - 1])) 00354 { 00355 /* move child up */ 00356 pArr[k - 1] = pArr[child - 1]; 00357 k = child; 00358 } 00359 else 00360 { 00361 break; 00362 } 00363 } 00364 pArr[k - 1] = temp; 00365 } /*downHeap*/ 00366 00367 void swap(int index0,int index1) 00368 { 00369 #ifdef BT_USE_MEMCPY 00370 char temp[sizeof(T)]; 00371 memcpy(temp,&m_data[index0],sizeof(T)); 00372 memcpy(&m_data[index0],&m_data[index1],sizeof(T)); 00373 memcpy(&m_data[index1],temp,sizeof(T)); 00374 #else 00375 T temp = m_data[index0]; 00376 m_data[index0] = m_data[index1]; 00377 m_data[index1] = temp; 00378 #endif //BT_USE_PLACEMENT_NEW 00379 00380 } 00381 00382 template <typename L> 00383 void heapSort(L CompareFunc) 00384 { 00385 /* sort a[0..N-1], N.B. 0 to N-1 */ 00386 int k; 00387 int n = m_size; 00388 for (k = n/2; k > 0; k--) 00389 { 00390 downHeap(m_data, k, n, CompareFunc); 00391 } 00392 00393 /* a[1..N] is now a heap */ 00394 while ( n>=1 ) 00395 { 00396 swap(0,n-1); /* largest of a[0..n-1] */ 00397 00398 00399 n = n - 1; 00400 /* restore a[1..i-1] heap */ 00401 downHeap(m_data, 1, n, CompareFunc); 00402 } 00403 } 00404 00406 int findBinarySearch(const T& key) const 00407 { 00408 int first = 0; 00409 int last = size()-1; 00410 00411 //assume sorted array 00412 while (first <= last) { 00413 int mid = (first + last) / 2; // compute mid point. 00414 if (key > m_data[mid]) 00415 first = mid + 1; // repeat search in top half. 00416 else if (key < m_data[mid]) 00417 last = mid - 1; // repeat search in bottom half. 00418 else 00419 return mid; // found it. return position ///// 00420 } 00421 return size(); // failed to find key 00422 } 00423 00424 00425 int findLinearSearch(const T& key) const 00426 { 00427 int index=size(); 00428 int i; 00429 00430 for (i=0;i<size();i++) 00431 { 00432 if (m_data[i] == key) 00433 { 00434 index = i; 00435 break; 00436 } 00437 } 00438 return index; 00439 } 00440 00441 void remove(const T& key) 00442 { 00443 00444 int findIndex = findLinearSearch(key); 00445 if (findIndex<size()) 00446 { 00447 swap( findIndex,size()-1); 00448 pop_back(); 00449 } 00450 } 00451 00452 //PCK: whole function 00453 void initializeFromBuffer(void *buffer, int size, int capacity) 00454 { 00455 clear(); 00456 m_ownsMemory = false; 00457 m_data = (T*)buffer; 00458 m_size = size; 00459 m_capacity = capacity; 00460 } 00461 00462 void copyFromArray(const btAlignedObjectArray& otherArray) 00463 { 00464 int otherSize = otherArray.size(); 00465 resize (otherSize); 00466 otherArray.copy(0, otherSize, m_data); 00467 } 00468 00469 }; 00470 00471 #endif //BT_OBJECT_ARRAY__