internal void splitNode(SSBVHNodeAdaptor <GO> nAda) { // second, decide which axis to split on, and sort.. List <GO> splitlist = gobjects; splitlist.ForEach(o => nAda.unmapObject(o)); Axis splitAxis = pickSplitAxis(); switch (splitAxis) // sort along the appropriate axis { case Axis.X: splitlist.Sort(delegate(GO go1, GO go2) { return(nAda.objectpos(go1).X.CompareTo(nAda.objectpos(go2).X)); }); break; case Axis.Y: splitlist.Sort(delegate(GO go1, GO go2) { return(nAda.objectpos(go1).Y.CompareTo(nAda.objectpos(go2).Y)); }); break; case Axis.Z: splitlist.Sort(delegate(GO go1, GO go2) { return(nAda.objectpos(go1).Z.CompareTo(nAda.objectpos(go2).Z)); }); break; default: throw new NotImplementedException(); } int center = (int)(splitlist.Count / 2); // Find the center object in our current sub-list gobjects = null; // create the new left and right nodes... left = new ssBVHNode <GO>(nAda.BVH, this, splitlist.GetRange(0, center), splitAxis, this.depth + 1); // Split the Hierarchy to the left right = new ssBVHNode <GO>(nAda.BVH, this, splitlist.GetRange(center, splitlist.Count - center), splitAxis, this.depth + 1); // Split the Hierarchy to the right }
// TODO: will need to calculate center of AABB internal void splitNode(SSBVHNodeAdaptor <GO> nAda) { // second, decide which axis to split on, and sort.. List <GO> splitlist = gobjects; splitlist.ForEach(o => nAda.unmapObject(o)); int center = (int)(splitlist.Count / 2); // find the center object SplitAxisOpt <GO> bestSplit = eachAxis.Min((axis) => { var orderedlist = new List <GO>(splitlist); switch (axis) { case Axis.X: orderedlist.Sort(delegate(GO go1, GO go2) { return(nAda.boundingBox(go1).Center().X.CompareTo(nAda.boundingBox(go2).Center().X)); }); break; case Axis.Y: orderedlist.Sort(delegate(GO go1, GO go2) { return(nAda.boundingBox(go1).Center().Y.CompareTo(nAda.boundingBox(go2).Center().Y)); }); break; case Axis.Z: orderedlist.Sort(delegate(GO go1, GO go2) { return(nAda.boundingBox(go1).Center().Z.CompareTo(nAda.boundingBox(go2).Center().Z)); }); break; default: throw new NotImplementedException("unknown split axis: " + axis.ToString()); } var left_s = orderedlist.GetRange(0, center); var right_s = orderedlist.GetRange(center, splitlist.Count - center); float SAH = SAofList(nAda, left_s) * left_s.Count + SAofList(nAda, right_s) * right_s.Count; return(new SplitAxisOpt <GO>(SAH, axis, left_s, right_s)); }); // perform the split gobjects = null; this.left = new ssBVHNode <GO>(nAda.BVH, this, bestSplit.left, bestSplit.axis, this.depth + 1); // Split the Hierarchy to the left this.right = new ssBVHNode <GO>(nAda.BVH, this, bestSplit.right, bestSplit.axis, this.depth + 1); // Split the Hierarchy to the right }
internal void removeObject(SSBVHNodeAdaptor <GO> nAda, GO newOb) { if (gobjects == null) { throw new Exception("removeObject() called on nonLeaf!"); } nAda.unmapObject(newOb); gobjects.Remove(newOb); if (gobjects.Count > 0) { refitVolume(nAda); } else { // our leaf is empty, so collapse it if we are not the root... if (parent != null) { gobjects = null; parent.removeLeaf(nAda, this); parent = null; } } }