public static void UpdateThermodynamicsPre(ModularFI.ModularFlightIntegrator fi) { if (fi.CurrentMainBody != body) { body = fi.CurrentMainBody; RealHeatUtils.baseTempCurve.CalculateNewAtmTempCurve(body, RealHeatUtils.debugging); } if (fi.staticPressurekPa > 0d) { float spd = (float)fi.spd; // set shock temperature fi.Vessel.externalTemperature = fi.externalTemperature = fi.atmosphericTemperature + (double)RealHeatUtils.baseTempCurve.EvaluateTempDiffCurve(spd); // get gamma double Cp = (double)RealHeatUtils.baseTempCurve.EvaluateVelCpCurve(spd); double R = (double)RealHeatUtils.baseTempCurve.specificGasConstant; double Cv = Cp - R; double gamma = Cp / Cv; // change density lerp double shockDensity = GetShockDensity(fi.density, fi.mach, gamma); fi.DensityThermalLerp = CalculateDensityThermalLerp(shockDensity); // reset background temps fi.backgroundRadiationTemp = CalculateBackgroundRadiationTemperature(fi.atmosphericTemperature, fi.DensityThermalLerp); fi.backgroundRadiationTempExposed = CalculateBackgroundRadiationTemperature(fi.externalTemperature * 2d, fi.DensityThermalLerp); // blunt bodies multiply BRT by 0.5, so multiply by 2 here. //print("At rho " + fi.density + "/" + shockDensity + ", gamma " + gamma + ", DTL " + fi.DensityThermalLerp + ", BT = " + fi.backgroundRadiationTempExposed.ToString("N2") + "/" + fi.backgroundRadiationTemp.ToString("N2")); } }
double CalculateAreaExposed(ModularFI.ModularFlightIntegrator fi, Part part) { FARAeroPartModule module = null; if (part.Modules.Contains("FARAeroPartModule")) module = (FARAeroPartModule)part.Modules["FARAeroPartModule"]; return CalculateAreaExposed(fi, part, module); }
double CalculateAreaRadiative(ModularFI.ModularFlightIntegrator fi, Part part, FARAeroPartModule aeroModule) { //double dragCubeExposed = fi.BaseFICalculateAreaExposed(part); if ((object)aeroModule == null) return fi.BaseFICalculateAreaRadiative(part); else { return aeroModule.ProjectedAreas.totalArea; } }
double CalculateAreaExposed(ModularFI.ModularFlightIntegrator fi, Part part, FARAeroPartModule aeroModule) { if ((object)aeroModule == null) return fi.BaseFICalculateAreaExposed(part); else return aeroModule.ProjectedAreaLocal(-part.dragVectorDirLocal); /*else { if (stockRadArea > 0) return aeroModule.ProjectedAreas.totalArea * dragCubeExposed / stockRadArea; else return aeroModule.ProjectedAreas.totalArea; }*/ }
double CalculateAreaExposed(ModularFI.ModularFlightIntegrator fi, Part part, FARAeroPartModule aeroModule) { double dragCubeExposed = fi.BaseFICalculateAreaExposed(part); if (aeroModule == null) return dragCubeExposed; else { double cubeRadiative = fi.BaseFICalculateAreaRadiative(part); if (cubeRadiative > 0) return aeroModule.ProjectedAreas.totalArea * dragCubeExposed / cubeRadiative; else return aeroModule.ProjectedAreas.totalArea; } }
void UpdateThermodynamicsPre(ModularFI.ModularFlightIntegrator fi) { for (int i = 0; i < fi.PartThermalDataCount; i++) { FlightIntegrator.PartThermalData ptd = fi.partThermalDataList[i]; Part part = ptd.part; if (!part.Modules.Contains("FARAeroPartModule")) continue; PartModule module = part.Modules["FARAeroPartModule"]; FARAeroPartModule aeroModule = (FARAeroPartModule)module; part.radiativeArea = CalculateAreaRadiative(fi, part, aeroModule); part.exposedArea = part.machNumber > 0 ? CalculateAreaExposed(fi, part, aeroModule) : part.radiativeArea; if (part.exposedArea > part.radiativeArea) part.exposedArea = part.radiativeArea; //sanity check just in case //fi.SetSkinProperties(ptd); } //fi.timeSinceLastUpdate = 0; //Debug.Log("MFI: " + fi.CoM + " " + Planetarium.GetUniversalTime()); }
void SkinThermalMassShenanigansForShieldedParts(ModularFI.ModularFlightIntegrator fi, Part part, double stockRadArea, double calculatedArea) { part.thermalMass += part.skinThermalMass; //reset overall thermalmass part.radiativeArea = stockRadArea; //set rad area to stock values fi.SetSkinThermalMass(part); //re-run setting skin thermal mass part.thermalMass -= part.skinThermalMass; //re-subtract skin thermal mass part.thermalMassReciprocal = 1.0 / Math.Max(part.thermalMass, 0.001); //reset thermalMassRecip //part.radiativeArea = calculatedArea; //I doubt that this ever caused a problem, but let's be sure }
void UpdateThermodynamicsPre(ModularFI.ModularFlightIntegrator fi) { for (int i = 0; i < fi.PartThermalDataCount; i++) { Part part = fi.partThermalDataList[i].part; if (!part.Modules.Contains("FARAeroPartModule")) continue; PartModule module = part.Modules["FARAeroPartModule"]; FARAeroPartModule aeroModule = (FARAeroPartModule)module; double stockRadArea = fi.BaseFICalculateAreaRadiative(part); part.radiativeArea = CalculateAreaRadiative(fi, part, aeroModule); part.exposedArea = part.machNumber > 0 ? CalculateAreaExposed(fi, part, aeroModule) : part.radiativeArea; if (part.radiativeArea < stockRadArea) SkinThermalMassShenanigansForShieldedParts(fi, part, stockRadArea, part.radiativeArea); //very hacky method to deal with the fact that stock assumes that radiative area is also the skin area for the part. This causes issues for parts that cannot radiate to the environment because they are completely enclosed if (part.exposedArea > part.radiativeArea) part.exposedArea = part.radiativeArea; //sanity check just in case } //Debug.Log("MFI: " + fi.CoM + " " + Planetarium.GetUniversalTime()); }
void UpdateAerodynamics(ModularFI.ModularFlightIntegrator fi, Part part) { if (part.dragModel != Part.DragModel.CYLINDRICAL || part.vessel.isEVA) //FIXME Proper model for airbrakes { fi.BaseFIUpdateAerodynamics(part); return; } else { Rigidbody rb = part.Rigidbody; if (rb) { part.dragVector = rb.velocity + Krakensbane.GetFrameVelocity(); part.dragVectorSqrMag = part.dragVector.sqrMagnitude; if (part.dragVectorSqrMag == 0f) { part.dragVectorMag = 0f; part.dragVectorDir = Vector3.zero; part.dragVectorDirLocal = Vector3.zero; part.dragScalar = 0f; } else { part.dragVectorMag = (float)Math.Sqrt(part.dragVectorSqrMag); part.dragVectorDir = part.dragVector / part.dragVectorMag; part.dragVectorDirLocal = -part.partTransform.InverseTransformDirection(part.dragVectorDir); part.dragScalar = 0f; } if (!part.DragCubes.None) part.DragCubes.SetDrag(part.dragVectorDirLocal, (float)fi.mach); } } }
void UpdateAerodynamics(ModularFI.ModularFlightIntegrator fi, Part part) { if (part.dragModel != Part.DragModel.CYLINDRICAL)// || part.Modules.Contains("KerbalEVA")) //FIXME Proper model for airbrakes { fi.BaseFIUpdateAerodynamics(part); return; } else if (!part.DragCubes.None) { Rigidbody rb = part.Rigidbody; if (rb) { part.dragVectorDir = -rb.velocity - Krakensbane.GetFrameVelocityV3f().normalized; part.dragVectorDirLocal = part.partTransform.worldToLocalMatrix.MultiplyVector(part.dragVectorDir); part.DragCubes.SetDrag(part.dragVectorDirLocal, (float)part.machNumber); } } }
double CalculateSunArea(ModularFI.ModularFlightIntegrator fi, FlightIntegrator.PartThermalData ptd) { FARAeroPartModule module = null; if (ptd.part.Modules.Contains("FARAeroPartModule")) module = (FARAeroPartModule)ptd.part.Modules["FARAeroPartModule"]; if ((object)module == null) return fi.BaseFIGetSunArea(ptd); else return module.ProjectedAreaWorld(fi.sunVector) * ptd.sunAreaMultiplier; }
void CalculateLocalDynPresAndAngularDrag(ModularFI.ModularFlightIntegrator fi, Part p) { if(fi.CurrentMainBody.ocean && p.submergedPortion > 0) { p.submergedDynamicPressurekPa = fi.CurrentMainBody.oceanDensity * 1000; p.dynamicPressurekPa = p.atmDensity; } else { p.submergedDynamicPressurekPa = 0; p.dynamicPressurekPa = p.atmDensity; } double tmp = 0.0005 * p.dragVectorSqrMag; p.submergedDynamicPressurekPa *= tmp; p.dynamicPressurekPa *= tmp; tmp = p.dynamicPressurekPa * (1.0 - p.submergedPortion); tmp += p.submergedDynamicPressurekPa * PhysicsGlobals.BuoyancyWaterAngularDragScalar * p.waterAngularDragMultiplier * p.submergedPortion; p.rb.angularDrag = (float)(p.angularDrag * tmp * PhysicsGlobals.AngularDragMultiplier); tmp = Math.Max(fi.pseudoReDragMult, 1); p.dynamicPressurekPa = (p.dynamicPressurekPa * (1.0 - p.submergedPortion) + p.submergedDynamicPressurekPa * p.submergedPortion * p.submergedDragScalar) * tmp; //dyn pres adjusted for submersion p.submergedDynamicPressurekPa = (p.dynamicPressurekPa * (1.0 - p.submergedPortion) + p.submergedDynamicPressurekPa * p.submergedPortion * p.submergedLiftScalar); }
double CalculateBodyArea(ModularFI.ModularFlightIntegrator fi, FlightIntegrator.PartThermalData ptd) { FARAeroPartModule module = null; if (ptd.part.Modules.Contains("FARAeroPartModule")) module = (FARAeroPartModule)ptd.part.Modules["FARAeroPartModule"]; if ((object)module != null) { double bodyArea = module.ProjectedAreaWorld(-fi.Vessel.upAxis) * ptd.bodyAreaMultiplier; if (bodyArea > 0) return bodyArea; else return fi.BaseFIBodyArea(ptd); } else return fi.BaseFIBodyArea(ptd); }
void UpdateAerodynamics(ModularFI.ModularFlightIntegrator fi, Part part) { if (part.Modules.Contains("ModuleAeroSurface") || part.Modules.Contains("KerbalEVA")) //FIXME Proper model for airbrakes { fi.BaseFIUpdateAerodynamics(part); return; } else if (!part.DragCubes.None) { Rigidbody rb = part.Rigidbody; if (rb) part.DragCubes.SetDrag(-part.partTransform.worldToLocalMatrix.MultiplyVector(rb.velocity + Krakensbane.GetFrameVelocityV3f()).normalized, (float)part.machNumber); } }
void UpdateThermodynamicsPre(ModularFI.ModularFlightIntegrator fi) { for (int i = 0; i < fi.PartThermalDataCount; i++) { Part part = fi.partThermalDataList[i].part; if (!part.Modules.Contains("FARAeroPartModule")) continue; PartModule module = part.Modules["FARAeroPartModule"]; FARAeroPartModule aeroModule = (FARAeroPartModule)module; part.radiativeArea = CalculateAreaRadiative(fi, part, aeroModule); part.exposedArea = part.machNumber > 0 ? CalculateAreaExposed(fi, part, aeroModule) : 0; } //Debug.Log("MFI: " + fi.CoM + " " + Planetarium.GetUniversalTime()); }