Example #1
0
        /// <summary>
        /// Utility method to build KDTreeNode variables, as long as min and max
        /// </summary>
        public void Build()
        {
            Leaf   = new VertexKDTree(new Vector3(maxV + minV) / 2.0f, -1);
            rangeV = maxV - minV;

            SplitAxis = rangeV.LargestAxis();

            BoundingBox = new BoundingBoxAxisAligned(minV, maxV);

            IsBuilt = true;
        }
Example #2
0
        /// <summary>
        /// BoundingBox intersects another BoundingBox
        /// </summary>
        /// <param name="aabb"></param>
        /// <returns></returns>
        public bool Intersects(BoundingBoxAxisAligned aabb)
        {
            Vector3 v1 = aabb.MinCorner;
            Vector3 v2 = aabb.MaxCorner;

            Vector3 v3 = MinCorner;
            Vector3 v4 = MaxCorner;

            return((v4.X >= v1.X) && (v3.X <= v2.X) &&                          //x-axis overlap
                   (v4.Y >= v1.Y) && (v3.Y <= v2.Y) &&                          //y-axis overlap
                   (v4.Y >= v1.Y) && (v3.Y <= v2.Y));                           //z-axis overlap
        }
Example #3
0
        /// <summary>
        /// Find the closest matching vertex
        /// </summary>
        /// <param name="vertex">Vertex to find closest match.</param>
        /// <param name="distance">Search distance.</param>
        /// <param name="nearest_index">Index of matching vertex in the KDTree vertex array</param>
        /// <returns>Nearest matching vertex</returns>
        public VertexKDTree FindClosestPoint(VertexKDTree vertex, ref float distance, ref int nearest_index)
        {
            if (root == null)
            {
                Console.WriteLine("Null root, Build() must be called before using the KDTree.");
                return(new VertexKDTree(new Vector3(0, 0, 0), -1));
            }

            BoundingBoxAxisAligned search_bounds = null;

            if (distance != 0)
            {
                Vector3 distance_vector = new Vector3(distance, distance, distance);
                search_bounds = new BoundingBoxAxisAligned(vertex.Vector - distance_vector, vertex.Vector + distance_vector);
            }
            return(FindClosestPoint_Recursive(Root, vertex, search_bounds, ref nearest_index));
        }
Example #4
0
        /// <summary>
        /// Does BoundingSphere intersect BoundingBoxAxisAligned
        /// </summary>
        /// <notes>
        /// Code modified from: http://tog.acm.org/resources/GraphicsGems/gems/BoxSphere.c
        ///	Support for mixed hollow/solid intersections was dropped.  Only hollow-hollow and solid-solid
        ///	are supported
        /// </notes>
        /// <param name="intersection_type">Defines intersection method</param>
        /// <returns>True if sphere intersects bounding box, else FALSE</returns>
        public bool Intersects(BoundingBoxAxisAligned aabb, IntersectionTypes intersection_type)
        {
            float a, b;
            float r2 = Radius2;
            bool  face;

            switch (intersection_type)
            {
            case IntersectionTypes.HOLLOW:                     // Hollow Box - Hollow Sphere
            {
                float dmin = 0;
                float dmax = 0;
                face = false;
                for (int i = 0; i < 3; i++)
                {
                    a = (float)Math.Pow(Center[i] - aabb.MinCorner[i], 2.0);
                    b = (float)Math.Pow(Center[i] - aabb.MaxCorner[i], 2.0);

                    dmax += Math.Max(a, b);
                    if (Center[i] < aabb.MinCorner[i])
                    {
                        face  = true;
                        dmin += a;
                    }
                    else if (Center[i] > aabb.MaxCorner[i])
                    {
                        face  = true;
                        dmin += b;
                    }
                    else if (Math.Min(a, b) <= r2)
                    {
                        face = true;
                    }
                }
                if (face && (dmin <= r2) && (r2 <= dmax))
                {
                    return(true);
                }
                break;
            }

            case IntersectionTypes.SOLID:                     // Solid Box - Solid Sphere
            {
                float dmin = 0;
                for (int i = 0; i < 3; i++)
                {
                    if (Center[i] < aabb.MinCorner[i])
                    {
                        dmin += (float)Math.Pow(Center[i] - aabb.MinCorner[i], 2.0);
                    }
                    else if (Center[i] > aabb.MaxCorner[i])
                    {
                        dmin += (float)Math.Pow(Center[i] - aabb.MaxCorner[i], 2.0);
                    }
                }
                if (dmin <= r2)
                {
                    return(true);
                }
                break;
            }
            }

            return(false);
        }
Example #5
0
 public bool Intersects(BoundingBoxAxisAligned aabb, IntersectionTypes type)
 {
     return(Intersects(aabb));
 }
Example #6
0
 public BoundingBoxAxisAligned(BoundingBoxAxisAligned aabb)
 {
     MinCorner = aabb.MinCorner;
     MaxCorner = aabb.MaxCorner;
 }
Example #7
0
        /// <summary>
        /// Find closest point using an axis aligned search boundary
        /// </summary>
        /// <param name="node"></param>
        /// <param name="point"></param>
        /// <returns></returns>
        VertexKDTree FindClosestPoint_Recursive(KDNodeJeremyC node, VertexKDTree vertex, BoundingBoxAxisAligned search_bounds, ref int nearest_index)
        {
            int tmp_index = -1;

            if (node.IsLeaf)
            {
                tmp_index = -1;
                VertexKDTree result = GetClosestVertexFromIndices(node.Indices, vertex, ref tmp_index);
                if (result != null)
                {
                    nearest_index = tmp_index;
                    return(result);
                }
                else
                {
                    return(null);
                }
            }

            tmp_index = -1;
            KDNodeJeremyC near_child = node.GetSplitNode(vertex);

            VertexKDTree retV = FindClosestPoint_Recursive(near_child, vertex, search_bounds, ref tmp_index);
            //Edgar - TakenVector implementation - have to go one level up if vector is taken
            float near_distance = float.MaxValue;

            if (retV != null)
            {
                //near_distance = retV.Vector.Distance(vertex.Vector);
                near_distance = retV.Vector.DistanceSquared(vertex.Vector);
                nearest_index = tmp_index;
            }

            KDNodeJeremyC far_child = near_child.Sibling;

            if (search_bounds != null && far_child.BoundingBox.Intersects(search_bounds))
            {
                VertexKDTree far_result = FindClosestPoint_Recursive(far_child, vertex, search_bounds, ref tmp_index);
                //Edgar - TakenVector implementation - have to go one level up if vector is taken
                if (far_result != null)
                {
                    //float far_distance = far_result.Vector.Distance(vertex.Vector);
                    float far_distance = far_result.Vector.DistanceSquared(vertex.Vector);
                    if (far_distance < near_distance)
                    {
                        nearest_index = tmp_index;
                        retV          = far_result;
                    }
                }
            }

            if (retV == null)
            {
            }
            return(retV);
        }