public Overlay(string planet, float altitude, Material scaledMaterial, Material macroMaterial, Vector2 rotation, int layer, Transform celestialTransform, bool mainMenu, bool matchTerrain)
        {
            this.MainMenu = mainMenu;
            this.OverlayGameObject = new GameObject();
            this.Body = planet;
            this.Rotation = rotation;
            this.scaledMaterial = scaledMaterial;
            this.macroMaterial = macroMaterial;
            this.OriginalLayer = layer;
            this.celestialTransform = celestialTransform;
            this.altitude = altitude;
            this.matchTerrain = matchTerrain;

            CelestialBody[] celestialBodies = (CelestialBody[])CelestialBody.FindObjectsOfType(typeof(CelestialBody));
            celestialBody = celestialBodies.First(n => n.bodyName == this.Body);

            if (!mainMenu && matchTerrain)
            {
                IsoSphere.Create(OverlayGameObject, this.altitude, celestialBody);
            }
            else
            {
                IsoSphere.Create(OverlayGameObject, this.Radius, null);
            }

            var mr = OverlayGameObject.AddComponent<MeshRenderer>();
            mr.sharedMaterial = scaledMaterial;
            mr.castShadows = false;
            mr.receiveShadows = false;
            //mr.enabled = mainMenu;
            mr.enabled = true;
        }
        public PowerUpDarkSide(Simulator simulator)
            : base(simulator)
        {
            Type = PowerUpType.DarkSide;
            Category = PowerUpCategory.Other;
            BuyImage = "darkside";
            BuyPrice = 500;
            BuyTitle = "Dark side (" + BuyPrice + "M$)";
            BuyDescription = "Enemies are hit by a mysterious force when they go behind a planet.";
            NeedInput = false;
            Position = Vector3.Zero;

            CorpsCeleste = new CelestialBody(
                    Simulation,
                    "",
                    Vector3.Zero,
                    Vector3.Zero,
                    0,
                    Size.Small,
                    float.MaxValue,
                    null,
                    0,
                    0,
                    false);
            CorpsCeleste.AttackPoints = 0.5f;

            SfxIn = "sfxDarkSide";
        }
