Ejemplo n.º 1
0
        public static double TimeToDaylight(double lat, double lon, CelestialBody body)
        {
            CelestialBody sun = Planetarium.fetch.Sun;

            double rotPeriod, localTime;

            localTime = GetLocalTime(lon, body, sun);
            rotPeriod = body.rotationPeriod;
            var orbit = body.orbit;

            while (orbit?.referenceBody != sun)
            {
                orbit = orbit.referenceBody.orbit;
            }
            if (orbit != null)
            {
                //Convert the absolute rotation period into a day lenght
                rotPeriod = orbit.period * rotPeriod / (orbit.period - rotPeriod);
            }

            double dayLength      = GetDayLengthPercentage(lat, body, sun);
            double timeOfDawn     = 0.5 - dayLength / 2;
            double timeToDaylight = rotPeriod * UtilMath.WrapAround(timeOfDawn - localTime, 0, 1);

            return(timeToDaylight);
        }
Ejemplo n.º 2
0
        public double GetTime(List <ProtoCrewMember> students)
        {
            double curTime = time;

            double level = ScenarioUpgradeableFacilities.GetFacilityLevel(SpaceCenterFacility.AstronautComplex);

            curTime *= (1d - level * 0.5d);

            if (students == null || students.Count == 0 || !timeUseStupid)
            {
                return(curTime);
            }

            double averageStupid = 0d;
            int    sC            = students.Count;

            for (int i = sC; i-- > 0;)
            {
                averageStupid += students[i].stupidity;
            }

            averageStupid /= sC;

            return(curTime * UtilMath.Lerp(CrewHandler.Settings.trainingMissionStupidMin, CrewHandler.Settings.trainingMissionStupidMax, averageStupid));
        }
        protected void TransferResourceFromEVA(string resourceName)
        {
            double availableSpace = GetResourceAmount(resourceName, true) - GetResourceAmount(resourceName);
            double toAdd          = 0d;

            for (int i = 0; i < FlightGlobals.ActiveVessel.evaController.ModuleInventoryPartReference.InventorySlots; i++)
            {
                if (availableSpace > 0d)
                {
                    if (!FlightGlobals.ActiveVessel.evaController.ModuleInventoryPartReference.IsSlotEmpty(i))
                    {
                        StoredPart sPart = FlightGlobals.ActiveVessel.evaController.ModuleInventoryPartReference.storedParts[i];
                        if (sPart.partName == RefuelCargoPartName)
                        {
                            ProtoPartResourceSnapshot res = sPart.snapshot.resources.Find(x => x.resourceName == resourceName);
                            double availableResource      = res.amount;
                            double addable = UtilMath.Min(availableSpace, availableResource);
                            toAdd += addable;

                            Utils.Log($"Removed {addable} {resourceName} from {sPart.partName} ({availableResource} units in part, {availableSpace} space in target)");

                            availableSpace = UtilMath.Clamp(availableSpace - addable, 0, availableSpace);
                            res.amount     = UtilMath.Clamp(res.amount - addable, 0d, res.maxAmount);
                        }
                    }
                }
            }
            ScreenMessages.PostScreenMessage(new ScreenMessage(Localizer.Format("#LOC_SystemHeat_ModuleSystemHeatFissionFuelContainer_Message_Stored",
                                                                                toAdd.ToString("F2"),
                                                                                resourceName,
                                                                                part.partInfo.title
                                                                                ), 5.0f, ScreenMessageStyle.UPPER_CENTER));;
            Utils.Log($"Added {toAdd} {resourceName} to {part.partInfo.title}");
            part.RequestResource(resourceName, -toAdd, ResourceFlowMode.NO_FLOW);
        }
