Esempio n. 1
0
 private void TestInternals(PureQuadTreeNode leaf, ref ulong[] codes)
 {
     if (leaf.ChildNum == 0)
     {
         if (leaf.Parent.Children[1].Children == null)
         {
             codes[1] = leaf.Parent.Children[1].Code;
         }
         if (leaf.Parent.Children[2].Children == null)
         {
             codes[2] = leaf.Parent.Children[2].Code;
         }
     }
     else if (leaf.ChildNum == 1)
     {
         if (leaf.Parent.Children[0].Children == null)
         {
             codes[0] = leaf.Parent.Children[0].Code;
         }
         if (leaf.Parent.Children[3].Children == null)
         {
             codes[2] = leaf.Parent.Children[3].Code;
         }
     }
     else if (leaf.ChildNum == 2)
     {
         if (leaf.Parent.Children[0].Children == null)
         {
             codes[3] = leaf.Parent.Children[0].Code;
         }
         if (leaf.Parent.Children[3].Children == null)
         {
             codes[1] = leaf.Parent.Children[3].Code;
         }
     }
     else if (leaf.ChildNum == 3)
     {
         if (leaf.Parent.Children[2].Children == null)
         {
             codes[0] = leaf.Parent.Children[2].Code;
         }
         if (leaf.Parent.Children[1].Children == null)
         {
             codes[3] = leaf.Parent.Children[1].Code;
         }
     }
 }
