Esempio n. 1
0
 //see if a given item should be stored in containeditems list of items for this particular node
 public bool ProcessItem(OctreeItem item)
 {
     //check if this particular node contains position
     if (ContainsItemPos(item.transform.position))
     {
         //Check if this node doesnt have children
         if (ReferenceEquals(ChildrenNodes[0], null))
         {
             PushItem(item);
             return(true);
         }
         else
         {
             foreach (OctreeNode childNode in ChildrenNodes)
             {
                 if (childNode.ProcessItem(item))
                 {
                     return(true);
                 }
             }
         }
     }
     //end if the item is inside of this particular node
     return(false);
 }
Esempio n. 2
0
    private void Start()
    {
        // Initialize stuff
        Logger.Instance.DebugInfo("CollisionManager: Started");
        CachedSeparatingAxis = new Dictionary <int, Vector3>();

        //=======
        // Octree
        //=======
        OctreeNode.Init();

        // Update in Octree
        foreach (BaseCollider bc in this.Colliders)
        {
            OctreeItem oi = bc.GetComponent <OctreeItem>();
            if (oi != null)
            {
                oi.RefreshOwners();
            }
        }

        //=======
        // Debug
        //=======
        if (debug)
        {
            SATDebugCube = Instantiate(SATDebugCubePrefab);
            SATDebugCube.SetActive(false);
        }
    }
Esempio n. 3
0
        public bool Add(ref BoundingBox box, OctreeItem <T> item)
        {
            if (this.Bounds.Contains(ref box) == BoundingContainmentType.Disjoint)
            {
                return(false);
            }

            if (items.Count >= MaximumChildren && IsLeaf())
            {
                if (this.Bounds.Contains(ref item.Bound) == BoundingContainmentType.Contains)
                {
                    //split nodes if can
                    items.Add(item);
                    return(RebuildTree());
                }
                return(false);
            }
            if (!IsLeaf())
            {
                AddIntoNodes(item);
            }
            else
            {
                item.AddOwner(this);
                items.Add(item);
            }

            return(true);
        }
Esempio n. 4
0
    public void DetectCollisions()
    {
        foreach (OctreeNode octNode in OctreeNode.NodesToCheckForCollision)
        {
            OctreeItem[] octreeItems = octNode.containedItems.ToArray();
            for (int i = 0; i < octreeItems.Length; i++)
            {
                for (int j = i + 1; j < octreeItems.Length; j++)
                {
                    OctreeItem oi0 = octreeItems[i];
                    OctreeItem oi1 = octreeItems[j];


                    if (oi0.sphereCollider != null && oi1.sphereCollider != null)
                    {
                        //SPHERE vs SPHERE
                        SphereCollider s0 = oi0.sphereCollider;
                        SphereCollider s1 = oi1.sphereCollider;

                        if (AreSpheresColliding(s0, s1))
                        {
                            Logger.Instance.DebugInfo("Collision happened [Sphere vs Sphere]: " +
                                                      Colliders[i].Id + " - " +
                                                      Colliders[j].Id + " !",
                                                      "COLLISION_MANAGER");
                        }
                    }

                    else
                    {
                        //OBB vs SPHERE
                        SphereCollider s;
                        ColliderBox    b;

                        if (oi0.sphereCollider != null)
                        {
                            s = oi0.sphereCollider;
                            b = oi1.colliderBox;
                        }
                        else
                        {
                            s = oi1.sphereCollider;
                            b = oi0.colliderBox;
                        }
                        if (b != null && s != null)
                        {
                            //Debug.Log(octreeItems.Length);
                            if (AreSphereOBBColliding(b, s))
                            {
                                Logger.Instance.DebugInfo("Collision happened [OBB vs Sphere]: " +
                                                          Colliders[i].Id + " - " +
                                                          Colliders[j].Id + " !",
                                                          "COLLISION_MANAGER");
                            }
                        }
                    }
                }
            }
        }
    }
Esempio n. 5
0
 public bool TryGet(T key, out OctreeItem <T> item)
 {
     if (items.TryGetValue(key, out item))
     {
         return(true);
     }
     return(false);
 }
Esempio n. 6
0
 public void AddOctreeItem(OctreeItem <T> octreeItem)
 {
     if (_cachedItems.Count < MaxCachedItemCount)
     {
         octreeItem.Item      = default(T);
         octreeItem.Container = null;
         _cachedItems.Push(octreeItem);
     }
 }