Ejemplo n.º 4
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="altitude"></param>
 /// <returns></returns>
 double CalculateAltFactor(double altitude)
 {
     altitude -= BodyRadius;
     if (altitudeFalloff == FalloffType.Linear)
     {
         if (altitude > centerAltitude)
         {
             return(1d - UtilMath.Clamp((altitude - centerAltitude) / (maximumAltitude - centerAltitude), 0d, 1d));
         }
         else
         {
             return(1d - UtilMath.Clamp((altitude - centerAltitude) / (minimumAltitude - centerAltitude), 0d, 1d));
         }
     }
     else if (altitudeFalloff == FalloffType.None)
     {
         if (altitude >= minimumAltitude && altitude <= maximumAltitude)
         {
             return(1d);
         }
         else
         {
             return(0d);
         }
     }
     return(0d);
 }
Ejemplo n.º 5
0
        public float GetTemperature(float altitude)
        {
            double temperature = 0;

            if (altitude >= body.atmosphereDepth)
            {
                return((float)this.SpaceTemperature);
            }
            if (!body.atmosphereUseTemperatureCurve)
            {
                temperature = body.atmosphereTemperatureSeaLevel - body.atmosphereTemperatureLapseRate * altitude;
            }
            else
            {
                lock (this.AtmosphereTemperatureCurve)
                    temperature = !body.atmosphereTemperatureCurveIsNormalized ?
                                  this.AtmosphereTemperatureCurve.Evaluate((float)altitude) :
                                  UtilMath.Lerp(this.SpaceTemperature, body.atmosphereTemperatureSeaLevel, this.AtmosphereTemperatureCurve.Evaluate((float)(altitude / body.atmosphereDepth)));
            }
            lock (this.AtmosphereTemperatureSunMultCurve)
                temperature += this.AtmosphereTemperatureSunMultCurve.Evaluate(altitude)
                               * (this.LatitudeTemperatureBiasCurve.Evaluate(0)
                                  + this.LatitudeTemperatureSunMultCurve.Evaluate(0)
                                  + this.AxialTemperatureSunMultCurve.Evaluate(0));

            return((float)temperature);
        }
Ejemplo n.º 6
0
    private void FixedUpdate()
    {
        float dt = ts.DeltaTime();

        while (timerHesitate.TimeUp(dt))
        {
            timerFinished = true;
        }
        if (timerFinished)
        {
            // Shrink the buffer.
            float stepSize = dt * shrinkSpeed;
            if (shrinkToLeft)
            {
                bufferUpper = UtilMath.Approach(bufferUpper, bufferLower, stepSize);
            }
            else
            {
                bufferLower = UtilMath.Approach(bufferLower, bufferUpper, stepSize);
            }
            UpdateBufferMeter();

            if (bufferLower == bufferUpper)
            {
                timerFinished = false;
            }
        }
    }
Ejemplo n.º 7
0
        public static double TimeToDaylight(double lat, double lon,
                                            CelestialBody body, double offset)
        {
            double rotPeriod, localTime;

            localTime = Sunrise.GetLocalTime(lon, body, instance.sun);
            rotPeriod = body.rotationPeriod;
            var orbit = body.orbit;

            while (orbit?.referenceBody != instance.sun)
            {
                orbit = orbit.referenceBody.orbit;
            }
            if (orbit != null)
            {
                double or = rotPeriod;
                rotPeriod = orbit.period * rotPeriod / (orbit.period - rotPeriod);
                Debug.Log($"[EarlyBird] rotation period: {or} reference period: {orbit.period} day length: {rotPeriod}");
            }

            offset = (offset * 60) / rotPeriod;
            double dayLength      = Sunrise.GetDayLength(lat, body, instance.sun);
            double timeOfDawn     = 0.5 - dayLength / 2 + offset;
            double timeToDaylight = rotPeriod * UtilMath.WrapAround(timeOfDawn - localTime, 0, 1);

            Debug.Log($"[EarlyBird] WarpToMorning: daylight: {dayLength}({dayLength * rotPeriod}), dawn {timeOfDawn}, warpTime: {timeToDaylight}");
            return(timeToDaylight);
        }
