Example #1
0
        private static Node createnode(Dbvt pdbvt, Node parent, DbvtAabbMm volume, DbvtProxy data)
        {
            Node node = new Node();

            node.parent = parent;
            node.volume = volume;
            node.data   = data;
            node.height = 0;
            return(node);
        }
Example #2
0
        public VFixedPoint predictedframes;                        // Frames predicted

        public DbvtBroadphase(OverlappingPairCache paircache)
        {
            predictedframes = VFixedPoint.Two;
            this.paircache  = paircache != null ? paircache : new HashedOverlappingPairCache();
            for (int i = 0; i < STAGECOUNT; i++)
            {
                sets[i]       = new Dbvt();
                stageRoots[i] = null;
            }
        }
Example #3
0
 private static void deletenode(Dbvt pdbvt, Node node)
 {
     node.childs[0] = null;
     node.childs[1] = null;
     node.data      = null;
     node.parent    = null;
     node.volume    = null;
     node.height    = -1;
     pdbvt.leaves--;
 }
Example #4
0
        private static void insertleaf(Dbvt pdbvt, Node leaf)
        {
            if (pdbvt.root == null)
            {
                pdbvt.root  = leaf;
                leaf.parent = null;
            }
            else
            {
                Node node = pdbvt.root;
                while (!node.isleaf())
                {
                    if (DbvtAabbMm.Proximity(node.childs[0].volume, leaf.volume) <
                        DbvtAabbMm.Proximity(node.childs[1].volume, leaf.volume))
                    {
                        node = node.childs[0];
                    }
                    else
                    {
                        node = node.childs[1];
                    }
                }
                Node sibling   = node;
                Node oldParent = node.parent;
                Node newParent = createnode(pdbvt, oldParent, merge(leaf.volume, sibling.volume, new DbvtAabbMm()), null);
                if (oldParent != null)
                {
                    oldParent.childs[indexof(sibling)] = newParent;
                    newParent.childs[0] = sibling;
                    newParent.childs[1] = leaf;
                    sibling.parent      = newParent;
                    leaf.parent         = newParent;
                }
                else
                {
                    newParent.childs[0] = sibling;
                    newParent.childs[1] = leaf;
                    sibling.parent      = newParent;
                    leaf.parent         = newParent;
                    pdbvt.root          = newParent;
                }

                node = leaf.parent;
                while (node != null)
                {
                    node = Balance(pdbvt, node);
                    Node child0 = node.childs[0];
                    Node child1 = node.childs[1];
                    node.height = Math.Max(child0.height, child1.height) + 1;
                    node.volume = merge(child0.volume, child1.volume, new DbvtAabbMm());
                    node        = node.parent;
                }
            }
        }
Example #5
0
 private static void recursedeletenode(Dbvt pdbvt, Node node)
 {
     if (!node.isleaf())
     {
         recursedeletenode(pdbvt, node.childs[0]);
         recursedeletenode(pdbvt, node.childs[1]);
     }
     if (node == pdbvt.root)
     {
         pdbvt.root = null;
     }
     deletenode(pdbvt, node);
 }
Example #6
0
        public void collide(Dispatcher dispatcher)
        {
            DbvtTreeCollider collider = new DbvtTreeCollider(this);

            //collide dynamics:
            {
                Dbvt.collideTT(sets[DYNAMIC_SET].root, sets[FIXED_SET].root, dispatcher, collider);
                Dbvt.collideTT(sets[DYNAMIC_SET].root, sets[DYNAMIC_SET].root, dispatcher, collider);
            }

            //dynamic -> fixed set:
            DbvtProxy current = stageRoots[DYNAMIC_SET];

            while (current != null)
            {
                stageRoots[DYNAMIC_SET] = listremove(current, stageRoots[DYNAMIC_SET]);
                stageRoots[FIXED_SET]   = listappend(current, stageRoots[FIXED_SET]);
                DbvtAabbMm volume = current.leaf.volume;
                sets[DYNAMIC_SET].remove(current.leaf);
                current.leaf  = sets[FIXED_SET].insert(volume, current);
                current.stage = FIXED_SET;
                current       = stageRoots[DYNAMIC_SET];
            }


            // clean up:
            {
                List <BroadphasePair> pairs = paircache.getOverlappingPairArray();
                if (pairs.Count > 0)
                {
                    for (int i = 0, ni = pairs.Count; i < ni; i++)
                    {
                        BroadphasePair p  = pairs[i];
                        DbvtProxy      pa = (DbvtProxy)p.pProxy0;
                        DbvtProxy      pb = (DbvtProxy)p.pProxy1;
                        if (!DbvtAabbMm.Intersect(pa.leaf.volume, pb.leaf.volume))
                        {
                            if (pa.getUid() > pb.getUid())
                            {
                                DbvtProxy tmp = pa;
                                pa = pb;
                                pb = tmp;
                            }
                            paircache.removeOverlappingPair(pa, pb);
                            ni--;
                            i--;
                        }
                    }
                }
            }
        }
