Пример #1
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]);
        }