Beispiel #1
0
            /// <summary>
            /// Update the 'sunsInfo' list and the 'mainSun', 'solarFluxTotal' variables.
            /// Uses discrete or analytic (for high timewarp speeds) evaluation methods based on the isAnalytic bool.
            /// Require the 'visibleBodies' variable to be set.
            /// </summary>
            // at the two highest timewarp speed, the number of sun visibility samples drop to the point that
            // the quantization error first became noticeable, and then exceed 100%, to solve this :
            // - we switch to an analytical estimation of the sunlight/shadow period
            // - atmo_factor become an average atmospheric absorption factor over the daylight period (not the whole day)
            public static void UpdateSunsInfo(VesselData vd, Vector3d vesselPosition)
            {
                Vessel v             = vd.Vessel;
                double lastSolarFlux = 0.0;

                vd.sunsInfo          = new List <SunInfo>(Sim.suns.Count);
                vd.solarFluxTotal    = 0.0;
                vd.rawSolarFluxTotal = 0.0;

                foreach (Sim.SunData sunData in Sim.suns)
                {
                    SunInfo sunInfo = new SunInfo(sunData);

                    if (vd.isAnalytic)
                    {
                        // get sun direction and distance
                        Lib.DirectionAndDistance(vesselPosition, sunInfo.sunData.body, out sunInfo.direction, out sunInfo.distance);
                        // analytical estimation of the portion of orbit that was in sunlight, current limitations :
                        // - the result is dependant on the vessel altitude at the time of evaluation,
                        //   consequently it gives inconsistent behavior with highly eccentric orbits
                        // - this totally ignore the orbit inclinaison, polar orbits will be treated as equatorial orbits
                        sunInfo.sunlightFactor = 1.0 - Sim.ShadowPeriod(v) / Sim.OrbitalPeriod(v);
                        // get atmospheric absorbtion
                        // for atmospheric bodies whose rotation period is less than 120 hours,
                        // determine analytic atmospheric absorption over a single body revolution instead
                        // of using a discrete value that would be unreliable at large timesteps :
                        if (vd.inAtmosphere)
                        {
                            sunInfo.atmoFactor = Sim.AtmosphereFactorAnalytic(v.mainBody, vesselPosition, sunInfo.direction);
                        }
                        else
                        {
                            sunInfo.atmoFactor = 1.0;
                        }
                    }
                    else
                    {
                        // determine if in sunlight, calculate sun direction and distance
                        sunInfo.sunlightFactor = Sim.IsBodyVisible(v, vesselPosition, sunData.body, vd.visibleBodies, out sunInfo.direction, out sunInfo.distance) ? 1.0 : 0.0;
                        // get atmospheric absorbtion
                        sunInfo.atmoFactor = Sim.AtmosphereFactor(v.mainBody, vesselPosition, sunInfo.direction);
                    }

                    // get resulting solar flux in W/m²
                    sunInfo.rawSolarFlux = sunInfo.sunData.SolarFlux(sunInfo.distance);
                    sunInfo.solarFlux    = sunInfo.rawSolarFlux * sunInfo.sunlightFactor * sunInfo.atmoFactor;
                    // increment total flux from all stars
                    vd.rawSolarFluxTotal += sunInfo.rawSolarFlux;
                    vd.solarFluxTotal    += sunInfo.solarFlux;
                    // add the star to the list
                    vd.sunsInfo.Add(sunInfo);
                    // the most powerful star will be our "default" sun. Uses raw flux before atmo / sunlight factor
                    if (sunInfo.rawSolarFlux > lastSolarFlux)
                    {
                        lastSolarFlux = sunInfo.rawSolarFlux;
                        vd.mainSun    = sunInfo;
                    }
                }

                vd.sunlightFactor = 0.0;
                foreach (SunInfo sunInfo in vd.sunsInfo)
                {
                    sunInfo.fluxProportion = sunInfo.rawSolarFlux / vd.rawSolarFluxTotal;
                    vd.sunlightFactor     += sunInfo.SunlightFactor * sunInfo.fluxProportion;
                }
                // avoid rounding errors
                if (vd.sunlightFactor > 0.99)
                {
                    vd.sunlightFactor = 1.0;
                }
            }