Ejemplo n.º 8
0
        // 每一个状态对应一个特效,这个特效是循环特效,每一次战斗都要更新状态,双方的场牌,英雄卡、技能卡
        override public void updateAttHurtStateEffect(FightItemBase item)
        {
            LinkEffect effect = null;

            if (item.bStateChange())       // 每一个状态对应一个特效,需要播放特效
            {
                int idx = 0;
                TableStateItemBody stateTabelItem = null;
                for (idx = 1; idx < (int)StateID.CARD_STATE_MAX; ++idx)
                {
                    if (UtilMath.checkState((StateID)idx, item.changedState))   // 如果这个状态改变
                    {
                        if (UtilMath.checkState((StateID)idx, item.curState))   // 如果是增加状态
                        {
                            stateTabelItem = Ctx.m_instance.m_tableSys.getItem(TableID.TABLE_STATE, (uint)idx).m_itemBody as TableStateItemBody;
                            if (stateTabelItem.m_effectId > 0)
                            {
                                effect = m_card.effectControl.startStateEffect((StateID)idx, stateTabelItem.m_effectId);
                            }
                        }
                        else    // 删除状态,停止特效
                        {
                            m_card.effectControl.stopStateEffect((StateID)idx);
                        }
                    }
                }
            }
        }
Ejemplo n.º 9
0
        public static int GetBiomeIndex(CelestialBody body, double lat, double lon)
        {
            int currentBiomeIndex = -1;

            if (body.BiomeMap != null)
            {
                CBAttributeMapSO biomeMap = body.BiomeMap;
                // CBAttributeMapSO.GetAtt
                lon -= Math.PI / 2.0;
                lon  = UtilMath.WrapAround(lon, 0.0, Math.PI * 2.0);
                double y          = lat * (1.0 / Math.PI) + 0.5;
                double x          = 1.0 - lon * 0.15915494309189535;
                Color  pixelColor = biomeMap.GetPixelColor(x, y);
                currentBiomeIndex = 0;                 // this is mandatory because the first biome is a used as fallback in the stock code (!)
                float currentSqrMag = float.MaxValue;
                for (int i = 0; i < biomeMap.Attributes.Length; i++)
                {
                    if (!biomeMap.Attributes[i].notNear)
                    {
                        float sqrMag = RGBColorSqrMag(pixelColor, biomeMap.Attributes[i].mapColor);
                        if (sqrMag < currentSqrMag && (biomeMap.nonExactThreshold == -1f || sqrMag < biomeMap.nonExactThreshold))
                        {
                            currentBiomeIndex = i;
                            currentSqrMag     = sqrMag;
                        }
                    }
                }
            }

            return(currentBiomeIndex);
        }
Ejemplo n.º 10
0
    void loadDataFromTextFile(string file)
    {
        //open file
        string positionsAndMatrix = UtilMath.openFile(file);         //@"C:\Users\maxc\Documents\OculusCave Design\ExpeGraphs\nodesMatrix0.txt");

        string[] positionsAndMatrixSplit = positionsAndMatrix.Split('#');

        List <Vector3> positionsGraph = convertPositions(positionsAndMatrixSplit[0]);

        int[,] adjencyMatrix = convertAdjencyMatrix(positionsAndMatrixSplit[1], positionsGraph.Count);

        if (interactiveEditing)
        {
            disconnectNodes(ref adjencyMatrix, 0, chainLength);
            disconnectNodes(ref adjencyMatrix, chainLength, 0);
        }

        //get the path
        if (positionsAndMatrixSplit[2].Length > 0)
        {
            path = convertPath(positionsAndMatrixSplit[2]);
        }

        //triangles
        //test length of the split file to see if there are triangles ...
        if (positionsAndMatrixSplit.Length > 3)
        {
            //read the triangles
            triangles = convertTriangleList(positionsAndMatrixSplit[3]);
        }

        createTubesFromDataUnityGeometry(scaleSphere, positionsGraph, adjencyMatrix, false);
    }
