void Octant::InsertDrawable(Drawable* drawable) { const BoundingBox& box = drawable->GetWorldBoundingBox(); // If root octant, insert all non-occludees here, so that octant occlusion does not hide the drawable. // Also if drawable is outside the root octant bounds, insert to root bool insertHere; if (this == root_) insertHere = !drawable->IsOccludee() || cullingBox_.IsInside(box) != INSIDE || CheckDrawableFit(box); else insertHere = CheckDrawableFit(box); if (insertHere) { Octant* oldOctant = drawable->octant_; if (oldOctant != this) { // Add first, then remove, because drawable count going to zero deletes the octree branch in question AddDrawable(drawable); if (oldOctant) oldOctant->RemoveDrawable(drawable, false); } } else { Vector3 boxCenter = box.Center(); unsigned x = boxCenter.x_ < center_.x_ ? 0 : 1; unsigned y = boxCenter.y_ < center_.y_ ? 0 : 2; unsigned z = boxCenter.z_ < center_.z_ ? 0 : 4; GetOrCreateChild(x + y + z)->InsertDrawable(drawable); } }
void Octree::RemoveManualDrawable(Drawable* drawable) { if (!drawable) return; Octant* octant = drawable->GetOctant(); if (octant && octant->GetRoot() == this) octant->RemoveDrawable(drawable); }