Example #3
0
	protected override void Start()
	{
		//Initialize the map object
		Visible = SCANcontroller.controller.bigMapVisible;
		if (v == null)
			v = FlightGlobals.ActiveVessel;
		if (b == null)
			b = v.mainBody;
		if (bigmap == null)
		{
			bigmap = new SCANmap(b, true);
			bigmap.setProjection((MapProjection)SCANcontroller.controller.projection);
			bigmap.setWidth(SCANcontroller.controller.map_width);
		}
		WindowRect.x = SCANcontroller.controller.map_x;
		WindowRect.y = SCANcontroller.controller.map_y;
		currentColor = SCANcontroller.controller.colours == 0;
		lastColor = currentColor;
		lastResource = SCANcontroller.controller.map_ResourceOverlay;
		WindowCaption = string.Format("Map of {0}", b.theName);
		data = SCANUtil.getData(b);
		if (data == null)
		{
			data = new SCANdata(b);
			SCANcontroller.controller.addToBodyData(b, data);
		}
		bigmap.setBody(b);
		if (SCANconfigLoader.GlobalResource)
		{
			loadedResources = SCANcontroller.setLoadedResourceList();
		}
		TooltipsEnabled = SCANcontroller.controller.toolTips;
	}
		public progressBodyCollection(CelestialBodySubtree b)
		{
			body = b.Body;

			if (b.Body.isHomeWorld)
			{
				homeworld = true;
			}
			else
			{
				addProgressStandard(ProgressType.FLIGHT, b.Body, b.flight, progressParser.flightDescriptor, progressParser.StandardNote, progressParser.vesselNameFromNode(b.flight));
				addProgressStandard(ProgressType.SUBORBIT, b.Body, b.suborbit, progressParser.suborbitDescriptor, progressParser.StandardNote, progressParser.vesselNameFromNode(b.suborbit));
				addProgressStandard(ProgressType.FLYBY, b.Body, b.flyBy, progressParser.flybyDescriptor);
				addProgressStandard(ProgressType.FLYBYRETURN, b.Body, b.returnFromFlyby, progressParser.returnFlybyDescriptor, progressParser.RecoveryNote, progressParser.vesselNameFromNode(b.returnFromFlyby));
				addProgressStandard(ProgressType.LANDINGRETURN, b.Body, b.returnFromSurface, progressParser.returnLandingDescriptor, progressParser.RecoveryNote, progressParser.vesselNameFromNode(b.returnFromSurface));
			}

			addProgressStandard(ProgressType.ESCAPE, b.Body, b.escape, progressParser.escapeDescriptor);
			addProgressStandard(ProgressType.BASECONSTRUCTION, b.Body, b.baseConstruction, progressParser.baseDescriptor, progressParser.FacilityNote, progressParser.vesselNameFromNode(b.baseConstruction));
			addProgressStandard(ProgressType.CREWTRANSFER, b.Body, b.crewTransfer, progressParser.crewTransferDescriptor);
			addProgressStandard(ProgressType.DOCKING, b.Body, b.docking, progressParser.dockingDescriptor);
			addProgressStandard(ProgressType.FLAGPLANT, b.Body, b.flagPlant, progressParser.flagDescriptor);
			addProgressStandard(ProgressType.LANDING, b.Body, b.landing, progressParser.landingDescriptor, progressParser.StandardNote, progressParser.vesselNameFromNode(b.landing));
			addProgressStandard(ProgressType.ORBIT, b.Body, b.orbit, progressParser.orbitDescriptor, progressParser.StandardNote, progressParser.vesselNameFromNode(b.orbit));
			addProgressStandard(ProgressType.ORBITRETURN, b.Body, b.returnFromOrbit, progressParser.returnOrbitDescriptor, progressParser.RecoveryNote, progressParser.vesselNameFromNode(b.returnFromOrbit));
			addProgressStandard(ProgressType.RENDEZVOUS, b.Body, b.rendezvous, progressParser.rendezvousDescriptor);
			addProgressStandard(ProgressType.SCIENCE, b.Body, b.science, progressParser.scienceDescriptor, progressParser.StandardNote, progressParser.vesselNameFromNode(b.science));
			addProgressStandard(ProgressType.SPACEWALK, b.Body, b.spacewalk, progressParser.spacewalkDescriptor, progressParser.CrewNote, progressParser.crewNameFromNode(b.spacewalk));
			addProgressStandard(ProgressType.SPLASHDOWN, b.Body, b.splashdown, progressParser.splashdownDescriptor);
			addProgressStandard(ProgressType.STATIONCONSTRUCTION, b.Body, b.stationConstruction, progressParser.stationDescriptor, progressParser.FacilityNote, progressParser.vesselNameFromNode(b.stationConstruction));
			addProgressStandard(ProgressType.SURFACEEVA, b.Body, b.surfaceEVA, progressParser.EVADescriptor, progressParser.CrewNote, progressParser.crewNameFromNode(b.surfaceEVA));
		}
Example #5
0
        public static void DrawMapViewGroundMarker(CelestialBody body, double latitude, double longitude, Color c, double rotation = 0, double radius = 0)
        {
            Vector3d up = body.GetSurfaceNVector(latitude, longitude);
            var height = body.pqsController.GetSurfaceHeight(QuaternionD.AngleAxis(longitude, Vector3d.down) * QuaternionD.AngleAxis(latitude, Vector3d.forward) * Vector3d.right);
            if (height < body.Radius) { height = body.Radius; }
            Vector3d center = body.position + height * up;

            if (IsOccluded(center, body)) return;

            Vector3d north = Vector3d.Exclude(up, body.transform.up).normalized;

            if (radius <= 0) { radius = body.Radius / 15; }

            GLTriangleMap(new Vector3d[]{
                center,
                center + radius * (QuaternionD.AngleAxis(rotation - 10, up) * north),
                center + radius * (QuaternionD.AngleAxis(rotation + 10, up) * north)
            }, c);

            GLTriangleMap(new Vector3d[]{
                center,
                center + radius * (QuaternionD.AngleAxis(rotation + 110, up) * north),
                center + radius * (QuaternionD.AngleAxis(rotation + 130, up) * north)
            }, c);

            GLTriangleMap(new Vector3d[]{
                center,
                center + radius * (QuaternionD.AngleAxis(rotation - 110, up) * north),
                center + radius * (QuaternionD.AngleAxis(rotation - 130, up) * north)
            }, c);
        }
        public static VesselAerodynamicModel GetModel(Vessel ship, CelestialBody body)
        {
            foreach (var loadedAssembly in AssemblyLoader.loadedAssemblies)
            {
                try
                {
                    switch (loadedAssembly.name)
                    {
                        case "FerramAerospaceResearch":
                            var FARAPIType = loadedAssembly.assembly.GetType("FerramAerospaceResearch.FARAPI");

                                var FARAPI_CalculateVesselAeroForces = FARAPIType.GetMethodEx("CalculateVesselAeroForces", BindingFlags.Public | BindingFlags.Static, new Type[] { typeof(Vessel), typeof(Vector3).MakeByRefType(), typeof(Vector3).MakeByRefType(), typeof(Vector3), typeof(double) });

                            return new FARModel(ship, body, FARAPI_CalculateVesselAeroForces);

                        //case "MyModAssembly":
                        // implement here your atmo mod detection
                        // return new MyModModel(ship, body, any other parameter);
                    }
                }
                catch (Exception e)
                {
                    Debug.Log("Trajectories: failed to interface with assembly " + loadedAssembly.name);
                    Debug.Log("Using stock model instead");
                    Debug.Log(e.ToString());
                }
            }

            // Using stock model if no other aerodynamic is detected or if any error occured
            return new StockModel(ship, body);
        }