Ejemplo n.º 11
0
    public void setDataDimension(float[] dat, VIEW_DIMENSION dimension)
    {
        float minValue = dat.Min();
        float maxValue = dat.Max();

        for (int i = 0; i < dat.Length; i++)
        {
            Vector3 p = positions[i];

            switch (dimension)
            {
            case VIEW_DIMENSION.X:
                p.x = UtilMath.normaliseValue(dat[i], minValue, maxValue, -0.5f, 0.5f);
                break;

            case VIEW_DIMENSION.Y:
                p.y = UtilMath.normaliseValue(dat[i], minValue, maxValue, -0.5f, 0.5f);
                break;

            case VIEW_DIMENSION.Z:
                p.z = UtilMath.normaliseValue(dat[i], minValue, maxValue, -0.5f, 0.5f);
                break;
            }
            positions[i] = p;
        }
    }
Ejemplo n.º 12
0
    public void SetMaxFilter(float val)
    {
        MaxFilter = Mathf.Clamp(val, -0.505f, 0.505f);
        OnFiltered.Invoke(MinFilter, MaxFilter);

        SetLocalYPosition(maxFilterObject.transform, UtilMath.normaliseValue(MaxFilter, -0.505f, 0.505f, -0.45f, 0.45f));
    }
Ejemplo n.º 13
0
        public static void WarpToMorning(double lat, double lon,
                                         CelestialBody body, double offset)
        {
            if (FlightDriver.Pause)
            {
                return;
            }
            if (instance.sun == null)
            {
                Debug.LogError("Cannot warp to next morning due to lack of sun");
                return;
            }

            if (TimeWarp.fetch.CancelAutoWarp(0))
            {
                return;
            }

            double rotPeriod, localTime;

            localTime = Sunrise.GetLocalTime(lon, body, instance.sun);
            rotPeriod = body.rotationPeriod;
            if (body.orbit != null)
            {
                rotPeriod = body.orbit.period * rotPeriod / (body.orbit.period - rotPeriod);
            }

            offset = (offset * 60) / rotPeriod;
            double dayLength      = Sunrise.GetDayLength(lat, body, instance.sun);
            double timeOfDawn     = 0.5 - dayLength / 2 + offset;;
            double timeToDaylight = rotPeriod * UtilMath.WrapAround(timeOfDawn - localTime, 0, 1);

            Debug.LogFormat("[EarlyBird] WarpToMorning: daylight: {0}({1}), dawn {2}, warpTime: {3}", dayLength, dayLength * rotPeriod, timeOfDawn, timeToDaylight);
            TimeWarp.fetch.WarpTo(Planetarium.GetUniversalTime() + timeToDaylight, 8, 1);
        }
Ejemplo n.º 14
0
 public void SetState(double inputVal)
 {
     animState = (float)UtilMath.Clamp(
         (Math.Pow(inputVal * lerpInnerScalar, lerpPow) * lerpOuterScalar + lerpOffset) * lerpDivRecip,
         lerpMin,
         lerpMax);
 }
