Ejemplo n.º 1
0
        public void TestBvhClosestIntersection()
        {
            // for this shape imagine the 8 corners of a Rubik's cube and the center
            var data = new List <BvhTreeItemData <int> >();

            // left, front, bottom
            data.Add(new BvhTreeItemData <int>(0, new AxisAlignedBoundingBox(0, 0, 0, 1, 1, 1)));
            // right, front, bottom
            data.Add(new BvhTreeItemData <int>(1, new AxisAlignedBoundingBox(2, 0, 0, 3, 1, 1)));
            // left, back, bottom
            data.Add(new BvhTreeItemData <int>(2, new AxisAlignedBoundingBox(0, 2, 0, 1, 3, 1)));
            // right, back, bottom
            data.Add(new BvhTreeItemData <int>(3, new AxisAlignedBoundingBox(2, 2, 0, 3, 3, 1)));
            // center, center, center
            data.Add(new BvhTreeItemData <int>(4, new AxisAlignedBoundingBox(1, 1, 1, 2, 2, 2)));
            // left, front, top
            data.Add(new BvhTreeItemData <int>(5, new AxisAlignedBoundingBox(0, 0, 2, 1, 1, 3)));
            // right, front, top
            data.Add(new BvhTreeItemData <int>(6, new AxisAlignedBoundingBox(2, 0, 2, 3, 1, 3)));
            // left, back, top
            data.Add(new BvhTreeItemData <int>(7, new AxisAlignedBoundingBox(0, 2, 2, 1, 3, 3)));
            // right, back, top
            data.Add(new BvhTreeItemData <int>(8, new AxisAlignedBoundingBox(2, 2, 2, 3, 3, 3)));
            var bvhBuilder = new TradeOffBvhConstructor <int>();
            var tree       = bvhBuilder.CreateNewHierachy(data);

            Assert.AreEqual(7, tree.CountBranches(), "these must be split up into multiple bounds");

            var hitInfo = tree.GetClosestIntersection(new Ray(new Vector3(-.5, .5, .5), Vector3.UnitX));

            Assert.IsNotNull(hitInfo, "found a hit");
            Assert.AreEqual(0, hitInfo.ClosestHitObject, "found the left front bottom");
            Assert.AreEqual(.5, hitInfo.DistanceToHit);
            Assert.AreEqual(new Vector3(0, .5, .5), hitInfo.HitPosition);
            Assert.AreEqual(IntersectionType.FrontFace, hitInfo.HitType);
            Assert.AreEqual(new Vector3(-1, 0, 0), hitInfo.NormalAtHit);

            hitInfo = tree.GetClosestIntersection(new Ray(new Vector3(3.5, .5, .5), -Vector3.UnitX));
            Assert.IsNotNull(hitInfo, "found a hit");
            Assert.AreEqual(1, hitInfo.ClosestHitObject, "found the right front bottom");
            Assert.AreEqual(.5, hitInfo.DistanceToHit);
            Assert.AreEqual(new Vector3(3, .5, .5), hitInfo.HitPosition);
            Assert.AreEqual(IntersectionType.FrontFace, hitInfo.HitType);
            Assert.AreEqual(new Vector3(1, 0, 0), hitInfo.NormalAtHit);

            hitInfo = tree.GetClosestIntersection(new Ray(new Vector3(-.5, 1.5, 1.5), -Vector3.UnitX));
            Assert.IsNull(hitInfo, "Found no items.");

            hitInfo = tree.GetClosestIntersection(new Ray(new Vector3(-.5, 1.5, 1.5), Vector3.UnitX));
            Assert.AreEqual(4, hitInfo.ClosestHitObject, "Found only center.");
            Assert.AreEqual(new Vector3(1, 1.5, 1.5), hitInfo.HitPosition);
            Assert.AreEqual(IntersectionType.FrontFace, hitInfo.HitType);
            Assert.AreEqual(new Vector3(-1, 0, 0), hitInfo.NormalAtHit);
        }
