Exemple #1
0
        private void LEGACY_UpdateWingAeroModels(bool updateWingInteractions)
        {
            List <Part> partsList = EditorLogic.SortedShipList;

            _wingAerodynamicModel.Clear();
            foreach (Part p in partsList)
            {
                if (p == null)
                {
                    continue;
                }
                if (p.Modules.Contains <FARWingAerodynamicModel>())
                {
                    FARWingAerodynamicModel w = p.Modules.GetModule <FARWingAerodynamicModel>();
                    if (updateWingInteractions)
                    {
                        w.EditorUpdateWingInteractions();
                    }
                    _wingAerodynamicModel.Add(w);
                }
                else if (p.Modules.Contains <FARControllableSurface>())
                {
                    FARControllableSurface c = p.Modules.GetModule <FARControllableSurface>();
                    if (updateWingInteractions)
                    {
                        c.EditorUpdateWingInteractions();
                    }
                    _wingAerodynamicModel.Add(c);
                }
            }
        }
        public static bool PartIsGreeble(Part p, double crossSectionalArea, double finenessRatio, double area)
        {
            bool isGreeble = false;

            if (p.parent)
            {
                Part parent = p.parent;
                if (parent.Modules.Contains("FARBasicDragModel"))
                {
                    FARBasicDragModel d            = parent.GetComponent <FARBasicDragModel>();
                    Vector3           parentVector = (p.transform.worldToLocalMatrix * parent.transform.localToWorldMatrix).MultiplyVector(d.localUpVector);

                    double dotProd = Vector3.Dot(parentVector, Vector3.up);
                    if (Math.Abs(dotProd) < 0.3)
                    {
                        if (crossSectionalArea / d.S <= 0.1 && d.S > area * 0.2 * Math.Sqrt(1 - dotProd * dotProd))
                        {
                            isGreeble = true;
                        }
                    }
                }
                else if (parent.Modules.Contains("FARWingAerodynamicModel"))
                {
                    FARWingAerodynamicModel w = parent.GetComponent <FARWingAerodynamicModel>();

                    if (w.S * 0.5 > area)
                    {
                        isGreeble = true;
                    }
                }
            }

            return(isGreeble);
        }
