Example #1
0
        public string RemapWaypointGroupName(string currentName)
        {
            string name      = currentName;
            uint   endNumber = 0;

            // if the group exists, make another group name by adding _1, _2, _3, ...
            while (MyWayPointGraph.GetPath(name) != null)
            {
                endNumber++;
                if (endNumber == 1)
                {
                    name += "_1";
                }
                else
                {
                    int last_ = name.LastIndexOf('_');
                    name = name.Substring(0, last_ + 1) + endNumber.ToString();
                }

                // name length cap: hashing
                if (name.Length > MyWaypointConstants.MAXIMUM_WAYPOINT_PATH_NAME_LENGTH)
                {
                    endNumber = (uint)name.GetHashCode();
                    name      = "G_" + endNumber.ToString();
                }
            }
            return(name);
        }
Example #2
0
        // Return true if the given waypoints are connected by a path. O(n) (or O(1) if connected components were unchanged)
        /// <summary>This function needs to be called with EntityCloseLock already acquired, or not an issue.</summary>
        public static bool Connected(MyWayPoint v1, MyWayPoint v2)
        {
            int c1 = MyWayPointGraph.GetConnectedComponentId(v1);
            int c2 = MyWayPointGraph.GetConnectedComponentId(v2);

            return(c1 == c2 && c1 != -1);
        }
Example #3
0
        // Return true if the given waypoints are connected by a path. O(n) (or O(1) if connected components were unchanged)
        /// <summary>This function needs to be called with EntityCloseLock already acquired, or not an issue.</summary>
        public static bool Connected(IEnumerable <MyWayPoint> vertices)
        {
            int  component = -1;
            bool first     = true;

            foreach (var v in vertices)
            {
                if (first)
                {
                    component = MyWayPointGraph.GetConnectedComponentId(v);
                    first     = false;
                }
                else
                {
                    int c = MyWayPointGraph.GetConnectedComponentId(v);
                    if (c != component)
                    {
                        return(false);
                    }
                    else if (c == -1)
                    {
                        return(false);               // two vertices that don't lie in the waypoint graph must be unconnected
                    }
                }
            }
            return(true);  // 0 or 1 vertices are always connected
        }
 protected override void OnCancelClick(MyGuiControlButton sender)
 {
     if (m_waypointPath != null)
     {
         if (m_newlyAdded)
         {
             MyWayPointGraph.RemovePath(MyWayPointGraph.SelectedPath);
         }
     }
     CloseScreen();
 }
Example #5
0
 // Remove all edges from this. O(deg(this))
 public void DisconnectFromAllNeighbors()
 {
     using (NeighborsLock.AcquireExclusiveUsing())
     {
         MyWayPointGraph.MakeConnectedComponentsDirty();
         foreach (var v in m_neighbors)
         {
             v.m_neighbors.Remove(this);
         }
         m_neighbors.Clear();
     }
 }
Example #6
0
 // Add a symmetric edge between two vertices. O(1)
 public static void Connect(MyWayPoint v1, MyWayPoint v2)
 {
     if (v1 == v2)
     {
         return;
     }
     using (NeighborsLock.AcquireExclusiveUsing())
     {
         MyWayPointGraph.MakeConnectedComponentsDirty();
         v1.m_neighbors.Add(v2);
         v2.m_neighbors.Add(v1);
     }
 }
        private void LoadWaypointEdges()
        {
            m_edges.Clear();

            BoundingBox bb = BoundingBoxHelper.InitialBox;

            foreach (var part in m_parts)
            {
                if (part != null)
                {
                    BoundingBoxHelper.AddBBox(part.WorldAABB, ref bb);
                }
            }

            m_edges.AddRange(MyWayPointGraph.GetAllEdgesInBox(ref bb));
        }
        /// <summary>
        /// Create entities from action object builders
        /// </summary>
        void AddOrCreate()
        {
            MyEditorGizmo.ClearSelection();

            // Once entities has been created in this action, they remain and if needed, are only removed/added to scene
            if (ActionEntities != null && ActionEntities.Count > 0)
            {
                foreach (MyEntity actionEntity in ActionEntities)
                {
                    AddToScene(actionEntity);
                }
            }
            else
            {
                // If no ActionEntites are present, create them from provided object builders
                foreach (ObjectBuilderCreate crate in ActionObjectBuilders)
                {
                    CreateFromObjectBuilder(crate.ObjectBuilder, crate.Matrix, crate.ScreenPosition);
                }
            }

            // Link the new entities and clean up waypoint vertices
            foreach (var e in ActionEntities)
            {
                e.Link();
            }
            MyWayPointGraph.DeleteNullVerticesFromPaths();

            // When copying a single waypoint, connect it to its source
            if (this is MyEditorActionEntityCopy && ActionEntities.Count == 1 && ActionEntities[0] is MyWayPoint)
            {
                var source = (this as MyEditorActionEntityCopy).SourceEntities[0] as MyWayPoint;
                if (source != null)
                {
                    MyWayPoint.Connect(source, ActionEntities[0] as MyWayPoint);
                }
            }

            // When copying prefabs, connect snap points connections
            if (this is MyEditorActionEntityCopy)
            {
                MyEditor.Static.CopySnapPointLinks((this as MyEditorActionEntityCopy).SourceEntities, (this as MyEditorActionEntityCopy).RemapContext);
            }

            MyEditor.Static.IssueCheckAllCollidingObjects();
        }