Ejemplo n.º 15
0
        public double GetAutolandTargetVerticalSpeed(Vector3d vectorToWaypoint)
        {
            double timeToWaypoint = LateralDistance(vesselState.CoM, vectorToWaypoint) / vesselState.speedSurfaceHorizontal;
            double deltaAlt       = GetAutolandTargetAltitude(vectorToWaypoint) - 10 - vesselState.altitudeASL;

            double vertSpeed = deltaAlt / timeToWaypoint;

            // If we are on final, we want to maintain glideslope as much as
            // possible so that we don't overshoot or undershoot the runway.
            if (approachState == AutolandApproachState.TOUCHDOWN || approachState == AutolandApproachState.FAP)
            {
                Debug.Assert(vertSpeed < 0);

                Vector3d vectorToCorrectPointOnGlideslope = runway.GetPointOnGlideslope(glideslope, LateralDistance(vesselState.CoM, runway.GetVectorToTouchdown()));
                double   desiredAlt        = GetAutolandTargetAltitude(vectorToCorrectPointOnGlideslope) - 10;
                double   deltaToCorrectAlt = desiredAlt - vesselState.altitudeTrue;
                double   expPerMeter       = (Math.Log(maximumVerticalSpeedCorrection + 1) - Math.Log(1)) / desiredAlt;
                double   adjustment        = Math.Exp(expPerMeter * Math.Abs(deltaToCorrectAlt)) - 1;

                vertSpeed += deltaToCorrectAlt > 0 ? adjustment : -adjustment;
            }

            if (approachState == AutolandApproachState.FLARE)
            {
                vertSpeed = deltaAlt / 8 - 0.2f;
                vertSpeed = UtilMath.Clamp(vertSpeed, -2, 2);
            }

            return(vertSpeed);
        }
        //Calculates the temperature of the chute and cuts it if needed
        private bool CalculateChuteTemp()
        {
            if (this.chuteTemperature < PhysicsGlobals.SpaceTemperature)
            {
                this.chuteTemperature = startTemp;
            }

            double flux = this.vessel.convectiveCoefficient * UtilMath.Lerp(1d, 1d + this.vessel.mach * this.vessel.mach * this.vessel.mach,
                                                                            (this.vessel.mach - PhysicsGlobals.FullToCrossSectionLerpStart) / (PhysicsGlobals.FullToCrossSectionLerpEnd))
                          * (this.vessel.externalTemperature - this.chuteTemperature);

            if (this.vessel.mach > PhysicsGlobals.MachConvectionStart)
            {
                double machLerp = (this.part.machNumber - PhysicsGlobals.MachConvectionStart) / (PhysicsGlobals.MachConvectionEnd - PhysicsGlobals.MachConvectionStart);
                machLerp = Math.Pow(machLerp, PhysicsGlobals.MachConvectionExponent);
                flux     = UtilMath.Lerp(flux, this.vessel.convectiveMachFlux, machLerp);
            }
            this.chuteTemperature += 0.001 * this.invThermalMass * flux * this.convectionArea * TimeWarp.fixedDeltaTime;
            if (chuteTemperature > 0d)
            {
                this.chuteTemperature -= 0.001 * this.invThermalMass * PhysicsGlobals.StefanBoltzmanConstant * this.convectionArea * this.chuteEmissivity
                                         * PhysicsGlobals.RadiationFactor * TimeWarp.fixedDeltaTime
                                         * Math.Pow(this.chuteTemperature, PhysicsGlobals.PartEmissivityExponent);
            }
            this.chuteTemperature = Math.Max(PhysicsGlobals.SpaceTemperature, this.chuteTemperature);
            if (this.chuteTemperature > maxTemp)
            {
                ScreenMessages.PostScreenMessage("<color=orange>[RealChute]: " + this.part.partInfo.title + "'s parachute has been destroyed due to aero forces and heat.</color>", 6f, ScreenMessageStyle.UPPER_LEFT);
                Cut();
                return(false);
            }
            this.currentTemp = (float)(this.chuteTemperature + absoluteZero);
            return(true);
        }
Ejemplo n.º 17
0
    // Positions and resizes the camera so that a given edge of the camera matches
    // the line formed by the given vertices. Each vertex corresponds to one corner
    // of the camera. The vertices should be defined in a clockwise order.
    // If the given edge is diagonal, nothing happens.
    // (TODO: Perhaps diagonal edges should rotate the camera to match the edge?)
    public void AnchorClockwiseEdge(Vector3 vertexFirst, Vector3 vertexSecond)
    {
        float differenceX = vertexSecond.x - vertexFirst.x;
        float differenceY = vertexSecond.y - vertexFirst.y;
        int   signX       = UtilMath.SignWithZero(differenceX);
        int   signY       = UtilMath.SignWithZero(differenceY);

        if (signX == 0)
        {
            FitHeight(Mathf.Abs(differenceY));
            position = new Vector3(vertexFirst.x + GetHalfWidth() * signY,
                                   vertexFirst.y + GetHalfHeight() * signY);
        }
        else if (signY == 0)
        {
            FitWidth(Mathf.Abs(differenceX));
            position = new Vector3(vertexFirst.x + GetHalfWidth() * signX,
                                   vertexFirst.y - GetHalfHeight() * signX);
        }
        else
        {
            // The edge is diagonal.
            Debug.LogWarning("CameraDataOrtho2D: Attempted to anchor to diagonal edge.");
        }
    }