Exemple #3
0
        void Start()
        {
            if (waterSlowDragNew < 0)
            {
                waterSlowDragNew    = PhysicsGlobals.BuoyancyWaterDragSlow;
                minVelVesselMultNew = (float)PhysicsGlobals.BuoyancyWaterDragPartVelGreaterVesselMult;
                PhysicsGlobals.BuoyancyWaterDragPartVelGreaterVesselMult = 0;
            }

            part.maximum_drag = 0;
            part.minimum_drag = 0;
            part.angularDrag  = 0;
            if (HighLogic.LoadedSceneIsFlight)
            {
                this.enabled = true;
            }
            else if (HighLogic.LoadedSceneIsEditor)
            {
                this.enabled = false;
            }

            partLocalVel    = Vector3.zero;
            partLocalForce  = Vector3.zero;
            partLocalTorque = Vector3.zero;

            //if (!part.Modules.Contains("ModuleAeroSurface"))
            //    part.dragModel = Part.DragModel.CYLINDRICAL;

            if (FARDebugValues.allowStructuralFailures)
            {
                FARPartStressTemplate template = FARAeroStress.DetermineStressTemplate(this.part);
                partStressMaxY  = template.YmaxStress;
                partStressMaxXZ = template.XZmaxStress;
            }
            partTransform = part.partTransform;

            materialColorUpdater = new MaterialColorUpdater(partTransform, PhysicsGlobals.TemperaturePropertyID);
            if (part.Modules.Contains <FARWingAerodynamicModel>())
            {
                legacyWingModel = part.Modules.GetModule <FARWingAerodynamicModel>();
            }
            else if (part.Modules.Contains <FARControllableSurface>())
            {
                legacyWingModel = part.Modules.GetModule <FARControllableSurface>();
            }
            else
            {
                legacyWingModel = null;
            }

            // For handling airbrakes aero visualization
            if (part.Modules.Contains <ModuleAeroSurface>())
            {
                stockAeroSurfaceModule = part.Modules.GetModule <ModuleAeroSurface>();
            }
            else
            {
                stockAeroSurfaceModule = null;
            }
        }
 public void Destroy()
 {
     nearbyWingModulesForwardList      = nearbyWingModulesBackwardList = nearbyWingModulesLeftwardList = nearbyWingModulesRightwardList = null;
     nearbyWingModulesForwardInfluence = nearbyWingModulesBackwardInfluence = nearbyWingModulesLeftwardInfluence = nearbyWingModulesRightwardInfluence = null;
     parentWingModule = null;
     parentWingPart   = null;
 }
        private void CompressArrayToList(FARWingAerodynamicModel[] arrayIn, ref List <FARWingAerodynamicModel> moduleList, ref List <double> associatedInfluences)
        {
            moduleList.Clear();
            associatedInfluences.Clear();
            double influencePerIndex = 1 / (double)arrayIn.Length;

            for (int i = 0; i < arrayIn.Length; i++)
            {
                FARWingAerodynamicModel w = arrayIn[i];
                bool foundModule          = false;
                for (int j = 0; j < moduleList.Count; j++)
                {
                    if (moduleList[j] == w)
                    {
                        associatedInfluences[j] += influencePerIndex * Math.Abs(Vector3.Dot(parentWingPart.partTransform.forward, w.part.partTransform.forward));
                        foundModule              = true;
                        break;
                    }
                }
                if (foundModule || (object)w == null)
                {
                    continue;
                }


                moduleList.Add(w);
                associatedInfluences.Add(influencePerIndex * Math.Abs(Vector3.Dot(parentWingPart.partTransform.forward, w.part.partTransform.forward)));
            }
        }
        private double ExposureInSpanDirection(out FARWingAerodynamicModel[] nearbyWings, Vector3 rayDirection, List <Part> vesselPartList, float b_2, float MAC, float TaperRatio, float MidChordSweep)
        {
            Ray ray = new Ray();

            ray.direction = rayDirection;

            nearbyWings = new FARWingAerodynamicModel[5];

            double exposure = 1;

            for (int i = 0; i < 5; i++)
            {
                ray.origin = rootChordMidPt + (0.5f) * -b_2 * (parentWingPart.partTransform.right * srfAttachFlipped + parentWingPart.partTransform.up * (float)Math.Tan(MidChordSweep * FARMathUtil.deg2rad)); //shift the origin along the midchord line

                float chord_length = 2 * MAC / (1 + TaperRatio);                                                                                                                                                //first, calculate the root chord

                chord_length = chord_length * (1 - 0.5f) + TaperRatio * chord_length * 0.5f;                                                                                                                    //determine the chord length based on how far down the span it is

                ray.origin += (chord_length * (-0.4f + 0.2f * i) * parentWingPart.partTransform.up);

                RaycastHit[] hits = Physics.RaycastAll(ray, b_2, FARAeroUtil.RaycastMask);

                nearbyWings[i] = ExposureHitDetectionAndWingDetection(hits, vesselPartList, ref exposure, 0.2);
            }
            return(exposure);
        }
        private double ExposureInChordDirection(
            out FARWingAerodynamicModel[] nearbyWings,
            Vector3 rayDirection,
            List <Part> vesselPartList,
            float b_2,
            float MAC,
            float MidChordSweep
            )
        {
            var ray = new Ray {
                direction = rayDirection
            };

            nearbyWings = new FARWingAerodynamicModel[5];

            double  exposure           = 1;
            Vector3 partTransformRight = parentWingPart.partTransform.right;
            Vector3 partTransformUp    = parentWingPart.partTransform.up;

            for (int i = 0; i < 5; i++)
            {
                //shift the raycast origin along the midchord line
                ray.origin = rootChordMidPt +
                             (float)(i * 0.2 + 0.1) *
                             -b_2 *
                             (partTransformRight * srfAttachFlipped +
                              partTransformUp * (float)Math.Tan(MidChordSweep * FARMathUtil.deg2rad));

                RaycastHit[] hits = Physics.RaycastAll(ray, MAC, FARAeroUtil.RaycastMask);

                nearbyWings[i] = ExposureHitDetectionAndWingDetection(hits, vesselPartList, ref exposure, 0.2);
            }

            return(exposure);
        }
        private void UpdateUpstreamValuesFromWingModules(List <FARWingAerodynamicModel> wingModules, List <double> associatedInfluences, double directionalInfluence, double thisWingAoA)
        {
            for (int i = 0; i < wingModules.Count; i++)
            {
                FARWingAerodynamicModel wingModule = wingModules[i];
                double wingInfluenceFactor         = associatedInfluences[i] * directionalInfluence;

                double tmp = Vector3.Dot(wingModule.transform.forward, parentWingModule.transform.forward);

                effectiveUpstreamMAC  += wingModule.GetMAC() * wingInfluenceFactor;
                effectiveUpstreamb_2  += wingModule.Getb_2() * wingInfluenceFactor;
                effectiveUpstreamArea += wingModule.S * wingInfluenceFactor;

                effectiveUpstreamLiftSlope     += wingModule.GetLiftSlope() * wingInfluenceFactor;
                effectiveUpstreamStall         += wingModule.GetStall() * wingInfluenceFactor;
                effectiveUpstreamCosSweepAngle += wingModule.GetCosSweepAngle() * wingInfluenceFactor;
                effectiveUpstreamAoAMax        += wingModule.AoAmax * wingInfluenceFactor;
                effectiveUpstreamCd0           += wingModule.GetCd0() * wingInfluenceFactor;
                effectiveUpstreamInfluence     += wingInfluenceFactor;

                double wAoA = wingModule.CalculateAoA(wingModule.GetVelocity()) * Math.Sign(tmp);
                tmp = (thisWingAoA - wAoA) * wingInfluenceFactor;                //First, make sure that the AoA are wrt the same direction; then account for any strange angling of the part that shouldn't be there

                effectiveUpstreamAoA += tmp;
            }
        }
