コード例 #1
0
        internal static void addObject(SSBVHNodeAdaptor <GO> nAda, ssBVHNode <GO> curNode, GO newOb, ref SSAABB newObBox, float newObSAH)
        {
            // 1. first we traverse the node looking for the best leaf
            while (curNode.gobjects == 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;

                float leftSAH               = SA(left);
                float rightSAH              = SA(right);
                float sendLeftSAH           = rightSAH + SA(left.box.ExpandedBy(newObBox)); // (L+N,R)
                float sendRightSAH          = leftSAH + SA(right.box.ExpandedBy(newObBox)); // (L,R+N)
                float mergedLeftAndRightSAH = SA(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)
                {
                    addObject_Pushdown(nAda, curNode, newOb);
                    return;
                }
                else
                {
                    if (sendLeftSAH < sendRightSAH)
                    {
                        curNode = left;
                    }
                    else
                    {
                        curNode = right;
                    }
                }
            }

            // 2. then we add the object and map it to our leaf
            curNode.gobjects.Add(newOb);
            nAda.mapObjectToBVHLeaf(newOb, curNode);
            curNode.refitVolume(nAda);
            // split if necessary...
            curNode.splitIfNecessary(nAda);
        }