Ejemplo n.º 18
0
    // Positions and resizes the camera so that the camera is placed between
    // two given points and has edges that contain those points.
    public void AnchorBetween(Vector3 first, Vector3 second)
    {
        position = Vector3.Lerp(first, second, 0.5f);
        float differenceX  = second.x - first.x;
        float differenceY  = second.y - first.y;
        int   signX        = UtilMath.SignWithZero(differenceX);
        int   signY        = UtilMath.SignWithZero(differenceY);
        float targetWidth  = Mathf.Abs(differenceX);
        float targetHeight = Mathf.Abs(differenceY);

        if (signX == 0)
        {
            FitHeight(targetHeight);
        }
        else if (signY == 0)
        {
            FitWidth(targetWidth);
        }
        else
        {
            if (targetWidth / targetHeight < aspect)
            {
                FitHeight(targetHeight);
            }
            else
            {
                FitWidth(targetWidth);
            }
        }
    }
Ejemplo n.º 19
0
        public double GetTemperature(Vector3d pos)
        {
            double altitude = pos.magnitude - bodyRadius;
            double temperature;

            if (altitude >= mainBody.atmosphereDepth)
            {
                return(PhysicsGlobals.SpaceTemperature);
            }
            if (!mainBody.atmosphereUseTemperatureCurve)
            {
                temperature = mainBody.atmosphereTemperatureSeaLevel - mainBody.atmosphereTemperatureLapseRate * altitude;
            }
            else
            {
                temperature = !mainBody.atmosphereTemperatureCurveIsNormalized ?
                              simCurves.AtmosphereTemperatureCurve.Evaluate((float)altitude) :
                              UtilMath.Lerp(PhysicsGlobals.SpaceTemperature, mainBody.atmosphereTemperatureSeaLevel, simCurves.AtmosphereTemperatureCurve.Evaluate((float)(altitude / mainBody.atmosphereDepth)));
            }
            double latitude = referenceFrame.Latitude(pos);

            temperature += simCurves.AtmosphereTemperatureSunMultCurve.Evaluate((float)altitude)
                           * (simCurves.LatitudeTemperatureBiasCurve.Evaluate((float)latitude)
                              + simCurves.LatitudeTemperatureSunMultCurve.Evaluate((float)latitude)
                              + simCurves.AxialTemperatureSunMultCurve.Evaluate(0));

            return(temperature);
        }
Ejemplo n.º 20
0
    private void Rotate(float linearVelocity)
    {
        float angularVelocity = Angle.FromAngularVelocity(linearVelocity, radius)
                                .GetDegrees() * UtilMath.Sign(inverted);

        mover.OffsetRotation(angularVelocity);
    }
Ejemplo n.º 21
0
 private double GetServiceTime(ProtoCrewMember pcm)
 {
     return(86400d * 365d *
            (Settings.retireBaseYears +
             UtilMath.Lerp(Settings.retireCourageMin, Settings.retireCourageMax, pcm.courage) +
             UtilMath.Lerp(Settings.retireStupidMin, Settings.retireStupidMax, pcm.stupidity)));
 }
Ejemplo n.º 22
0
        public static void UpdateThermodynamicsPre(ModularFI.ModularFlightIntegrator fi)
        {
            if (lastVessel != fi.Vessel || parts.Count != fi.partThermalDataList.Count)
            {
                parts.Clear();
                lastVessel = fi.Vessel;

                for (int i = fi.partThermalDataList.Count; i-- > 0;)
                {
                    var ptd  = fi.partThermalDataList[i];
                    var part = ptd.part;
                    if (part.GetComponent <ModuleNonReentryRated>())
                    {
                        parts.Add(part);
                    }
                }
            }

            for (int i = fi.partThermalDataList.Count; i-- > 0;)
            {
                PartThermalData ptd  = fi.partThermalDataList[i];
                var             part = ptd.part;
                if (parts.Contains(part))
                {
                    ptd.convectionTempMultiplier  = Math.Max(ptd.convectionTempMultiplier, 0.75d);
                    ptd.convectionCoeffMultiplier = Math.Max(ptd.convectionCoeffMultiplier, 0.75d);
                    ptd.convectionAreaMultiplier  = Math.Max(ptd.convectionAreaMultiplier, 0.75d);

                    ptd.postShockExtTemp = UtilMath.LerpUnclamped(part.vessel.atmosphericTemperature, part.vessel.externalTemperature, ptd.convectionTempMultiplier);
                    ptd.finalCoeff       = part.vessel.convectiveCoefficient * ptd.convectionArea * 0.001d * part.heatConvectiveConstant * ptd.convectionCoeffMultiplier;
                }
            }
        }
