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 }
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); } }
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); }
/// <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); } }
/// <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); }