예제 #1
0
        private static float HlCriterion(MyNavigationPrimitive primitive)
        {
            MyHighLevelPrimitive item = primitive as MyHighLevelPrimitive;

            if ((item == null) || m_pathfindingStatic.m_ignoredPrimitives.Contains(item))
            {
                return(float.PositiveInfinity);
            }
            float num = m_pathfindingStatic.m_destination.PointAdmissibility(primitive.WorldPosition, 8.7f);

            if (num < float.PositiveInfinity)
            {
                return(num * 4f);
            }
            IMyHighLevelComponent component = item.GetComponent();

            return((component != null) ? (component.FullyExplored ? float.PositiveInfinity : (((float)Vector3D.RectangularDistance(primitive.WorldPosition, m_pathfindingStatic.m_destinationCenter)) * 8f)) : float.PositiveInfinity);
        }
예제 #2
0
        private void ExpandPath(Vector3D currentPosition)
        {
            if (m_pathNodePosition >= m_pathNodes.Count - 1)
            {
                ProfilerShort.Begin("GenerateHighLevelPath");
                GenerateHighLevelPath();
                ProfilerShort.End();
            }

            if (m_pathNodePosition >= m_pathNodes.Count)
            {
                return;
            }

            MyPath <MyNavigationPrimitive> path = null;
            bool isLastPath = false;

            m_expandedPath.Clear();
            if (m_pathNodePosition + 1 < m_pathNodes.Count)
            {
                if (m_pathNodes[m_pathNodePosition].IsExpanded)
                {
                    if (m_pathNodes[m_pathNodePosition + 1].IsExpanded)
                    {
                        IMyHighLevelComponent component      = m_pathNodes[m_pathNodePosition].GetComponent();
                        IMyHighLevelComponent otherComponent = m_pathNodes[m_pathNodePosition + 1].GetComponent();

                        // CH: TODO: Preallocate the functions to avoid using lambdas.
                        ProfilerShort.Begin("FindPath to next compo");
                        path = m_pathfinding.FindPath(m_currentPrimitive, m_goal.PathfindingHeuristic, (prim) => otherComponent.Contains(prim) ? 0.0f : float.PositiveInfinity, (prim) => component.Contains(prim) || otherComponent.Contains(prim));
                        ProfilerShort.End();
                    }
                    else
                    {
                        Debug.Assert(!MyFakes.SHOW_PATH_EXPANSION_ASSERTS, "First hierarchy path node is expanded, but the second one is not! First two nodes should always be expanded so that pathfinding can be done.");
                    }
                }
                else
                {
                    Debug.Assert(!MyFakes.SHOW_PATH_EXPANSION_ASSERTS, "Nodes of smart path are not expanded!");
                }
            }
            else
            {
                if (m_pathNodes[m_pathNodePosition].IsExpanded)
                {
                    // Try to find a path to a goal primitive inside the last high level component.
                    // If the last primitive of the found path is not in the last high level component, add that component to the goal's ignore list
                    IMyHighLevelComponent component = m_pathNodes[m_pathNodePosition].GetComponent();

                    ProfilerShort.Begin("FindPath to goal in the last component");
                    path = m_pathfinding.FindPath(m_currentPrimitive, m_goal.PathfindingHeuristic, (prim) => component.Contains(prim) ? m_goal.TerminationCriterion(prim) : 30.0f, (prim) => component.Contains(prim));
                    ProfilerShort.End();

                    if (path != null)
                    {
                        // We reached goal
                        if (path.Count != 0 && component.Contains(path[path.Count - 1].Vertex as MyNavigationPrimitive))
                        {
                            isLastPath = true;
                        }
                        // We reached other component (goal could not be reached in this component)
                        else
                        {
                            m_goal.IgnoreHighLevel(m_pathNodes[m_pathNodePosition]);
                        }
                    }
                }
                else
                {
                    Debug.Assert(!MyFakes.SHOW_PATH_EXPANSION_ASSERTS, "Nodes of smart path are not expanded!");
                }
            }

            if (path == null || path.Count == 0)
            {
                return;
            }

            Vector3D end           = default(Vector3D);
            var      lastPrimitive = path[path.Count - 1].Vertex as MyNavigationPrimitive;

            if (isLastPath)
            {
                Vector3 endPoint = m_goal.Destination.GetBestPoint(lastPrimitive.WorldPosition);
                Vector3 localEnd = lastPrimitive.Group.GlobalToLocal(endPoint);
                localEnd = lastPrimitive.ProjectLocalPoint(localEnd);
                end      = lastPrimitive.Group.LocalToGlobal(localEnd);
            }
            else
            {
                end = lastPrimitive.WorldPosition;
            }

            RefineFoundPath(ref currentPosition, ref end, path);

            // If the path is too short, don't use it to prevent jerking in stuck situations
            if (m_pathNodes.Count <= 1 && isLastPath && m_expandedPath.Count > 0 && path.Count <= 2 && !m_goal.ShouldReinitPath())
            {
                Vector4D end4D = m_expandedPath[m_expandedPath.Count - 1];
                // Here, 256 is just a small enough value to catch most false-positives
                if (Vector3D.DistanceSquared(currentPosition, end) < end4D.W * end4D.W / 256)
                {
                    m_expandedPath.Clear();
                }
            }
        }