Ejemplo n.º 23
0
 public static double CalculateBackgroundRadiationTemperature(double ambientTemp, double densityThermalLerp)
 {
     return(UtilMath.Lerp(
                ambientTemp,
                PhysicsGlobals.SpaceTemperature,
                densityThermalLerp));
 }
    private void Rotate(float linearVelocity)
    {
        float angularVelocity = UtilCircle.AngularVelocityDegrees(linearVelocity, radius)
                                * UtilMath.Sign(inverted);

        mover.OffsetRotation(angularVelocity);
    }
Ejemplo n.º 25
0
        /// <summary>
        /// Returns the mean anomaly of the orbit at the given time.
        /// </summary>
        ///
        /// <param name="orbit">The orbit whose anomaly is desired.</param>
        /// <param name="ut">The time at which to measure the mean anomaly.</param>
        /// <returns>The mean anomaly at the specified epoch.</returns>
        static double meanAnomalyAtUT(Orbit orbit, double ut)
        {
            double fracOrbit = (ut - orbit.epoch) / orbit.period;

            return(UtilMath.Clamp(orbit.meanAnomalyAtEpoch + 2.0 * Math.PI * fracOrbit,
                                  0.0, 2.0 * Math.PI));
        }
        double getIntakeMultiplier()
        {
            if (this.part.ShieldedFromAirstream)
            {
                return(0.0f);
            }
            if (this.intakeTransform == null)
            {
                return(1.0f);
            }
            if (this.currentHarvestType == HarvestTypes.Planetary)
            {
                return(1.0f);
            }

            double density = this.part.vessel.atmDensity;

            if (currentHarvestType == HarvestTypes.Exospheric)
            {
                density = 1.0f;
            }

            double speed = this.part.vessel.srfSpeed + this.airSpeedStatic;

            double intakeAngle = UtilMath.Clamp01((double)Vector3.Dot((Vector3)this.vessel.srf_vel_direction, this.intakeTransform.forward));

            return(density * speed * intakeAngle);
        }
Ejemplo n.º 27
0
        public void FixedUpdate()
        {
            if (!HighLogic.LoadedSceneIsFlight)
            {
                return;
            }
            double skinTemp = part.skinTemperature;

            guiShieldTemp = skinTemp;
            guiShieldFlux = 0;
            guiShieldUse  = 0;
            guiShieldEff  = 0;
            part.skinInternalConductionMult = baseSkinIntMult;
            part.heatConductivity           = baseCondMult;
            updateDebugGuiStatus();
            if (part.atmDensity <= 0)
            {
                return;
            }
            if (part.temperature > part.skinTemperature)
            {
                return;
            }

            Vector3 localFlightDirection = -part.dragVectorDirLocal;
            float   dot = Vector3.Dot(heatShieldVector, localFlightDirection);

            if (dot < heatShieldMinDot)
            {
                return;
            }
            //TODO check for occlusion

            float directionalEffectiveness = 0;

            if (dot > heatShieldMaxDot)
            {
                directionalEffectiveness = 1f;
            }
            else
            {
                float minMaxDelta = heatShieldMaxDot - heatShieldMinDot;
                float offset      = dot - heatShieldMinDot;
                directionalEffectiveness = offset / minMaxDelta;
            }
            guiShieldEff = directionalEffectiveness;
            float mult = (1.0f - (0.8f * directionalEffectiveness));

            part.skinInternalConductionMult = mult * baseSkinIntMult;
            part.heatConductivity           = mult * baseCondMult;
            if (skinTemp > ablationStartTemp)
            {
                //convert input value to 0-1 domain
                double d = skinTemp - ablationStartTemp;
                d /= ablationEndTemp;
                d  = UtilMath.Clamp(d, 0, 1);
                applyAblation(d, directionalEffectiveness);
            }
        }
