public static (Vector3 pos, Vector3 Velocity) GetRalitiveState(Entity entity) { var pos = entity.GetDataBlob <PositionDB>().RelativePosition_m; if (entity.HasDataBlob <OrbitDB>()) { var datetime = entity.StarSysDateTime; var orbit = entity.GetDataBlob <OrbitDB>(); var vel = OrbitProcessor.InstantaneousOrbitalVelocityVector_m(orbit, datetime); return(pos, vel); } if (entity.HasDataBlob <OrbitUpdateOftenDB>()) { var datetime = entity.StarSysDateTime; var orbit = entity.GetDataBlob <OrbitUpdateOftenDB>(); var vel = OrbitProcessor.InstantaneousOrbitalVelocityVector_m(orbit, datetime); return(pos, vel); } if (entity.HasDataBlob <NewtonMoveDB>()) { var move = entity.GetDataBlob <NewtonMoveDB>(); var vel = move.CurrentVector_ms; return(pos, vel); } if (entity.HasDataBlob <ColonyInfoDB>()) { var daylen = entity.GetDataBlob <ColonyInfoDB>().PlanetEntity.GetDataBlob <SystemBodyInfoDB>().LengthOfDay.TotalSeconds; var radius = pos.Length(); var d = 2 * Math.PI * radius; var speed = d / daylen; Vector3 vel = new Vector3(0, speed, 0); var posAngle = Math.Atan2(pos.Y, pos.X); var mtx = Matrix3d.IDRotateZ(posAngle + (Math.PI * 0.5)); Vector3 transformedVector = mtx.Transform(vel); return(pos, transformedVector); } else { throw new Exception("Entity has no velocity"); } }
/// <summary> /// This asteroid was destroyed, see if it is big enough for child asteroids to spawn, and if so spawn them. /// </summary> /// <param name="Asteroid"></param> internal static void SpawnSubAsteroids(Entity Asteroid, DateTime atDateTime) { Game game = Asteroid.Manager.Game; MassVolumeDB ADB = Asteroid.GetDataBlob <MassVolumeDB>(); //const double massDefault = 1.5e+12; //150 B tonnes? const double massThreshold = 1.5e+9; //150 M tonnes? if (ADB.Mass > massThreshold) { //spawn new asteroids. call the asteroid factory? double newMass = ADB.Mass * 0.4; //add a random factor into this? do we care? will mass be printed to the player? OrbitDB origOrbit = Asteroid.GetDataBlob <OrbitDB>(); PositionDB pDB = Asteroid.GetDataBlob <PositionDB>(); EntityManager mySystem = Asteroid.Manager; var origVel = OrbitProcessor.AbsoluteOrbitalVector_AU(origOrbit, atDateTime); //public static Entity CreateAsteroid(StarSystem starSys, Entity target, DateTime collisionDate, double asteroidMass = -1.0) //I need the target entity, the collisionDate, and the starSystem. I may have starsystem from guid. //Ok so this should create the asteroid without having to add the new asteroids to a list. as that is done in the factory. Entity newAsteroid1 = AsteroidFactory.CreateAsteroid4(pDB.AbsolutePosition_AU, origOrbit, atDateTime, newMass); //var newOrbit = OrbitDB.FromVector(origOrbit.Parent, ) Entity newAsteroid2 = AsteroidFactory.CreateAsteroid4(pDB.AbsolutePosition_AU, origOrbit, atDateTime, newMass); mySystem.RemoveEntity(Asteroid); //Randomize the number of created asteroids? } else { //delete the existing asteroid. PositionDB pDB = Asteroid.GetDataBlob <PositionDB>(); StarSystem mySystem; if (!game.Systems.TryGetValue(pDB.SystemGuid, out mySystem)) { throw new GuidNotFoundException(pDB.SystemGuid); } mySystem.RemoveEntity(Asteroid); } }
/// <summary> /// Calculates a cartisian position for an intercept for a ship and an target's orbit. /// </summary> /// <returns>The intercept position and DateTime</returns> /// <param name="mover">The entity that is trying to intercept a target.</param> /// <param name="targetOrbit">Target orbit.</param> /// <param name="atDateTime">Datetime of transit start</param> public static (Vector3 position, DateTime etiDateTime) GetInterceptPosition(Entity mover, OrbitDB targetOrbit, DateTime atDateTime, Vector3 offsetPosition = new Vector3()) { Vector3 moverPos; if (mover.HasDataBlob <OrbitDB>()) { //moverPos = Distance.AuToMt(OrbitProcessor.GetAbsolutePosition_AU(mover.GetDataBlob<OrbitDB>(), atDateTime)); moverPos = OrbitProcessor.GetAbsolutePosition_AU(mover.GetDataBlob <OrbitDB>(), atDateTime); } else { moverPos = mover.GetDataBlob <PositionDB>().AbsolutePosition_AU; } double spd = mover.GetDataBlob <PropulsionAbilityDB>().MaximumSpeed_MS; var spd1 = Distance.MToAU(spd); return(GetInterceptPosition2(moverPos, spd1, targetOrbit, atDateTime, offsetPosition)); }
public static OrbitDB FromVectorKM(Entity parent, double myMass, double parentMass, double sgp, Vector3 position, Vector3 velocity, DateTime atDateTime) { if (Distance.KmToAU(position.Length()) > OrbitProcessor.GetSOI(parent)) { throw new Exception("Entity not in target SOI"); } //var sgp = GameConstants.Science.GravitationalConstant * (myMass + parentMass) / 3.347928976e33; var ke = OrbitMath.KeplerFromPositionAndVelocity(sgp, position, velocity, atDateTime); OrbitDB orbit = new OrbitDB(parent, parentMass, myMass, Distance.KmToAU(ke.SemiMajorAxis), ke.Eccentricity, Angle.ToDegrees(ke.Inclination), Angle.ToDegrees(ke.LoAN), Angle.ToDegrees(ke.AoP), Angle.ToDegrees(ke.MeanAnomalyAtEpoch), atDateTime);// - TimeSpan.FromSeconds(ke.Epoch)); var pos = OrbitProcessor.GetAbsolutePosition_AU(orbit, atDateTime); return(orbit); }
void SetOrbitHere(Entity entity, PropulsionAbilityDB propulsionDB, PositionDB positionDB, TranslateMoveDB moveDB, DateTime atDateTime) { propulsionDB.CurrentVectorMS = new Vector3(0, 0, 0); double targetSOI = OrbitProcessor.GetSOI(moveDB.TargetEntity); Entity targetEntity; if (moveDB.TargetEntity.GetDataBlob <PositionDB>().GetDistanceTo(positionDB) > targetSOI) { targetEntity = moveDB.TargetEntity.GetDataBlob <OrbitDB>().Parent; //TODO: it's concevable we could be in another SOI not the parent (ie we could be in a target's moon's SOI) } else { targetEntity = moveDB.TargetEntity; } OrbitDB targetOrbit = targetEntity.GetDataBlob <OrbitDB>(); var orbitalVector = OrbitProcessor.GetOrbitalVector(targetOrbit, atDateTime); var insertionVector2d = OrbitProcessor.GetOrbitalInsertionVector(moveDB.SavedNewtonionVector_AU, targetOrbit, atDateTime); Vector3 parentOrbitalVector = new Vector3(orbitalVector.X, orbitalVector.Y, 0); Vector3 insertionVector = new Vector3(insertionVector2d.X, insertionVector2d.Y, 0); insertionVector += moveDB.ExpendDeltaV_AU; //TODO: only use it if we have it. propulsionDB.RemainingDV_MS -= (float)Distance.AuToMt(moveDB.ExpendDeltaV_AU).Length(); OrbitDB newOrbit = OrbitDB.FromVector(targetEntity, entity, insertionVector, atDateTime); if (newOrbit.Periapsis > targetSOI) { //TODO: find who's SOI we're currently in and create an orbit for that; } if (newOrbit.Apoapsis > targetSOI) { //TODO: change orbit to new parent at SOI change } positionDB.SetParent(targetEntity); moveDB.IsAtTarget = true; entity.RemoveDataBlob <TranslateMoveDB>(); entity.SetDataBlob(newOrbit); newOrbit.SetParent(targetEntity); }
/// <summary> /// Creates orbit here using the current distance between the two entites as aphelion(furthest distance) and a given semiMajorAxis /// *NOTE BUG* this only returns a correct orbit DB if the position is y=0 and is +x (ie the position is in the reference direction) /// </summary> /// <returns>An OrbitDB. Does Not set DB to Entity.</returns> /// <param name="shipEntity">Ship entity.</param> /// <param name="parentEntity">The Entity to orbit</param> /// <param name="semiMajorAxsis">Largest Radius</param> public static OrbitDB CreateOrbitHereWithSemiMajAxis(Entity shipEntity, Entity parentEntity, double semiMajAxsisKM, DateTime time) { PositionDB parentPosition = parentEntity.GetDataBlob <PositionDB>(); PositionDB myPosition = shipEntity.GetDataBlob <PositionDB>(); double parentMass = parentEntity.GetDataBlob <MassVolumeDB>().Mass; double myMass = shipEntity.GetDataBlob <MassVolumeDB>().Mass; double aphelionAU = PositionDB.GetDistanceBetween(parentPosition, myPosition); double semiMajAxisAU = semiMajAxsisKM / GameConstants.Units.KmPerAu; double linierEcentricity = aphelionAU - semiMajAxisAU; double semiMinorAxsis = Math.Sqrt(Math.Pow(semiMajAxisAU, 2) - Math.Pow(linierEcentricity, 2)); double ecentricity = linierEcentricity / semiMajAxisAU; Vector3 ralitivePos = myPosition.RelativePosition_AU; double angle = Math.Atan2(ralitivePos.Y, ralitivePos.X); var theta = Angle.ToDegrees(angle); OrbitDB newOrbit = OrbitDB.FromAsteroidFormat(parentEntity, parentMass, myMass, semiMajAxisAU, ecentricity, 0, 0, angle, angle, time); var pos = OrbitProcessor.GetPosition_AU(newOrbit, time); var pos2 = Distance.AuToKm(pos); return(newOrbit); }
public static (Vector3 pos, Vector3 Velocity) GetAbsoluteState(Entity entity) { var posdb = entity.GetDataBlob <PositionDB>(); var pos = posdb.AbsolutePosition_m; if (entity.HasDataBlob <OrbitDB>()) { var datetime = entity.StarSysDateTime; var orbit = entity.GetDataBlob <OrbitDB>(); var vel = OrbitProcessor.InstantaneousOrbitalVelocityVector_m(orbit, datetime); if (posdb.Parent != null) { vel += GetAbsoluteState(posdb.Parent).Velocity; } return(pos, vel); } if (entity.HasDataBlob <OrbitUpdateOftenDB>()) { var datetime = entity.StarSysDateTime; var orbit = entity.GetDataBlob <OrbitUpdateOftenDB>(); var vel = OrbitProcessor.InstantaneousOrbitalVelocityVector_m(orbit, datetime); if (posdb.Parent != null) { vel += GetAbsoluteState(posdb.Parent).Velocity; } return(pos, vel); } if (entity.HasDataBlob <NewtonMoveDB>()) { var move = entity.GetDataBlob <NewtonMoveDB>(); var vel = move.CurrentVector_ms; return(pos, vel); } else { throw new Exception("Entity has no velocity"); } }
/// <summary> /// Gets a future position for this entity, regarless of wheter it's orbit or newtonion trajectory /// </summary> /// <param name="entity"></param> /// <param name="atDateTime"></param> /// <param name="ralitive"></param> /// <returns>In Meters</returns> /// <exception cref="Exception"></exception> public static Vector3 GetPosition_m(Entity entity, DateTime atDateTime, bool ralitive = true) { if (entity.HasDataBlob <OrbitDB>()) { if (ralitive) { return(OrbitProcessor.GetPosition_m(entity.GetDataBlob <OrbitDB>(), atDateTime)); } else { return(OrbitProcessor.GetAbsolutePosition_m(entity.GetDataBlob <OrbitDB>(), atDateTime)); } } else if (entity.HasDataBlob <NewtonMoveDB>()) { if (ralitive) { return(NewtonionMovementProcessor.GetPositon_m(entity, entity.GetDataBlob <NewtonMoveDB>(), atDateTime).pos); } else { return(NewtonionMovementProcessor.GetAbsulutePositon_m(entity, entity.GetDataBlob <NewtonMoveDB>(), atDateTime).pos); } } else if (entity.HasDataBlob <PositionDB>()) { if (ralitive) { return(entity.GetDataBlob <PositionDB>().RelativePosition_m); } else { return(entity.GetDataBlob <PositionDB>().AbsolutePosition_m); } } else { throw new Exception("Entity is positionless"); } }
public StarSystem CreateSystem(Game game, string name, int seed) { StarSystem newSystem = new StarSystem(game, name, seed); int numStars = StaticRefLib.GameSettings.StarChances.Select(newSystem.RNG.NextDouble()); List <Entity> stars = _starFactory.CreateStarsForSystem(newSystem, numStars, StaticRefLib.CurrentDateTime); foreach (Entity star in stars) { _systemBodyFactory.GenerateSystemBodiesForStar(game.StaticData, newSystem, star, StaticRefLib.CurrentDateTime); } // Generate Jump Points JPSurveyFactory.GenerateJPSurveyPoints(newSystem); JPFactory.GenerateJumpPoints(this, newSystem); //add this system to the GameMaster's Known Systems list. game.GameMasterFaction.GetDataBlob <FactionInfoDB>().KnownSystems.Add(newSystem.Guid); OrbitProcessor.UpdateSystemOrbits(newSystem, StaticRefLib.CurrentDateTime); //sets the positions of all the entites. return(newSystem); }
/// <summary> /// Gets a future position for this entity, regarless of wheter it's orbit or newtonion trajectory /// </summary> /// <param name="entity"></param> /// <param name="atDateTime"></param> /// <returns>In Meters</returns> /// <exception cref="Exception"> if entity doesn't have one of the correct datablobs</exception> public static Vector3 GetAbsoluteFuturePosition(Entity entity, DateTime atDateTime) { if (entity.HasDataBlob <OrbitDB>()) { return(OrbitProcessor.GetAbsolutePosition_m(entity.GetDataBlob <OrbitDB>(), atDateTime)); } else if (entity.HasDataBlob <OrbitUpdateOftenDB>()) { return(OrbitProcessor.GetAbsolutePosition_m(entity.GetDataBlob <OrbitUpdateOftenDB>(), atDateTime)); } else if (entity.HasDataBlob <NewtonMoveDB>()) { return(NewtonionMovementProcessor.GetAbsoluteState(entity, entity.GetDataBlob <NewtonMoveDB>(), atDateTime).pos); } else if (entity.HasDataBlob <PositionDB>()) { return(entity.GetDataBlob <PositionDB>().AbsolutePosition_m); } else { throw new Exception("Entity is positionless"); } }
/// <summary> /// Gets future velocity for this entity, datablob agnostic. /// </summary> /// <param name="entity"></param> /// <param name="atDateTime"></param> /// <returns>Velocity in m/s ralitive to SOI parent</returns> /// <exception cref="Exception"></exception> public static Vector3 GetRalitiveFutureVelocity(Entity entity, DateTime atDateTime) { if (entity.HasDataBlob <OrbitDB>()) { return(OrbitProcessor.InstantaneousOrbitalVelocityVector_m(entity.GetDataBlob <OrbitDB>(), atDateTime)); } if (entity.HasDataBlob <OrbitUpdateOftenDB>()) { return(OrbitProcessor.InstantaneousOrbitalVelocityVector_m(entity.GetDataBlob <OrbitUpdateOftenDB>(), atDateTime)); } else if (entity.HasDataBlob <NewtonMoveDB>()) { return(NewtonionMovementProcessor.GetRelativeState(entity, entity.GetDataBlob <NewtonMoveDB>(), atDateTime).vel); } else if (entity.HasDataBlob <WarpMovingDB>()) { return(entity.GetDataBlob <WarpMovingDB>().SavedNewtonionVector); } else { throw new Exception("Entity has no velocity"); } }
public static void UpdateOrbit(OrbitUpdateOftenDB entityOrbitDB, DateTime toDate) { PositionDB entityPosition = entityOrbitDB.OwningEntity.GetDataBlob <PositionDB>(PositionTypeIndex); try { Vector3 newPosition = OrbitProcessor.GetPosition_m(entityOrbitDB, toDate); entityPosition.RelativePosition_m = newPosition; } catch (OrbitProcessor.OrbitProcessorException e) { var entity = e.Entity; string name = "Un-Named"; if (entity.HasDataBlob <NameDB>()) { name = entity.GetDataBlob <NameDB>().OwnersName; } //Do NOT fail to the UI. There is NO data-corruption on this exception. // In this event, we did NOT update our position. Event evt = new Event(StaticRefLib.CurrentDateTime, "Non Critical Position Exception thrown in OrbitProcessor for EntityItem " + name + " " + entity.Guid + " " + e.Message); evt.EventType = EventType.Opps; StaticRefLib.EventLog.AddEvent(evt); } }
/// <summary> /// 2d vector /// </summary> /// <returns>The orbital vector ralitive to the parent</returns> /// <param name="orbit">Orbit.</param> /// <param name="atDateTime">At date time.</param> public static Vector2 InstantaneousOrbitalVelocityVector(OrbitDB orbit, DateTime atDateTime) { var position = GetPosition_AU(orbit, atDateTime); var sma = orbit.SemiMajorAxis; if (orbit.GravitationalParameter == 0 || sma == 0) { return(new Vector2()); //so we're not returning NaN; } var sgp = orbit.GravitationalParameterAU; double e = orbit.Eccentricity; double trueAnomaly = OrbitProcessor.GetTrueAnomaly(orbit, atDateTime); (double speed, double angle)polarvector = InstantaneousOrbitalVelocityPolarCoordinate(orbit, atDateTime); var v = new Vector2() { Y = Math.Sin(polarvector.angle) * polarvector.speed, X = Math.Cos(polarvector.angle) * polarvector.speed }; return(v); //return OrbitMath.InstantaneousOrbitalVelocityVector(sgp, position, sma, e, trueAnomaly); }
/// <summary> /// Creates an test system with planets of varying eccentricity. /// Adds to game.StarSystems /// </summary> public StarSystem CreateEccTest(Game game) { StarSystem system = new StarSystem(game, "Eccentricity test", -1); Entity sun = _starFactory.CreateStar(system, GameConstants.Units.SolarMassInKG, GameConstants.Units.SolarRadiusInAu, 4.6E9, "G", 5778, 1, SpectralType.G, "_ecc"); MassVolumeDB sunMVDB = sun.GetDataBlob <MassVolumeDB>(); double planetSemiMajAxis = 0.387098; double planetEccentricity = 0.205630; double planetInclination = 0; double planetLoAN = 48.33167; double planetLoP = 77.45645; double planetMeanLongd = 252.25084; for (int i = 0; i < 16; i++) { NameDB planetNameDB = new NameDB("planet" + i); SystemBodyInfoDB planetBodyDB = new SystemBodyInfoDB { BodyType = BodyType.Terrestrial, SupportsPopulations = true }; MassVolumeDB planetMVDB = MassVolumeDB.NewFromMassAndRadius_AU(3.3022E23, Distance.KmToAU(2439.7)); PositionDB planetPositionDB = new PositionDB(system.Guid); planetEccentricity = i / 16.0; OrbitDB planetOrbitDB = OrbitDB.FromMajorPlanetFormat(sun, sunMVDB.MassDry, planetMVDB.MassDry, planetSemiMajAxis, planetEccentricity, planetInclination, planetLoAN, planetLoP, planetMeanLongd, GalaxyGen.Settings.J2000); planetPositionDB.AbsolutePosition_AU = OrbitProcessor.GetPosition_AU(planetOrbitDB, StaticRefLib.CurrentDateTime); Entity planet = new Entity(system, new List <BaseDataBlob> { planetPositionDB, planetBodyDB, planetMVDB, planetNameDB, planetOrbitDB }); } game.GameMasterFaction.GetDataBlob <FactionInfoDB>().KnownSystems.Add(system.Guid); return(system); }
/// <summary> /// This was designed so that fast moving objects will get interpolated a lot more than slow moving objects /// so fast moving objects shouldn't loose positional acuracy when close to a planet, /// and slow moving objects won't have processor time wasted on them by calulcating too often. /// However this seems to be unstable and looses energy, unsure why. currently set it to just itterate/interpolate every second. /// so currently will be using more time to get through this than neccisary. /// </summary> /// <param name="entity">Entity.</param> /// <param name="deltaSeconds">Delta seconds.</param> public static void NewtonMove(Entity entity, int deltaSeconds) { NewtonMoveDB newtonMoveDB = entity.GetDataBlob <NewtonMoveDB>(); PositionDB positionDB = entity.GetDataBlob <PositionDB>(); double Mass_Kg = entity.GetDataBlob <MassVolumeDB>().Mass; double ParentMass_kg = newtonMoveDB.ParentMass; var manager = entity.Manager; DateTime dateTimeFrom = newtonMoveDB.LastProcessDateTime; DateTime dateTimeNow = manager.ManagerSubpulses.StarSysDateTime; DateTime dateTimeFuture = dateTimeNow + TimeSpan.FromSeconds(deltaSeconds); double deltaT = (dateTimeFuture - dateTimeFrom).TotalSeconds; double secondsToItterate = deltaT; while (secondsToItterate > 0) { double speed_kms = newtonMoveDB.CurrentVector_kms.Length(); //double timeStep = Math.Max(secondsToItterate / speed_kms, 1); //timeStep = Math.Min(timeStep, secondsToItterate); double timeStep = 1;//because the above seems unstable and looses energy. double distanceToParent_m = Distance.AuToMt(positionDB.GetDistanceTo(newtonMoveDB.SOIParent.GetDataBlob <PositionDB>())); distanceToParent_m = Math.Max(distanceToParent_m, 0.1); //don't let the distance be 0 (once collision is in this will likely never happen anyway) double gravForce = GameConstants.Science.GravitationalConstant * (Mass_Kg * ParentMass_kg / Math.Pow(distanceToParent_m, 2)); Vector3 gravForceVector = gravForce * -Vector3.Normalise(positionDB.RelativePosition_AU); double distance = Distance.AuToKm(positionDB.RelativePosition_AU).Length(); Vector3 totalForce = gravForceVector + newtonMoveDB.ThrustVector; Vector3 acceleration_mps = totalForce / Mass_Kg; Vector3 newVelocity = (acceleration_mps * timeStep * 0.001) + newtonMoveDB.CurrentVector_kms; newtonMoveDB.CurrentVector_kms = newVelocity; Vector3 deltaPos = (newtonMoveDB.CurrentVector_kms + newVelocity) / 2 * timeStep; //Vector4 deltaPos = newtonMoveDB.CurrentVector_kms * timeStep; positionDB.RelativePosition_AU += Distance.KmToAU(deltaPos); double sOIRadius_AU = OrbitProcessor.GetSOI(newtonMoveDB.SOIParent); if (positionDB.RelativePosition_AU.Length() >= sOIRadius_AU) { Entity newParent; Vector3 parentRalitiveVector; //if our parent is a regular kepler object (normaly this is the case) if (newtonMoveDB.SOIParent.HasDataBlob <OrbitDB>()) { var orbitDB = newtonMoveDB.SOIParent.GetDataBlob <OrbitDB>(); newParent = orbitDB.Parent; var parentVelocity = OrbitProcessor.InstantaneousOrbitalVelocityVector(orbitDB, entity.Manager.ManagerSubpulses.StarSysDateTime); parentRalitiveVector = Distance.KmToAU(newtonMoveDB.CurrentVector_kms) + parentVelocity; var pvlen = Distance.AuToKm(parentVelocity.Length()); var vlen = newtonMoveDB.CurrentVector_kms.Length(); var rvlen = Distance.AuToKm(parentRalitiveVector.Length()); } else //if (newtonMoveDB.SOIParent.HasDataBlob<NewtonMoveDB>()) { //this will pretty much never happen. newParent = newtonMoveDB.SOIParent.GetDataBlob <NewtonMoveDB>().SOIParent; var parentVelocity = newtonMoveDB.SOIParent.GetDataBlob <NewtonMoveDB>().CurrentVector_kms; parentRalitiveVector = Distance.KmToAU(newtonMoveDB.CurrentVector_kms + parentVelocity); } double newParentMass = newParent.GetDataBlob <MassVolumeDB>().Mass; double sgp = GameConstants.Science.GravitationalConstant * (newParentMass + Mass_Kg) / 3.347928976e33; Vector3 posRalitiveToNewParent = positionDB.AbsolutePosition_AU - newParent.GetDataBlob <PositionDB>().AbsolutePosition_AU; var dateTime = dateTimeNow + TimeSpan.FromSeconds(deltaSeconds - secondsToItterate); var kE = OrbitMath.KeplerFromPositionAndVelocity(sgp, posRalitiveToNewParent, parentRalitiveVector, dateTime); if (kE.Eccentricity < 1) //if we're going to end up in a regular orbit around our new parent { /* * var newOrbit = OrbitDB.FromKeplerElements( * newParent, * newParentMass, * Mass_Kg, * kE, * dateTime); */ var newOrbit = OrbitDB.FromVector(newParent, entity, parentRalitiveVector, dateTime); entity.RemoveDataBlob <NewtonMoveDB>(); entity.SetDataBlob(newOrbit); positionDB.SetParent(newParent); var currentPos = Distance.AuToKm(positionDB.RelativePosition_AU); var newPos = OrbitProcessor.GetPosition_AU(newOrbit, dateTime); var newPosKM = Distance.AuToKm(newPos); positionDB.RelativePosition_AU = newPos; break; } else //else we're in a hyperbolic trajectory around our new parent, so just coninue the newtonion move. { positionDB.SetParent(newParent); newtonMoveDB.ParentMass = newParentMass; newtonMoveDB.SOIParent = newParent; } } secondsToItterate -= timeStep; } newtonMoveDB.LastProcessDateTime = dateTimeFuture; }
/// <summary> /// Creates on Orbit at current location from a given velocity /// </summary> /// <returns>The Orbit Does not attach the OrbitDB to the entity!</returns> /// <param name="parent">Parent. must have massdb</param> /// <param name="entity">Entity. must have massdb</param> /// <param name="velocity_m">Velocity in meters.</param> public static OrbitDB FromVelocity_m(Entity parent, Entity entity, Vector3 velocity_m, DateTime atDateTime) { var parentMass = parent.GetDataBlob <MassVolumeDB>().Mass; var myMass = entity.GetDataBlob <MassVolumeDB>().Mass; //var epoch1 = parent.Manager.ManagerSubpulses.StarSysDateTime; //getting epoch from here is incorrect as the local datetime doesn't change till after the subpulse. //var parentPos = OrbitProcessor.GetAbsolutePosition_AU(parent.GetDataBlob<OrbitDB>(), atDateTime); //need to use the parent position at the epoch var posdb = entity.GetDataBlob <PositionDB>(); posdb.SetParent(parent); var ralitivePos = posdb.RelativePosition_m;//entity.GetDataBlob<PositionDB>().AbsolutePosition_AU - parentPos; if (ralitivePos.Length() > OrbitProcessor.GetSOI_m(parent)) { throw new Exception("Entity not in target SOI"); } //var sgp = GameConstants.Science.GravitationalConstant * (myMass + parentMass) / 3.347928976e33; var sgp_m = GMath.StandardGravitationalParameter(myMass + parentMass); var ke_m = OrbitMath.KeplerFromPositionAndVelocity(sgp_m, ralitivePos, velocity_m, atDateTime); OrbitDB orbit = new OrbitDB(parent) { SemiMajorAxis = ke_m.SemiMajorAxis, Eccentricity = ke_m.Eccentricity, Inclination = ke_m.Inclination, LongitudeOfAscendingNode = ke_m.LoAN, ArgumentOfPeriapsis = ke_m.AoP, MeanAnomalyAtEpoch = ke_m.MeanAnomalyAtEpoch, Epoch = atDateTime, _parentMass = parentMass, _myMass = myMass }; orbit.CalculateExtendedParameters(); var pos = OrbitProcessor.GetPosition_m(orbit, atDateTime); var d = (pos - ralitivePos).Length(); if (d > 1) { var e = new Event(atDateTime, "Positional difference of " + Stringify.Distance(d) + " when creating orbit from velocity"); e.Entity = entity; e.SystemGuid = entity.Manager.ManagerGuid; e.EventType = EventType.Opps; //e.Faction = entity.FactionOwner; StaticRefLib.EventLog.AddEvent(e); //other info: var keta = Angle.ToDegrees(ke_m.TrueAnomalyAtEpoch); var obta = Angle.ToDegrees(OrbitProcessor.GetTrueAnomaly(orbit, atDateTime)); var tadif = Angle.ToDegrees(Angle.DifferenceBetweenRadians(keta, obta)); var pos1 = OrbitProcessor.GetPosition_m(orbit, atDateTime); var pos2 = OrbitProcessor.GetPosition_m(orbit, ke_m.TrueAnomalyAtEpoch); var d2 = (pos1 - pos2).Length(); } return(orbit); }
public static Entity CreateAsteroid2(StarSystem starSys, Entity target, DateTime collisionDate, double asteroidMass = -1.0) { //todo rand these a bit. double radius = Distance.KmToAU(0.5); double mass; if (asteroidMass == -1.0) { mass = 1.5e+12; //about 1.5 billion tonne } else { mass = asteroidMass; } Vector3 velocity = new Vector3(8, 7, 0); var position = new PositionDB(0, 0, 0, Guid.Empty); var massVolume = MassVolumeDB.NewFromMassAndRadius(mass, radius); var planetInfo = new SystemBodyInfoDB(); var balisticTraj = new NewtonBalisticDB(target.Guid, collisionDate); var name = new NameDB("Ellie"); var AsteroidDmg = new AsteroidDamageDB(); var sensorPfil = new SensorProfileDB(); planetInfo.SupportsPopulations = false; planetInfo.BodyType = BodyType.Asteroid; Vector3 targetPos = OrbitProcessor.GetAbsolutePosition_AU(target.GetDataBlob <OrbitDB>(), collisionDate); TimeSpan timeToCollision = collisionDate - StaticRefLib.CurrentDateTime; Vector3 offset = velocity * timeToCollision.TotalSeconds; targetPos -= Distance.KmToAU(offset); position.AbsolutePosition_AU = targetPos; position.SystemGuid = starSys.Guid; balisticTraj.CurrentSpeed = velocity; var parent = target.GetDataBlob <OrbitDB>().Parent; var parentMass = parent.GetDataBlob <MassVolumeDB>().Mass; var myMass = massVolume.Mass; var mySemiMajorAxis = 5.055; var myEccentricity = 0.8; var myInclination = 0; var myLoAN = 0; var myAoP = -10; //var EccentricAnomaly = Math.Atan2() //var meanAnomaly =; double myLoP = 0; double myMeanLongd = 355.5; //OrbitDB orbit = OrbitDB.FromAsteroidFormat(parent, parentMass, myMass, mySemiMajorAxis, myEccentricity, myInclination, myLoAN, myAoP, meanAnomaly, starSys.Game.CurrentDateTime); OrbitDB orbit = OrbitDB.FromMajorPlanetFormat(parent, parentMass, myMass, mySemiMajorAxis, myEccentricity, myInclination, myLoAN, myLoP, myMeanLongd, StaticRefLib.CurrentDateTime); var planetDBs = new List <BaseDataBlob> { position, massVolume, planetInfo, name, orbit, AsteroidDmg, sensorPfil }; Entity newELE = new Entity(starSys, planetDBs); return(newELE); }
public StarSystem CreateTestSystem(Game game, int x = 0, int y = 0) { StarSystem sol = new StarSystem(game, "something", -1); Entity sun = _starFactory.CreateStar(sol, GameConstants.Units.SolarMassInKG, GameConstants.Units.SolarRadiusInAu, 4.6E9, "G", 5778, 1, SpectralType.G, "something"); sun.GetDataBlob <PositionDB>().X_AU += x; sun.GetDataBlob <PositionDB>().Y_AU += x; MassVolumeDB sunMVDB = sun.GetDataBlob <MassVolumeDB>(); SystemBodyInfoDB mercuryBodyDB = new SystemBodyInfoDB { BodyType = BodyType.Terrestrial, SupportsPopulations = true, Albedo = 0.068f }; //Albedo = 0.068f MassVolumeDB mercuryMVDB = MassVolumeDB.NewFromMassAndRadius_AU(3.3022E23, Distance.KmToAU(2439.7)); NameDB mercuryNameDB = new NameDB("LOLXDWTF"); double mercurySemiMajAxis = 0.387098; double mercuryEccentricity = 0.205630; double mercuryInclination = 0; double mercuryLoAN = 48.33167; double mercuryLoP = 77.45645; double mercuryMeanLongd = 252.25084; OrbitDB mercuryOrbitDB = OrbitDB.FromMajorPlanetFormat(sun, sunMVDB.MassDry, mercuryMVDB.MassDry, mercurySemiMajAxis, mercuryEccentricity, mercuryInclination, mercuryLoAN, mercuryLoP, mercuryMeanLongd, GalaxyGen.Settings.J2000); PositionDB mercuryPositionDB = new PositionDB(OrbitProcessor.GetPosition_AU(mercuryOrbitDB, StaticRefLib.CurrentDateTime), sol.Guid, sun); //AtmosphereDB mercuryAtmo = new AtmosphereDB(); SensorProfileDB sensorProfile = new SensorProfileDB(); mercuryPositionDB.X_AU += x; mercuryPositionDB.Y_AU += x; Entity mercury = new Entity(sol, new List <BaseDataBlob> { sensorProfile, mercuryPositionDB, mercuryBodyDB, mercuryMVDB, mercuryNameDB, mercuryOrbitDB }); _systemBodyFactory.MineralGeneration(game.StaticData, sol, mercury); SensorProcessorTools.PlanetEmmisionSig(sensorProfile, mercuryBodyDB, mercuryMVDB); SystemBodyInfoDB venusBodyDB = new SystemBodyInfoDB { BodyType = BodyType.Terrestrial, SupportsPopulations = true, Albedo = 0.77f }; MassVolumeDB venusMVDB = MassVolumeDB.NewFromMassAndRadius_AU(4.8676E24, Distance.KmToAU(6051.8)); NameDB venusNameDB = new NameDB("AYLMAOROFL"); double venusSemiMajAxis = 0.72333199; double venusEccentricity = 0.00677323; double venusInclination = 0; double venusLoAN = 76.68069; double venusLoP = 131.53298; double venusMeanLongd = 181.97973; OrbitDB venusOrbitDB = OrbitDB.FromMajorPlanetFormat(sun, sunMVDB.MassDry, venusMVDB.MassDry, venusSemiMajAxis, venusEccentricity, venusInclination, venusLoAN, venusLoP, venusMeanLongd, GalaxyGen.Settings.J2000); PositionDB venusPositionDB = new PositionDB(OrbitProcessor.GetPosition_AU(venusOrbitDB, StaticRefLib.CurrentDateTime), sol.Guid, sun); sensorProfile = new SensorProfileDB(); Entity venus = new Entity(sol, new List <BaseDataBlob> { sensorProfile, venusPositionDB, venusBodyDB, venusMVDB, venusNameDB, venusOrbitDB }); _systemBodyFactory.MineralGeneration(game.StaticData, sol, venus); SensorProcessorTools.PlanetEmmisionSig(sensorProfile, venusBodyDB, venusMVDB); SystemBodyInfoDB earthBodyDB = new SystemBodyInfoDB { BodyType = BodyType.Terrestrial, SupportsPopulations = true, Albedo = 0.306f }; MassVolumeDB earthMVDB = MassVolumeDB.NewFromMassAndRadius_AU(5.9726E24, Distance.KmToAU(6378.1)); NameDB earthNameDB = new NameDB("OMG"); double earthSemiMajAxis = 1.00000011; double earthEccentricity = 0.01671022; double earthInclination = 0; double earthLoAN = -11.26064; double earthLoP = 102.94719; double earthMeanLongd = 100.46435; OrbitDB earthOrbitDB = OrbitDB.FromMajorPlanetFormat(sun, sunMVDB.MassDry, earthMVDB.MassDry, earthSemiMajAxis, earthEccentricity, earthInclination, earthLoAN, earthLoP, earthMeanLongd, GalaxyGen.Settings.J2000); earthBodyDB.Tectonics = TectonicActivity.EarthLike; PositionDB earthPositionDB = new PositionDB(OrbitProcessor.GetPosition_AU(earthOrbitDB, StaticRefLib.CurrentDateTime), sol.Guid, sun); Dictionary <AtmosphericGasSD, float> atmoGasses = new Dictionary <AtmosphericGasSD, float>(); atmoGasses.Add(game.StaticData.AtmosphericGases.SelectAt(6), 0.78f); atmoGasses.Add(game.StaticData.AtmosphericGases.SelectAt(9), 0.12f); atmoGasses.Add(game.StaticData.AtmosphericGases.SelectAt(11), 0.01f); AtmosphereDB earthAtmosphereDB = new AtmosphereDB(1f, true, 71, 1f, 1f, 57.2f, atmoGasses); //TODO what's our greenhouse factor an pressure? sensorProfile = new SensorProfileDB(); Entity earth = new Entity(sol, new List <BaseDataBlob> { sensorProfile, earthPositionDB, earthBodyDB, earthMVDB, earthNameDB, earthOrbitDB, earthAtmosphereDB }); _systemBodyFactory.HomeworldMineralGeneration(game.StaticData, sol, earth); SensorProcessorTools.PlanetEmmisionSig(sensorProfile, earthBodyDB, earthMVDB); SystemBodyInfoDB lunaBodyDB = new SystemBodyInfoDB { BodyType = BodyType.Moon, SupportsPopulations = true }; MassVolumeDB lunaMVDB = MassVolumeDB.NewFromMassAndRadius_AU(0.073E24, Distance.KmToAU(1738.14)); NameDB lunaNameDB = new NameDB("NOWAY"); double lunaSemiMajAxis = Distance.KmToAU(0.3844E6); double lunaEccentricity = 0.0549; double lunaInclination = 0;//5.1; // Next three values are unimportant. Luna's LoAN and AoP regress/progress by one revolution every 18.6/8.85 years respectively. // Our orbit code it not advanced enough to deal with LoAN/AoP regression/progression. double lunaLoAN = 125.08; double lunaAoP = 318.0634; double lunaMeanAnomaly = 115.3654; OrbitDB lunaOrbitDB = OrbitDB.FromAsteroidFormat(earth, earthMVDB.MassDry, lunaMVDB.MassDry, lunaSemiMajAxis, lunaEccentricity, lunaInclination, lunaLoAN, lunaAoP, lunaMeanAnomaly, GalaxyGen.Settings.J2000); PositionDB lunaPositionDB = new PositionDB(OrbitProcessor.GetPosition_AU(lunaOrbitDB, StaticRefLib.CurrentDateTime) + earthPositionDB.AbsolutePosition_AU, sol.Guid, earth); sensorProfile = new SensorProfileDB(); Entity luna = new Entity(sol, new List <BaseDataBlob> { sensorProfile, lunaPositionDB, lunaBodyDB, lunaMVDB, lunaNameDB, lunaOrbitDB }); _systemBodyFactory.MineralGeneration(game.StaticData, sol, luna); SensorProcessorTools.PlanetEmmisionSig(sensorProfile, lunaBodyDB, lunaMVDB); SystemBodyInfoDB halleysBodyDB = new SystemBodyInfoDB { BodyType = BodyType.Comet, SupportsPopulations = false, Albedo = 0.04f }; //Albedo = 0.04f MassVolumeDB halleysMVDB = MassVolumeDB.NewFromMassAndRadius_AU(2.2e14, Distance.KmToAU(11)); NameDB halleysNameDB = new NameDB("ASSHOLE"); double halleysSemiMajAxis = 17.834; //AU double halleysEccentricity = 0.96714; double halleysInclination = 180; //162.26° note retrograde orbit. double halleysLoAN = 58.42; //° double halleysAoP = 111.33; //° double halleysMeanAnomaly = 38.38; //° OrbitDB halleysOrbitDB = OrbitDB.FromAsteroidFormat(sun, sunMVDB.MassDry, halleysMVDB.MassDry, halleysSemiMajAxis, halleysEccentricity, halleysInclination, halleysLoAN, halleysAoP, halleysMeanAnomaly, new System.DateTime(1994, 2, 17)); PositionDB halleysPositionDB = new PositionDB(OrbitProcessor.GetPosition_AU(halleysOrbitDB, StaticRefLib.CurrentDateTime), sol.Guid, sun); // + earthPositionDB.AbsolutePosition_AU, sol.ID); sensorProfile = new SensorProfileDB(); Entity halleysComet = new Entity(sol, new List <BaseDataBlob> { sensorProfile, halleysPositionDB, halleysBodyDB, halleysMVDB, halleysNameDB, halleysOrbitDB }); _systemBodyFactory.MineralGeneration(game.StaticData, sol, halleysComet); SensorProcessorTools.PlanetEmmisionSig(sensorProfile, halleysBodyDB, halleysMVDB); JPSurveyFactory.GenerateJPSurveyPoints(sol); game.GameMasterFaction.GetDataBlob <FactionInfoDB>().KnownSystems.Add(sol.Guid); return(sol); }
/// <summary> /// Creates our own solar system. /// This probibly needs to be Json! (since we're getting atmo stuff) /// Adds sol to game.StarSystems. /// </summary> public StarSystem CreateSol(Game game) { // WIP Function. Not complete. StarSystem sol = new StarSystem(game, "Sol", -1); Entity sun = _starFactory.CreateStar(sol, GameConstants.Units.SolarMassInKG, GameConstants.Units.SolarRadiusInAu, 4.6E9, "G", 5778, 1, SpectralType.G, "Sol"); MassVolumeDB sunMVDB = sun.GetDataBlob <MassVolumeDB>(); SystemBodyInfoDB mercuryBodyDB = new SystemBodyInfoDB { BodyType = BodyType.Terrestrial, SupportsPopulations = true, Albedo = 0.068f }; //Albedo = 0.068f MassVolumeDB mercuryMVDB = MassVolumeDB.NewFromMassAndRadius_AU(3.3022E23, Distance.KmToAU(2439.7)); NameDB mercuryNameDB = new NameDB("Mercury"); double mercurySemiMajAxis = 0.387098; double mercuryEccentricity = 0.205630; double mercuryInclination = 0; double mercuryLoAN = 48.33167; double mercuryLoP = 77.45645; double mercuryMeanLongd = 252.25084; OrbitDB mercuryOrbitDB = OrbitDB.FromMajorPlanetFormat(sun, sunMVDB.MassDry, mercuryMVDB.MassDry, mercurySemiMajAxis, mercuryEccentricity, mercuryInclination, mercuryLoAN, mercuryLoP, mercuryMeanLongd, GalaxyGen.Settings.J2000); mercuryBodyDB.BaseTemperature = (float)SystemBodyFactory.CalculateBaseTemperatureOfBody(sun, mercuryOrbitDB); PositionDB mercuryPositionDB = new PositionDB(OrbitProcessor.GetPosition_AU(mercuryOrbitDB, StaticRefLib.CurrentDateTime), sol.Guid, sun); //AtmosphereDB mercuryAtmo = new AtmosphereDB(); SensorProfileDB sensorProfile = new SensorProfileDB(); Entity mercury = new Entity(sol, new List <BaseDataBlob> { sensorProfile, mercuryPositionDB, mercuryBodyDB, mercuryMVDB, mercuryNameDB, mercuryOrbitDB }); _systemBodyFactory.MineralGeneration(game.StaticData, sol, mercury); SensorProcessorTools.PlanetEmmisionSig(sensorProfile, mercuryBodyDB, mercuryMVDB); SystemBodyInfoDB venusBodyDB = new SystemBodyInfoDB { BodyType = BodyType.Terrestrial, SupportsPopulations = true, Albedo = 0.77f }; MassVolumeDB venusMVDB = MassVolumeDB.NewFromMassAndRadius_AU(4.8676E24, Distance.KmToAU(6051.8)); NameDB venusNameDB = new NameDB("Venus"); double venusSemiMajAxis = 0.72333199; double venusEccentricity = 0.00677323; double venusInclination = 0; double venusLoAN = 76.68069; double venusLoP = 131.53298; double venusMeanLongd = 181.97973; OrbitDB venusOrbitDB = OrbitDB.FromMajorPlanetFormat(sun, sunMVDB.MassDry, venusMVDB.MassDry, venusSemiMajAxis, venusEccentricity, venusInclination, venusLoAN, venusLoP, venusMeanLongd, GalaxyGen.Settings.J2000); venusBodyDB.BaseTemperature = (float)SystemBodyFactory.CalculateBaseTemperatureOfBody(sun, venusOrbitDB); PositionDB venusPositionDB = new PositionDB(OrbitProcessor.GetPosition_AU(venusOrbitDB, StaticRefLib.CurrentDateTime), sol.Guid, sun); sensorProfile = new SensorProfileDB(); Entity venus = new Entity(sol, new List <BaseDataBlob> { sensorProfile, venusPositionDB, venusBodyDB, venusMVDB, venusNameDB, venusOrbitDB }); _systemBodyFactory.MineralGeneration(game.StaticData, sol, venus); SensorProcessorTools.PlanetEmmisionSig(sensorProfile, venusBodyDB, venusMVDB); SystemBodyInfoDB earthBodyDB = new SystemBodyInfoDB { BodyType = BodyType.Terrestrial, SupportsPopulations = true, Albedo = 0.306f }; MassVolumeDB earthMVDB = MassVolumeDB.NewFromMassAndRadius_AU(5.9726E24, Distance.KmToAU(6378.1)); NameDB earthNameDB = new NameDB("Earth"); double earthSemiMajAxis = 1.00000011; double earthEccentricity = 0.01671022; double earthInclination = 0; double earthLoAN = -11.26064; double earthLoP = 102.94719; double earthMeanLongd = 100.46435; OrbitDB earthOrbitDB = OrbitDB.FromMajorPlanetFormat(sun, sunMVDB.MassDry, earthMVDB.MassDry, earthSemiMajAxis, earthEccentricity, earthInclination, earthLoAN, earthLoP, earthMeanLongd, GalaxyGen.Settings.J2000); earthBodyDB.BaseTemperature = (float)SystemBodyFactory.CalculateBaseTemperatureOfBody(sun, earthOrbitDB); earthBodyDB.Tectonics = TectonicActivity.EarthLike; PositionDB earthPositionDB = new PositionDB(OrbitProcessor.GetPosition_AU(earthOrbitDB, StaticRefLib.CurrentDateTime), sol.Guid, sun); Dictionary <AtmosphericGasSD, float> atmoGasses = new Dictionary <AtmosphericGasSD, float>(); atmoGasses.Add(game.StaticData.AtmosphericGases.SelectAt(6), 0.78f); atmoGasses.Add(game.StaticData.AtmosphericGases.SelectAt(9), 0.12f); atmoGasses.Add(game.StaticData.AtmosphericGases.SelectAt(11), 0.01f); AtmosphereDB earthAtmosphereDB = new AtmosphereDB(1f, true, 71, 1f, 1f, 57.2f, atmoGasses); //TODO what's our greenhouse factor an pressure? sensorProfile = new SensorProfileDB(); Entity earth = new Entity(sol, new List <BaseDataBlob> { sensorProfile, earthPositionDB, earthBodyDB, earthMVDB, earthNameDB, earthOrbitDB, earthAtmosphereDB }); _systemBodyFactory.HomeworldMineralGeneration(game.StaticData, sol, earth); SensorProcessorTools.PlanetEmmisionSig(sensorProfile, earthBodyDB, earthMVDB); SystemBodyInfoDB lunaBodyDB = new SystemBodyInfoDB { BodyType = BodyType.Moon, SupportsPopulations = true }; MassVolumeDB lunaMVDB = MassVolumeDB.NewFromMassAndRadius_AU(0.073E24, Distance.KmToAU(1738.14)); NameDB lunaNameDB = new NameDB("Luna"); double lunaSemiMajAxis = Distance.KmToAU(0.3844E6); double lunaEccentricity = 0.0549; double lunaInclination = 0;//5.1; // Next three values are unimportant. Luna's LoAN and AoP regress/progress by one revolution every 18.6/8.85 years respectively. // Our orbit code it not advanced enough to deal with LoAN/AoP regression/progression. double lunaLoAN = 125.08; double lunaAoP = 318.0634; double lunaMeanAnomaly = 115.3654; OrbitDB lunaOrbitDB = OrbitDB.FromAsteroidFormat(earth, earthMVDB.MassDry, lunaMVDB.MassDry, lunaSemiMajAxis, lunaEccentricity, lunaInclination, lunaLoAN, lunaAoP, lunaMeanAnomaly, GalaxyGen.Settings.J2000); lunaBodyDB.BaseTemperature = (float)SystemBodyFactory.CalculateBaseTemperatureOfBody(sun, earthOrbitDB); //yes, using earth orbit here, since this is the DB it calculates the average distance from. PositionDB lunaPositionDB = new PositionDB(OrbitProcessor.GetPosition_AU(lunaOrbitDB, StaticRefLib.CurrentDateTime) + earthPositionDB.AbsolutePosition_AU, sol.Guid, earth); sensorProfile = new SensorProfileDB(); Entity luna = new Entity(sol, new List <BaseDataBlob> { sensorProfile, lunaPositionDB, lunaBodyDB, lunaMVDB, lunaNameDB, lunaOrbitDB }); _systemBodyFactory.MineralGeneration(game.StaticData, sol, luna); SensorProcessorTools.PlanetEmmisionSig(sensorProfile, lunaBodyDB, lunaMVDB); SystemBodyInfoDB marsBodyDB = new SystemBodyInfoDB { BodyType = BodyType.Terrestrial, SupportsPopulations = true, Albedo = 0.25f }; MassVolumeDB marsMVDB = MassVolumeDB.NewFromMassAndRadius_AU(0.64174E24, Distance.KmToAU(3396.2)); NameDB marsNameDB = new NameDB("Mars"); double marsSemiMajAxis = Distance.KmToAU(227.92E6); double marsEccentricity = 0.0934; //wiki says .0934 double marsInclination = 0; //1.85; double marsLoAN = 49.57854; double marsAoP = 336.04084; double marsMeanLong = 355.45332; OrbitDB marsOrbitDB = OrbitDB.FromMajorPlanetFormat(sun, sunMVDB.MassDry, marsMVDB.MassDry, marsSemiMajAxis, marsEccentricity, marsInclination, marsLoAN, marsAoP, marsMeanLong, GalaxyGen.Settings.J2000); marsBodyDB.BaseTemperature = (float)SystemBodyFactory.CalculateBaseTemperatureOfBody(sun, marsOrbitDB); Dictionary <AtmosphericGasSD, float> marsAtmoGasses = new Dictionary <AtmosphericGasSD, float>(); marsAtmoGasses.Add(game.StaticData.AtmosphericGases.SelectAt(12), 0.95f * 0.01f); // C02% * Mars Atms marsAtmoGasses.Add(game.StaticData.AtmosphericGases.SelectAt(6), 0.027f * 0.01f); // N% * Mars Atms marsAtmoGasses.Add(game.StaticData.AtmosphericGases.SelectAt(9), 0.007f * 0.01f); // O% * Mars Atms marsAtmoGasses.Add(game.StaticData.AtmosphericGases.SelectAt(11), 0.016f * 0.01f); // Ar% * Mars Atms AtmosphereDB marsAtmo = new AtmosphereDB(0.087f, false, 0, 0, 0, -55, marsAtmoGasses); PositionDB marsPositionDB = new PositionDB(OrbitProcessor.GetPosition_AU(marsOrbitDB, StaticRefLib.CurrentDateTime), sol.Guid, sun); sensorProfile = new SensorProfileDB(); Entity mars = new Entity(sol, new List <BaseDataBlob> { sensorProfile, marsPositionDB, marsBodyDB, marsMVDB, marsNameDB, marsOrbitDB, marsAtmo }); _systemBodyFactory.MineralGeneration(game.StaticData, sol, mars); SensorProcessorTools.PlanetEmmisionSig(sensorProfile, marsBodyDB, marsMVDB); SystemBodyInfoDB halleysBodyDB = new SystemBodyInfoDB { BodyType = BodyType.Comet, SupportsPopulations = false, Albedo = 0.04f }; //Albedo = 0.04f MassVolumeDB halleysMVDB = MassVolumeDB.NewFromMassAndRadius_AU(2.2e14, Distance.KmToAU(11)); NameDB halleysNameDB = new NameDB("Halleys Comet"); double halleysSemiMajAxis = 17.834; //AU double halleysEccentricity = 0.96714; double halleysInclination = 180; //162.26° note retrograde orbit. double halleysLoAN = 58.42; //° double halleysAoP = 111.33; //° double halleysMeanAnomaly = 38.38; //° OrbitDB halleysOrbitDB = OrbitDB.FromAsteroidFormat(sun, sunMVDB.MassDry, halleysMVDB.MassDry, halleysSemiMajAxis, halleysEccentricity, halleysInclination, halleysLoAN, halleysAoP, halleysMeanAnomaly, new System.DateTime(1994, 2, 17)); halleysBodyDB.BaseTemperature = (float)SystemBodyFactory.CalculateBaseTemperatureOfBody(sun, halleysOrbitDB); PositionDB halleysPositionDB = new PositionDB(OrbitProcessor.GetPosition_AU(halleysOrbitDB, StaticRefLib.CurrentDateTime), sol.Guid, sun); // + earthPositionDB.AbsolutePosition_AU, sol.ID); sensorProfile = new SensorProfileDB(); Entity halleysComet = new Entity(sol, new List <BaseDataBlob> { sensorProfile, halleysPositionDB, halleysBodyDB, halleysMVDB, halleysNameDB, halleysOrbitDB }); _systemBodyFactory.MineralGeneration(game.StaticData, sol, halleysComet); SensorProcessorTools.PlanetEmmisionSig(sensorProfile, halleysBodyDB, halleysMVDB); /* * * SystemBody Jupiter = new SystemBody(sun, SystemBody.PlanetType.GasGiant); * Jupiter.Name = "Jupiter"; * Jupiter.Orbit = Orbit.FromMajorPlanetFormat(1898.3E24, sun.Orbit.Mass, 5.20336301, 0.04839266, 1.30530, 100.55615, 14.75385, 34.40438, GalaxyGen.J2000); * Jupiter.Radius = Distance.ToAU(71492); * Jupiter.Orbit.GetPosition(GameState.Instance.CurrentDate, out x, out y); * Jupiter.Position.System = Sol; * Jupiter.Position.X = x; * Jupiter.Position.Y = y; * sun.Planets.Add(Jupiter); * * SystemBody Saturn = new SystemBody(sun, SystemBody.PlanetType.GasGiant); * Saturn.Name = "Saturn"; * Saturn.Orbit = Orbit.FromMajorPlanetFormat(568.36E24, sun.Orbit.Mass, 9.53707032, 0.05415060, 2.48446, 113.71504, 92.43194, 49.94432, GalaxyGen.J2000); * Saturn.Radius = Distance.ToAU(60268); * Saturn.Orbit.GetPosition(GameState.Instance.CurrentDate, out x, out y); * Saturn.Position.System = Sol; * Saturn.Position.X = x; * Saturn.Position.Y = y; * sun.Planets.Add(Saturn); * * SystemBody Uranus = new SystemBody(sun, SystemBody.PlanetType.IceGiant); * Uranus.Name = "Uranus"; * Uranus.Orbit = Orbit.FromMajorPlanetFormat(86.816E24, sun.Orbit.Mass, 19.19126393, 0.04716771, 0.76986, 74.22988, 170.96424, 313.23218, GalaxyGen.J2000); * Uranus.Radius = Distance.ToAU(25559); * Uranus.Orbit.GetPosition(GameState.Instance.CurrentDate, out x, out y); * Uranus.Position.System = Sol; * Uranus.Position.X = x; * Uranus.Position.Y = y; * sun.Planets.Add(Uranus); * * SystemBody Neptune = new SystemBody(sun, SystemBody.PlanetType.IceGiant); * Neptune.Name = "Neptune"; * Neptune.Orbit = Orbit.FromMajorPlanetFormat(102E24, sun.Orbit.Mass, Distance.ToAU(4495.1E6), 0.011, 1.8, 131.72169, 44.97135, 304.88003, GalaxyGen.J2000); * Neptune.Radius = Distance.ToAU(24764); * Neptune.Orbit.GetPosition(GameState.Instance.CurrentDate, out x, out y); * Neptune.Position.System = Sol; * Neptune.Position.X = x; * Neptune.Position.Y = y; * sun.Planets.Add(Neptune); * * SystemBody Pluto = new SystemBody(sun, SystemBody.PlanetType.DwarfPlanet); * Pluto.Name = "Pluto"; * Pluto.Orbit = Orbit.FromMajorPlanetFormat(0.0131E24, sun.Orbit.Mass, Distance.ToAU(5906.38E6), 0.24880766, 17.14175, 110.30347, 224.06676, 238.92881, GalaxyGen.J2000); * Pluto.Radius = Distance.ToAU(1195); * Pluto.Orbit.GetPosition(GameState.Instance.CurrentDate, out x, out y); * Pluto.Position.System = Sol; * Pluto.Position.X = x; * Pluto.Position.Y = y; * sun.Planets.Add(Pluto); * * GenerateJumpPoints(Sol); * * // Clean up cached RNG: * m_RNG = null; * GameState.Instance.StarSystems.Add(Sol); * GameState.Instance.StarSystemCurrentIndex++; */ /* * double planetSemiMajAxis = 0.387098; * double planetEccentricity = 0.205630; * double planetInclination = 0; * double planetLoAN = 0;//48.33167; * double planetLoP = 0;//77.45645; * double planetMeanLongd = 252.25084; * * EMWaveForm waveform; * * for (int i = 0; i < 8; i++) * { * NameDB planetNameDB = new NameDB("planetE" + i); * * SystemBodyInfoDB planetBodyDB = new SystemBodyInfoDB { BodyType = BodyType.Terrestrial, SupportsPopulations = true }; * MassVolumeDB planetMVDB = MassVolumeDB.NewFromMassAndRadius_AU(3.3022E23, Distance.KmToAU(2439.7)); * PositionDB planetPositionDB = new PositionDB(sol.ID); * planetEccentricity = i * 2 / 16.0; * OrbitDB planetOrbitDB = OrbitDB.FromMajorPlanetFormat(sun, sunMVDB.Mass, planetMVDB.Mass, planetSemiMajAxis, planetEccentricity, planetInclination, planetLoAN, planetLoP, planetMeanLongd, GalaxyGen.Settings.J2000); * planetPositionDB.AbsolutePosition = OrbitProcessor.GetPosition(planetOrbitDB, game.CurrentDateTime); * * waveform = new EMWaveForm() * { * WavelengthAverage_nm = 600, * WavelengthMin_nm = 600 - 400, //4k angstrom, semi arbitrary number pulled outa my ass from 0min of internet research. * WavelengthMax_nm = 600 + 600 * }; * * sensorProfile = new SensorProfileDB(); * sensorProfile.EmittedEMSpectra.Add(waveform, 3.827e23); * Entity planet = new Entity(sol, new List<BaseDataBlob> { sensorProfile, planetPositionDB, planetBodyDB, planetMVDB, planetNameDB, planetOrbitDB }); * } * * planetEccentricity = 0.9; * for (int i = 0; i < 8; i++) * { * NameDB planetNameDB = new NameDB("planetL" + i); * SystemBodyInfoDB planetBodyDB = new SystemBodyInfoDB { BodyType = BodyType.Terrestrial, SupportsPopulations = true }; * MassVolumeDB planetMVDB = MassVolumeDB.NewFromMassAndRadius_AU(3.3022E23, Distance.KmToAU(2439.7)); * PositionDB planetPositionDB = new PositionDB(sol.ID); * planetLoP = i * 15; * OrbitDB planetOrbitDB = OrbitDB.FromMajorPlanetFormat(sun, sunMVDB.Mass, planetMVDB.Mass, planetSemiMajAxis, planetEccentricity, planetInclination, planetLoAN, planetLoP, planetMeanLongd, GalaxyGen.Settings.J2000); * planetPositionDB.AbsolutePosition = OrbitProcessor.GetPosition(planetOrbitDB, game.CurrentDateTime); * * waveform = new EMWaveForm() * { * WavelengthAverage_nm = 600, * WavelengthMin_nm = 600 - 400, //4k angstrom, semi arbitrary number pulled outa my ass from 0min of internet research. * WavelengthMax_nm = 600 + 600 * }; * * sensorProfile = new SensorProfileDB(); * sensorProfile.EmittedEMSpectra.Add(waveform, 3.827e23); * Entity planet = new Entity(sol, new List<BaseDataBlob> {sensorProfile, planetPositionDB, planetBodyDB, planetMVDB, planetNameDB, planetOrbitDB }); * } */ JPSurveyFactory.GenerateJPSurveyPoints(sol); game.GameMasterFaction.GetDataBlob <FactionInfoDB>().KnownSystems.Add(sol.Guid); return(sol); }
/// <summary> /// creates an asteroid that will collide with the given entity on the given date. /// </summary> /// <param name="starSys"></param> /// <param name="target"></param> /// <param name="collisionDate"></param> /// <returns></returns> public static Entity CreateAsteroid(StarSystem starSys, Entity target, DateTime collisionDate, double asteroidMass = -1.0) { //todo rand these a bit. double radius = Distance.KmToAU(0.5); double mass; if (asteroidMass < 0) { mass = 1.5e+12; //about 1.5 billion tonne } else { mass = asteroidMass; } var speed = 40000; Vector3 velocity = new Vector3(speed, 0, 0); var massVolume = MassVolumeDB.NewFromMassAndRadius_AU(mass, radius); var planetInfo = new SystemBodyInfoDB(); var name = new NameDB("Ellie"); var AsteroidDmg = new AsteroidDamageDB(); AsteroidDmg.FractureChance = new PercentValue(0.75f); var dmgPfl = EntityDamageProfileDB.AsteroidDamageProfile(massVolume.Volume_km3, massVolume.Density, massVolume.RadiusInM, 50); var sensorPfil = new SensorProfileDB(); planetInfo.SupportsPopulations = false; planetInfo.BodyType = BodyType.Asteroid; Vector3 targetPos = OrbitProcessor.GetAbsolutePosition_m(target.GetDataBlob <OrbitDB>(), collisionDate); TimeSpan timeToCollision = collisionDate - StaticRefLib.CurrentDateTime; var parent = target.GetDataBlob <OrbitDB>().Parent; var parentMass = parent.GetDataBlob <MassVolumeDB>().Mass; var myMass = massVolume.Mass; double sgp = OrbitMath.CalculateStandardGravityParameterInM3S2(myMass, parentMass); OrbitDB orbit = OrbitDB.FromVector(parent, myMass, parentMass, sgp, targetPos, velocity, collisionDate); var currentpos = OrbitProcessor.GetAbsolutePosition_AU(orbit, StaticRefLib.CurrentDateTime); var posDB = new PositionDB(currentpos.X, currentpos.Y, currentpos.Z, parent.Manager.ManagerGuid, parent); var planetDBs = new List <BaseDataBlob> { posDB, massVolume, planetInfo, name, orbit, AsteroidDmg, dmgPfl, sensorPfil }; Entity newELE = new Entity(starSys, planetDBs); return(newELE); }
public static (Vector3 position, DateTime etiDateTime) GetInterceptPosition2(Vector3 moverPos, double speed, OrbitDB targetOrbit, DateTime atDateTime, Vector3 offsetPosition = new Vector3()) { var pos = moverPos; double tim = 0; var pl = new obit() { position = moverPos, T = targetOrbit.OrbitalPeriod.TotalSeconds, }; double a = targetOrbit.SemiMajorAxis * 2; Vector3 p; int i; double tt, t, dt, a0, a1, T; // find orbital position with min error (coarse) a1 = -1.0; dt = 0.01 * pl.T; for (t = 0; t < pl.T; t += dt) { p = OrbitProcessor.GetAbsolutePosition_AU(targetOrbit, atDateTime + TimeSpan.FromSeconds(t)); //pl.position(sim_t + t); // try time t p += offsetPosition; tt = Vector3.Magnitude(p - pos) / speed; //length(p - pos) / speed; a0 = tt - t; if (a0 < 0.0) { continue; // ignore overshoots } a0 /= pl.T; // remove full periods from the difference a0 -= Math.Floor(a0); a0 *= pl.T; if ((a0 < a1) || (a1 < 0.0)) { a1 = a0; tim = tt; } // remember best option } // find orbital position with min error (fine) for (i = 0; i < 10; i++) // recursive increase of accuracy { for (a1 = -1.0, t = tim - dt, T = tim + dt, dt *= 0.1; t < T; t += dt) { p = OrbitProcessor.GetAbsolutePosition_AU(targetOrbit, atDateTime + TimeSpan.FromSeconds(t)); //p = pl.position(sim_t + t); // try time t p += offsetPosition; tt = Vector3.Magnitude(p - pos) / speed; //tt = length(p - pos) / speed; a0 = tt - t; if (a0 < 0.0) { continue; // ignore overshoots } a0 /= pl.T; // remove full periods from the difference a0 -= Math.Floor(a0); a0 *= pl.T; if ((a0 < a1) || (a1 < 0.0)) { a1 = a0; tim = tt; } // remember best option } } // direction p = OrbitProcessor.GetAbsolutePosition_AU(targetOrbit, atDateTime + TimeSpan.FromSeconds(tim));//pl.position(sim_t + tim); p += offsetPosition; //dir = normalize(p - pos); return(p, atDateTime + TimeSpan.FromSeconds(tim)); }
/// <summary> /// Creates our own solar system. /// This probibly needs to be Json! (since we're getting atmo stuff) /// Adds sol to game.StarSystems. /// </summary> public StarSystem CreateSol(Game game) { // WIP Function. Not complete. StarSystem sol = new StarSystem(game, "Sol", -1); Entity sun = _starFactory.CreateStar(sol, GameConstants.Units.SolarMassInKG, GameConstants.Units.SolarRadiusInAu, 4.6E9, "G", 5778, 1, SpectralType.G, "Sol"); MassVolumeDB sunMVDB = sun.GetDataBlob <MassVolumeDB>(); SystemBodyInfoDB mercuryBodyDB = new SystemBodyInfoDB { BodyType = BodyType.Terrestrial, SupportsPopulations = true }; MassVolumeDB mercuryMVDB = MassVolumeDB.NewFromMassAndRadius(3.3022E23, Distance.KmToAU(2439.7)); NameDB mercuryNameDB = new NameDB("Mercury"); double mercurySemiMajAxis = 0.387098; double mercuryEccentricity = 0.205630; double mercuryInclination = 0; double mercuryLoAN = 48.33167; double mercuryLoP = 77.45645; double mercuryMeanLongd = 252.25084; OrbitDB mercuryOrbitDB = OrbitDB.FromMajorPlanetFormat(sun, sunMVDB.Mass, mercuryMVDB.Mass, mercurySemiMajAxis, mercuryEccentricity, mercuryInclination, mercuryLoAN, mercuryLoP, mercuryMeanLongd, GalaxyGen.Settings.J2000); PositionDB mercuryPositionDB = new PositionDB(OrbitProcessor.GetPosition(mercuryOrbitDB, game.CurrentDateTime), sol.Guid); Entity mercury = new Entity(sol.SystemManager, new List <BaseDataBlob> { mercuryPositionDB, mercuryBodyDB, mercuryMVDB, mercuryNameDB, mercuryOrbitDB }); _systemBodyFactory.MineralGeneration(game.StaticData, sol, mercury); SystemBodyInfoDB venusBodyDB = new SystemBodyInfoDB { BodyType = BodyType.Terrestrial, SupportsPopulations = true }; MassVolumeDB venusMVDB = MassVolumeDB.NewFromMassAndRadius(4.8676E24, Distance.KmToAU(6051.8)); NameDB venusNameDB = new NameDB("Venus"); double venusSemiMajAxis = 0.72333199; double venusEccentricity = 0.00677323; double venusInclination = 0; double venusLoAN = 76.68069; double venusLoP = 131.53298; double venusMeanLongd = 181.97973; OrbitDB venusOrbitDB = OrbitDB.FromMajorPlanetFormat(sun, sunMVDB.Mass, venusMVDB.Mass, venusSemiMajAxis, venusEccentricity, venusInclination, venusLoAN, venusLoP, venusMeanLongd, GalaxyGen.Settings.J2000); PositionDB venusPositionDB = new PositionDB(OrbitProcessor.GetPosition(venusOrbitDB, game.CurrentDateTime), sol.Guid); Entity venus = new Entity(sol.SystemManager, new List <BaseDataBlob> { venusPositionDB, venusBodyDB, venusMVDB, venusNameDB, venusOrbitDB }); _systemBodyFactory.MineralGeneration(game.StaticData, sol, venus); SystemBodyInfoDB earthBodyDB = new SystemBodyInfoDB { BodyType = BodyType.Terrestrial, SupportsPopulations = true }; MassVolumeDB earthMVDB = MassVolumeDB.NewFromMassAndRadius(5.9726E24, Distance.KmToAU(6378.1)); NameDB earthNameDB = new NameDB("Earth"); double earthSemiMajAxis = 1.00000011; double earthEccentricity = 0.01671022; double earthInclination = 0; double earthLoAN = -11.26064; double earthLoP = 102.94719; double earthMeanLongd = 100.46435; OrbitDB earthOrbitDB = OrbitDB.FromMajorPlanetFormat(sun, sunMVDB.Mass, earthMVDB.Mass, earthSemiMajAxis, earthEccentricity, earthInclination, earthLoAN, earthLoP, earthMeanLongd, GalaxyGen.Settings.J2000); earthBodyDB.Tectonics = TectonicActivity.EarthLike; PositionDB earthPositionDB = new PositionDB(OrbitProcessor.GetPosition(earthOrbitDB, game.CurrentDateTime), sol.Guid); Dictionary <AtmosphericGasSD, float> atmoGasses = new Dictionary <AtmosphericGasSD, float>(); atmoGasses.Add(game.StaticData.AtmosphericGases.SelectAt(6), 0.78f); atmoGasses.Add(game.StaticData.AtmosphericGases.SelectAt(9), 0.12f); atmoGasses.Add(game.StaticData.AtmosphericGases.SelectAt(11), 0.01f); AtmosphereDB earthAtmosphereDB = new AtmosphereDB(1f, true, 71, 1f, 1f, 0.3f, 57.2f, atmoGasses); //TODO what's our greenhouse factor an pressure? Entity earth = new Entity(sol.SystemManager, new List <BaseDataBlob> { earthPositionDB, earthBodyDB, earthMVDB, earthNameDB, earthOrbitDB, earthAtmosphereDB }); _systemBodyFactory.HomeworldMineralGeneration(game.StaticData, sol, earth); SystemBodyInfoDB lunaBodyDB = new SystemBodyInfoDB { BodyType = BodyType.Moon, SupportsPopulations = true }; MassVolumeDB lunaMVDB = MassVolumeDB.NewFromMassAndRadius(0.073E24, Distance.KmToAU(1738.14)); NameDB lunaNameDB = new NameDB("Luna"); double lunaSemiMajAxis = Distance.KmToAU(0.3844E6); double lunaEccentricity = 0.0549; double lunaInclination = 5.1; // Next three values are unimportant. Luna's LoAN and AoP regress/progress by one revolution every 18.6/8.85 years respectively. // Our orbit code it not advanced enough to deal with LoAN/AoP regression/progression. double lunaLoAN = 125.08; double lunaAoP = 318.0634; double lunaMeanAnomaly = 115.3654; OrbitDB lunaOrbitDB = OrbitDB.FromAsteroidFormat(earth, earthMVDB.Mass, lunaMVDB.Mass, lunaSemiMajAxis, lunaEccentricity, lunaInclination, lunaLoAN, lunaAoP, lunaMeanAnomaly, GalaxyGen.Settings.J2000); PositionDB lunaPositionDB = new PositionDB(OrbitProcessor.GetPosition(lunaOrbitDB, game.CurrentDateTime), sol.Guid); Entity luna = new Entity(sol.SystemManager, new List <BaseDataBlob> { lunaPositionDB, lunaBodyDB, lunaMVDB, lunaNameDB, lunaOrbitDB }); _systemBodyFactory.MineralGeneration(game.StaticData, sol, luna); SystemBodyInfoDB marsBodyDB = new SystemBodyInfoDB { BodyType = BodyType.Terrestrial, SupportsPopulations = true }; MassVolumeDB marsMVDB = MassVolumeDB.NewFromMassAndRadius(0.64174E24, Distance.KmToAU(3396.2)); NameDB marsNameDB = new NameDB("Mars"); double marsSemiMajAxis = Distance.KmToAU(227.92E6); double marsEccentricity = 0.0934; //wiki says .0934 double marsInclination = 1.85; double marsLoAN = 49.57854; double marsAoP = 336.04084; double marsMeanLong = 355.45332; OrbitDB marsOrbitDB = OrbitDB.FromMajorPlanetFormat(sun, sunMVDB.Mass, marsMVDB.Mass, marsSemiMajAxis, marsEccentricity, marsInclination, marsLoAN, marsAoP, marsMeanLong, GalaxyGen.Settings.J2000); PositionDB marsPositionDB = new PositionDB(OrbitProcessor.GetPosition(marsOrbitDB, game.CurrentDateTime), sol.Guid); Entity mars = new Entity(sol.SystemManager, new List <BaseDataBlob> { marsPositionDB, marsBodyDB, marsMVDB, marsNameDB, marsOrbitDB }); _systemBodyFactory.MineralGeneration(game.StaticData, sol, mars); /* * * SystemBody Mars = new SystemBody(sun, SystemBody.PlanetType.Terrestrial); * Mars.Name = "Mars"; * Mars.Orbit = Orbit.FromMajorPlanetFormat(0.64174E24, sun.Orbit.Mass, 1.52366231, 0.09341233, 1.85061, 49.57854, 336.04084, 355.45332, GalaxyGen.J2000); * Mars.Radius = Distance.ToAU(3396.2); * Mars.BaseTemperature = (float)CalculateBaseTemperatureOfBody(sun, Mars.Orbit.SemiMajorAxis);// 210.1f + (float)Constants.Units.KELVIN_TO_DEGREES_C; * Mars.Tectonics = SystemBody.TectonicActivity.Dead; * Mars.SurfaceGravity = 3.71f; * Mars.Atmosphere = new Atmosphere(Mars); * Mars.Atmosphere.Albedo = 0.250f; * Mars.Atmosphere.SurfaceTemperature = Mars.BaseTemperature; * AddGasToAtmoSafely(Mars.Atmosphere, AtmosphericGas.AtmosphericGases.SelectAt(12), 0.95f * 0.01f); // C02% * Mars Atms * AddGasToAtmoSafely(Mars.Atmosphere, AtmosphericGas.AtmosphericGases.SelectAt(6), 0.027f * 0.01f); // N% * Mars Atms * AddGasToAtmoSafely(Mars.Atmosphere, AtmosphericGas.AtmosphericGases.SelectAt(9), 0.007f * 0.01f); // O% * Mars Atms * AddGasToAtmoSafely(Mars.Atmosphere, AtmosphericGas.AtmosphericGases.SelectAt(11), 0.016f * 0.01f); // Ar% * Mars Atms * Mars.Atmosphere.UpdateState(); * Mars.Orbit.GetPosition(GameState.Instance.CurrentDate, out x, out y); * Mars.Position.System = Sol; * Mars.Position.X = x; * Mars.Position.Y = y; * sun.Planets.Add(Mars); * * SystemBody Jupiter = new SystemBody(sun, SystemBody.PlanetType.GasGiant); * Jupiter.Name = "Jupiter"; * Jupiter.Orbit = Orbit.FromMajorPlanetFormat(1898.3E24, sun.Orbit.Mass, 5.20336301, 0.04839266, 1.30530, 100.55615, 14.75385, 34.40438, GalaxyGen.J2000); * Jupiter.Radius = Distance.ToAU(71492); * Jupiter.Orbit.GetPosition(GameState.Instance.CurrentDate, out x, out y); * Jupiter.Position.System = Sol; * Jupiter.Position.X = x; * Jupiter.Position.Y = y; * sun.Planets.Add(Jupiter); * * SystemBody Saturn = new SystemBody(sun, SystemBody.PlanetType.GasGiant); * Saturn.Name = "Saturn"; * Saturn.Orbit = Orbit.FromMajorPlanetFormat(568.36E24, sun.Orbit.Mass, 9.53707032, 0.05415060, 2.48446, 113.71504, 92.43194, 49.94432, GalaxyGen.J2000); * Saturn.Radius = Distance.ToAU(60268); * Saturn.Orbit.GetPosition(GameState.Instance.CurrentDate, out x, out y); * Saturn.Position.System = Sol; * Saturn.Position.X = x; * Saturn.Position.Y = y; * sun.Planets.Add(Saturn); * * SystemBody Uranus = new SystemBody(sun, SystemBody.PlanetType.IceGiant); * Uranus.Name = "Uranus"; * Uranus.Orbit = Orbit.FromMajorPlanetFormat(86.816E24, sun.Orbit.Mass, 19.19126393, 0.04716771, 0.76986, 74.22988, 170.96424, 313.23218, GalaxyGen.J2000); * Uranus.Radius = Distance.ToAU(25559); * Uranus.Orbit.GetPosition(GameState.Instance.CurrentDate, out x, out y); * Uranus.Position.System = Sol; * Uranus.Position.X = x; * Uranus.Position.Y = y; * sun.Planets.Add(Uranus); * * SystemBody Neptune = new SystemBody(sun, SystemBody.PlanetType.IceGiant); * Neptune.Name = "Neptune"; * Neptune.Orbit = Orbit.FromMajorPlanetFormat(102E24, sun.Orbit.Mass, Distance.ToAU(4495.1E6), 0.011, 1.8, 131.72169, 44.97135, 304.88003, GalaxyGen.J2000); * Neptune.Radius = Distance.ToAU(24764); * Neptune.Orbit.GetPosition(GameState.Instance.CurrentDate, out x, out y); * Neptune.Position.System = Sol; * Neptune.Position.X = x; * Neptune.Position.Y = y; * sun.Planets.Add(Neptune); * * SystemBody Pluto = new SystemBody(sun, SystemBody.PlanetType.DwarfPlanet); * Pluto.Name = "Pluto"; * Pluto.Orbit = Orbit.FromMajorPlanetFormat(0.0131E24, sun.Orbit.Mass, Distance.ToAU(5906.38E6), 0.24880766, 17.14175, 110.30347, 224.06676, 238.92881, GalaxyGen.J2000); * Pluto.Radius = Distance.ToAU(1195); * Pluto.Orbit.GetPosition(GameState.Instance.CurrentDate, out x, out y); * Pluto.Position.System = Sol; * Pluto.Position.X = x; * Pluto.Position.Y = y; * sun.Planets.Add(Pluto); * * GenerateJumpPoints(Sol); * * // Clean up cached RNG: * m_RNG = null; * GameState.Instance.StarSystems.Add(Sol); * GameState.Instance.StarSystemCurrentIndex++; */ JPSurveyFactory.GenerateJPSurveyPoints(sol); game.GameMasterFaction.GetDataBlob <FactionInfoDB>().KnownSystems.Add(sol.Guid); return(sol); }
/// <summary> /// This was designed so that fast moving objects will get interpolated a lot more than slow moving objects /// so fast moving objects shouldn't loose positional acuracy when close to a planet, /// and slow moving objects won't have processor time wasted on them by calulcating too often. /// However this seems to be unstable and looses energy, unsure why. currently set it to just itterate/interpolate every second. /// so currently will be using more time to get through this than neccisary. /// </summary> /// <param name="entity">Entity.</param> /// <param name="deltaSeconds">Delta seconds.</param> public static void NewtonMove(Entity entity, int deltaSeconds) { NewtonMoveDB newtonMoveDB = entity.GetDataBlob <NewtonMoveDB>(); NewtonThrustAbilityDB newtonThrust = entity.GetDataBlob <NewtonThrustAbilityDB>(); PositionDB positionDB = entity.GetDataBlob <PositionDB>(); double mass_Kg = entity.GetDataBlob <MassVolumeDB>().Mass; double parentMass_kg = newtonMoveDB.ParentMass; var manager = entity.Manager; DateTime dateTimeFrom = newtonMoveDB.LastProcessDateTime; DateTime dateTimeNow = manager.ManagerSubpulses.StarSysDateTime; DateTime dateTimeFuture = dateTimeNow + TimeSpan.FromSeconds(deltaSeconds); double deltaT = (dateTimeFuture - dateTimeFrom).TotalSeconds; double secondsToItterate = deltaT; while (secondsToItterate > 0) { //double timeStep = Math.Max(secondsToItterate / speed_kms, 1); //timeStep = Math.Min(timeStep, secondsToItterate); double timeStepInSeconds = 1;//because the above seems unstable and looses energy. double distanceToParent_m = positionDB.GetDistanceTo_m(newtonMoveDB.SOIParent.GetDataBlob <PositionDB>()); distanceToParent_m = Math.Max(distanceToParent_m, 0.1); //don't let the distance be 0 (once collision is in this will likely never happen anyway) double gravForce = GameConstants.Science.GravitationalConstant * (mass_Kg * parentMass_kg / Math.Pow(distanceToParent_m, 2)); Vector3 gravForceVector = gravForce * -Vector3.Normalise(positionDB.RelativePosition_m); Vector3 totalDVFromGrav = (gravForceVector / mass_Kg) * timeStepInSeconds; double maxAccelFromThrust1 = newtonThrust.ExhaustVelocity * Math.Log(mass_Kg / (mass_Kg - newtonThrust.FuelBurnRate)); //per second double maxAccelFromThrust = newtonThrust.ThrustInNewtons / mass_Kg; //per second Vector3 manuverDV = newtonMoveDB.DeltaVForManuver_m; //how much dv needed to complete the manuver. double dryMass = mass_Kg - newtonThrust.FuelBurnRate * timeStepInSeconds; //how much our ship weighs after a timestep of fuel is used. //how much dv can we get in this timestep. double deltaVThisStep = OrbitMath.TsiolkovskyRocketEquation(mass_Kg, dryMass, newtonThrust.ExhaustVelocity); deltaVThisStep = Math.Min(manuverDV.Length(), deltaVThisStep); //don't use more Dv than what is called for. deltaVThisStep = Math.Min(newtonThrust.DeltaV, deltaVThisStep); //check we've got the deltaV to spend. Vector3 totalDVFromThrust = Vector3.Normalise(manuverDV) * deltaVThisStep; //remove the deltaV we're expending from the max (TODO: Remove fuel from cargo, change mass of ship) newtonThrust.DeltaV -= deltaVThisStep; //remove the vectorDV from the amount needed to fully complete the manuver. newtonMoveDB.DeltaVForManuver_m -= totalDVFromThrust; Vector3 totalDV = totalDVFromGrav + totalDVFromThrust; Vector3 newVelocity = totalDV + newtonMoveDB.CurrentVector_ms; newtonMoveDB.CurrentVector_ms = newVelocity; Vector3 deltaPos = (newtonMoveDB.CurrentVector_ms + newVelocity) / 2 * timeStepInSeconds; positionDB.RelativePosition_m += deltaPos; double sOIRadius = OrbitProcessor.GetSOI_m(newtonMoveDB.SOIParent); if (positionDB.RelativePosition_m.Length() >= sOIRadius) { Entity newParent; Vector3 parentRalitiveVector; //if our parent is a regular kepler object (normaly this is the case) if (newtonMoveDB.SOIParent.HasDataBlob <OrbitDB>()) { var orbitDB = newtonMoveDB.SOIParent.GetDataBlob <OrbitDB>(); newParent = orbitDB.Parent; var parentVelocity = OrbitProcessor.InstantaneousOrbitalVelocityVector_m(orbitDB, entity.StarSysDateTime); parentRalitiveVector = newtonMoveDB.CurrentVector_ms + parentVelocity; } else //if (newtonMoveDB.SOIParent.HasDataBlob<NewtonMoveDB>()) { //this will pretty much never happen. newParent = newtonMoveDB.SOIParent.GetDataBlob <NewtonMoveDB>().SOIParent; var parentVelocity = newtonMoveDB.SOIParent.GetDataBlob <NewtonMoveDB>().CurrentVector_ms; parentRalitiveVector = newtonMoveDB.CurrentVector_ms + parentVelocity; } parentMass_kg = newParent.GetDataBlob <MassVolumeDB>().Mass; Vector3 posRalitiveToNewParent = positionDB.AbsolutePosition_m - newParent.GetDataBlob <PositionDB>().AbsolutePosition_m; var dateTime = dateTimeNow + TimeSpan.FromSeconds(deltaSeconds - secondsToItterate); double sgp = GMath.StandardGravitationalParameter(parentMass_kg + mass_Kg); var kE = OrbitMath.KeplerFromPositionAndVelocity(sgp, posRalitiveToNewParent, parentRalitiveVector, dateTime); positionDB.SetParent(newParent); newtonMoveDB.ParentMass = parentMass_kg; newtonMoveDB.SOIParent = newParent; newtonMoveDB.CurrentVector_ms = parentRalitiveVector; } if (newtonMoveDB.DeltaVForManuver_m.Length() <= 0) //if we've completed the manuver. { var dateTime = dateTimeNow + TimeSpan.FromSeconds(deltaSeconds - secondsToItterate); double sgp = GMath.StandardGravitationalParameter(parentMass_kg + mass_Kg); KeplerElements kE = OrbitMath.KeplerFromPositionAndVelocity(sgp, positionDB.RelativePosition_m, newtonMoveDB.CurrentVector_ms, dateTime); var parentEntity = Entity.GetSOIParentEntity(entity, positionDB); if (kE.Eccentricity < 1) //if we're going to end up in a regular orbit around our new parent { var newOrbit = OrbitDB.FromKeplerElements( parentEntity, mass_Kg, kE, dateTime); entity.RemoveDataBlob <NewtonMoveDB>(); entity.SetDataBlob(newOrbit); positionDB.SetParent(parentEntity); var newPos = OrbitProcessor.GetPosition_m(newOrbit, dateTime); positionDB.RelativePosition_m = newPos; } break; } secondsToItterate -= timeStepInSeconds; } newtonMoveDB.LastProcessDateTime = dateTimeFuture; }