예제 #3
0
 private void ExpandPath(Vector3D currentPosition)
 {
     if (this.m_pathNodePosition >= (this.m_pathNodes.Count - 1))
     {
         this.GenerateHighLevelPath();
     }
     if (this.m_pathNodePosition < this.m_pathNodes.Count)
     {
         MyPath <MyNavigationPrimitive> path = null;
         bool flag = false;
         this.m_expandedPath.Clear();
         if ((this.m_pathNodePosition + 1) < this.m_pathNodes.Count)
         {
             if (this.m_pathNodes[this.m_pathNodePosition].IsExpanded && this.m_pathNodes[this.m_pathNodePosition + 1].IsExpanded)
             {
                 IMyHighLevelComponent component      = this.m_pathNodes[this.m_pathNodePosition].GetComponent();
                 IMyHighLevelComponent otherComponent = this.m_pathNodes[this.m_pathNodePosition + 1].GetComponent();
                 path = this.m_pathfinding.FindPath(this.m_currentPrimitive, this.m_goal.PathfindingHeuristic, prim => otherComponent.Contains(prim) ? 0f : float.PositiveInfinity, prim => component.Contains(prim) || otherComponent.Contains(prim), true);
             }
         }
         else if (this.m_pathNodes[this.m_pathNodePosition].IsExpanded)
         {
             IMyHighLevelComponent component1 = this.m_pathNodes[this.m_pathNodePosition].GetComponent();
             path = this.m_pathfinding.FindPath(this.m_currentPrimitive, this.m_goal.PathfindingHeuristic, prim => component1.Contains(prim) ? this.m_goal.TerminationCriterion(prim) : 30f, prim => component1.Contains(prim), true);
             if (path != null)
             {
                 if ((path.Count == 0) || !component1.Contains(path[path.Count - 1].Vertex as MyNavigationPrimitive))
                 {
                     this.m_goal.IgnoreHighLevel(this.m_pathNodes[this.m_pathNodePosition]);
                 }
                 else
                 {
                     flag = true;
                 }
             }
         }
         if ((path != null) && (path.Count != 0))
         {
             Vector3D end = new Vector3D();
             MyNavigationPrimitive vertex = path[path.Count - 1].Vertex as MyNavigationPrimitive;
             if (!flag)
             {
                 end = vertex.WorldPosition;
             }
             else
             {
                 Vector3 bestPoint = (Vector3)this.m_goal.Destination.GetBestPoint(vertex.WorldPosition);
                 Vector3 localPos  = vertex.ProjectLocalPoint(vertex.Group.GlobalToLocal(bestPoint));
                 end = vertex.Group.LocalToGlobal(localPos);
             }
             this.RefineFoundPath(ref currentPosition, ref end, path);
             if ((((this.m_pathNodes.Count <= 1) & flag) && ((this.m_expandedPath.Count > 0) && (path.Count <= 2))) && !this.m_goal.ShouldReinitPath())
             {
                 Vector4D vectord2 = this.m_expandedPath[this.m_expandedPath.Count - 1];
                 if (Vector3D.DistanceSquared(currentPosition, end) < ((vectord2.W * vectord2.W) / 256.0))
                 {
                     this.m_expandedPath.Clear();
                 }
             }
         }
     }
 }