Esempio n. 2
0
        private void DrawChildren(Graphics g, PureQuadTreeNode node)
        {
            if (node.Children != null)
            {
                float halfX = node.Size.X / 2;
                float halfY = node.Size.Y / 2;
                g.DrawLine(Pens.Black, node.Location.X + halfX, node.Location.Y,
                           node.Location.X + halfX, node.Location.Y + node.Size.Y);
                g.DrawLine(Pens.Black, node.Location.X, node.Location.Y + halfY,
                           node.Location.X + node.Size.X, node.Location.Y + halfY);

                for (int i = 0; i < 4; i++)
                {
                    DrawChildren(g, node.Children[i]);
                }
            }
            else
            {
                using (Brush brush = new SolidBrush(Color.FromArgb(255, 0, 0, 152)))
                {
                    g.FillRectangle(brush, node.Location.X + 1, node.Location.Y + 1, node.Size.X - 1, node.Size.Y - 1);
                }
                string debug = "[" + node.Code + "]";
                if (leafPatches.ContainsKey(node.Code))
                {
                    // draw right patches
                    if ((leafPatches[node.Code] & (byte)Directions.Down) > 0)
                    {
                        using (Brush brush = new SolidBrush(Color.FromArgb(255, 111, 49, 152)))
                        {
                            g.FillRectangle(brush, node.Location.X + 1, node.Location.Y + 1, node.Size.X - 1, node.Size.Y / 8);
                        }
                        if (patchCodes[node.Code][2] != ulong.MaxValue)
                        {
                            using (Brush brush = new SolidBrush(Color.FromArgb(255, 64, 49, 96)))
                            {
                                g.FillRectangle(brush, node.Location.X + 1, node.Location.Y + node.Size.Y - (node.Size.Y / 8), node.Size.X - 1, node.Size.Y / 8);
                            }
                        }
                        //debug += "(D=" + patchCodes[node.Code][2] + ")";
                    }
                    else if ((leafPatches[node.Code] & (byte)Directions.Up) > 0)
                    {
                        using (Brush brush = new SolidBrush(Color.FromArgb(255, 111, 49, 152)))
                        {
                            g.FillRectangle(brush, node.Location.X + 1, node.Location.Y + node.Size.Y - (node.Size.Y / 8), node.Size.X - 1, node.Size.Y / 8);
                        }
                        if (patchCodes[node.Code][3] != ulong.MaxValue)
                        {
                            using (Brush brush = new SolidBrush(Color.FromArgb(255, 64, 49, 96)))
                            {
                                g.FillRectangle(brush, node.Location.X + 1, node.Location.Y + 1, node.Size.X - 1, node.Size.Y / 8);
                            }
                        }
                        // += "(U=" + patchCodes[node.Code][3] + ")";
                    }
                    else
                    {
                        if (patchCodes[node.Code][2] != ulong.MaxValue)
                        {
                            using (Brush brush = new SolidBrush(Color.FromArgb(255, 64, 49, 96)))
                            {
                                g.FillRectangle(brush, node.Location.X + 1, node.Location.Y + node.Size.Y - (node.Size.Y / 8), node.Size.X - 1, node.Size.Y / 8);
                            }
                            //debug += "(D=" + patchCodes[node.Code][2] + ")";
                        }
                        if (patchCodes[node.Code][3] != ulong.MaxValue)
                        {
                            using (Brush brush = new SolidBrush(Color.FromArgb(255, 64, 49, 96)))
                            {
                                g.FillRectangle(brush, node.Location.X + 1, node.Location.Y + 1, node.Size.X - 1, node.Size.Y / 8);
                            }
                            //debug += "(U=" + patchCodes[node.Code][3] + ")";
                        }
                    }

                    if ((leafPatches[node.Code] & (byte)Directions.Left) > 0)
                    {
                        using (Brush brush = new SolidBrush(Color.FromArgb(255, 111, 49, 152)))
                        {
                            g.FillRectangle(brush, node.Location.X + 1, node.Location.Y + 1, node.Size.X / 8, node.Size.Y - 1);
                        }
                        if (patchCodes[node.Code][1] != ulong.MaxValue)
                        {
                            using (Brush brush = new SolidBrush(Color.FromArgb(255, 64, 49, 96)))
                            {
                                g.FillRectangle(brush, node.Location.X + node.Size.X - (node.Size.X / 8), node.Location.Y + 1, node.Size.X / 8, node.Size.Y - 1);
                            }
                        }
                    }
                    else if ((leafPatches[node.Code] & (byte)Directions.Right) > 0)
                    {
                        using (Brush brush = new SolidBrush(Color.FromArgb(255, 111, 49, 152)))
                        {
                            g.FillRectangle(brush, node.Location.X + node.Size.X - (node.Size.X / 8), node.Location.Y + 1, node.Size.X / 8, node.Size.Y - 1);
                        }
                        if (patchCodes[node.Code][0] != ulong.MaxValue)
                        {
                            using (Brush brush = new SolidBrush(Color.FromArgb(255, 64, 49, 96)))
                            {
                                g.FillRectangle(brush, node.Location.X + 1, node.Location.Y + 1, node.Size.X / 8, node.Size.Y - 1);
                            }
                        }
                    }
                    else
                    {
                        if (patchCodes[node.Code][1] != ulong.MaxValue)
                        {
                            using (Brush brush = new SolidBrush(Color.FromArgb(255, 64, 49, 96)))
                            {
                                g.FillRectangle(brush, node.Location.X + node.Size.X - (node.Size.X / 8), node.Location.Y + 1, node.Size.X / 8, node.Size.Y - 1);
                            }
                        }
                        if (patchCodes[node.Code][0] != ulong.MaxValue)
                        {
                            using (Brush brush = new SolidBrush(Color.FromArgb(255, 64, 49, 96)))
                            {
                                g.FillRectangle(brush, node.Location.X + 1, node.Location.Y + 1, node.Size.X / 8, node.Size.Y - 1);
                            }
                        }
                    }

                    /*if (patchCodes[node.Code][0] != ulong.MaxValue)
                    *   debug += "L(" + patchCodes[node.Code][0] + ")";
                    *  if (patchCodes[node.Code][1] != ulong.MaxValue)
                    *   debug += "R(" + patchCodes[node.Code][1] + ")";*/
                    if (patchCodes[node.Code][2] != ulong.MaxValue)
                    {
                        debug += "D(" + patchCodes[node.Code][2] + ")";
                    }
                    if (patchCodes[node.Code][3] != ulong.MaxValue)
                    {
                        debug += "U(" + patchCodes[node.Code][3] + ")";
                    }

                    /*if (patchCodes[node.Code][1] != 14)
                     *  g.DrawString(patchCodes[node.Code][0] + "," + patchCodes[node.Code][1], Font, Brushes.Red, (int)node.Location.X, (int)node.Location.Y);
                     * else
                     *  g.DrawString(patchCodes[node.Code][0].ToString(), Font, Brushes.Red, (int)node.Location.X, (int)node.Location.Y);*/
                }
                else if (patchCodes.ContainsKey(node.Code))
                {
                    // just internal patches
                    if (patchCodes[node.Code][2] != ulong.MaxValue)
                    {
                        using (Brush brush = new SolidBrush(Color.FromArgb(255, 64, 49, 96)))
                        {
                            g.FillRectangle(brush, node.Location.X + 1, node.Location.Y + node.Size.Y - (node.Size.Y / 8), node.Size.X - 1, node.Size.Y / 8);
                        }
                    }
                    if (patchCodes[node.Code][3] != ulong.MaxValue)
                    {
                        using (Brush brush = new SolidBrush(Color.FromArgb(255, 64, 49, 96)))
                        {
                            g.FillRectangle(brush, node.Location.X + 1, node.Location.Y + 1, node.Size.X - 1, node.Size.Y / 8);
                        }
                    }
                    if (patchCodes[node.Code][1] != ulong.MaxValue)
                    {
                        using (Brush brush = new SolidBrush(Color.FromArgb(255, 64, 49, 96)))
                        {
                            g.FillRectangle(brush, node.Location.X + node.Size.X - (node.Size.X / 8), node.Location.Y + 1, node.Size.X / 8, node.Size.Y - 1);
                        }
                    }
                    if (patchCodes[node.Code][0] != ulong.MaxValue)
                    {
                        using (Brush brush = new SolidBrush(Color.FromArgb(255, 64, 49, 96)))
                        {
                            g.FillRectangle(brush, node.Location.X + 1, node.Location.Y + 1, node.Size.X / 8, node.Size.Y - 1);
                        }
                    }
                }

                Font font = new Font("Verdana", 6);
                g.DrawString(debug, font, Brushes.Orange, (int)node.Location.X, (int)node.Location.Y);
            }
        }