Example #7
0
 public static Vector3 GetNorthVector(Vector3 position, CelestialBody body)
 {
     Vector3 geoPosA = VectorUtils.WorldPositionToGeoCoords(position, body);
     Vector3 geoPosB = new Vector3(geoPosA.x+1, geoPosA.y, geoPosA.z);
     Vector3 north = GetWorldSurfacePostion(geoPosB, body)-GetWorldSurfacePostion(geoPosA, body);
     return Vector3.ProjectOnPlane(north, body.GetSurfaceNVector(geoPosA.x, geoPosA.y)).normalized;
 }
 public LocationAndSituationParameter()
 {
     targetSituation = Vessel.Situations.ESCAPING;
     targetBody = null;
     noun = "potato";
     this.successCounter = 0;
 }
 public LocationAndSituationParameter(CelestialBody targetBody, Vessel.Situations targetSituation, string noun)
 {
     this.targetBody = targetBody;
     this.targetSituation = targetSituation;
     this.noun = noun;
     this.successCounter = 0;
 }
        public static double GetPressure(Vector3 position, CelestialBody body)
        {
            double latitude = body.GetLatitude(position) / 180.0 * Math.PI;
            double altitude = (position - body.position).magnitude - body.Radius;
            return GetPressure(altitude, latitude, body);

        }
Example #11
0
        private static Orbit CreateOrbit(double inc, double e, double sma, double lan, double w, double mEp, double epoch, CelestialBody body)
        {
            if (double.IsNaN(inc))
                inc = 0;
            if (double.IsNaN(e))
                e = 0;
            if (double.IsNaN(sma))
                sma = body.Radius + body.maxAtmosphereAltitude + 10000;
            if (double.IsNaN(lan))
                lan = 0;
            if (double.IsNaN(w))
                w = 0;
            if (double.IsNaN(mEp))
                mEp = 0;
            if (double.IsNaN(epoch))
                mEp = Planetarium.GetUniversalTime();

            if (Math.Sign(e - 1) == Math.Sign(sma))
                sma = -sma;

            if (Math.Sign(sma) >= 0)
            {
                while (mEp < 0)
                    mEp += Math.PI * 2;
                while (mEp > Math.PI * 2)
                    mEp -= Math.PI * 2;
            }

            return new Orbit(inc, e, sma, lan, w, mEp, epoch, body);
        }
        double tauP; //normalized parabolic transfer time

        #endregion Fields

        #region Constructors

        /// <summary>
        /// Initializes a new instance of the <see cref="ThrottleControlledAvionics.LambertSolver"/> class.
        /// </summary>
        /// <param name="orb">Starting orbit.</param>
        /// <param name="destination">Destination radius-vector.</param>
        /// <param name="UT">Starting UT.</param>
        public LambertSolver(Orbit orb, Vector3d destination, double UT)
        {
            orbit = orb;
            body = orbit.referenceBody;
            StartUT = UT;
            mu = body.gravParameter;

            r1 = orb.getRelativePositionAtUT(UT);
            var h  = Vector3d.Cross(r1, destination);
            if(h.sqrMagnitude < 0.01) h = orb.GetOrbitNormal();
            c  = destination-r1;

            cm  = c.magnitude;
            var r1m = r1.magnitude;
            var r2m = destination.magnitude;
            var rrm = r1m+r2m;
            m  = rrm+cm;
            n  = rrm-cm;
            m3 = m*m*m;

            var transfer_angle = Vector3d.Angle(r1, destination)*Mathf.Deg2Rad;
            if(h.z < 0) transfer_angle = Utils.TwoPI-transfer_angle;
            sigma = Math.Sqrt(n/m);
            if(transfer_angle > Math.PI) sigma = -sigma;
            sigma2 = sigma*sigma;
            sigma3 = sigma2*sigma;
            sigma5 = sigma2*sigma3;

            tauP = 2/3.0*(1-sigma3);
            tauME = Math.Acos(sigma)+sigma*Math.Sqrt(1-sigma2);
        }