Exemple #9
0
        public void SetState(double machNumber, double Cl, Vector3d CoM, double pitch, int flapSetting, bool spoilers)
        {
            iterationInput.machNumber = machNumber;
            neededCl = Cl;
            iterationInput.pitchValue = pitch;
            iterationInput.flaps      = flapSetting;
            iterationInput.spoilers   = spoilers;

            iterationInput.alphaDot = 0;
            iterationInput.beta     = 0;
            iterationInput.betaDot  = 0;
            iterationInput.phi      = 0;
            iterationInput.phiDot   = 0;

            for (int i = 0; i < _wingAerodynamicModel.Count; i++)
            {
                FARWingAerodynamicModel w = _wingAerodynamicModel[i];
                if (w.isShielded)
                {
                    continue;
                }

                if (w is FARControllableSurface)
                {
                    (w as FARControllableSurface).SetControlStateEditor(CoM, Vector3.up, (float)pitch, 0, 0, flapSetting, spoilers);
                }
            }
        }
        public void SimulateAeroProperties(out Vector3 aeroForce, out Vector3 aeroTorque, Vector3 velocityWorldVector, double altitude)
        {
            // Rodhern: It seems that this method, 'SimulateAeroProperties', is only used in FARAPI, which in turn can be used by say KSPTrajectories.
            //          The parameter 'FARCenterQuery dummy' is from a code fix by Benjamin Chung (commit 18fbb9d29431679a4de9dfc22a443f400d2d4f8b).

            FARCenterQuery center = new FARCenterQuery();
            FARCenterQuery dummy  = new FARCenterQuery();

            float pressure;
            float density;
            float temperature;
            float speedOfSound;

            CelestialBody body = vessel.mainBody;      //Calculate main gas properties

            pressure     = (float)body.GetPressure(altitude);
            temperature  = (float)body.GetTemperature(altitude);
            density      = (float)body.GetDensity(pressure, temperature);
            speedOfSound = (float)body.GetSpeedOfSound(pressure, density);

            if (pressure <= 0 || temperature <= 0 || density <= 0 || speedOfSound <= 0)
            {
                aeroForce  = Vector3.zero;
                aeroTorque = Vector3.zero;
                return;
            }

            float     velocityMag         = velocityWorldVector.magnitude;
            float     machNumber          = velocityMag / speedOfSound;
            float     reynoldsNumber      = (float)FARAeroUtil.CalculateReynoldsNumber(density, Length, velocityMag, machNumber, temperature, body.atmosphereAdiabaticIndex);
            float     reynoldsPerLength   = reynoldsNumber / (float)Length;
            float     pseudoKnudsenNumber = machNumber / (reynoldsNumber + machNumber);
            float     skinFriction        = (float)FARAeroUtil.SkinFrictionDrag(reynoldsNumber, machNumber);
            FlightEnv fenv = FlightEnv.NewPredicted(vessel.mainBody, altitude, machNumber);

            if (_currentAeroSections != null)
            {
                for (int i = 0; i < _currentAeroSections.Count; i++)
                {
                    FARAeroSection curSection = _currentAeroSections[i];
                    if (curSection != null)
                    {
                        curSection.PredictionCalculateAeroForces(density, machNumber, reynoldsPerLength, pseudoKnudsenNumber, skinFriction, velocityWorldVector, center);
                    }
                }

                for (int i = 0; i < _legacyWingModels.Count; i++)
                {
                    FARWingAerodynamicModel curWing = _legacyWingModels[i];
                    if ((object)curWing != null)
                    {
                        Vector3d force = curWing.PrecomputeCenterOfLift(velocityWorldVector, fenv, dummy);
                        center.AddForce(curWing.transform.position, force);
                    }
                }
            }

            aeroForce  = center.force;
            aeroTorque = center.TorqueAt(vessel.CoM);
        }