Esempio n. 3
0
        private void BuildNode(PureQuadTreeNode node)
        {
            float levelFalloff = falloff / node.Level;

            // first establish if visible or not by testing centre of node, then corners until visible
            bool visible = (node.Level == 0 || TestPoint(node.Centre) || TestPoint(node.Location) ||
                            TestPoint(new Vector2(node.Location.X + node.Size.X, node.Location.Y)) ||
                            TestPoint(new Vector2(node.Location.X, node.Location.Y + node.Size.Y)) ||
                            TestPoint(new Vector2(node.Location.X + node.Size.X, node.Location.Y + node.Size.Y)));

            // log what detail the leaf is to be, and if visible
            if (visible)
            {
                leafDetail[node.Code] = (short)node.Level;
            }
            else
            {
                leafDetail[node.Code] = (short)-node.Level;
            }

            if (visible)
            {
                // decide if to fork or not
                //Vector2 halfChildSize = node.Size * 0.25f;
                float distance = (node.Centre - viewPos).Length();
                // test this node first directly
                if (distance < levelFalloff)
                {
                    node.Fork(1, false);
                    for (int c = 0; c < 4; c++)
                    {
                        BuildNode(node.Children[c]);
                    }
                }
            }

            //else
            //{
            //    // test children directly
            //    for (int i = 0; i < 4; i++)
            //    {
            //        // check centre distance
            //        Vector2 centre = new Vector2();
            //        switch (i)
            //        {
            //            case 2:
            //                centre = new Vector2(node.Location.X + halfChildSize.X, node.Location.Y + halfChildSize.Y);
            //                break;
            //            case 3:
            //                centre = new Vector2(node.Location.X + (halfChildSize.X * 3), node.Location.Y + halfChildSize.Y);
            //                break;
            //            case 0:
            //                centre = new Vector2(node.Location.X + halfChildSize.X, node.Location.Y + (halfChildSize.Y * 3));
            //                break;
            //            case 1:
            //                centre = new Vector2(node.Location.X + (halfChildSize.X * 3), node.Location.Y + (halfChildSize.Y * 3));
            //                break;
            //        }
            //        float distance = (centre - viewPos).Length();
            //        if (distance < levelFalloff)
            //        {
            //            if (node.Children == null)
            //            {
            //                node.Fork(1, false);
            //                for (int c = 0; c < 4; c++)
            //                {
            //                    BuildNode(node.Children[c]);
            //                }
            //            }
            //        }
            //        else
            //        {
            //            // check visibility
            //            bool visible = false;

            //            //if (distance < falloff)
            //            //{
            //            float value = viewFOVpl1.Dot(new Vector3(node.Centre.X, 0, node.Centre.Y));
            //            if (value > 0)
            //            {
            //                //if (viewFOVpl2.Dot(new Vector3(node.Centre.X, 0, node.Centre.Y)) < 0)
            //                visible = true;
            //            }
            //            //}

            //            // log what detail the leaf is to be, and if visible
            //            if (visible)
            //                leafDetail[node.Code] = (short)node.Level;
            //            else
            //                leafDetail[node.Code] = (short)-node.Level;
            //        }
            //    }
            //}
        }
Esempio n. 4
0
        private bool TraceNode(PureQuadTreeNode node, bool axis, int index)
        {
            PureQuadTreeNode current = node.Parent;
            // move upwards until we can switch over
            Stack <byte> upTrace = new Stack <byte>();

            upTrace.Push((byte)node.ChildNum);
            while (current != null && current.Level > 0)
            {
                bool flip = false;
                if (axis)
                {
                    if (node.ChildNum == 0 || node.ChildNum == 2)
                    {
                        if (current.ChildNum == 1 || current.ChildNum == 3)
                        {
                            flip = true;
                        }
                    }
                    else if (node.ChildNum == 1 || node.ChildNum == 3)
                    {
                        if (current.ChildNum == 0 || current.ChildNum == 2)
                        {
                            flip = true;
                        }
                    }
                }
                else
                {
                    if (node.ChildNum == 0 || node.ChildNum == 1)
                    {
                        if (current.ChildNum == 2 || current.ChildNum == 3)
                        {
                            flip = true;
                        }
                    }
                    else if (node.ChildNum == 2 || node.ChildNum == 3)
                    {
                        if (current.ChildNum == 0 || current.ChildNum == 1)
                        {
                            flip = true;
                        }
                    }
                }
                if (flip)
                {
                    // flip this and move down tree by slipping the stack until we hit and end
                    //upTrace.Push((byte)current.ChildNum);
                    int target = FlipNode(current.ChildNum, axis);
                    current = current.Parent.Children[target];
                    ushort level = current.Level;
                    ulong  code  = current.Code;
                    while (current != null)
                    {
                        level = current.Level;
                        code  = current.Code;
                        if (level == node.Level)
                        {
                            break;
                        }
                        if (level >= node.Level)
                        {
                            return(false);
                        }

                        /*if (upTrace.Count == 0)
                         *  break;*/

                        target = FlipNode(upTrace.Pop(), axis);
                        if (current.Children != null)
                        {
                            current = current.Children[target];
                        }
                        else
                        {
                            current = null;
                        }
                    }
                    if (!patchCodes.ContainsKey(node.Code))
                    {
                        patchCodes[node.Code] = new ulong[] { ulong.MaxValue, ulong.MaxValue, ulong.MaxValue, ulong.MaxValue }
                    }
                    ;
                    patchCodes[node.Code][index] = code;
                    return(true);
                }
                upTrace.Push((byte)current.ChildNum);
                current = current.Parent;
            }
            return(false);
        }
