Esempio n. 1
0
File: KDTree.cs Progetto: Arnyev/MG
        public KDTreeNode(List <int> triangleIndicesA, List <int> triangleIndicesB, SimpleMesh meshA, SimpleMesh meshB, int level, Dimension dimension, Vector3 minValues, Vector3 maxValues, bool additionalSplit)
        {
            MeshA            = meshA;
            MeshB            = meshB;
            _level           = level;
            _dimension       = dimension;
            MinValues        = minValues;
            MaxValues        = maxValues;
            _additionalSplit = additionalSplit;

            MyIndicesA = triangleIndicesA;
            MyIndicesB = triangleIndicesB;

            if (triangleIndicesA.LongCount() * triangleIndicesB.Count >= ExpectedCount)
            {
                PrepareChildNodes(triangleIndicesA, triangleIndicesB, meshA, meshB, level, dimension, minValues,
                                  maxValues);
            }

            _possibleIntersections = MyIndicesA.LongCount() * MyIndicesB.Count;

            if (_possibleIntersections > ExpectedCount * ExpectedCount && _additionalSplit)
            {
                MyIndicesA = new List <int>();
                MyIndicesB = new List <int>();
                PrepareAdditionalSplit(meshA, meshB, dimension, minValues, maxValues);
            }
        }
Esempio n. 2
0
File: KDTree.cs Progetto: Arnyev/MG
        public KDTree(SimpleMesh meshA, SimpleMesh meshB, bool additionalSplit)
        {
            var indicesA = Enumerable.Range(0, meshA.Indices.Count).ToList();
            var indicesB = Enumerable.Range(0, meshB.Indices.Count).ToList();

            var minValues = Vector3.Min(meshA.MinValues, meshB.MinValues);
            var maxValues = Vector3.Max(meshA.MaxValues, meshB.MaxValues);

            StartingNode = new KDTreeNode(indicesA, indicesB, meshA, meshB, 0, Dimension.X, minValues, maxValues, additionalSplit);
        }
Esempio n. 3
0
File: KDTree.cs Progetto: Arnyev/MG
        private void PrepareAdditionalSplit(SimpleMesh meshA, SimpleMesh meshB, Dimension dimension, Vector3 minValues,
                                            Vector3 maxValues)
        {
            var dimDivisor =
                (MyIndicesA.Count > MyIndicesB.Count ? MyIndicesA.Count : MyIndicesB.Count) / ExpectedSmallCount;

            _dividedTrianglesA = new List <int> [dimDivisor];
            _dividedTrianglesB = new List <int> [dimDivisor];

            var ranges = new float[dimDivisor + 1];

            for (int i = 0; i < dimDivisor; i++)
            {
                _dividedTrianglesA[i] = new List <int>();
                _dividedTrianglesB[i] = new List <int>();
            }

            switch (dimension)
            {
            case Dimension.X:
                for (int i = 0; i <= dimDivisor; i++)
                {
                    ranges[i] = minValues.Y + (maxValues.Y - minValues.Y) * i / dimDivisor;
                }

                AdditionallySplitByY(meshA, dimDivisor, ranges, MyIndicesA, _dividedTrianglesA);
                AdditionallySplitByY(meshB, dimDivisor, ranges, MyIndicesB, _dividedTrianglesB);
                break;

            case Dimension.Y:
                for (int i = 0; i <= dimDivisor; i++)
                {
                    ranges[i] = minValues.Z + (maxValues.Z - minValues.Z) * i / dimDivisor;
                }

                AdditionallySplitByZ(meshA, dimDivisor, ranges, MyIndicesA, _dividedTrianglesA);
                AdditionallySplitByZ(meshB, dimDivisor, ranges, MyIndicesB, _dividedTrianglesB);
                break;

            default:

            case Dimension.Z:
                for (int i = 0; i <= dimDivisor; i++)
                {
                    ranges[i] = minValues.X + (maxValues.X - minValues.X) * i / dimDivisor;
                }

                AdditionallySplitByX(meshA, dimDivisor, ranges, MyIndicesA, _dividedTrianglesA);
                AdditionallySplitByX(meshB, dimDivisor, ranges, MyIndicesB, _dividedTrianglesB);
                break;
            }
        }