Exemple #11
0
        private void LEGACY_UpdateWingAeroModels(bool updateWingInteractions)
        {
            List <Part> partsList = EditorLogic.SortedShipList;

            _wingAerodynamicModel.Clear();
            for (int i = 0; i < partsList.Count; i++)
            {
                Part p = partsList[i];
                if (p != null)
                {
                    if (p.Modules.Contains <FARWingAerodynamicModel>())
                    {
                        FARWingAerodynamicModel w = p.Modules.GetModule <FARWingAerodynamicModel>();
                        if (updateWingInteractions)
                        {
                            w.EditorUpdateWingInteractions();
                        }
                        _wingAerodynamicModel.Add(w);
                    }
                    else if (p.Modules.Contains <FARControllableSurface>())
                    {
                        FARControllableSurface c = p.Modules.GetModule <FARControllableSurface>();
                        if (updateWingInteractions)
                        {
                            c.EditorUpdateWingInteractions();
                        }
                        _wingAerodynamicModel.Add(c);
                    }
                }
            }
        }
        public static bool PartIsGreeble(Part p, double crossSectionalArea, double finenessRatio, double area)
        {
            bool isGreeble = false;

            if (p.parent && p.parent.Modules != null)
            {
                Part parent = p.parent;
                if (parent.Modules.Contains("FARBasicDragModel"))
                {
                    FARBasicDragModel d = null;
                    foreach (PartModule m in parent.Modules)
                    {
                        if (m is FARBasicDragModel)
                        {
                            d = m as FARBasicDragModel;
                            return(false);
                        }
                    }

                    Transform selfTransform = p.transform;
                    if ((object)selfTransform == null)
                    {
                        selfTransform = p.vessel.vesselTransform;
                    }

                    Transform parentTransform = p.parent.transform;
                    if ((object)parentTransform == null)
                    {
                        parentTransform = p.vessel.vesselTransform;
                    }

                    Vector3d parentVector = (selfTransform.worldToLocalMatrix * parentTransform.localToWorldMatrix).MultiplyVector(d.localUpVector);

                    double dotProd = Vector3d.Dot(parentVector, Vector3d.up);
                    if (Math.Abs(dotProd) < 0.3)
                    {
                        if (crossSectionalArea / d.S <= 0.1 && d.S > area * 0.2 * Math.Sqrt(1 - dotProd * dotProd))
                        {
                            isGreeble = true;
                        }
                    }
                }
                else if (parent.Modules.Contains("FARWingAerodynamicModel") || parent.Modules.Contains("FARControllableSurface"))
                {
                    FARWingAerodynamicModel w = parent.GetComponent <FARWingAerodynamicModel>();

                    double comparisonArea = w.b_2 * w.MAC * 0.5;
                    if (comparisonArea > area)
                    {
                        isGreeble = true;
                    }

                    Debug.Log(p.partInfo.title + " is greeble on wing? " + isGreeble + "\n\rPart area: " + area + " wing area comparison: " + comparisonArea);
                }
            }

            return(isGreeble);
        }