Esempio n. 5
0
        private void TraceLeaf(PureQuadTreeNode leaf)
        {
            // decide which directions to look at
            switch (leaf.ChildNum)
            {
            case 0:
                if (TraceNode(leaf, true, 0))
                {
                    leafPatches[leaf.Code] = (byte)Directions.Left;
                    if (TraceNode(leaf, false, 3))
                    {
                        leafPatches[leaf.Code] |= (byte)Directions.Down;
                    }
                }
                else if (TraceNode(leaf, false, 3))
                {
                    leafPatches[leaf.Code] = (byte)Directions.Down;
                }
                break;

            case 1:
                if (TraceNode(leaf, true, 1))
                {
                    leafPatches[leaf.Code] = (byte)Directions.Right;
                    if (TraceNode(leaf, false, 3))
                    {
                        leafPatches[leaf.Code] |= (byte)Directions.Down;
                    }
                }
                else if (TraceNode(leaf, false, 3))
                {
                    leafPatches[leaf.Code] = (byte)Directions.Down;
                }
                break;

            case 2:
                if (TraceNode(leaf, true, 0))
                {
                    leafPatches[leaf.Code] = (byte)Directions.Left;
                    if (TraceNode(leaf, false, 2))
                    {
                        leafPatches[leaf.Code] |= (byte)Directions.Up;
                    }
                }
                else if (TraceNode(leaf, false, 2))
                {
                    leafPatches[leaf.Code] = (byte)Directions.Up;
                }
                break;

            case 3:
                if (TraceNode(leaf, true, 1))
                {
                    leafPatches[leaf.Code] = (byte)Directions.Right;
                    if (TraceNode(leaf, false, 2))
                    {
                        leafPatches[leaf.Code] |= (byte)Directions.Up;
                    }
                    break;
                }
                else if (TraceNode(leaf, false, 2))
                {
                    leafPatches[leaf.Code] = (byte)Directions.Up;
                }
                break;
            }
        }
Esempio n. 6
0
 private void TestInternals(PureQuadTreeNode leaf)
 {
     if (leaf.ChildNum == 0)
     {
         if (leaf.Parent.Children[1].Children == null)
         {
             if (!patchCodes.ContainsKey(leaf.Code))
             {
                 patchCodes[leaf.Code] = new ulong[] { ulong.MaxValue, ulong.MaxValue, ulong.MaxValue, ulong.MaxValue }
             }
             ;
             patchCodes[leaf.Code][1] = leaf.Parent.Children[1].Code;
         }
         if (leaf.Parent.Children[2].Children == null)
         {
             if (!patchCodes.ContainsKey(leaf.Code))
             {
                 patchCodes[leaf.Code] = new ulong[] { ulong.MaxValue, ulong.MaxValue, ulong.MaxValue, ulong.MaxValue }
             }
             ;
             patchCodes[leaf.Code][2] = leaf.Parent.Children[2].Code;
         }
     }
     else if (leaf.ChildNum == 1)
     {
         if (leaf.Parent.Children[0].Children == null)
         {
             if (!patchCodes.ContainsKey(leaf.Code))
             {
                 patchCodes[leaf.Code] = new ulong[] { ulong.MaxValue, ulong.MaxValue, ulong.MaxValue, ulong.MaxValue }
             }
             ;
             patchCodes[leaf.Code][0] = leaf.Parent.Children[0].Code;
         }
         if (leaf.Parent.Children[3].Children == null)
         {
             if (!patchCodes.ContainsKey(leaf.Code))
             {
                 patchCodes[leaf.Code] = new ulong[] { ulong.MaxValue, ulong.MaxValue, ulong.MaxValue, ulong.MaxValue }
             }
             ;
             patchCodes[leaf.Code][2] = leaf.Parent.Children[3].Code;
         }
     }
     else if (leaf.ChildNum == 2)
     {
         if (leaf.Parent.Children[0].Children == null)
         {
             if (!patchCodes.ContainsKey(leaf.Code))
             {
                 patchCodes[leaf.Code] = new ulong[] { ulong.MaxValue, ulong.MaxValue, ulong.MaxValue, ulong.MaxValue }
             }
             ;
             patchCodes[leaf.Code][3] = leaf.Parent.Children[0].Code;
         }
         if (leaf.Parent.Children[3].Children == null)
         {
             if (!patchCodes.ContainsKey(leaf.Code))
             {
                 patchCodes[leaf.Code] = new ulong[] { ulong.MaxValue, ulong.MaxValue, ulong.MaxValue, ulong.MaxValue }
             }
             ;
             patchCodes[leaf.Code][1] = leaf.Parent.Children[3].Code;
         }
     }
     else if (leaf.ChildNum == 3)
     {
         if (leaf.Parent.Children[2].Children == null)
         {
             if (!patchCodes.ContainsKey(leaf.Code))
             {
                 patchCodes[leaf.Code] = new ulong[] { ulong.MaxValue, ulong.MaxValue, ulong.MaxValue, ulong.MaxValue }
             }
             ;
             patchCodes[leaf.Code][0] = leaf.Parent.Children[2].Code;
         }
         if (leaf.Parent.Children[1].Children == null)
         {
             if (!patchCodes.ContainsKey(leaf.Code))
             {
                 patchCodes[leaf.Code] = new ulong[] { ulong.MaxValue, ulong.MaxValue, ulong.MaxValue, ulong.MaxValue }
             }
             ;
             patchCodes[leaf.Code][3] = leaf.Parent.Children[1].Code;
         }
     }
 }