Esempio n. 4
0
File: KDTree.cs Progetto: Arnyev/MG
        private static void AdditionallySplitByZ(SimpleMesh meshA, long dimDivisor, float[] ranges, List <int> triangleIndices, List <int>[] dividedTriangles)
        {
            foreach (var triIndex in triangleIndices)
            {
                var triangle = meshA.Indices[triIndex];
                var pA       = meshA.Points[triangle.A];
                var pB       = meshA.Points[triangle.B];
                var pC       = meshA.Points[triangle.C];

                float minZ;
                if (pA.Z < pB.Z)
                {
                    minZ = pA.Z < pC.Z ? pA.Z : pC.Z;
                }
                else
                {
                    minZ = pB.Z < pC.Z ? pB.Z : pC.Z;
                }

                float maxZ;
                if (pA.Z > pB.Z)
                {
                    maxZ = pA.Z > pC.Z ? pA.Z : pC.Z;
                }
                else
                {
                    maxZ = pB.Z > pC.Z ? pB.Z : pC.Z;
                }

                for (int i = 0; i < dimDivisor; i++)
                {
                    if (minZ <= ranges[i + 1] && maxZ >= ranges[i])
                    {
                        dividedTriangles[i].Add(triIndex);
                    }
                }
            }
        }
Esempio n. 5
0
File: KDTree.cs Progetto: Arnyev/MG
        private static void AdditionallySplitByY(SimpleMesh meshA, long dimDivisor, float[] ranges, List <int> indices, List <int>[] dividedTriangles)
        {
            foreach (var triIndex in indices)
            {
                var triangle = meshA.Indices[triIndex];
                var pA       = meshA.Points[triangle.A];
                var pB       = meshA.Points[triangle.B];
                var pC       = meshA.Points[triangle.C];

                float minY;
                if (pA.Y < pB.Y)
                {
                    minY = pA.Y < pC.Y ? pA.Y : pC.Y;
                }
                else
                {
                    minY = pB.Y < pC.Y ? pB.Y : pC.Y;
                }

                float maxY;
                if (pA.Y > pB.Y)
                {
                    maxY = pA.Y > pC.Y ? pA.Y : pC.Y;
                }
                else
                {
                    maxY = pB.Y > pC.Y ? pB.Y : pC.Y;
                }

                for (int i = 0; i < dimDivisor; i++)
                {
                    if (minY < ranges[i + 1] && maxY > ranges[i])
                    {
                        dividedTriangles[i].Add(triIndex);
                    }
                }
            }
        }
Esempio n. 6
0
File: KDTree.cs Progetto: Arnyev/MG
        private static void AdditionallySplitByX(SimpleMesh mesh, long dimDivisor, float[] ranges, List <int> triangleIndices, List <int>[] dividedTriangles)
        {
            foreach (var triIndex in triangleIndices)
            {
                var triangle = mesh.Indices[triIndex];
                var pA       = mesh.Points[triangle.A];
                var pB       = mesh.Points[triangle.B];
                var pC       = mesh.Points[triangle.C];

                float minX;
                if (pA.X < pB.X)
                {
                    minX = pA.X < pC.X ? pA.X : pC.X;
                }
                else
                {
                    minX = pB.X < pC.X ? pB.X : pC.X;
                }

                float maxX;
                if (pA.X > pB.X)
                {
                    maxX = pA.X > pC.X ? pA.X : pC.X;
                }
                else
                {
                    maxX = pB.X > pC.X ? pB.X : pC.X;
                }

                for (int i = 0; i < dimDivisor; i++)
                {
                    if (minX < ranges[i + 1] && maxX > ranges[i])
                    {
                        dividedTriangles[i].Add(triIndex);
                    }
                }
            }
        }