Exemple #13
0
        private double WingInterference(Vector3 rayDirection, List <Part> PartList, float dist)
        {
            double interferencevalue = 1;

            Ray ray = new Ray();

            ray.origin    = parentWingModule.WingCentroid();
            ray.direction = rayDirection;

            RaycastHit hit = new RaycastHit();

            bool gotSomething = false;

            hit.distance = 0;
            RaycastHit[] hits = Physics.RaycastAll(ray, dist, FARAeroUtil.RaycastMask);
            for (int i = 0; i < hits.Length; i++)
            {
                RaycastHit h = hits[i];
                if (h.collider != null)
                {
                    for (int j = 0; j < PartList.Count; j++)
                    {
                        Part p = PartList[j];

                        if (p == parentWingPart)
                        {
                            continue;
                        }

                        FARWingAerodynamicModel w = p.GetComponent <FARWingAerodynamicModel>();

                        if ((object)w != null)
                        {
                            Collider[] colliders = w.PartColliders;

                            for (int k = 0; k < colliders.Length; k++)
                            {
                                if (h.collider == colliders[k] && h.distance > 0)
                                {
                                    double tmp = h.distance / dist;
                                    tmp = FARMathUtil.Clamp(tmp, 0, 1);
                                    interferencevalue = Math.Min(tmp, interferencevalue);
                                    gotSomething      = true;

                                    break;
                                }
                            }
                        }
                        if (gotSomething)
                        {
                            break;
                        }
                    }
                }
            }
            return(interferencevalue);
        }
        private void CountSurfaces()
        {
            print("Counting wings for " + vessel.GetName());

            liftingSurfaces = new List <FARWingEntry>();


            inRange = true;

            groundPlane = new Plane();

            // This will be calculated later
            wingSpan = 42 / 42;

            foreach (Part part in vessel.Parts)
            {
                FARWingAerodynamicModel thingThatLiftsParts = null;
                float multiplyingLiftWhatever = DefaultLiftMultiplier;

                // Look through the list of part modules to find anything that
                // inherits FARWingAerodynamicModel
                foreach (PartModule module in part.Modules)
                {
                    if (typeof(FARWingAerodynamicModel).IsAssignableFrom(module.GetType()))
                    {
                        thingThatLiftsParts = (FARWingAerodynamicModel)(module);
                        //initialLift = thingThatLiftsParts.deflectionLiftCoeff;



                        if (module is ModuleControlSurface)
                        {
                            // maybe do specific for control surfaces
                        }
                    }
                    else if (module is ModuleGroundEffect)
                    {
                        multiplyingLiftWhatever = ((ModuleGroundEffect)module)
                                                  .groundEffectMultiplier;
                    }
                }

                if (thingThatLiftsParts != null)
                {
                    FARWingEntry entry = new FARWingEntry();
                    entry.groundEffectMultiplier = multiplyingLiftWhatever;
                    entry.surface = thingThatLiftsParts;
                    liftingSurfaces.Add(entry);
                }


                //thingThatLiftsPartsAndMoves.OnCenterOfLiftQuery();
            }

            print("LiftingSurfaces counted for " + vessel.GetName()
                  + ": " + liftingSurfaces.Count);
        }
        public void SimulateAeroProperties(out Vector3 aeroForce, out Vector3 aeroTorque, Vector3 velocityWorldVector, double altitude)
        {
            FARCenterQuery center = new FARCenterQuery();

            float pressure;
            float density;
            float temperature;
            float speedOfSound;

            CelestialBody body = vessel.mainBody;      //Calculate main gas properties

            pressure     = (float)body.GetPressure(altitude);
            temperature  = (float)body.GetTemperature(altitude);
            density      = (float)body.GetDensity(pressure, temperature);
            speedOfSound = (float)body.GetSpeedOfSound(pressure, density);

            if (pressure <= 0 || temperature <= 0 || density <= 0 || speedOfSound <= 0)
            {
                aeroForce  = Vector3.zero;
                aeroTorque = Vector3.zero;
                return;
            }

            float velocityMag    = velocityWorldVector.magnitude;
            float machNumber     = velocityMag / speedOfSound;
            float reynoldsNumber = (float)FARAeroUtil.CalculateReynoldsNumber(density, Length, velocityMag, machNumber, temperature, body.atmosphereAdiabaticIndex);

            float reynoldsPerLength = reynoldsNumber / (float)Length;
            float skinFriction      = (float)FARAeroUtil.SkinFrictionDrag(reynoldsNumber, machNumber);

            float pseudoKnudsenNumber = machNumber / (reynoldsNumber + machNumber);

            if (_currentAeroSections != null)
            {
                for (int i = 0; i < _currentAeroSections.Count; i++)
                {
                    FARAeroSection curSection = _currentAeroSections[i];
                    if (curSection != null)
                    {
                        curSection.PredictionCalculateAeroForces(density, machNumber, reynoldsPerLength, pseudoKnudsenNumber, skinFriction, velocityWorldVector, center);
                    }
                }

                for (int i = 0; i < _legacyWingModels.Count; i++)
                {
                    FARWingAerodynamicModel curWing = _legacyWingModels[i];
                    if ((object)curWing != null)
                    {
                        curWing.PrecomputeCenterOfLift(velocityWorldVector, machNumber, density, center);
                    }
                }
            }

            aeroForce  = center.force;
            aeroTorque = center.TorqueAt(vessel.CoM);
        }
        private void CalculateStallFraction()
        {
            for (int i = 0; i < _LEGACY_currentWingAeroModel.Count; i++)
            {
                FARWingAerodynamicModel w = _LEGACY_currentWingAeroModel[i];
                vesselInfo.stallFraction += w.GetStall() * w.S;
            }

            vesselInfo.stallFraction /= wingArea;
        }
        public static bool PartIsGreeble(Part p, double crossSectionalArea, double finenessRatio, double area)
        {
            bool isGreeble = false;

            if (p.parent && p.parent.Modules != null)
            {
                Part parent = p.parent;
                if (parent.Modules.Contains("FARBasicDragModel"))
                {
                    FARBasicDragModel d = null;
                    foreach (PartModule m in parent.Modules)
                    {
                        if (m is FARBasicDragModel)
                        {
                            d = m as FARBasicDragModel;
                            return(false);
                        }
                    }

                    Transform selfTransform = p.partTransform;
                    if ((object)selfTransform == null)
                    {
                        selfTransform = p.vessel.vesselTransform;
                    }

                    Transform parentTransform = p.parent.partTransform;
                    if ((object)parentTransform == null)
                    {
                        parentTransform = p.vessel.vesselTransform;
                    }

                    Vector3d parentVector = (selfTransform.worldToLocalMatrix * parentTransform.localToWorldMatrix).MultiplyVector(d.localUpVector);

                    double dotProd = Vector3d.Dot(parentVector, Vector3d.up);
                    if (Math.Abs(dotProd) < 0.3)
                    {
                        if (crossSectionalArea / d.S <= 0.1 && d.S > area * 0.2 * Math.Sqrt(1 - dotProd * dotProd))
                        {
                            isGreeble = true;
                        }
                    }
                }
                else if (parent.Modules.Contains("FARWingAerodynamicModel"))
                {
                    FARWingAerodynamicModel w = parent.GetComponent <FARWingAerodynamicModel>();

                    if (w.S * 0.5 > area)
                    {
                        isGreeble = true;
                    }
                }
            }

            return(isGreeble);
        }