Ejemplo n.º 28
0
        public override void CalculatePerformance(double airRatio, double commandedThrottle, double flowMult, double ispMult)
        {
            // set base bits
            base.CalculatePerformance(airRatio, commandedThrottle, flowMult, ispMult);

            // Calculate Isp (before the shutdown check, so it displays even then)
            Isp = atmosphereCurve.Evaluate((float)(p0 * 0.001d * PhysicsGlobals.KpaToAtmospheres)) * ispMult;

            // if we're not combusting, don't combust and start cooling off
            bool shutdown = !running;

            statusString = "Nominal";
            if (ffFraction <= 0d)
            {
                shutdown     = true;
                statusString = "No propellants";
            }
            if (shutdown || commandedThrottle <= 0d)
            {
                double declinePow = Math.Pow(tempDeclineRate, TimeWarp.fixedDeltaTime);
                chamberTemp = Math.Max(t0, chamberTemp * declinePow);
                return;
            }

            // get current flow, and thus thrust.
            double fuelFlowMult = FlowMult();

            if (fuelFlowMult < 0.05d)
            {
                fuelFlow = 0d;
            }
            else
            {
                fuelFlow = flowMult * UtilMath.LerpUnclamped(minFlow, maxFlow, commandedThrottle) * fuelFlowMult;
            }

            double exhaustVelocity = Isp * 9.80665d;

            thrust = fuelFlow * exhaustVelocity;

            // Calculate chamber temperature as ratio
            double desiredTempRatio = Math.Max(tempMin, commandedThrottle);
            double machTemp         = MachTemp() * 0.05d;

            desiredTempRatio = desiredTempRatio * (1d + machTemp) + machTemp;

            // set based on desired
            double desiredTemp = desiredTempRatio * chamberNominalTemp;

            if (Math.Abs(desiredTemp - chamberTemp) < 1d)
            {
                chamberTemp = desiredTemp;
            }
            else
            {
                double lerpVal = Math.Min(1d, tempLerpRate * TimeWarp.fixedDeltaTime);
                chamberTemp = UtilMath.LerpUnclamped(chamberTemp, desiredTemp, lerpVal);
            }
        }
Ejemplo n.º 29
0
 /// <summary>
 /// Returns an angle from 0 to 360° between the two vectors, based on the up axis to tell left from right
 /// </summary>
 /// <param name="v1"></param>
 /// <param name="v2"></param>
 /// <param name="upAxis"></param>
 /// <returns></returns>
 public static float HeadingDegrees(Vector3 v1, Vector3 v2, Vector3 upAxis)
 {
     if (v1 == v2)
     {
         return(0f);
     }
     return(UtilMath.WrapAround(Mathf.Acos(Vector3.Dot(v1, v2)) * Mathf.Sign(Vector3.Dot(Vector3.Cross(v1, v2), upAxis)) * Mathf.Rad2Deg, 0f, 360f));
 }
Ejemplo n.º 30
0
 /// <summary>
 /// Returns an angle from 0 to 2PI between the two vectors, based on the up axis to tell left from right
 /// </summary>
 /// <param name="v1"></param>
 /// <param name="v2"></param>
 /// <param name="upAxis"></param>
 /// <returns></returns>
 public static float HeadingRadians(Vector3 v1, Vector3 v2, Vector3 upAxis)
 {
     if (v1 == v2)
     {
         return(0f);
     }
     return(UtilMath.WrapAround(Mathf.Acos(Vector3.Dot(v1, v2)) * Mathf.Sign(Vector3.Dot(Vector3.Cross(v1, v2), upAxis)), 0f, Mathf.PI * 2.0f));
 }