Example #9
0
        public virtual void Init(string hudLabelText, MyMwcObjectBuilder_WaypointNew ob, Matrix matrix)
        {
            StringBuilder hudLabelTextSb = (hudLabelText == null) ? null : new StringBuilder(hudLabelText);

            base.Init(hudLabelTextSb, ob);

            objectBuilder = ob;

            SetWorldMatrix(matrix);

            MyWayPointGraph.AddVertex(this);

            this.LocalVolume = new BoundingSphere(Vector3.Zero, MAX_RADIUS_WAYPOINT);
            //VisibleInGame = false;
            Visible     = true;
            Flags      |= EntityFlags.EditableInEditor;
            CastShadows = false;
            UpdateRenderObject(Visible);
        }
Example #10
0
        /// <summary>
        /// This method is called when sector and all entities are loaded (created from object builder - or generated other way).
        /// It raises LinkEntities event, and calls method MyEntities.Link.
        /// </summary>
        public void AfterLoad(MyMwcObjectBuilder_Checkpoint checkpoint)
        {
            CheckpointName = checkpoint.CheckpointName;

            MyEntityIdentifier.AllocationSuspended = false;

            var handler = LinkEntities;

            if (handler != null)
            {
                handler();
            }

            MyEntities.Link();
            MyWayPointGraph.DeleteNullVerticesFromPaths();
            MyWayPointGraph.RemoveWaypointsAroundLargeStaticObjects();
            FactionRelationChanges.Init(checkpoint.FactionRelationChangesBuilder);
            //  GPS waypoints must be created after the first physics pass: see end of MyGuiScreenGamePlay.Update()
        }
Example #11
0
        private void SetBotPath(MySmallShipBot bot)
        {
            bot.WaypointPath = MyWayPointGraph.GetPath(m_wayPointPath);
            bot.PatrolMode   = PatrolMode;

            //check if any leader present
            Bot leader = m_botShips.Find(s => (s.Ship != null && s.Ship.Leader == null));

            if (leader != null)
            {
                bot.Follow(leader.Ship);
            }
            else if (bot.WaypointPath != null)
            {
                bot.Patrol();
            }

            if (Leader != null)
            {
                bot.Follow(Leader);
            }
        }
Example #12
0
        public override bool DebugDraw()
        {            /*
                      * int i = MyWayPointGraph.GetConnectedComponentId(this);
                      * var vertexColor = HsvToRgb((0.36f + i * 0.618034f) % 1.0f, 0.8f, 0.75f);
                      *
                      * DrawWaypointVertex(WorldMatrix.Translation, vertexColor);  // draw only edges for generated waypoints
                      *
                      *
                      * // draw edges
                      * foreach (var neighbor in Neighbors)
                      * {
                      * //DrawWaypointEdge(wp.WorldMatrix.Translation, neighbor.WorldMatrix.Translation, Color.Red, Color.Green);  // selected path: red-green edges
                      *
                      * if (neighbor.WorldMatrix.Translation != WorldMatrix.Translation)
                      * {
                      * Vector3 direction = neighbor.WorldMatrix.Translation - WorldMatrix.Translation;
                      * float lineLength = direction.Length();
                      * direction.Normalize();
                      * MyTransparentGeometry.AddLineBillboard(MyTransparentMaterialEnum.ProjectileTrailLine, Color.Yellow.ToVector4(), WorldMatrix.Translation, direction, lineLength, 0.25f);
                      * }
                      *
                      * }
                      */
            if (((MyHud.ShowDebugWaypoints) || (MyGuiScreenGamePlay.Static.IsEditorActive() && !MyGuiScreenGamePlay.Static.IsIngameEditorActive())) && (MyFakes.ENABLE_GENERATED_WAYPOINTS_IN_EDITOR || MyHud.ShowDebugGeneratedWaypoints || Save))
            {
                // color by connected components
                int i           = MyWayPointGraph.GetConnectedComponentId(this);
                var vertexColor = HsvToRgb((0.36f + i * 0.618034f) % 1.0f, 0.8f, 0.75f);

                if (MyWayPointGraph.SelectedPath != null && MyWayPointGraph.SelectedPath.WayPoints.Contains(this))
                {
                    vertexColor = Color.Orange.ToVector3();  // selected path: orange vertices
                }

                if (IsSecret)
                {
                    vertexColor *= 0.25f;
                }

                // draw vertices
                if (MyEditorGizmo.SelectedEntities.Contains(this))
                {
                    DrawWaypointVertex(WorldMatrix.Translation, vertexColor + (IsSecret ? 1 : 3) * GetHighlightColor());
                    var name = new StringBuilder();
                    if (MyWayPointGraph.SelectedPath != null && MyWayPointGraph.SelectedPath.WayPoints.Contains(this))
                    {
                        name.Append(MyWayPointGraph.SelectedPath.Name).Append(": ").Append(MyWayPointGraph.SelectedPath.WayPoints.IndexOf(this) + 1);
                    }
                    else
                    {
                        name.Append(MyWayPoint.FilterWayPoints(MyEditorGizmo.SelectedEntities).IndexOf(this) + 1);
                    }
                    MyDebugDraw.DrawText(WorldMatrix.Translation, name, Color.White, 1);
                }
                else
                {
                    if (Save)
                    {
                        DrawWaypointVertex(WorldMatrix.Translation, vertexColor);  // for generated waypoints, draw only edges
                    }
                }

                // draw edges
                if (Save || MyHud.ShowDebugGeneratedWaypoints)
                {
                    using (MyWayPoint.NeighborsLock.AcquireSharedUsing())
                    {
                        foreach (var neighbor in Neighbors)
                        {
                            if (MyWayPointGraph.SelectedPath != null && MyWayPointGraph.SelectedPath.ContainsEdge(this, neighbor))
                            {
                                DrawWaypointEdge(WorldMatrix.Translation, neighbor.WorldMatrix.Translation, Color.Yellow, Color.White);  // on selected path: yellow-white
                                continue;
                            }

                            if (neighbor.Save || MyHud.ShowDebugGeneratedWaypoints)
                            {
                                using (MyWayPoint.BlockedEdgesLock.AcquireSharedUsing())
                                {
                                    // blocked for player (by a locked indestructible door: white-gray)
                                    if (BlockedEdgesForPlayer.Contains(Tuple.Create(this, neighbor)) || BlockedEdgesForPlayer.Contains(Tuple.Create(neighbor, this)))
                                    {
                                        DrawWaypointEdge(WorldMatrix.Translation, neighbor.WorldMatrix.Translation, Color.White, Color.Gray);
                                        continue;
                                    }

                                    // blocked for bots by a locked door: black-gray
                                    if (BlockedEdgesForBots.Contains(Tuple.Create(this, neighbor)) || BlockedEdgesForBots.Contains(Tuple.Create(neighbor, this)))
                                    {
                                        DrawWaypointEdge(WorldMatrix.Translation, neighbor.WorldMatrix.Translation, Color.Black, Color.Gray);
                                        continue;
                                    }
                                }

                                // obstructed: violet-white
                                if (MyHud.ShowDebugWaypointsCollisions && Position != neighbor.Position)
                                {
                                    var line = new MyLine(Position, neighbor.Position, true);
                                    if (MyEntities.GetAnyIntersectionWithLine(ref line, null, null, true, true, true, false) != null)
                                    {
                                        DrawWaypointEdge(WorldMatrix.Translation, neighbor.WorldMatrix.Translation, Color.Violet, Color.White);
                                        continue;
                                    }
                                }

                                // normal-normal: red-green
                                // generated-normal: orange-green (normally invisible)
                                // generated-generated: yellow-green (normally invisible)
                                bool generated      = !(Save && neighbor.Save);
                                bool fullyGenerated = !Save && !neighbor.Save;
                                DrawWaypointEdge(WorldMatrix.Translation, neighbor.WorldMatrix.Translation, generated ? fullyGenerated ? Color.Yellow : Color.Orange : Color.Red, Color.Green);
                                continue;
                            }
                        }
                    }
                }
            }
            return(base.DebugDraw());
        }
