internal void ComputeVolume(IBVHNodeAdapter <T> nAda)
 {
     AssignVolume(nAda.GetObjectPos(GObjects[0]), nAda.GetRadius(GObjects[0]));
     for (int i = 1; i < GObjects.Count; i++)
     {
         ExpandVolume(nAda, nAda.GetObjectPos(GObjects[i]), nAda.GetRadius(GObjects[i]));
     }
 }
        public void Add(T newOb)
        {
            Bounds box    = BoundsFromSphere(nAda.GetObjectPos(newOb), nAda.GetRadius(newOb));
            float  boxSAH = BVHNode <T> .SA(ref box);

            rootBVH.Add(nAda, newOb, ref box, boxSAH);
        }
        internal void SplitNode(IBVHNodeAdapter <T> nAda)
        {
            // second, decide which axis to split on, and sort..
            List <T> splitlist = GObjects;

            splitlist.ForEach(o => nAda.UnmapObject(o));
            int center = (int)(splitlist.Count / 2);             // find the center object

            SplitAxisOpt <T> bestSplit = EachAxis.Min((axis) =>
            {
                var orderedlist = new List <T>(splitlist);
                switch (axis)
                {
                case Axis.X:
                    orderedlist.Sort(delegate(T go1, T go2) { return(nAda.GetObjectPos(go1).x.CompareTo(nAda.GetObjectPos(go2).x)); });
                    break;

                case Axis.Y:
                    orderedlist.Sort(delegate(T go1, T go2) { return(nAda.GetObjectPos(go1).y.CompareTo(nAda.GetObjectPos(go2).y)); });
                    break;

                case Axis.Z:
                    orderedlist.Sort(delegate(T go1, T go2) { return(nAda.GetObjectPos(go1).z.CompareTo(nAda.GetObjectPos(go2).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 <T>(SAH, axis, left_s, right_s));
            });

            // perform the split
            GObjects   = null;
            this.Left  = new BVHNode <T>(nAda.BVH, this, bestSplit.left, bestSplit.axis, this.Depth + 1);           // Split the Hierarchy to the left
            this.Right = new BVHNode <T>(nAda.BVH, this, bestSplit.right, bestSplit.axis, this.Depth + 1);          // Split the Hierarchy to the right
        }