private BVHInsertion FindBestLocalInsertion(ImplicitBoundingBoxNode aabb, float inheritedCost) { float newArea = GetAABBArea(BoundingBox.CreateMerged(Bound, aabb.Bound)); float asSiblingCost = 2.0f * newArea; float areaDiff = newArea - GetAABBArea(Bound); if (IsLeaf) { BVHInsertion leafInsertion = new BVHInsertion(this, BVHInsertion.InsertionMethod.AsSibling); leafInsertion.Cost = asSiblingCost + inheritedCost; leafInsertion.LocationInheritance = inheritedCost; return(leafInsertion); } float asChildCost = mChildren.Count * areaDiff + newArea; BVHInsertion bestInsertion; if (asSiblingCost < asChildCost) { bestInsertion = new BVHInsertion(this, BVHInsertion.InsertionMethod.AsSibling); bestInsertion.Cost = asSiblingCost + inheritedCost; } else { bestInsertion = new BVHInsertion(this, BVHInsertion.InsertionMethod.AsChild); bestInsertion.Cost = asChildCost + inheritedCost; } bestInsertion.LocationInheritance = mChildren.Count * areaDiff + inheritedCost; return(bestInsertion); }
public void InsertNodeIntoBVH(ImplicitBoundingBoxNode aabb) { // See http://tog.acm.org/resources/RTNews/html/rtnews3a.html#art6 for algorithm details. BVHInsertion bestInsertion = FindBestLocalInsertion(aabb, 0.0f); BVHInsertion bestDeepInsertion = FindBestDeepInsertion(aabb, bestInsertion.LocationInheritance, bestInsertion.Cost); if (bestDeepInsertion.Cost < bestInsertion.Cost) { bestInsertion = bestDeepInsertion; } // Perform insertion. switch (bestInsertion.Method) { case BVHInsertion.InsertionMethod.AsSibling: ImplicitBoundingBoxNode copyOfLocation = new ImplicitBoundingBoxNode(bestInsertion.Location); bestInsertion.Location.IsLeaf = false; bestInsertion.Location.mChildren = new List <SceneNode>(); bestInsertion.Location.AddChild(copyOfLocation); bestInsertion.Location.AddChild(aabb); break; case BVHInsertion.InsertionMethod.AsChild: bestInsertion.Location.AddChild(aabb); break; } // The Bound must be recomputed after this operation. bestInsertion.Location.RecalculateBound(); }
private BVHInsertion FindBestDeepInsertion(ImplicitBoundingBoxNode aabb, float inheritance, float costToBeat) { if (IsLeaf) { return(BVHInsertion.WorstInsertion); } // Find best local insertion cost for each child: BVHInsertion bestChildInsertion = BVHInsertion.WorstInsertion; foreach (ImplicitBoundingBoxNode child in mChildren.OfType <ImplicitBoundingBoxNode>()) { BVHInsertion altChildInsertion = child.FindBestLocalInsertion(aabb, inheritance); if (altChildInsertion.Cost < bestChildInsertion.Cost) { bestChildInsertion = altChildInsertion; } } // Which child had the best local cost? Was it better than our local cost? If so, update the costToBeat. if (bestChildInsertion.Cost < costToBeat) { costToBeat = bestChildInsertion.Cost; } // Finally, explore the deeper insertion costs of that child... // Make sure the child's inheritance permits improvement before recursing. if (bestChildInsertion.LocationInheritance < costToBeat) { BVHInsertion bestChildDeepInsertion = bestChildInsertion.Location.FindBestDeepInsertion(aabb, bestChildInsertion.LocationInheritance, costToBeat); // Compare the deep insertion cost with our best so far... if (bestChildDeepInsertion.Cost < bestChildInsertion.Cost) { return(bestChildDeepInsertion); } } return(bestChildInsertion); }
static BVHInsertion() { WorstInsertion = new BVHInsertion(null, BVHInsertion.InsertionMethod.AsChild); WorstInsertion.Cost = Single.MaxValue; WorstInsertion.LocationInheritance = Single.MaxValue; }
private BVHInsertion FindBestLocalInsertion(ImplicitBoundingBoxNode aabb, float inheritedCost) { float newArea = GetAABBArea(BoundingBox.CreateMerged(Bound, aabb.Bound)); float asSiblingCost = 2.0f * newArea; float areaDiff = newArea - GetAABBArea(Bound); if (IsLeaf) { BVHInsertion leafInsertion = new BVHInsertion(this, BVHInsertion.InsertionMethod.AsSibling); leafInsertion.Cost = asSiblingCost + inheritedCost; leafInsertion.LocationInheritance = inheritedCost; return leafInsertion; } float asChildCost = mChildren.Count * areaDiff + newArea; BVHInsertion bestInsertion; if (asSiblingCost < asChildCost) { bestInsertion = new BVHInsertion(this, BVHInsertion.InsertionMethod.AsSibling); bestInsertion.Cost = asSiblingCost + inheritedCost; } else { bestInsertion = new BVHInsertion(this, BVHInsertion.InsertionMethod.AsChild); bestInsertion.Cost = asChildCost + inheritedCost; } bestInsertion.LocationInheritance = mChildren.Count * areaDiff + inheritedCost; return bestInsertion; }