Example #13
0
 public override void Close()
 {
     MyWayPointGraph.RemoveVertex(this);
     base.Close();
 }
Example #14
0
        // Resolve EntityId links.
        public void ResolveLinks()
        {
            // parent entities (prefabs)
            if (objectBuilder.ParentEntityId != null && MyEntities.GetEntities().Contains(this))
            {
                var parent = MyEntities.GetEntityByIdOrNull(new MyEntityIdentifier((uint)objectBuilder.ParentEntityId.Value));
                if (parent != null)
                {
                    var worldMatrix = WorldMatrix;
                    MyEntities.Remove(this);
                    //parent.Children.Add(this);  // remove it and add back through the parent
                    parent.AddChild(this);
                    this.Activate(true, false);
                    SetWorldMatrix(worldMatrix);
                }
            }

            // neighbors
            foreach (var neighborId in objectBuilder.NeighborEntityIds)
            {
                var neighbor = MyEntities.GetEntityByIdOrNull(new MyEntityIdentifier((uint)neighborId));
                if (neighbor != null && neighbor is MyWayPoint)
                {
                    Connect(this, (MyWayPoint)neighbor);
                }
            }

            // path placing
            for (int i = 0; i < objectBuilder.GroupPlacings.Count; i++)
            {
                var name    = objectBuilder.GroupNames[i];
                var placing = objectBuilder.GroupPlacings[i];

                // resolve path by name: create it if it didn't exist
                MyWayPointPath path = MyWayPointGraph.GetPath(name);
                if (path == null)
                {
                    path = new MyWayPointPath(name);
                }

                // make enough empty waypoints to make it fit
                while (placing >= path.WayPoints.Count)
                {
                    path.WayPoints.Add(null);
                }

                path.WayPoints[placing] = this;
            }

            // can't delete object builder
            // This function is reentrant and sometimes we need both runs.
            //objectBuilder = null;

            // but we can delete neighbor and path info
            if (MyGuiScreenGamePlay.Static.IsGameActive())
            {
                objectBuilder.GroupNames.Clear();
                objectBuilder.GroupPlacings.Clear();
                objectBuilder.NeighborEntityIds.Clear();
            }
        }