Exemple #18
0
        void Start()
        {
            part.maximum_drag = 0;
            part.minimum_drag = 0;
            part.angularDrag  = 0;
            if (HighLogic.LoadedSceneIsFlight)
            {
                this.enabled = true;
            }
            else if (HighLogic.LoadedSceneIsEditor)
            {
                this.enabled = false;
            }

            partLocalVel    = Vector3.zero;
            partLocalForce  = Vector3.zero;
            partLocalTorque = Vector3.zero;

            if (!part.Modules.Contains("ModuleAeroSurface"))
            {
                part.dragModel = Part.DragModel.CYLINDRICAL;
            }

            if (FARDebugValues.allowStructuralFailures)
            {
                FARPartStressTemplate template = FARAeroStress.DetermineStressTemplate(this.part);
                partStressMaxY  = template.YmaxStress;
                partStressMaxXZ = template.XZmaxStress;
            }
            partTransform = part.partTransform;

            materialColorUpdater = new MaterialColorUpdater(partTransform, PhysicsGlobals.TemperaturePropertyID);
            if (part.Modules.Contains("FARWingAerodynamicModel"))
            {
                legacyWingModel = part.Modules["FARWingAerodynamicModel"] as FARWingAerodynamicModel;
            }
            else if (part.Modules.Contains("FARControllableSurface"))
            {
                legacyWingModel = part.Modules["FARControllableSurface"] as FARWingAerodynamicModel;
            }
            else
            {
                legacyWingModel = null;
            }

            // For handling airbrakes aero visualization
            if (part.Modules.Contains("ModuleAeroSurface"))
            {
                stockAeroSurfaceModule = part.Modules["ModuleAeroSurface"] as ModuleAeroSurface;
            }
            else
            {
                stockAeroSurfaceModule = null;
            }
        }
        public FARWingInteraction(
            FARWingAerodynamicModel parentModule,
            Part parentPart,
            Vector3 rootChordMid,
            short srfAttachNegative
            )
        {
            parentWingModule  = parentModule;
            parentWingPart    = parentPart;
            rootChordMidLocal = rootChordMid;
            srfAttachFlipped  = srfAttachNegative;

            if (wingCamberFactor == null)
            {
                wingCamberFactor = new FloatCurve();
                wingCamberFactor.Add(0, 0);
                for (double i = 0.1; i <= 0.9; i += 0.1)
                {
                    double tmp = i * 2;
                    tmp--;
                    tmp = Math.Acos(tmp);

                    tmp -= Math.Sin(tmp);
                    tmp /= Math.PI;
                    tmp  = 1 - tmp;

                    wingCamberFactor.Add((float)i, (float)tmp);
                }

                wingCamberFactor.Add(1, 1);
            }

            if (wingCamberMoment != null)
            {
                return;
            }
            wingCamberMoment = new FloatCurve();
            for (double i = 0; i <= 1; i += 0.1)
            {
                double tmp = i * 2;
                tmp--;
                tmp = Math.Acos(tmp);

                tmp = (Math.Sin(2 * tmp) - 2 * Math.Sin(tmp)) / (8 * (Math.PI - tmp + Math.Sin(tmp)));

                wingCamberMoment.Add((float)i, (float)tmp);
            }
        }
 public void UpdateAeroModules(List <FARAeroPartModule> newAeroModules, List <FARWingAerodynamicModel> legacyWingModels)
 {
     _currentAeroModules          = newAeroModules;
     _LEGACY_currentWingAeroModel = legacyWingModels;
     wingArea    = 0;
     useWingArea = false;
     for (int i = 0; i < legacyWingModels.Count; i++)
     {
         FARWingAerodynamicModel w = legacyWingModels[i];
         if ((object)w != null)
         {
             useWingArea = true;
             wingArea   += w.S;
         }
     }
 }