Ejemplo n.º 2
0
        public void TestBvhTreeSearches()
        {
            // for this shape imagine the 8 corners of a Rubik's cube and the center
            var data = new List <BvhTreeItemData <int> >();

            // left, front, bottom
            data.Add(new BvhTreeItemData <int>(0, new AxisAlignedBoundingBox(0, 0, 0, 1, 1, 1)));
            // right, front, bottom
            data.Add(new BvhTreeItemData <int>(1, new AxisAlignedBoundingBox(2, 0, 0, 3, 1, 1)));
            // left, back, bottom
            data.Add(new BvhTreeItemData <int>(2, new AxisAlignedBoundingBox(0, 2, 0, 1, 3, 1)));
            // right, back, bottom
            data.Add(new BvhTreeItemData <int>(3, new AxisAlignedBoundingBox(2, 2, 0, 3, 3, 1)));
            // center, center, center
            data.Add(new BvhTreeItemData <int>(4, new AxisAlignedBoundingBox(1, 1, 1, 2, 2, 2)));
            // left, front, top
            data.Add(new BvhTreeItemData <int>(5, new AxisAlignedBoundingBox(0, 0, 2, 1, 1, 3)));
            // right, front, top
            data.Add(new BvhTreeItemData <int>(6, new AxisAlignedBoundingBox(2, 0, 2, 3, 1, 3)));
            // left, back, top
            data.Add(new BvhTreeItemData <int>(7, new AxisAlignedBoundingBox(0, 2, 2, 1, 3, 3)));
            // right, back, top
            data.Add(new BvhTreeItemData <int>(8, new AxisAlignedBoundingBox(2, 2, 2, 3, 3, 3)));
            var bvhBuilder = new TradeOffBvhConstructor <int>();
            var tree       = bvhBuilder.CreateNewHierachy(data);

            Assert.AreEqual(7, tree.CountBranches(), "these must be split up into multiple bounds");

            var results = new List <int>();

            tree.SearchBounds(new AxisAlignedBoundingBox(0, 0, 0, 3, 3, 3), results);
            Assert.AreEqual(results.Count(), 9, "Found all items.");

            results.Clear();
            tree.SearchPoint(1.5, 1.5, 1.5, results);
            Assert.AreEqual(1, results.Count(), "All or around this point.");
            Assert.AreEqual(4, results[0], "found the center point.");

            results.Clear();
            tree.SearchBounds(new AxisAlignedBoundingBox(1.5, 1.5, 0, 3, 3, 3), results);
            Assert.AreEqual(3, results.Count(), "All or around this point.");
            Assert.IsTrue(results.Contains(4), "found the center point.");
            Assert.IsTrue(results.Contains(8), "found the center point.");
            Assert.IsTrue(results.Contains(3), "found the center point.");
        }
Ejemplo n.º 3
0
        public void TestBvhSimpleTreeSearches()
        {
            var data = new List <BvhTreeItemData <int> >();

            data.Add(new BvhTreeItemData <int>(1, new AxisAlignedBoundingBox(-10, -20, -30, 10, 20, 30)));
            data.Add(new BvhTreeItemData <int>(2, new AxisAlignedBoundingBox(-9, -18, -29, 9, 19, 29)));
            data.Add(new BvhTreeItemData <int>(3, new AxisAlignedBoundingBox(-9, -17, -29, 9, 19, 28)));
            data.Add(new BvhTreeItemData <int>(4, new AxisAlignedBoundingBox(-9, -16, -29, 9, 19, 27)));

            var bvhBuilder = new TradeOffBvhConstructor <int>();
            var tree       = bvhBuilder.CreateNewHierachy(data);

            Assert.IsTrue(tree.CountBranches() == 1, "all the bounds overlap, there is no value in splitting them up");

            var results = new List <int>();

            tree.SearchBounds(new AxisAlignedBoundingBox(-9, -19, -29, 9, 19, 29), results);
            Assert.AreEqual(results.Count(), 4, "Found all items.");

            results.Clear();
            tree.SearchPoint(0, 0, 0, results);
            Assert.AreEqual(4, results.Count(), "All or around this point.");
        }
Ejemplo n.º 4
0
        public void MergeVertices(double treatAsSameDistance)
        {
            if (Vertices.Count < 2)
            {
                return;
            }

            var sameDistance = new Vector3Float(treatAsSameDistance, treatAsSameDistance, treatAsSameDistance);
            var tinyDistance = new Vector3Float(.001, .001, .001);
            // build a bvh tree of all the vertices
            var bvhBuilder = new TradeOffBvhConstructor <int>();
            var bvhTree    = bvhBuilder.CreateNewHierachy(this.Vertices
                                                          .Select((v, i) => new BvhTreeItemData <int>(i, new AxisAlignedBoundingBox(v - tinyDistance, v + tinyDistance))).ToList());

            var newVertices         = new List <Vector3Float>(Vertices.Count);
            var vertexIndexRemaping = Enumerable.Range(0, Vertices.Count).Select(i => - 1).ToList();
            var searchResults       = new List <int>();

            // build up the list of index mapping
            for (int i = 0; i < Vertices.Count; i++)
            {
                // first check if we have already found this vertex
                if (vertexIndexRemaping[i] == -1)
                {
                    var vertex = Vertices[i];
                    // remember the new index
                    var newIndex = newVertices.Count;
                    // add it to the vertices we will end up with
                    newVertices.Add(vertex);
                    // clear for new search
                    searchResults.Clear();
                    // find everything close
                    bvhTree.SearchBounds(new AxisAlignedBoundingBox(vertex - sameDistance, vertex + sameDistance), searchResults);
                    // map them to this new vertex
                    foreach (var result in searchResults)
                    {
                        // this vertex has not been mapped
                        if (vertexIndexRemaping[result] == -1)
                        {
                            vertexIndexRemaping[result] = newIndex;
                        }
                    }
                }
            }

            // now make a new face list with the merge vertices
            int GetIndex(int originalIndex)
            {
                return(vertexIndexRemaping[originalIndex]);
            }

            var newFaces = new FaceList();

            foreach (var face in Faces)
            {
                int iv0 = GetIndex(face.v0);
                int iv1 = GetIndex(face.v1);
                int iv2 = GetIndex(face.v2);
                if (iv0 != iv1 && iv1 != iv2 && iv2 != iv0)
                {
                    newFaces.Add(iv0, iv1, iv2, newVertices);
                }
            }

            this.Faces    = newFaces;
            this.Vertices = newVertices;
        }
