Пример #1
0
        /// <summary>
        /// Recursively split node across its pivot axis.
        /// </summary>
        /// <param name="node">KDTreeNode to split</param>
        /// <param name="depth">Current recursion depth, set lower if you get stack overflow</param>
        /// <returns>True if split was a success or max_depth/max_node_size criterion met</returns>
        bool BuildNode(KDNodeJeremyC node, int depth)
        {
            if (depth >= MaxNodeDepth)
            {
                return(true);
            }
            if (node.Indices.Count <= MaxNodeSize)
            {
                return(true);
            }

            foreach (var index in node.Indices)
            {
                VertexKDTree vertex = TreeVectors[index];

                if (!node.IsBuilt)
                {
                    node.Build();
                }
                KDNodeJeremyC child = node.GetSplitNode(vertex);
                child.AddVertex(index, vertex);
            }

            // TODO:  Do we need to check if either child is empty?  Since we're calculating the split axis
            //		  using raw data it's unlikely.
            node.Clear();
            node.ChildLeft.Build();
            node.ChildRight.Build();

            BuildNode(node.ChildLeft, depth + 1);
            BuildNode(node.ChildRight, depth + 1);
            return(true);
        }
Пример #2
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);
        }
Пример #3
0
        /// <summary>
        /// Find closest point using a centered bounding sphere
        /// </summary>
        /// <param name="node"></param>
        /// <param name="vertex"></param>
        /// <param name="search_bounds"></param>
        /// <param name="nearest_index"></param>
        /// <returns></returns>
        VertexKDTree FindClosestPoint(KDNodeJeremyC node, VertexKDTree vertex, BoundingSphere 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);
                nearest_index = tmp_index;
                return(result);
            }

            tmp_index = -1;
            KDNodeJeremyC near_child  = node.GetSplitNode(vertex);
            VertexKDTree  near_result = FindClosestPoint(near_child, vertex, search_bounds, ref tmp_index);
            VertexKDTree  ret         = near_result;
            //float near_distance = near_result.Vector.Distance(vertex.Vector);
            float near_distance = near_result.Vector.DistanceSquared(vertex.Vector);

            nearest_index = tmp_index;

            KDNodeJeremyC far_child = near_child.Sibling;

            if (far_child.BoundingBox.Intersects(search_bounds))
            {
                VertexKDTree far_result   = FindClosestPoint(far_child, vertex, search_bounds, ref tmp_index);
                float        far_distance = far_result.Vector.DistanceSquared(vertex.Vector);
                //float far_distance = far_result.Vector.Distance(vertex.Vector);
                if (far_distance < near_distance)
                {
                    nearest_index = tmp_index;
                    ret           = far_result;
                }
            }
            return(ret);
        }