Exemple #21
0
        public void GetCoMAndSize(out Vector3d CoM, out double mass, out double area, out double MAC, out double b)
        {
            CoM  = Vector3d.zero;
            mass = 0; area = 0; MAC = 0; b = 0;

            List <Part> partsList = EditorLogic.SortedShipList;

            for (int i = 0; i < partsList.Count; i++)
            {
                Part p = partsList[i];
                if (FARAeroUtil.IsNonphysical(p))
                {
                    continue;
                }

                double partMass = p.mass;
                if (p.Resources.Count > 0)
                {
                    partMass += p.GetResourceMass();
                }
                //partMass += p.GetModuleMass(p.mass); // If you want to use GetModuleMass, you need to start from p.partInfo.mass, not p.mass

                CoM  += partMass * (Vector3d)p.transform.TransformPoint(p.CoMOffset);
                mass += partMass;

                FARWingAerodynamicModel w = p.GetComponent <FARWingAerodynamicModel>();
                if (w != null && !w.isShielded)
                {
                    area += w.S;
                    MAC  += w.GetMAC() * w.S;
                    b    += w.Getb_2() * w.S;
                }
            }
            if (area > 0)
            {
                MAC /= area;
                b   /= area;
            }
            else
            {
                area = _maxCrossSectionFromBody;
                MAC  = _bodyLength;
                b    = 1;
            }
            CoM  /= mass;
            mass *= 1000;
        }
        public static List <FARWingAerodynamicModel> ListEditorWings(bool include_selected)
        {
            List <Part> list = CurEditorParts;

            List <FARWingAerodynamicModel> wings = new List <FARWingAerodynamicModel>();

            for (int i = 0; i < list.Count; i++)
            {
                Part p = list[i];
                FARWingAerodynamicModel wing = p.GetComponent <FARWingAerodynamicModel>();
                if ((object)wing != null)
                {
                    wings.Add(wing);
                }
            }
            return(wings);
        }
 public void UpdateAeroModules(List <FARAeroPartModule> newAeroModules)
 {
     _currentAeroModules = newAeroModules;
     _LEGACY_currentWingAeroModel.Clear();
     wingArea    = 0;
     useWingArea = false;
     for (int i = 0; i < _vessel.parts.Count; i++)
     {
         Part p = _vessel.parts[i];
         FARWingAerodynamicModel w = p.GetComponent <FARWingAerodynamicModel>();
         if ((object)w != null)
         {
             _LEGACY_currentWingAeroModel.Add(w);
             useWingArea = true;
             wingArea   += w.S;
         }
     }
 }
        private double ExposureSmallSrf(out FARWingAerodynamicModel[] nearbyWings, Vector3 rayDirection, List <Part> vesselPartList, float rayCastDist, float MAC)
        {
            Ray ray = new Ray();

            ray.direction = rayDirection;

            nearbyWings = new FARWingAerodynamicModel[1];

            double exposure = 1;

            ray.origin = rootChordMidPt - (MAC * 0.7f) * parentWingPart.partTransform.up;

            RaycastHit[] hits = Physics.RaycastAll(ray.origin, ray.direction, rayCastDist, FARAeroUtil.RaycastMask);

            nearbyWings[0] = ExposureHitDetectionAndWingDetection(hits, vesselPartList, ref exposure, 1);

            return(exposure);
        }
