public Node(Quadtree <T> quadtree, Node parent, Node createrChild, object newObjectBounding)
            {
                this.quadtree = quadtree;
                Vector2 minPoint;
                var     bb             = Boundings.BoundingToBox(newObjectBounding);
                var     rootBB         = (BoundingBox)createrChild.bounding;
                var     oldOrientation = FindNewNodeMinPoint(rootBB, bb, out minPoint);

                float childWidth  = rootBB.Maximum.X - rootBB.Minimum.X;
                float childHeight = rootBB.Maximum.Y - rootBB.Minimum.Y;

                bounding            = new BoundingBox(new Vector3(minPoint.X, minPoint.Y, float.MaxValue), new Vector3(minPoint.X + 2 * childWidth, minPoint.Y + 2 * childHeight, float.MinValue));
                this.parent         = parent;
                this.depth          = createrChild.depth + 1;
                createrChild.parent = this;

                for (int i = 0; i < 4; i++)
                {
                    int r = i % 2;
                    int t = i / 2;

                    if (oldOrientation.Right == (r == 1) && (oldOrientation.Top == (t == 1)))
                    {
                        children[i] = createrChild;
                    }
                    else
                    {
                        children[i] = new Node(quadtree, this, minPoint.X + r * childWidth,
                                               minPoint.Y + t * childHeight,
                                               childWidth, childHeight,
                                               depth - 1);            // recalculate depth later
                    }
                }
            }
            public void Insert(T objct, object bounding)
            {
                UpdateNodeHeight(objct, Boundings.BoundingToBox(bounding));
                objct_to_boundings[objct] = bounding;
#if DEBUGQT
                CheckInsertedObject(objct, this, null);
#endif
            }
            void InitLeafBounding()
            {
                var     v   = Boundings.BoundingToBox(objects[0].Second);
                Vector3 min = v.Minimum;
                Vector3 max = v.Maximum;

                for (int i = 1; i < objects.Count; i++)
                {
                    v   = Boundings.BoundingToBox(objects[i].Second);
                    min = Math.Min(min, v.Minimum);
                    max = Math.Max(max, v.Maximum);
                }
                bounding = new BoundingBox(min, max);
            }
        public override void Move(T objct, Matrix translation)
        {
            object bounding;
            Node   n;

            if (objectToNode.TryGetValue(objct, out n))
            {
                bounding = n.objct_to_boundings[objct];
            }
            else
            {
                bounding = nonfittableObjects[objct];
            }
            Move(objct, Boundings.Transform(bounding, translation));
        }
        private void InitFromInsert(object bounding)
        {
            var     bb   = Boundings.BoundingToBox(bounding);
            Vector2 diff = Common.Math.ToVector2(bb.Maximum - bb.Minimum);

            float   of       = 0.00001f; // slight offset so the inserted object actually ends up inside the cell
            float   cellSize = System.Math.Max(FindOrigoCoveringCellSize(diff, nodeSize), nodeSize);
            Vector2 farPoint = new Vector2(bb.Minimum.X + bb.Maximum.X < 0 ? bb.Minimum.X - of : bb.Maximum.X + of,
                                           bb.Minimum.Y + bb.Maximum.Y < 0 ? bb.Minimum.Y - of : bb.Maximum.Y + of);

            float origoCellSize = System.Math.Max(FindOrigoCoveringCellSize(farPoint, cellSize), cellSize);

            int depth = System.Math.Max(0, (int)System.Math.Log(origoCellSize / nodeSize, 2f));

            root = new Node(
                this,
                null,
                farPoint.X < 0 ? farPoint.X : farPoint.X - origoCellSize,
                farPoint.Y < 0 ? farPoint.Y : farPoint.Y - origoCellSize,
                origoCellSize,
                origoCellSize,
                depth);
        }
Beispiel #6
0
 public override void Move(T objct, Matrix translation)
 {
     entities[objct] = Boundings.Transform(entities[objct], translation);
 }
            private void UpdateHeightBounding(T removedObject)
            {
                bool wasMinObject = removedObject.Equals(minObject);
                bool wasMaxObject = removedObject.Equals(maxObject);

                if (wasMinObject || wasMaxObject)
                {
                    if (wasMinObject)
                    {
                        minObject          = default(T);
                        bounding.Minimum.Z = float.MaxValue;
                    }
                    if (wasMaxObject)
                    {
                        maxObject          = default(T);
                        bounding.Maximum.Z = float.MinValue;
                    }
                    foreach (var c in children)
                    {
                        if (c != null)
                        {
                            // set to childrens min/maxobject if that is what spans the box
                            if (wasMinObject && c.bounding.Minimum.Z < bounding.Minimum.Z)
                            {
                                bounding.Minimum.Z = c.bounding.Minimum.Z;
                                minObject          = c.minObject;
                            }
                            if (wasMaxObject && c.bounding.Maximum.Z > bounding.Maximum.Z)
                            {
                                bounding.Maximum.Z = c.bounding.Maximum.Z;
                                maxObject          = c.maxObject;
                            }
                        }
                    }
                    foreach (var o in objct_to_boundings.Keys)
                    {
                        BoundingBox bb = Boundings.BoundingToBox(objct_to_boundings[o]);
                        if (wasMinObject && bb.Minimum.Z < bounding.Minimum.Z)
                        {
                            bounding.Minimum.Z = bb.Minimum.Z;
                            minObject          = o;
                        }
                        if (wasMaxObject && bb.Maximum.Z > bounding.Maximum.Z)
                        {
                            bounding.Maximum.Z = bb.Maximum.Z;
                            maxObject          = o;
                        }
                    }

#if DEBUGQT
                    if ((minObject != null || maxObject != null) && !(minObject != null && maxObject != null))
                    {
                        System.Diagnostics.Debugger.Break();        // this should not happen
                    }
#endif

                    if (parent != null)
                    {
                        parent.UpdateHeightBounding(removedObject);
                    }
                }
            }