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); }
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; } }
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); }
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); }
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); }
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; } } }
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); }
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; } }
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 } }