Example #7
0
        private static void removeleaf(Dbvt pdbvt, Node leaf)
        {
            if (leaf == pdbvt.root)
            {
                pdbvt.root = null;
                return;
            }
            else
            {
                Node parent      = leaf.parent;
                Node grandParent = parent != null ? parent.parent : null;
                Node sibling     = parent.childs[1 - indexof(leaf)];
                if (grandParent != null)
                {
                    grandParent.childs[indexof(parent)] = sibling;
                    sibling.parent = grandParent;
                    deletenode(pdbvt, parent);

                    Node node = grandParent;
                    while (node != null)
                    {
                        node = Balance(pdbvt, node);
                        Node child0 = node.childs[0];
                        Node child1 = node.childs[1];
                        node.height = Math.Max(child0.height, child1.height) + 1;
                        node.volume = merge(child0.volume, child1.volume, new DbvtAabbMm());
                        node        = node.parent;
                    }
                }
                else
                {
                    pdbvt.root     = sibling;
                    sibling.parent = null;
                    deletenode(pdbvt, parent);
                }
            }
        }
Example #8
0
        private static Node Balance(Dbvt pdbvt, Node A)
        {
            if (A.isleaf() || A.height < 2)
            {
                return(A);
            }

            Node B = A.childs[0];
            Node C = A.childs[1];

            int balance = C.height - B.height;

            if (balance > 1)
            {
                Node F = C.childs[0];
                Node G = C.childs[1];

                // Swap A and C
                C.childs[0] = A;
                C.parent    = A.parent;
                // A's old parent should point to C
                if (A.parent != null)
                {
                    A.parent.childs[indexof(A)] = C;
                }
                else
                {
                    pdbvt.root = C;
                }
                A.parent = C;

                // Rotate
                if (F.height > G.height)
                {
                    C.childs[1] = F;
                    A.childs[1] = G;
                    G.parent    = A;
                    A.volume    = merge(B.volume, G.volume, new DbvtAabbMm());
                    C.volume    = merge(A.volume, F.volume, new DbvtAabbMm());

                    A.height = 1 + Math.Max(B.height, G.height);
                    C.height = 1 + Math.Max(A.height, F.height);
                }
                else
                {
                    C.childs[1] = G;
                    A.childs[1] = F;
                    F.parent    = A;
                    A.volume    = merge(B.volume, F.volume, new DbvtAabbMm());
                    C.volume    = merge(A.volume, G.volume, new DbvtAabbMm());

                    A.height = 1 + Math.Max(B.height, F.height);
                    C.height = 1 + Math.Max(A.height, G.height);
                }

                return(C);
            }

            if (balance < -1)
            {
                Node D = B.childs[0];
                Node E = B.childs[1];

                // Swap A andB
                B.childs[0] = A;
                B.parent    = A.parent;
                // A's old parent should point to B
                if (A.parent != null)
                {
                    A.parent.childs[indexof(A)] = B;
                }
                else
                {
                    pdbvt.root = B;
                }
                A.parent = B;

                // Rotate
                if (D.height > E.height)
                {
                    B.childs[1] = D;
                    A.childs[0] = E;
                    E.parent    = A;
                    A.volume    = merge(C.volume, E.volume, new DbvtAabbMm());
                    B.volume    = merge(A.volume, D.volume, new DbvtAabbMm());

                    A.height = 1 + Math.Max(C.height, E.height);
                    B.height = 1 + Math.Max(A.height, D.height);
                }
                else
                {
                    B.childs[1] = E;
                    A.childs[0] = D;
                    D.parent    = A;
                    A.volume    = merge(C.volume, D.volume, new DbvtAabbMm());
                    B.volume    = merge(A.volume, E.volume, new DbvtAabbMm());

                    A.height = 1 + Math.Max(C.height, D.height);
                    B.height = 1 + Math.Max(A.height, E.height);
                }

                return(B);
            }

            return(A);
        }