Esempio n. 7
0
            public BoundsRenderItemEntry(BoundsRenderItem bri, Transform transform, OctreeItem <RenderItem> oi)
            {
                Debug.Assert(bri != null);
                Debug.Assert(transform != null);
                Debug.Assert(oi != null);

                BoundsRenderItem = bri;
                Transform        = transform;
                OctreeItem       = oi;
            }
Esempio n. 8
0
        public bool Add(BoundingBox box, T item)
        {
            var oitem = new OctreeItem <T>(ref box, item);

            if (root.Add(ref box, oitem))
            {
                items.Add(item, oitem);
                return(true);
            }
            return(false);
        }
Esempio n. 9
0
 private void AddItem(OctreeItem item)
 {
     if (!items.Contains(item))
     {
         items.Add(item);
         item.nodes.Add(this);
     }
     if (items.Count > capacity)
     {
         Subdivide();
     }
 }
Esempio n. 10
0
 //We know that an item should be accquired and contained by this node work on adding it
 private void PushItem(OctreeItem item)
 {
     //only add it to our list of contained items if its not mentioned yet within the list
     if (!ContainedItems.Contains(item))
     {
         ContainedItems.Add(item);
         item.MyOwnerNodes.Add(this);
     }
     if (ContainedItems.Count > MaxObjectLimit)
     {
         Split();
     }
 }
Esempio n. 11
0
    private void PushItem(OctreeItem item)
    {
        if (!containedItems.Contains(item))
        {
            containedItems.Add(item);
            item.my_ownerNodes.Add(this);
        }

        if (containedItems.Count > s_maxObjectLimit)
        {
            Split();
        }
    }
Esempio n. 12
0
    private void PushItem(OctreeItem item)  // we know that an item should be accquired and contained by this node.
    {
        if (!containedItems.Contains(item)) // only add it to our list of contained items if its not mentioned yet within the list
        {
            containedItems.Add(item);
            item.my_ownerNodes.Add(this);
        }

        if (containedItems.Count > maxObjectLimit)
        {
            Split();
        }
    }
Esempio n. 13
0
    private void PushItem(OctreeItem item)
    {
        if (!containedItems.Contains(item))
        {
            containedItems.Add(item);
            item.overlappingNodes.Add(this);
        }

        if (containedItems.Count > maxObjectLimit && depth <= maxDepth)
        {
            Split();
        }
    }
Esempio n. 14
0
        public void MoveItem(OctreeItem <T> octreeItem, BoundingBox newBounds)
        {
            if (newBounds.ContainsNaN())
            {
                throw new Exception("Invalid bounds: " + newBounds);
            }
            OctreeNode <T> newRoot = octreeItem.Container.MoveContainedItem(octreeItem, newBounds);

            if (newRoot != null)
            {
                _currentRoot = newRoot;
            }

            _currentRoot = _currentRoot.TryTrimChildren();
        }
Esempio n. 15
0
 public void TryDeleteSubdivision(OctreeItem item)
 {
     if (!ReferenceEquals(this, Root) && !DeleteItems())
     {
         foreach (var child in parent.Childs)
         {
             child.RemoveNode(parent.Childs.Where(i => !ReferenceEquals(i, this)).ToArray());
         }
         parent.EraseChildNodes();
     }
     else
     {
         items.Remove(item);
         item.nodes.Remove(this);
     }
 }
Esempio n. 16
0
    /// <summary>
    /// Checking if an item is inside the node (or subnodes of the node).
    /// If inside of node: PushItem() (reference from item and node are updated and also split if necessary).
    /// If there are childs go down the chain.
    /// </summary>
    public bool ProcessItem(OctreeItem item)
    {
        //if (ContainsItemPos(item.transform.position))
        if (ContainsItemColliderBox(item.colliderBox))
        {
            Logger.Instance.DebugInfo("ProcessItem: item is colliding with node", "OCTREE NODE");
            // If the item is inside this node return true
            if (ReferenceEquals(childrenNodes[0], null))
            {
                PushItem(item);

                // TODO: DEBUG (comment later)
                //this.UpdateDebugMeshText();
                //item.UpdateDebugMeshText();

                return(true);
            }
            else
            {
                bool proc = false;
                // If this node has childs then process all the subnodes to see who containts this item
                foreach (OctreeNode childNode in childrenNodes)
                {
                    // TODO: after fix, try swapping this comment/uncomment group
                    if (childNode.ProcessItem(item))
                    {
                        //return true;
                        proc = true;
                    }
                    childNode.ProcessItem(item);
                }

                // TODO: DEBUG (comment later)
                //this.UpdateDebugMeshText();
                //item.UpdateDebugMeshText();

                return(proc);
            }
        }

        // TODO: DEBUG (comment later)
        //this.UpdateDebugMeshText();
        //item.UpdateDebugMeshText();

        return(false);
    }
