private void InsertRecursive(T elem, OctreeBound bound) { Octree <T> overlapChild = null; int overlapCount = BoundOverlapChildren(bound, ref overlapChild); if (overlapCount == 0) { if (m_items.Count < m_capacity || m_bound.size / 2 < m_minSize) { m_items.Add(new OctreeItem(elem, bound)); } else { Split(); InsertRecursive(elem, bound); } } else if (overlapCount == 1) { overlapChild.InsertRecursive(elem, bound); } else { m_items.Add(new OctreeItem(elem, bound)); } }
public Octree(OctreeBound bound, int capacity, float minSize) { m_bound = bound; m_capacity = capacity; m_minSize = minSize; m_items = new List <OctreeItem>(capacity); }
void OnDrawGizmos() { if (m_octree == null) { m_octree = new Octree <BoxCollider>(new OctreeBound(m_maxSize / 2, m_maxSize / 2, m_maxSize / 2, m_maxSize), m_capacity, m_minSize); } m_octree.Reset(); for (int i = 0; i < transform.childCount; i++) { var e = transform.GetChild(i).GetComponent <BoxCollider>(); if (e == null) { continue; } var bl = e.transform.position - e.size / 2; float size = Mathf.Max(e.bounds.size.x, Mathf.Max(e.bounds.size.y, e.bounds.size.z)); OctreeBound bound = new OctreeBound(bl, size); m_octree.Insert(e, bound); } DrawOctree(m_octree); }
public void Insert(T elem, OctreeBound bound) { if (!m_bound.Overlaps(bound)) { return; } InsertRecursive(elem, bound); }
private void BoundOverlapChildren(OctreeBound bound, List <Octree <T> > treeList) { if (m_children == null) { return; } bool overlapLeft = bound.xMin <= m_bound.center.x; bool overlapRight = bound.xMax >= m_bound.center.x; bool overlapBottom = bound.yMin <= m_bound.center.y; bool overlapTop = bound.yMax >= m_bound.center.y; bool overlapFront = bound.zMin <= m_bound.center.z; bool overlapRear = bound.zMax >= m_bound.center.z; if (overlapFront && overlapBottom && overlapLeft) { treeList.Add(m_children[k_FBL]); } if (overlapFront && overlapBottom && overlapRight) { treeList.Add(m_children[k_FBR]); } if (overlapFront && overlapTop && overlapLeft) { treeList.Add(m_children[k_FTL]); } if (overlapFront && overlapTop && overlapRight) { treeList.Add(m_children[k_FTR]); } if (overlapRear && overlapBottom && overlapLeft) { treeList.Add(m_children[k_RBL]); } if (overlapRear && overlapBottom && overlapRight) { treeList.Add(m_children[k_RBR]); } if (overlapRear && overlapTop && overlapLeft) { treeList.Add(m_children[k_RTL]); } if (overlapRear && overlapTop && overlapRight) { treeList.Add(m_children[k_RTR]); } }
public bool Overlaps(OctreeBound other) { if (other.xMax < xMin || other.xMin > xMax) { return(false); } if (other.yMax < yMin || other.yMin > yMax) { return(false); } if (other.zMax < zMin || other.zMin > zMax) { return(false); } return(true); }
public void Query(OctreeBound bound, List <T> result) { if (!m_bound.Overlaps(bound)) { return; } for (int i = 0; i < m_items.Count; i++) { if (bound.Overlaps(m_items[i].m_bound)) { result.Add(m_items[i].m_elem); } } List <Octree <T> > subTrees = new List <Octree <T> >(); BoundOverlapChildren(bound, subTrees); for (int i = 0; i < subTrees.Count; i++) { subTrees[i].Query(bound, result); } }
public bool Remove(T elem, OctreeBound bound) { for (int i = 0; i < m_items.Count; i++) { if (m_items[i].m_elem.Equals(elem)) { m_items.RemoveAt(i); return(true); } } List <Octree <T> > subTrees = new List <Octree <T> >(); BoundOverlapChildren(bound, subTrees); for (int i = 0; i < subTrees.Count; i++) { if (subTrees[i].Remove(elem, bound)) { return(true); } } return(false); }
public OctreeItem(T elem, OctreeBound bound) { m_elem = elem; m_bound = bound; }
private int BoundOverlapChildren(OctreeBound bound, ref Octree <T> tree) { if (m_children == null) { return(0); } int count = 0; bool overlapLeft = bound.xMin <= m_bound.center.x; bool overlapRight = bound.xMax >= m_bound.center.x; bool overlapBottom = bound.yMin <= m_bound.center.y; bool overlapTop = bound.yMax >= m_bound.center.y; bool overlapFront = bound.zMin <= m_bound.center.z; bool overlapRear = bound.zMax >= m_bound.center.z; if (overlapFront && overlapBottom && overlapLeft) { count++; tree = m_children[k_FBL]; } if (overlapFront && overlapBottom && overlapRight) { count++; tree = m_children[k_FBR]; } if (overlapFront && overlapTop && overlapLeft) { count++; tree = m_children[k_FTL]; } if (overlapFront && overlapTop && overlapRight) { count++; tree = m_children[k_FTR]; } if (overlapRear && overlapBottom && overlapLeft) { count++; tree = m_children[k_RBL]; } if (overlapRear && overlapBottom && overlapRight) { count++; tree = m_children[k_RBR]; } if (overlapRear && overlapTop && overlapLeft) { count++; tree = m_children[k_RTL]; } if (overlapRear && overlapTop && overlapRight) { count++; tree = m_children[k_RTR]; } return(count); }
private static void DrawBox(OctreeBound box) { Gizmos.color = Color.blue; Gizmos.DrawWireCube(box.center, new Vector3(box.size, box.size, box.size)); }