public int RemoveCollisionShapesWithHandleInternal(long handle) { // The dumb version: iterate over all containment spheres // looking for obstacles with the given handle, returning true // if a child changed. (The smarter version would maintain an // index mapping handles to SphereTreeNodes whose // containedShape or intersectingShapes have a shape with // that handle.) // // This runs bottom-up, to provide an opportunity to coalesce // the sphere tree. // intersectingShapes are easy - - just remove if they have a // matching handle, since their removal doesn't change the tree int removeCount = 0; for (int i = 0; i < intersectingShapes.Count; i++) { CollisionShape obstacle = intersectingShapes[i]; if (obstacle.handle == handle) { if (MO.DoLog) { MO.Log(" Removing intersecting shape {0} of {1}", obstacle, this); } intersectingShapes.RemoveAt(i); i--; sphereTree.intersectingShapeCount--; Debug.Assert(sphereTree.intersectingShapeCount >= 0, "intersectingShapeCount < 0!"); } } // Now handle the children for (int i = 0; i < childCount; i++) { SphereTreeNode child = children[i]; if (child != null) { if (child.leafNode && child.containedShape.handle == handle) { if (MO.DoLog) { MO.Log(" Removing child leaf {0} of {1}", child, this); } children[i] = null; child.parent = null; RenderedNode.RemoveNodeRendering(child.id, ref child.renderedNodes); sphereTree.shapesRemoved++; sphereTree.nodeCount--; removeCount++; } else if (!child.leafNode) { removeCount += child.RemoveCollisionShapesWithHandleInternal(handle); } } } int count = CountChildren(); if (count == 0 && containedShape == null) { // This is now a truly pointless node - - remove from its // parent. Parent will only be null for the root node if (parent != null) { if (MO.DoLog) { MO.Log(" Removing branch with no kids {0} of {1}", this, parent); } parent.RemoveChild(this); sphereTree.nodeCount--; Debug.Assert(sphereTree.nodeCount > 0, "nodeCount <= 0"); return(removeCount); } } else if (count == 1) { if (parent != null) { // Make my child the child of my parent if (MO.DoLog) { MO.Log(" Replacing 1-child node {0} in parent {1}", this, parent); } parent.ReplaceChild(this, FindFirstChild()); sphereTree.nodeCount--; Debug.Assert(sphereTree.nodeCount > 0, "nodeCount <= 0"); return(removeCount); } } if (removeCount > 0) { RecalculateCenterAndRadius(); } return(removeCount); }