Esempio n. 17
0
 public void Attempt_ReduceSubdivisions(OctreeItem escapedItem)
 {
     if (!ReferenceEquals(this, octreeRoot) && !Siblings_ChildrenNodesPresent_too_manyItems())
     {
         // Delete node and siblings
         foreach (OctreeNode on in parent.childrenNodes)                                        // iterate through this node and its 7 siblings, them kill them
         {
             on.KillNode(parent.childrenNodes.Where(i => !ReferenceEquals(i, this)).ToArray()); // pass 7 siblings as we will be killing this node.
         }
         parent.EraseChildrenNodes();                                                           //make parent forget about its old, already killed children nodes.
     }
     else // otherwise, of there are children in siblings, or there are too many items for the parent to potentially hold, then:
     {
         containedItems.Remove(escapedItem); //remove the item from the contained items of this particular node since such item no longer falls into the domain of this node.
         escapedItem.my_ownerNodes.Remove(this);
     }
 }
Esempio n. 18
0
            public void AddNode(OctreeNode <T> child)
            {
                Debug.Assert(!_cachedNodes.Contains(child));
                if (_cachedNodes.Count < MaxCachedItemCount)
                {
                    for (int i = 0; i < child._items.Count; i++)
                    {
                        OctreeItem <T> item = child._items[i];
                        item.Item      = default(T);
                        item.Container = null;
                    }
                    child.Parent    = null;
                    child._children = Array.Empty <OctreeNode <T> >();

                    _cachedNodes.Push(child);
                }
            }
Esempio n. 19
0
    public void AttemptReduceSubdivisions(OctreeItem escapedItem)
    {
        if (!ReferenceEquals(this, OctreeRoot) && !SiblingsChildrenNodesPresentTooManyItems())
        {
            for (int i = 0; i < parent.ChildrenNodes.Length; i++)
            {
                parent.ChildrenNodes[i].KillNode(parent.ChildrenNodes.Where(x => !ReferenceEquals(x, this)).ToArray());
            }

            parent.EraseChildrenNodes();
        }
        else
        {
            containedItems.Remove(escapedItem);
            escapedItem.my_ownerNodes.Remove(this);
        }
    }
Esempio n. 20
0
    /// <summary>
    /// Add an item to the contained items of the node. Check also if needed to split.
    /// </summary>
    private void PushItem(OctreeItem item)
    {
        // Add item to the contained item.
        if (!containedItems.Contains(item))
        {
            containedItems.Add(item);
            item.my_ownerNodes.Add(this);
            AddContainedItemsToItemCollisionCheckList(this);
            Logger.Instance.DebugInfo("PushItem: adding item to the current node (no need to split).", "OCTREE NODE");
        }

        // Check if needed to split
        if (containedItems.Count > maxObjectLimit && nodeDepth < maxDepth)
        {
            Logger.Instance.DebugInfo("PushItem: splitting node -> too many items in current node and can go deeper.", "OCTREE NODE");
            Split();
        }
    }
Esempio n. 21
0
    public void Attempt_ReduceSubdivisions(OctreeItem escapedItem)
    {
        if (!ReferenceEquals(this, OctreeRoot) && !Siblings_ChildrenNodesPresent_TooManyItems())
        {
            //iterate thorugh this node and its 7 siblings then kill them
            foreach (OctreeNode item in Parent.ChildrenNodes)
            {
                item.KillNode(Parent.ChildrenNodes.Where(i => !ReferenceEquals(i, this)).ToArray());
            }

            Parent.EreaseChildrennodes();
        }
        else//otherwise if there are children in siblings or there are too many items for the parent to potentially hold them
        {  //remove the item from the contained items of this particuar node
            ContainedItems.Remove(escapedItem);
            escapedItem.MyOwnerNodes.Remove(this);
        }
    }