Example #13
0
        void Start() {
            if ( !Target ) {
                var ship = GameObject.Find( "Ship" );
                if ( ship ) {
                    Target = ship.GetComponentInParent<CelestialBody>();
                }
            }
            _defaultTimeScale = SimulationControl.instance.TimeScale;
            if ( timeScaleButtons.Length == 3 ) {
                timeScaleButtons[0].interactable = false;
            }
            if ( !ShipControl ) {
                ShipControl = Target.GetComponent<ShipController>();
            }
            if ( !FuelSlider ) {
				Debug.Log("SpaceGravity2D.ShipGUI: fuel slider ref is null");
            } else {
                FuelSlider.maxValue = ShipControl.MaxFuel;
                FuelSlider.value = ShipControl.Fuel;
            }
            if ( MarkPrefab ) {
                _markApoapsis = Instantiate( MarkPrefab ) as Transform;
                _markApoapsis.name = "apoapsisMark";
                _markApoapsis.GetComponentInChildren<Text>().text = "A";
                _markPeriapsis = Instantiate( MarkPrefab ) as Transform;
                _markPeriapsis.name = "periapsisMark";
                _markPeriapsis.GetComponentInChildren<Text>().text = "P";
            }

        }
            public VesselData(VesselData vd)
            {
                name = vd.name;
                id = vd.id;
                craftURL = vd.craftURL;
                craftPart = vd.craftPart;
                flagURL = vd.flagURL;
                vesselType = vd.vesselType;
                body = vd.body;
                orbit = vd.orbit;
                latitude = vd.latitude;
                longitude = vd.longitude;
                altitude = vd.altitude;
                height = vd.height;
                orbiting = vd.orbiting;
                owned = vd.owned;
                pqsCity = vd.pqsCity;
                pqsOffset = vd.pqsOffset;
                heading = vd.heading;
                pitch = vd.pitch;
                roll = vd.roll;

                foreach (CrewData cd in vd.crew)
                {
                    crew.Add(new CrewData(cd));
                }
            }
Example #15
0
 public static void Complex(OrbitDriver currentlyEditing, double inclination, double eccentricity,
     double semiMajorAxis, double longitudeAscendingNode, double argumentOfPeriapsis,
     double meanAnomalyAtEpoch, double epoch, CelestialBody body)
 {
     SetOrbit(currentlyEditing, CreateOrbit(inclination, eccentricity, semiMajorAxis,
         longitudeAscendingNode, argumentOfPeriapsis, meanAnomalyAtEpoch, epoch, body));
 }
Example #16
0
 public static float getMaxAtmosphericAltitude(CelestialBody body) 
 {
     if (!body.atmosphere) return 0;
     
     //return (float)-body.atmosphereScaleHeight * 1000.0f * Mathf.Log(1e-6f);
     return (float)-body.atmosphereDepth * 1000.0f * Mathf.Log(1e-6f);
 }
