Blender V2.61 - r43446

btUnionFind.h

Go to the documentation of this file.
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 #ifndef UNION_FIND_H
00017 #define UNION_FIND_H
00018 
00019 #include "LinearMath/btAlignedObjectArray.h"
00020 
00021 #define USE_PATH_COMPRESSION 1
00022 
00024 #define STATIC_SIMULATION_ISLAND_OPTIMIZATION 1
00025 
00026 struct  btElement
00027 {
00028     int m_id;
00029     int m_sz;
00030 };
00031 
00033 // Implements weighted Quick Union with path compression
00034 // optimization: could use short ints instead of ints (halving memory, would limit the number of rigid bodies to 64k, sounds reasonable)
00035 class btUnionFind
00036   {
00037     private:
00038         btAlignedObjectArray<btElement> m_elements;
00039 
00040     public:
00041       
00042         btUnionFind();
00043         ~btUnionFind();
00044 
00045     
00046         //this is a special operation, destroying the content of btUnionFind.
00047         //it sorts the elements, based on island id, in order to make it easy to iterate over islands
00048         void    sortIslands();
00049 
00050       void  reset(int N);
00051 
00052       SIMD_FORCE_INLINE int getNumElements() const
00053       {
00054           return int(m_elements.size());
00055       }
00056       SIMD_FORCE_INLINE bool  isRoot(int x) const
00057       {
00058           return (x == m_elements[x].m_id);
00059       }
00060 
00061       btElement&    getElement(int index)
00062       {
00063           return m_elements[index];
00064       }
00065       const btElement& getElement(int index) const
00066       {
00067           return m_elements[index];
00068       }
00069    
00070       void  allocate(int N);
00071       void  Free();
00072 
00073 
00074 
00075 
00076       int find(int p, int q)
00077         { 
00078             return (find(p) == find(q)); 
00079         }
00080 
00081         void unite(int p, int q)
00082         {
00083             int i = find(p), j = find(q);
00084             if (i == j) 
00085                 return;
00086 
00087 #ifndef USE_PATH_COMPRESSION
00088             //weighted quick union, this keeps the 'trees' balanced, and keeps performance of unite O( log(n) )
00089             if (m_elements[i].m_sz < m_elements[j].m_sz)
00090             { 
00091                 m_elements[i].m_id = j; m_elements[j].m_sz += m_elements[i].m_sz; 
00092             }
00093             else 
00094             { 
00095                 m_elements[j].m_id = i; m_elements[i].m_sz += m_elements[j].m_sz; 
00096             }
00097 #else
00098             m_elements[i].m_id = j; m_elements[j].m_sz += m_elements[i].m_sz; 
00099 #endif //USE_PATH_COMPRESSION
00100         }
00101 
00102         int find(int x)
00103         { 
00104             //btAssert(x < m_N);
00105             //btAssert(x >= 0);
00106 
00107             while (x != m_elements[x].m_id) 
00108             {
00109         //not really a reason not to use path compression, and it flattens the trees/improves find performance dramatically
00110     
00111         #ifdef USE_PATH_COMPRESSION
00112                 const btElement* elementPtr = &m_elements[m_elements[x].m_id];
00113                 m_elements[x].m_id = elementPtr->m_id;
00114                 x = elementPtr->m_id;           
00115         #else//
00116                 x = m_elements[x].m_id;
00117         #endif      
00118                 //btAssert(x < m_N);
00119                 //btAssert(x >= 0);
00120 
00121             }
00122             return x; 
00123         }
00124 
00125 
00126   };
00127 
00128 
00129 #endif //UNION_FIND_H