Esempio n. 7
0
File: KDTree.cs Progetto: Arnyev/MG
        private static void SplitByZ(List <int> inputIndices, List <int> myTriangleIndices, SimpleMesh mesh, List <int> biggerTriangleIndices, List <int> smallerTriangleIndices, float midZ)
        {
            foreach (var i in inputIndices)
            {
                var triangle = mesh.Indices[i];
                var pA       = mesh.Points[triangle.A];
                var pB       = mesh.Points[triangle.B];
                var pC       = mesh.Points[triangle.C];

                if (pA.Z > midZ && pB.Z > midZ && pC.Z > midZ)
                {
                    biggerTriangleIndices.Add(i);
                }

                else if (pA.Z < midZ && pB.Z < midZ && pC.Z < midZ)
                {
                    smallerTriangleIndices.Add(i);
                }

                else
                {
                    smallerTriangleIndices.Add(i);
                    myTriangleIndices.Add(i);
                    biggerTriangleIndices.Add(i);
                }
            }
        }
Esempio n. 8
0
File: KDTree.cs Progetto: Arnyev/MG
        private void PrepareChildNodes(List <int> triangleIndicesA, List <int> triangleIndicesB, SimpleMesh meshA,
                                       SimpleMesh meshB, int level,
                                       Dimension dimension, Vector3 minValues, Vector3 maxValues)
        {
            MyIndicesA = new List <int>();
            var smallerTriangleIndicesA = new List <int>();
            var biggerTriangleIndicesA  = new List <int>();

            MyIndicesB = new List <int>();
            var smallerTriangleIndicesB = new List <int>();
            var biggerTriangleIndicesB  = new List <int>();

            var     nextDim = NextDimension(dimension);
            Vector3 mid1;
            Vector3 mid2;

            switch (dimension)
            {
            case Dimension.X:
                var midX = (MinValues.X + MaxValues.X) / 2;
                SplitByX(triangleIndicesA, MyIndicesA, meshA, biggerTriangleIndicesA, smallerTriangleIndicesA,
                         midX);
                SplitByX(triangleIndicesB, MyIndicesB, meshB, biggerTriangleIndicesB, smallerTriangleIndicesB,
                         midX);
                mid1 = new Vector3(midX, maxValues.Y, maxValues.Z);
                mid2 = new Vector3(midX, minValues.Y, minValues.Z);
                break;

            case Dimension.Y:
                var midY = (MinValues.Y + MaxValues.Y) / 2;
                SplitByY(triangleIndicesA, MyIndicesA, meshA, biggerTriangleIndicesA, smallerTriangleIndicesA,
                         midY);
                SplitByY(triangleIndicesB, MyIndicesB, meshB, biggerTriangleIndicesB, smallerTriangleIndicesB,
                         midY);
                mid1 = new Vector3(maxValues.X, midY, maxValues.Z);
                mid2 = new Vector3(minValues.X, midY, minValues.Z);
                break;

            default:
            case Dimension.Z:
                var midZ = (MinValues.Z + MaxValues.Z) / 2;
                SplitByZ(triangleIndicesA, MyIndicesA, meshA, biggerTriangleIndicesA, smallerTriangleIndicesA,
                         midZ);
                SplitByZ(triangleIndicesB, MyIndicesB, meshB, biggerTriangleIndicesB, smallerTriangleIndicesB,
                         midZ);
                mid1 = new Vector3(maxValues.X, maxValues.Y, midZ);
                mid2 = new Vector3(minValues.X, minValues.Y, midZ);
                break;
            }

            if (triangleIndicesA.Count * triangleIndicesB.Count > MyIndicesA.Count * MyIndicesB.Count * 2)
            {
                Smaller = new KDTreeNode(smallerTriangleIndicesA, smallerTriangleIndicesB, meshA, meshB, level + 1,
                                         nextDim, minValues, mid1, _additionalSplit);

                Bigger = new KDTreeNode(biggerTriangleIndicesA, biggerTriangleIndicesB, meshA, meshB, level + 1,
                                        nextDim, mid2, maxValues, _additionalSplit);
            }
            else
            {
                MyIndicesA = triangleIndicesA;
                MyIndicesB = triangleIndicesB;
            }
        }