Beispiel #1
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();
     }
 }
Beispiel #2
0
        public virtual void GetBroadphaseAabb(out IndexedVector3 aabbMin, out IndexedVector3 aabbMax)
        {
            DbvtAabbMm bounds = new DbvtAabbMm();

            if (!m_sets[0].Empty())
            {
                if (!m_sets[1].Empty())
                {
                    DbvtAabbMm.Merge(ref m_sets[0].m_root.volume, ref m_sets[1].m_root.volume, ref bounds);
                }
                else
                {
                    bounds = m_sets[0].m_root.volume;
                }
            }
            else if (!m_sets[1].Empty())
            {
                bounds = m_sets[1].m_root.volume;
            }
            else
            {
                IndexedVector3 temp = IndexedVector3.Zero;
                bounds = DbvtAabbMm.FromCR(ref temp, 0);
            }
            aabbMin = bounds.Mins();
            aabbMax = bounds.Maxs();
        }
Beispiel #3
0
        //
        public static DbvtAabbMm Bounds(ObjectArray <DbvtNode> leafs)
        {
            DbvtAabbMm volume = leafs[0].volume;

            for (int i = 1, ni = leafs.Count; i < ni; ++i)
            {
                DbvtAabbMm.Merge(ref volume, ref leafs[i].volume, ref volume);
            }
            return(volume);
        }
Beispiel #4
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 #5
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 #6
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);
         }
     }
 }