Esempio n. 22
0
        void AddIntoNodes(OctreeItem <T> item)
        {
            for (int j = 0; j < octants?.Length; j++)
            {
                var node = octants[j];

                var cross = node.Bounds.Contains(ref item.Bound);

                if (cross == BoundingContainmentType.Contains)
                {
                    node.Add(item);
                    return;
                }
                if (cross == BoundingContainmentType.Intersects)
                {
                    node.Add(item);
                }
            }
            //items.Add(item);
        }
Esempio n. 23
0
 public void AttemptReduceSubdivisions(OctreeItem item)
 {
     if (!ReferenceEquals(this, OctreeRoot) && !ChildrenInSiblingsOrMaxLimitInParentExceeded()) // If this is not a root node and the siblings of this do not have any child nodes nor is the max limit in parent exceeded...
     {
         foreach (OctreeNode node in parent.Children)
         {
             if (node == null)
             {
                 continue;
             }
             node.KillNode(parent.Children.Where(i => !ReferenceEquals(i, this)).ToArray());
         }
         parent.EraseChildrenNodes();
     }
     else
     {
         containedItems.Remove(item);
         item.overlappingNodes.Remove(this);
     }
 }
Esempio n. 24
0
 public bool Insert(OctreeItem item)
 {
     if (Contains(item.transform.position))
     {
         if (ReferenceEquals(Childs[0], null))
         {
             AddItem(item);
             return(true);
         }
         else
         {
             foreach (var child in childs)
             {
                 if (child.Insert(item))
                 {
                     return(true);
                 }
             }
         }
     }
     return(false);
 }
Esempio n. 25
0
    /// <summary>
    /// If an item moved check if the previous nodes can be reduces in size.
    /// Can remove childs in case of:
    /// (1) If the node has empty leaf nodes.
    /// (2) If the node doesn't exceed max amount of childs.
    /// </summary>
    public void Attempt_ReduceSubdivisions(OctreeItem escapedItem)
    {
        if (!ReferenceEquals(this, octreeRoot) && !Siblings_ChildrenNodesPresent_too_manyItems())
        {
            // delte node and siblings
            foreach (OctreeNode on in parent.childrenNodes)
            {
                // TODO: passing only this node should be enough or not? -> because we are iterating over all sibling nodes
                on.KillNode(parent.childrenNodes.Where(i => !ReferenceEquals(i, this)).ToArray());
            }
            parent.EraseChildrenNodes();
        }
        else
        {
            // remove the item from the contained items of this particular node (because item is no longer inside this node)
            containedItems.Remove(escapedItem);
            escapedItem.my_ownerNodes.Remove(this);
        }

        // TODO: DEBUG (comment later)
        //this.UpdateDebugMeshText();
    }
Esempio n. 26
0
    public bool ProcessItem(OctreeItem item)
    {
        if (ContainsItemPosition(item.transform.position))
        {
            if (ReferenceEquals(ChildrenNodes[0], null))
            {
                PushItem(item);
                return(true);
            }
            else
            {
                for (int i = 0; i < ChildrenNodes.Length; i++)
                {
                    if (ChildrenNodes[i].ProcessItem(item))
                    {
                        return(true);
                    }
                }
            }
        }

        return(false);
    }
Esempio n. 27
0
    public bool ProcessItem(OctreeItem item)
    {
        if (ContainsItemPos(item.transform))        // is the position in octant?
        {
            if (ReferenceEquals(Children[0], null)) // there are no other children
            {
                PushItem(item);
                return(true);
            }
            else
            {
                foreach (OctreeNode childNode in Children)
                {
                    if (childNode.ProcessItem(item))
                    {
                        return(true);
                    }
                }
            }
        }

        return(false);
    }
Esempio n. 28
0
    public bool ProcessItem(OctreeItem item)
    {
        if (ContainsItemPos(item.transform.position))
        {
            if (ReferenceEquals(childrenNodes[0], null)) // check if the childrenNodes are null
            {
                PushItem(item);

                return(true);
            }
            else // if there are childrenNodes, do recursion
            {
                foreach (OctreeNode childNode in childrenNodes)
                {
                    if (childNode.ProcessItem(item))
                    {
                        return(true);
                    }
                }
            }
        }

        return(false);
    }
Esempio n. 29
0
 public void RemoveItem(OctreeItem <T> octreeItem)
 {
     octreeItem.Container.RemoveItem(octreeItem);
     _currentRoot = _currentRoot.TryTrimChildren();
 }
Esempio n. 30
0
        void Add(OctreeItem <T> item)
        {
            var box = item.Bound;

            Add(ref box, item);
        }