Beispiel #2
0
            /// <summary>
            /// Update the 'sunsInfo' list and the 'mainSun', 'solarFluxTotal' variables.
            /// Uses discrete or analytic (for high timewarp speeds) evaluation methods based on the isAnalytic bool.
            /// Require the 'visibleBodies' variable to be set.
            /// </summary>
            // at the two highest timewarp speed, the number of sun visibility samples drop to the point that
            // the quantization error first became noticeable, and then exceed 100%, to solve this:
            // - we switch to an analytical estimation of the sunlight/shadow period
            // - atmo_factor become an average atmospheric absorption factor over the daylight period (not the whole day)
            public static void UpdateSunsInfo(VesselData vd, Vector3d vesselPosition, double elapsedSeconds)
            {
                Vessel v             = vd.Vessel;
                double lastSolarFlux = 0.0;

                vd.sunsInfo          = new List <SunInfo>(Sim.suns.Count);
                vd.solarFluxTotal    = 0.0;
                vd.rawSolarFluxTotal = 0.0;

                foreach (Sim.SunData sunData in Sim.suns)
                {
                    SunInfo sunInfo = new SunInfo(sunData);

                    if (vd.isAnalytic)
                    {
                        // get sun direction and distance
                        Lib.DirectionAndDistance(vesselPosition, sunInfo.sunData.body, out sunInfo.direction, out sunInfo.distance);
                        // analytical estimation of the portion of orbit that was in sunlight.
                        // it has some limitations, see the comments on Sim.ShadowPeriod

                        if (Settings.UseSamplingSunFactor)
                        {
                            // sampling estimation of the portion of orbit that is in sunlight
                            // until we will calculate again
                            sunInfo.sunlightFactor = Sim.SampleSunFactor(v, elapsedSeconds);
                        }

                        else
                        {
                            // analytical estimation of the portion of orbit that was in sunlight.
                            // it has some limitations, see the comments on Sim.ShadowPeriod
                            sunInfo.sunlightFactor = 1.0 - Sim.ShadowPeriod(v) / Sim.OrbitalPeriod(v);
                        }


                        // get atmospheric absorbtion
                        // for atmospheric bodies whose rotation period is less than 120 hours,
                        // determine analytic atmospheric absorption over a single body revolution instead
                        // of using a discrete value that would be unreliable at large timesteps :
                        if (vd.inAtmosphere)
                        {
                            sunInfo.atmoFactor = Sim.AtmosphereFactorAnalytic(v.mainBody, vesselPosition, sunInfo.direction);
                        }
                        else
                        {
                            sunInfo.atmoFactor = 1.0;
                        }
                    }
                    else
                    {
                        // determine if in sunlight, calculate sun direction and distance
                        sunInfo.sunlightFactor = Sim.IsBodyVisible(v, vesselPosition, sunData.body, vd.visibleBodies, out sunInfo.direction, out sunInfo.distance) ? 1.0 : 0.0;
                        // get atmospheric absorbtion
                        sunInfo.atmoFactor = Sim.AtmosphereFactor(v.mainBody, vesselPosition, sunInfo.direction);
                    }

                    // get resulting solar flux in W/m²
                    sunInfo.rawSolarFlux = sunInfo.sunData.SolarFlux(sunInfo.distance);
                    sunInfo.solarFlux    = sunInfo.rawSolarFlux * sunInfo.sunlightFactor * sunInfo.atmoFactor;
                    // increment total flux from all stars
                    vd.rawSolarFluxTotal += sunInfo.rawSolarFlux;
                    vd.solarFluxTotal    += sunInfo.solarFlux;
                    // add the star to the list
                    vd.sunsInfo.Add(sunInfo);
                    // the most powerful star will be our "default" sun. Uses raw flux before atmo / sunlight factor
                    if (sunInfo.rawSolarFlux > lastSolarFlux)
                    {
                        lastSolarFlux = sunInfo.rawSolarFlux;
                        vd.mainSun    = sunInfo;
                    }
                }

                vd.sunlightFactor = 0.0;
                foreach (SunInfo sunInfo in vd.sunsInfo)
                {
                    sunInfo.fluxProportion = sunInfo.rawSolarFlux / vd.rawSolarFluxTotal;
                    vd.sunlightFactor     += sunInfo.SunlightFactor * sunInfo.fluxProportion;
                }
                // avoid rounding errors
                if (vd.sunlightFactor > 0.99)
                {
                    vd.sunlightFactor = 1.0;
                }
            }