Example #17
0
        protected override Vector3 UpdatePosition()
        {
            if (EditorLogic.RootPart == null) {
                /* DragCubes can get NaNed without this check */
                return Vector3.zero;
            }
            if (RCSBuildAid.Mode != PluginMode.Parachutes) {
                return Vector3.zero;
            }

            hasParachutes = RCSBuildAid.Parachutes.Count > 0;
            body = Settings.selected_body;
            altitude = MenuParachutes.altitude;
            temperature = body.GetTemperature (altitude);
            pressure = body.GetPressure (altitude);
            density = body.GetDensity (pressure, temperature);
            mach = (float)(speed / body.GetSpeedOfSound(pressure, density));
            gravity = body.gravity(altitude);

            findCenterOfDrag();
            speed = Vt = calculateTerminalVelocity ();
            /* unless I go at mach speeds I don't care about this
            reynolds = (float)(density * speed);
            reynoldsDragMult = PhysicsGlobals.DragCurvePseudoReynolds.Evaluate (reynolds);
            */
            dragForce.Vector = calculateDragForce ();

            return position;
        }
 public CelestialBodyCoverageParameter(double coverage, CelestialBody targetBody, string title = null)
     : base(title)
 {
     this.coverage = coverage;
     this.targetBody = targetBody;
     disableOnStateChange = false;
 }
Example #19
0
		private void Startup()
		{
			//Initialize the map object
			Visible = false;
			if (HighLogic.LoadedSceneIsFlight)
			{
				v = SCANcontroller.controller.BigMap.V;
				b = SCANcontroller.controller.BigMap.Body;
				data = SCANcontroller.controller.BigMap.Data;
			}
			else if (HighLogic.LoadedSceneHasPlanetarium)
			{
				v = null;
				b = SCANcontroller.controller.kscMap.Body;
				data = SCANcontroller.controller.kscMap.Data;
			}
			if (spotmap == null)
			{
				spotmap = new SCANmap();
				spotmap.setSize(320, 240);
			}

			showOrbit = SCANcontroller.controller.map_orbit;
			showAnomaly = SCANcontroller.controller.map_markers;

			if (HighLogic.LoadedScene == GameScenes.SPACECENTER)
				showWaypoints = false;
			else
				showWaypoints = SCANcontroller.controller.map_waypoints;

			TooltipsEnabled = SCANcontroller.controller.toolTips;

			spotmap.setBody(b);
		}
Example #20
0
            public Vector3d velocity; // velocity in world frame relatively to the reference body

            public VesselState(Vessel vessel)
            {
                referenceBody = vessel.orbit.referenceBody;
                time = Planetarium.GetUniversalTime();
                position = vessel.GetWorldPos3D() - referenceBody.position;
                velocity = vessel.obt_velocity;
            }
        public PerformOrbitalSurvey(string title,  CelestialBody targetBody)
            : base(title)
        {
            disableOnStateChange = true;

            this.targetBody = targetBody;
        }
Example #22
0
        public static void UpdateThermodynamicsPre(ModularFI.ModularFlightIntegrator fi)
        {
            if (fi.CurrentMainBody != body)
            {
                body = fi.CurrentMainBody;
                RealHeatUtils.baseTempCurve.CalculateNewAtmTempCurve(body, RealHeatUtils.debugging);
            }

            if (fi.staticPressurekPa > 0d)
            {
                float spd = (float)fi.spd;

                // set shock temperature
                fi.Vessel.externalTemperature = fi.externalTemperature = fi.atmosphericTemperature + (double)RealHeatUtils.baseTempCurve.EvaluateTempDiffCurve(spd);

                // get gamma
                double Cp = (double)RealHeatUtils.baseTempCurve.EvaluateVelCpCurve(spd);
                double R = (double)RealHeatUtils.baseTempCurve.specificGasConstant;
                double Cv = Cp - R;
                double gamma = Cp / Cv;

                // change density lerp
                double shockDensity = GetShockDensity(fi.density, fi.mach, gamma);
                fi.DensityThermalLerp = CalculateDensityThermalLerp(shockDensity);

                // reset background temps
                fi.backgroundRadiationTemp = CalculateBackgroundRadiationTemperature(fi.atmosphericTemperature, fi.DensityThermalLerp);
                fi.backgroundRadiationTempExposed = CalculateBackgroundRadiationTemperature(fi.externalTemperature * 2d, fi.DensityThermalLerp); // blunt bodies multiply BRT by 0.5, so multiply by 2 here.
                //print("At rho " + fi.density + "/" + shockDensity + ", gamma " + gamma + ", DTL " + fi.DensityThermalLerp + ", BT = " + fi.backgroundRadiationTempExposed.ToString("N2") + "/" + fi.backgroundRadiationTemp.ToString("N2"));
            }
        }
