private static void CalculateLocalDynPresAndAngularDrag(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); //dyn pres adjusted for submersion p.dragScalar = (float)((p.dynamicPressurekPa * (1.0 - p.submergedPortion) + p.submergedDynamicPressurekPa * p.submergedPortion) * tmp); p.bodyLiftScalar = (float)(p.dynamicPressurekPa * (1.0 - p.submergedPortion) + p.submergedDynamicPressurekPa * p.submergedPortion); }
private static void UpdateThermodynamicsPre(ModularFlightIntegrator fi) { for (int i = 0; i < fi.PartThermalDataCount; i++) { PartThermalData ptd = fi.partThermalDataList[i]; Part part = ptd.part; if (!part.Modules.Contains <FARAeroPartModule>()) { continue; } FARAeroPartModule aeroModule = part.Modules.GetModule <FARAeroPartModule>(); // make sure drag cube areas are correct based on voxelization if (!part.DragCubes.None && aeroModule) { for (int j = 0; j < 6; j++) { part.DragCubes.AreaOccluded[FARAeroPartModule.ProjectedArea.FaceMap[j]] = (float)aeroModule.ProjectedAreas[j]; } } part.radiativeArea = CalculateAreaRadiative(fi, part, aeroModule); part.exposedArea = part.machNumber > 0 ? CalculateAreaExposed(fi, part, aeroModule) : part.radiativeArea; if (FARSettings.ExposedAreaLimited && part.exposedArea > part.radiativeArea) { part.exposedArea = part.radiativeArea; //sanity check just in case } } }
private static Double Flux(ModularFlightIntegrator fi, KopernicusStar star) { // Nullchecks if (fi.Vessel == null || fi.Vessel.state == Vessel.State.DEAD || fi.CurrentMainBody == null) { return(0); } // Get sunVector Boolean directSunlight = false; Vector3 integratorPosition = fi.transform.position; Vector3d scaledSpace = ScaledSpace.LocalToScaledSpace(integratorPosition); Vector3 position = star.sun.scaledBody.transform.position; Double scale = Math.Max((position - scaledSpace).magnitude, 1); Vector3 sunVector = (position - scaledSpace) / scale; Ray ray = new Ray(ScaledSpace.LocalToScaledSpace(integratorPosition), sunVector); // Get Solar Flux Double realDistanceToSun = 0; if (!Physics.Raycast(ray, out RaycastHit raycastHit, Single.MaxValue, ModularFlightIntegrator.SunLayerMask)) { directSunlight = true; realDistanceToSun = scale * ScaledSpace.ScaleFactor - star.sun.Radius; }
/// <summary> /// Override for <see cref="FlightIntegrator.CalculateSunBodyFlux"/> /// </summary> public static void SunBodyFlux(ModularFlightIntegrator flightIntegrator) { // Set Physics PhysicsGlobals.SolarLuminosityAtHome = Current.shifter.solarLuminosity; PhysicsGlobals.SolarInsolationAtHome = Current.shifter.solarInsolation; CalculatePhysics(); // Get "Correct" values flightIntegrator.BaseFICalculateSunBodyFlux(); // FI Values Boolean directSunlight = flightIntegrator.Vessel.directSunlight; Double solarFlux = flightIntegrator.solarFlux; if (!SolarFlux.ContainsKey(Current.name)) { SolarFlux.Add(Current.name, solarFlux); } else { SolarFlux[Current.name] = solarFlux; } // Calculate the values for all bodies foreach (KopernicusStar star in Stars.Where(s => s.sun != FlightIntegrator.sunBody)) { // Set Physics PhysicsGlobals.SolarLuminosityAtHome = star.shifter.solarLuminosity; PhysicsGlobals.SolarInsolationAtHome = star.shifter.solarInsolation; CalculatePhysics(); // Calculate Flux Double flux = Flux(flightIntegrator, star); // And save them if (flux > 0) { directSunlight = true; } solarFlux += flux; if (!SolarFlux.ContainsKey(star.name)) { SolarFlux.Add(star.name, flux); } else { SolarFlux[star.name] = flux; } } // Reapply flightIntegrator.Vessel.directSunlight = directSunlight; flightIntegrator.solarFlux = solarFlux; // Set Physics PhysicsGlobals.SolarLuminosityAtHome = Current.shifter.solarLuminosity; PhysicsGlobals.SolarInsolationAtHome = Current.shifter.solarInsolation; CalculatePhysics(); }
/// <summary> /// Small method to handle flux /// </summary> public static Double Flux(ModularFlightIntegrator fi, KopernicusStar star) { // Nullchecks if (fi.Vessel == null || fi.Vessel.state == Vessel.State.DEAD || fi.CurrentMainBody == null) { return(0); } // Get sunVector RaycastHit raycastHit; Boolean directSunlight = false; Vector3d scaledSpace = ScaledSpace.LocalToScaledSpace(fi.IntegratorTransform.position); Double scale = Math.Max((star.sun.scaledBody.transform.position - scaledSpace).magnitude, 1); Vector3 sunVector = (star.sun.scaledBody.transform.position - scaledSpace) / scale; Ray ray = new Ray(ScaledSpace.LocalToScaledSpace(fi.IntegratorTransform.position), sunVector); // Get Solar Flux Double realDistanceToSun = 0; if (!Physics.Raycast(ray, out raycastHit, Single.MaxValue, ModularFlightIntegrator.SunLayerMask)) { directSunlight = true; realDistanceToSun = scale * ScaledSpace.ScaleFactor - star.sun.Radius; } else if (raycastHit.transform.GetComponent <ScaledMovement>().celestialBody == star.sun) { realDistanceToSun = ScaledSpace.ScaleFactor * raycastHit.distance; directSunlight = true; } if (directSunlight) { return(PhysicsGlobals.SolarLuminosity / (12.5663706143592 * realDistanceToSun * realDistanceToSun)); } return(0); }
// Patch FlightIntegrator void PatchFI() { if (HighLogic.LoadedScene == GameScenes.SPACECENTER) { Events.OnRuntimeUtilityPatchFI.Fire(); ModularFlightIntegrator.RegisterCalculateSunBodyFluxOverride(KopernicusStar.SunBodyFlux); } }
// Patch FlightIntegrator private static void PatchFlightIntegrator() { if (HighLogic.LoadedScene.Equals(GameScenes.SPACECENTER)) { Events.OnRuntimeUtilityPatchFI.Fire(); ModularFlightIntegrator.RegisterCalculateSunBodyFluxOverride(KopernicusStar.SunBodyFlux); ModularFlightIntegrator.RegisterCalculateBackgroundRadiationTemperatureOverride(KopernicusHeatManager.RadiationTemperature); } }
// Patch FlightIntegrator private static void PatchFlightIntegrator() { if (HighLogic.LoadedScene != GameScenes.SPACECENTER) { return; } Events.OnRuntimeUtilityPatchFI.Fire(); ModularFlightIntegrator.RegisterCalculateBackgroundRadiationTemperatureOverride(KopernicusHeatManager.RadiationTemperature); }
private static double CalculateAreaExposed(ModularFlightIntegrator fi, Part part, FARAeroPartModule aeroModule) { if (aeroModule is null) { return(fi.BaseFICalculateAreaExposed(part)); } double exposedArea = aeroModule.ProjectedAreaLocal(-part.dragVectorDirLocal); return(exposedArea > 0 ? exposedArea : fi.BaseFICalculateAreaExposed(part)); }
// ReSharper disable once UnusedMember.Local private double CalculateAreaExposed(ModularFlightIntegrator fi, Part part) { FARAeroPartModule module = null; if (part.Modules.Contains <FARAeroPartModule>()) { module = part.Modules.GetModule <FARAeroPartModule>(); } return(CalculateAreaExposed(fi, part, module)); }
private static double CalculateBodyArea(ModularFlightIntegrator fi, PartThermalData ptd) { FARAeroPartModule module = ptd.part.Modules.GetModule <FARAeroPartModule>(); if (module is null) { return(fi.BaseFIBodyArea(ptd)); } double bodyArea = module.ProjectedAreaWorld(-fi.Vessel.upAxis) * ptd.bodyAreaMultiplier; return(bodyArea > 0 ? bodyArea : fi.BaseFIBodyArea(ptd)); }
private static double CalculateSunArea(ModularFlightIntegrator fi, PartThermalData ptd) { FARAeroPartModule module = ptd.part.Modules.GetModule <FARAeroPartModule>(); if (module is null) { return(fi.BaseFIGetSunArea(ptd)); } double sunArea = module.ProjectedAreaWorld(fi.sunVector) * ptd.sunAreaMultiplier; return(sunArea > 0 ? sunArea : fi.BaseFIGetSunArea(ptd)); }
private void Start() { FARLogger.Info("Modular Flight Integrator function registration started"); ModularFlightIntegrator.RegisterUpdateAerodynamicsOverride(UpdateAerodynamics); ModularFlightIntegrator.RegisterUpdateThermodynamicsPre(UpdateThermodynamicsPre); ModularFlightIntegrator.RegisterCalculateAreaExposedOverride(CalculateAreaRadiative); ModularFlightIntegrator.RegisterCalculateAreaRadiativeOverride(CalculateAreaRadiative); ModularFlightIntegrator.RegisterGetSunAreaOverride(CalculateSunArea); ModularFlightIntegrator.RegisterGetBodyAreaOverride(CalculateBodyArea); FARLogger.Info("Modular Flight Integrator function registration complete"); Destroy(this); }
private static double CalculateAreaRadiative( ModularFlightIntegrator fi, Part part, FARAeroPartModule aeroModule ) { if (aeroModule is null) { return(fi.BaseFICalculateAreaRadiative(part)); } double radArea = aeroModule.ProjectedAreas.totalArea; return(radArea > 0 ? radArea : fi.BaseFICalculateAreaRadiative(part)); }
void OnCalculateBackgroundRadiationTemperature(ModularFlightIntegrator flightIntegrator, ModularScatter system) { List <GameObject> scatters = system.scatterObjects; Vessel vessel = flightIntegrator.Vessel; CelestialBody _body = system.body; if (_body != vessel.mainBody) { return; } for (Int32 i = 0; i < scatters.Count; i++) { GameObject scatter = scatters[i]; if (scatter?.activeSelf != true) { continue; } if (!string.IsNullOrEmpty(biomeName)) { String biome = ScienceUtil.GetExperimentBiome(_body, vessel.latitude, vessel.longitude); if (biomeName != biome) { continue; } } Single distance = distanceCurve.Evaluate(Vector3.Distance(vessel.transform.position, scatter.transform.position)); Double altitude = altitudeCurve.Evaluate((Single)Vector3d.Distance(vessel.transform.position, _body.transform.position)); Double latitude = latitudeCurve.Evaluate((Single)vessel.latitude); Double longitude = longitudeCurve.Evaluate((Single)vessel.longitude); Double newTemp = altitude * latitude * longitude * ambientTemp; if (heatMap) { Double x = ((450 - vessel.longitude) % 360) / 360.0; Double y = (vessel.latitude + 90) / 180.0; Double m = heatMap.GetPixelFloat(x, y); newTemp *= m; } KopernicusHeatManager.NewTemp(newTemp, sumTemp); } }
private static double CalculateAreaExposed(ModularFlightIntegrator fi, Part part, FARAeroPartModule aeroModule) { if (aeroModule is null) { return(fi.BaseFICalculateAreaExposed(part)); } // Apparently stock exposed area is actually weighted by some function of mach number... // otherwise heating is much lower double exposedArea = FARSettings.ExposedAreaUsesKSPHack ? part.DragCubes.ExposedArea : aeroModule.ProjectedAreaLocal(-part.dragVectorDirLocal); return(exposedArea > 0 ? exposedArea : fi.BaseFICalculateAreaExposed(part)); }
/// <summary> /// Override for <see cref="FlightIntegrator.CalculateBackgroundRadiationTemperature"/> /// </summary> internal static double RadiationTemperature(ModularFlightIntegrator flightIntegrator, Double baseTemp) { // Stock Behaviour baseTemp = UtilMath.Lerp(baseTemp, PhysicsGlobals.SpaceTemperature, flightIntegrator.DensityThermalLerp); // Kopernicus Heat Manager maxTemp = baseTemp; sumTemp = 0; Events.OnCalculateBackgroundRadiationTemperature.Fire(flightIntegrator); baseTemp = maxTemp + sumTemp; return(baseTemp); }
private static void UpdateThermodynamicsPre(ModularFlightIntegrator fi) { bool voxelizationCompleted = (fi.Vessel.vesselModules.Find(module => module is FARVesselAero) as FARVesselAero)? .HasEverValidVoxelization() ?? false; for (int i = 0; i < fi.PartThermalDataCount; i++) { PartThermalData ptd = fi.partThermalDataList[i]; Part part = ptd.part; FARAeroPartModule aeroModule = part.Modules.GetModule <FARAeroPartModule>(); if (aeroModule is null) { continue; } // make sure drag cube areas are correct based on voxelization if (voxelizationCompleted) { if (!part.DragCubes.None && aeroModule) { for (int j = 0; j < 6; j++) { part.DragCubes.AreaOccluded[FARAeroPartModule.ProjectedArea.FaceMap[j]] = (float)aeroModule.ProjectedAreas[j]; } } part.radiativeArea = CalculateAreaRadiative(fi, part, aeroModule); part.exposedArea = part.machNumber > 0 ? CalculateAreaExposed(fi, part, aeroModule) : part.radiativeArea; } else { part.radiativeArea = fi.BaseFICalculateAreaRadiative(part); part.exposedArea = fi.BaseFICalculateAreaExposed(part); } if (FARSettings.ExposedAreaLimited && part.exposedArea > part.radiativeArea) { part.exposedArea = part.radiativeArea; //sanity check just in case } } }
/// <summary> /// Small method to handle flux /// </summary> public static void Flux(ModularFlightIntegrator fi, KopernicusStar star) { // Nullchecks if (fi.Vessel == null || fi.Vessel.state == Vessel.State.DEAD || fi.CurrentMainBody == null) { return; } // Get sunVector RaycastHit raycastHit; Vector3d scaledSpace = ScaledSpace.LocalToScaledSpace(fi.IntegratorTransform.position); double scale = Math.Max((star.sun.scaledBody.transform.position - scaledSpace).magnitude, 1); Vector3 sunVector = (star.sun.scaledBody.transform.position - scaledSpace) / scale; Ray ray = new Ray(ScaledSpace.LocalToScaledSpace(fi.IntegratorTransform.position), sunVector); // Get Body flux Vector3d scaleFactor = ((Vector3d)star.sun.scaledBody.transform.position - fi.CurrentMainBody.scaledBody.transform.position) * (double)ScaledSpace.ScaleFactor; fi.bodySunFlux = star.sunFlare == fi.CurrentMainBody ? 0 : PhysicsGlobals.SolarLuminosity / Math.PI * 4 * scaleFactor.sqrMagnitude; // Get Solar Flux double realDistanceToSun = 0; bool localDirectSunLight = false; if (!Physics.Raycast(ray, out raycastHit, Single.MaxValue, ModularFI.ModularFlightIntegrator.SunLayerMask)) { localDirectSunLight = true; realDistanceToSun = scale * ScaledSpace.ScaleFactor - star.sun.Radius; } else if (raycastHit.transform.GetComponent <ScaledMovement>().celestialBody == star.sun) { realDistanceToSun = ScaledSpace.ScaleFactor * raycastHit.distance; localDirectSunLight = true; } if (localDirectSunLight) { fi.solarFlux = PhysicsGlobals.SolarLuminosity / (12.5663706143592 * realDistanceToSun * realDistanceToSun); if (!fi.Vessel.directSunlight) { fi.Vessel.directSunlight = true; } } }
/// <summary> /// Override for <see cref="FlightIntegrator.CalculateSunBodyFlux"/> /// </summary> public static void SunBodyFlux(ModularFlightIntegrator flightIntegrator) { // Set Physics PhysicsGlobals.SolarLuminosityAtHome = Current.shifter.solarLuminosity; PhysicsGlobals.SolarInsolationAtHome = Current.shifter.solarInsolation; CalculatePhysics(); // Get "Correct" values flightIntegrator.BaseFICalculateSunBodyFlux(); // FI Values bool directSunlight = flightIntegrator.Vessel.directSunlight; double solarFlux = flightIntegrator.solarFlux; double bodyEmissiveFlux = flightIntegrator.bodyEmissiveFlux; double bodyAlbedoFlux = flightIntegrator.bodyAlbedoFlux; // Calculate the values for all bodies foreach (KopernicusStar star in Stars.Where(s => s.sun != FlightIntegrator.sunBody)) { // Set Physics PhysicsGlobals.SolarLuminosityAtHome = star.shifter.solarLuminosity; PhysicsGlobals.SolarInsolationAtHome = star.shifter.solarInsolation; CalculatePhysics(); // Calculate Flux Flux(flightIntegrator, star); // And save them if (flightIntegrator.Vessel.directSunlight) { directSunlight = true; } solarFlux += flightIntegrator.solarFlux; bodyEmissiveFlux += flightIntegrator.bodyEmissiveFlux; bodyAlbedoFlux += flightIntegrator.bodyAlbedoFlux; } // Reapply flightIntegrator.Vessel.directSunlight = directSunlight; flightIntegrator.solarFlux = solarFlux; flightIntegrator.bodyEmissiveFlux = bodyEmissiveFlux; flightIntegrator.bodyAlbedoFlux = bodyAlbedoFlux; }
private static void UpdateAerodynamics(ModularFlightIntegrator fi, Part part) { //FIXME Proper model for airbrakes if (part.Modules.Contains <ModuleAeroSurface>() || part.Modules.Contains("MissileLauncher") && part.vessel.rootPart == part) { fi.BaseFIUpdateAerodynamics(part); } else { Rigidbody rb = part.rb; if (!rb) { return; } part.dragVector = rb.velocity + Krakensbane.GetFrameVelocity() - FARAtmosphere.GetWind(FlightGlobals.currentMainBody, part, rb.position); part.dragVectorSqrMag = part.dragVector.sqrMagnitude; if (part.dragVectorSqrMag.NearlyEqual(0) || part.ShieldedFromAirstream) { 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); CalculateLocalDynPresAndAngularDrag(fi, part); } if (part.DragCubes.None) { return; } part.DragCubes.SetDrag(part.dragVectorDirLocal, (float)fi.mach); } }
/// <summary> /// Small method to handle flux /// </summary> public static void Flux(ModularFlightIntegrator fi, KopernicusStar star) { // Nullchecks if (fi.Vessel == null || fi.Vessel.state == Vessel.State.DEAD || fi.CurrentMainBody == null) { return; } // Get sunVector RaycastHit raycastHit; fi.Vessel.directSunlight = false; Vector3d scaledSpace = ScaledSpace.LocalToScaledSpace(fi.IntegratorTransform.position); double scale = Math.Max((star.sun.scaledBody.transform.position - scaledSpace).magnitude, 1); Vector3 sunVector = (star.sun.scaledBody.transform.position - scaledSpace) / scale; Ray ray = new Ray(ScaledSpace.LocalToScaledSpace(fi.IntegratorTransform.position), sunVector); // Get Body flux fi.solarFlux = 0; fi.sunDot = Vector3d.Dot(fi.sunVector, fi.Vessel.upAxis); fi.CurrentMainBody.GetAtmoThermalStats(true, FlightIntegrator.sunBody, fi.sunVector, fi.sunDot, fi.Vessel.upAxis, fi.altitude, out fi.atmosphereTemperatureOffset, out fi.bodyEmissiveFlux, out fi.bodyAlbedoFlux); Vector3d scaleFactor = ((Vector3d)star.sun.scaledBody.transform.position - fi.CurrentMainBody.scaledBody.transform.position) * (double)ScaledSpace.ScaleFactor; // Get Solar Flux double realDistanceToSun = 0; if (!Physics.Raycast(ray, out raycastHit, Single.MaxValue, ModularFI.ModularFlightIntegrator.SunLayerMask)) { fi.Vessel.directSunlight = true; realDistanceToSun = scale * ScaledSpace.ScaleFactor - star.sun.Radius; } else if (raycastHit.transform.GetComponent <ScaledMovement>().celestialBody == star.sun) { realDistanceToSun = ScaledSpace.ScaleFactor * raycastHit.distance; fi.Vessel.directSunlight = true; } if (fi.Vessel.directSunlight) { fi.solarFlux = PhysicsGlobals.SolarLuminosity / (12.5663706143592 * realDistanceToSun * realDistanceToSun); } }
/// <summary> /// Override for <see cref="FlightIntegrator.CalculateSunBodyFlux"/> /// </summary> public static void SunBodyFlux(ModularFlightIntegrator flightIntegrator) { // Set Physics PhysicsGlobals.SolarLuminosityAtHome = Current.shifter.solarLuminosity; PhysicsGlobals.SolarInsolationAtHome = Current.shifter.solarInsolation; CalculatePhysics(); // Get "Correct" values flightIntegrator.BaseFICalculateSunBodyFlux(); // FI Values bool directSunlight = flightIntegrator.Vessel.directSunlight; double solarFlux = flightIntegrator.solarFlux; double bodyEmissiveFlux = flightIntegrator.bodyEmissiveFlux; double bodyAlbedoFlux = flightIntegrator.bodyAlbedoFlux; // Calculate the values for all bodies foreach (KopernicusStar star in Stars.Where(s => s.sun != FlightIntegrator.sunBody)) { // Set Physics PhysicsGlobals.SolarLuminosityAtHome = star.shifter.solarLuminosity; PhysicsGlobals.SolarInsolationAtHome = star.shifter.solarInsolation; CalculatePhysics(); // Calculate Flux Flux(flightIntegrator, star); // And save them if (flightIntegrator.Vessel.directSunlight) directSunlight = true; solarFlux += flightIntegrator.solarFlux; bodyEmissiveFlux += flightIntegrator.bodyEmissiveFlux; bodyAlbedoFlux += flightIntegrator.bodyAlbedoFlux; } // Reapply flightIntegrator.Vessel.directSunlight = directSunlight; flightIntegrator.solarFlux = solarFlux; flightIntegrator.bodyEmissiveFlux = bodyEmissiveFlux; flightIntegrator.bodyAlbedoFlux = bodyAlbedoFlux; }
//private static voidThermalDataDelegate updateConvectionOverride; //ModularFlightIntegrator.voidThermalDataDelegate //solarFlux //solarFluxMultiplier; //bodyEmissiveFlux // bodyAlbedoFlux; //densityThermalLerp public void Awake() { if (HighLogic.LoadedScene != GameScenes.SPACECENTER) { return; } print("Attempting to register ProcessUpdateConvection with ModularFlightIntegrator"); bool result = false; result = ModularFlightIntegrator.RegisterUpdateConvectionOverride(ProcessUpdateConvection); if (!result) { print("Unable to override stock convection heating!"); } result = false; result = ModularFlightIntegrator.RegisterUpdateRadiationOverride(ProcessUpdateRadiation); if (!result) { print("Unable to override stock radiant heating!"); } }
private static void UpdateThermodynamicsPre(ModularFlightIntegrator fi) { for (int i = 0; i < fi.PartThermalDataCount; i++) { PartThermalData ptd = fi.partThermalDataList[i]; Part part = ptd.part; if (!part.Modules.Contains <FARAeroPartModule>()) { continue; } var aeroModule = part.Modules.GetModule <FARAeroPartModule>(); 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 } } }
void OnCalculateBackgroundRadiationTemperature(ModularFlightIntegrator flightIntegrator) { Vessel vessel = flightIntegrator?.Vessel; CelestialBody _body = GetComponent <CelestialBody>(); if (_body != vessel.mainBody) { return; } if (!string.IsNullOrEmpty(biomeName)) { String biome = ScienceUtil.GetExperimentBiome(_body, vessel.latitude, vessel.longitude); if (biomeName != biome) { return; } } Double altitude = altitudeCurve.Evaluate((Single)Vector3d.Distance(vessel.transform.position, _body.transform.position)); Double latitude = latitudeCurve.Evaluate((Single)vessel.latitude); Double longitude = longitudeCurve.Evaluate((Single)vessel.longitude); Double newTemp = altitude * latitude * longitude * ambientTemp; if (heatMap) { Double x = ((450 - vessel.longitude) % 360) / 360.0; Double y = (vessel.latitude + 90) / 180.0; Double m = heatMap.GetPixelFloat(x, y); newTemp *= m; } KopernicusHeatManager.NewTemp(newTemp, sumTemp); }
protected void ProcessUpdateRadiation(ModularFlightIntegrator fi, ModularFlightIntegrator.PartThermalData ptd) { }
/// <summary> /// Small method to handle flux /// </summary> public static void Flux(ModularFlightIntegrator fi, KopernicusStar star) { // Nullchecks if (fi.Vessel == null || fi.Vessel.state == Vessel.State.DEAD || fi.CurrentMainBody == null) { return; } // Get sunVector RaycastHit raycastHit; Vector3d scaledSpace = ScaledSpace.LocalToScaledSpace(fi.IntegratorTransform.position); double scale = Math.Max((star.sun.scaledBody.transform.position - scaledSpace).magnitude, 1); Vector3 sunVector = (star.sun.scaledBody.transform.position - scaledSpace) / scale; Ray ray = new Ray(ScaledSpace.LocalToScaledSpace(fi.IntegratorTransform.position), sunVector); // Get Body flux Vector3d scaleFactor = ((Vector3d)star.sun.scaledBody.transform.position - fi.CurrentMainBody.scaledBody.transform.position) * (double)ScaledSpace.ScaleFactor; fi.bodySunFlux = star.sunFlare == fi.CurrentMainBody ? 0 : PhysicsGlobals.SolarLuminosity / Math.PI * 4 * scaleFactor.sqrMagnitude; // Get Solar Flux double realDistanceToSun = 0; bool localDirectSunLight = false; if (!Physics.Raycast(ray, out raycastHit, Single.MaxValue, ModularFI.ModularFlightIntegrator.SunLayerMask)) { localDirectSunLight = true; realDistanceToSun = scale * ScaledSpace.ScaleFactor - star.sun.Radius; } else if (raycastHit.transform.GetComponent<ScaledMovement>().celestialBody == star.sun) { realDistanceToSun = ScaledSpace.ScaleFactor * raycastHit.distance; localDirectSunLight = true; } if (localDirectSunLight) { fi.solarFlux = PhysicsGlobals.SolarLuminosity/(12.5663706143592*realDistanceToSun*realDistanceToSun); if (!fi.Vessel.directSunlight) fi.Vessel.directSunlight = true; } }
public double _GetSunArea(ModularFlightIntegrator fi, ModularFlightIntegrator.PartThermalData ptd) { Part p = ptd.part; if (p.DragCubes.None) return 0d; Vector3 localSun = p.partTransform.InverseTransformDirection(FI.sunVector); return p.DragCubes.GetCubeAreaDir(localSun) * ptd.sunAreaMultiplier; }
// Patch FlightIntegrator void PatchFI() { ModularFlightIntegrator.RegisterCalculateSunBodyFluxOverride(KopernicusStar.SunBodyFlux); }
public double _GetBodyArea(ModularFlightIntegrator.PartThermalData ptd) { Part p = ptd.part; if (p.DragCubes.None) return 0d; Vector3 bodyLocal = p.partTransform.InverseTransformDirection(-vessel.upAxis); return p.DragCubes.GetCubeAreaDir(bodyLocal) * ptd.bodyAreaMultiplier; }
private static double CalculateAreaExposed(ModularFlightIntegrator fi, Part part) { FARAeroPartModule module = part.Modules.GetModule <FARAeroPartModule>(); return(CalculateAreaExposed(fi, part, module)); }
// Patch FlightIntegrator void PatchFI() { Events.OnRuntimeUtilityPatchFI.Fire(); ModularFlightIntegrator.RegisterCalculateSunBodyFluxOverride(KopernicusStar.SunBodyFlux); }
/// <summary> /// Small method to handle flux /// </summary> public static void Flux(ModularFlightIntegrator fi, KopernicusStar star) { // Nullchecks if (fi.Vessel == null || fi.Vessel.state == Vessel.State.DEAD || fi.CurrentMainBody == null) { return; } // Get sunVector RaycastHit raycastHit; fi.Vessel.directSunlight = false; Vector3d scaledSpace = ScaledSpace.LocalToScaledSpace(fi.IntegratorTransform.position); double scale = Math.Max((star.sun.scaledBody.transform.position - scaledSpace).magnitude, 1); Vector3 sunVector = (star.sun.scaledBody.transform.position - scaledSpace) / scale; Ray ray = new Ray(ScaledSpace.LocalToScaledSpace(fi.IntegratorTransform.position), sunVector); // Get Body flux fi.solarFlux = 0; fi.sunDot = Vector3d.Dot(fi.sunVector, fi.Vessel.upAxis); fi.CurrentMainBody.GetAtmoThermalStats(true, FlightIntegrator.sunBody, fi.sunVector, fi.sunDot, fi.Vessel.upAxis, fi.altitude, out fi.atmosphereTemperatureOffset, out fi.bodyEmissiveFlux, out fi.bodyAlbedoFlux); Vector3d scaleFactor = ((Vector3d)star.sun.scaledBody.transform.position - fi.CurrentMainBody.scaledBody.transform.position) * (double)ScaledSpace.ScaleFactor; // Get Solar Flux double realDistanceToSun = 0; if (!Physics.Raycast(ray, out raycastHit, Single.MaxValue, ModularFI.ModularFlightIntegrator.SunLayerMask)) { fi.Vessel.directSunlight = true; realDistanceToSun = scale * ScaledSpace.ScaleFactor - star.sun.Radius; } else if (raycastHit.transform.GetComponent<ScaledMovement>().celestialBody == star.sun) { realDistanceToSun = ScaledSpace.ScaleFactor * raycastHit.distance; fi.Vessel.directSunlight = true; } if (fi.Vessel.directSunlight) { fi.solarFlux = PhysicsGlobals.SolarLuminosity/(12.5663706143592*realDistanceToSun*realDistanceToSun); } }