Example #15
0
        public void InsertRequiredActors()
        {
            MyMwcLog.WriteLine("InsertRequiredActors - START");

            foreach (MyActorEnum actor in RequiredActors)
            {
                switch (actor)
                {
                //Insert Madelyn
                case MyActorEnum.MADELYN:
                {
                    if (!MyEntities.EntityExists("Madelyn"))
                    {
                        MyMwcLog.WriteLine("Insert Madelyne - START");

                        // Holds ids for remap
                        IMyEntityIdRemapContext remapContext = new MyEntityIdRemapContext();

                        //MyMwcObjectBuilder_SectorObjectGroups groups = MySectorGenerator.LoadSectorGroups(MyTemplateGroups.GetGroupSector(MyTemplateGroupEnum.Madelyn));
                        MyMwcObjectBuilder_SectorObjectGroups groups = MySession.Static.LoadSectorGroups(MyTemplateGroups.GetGroupSector(MyTemplateGroupEnum.Madelyn));
                        System.Diagnostics.Debug.Assert(groups.Groups.Count > 0);

                        MyMwcObjectBuilder_ObjectGroup madelynGroup = groups.Groups[0];
                        groups.RemapEntityIds(remapContext);
                        IEnumerable <MyMwcObjectBuilder_Base> rootObjects = madelynGroup.GetRootBuilders(groups.Entities);

                        List <MyMwcObjectBuilder_Base> clonedList = new List <MyMwcObjectBuilder_Base>();
                        foreach (MyMwcObjectBuilder_Base o in rootObjects)
                        {
                            // Clone
                            var clone = o.Clone() as MyMwcObjectBuilder_Base;
                            // we want Madelyn's prefab container as first builder
                            if (clone is MyMwcObjectBuilder_PrefabContainer)
                            {
                                clonedList.Insert(0, clone);
                            }
                            else
                            {
                                clonedList.Add(clone);
                            }
                        }

                        System.Diagnostics.Debug.Assert(clonedList.Count > 0 && clonedList[0] is MyMwcObjectBuilder_PrefabContainer);

                        // create Madelyn's prefab container
                        MyEntity madelynMothership = MyEntities.CreateFromObjectBuilder(MyTextsWrapper.Get(MyTextsWrapperEnum.Actor_Madelyn).ToString(), clonedList[0], ((MyMwcObjectBuilder_Object3dBase)clonedList[0]).PositionAndOrientation.GetMatrix());
                        madelynMothership.FindChild(MyMissionLocation.MADELYN_HANGAR).DisplayName = MyTextsWrapper.Get(MyTextsWrapperEnum.Sapho).ToString();
                        madelynMothership.SetName(MyActorConstants.GetActorName(MyActorEnum.MADELYN));
                        Matrix madelynMothershipWorldInv = Matrix.Invert(madelynMothership.WorldMatrix);

                        List <MinerWars.AppCode.Game.Entities.WayPoints.MyWayPoint> waypoints = new List <Entities.WayPoints.MyWayPoint>();

                        // create other entities as children of Madelyn's prefab container
                        for (int i = 1; i < clonedList.Count; i++)
                        {
                            System.Diagnostics.Debug.Assert(clonedList[i] is MyMwcObjectBuilder_Object3dBase);
                            MyEntity childEntity = MyEntities.CreateFromObjectBuilder(null, clonedList[i], ((MyMwcObjectBuilder_Object3dBase)clonedList[i]).PositionAndOrientation.GetMatrix());
                            childEntity.SetLocalMatrix(childEntity.WorldMatrix * madelynMothershipWorldInv);
                            madelynMothership.Children.Add(childEntity);
                            if (childEntity is MinerWars.AppCode.Game.Entities.WayPoints.MyWayPoint)
                            {
                                waypoints.Add(childEntity as MinerWars.AppCode.Game.Entities.WayPoints.MyWayPoint);
                            }
                        }

                        // connect waypoints of Madelyn's prefab container
                        foreach (var waypoint in waypoints)
                        {
                            waypoint.ResolveLinks();
                        }

                        // set correct Madelyn's position and add to scene
                        madelynMothership.SetWorldMatrix(MyPlayer.FindMothershipPosition());
                        madelynMothership.Link();
                        MyEntities.Add(madelynMothership);

                        MyMwcLog.WriteLine("Insert Madelyne - END");
                    }
                    else
                    {
                        MyMwcLog.WriteLine("Insert Madelyne - Madelyne already loaded");
                    }

                    MyWayPointGraph.RecreateWaypointsAroundMadelyn();
                }
                break;

                //Insert Marcus
                case MyActorEnum.MARCUS:
                    InsertFriend(MyActorEnum.MARCUS);
                    break;

                //Insert RavenGirl
                case MyActorEnum.TARJA:
                    InsertFriend(MyActorEnum.TARJA);
                    break;

                //Insert RavenGuy
                case MyActorEnum.VALENTIN:
                    InsertFriend(MyActorEnum.VALENTIN, MyMwcObjectBuilder_SmallShip_TypesEnum.HAMMER);
                    break;

                default:
                    System.Diagnostics.Debug.Assert(false, "Uknown actor to insert!");
                    break;
                }
            }

            MyMwcLog.WriteLine("InsertRequiredActors - END");
        }
