Пример #1
0
        private void FillAirDensity()
        {
#if DEBUG_IN_SPACE
            m_airDensity = 1f;
#else
            Vector3D gridCentre    = m_grid.GetCentre();
            MyPlanet closestPlanet = MyPlanetExtensions.GetClosestPlanet(gridCentre);
            if (closestPlanet == null)
            {
                m_airDensity = 0f;
            }
            else
            {
                m_airDensity = closestPlanet.GetAirDensity(gridCentre);
            }
#endif
        }
Пример #2
0
        private void Update10()
        {
            MyPlayer player = MySession.Static.LocalHumanPlayer;

            if (player == null)
            {
                return;
            }

            MyCubeBlock block = player.Controller.ControlledEntity as MyCubeBlock;

            if (block == null || block != m_cockpit)
            {
                return;
            }

            bool skipInput = MyGuiScreenGamePlay.ActiveGameplayScreen != null || MyAPIGateway.Input.IsGameControlPressed(MyControlsSpace.LOOKAROUND);

            Log.DebugLog("active screen: " + MyGuiScreenGamePlay.ActiveGameplayScreen, condition: MyGuiScreenGamePlay.ActiveGameplayScreen != null);
            Log.DebugLog("Lookaround", condition: MyAPIGateway.Input.IsGameControlPressed(MyControlsSpace.LOOKAROUND));

            Vector3D gridCentre = m_grid.GetCentre();
            MyPlanet closest    = MyPlanetExtensions.GetClosestPlanet(gridCentre);

            if (closest.GetAirDensity(gridCentre) == 0f)
            {
                return;
            }
            Vector3 gravityDirection = closest.GetWorldGravityNormalized(ref gridCentre);

            if (m_aileron != null)
            {
                AileronHelper(ref gravityDirection, skipInput);
            }
            if (m_elevator != null)
            {
                ElevatorHelper(skipInput);
            }
            if (m_rudder != null)
            {
                RudderHelper(skipInput);
            }
        }
Пример #3
0
        public VoxelLander(Pathfinder pathfinder, bool planet, PseudoBlock landBlock = null)
            : base(pathfinder)
        {
            this.m_landBlock  = landBlock ?? m_navSet.Settings_Current.LandingBlock;
            this.m_targetType = planet ? "Planet" : "Asteroid";

            if (this.m_landBlock == null)
            {
                Log.DebugLog("No landing block", Logger.severity.INFO);
                return;
            }

            IMyLandingGear asGear = m_landBlock.Block as IMyLandingGear;

            if (asGear != null)
            {
                ITerminalProperty <bool> autolock = asGear.GetProperty("Autolock") as ITerminalProperty <bool>;
                Log.DebugLog("autolock == null", Logger.severity.FATAL, condition: autolock == null);
                if (!autolock.GetValue(asGear))
                {
                    autolock.SetValue(asGear, true);
                }
            }

            Vector3D    currentPostion = m_landBlock.WorldPosition;
            MyVoxelBase closest        = null;

            if (planet)
            {
                closest = MyPlanetExtensions.GetClosestPlanet(m_landBlock.WorldPosition);

                if (closest == null)
                {
                    Log.DebugLog("No planets in the world", Logger.severity.WARNING);
                    return;
                }
            }
            else
            {
                BoundingSphereD    search = new BoundingSphereD(currentPostion, 10000d);
                List <MyVoxelBase> nearby = new List <MyVoxelBase>();
                MyGamePruningStructure.GetAllVoxelMapsInSphere(ref search, nearby);

                double closestDistSquared = double.MaxValue;

                foreach (MyVoxelBase voxel in nearby)
                {
                    if (!(voxel is MyVoxelMap))
                    {
                        continue;
                    }

                    double distSquared = Vector3D.DistanceSquared(currentPostion, voxel.GetCentre());
                    if (distSquared < closestDistSquared)
                    {
                        closestDistSquared = distSquared;
                        closest            = voxel;
                    }
                }

                if (closest == null)
                {
                    Log.DebugLog("No asteroids nearby", Logger.severity.WARNING);
                    return;
                }
            }

            Vector3D    end = closest.GetCentre();
            MyVoxelBase hitVoxel;
            Vector3D    hitPosition;

            if (!RayCast.RayCastVoxels(ref currentPostion, ref end, out hitVoxel, out hitPosition))
            {
                throw new Exception("Failed to intersect voxel");
            }

            m_targetPostion = Destination.FromWorld(hitVoxel, hitPosition);

            m_navSet.Settings_Task_NavRot.NavigatorMover = this;
            m_navSet.Settings_Task_NavRot.IgnoreAsteroid = true;

            Log.DebugLog("Landing on " + m_targetType + " at " + m_targetPostion, Logger.severity.DEBUG);
        }
