//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); }
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); } }
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); }
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"); } } } } } } }
public bool TryGet(T key, out OctreeItem <T> item) { if (items.TryGetValue(key, out item)) { return(true); } return(false); }
public void AddOctreeItem(OctreeItem <T> octreeItem) { if (_cachedItems.Count < MaxCachedItemCount) { octreeItem.Item = default(T); octreeItem.Container = null; _cachedItems.Push(octreeItem); } }
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; }
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); }
private void AddItem(OctreeItem item) { if (!items.Contains(item)) { items.Add(item); item.nodes.Add(this); } if (items.Count > capacity) { Subdivide(); } }
//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(); } }
private void PushItem(OctreeItem item) { if (!containedItems.Contains(item)) { containedItems.Add(item); item.my_ownerNodes.Add(this); } if (containedItems.Count > s_maxObjectLimit) { Split(); } }
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(); } }
private void PushItem(OctreeItem item) { if (!containedItems.Contains(item)) { containedItems.Add(item); item.overlappingNodes.Add(this); } if (containedItems.Count > maxObjectLimit && depth <= maxDepth) { Split(); } }
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(); }
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); } }
/// <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); }
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); } }
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); } }
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); } }
/// <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(); } }
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); } }
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); }
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); } }
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); }
/// <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(); }
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); }
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); }
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); }
public void RemoveItem(OctreeItem <T> octreeItem) { octreeItem.Container.RemoveItem(octreeItem); _currentRoot = _currentRoot.TryTrimChildren(); }
void Add(OctreeItem <T> item) { var box = item.Bound; Add(ref box, item); }