Example #23
0
	protected override void Start()
	{
		Visible = SCANcontroller.controller.kscMapVisible;
		if (b == null)
			b = Planetarium.fetch.Home;
		if (bigmap == null)
		{
			bigmap = new SCANmap(b, true);
			bigmap.setProjection((MapProjection)SCANcontroller.controller.projection);
			bigmap.setWidth(720);
		}
		currentColor = SCANcontroller.controller.colours == 0;
		lastColor = currentColor;
		lastResource = SCANcontroller.controller.map_ResourceOverlay;
		WindowCaption = string.Format("Map of {0}", b.theName);
		data = SCANUtil.getData(b);
		if (data == null)
		{
			data = new SCANdata(b);
			SCANcontroller.controller.addToBodyData(b, data);
		}
		bigmap.setBody(b);
		if (SCANconfigLoader.GlobalResource)
		{
			loadedResources = SCANcontroller.setLoadedResourceList();
		}
		TooltipsEnabled = SCANcontroller.controller.toolTips;
	}
 public static void GravParamToOthers(CelestialBody body)
 {
     double rsq = body.Radius * body.Radius;
     body.Mass = body.gravParameter * (1 / 6.674E-11);
     body.GeeASL = body.gravParameter / 9.81 / rsq;
     body.gMagnitudeAtCenter = body.gravParameter;
 }
		private static void DrawOrbit(Orbit o, CelestialBody referenceBody, Matrix4x4 screenTransform, int numSegments)
		{
			if (!o.activePatch) {
				return;
			}

			double startTA;
			double endTA;
			double now = Planetarium.GetUniversalTime();
			if (o.patchEndTransition != Orbit.PatchTransitionType.FINAL) {
				startTA = o.TrueAnomalyAtUT(o.StartUT);
				endTA = o.TrueAnomalyAtUT(o.EndUT);
				if (endTA < startTA) {
					endTA += 2.0 * Math.PI;
				}
			} else {
				startTA = o.GetUTforTrueAnomaly(0.0, now);
				endTA = startTA + 2.0 * Math.PI;
			}
			double dTheta = (endTA - startTA) / (double)numSegments;
			double theta = startTA;
			double timeAtTA = o.GetUTforTrueAnomaly(theta, now);
			Vector3 lastVertex = screenTransform.MultiplyPoint3x4(o.getRelativePositionFromTrueAnomaly(theta).xzy + (o.referenceBody.getTruePositionAtUT(timeAtTA)) - (referenceBody.getTruePositionAtUT(timeAtTA)));
			for (int i = 0; i < numSegments; ++i) {
				GL.Vertex3(lastVertex.x, lastVertex.y, 0.0f);
				theta += dTheta;
				timeAtTA = o.GetUTforTrueAnomaly(theta, now);

				Vector3 newVertex = screenTransform.MultiplyPoint3x4(o.getRelativePositionFromTrueAnomaly(theta).xzy + (o.referenceBody.getTruePositionAtUT(timeAtTA)) - (referenceBody.getTruePositionAtUT(timeAtTA)));
				GL.Vertex3(newVertex.x, newVertex.y, 0.0f);

				lastVertex = newVertex;
			}
		}
        public bool isValidFor(Vessel vessel, CelestialBody body)
        {
            if (vessel != vessel_ || body_ != body)
                return false;

            if (Settings.fetch.AutoUpdateAerodynamicModel)
            {
                double newRefDrag = computeFARReferenceDrag();
                if (referenceDrag == 0)
                {
                    referenceDrag = newRefDrag;
                }
                double ratio = Math.Max(newRefDrag, referenceDrag) / Math.Max(1, Math.Min(newRefDrag, referenceDrag));
                if (ratio > 1.2 && DateTime.Now > nextAllowedAutomaticUpdate || referencePartCount != vessel.Parts.Count)
                {
                    nextAllowedAutomaticUpdate = DateTime.Now.AddSeconds(10); // limit updates frequency (could make the game almost unresponsive on some computers)
                    #if DEBUG
                    ScreenMessages.PostScreenMessage("Trajectory aerodynamic model auto-updated");
                    #endif
                    isValid = false;
                }
            }

            return isValid;
        }