Пример #4
0
        /// <summary>
        /// Starts checking path against the geometry of the closest planet.
        /// </summary>
        /// <param name="displacement">Destination - current postion</param>
        private void Start(ref Vector3 displacement)
        {
            using (m_lock.AcquireExclusiveUsing())
            {
                if ((CurrentState & State.Running) != 0)
                {
                    return;
                }
                CurrentState |= State.Running;

                m_displacement = displacement;

                m_cells.Clear();

                Vector3D gridCentre = m_grid.GetCentre();
                double   distSq;
                gravcomp = MyPlanetExtensions.GetClosestPlanet(gridCentre, out distSq);

                if (gravcomp == null)
                {
                    //m_logger.debugLog("No planets found", "Start()", Logger.severity.TRACE);
                    CurrentState = State.Clear;
                    return;
                }

                if (distSq > gravcomp.MaximumRadius * gravcomp.MaximumRadius)
                {
                    //m_logger.debugLog("Outside maximum radius of closest planet", "Start()", Logger.severity.TRACE);

                    // gravity test
                    // TODO: it might be worthwhile to perform gravity test against multiple planets
                    Path.From = gridCentre;
                    Path.To   = gridCentre + displacement;

                    Vector3D closestPoint = Path.ClosestPoint(gravcomp.WorldMatrix.Translation);
                    if (closestPoint != Path.From && closestPoint != Path.To)
                    {
                        //float gravityAtClose = ClosestPlanet.GetGravityMultiplier(closestPoint) - MinGravityAvoid;
                        float gravityAtClose = gravComp.GetGravityMultiplier(closestPoint) - MinGravityAvoid;
                        //if (gravityAtClose > 0f && gravityAtClose > ClosestPlanet.GetGravityMultiplier(Path.From) && gravityAtClose > ClosestPlanet.GetGravityMultiplier(Path.To))
                        if (gravityAtClose > 0f && gravityAtClose > gravComp.GetGravityMultiplier(Path.From) && gravityAtClose > gravComp.GetGravityMultiplier(Path.To))
                        {
                            ObstructionPoint = closestPoint;
                            CurrentState     = State.BlockedGravity;
                            return;
                        }
                    }

                    CurrentState = State.Clear;
                    return;
                }

                Vector3 direction;
                Vector3.Normalize(ref displacement, out direction);
                direction = Vector3.Transform(direction, m_grid.WorldMatrixNormalizedInv.GetOrientation());

                GridCellCache.GetCellCache(m_grid).ForEach(cell => {
                    Vector3I rejected;
                    Vector3.Reject(cell, direction).ApplyOperation(x => (int)Math.Round(x), out rejected);

                    if (m_cellsUnique.Add(rejected))
                    {
                        m_cells.Enqueue(rejected);
                    }
                });

                m_cellsUnique.Clear();

                DoTests.Enqueue(TestPath);
            }
        }
