示例#1
0
        public void CalculateStatistic(BvhNode node)
        {
            if (node.IsLeaf)
            {
                _minCount = Math.Min(_minCount, node.Objects.Length);
                _maxCount = Math.Max(_maxCount, node.Objects.Length);
                _totalCount += node.Objects.Length;
                _leafCount++;
            }
            else
            {
                if (node.Left != null)
                    CalculateStatistic(node.Left);

                if (node.Right != null)
                    CalculateStatistic(node.Right);
            }
            if (_leafCount != 0)
            {
                _avrCount = _totalCount / _leafCount;
            }
        }
示例#2
0
        public BvhTree BuildBvhTree(IEnumerable<Geomertry> geomertries, int maxDepth, int minObjPerLeaf, float triangleCost, float boxCost)
        {
            _maxDepth = maxDepth;
            _minObjectsPerLeaf = minObjPerLeaf;
            _triangleCost = triangleCost;
            _boxCost = boxCost;

            Stopwatch stopwatch = new Stopwatch();
            stopwatch.Start();

            _objects = geomertries.Select(Intersectable.CreateIntersectable).ToArray();

            //			BoundingBox rootBoundingBox = OptimisationUtils.GetBoundingBox(geomertries);
            BoundingBox rootBoundingBox = CalculateBoundingBox(_objects);
            BvhNode root = new BvhNode(rootBoundingBox);

            BuildRecursive(root, _objects, 0);

            stopwatch.Stop();
            _loger.Log(Level.Info, string.Format("BVH tree build time: {0} ms", stopwatch.ElapsedMilliseconds));

            return new BvhTree(root);
        }
示例#3
0
 public BvhTree(BvhNode root)
 {
     _root = root;
 }
示例#4
0
        private void GetObjects(Ray ray, BvhNode node, List<Intersectable[]> result)
        {
            if (!ray.Intersects(node.BoundingBox).HasValue)
                return;

            float? leftIntersection = null;
            float? rightIntersection = null;

            BvhNode leftNode = node.Left;
            BvhNode rightNode = node.Right;

            if (leftNode != null)
            {
                leftIntersection = ray.Intersects(leftNode.BoundingBox);
                if (leftIntersection.HasValue)
                {
                    if (leftNode.IsLeaf)
                    {
                        result.Add(leftNode.Objects);
                    }
                    else
                    {
                        GetObjects(ray, leftNode, result);
                    }
                }
            }

            if (rightNode != null)
            {
                rightIntersection = ray.Intersects(rightNode.BoundingBox);
                if (rightIntersection.HasValue)
                {
                    if (rightNode.IsLeaf)
                    {
                        result.Add(rightNode.Objects);
                    }
                    else
                    {
                        GetObjects(ray, rightNode, result);
                    }
                }
            }
        }
示例#5
0
        private float? FindSplit(BvhNode node, Intersectable[] objects, out int axisIndexa)
        {
            float sP = BoxSurface(node.BoundingBox);

            int bestAxis = MaxAxisIndex(node.BoundingBox);
            float? bestSplit = null;
            float minC = float.MaxValue;

            for (int axis = 0; axis < 3; axis++)
            {
                Array.Sort(objects, (objA, objB) => objA.Center.AxisValue(axis).CompareTo(objB.Center.AxisValue(axis)));
                float[] centers = objects.Select(intersectable => intersectable.Center.AxisValue(axis)).ToArray();

                float min = node.BoundingBox.Min.AxisValue(axis);
                float max = node.BoundingBox.Max.AxisValue(axis);
                float step = (max - min)/10;

                for (float split = min + step; split < max; split += step)
                {
                    int splitIndex = Array.BinarySearch(centers, split);
                    splitIndex = splitIndex < 0 ? ~splitIndex : splitIndex;

                    int nL = splitIndex;
                    int nR = objects.Length - splitIndex;

                    float sL = BoxSurface(CalculateBoundingBox(objects, 0, nL));
                    float sR = BoxSurface(CalculateBoundingBox(objects, splitIndex, nR));

                    float c = _boxCost + (sL/sP)*nL*_triangleCost + (sR/sP)*nR*_triangleCost;

                    if (c < minC)
                    {
                        minC = c;
                        bestSplit = split;
                        bestAxis = axis;
                    }
                }
            }

            if (minC < objects.Length*_triangleCost)
            {
                axisIndexa = bestAxis;
                return bestSplit;
            }
            else
            {
                axisIndexa = 1;
                return null;
            }
        }
示例#6
0
        private void CreateAndSplitChildNode(BvhNode node, Intersectable[] objects, int splitIndex, long lenght, int depht)
        {
            var right = CopyArraySection(objects, splitIndex, lenght);

            node.BoundingBox = CalculateBoundingBox(right);

            BuildRecursive(node, right, depht);
        }
示例#7
0
        private void BuildRecursive(BvhNode node, Intersectable[] objects, int depht)
        {
            //var axisIndex = MaxAxisIndex(node.BoundingBox);
            int axisIndex;

            float? splitPoint = FindSplit(node, objects, out axisIndex);

            if (!splitPoint.HasValue || objects.Length < _minObjectsPerLeaf || depht > _maxDepth)
            {
                node.IsLeaf = true;
                node.Objects = objects;
                //Console.WriteLine("{2} {1} {0}", depht, objects.Length, Math.Max(Math.Max(node.BoundingBox.Max.X - node.BoundingBox.Min.X,node.BoundingBox.Max.Y - node.BoundingBox.Min.Y),node.BoundingBox.Max.Z - node.BoundingBox.Min.Z));
                return;
            }

            Array.Sort(objects, (objA, objB) => objA.Center.AxisValue(axisIndex).CompareTo(objB.Center.AxisValue(axisIndex)));
            float[] centers = objects.Select(intersectable => intersectable.Center.AxisValue(axisIndex)).ToArray();

            int splitIndex = Array.BinarySearch(centers, splitPoint);
            splitIndex = splitIndex < 0 ? ~splitIndex : splitIndex;

            long leftLenght = splitIndex;
            if (leftLenght > 0)
            {
                node.Left = new BvhNode();
                CreateAndSplitChildNode(node.Left, objects, 0, leftLenght, depht + 1);
            }

            long rightLenght = objects.LongLength - splitIndex;
            if (rightLenght > 0)
            {
                node.Right = new BvhNode();
                CreateAndSplitChildNode(node.Right, objects, splitIndex, rightLenght, depht + 1);
            }
        }