Exemplo n.º 1
0
        private static void AddObject(SSBVHNodeAdaptor <GO> nAda, ssBVHNode <GO> curNode, GO newOb, ref Bounds_d newObBox, double newObSAH)
        {
            // 1. first we traverse the node looking for the best leaf
            while (curNode.ContainedObjects == null)
            {
                // 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)

                var left  = curNode.Left;
                var right = curNode.Right;

                double leftSAH               = SA(left);
                double rightSAH              = SA(right);
                double sendLeftSAH           = rightSAH + SA(left.Bounds.ExpandedToFit(newObBox));       // (L+N,R)
                double sendRightSAH          = leftSAH + SA(right.Bounds.ExpandedToFit(newObBox));       // (L,R+N)
                double mergedLeftAndRightSAH = SA(BoundsOfPair(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 double MERGE_DISCOUNT = 0.3f;

                if (mergedLeftAndRightSAH < (Math.Min(sendLeftSAH, sendRightSAH)) * MERGE_DISCOUNT)
                {
                    addObject_Pushdown(nAda, curNode, newOb);
                    return;
                }

                if (sendLeftSAH < sendRightSAH)
                {
                    curNode = left;
                }
                else
                {
                    curNode = right;
                }
            }

            // 2. then we add the object and map it to our leaf
            curNode.ContainedObjects.Add(newOb);
            nAda.MapObjectToBvhLeaf(newOb, curNode);
            curNode.RefitVolume(nAda);
            // split if necessary...
            curNode.SplitIfNecessary(nAda);
        }