public void addObject(GO newOb) { SSAABB box = SSAABB.FromSphere(nAda.objectpos(newOb), nAda.radius(newOb)); float boxSAH = ssBVHNode <GO> .SA(ref box); rootBVH.addObject(nAda, newOb, ref box, boxSAH); }
public void addObject(GO newOb) { SSAABB box = nAda.boundingBox(newOb); float boxSAH = ssBVHNode <GO> .SA(ref box); rootBVH.addObject(nAda, newOb, ref box, boxSAH); }
internal void addObject(SSBVHNodeAdaptor <GO> nAda, GO newOb, ref SSAABB newObBox, float newObSAH) { if (gobjects != null) { // add the object and map it to our leaf gobjects.Add(newOb); nAda.mapObjectToBVHLeaf(newOb, this); refitVolume(nAda); // split if necessary... splitIfNecessary(nAda); } else { // find the best way to add this object.. 3 options.. // 1. send to left node (L+N,R) // 2. send to right node (L,R+N) // 3. merge and pushdown left-and-right node (L+R,N) float leftSAH = SAH(left); float rightSAH = SAH(right); float sendLeftSAH = rightSAH + SAH(left.box.ExpandedBy(newObBox)); // (L+N,R) float sendRightSAH = leftSAH + SAH(right.box.ExpandedBy(newObBox)); // (L,R+N) float mergedLeftAndRightSAH = SAH(AABBofPair(left, right)) + newObSAH; // (L+R,N) // Doing a merge-and-pushdown can be expensive, so we only do it if it's notably better const float MERGE_DISCOUNT = 0.3f; if (mergedLeftAndRightSAH < (Math.Min(sendLeftSAH, sendRightSAH)) * MERGE_DISCOUNT) { // merge and pushdown left and right as a new node.. var mSubnode = new ssBVHNode <GO>(nAda.BVH); mSubnode.left = left; mSubnode.right = right; mSubnode.parent = this; mSubnode.gobjects = null; // we need to be an interior node... so null out our object list.. left.parent = mSubnode; right.parent = mSubnode; mSubnode.childRefit(nAda, recurse: false); // make new subnode for obj var nSubnode = new ssBVHNode <GO>(nAda.BVH); nSubnode.parent = this; nSubnode.gobjects = new List <GO> { newOb }; nAda.mapObjectToBVHLeaf(newOb, nSubnode); nSubnode.computeVolume(nAda); // make assignments.. this.left = mSubnode; this.right = nSubnode; this.setDepth(this.depth); // propagate new depths to our children. this.childRefit(nAda); } else { if (sendLeftSAH < sendRightSAH) { // send left left.addObject(nAda, newOb, ref newObBox, newObSAH); } else { // send right right.addObject(nAda, newOb, ref newObBox, newObSAH); } } } }