Beispiel #1
0
 public static void DeleteNode(Dbvt pdbvt, DbvtNode node)
 {
     //btAlignedFree(pdbvt.m_free);
     //pdbvt.m_free = node;
     node.Reset();
     BulletGlobals.DbvtNodePool.Free(node);
 }
        public DbvtBroadphase(IOverlappingPairCache paircache)
        {
            m_sets[0] = new Dbvt();
            m_sets[1] = new Dbvt();

            m_deferedcollide   = false;
            m_needcleanup      = true;
            m_releasepaircache = (paircache != null) ? false : true;
            m_prediction       = 0;
            m_stageCurrent     = 0;
            m_fixedleft        = 0;
            m_fupdates         = 1;
            m_dupdates         = 0;
            m_cupdates         = 10;
            m_newpairs         = 1;
            m_updates_call     = 0;
            m_updates_done     = 0;
            m_updates_ratio    = 0;
            m_paircache        = paircache != null ? paircache : new HashedOverlappingPairCache();
            m_gid = 0;
            m_pid = 0;
            m_cid = 0;
#if DBVT_BP_PROFILE
            m_profiling = new ProfileBlock();
            m_profiling.clear();
#endif
        }
Beispiel #3
0
 //
 public static void BottomUp(Dbvt pdbvt, ObjectArray <DbvtNode> leaves)
 {
     while (leaves.Count > 1)
     {
         float minsize = float.MaxValue;
         int[] minidx  = { -1, -1 };
         for (int i = 0; i < leaves.Count; ++i)
         {
             for (int j = i + 1; j < leaves.Count; ++j)
             {
                 DbvtAabbMm mergeResults = DbvtAabbMm.Merge(ref leaves[i].volume, ref leaves[j].volume);
                 float      sz           = Size(ref mergeResults);
                 if (sz < minsize)
                 {
                     minsize   = sz;
                     minidx[0] = i;
                     minidx[1] = j;
                 }
             }
         }
         DbvtNode[] n = { leaves[minidx[0]], leaves[minidx[1]] };
         DbvtNode   p = CreateNode(pdbvt, null, ref n[0].volume, ref n[1].volume, null);
         p._children[0]    = n[0];
         p._children[1]    = n[1];
         n[0].parent       = p;
         n[1].parent       = p;
         leaves[minidx[0]] = p;
         leaves.Swap(minidx[1], leaves.Count - 1);
         leaves.PopBack();
     }
 }
        public virtual void AabbTest(ref IndexedVector3 aabbMin, ref IndexedVector3 aabbMax, IBroadphaseAabbCallback aabbCallback)
        {
            BroadphaseAabbTester callback = new BroadphaseAabbTester(aabbCallback);
            DbvtAabbMm           bounds   = DbvtAabbMm.FromMM(ref aabbMin, ref aabbMax);

            Dbvt.CollideTV(m_sets[0].m_root, ref bounds, callback);
            Dbvt.CollideTV(m_sets[1].m_root, ref bounds, callback);
        }
Beispiel #5
0
        //
        public static DbvtNode CreateNode(Dbvt pdbvt,
                                          DbvtNode parent,
                                          ref DbvtAabbMm volume,
                                          Object data)
        {
            DbvtNode node = CreateNode(pdbvt, parent, data);

            node.volume = volume;
            return(node);
        }
Beispiel #6
0
        public static DbvtNode CreateNode(Dbvt pdbvt, DbvtNode parent, int data)
        {
            DbvtNode node = BulletGlobals.DbvtNodePool.Get();

            node.parent       = parent;
            node.data         = null;
            node.dataAsInt    = data;
            node._children[0] = null;
            node._children[1] = null;
            return(node);
        }
Beispiel #7
0
 public DbvtNode(Dbvt tree, DbvtNode aparent, ref DbvtAabbMm avolume, Object adata)
     : this()
 {
     volume = avolume;
     parent = aparent;
     data   = adata;
     if (data is int)
     {
         dataAsInt = (int)data;
     }
 }
Beispiel #8
0
        //
        public static DbvtNode CreateNode(Dbvt pdbvt,
                                          DbvtNode parent,
                                          ref DbvtAabbMm volume0,
                                          ref DbvtAabbMm volume1,
                                          Object data)
        {
            DbvtNode node = CreateNode(pdbvt, parent, data);

            DbvtAabbMm.Merge(ref volume0, ref volume1, ref node.volume);
            return(node);
        }