Пример #5
0
        /// <summary>
        /// Test if it is safe for the grid to rotate.
        /// </summary>
        /// <param name="axis">Normalized axis of rotation in world space.</param>
        /// <param name="ignoreAsteroids"></param>
        /// <returns>True iff the path is clear.</returns>
        public bool TestRotate(Vector3 axis, bool ignoreAsteroids, out IMyEntity obstruction)
        {
            Vector3 centreOfMass = m_grid.Physics.CenterOfMassWorld;
            float   longestDim   = m_grid.GetLongestDim();

            // calculate height
            Matrix  toMyLocal     = m_grid.WorldMatrixNormalizedInv;
            Vector3 myLocalCoM    = Vector3.Transform(centreOfMass, toMyLocal);
            Vector3 myLocalAxis   = Vector3.Transform(axis, toMyLocal.GetOrientation());
            Vector3 myLocalCentre = m_grid.LocalAABB.Center;             // CoM may not be on ship (it now considers mass from attached grids)
            Ray     upper         = new Ray(myLocalCentre + myLocalAxis * longestDim * 2f, -myLocalAxis);
            float?  upperBound    = m_grid.LocalAABB.Intersects(upper);

            if (!upperBound.HasValue)
            {
                m_logger.alwaysLog("Math fail, upperBound does not have a value", Logger.severity.FATAL);
            }
            Ray   lower      = new Ray(myLocalCentre - myLocalAxis * longestDim * 2f, myLocalAxis);
            float?lowerBound = m_grid.LocalAABB.Intersects(lower);

            if (!lowerBound.HasValue)
            {
                m_logger.alwaysLog("Math fail, lowerBound does not have a value", Logger.severity.FATAL);
            }
            m_logger.debugLog("LocalAABB: " + m_grid.LocalAABB + ", centre: " + myLocalCentre + ", axis: " + myLocalAxis + ", longest dimension: " + longestDim + ", upper ray: " + upper + ", lower ray: " + lower);
            float height = longestDim * 4f - upperBound.Value - lowerBound.Value;

            float furthest = 0f;

            m_cells.ForEach(cell => {
                Vector3 rejection     = Vector3.Reject(cell * m_grid.GridSize, myLocalAxis);
                float cellDistSquared = Vector3.DistanceSquared(myLocalCoM, rejection);
                if (cellDistSquared > furthest)
                {
                    furthest = cellDistSquared;
                }
            });
            float length = (float)Math.Sqrt(furthest) + m_grid.GridSize * 0.5f;

            m_logger.debugLog("height: " + height + ", length: " + length);

            BoundingSphereD surroundingSphere = new BoundingSphereD(centreOfMass, Math.Max(length, height));

            m_obstructions.Clear();
            MyGamePruningStructure.GetAllTopMostEntitiesInSphere(ref surroundingSphere, m_obstructions);

            LineSegment axisSegment = new LineSegment();

            ClosestPlanet = MyPlanetExtensions.GetClosestPlanet(centreOfMass);
            MyAPIGateway.Utilities.TryInvokeOnGameThread(TestPlanet);

            foreach (MyEntity entity in m_obstructions)
            {
                if (PathChecker.collect_Entity(m_grid, entity))
                {
                    if (entity is IMyVoxelBase)
                    {
                        if (ignoreAsteroids)
                        {
                            continue;
                        }

                        IMyVoxelMap voxel = entity as IMyVoxelMap;
                        if (voxel != null)
                        {
                            if (voxel.GetIntersectionWithSphere(ref surroundingSphere))
                            {
                                m_logger.debugLog("Too close to " + voxel.getBestName() + ", CoM: " + centreOfMass.ToGpsTag("Centre of Mass") + ", required distance: " + surroundingSphere.Radius);
                                obstruction = voxel;
                                return(false);
                            }
                            continue;
                        }

                        if (PlanetState != Pathfinder.PathState.No_Obstruction)
                        {
                            m_logger.debugLog("planet blocking");
                            obstruction = ClosestPlanet;
                            return(false);
                        }
                        continue;
                    }

                    IMyCubeGrid grid = entity as IMyCubeGrid;
                    if (grid != null)
                    {
                        Matrix  toLocal     = grid.WorldMatrixNormalizedInv;
                        Vector3 localAxis   = Vector3.Transform(axis, toLocal.GetOrientation());
                        Vector3 localCentre = Vector3.Transform(centreOfMass, toLocal);
                        axisSegment.From = localCentre - localAxis * height;
                        axisSegment.To   = localCentre + localAxis * height;

                        bool found = false;
                        GridCellCache.GetCellCache(grid).ForEach(cell => {
                            if (axisSegment.PointInCylinder(length, cell * grid.GridSize))
                            {
                                found = true;
                                return(true);
                            }
                            return(false);
                        });

                        if (found)
                        {
                            obstruction = grid;
                            return(false);
                        }
                        continue;
                    }

                    m_logger.debugLog("No tests for object: " + entity.getBestName(), Logger.severity.INFO);
                    obstruction = entity;
                    return(false);
                }
            }

            obstruction = null;
            return(true);
        }