Exemple #25
0
        private void UpdateWingInteractionsPart(ConstructionEventType type, Part p)
        {
            EditorPartsChanged = true;
            FARWingAerodynamicModel w = p.GetComponent <FARWingAerodynamicModel>();

            if ((object)w != null)
            {
                if (type == ConstructionEventType.PartAttached)
                {
                    w.OnWingAttach();
                }
                else if (type == ConstructionEventType.PartDetached)
                {
                    w.OnWingDetach();
                }
                w.EditorUpdateWingInteractions();
            }
        }
        //This updates the interactions of all wings near this one; call this one when somethign changes rather than all of them at once
        public HashSet <FARWingAerodynamicModel> UpdateNearbyWingInteractions(HashSet <FARWingAerodynamicModel> wingsHandled)
        {
            //Hashset to avoid repeating the same one affected

            for (int i = 0; i < nearbyWingModulesForwardList.Count; i++)
            {
                FARWingAerodynamicModel w = nearbyWingModulesForwardList[i];
                if (!wingsHandled.Contains(w))
                {
                    w.UpdateThisWingInteractions();
                    wingsHandled.Add(w);
                }
            }
            for (int i = 0; i < nearbyWingModulesBackwardList.Count; i++)
            {
                FARWingAerodynamicModel w = nearbyWingModulesBackwardList[i];
                if (!wingsHandled.Contains(w))
                {
                    w.UpdateThisWingInteractions();
                    wingsHandled.Add(w);
                }
            }
            for (int i = 0; i < nearbyWingModulesRightwardList.Count; i++)
            {
                FARWingAerodynamicModel w = nearbyWingModulesRightwardList[i];
                if (!wingsHandled.Contains(w))
                {
                    w.UpdateThisWingInteractions();
                    wingsHandled.Add(w);
                }
            }
            for (int i = 0; i < nearbyWingModulesLeftwardList.Count; i++)
            {
                FARWingAerodynamicModel w = nearbyWingModulesLeftwardList[i];
                if (!wingsHandled.Contains(w))
                {
                    w.UpdateThisWingInteractions();
                    wingsHandled.Add(w);
                }
            }
            return(wingsHandled);
        }
 private void OnDestroy()
 {
     if (liftArrow != null)
     {
         UnityEngine.Object.Destroy(liftArrow);
         liftArrow = null;
     }
     if (dragArrow != null)
     {
         UnityEngine.Object.Destroy(dragArrow);
         dragArrow = null;
     }
     if (momentArrow != null)
     {
         UnityEngine.Object.Destroy(momentArrow);
         momentArrow = null;
     }
     legacyWingModel        = null;
     stockAeroSurfaceModule = null;
 }
        private FARWingAerodynamicModel ExposureHitDetectionAndWingDetection(
            RaycastHit[] hits,
            List <Part> vesselPartList,
            ref double exposure,
            double exposureDecreasePerHit
            )
        {
            bool   firstHit = true;
            double wingInteractionFactor = 0;

            FARWingAerodynamicModel wingHit = null;

            RaycastHit[] sortedHits = SortHitsByDistance(hits);
            foreach (RaycastHit h in sortedHits)
            {
                bool gotSomething = false;
                if (h.collider == null)
                {
                    continue;
                }
                foreach (Part p in vesselPartList)
                {
                    if (p == null || p == parentWingPart)
                    {
                        continue;
                    }

                    var farModule = p.GetComponent <FARPartModule>();

                    Collider[] colliders;

                    if (!(farModule is null))
                    {
                        colliders = farModule.PartColliders;
                        if (colliders == null)
                        {
                            farModule.TriggerPartColliderUpdate();
                            colliders = farModule.PartColliders;
                        }
                    }
Exemple #29
0
        public void SetState(double M, double Cl, Vector3d CoM, double pitch, int flapSetting, bool spoilers)
        {
            MachNumber    = M;
            neededCl      = Cl;
            this.CoM      = CoM;
            this.pitch    = pitch;
            flaps         = flapSetting;
            this.spoilers = spoilers;

            for (int i = 0; i < FARAeroUtil.CurEditorWings.Count; i++)
            {
                FARWingAerodynamicModel w = FARAeroUtil.CurEditorWings[i];
                if (w.isShielded)
                {
                    continue;
                }

                if (w is FARControllableSurface)
                {
                    (w as FARControllableSurface).SetControlStateEditor(CoM, Vector3.up, (float)pitch, 0, 0, flapSetting, spoilers);
                }
            }
        }
        private void CalculateTotalAeroForce()
        {
            totalAeroForceVector = Vector3.zero;

            if (_vessel.dynamicPressurekPa <= 0.00001)
            {
                return;
            }

            if (_currentAeroModules != null)
            {
                for (int i = 0; i < _currentAeroModules.Count; i++)
                {
                    FARAeroPartModule m = _currentAeroModules[i];
                    if ((object)m != null)
                    {
                        totalAeroForceVector += m.worldSpaceAeroForce;
                    }
                }
            }

            for (int i = 0; i < _LEGACY_currentWingAeroModel.Count; i++)
            {
                FARWingAerodynamicModel w = _LEGACY_currentWingAeroModel[i];
                if ((object)w != null)
                {
                    totalAeroForceVector += w.worldSpaceForce;
                }
            }

            for (int i = 0; i < _vessel.parts.Count; i++)
            {
                Part p = _vessel.parts[i];
                totalAeroForceVector += -p.dragVectorDir * p.dragScalar; // dragVectorDir is actually the velocity vector direction
            }
        }