Example #16
0
        private static List <Vector3> FindPath(Vector3 start, Vector3 end, bool useRaycasts)
        {
            using (MyEntities.EntityCloseLock.AcquireSharedUsing())
            {
                var closestToStart = MyWayPointGraph.GetClosestWaypointReachableByShip(start, null, MyAIConstants.PATHFINDING_MAX_START_RAYCASTS, MyAIConstants.PATHFINDING_SHIP_RADIUS);
                if (closestToStart == null)
                {
                    return(null);
                }

                var closestToEnd = MyWayPointGraph.GetClosestWaypointReachableByShip(end, null, MyAIConstants.PATHFINDING_MAX_END_RAYCASTS, MyAIConstants.PATHFINDING_SHIP_RADIUS);
                if (closestToEnd == null)
                {
                    return(null);
                }

                if (useRaycasts)
                {
                    HashSet <Tuple <MyWayPoint, MyWayPoint> > blockedEdges   = null;
                    HashSet <Tuple <MyWayPoint, MyWayPoint> > unblockedEdges = null;

                    using (MyWayPoint.BlockedEdgesLock.AcquireSharedUsing())
                    {
                        blockedEdges   = new HashSet <Tuple <MyWayPoint, MyWayPoint> >(MyWayPoint.BlockedEdgesForBots); // TODO: do we need to copy this every time?
                        unblockedEdges = new HashSet <Tuple <MyWayPoint, MyWayPoint> >();
                    }

                    for (int retryCount = 0; retryCount < 30; retryCount++)
                    {
                        var pathWaypoints = closestToStart.GetShortestPathTo(closestToEnd, blockedEdges, true, true);
                        if (pathWaypoints == null || pathWaypoints.Count == 0)
                        {
                            return(null);  // no path (we can exit right away since we only *add* blocked edges)
                        }
                        bool blocked = false;
                        for (int i = 0; i < pathWaypoints.Count - 2; i++)
                        {
                            var tuple = Tuple.Create(pathWaypoints[i], pathWaypoints[i + 1]);
                            if (unblockedEdges.Contains(tuple))  // already tested and it was ok
                            {
                            }
                            else if (pathWaypoints[i + 1].IsVisibleFrom(pathWaypoints[i].Position))
                            {
                                unblockedEdges.Add(tuple);
                                unblockedEdges.Add(Tuple.Create(pathWaypoints[i + 1], pathWaypoints[i]));
                            }
                            else
                            {
                                blockedEdges.Add(tuple);
                                blockedEdges.Add(Tuple.Create(pathWaypoints[i + 1], pathWaypoints[i]));
                                blocked = true;
                                break;
                            }
                        }
                        if (blocked)
                        {
                            continue;
                        }

                        var path = new List <Vector3>();
                        path.Add(start);
                        foreach (var waypoint in pathWaypoints)
                        {
                            path.Add(waypoint.Position);
                        }
                        path.Add(end);
                        return(path);
                    }
                    return(null);  // no path found after many tries
                }
                else
                {
                    List <MyWayPoint> pathWaypoints = null;

                    using (MyWayPoint.BlockedEdgesLock.AcquireSharedUsing())
                    {
                        pathWaypoints = closestToStart.GetShortestPathTo(closestToEnd, MyWayPoint.BlockedEdgesForBots, true, true);
                    }

                    if (pathWaypoints == null || pathWaypoints.Count == 0)
                    {
                        return(null);  // no path
                    }
                    var path = new List <Vector3>();
                    path.Add(start);
                    foreach (var waypoint in pathWaypoints)
                    {
                        path.Add(waypoint.Position);
                    }
                    path.Add(end);
                    return(path);
                }
            }
        }