Example #27
0
        /// <summary>
        /// This function should return exactly the same value as Vessel.atmDensity, but is more generic because you don't need an actual vessel updated by KSP to get a value at the desired location.
        /// Computations are performed for the current body position, which means it's theoritically wrong if you want to know the temperature in the future, but since body rotation is not used (position is given in sun frame), you should get accurate results up to a few weeks.
        /// </summary>
        /// <param name="position"></param>
        /// <param name="body"></param>
        /// <returns></returns>
        public static double GetTemperature(Vector3d position, CelestialBody body)
        {
            if (!body.atmosphere)
                return PhysicsGlobals.SpaceTemperature;

            double altitude = (position - body.position).magnitude - body.Radius;
            if (altitude > body.atmosphereDepth)
                return PhysicsGlobals.SpaceTemperature;

            Vector3 up = (position - body.position).normalized;
            float polarAngle = Mathf.Acos(Vector3.Dot(body.bodyTransform.up, up));
            if (polarAngle > Mathf.PI / 2.0f)
            {
                polarAngle = Mathf.PI - polarAngle;
            }
            float time = (Mathf.PI / 2.0f - polarAngle) * 57.29578f;

            Vector3 sunVector = (FlightGlobals.Bodies[0].position - position).normalized;
            float sunAxialDot = Vector3.Dot(sunVector, body.bodyTransform.up);
            float bodyPolarAngle = Mathf.Acos(Vector3.Dot(body.bodyTransform.up, up));
            float sunPolarAngle = Mathf.Acos(sunAxialDot);
            float sunBodyMaxDot = (1.0f + Mathf.Cos(sunPolarAngle - bodyPolarAngle)) * 0.5f;
            float sunBodyMinDot = (1.0f + Mathf.Cos(sunPolarAngle + bodyPolarAngle)) * 0.5f;
            float sunDotCorrected = (1.0f + Vector3.Dot(sunVector, Quaternion.AngleAxis(45f * Mathf.Sign((float)body.rotationPeriod), body.bodyTransform.up) * up)) * 0.5f;
            float sunDotNormalized = (sunDotCorrected - sunBodyMinDot) / (sunBodyMaxDot - sunBodyMinDot);
            double atmosphereTemperatureOffset = (double)body.latitudeTemperatureBiasCurve.Evaluate(time) + (double)body.latitudeTemperatureSunMultCurve.Evaluate(time) * sunDotNormalized + (double)body.axialTemperatureSunMultCurve.Evaluate(sunAxialDot);
            double temperature = body.GetTemperature(altitude) + (double)body.atmosphereTemperatureSunMultCurve.Evaluate((float)altitude) * atmosphereTemperatureOffset;

            return temperature;
        }
        //Computes the time until the phase angle between the launchpad and the target equals the given angle.
        //The convention used is that phase angle is the angle measured starting at the target and going east until
        //you get to the launchpad.
        //The time returned will not be exactly accurate unless the target is in an exactly circular orbit. However,
        //the time returned will go to exactly zero when the desired phase angle is reached.
        public static double TimeToPhaseAngle(double phaseAngle, CelestialBody launchBody, double launchLongitude, Orbit target)
        {
            double launchpadAngularRate = 360 / launchBody.rotationPeriod;
            double targetAngularRate = 360.0 / target.period;
            if (Vector3d.Dot(target.SwappedOrbitNormal(), launchBody.angularVelocity) < 0) targetAngularRate *= -1; //retrograde target

            Vector3d currentLaunchpadDirection = launchBody.GetSurfaceNVector(0, launchLongitude);
            Vector3d currentTargetDirection = target.SwappedRelativePositionAtUT(Planetarium.GetUniversalTime());
            currentTargetDirection = Vector3d.Exclude(launchBody.angularVelocity, currentTargetDirection);

            double currentPhaseAngle = Math.Abs(Vector3d.Angle(currentLaunchpadDirection, currentTargetDirection));
            if (Vector3d.Dot(Vector3d.Cross(currentTargetDirection, currentLaunchpadDirection), launchBody.angularVelocity) < 0)
            {
                currentPhaseAngle = 360 - currentPhaseAngle;
            }

            double phaseAngleRate = launchpadAngularRate - targetAngularRate;

            double phaseAngleDifference = MuUtils.ClampDegrees360(phaseAngle - currentPhaseAngle);

            if (phaseAngleRate < 0)
            {
                phaseAngleRate *= -1;
                phaseAngleDifference = 360 - phaseAngleDifference;
            }

            return phaseAngleDifference / phaseAngleRate;
        }
        public static Vector3d DeltaVAndTimeForCheapestCourseCorrection(Orbit o, double UT, Orbit target, CelestialBody targetBody, double finalPeR, out double burnUT)
        {
            Vector3d collisionDV = DeltaVAndTimeForCheapestCourseCorrection(o, UT, target, out burnUT);
            Orbit collisionOrbit = o.PerturbedOrbit(burnUT, collisionDV);
            double collisionUT = collisionOrbit.NextClosestApproachTime(target, burnUT);
            Vector3d collisionPosition = target.SwappedAbsolutePositionAtUT(collisionUT);
            Vector3d collisionRelVel = collisionOrbit.SwappedOrbitalVelocityAtUT(collisionUT) - target.SwappedOrbitalVelocityAtUT(collisionUT);

            double soiEnterUT = collisionUT - targetBody.sphereOfInfluence / collisionRelVel.magnitude;
            Vector3d soiEnterRelVel = collisionOrbit.SwappedOrbitalVelocityAtUT(soiEnterUT) - target.SwappedOrbitalVelocityAtUT(soiEnterUT);

            double E = 0.5 * soiEnterRelVel.sqrMagnitude - targetBody.gravParameter / targetBody.sphereOfInfluence; //total orbital energy on SoI enter
            double finalPeSpeed = Math.Sqrt(2 * (E + targetBody.gravParameter / finalPeR)); //conservation of energy gives the orbital speed at finalPeR.
            double desiredImpactParameter = finalPeR * finalPeSpeed / soiEnterRelVel.magnitude; //conservation of angular momentum gives the required impact parameter

            Vector3d displacementDir = Vector3d.Cross(collisionRelVel, o.SwappedOrbitNormal()).normalized;
            Vector3d interceptTarget = collisionPosition + desiredImpactParameter * displacementDir;

            Vector3d velAfterBurn;
            Vector3d arrivalVel;
            LambertSolver.Solve(o.SwappedRelativePositionAtUT(burnUT), interceptTarget - o.referenceBody.position, collisionUT - burnUT, o.referenceBody, true, out velAfterBurn, out arrivalVel);

            Vector3d deltaV = velAfterBurn - o.SwappedOrbitalVelocityAtUT(burnUT);
            return deltaV;
        }
