コード例 #1
0
        public KdTree(Triangle[] triangles)
        {
            var minX = float.MaxValue;
            var minY = float.MaxValue;
            var minZ = float.MaxValue;

            var maxX = float.MinValue;
            var maxY = float.MinValue;
            var maxZ = float.MinValue;

            foreach (var triangle in triangles)
            {
                if (minX > triangle.BoxMin.X)
                {
                    minX = triangle.BoxMin.X;
                }
                if (minY > triangle.BoxMin.Y)
                {
                    minY = triangle.BoxMin.Y;
                }
                if (minZ > triangle.BoxMin.Z)
                {
                    minZ = triangle.BoxMin.Z;
                }

                if (maxX < triangle.BoxMax.X)
                {
                    maxX = triangle.BoxMax.X;
                }
                if (maxY < triangle.BoxMax.Y)
                {
                    maxY = triangle.BoxMax.Y;
                }
                if (maxZ < triangle.BoxMax.Z)
                {
                    maxZ = triangle.BoxMax.Z;
                }
            }


            var boxMax = new Vector3(maxX, maxY, maxZ);
            var boxMin = new Vector3(minX, minY, minZ);

            HeadNode = new KdTreeNode(triangles, boxMin, boxMax, 1);
            HeadNode.SplitNode();
        }
コード例 #2
0
        public void SplitNode()
        {
            if (_splitted)
            {
                return;
            }
            _splitted = true;

            if (Triangles == null || Triangles.Length == 0)
            {
                return;
            }

            CalculateElementsAmountInPossibleSubsections();

            var lowestSah    = float.MaxValue;
            var boxSplits    = CalculateSplits();
            var parentSquare = CalculateSquare(BoxMin, BoxMax);

            var bestBoxSplitIndex = 0;
            var axis = 0;
            int nLeft = 0, nRight = 0;

            for (var i = 0; i < SplitsNumber; i++)
            {
                var xRightN = Triangles.Length - _xHigh[i];
                var xLeftN  = Triangles.Length - _xLow[i + 1];
                var yRightN = Triangles.Length - _yHigh[i];
                var yLeftN  = Triangles.Length - _yLow[i + 1];
                var zRightN = Triangles.Length - _zHigh[i];
                var zLeftN  = Triangles.Length - _zLow[i + 1];

                var xLeftSquare  = CalculateSquare(BoxMin, boxSplits[i].LBoxMax);
                var xRightSquare = CalculateSquare(boxSplits[i].RBoxMin, BoxMax);
                var yLeftSquare  = CalculateSquare(BoxMin, boxSplits[i + SplitsNumber].LBoxMax);
                var yRightSquare = CalculateSquare(boxSplits[i + SplitsNumber].RBoxMin, BoxMax);
                var zLeftSquare  = CalculateSquare(BoxMin, boxSplits[i + SplitsNumber * 2].LBoxMax);
                var zRightSquare = CalculateSquare(boxSplits[i + SplitsNumber * 2].RBoxMin, BoxMax);

                var tmpSah = CalculateSah(xLeftSquare, xLeftN, xRightSquare, xRightN, parentSquare);
                if (tmpSah < lowestSah)
                {
                    bestBoxSplitIndex = i;
                    lowestSah         = tmpSah;
                    axis   = 0;
                    nLeft  = xLeftN;
                    nRight = xRightN;
                }

                tmpSah = CalculateSah(yLeftSquare, yLeftN, yRightSquare, yRightN, parentSquare);
                if (tmpSah < lowestSah)
                {
                    bestBoxSplitIndex = i + SplitsNumber;
                    lowestSah         = tmpSah;
                    axis   = 1;
                    nLeft  = yLeftN;
                    nRight = yRightN;
                }

                tmpSah = CalculateSah(zLeftSquare, zLeftN, zRightSquare, zRightN, parentSquare);
                if (tmpSah < lowestSah)
                {
                    bestBoxSplitIndex = i + SplitsNumber * 2;
                    lowestSah         = tmpSah;
                    axis   = 2;
                    nLeft  = zLeftN;
                    nRight = zRightN;
                }
            }

            if (Ci * lowestSah > Triangles.Length || Depth > MaxDepth)
            {
                return;
            }

            Split     = boxSplits[bestBoxSplitIndex];
            SplitAxis = axis;

            var splitTriangles = SplitTriangles(Split, axis, nLeft, nRight);

            LeftNode = new KdTreeNode(splitTriangles[0], BoxMin, Split.LBoxMax, Depth + 1);
            LeftNode.SplitNode();

            RightNode = new KdTreeNode(splitTriangles[1], Split.RBoxMin, BoxMax, Depth + 1);
            RightNode.SplitNode();

            Triangles = null;
        }