Example #17
0
        void OnAddSelected(MyGuiControlButton sender)
        {
            CloseScreen();

            // Holds ids for remap
            IMyEntityIdRemapContext remapContext = new MyEntityIdRemapContext();

            var newEntities = new List <MyEntity>();

            foreach (var item in m_objectList.GetSelectedItems())
            {
                var builder = m_sectorBuilder.SectorObjects[item.Key];
                builder.RemapEntityIds(remapContext);

                //builder.EntityId = null;                                        // reset entityId because it's new object
                //builder.Name = null;

                //var container = builder as MyMwcObjectBuilder_PrefabContainer;  // reset entityIds also on prefabs in container
                //if (container != null)
                //{
                //    foreach (var prefabBuilder in container.Prefabs)
                //    {
                //        prefabBuilder.EntityId = null;
                //        prefabBuilder.Name = null;
                //    }
                //}

                var entity = CreateFromObjectBuilder(builder);
                if (entity != null)
                {
                    newEntities.Add(entity);
                }
            }

            foreach (var e in newEntities)
            {
                e.Link();
            }

            // recreate snap point links
            var snapPointLinks = m_sectorBuilder.SnapPointLinks;

            foreach (var item in snapPointLinks)
            {
                List <MySnapPointLink> group = new List <MySnapPointLink>();

                foreach (var link in item.Links)
                {
                    MyEntity entity;
                    if (!MyEntities.TryGetEntityById(new MyEntityIdentifier(remapContext.RemapEntityId(link.EntityId).Value), out entity))
                    {
                        continue;
                    }
                    var prefab = entity as MyPrefabBase;
                    if (prefab == null)
                    {
                        continue;
                    }

                    if (string.IsNullOrEmpty(link.SnapPointName))
                    {
                        if (prefab != null && link.Index < prefab.SnapPoints.Count)
                        {
                            group.Add(new MySnapPointLink(prefab.SnapPoints[link.Index]));
                        }
                    }
                    else
                    {
                        foreach (var snapPoint in prefab.SnapPoints)
                        {
                            if (snapPoint.Name == link.SnapPointName)
                            {
                                group.Add(new MySnapPointLink(snapPoint));
                            }
                        }
                    }
                }

                if (group.Count >= 2)
                {
                    MyEditor.Static.AddLinkedSnapPoints(group);
                }
            }

            MyWayPointGraph.DeleteNullVerticesFromPaths();
        }
        public void DoWork()
        {
            try
            {
                MyEntities.EntityCloseLock.AcquireShared();

                if (m_goalEntity == null)
                {
                    return;
                }
                // try the direct path
                {
                    var directLine = new MyLine(m_startPos, m_goalPos, true);
                    if (MyEntities.GetAnyIntersectionWithLine(ref directLine, m_goalEntity, null, true, true, true, false) == null)
                    {
                        Path.Add(m_startPos);
                        Path.Add(m_goalPos);
                        Message = new StringBuilder().AppendFormat(MyTextsWrapper.Get(MyTextsWrapperEnum.GPSDistance).ToString(), Vector3.Distance(m_startPos, m_goalPos));
                        return;
                    }
                }

                // get the closest waypoint to the goal (ignore visibility)
                MyWayPoint goal = MyWayPointGraph.GetClosestNonGeneratedWaypoint(m_goalPos);
                if (goal == null)
                {
                    return;
                }

                // remember which waypoints were visible/invisible from startPos
                // remember blocked/unblocked edges
                var visibleFromStartPosCache = new Dictionary <MyWayPoint, bool>();
                //var blockedEdges = new HashSet<Tuple<MyWayPoint, MyWayPoint>>();
                HashSet <Tuple <MyWayPoint, MyWayPoint> > blockedEdges = null;

                using (MyWayPoint.BlockedEdgesLock.AcquireSharedUsing())
                {
                    blockedEdges = new HashSet <Tuple <MyWayPoint, MyWayPoint> >(MyWayPoint.BlockedEdgesForPlayer);
                }

                var unblockedEdges = new HashSet <Tuple <MyWayPoint, MyWayPoint> >();

                // get 7 closest visible waypoints to startPos and compute shortest paths from them

                // first try 7 closest
                var closestVisibleWaypoints = MyWayPointGraph.GetClosestVisibleWaypoints(m_startPos, m_goalEntity, 7, 7, visibleFromStartPosCache);

                if (closestVisibleWaypoints.Count == 0 || !FindPathBetweenWaypoints(closestVisibleWaypoints, goal, visibleFromStartPosCache, blockedEdges, unblockedEdges))
                {
                    // failure: try 50 closest
                    closestVisibleWaypoints = MyWayPointGraph.GetClosestVisibleWaypoints(m_startPos, m_goalEntity, 12, 50, visibleFromStartPosCache);

                    if (closestVisibleWaypoints.Count == 0 || !FindPathBetweenWaypoints(closestVisibleWaypoints, goal, visibleFromStartPosCache, blockedEdges, unblockedEdges))
                    {
                        return;  // no use
                    }
                }
            }
            finally
            {
                if (m_goalEntity != null)
                {
                    m_goalEntity.OnClose -= goalEntity_OnClose;
                }

                MyEntities.EntityCloseLock.ReleaseShared();
            }
        }
Example #19
0
        // Get the shortest path to the goal vertex using the A* algorithm. Return an empty list if the goal is unreachable.
        /// <summary>This function needs to be called with EntityCloseLock already acquired, or not an issue.</summary>
        public List <MyWayPoint> GetShortestPathTo(MyWayPoint goal, HashSet <Tuple <MyWayPoint, MyWayPoint> > blockedEdges = null, bool useGeneratedWaypoints = true, bool useSecretWaypoints = true)
        {
            lock (m_shortestPathLock)
            {
                if (Connected(this, goal) && (useGeneratedWaypoints || (Save && goal.Save)) && (useSecretWaypoints || (!IsSecret && !goal.IsSecret)))
                {
                    // use next search id, handle overflow
                    m_searchId++;
                    if (m_searchId == int.MaxValue)
                    {
                        MyWayPointGraph.ResetAllVisitedSearchIds();
                        m_searchId = 1;
                    }

                    // seen but yet unvisited vertices; add start vertex
                    m_openSet.Clear();
                    m_fScore   = Distance(this, goal); // estimate distance to goal as Euclidean (= consistent)
                    m_gScore   = 0;
                    m_cameFrom = this;
                    m_openSet.Add(this);

                    int num = 0;

                    while (m_openSet.Count != 0)
                    {
                        if (num++ > MyWayPointGraph.WaypointCount() + 10)
                        {
                            int maxSearchId = 0;
                            foreach (var v in MyWayPointGraph.GetCopyOfAllWaypoints())
                            {
                                maxSearchId = Math.Max(maxSearchId, v.m_visitedSearchId);
                            }
                            Debug.Fail(string.Format(
                                           "Infinite path search... contact JanK! \nDebug info: set_count={0} start_end_connected={1} current_search_id={2} max_search_id={3}",
                                           m_openSet.Count,
                                           Connected(this, goal),
                                           m_searchId,
                                           maxSearchId
                                           ));
                            break;
                        }

                        var current = m_openSet.Min;  // get vertex with the smallest f (ties: highest g)
                        m_openSet.Remove(current);
                        if (current == goal)
                        {
                            return(ReconstructPath(goal));       // found the shortest path, return it
                        }
                        current.m_visitedSearchId = m_searchId;  // mark current as visited

                        using (NeighborsLock.AcquireSharedUsing())
                        {
                            // look at all neighbors
                            foreach (var neighbor in current.m_neighbors)
                            {
                                if (!useGeneratedWaypoints && !neighbor.Save)
                                {
                                    continue;                                            // generated
                                }
                                if (!useSecretWaypoints && neighbor.IsSecret)
                                {
                                    continue;                                            // secret
                                }
                                if (neighbor.m_visitedSearchId == m_searchId)
                                {
                                    continue;                                            // already visited
                                }
                                if (blockedEdges != null && blockedEdges.Contains(Tuple.Create(current, neighbor)))
                                {
                                    continue;                                                                                  // blocked
                                }
                                var gScoreThroughCurrent = current.m_gScore + Distance(current, neighbor);

                                if (m_openSet.Contains(neighbor))  // already seen
                                {
                                    if (gScoreThroughCurrent < neighbor.m_gScore)
                                    {
                                        m_openSet.Remove(neighbor);                                            // path through current is better: remove neighbor and put it back with updated score
                                    }
                                    else
                                    {
                                        continue;
                                    }
                                }

                                neighbor.m_fScore   = gScoreThroughCurrent + Distance(neighbor, goal);
                                neighbor.m_gScore   = gScoreThroughCurrent;
                                neighbor.m_cameFrom = current;
                                m_openSet.Add(neighbor);
                            }
                        }
                    }
                }
            }
            return(new List <MyWayPoint>());  // unreachable
        }