Beispiel #9
0
        public static void InsertLeaf(Dbvt pdbvt, DbvtNode root, DbvtNode leaf)
        {
            if (pdbvt.Root == null)
            {
                pdbvt.Root  = leaf;
                leaf.parent = null;
            }
            else
            {
                if (!root.IsLeaf())
                {
                    do
                    {
                        root = root._children[DbvtAabbMm.Select(ref leaf.volume,
                                                                ref root._children[0].volume,
                                                                ref root._children[1].volume)];
                    } while (!root.IsLeaf());
                }
                DbvtNode   prev         = root.parent;
                DbvtAabbMm mergeResults = DbvtAabbMm.Merge(ref leaf.volume, ref root.volume);

                DbvtNode node = CreateNode2(pdbvt, prev, ref mergeResults, null);
                if (prev != null)
                {
                    prev._children[IndexOf(root)] = node;
                    node._children[0]             = root;
                    root.parent       = node;
                    node._children[1] = leaf;
                    leaf.parent       = node;
                    do
                    {
                        if (!prev.volume.Contain(ref node.volume))
                        {
                            DbvtAabbMm.Merge(ref prev._children[0].volume, ref prev._children[1].volume, ref prev.volume);
                        }
                        else
                        {
                            break;
                        }
                        node = prev;
                    } while (null != (prev = node.parent));
                }
                else
                {
                    node._children[0] = root;
                    root.parent       = node;
                    node._children[1] = leaf;
                    leaf.parent       = node;
                    pdbvt.Root        = node;
                }
            }
        }
Beispiel #10
0
 public static void FetchLeafs(Dbvt pdbvt, DbvtNode root, ObjectArray <DbvtNode> leafs, int depth)
 {
     if (root.IsInternal() && depth != 0)
     {
         FetchLeafs(pdbvt, root._children[0], leafs, depth - 1);
         FetchLeafs(pdbvt, root._children[1], leafs, depth - 1);
         DeleteNode(pdbvt, root);
     }
     else
     {
         leafs.Add(root);
     }
 }
Beispiel #11
0
 public static void RecurseDeleteNode(Dbvt pdbvt, DbvtNode node)
 {
     if (!node.IsLeaf())
     {
         RecurseDeleteNode(pdbvt, node._children[0]);
         RecurseDeleteNode(pdbvt, node._children[1]);
     }
     if (node == pdbvt.m_root)
     {
         pdbvt.m_root = null;
     }
     DeleteNode(pdbvt, node);
 }
 public CompoundShape(bool enableDynamicAabbTree)
 {
     m_children        = new ObjectArray <CompoundShapeChild>();
     m_localAabbMax    = new IndexedVector3(float.MinValue);
     m_localAabbMin    = new IndexedVector3(float.MaxValue);
     m_collisionMargin = 0f;
     m_localScaling    = new IndexedVector3(1f);
     m_dynamicAabbTree = null;
     m_updateRevision  = 1;
     m_shapeType       = BroadphaseNativeTypes.COMPOUND_SHAPE_PROXYTYPE;
     if (enableDynamicAabbTree)
     {
         m_dynamicAabbTree = new Dbvt();
     }
 }
Beispiel #13
0
        public static DbvtNode CreateNode(Dbvt pdbvt, DbvtNode parent, Object data)
        {
            DbvtNode node = BulletGlobals.DbvtNodePool.Get();

            node.parent = parent;
            node.data   = data;
            if (node.data is int)
            {
                //Debug.Assert(false);
                node.dataAsInt = (int)node.data;
            }
            node._children[0] = null;
            node._children[1] = null;
            return(node);
        }
Beispiel #14
0
        public static DbvtNode CreateNode2(Dbvt tree, DbvtNode aparent, ref DbvtAabbMm avolume, Object adata)
        {
            DbvtNode node = BulletGlobals.DbvtNodePool.Get();

            node.volume       = avolume;
            node.parent       = aparent;
            node.data         = adata;
            node._children[0] = null;
            node._children[1] = null;

            if (node.data is int)
            {
                Debug.Assert(false);
                node.dataAsInt = (int)node.data;
            }

            return(node);
        }
        public void CreateAabbTreeFromChildren()
        {
            if (m_dynamicAabbTree == null)
            {
                m_dynamicAabbTree = new Dbvt();

                for (int index = 0; index < m_children.Count; index++)
                {
                    CompoundShapeChild child = m_children[index];

                    //extend the local aabbMin/aabbMax
                    IndexedVector3 localAabbMin, localAabbMax;
                    child.m_childShape.GetAabb(ref child.m_transform, out localAabbMin, out localAabbMax);

                    DbvtAabbMm bounds = DbvtAabbMm.FromMM(ref localAabbMin, ref localAabbMax);
                    child.m_treeNode = m_dynamicAabbTree.Insert(ref bounds, (object)index);
                }
            }
        }