Esempio n. 7
0
        private bool TraceNode(PureQuadTreeNode node, bool axis, ref ulong result)
        {
            PureQuadTreeNode current = node.Parent;
            // move upwards until we can switch over
            Stack <byte> upTrace = new Stack <byte>();

            upTrace.Push((byte)node.ChildNum);
            while (current != null && current.Level > 0)
            {
                bool flip = false;
                if (axis)
                {
                    if (node.ChildNum == 0 || node.ChildNum == 2)
                    {
                        if (current.ChildNum == 1 || current.ChildNum == 3)
                        {
                            flip = true;
                        }
                    }
                    else if (node.ChildNum == 1 || node.ChildNum == 3)
                    {
                        if (current.ChildNum == 0 || current.ChildNum == 2)
                        {
                            flip = true;
                        }
                    }
                }
                else
                {
                    if (node.ChildNum == 0 || node.ChildNum == 1)
                    {
                        if (current.ChildNum == 2 || current.ChildNum == 3)
                        {
                            flip = true;
                        }
                    }
                    else if (node.ChildNum == 2 || node.ChildNum == 3)
                    {
                        if (current.ChildNum == 0 || current.ChildNum == 1)
                        {
                            flip = true;
                        }
                    }
                }
                if (flip)
                {
                    // flip this and move down tree by slipping the stack until we hit and end
                    //upTrace.Push((byte)current.ChildNum);
                    int target = FlipNode(current.ChildNum, axis);
                    current = current.Parent.Children[target];
                    ushort level = current.Level;
                    ulong  code  = current.Code;
                    while (current != null)
                    {
                        level = current.Level;
                        code  = current.Code;
                        if (level == node.Level)
                        {
                            break;
                        }
                        if (level >= node.Level)
                        {
                            return(false);
                        }

                        target = FlipNode(upTrace.Pop(), axis);
                        if (current.Children != null)
                        {
                            current = current.Children[target];
                        }
                        else
                        {
                            current = null;
                        }
                    }
                    result = code;
                    return(true);
                }
                upTrace.Push((byte)current.ChildNum);
                current = current.Parent;
            }
            return(false);
        }
Esempio n. 8
0
        private byte TraceLeaf(PureQuadTreeNode leaf, out ulong[] codes)
        {
            byte result = 0;

            codes = new ulong[] { ulong.MaxValue, ulong.MaxValue, ulong.MaxValue, ulong.MaxValue };
            // decide which directions to look at
            switch (leaf.ChildNum)
            {
            case 0:
                if (TraceNode(leaf, true, ref codes[0]))
                {
                    result = (byte)Directions.Left;
                    if (TraceNode(leaf, false, ref codes[3]))
                    {
                        result |= (byte)Directions.Down;
                    }
                }
                else if (TraceNode(leaf, false, ref codes[3]))
                {
                    result = (byte)Directions.Down;
                }
                break;

            case 1:
                if (TraceNode(leaf, true, ref codes[1]))
                {
                    result = (byte)Directions.Right;
                    if (TraceNode(leaf, false, ref codes[3]))
                    {
                        result |= (byte)Directions.Down;
                    }
                }
                else if (TraceNode(leaf, false, ref codes[3]))
                {
                    result = (byte)Directions.Down;
                }
                break;

            case 2:
                if (TraceNode(leaf, true, ref codes[0]))
                {
                    result = (byte)Directions.Left;
                    if (TraceNode(leaf, false, ref codes[2]))
                    {
                        result |= (byte)Directions.Up;
                    }
                }
                else if (TraceNode(leaf, false, ref codes[2]))
                {
                    result = (byte)Directions.Up;
                }
                break;

            case 3:
                if (TraceNode(leaf, true, ref codes[1]))
                {
                    result = (byte)Directions.Right;
                    if (TraceNode(leaf, false, ref codes[2]))
                    {
                        result |= (byte)Directions.Up;
                    }
                    break;
                }
                else if (TraceNode(leaf, false, ref codes[2]))
                {
                    result = (byte)Directions.Up;
                }
                break;
            }
            return(result);
        }