Ejemplo n.º 5
0
        public void TestBvhAlongRay()
        {
            // for this shape imagine the 8 corners of a Rubik's cube and the center
            var data = new List <BvhTreeItemData <int> >();

            // left, front, bottom
            data.Add(new BvhTreeItemData <int>(0, new AxisAlignedBoundingBox(0, 0, 0, 1, 1, 1)));
            // right, front, bottom
            data.Add(new BvhTreeItemData <int>(1, new AxisAlignedBoundingBox(2, 0, 0, 3, 1, 1)));
            // left, back, bottom
            data.Add(new BvhTreeItemData <int>(2, new AxisAlignedBoundingBox(0, 2, 0, 1, 3, 1)));
            // right, back, bottom
            data.Add(new BvhTreeItemData <int>(3, new AxisAlignedBoundingBox(2, 2, 0, 3, 3, 1)));
            // center, center, center
            data.Add(new BvhTreeItemData <int>(4, new AxisAlignedBoundingBox(1, 1, 1, 2, 2, 2)));
            // left, front, top
            data.Add(new BvhTreeItemData <int>(5, new AxisAlignedBoundingBox(0, 0, 2, 1, 1, 3)));
            // right, front, top
            data.Add(new BvhTreeItemData <int>(6, new AxisAlignedBoundingBox(2, 0, 2, 3, 1, 3)));
            // left, back, top
            data.Add(new BvhTreeItemData <int>(7, new AxisAlignedBoundingBox(0, 2, 2, 1, 3, 3)));
            // right, back, top
            data.Add(new BvhTreeItemData <int>(8, new AxisAlignedBoundingBox(2, 2, 2, 3, 3, 3)));
            var bvhBuilder = new TradeOffBvhConstructor <int>();
            var tree       = bvhBuilder.CreateNewHierachy(data);

            Assert.AreEqual(7, tree.CountBranches(), "these must be split up into multiple bounds");

            var results = new List <int>();

            tree.AlongRay(new Ray(new Vector3(-.5, .5, .5), Vector3.UnitX), results);
            Assert.AreEqual(results.Count(), 2, "Found all items.");
            Assert.IsTrue(results.Contains(0), "found the front left point.");
            Assert.IsTrue(results.Contains(1), "found the front right point.");

            results.Clear();
            tree.AlongRay(new Ray(new Vector3(-.5, 1.5, 1.5), -Vector3.UnitX), results);
            Assert.AreEqual(results.Count(), 0, "Found no items.");

            results.Clear();
            tree.AlongRay(new Ray(new Vector3(-.5, 1.5, 1.5), Vector3.UnitX), results);
            Assert.AreEqual(results.Count(), 1, "Found only center.");
            Assert.IsTrue(results.Contains(4), "found the center point.");

            results.Clear();
            tree.AlongRay(new Ray(new Vector3(-.5, -.5, -.5), new Vector3(1, 1, 1).GetNormal()), results);
            Assert.AreEqual(results.Count(), 3, "Found all items.");
            Assert.IsTrue(results.Contains(0), "found the left front bottom.");
            Assert.IsTrue(results.Contains(4), "found the center.");
            Assert.IsTrue(results.Contains(8), "found the right back top.");

            results.Clear();
            var shortRay = new Ray(new Vector3(-.5, -.5, -.5), new Vector3(1, 1, 1).GetNormal())
            {
                maxDistanceToConsider = 1
            };

            tree.AlongRay(shortRay, results);
            Assert.AreEqual(results.Count(), 1, "Found all items.");
            Assert.IsTrue(results.Contains(0), "found the left front bottom.");
        }