Beispiel #16
0
 public static DbvtNode RemoveLeaf(Dbvt pdbvt, DbvtNode leaf)
 {
     if (leaf == pdbvt.Root)
     {
         pdbvt.Root = null;
         return(null);
     }
     else
     {
         DbvtNode parent  = leaf.parent;
         DbvtNode prev    = parent.parent;
         DbvtNode sibling = parent._children[1 - IndexOf(leaf)];
         if (prev != null)
         {
             prev._children[IndexOf(parent)] = sibling;
             sibling.parent = prev;
             DeleteNode(pdbvt, parent);
             while (prev != null)
             {
                 DbvtAabbMm pb = prev.volume;
                 DbvtAabbMm.Merge(ref prev._children[0].volume, ref prev._children[1].volume, ref prev.volume);
                 if (DbvtAabbMm.NotEqual(ref pb, ref prev.volume))
                 {
                     sibling = prev;
                     prev    = prev.parent;
                 }
                 else
                 {
                     break;
                 }
             }
             return(prev != null ? prev : pdbvt.Root);
         }
         else
         {
             pdbvt.Root     = sibling;
             sibling.parent = null;
             DeleteNode(pdbvt, parent);
             return(pdbvt.Root);
         }
     }
 }
        public virtual BroadphaseProxy CreateProxy(ref IndexedVector3 aabbMin, ref IndexedVector3 aabbMax, BroadphaseNativeTypes shapeType, Object userPtr, CollisionFilterGroups collisionFilterGroup, CollisionFilterGroups collisionFilterMask, IDispatcher dispatcher, Object multiSapProxy)
        {
            DbvtProxy proxy = new DbvtProxy(ref aabbMin, ref aabbMax, userPtr, collisionFilterGroup, collisionFilterMask);

            DbvtAabbMm aabb = DbvtAabbMm.FromMM(ref aabbMin, ref aabbMax);

            //bproxy.aabb			=	btDbvtAabbMm::FromMM(aabbMin,aabbMax);
            proxy.stage      = m_stageCurrent;
            proxy.m_uniqueId = ++m_gid;
            proxy.leaf       = m_sets[0].Insert(ref aabb, proxy);
            ListAppend(proxy, ref m_stageRoots[m_stageCurrent]);
            if (!m_deferedcollide)
            {
                DbvtTreeCollider collider = BulletGlobals.DbvtTreeColliderPool.Get();
                collider.Initialize(this);
                collider.proxy = proxy;
                Dbvt.CollideTV(m_sets[0].m_root, ref aabb, collider);
                Dbvt.CollideTV(m_sets[1].m_root, ref aabb, collider);
                BulletGlobals.DbvtTreeColliderPool.Free(collider);
            }
            return(proxy);
        }
        ///this setAabbForceUpdate is similar to setAabb but always forces the aabb update.
        ///it is not part of the btBroadphaseInterface but specific to btDbvtBroadphase.
        ///it bypasses certain optimizations that prevent aabb updates (when the aabb shrinks), see
        ///http://code.google.com/p/bullet/issues/detail?id=223
        public void SetAabbForceUpdate(BroadphaseProxy absproxy, ref IndexedVector3 aabbMin, ref IndexedVector3 aabbMax, IDispatcher dispatcher)
        {
            DbvtProxy  proxy     = absproxy as DbvtProxy;
            DbvtAabbMm bounds    = DbvtAabbMm.FromMM(ref aabbMin, ref aabbMax);
            bool       docollide = false;

            if (proxy.stage == STAGECOUNT)
            {/* fixed . dynamic set	*/
                m_sets[1].Remove(proxy.leaf);
                proxy.leaf = m_sets[0].Insert(ref bounds, proxy);
                docollide  = true;
            }
            else
            {/* dynamic set				*/
                ++m_updates_call;
                /* Teleporting			*/
                m_sets[0].Update(proxy.leaf, ref bounds);
                ++m_updates_done;
                docollide = true;
            }
            ListRemove(proxy, ref m_stageRoots[proxy.stage]);
            proxy.m_aabbMin = aabbMin;
            proxy.m_aabbMax = aabbMax;
            proxy.stage     = m_stageCurrent;
            ListAppend(proxy, ref m_stageRoots[m_stageCurrent]);
            if (docollide)
            {
                m_needcleanup = true;
                if (!m_deferedcollide)
                {
                    DbvtTreeCollider collider = BulletGlobals.DbvtTreeColliderPool.Get();
                    collider.Initialize(this);
                    Dbvt.CollideTTpersistentStack(m_sets[1].m_root, proxy.leaf, collider);
                    Dbvt.CollideTTpersistentStack(m_sets[0].m_root, proxy.leaf, collider);
                    BulletGlobals.DbvtTreeColliderPool.Free(collider);
                }
            }
        }
        public void Collide(IDispatcher dispatcher)
        {
            BulletGlobals.StartProfile("BroadphaseCollide");
            //SPC(m_profiling.m_total);
            /* optimize				*/
            m_sets[0].OptimizeIncremental(1 + (m_sets[0].m_leaves * m_dupdates) / 100);
            if (m_fixedleft > 0)
            {
                int count = 1 + (m_sets[1].m_leaves * m_fupdates) / 100;
                m_sets[1].OptimizeIncremental(1 + (m_sets[1].m_leaves * m_fupdates) / 100);
                m_fixedleft = Math.Max(0, m_fixedleft - count);
            }
            /* dynamic . fixed set	*/
            m_stageCurrent = (m_stageCurrent + 1) % STAGECOUNT;

            DbvtProxy current = m_stageRoots[m_stageCurrent];

            if (current != null)
            {
                DbvtTreeCollider collider = BulletGlobals.DbvtTreeColliderPool.Get();
                collider.Initialize(this);
                do
                {
                    DbvtProxy next = current.links[1];
                    ListRemove(current, ref m_stageRoots[current.stage]);
                    ListAppend(current, ref m_stageRoots[STAGECOUNT]);
#if DBVT_BP_ACCURATESLEEPING
                    m_paircache.removeOverlappingPairsContainingProxy(current, dispatcher);
                    collider.proxy = current;
                    btDbvt::collideTV(m_sets[0].m_root, current.aabb, collider);
                    btDbvt::collideTV(m_sets[1].m_root, current.aabb, collider);
#endif
                    m_sets[0].Remove(current.leaf);
                    DbvtAabbMm curAabb = DbvtAabbMm.FromMM(ref current.m_aabbMin, ref current.m_aabbMax);
                    current.leaf  = m_sets[1].Insert(ref curAabb, current);
                    current.stage = STAGECOUNT;
                    current       = next;
                } while (current != null);
                m_fixedleft = m_sets[1].m_leaves;
                BulletGlobals.DbvtTreeColliderPool.Free(collider);
                m_needcleanup = true;
            }
            /* collide dynamics		*/
            {
                DbvtTreeCollider collider = BulletGlobals.DbvtTreeColliderPool.Get();
                collider.Initialize(this);
                if (m_deferedcollide)
                {
                    //Stopwatch fdCollideStopwatch = new Stopwatch();
                    //fdCollideStopwatch.Start();
                    //SPC(m_profiling.m_fdcollide);
                    Dbvt.CollideTTpersistentStack(m_sets[0].m_root, m_sets[1].m_root, collider);
                    //fdCollideStopwatch.Stop();
                    //m_profiling.m_fdcollide += (ulong)fdCollideStopwatch.ElapsedMilliseconds;
                }
                if (m_deferedcollide)
                {
                    //Stopwatch ddCollideStopwatch = new Stopwatch();
                    //ddCollideStopwatch.Start();
                    //SPC(m_profiling.m_ddcollide);
                    Dbvt.CollideTTpersistentStack(m_sets[0].m_root, m_sets[0].m_root, collider);
                    //ddCollideStopwatch.Stop();
                    //m_profiling.m_ddcollide += (ulong)ddCollideStopwatch.ElapsedMilliseconds;
                }
                BulletGlobals.DbvtTreeColliderPool.Free(collider);
            }
            /* clean up				*/
            if (m_needcleanup)
            {
                Stopwatch cleanupStopwatch = new Stopwatch();
                cleanupStopwatch.Start();
                //SPC(m_profiling.m_cleanup);
                IList <BroadphasePair> pairs = m_paircache.GetOverlappingPairArray();
                if (pairs.Count > 0)
                {
                    int ni = Math.Min(pairs.Count, Math.Max(m_newpairs, (pairs.Count * m_cupdates) / 100));
                    for (int i = 0; i < ni; ++i)
                    {
                        BroadphasePair p  = pairs[(m_cid + i) % pairs.Count];
                        DbvtProxy      pa = p.m_pProxy0 as DbvtProxy;
                        DbvtProxy      pb = p.m_pProxy1 as DbvtProxy;
                        if (!DbvtAabbMm.Intersect(ref pa.leaf.volume, ref pb.leaf.volume))
                        {
#if DBVT_BP_SORTPAIRS
                            if (pa.m_uniqueId > pb.m_uniqueId)
                            {
                                btSwap(pa, pb);
                            }
#endif
                            m_paircache.RemoveOverlappingPair(pa, pb, dispatcher);
                            --ni; --i;
                        }
                    }
                    if (pairs.Count > 0)
                    {
                        m_cid = (m_cid + ni) % pairs.Count;
                    }
                    else
                    {
                        m_cid = 0;
                    }
                }
                cleanupStopwatch.Stop();
                //m_profiling.m_cleanup += (ulong)cleanupStopwatch.ElapsedMilliseconds;
            }
            ++m_pid;
            m_newpairs    = 1;
            m_needcleanup = false;
            if (m_updates_call > 0)
            {
                m_updates_ratio = m_updates_done / (float)m_updates_call;
            }
            else
            {
                m_updates_ratio = 0;
            }
            m_updates_done /= 2;
            m_updates_call /= 2;

            BulletGlobals.StopProfile();
        }
        public virtual void SetAabb(BroadphaseProxy absproxy, ref IndexedVector3 aabbMin, ref IndexedVector3 aabbMax, IDispatcher dispatcher)
        {
            DbvtProxy  proxy = absproxy as DbvtProxy;
            DbvtAabbMm aabb  = DbvtAabbMm.FromMM(ref aabbMin, ref aabbMax);

#if DBVT_BP_PREVENTFALSEUPDATE
            if (NotEqual(ref aabb, proxy, leaf.volume))
#endif
            {
                bool docollide = false;
                if (proxy.stage == STAGECOUNT)
                {/* fixed . dynamic set	*/
                    m_sets[1].Remove(proxy.leaf);
                    proxy.leaf = m_sets[0].Insert(ref aabb, proxy);
                    docollide  = true;
                }
                else
                {/* dynamic set				*/
                    ++m_updates_call;
                    if (DbvtAabbMm.Intersect(ref proxy.leaf.volume, ref aabb))
                    {/* Moving				*/
                        IndexedVector3 delta    = aabbMin - proxy.m_aabbMin;
                        IndexedVector3 velocity = (((proxy.m_aabbMax - proxy.m_aabbMin) / 2f) * m_prediction);
                        if (delta.X < 0)
                        {
                            velocity.X = -velocity.X;
                        }
                        if (delta.Y < 0)
                        {
                            velocity.Y = -velocity.Y;
                        }
                        if (delta.Z < 0)
                        {
                            velocity.Z = -velocity.Z;
                        }
                        if (
#if DBVT_BP_MARGIN
                            m_sets[0].Update(proxy.leaf, ref aabb, ref velocity, DBVT_BP_MARGIN)
#else
                            m_sets[0].update(proxy.leaf, aabb, ref velocity)
#endif
                            )
                        {
                            ++m_updates_done;
                            docollide = true;
                        }
                    }
                    else
                    {/* Teleporting			*/
                        m_sets[0].Update(proxy.leaf, ref aabb);
                        ++m_updates_done;
                        docollide = true;
                    }
                }
                ListRemove(proxy, ref m_stageRoots[proxy.stage]);
                proxy.m_aabbMin = aabbMin;
                proxy.m_aabbMax = aabbMax;
                proxy.stage     = m_stageCurrent;
                ListAppend(proxy, ref m_stageRoots[m_stageCurrent]);
                if (docollide)
                {
                    m_needcleanup = true;
                    if (!m_deferedcollide)
                    {
                        DbvtTreeCollider collider = BulletGlobals.DbvtTreeColliderPool.Get();
                        collider.Initialize(this);
                        Dbvt.CollideTTpersistentStack(m_sets[1].m_root, proxy.leaf, collider);
                        Dbvt.CollideTTpersistentStack(m_sets[0].m_root, proxy.leaf, collider);
                        BulletGlobals.DbvtTreeColliderPool.Free(collider);
                    }
                }
            }
        }
        public void Visualise()
        {
            DbvtDraw dd = new DbvtDraw();

            Dbvt.EnumNodes(m_sets[0].m_root, dd);
        }