Esempio n. 9
0
        private void DrawChildren(Graphics g, PureQuadTreeNode node)
        {
            if (node.Children != null)
            {
                float halfX = node.Size.X / 2;
                float halfY = node.Size.Y / 2;
                g.DrawLine(Pens.Black, node.Location.X + halfX, node.Location.Y,
                                       node.Location.X + halfX, node.Location.Y + node.Size.Y);
                g.DrawLine(Pens.Black, node.Location.X, node.Location.Y + halfY,
                                       node.Location.X + node.Size.X, node.Location.Y + halfY);

                for (int i = 0; i < 4; i++)
                {
                    DrawChildren(g, node.Children[i]);
                }
            }
            else
            {
                using (Brush brush = new SolidBrush(Color.FromArgb(255, 0, 0, 152)))
                {
                    g.FillRectangle(brush, node.Location.X + 1, node.Location.Y + 1, node.Size.X - 1, node.Size.Y - 1);
                }
                string debug = "[" + node.Code + "]";
                if (leafPatches.ContainsKey(node.Code))
                {
                    // draw right patches
                    if ((leafPatches[node.Code] & (byte)Directions.Down) > 0)
                    {
                        using (Brush brush = new SolidBrush(Color.FromArgb(255, 111, 49, 152)))
                        {
                            g.FillRectangle(brush, node.Location.X + 1, node.Location.Y + 1, node.Size.X - 1, node.Size.Y / 8);
                        }
                        if (patchCodes[node.Code][2] != ulong.MaxValue)
                        {
                            using (Brush brush = new SolidBrush(Color.FromArgb(255, 64, 49, 96)))
                            {
                                g.FillRectangle(brush, node.Location.X + 1, node.Location.Y + node.Size.Y - (node.Size.Y / 8), node.Size.X - 1, node.Size.Y / 8);
                            }
                        }
                        //debug += "(D=" + patchCodes[node.Code][2] + ")";
                    }
                    else if ((leafPatches[node.Code] & (byte)Directions.Up) > 0)
                    {
                        using (Brush brush = new SolidBrush(Color.FromArgb(255, 111, 49, 152)))
                        {
                            g.FillRectangle(brush, node.Location.X + 1, node.Location.Y + node.Size.Y - (node.Size.Y / 8), node.Size.X - 1, node.Size.Y / 8);
                        }
                        if (patchCodes[node.Code][3] != ulong.MaxValue)
                        {
                            using (Brush brush = new SolidBrush(Color.FromArgb(255, 64, 49, 96)))
                            {
                                g.FillRectangle(brush, node.Location.X + 1, node.Location.Y + 1, node.Size.X - 1, node.Size.Y / 8);
                            }
                        }
                        // += "(U=" + patchCodes[node.Code][3] + ")";
                    }
                    else
                    {
                        if (patchCodes[node.Code][2] != ulong.MaxValue)
                        {
                            using (Brush brush = new SolidBrush(Color.FromArgb(255, 64, 49, 96)))
                            {
                                g.FillRectangle(brush, node.Location.X + 1, node.Location.Y + node.Size.Y - (node.Size.Y / 8), node.Size.X - 1, node.Size.Y / 8);
                            }
                            //debug += "(D=" + patchCodes[node.Code][2] + ")";
                        }
                        if (patchCodes[node.Code][3] != ulong.MaxValue)
                        {
                            using (Brush brush = new SolidBrush(Color.FromArgb(255, 64, 49, 96)))
                            {
                                g.FillRectangle(brush, node.Location.X + 1, node.Location.Y + 1, node.Size.X - 1, node.Size.Y / 8);
                            }
                            //debug += "(U=" + patchCodes[node.Code][3] + ")";
                        }
                    }

                    if ((leafPatches[node.Code] & (byte)Directions.Left) > 0)
                    {
                        using (Brush brush = new SolidBrush(Color.FromArgb(255, 111, 49, 152)))
                        {
                            g.FillRectangle(brush, node.Location.X + 1, node.Location.Y + 1, node.Size.X / 8, node.Size.Y - 1);
                        }
                        if (patchCodes[node.Code][1] != ulong.MaxValue)
                        {
                            using (Brush brush = new SolidBrush(Color.FromArgb(255, 64, 49, 96)))
                            {
                                g.FillRectangle(brush, node.Location.X + node.Size.X - (node.Size.X / 8), node.Location.Y + 1, node.Size.X / 8, node.Size.Y - 1);
                            }
                        }
                    }
                    else if ((leafPatches[node.Code] & (byte)Directions.Right) > 0)
                    {
                        using (Brush brush = new SolidBrush(Color.FromArgb(255, 111, 49, 152)))
                        {
                            g.FillRectangle(brush, node.Location.X + node.Size.X - (node.Size.X / 8), node.Location.Y + 1, node.Size.X / 8, node.Size.Y - 1);
                        }
                        if (patchCodes[node.Code][0] != ulong.MaxValue)
                        {
                            using (Brush brush = new SolidBrush(Color.FromArgb(255, 64, 49, 96)))
                            {
                                g.FillRectangle(brush, node.Location.X + 1, node.Location.Y + 1, node.Size.X / 8, node.Size.Y - 1);
                            }
                        }
                    }
                    else
                    {
                        if (patchCodes[node.Code][1] != ulong.MaxValue)
                        {
                            using (Brush brush = new SolidBrush(Color.FromArgb(255, 64, 49, 96)))
                            {
                                g.FillRectangle(brush, node.Location.X + node.Size.X - (node.Size.X / 8), node.Location.Y + 1, node.Size.X / 8, node.Size.Y - 1);
                            }
                        }
                        if (patchCodes[node.Code][0] != ulong.MaxValue)
                        {
                            using (Brush brush = new SolidBrush(Color.FromArgb(255, 64, 49, 96)))
                            {
                                g.FillRectangle(brush, node.Location.X + 1, node.Location.Y + 1, node.Size.X / 8, node.Size.Y - 1);
                            }
                        }
                    }
                    /*if (patchCodes[node.Code][0] != ulong.MaxValue)
                        debug += "L(" + patchCodes[node.Code][0] + ")";
                    if (patchCodes[node.Code][1] != ulong.MaxValue)
                        debug += "R(" + patchCodes[node.Code][1] + ")";*/
                    if (patchCodes[node.Code][2] != ulong.MaxValue)
                        debug += "D(" + patchCodes[node.Code][2] + ")";
                    if (patchCodes[node.Code][3] != ulong.MaxValue)
                        debug += "U(" + patchCodes[node.Code][3] + ")";
                    /*if (patchCodes[node.Code][1] != 14)
                        g.DrawString(patchCodes[node.Code][0] + "," + patchCodes[node.Code][1], Font, Brushes.Red, (int)node.Location.X, (int)node.Location.Y);
                    else
                        g.DrawString(patchCodes[node.Code][0].ToString(), Font, Brushes.Red, (int)node.Location.X, (int)node.Location.Y);*/
                }
                else if (patchCodes.ContainsKey(node.Code))
                {
                    // just internal patches
                    if (patchCodes[node.Code][2] != ulong.MaxValue)
                    {
                        using (Brush brush = new SolidBrush(Color.FromArgb(255, 64, 49, 96)))
                        {
                            g.FillRectangle(brush, node.Location.X + 1, node.Location.Y + node.Size.Y - (node.Size.Y / 8), node.Size.X - 1, node.Size.Y / 8);
                        }
                    }
                    if (patchCodes[node.Code][3] != ulong.MaxValue)
                    {
                        using (Brush brush = new SolidBrush(Color.FromArgb(255, 64, 49, 96)))
                        {
                            g.FillRectangle(brush, node.Location.X + 1, node.Location.Y + 1, node.Size.X - 1, node.Size.Y / 8);
                        }
                    }
                    if (patchCodes[node.Code][1] != ulong.MaxValue)
                    {
                        using (Brush brush = new SolidBrush(Color.FromArgb(255, 64, 49, 96)))
                        {
                            g.FillRectangle(brush, node.Location.X + node.Size.X - (node.Size.X / 8), node.Location.Y + 1, node.Size.X / 8, node.Size.Y - 1);
                        }
                    }
                    if (patchCodes[node.Code][0] != ulong.MaxValue)
                    {
                        using (Brush brush = new SolidBrush(Color.FromArgb(255, 64, 49, 96)))
                        {
                            g.FillRectangle(brush, node.Location.X + 1, node.Location.Y + 1, node.Size.X / 8, node.Size.Y - 1);
                        }
                    }
                }

                Font font = new Font("Verdana", 6);
                g.DrawString(debug, font, Brushes.Orange, (int)node.Location.X, (int)node.Location.Y);
            }
        }