Example #20
0
 private void ShowWayPoints(MyGuiControlCheckbox sender)
 {
     MyHud.ShowDebugWaypoints = !MyHud.ShowDebugWaypoints;
     MyWayPointGraph.SetVisibilityOfAllWaypoints(MyHud.ShowDebugWaypoints);
 }
        public static Matrix UpdateShapePosition()
        {
            if (DetachedVoxelHand != null)
            {
                VoxelHandShape.MoveAndRotate(DetachedVoxelHand.WorldMatrix.Translation, DetachedVoxelHand.WorldMatrix);
                return(DetachedVoxelHand.WorldMatrix);
            }

            Matrix world = Matrix.Identity;

            float   minDist = 2 * VoxelHandShape.LocalVolume.Radius;
            float   dist    = 2 * minDist;
            Vector3 from    = MyCamera.Position - MyCamera.UpVector * minDist * 0.5f;

            if (IsProjected)
            {
                if (!MyFakes.MWBUILDER)
                {
                    var line = new MyLine(from, from + MyCamera.ForwardVector * 10000, true);
                    var hit  = MyEntities.GetIntersectionWithLine_IgnoreOtherThanSpecifiedClass(ref line, new System.Type[] { typeof(MyVoxelMap) });
                    if (hit != null)
                    {
                        dist = Vector3.Distance(MyCamera.Position, hit.Value.IntersectionPointInWorldSpace);
                    }
                    else
                    {
                        dist = 5000;
                    }

                    m_conePosition = from + MyCamera.ForwardVector * minDist * 0.7f;
                    Vector3 shapePosition = from + MyCamera.ForwardVector * (dist + VoxelHandShape.LocalVolume.Radius * m_distance * 2);
                    Vector3 shapeForward  = Vector3.Normalize(MyCamera.UpVector * minDist * 0.5f + shapePosition - from);
                    Vector3 shapeUp       = shapeForward - MyCamera.ForwardVector + MyCamera.UpVector;
                    world = Matrix.CreateWorld(shapePosition, shapeForward, shapeUp);
                    VoxelHandShape.MoveAndRotate(shapePosition, world);
                    return(world);
                }
                else
                {
                    var     line   = new MyLine(from, from + MyCamera.ForwardVector * 10000, true);
                    var     hit    = MyEntities.GetIntersectionWithLine_IgnoreOtherThanSpecifiedClass(ref line, new System.Type[] { typeof(MyVoxelMap) });
                    Vector3 normal = Vector3.Up;
                    dist = 5000;
                    Vector3 shapePosition = from + MyCamera.ForwardVector * dist;
                    if (hit != null)
                    {
                        dist          = Vector3.Distance(MyCamera.Position, hit.Value.IntersectionPointInWorldSpace);
                        normal        = hit.Value.NormalInWorldSpace;
                        shapePosition = hit.Value.IntersectionPointInWorldSpace;
                    }


                    m_conePosition = from + MyCamera.ForwardVector * minDist * 0.7f;

                    Vector3 shapeUp      = normal;
                    Vector3 shapeForward = Vector3.Cross(-MyCamera.LeftVector, shapeUp);
                    float   dot          = Vector3.Dot(shapeUp, shapeForward);
                    if ((dot > 0.9f) || (dot < -0.9f))
                    {
                        shapeForward = Vector3.Forward;
                    }

                    shapePosition.X = MyEditorGrid.GetGridStepInMeters() *
                                      (float)Math.Round(shapePosition.X / MyEditorGrid.GetGridStepInMeters());
                    shapePosition.Y = MyEditorGrid.GetGridStepInMeters() *
                                      (float)Math.Round(shapePosition.Y / MyEditorGrid.GetGridStepInMeters());
                    shapePosition.Z = MyEditorGrid.GetGridStepInMeters() *
                                      (float)Math.Round(shapePosition.Z / MyEditorGrid.GetGridStepInMeters());


                    world = Matrix.CreateWorld(shapePosition, shapeForward, shapeUp);
                    VoxelHandShape.MoveAndRotate(shapePosition, world);
                    return(world);
                }
            }
            else if (IsProjectedToWaypoints)
            {
                //Lets find projection on closest collision with waypoint edge
                from           = MyCamera.Position - MyCamera.UpVector * 10.5f;
                m_conePosition = from + MyCamera.ForwardVector * 10.7f;
                Vector3 shapePosition = from + MyCamera.ForwardVector * m_distance;

                List <Tuple <MyWayPoint, MyWayPoint> > edges = MyWayPointGraph.GetAllEdgesInSphere(shapePosition, VoxelHandShape.LocalVolume.Radius * 2);

                Tuple <MyWayPoint, MyWayPoint> closestEdge = null;
                float   minDistance           = float.MaxValue;
                Vector3 closestPoint          = shapePosition;
                float   distFromFirstWaypoint = 0;

                foreach (Tuple <MyWayPoint, MyWayPoint> edge in edges)
                {
                    Vector3 linePos1 = edge.Item1.Position;
                    Vector3 linePos2 = edge.Item2.Position;

                    Vector3 point = MyUtils.GetClosestPointOnLine(ref linePos1, ref linePos2, ref shapePosition, out distFromFirstWaypoint);

                    float distance = Vector3.Distance(shapePosition, point);
                    if (distance < minDistance)
                    {
                        minDistance  = distance;
                        closestEdge  = edge;
                        closestPoint = point;
                    }
                }

                if (closestEdge != null)
                {
                    shapePosition = closestPoint;

                    Vector3 shapeForward = Vector3.Normalize(shapePosition - from);
                    Vector3 shapeUp      = MyCamera.UpVector;
                    world = Matrix.CreateWorld(shapePosition, shapeForward, shapeUp);
                    VoxelHandShape.MoveAndRotate(shapePosition, world);

                    MyWayPoint firstWaypoint  = null;
                    MyWayPoint secondWaypoint = null;
                    float      edgeDistance   = Vector3.Distance(closestEdge.Item1.Position, closestEdge.Item2.Position);

                    if (closestEdge.Item1.Position.Y < closestEdge.Item2.Position.Y)
                    {
                        firstWaypoint  = closestEdge.Item1;
                        secondWaypoint = closestEdge.Item2;
                    }
                    else
                    {
                        firstWaypoint         = closestEdge.Item2;
                        secondWaypoint        = closestEdge.Item1;
                        distFromFirstWaypoint = edgeDistance - distFromFirstWaypoint;
                    }

                    float edgeRatio = edgeDistance > 0 ? distFromFirstWaypoint / edgeDistance : 0;

                    Quaternion quaternion1 = Quaternion.CreateFromRotationMatrix(closestEdge.Item1.WorldMatrix);
                    Quaternion quaternion2 = Quaternion.CreateFromRotationMatrix(closestEdge.Item2.WorldMatrix);

                    Quaternion resultQuaternion = Quaternion.Lerp(quaternion1, quaternion2, edgeRatio);

                    Matrix resultMatrix = Matrix.CreateFromQuaternion(resultQuaternion);
                    resultMatrix.Translation = shapePosition;

                    VoxelHandShape.MoveAndRotate(shapePosition, resultMatrix);

                    return(resultMatrix);
                }
            }

            if (MyFakes.MWBUILDER)
            {
                from           = MyCamera.Position;
                m_conePosition = from + MyCamera.ForwardVector * 10.7f;

                /*
                 * //Vector3 planeNormal = new Vector3(MyCamera.ForwardVector.X, 0, MyCamera.ForwardVector.Z);
                 * Vector3 planeNormal = new Vector3(0, MyCamera.ForwardVector.Y, MyCamera.ForwardVector.Z);
                 *
                 *
                 * planeNormal.Normalize();
                 * Vector3 planePoint = planePoint = from + planeNormal * m_distance;
                 * planeNormal = -planeNormal;
                 *
                 * Plane plane = new Plane(planeNormal, -Vector3.Dot(planeNormal, planePoint));
                 *
                 * Ray r = new Ray(from, MyCamera.ForwardVector);
                 * float? intr = r.Intersects(plane); */
                // if (intr.HasValue)
                {
                    Vector3 shapePosition = from + MyCamera.ForwardVector * m_distance;
                    Vector3 shapeForward  = Vector3.Forward;
                    Vector3 shapeUp       = Vector3.Up;

                    shapePosition.X = MyEditorGrid.GetGridStepInMeters() *
                                      (float)Math.Round(shapePosition.X / MyEditorGrid.GetGridStepInMeters());
                    shapePosition.Y = MyEditorGrid.GetGridStepInMeters() *
                                      (float)Math.Round(shapePosition.Y / MyEditorGrid.GetGridStepInMeters());
                    shapePosition.Z = MyEditorGrid.GetGridStepInMeters() *
                                      (float)Math.Round(shapePosition.Z / MyEditorGrid.GetGridStepInMeters());

                    world = Matrix.CreateWorld(shapePosition, shapeForward, shapeUp);
                    VoxelHandShape.MoveAndRotate(shapePosition, world);
                }
            }
            else
            {
                from           = MyCamera.Position - MyCamera.UpVector * 10.5f;
                m_conePosition = from + MyCamera.ForwardVector * 10.7f;
                Vector3 shapePosition = from + MyCamera.ForwardVector * m_distance;
                Vector3 shapeForward  = Vector3.Normalize(/*MyCamera.UpVector * minDist * 0.5f*/ shapePosition - from);
                Vector3 shapeUp       = /*shapeForward - MyCamera.ForwardVector +*/ MyCamera.UpVector;
                world = Matrix.CreateWorld(shapePosition, shapeForward, shapeUp);
                VoxelHandShape.MoveAndRotate(shapePosition, world);
            }

            return(world);
        }