Пример #1
0
        // return the surface radiation for the body specified (used by body info panel)
        public static double ComputeSurface(CelestialBody b, double gamma_transparency)
        {
            // store stuff
            Space   gsm;
            Vector3 p;
            float   D;

            // transform to local space once
            Vector3d position = ScaledSpace.LocalToScaledSpace(b.position);

            // accumulate radiation
            double        radiation = 0.0;
            CelestialBody body      = b;

            while (body != null)
            {
                RadiationBody  rb = Info(body);
                RadiationModel mf = rb.model;
                if (mf.Has_Field())
                {
                    // generate radii-normalized GSM space
                    gsm = GSM_Space(rb.body, FlightGlobals.Bodies[rb.reference]);

                    // move the poing in GSM space
                    p = gsm.Transform_IN(position);

                    // accumulate radiation and determine pause/belt flags
                    if (mf.has_inner)
                    {
                        D          = mf.Inner_Func(p);
                        radiation += Lib.Clamp(D / -0.0666f, 0.0f, 1.0f) * rb.radiation_inner;
                    }
                    if (mf.has_outer)
                    {
                        D          = mf.Outer_Func(p);
                        radiation += Lib.Clamp(D / -0.0333f, 0.0f, 1.0f) * rb.radiation_outer;
                    }
                    if (mf.has_pause)
                    {
                        D          = mf.Pause_Func(p);
                        radiation += Lib.Clamp(D / -0.1332f, 0.0f, 1.0f) * rb.radiation_pause;
                    }
                }

                // avoid loops in the chain
                body = (body.referenceBody != null && body.referenceBody.referenceBody == body) ? null : body.referenceBody;
            }

            // add extern radiation
            radiation += Settings.ExternRadiation;

            // clamp radiation to positive range
            // note: we avoid radiation going to zero by using a small positive value
            radiation = Math.Max(radiation, Nominal);

            // return radiation, scaled by gamma transparency if inside atmosphere
            return(radiation * gamma_transparency);
        }
Пример #2
0
        // return the total environent radiation at position specified
        public static double Compute(Vessel v, Vector3d position, double gamma_transparency, double sunlight, out bool blackout,
                                     out bool magnetosphere, out bool inner_belt, out bool outer_belt, out bool interstellar)
        {
            // prepare out parameters
            blackout      = false;
            magnetosphere = false;
            inner_belt    = false;
            outer_belt    = false;
            interstellar  = false;

            // no-op when Radiation is disabled
            if (!Features.Radiation)
            {
                return(0.0);
            }

            // store stuff
            Space   gsm;
            Vector3 p;
            float   D;

            // transform to local space once
            position = ScaledSpace.LocalToScaledSpace(position);

            // accumulate radiation
            double        radiation = 0.0;
            CelestialBody body      = v.mainBody;

            while (body != null)
            {
                RadiationBody  rb = Info(body);
                RadiationModel mf = rb.model;
                if (mf.Has_Field())
                {
                    // generate radii-normalized GSM space
                    gsm = GSM_Space(rb.body, FlightGlobals.Bodies[rb.reference]);

                    // move the poing in GSM space
                    p = gsm.Transform_IN(position);

                    // accumulate radiation and determine pause/belt flags
                    if (mf.has_inner)
                    {
                        D           = mf.Inner_Func(p);
                        radiation  += Lib.Clamp(D / -0.0666f, 0.0f, 1.0f) * rb.radiation_inner;
                        inner_belt |= D < 0.0f;
                    }
                    if (mf.has_outer)
                    {
                        D           = mf.Outer_Func(p);
                        radiation  += Lib.Clamp(D / -0.0333f, 0.0f, 1.0f) * rb.radiation_outer;
                        outer_belt |= D < 0.0f;
                    }
                    if (mf.has_pause)
                    {
                        D              = mf.Pause_Func(p);
                        radiation     += Lib.Clamp(D / -0.1332f, 0.0f, 1.0f) * rb.radiation_pause;
                        magnetosphere |= D < 0.0f && rb.body.flightGlobalsIndex != 0; //< ignore heliopause
                        interstellar  |= D > 0.0f && rb.body.flightGlobalsIndex == 0; //< outside heliopause
                    }
                }

                // avoid loops in the chain
                body = (body.referenceBody != null && body.referenceBody.referenceBody == body) ? null : body.referenceBody;
            }

            // add extern radiation
            radiation += Settings.ExternRadiation;

            // add emitter radiation
            radiation += Emitter.Total(v);

            // if there is a storm in progress
            if (Storm.InProgress(v))
            {
                // inside a magnetopause (except heliosphere), blackout the signal
                // outside, add storm radiations modulated by sun visibility
                if (magnetosphere)
                {
                    blackout = true;
                }
                else
                {
                    radiation += Settings.StormRadiation * sunlight;
                }
            }

            // clamp radiation to positive range
            // note: we avoid radiation going to zero by using a small positive value
            radiation = Math.Max(radiation, Nominal);

            // return radiation, scaled by gamma transparency if inside atmosphere
            return(radiation * gamma_transparency);
        }
Пример #3
0
        // do the particle-fitting in another thread
        public static void Preprocess()
        {
            // deduce number of particles
            int inner_count = 150000;
            int outer_count = 600000;
            int pause_count = 250000;

            if (Settings.LowQualityRendering)
            {
                inner_count /= 5;
                outer_count /= 5;
                pause_count /= 5;
            }

            // start time
            UInt64 time = Lib.Clocks();

            // create all magnetic fields and do particle-fitting
            List <string> done = new List <string>();

            foreach (var pair in models)
            {
                // get radiation data
                RadiationModel mf = pair.Value;

                // skip if model is already done
                if (done.Contains(mf.name))
                {
                    continue;
                }

                // add to the skip list
                done.Add(mf.name);

                // if it has a field
                if (mf.Has_Field())
                {
                    // some feedback in the log
                    // note: can't use BuildString here, as it is not thread-safe
                    Lib.Verbose("particle-fitting '" + mf.name + "'...");
                }

                // particle-fitting for the inner radiation belt
                if (mf.has_inner)
                {
                    mf.inner_pmesh = new ParticleMesh(mf.Inner_Func, mf.Inner_Domain(), mf.Inner_Offset(), inner_count, mf.inner_quality);
                }

                // particle-fitting for the outer radiation belt
                if (mf.has_outer)
                {
                    mf.outer_pmesh = new ParticleMesh(mf.Outer_Func, mf.Outer_Domain(), mf.Outer_Offset(), outer_count, mf.outer_quality);
                }

                // particle-fitting for the magnetopause
                if (mf.has_pause)
                {
                    mf.pause_pmesh = new ParticleMesh(mf.Pause_Func, mf.Pause_Domain(), mf.Pause_Offset(), pause_count, mf.pause_quality);
                }
            }

            // measure time required
            // note: can't use BuildString here, as it is not thread-safe
            Lib.Verbose("particle-fitting completed in " + Lib.Seconds(Lib.Clocks() - time).ToString("F3") + " seconds");
        }