Esempio n. 10
0
        private void BuildNode(PureQuadTreeNode node)
        {
            float levelFalloff = falloff / node.Level;

            // first establish if visible or not by testing centre of node, then corners until visible
            bool visible = (node.Level == 0 || TestPoint(node.Centre) || TestPoint(node.Location) ||
                            TestPoint(new Vector2(node.Location.X + node.Size.X, node.Location.Y)) ||
                            TestPoint(new Vector2(node.Location.X, node.Location.Y + node.Size.Y)) ||
                            TestPoint(new Vector2(node.Location.X + node.Size.X, node.Location.Y + node.Size.Y)));

            // log what detail the leaf is to be, and if visible
            if (visible)
                leafDetail[node.Code] = (short)node.Level;
            else
                leafDetail[node.Code] = (short)-node.Level;

            if (visible)
            {
                // decide if to fork or not
                //Vector2 halfChildSize = node.Size * 0.25f;
                float distance = (node.Centre - viewPos).Length();
                // test this node first directly
                if (distance < levelFalloff)
                {
                    node.Fork(1, false);
                    for (int c = 0; c < 4; c++)
                    {
                        BuildNode(node.Children[c]);
                    }
                }
            }
            
            //else
            //{
            //    // test children directly
            //    for (int i = 0; i < 4; i++)
            //    {
            //        // check centre distance
            //        Vector2 centre = new Vector2();
            //        switch (i)
            //        {
            //            case 2:
            //                centre = new Vector2(node.Location.X + halfChildSize.X, node.Location.Y + halfChildSize.Y);
            //                break;
            //            case 3:
            //                centre = new Vector2(node.Location.X + (halfChildSize.X * 3), node.Location.Y + halfChildSize.Y);
            //                break;
            //            case 0:
            //                centre = new Vector2(node.Location.X + halfChildSize.X, node.Location.Y + (halfChildSize.Y * 3));
            //                break;
            //            case 1:
            //                centre = new Vector2(node.Location.X + (halfChildSize.X * 3), node.Location.Y + (halfChildSize.Y * 3));
            //                break;
            //        }
            //        float distance = (centre - viewPos).Length();
            //        if (distance < levelFalloff)
            //        {
            //            if (node.Children == null)
            //            {
            //                node.Fork(1, false);
            //                for (int c = 0; c < 4; c++)
            //                {
            //                    BuildNode(node.Children[c]);
            //                }
            //            }
            //        }
            //        else
            //        {
            //            // check visibility
            //            bool visible = false;

            //            //if (distance < falloff)
            //            //{
            //            float value = viewFOVpl1.Dot(new Vector3(node.Centre.X, 0, node.Centre.Y));
            //            if (value > 0)
            //            {
            //                //if (viewFOVpl2.Dot(new Vector3(node.Centre.X, 0, node.Centre.Y)) < 0)
            //                visible = true;
            //            }
            //            //}

            //            // log what detail the leaf is to be, and if visible
            //            if (visible)
            //                leafDetail[node.Code] = (short)node.Level;
            //            else
            //                leafDetail[node.Code] = (short)-node.Level;
            //        }
            //    }
            //}
        }
Esempio n. 11
0
        private bool TraceNode(PureQuadTreeNode node, bool axis, int index)
        {
            PureQuadTreeNode current = node.Parent;
            // move upwards until we can switch over
            Stack<byte> upTrace = new Stack<byte>();
            upTrace.Push((byte)node.ChildNum);
            while (current != null && current.Level > 0)
            {
                bool flip = false;
                if (axis)
                {
                    if (node.ChildNum == 0 || node.ChildNum == 2)
                    {
                        if (current.ChildNum == 1 || current.ChildNum == 3)
                            flip = true;
                    }
                    else if (node.ChildNum == 1 || node.ChildNum == 3)
                    {
                        if (current.ChildNum == 0 || current.ChildNum == 2)
                            flip = true;
                    }
                }
                else
                {
                    if (node.ChildNum == 0 || node.ChildNum == 1)
                    {
                        if (current.ChildNum == 2 || current.ChildNum == 3)
                            flip = true;
                    }
                    else if (node.ChildNum == 2 || node.ChildNum == 3)
                    {
                        if (current.ChildNum == 0 || current.ChildNum == 1)
                            flip = true;
                    }
                }
                if (flip)
                {
                    // flip this and move down tree by slipping the stack until we hit and end
                    //upTrace.Push((byte)current.ChildNum);
                    int target = FlipNode(current.ChildNum, axis);
                    current = current.Parent.Children[target];
                    ushort level = current.Level;
                    ulong code = current.Code;
                    while (current != null)
                    {
                        level = current.Level;
                        code = current.Code;
                        if (level == node.Level)
                            break;
                        if (level >= node.Level)
                            return false;
                        /*if (upTrace.Count == 0)
                            break;*/

                        target = FlipNode(upTrace.Pop(), axis);
                        if (current.Children != null)
                            current = current.Children[target];
                        else
                            current = null;
                    }
                    if (!patchCodes.ContainsKey(node.Code))
                        patchCodes[node.Code] = new ulong[] { ulong.MaxValue, ulong.MaxValue, ulong.MaxValue, ulong.MaxValue };
                    patchCodes[node.Code][index] = code;
                    return true;
                }
                upTrace.Push((byte)current.ChildNum);
                current = current.Parent;
            }
            return false;
        }