Example #30
0
        public static Texture2D getHillshadingTile(CelestialBody body, int tileX, int tileY, int z, int size = 256)
        {
            if (body.pqsController == null)
                return null;
            size = getSize (body, size, z);
            TileData data = getTileData(body, tileX, tileY, z, size);
            size = data.size;
            Texture2D ret = new Texture2D (size, size, TextureFormat.ARGB32, false);
            for (int x = 0; x < size; x++) {
                for (int y = 0; y < size; y++) {
                    double s = Math.PI * 2 * body.Radius / ((size - 1) << z);
                    double dx = ((data.getEle(x-1, y-1) + 2*data.getEle(x, y-1) + data.getEle(x+1, y-1)) -
                        (data.getEle(x-1, y+1) + 2*data.getEle(x, y+1) + data.getEle(x+1, y+1))) /
                        (4.0 * s);
                    double dy = ((data.getEle(x-1, y-1) + 2*data.getEle(x-1, y) + data.getEle(x-1, y+1)) -
                        (data.getEle(x+1, y-1) + 2*data.getEle(x+1, y) + data.getEle(x+1, y+1))) /
                        (4.0 * s);

                    double slope = Math.PI / 2 - Math.Atan (Math.Sqrt (dx * dx + dy * dy));
                    double aspect = Math.Atan2 (dx, dy);

                    double cang = Math.Sin (Math.PI / 4) * Math.Sin (slope) +
                        Math.Cos (Math.PI / 4) * Math.Cos (slope) *
                        Math.Cos ((315) / 180 * Math.PI - Math.PI / 2 - aspect);
                    //Color c = (cang > 0.5)?(new Color(1f, 1f, 1f, (float)cang*2-1)):(new Color(0f, 0f, 0f, (float)cang*2));
                    Color c = new Color ((float)cang, (float)cang, (float)cang, 1.0f);
                    ret.SetPixel (x, y, c);
                }
            }
            ret.Apply ();
            return ret;
        }