Beispiel #22
0
 //
 // depth is defaulted to -1
 public static void FetchLeafs(Dbvt pdbvt, DbvtNode root, ObjectArray <DbvtNode> leafs)
 {
     FetchLeafs(pdbvt, root, leafs, -1);
 }
Beispiel #23
0
        public static DbvtNode TopDown(Dbvt pdbvt, ObjectArray <DbvtNode> leaves, int bu_treshold)
        {
            if (leaves.Count > 1)
            {
                if (leaves.Count > bu_treshold)
                {
                    DbvtAabbMm               vol  = Bounds(leaves);
                    IndexedVector3           org  = vol.Center();
                    ObjectArray <DbvtNode>[] sets = { new ObjectArray <DbvtNode>(), new ObjectArray <DbvtNode>() };
                    int   bestaxis = -1;
                    int   bestmidp = leaves.Count;
                    int[] a1       = new int[] { 0, 0 };
                    int[] a2       = new int[] { 0, 0 };
                    int[] a3       = new int[] { 0, 0 };

                    int[][] splitcount = new int[][] { a1, a2, a3 };
                    int     i;
                    for (i = 0; i < leaves.Count; ++i)
                    {
                        IndexedVector3 x = leaves[i].volume.Center() - org;
                        for (int j = 0; j < 3; ++j)
                        {
                            ++splitcount[j][IndexedVector3.Dot(x, axis[j]) > 0 ? 1 : 0];
                        }
                    }
                    for (i = 0; i < 3; ++i)
                    {
                        if ((splitcount[i][0] > 0) && (splitcount[i][1] > 0))
                        {
                            int midp = (int)Math.Abs((splitcount[i][0] - splitcount[i][1]));
                            if (midp < bestmidp)
                            {
                                bestaxis = i;
                                bestmidp = midp;
                            }
                        }
                    }
                    if (bestaxis >= 0)
                    {
                        sets[0].EnsureCapacity(splitcount[bestaxis][0]);
                        sets[1].EnsureCapacity(splitcount[bestaxis][1]);
                        Split(leaves, sets[0], sets[1], ref org, ref axis[bestaxis]);
                    }
                    else
                    {
                        sets[0].EnsureCapacity(leaves.Count / 2 + 1);
                        sets[1].EnsureCapacity(leaves.Count / 2);
                        for (int i2 = 0, ni = leaves.Count; i2 < ni; ++i2)
                        {
                            sets[i2 & 1].Add(leaves[i2]);
                        }
                    }
                    DbvtNode node = CreateNode(pdbvt, null, ref vol, null);
                    node._children[0]        = TopDown(pdbvt, sets[0], bu_treshold);
                    node._children[1]        = TopDown(pdbvt, sets[1], bu_treshold);
                    node._children[0].parent = node;
                    node._children[1].parent = node;
                    return(node);
                }
                else
                {
                    BottomUp(pdbvt, leaves);
                    return(leaves[0]);
                }
            }
            return(leaves[0]);
        }
        public override void ProcessCollision(CollisionObject body0, CollisionObject body1, DispatcherInfo dispatchInfo, ManifoldResult resultOut)
        {
            //resultOut = null;
            CollisionObject colObj   = m_isSwapped ? body1 : body0;
            CollisionObject otherObj = m_isSwapped ? body0 : body1;

            Debug.Assert(colObj.GetCollisionShape().IsCompound());
            CompoundShape compoundShape = (CompoundShape)(colObj.GetCollisionShape());

            ///btCompoundShape might have changed:
            ////make sure the internal child collision algorithm caches are still valid
            if (compoundShape.GetUpdateRevision() != m_compoundShapeRevision)
            {
                ///clear and update all
                RemoveChildAlgorithms();
                PreallocateChildAlgorithms(body0, body1);
            }


            Dbvt tree = compoundShape.GetDynamicAabbTree();

            //use a dynamic aabb tree to cull potential child-overlaps
            using (CompoundLeafCallback callback = BulletGlobals.CompoundLeafCallbackPool.Get())
            {
                callback.Initialize(colObj, otherObj, m_dispatcher, dispatchInfo, resultOut, this, m_childCollisionAlgorithms, m_sharedManifold);

                ///we need to refresh all contact manifolds
                ///note that we should actually recursively traverse all children, btCompoundShape can nested more then 1 level deep
                ///so we should add a 'refreshManifolds' in the btCollisionAlgorithm
                {
                    m_manifoldArray.Clear();
                    for (int i = 0; i < m_childCollisionAlgorithms.Count; i++)
                    {
                        if (m_childCollisionAlgorithms[i] != null)
                        {
                            m_childCollisionAlgorithms[i].GetAllContactManifolds(m_manifoldArray);
                            for (int m = 0; m < m_manifoldArray.Count; m++)
                            {
                                if (m_manifoldArray[m].GetNumContacts() > 0)
                                {
                                    resultOut.SetPersistentManifold(m_manifoldArray[m]);
                                    resultOut.RefreshContactPoints();
                                    resultOut.SetPersistentManifold(null);//??necessary?
                                }
                            }
                            m_manifoldArray.Clear();
                        }
                    }
                }

                if (tree != null)
                {
                    IndexedVector3 localAabbMin;
                    IndexedVector3 localAabbMax;
                    IndexedMatrix  otherInCompoundSpace;
                    //otherInCompoundSpace = MathUtil.BulletMatrixMultiply(colObj.GetWorldTransform(),otherObj.GetWorldTransform());
                    otherInCompoundSpace = colObj.GetWorldTransform().Inverse() * otherObj.GetWorldTransform();

                    otherObj.GetCollisionShape().GetAabb(ref otherInCompoundSpace, out localAabbMin, out localAabbMax);

                    DbvtAabbMm bounds = DbvtAabbMm.FromMM(ref localAabbMin, ref localAabbMax);
                    //process all children, that overlap with  the given AABB bounds
                    Dbvt.CollideTV(tree.m_root, ref bounds, callback);
                }
                else
                {
                    //iterate over all children, perform an AABB check inside ProcessChildShape
                    int numChildren = m_childCollisionAlgorithms.Count;
                    for (int i = 0; i < numChildren; i++)
                    {
                        callback.ProcessChildShape(compoundShape.GetChildShape(i), i);
                    }
                }

                {
                    //iterate over all children, perform an AABB check inside ProcessChildShape
                    int numChildren = m_childCollisionAlgorithms.Count;

                    m_manifoldArray.Clear();
                    CollisionShape childShape = null;
                    IndexedMatrix  orgTrans;
                    IndexedMatrix  orgInterpolationTrans;
                    IndexedMatrix  newChildWorldTrans;


                    for (int i = 0; i < numChildren; i++)
                    {
                        if (m_childCollisionAlgorithms[i] != null)
                        {
                            childShape = compoundShape.GetChildShape(i);
                            //if not longer overlapping, remove the algorithm
                            orgTrans = colObj.GetWorldTransform();
                            orgInterpolationTrans = colObj.GetInterpolationWorldTransform();
                            IndexedMatrix childTrans = compoundShape.GetChildTransform(i);

                            newChildWorldTrans = orgTrans * childTrans;

                            //perform an AABB check first
                            IndexedVector3 aabbMin0;
                            IndexedVector3 aabbMax0;
                            IndexedVector3 aabbMin1;
                            IndexedVector3 aabbMax1;

                            childShape.GetAabb(ref newChildWorldTrans, out aabbMin0, out aabbMax0);
                            otherObj.GetCollisionShape().GetAabb(otherObj.GetWorldTransform(), out aabbMin1, out aabbMax1);

                            if (!AabbUtil2.TestAabbAgainstAabb2(ref aabbMin0, ref aabbMax0, ref aabbMin1, ref aabbMax1))
                            {
                                m_dispatcher.FreeCollisionAlgorithm(m_childCollisionAlgorithms[i]);
                                m_childCollisionAlgorithms[i] = null;
                            }
                        }
                    }
                }
            }
        }