Esempio n. 12
0
 private void TraceLeaf(PureQuadTreeNode leaf)
 {
     // decide which directions to look at
     switch (leaf.ChildNum)
     {
         case 0:
             if (TraceNode(leaf, true, 0))
             {
                 leafPatches[leaf.Code] = (byte)Directions.Left;
                 if (TraceNode(leaf, false, 3))
                     leafPatches[leaf.Code] |= (byte)Directions.Down;
             }
             else if (TraceNode(leaf, false, 3))
                 leafPatches[leaf.Code] = (byte)Directions.Down;
             break;
         case 1:
             if (TraceNode(leaf, true, 1))
             {
                 leafPatches[leaf.Code] = (byte)Directions.Right;
                 if (TraceNode(leaf, false, 3))
                     leafPatches[leaf.Code] |= (byte)Directions.Down;
             }
             else if (TraceNode(leaf, false, 3))
                 leafPatches[leaf.Code] = (byte)Directions.Down;
             break;
         case 2:
             if (TraceNode(leaf, true, 0))
             {
                 leafPatches[leaf.Code] = (byte)Directions.Left;
                 if (TraceNode(leaf, false, 2))
                     leafPatches[leaf.Code] |= (byte)Directions.Up;
             }
             else if (TraceNode(leaf, false, 2))
                 leafPatches[leaf.Code] = (byte)Directions.Up;
             break;
         case 3:
             if (TraceNode(leaf, true, 1))
             {
                 leafPatches[leaf.Code] = (byte)Directions.Right;
                 if (TraceNode(leaf, false, 2))
                     leafPatches[leaf.Code] |= (byte)Directions.Up;
                 break;
             }
             else if (TraceNode(leaf, false, 2))
                 leafPatches[leaf.Code] = (byte)Directions.Up;
             break;
     }
 }
Esempio n. 13
0
 private void TestInternals(PureQuadTreeNode leaf)
 {
     if (leaf.ChildNum == 0)
     {
         if (leaf.Parent.Children[1].Children == null)
         {
             if (!patchCodes.ContainsKey(leaf.Code))
                 patchCodes[leaf.Code] = new ulong[] { ulong.MaxValue, ulong.MaxValue, ulong.MaxValue, ulong.MaxValue };
             patchCodes[leaf.Code][1] = leaf.Parent.Children[1].Code;
         }
         if (leaf.Parent.Children[2].Children == null)
         {
             if (!patchCodes.ContainsKey(leaf.Code))
                 patchCodes[leaf.Code] = new ulong[] { ulong.MaxValue, ulong.MaxValue, ulong.MaxValue, ulong.MaxValue };
             patchCodes[leaf.Code][2] = leaf.Parent.Children[2].Code;
         }
     }
     else if (leaf.ChildNum == 1)
     {
         if (leaf.Parent.Children[0].Children == null)
         {
             if (!patchCodes.ContainsKey(leaf.Code))
                 patchCodes[leaf.Code] = new ulong[] { ulong.MaxValue, ulong.MaxValue, ulong.MaxValue, ulong.MaxValue };
             patchCodes[leaf.Code][0] = leaf.Parent.Children[0].Code;
         }
         if (leaf.Parent.Children[3].Children == null)
         {
             if (!patchCodes.ContainsKey(leaf.Code))
                 patchCodes[leaf.Code] = new ulong[] { ulong.MaxValue, ulong.MaxValue, ulong.MaxValue, ulong.MaxValue };
             patchCodes[leaf.Code][2] = leaf.Parent.Children[3].Code;
         }
     }
     else if (leaf.ChildNum == 2)
     {
         if (leaf.Parent.Children[0].Children == null)
         {
             if (!patchCodes.ContainsKey(leaf.Code))
                 patchCodes[leaf.Code] = new ulong[] { ulong.MaxValue, ulong.MaxValue, ulong.MaxValue, ulong.MaxValue };
             patchCodes[leaf.Code][3] = leaf.Parent.Children[0].Code;
         }
         if (leaf.Parent.Children[3].Children == null)
         {
             if (!patchCodes.ContainsKey(leaf.Code))
                 patchCodes[leaf.Code] = new ulong[] { ulong.MaxValue, ulong.MaxValue, ulong.MaxValue, ulong.MaxValue };
             patchCodes[leaf.Code][1] = leaf.Parent.Children[3].Code;
         }
     }
     else if (leaf.ChildNum == 3)
     {
         if (leaf.Parent.Children[2].Children == null)
         {
             if (!patchCodes.ContainsKey(leaf.Code))
                 patchCodes[leaf.Code] = new ulong[] { ulong.MaxValue, ulong.MaxValue, ulong.MaxValue, ulong.MaxValue };
             patchCodes[leaf.Code][0] = leaf.Parent.Children[2].Code;
         }
         if (leaf.Parent.Children[1].Children == null)
         {
             if (!patchCodes.ContainsKey(leaf.Code))
                 patchCodes[leaf.Code] = new ulong[] { ulong.MaxValue, ulong.MaxValue, ulong.MaxValue, ulong.MaxValue };
             patchCodes[leaf.Code][3] = leaf.Parent.Children[1].Code;
         }
     }
 }