Пример #1
0
 public static Box Wrap(Box box0, Box box1)
 {
     box0.Include(box1);
     return box0;
 }
Пример #2
0
 public static Box Wrap(Box box0, Box box1)
 {
     box0.Include(box1);
     return(box0);
 }
Пример #3
0
        private static Node BuildNode(List <Entry> elements, Bucket[] buckets)
        {
            Box boundingBox = new Box(new Range(float.MaxValue, float.MinValue));

            foreach (Entry e in elements)
            {
                boundingBox.Include(e.BoundingBox);
            }
            if (elements.Count <= 4)
            {
                LeafNode leaf = new LeafNode(boundingBox);
                leaf.Elements = elements;
                return(leaf);
            }

            InnerNode innerNode = new InnerNode(boundingBox);

            Box centerVolume = new Box(new Range(float.MaxValue, float.MinValue));

            foreach (Entry e in elements)
            {
                centerVolume.Include(e.BoundingBox.Center);
            }


            float minVolume     = float.MaxValue;
            int   useAxis       = -1;
            int   splitAtBucket = 0;

            for (int axis = 0; axis < 3; axis++)
            {
                Range axisRange = centerVolume[axis];
                float extend    = axisRange.Extend;
                if (extend == 0)
                {
                    continue;
                }
                //extend = 1.0f;
                foreach (Entry e in elements)
                {
                    Bucket bucket = buckets[Math.Min(buckets.Length - 1, (int)((e.BoundingBox[axis].Center - axisRange.Min) / extend * buckets.Length))];
                    bucket.Elements.Add(e);
                    bucket.BoundingBox.Include(e.BoundingBox);
                }
                Box   bounds = buckets[0].BoundingBox;
                float volume = bounds.Volume;
                buckets[0].VolumeUntilThis = volume;
                for (int i = 1; i < buckets.Length; i++)
                {
                    if (buckets[i].Elements.Count > 0)
                    {
                        bounds.Include(buckets[i].BoundingBox);
                        volume = bounds.Volume;
                    }
                    buckets[i].VolumeUntilThis = volume;
                    // Debug.WriteLine("volumeUntil(axis " + axis + ", bucket " + i + ") = " + volume);
                }
                bounds = buckets[buckets.Length - 1].BoundingBox;
                volume = bounds.Volume;
                buckets[buckets.Length - 1].VolumeFromThis = volume;
                for (int i = buckets.Length - 2; i > -1; i--)
                {
                    if (buckets[i].Elements.Count > 0)
                    {
                        bounds.Include(buckets[i].BoundingBox);
                        volume = bounds.Volume;
                    }
                    buckets[i].VolumeFromThis = volume;
                    //Debug.WriteLine("volumeFrom(axis " + axis + ", bucket " + i + ") = " + volume);
                }

                for (int b = 1; b < buckets.Length; b++)
                {
                    volume = buckets[b - 1].VolumeUntilThis + buckets[b].VolumeFromThis;
                    if (volume < minVolume)
                    {
                        minVolume     = volume;
                        useAxis       = axis;
                        splitAtBucket = b;
                    }
                    //Debug.WriteLine("volume(axis " + axis + ", split " + b + ") = " + volume);
                }
                foreach (Bucket b in buckets)
                {
                    b.Reset();
                }
            }
            if (useAxis == -1)
            {
                LeafNode leaf = new LeafNode(boundingBox);
                leaf.Elements = elements;
                return(leaf);
            }

            Range axisRange2 = centerVolume[useAxis];
            float extend2    = axisRange2.Extend;

            Debug.Assert(extend2 != 0);

            List <Entry> lower = new List <Entry>(),
                         upper = new List <Entry>();

            foreach (Entry e in elements)
            {
                int bucketIndex = Math.Min(buckets.Length - 1, (int)((e.BoundingBox[useAxis].Center - axisRange2.Min) / extend2 * buckets.Length));
                if (bucketIndex >= splitAtBucket)
                {
                    upper.Add(e);
                }
                else
                {
                    lower.Add(e);
                }
            }

            innerNode.Axis   = useAxis;
            innerNode.Child0 = BuildNode(lower, buckets);
            innerNode.Child1 = BuildNode(upper, buckets);
            return(innerNode);
        }