diff --git a/Directory.Build.props b/Directory.Build.props index 14ad2bc20..bd41770fd 100644 --- a/Directory.Build.props +++ b/Directory.Build.props @@ -1,6 +1,6 @@ - C:\Zaidimai\KSP 1.10\ + C:\Zaidimai\KSP 1.11\ cd "$(SolutionDir)"" python -m buildtools postbuild -f "$(SolutionDir)config.json" -c "$(Configuration)" -t diff --git a/FerramAerospaceResearch.Base/Config/GUIColors.cs b/FerramAerospaceResearch.Base/Config/GUIColors.cs index 26141a23e..32d9dcd74 100644 --- a/FerramAerospaceResearch.Base/Config/GUIColors.cs +++ b/FerramAerospaceResearch.Base/Config/GUIColors.cs @@ -1,4 +1,4 @@ -using FerramAerospaceResearch.Reflection; +using FerramAerospaceResearch.Reflection; using UnityEngine; namespace FerramAerospaceResearch.Config diff --git a/FerramAerospaceResearch.Base/FerramAerospaceResearch.Base.csproj b/FerramAerospaceResearch.Base/FerramAerospaceResearch.Base.csproj index 1c16bb9b9..455104051 100644 --- a/FerramAerospaceResearch.Base/FerramAerospaceResearch.Base.csproj +++ b/FerramAerospaceResearch.Base/FerramAerospaceResearch.Base.csproj @@ -1,6 +1,5 @@ - + Debug @@ -12,7 +11,7 @@ FerramAerospaceResearch.Base v4.8 512 - 8 + 9 AnyCPU @@ -37,6 +36,22 @@ + + False + $(KSP_DIR_BUILD)GameData\000_KSPBurst\Plugins\Unity.Burst.dll + + + False + $(KSP_DIR_BUILD)GameData\000_KSPBurst\Plugins\Unity.Burst.Unsafe.dll + + + False + $(KSP_DIR_BUILD)GameData\000_KSPBurst\Plugins\\Unity.Collections.dll + + + False + $(KSP_DIR_BUILD)GameData\000_KSPBurst\Plugins\Unity.Mathematics.dll + $(KSP_DIR_BUILD)KSP_x64_Data\Managed\UnityEngine.dll @@ -120,10 +135,12 @@ + + diff --git a/FerramAerospaceResearch.Base/Properties/AssemblyInfo.cs b/FerramAerospaceResearch.Base/Properties/AssemblyInfo.cs index 3bdc84e87..5a16a7ffa 100644 --- a/FerramAerospaceResearch.Base/Properties/AssemblyInfo.cs +++ b/FerramAerospaceResearch.Base/Properties/AssemblyInfo.cs @@ -1,4 +1,4 @@ -using System.Reflection; +using System.Reflection; using System.Runtime.InteropServices; // General Information about an assembly is controlled through the following @@ -31,5 +31,5 @@ // You can specify all the values or you can default the Build and Revision Numbers // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("0.16.0.0")] -[assembly: AssemblyFileVersion("0.16.0.0")] +[assembly: AssemblyVersion("0.16.0.2")] +[assembly: AssemblyFileVersion("0.16.0.2")] diff --git a/FerramAerospaceResearch.Base/Resources/FARAssets.cs b/FerramAerospaceResearch.Base/Resources/FARAssets.cs index 85e664bd7..64930a610 100644 --- a/FerramAerospaceResearch.Base/Resources/FARAssets.cs +++ b/FerramAerospaceResearch.Base/Resources/FARAssets.cs @@ -1,4 +1,4 @@ -using System.Collections; +using System.Collections; using FerramAerospaceResearch.Interfaces; using FerramAerospaceResearch.Resources.Loading; using FerramAerospaceResearch.Threading; diff --git a/FerramAerospaceResearch.Base/UnityJobs/OcclusionJobs.cs b/FerramAerospaceResearch.Base/UnityJobs/OcclusionJobs.cs new file mode 100644 index 000000000..0cfc3140c --- /dev/null +++ b/FerramAerospaceResearch.Base/UnityJobs/OcclusionJobs.cs @@ -0,0 +1,381 @@ +using System; +using Unity.Burst; +using Unity.Collections; +using Unity.Collections.LowLevel.Unsafe; +using Unity.Jobs; +using Unity.Mathematics; +using UnityEngine; + +namespace FerramAerospaceResearch.UnityJobs +{ + [BurstCompile] + public struct SphereDistanceInfo : IComparable, IEquatable + { + public quaternion q; + public float distance; + + public int CompareTo(SphereDistanceInfo obj) + { + return distance.CompareTo(obj.distance); + } + + public bool Equals(SphereDistanceInfo other) + { + return q.Equals(other.q) && distance.Equals(other.distance); + } + } + + public struct EMPTY_STRUCT { } + + //http://extremelearning.com.au/how-to-evenly-distribute-points-on-a-sphere-more-effectively-than-the-canonical-fibonacci-lattice/ + [BurstCompile] + public struct SpherePointsJob : IJobParallelFor + { + [ReadOnly] public int points; + [ReadOnly] public float epsilon; + [WriteOnly] public NativeArray results; + public void Execute(int index) + { + float goldenRatio = (1 + math.sqrt(5)) / 2; + float thetaConstantTerm = 2 * math.PI / goldenRatio; + if (index == 0) + { + results[index] = quaternion.identity; + } + else if (index == points - 1) + { + results[index] = quaternion.Euler(180, 0, 0); + } + else + { + float theta = index * thetaConstantTerm; + float denom = points - 1 + (2 * epsilon); + float num = 2 * (index + epsilon); + float phi = math.acos(1 - num / denom); + float3 res = new float3(math.cos(theta) * math.sin(phi), + math.sin(theta) * math.sin(phi), + math.cos(phi)); + results[index] = Quaternion.FromToRotation(new float3(0,0,1), res); + } + } + } + + [BurstCompile] + public struct SetBoundsJob : IJobParallelFor + { + [ReadOnly] public float3 boundsCenter; + [ReadOnly] public float3 extents; + [ReadOnly] public NativeArray quaternions; + [WriteOnly] public NativeArray bounds; + + // We now have center, extents, and the raycaster plane (normal = rotation * vessel.forward) + // Project each of the 8 corners of the bounding box onto the plane. + // https://stackoverflow.com/questions/9605556/how-to-project-a-point-onto-a-plane-in-3d/41897378#41897378 + public void Execute(int index) + { + float3 normal = math.mul(quaternions[index], new float3(0, 0, 1)); + float3 origin = float3.zero + 10000 * normal; + float2 min = new float2(float.PositiveInfinity, float.PositiveInfinity); + float2 max = new float2(float.NegativeInfinity, float.NegativeInfinity); + float3 ext = extents / 2; + float3 center = boundsCenter; + unsafe + { + float3* arr = stackalloc[] + { + center - (ext / 2), + new float3(center.x - ext.x, center.y - ext.y, center.z + ext.z), + new float3(center.x - ext.x, center.y + ext.y, center.z - ext.z), + new float3(center.x - ext.x, center.y + ext.y, center.z + ext.z), + new float3(center.x + ext.x, center.y - ext.y, center.z - ext.z), + new float3(center.x + ext.x, center.y - ext.y, center.z + ext.z), + new float3(center.x + ext.x, center.y + ext.y, center.z - ext.z), + center + (ext / 2), + }; + + for (int i = 0; i < 8; i++) + { + // Project the bounding box onto the plane + float dist = math.dot(arr[i] - origin, normal); + float3 projection = arr[i] - dist * normal; + // Rotate the projection back towards the vessel alignment + projection = math.mul(math.inverse(quaternions[index]), projection); + + // The x,y coords of projection are again aligned to the vessel axes. + min.x = math.min(min.x, projection.x); + min.y = math.min(min.y, projection.y); + max.x = math.max(max.x, projection.x); + max.y = math.max(max.y, projection.y); + } + } + + bounds[index] = new float2(math.abs(max.x - min.x), math.abs(max.y - min.y)); + } + } + + [BurstCompile] + public struct SetIntervalAndDimensionsJob : IJobParallelFor + { + [ReadOnly] public NativeArray bounds; + [ReadOnly] public int maxDim; + [ReadOnly] public float resolution; + [WriteOnly] public NativeArray interval; + [WriteOnly] public NativeArray dims; + + public void Execute(int index) + { + int minXsize = (int)math.ceil(bounds[index].x / resolution); + int minYsize = (int)math.ceil(bounds[index].y / resolution); + dims[index] = new int2(math.min(maxDim, minXsize), math.min(maxDim, minYsize)); + + interval[index] = new float2(math.max(bounds[index].x / maxDim, resolution), math.max(bounds[index].y / maxDim, resolution)); + } + } + + [BurstCompile] + public struct SetVectorsJob : IJobParallelFor + { + [ReadOnly] public NativeArray quaternions; + [ReadOnly] public float4x4 localToWorldMatrix; + [WriteOnly] public NativeArray forward; + [WriteOnly] public NativeArray up; + [WriteOnly] public NativeArray right; + + public void Execute(int index) + { + float3 dir = math.mul(quaternions[index], new float3(0, 0, 1)); + float4 tmp = math.mul(localToWorldMatrix, new float4(dir.x, dir.y, dir.z, 0)); + forward[index] = new float3(tmp.x, tmp.y, tmp.z); + + dir = math.mul(quaternions[index], new float3(0, 1, 0)); + tmp = math.mul(localToWorldMatrix, new float4(dir.x, dir.y, dir.z, 0)); + up[index] = new float3(tmp.x, tmp.y, tmp.z); + + dir = math.mul(quaternions[index], new float3(1 ,0, 0)); + tmp = math.mul(localToWorldMatrix, new float4(dir.x, dir.y, dir.z, 0)); + right[index] = new float3(tmp.x, tmp.y, tmp.z); + } + } + + [BurstCompile] + public struct AngleBetween : IJobParallelFor + { + [ReadOnly] public float3 dir; + [ReadOnly] public NativeArray rotations; + [WriteOnly] public NativeArray angles; + + public void Execute(int index) + { + float3 rot_dir = math.mul(rotations[index], new float3(0, 0, 1)); + angles[index] = math.degrees(math.acos(math.min(math.max(math.dot(dir, rot_dir), -1f), 1f))); + } + } + + [BurstCompile] + public struct GeneralDistanceInfo : IJob + { + [ReadOnly] public NativeArray distances; + [WriteOnly] public NativeArray output; + + public void Execute() + { + float min = float.PositiveInfinity; + float max = 0; + float total = 0; + for (int i = 0; i < distances.Length; i++) + { + total += distances[i]; + max = math.max(max, distances[i]); + min = math.min(min, distances[i]); + } + output[0] = new float3(min, max, total / distances.Length); + } + } + + [BurstCompile] + public struct DotProductJob : IJobParallelFor + { + [ReadOnly] public NativeArray A; + [ReadOnly] public float3 B; + [WriteOnly] public NativeArray result; + + public void Execute(int index) + { + result[index] = math.dot(A[index], B); + } + } + + [BurstCompile] + public struct SortedFilterAndMapByDistanceJob : IJob + { + [ReadOnly] public NativeArray quaternions; + [ReadOnly] public NativeArray distances; + [ReadOnly] public NativeArray cutoffDistance; + public NativeList sdiList; + [WriteOnly] public NativeList orderedQuaternions; + + public void Execute() + { + for (int i = 0; i < quaternions.Length; i++) + { + if (distances[i] < cutoffDistance[0]) + { + SphereDistanceInfo sdi = new SphereDistanceInfo + { + q = quaternions[i], + distance = distances[i] + }; + sdiList.Add(sdi); + } + } + NativeSortExtension.Sort(sdiList); + for (int i = 0; i < sdiList.Length; i++) + orderedQuaternions.Add(sdiList[i].q); + } + } + + [BurstCompile] + public struct MakeQuaternionIndexMapJob : IJobParallelFor + { + [ReadOnly] public NativeArray arr; + [WriteOnly] public NativeHashMap.ParallelWriter map; + + public void Execute(int index) + { + map.TryAdd(arr[index], index); + } + } + + // Given anl array of items and a map, update the map s.t. map[item] = min(current value, index in array) + // Can't parallelize the read/write cycle of the NativeHashMap, so can't do .ParallelWriter + [BurstCompile] + public struct ListToIndexedMap : IJob + { + [ReadOnly] public NativeArray sorted; + public NativeHashMap map; + public void Execute() + { + for (int index=0; index < sorted.Length; index++) + { + quaternion q = sorted[index]; + if (map.TryGetValue(q, out int i) && index < i) + { + map[q] = index; + } + else + map.TryAdd(q, index); + } + } + } + + [BurstCompile] + public struct BucketSortByPriority : IJobParallelFor + { + [ReadOnly] public NativeArray quaternions; + [ReadOnly] public NativeHashMap priorityMap; + [ReadOnly] public NativeHashMap completed; + [ReadOnly] public int maxIndexForPriority0; + [WriteOnly] public NativeMultiHashMap.ParallelWriter map; + + public void Execute(int index) + { + if (!completed.ContainsKey(quaternions[index])) + { + int pri = 2; + if (priorityMap.TryGetValue(quaternions[index], out int i)) + pri = math.min(pri, (i <= maxIndexForPriority0) ? 0 : 1); + map.Add(pri, index); + } + } + } + + [BurstCompile] + public struct ClearNativeHashMapIntFloat : IJob + { + public NativeHashMap map; + public void Execute() => map.Clear(); + } + + [BurstCompile] + public struct ClearNativeMultiHashMapIntInt : IJob + { + public NativeMultiHashMap map; + public void Execute() => map.Clear(); + } + + // hitsMap is the mapping from collider to all of the indicies in the hitsIn array. + [BurstCompile] + public struct RaycastPrepareJob : IJobParallelFor + { + [ReadOnly] public NativeArray hitsIn; + [WriteOnly] public NativeMultiHashMap.ParallelWriter hitsMap; + + public void Execute(int index) + { + unsafe + { + RaycastHit* array_ptr = (RaycastHit*)hitsIn.GetUnsafeReadOnlyPtr(); + int collider_id = *(int*)((byte*)&array_ptr[index] + 40); + if (collider_id != 0) + hitsMap.Add(collider_id, index); + } + } + } + + // hits is the array of all Raycasts + // hitMap is the mapping from collider to all of the indicies in the hits array. + [BurstCompile] + public struct RaycastProcessorJob : IJobNativeMultiHashMapMergedSharedKeyIndices + { + [ReadOnly] public NativeArray hits; + [ReadOnly] public NativeMultiHashMap hitMap; + [ReadOnly] public float area; + [WriteOnly] public NativeHashMap.ParallelWriter hitsOut; + public NativeArray areaSum; + + // index is the *value* in the MultiHashMap hitMap + // The key generating this is a RaycastHitSummary = Tuple + public void ExecuteFirst(int index) + { + unsafe + { + areaSum[index] = area; + hitsOut.TryAdd(index, area); + } + } + + public void ExecuteNext(int firstIndex, int index) + { + float t = areaSum[firstIndex]; + areaSum[firstIndex] = t + area; + } + } + + [BurstCompile] + public struct OcclusionRaycastBuilder : IJobParallelFor + { + [ReadOnly] public float3 forwardDir; + [ReadOnly] public float3 rightDir; + [ReadOnly] public float3 upDir; + [ReadOnly] public float3 startPosition; + [ReadOnly] public float offset; + [ReadOnly] public int2 dimensions; + [ReadOnly] public float2 interval; + [WriteOnly] public NativeArray commands; + + public void Execute(int index) + { + // Everything is already rotated by the quaternion rotation and transformed to worldspace + // Iterate raycasts in X, Y + float3 origin = startPosition + offset * forwardDir; + int row = index / dimensions.x; + int col = index % dimensions.x; + float row_eff = row - (dimensions.x / 2); + float col_eff = col - (dimensions.y / 2); + + // All raycasts are in the same direction. + float3 pos = origin + (row_eff * interval.x * upDir) + (col_eff * interval.y * rightDir); + commands[index] = new RaycastCommand(pos, -forwardDir, distance: 1e5f, layerMask: 19, maxHits: 1); + } + } +} diff --git a/FerramAerospaceResearch.Base/Utils/CsvWriter.cs b/FerramAerospaceResearch.Base/Utils/CsvWriter.cs index 7dc67e14b..9a7e82ea9 100644 --- a/FerramAerospaceResearch.Base/Utils/CsvWriter.cs +++ b/FerramAerospaceResearch.Base/Utils/CsvWriter.cs @@ -38,6 +38,10 @@ public void Open(string filename) Appending = File.Exists(filename); Writer = File.AppendText(filename); Writer.AutoFlush = false; + + // excel needs "sep=..." as the first line to recognize this as csv + Writer.Write("sep="); + Writer.WriteLine(Separator); } public void Close() diff --git a/FerramAerospaceResearch.Base/Utils/Metrics.cs b/FerramAerospaceResearch.Base/Utils/Metrics.cs new file mode 100644 index 000000000..8e680093a --- /dev/null +++ b/FerramAerospaceResearch.Base/Utils/Metrics.cs @@ -0,0 +1,31 @@ +using System.Collections.Generic; + +namespace FerramAerospaceResearch.Utils +{ + public class Metrics + { + public Dictionary data = new Dictionary(); + const int hysteresisFactor = 20; + public Metrics() { } + public void Reset() => data.Clear(); + public void AddMeasurement(string name, double t) + { + if (!data.ContainsKey(name)) + { + data.Add(name, new MetricsElement()); + } + MetricsElement m = data[name]; + m.iterations++; + m.hysteresisTime = (m.hysteresisTime * (hysteresisFactor - 1) + t) / hysteresisFactor; + } + } + + public class MetricsElement + { + public int iterations = 0; + public double hysteresisTime = 0; + + public MetricsElement() { } + public override string ToString() => $"iter: {iterations} TimePerRun: {hysteresisTime:F2} ms"; + } +} diff --git a/FerramAerospaceResearch.Base/Version.cs b/FerramAerospaceResearch.Base/Version.cs index 766a91ddd..03a9c8669 100644 --- a/FerramAerospaceResearch.Base/Version.cs +++ b/FerramAerospaceResearch.Base/Version.cs @@ -6,7 +6,7 @@ public class Version public const byte Major = 0; public const byte Minor = 16; public const byte Build = 0; - public const byte Revision = 0; + public const byte Revision = 2; public const string Name = "Mader"; /// diff --git a/FerramAerospaceResearch/FARAPI.cs b/FerramAerospaceResearch/FARAPI.cs index 93ae19406..790f57cc0 100644 --- a/FerramAerospaceResearch/FARAPI.cs +++ b/FerramAerospaceResearch/FARAPI.cs @@ -1,5 +1,5 @@ /* -Ferram Aerospace Research v0.16.0.0 "Mader" +Ferram Aerospace Research v0.16.0.2 "Mader" ========================= Aerodynamics model for Kerbal Space Program diff --git a/FerramAerospaceResearch/FARAeroComponents/CrossSectionAeroData.cs b/FerramAerospaceResearch/FARAeroComponents/CrossSectionAeroData.cs index daa319642..5708bfa1b 100644 --- a/FerramAerospaceResearch/FARAeroComponents/CrossSectionAeroData.cs +++ b/FerramAerospaceResearch/FARAeroComponents/CrossSectionAeroData.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Text; diff --git a/FerramAerospaceResearch/FARAeroComponents/FARAeroPartModule.cs b/FerramAerospaceResearch/FARAeroComponents/FARAeroPartModule.cs index 4bcbf6dee..efe805813 100644 --- a/FerramAerospaceResearch/FARAeroComponents/FARAeroPartModule.cs +++ b/FerramAerospaceResearch/FARAeroComponents/FARAeroPartModule.cs @@ -1,5 +1,5 @@ -/* -Ferram Aerospace Research v0.16.0.0 "Mader" +/* +Ferram Aerospace Research v0.16.0.2 "Mader" ========================= Aerodynamics model for Kerbal Space Program @@ -90,14 +90,20 @@ public class FARAeroPartModule : PartModule, ILiftProvider private DummyAirstreamShield shield; + public const string GroupName = "FARAeroGroup"; + public const string GroupDisplayName = "FAR Debug"; private bool fieldsVisible; + private bool thermalFieldsVisible; + public readonly List ThermalFields = new List(); // ReSharper disable once NotAccessedField.Global -> unity [KSPField(isPersistant = false, guiActive = false, guiActiveEditor = false, guiFormat = "F3", - guiUnits = "FARUnitKN")] + guiUnits = "FARUnitKN", + groupName = GroupName, + groupDisplayName = GroupDisplayName)] public float dragForce; // ReSharper disable once NotAccessedField.Global -> unity @@ -105,9 +111,58 @@ public class FARAeroPartModule : PartModule, ILiftProvider guiActive = false, guiActiveEditor = false, guiFormat = "F3", - guiUnits = "FARUnitKN")] + guiUnits = "FARUnitKN", + groupName = GroupName)] public float liftForce; + [KSPField(guiFormat = "F3", guiUnits = "FARUnitMSq", groupName = GroupName, groupDisplayName = GroupDisplayName)] + public double radiativeArea; + [KSPField(guiFormat = "F3", guiUnits = "FARUnitMSq", groupName = GroupName)] + public double convectionArea; + [KSPField(guiFormat = "F1", guiUnits = "K", groupName = GroupName)] + public double exposedSkinTemp; + [KSPField(guiFormat = "F1", guiUnits = "K", groupName = GroupName)] + public double unexposedSkinTemp; + [KSPField(guiFormat = "F1", guiUnits = "K", groupName = GroupName)] + public double partTemp; + [KSPField(guiFormat = "F1", guiUnits = "K", groupName = GroupName)] + public double atmosphereTemp; + [KSPField(guiFormat = "F1", guiUnits = "K", groupName = GroupName)] + public double externalTemp; + [KSPField(guiFormat = "F1", guiUnits = "K", groupName = GroupName)] + public double exposedBackgroundTemp; + + [KSPField(guiFormat = "F3", groupName = GroupName)] + public double convergenceFactor; + [KSPField(guiFormat = "F3", groupName = GroupName)] + public double skinSkinConductionMult; + [KSPField(guiFormat = "F3", groupName = GroupName)] + public double skinSkinConductionFactor; + [KSPField(guiFormat = "F1", guiUnits = "kW", groupName = GroupName)] + public double convectionFlux; + [KSPField(guiFormat = "F3", groupName = GroupName)] + public double finalConvCoeff; + [KSPField(guiFormat = "F1", guiUnits = "kW", groupName = GroupName)] + public double intConductionFlux; + [KSPField(guiFormat = "F1", guiUnits = "kW", groupName = GroupName)] + public double skinConductionFlux; + [KSPField(guiFormat = "F1", guiUnits = "kW", groupName = GroupName)] + public double skinInternalConductionFlux; + [KSPField(guiFormat = "F1", guiUnits = "kW", groupName = GroupName)] + public double unexpSkinInternalConductionFlux; + [KSPField(guiFormat = "P1", groupName = GroupName)] + public double skinExposedAreaFrac; + [KSPField(guiFormat = "F1", guiUnits = "kW", groupName = GroupName)] + public double radiationFlux; + [KSPField(guiFormat = "F1", guiUnits = "kW", groupName = GroupName)] + public double unexpRadiationFlux; + [KSPField(guiFormat = "F1", guiUnits = "kW", groupName = GroupName)] + public double skinSkinConductionFlux; + [KSPField(guiFormat = "F3", guiUnits = "ms", groupName = GroupName)] + public double fixedUpdateStall; + [KSPField(guiFormat = "F3", guiUnits = "ms", groupName = GroupName)] + public double updateStall; + private Transform partTransform; private MaterialColorUpdater materialColorUpdater; @@ -202,12 +257,6 @@ public void SetProjectedArea(ProjectedArea areas, Matrix4x4 vesselToWorldMatrix) { part.ShieldedFromAirstream = true; part.AddShield(shield); - if (fieldsVisible) - { - Fields["dragForce"].guiActive = false; - Fields["liftForce"].guiActive = false; - fieldsVisible = false; - } if (!(liftArrow is null)) { @@ -312,6 +361,74 @@ private void Start() stockAeroSurfaceModule = part.Modules.Contains() ? part.Modules.GetModule() : null; + AddThermalDebugFields(); + } + + private void AddThermalDebugFields() + { + ThermalFields.Clear(); + ThermalFields.Add(Fields[nameof(convergenceFactor)]); + ThermalFields.Add(Fields[nameof(skinSkinConductionMult)]); + ThermalFields.Add(Fields[nameof(skinSkinConductionFactor)]); + ThermalFields.Add(Fields[nameof(convectionArea)]); + ThermalFields.Add(Fields[nameof(radiativeArea)]); + ThermalFields.Add(Fields[nameof(skinExposedAreaFrac)]); + ThermalFields.Add(Fields[nameof(exposedSkinTemp)]); + ThermalFields.Add(Fields[nameof(unexposedSkinTemp)]); + ThermalFields.Add(Fields[nameof(partTemp)]); + ThermalFields.Add(Fields[nameof(externalTemp)]); + ThermalFields.Add(Fields[nameof(atmosphereTemp)]); + ThermalFields.Add(Fields[nameof(exposedBackgroundTemp)]); + ThermalFields.Add(Fields[nameof(convectionFlux)]); + ThermalFields.Add(Fields[nameof(finalConvCoeff)]); + ThermalFields.Add(Fields[nameof(intConductionFlux)]); + ThermalFields.Add(Fields[nameof(skinConductionFlux)]); + ThermalFields.Add(Fields[nameof(skinInternalConductionFlux)]); + ThermalFields.Add(Fields[nameof(skinSkinConductionFlux)]); + ThermalFields.Add(Fields[nameof(unexpSkinInternalConductionFlux)]); + ThermalFields.Add(Fields[nameof(radiationFlux)]); + ThermalFields.Add(Fields[nameof(unexpRadiationFlux)]); + ThermalFields.Add(Fields[nameof(fixedUpdateStall)]); + ThermalFields.Add(Fields[nameof(updateStall)]); + } + private void SetThermalFieldsVisibility(bool enabled) + { + thermalFieldsVisible = enabled; + foreach (BaseField f in ThermalFields) + f.guiActive = enabled; + } + private void UpdateThermalDebugFields() + { + convergenceFactor = PhysicsGlobals.ThermalConvergenceFactor; + skinSkinConductionMult = part.skinSkinConductionMult; + skinSkinConductionFactor = PhysicsGlobals.SkinSkinConductionFactor; + convectionArea = part.ptd.convectionArea; + radiativeArea = 1f / part.ptd.radAreaRecip; + skinExposedAreaFrac = part.skinExposedAreaFrac; + exposedSkinTemp = part.skinTemperature; + unexposedSkinTemp = part.skinUnexposedTemperature; + partTemp = part.temperature; + externalTemp = FlightIntegrator.ActiveVesselFI.externalTemperature; + atmosphereTemp = FlightIntegrator.ActiveVesselFI.atmosphericTemperature; + exposedBackgroundTemp = part.ptd.brtExposed; + //bodyArea = FlightIntegrator.ActiveVesselFI.GetBodyArea(part.ptd); + //sunArea = FlightIntegrator.ActiveVesselFI.GetSunArea(part.ptd); + convectionFlux = part.ptd.convectionFlux; + finalConvCoeff = part.ptd.finalCoeff; + intConductionFlux = part.ptd.intConductionFlux; + skinConductionFlux = part.ptd.skinConductionFlux; + skinInternalConductionFlux = part.ptd.skinInteralConductionFlux; + skinSkinConductionFlux = part.ptd.skinSkinConductionFlux; + unexpSkinInternalConductionFlux = part.ptd.unexpSkinInternalConductionFlux; + //expFlux = part.ptd.expFlux; + //unexpFlux = part.ptd.unexpFlux; + radiationFlux = part.ptd.radiationFlux; + unexpRadiationFlux = part.ptd.unexpRadiationFlux; + if (vessel.GetComponent() is VehicleOcclusion vo) + { + fixedUpdateStall = vo.metrics.data.TryGetValue(VehicleOcclusion.FixedUpdateMetric, out Utils.MetricsElement e) ? e.hysteresisTime : 0; + updateStall = vo.metrics.data.TryGetValue(VehicleOcclusion.UpdateMetric, out Utils.MetricsElement e2) ? e2.hysteresisTime : 0; + } } public double ProjectedAreaWorld(Vector3 normalizedDirectionVector) @@ -557,7 +674,7 @@ public void UpdateVelocityAndAngVelocity(Vector3 frameVel) return; //world velocity - partLocalVel = rb.velocity + frameVel - FARWind.GetWind(FARAeroUtil.CurrentBody, part, rb.position); + partLocalVel = rb.velocity + frameVel - FARAtmosphere.GetWind(FARAeroUtil.CurrentBody, part, rb.position); worldSpaceVelNorm = partLocalVel.normalized; partLocalVel = partTransform.InverseTransformDirection(partLocalVel); @@ -701,13 +818,12 @@ private void UpdateAeroDisplay() momentArrow = null; } } - if (PhysicsGlobals.AeroDataDisplay && !part.ShieldedFromAirstream) { if (!fieldsVisible) { - Fields["dragForce"].guiActive = true; - Fields["liftForce"].guiActive = true; + Fields[nameof(dragForce)].guiActive = true; + Fields[nameof(liftForce)].guiActive = true; fieldsVisible = true; } @@ -716,12 +832,20 @@ private void UpdateAeroDisplay() } else if (fieldsVisible) { - Fields["dragForce"].guiActive = false; - Fields["liftForce"].guiActive = false; + Fields[nameof(dragForce)].guiActive = false; + Fields[nameof(liftForce)].guiActive = false; fieldsVisible = false; } } + public override void OnUpdate() + { + if (PhysicsGlobals.ThermalDataDisplay != thermalFieldsVisible) + SetThermalFieldsVisibility(PhysicsGlobals.ThermalDataDisplay); + if (PhysicsGlobals.ThermalDataDisplay) + UpdateThermalDebugFields(); + } + public override void OnLoad(ConfigNode node) { base.OnLoad(node); diff --git a/FerramAerospaceResearch/FARAeroComponents/FARAeroSection.cs b/FerramAerospaceResearch/FARAeroComponents/FARAeroSection.cs index 593ab28de..342111f35 100644 --- a/FerramAerospaceResearch/FARAeroComponents/FARAeroSection.cs +++ b/FerramAerospaceResearch/FARAeroComponents/FARAeroSection.cs @@ -1,5 +1,5 @@ -/* -Ferram Aerospace Research v0.16.0.0 "Mader" +/* +Ferram Aerospace Research v0.16.0.2 "Mader" ========================= Aerodynamics model for Kerbal Space Program diff --git a/FerramAerospaceResearch/FARAeroComponents/FARVesselAero.cs b/FerramAerospaceResearch/FARAeroComponents/FARVesselAero.cs index 00923e357..6130bb436 100644 --- a/FerramAerospaceResearch/FARAeroComponents/FARVesselAero.cs +++ b/FerramAerospaceResearch/FARAeroComponents/FARVesselAero.cs @@ -1,5 +1,5 @@ -/* -Ferram Aerospace Research v0.16.0.0 "Mader" +/* +Ferram Aerospace Research v0.16.0.2 "Mader" ========================= Aerodynamics model for Kerbal Space Program @@ -72,6 +72,13 @@ public class FARVesselAero : VesselModule private VehicleAerodynamics _vehicleAero; private VesselIntakeRamDrag _vesselIntakeRamDrag; + internal VehicleAerodynamics VehicleAero + { + get { return _vehicleAero; } + } + + public VehicleOcclusion vehicleOcclusion { get; private set; } + public double Length { get { return _vehicleAero.Length; } @@ -126,6 +133,11 @@ protected override void OnStart() p.AddModule("FARAeroPartModule").OnStart(StartState()); _currentGeoModules.Add(g); } + if (Settings.OcclusionSettings.UseRaycaster) + { + vehicleOcclusion = Vessel.gameObject.AddComponent(); + vehicleOcclusion.Setup(this); + } RequestUpdateVoxel(false); @@ -179,6 +191,17 @@ private void FixedUpdate() out _currentAeroSections, out _legacyWingModels); + if (Settings.OcclusionSettings.UseRaycaster) + { + if (vehicleOcclusion is null) + { + vehicleOcclusion = Vessel.gameObject.AddComponent(); + vehicleOcclusion.Setup(this); + } + vehicleOcclusion.RequestReset = true; + vehicleOcclusion.SetVehicleBounds(_vehicleAero.VoxelCenter, _vehicleAero.VoxelMeshExtents); + } + if (_flightGUI is null) _flightGUI = vessel.GetComponent(); @@ -225,10 +248,8 @@ private void CalculateAndApplyVesselAeroProperties() Length, vessel.srfSpeed, MachNumber, - FlightGlobals.getExternalTemperature((float)vessel - .altitude, - vessel.mainBody), - vessel.mainBody.atmosphereAdiabaticIndex); + FARAtmosphere.GetTemperature(vessel), + FARAtmosphere.GetAdiabaticIndex(vessel)); float skinFrictionDragCoefficient = (float)FARAeroUtil.SkinFrictionDrag(ReynoldsNumber, MachNumber); float pseudoKnudsenNumber = (float)(MachNumber / (ReynoldsNumber + MachNumber)); @@ -267,13 +288,10 @@ double altitude var center = new FARCenterQuery(); var dummy = new FARCenterQuery(); - CelestialBody body = vessel.mainBody; //Calculate main gas properties - float pressure = (float)body.GetPressure(altitude); - float temperature = (float)body.GetTemperature(altitude); - float density = (float)body.GetDensity(pressure, temperature); - float speedOfSound = (float)body.GetSpeedOfSound(pressure, density); + //Calculate main gas properties + GasProperties properties = FARAtmosphere.GetGasProperties(vessel); - if (pressure <= 0 || temperature <= 0 || density <= 0 || speedOfSound <= 0) + if (properties.Pressure <= 0 || properties.Temperature <= 0) { aeroForce = Vector3.zero; aeroTorque = Vector3.zero; @@ -281,14 +299,13 @@ double altitude } float velocityMag = velocityWorldVector.magnitude; - float machNumber = velocityMag / speedOfSound; - float reynoldsNumber = - (float)FARAeroUtil.CalculateReynoldsNumber(density, - Length, - velocityMag, - machNumber, - temperature, - body.atmosphereAdiabaticIndex); + float machNumber = (float)(velocityMag / properties.SpeedOfSound); + float reynoldsNumber = (float)FARAeroUtil.CalculateReynoldsNumber(properties.Density, + Length, + velocityMag, + machNumber, + properties.Temperature, + properties.AdiabaticIndex); float reynoldsPerLength = reynoldsNumber / (float)Length; float skinFriction = (float)FARAeroUtil.SkinFrictionDrag(reynoldsNumber, machNumber); @@ -298,7 +315,7 @@ double altitude if (_currentAeroSections != null) { foreach (FARAeroSection curSection in _currentAeroSections) - curSection?.PredictionCalculateAeroForces(density, + curSection?.PredictionCalculateAeroForces((float)properties.Density, machNumber, reynoldsPerLength, pseudoKnudsenNumber, @@ -311,7 +328,7 @@ double altitude center.AddForce(curWing.transform.position, curWing.PrecomputeCenterOfLift(velocityWorldVector, machNumber, - density, + properties.Density, dummy)); } @@ -447,7 +464,8 @@ public void VesselUpdate(bool recalcGeoModules) _voxelCount, vessel.Parts, _currentGeoModules, - !setup)) + !setup, + vessel)) { _updateRateLimiter = FARSettingsScenarioModule.VoxelSettings.minPhysTicksPerUpdate - 2; _updateQueued = true; diff --git a/FerramAerospaceResearch/FARAeroComponents/FlightForceContext.cs b/FerramAerospaceResearch/FARAeroComponents/FlightForceContext.cs index 37328e156..dea3d64f6 100644 --- a/FerramAerospaceResearch/FARAeroComponents/FlightForceContext.cs +++ b/FerramAerospaceResearch/FARAeroComponents/FlightForceContext.cs @@ -1,5 +1,5 @@ /* -Ferram Aerospace Research v0.16.0.0 "Mader" +Ferram Aerospace Research v0.16.0.2 "Mader" ========================= Copyright 2020, Benjamin Chung, aka BenChung diff --git a/FerramAerospaceResearch/FARAeroComponents/ModularFlightIntegratorRegisterer.cs b/FerramAerospaceResearch/FARAeroComponents/ModularFlightIntegratorRegisterer.cs index 955f3ee2b..6a17fa10e 100644 --- a/FerramAerospaceResearch/FARAeroComponents/ModularFlightIntegratorRegisterer.cs +++ b/FerramAerospaceResearch/FARAeroComponents/ModularFlightIntegratorRegisterer.cs @@ -1,5 +1,5 @@ -/* -Ferram Aerospace Research v0.16.0.0 "Mader" +/* +Ferram Aerospace Research v0.16.0.2 "Mader" ========================= Aerodynamics model for Kerbal Space Program @@ -52,6 +52,7 @@ namespace FerramAerospaceResearch.FARAeroComponents [KSPAddon(KSPAddon.Startup.SpaceCentre, true)] public class ModularFlightIntegratorRegisterer : MonoBehaviour { + public static float MIN_AREA_FRACTION = 0.01f; private void Start() { FARLogger.Info("Modular Flight Integrator function registration started"); @@ -61,30 +62,183 @@ private void Start() ModularFlightIntegrator.RegisterCalculateAreaRadiativeOverride(CalculateAreaRadiative); ModularFlightIntegrator.RegisterGetSunAreaOverride(CalculateSunArea); ModularFlightIntegrator.RegisterGetBodyAreaOverride(CalculateBodyArea); + ModularFlightIntegrator.RegisterUpdateOcclusionOverride(UpdateOcclusion); + ModularFlightIntegrator.RegisterSetSkinProperties(SetSkinProperties); + ModularFlightIntegrator.RegisterUpdateConductionOverride(UpdateConduction); FARLogger.Info("Modular Flight Integrator function registration complete"); Destroy(this); } + private void UpdateConduction(ModularFlightIntegrator fi) + { + // Improve the skinSkinTransfer calc: move the exposed fraction into the sqrt. + foreach (PartThermalData ptd in fi.partThermalDataList) + { + double frac = Math.Min(ptd.part.skinExposedAreaFrac, 1.0 - ptd.part.skinExposedAreaFrac); + double exposedArea = frac * ptd.part.radiativeArea; + ptd.skinSkinTransfer = ptd.part.skinSkinConductionMult * PhysicsGlobals.SkinSkinConductionFactor * 2.0 * Math.Sqrt(exposedArea); + } + fi.BaseFIUpdateConduction(); + } + + // This is the primary consumer of DragCube.ExposedArea, so handling this ourselves may + // remove the need for any calculation gymnastics we were doing to not interfere with stock handling. + private static void SetSkinProperties(ModularFlightIntegrator fi, PartThermalData ptd) + { + Part part = ptd.part; + + //if (occlusion == null || occlusion.state == VehicleOcclusion.State.Invalid || aeroModule == null) + if (!(fi.Vessel.GetComponent() is VehicleOcclusion occlusion && + part.Modules.GetModule() is FARAeroPartModule aeroModule && + occlusion.state != VehicleOcclusion.State.Invalid)) + { + fi.BaseFIetSkinPropertie(ptd); + return; + } + if (part.skinUnexposedTemperature < PhysicsGlobals.SpaceTemperature) + part.skinUnexposedTemperature = part.skinTemperature; + + double a = Math.Max(part.radiativeArea, 0.001); + ptd.radAreaRecip = 1.0 / Math.Max(part.radiativeArea, 0.001); + +// Vector3 localForward = (part.vessel.transform.worldToLocalMatrix * part.vessel.transform.forward); +// Vector3 localVel = part.vessel.transform.worldToLocalMatrix * fi.Vel; + double areaFraction = 0; + if (!part.ShieldedFromAirstream && part.atmDensity > 0) + { + // Stock calculation: + //ptd.convectionArea = UtilMath.Lerp(a, part.exposedArea, -PhysicsGlobals.FullConvectionAreaMin + (fi.mach - PhysicsGlobals.FullToCrossSectionLerpStart) / (PhysicsGlobals.FullToCrossSectionLerpEnd - PhysicsGlobals.FullToCrossSectionLerpStart)) * ptd.convectionAreaMultiplier; + // Note that part.exposedArea has some scaling based on the mach factor: + //float dot = Vector3.Dot(direction, faceDirection); + //float num2 = PhysicsGlobals.DragCurveValue(PhysicsGlobals.SurfaceCurves, ((dot + 1.0)/2), machNumber); + //retData.exposedArea += this.areaOccluded[index] * num2 / PhysicsGlobals.DragCurveMultiplier.Evaluate(machNumber) + // PhysicsGlobals.DragCurveValue scales its transsonic calcs by *= PhysicsGlobals.DragCubeMultiplier.Evaluate(machNumber) + // So thermal convection undoes -that- part of the scaling, but leaves: + /* + DRAG_TIP + { + key = 0 1 0 0 + key = 0.85 1.19 0.6960422 0.6960422 + key = 1.1 2.83 0.730473 0.730473 + key = 5 4 0 0 + } + Mach 1.1 - 5 has a multiplier from 2.83 to 4. Mach 5+ has a multiplier of 4. + Does this make sense for convection heating? + */ + + // VehicleOcclusion's handler might need to be more careful about how it averages values. + // Otherwise parts behind same-size shields can tend towards very small convectionArea when it should probably be 0. + ptd.convectionArea = occlusion.ConvectionArea(part, fi.Vel); + ptd.convectionCoeffMultiplier = PhysicsGlobals.SurfaceCurves.dragCurveTip.Evaluate(Convert.ToSingle(fi.mach)); + + double d = ptd.convectionArea * ptd.radAreaRecip; + areaFraction = (!double.IsNaN(d) && d > 0.001) ? d : 0; + areaFraction = Math.Min(areaFraction, 1); + if (areaFraction < MIN_AREA_FRACTION) + areaFraction = 0; + } + if (areaFraction > 0) + { + StockSkinTemperatureHandling(ptd, areaFraction); + ptd.exposed = true; + part.skinExposedAreaFrac = areaFraction; + part.skinExposedArea = areaFraction * a; // == ptd.convectionArea + } + else + { + if (ptd.exposed) + fi.UnifySkinTemp(ptd); + ptd.exposed = false; + ptd.convectionArea = part.skinExposedArea = part.skinUnexposedMassMult = 0.0; + part.skinExposedAreaFrac = part.skinExposedMassMult = 1.0; + } + ptd.convectionTempMultiplier = ptd.exposed ? 1 : 0; + } + + private static void StockSkinTemperatureHandling(PartThermalData ptd, double areaFraction) + { + if (areaFraction <= 0) + return; + Part part = ptd.part; + if (!ptd.exposed || areaFraction == 1.0) + part.skinUnexposedTemperature = part.skinTemperature; + ptd.exposed = true; + part.skinExposedMassMult = 1.0 / areaFraction; + if (areaFraction < 1.0) + part.skinUnexposedMassMult = 1.0 / (1.0 - areaFraction); + else + part.skinUnexposedMassMult = 0.0; + + // If the area fraction has changed since last calculation + if (part.skinExposedAreaFrac != areaFraction) + { + if (part.skinUnexposedTemperature != part.skinTemperature && + part.skinExposedAreaFrac > 0.0 && + part.skinExposedAreaFrac < 1.0 && + areaFraction < 1.0) + { + double unexposedAreaFrac = 1.0 - part.skinExposedAreaFrac; + double thermalEnergyInExposedSkin = part.skinTemperature * part.skinExposedAreaFrac * part.skinThermalMass; + double thermalEnergyInUnexposedSkin = part.skinUnexposedTemperature * unexposedAreaFrac * part.skinThermalMass; + double dAreaFrac = areaFraction - part.skinExposedAreaFrac; + double dThermalEnergy; + if (dAreaFrac > 0.0) + dThermalEnergy = dAreaFrac / unexposedAreaFrac * thermalEnergyInUnexposedSkin; + else + dThermalEnergy = dAreaFrac / part.skinExposedAreaFrac * thermalEnergyInExposedSkin; + part.skinTemperature = (thermalEnergyInExposedSkin + dThermalEnergy) * part.skinExposedMassMult * part.skinThermalMassRecip; + part.skinUnexposedTemperature = (thermalEnergyInUnexposedSkin - dThermalEnergy) * part.skinUnexposedMassMult * part.skinThermalMassRecip; + } + } + } + + private static void UpdateOcclusion(ModularFlightIntegrator fi, bool all) + { + if (fi.Vessel.GetComponent() is VehicleOcclusion occlusion + && occlusion.state != VehicleOcclusion.State.Invalid) + { + foreach (Part p in fi.Vessel.Parts) + { + p.ptd.bodyAreaMultiplier = 1; + p.ptd.sunAreaMultiplier = 1; + p.ptd.convectionAreaMultiplier = 1; + p.ptd.convectionTempMultiplier = 1; + } + } + else + fi.BaseFIUpdateOcclusion(all); + } + private static void UpdateThermodynamicsPre(ModularFlightIntegrator fi) { + bool voxelizationCompleted = + fi.Vessel.FindVesselModuleImplementing().HasEverValidVoxelization(); + for (int i = 0; i < fi.PartThermalDataCount; i++) { PartThermalData ptd = fi.partThermalDataList[i]; Part part = ptd.part; - if (!part.Modules.Contains()) + if (!(part.Modules.GetModule() is FARAeroPartModule aeroModule)) continue; - FARAeroPartModule aeroModule = part.Modules.GetModule(); - // 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 (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 @@ -106,7 +260,7 @@ private static void UpdateAerodynamics(ModularFlightIntegrator fi, Part part) return; part.dragVector = rb.velocity + Krakensbane.GetFrameVelocity() - - FARWind.GetWind(FlightGlobals.currentMainBody, part, rb.position); + FARAtmosphere.GetWind(FlightGlobals.currentMainBody, part, rb.position); part.dragVectorSqrMag = part.dragVector.sqrMagnitude; if (part.dragVectorSqrMag.NearlyEqual(0) || part.ShieldedFromAirstream) { @@ -132,15 +286,14 @@ private static void UpdateAerodynamics(ModularFlightIntegrator fi, Part part) private static void CalculateLocalDynPresAndAngularDrag(ModularFlightIntegrator fi, Part p) { + p.dynamicPressurekPa = p.atmDensity; 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; @@ -159,18 +312,20 @@ private static void CalculateLocalDynPresAndAngularDrag(ModularFlightIntegrator tmp = Math.Max(fi.pseudoReDragMult, 1); //dyn pres adjusted for submersion p.dragScalar = (float)((p.dynamicPressurekPa * (1.0 - p.submergedPortion) + - p.submergedDynamicPressurekPa * p.submergedPortion) * + p.submergedDynamicPressurekPa * + p.submergedPortion * + FARSettings.SubmergedDragMultiplier) * tmp); p.bodyLiftScalar = (float)(p.dynamicPressurekPa * (1.0 - p.submergedPortion) + - p.submergedDynamicPressurekPa * p.submergedPortion); + p.submergedDynamicPressurekPa * + p.submergedPortion * + FARSettings.SubmergedLiftMultiplier) * + p.bodyLiftMultiplier; } private static double CalculateAreaRadiative(ModularFlightIntegrator fi, Part part) { - FARAeroPartModule module = null; - if (part.Modules.Contains()) - module = part.Modules.GetModule(); - + FARAeroPartModule module = part.Modules.GetModule(); return CalculateAreaRadiative(fi, part, module); } @@ -180,7 +335,7 @@ private static double CalculateAreaRadiative( FARAeroPartModule aeroModule ) { - if (aeroModule is null) + if (aeroModule is null || !FARAPI.VesselVoxelizationCompletedEver(part.vessel)) return fi.BaseFICalculateAreaRadiative(part); double radArea = aeroModule.ProjectedAreas.totalArea; @@ -189,16 +344,13 @@ FARAeroPartModule aeroModule private static double CalculateAreaExposed(ModularFlightIntegrator fi, Part part) { - FARAeroPartModule module = null; - if (part.Modules.Contains()) - module = part.Modules.GetModule(); - + FARAeroPartModule module = part.Modules.GetModule(); return CalculateAreaExposed(fi, part, module); } private static double CalculateAreaExposed(ModularFlightIntegrator fi, Part part, FARAeroPartModule aeroModule) { - if (aeroModule is null) + if (aeroModule is null || !FARAPI.VesselVoxelizationCompletedEver(part.vessel)) return fi.BaseFICalculateAreaExposed(part); // Apparently stock exposed area is actually weighted by some function of mach number... @@ -212,27 +364,30 @@ private static double CalculateAreaExposed(ModularFlightIntegrator fi, Part part private static double CalculateSunArea(ModularFlightIntegrator fi, PartThermalData ptd) { - FARAeroPartModule module = null; - if (ptd.part.Modules.Contains()) - module = ptd.part.Modules.GetModule(); - - if (module is null) - return fi.BaseFIGetSunArea(ptd); - double sunArea = module.ProjectedAreaWorld(fi.sunVector) * ptd.sunAreaMultiplier; - + double sunArea = 0; + if (fi.Vessel.GetComponent() is VehicleOcclusion occlusion) + { + sunArea = occlusion.SunArea(ptd.part, fi.sunVector); + } + else if (ptd.part.Modules.GetModule() is FARAeroPartModule module && FARAPI.VesselVoxelizationCompletedEver(ptd.part.vessel)) + { + sunArea = module.ProjectedAreaWorld(fi.sunVector) * ptd.sunAreaMultiplier; + } return sunArea > 0 ? sunArea : fi.BaseFIGetSunArea(ptd); } private static double CalculateBodyArea(ModularFlightIntegrator fi, PartThermalData ptd) { - FARAeroPartModule module = null; - if (ptd.part.Modules.Contains()) - module = ptd.part.Modules.GetModule(); - - if (module is null) - return fi.BaseFIBodyArea(ptd); - double bodyArea = module.ProjectedAreaWorld(-fi.Vessel.upAxis) * ptd.bodyAreaMultiplier; - + double bodyArea = 0; + Vector3 bodyVec = fi.Vessel.transform.worldToLocalMatrix * (Vector3)(fi.Vessel.mainBody.position - fi.Vessel.transform.position); + if (fi.Vessel.GetComponent() is VehicleOcclusion occlusion && occlusion.state != VehicleOcclusion.State.Invalid) + { + bodyArea = occlusion.BodyArea(ptd.part, bodyVec.normalized); + } + else if (ptd.part.Modules.GetModule() is FARAeroPartModule module && FARAPI.VesselVoxelizationCompletedEver(ptd.part.vessel)) + { + bodyArea = module.ProjectedAreaWorld(bodyVec.normalized) * ptd.bodyAreaMultiplier; + } return bodyArea > 0 ? bodyArea : fi.BaseFIBodyArea(ptd); } } diff --git a/FerramAerospaceResearch/FARAeroComponents/SimulatedForceContext.cs b/FerramAerospaceResearch/FARAeroComponents/SimulatedForceContext.cs index 24c1207b4..bd41e40d3 100644 --- a/FerramAerospaceResearch/FARAeroComponents/SimulatedForceContext.cs +++ b/FerramAerospaceResearch/FARAeroComponents/SimulatedForceContext.cs @@ -1,5 +1,5 @@ /* -Ferram Aerospace Research v0.16.0.0 "Mader" +Ferram Aerospace Research v0.16.0.2 "Mader" ========================= Copyright 2020, Benjamin Chung, aka BenChung diff --git a/FerramAerospaceResearch/FARAeroComponents/VehicleAerodynamics.cs b/FerramAerospaceResearch/FARAeroComponents/VehicleAerodynamics.cs index 2916ab562..8da656895 100644 --- a/FerramAerospaceResearch/FARAeroComponents/VehicleAerodynamics.cs +++ b/FerramAerospaceResearch/FARAeroComponents/VehicleAerodynamics.cs @@ -1,5 +1,5 @@ /* -Ferram Aerospace Research v0.16.0.0 "Mader" +Ferram Aerospace Research v0.16.0.2 "Mader" ========================= Aerodynamics model for Kerbal Space Program @@ -49,6 +49,7 @@ You should have received a copy of the GNU General Public License using FerramAerospaceResearch.FARPartGeometry; using FerramAerospaceResearch.FARPartGeometry.GeometryModification; using FerramAerospaceResearch.FARThreading; +using FerramAerospaceResearch.Settings; using UnityEngine; namespace FerramAerospaceResearch.FARAeroComponents @@ -82,6 +83,8 @@ internal class VehicleAerodynamics private Vector3d _voxelLowerRightCorner; private double _voxelElementSize; private double _sectionThickness; + public Vector3d VoxelCenter { get; private set; } + public Vector3d VoxelMeshExtents { get; private set; } private Vector3 _vehicleMainAxis; private List _vehiclePartList; @@ -105,7 +108,7 @@ internal class VehicleAerodynamics private int firstSection; private bool visualizing; - private bool voxelizing; + public bool Voxelizing { get; private set; } public VehicleAerodynamics() { @@ -335,12 +338,13 @@ public bool TryVoxelUpdate( int voxelCount, List vehiclePartList, List currentGeoModules, - bool updateGeometryPartModules = true + bool updateGeometryPartModules = true, + Vessel vessel = null ) { //set to true when this function ends; only continue to voxelizing if the voxelization thread has not been queued //this should catch conditions where this function is called again before the voxelization thread starts - if (voxelizing) + if (Voxelizing) return false; //only continue if the voxelizing thread has not locked this object if (!Monitor.TryEnter(this, 0)) @@ -373,8 +377,8 @@ public bool TryVoxelUpdate( _voxel?.CleanupVoxel(); //set flag so that this function can't run again before voxelizing completes and queue voxelizing thread - voxelizing = true; - VoxelizationThreadpool.Instance.QueueVoxelization(CreateVoxel); + Voxelizing = true; + VoxelizationThreadpool.Instance.QueueVoxelization(() => CreateVoxel(vessel)); return true; } finally @@ -384,19 +388,21 @@ public bool TryVoxelUpdate( } //And this actually creates the voxel and then begins the aero properties determination - private void CreateVoxel() + private void CreateVoxel(Vessel vessel = null) { lock (this) //lock this object to prevent race with main thread { try { //Actually voxelize it - _voxel = VehicleVoxel.CreateNewVoxel(_currentGeoModules, _voxelCount); + _voxel = VehicleVoxel.CreateNewVoxel(_currentGeoModules, _voxelCount, vessel: vessel); if (_vehicleCrossSection.Length < _voxel.MaxArrayLength) _vehicleCrossSection = _voxel.EmptyCrossSectionArray; _voxelLowerRightCorner = _voxel.LocalLowerRightCorner; _voxelElementSize = _voxel.ElementSize; + VoxelCenter = _voxel.Center; + VoxelMeshExtents = _voxel.MeshExtents; CalculateVesselAeroProperties(); CalculationCompleted = true; @@ -408,14 +414,14 @@ private void CreateVoxel() finally { //Always, when we finish up, if we're in flight, cleanup the voxel - if (HighLogic.LoadedSceneIsFlight && _voxel != null) + if (HighLogic.LoadedSceneIsFlight && !VoxelizationSettings.DebugInFlight && _voxel != null) { _voxel.CleanupVoxel(); _voxel = null; } //And unset the flag so that the main thread can queue it again - voxelizing = false; + Voxelizing = false; } } } @@ -1029,8 +1035,9 @@ private void CalculateVesselAeroProperties() for (int i = front; i <= back; i++) { if (double.IsNaN(_vehicleCrossSection[i].area)) - ThreadSafeDebugLogger - .Instance.RegisterMessage("FAR VOXEL ERROR: Voxel CrossSection Area is NaN at section " + i); + ThreadSafeDebugLogger.Instance + .RegisterMessage("FAR VOXEL ERROR: Voxel CrossSection Area is NaN at section " + + i); filledVolume += _vehicleCrossSection[i].area; } diff --git a/FerramAerospaceResearch/FARAeroComponents/VehicleOcclusion.cs b/FerramAerospaceResearch/FARAeroComponents/VehicleOcclusion.cs new file mode 100644 index 000000000..4480b243d --- /dev/null +++ b/FerramAerospaceResearch/FARAeroComponents/VehicleOcclusion.cs @@ -0,0 +1,828 @@ +using System.Collections; +using System.Collections.Generic; +using FerramAerospaceResearch.UnityJobs; +using Unity.Collections; +using Unity.Jobs; +using Unity.Mathematics; +using UnityEngine; +using UnityEngine.Jobs; +using UnityEngine.Profiling; +using FerramAerospaceResearch.Settings; + +/* Theory of Job Control: + * At beginning of FixedUpdate cycle, pre-calculate the occlusion orientations we need. + * Convection occlusion calcuation and sun occlusion calculation are separate orientations. + * Weighted-average / lerp the 3 closest orientations; this can be 6 raycasts on first execution if we missed all caches. + * On exemplar system (4-core I5-6500 3.2GHz 16GB RAM): + * <2ms at FixedUpdate.ObscenelyEarly to gather the raycast data + * Expensive raycasts can cost ~4ms (10,000 rays), cheaper ones 0.5ms + * + * */ +namespace FerramAerospaceResearch.FARAeroComponents +{ + public class VehicleOcclusion : MonoBehaviour + { + public enum State { Invalid, Initialized, Running, Completed } + public State state = State.Invalid; + public static bool PassStarted { get; private set; } = false; + public static int JobsInCurrentPass { get; private set; } = 0; + private bool resetCoroutineRunning = false; + private IEnumerator resetWaitCoroutine; + + private FARVesselAero farVesselAero; + //private Vessel Vessel => farVesselAero?.Vessel; + public Vessel Vessel { get; private set; } + bool OnValidPhysicsVessel => farVesselAero && Vessel && (!Vessel.packed || Vessel == FlightIntegrator.ActiveVesselFI?.Vessel); + + private readonly Dictionary partsByTransform = new Dictionary(); + private readonly Dictionary partOcclusionInfo = new Dictionary(); + + // Quaternions is the full list of orientations for measurement + // processedQuaternionsMap is the map of elements in Quaternions that have been processed + // quaternionWorkList is the list of quaternions to process on this specific pass. + private NativeHashMap processedQuaternionsMap; + private NativeArray Quaternions; + + // Closest 3 convection and sun quaternions for each FixedUpdate + private readonly SphereDistanceInfo[] convectionPoints = new SphereDistanceInfo[3]; + private readonly SphereDistanceInfo[] sunPoints = new SphereDistanceInfo[3]; + private readonly SphereDistanceInfo[] bodyPoints = new SphereDistanceInfo[3]; + + private readonly DirectionPreprocessInfo[] directionPreprocessInfos = new DirectionPreprocessInfo[3]; + private readonly List directionList = new List(OcclusionSettings.MaxJobs); + private readonly List occlusionPointsList = new List(3); + public float3 DefaultAngleWeights => new float3(0.85f, 0, 0.15f); + + // VehicleVoxel center and extents + private Vector3 center = Vector3.zero; + private Vector3 extents = new Vector3(10, 10, 10); + + private int jobsInProgress; + private float averageMissOnBestAngle = 0; + + // Large long-term allocations, memory re-used in each + // Cleaned and Allocated in ResetCalculations(). Disposed in OnDestroy() + private NativeMultiHashMap indexedPriorityMap; + + private readonly NativeArray[] allCasts = new NativeArray[OcclusionSettings.MaxJobs]; + private readonly NativeArray[] allHits = new NativeArray[OcclusionSettings.MaxJobs]; + private readonly NativeMultiHashMap[] allHitsMaps = new NativeMultiHashMap[OcclusionSettings.MaxJobs]; + private readonly NativeHashMap[] allHitSizeMaps = new NativeHashMap[OcclusionSettings.MaxJobs]; + private readonly NativeArray[] allSummedHitAreas = new NativeArray[OcclusionSettings.MaxJobs]; + + // allCasts => allHits + // allHits => allHitMaps + // allHitMaps => allHitSizeMaps, + // allSummedHitAreas, + + private readonly RaycastJobInfo[] raycastJobTracker = new RaycastJobInfo[OcclusionSettings.MaxJobs]; + public bool RequestReset = false; + public Utils.Metrics metrics = new Utils.Metrics(); + public const string FixedUpdateMetric = "FixedUpdateStall"; + public const string UpdateMetric = "UpdateStall"; + private System.Diagnostics.Stopwatch JobCompleteWatch = new System.Diagnostics.Stopwatch(); + + public void Setup(FARVesselAero farVesselAero) + { + this.farVesselAero = farVesselAero; + Vessel = farVesselAero.Vessel; + } + + //Extents = axis-aligned bounding box dimensions of combined vehicle meshes + public void SetVehicleBounds(Vector3d center, Vector3d extents) + { + this.center = center; + this.extents = extents; + FARLogger.Info($"[VehicleOcclusion] {Vessel?.name} Learned Center {center} and Extents {extents}"); + } + + private void DisposeLongTermAllocations() + { + if (state != State.Invalid) + { + Quaternions.Dispose(); + processedQuaternionsMap.Dispose(); + indexedPriorityMap.Dispose(); + + foreach (var x in allCasts) + x.Dispose(); + foreach (var x in allHits) + x.Dispose(); + foreach (var x in allHitsMaps) + x.Dispose(); + foreach (var x in allSummedHitAreas) + x.Dispose(); + foreach (var x in allHitSizeMaps) + x.Dispose(); + } + } + + private void ResetCalculations() + { + FARLogger.Info($"[VehicleOcclusion] {Vessel?.name} Resetting occlusion calculation data."); + if (resetCoroutineRunning && resetWaitCoroutine != null) + { + StopCoroutine(resetWaitCoroutine); + resetCoroutineRunning = false; + } + + partsByTransform.Clear(); + partOcclusionInfo.Clear(); + DisposeLongTermAllocations(); + + indexedPriorityMap = new NativeMultiHashMap(OcclusionSettings.FibonacciLatticeSize, Allocator.Persistent); + Quaternions = new NativeArray(OcclusionSettings.FibonacciLatticeSize, Allocator.Persistent); + var handle = new SpherePointsJob + { + points = OcclusionSettings.FibonacciLatticeSize, + epsilon = Lattice_epsilon(OcclusionSettings.FibonacciLatticeSize), + results = Quaternions, + }.Schedule(OcclusionSettings.FibonacciLatticeSize, 16); + JobHandle.ScheduleBatchedJobs(); + + processedQuaternionsMap = new NativeHashMap(OcclusionSettings.FibonacciLatticeSize, Allocator.Persistent); + int sz = OcclusionSettings.MaxRaycastDimension * OcclusionSettings.MaxRaycastDimension; + for (int i=0; i(sz, Allocator.Persistent); + allHits[i] = new NativeArray(sz, Allocator.Persistent); + allHitsMaps[i] = new NativeMultiHashMap(sz, Allocator.Persistent); + allSummedHitAreas[i] = new NativeArray(sz, Allocator.Persistent); + allHitSizeMaps[i] = new NativeHashMap(sz, Allocator.Persistent); + } + foreach (Part p in Vessel.Parts) + { + partsByTransform.Add(p.transform, p); + } + handle.Complete(); + RequestReset = false; + state = State.Initialized; + } + + public void Start() + { + FARLogger.Info($"VehicleOcclusion on {Vessel?.name} reporting startup"); + state = State.Invalid; + occlusionPointsList.Clear(); + occlusionPointsList.Add(convectionPoints); + occlusionPointsList.Add(sunPoints); + occlusionPointsList.Add(bodyPoints); + TimingManager.FixedUpdateAdd(TimingManager.TimingStage.ObscenelyEarly, FixedUpdateEarly); + TimingManager.UpdateAdd(TimingManager.TimingStage.ObscenelyEarly, UpdateEarly); + TimingManager.LateUpdateAdd(TimingManager.TimingStage.Late, LateUpdateComplete); + } + + public void OnDestroy() + { + DisposeLongTermAllocations(); + + TimingManager.FixedUpdateRemove(TimingManager.TimingStage.ObscenelyEarly, FixedUpdateEarly); + TimingManager.UpdateRemove(TimingManager.TimingStage.ObscenelyEarly, UpdateEarly); + TimingManager.LateUpdateRemove(TimingManager.TimingStage.Late, LateUpdateComplete); + } + + private void LaunchAngleJobs(ref DirectionPreprocessInfo info, in NativeArray quaternions) + { + var angleJob = new AngleBetween + { + dir = info.dir, + rotations = quaternions, + angles = info.angles, + }.Schedule(OcclusionSettings.FibonacciLatticeSize, 16); + + var statsJob = new GeneralDistanceInfo + { + distances = info.angles, + output = info.angleStats, + }.Schedule(angleJob); + + var statsCombineJob = new DotProductJob + { + A = info.angleStats, + B = info.weights, + result = info.distanceCutoff, + }.Schedule(info.angleStats.Length, 16, statsJob); + + info.sortJob = new SortedFilterAndMapByDistanceJob + { + quaternions = quaternions, + distances = info.angles, + cutoffDistance = info.distanceCutoff, + sdiList = info.sortedSDIList, + orderedQuaternions = info.orderedQuaternions, + }.Schedule(statsCombineJob); + JobHandle.ScheduleBatchedJobs(); + } + + private void LaunchRaycastJobs( + float4x4 localToWorldMatrix, + in NativeArray quaternions, + in NativeHashMap fullQuaternionIndexMap, + in NativeArray boundsArr, + in NativeArray intervalArr, + in NativeArray dimensionsArr, + in NativeArray forwardArr, + in NativeArray rightArr, + in NativeArray upArr, + out JobHandle indexMapJob, + out JobHandle vectorJob, + out JobHandle intervalJob) + { + indexMapJob = new MakeQuaternionIndexMapJob + { + arr = quaternions, + map = fullQuaternionIndexMap.AsParallelWriter(), + }.Schedule(OcclusionSettings.FibonacciLatticeSize, 16); + + vectorJob = new SetVectorsJob + { + quaternions = quaternions, + localToWorldMatrix = localToWorldMatrix, + forward = forwardArr, + up = upArr, + right = rightArr, + }.Schedule(OcclusionSettings.FibonacciLatticeSize, 16); + + var setBounds = new SetBoundsJob + { + boundsCenter = center, + extents = extents, + quaternions = quaternions, + bounds = boundsArr, + }.Schedule(OcclusionSettings.FibonacciLatticeSize, 16); + + intervalJob = new SetIntervalAndDimensionsJob + { + bounds = boundsArr, + maxDim = OcclusionSettings.MaxRaycastDimension, + resolution = OcclusionSettings.RaycastResolution, + interval = intervalArr, + dims = dimensionsArr, + }.Schedule(OcclusionSettings.FibonacciLatticeSize, 16, setBounds); + + JobHandle.ScheduleBatchedJobs(); + } + + private void BuildPreprocessInfo(DirectionPreprocessInfo[] infos, List directions) + { + for (int i=0; i(OcclusionSettings.FibonacciLatticeSize, Allocator.TempJob), + angleStats = new NativeArray(1, Allocator.TempJob), + sortedSDIList = new NativeList(OcclusionSettings.FibonacciLatticeSize, Allocator.TempJob), + orderedQuaternions = new NativeList(OcclusionSettings.FibonacciLatticeSize, Allocator.TempJob), + distanceCutoff = new NativeArray(1, Allocator.TempJob), + dir = v.normalized, + weights = DefaultAngleWeights, + }; + } + } + + private int BuildAndLaunchRaycastJobs( + Vessel v, + DirectionPreprocessInfo[] dirInfos, + RaycastJobInfo[] tracker, + in NativeArray quaternions, + in NativeHashMap processedMap, + in NativeMultiHashMap priorityMap, + int suggestedJobs, + float3 startPosition, + float offset, + NativeArray[] casts, + NativeArray[] hits, + NativeMultiHashMap[] hitsMaps, + NativeHashMap[] hitSizeMaps, + NativeArray[] summedHitAreas) + { + Profiler.BeginSample("VehicleOcclusion-LaunchJobs.Allocation_CastPlanes"); + var mapClearJob = new ClearNativeMultiHashMapIntInt { map = priorityMap }.Schedule(); + using var workList = new NativeList(OcclusionSettings.MaxJobs, Allocator.TempJob); + using var indexMap = new NativeHashMap(OcclusionSettings.FibonacciLatticeSize, Allocator.TempJob); + JobHandle lastJob = default; + for (int j = 0; j < dirInfos.Length; j++) + { + var x = new ListToIndexedMap + { + sorted = dirInfos[j].orderedQuaternions.AsDeferredJobArray(), + map = indexMap, + }.Schedule(lastJob); + lastJob = x; + } + + var bucketSortPriority = new BucketSortByPriority + { + quaternions = quaternions, + priorityMap = indexMap, + completed = processedMap, + maxIndexForPriority0 = 2, + map = priorityMap.AsParallelWriter(), + }.Schedule(OcclusionSettings.FibonacciLatticeSize, 16, JobHandle.CombineDependencies(lastJob, mapClearJob)); + JobHandle.ScheduleBatchedJobs(); + + using var fullQuaternionIndexMap = new NativeHashMap(OcclusionSettings.FibonacciLatticeSize, Allocator.TempJob); + using var boundsArr = new NativeArray(OcclusionSettings.FibonacciLatticeSize, Allocator.TempJob); + using var intervalArr = new NativeArray(OcclusionSettings.FibonacciLatticeSize, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); + using var dimensionsArr = new NativeArray(OcclusionSettings.FibonacciLatticeSize, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); + using var forwardArr = new NativeArray(OcclusionSettings.FibonacciLatticeSize, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); + using var rightArr = new NativeArray(OcclusionSettings.FibonacciLatticeSize, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); + using var upArr = new NativeArray(OcclusionSettings.FibonacciLatticeSize, Allocator.TempJob, NativeArrayOptions.UninitializedMemory); + Profiler.EndSample(); + + // Calculate raycast plane orientation/offset, dimensions, spacing, area/ray, element count + Profiler.BeginSample("VehicleOcclusion-LaunchJobs.JobSetup_CastPlanes"); + LaunchRaycastJobs( + v.transform.localToWorldMatrix, + in quaternions, + in fullQuaternionIndexMap, + in boundsArr, + in intervalArr, + in dimensionsArr, + in forwardArr, + in rightArr, + in upArr, + out var makeFullIndexMap, + out var setVectorsJob, + out var intervalJob); + Profiler.EndSample(); + + bucketSortPriority.Complete(); + SelectQuaternions(workList, priorityMap, OcclusionSettings.MaxJobs, 0); // Fill priority 0 (required) + SelectQuaternions(workList, priorityMap, suggestedJobs, 1); // Append priority 1 (desired) until size + SelectQuaternions(workList, priorityMap, suggestedJobs, 2); // Append priority 2 (anything) until size + + JobHandle.CompleteAll(ref setVectorsJob, ref intervalJob, ref makeFullIndexMap); + + int i = 0; + foreach (quaternion q in workList) + { + Profiler.BeginSample("VehicleOcclusion-LaunchJobs.SingleRaycastJobSetup"); + var clearMap1 = new ClearNativeMultiHashMapIntInt { map = hitsMaps[i], }.Schedule(); + var clearMap2 = new ClearNativeHashMapIntFloat { map = hitSizeMaps[i], }.Schedule(); + JobHandle.ScheduleBatchedJobs(); + + Profiler.BeginSample("VehicleOcclusion-LaunchJobs.SingleRaycastJobSetup.Prep"); + int index = fullQuaternionIndexMap[q]; + int elements = dimensionsArr[index].x * dimensionsArr[index].y; + tracker[i] = new RaycastJobInfo + { + q = q, + index = index, + area = intervalArr[index].x * intervalArr[index].y, + }; + Profiler.EndSample(); + + Profiler.BeginSample("VehicleOcclusion-LaunchJobs.SingleRaycastJobSetup.BuilderJob"); + tracker[i].builderJob = new OcclusionRaycastBuilder + { + startPosition = startPosition, + offset = offset, + forwardDir = forwardArr[index], + rightDir = rightArr[index], + upDir = upArr[index], + dimensions = dimensionsArr[index], + interval = intervalArr[index], + commands = casts[i], + }.Schedule(elements, 8); + Profiler.EndSample(); + + Profiler.BeginSample("VehicleOcclusion-LaunchJobs.SingleRaycastJobSetup.RaycastJob"); + tracker[i].raycastJob = RaycastCommand.ScheduleBatch(casts[i], hits[i], 1, tracker[i].builderJob); + Profiler.EndSample(); + + Profiler.BeginSample("VehicleOcclusion-LaunchJobs.SingleRaycastJobSetup.PreparerJob"); + tracker[i].preparerJob = new RaycastPrepareJob + { + hitsIn = hits[i], + hitsMap = hitsMaps[i].AsParallelWriter(), + }.Schedule(elements, 8, JobHandle.CombineDependencies(clearMap1, clearMap2, tracker[i].raycastJob)); + Profiler.EndSample(); + + Profiler.BeginSample("VehicleOcclusion-LaunchJobs.SingleRaycastJobSetup.ProcessorJob"); + tracker[i].processorJob = new RaycastProcessorJob + { + hits = hits[i], + hitMap = hitsMaps[i], + hitsOut = hitSizeMaps[i].AsParallelWriter(), + area = tracker[i].area, + areaSum = summedHitAreas[i], + }.Schedule(hitsMaps[i], 16, tracker[i].preparerJob); + Profiler.EndSample(); + + JobHandle.ScheduleBatchedJobs(); + Profiler.EndSample(); + i++; + + } + return i; + } + + + private void LaunchJobs(Vessel v, DirectionPreprocessInfo[] dirInfos, List dirs, List sdiArrays, int suggestedJobs = 1) + { + Profiler.BeginSample("VehicleOcclusion-LaunchJobs"); + + float offset = extents.magnitude * 2; + float4 tmp = math.mul(v.transform.localToWorldMatrix, new float4(center.x, center.y, center.z, 1)); + float3 startPosition = new float3(tmp.x, tmp.y, tmp.z); + + Profiler.BeginSample("VehicleOcclusion-LaunchJobs.FilterJob_Setup"); + + BuildPreprocessInfo(dirInfos, dirs); + + for (int i=0; i< dirs.Count; i++) + LaunchAngleJobs(ref dirInfos[i], Quaternions); + for (int i = 0; i < dirs.Count; i++) + dirInfos[i].sortJob.Complete(); + + using NativeList requiredQuaternions = new NativeList(sdiArrays.Count * dirs.Count, Allocator.Temp); + + for (int i = 0; i < sdiArrays.Count; i++) + { + for (int j=0; j < dirs.Count; j++) + { + sdiArrays[j][i] = dirInfos[j].sortedSDIList[i]; + if (!processedQuaternionsMap.ContainsKey(dirInfos[j].sortedSDIList[i].q)) + requiredQuaternions.Add(dirInfos[j].sortedSDIList[i].q); + + } + } + + jobsInProgress = 0; + + Profiler.EndSample(); + // Build raycast jobs only if we are processing and require or will accept additional work + if (state == State.Running && (requiredQuaternions.Length > 0 || suggestedJobs > 0)) + { + jobsInProgress = BuildAndLaunchRaycastJobs( + Vessel, + dirInfos, + raycastJobTracker, + Quaternions, + processedQuaternionsMap, + indexedPriorityMap, + suggestedJobs, + startPosition, + offset, + allCasts, + allHits, + allHitsMaps, + allHitSizeMaps, + allSummedHitAreas); + } + + for (int i=0; i< dirs.Count; i++) + { + dirInfos[i].DisposeAll(); + } + Profiler.EndSample(); + } + + // On demand, return the unoccluded area of Part p in + private float AreaOnDemand(Part p, Vector3 dir, bool worldSpace = false) + { + float area = 0; + if (p && p.vessel == Vessel) + { + if (worldSpace) + dir = Vessel.transform.worldToLocalMatrix * dir; + + float offset = extents.magnitude * 2; + float4 tmp = math.mul(p.vessel.transform.localToWorldMatrix, new float4(center.x, center.y, center.z, 1)); + float3 startPosition = new float3(tmp.x, tmp.y, tmp.z); + + var infos = new DirectionPreprocessInfo[1]; + BuildPreprocessInfo(infos, new List(1) { dir.normalized }); + LaunchAngleJobs(ref infos[0], Quaternions); + infos[0].sortJob.Complete(); + + NativeList requiredQuaternions = new NativeList(3, Allocator.Temp); + + for (int i=0; i<3; i++) + { + if (!processedQuaternionsMap.ContainsKey(infos[0].sortedSDIList[i].q)) + requiredQuaternions.Add(infos[0].sortedSDIList[i].q); + } + // Raycast if necessary + if (requiredQuaternions.Length > 0) + { + using var requiredArr = new NativeArray(requiredQuaternions, Allocator.Temp); + var tracker = new RaycastJobInfo[3]; + + var casts = new NativeArray[3]; + var hits = new NativeArray[3]; + var hitsMaps = new NativeMultiHashMap[3]; + var summedHitAreas = new NativeArray[3]; + var hitSizeMaps = new NativeHashMap[3]; + using var emptyPriMap = new NativeMultiHashMap(1, Allocator.TempJob); + + jobsInProgress = BuildAndLaunchRaycastJobs( + p.vessel, + infos, + tracker, + requiredArr, + processedQuaternionsMap, + emptyPriMap, + OcclusionSettings.MaxJobs, + startPosition, + offset, + casts, + hits, + hitsMaps, + hitSizeMaps, + summedHitAreas); + + int i = 0; + foreach (quaternion q in requiredQuaternions) + { + casts[i].Dispose(); + hits[i].Dispose(); + hitsMaps[i].Dispose(); + summedHitAreas[i].Dispose(); + hitSizeMaps[i].Dispose(); + i++; + } + } + + // Raycasts are complete, we have saved the angle data. + if (partOcclusionInfo.TryGetValue(p, out DirectionalOcclusionInfo info)) + area = Area(p, convectionPoints, info.convectionArea); + + infos[0].DisposeAll(); + requiredQuaternions.Dispose(); + } + return area; + } + + public struct RaycastJobInfo + { + public quaternion q; + public int index; + public float area; + public JobHandle builderJob; + public JobHandle raycastJob; + public JobHandle preparerJob; + public JobHandle processorJob; + } + + public struct DirectionPreprocessInfo + { + public float3 dir; + public NativeArray angles; + public NativeArray angleStats; + public NativeList sortedSDIList; + public NativeList orderedQuaternions; + public NativeArray distanceCutoff; + public float3 weights; + public JobHandle sortJob; + + public void DisposeAll() + { + angles.Dispose(); + angleStats.Dispose(); + sortedSDIList.Dispose(); + orderedQuaternions.Dispose(); + distanceCutoff.Dispose(); + } + } + + private void SelectQuaternions(in NativeList q, in NativeMultiHashMap map, int maxSize, int key=0) + { + if (q.Length < maxSize && map.TryGetFirstValue(key, out int index, out NativeMultiHashMapIterator iter)) + { + q.Add(Quaternions[index]); + while (q.Length< maxSize && map.TryGetNextValue(out index, ref iter)) + { + q.Add(Quaternions[index]); + } + } + } + + public void ProcessRaycastResults(ref RaycastJobInfo jobInfo, in NativeHashMap sizeMap, in NativeArray hits, in NativeArray summedHitAreas) + { + Profiler.BeginSample("VehicleOcclusion-ProcessRaycastResults"); + quaternion rotation = jobInfo.q; + processedQuaternionsMap.TryAdd(rotation, new EMPTY_STRUCT { }); + if (sizeMap.Length > 0) + { + // The value in sizeMap is the size of a single element [duplicative of jobInfo.area] + // The key is the index into summedHitAreas + NativeArray sizeIndices = sizeMap.GetKeyArray(Allocator.Temp); + for (int key = 0; key < sizeIndices.Length; key++) + { + int index = sizeIndices[key]; + float size = summedHitAreas[index]; + if (hits[index].transform is Transform t) + { + while (t.parent != null) + t = t.parent; + if (partsByTransform.TryGetValue(t, out Part p)) + { + if (!partOcclusionInfo.TryGetValue(p, out DirectionalOcclusionInfo occlInfo)) + { + occlInfo = new DirectionalOcclusionInfo(); + partOcclusionInfo.Add(p, occlInfo); + } + if (!occlInfo.convectionArea.ContainsKey(rotation)) + { + occlInfo.convectionArea.Add(rotation, 0); + } + occlInfo.convectionArea[rotation] += size; + } + else if (t.name.Equals("localspace") || (t.gameObject.GetComponent() is Part part && Vessel != part.vessel)) + { + } + else + { + Debug.LogWarning($"[VehicleOcclusion.ProcessRaycastResults] {Vessel?.name}: {hits[index].transform} ancestor {t} not associated with any part!"); + } + } + } + sizeIndices.Dispose(); + } + Profiler.EndSample(); + } + + private void SetupDefaultDirs(List dirs, Vessel v) + { + dirs.Clear(); + Vector3 localVelocity = v.velocityD.magnitude < OcclusionSettings.VelocityThreshold ? + Vector3.forward : + (Vector3)(v.transform.worldToLocalMatrix * (Vector3)v.velocityD); + Vector3 localSunVec = v.transform.worldToLocalMatrix * (Planetarium.fetch.Sun.transform.position - v.transform.position); + Vector3 bodyVec = v.transform.worldToLocalMatrix * (Vector3)(Vessel.mainBody.position - v.transform.position); + dirs.Add(localVelocity.normalized); + dirs.Add(localSunVec.normalized); + dirs.Add(bodyVec.normalized); + } + + public void FixedUpdateEarly() + { + if (!OnValidPhysicsVessel) + return; + + // We must call this to pre-calculate the nearest quaternions for sun and convection. + // It may return an empty work queue if we are not otherwise running, which is fine. + if (state == State.Initialized) + state = State.Running; + if (state == State.Running || state == State.Completed) + { + SetupDefaultDirs(directionList, Vessel); + LaunchJobs(Vessel, directionPreprocessInfos, directionList, occlusionPointsList, 0); + if (!PassStarted) + { + PassStarted = true; + JobsInCurrentPass = 0; + } + JobsInCurrentPass += jobsInProgress; + } + } + + public void FixedUpdate() + { + PassStarted = false; + if (!OnValidPhysicsVessel) + return; + if (state == State.Running) + HandleJobCompletion(raycastJobTracker, FixedUpdateMetric); + } + + public void UpdateEarly() + { + if (!OnValidPhysicsVessel) + return; + if (state == State.Running) + { + int threadCount = System.Environment.ProcessorCount - 1; + int availableJobs = math.max(OcclusionSettings.MaxJobs - JobsInCurrentPass, 0); + int updateJobs = math.min(availableJobs, math.max(1, Settings.OcclusionSettings.JobsPerThread * threadCount)); + SetupDefaultDirs(directionList, Vessel); + LaunchJobs(Vessel, directionPreprocessInfos, directionList, occlusionPointsList, updateJobs); + if (!PassStarted) + { + PassStarted = true; + JobsInCurrentPass = 0; + } + JobsInCurrentPass += jobsInProgress; + } + } + + public void LateUpdateComplete() + { + PassStarted = false; + if (!OnValidPhysicsVessel) + return; + if (state == State.Running && jobsInProgress == 0 && processedQuaternionsMap.Length == Quaternions.Length) + state = State.Completed; + else if (state == State.Running) + HandleJobCompletion(raycastJobTracker, UpdateMetric); + else if (state == State.Completed) + { + if (!resetCoroutineRunning) + StartCoroutine(resetWaitCoroutine = WaitForResetCR(OcclusionSettings.ResetInterval)); + } + if (RequestReset) + ResetCalculations(); + } + + IEnumerator WaitForResetCR(float interval) + { + resetCoroutineRunning = true; + yield return new WaitForSeconds(interval); + resetCoroutineRunning = false; + ResetCalculations(); + } + + public void HandleJobCompletion(RaycastJobInfo[] tracker, string metric) + { + JobCompleteWatch.Reset(); + for (int i=0; i 0.36f; + + public float SunArea(Part p, Vector3 dir) + { + if (partOcclusionInfo.TryGetValue(p, out DirectionalOcclusionInfo info)) + return Area(p, sunPoints, info.convectionArea); + return 0; + } + public float BodyArea(Part p, Vector3 dir) + { + if (partOcclusionInfo.TryGetValue(p, out DirectionalOcclusionInfo info)) + return Area(p, bodyPoints, info.convectionArea); + return 0; + } + + int counter = 0; + public float ConvectionArea(Part p, Vector3 dir) + { + // convectionPoints is a set of 3 quaternions that should be closest to dir. + // (They were precalculated, if dir is NOT what we expect for occlusion... that's bad.) + Vector3 localVelocity = dir.magnitude < OcclusionSettings.VelocityThreshold ? + Vector3.forward : + (Vector3) (Vessel.transform.worldToLocalMatrix * dir); + Quaternion q = Quaternion.FromToRotation(Vector3.forward, localVelocity); + float a = 0.25f; + + if (partOcclusionInfo.TryGetValue(p, out DirectionalOcclusionInfo info)) + { + float angle = Quaternion.Angle(q, convectionPoints[0].q); + averageMissOnBestAngle = (a * angle) + ((1f - a) * averageMissOnBestAngle); + if (counter++ % 500 == 0) + Debug.Log($"[VehicleOcclusion] {localVelocity} missed {angle} [average {averageMissOnBestAngle}]"); + return Area(p, convectionPoints, info.convectionArea); + } + return 0; + } + + public float Area(Part p, SphereDistanceInfo[] sdiArray, Dictionary areaInfos) + { + float area = 0; + float distanceSum = 0; + foreach (SphereDistanceInfo sdi in sdiArray) + { + if (areaInfos.TryGetValue(sdi.q, out float newArea)) + { + if (sdi.distance < float.Epsilon) + return newArea; + area += newArea / sdi.distance; + distanceSum += (1 / sdi.distance); + } + else if (processedQuaternionsMap.ContainsKey(sdi.q)) + { + // Processed quaternion but no per-part data means 0 area [no raycasters hit] + distanceSum += (1 / sdi.distance); + } + else + { + Debug.LogWarning($"[VehicleOcclusion.Area] {Vessel?.name} Quaternion {sdi.q} was in top-3 but had not been processed!"); + } + } + return area / distanceSum; + } + + private class DirectionalOcclusionInfo + { + public Dictionary convectionArea; + public Dictionary area; + + public DirectionalOcclusionInfo() + { + convectionArea = new Dictionary(); + area = new Dictionary(); + } + } + } +} diff --git a/FerramAerospaceResearch/FARAeroComponents/VesselIntakeRamDrag.cs b/FerramAerospaceResearch/FARAeroComponents/VesselIntakeRamDrag.cs index b1b58a76d..74326c7fc 100644 --- a/FerramAerospaceResearch/FARAeroComponents/VesselIntakeRamDrag.cs +++ b/FerramAerospaceResearch/FARAeroComponents/VesselIntakeRamDrag.cs @@ -1,5 +1,5 @@ -/* -Ferram Aerospace Research v0.16.0.0 "Mader" +/* +Ferram Aerospace Research v0.16.0.2 "Mader" ========================= Aerodynamics model for Kerbal Space Program diff --git a/FerramAerospaceResearch/FARAeroUtil.cs b/FerramAerospaceResearch/FARAeroUtil.cs index ab6b037a8..a0050d00f 100644 --- a/FerramAerospaceResearch/FARAeroUtil.cs +++ b/FerramAerospaceResearch/FARAeroUtil.cs @@ -1,5 +1,5 @@ -/* -Ferram Aerospace Research v0.16.0.0 "Mader" +/* +Ferram Aerospace Research v0.16.0.2 "Mader" ========================= Aerodynamics model for Kerbal Space Program @@ -105,6 +105,17 @@ public static CelestialBody CurrentBody } } + public static double CurrentAdiabaticIndex + { + get + { + Vessel vessel = FlightGlobals.ActiveVessel; + return FARAtmosphere.GetAdiabaticIndex(CurrentBody, + new Vector3d(vessel.latitude, vessel.longitude, vessel.altitude), + Planetarium.GetUniversalTime()); + } + } + public static FloatCurve PrandtlMeyerMach { get @@ -115,7 +126,7 @@ public static FloatCurve PrandtlMeyerMach prandtlMeyerMach = new FloatCurve(); prandtlMeyerAngle = new FloatCurve(); double M = 1; - double gamma = CurrentBody.atmosphereAdiabaticIndex; + double gamma = CurrentAdiabaticIndex; double gamma_ = Math.Sqrt((gamma + 1) / (gamma - 1)); @@ -141,14 +152,13 @@ public static FloatCurve PrandtlMeyerMach prandtlMeyerAngle.Add((float)nu, (float)M, (float)nu_mach, (float)nu_mach); - if (M < 3) - M += 0.1f; - else if (M < 10) - M += 0.5f; - else if (M < 25) - M += 2; - else - M += 25; + M += M switch + { + < 3 => 0.1f, + < 10 => 0.5f, + < 25 => 2, + _ => 25 + }; } maxPrandtlMeyerTurnAngle = gamma_ - 1; @@ -167,7 +177,7 @@ public static FloatCurve PrandtlMeyerAngle prandtlMeyerMach = new FloatCurve(); prandtlMeyerAngle = new FloatCurve(); double M = 1; - double gamma = CurrentBody.atmosphereAdiabaticIndex; + double gamma = CurrentAdiabaticIndex; double gamma_ = Math.Sqrt((gamma + 1) / (gamma - 1)); while (M < 250) @@ -192,14 +202,13 @@ public static FloatCurve PrandtlMeyerAngle prandtlMeyerAngle.Add((float)nu, (float)M, (float)nu_mach, (float)nu_mach); - if (M < 3) - M += 0.1; - else if (M < 10) - M += 0.5; - else if (M < 25) - M += 2; - else - M += 25; + M += M switch + { + < 3 => 0.1, + < 10 => 0.5, + < 25 => 2, + _ => 25 + }; } maxPrandtlMeyerTurnAngle = gamma_ - 1; @@ -279,7 +288,7 @@ private static void SetDefaultValuesIfNoValuesLoaded() // ReSharper disable once UnusedMember.Global public static double MaxPressureCoefficientCalc(double M) { - double gamma = CurrentBody.atmosphereAdiabaticIndex; + double gamma = CurrentAdiabaticIndex; if (M <= 0) return 1; @@ -293,7 +302,7 @@ public static double MaxPressureCoefficientCalc(double M) public static double StagnationPressureCalc(double M) { - double gamma = CurrentBody.atmosphereAdiabaticIndex; + double gamma = CurrentAdiabaticIndex; double ratio = M * M; ratio *= gamma - 1; @@ -309,7 +318,7 @@ public static double RayleighPitotTubeStagPressure(double M) if (M <= 1) return StagnationPressureCalc(M); - double gamma = CurrentBody.atmosphereAdiabaticIndex; + double gamma = CurrentAdiabaticIndex; //Rayleigh Pitot Tube Formula; gives max stagnation pressure behind shock double value = (gamma + 1) * M; value *= value; @@ -324,7 +333,7 @@ public static double RayleighPitotTubeStagPressure(double M) public static double PressureBehindShockCalc(double M) { - double gamma = CurrentBody.atmosphereAdiabaticIndex; + double gamma = CurrentAdiabaticIndex; double ratio = M * M; ratio *= 2 * gamma; @@ -336,7 +345,7 @@ public static double PressureBehindShockCalc(double M) public static double MachBehindShockCalc(double M) { - double gamma = CurrentBody.atmosphereAdiabaticIndex; + double gamma = CurrentAdiabaticIndex; double ratio = gamma - 1; ratio *= M * M; diff --git a/FerramAerospaceResearch/FARAtmosphere.cs b/FerramAerospaceResearch/FARAtmosphere.cs new file mode 100644 index 000000000..80244a552 --- /dev/null +++ b/FerramAerospaceResearch/FARAtmosphere.cs @@ -0,0 +1,365 @@ +/* +Ferram Aerospace Research v0.16.0.2 "Mader" +========================= +Aerodynamics model for Kerbal Space Program + +Copyright 2020, Michael Ferrara, aka Ferram4 + + This file is part of Ferram Aerospace Research. + + Ferram Aerospace Research is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + Ferram Aerospace Research is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with Ferram Aerospace Research. If not, see . + + Serious thanks: a.g., for tons of bugfixes and code-refactorings + stupid_chris, for the RealChuteLite implementation + Taverius, for correcting a ton of incorrect values + Tetryds, for finding lots of bugs and issues and not letting me get away with them, and work on example crafts + sarbian, for refactoring code for working with MechJeb, and the Module Manager updates + ialdabaoth (who is awesome), who originally created Module Manager + Regex, for adding RPM support + DaMichel, for some ferramGraph updates and some control surface-related features + Duxwing, for copy editing the readme + + CompatibilityChecker by Majiir, BSD 2-clause http://opensource.org/licenses/BSD-2-Clause + + Part.cfg changes powered by sarbian & ialdabaoth's ModuleManager plugin; used with permission + http://forum.kerbalspaceprogram.com/threads/55219 + + ModularFLightIntegrator by Sarbian, Starwaster and Ferram4, MIT: http://opensource.org/licenses/MIT + http://forum.kerbalspaceprogram.com/threads/118088 + + Toolbar integration powered by blizzy78's Toolbar plugin; used with permission + http://forum.kerbalspaceprogram.com/threads/60863 + */ + +using System; +using System.Reflection; +using UnityEngine; + +namespace FerramAerospaceResearch +{ + public static partial class FARAtmosphere + { + internal class DelegateDispatcher + { + private Func function; + + public DelegateDispatcher(Func function, string name) + { + this.function = function; + Default = function; + Name = name; + } + + public Func Function + { + get { return function; } + set + { + // if passed null, reset back to default so that function is never null + if (value is null) + { + FARLogger.InfoFormat("FARAtmosphere.{0}: attempted to set null function, using default {1}", + Name, + Default.Method.Name); + function = Default; + } + else + { + MethodInfo method = value.Method; + FARLogger.InfoFormat("FARAtmosphere.{0}: setting function to {1}.{2} from {3}", + Name, + method.DeclaringType?.Name ?? "(global)", + method.Name, + method.Module.Name); + function = value; + } + } + } + + public readonly Func Default; + public readonly string Name; + + public Ret Invoke(Arg1 arg1, Arg2 arg2, Arg3 arg3) + { + // swallow all exceptions so that simulation can still progress + try + { + return function(arg1, arg2, arg3); + } + catch (Exception e) + { + FARLogger.InfoFormat("FARAtmosphere.{0}: exception {1}\n{2}", Name, e.Message, e.StackTrace); + return Default(arg1, arg2, arg3); + } + } + } + } + + public readonly struct GasProperties + { + public readonly double Pressure; + public readonly double Temperature; + public readonly double Density; + public readonly double AdiabaticIndex; + public readonly double GasConstant; + + public double SpeedOfSound + { + get { return Math.Sqrt(AdiabaticIndex * GasConstant * Temperature); } + } + + public GasProperties(double pressure, double temperature, double adiabaticIndex, double gasConstant) + { + Pressure = pressure; + Temperature = temperature; + Density = Pressure / (gasConstant * Temperature); + AdiabaticIndex = adiabaticIndex; + GasConstant = gasConstant; + } + } +} + +// break namespace so that type aliases can be declared +namespace FerramAerospaceResearch +{ + // delegate aliases to avoid writing them all out, use System.Func<> instead of specific delegates for easier usage + // with reflection + using WindDelegate = Func; + using WindDispatcher = FARAtmosphere.DelegateDispatcher; + using PropertyDelegate = Func; + using PropertyDispatcher = FARAtmosphere.DelegateDispatcher; + + /// + /// Entry point where another assembly can specify a function to calculate the wind and atmospheric properties. + /// The rest of the simulation uses this class to get the wind and includes it in the + /// total airspeed for the simulation. + /// + public static partial class FARAtmosphere + { + /// + /// Wind function + /// + private static readonly WindDispatcher windFunction = new((body, part, pos) => Vector3.zero, "Wind"); + + /// + /// Simulation pressure function + /// + private static readonly PropertyDispatcher pressureFunction = + new(((body, latLonAltitude, ut) => body.GetPressure(latLonAltitude.z)), "Pressure"); + + /// + /// Simulation temperature function + /// + private static readonly PropertyDispatcher temperatureFunction = + new(((body, latLonAltitude, ut) => body.GetTemperature(latLonAltitude.z)), "Temperature"); + + /// + /// Simulation adiabatic index function + /// + private static readonly PropertyDispatcher adiabaticIndexFunction = + new(((body, latLonAltitude, ut) => body.atmosphereAdiabaticIndex), "AdiabaticIndex"); + + /// + /// Simulation gas constant function + /// + private static readonly PropertyDispatcher gasConstantFunction = + new(((body, latLonAltitude, ut) => PhysicsGlobals.IdealGasConstant / body.atmosphereMolarMass), + "GasConstant"); + + /// + /// Calculates the wind's intensity using the specified wind function. + /// If any exception occurs, it is suppressed and Vector3.zero is returned. + /// This function will never throw, (although it will spam the log). + /// + /// Current celestial body + /// Current part + /// Position of the part + /// Wind as a Vector3 (unit is m/s) + public static Vector3 GetWind(CelestialBody body, Part part, Vector3 position) + { + return windFunction.Invoke(body, part, position); + } + + // ReSharper disable once UnusedMember.Global + /// + /// "Set" method for the wind function. + /// + /// See for parameter meanings + public static void SetWindFunction(WindDelegate newFunction) + { + windFunction.Function = newFunction; + } + + /// + /// Calculates pressure at the specified universal time. + /// + /// Body to evaluate properties at + /// Latitude, longitude and altitude + /// Universal time + /// Pressure in Pa + public static double GetPressure(CelestialBody body, Vector3d latLonAltitude, double ut) + { + return pressureFunction.Invoke(body, latLonAltitude, ut); + } + + public static double GetPressure(Vessel vessel, double ut) + { + return GetPressure(vessel.mainBody, new Vector3d(vessel.latitude, vessel.longitude, vessel.altitude), ut); + } + + public static double GetPressure(Vessel vessel) + { + return GetPressure(vessel, Planetarium.GetUniversalTime()); + } + + // ReSharper disable once UnusedMember.Global + /// + /// "Set" method for the simulated pressure function. + /// + /// See for parameter meanings + public static void SetPressureFunction(PropertyDelegate newFunction) + { + pressureFunction.Function = newFunction; + } + + /// + /// Calculates temperature at the specified universal time. + /// + /// Body to evaluate properties at + /// Latitude, longitude and altitude + /// Universal time + /// Temperature in K + public static double GetTemperature(CelestialBody body, Vector3d latLonAltitude, double ut) + { + return temperatureFunction.Invoke(body, latLonAltitude, ut); + } + + public static double GetTemperature(Vessel vessel, double ut) + { + return GetTemperature(vessel.mainBody, + new Vector3d(vessel.latitude, vessel.longitude, vessel.altitude), + ut); + } + + public static double GetTemperature(Vessel vessel) + { + return GetTemperature(vessel, Planetarium.GetUniversalTime()); + } + + // ReSharper disable once UnusedMember.Global + /// + /// "Set" method for the simulated temperature function. + /// + /// See for parameter meanings + public static void SetTemperatureFunction(PropertyDelegate newFunction) + { + temperatureFunction.Function = newFunction; + } + + /// + /// Calculates adiabatic index at the specified universal time. + /// + /// Body to evaluate properties at + /// Latitude, longitude and altitude + /// Universal time + /// Adiabatic index + public static double GetAdiabaticIndex(CelestialBody body, Vector3d latLonAltitude, double ut) + { + return adiabaticIndexFunction.Invoke(body, latLonAltitude, ut); + } + + public static double GetAdiabaticIndex(Vessel vessel, double ut) + { + return GetAdiabaticIndex(vessel.mainBody, + new Vector3d(vessel.latitude, vessel.longitude, vessel.altitude), + ut); + } + + public static double GetAdiabaticIndex(Vessel vessel) + { + return GetAdiabaticIndex(vessel, Planetarium.GetUniversalTime()); + } + + // ReSharper disable once UnusedMember.Global + /// + /// "Set" method for the simulated adiabatic index function. + /// + /// See for parameter meanings + public static void SetAdiabaticIndexFunction(PropertyDelegate newFunction) + { + adiabaticIndexFunction.Function = newFunction; + } + + /// + /// Calculates gas constant at the specified universal time. + /// + /// Body to evaluate properties at + /// Latitude, longitude and altitude + /// Universal time + /// Gas constant in J/kg/K + public static double GetGasConstant(CelestialBody body, Vector3d latLonAltitude, double ut) + { + return gasConstantFunction.Invoke(body, latLonAltitude, ut); + } + + public static double GetGasConstant(Vessel vessel, double ut) + { + return GetGasConstant(vessel.mainBody, + new Vector3d(vessel.latitude, vessel.longitude, vessel.altitude), + ut); + } + + public static double GetGasConstant(Vessel vessel) + { + return GetGasConstant(vessel, Planetarium.GetUniversalTime()); + } + + // ReSharper disable once UnusedMember.Global + /// + /// "Set" method for the simulated gas constant function. + /// + /// See for parameter meanings + public static void SetGasConstantFunction(PropertyDelegate newFunction) + { + gasConstantFunction.Function = newFunction; + } + + /// + /// Calculates static gas properties at the specified universal time. + /// + /// Body to evaluate properties at + /// Latitude, longitude and altitude + /// Universal time + /// Static gas properties + public static GasProperties GetGasProperties(CelestialBody body, Vector3d latLonAltitude, double ut) + { + return new(pressure: GetPressure(body, latLonAltitude, ut), + temperature: GetTemperature(body, latLonAltitude, ut), + adiabaticIndex: GetAdiabaticIndex(body, latLonAltitude, ut), + gasConstant: GetGasConstant(body, latLonAltitude, ut)); + } + + public static GasProperties GetGasProperties(Vessel vessel, double ut) + { + return GetGasProperties(vessel.mainBody, + new Vector3d(vessel.latitude, vessel.longitude, vessel.altitude), + ut); + } + + public static GasProperties GetGasProperties(Vessel vessel) + { + return GetGasProperties(vessel, Planetarium.GetUniversalTime()); + } + } +} diff --git a/FerramAerospaceResearch/FARDebugAndSettings.cs b/FerramAerospaceResearch/FARDebugAndSettings.cs index 8cf50ff08..435353617 100644 --- a/FerramAerospaceResearch/FARDebugAndSettings.cs +++ b/FerramAerospaceResearch/FARDebugAndSettings.cs @@ -1,5 +1,5 @@ -/* -Ferram Aerospace Research v0.16.0.0 "Mader" +/* +Ferram Aerospace Research v0.16.0.2 "Mader" ========================= Aerodynamics model for Kerbal Space Program diff --git a/FerramAerospaceResearch/FARFloatCurve.cs b/FerramAerospaceResearch/FARFloatCurve.cs index 02d23971a..7c29f08c4 100644 --- a/FerramAerospaceResearch/FARFloatCurve.cs +++ b/FerramAerospaceResearch/FARFloatCurve.cs @@ -1,4 +1,4 @@ -using System; +using System; namespace FerramAerospaceResearch { diff --git a/FerramAerospaceResearch/FARGUI/FAREditorGUI/DesignConcerns/AeroStabilityConcern.cs b/FerramAerospaceResearch/FARGUI/FAREditorGUI/DesignConcerns/AeroStabilityConcern.cs index 41a901c27..4bdf73921 100644 --- a/FerramAerospaceResearch/FARGUI/FAREditorGUI/DesignConcerns/AeroStabilityConcern.cs +++ b/FerramAerospaceResearch/FARGUI/FAREditorGUI/DesignConcerns/AeroStabilityConcern.cs @@ -1,5 +1,5 @@ -/* -Ferram Aerospace Research v0.16.0.0 "Mader" +/* +Ferram Aerospace Research v0.16.0.2 "Mader" ========================= Aerodynamics model for Kerbal Space Program diff --git a/FerramAerospaceResearch/FARGUI/FAREditorGUI/DesignConcerns/AreaRulingConcern.cs b/FerramAerospaceResearch/FARGUI/FAREditorGUI/DesignConcerns/AreaRulingConcern.cs index 849bd8b98..d86516d49 100644 --- a/FerramAerospaceResearch/FARGUI/FAREditorGUI/DesignConcerns/AreaRulingConcern.cs +++ b/FerramAerospaceResearch/FARGUI/FAREditorGUI/DesignConcerns/AreaRulingConcern.cs @@ -1,5 +1,5 @@ -/* -Ferram Aerospace Research v0.16.0.0 "Mader" +/* +Ferram Aerospace Research v0.16.0.2 "Mader" ========================= Aerodynamics model for Kerbal Space Program diff --git a/FerramAerospaceResearch/FARGUI/FAREditorGUI/EditorAeroCenter.cs b/FerramAerospaceResearch/FARGUI/FAREditorGUI/EditorAeroCenter.cs index ff5a5e3b6..4c2550d9d 100644 --- a/FerramAerospaceResearch/FARGUI/FAREditorGUI/EditorAeroCenter.cs +++ b/FerramAerospaceResearch/FARGUI/FAREditorGUI/EditorAeroCenter.cs @@ -1,5 +1,5 @@ -/* -Ferram Aerospace Research v0.16.0.0 "Mader" +/* +Ferram Aerospace Research v0.16.0.2 "Mader" ========================= Aerodynamics model for Kerbal Space Program diff --git a/FerramAerospaceResearch/FARGUI/FAREditorGUI/EditorAreaRulingOverlay.cs b/FerramAerospaceResearch/FARGUI/FAREditorGUI/EditorAreaRulingOverlay.cs index 7b7b81c4b..252085bcd 100644 --- a/FerramAerospaceResearch/FARGUI/FAREditorGUI/EditorAreaRulingOverlay.cs +++ b/FerramAerospaceResearch/FARGUI/FAREditorGUI/EditorAreaRulingOverlay.cs @@ -1,5 +1,5 @@ -/* -Ferram Aerospace Research v0.16.0.0 "Mader" +/* +Ferram Aerospace Research v0.16.0.2 "Mader" ========================= Aerodynamics model for Kerbal Space Program diff --git a/FerramAerospaceResearch/FARGUI/FAREditorGUI/EditorGUI.cs b/FerramAerospaceResearch/FARGUI/FAREditorGUI/EditorGUI.cs index a83ab3da8..7ff387d5b 100644 --- a/FerramAerospaceResearch/FARGUI/FAREditorGUI/EditorGUI.cs +++ b/FerramAerospaceResearch/FARGUI/FAREditorGUI/EditorGUI.cs @@ -1,5 +1,5 @@ -/* -Ferram Aerospace Research v0.16.0.0 "Mader" +/* +Ferram Aerospace Research v0.16.0.2 "Mader" ========================= Aerodynamics model for Kerbal Space Program diff --git a/FerramAerospaceResearch/FARGUI/FAREditorGUI/Simulation/EditorSimManager.cs b/FerramAerospaceResearch/FARGUI/FAREditorGUI/Simulation/EditorSimManager.cs index 977a2af75..93c6b0c5a 100644 --- a/FerramAerospaceResearch/FARGUI/FAREditorGUI/Simulation/EditorSimManager.cs +++ b/FerramAerospaceResearch/FARGUI/FAREditorGUI/Simulation/EditorSimManager.cs @@ -1,5 +1,5 @@ -/* -Ferram Aerospace Research v0.16.0.0 "Mader" +/* +Ferram Aerospace Research v0.16.0.2 "Mader" ========================= Aerodynamics model for Kerbal Space Program diff --git a/FerramAerospaceResearch/FARGUI/FAREditorGUI/Simulation/EquationSystem.cs b/FerramAerospaceResearch/FARGUI/FAREditorGUI/Simulation/EquationSystem.cs index 682a6a2b7..a617ef903 100644 --- a/FerramAerospaceResearch/FARGUI/FAREditorGUI/Simulation/EquationSystem.cs +++ b/FerramAerospaceResearch/FARGUI/FAREditorGUI/Simulation/EquationSystem.cs @@ -1,5 +1,5 @@ -/* -Ferram Aerospace Research v0.16.0.0 "Mader" +/* +Ferram Aerospace Research v0.16.0.2 "Mader" ========================= Aerodynamics model for Kerbal Space Program diff --git a/FerramAerospaceResearch/FARGUI/FAREditorGUI/Simulation/GraphData.cs b/FerramAerospaceResearch/FARGUI/FAREditorGUI/Simulation/GraphData.cs index 704905f29..ac16afbae 100644 --- a/FerramAerospaceResearch/FARGUI/FAREditorGUI/Simulation/GraphData.cs +++ b/FerramAerospaceResearch/FARGUI/FAREditorGUI/Simulation/GraphData.cs @@ -1,5 +1,5 @@ -/* -Ferram Aerospace Research v0.16.0.0 "Mader" +/* +Ferram Aerospace Research v0.16.0.2 "Mader" ========================= Aerodynamics model for Kerbal Space Program diff --git a/FerramAerospaceResearch/FARGUI/FAREditorGUI/Simulation/InstantConditionSim.cs b/FerramAerospaceResearch/FARGUI/FAREditorGUI/Simulation/InstantConditionSim.cs index ecf84f338..5a4e954ee 100644 --- a/FerramAerospaceResearch/FARGUI/FAREditorGUI/Simulation/InstantConditionSim.cs +++ b/FerramAerospaceResearch/FARGUI/FAREditorGUI/Simulation/InstantConditionSim.cs @@ -1,5 +1,5 @@ -/* -Ferram Aerospace Research v0.16.0.0 "Mader" +/* +Ferram Aerospace Research v0.16.0.2 "Mader" ========================= Aerodynamics model for Kerbal Space Program diff --git a/FerramAerospaceResearch/FARGUI/FAREditorGUI/Simulation/InstantConditionSimInput.cs b/FerramAerospaceResearch/FARGUI/FAREditorGUI/Simulation/InstantConditionSimInput.cs index 6e1b70231..4e302a91b 100644 --- a/FerramAerospaceResearch/FARGUI/FAREditorGUI/Simulation/InstantConditionSimInput.cs +++ b/FerramAerospaceResearch/FARGUI/FAREditorGUI/Simulation/InstantConditionSimInput.cs @@ -1,5 +1,5 @@ -/* -Ferram Aerospace Research v0.16.0.0 "Mader" +/* +Ferram Aerospace Research v0.16.0.2 "Mader" ========================= Aerodynamics model for Kerbal Space Program diff --git a/FerramAerospaceResearch/FARGUI/FAREditorGUI/Simulation/InstantConditionSimOutput.cs b/FerramAerospaceResearch/FARGUI/FAREditorGUI/Simulation/InstantConditionSimOutput.cs index 2de88ed45..a2cc61534 100644 --- a/FerramAerospaceResearch/FARGUI/FAREditorGUI/Simulation/InstantConditionSimOutput.cs +++ b/FerramAerospaceResearch/FARGUI/FAREditorGUI/Simulation/InstantConditionSimOutput.cs @@ -1,5 +1,5 @@ -/* -Ferram Aerospace Research v0.16.0.0 "Mader" +/* +Ferram Aerospace Research v0.16.0.2 "Mader" ========================= Aerodynamics model for Kerbal Space Program diff --git a/FerramAerospaceResearch/FARGUI/FAREditorGUI/Simulation/RungeKutta.cs b/FerramAerospaceResearch/FARGUI/FAREditorGUI/Simulation/RungeKutta.cs index 660c72ecf..4fe38e0e2 100644 --- a/FerramAerospaceResearch/FARGUI/FAREditorGUI/Simulation/RungeKutta.cs +++ b/FerramAerospaceResearch/FARGUI/FAREditorGUI/Simulation/RungeKutta.cs @@ -1,4 +1,5 @@ -/*Ferram Aerospace Research v0.16.0.0 "Mader" +/* +Ferram Aerospace Research v0.16.0.2 "Mader" ========================= Aerodynamics model for Kerbal Space Program diff --git a/FerramAerospaceResearch/FARGUI/FAREditorGUI/Simulation/StabilityDerivApproxSim.cs b/FerramAerospaceResearch/FARGUI/FAREditorGUI/Simulation/StabilityDerivApproxSim.cs index 63886a9b1..18ab1191a 100644 --- a/FerramAerospaceResearch/FARGUI/FAREditorGUI/Simulation/StabilityDerivApproxSim.cs +++ b/FerramAerospaceResearch/FARGUI/FAREditorGUI/Simulation/StabilityDerivApproxSim.cs @@ -1,5 +1,5 @@ -/* -Ferram Aerospace Research v0.16.0.0 "Mader" +/* +Ferram Aerospace Research v0.16.0.2 "Mader" ========================= Aerodynamics model for Kerbal Space Program diff --git a/FerramAerospaceResearch/FARGUI/FAREditorGUI/Simulation/StabilityDerivCalculator.cs b/FerramAerospaceResearch/FARGUI/FAREditorGUI/Simulation/StabilityDerivCalculator.cs index 932d54fb1..803dca3ab 100644 --- a/FerramAerospaceResearch/FARGUI/FAREditorGUI/Simulation/StabilityDerivCalculator.cs +++ b/FerramAerospaceResearch/FARGUI/FAREditorGUI/Simulation/StabilityDerivCalculator.cs @@ -1,5 +1,5 @@ -/* -Ferram Aerospace Research v0.16.0.0 "Mader" +/* +Ferram Aerospace Research v0.16.0.2 "Mader" ========================= Aerodynamics model for Kerbal Space Program @@ -70,10 +70,14 @@ public StabilityDerivOutput CalculateStabilityDerivs( double phi ) { - double pressure = body.GetPressure(alt); - double temperature = body.GetTemperature(alt); - double density = body.GetDensity(pressure, temperature); - double sspeed = body.GetSpeedOfSound(pressure, density); + GasProperties properties = FARAtmosphere.GetGasProperties(body, + new Vector3d(0, 0, alt), + Planetarium.GetUniversalTime()); + + double pressure = properties.Pressure; + double temperature = properties.Temperature; + double density = properties.Density; + double sspeed = properties.SpeedOfSound; double u0 = sspeed * machNumber; double q = u0 * u0 * density * 0.5f; @@ -191,14 +195,16 @@ double phi 2 * (prncInertRot.x * prncInertRot.z - prncInertRot.y * prncInertRot.w)); var Row2 = new Vector3(2 * (prncInertRot.x * prncInertRot.y - prncInertRot.z * prncInertRot.w), - -prncInertRot.x * prncInertRot.x + prncInertRot.y * prncInertRot.y - + -prncInertRot.x * prncInertRot.x + + prncInertRot.y * prncInertRot.y - prncInertRot.z * prncInertRot.z + prncInertRot.w * prncInertRot.w, 2 * (prncInertRot.y * prncInertRot.z + prncInertRot.x * prncInertRot.w)); var Row3 = new Vector3(2 * (prncInertRot.x * prncInertRot.z + prncInertRot.y * prncInertRot.w), 2 * (prncInertRot.y * prncInertRot.z - prncInertRot.x * prncInertRot.w), - -prncInertRot.x * prncInertRot.x - prncInertRot.y * prncInertRot.y + + -prncInertRot.x * prncInertRot.x - + prncInertRot.y * prncInertRot.y + prncInertRot.z * prncInertRot.z + prncInertRot.w * prncInertRot.w); diff --git a/FerramAerospaceResearch/FARGUI/FAREditorGUI/Simulation/StabilityDerivOutput.cs b/FerramAerospaceResearch/FARGUI/FAREditorGUI/Simulation/StabilityDerivOutput.cs index 6eafc2ae5..3dda8c03b 100644 --- a/FerramAerospaceResearch/FARGUI/FAREditorGUI/Simulation/StabilityDerivOutput.cs +++ b/FerramAerospaceResearch/FARGUI/FAREditorGUI/Simulation/StabilityDerivOutput.cs @@ -1,5 +1,5 @@ -/* -Ferram Aerospace Research v0.16.0.0 "Mader" +/* +Ferram Aerospace Research v0.16.0.2 "Mader" ========================= Aerodynamics model for Kerbal Space Program diff --git a/FerramAerospaceResearch/FARGUI/FAREditorGUI/Simulation/SweepSim.cs b/FerramAerospaceResearch/FARGUI/FAREditorGUI/Simulation/SweepSim.cs index 120f2eb5a..e2a912d82 100644 --- a/FerramAerospaceResearch/FARGUI/FAREditorGUI/Simulation/SweepSim.cs +++ b/FerramAerospaceResearch/FARGUI/FAREditorGUI/Simulation/SweepSim.cs @@ -1,5 +1,5 @@ -/* -Ferram Aerospace Research v0.16.0.0 "Mader" +/* +Ferram Aerospace Research v0.16.0.2 "Mader" ========================= Aerodynamics model for Kerbal Space Program diff --git a/FerramAerospaceResearch/FARGUI/FAREditorGUI/StabilityDerivGUI.cs b/FerramAerospaceResearch/FARGUI/FAREditorGUI/StabilityDerivGUI.cs index 26143c7f9..8c07e2bb9 100644 --- a/FerramAerospaceResearch/FARGUI/FAREditorGUI/StabilityDerivGUI.cs +++ b/FerramAerospaceResearch/FARGUI/FAREditorGUI/StabilityDerivGUI.cs @@ -1,5 +1,5 @@ -/* -Ferram Aerospace Research v0.16.0.0 "Mader" +/* +Ferram Aerospace Research v0.16.0.2 "Mader" ========================= Aerodynamics model for Kerbal Space Program @@ -391,7 +391,7 @@ private void StabDerivCalcButtonAction() int flapsettingInt = _flapSettingDropdown.ActiveSelection; bool spoilersDeployedBool = spoilersDeployed; - if (body.GetPressure(altitudeDouble) > 0) + if (FARAtmosphere.GetPressure(body, new Vector3d(0, 0, altitudeDouble), Planetarium.GetUniversalTime()) > 0) { stabDerivOutput = simManager.StabDerivCalculator.CalculateStabilityDerivs(body, diff --git a/FerramAerospaceResearch/FARGUI/FAREditorGUI/StabilityDerivSimulationGUI.cs b/FerramAerospaceResearch/FARGUI/FAREditorGUI/StabilityDerivSimulationGUI.cs index 38b636962..6cc9e46bd 100644 --- a/FerramAerospaceResearch/FARGUI/FAREditorGUI/StabilityDerivSimulationGUI.cs +++ b/FerramAerospaceResearch/FARGUI/FAREditorGUI/StabilityDerivSimulationGUI.cs @@ -1,5 +1,5 @@ -/* -Ferram Aerospace Research v0.16.0.0 "Mader" +/* +Ferram Aerospace Research v0.16.0.2 "Mader" ========================= Aerodynamics model for Kerbal Space Program diff --git a/FerramAerospaceResearch/FARGUI/FAREditorGUI/StaticAnalysisGraphGUI.cs b/FerramAerospaceResearch/FARGUI/FAREditorGUI/StaticAnalysisGraphGUI.cs index 4a5a37400..984fd5b09 100644 --- a/FerramAerospaceResearch/FARGUI/FAREditorGUI/StaticAnalysisGraphGUI.cs +++ b/FerramAerospaceResearch/FARGUI/FAREditorGUI/StaticAnalysisGraphGUI.cs @@ -1,5 +1,5 @@ -/* -Ferram Aerospace Research v0.16.0.0 "Mader" +/* +Ferram Aerospace Research v0.16.0.2 "Mader" ========================= Aerodynamics model for Kerbal Space Program diff --git a/FerramAerospaceResearch/FARGUI/FARFlightGUI/AeroVisualizationGUI.cs b/FerramAerospaceResearch/FARGUI/FARFlightGUI/AeroVisualizationGUI.cs index 8e0478298..8ac87bc21 100644 --- a/FerramAerospaceResearch/FARGUI/FARFlightGUI/AeroVisualizationGUI.cs +++ b/FerramAerospaceResearch/FARGUI/FARFlightGUI/AeroVisualizationGUI.cs @@ -1,5 +1,5 @@ /* -Ferram Aerospace Research v0.16.0.0 "Mader" +Ferram Aerospace Research v0.16.0.2 "Mader" ========================= Aerodynamics model for Kerbal Space Program diff --git a/FerramAerospaceResearch/FARGUI/FARFlightGUI/AirspeedSettingsGUI.cs b/FerramAerospaceResearch/FARGUI/FARFlightGUI/AirspeedSettingsGUI.cs index d27dc3abc..11bbf2a8d 100644 --- a/FerramAerospaceResearch/FARGUI/FARFlightGUI/AirspeedSettingsGUI.cs +++ b/FerramAerospaceResearch/FARGUI/FARFlightGUI/AirspeedSettingsGUI.cs @@ -1,5 +1,5 @@ /* -Ferram Aerospace Research v0.16.0.0 "Mader" +Ferram Aerospace Research v0.16.0.2 "Mader" ========================= Aerodynamics model for Kerbal Space Program @@ -136,7 +136,7 @@ public double CalculateIAS() double pressureRatio = FARAeroUtil.RayleighPitotTubeStagPressure(_vessel.mach); double velocity = pressureRatio - 1; - velocity *= _vessel.staticPressurekPa * 1000 * 2; + velocity *= FARAtmosphere.GetPressure(_vessel) * 2; velocity /= 1.225; velocity = Math.Sqrt(velocity); diff --git a/FerramAerospaceResearch/FARGUI/FARFlightGUI/FlightDataGUI.cs b/FerramAerospaceResearch/FARGUI/FARFlightGUI/FlightDataGUI.cs index b8ba2d1e5..2669fb25c 100644 --- a/FerramAerospaceResearch/FARGUI/FARFlightGUI/FlightDataGUI.cs +++ b/FerramAerospaceResearch/FARGUI/FARFlightGUI/FlightDataGUI.cs @@ -1,5 +1,5 @@ -/* -Ferram Aerospace Research v0.16.0.0 "Mader" +/* +Ferram Aerospace Research v0.16.0.2 "Mader" ========================= Aerodynamics model for Kerbal Space Program diff --git a/FerramAerospaceResearch/FARGUI/FARFlightGUI/FlightDataLogger.cs b/FerramAerospaceResearch/FARGUI/FARFlightGUI/FlightDataLogger.cs index 23b389aa1..d5458f9df 100644 --- a/FerramAerospaceResearch/FARGUI/FARFlightGUI/FlightDataLogger.cs +++ b/FerramAerospaceResearch/FARGUI/FARFlightGUI/FlightDataLogger.cs @@ -1,5 +1,5 @@ /* -Ferram Aerospace Research v0.16.0.0 "Mader" +Ferram Aerospace Research v0.16.0.2 "Mader" ========================= Aerodynamics model for Kerbal Space Program @@ -46,6 +46,7 @@ You should have received a copy of the GNU General Public License using System.Collections; using System.Collections.Generic; using System.IO; +using KSP.Localization; using UnityEngine; namespace FerramAerospaceResearch.FARGUI.FARFlightGUI @@ -247,7 +248,7 @@ private void Log(FlightGUI gui) private string GetFilename() { if (Vessel != null) - replacements[VesselNameKey] = Vessel.vesselName; + replacements[VesselNameKey] = Localizer.Format(Vessel.vesselName); replacements[DatetimeKey] = DateTime.Now.ToString(FARConfig.FlightLog.DatetimeFormat); string filename = Path.Combine(FARConfig.FlightLog.Directory, FARConfig.FlightLog.NameFormat.ToString(replacements)); diff --git a/FerramAerospaceResearch/FARGUI/FARFlightGUI/FlightGUI.cs b/FerramAerospaceResearch/FARGUI/FARFlightGUI/FlightGUI.cs index ed8abe398..b99e7854a 100644 --- a/FerramAerospaceResearch/FARGUI/FARFlightGUI/FlightGUI.cs +++ b/FerramAerospaceResearch/FARGUI/FARFlightGUI/FlightGUI.cs @@ -1,5 +1,5 @@ -/* -Ferram Aerospace Research v0.16.0.0 "Mader" +/* +Ferram Aerospace Research v0.16.0.2 "Mader" ========================= Aerodynamics model for Kerbal Space Program @@ -47,6 +47,7 @@ You should have received a copy of the GNU General Public License using ferram4; using FerramAerospaceResearch.FARAeroComponents; using FerramAerospaceResearch.Resources; +using FerramAerospaceResearch.Settings; using KSP.IO; using KSP.Localization; using StringLeakTest; @@ -362,6 +363,7 @@ private void MainFlightGUIWindow(int windowId) GUIUtils.TextEntryForInt(Localizer.Format("FARFlightGUIFltLogFlushPeriod"), 150, flightDataLogger.FlushPeriod); + DebugVisualizationGUI(); GUILayout.Label(Localizer.Format("FARFlightGUIFltAssistance")); @@ -371,6 +373,21 @@ private void MainFlightGUIWindow(int windowId) GUI.DragWindow(); } + private void DebugVisualizationGUI() + { + if (!VoxelizationSettings.DebugInFlight) + return; + GUILayout.BeginHorizontal(); + GUI.enabled = !_vesselAero.VehicleAero.Voxelizing; + if (GUILayout.Button(Localizer.Format("FARDebugVoxels"))) + { + _vesselAero.VehicleAero.DebugVisualizeVoxels(vessel.transform.localToWorldMatrix); + } + + GUI.enabled = true; + GUILayout.EndHorizontal(); + } + private void FlightDataWindow(int windowId) { _flightDataGUI.DataDisplay(); diff --git a/FerramAerospaceResearch/FARGUI/FARFlightGUI/FlightGUIDrawer.cs b/FerramAerospaceResearch/FARGUI/FARFlightGUI/FlightGUIDrawer.cs index a3153d7b9..fcc4665ad 100644 --- a/FerramAerospaceResearch/FARGUI/FARFlightGUI/FlightGUIDrawer.cs +++ b/FerramAerospaceResearch/FARGUI/FARFlightGUI/FlightGUIDrawer.cs @@ -1,5 +1,5 @@ -/* -Ferram Aerospace Research v0.16.0.0 "Mader" +/* +Ferram Aerospace Research v0.16.0.2 "Mader" ========================= Aerodynamics model for Kerbal Space Program diff --git a/FerramAerospaceResearch/FARGUI/FARFlightGUI/FlightStatusGUI.cs b/FerramAerospaceResearch/FARGUI/FARFlightGUI/FlightStatusGUI.cs index 36003f510..128c102bc 100644 --- a/FerramAerospaceResearch/FARGUI/FARFlightGUI/FlightStatusGUI.cs +++ b/FerramAerospaceResearch/FARGUI/FARFlightGUI/FlightStatusGUI.cs @@ -1,5 +1,5 @@ -/* -Ferram Aerospace Research v0.16.0.0 "Mader" +/* +Ferram Aerospace Research v0.16.0.2 "Mader" ========================= Aerodynamics model for Kerbal Space Program diff --git a/FerramAerospaceResearch/FARGUI/FARFlightGUI/InternalSpeedFAR.cs b/FerramAerospaceResearch/FARGUI/FARFlightGUI/InternalSpeedFAR.cs index 317cca9fd..2f2cdecec 100644 --- a/FerramAerospaceResearch/FARGUI/FARFlightGUI/InternalSpeedFAR.cs +++ b/FerramAerospaceResearch/FARGUI/FARFlightGUI/InternalSpeedFAR.cs @@ -1,5 +1,5 @@ -/* -Ferram Aerospace Research v0.16.0.0 "Mader" +/* +Ferram Aerospace Research v0.16.0.2 "Mader" ========================= Aerodynamics model for Kerbal Space Program diff --git a/FerramAerospaceResearch/FARGUI/FARFlightGUI/PhysicsCalcs.cs b/FerramAerospaceResearch/FARGUI/FARFlightGUI/PhysicsCalcs.cs index 15deb949f..40f80edee 100644 --- a/FerramAerospaceResearch/FARGUI/FARFlightGUI/PhysicsCalcs.cs +++ b/FerramAerospaceResearch/FARGUI/FARFlightGUI/PhysicsCalcs.cs @@ -1,5 +1,5 @@ -/* -Ferram Aerospace Research v0.16.0.0 "Mader" +/* +Ferram Aerospace Research v0.16.0.2 "Mader" ========================= Aerodynamics model for Kerbal Space Program @@ -107,7 +107,7 @@ public VesselFlightInfo UpdatePhysicsParameters() return vesselInfo; Vector3d velVector = _vessel.srf_velocity - - FARWind.GetWind(_vessel.mainBody, + FARAtmosphere.GetWind(_vessel.mainBody, _vessel.rootPart, _vessel.ReferenceTransform.position); Vector3d velVectorNorm = velVector.normalized; diff --git a/FerramAerospaceResearch/FARGUI/FARFlightGUI/StabilityAugmentation.cs b/FerramAerospaceResearch/FARGUI/FARFlightGUI/StabilityAugmentation.cs index cf34536a9..60c781ba6 100644 --- a/FerramAerospaceResearch/FARGUI/FARFlightGUI/StabilityAugmentation.cs +++ b/FerramAerospaceResearch/FARGUI/FARFlightGUI/StabilityAugmentation.cs @@ -1,5 +1,5 @@ -/* -Ferram Aerospace Research v0.16.0.0 "Mader" +/* +Ferram Aerospace Research v0.16.0.2 "Mader" ========================= Aerodynamics model for Kerbal Space Program diff --git a/FerramAerospaceResearch/FARGUI/FARFlightGUI/VesselFlightInfo.cs b/FerramAerospaceResearch/FARGUI/FARFlightGUI/VesselFlightInfo.cs index 887fc5d4c..b83d221ba 100644 --- a/FerramAerospaceResearch/FARGUI/FARFlightGUI/VesselFlightInfo.cs +++ b/FerramAerospaceResearch/FARGUI/FARFlightGUI/VesselFlightInfo.cs @@ -1,5 +1,5 @@ -/* -Ferram Aerospace Research v0.16.0.0 "Mader" +/* +Ferram Aerospace Research v0.16.0.2 "Mader" ========================= Aerodynamics model for Kerbal Space Program diff --git a/FerramAerospaceResearch/FARGUI/GUIDropDown.cs b/FerramAerospaceResearch/FARGUI/GUIDropDown.cs index 22fb64a8c..07123f5e3 100644 --- a/FerramAerospaceResearch/FARGUI/GUIDropDown.cs +++ b/FerramAerospaceResearch/FARGUI/GUIDropDown.cs @@ -1,5 +1,5 @@ -/* -Ferram Aerospace Research v0.16.0.0 "Mader" +/* +Ferram Aerospace Research v0.16.0.2 "Mader" ========================= Aerodynamics model for Kerbal Space Program diff --git a/FerramAerospaceResearch/FARGUI/GUIUtils.cs b/FerramAerospaceResearch/FARGUI/GUIUtils.cs index 2fc7fa528..9e5e7b5dd 100644 --- a/FerramAerospaceResearch/FARGUI/GUIUtils.cs +++ b/FerramAerospaceResearch/FARGUI/GUIUtils.cs @@ -1,5 +1,5 @@ -/* -Ferram Aerospace Research v0.16.0.0 "Mader" +/* +Ferram Aerospace Research v0.16.0.2 "Mader" ========================= Aerodynamics model for Kerbal Space Program diff --git a/FerramAerospaceResearch/FARKSPAddonFlightScene.cs b/FerramAerospaceResearch/FARKSPAddonFlightScene.cs index d9a3ef529..efb29471c 100644 --- a/FerramAerospaceResearch/FARKSPAddonFlightScene.cs +++ b/FerramAerospaceResearch/FARKSPAddonFlightScene.cs @@ -1,5 +1,5 @@ -/* -Ferram Aerospace Research v0.16.0.0 "Mader" +/* +Ferram Aerospace Research v0.16.0.2 "Mader" ========================= Aerodynamics model for Kerbal Space Program diff --git a/FerramAerospaceResearch/FARKSPAddonMainMenuSetup.cs b/FerramAerospaceResearch/FARKSPAddonMainMenuSetup.cs index 9a9f1fb43..75298d2ab 100644 --- a/FerramAerospaceResearch/FARKSPAddonMainMenuSetup.cs +++ b/FerramAerospaceResearch/FARKSPAddonMainMenuSetup.cs @@ -1,5 +1,5 @@ -/* -Ferram Aerospace Research v0.16.0.0 "Mader" +/* +Ferram Aerospace Research v0.16.0.2 "Mader" ========================= Aerodynamics model for Kerbal Space Program diff --git a/FerramAerospaceResearch/FARKSPAddonSpaceCenterScene.cs b/FerramAerospaceResearch/FARKSPAddonSpaceCenterScene.cs index 8b0639add..73c5e87c1 100644 --- a/FerramAerospaceResearch/FARKSPAddonSpaceCenterScene.cs +++ b/FerramAerospaceResearch/FARKSPAddonSpaceCenterScene.cs @@ -1,4 +1,4 @@ -using UnityEngine; +using UnityEngine; namespace FerramAerospaceResearch { diff --git a/FerramAerospaceResearch/FARMathUtil.cs b/FerramAerospaceResearch/FARMathUtil.cs index 4672a829c..2cc253ddd 100644 --- a/FerramAerospaceResearch/FARMathUtil.cs +++ b/FerramAerospaceResearch/FARMathUtil.cs @@ -1,5 +1,5 @@ -/* -Ferram Aerospace Research v0.16.0.0 "Mader" +/* +Ferram Aerospace Research v0.16.0.2 "Mader" ========================= Aerodynamics model for Kerbal Space Program diff --git a/FerramAerospaceResearch/FARPM.cs b/FerramAerospaceResearch/FARPM.cs index 36731cce3..d93a2e9ed 100644 --- a/FerramAerospaceResearch/FARPM.cs +++ b/FerramAerospaceResearch/FARPM.cs @@ -1,5 +1,5 @@ /* -Ferram Aerospace Research v0.16.0.0 "Mader" +Ferram Aerospace Research v0.16.0.2 "Mader" ========================= Aerodynamics model for Kerbal Space Program diff --git a/FerramAerospaceResearch/FARPartExtensions.cs b/FerramAerospaceResearch/FARPartExtensions.cs index 46e3b8d3e..74ad3e849 100644 --- a/FerramAerospaceResearch/FARPartExtensions.cs +++ b/FerramAerospaceResearch/FARPartExtensions.cs @@ -1,5 +1,5 @@ -/* -Ferram Aerospace Research v0.16.0.0 "Mader" +/* +Ferram Aerospace Research v0.16.0.2 "Mader" ========================= Aerodynamics model for Kerbal Space Program diff --git a/FerramAerospaceResearch/FARPartGeometry/GeometryMesh.cs b/FerramAerospaceResearch/FARPartGeometry/GeometryMesh.cs index 77c9d153a..deb221f6e 100644 --- a/FerramAerospaceResearch/FARPartGeometry/GeometryMesh.cs +++ b/FerramAerospaceResearch/FARPartGeometry/GeometryMesh.cs @@ -1,5 +1,5 @@ -/* -Ferram Aerospace Research v0.16.0.0 "Mader" +/* +Ferram Aerospace Research v0.16.0.2 "Mader" ========================= Aerodynamics model for Kerbal Space Program diff --git a/FerramAerospaceResearch/FARPartGeometry/GeometryModification/AirbreathingEngineCrossSectionAdjuster.cs b/FerramAerospaceResearch/FARPartGeometry/GeometryModification/AirbreathingEngineCrossSectionAdjuster.cs index a2415eccd..e69c793e6 100644 --- a/FerramAerospaceResearch/FARPartGeometry/GeometryModification/AirbreathingEngineCrossSectionAdjuster.cs +++ b/FerramAerospaceResearch/FARPartGeometry/GeometryModification/AirbreathingEngineCrossSectionAdjuster.cs @@ -1,5 +1,5 @@ -/* -Ferram Aerospace Research v0.16.0.0 "Mader" +/* +Ferram Aerospace Research v0.16.0.2 "Mader" ========================= Aerodynamics model for Kerbal Space Program diff --git a/FerramAerospaceResearch/FARPartGeometry/GeometryModification/CompoundPartGeoUpdater.cs b/FerramAerospaceResearch/FARPartGeometry/GeometryModification/CompoundPartGeoUpdater.cs index 35e9d9661..596c038e8 100644 --- a/FerramAerospaceResearch/FARPartGeometry/GeometryModification/CompoundPartGeoUpdater.cs +++ b/FerramAerospaceResearch/FARPartGeometry/GeometryModification/CompoundPartGeoUpdater.cs @@ -1,5 +1,5 @@ -/* -Ferram Aerospace Research v0.16.0.0 "Mader" +/* +Ferram Aerospace Research v0.16.0.2 "Mader" ========================= Aerodynamics model for Kerbal Space Program diff --git a/FerramAerospaceResearch/FARPartGeometry/GeometryModification/ICrossSectionAdjuster.cs b/FerramAerospaceResearch/FARPartGeometry/GeometryModification/ICrossSectionAdjuster.cs index 5ddeffbff..0d277c8d5 100644 --- a/FerramAerospaceResearch/FARPartGeometry/GeometryModification/ICrossSectionAdjuster.cs +++ b/FerramAerospaceResearch/FARPartGeometry/GeometryModification/ICrossSectionAdjuster.cs @@ -1,5 +1,5 @@ -/* -Ferram Aerospace Research v0.16.0.0 "Mader" +/* +Ferram Aerospace Research v0.16.0.2 "Mader" ========================= Aerodynamics model for Kerbal Space Program diff --git a/FerramAerospaceResearch/FARPartGeometry/GeometryModification/IGeometryUpdater.cs b/FerramAerospaceResearch/FARPartGeometry/GeometryModification/IGeometryUpdater.cs index 0ed98326a..2be0969b7 100644 --- a/FerramAerospaceResearch/FARPartGeometry/GeometryModification/IGeometryUpdater.cs +++ b/FerramAerospaceResearch/FARPartGeometry/GeometryModification/IGeometryUpdater.cs @@ -1,5 +1,5 @@ -/* -Ferram Aerospace Research v0.16.0.0 "Mader" +/* +Ferram Aerospace Research v0.16.0.2 "Mader" ========================= Aerodynamics model for Kerbal Space Program diff --git a/FerramAerospaceResearch/FARPartGeometry/GeometryModification/IntakeCrossSectionAdjuster.cs b/FerramAerospaceResearch/FARPartGeometry/GeometryModification/IntakeCrossSectionAdjuster.cs index 5f977d874..91fa781d3 100644 --- a/FerramAerospaceResearch/FARPartGeometry/GeometryModification/IntakeCrossSectionAdjuster.cs +++ b/FerramAerospaceResearch/FARPartGeometry/GeometryModification/IntakeCrossSectionAdjuster.cs @@ -1,5 +1,5 @@ -/* -Ferram Aerospace Research v0.16.0.0 "Mader" +/* +Ferram Aerospace Research v0.16.0.2 "Mader" ========================= Aerodynamics model for Kerbal Space Program diff --git a/FerramAerospaceResearch/FARPartGeometry/GeometryModification/IntegratedIntakeEngineCrossSectionAdjuster.cs b/FerramAerospaceResearch/FARPartGeometry/GeometryModification/IntegratedIntakeEngineCrossSectionAdjuster.cs index 139254149..e988c1046 100644 --- a/FerramAerospaceResearch/FARPartGeometry/GeometryModification/IntegratedIntakeEngineCrossSectionAdjuster.cs +++ b/FerramAerospaceResearch/FARPartGeometry/GeometryModification/IntegratedIntakeEngineCrossSectionAdjuster.cs @@ -1,5 +1,5 @@ -/* -Ferram Aerospace Research v0.16.0.0 "Mader" +/* +Ferram Aerospace Research v0.16.0.2 "Mader" ========================= Aerodynamics model for Kerbal Space Program diff --git a/FerramAerospaceResearch/FARPartGeometry/GeometryModification/StockJettisonTransformGeoUpdater.cs b/FerramAerospaceResearch/FARPartGeometry/GeometryModification/StockJettisonTransformGeoUpdater.cs index 69910b080..2c3210ce1 100644 --- a/FerramAerospaceResearch/FARPartGeometry/GeometryModification/StockJettisonTransformGeoUpdater.cs +++ b/FerramAerospaceResearch/FARPartGeometry/GeometryModification/StockJettisonTransformGeoUpdater.cs @@ -1,5 +1,5 @@ -/* -Ferram Aerospace Research v0.16.0.0 "Mader" +/* +Ferram Aerospace Research v0.16.0.2 "Mader" ========================= Aerodynamics model for Kerbal Space Program diff --git a/FerramAerospaceResearch/FARPartGeometry/GeometryModification/StockProcAsteroidGeoUpdater.cs b/FerramAerospaceResearch/FARPartGeometry/GeometryModification/StockProcAsteroidGeoUpdater.cs index 665a31676..ef6ee9242 100644 --- a/FerramAerospaceResearch/FARPartGeometry/GeometryModification/StockProcAsteroidGeoUpdater.cs +++ b/FerramAerospaceResearch/FARPartGeometry/GeometryModification/StockProcAsteroidGeoUpdater.cs @@ -1,5 +1,5 @@ -/* -Ferram Aerospace Research v0.16.0.0 "Mader" +/* +Ferram Aerospace Research v0.16.0.2 "Mader" ========================= Aerodynamics model for Kerbal Space Program diff --git a/FerramAerospaceResearch/FARPartGeometry/GeometryModification/StockProcFairingGeoUpdater.cs b/FerramAerospaceResearch/FARPartGeometry/GeometryModification/StockProcFairingGeoUpdater.cs index 8a6c97566..bde1a1405 100644 --- a/FerramAerospaceResearch/FARPartGeometry/GeometryModification/StockProcFairingGeoUpdater.cs +++ b/FerramAerospaceResearch/FARPartGeometry/GeometryModification/StockProcFairingGeoUpdater.cs @@ -1,5 +1,5 @@ -/* -Ferram Aerospace Research v0.16.0.0 "Mader" +/* +Ferram Aerospace Research v0.16.0.2 "Mader" ========================= Aerodynamics model for Kerbal Space Program diff --git a/FerramAerospaceResearch/FARPartGeometry/GeometryPartModule.cs b/FerramAerospaceResearch/FARPartGeometry/GeometryPartModule.cs index 16a27ed46..cb4bfb1b2 100644 --- a/FerramAerospaceResearch/FARPartGeometry/GeometryPartModule.cs +++ b/FerramAerospaceResearch/FARPartGeometry/GeometryPartModule.cs @@ -1,5 +1,5 @@ -/* -Ferram Aerospace Research v0.16.0.0 "Mader" +/* +Ferram Aerospace Research v0.16.0.2 "Mader" ========================= Aerodynamics model for Kerbal Space Program @@ -334,7 +334,18 @@ internal void RebuildAllMeshData() private bool IgnoredPredicate(Transform t) { - return ignoredTransforms.Contains(t.name); + if (ignoredTransforms.Contains(t.name)) + return true; + + if (t.gameObject.layer != ignoreLayer0) + { + Transform prefabTransform = part.partInfo.partPrefab.FindModelTransform(t.gameObject.name); + if (prefabTransform is null || prefabTransform.gameObject.layer != ignoreLayer0) + return false; + } + + FARLogger.DebugFormat("Ignoring {0}.{1} for voxelization: layer is ignored", part.name, t.gameObject.name); + return true; } private Bounds SetBoundsFromMeshes() @@ -735,9 +746,6 @@ private MeshData GetVisibleMeshData(Transform t, bool skipIfNoRenderer, bool onl if (part.Modules.Contains() || part.Modules.Contains()) return new MeshData(m.vertices, m.triangles, m.bounds); - Transform prefabTransform = part.partInfo.partPrefab.FindModelTransform(t.gameObject.name); - if (!(prefabTransform is null) && prefabTransform.gameObject.layer == ignoreLayer0) - return null; return new MeshData(m.vertices, m.triangles, m.bounds); } diff --git a/FerramAerospaceResearch/FARPartGeometry/MeshData.cs b/FerramAerospaceResearch/FARPartGeometry/MeshData.cs index ab063ae0d..2d1f4d4f5 100644 --- a/FerramAerospaceResearch/FARPartGeometry/MeshData.cs +++ b/FerramAerospaceResearch/FARPartGeometry/MeshData.cs @@ -1,5 +1,5 @@ -/* -Ferram Aerospace Research v0.16.0.0 "Mader" +/* +Ferram Aerospace Research v0.16.0.2 "Mader" ========================= Aerodynamics model for Kerbal Space Program diff --git a/FerramAerospaceResearch/FARPartGeometry/PartGeometryExtensions.cs b/FerramAerospaceResearch/FARPartGeometry/PartGeometryExtensions.cs index 595aaf02e..7aca180aa 100644 --- a/FerramAerospaceResearch/FARPartGeometry/PartGeometryExtensions.cs +++ b/FerramAerospaceResearch/FARPartGeometry/PartGeometryExtensions.cs @@ -1,5 +1,5 @@ -/* -Ferram Aerospace Research v0.16.0.0 "Mader" +/* +Ferram Aerospace Research v0.16.0.2 "Mader" ========================= Aerodynamics model for Kerbal Space Program diff --git a/FerramAerospaceResearch/FARPartGeometry/PartSizePair.cs b/FerramAerospaceResearch/FARPartGeometry/PartSizePair.cs index 43cf30111..d03dfff9a 100644 --- a/FerramAerospaceResearch/FARPartGeometry/PartSizePair.cs +++ b/FerramAerospaceResearch/FARPartGeometry/PartSizePair.cs @@ -1,5 +1,5 @@ -/* -Ferram Aerospace Research v0.16.0.0 "Mader" +/* +Ferram Aerospace Research v0.16.0.2 "Mader" ========================= Aerodynamics model for Kerbal Space Program diff --git a/FerramAerospaceResearch/FARPartGeometry/PartSizePair4Bit.cs b/FerramAerospaceResearch/FARPartGeometry/PartSizePair4Bit.cs index 41c9f0217..d46d5c095 100644 --- a/FerramAerospaceResearch/FARPartGeometry/PartSizePair4Bit.cs +++ b/FerramAerospaceResearch/FARPartGeometry/PartSizePair4Bit.cs @@ -1,5 +1,5 @@ -/* -Ferram Aerospace Research v0.16.0.0 "Mader" +/* +Ferram Aerospace Research v0.16.0.2 "Mader" ========================= Aerodynamics model for Kerbal Space Program diff --git a/FerramAerospaceResearch/FARPartGeometry/PartSizePair8Bit.cs b/FerramAerospaceResearch/FARPartGeometry/PartSizePair8Bit.cs index 0944540cd..4c0cbfc52 100644 --- a/FerramAerospaceResearch/FARPartGeometry/PartSizePair8Bit.cs +++ b/FerramAerospaceResearch/FARPartGeometry/PartSizePair8Bit.cs @@ -1,5 +1,5 @@ -/* -Ferram Aerospace Research v0.16.0.0 "Mader" +/* +Ferram Aerospace Research v0.16.0.2 "Mader" ========================= Aerodynamics model for Kerbal Space Program diff --git a/FerramAerospaceResearch/FARPartGeometry/PartTransformInfo.cs b/FerramAerospaceResearch/FARPartGeometry/PartTransformInfo.cs index f44881cb8..aa4975928 100644 --- a/FerramAerospaceResearch/FARPartGeometry/PartTransformInfo.cs +++ b/FerramAerospaceResearch/FARPartGeometry/PartTransformInfo.cs @@ -1,5 +1,5 @@ -/* -Ferram Aerospace Research v0.16.0.0 "Mader" +/* +Ferram Aerospace Research v0.16.0.2 "Mader" ========================= Aerodynamics model for Kerbal Space Program diff --git a/FerramAerospaceResearch/FARPartGeometry/VehicleVoxel.cs b/FerramAerospaceResearch/FARPartGeometry/VehicleVoxel.cs index 4340888bb..e4e0ac25c 100644 --- a/FerramAerospaceResearch/FARPartGeometry/VehicleVoxel.cs +++ b/FerramAerospaceResearch/FARPartGeometry/VehicleVoxel.cs @@ -1,5 +1,5 @@ /* -Ferram Aerospace Research v0.16.0.0 "Mader" +Ferram Aerospace Research v0.16.0.2 "Mader" ========================= Aerodynamics model for Kerbal Space Program @@ -79,11 +79,11 @@ public class VehicleVoxel private int xCellLength, yCellLength, zCellLength; private int threadsQueued; - private VehicleVoxel() + private VehicleVoxel(Vessel vessel) { VoxelizationThreadpool.Instance.RunOnMainThread(() => { - voxelMesh = DebugVoxelMesh.Create(); + voxelMesh = DebugVoxelMesh.Create(vessel == null ? null : vessel.vesselTransform); voxelMesh.gameObject.SetActive(false); }); } @@ -91,6 +91,8 @@ private VehicleVoxel() public double ElementSize { get; private set; } public Vector3d LocalLowerRightCorner { get; private set; } + public Vector3d Center { get; private set; } + public Vector3d MeshExtents { get; private set; } public VoxelCrossSection[] EmptyCrossSectionArray { @@ -152,10 +154,11 @@ public static VehicleVoxel CreateNewVoxel( List geoModules, int elementCount, bool multiThreaded = true, - bool solidify = true + bool solidify = true, + Vessel vessel = null ) { - var newVoxel = new VehicleVoxel(); + var newVoxel = new VehicleVoxel(vessel); newVoxel.CreateVoxel(geoModules, elementCount, multiThreaded, solidify); @@ -209,6 +212,7 @@ bool solidify } Vector3d size = max - min; + MeshExtents = size; Volume = size.x * size.y * size.z; //from bounds, get voxel volume @@ -244,17 +248,17 @@ bool solidify zCellLength = zLength * 8; //this will be the distance from the center to the edges of the voxel object - var extents = new Vector3d + Vector3d extents = new Vector3d { x = xLength * 4 * ElementSize, y = yLength * 4 * ElementSize, z = zLength * 4 * ElementSize }; - Vector3d center = (max + min) * 0.5f; //Center of the vessel + Center = (max + min) * 0.5f; //Center of the vessel //This places the center of the voxel at the center of the vehicle to achieve maximum symmetry - LocalLowerRightCorner = center - extents; + LocalLowerRightCorner = Center - extents; voxelChunks = new VoxelChunk[xLength, yLength, zLength]; @@ -1365,6 +1369,9 @@ public void ClearVisualVoxels() public void VisualizeVoxel(Matrix4x4 vesselLocalToWorldMatrix) { FARLogger.Debug("Creating visual voxels"); + // Unity's to matrix naming is confusing, would be better to use from to actually + // correspond with multiplication order... + Matrix4x4 vesselLocalToVoxelMeshMatrix = voxelMesh.transform.worldToLocalMatrix * vesselLocalToWorldMatrix; var builder = new DebugVoxel.Builder(); var tintMap = new PartTint(); voxelMesh.Clear(builder, xLength * yLength * zLength * 128, false); @@ -1373,7 +1380,8 @@ public void VisualizeVoxel(Matrix4x4 vesselLocalToWorldMatrix) for (int j = 0; j < yLength; j++) { for (int k = 0; k < zLength; k++) - voxelChunks[i, j, k]?.VisualizeVoxels(vesselLocalToWorldMatrix, tintMap, voxelMesh, builder); + voxelChunks[i, j, k] + ?.VisualizeVoxels(vesselLocalToVoxelMeshMatrix, tintMap, voxelMesh, builder); } } diff --git a/FerramAerospaceResearch/FARPartGeometry/VoxelChunk.cs b/FerramAerospaceResearch/FARPartGeometry/VoxelChunk.cs index 8b3762c7a..6af51f751 100644 --- a/FerramAerospaceResearch/FARPartGeometry/VoxelChunk.cs +++ b/FerramAerospaceResearch/FARPartGeometry/VoxelChunk.cs @@ -1,5 +1,5 @@ /* -Ferram Aerospace Research v0.16.0.0 "Mader" +Ferram Aerospace Research v0.16.0.2 "Mader" ========================= Aerodynamics model for Kerbal Space Program diff --git a/FerramAerospaceResearch/FARPartGeometry/VoxelCrossSection.cs b/FerramAerospaceResearch/FARPartGeometry/VoxelCrossSection.cs index 30e787535..8091cb2bc 100644 --- a/FerramAerospaceResearch/FARPartGeometry/VoxelCrossSection.cs +++ b/FerramAerospaceResearch/FARPartGeometry/VoxelCrossSection.cs @@ -1,5 +1,5 @@ -/* -Ferram Aerospace Research v0.16.0.0 "Mader" +/* +Ferram Aerospace Research v0.16.0.2 "Mader" ========================= Aerodynamics model for Kerbal Space Program diff --git a/FerramAerospaceResearch/FARSettingsScenarioModule.cs b/FerramAerospaceResearch/FARSettingsScenarioModule.cs index 836569fcb..151c5eb38 100644 --- a/FerramAerospaceResearch/FARSettingsScenarioModule.cs +++ b/FerramAerospaceResearch/FARSettingsScenarioModule.cs @@ -1,5 +1,5 @@ -/* -Ferram Aerospace Research v0.16.0.0 "Mader" +/* +Ferram Aerospace Research v0.16.0.2 "Mader" ========================= Aerodynamics model for Kerbal Space Program diff --git a/FerramAerospaceResearch/FARThreading/ThreadBarrier.cs b/FerramAerospaceResearch/FARThreading/ThreadBarrier.cs index a347eb172..82f151d97 100644 --- a/FerramAerospaceResearch/FARThreading/ThreadBarrier.cs +++ b/FerramAerospaceResearch/FARThreading/ThreadBarrier.cs @@ -1,5 +1,5 @@ -/* -Ferram Aerospace Research v0.16.0.0 "Mader" +/* +Ferram Aerospace Research v0.16.0.2 "Mader" ========================= Aerodynamics model for Kerbal Space Program diff --git a/FerramAerospaceResearch/FARThreading/ThreadSafeDebugLogger.cs b/FerramAerospaceResearch/FARThreading/ThreadSafeDebugLogger.cs index 58c512791..543095e90 100644 --- a/FerramAerospaceResearch/FARThreading/ThreadSafeDebugLogger.cs +++ b/FerramAerospaceResearch/FARThreading/ThreadSafeDebugLogger.cs @@ -1,5 +1,5 @@ -/* -Ferram Aerospace Research v0.16.0.0 "Mader" +/* +Ferram Aerospace Research v0.16.0.2 "Mader" ========================= Aerodynamics model for Kerbal Space Program diff --git a/FerramAerospaceResearch/FARThreading/VoxelizationThreadpool.cs b/FerramAerospaceResearch/FARThreading/VoxelizationThreadpool.cs index bede52d76..b16f0f90c 100644 --- a/FerramAerospaceResearch/FARThreading/VoxelizationThreadpool.cs +++ b/FerramAerospaceResearch/FARThreading/VoxelizationThreadpool.cs @@ -1,5 +1,5 @@ -/* -Ferram Aerospace Research v0.16.0.0 "Mader" +/* +Ferram Aerospace Research v0.16.0.2 "Mader" ========================= Aerodynamics model for Kerbal Space Program diff --git a/FerramAerospaceResearch/FARWind.cs b/FerramAerospaceResearch/FARWind.cs deleted file mode 100644 index 2b305ea7a..000000000 --- a/FerramAerospaceResearch/FARWind.cs +++ /dev/null @@ -1,114 +0,0 @@ -/* -Ferram Aerospace Research v0.16.0.0 "Mader" -========================= -Aerodynamics model for Kerbal Space Program - -Copyright 2020, Michael Ferrara, aka Ferram4 - - This file is part of Ferram Aerospace Research. - - Ferram Aerospace Research is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 3 of the License, or - (at your option) any later version. - - Ferram Aerospace Research is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with Ferram Aerospace Research. If not, see . - - Serious thanks: a.g., for tons of bugfixes and code-refactorings - stupid_chris, for the RealChuteLite implementation - Taverius, for correcting a ton of incorrect values - Tetryds, for finding lots of bugs and issues and not letting me get away with them, and work on example crafts - sarbian, for refactoring code for working with MechJeb, and the Module Manager updates - ialdabaoth (who is awesome), who originally created Module Manager - Regex, for adding RPM support - DaMichel, for some ferramGraph updates and some control surface-related features - Duxwing, for copy editing the readme - - CompatibilityChecker by Majiir, BSD 2-clause http://opensource.org/licenses/BSD-2-Clause - - Part.cfg changes powered by sarbian & ialdabaoth's ModuleManager plugin; used with permission - http://forum.kerbalspaceprogram.com/threads/55219 - - ModularFLightIntegrator by Sarbian, Starwaster and Ferram4, MIT: http://opensource.org/licenses/MIT - http://forum.kerbalspaceprogram.com/threads/118088 - - Toolbar integration powered by blizzy78's Toolbar plugin; used with permission - http://forum.kerbalspaceprogram.com/threads/60863 - */ - -using System; -using UnityEngine; - -namespace FerramAerospaceResearch -{ - /// - /// Entry point where another assembly can specify a function to calculate the wind. - /// The rest of the simulation uses this class to get the wind and includes it in the - /// total airspeed for the simulation. - /// - public static class FARWind - { - /// - /// A WindFunction takes the current celestial body and a position (should be the position of the part) - /// and returns the wind as a Vector3 (unit is m/s) - /// - public delegate Vector3 WindFunction(CelestialBody body, Part part, Vector3 position); - - - /// - /// The actual delegate is private: we want to avoid a public get method, so that the only way to call the function - /// is using the safe wrapper GetWind, which suppresses all exceptions - /// - private static WindFunction func = ZeroWind; - - /// - /// Calculates the wind's intensity using the specified wind function. - /// If any exception occurs, it is suppressed and Vector3.zero is returned. - /// This function will never throw, (although it will spam the log). - /// - public static Vector3 GetWind(CelestialBody body, Part part, Vector3 position) - { - try - { - return func(body, part, position); - } - catch (Exception e) - { - FARLogger.InfoFormat("[FARWIND] Exception! {0}\n{1}", e.Message, e.StackTrace); - return Vector3.zero; - } - } - - - // ReSharper disable once UnusedMember.Global - /// - /// "Set" method for the wind function. - /// If newFunction is null, it resets the function to ZeroWind. - /// - public static void SetWindFunction(WindFunction newFunction) - { - if (newFunction == null) - { - FARLogger.Info("[FARWind] Attempted to set a null wind function, using ZeroWind instead."); - func = ZeroWind; - } - else - { - FARLogger.Info("[FARWind] Setting wind function to " + newFunction.Method.Name); - func = newFunction; - } - } - - - public static Vector3 ZeroWind(CelestialBody body, Part part, Vector3 position) - { - return Vector3.zero; - } - } -} diff --git a/FerramAerospaceResearch/FerramAerospaceResearch.csproj b/FerramAerospaceResearch/FerramAerospaceResearch.csproj index e9887b190..eba953e2e 100644 --- a/FerramAerospaceResearch/FerramAerospaceResearch.csproj +++ b/FerramAerospaceResearch/FerramAerospaceResearch.csproj @@ -14,14 +14,14 @@ 512 - 8 + 9 true portable false $(SolutionDir)bin\$(Configuration)\ - DEBUG;TRACE;ASSERT;LOG_TRACE + DEBUG;TRACE;ASSERT;LOG_TRACE;ENABLE_PROFILER prompt 4 true @@ -54,7 +54,18 @@ False ..\GameData\FerramAerospaceResearch\Plugins\Scale_Redist.dll - + + + $(KSP_DIR_BUILD)GameData\000_KSPBurst\Plugins\System.Runtime.CompilerServices.Unsafe.dll + + + False + $(KSP_DIR_BUILD)GameData\000_KSPBurst\Plugins\Unity.Collections.dll + + + False + $(KSP_DIR_BUILD)GameData\000_KSPBurst\Plugins\Unity.Mathematics.dll + False $(KSP_DIR_BUILD)KSP_x64_Data\Managed\UnityEngine.dll @@ -90,6 +101,7 @@ + @@ -168,7 +180,7 @@ - + @@ -178,6 +190,7 @@ + @@ -215,4 +228,4 @@ --> - + \ No newline at end of file diff --git a/FerramAerospaceResearch/InstallChecker.cs b/FerramAerospaceResearch/InstallChecker.cs index 70a31f233..0722fceb4 100644 --- a/FerramAerospaceResearch/InstallChecker.cs +++ b/FerramAerospaceResearch/InstallChecker.cs @@ -1,4 +1,4 @@ -/* +/* * InstallChecker, originally by Majiir * Released into the public domain using a CC0 Public Domain Dedication: http://creativecommons.org/publicdomain/zero/1.0/ */ diff --git a/FerramAerospaceResearch/LEGACYferram4/FARAction.cs b/FerramAerospaceResearch/LEGACYferram4/FARAction.cs index 134a440bb..93ced68c8 100644 --- a/FerramAerospaceResearch/LEGACYferram4/FARAction.cs +++ b/FerramAerospaceResearch/LEGACYferram4/FARAction.cs @@ -1,5 +1,5 @@ -/* -Ferram Aerospace Research v0.16.0.0 "Mader" +/* +Ferram Aerospace Research v0.16.0.2 "Mader" ========================= Aerodynamics model for Kerbal Space Program diff --git a/FerramAerospaceResearch/LEGACYferram4/FARBaseAerodynamics.cs b/FerramAerospaceResearch/LEGACYferram4/FARBaseAerodynamics.cs index e0ef47742..76d63b76f 100644 --- a/FerramAerospaceResearch/LEGACYferram4/FARBaseAerodynamics.cs +++ b/FerramAerospaceResearch/LEGACYferram4/FARBaseAerodynamics.cs @@ -1,5 +1,5 @@ -/* -Ferram Aerospace Research v0.16.0.0 "Mader" +/* +Ferram Aerospace Research v0.16.0.2 "Mader" ========================= Aerodynamics model for Kerbal Space Program @@ -113,7 +113,7 @@ public Vector3d GetVelocity() if (HighLogic.LoadedSceneIsFlight) return part.Rigidbody.velocity + Krakensbane.GetFrameVelocityV3f() - - FARWind.GetWind(FlightGlobals.currentMainBody, part, part.Rigidbody.position); + FARAtmosphere.GetWind(FlightGlobals.currentMainBody, part, part.Rigidbody.position); return velocityEditor; } @@ -127,7 +127,7 @@ public Vector3d GetVelocity(Vector3 refPoint) velocity += part.Rigidbody.GetPointVelocity(refPoint); velocity += Krakensbane.GetFrameVelocity() - Krakensbane.GetLastCorrection() * TimeWarp.fixedDeltaTime; - velocity -= FARWind.GetWind(FlightGlobals.currentMainBody, part, part.Rigidbody.position); + velocity -= FARAtmosphere.GetWind(FlightGlobals.currentMainBody, part, part.Rigidbody.position); return velocity; } diff --git a/FerramAerospaceResearch/LEGACYferram4/FARCenterQuery.cs b/FerramAerospaceResearch/LEGACYferram4/FARCenterQuery.cs index 05db906dc..b85e79e01 100644 --- a/FerramAerospaceResearch/LEGACYferram4/FARCenterQuery.cs +++ b/FerramAerospaceResearch/LEGACYferram4/FARCenterQuery.cs @@ -1,5 +1,5 @@ -/* -Ferram Aerospace Research v0.16.0.0 "Mader" +/* +Ferram Aerospace Research v0.16.0.2 "Mader" ========================= Aerodynamics model for Kerbal Space Program diff --git a/FerramAerospaceResearch/LEGACYferram4/FARControllableSurface.cs b/FerramAerospaceResearch/LEGACYferram4/FARControllableSurface.cs index 4999daa89..30745d042 100644 --- a/FerramAerospaceResearch/LEGACYferram4/FARControllableSurface.cs +++ b/FerramAerospaceResearch/LEGACYferram4/FARControllableSurface.cs @@ -1,5 +1,5 @@ -/* -Ferram Aerospace Research v0.16.0.0 "Mader" +/* +Ferram Aerospace Research v0.16.0.2 "Mader" ========================= Aerodynamics model for Kerbal Space Program diff --git a/FerramAerospaceResearch/LEGACYferram4/FARPartModule.cs b/FerramAerospaceResearch/LEGACYferram4/FARPartModule.cs index 0886050a4..9697922fa 100644 --- a/FerramAerospaceResearch/LEGACYferram4/FARPartModule.cs +++ b/FerramAerospaceResearch/LEGACYferram4/FARPartModule.cs @@ -1,5 +1,5 @@ -/* -Ferram Aerospace Research v0.16.0.0 "Mader" +/* +Ferram Aerospace Research v0.16.0.2 "Mader" ========================= Aerodynamics model for Kerbal Space Program diff --git a/FerramAerospaceResearch/LEGACYferram4/FARWingAerodynamicModel.cs b/FerramAerospaceResearch/LEGACYferram4/FARWingAerodynamicModel.cs index 1bd7527ef..5782a7ee2 100644 --- a/FerramAerospaceResearch/LEGACYferram4/FARWingAerodynamicModel.cs +++ b/FerramAerospaceResearch/LEGACYferram4/FARWingAerodynamicModel.cs @@ -1,5 +1,5 @@ -/* -Ferram Aerospace Research v0.16.0.0 "Mader" +/* +Ferram Aerospace Research v0.16.0.2 "Mader" ========================= Aerodynamics model for Kerbal Space Program @@ -80,19 +80,15 @@ public class FARWingAerodynamicModel : FARBaseAerodynamics, IRescalable 1.4) { - double coefMult = 2 / (FARAeroUtil.CurrentBody.atmosphereAdiabaticIndex * MachNumber * MachNumber); + double coefMult = 2 / (FARAeroUtil.CurrentAdiabaticIndex * MachNumber * MachNumber); double supersonicLENormalForceFactor = CalculateSupersonicLEFactor(beta, TanSweep, beta_TanSweep); @@ -1074,7 +1071,7 @@ private void CalculateCoefficients(double MachNumber, double AoA, double skinFri double M = MachNumber.Clamp(1.2, double.PositiveInfinity); - double coefMult = 2 / (FARAeroUtil.CurrentBody.atmosphereAdiabaticIndex * M * M); + double coefMult = 2 / (FARAeroUtil.CurrentAdiabaticIndex * M * M); double supersonicLENormalForceFactor = CalculateSupersonicLEFactor(beta, TanSweep, beta_TanSweep); @@ -1159,8 +1156,7 @@ private double CalculateSupersonicLEFactor(double beta, double TanSweep, double private static double GetSupersonicPressureDifference(double M, double AoA) { - double maxSinBeta = - FARAeroUtil.CalculateSinMaxShockAngle(M, FARAeroUtil.CurrentBody.atmosphereAdiabaticIndex); + double maxSinBeta = FARAeroUtil.CalculateSinMaxShockAngle(M, FARAeroUtil.CurrentAdiabaticIndex); double minSinBeta = 1 / M; //In radians, Corresponds to ~2.8 degrees or approximately what you would get from a ~4.8% thick diamond airfoil @@ -1202,9 +1198,7 @@ double minSinBeta ) { double sinBeta = - FARAeroUtil.CalculateSinWeakObliqueShockAngle(inM, - FARAeroUtil.CurrentBody.atmosphereAdiabaticIndex, - angle); + FARAeroUtil.CalculateSinWeakObliqueShockAngle(inM, FARAeroUtil.CurrentAdiabaticIndex, angle); if (double.IsNaN(sinBeta)) sinBeta = maxSinBeta; diff --git a/FerramAerospaceResearch/LEGACYferram4/FARWingInteraction.cs b/FerramAerospaceResearch/LEGACYferram4/FARWingInteraction.cs index 1598a9d31..af6a95385 100644 --- a/FerramAerospaceResearch/LEGACYferram4/FARWingInteraction.cs +++ b/FerramAerospaceResearch/LEGACYferram4/FARWingInteraction.cs @@ -1,5 +1,5 @@ -/* -Ferram Aerospace Research v0.16.0.0 "Mader" +/* +Ferram Aerospace Research v0.16.0.2 "Mader" ========================= Aerodynamics model for Kerbal Space Program diff --git a/FerramAerospaceResearch/ObjectReferenceEqualityComparer.cs b/FerramAerospaceResearch/ObjectReferenceEqualityComparer.cs index 233cc84a8..9c901b983 100644 --- a/FerramAerospaceResearch/ObjectReferenceEqualityComparer.cs +++ b/FerramAerospaceResearch/ObjectReferenceEqualityComparer.cs @@ -1,4 +1,4 @@ -using System.Collections.Generic; +using System.Collections.Generic; using System.Runtime.CompilerServices; namespace FerramAerospaceResearch diff --git a/FerramAerospaceResearch/Properties/AssemblyInfo.cs b/FerramAerospaceResearch/Properties/AssemblyInfo.cs index 751fc9040..920c46cb0 100644 --- a/FerramAerospaceResearch/Properties/AssemblyInfo.cs +++ b/FerramAerospaceResearch/Properties/AssemblyInfo.cs @@ -1,4 +1,4 @@ -using System.Reflection; +using System.Reflection; using System.Runtime.InteropServices; // General Information about an assembly is controlled through the following @@ -34,6 +34,6 @@ // by using the '*' as shown below: // [assembly: AssemblyVersion("1.0.*")] -[assembly: AssemblyVersion("0.16.0.0")] -[assembly: AssemblyFileVersion("0.16.0.0")] +[assembly: AssemblyVersion("0.16.0.2")] +[assembly: AssemblyFileVersion("0.16.0.2")] [assembly: KSPAssemblyDependency("ModularFlightIntegrator", 1, 0)] diff --git a/FerramAerospaceResearch/RealChuteLite/PhysicsWatch.cs b/FerramAerospaceResearch/RealChuteLite/PhysicsWatch.cs index a7f5c3472..ae4ed31a8 100644 --- a/FerramAerospaceResearch/RealChuteLite/PhysicsWatch.cs +++ b/FerramAerospaceResearch/RealChuteLite/PhysicsWatch.cs @@ -1,4 +1,4 @@ -using System; +using System; // ReSharper disable UnusedMember.Global diff --git a/FerramAerospaceResearch/RealChuteLite/RealChuteFAR.cs b/FerramAerospaceResearch/RealChuteLite/RealChuteFAR.cs index 77151a8b0..4445bb15b 100644 --- a/FerramAerospaceResearch/RealChuteLite/RealChuteFAR.cs +++ b/FerramAerospaceResearch/RealChuteLite/RealChuteFAR.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Globalization; using System.Linq; diff --git a/FerramAerospaceResearch/Settings/OcclusionSettings.cs b/FerramAerospaceResearch/Settings/OcclusionSettings.cs new file mode 100644 index 000000000..c4b0c926c --- /dev/null +++ b/FerramAerospaceResearch/Settings/OcclusionSettings.cs @@ -0,0 +1,18 @@ +using FerramAerospaceResearch.Reflection; + +namespace FerramAerospaceResearch.Settings +{ + [ConfigNode("Occlusion", shouldSave: false, parent: typeof(FARConfig))] + public static class OcclusionSettings + { + [ConfigValue("useRaycaster")] public static bool UseRaycaster { get; set; } = false; + [ConfigValue("jobsPerThread")] public static int JobsPerThread { get; set; } = 3; + [ConfigValue("maxJobs")] public static int MaxJobs { get; set; } = 10; + [ConfigValue("fibonacciLatticeSize")] public static int FibonacciLatticeSize { get; set; } = 2000; + // 1000 points produces typical misses 2-3 degrees when optimized for average miss distance. + [ConfigValue("maxRaycastDimension")] public static int MaxRaycastDimension { get; set; } = 100; + [ConfigValue("raycastResolution")] public static float RaycastResolution { get; set; } = 0.1f; + [ConfigValue("resetInterval")] public static float ResetInterval { get; set; } = 180; + [ConfigValue("velocityThreshold")] public static float VelocityThreshold { get; set; } = 0.01f; + } +} diff --git a/FerramAerospaceResearch/Settings/Settings.cs b/FerramAerospaceResearch/Settings/Settings.cs index b2f204934..af0b8503f 100644 --- a/FerramAerospaceResearch/Settings/Settings.cs +++ b/FerramAerospaceResearch/Settings/Settings.cs @@ -9,5 +9,8 @@ public static class FARSettings public static bool ExposedAreaUsesKSPHack = true; [ConfigValue("exposedAreaLimited")] public static bool ExposedAreaLimited = true; + + [ConfigValue("submergedDragMultiplier")] public static double SubmergedDragMultiplier = 0.25; + [ConfigValue("submergedLiftMultiplier")] public static double SubmergedLiftMultiplier = 0.25; } } diff --git a/FerramAerospaceResearch/Settings/VoxelizationSettings.cs b/FerramAerospaceResearch/Settings/VoxelizationSettings.cs index d2bee4383..ce4657968 100644 --- a/FerramAerospaceResearch/Settings/VoxelizationSettings.cs +++ b/FerramAerospaceResearch/Settings/VoxelizationSettings.cs @@ -11,8 +11,7 @@ namespace FerramAerospaceResearch.Settings [ConfigNode("ColorMap")] public class ColorMap { - [ConfigValueIgnore] - public static readonly ColorMap Default = new ColorMap + [ConfigValueIgnore] public static readonly ColorMap Default = new ColorMap { Name = "default", Colors = {new Color(0.18f, 0f, 0.106f)} @@ -39,12 +38,15 @@ public static class VoxelizationSettings { [ConfigValue("default")] public static string Default { get; set; } - [ConfigValue("ColorMap")] public static List ColorMaps { get; } = new List(); + [ConfigValue] public static List ColorMaps { get; } = new List(); + + [ConfigValue("debugInFlight")] public static bool DebugInFlight { get; set; } = false; public static ColorMap FirstOrDefault() { return FirstOrDefault(Default); } + public static ColorMap FirstOrDefault(string name) { if (string.IsNullOrEmpty(name)) diff --git a/FerramAerospaceResearch/ToolbarWrapper.cs b/FerramAerospaceResearch/ToolbarWrapper.cs index d29608613..b5188d9f1 100644 --- a/FerramAerospaceResearch/ToolbarWrapper.cs +++ b/FerramAerospaceResearch/ToolbarWrapper.cs @@ -1,4 +1,4 @@ -/* +/* Copyright (c) 2013-2014, Maik Schreiber All rights reserved. diff --git a/FerramAerospaceResearch/Utils/ConfigAdapter.cs b/FerramAerospaceResearch/Utils/ConfigAdapter.cs index 53292ac27..003c4f1e5 100644 --- a/FerramAerospaceResearch/Utils/ConfigAdapter.cs +++ b/FerramAerospaceResearch/Utils/ConfigAdapter.cs @@ -1,5 +1,7 @@ +using System; using System.Collections; using System.Collections.Generic; +using System.Threading; using System.Threading.Tasks; using FerramAerospaceResearch.Interfaces; using FerramAerospaceResearch.Reflection; @@ -10,6 +12,69 @@ namespace FerramAerospaceResearch [FARAddon(700, true)] public class ConfigAdapter : MonoSingleton, IWaitForAddon, IReloadable { + private enum Operation + { + None, + Loading, + Saving + } + + private struct LoadGuard : IDisposable + { + public Operation operation; + + // cannot override default ctor... + public LoadGuard(Operation op) + { + operation = op; + switch (op) + { + case Operation.Loading: + FARLogger.Debug("ConfigAdapter started loading"); + FARConfig.IsLoading = true; + Instance.loading = true; + break; + case Operation.Saving: + FARLogger.Debug("ConfigAdapter started saving"); + Instance.saving = true; + break; + case Operation.None: + FARLogger.Debug("ConfigAdapter started task"); + break; + default: + throw new ArgumentOutOfRangeException(nameof(op), op, null); + } + } + + public void Dispose() + { + switch (operation) + { + case Operation.Loading: + FARLogger.Debug("ConfigAdapter finished loading"); + FARConfig.IsLoading = false; + Instance.loading = false; + break; + case Operation.Saving: + FARLogger.Debug("ConfigAdapter finished saving"); + Instance.saving = false; + break; + case Operation.None: + FARLogger.Debug("ConfigAdapter finished task"); + break; + default: + throw new ArgumentOutOfRangeException(nameof(operation), operation, null); + } + + Instance.Completed = !(Instance.saving || Instance.loading); + } + } + + private static LoadGuard Guard(Operation op) + { + return new LoadGuard(op); + } + private static readonly Dictionary lastConfigs = new Dictionary(); public int Priority { get; set; } = 999; @@ -20,109 +85,96 @@ public void DoReload() public bool Completed { get; set; } + private volatile bool loading; + private volatile bool saving; + private void Start() { StartCoroutine(DoSetup()); } - private IEnumerator DoSetup() + private static IEnumerator DoSetup() { - try - { - Task task = Task.Factory.StartNew(() => ConfigReflection.Instance.Initialize()); + using LoadGuard guard = Guard(Operation.None); - while (!task.IsCompleted) - yield return null; + Task task = Task.Factory.StartNew(() => ConfigReflection.Instance.Initialize()); - if (task.Exception != null) - FARLogger.Exception(task.Exception, "Exception while setting up config"); - } - finally - { - Completed = true; - } + while (!task.IsCompleted) + yield return null; + + if (task.Exception != null) + FARLogger.Exception(task.Exception, "Exception while setting up config"); } - public static void LoadConfigs() + private static void LoadConfigs() { - FARConfig.IsLoading = true; - // clear config cache so it can be rebuilt lastConfigs.Clear(); var load = new LoadVisitor(); - try + foreach (KeyValuePair pair in ConfigReflection.Instance.Configs) { - foreach (KeyValuePair pair in ConfigReflection.Instance.Configs) + ConfigNode[] nodes = GameDatabase.Instance.GetConfigNodes(pair.Key); + if (pair.Value.Reflection.AllowMultiple) { - ConfigNode[] nodes = GameDatabase.Instance.GetConfigNodes(pair.Key); - if (pair.Value.Reflection.AllowMultiple) + var root = new ConfigNode(); + foreach (ConfigNode configNode in nodes) + root.AddNode(configNode); + + load.Node = root; + object instance = pair.Value.Instance; + int errors = pair.Value.Reflection.Load(load, ref instance); + + if (errors > 0) + FARLogger.ErrorFormat("{0} errors while loading {1}", errors.ToString(), pair.Key); + } + else + { + if (nodes.Length == 0) { - var root = new ConfigNode(); - foreach (ConfigNode configNode in nodes) - root.AddNode(configNode); + FARLogger.Warning($"Could not find config nodes {pair.Key}"); + continue; + } + + if (nodes.Length > 1) + FARLogger.Warning($"Found {nodes.Length.ToString()} {pair.Key} nodes"); - load.Node = root; + foreach (ConfigNode node in nodes) + { + load.Node = node; object instance = pair.Value.Instance; int errors = pair.Value.Reflection.Load(load, ref instance); if (errors > 0) - FARLogger.ErrorFormat("{0} errors while loading {1}", errors.ToString(), pair.Key); - } - else - { - if (nodes.Length == 0) - { - FARLogger.Warning($"Could not find config nodes {pair.Key}"); - continue; - } - - if (nodes.Length > 1) - FARLogger.Warning($"Found {nodes.Length.ToString()} {pair.Key} nodes"); - - foreach (ConfigNode node in nodes) - { - load.Node = node; - object instance = pair.Value.Instance; - int errors = pair.Value.Reflection.Load(load, ref instance); - - if (errors > 0) - FARLogger.ErrorFormat("{0} errors while loading {1}", errors.ToString(), node.name); - } + FARLogger.ErrorFormat("{0} errors while loading {1}", errors.ToString(), node.name); } } - - SaveConfigs("Custom", true, ".cfg.far", FARConfig.Debug.DumpOnLoad); - } - finally - { - FARConfig.IsLoading = false; } + + using LoadGuard guard = Guard(Operation.Saving); + SaveConfigs("Custom", true, ".cfg.far", FARConfig.Debug.DumpOnLoad); } public static IEnumerator SaveAll() { - if (FARConfig.IsLoading) + if (Instance.saving) yield break; - FARConfig.IsLoading = true; + while (Instance.loading) + yield return null; - try - { - Task task = Task.Factory.StartNew(Save); - yield return new WaitUntil(() => task.IsCompleted); + using LoadGuard guard = Guard(Operation.Saving); - if (task.Exception != null) - FARLogger.Exception(task.Exception, "Exception while saving up configs"); - } - finally - { - FARConfig.IsLoading = false; - } + Task task = Task.Factory.StartNew(Save); + yield return new WaitUntil(() => task.IsCompleted); + + if (task.Exception != null) + FARLogger.Exception(task.Exception, "Exception while saving up configs"); } public static void Save() { + using LoadGuard guard = Guard(Operation.Saving); SaveConfigs("Custom"); } @@ -133,7 +185,6 @@ private static void SaveConfigs( bool force = false ) { - var topNode = new ConfigNode(); var node = new ConfigNode(); var save = new SaveVisitor { @@ -151,18 +202,14 @@ private static void SaveConfigs( continue; string path = PathUtil.Combine(KSPUtils.GameDataPath, $"{prefix}_{pair.Key}{extension}"); - string nodeStr; if (!pair.Value.Reflection.AllowMultiple) { - Serialization.MakeTopNode(topNode, node, pair.Key, null, isPatch); - nodeStr = topNode.ToString(); - } - else - { - nodeStr = node.ToString(); + Serialization.MakeTopNode(node, pair.Key, null, isPatch); } + string nodeStr = node.ToString(); + if (lastConfigs.TryGetValue(pair.Key, out string oldStr)) lastConfigs[pair.Key] = nodeStr; else @@ -171,7 +218,7 @@ private static void SaveConfigs( // only write if requested or if the node has been modified, first time oldStr should be null so can be skipped if (force || (!string.IsNullOrEmpty(oldStr) && nodeStr != oldStr)) { - FARLogger.DebugFormat("Saving {0} config to {1}", pair.Key, path); + FARLogger.DebugFormat("Saving {0} config to {1}:\n{2}\n\n{3}", pair.Key, path, oldStr, nodeStr); System.IO.File.WriteAllText(path, nodeStr); } else @@ -179,21 +226,31 @@ private static void SaveConfigs( FARLogger.DebugFormat("{0} does not require saving", pair.Key); } - topNode.ClearData(); node.ClearData(); } } private IEnumerator DoLoadConfig() { + if (loading) + yield break; + + while (saving) + yield return null; + + using LoadGuard guard = Guard(Operation.Loading); Task task = Task.Factory.StartNew(LoadConfigs); yield return new WaitWhile(() => !task.IsCompleted); if (task.Exception != null) FARLogger.Exception(task.Exception, "Exception while loading config"); + } - Completed = true; + protected override void OnDestruct() + { + while (loading || saving) + Thread.Sleep(1); } } @@ -303,6 +360,7 @@ public bool OnValueList(ListValueReflection reflection, out IList newValue) newValue.Add(v); } + FARLogger.DebugFormat("Parsed {0}.{1} with {2} values", Node.name, reflection.Name, newValue.Count); return true; diff --git a/FerramAerospaceResearch/Utils/Serialization.cs b/FerramAerospaceResearch/Utils/Serialization.cs index 1bf370ea2..4f6f06503 100644 --- a/FerramAerospaceResearch/Utils/Serialization.cs +++ b/FerramAerospaceResearch/Utils/Serialization.cs @@ -293,7 +293,6 @@ public static bool TryGetValue(ConfigNode node, string id, out object value, Typ } public static void MakeTopNode( - ConfigNode node, ConfigNode child, string id, string name = null, @@ -315,7 +314,7 @@ public static void MakeTopNode( nodeName = id; } - node.AddNode(nodeName, child); + child.name = nodeName; } public static void AddNode( diff --git a/GameData/FerramAerospaceResearch/FAR.version b/GameData/FerramAerospaceResearch/FAR.version index e810d5880..e8890cb94 100644 --- a/GameData/FerramAerospaceResearch/FAR.version +++ b/GameData/FerramAerospaceResearch/FAR.version @@ -10,7 +10,7 @@ "MAJOR" : 0, "MINOR" : 16, "PATCH" : 0, - "BUILD" : 0 + "BUILD" : 2 }, "KSP_VERSION_MIN" : { "MAJOR" : 1, @@ -19,7 +19,7 @@ }, "KSP_VERSION_MAX" : { "MAJOR" : 1, - "MINOR" : 10, + "MINOR" : 11, "PATCH" : 99 } } diff --git a/GameData/FerramAerospaceResearch/FARConfig.cfg b/GameData/FerramAerospaceResearch/FARConfig.cfg index f3f91f834..89af94a69 100644 --- a/GameData/FerramAerospaceResearch/FARConfig.cfg +++ b/GameData/FerramAerospaceResearch/FARConfig.cfg @@ -10,6 +10,12 @@ FARConfig // limit exposed area to radiative area value exposedAreaLimited = true + + // constant value to multiple submerged drag by, use <1 otherwise submerged parts generate far too much drag + submergedDragMultiplier = 0.25 + + // constant value to multiple submerged lift by + submergedLiftMultiplier = 0.25 } Debug { @@ -49,7 +55,7 @@ FARConfig GuiColors { ClColor = 0.000,1.000,1.000 CdColor = 1.000,0.000,0.000 - CmColor = 1.000,0.9215686,0.01568628 + CmColor = 1.000,0.921570003,0.0156900007 L_DColor = 0.000,1.000,0.000 } @@ -111,6 +117,282 @@ FARConfig } } + Voxelization { + // enable debug voxels in flight mode + debugInFlight = false + + // check out colorcet (Python) for generating more maps + default = glasbey_bw + + ColorMap { + // similar color as the old debug voxels + name = old + color = 0.18, 0, 0.106 + } + + ColorMap { + // same as colorcet.glasbey_bw + name = glasbey_bw + + color = 0.843137, 0.000000, 0.000000 + color = 0.549020, 0.235294, 1.000000 + color = 0.007843, 0.533333, 0.000000 + color = 0.000000, 0.674510, 0.780392 + color = 0.596078, 1.000000, 0.000000 + color = 1.000000, 0.498039, 0.819608 + color = 0.423529, 0.000000, 0.309804 + color = 1.000000, 0.647059, 0.188235 + color = 0.000000, 0.000000, 0.615686 + color = 0.525490, 0.439216, 0.407843 + color = 0.000000, 0.286275, 0.258824 + color = 0.309804, 0.164706, 0.000000 + color = 0.000000, 0.992157, 0.811765 + color = 0.737255, 0.717647, 1.000000 + color = 0.584314, 0.705882, 0.478431 + color = 0.752941, 0.015686, 0.725490 + color = 0.145098, 0.400000, 0.635294 + color = 0.156863, 0.000000, 0.254902 + color = 0.862745, 0.701961, 0.686275 + color = 0.996078, 0.960784, 0.564706 + color = 0.313725, 0.270588, 0.356863 + color = 0.643137, 0.486275, 0.000000 + color = 1.000000, 0.443137, 0.400000 + color = 0.247059, 0.505882, 0.431373 + color = 0.509804, 0.000000, 0.050980 + color = 0.639216, 0.482353, 0.701961 + color = 0.203922, 0.305882, 0.000000 + color = 0.607843, 0.894118, 1.000000 + color = 0.921569, 0.000000, 0.466667 + color = 0.176471, 0.000000, 0.039216 + color = 0.368627, 0.564706, 1.000000 + color = 0.000000, 0.780392, 0.125490 + color = 0.345098, 0.003922, 0.666667 + color = 0.000000, 0.117647, 0.000000 + color = 0.603922, 0.278431, 0.000000 + color = 0.588235, 0.623529, 0.650980 + color = 0.607843, 0.258824, 0.360784 + color = 0.000000, 0.121569, 0.196078 + color = 0.784314, 0.768627, 0.000000 + color = 1.000000, 0.815686, 1.000000 + color = 0.000000, 0.745098, 0.603922 + color = 0.215686, 0.082353, 1.000000 + color = 0.176471, 0.145098, 0.145098 + color = 0.874510, 0.345098, 1.000000 + color = 0.745098, 0.905882, 0.752941 + color = 0.498039, 0.270588, 0.596078 + color = 0.321569, 0.309804, 0.235294 + color = 0.847059, 0.400000, 0.000000 + color = 0.392157, 0.454902, 0.219608 + color = 0.756863, 0.450980, 0.533333 + color = 0.431373, 0.454902, 0.541176 + color = 0.501961, 0.615686, 0.011765 + color = 0.745098, 0.545098, 0.396078 + color = 0.388235, 0.200000, 0.223529 + color = 0.792157, 0.803922, 0.854902 + color = 0.423529, 0.921569, 0.513725 + color = 0.133333, 0.250980, 0.411765 + color = 0.635294, 0.498039, 1.000000 + color = 0.996078, 0.011765, 0.796078 + color = 0.462745, 0.737255, 0.992157 + color = 0.850980, 0.764706, 0.509804 + color = 0.807843, 0.639216, 0.807843 + color = 0.427451, 0.313725, 0.000000 + color = 0.000000, 0.411765, 0.454902 + color = 0.278431, 0.623529, 0.368627 + color = 0.580392, 0.776471, 0.749020 + color = 0.976471, 1.000000, 0.000000 + color = 0.752941, 0.329412, 0.270588 + color = 0.000000, 0.396078, 0.235294 + color = 0.356863, 0.313725, 0.658824 + color = 0.325490, 0.125490, 0.392157 + color = 0.309804, 0.372549, 1.000000 + color = 0.494118, 0.560784, 0.466667 + color = 0.725490, 0.031373, 0.980392 + color = 0.545098, 0.572549, 0.764706 + color = 0.701961, 0.000000, 0.207843 + color = 0.533333, 0.376471, 0.494118 + color = 0.623529, 0.000000, 0.458824 + color = 1.000000, 0.870588, 0.768627 + color = 0.317647, 0.031373, 0.000000 + color = 0.101961, 0.031373, 0.000000 + color = 0.298039, 0.537255, 0.713725 + color = 0.000000, 0.874510, 0.874510 + color = 0.784314, 1.000000, 0.980392 + color = 0.188235, 0.207843, 0.082353 + color = 1.000000, 0.152941, 0.278431 + color = 1.000000, 0.592157, 0.666667 + color = 0.015686, 0.000000, 0.101961 + color = 0.788235, 0.376471, 0.694118 + color = 0.764706, 0.635294, 0.215686 + color = 0.486275, 0.309804, 0.227451 + color = 0.976471, 0.619608, 0.466667 + color = 0.337255, 0.396078, 0.392157 + color = 0.819608, 0.576471, 1.000000 + color = 0.176471, 0.121569, 0.411765 + color = 0.254902, 0.105882, 0.203922 + color = 0.686275, 0.576471, 0.596078 + color = 0.384314, 0.619608, 0.600000 + color = 0.741176, 0.870588, 0.482353 + color = 1.000000, 0.368627, 0.580392 + color = 0.058824, 0.160784, 0.137255 + color = 0.721569, 0.745098, 0.674510 + color = 0.454902, 0.231373, 0.396078 + color = 0.062745, 0.000000, 0.050980 + color = 0.498039, 0.431373, 0.741176 + color = 0.619608, 0.419608, 0.231373 + color = 1.000000, 0.274510, 0.000000 + color = 0.498039, 0.000000, 0.529412 + color = 1.000000, 0.807843, 0.243137 + color = 0.188235, 0.231373, 0.262745 + color = 0.996078, 0.647059, 1.000000 + color = 0.541176, 0.007843, 0.243137 + color = 0.462745, 0.172549, 0.003922 + color = 0.039216, 0.541176, 0.588235 + color = 0.019608, 0.000000, 0.321569 + color = 0.556863, 0.839216, 0.196078 + color = 0.325490, 0.768627, 0.450980 + color = 0.278431, 0.349020, 0.443137 + color = 0.345098, 0.007843, 0.133333 + color = 0.650980, 0.133333, 0.003922 + color = 0.564706, 0.576471, 0.298039 + color = 0.000000, 0.262745, 0.117647 + color = 0.505882, 0.000000, 0.819608 + color = 0.184314, 0.149020, 0.247059 + color = 0.749020, 0.223529, 0.517647 + color = 0.960784, 1.000000, 0.835294 + color = 0.000000, 0.827451, 1.000000 + color = 0.415686, 0.000000, 0.972549 + color = 0.611765, 0.733333, 0.823529 + color = 0.478431, 0.850980, 0.670588 + color = 0.411765, 0.341176, 0.364706 + color = 0.000000, 0.411765, 0.019608 + color = 0.211765, 0.211765, 0.611765 + color = 0.003922, 0.513725, 0.278431 + color = 0.266667, 0.117647, 0.094118 + color = 0.027451, 0.647059, 0.937255 + color = 1.000000, 0.505882, 0.188235 + color = 0.654902, 0.333333, 0.721569 + color = 0.407843, 0.352941, 0.513725 + color = 0.450980, 1.000000, 1.000000 + color = 0.850980, 0.529412, 0.007843 + color = 0.733333, 0.827451, 1.000000 + color = 0.556863, 0.215686, 0.184314 + color = 0.654902, 0.627451, 0.501961 + color = 0.000000, 0.490196, 0.890196 + color = 0.556863, 0.494118, 0.560784 + color = 0.600000, 0.266667, 0.533333 + color = 0.000000, 0.945098, 0.207843 + color = 0.682353, 0.666667, 0.788235 + color = 0.627451, 0.380392, 0.384314 + color = 0.298039, 0.227451, 0.466667 + color = 0.423529, 0.509804, 0.513725 + color = 0.945098, 0.866667, 0.905882 + color = 1.000000, 0.733333, 0.827451 + color = 0.219608, 0.647059, 0.137255 + color = 0.705882, 1.000000, 0.658824 + color = 0.047059, 0.070588, 0.027451 + color = 0.843137, 0.321569, 0.431373 + color = 0.584314, 0.623529, 0.996078 + color = 0.490196, 0.498039, 0.000000 + color = 0.462745, 0.623529, 0.725490 + color = 0.858824, 0.529412, 0.498039 + color = 0.066667, 0.074510, 0.098039 + color = 0.831373, 0.509804, 0.831373 + color = 0.623529, 0.000000, 0.749020 + color = 0.862745, 0.937255, 1.000000 + color = 0.556863, 0.670588, 0.603922 + color = 0.443137, 0.392157, 0.258824 + color = 0.290196, 0.235294, 0.243137 + color = 0.031373, 0.305882, 0.372549 + color = 0.611765, 0.721569, 0.266667 + color = 0.847059, 0.870588, 0.835294 + color = 0.796078, 1.000000, 0.423529 + color = 0.701961, 0.392157, 0.921569 + color = 0.274510, 0.364706, 0.200000 + color = 0.000000, 0.619608, 0.490196 + color = 0.760784, 0.254902, 0.000000 + color = 0.309804, 0.737255, 0.733333 + color = 0.850980, 0.545098, 0.694118 + color = 0.356863, 0.450980, 0.713725 + color = 0.294118, 0.254902, 0.003922 + color = 0.584314, 0.513725, 0.368627 + color = 0.286275, 0.454902, 0.545098 + color = 1.000000, 0.450980, 1.000000 + color = 0.513725, 0.415686, 0.113725 + color = 0.862745, 0.811765, 1.000000 + color = 0.494118, 0.419608, 0.996078 + color = 0.388235, 0.462745, 0.376471 + color = 1.000000, 0.756863, 0.572549 + color = 0.349020, 0.368627, 0.000000 + color = 0.894118, 0.035294, 0.901961 + color = 0.725490, 0.694118, 0.717647 + color = 0.827451, 0.176471, 0.254902 + color = 0.196078, 0.258824, 0.215686 + color = 0.850980, 0.639216, 0.388235 + color = 0.356863, 0.545098, 0.200000 + color = 0.184314, 0.121569, 0.000000 + color = 0.596078, 0.905882, 0.843137 + color = 0.164706, 0.384314, 0.341176 + color = 0.807843, 0.447059, 0.301961 + color = 0.364706, 0.239216, 0.156863 + color = 0.000000, 0.349020, 0.850980 + color = 0.678431, 0.580392, 0.839216 + color = 0.419608, 0.117647, 0.580392 + color = 0.705882, 0.003922, 0.368627 + color = 0.254902, 0.000000, 0.274510 + color = 0.615686, 1.000000, 0.811765 + color = 0.894118, 0.282353, 0.615686 + color = 0.890196, 0.890196, 0.278431 + color = 0.862745, 0.886275, 0.647059 + color = 0.000000, 0.156863, 0.352941 + color = 0.666667, 0.356863, 0.509804 + color = 0.000000, 0.000000, 0.862745 + color = 0.294118, 0.305882, 0.317647 + color = 0.854902, 0.749020, 0.835294 + color = 0.000000, 0.301961, 0.600000 + color = 0.533333, 0.392157, 0.619608 + color = 0.415686, 0.117647, 0.113725 + color = 0.556863, 0.321569, 0.772549 + color = 0.721569, 0.854902, 0.874510 + color = 0.866667, 0.701961, 0.992157 + color = 0.482353, 0.282353, 0.329412 + color = 0.298039, 0.450980, 0.000000 + color = 0.270588, 0.000000, 0.466667 + color = 0.698039, 0.372549, 0.000000 + color = 0.572549, 0.819608, 0.525490 + color = 0.333333, 0.200000, 0.298039 + color = 0.411765, 0.690196, 0.521569 + color = 0.670588, 0.576471, 0.690196 + color = 0.905882, 0.329412, 0.258824 + color = 0.560784, 0.549020, 0.541176 + color = 0.439216, 0.678431, 0.317647 + color = 0.670588, 0.486275, 0.454902 + color = 0.000000, 0.203922, 0.235294 + color = 0.145098, 0.058824, 0.074510 + color = 0.905882, 0.690196, 0.000000 + color = 0.478431, 0.800000, 0.862745 + color = 0.094118, 0.078431, 0.227451 + color = 0.615686, 0.321569, 0.223529 + color = 0.733333, 0.482353, 0.192157 + color = 0.717647, 0.792157, 0.580392 + color = 0.192157, 0.031373, 0.000000 + color = 0.639216, 0.584314, 0.023529 + color = 0.000000, 0.854902, 0.729412 + color = 0.454902, 0.627451, 0.870588 + color = 0.388235, 0.235294, 0.450980 + color = 1.000000, 0.854902, 0.560784 + color = 0.466667, 0.721569, 0.000000 + color = 0.250980, 0.184314, 0.113725 + color = 0.345098, 0.529412, 0.349020 + color = 0.176471, 0.000000, 0.129412 + color = 0.960784, 0.631373, 0.831373 + color = 0.854902, 0.000000, 0.666667 + color = 0.462745, 0.160784, 0.286275 + color = 0.741176, 0.898039, 0.000000 + color = 0.764706, 0.760784, 0.364706 + } + } + Voxelization { // check out colorcet (Python) for generating more maps default = glasbey_bw @@ -383,4 +665,16 @@ FARConfig color = 0.764706, 0.760784, 0.364706 } } + + Occlusion { + useRaycaster = false + jobsPerThread = 3 + maxJobs = 10 + // 1000 points produces typical misses 2-3 degrees when optimized for average miss distance. + fibonacciLatticeSize = 2000 + maxRaycastDimension = 100 + raycastResolution = 0.1 + resetInterval = 180 + velocityThreshold = 0.01 + } } diff --git a/GameData/FerramAerospaceResearch/FARVoxelGeometryOverrides.cfg b/GameData/FerramAerospaceResearch/FARVoxelGeometryOverrides.cfg index ab0e8c8ee..b8e712da6 100644 --- a/GameData/FerramAerospaceResearch/FARVoxelGeometryOverrides.cfg +++ b/GameData/FerramAerospaceResearch/FARVoxelGeometryOverrides.cfg @@ -193,6 +193,13 @@ %forceUseMeshes = true } } +@PART[mk1pod_v2]:AFTER[FerramAerospaceResearch] +{ + @MODULE[GeometryPartModule] + { + %forceUseMeshes = true + } +} @PART[SSME]:AFTER[FerramAerospaceResearch] { @MODULE[GeometryPartModule] @@ -281,3 +288,40 @@ { } } + +@PART[largeFanBlade]:AFTER[FerramAerospaceResearch] +{ + !MODULE[GeometryPartModule] {} +} +@PART[largeHeliBlade]:AFTER[FerramAerospaceResearch] +{ + !MODULE[GeometryPartModule] {} +} +@PART[largePropeller]:AFTER[FerramAerospaceResearch] +{ + !MODULE[GeometryPartModule] {} +} +@PART[mediumFanBlade]:AFTER[FerramAerospaceResearch] +{ + !MODULE[GeometryPartModule] {} +} +@PART[mediumHeliBlade]:AFTER[FerramAerospaceResearch] +{ + !MODULE[GeometryPartModule] {} +} +@PART[mediumPropeller]:AFTER[FerramAerospaceResearch] +{ + !MODULE[GeometryPartModule] {} +} +@PART[smallFanBlade]:AFTER[FerramAerospaceResearch] +{ + !MODULE[GeometryPartModule] {} +} +@PART[smallHeliBlade]:AFTER[FerramAerospaceResearch] +{ + !MODULE[GeometryPartModule] {} +} +@PART[smallPropeller]:AFTER[FerramAerospaceResearch] +{ + !MODULE[GeometryPartModule] {} +} diff --git a/GameData/FerramAerospaceResearch/Plugins/FerramAerospaceResearch.Base.dll b/GameData/FerramAerospaceResearch/Plugins/FerramAerospaceResearch.Base.dll index b1305ab7f..f97c1e33f 100644 Binary files a/GameData/FerramAerospaceResearch/Plugins/FerramAerospaceResearch.Base.dll and b/GameData/FerramAerospaceResearch/Plugins/FerramAerospaceResearch.Base.dll differ diff --git a/GameData/FerramAerospaceResearch/Plugins/FerramAerospaceResearch.dll b/GameData/FerramAerospaceResearch/Plugins/FerramAerospaceResearch.dll index 550f12b90..b17e6049b 100644 Binary files a/GameData/FerramAerospaceResearch/Plugins/FerramAerospaceResearch.dll and b/GameData/FerramAerospaceResearch/Plugins/FerramAerospaceResearch.dll differ diff --git a/GameData/FerramAerospaceResearch/Plugins/ferramGraph.dll b/GameData/FerramAerospaceResearch/Plugins/ferramGraph.dll index a0a7e978e..751316056 100644 Binary files a/GameData/FerramAerospaceResearch/Plugins/ferramGraph.dll and b/GameData/FerramAerospaceResearch/Plugins/ferramGraph.dll differ diff --git a/GameData/FerramAerospaceResearch/Textures/icon_button_stock.png b/GameData/FerramAerospaceResearch/Textures/icon_button_stock.png index 89e1e82c8..cb81765cf 100644 Binary files a/GameData/FerramAerospaceResearch/Textures/icon_button_stock.png and b/GameData/FerramAerospaceResearch/Textures/icon_button_stock.png differ diff --git a/README.md b/README.md index 4aded61ed..c20687e2d 100644 --- a/README.md +++ b/README.md @@ -1,70 +1,92 @@ -Ferram Aerospace Research Continued v0.16.0.0 "Mader" -========================= +# Ferram Aerospace Research Continued v0.16.0.2 "Mader" + +========================= Aerodynamics model for Kerbal Space Program - Serious thanks: - * a.g., for tons of bugfixes and code-refactorings - * stupid_chris, for the RealChuteLite implementation - * Taverius, for correcting a ton of incorrect values - * Tetryds, for finding lots of bugs and issues and not letting me get away with them, and work on example crafts - * sarbian, for refactoring code for working with MechJeb, and the Module Manager updates - * ialdabaoth (who is awesome), who originally created Module Manager - * Regex, for adding RPM support - * DaMichel, for some ferramGraph updates and some control surface-related features - * Duxwing, for copy editing the readme - - CompatibilityChecker by Majiir, BSD 2-clause http://opensource.org/licenses/BSD-2-Clause +Serious thanks: + +* a.g., for tons of bugfixes and code-refactorings +* stupid_chris, for the RealChuteLite implementation +* Taverius, for correcting a ton of incorrect values +* Tetryds, for finding lots of bugs and issues and not letting me get away with them, and work on example crafts +* sarbian, for refactoring code for working with MechJeb, and the Module Manager updates +* ialdabaoth (who is awesome), who originally created Module Manager +* Regex, for adding RPM support +* DaMichel, for some ferramGraph updates and some control surface-related features +* Duxwing, for copy editing the readme + +CompatibilityChecker by Majiir, BSD 2-clause [http://opensource.org/licenses/BSD-2-Clause](http://opensource.org/licenses/BSD-2-Clause) - Part.cfg changes powered by sarbian & ialdabaoth's ModuleManager plugin; used with permission - http://forum.kerbalspaceprogram.com/threads/55219 +Part.cfg changes powered by sarbian & ialdabaoth's ModuleManager plugin; used with permission +[http://forum.kerbalspaceprogram.com/threads/55219](http://forum.kerbalspaceprogram.com/threads/55219) - ModularFLightIntegrator by Sarbian, Starwaster and Ferram4, MIT: http://opensource.org/licenses/MIT - http://forum.kerbalspaceprogram.com/threads/118088 +ModularFLightIntegrator by Sarbian, Starwaster and Ferram4, MIT: [http://opensource.org/licenses/MIT](http://opensource.org/licenses/MIT) +[http://forum.kerbalspaceprogram.com/threads/118088](http://forum.kerbalspaceprogram.com/threads/118088) - Toolbar integration powered by blizzy78's Toolbar plugin; used with permission - http://forum.kerbalspaceprogram.com/threads/60863 +Toolbar integration powered by blizzy78's Toolbar plugin; used with permission +[http://forum.kerbalspaceprogram.com/threads/60863](http://forum.kerbalspaceprogram.com/threads/60863) -Source available at: https://github.com/ferram4/Ferram-Aerospace-Research +Source available at: [https://github.com/dkavolis/Ferram-Aerospace-Research](https://github.com/dkavolis/Ferram-Aerospace-Research) ----------------------------------------------- ----------------- INSTALLATION ---------------- ----------------------------------------------- +## Installation Install by merging the GameData folder in the zip with the GameData folder in your KSP install ModuleManager and ModularFlightIntegrator are REQUIRED for FAR to work properly. Failing to copy this over will result in strange errors. ------------------------------------------------------ ----------------- LEGACY WING CONFIGS ---------------- ------------------------------------------------------ +## Legacy wing configs Sample Part.cfg: For wings ------------------------------------ -``` + +```cfg MODULE { - name = FARControllableSurface / FARWingAerodynamicModel - b_2 = 0.5 //distance from wing root to tip; semi-span - MAC = 0.5 //Mean Aerodynamic Chord - nonSideAttach = 0 //0 for canard-like / normal wing pieces, 1 for ctrlsurfaces attached to the back of other wing parts - TaperRatio = 0.7 //Ratio of tip chord to root chord generally < 1, must be > 0 - MidChordSweep = 25 //Sweep angle in degrees; measured down the center of the span / midchord position - maxdeflect = 15 //Default maximum deflection value; only used by FARControlableSurface - controlSurfacePivot = 1, 0, 0; //Local vector that obj_ctrlSrf pivots about; defaults to 1, 0, 0 (right) - ctrlSurfFrac = 0.2 //Value from 0-1, percentage of the part that is a flap; only used by FARControlableSurface + name = FARControllableSurface / FARWingAerodynamicModel + b_2 = 0.5 // distance from wing root to tip; semi-span + MAC = 0.5 // Mean Aerodynamic Chord + nonSideAttach = 0 // 0 for canard-like / normal wing pieces, 1 for ctrlsurfaces attached to the back of other wing parts + TaperRatio = 0.7 // Ratio of tip chord to root chord generally < 1, must be > 0 + MidChordSweep = 25 // Sweep angle in degrees; measured down the center of the span / midchord position + maxdeflect = 15 // Default maximum deflection value; only used by FARControlableSurface + controlSurfacePivot = 1, 0, 0; // Local vector that obj_ctrlSrf pivots about; defaults to 1, 0, 0 (right) + ctrlSurfFrac = 0.2 // Value from 0-1, percentage of the part that is a flap; only used by FARControlableSurface } ``` -For control surfaces, use above but replace FARWingAerodynamicModel with FARControllableSurface and add maxdeflect value +For control surfaces, use above but replace `FARWingAerodynamicModel` with `FARControllableSurface` and add `maxdeflect` value Set all the other winglet/control surface values to zero +## CHANGELOG + +0.16.0.2V "Mader"------------------------------------ + +Updated KSP version 1.11 +Update to MFI 1.2.9 + +Fixed Mk1pod.v2 voxelization by switching to mesh voxelization, colliders are missing top and bottom planes resulting in shell-only voxelization +Rotor blades are no longer voxelized +Reduced submerged lift and drag, multipliers are controlled by `FARConfig/Settings/submerged[Drag|Lift]Multiplier` with default value of 0.25 +Renamed FARWind to FARAtmosphere and added overrides for gas properties + +0.16.0.1V "Mader"------------------------------------ -CHANGELOG -======================================================= -0.16.0.0V "Mader"------------------------------------ +Resized (again) toolbar icon to 64x64 +All meshes in `TransparentFX` layer are ignored for voxelization, previously only visible non-skinned meshes had this check ([f6a005d](https://github.com/dkavolis/Ferram-Aerospace-Research/commit/f6a005d6759e9de97434ef75d2da336c45931aad)) +Improve async config loading and saving ([9e67b32](https://github.com/dkavolis/Ferram-Aerospace-Research/commit/9e67b32878c9fb872515b3f8ea41135ac23a5718)) +Enable debug voxels in flight mode ([5560079](https://github.com/dkavolis/Ferram-Aerospace-Research/commit/5560079e6682e762dfff53ee4422979b90998b69)) with: + +```cfg +@FARConfig:FINAL { + @Voxelization { + %debugInFlight = true + } +} +``` + +0.16.0.0V "Mader"------------------------------------ Update to MM 4.1.4 Update to KSP 1.10 @@ -142,7 +164,7 @@ Fix NRE spam on EVA [#43](https://github.com/dkavolis/Ferram-Aerospace-Research/ 0.15.10.0V "Lundgren"------------------------------------ -**Note for Kopernicus users: DO NOT overwrite MFI that comes with Kopernicus since it is locked to that particular version** +**Note for Kopernicus users: DO NOT overwrite MFI that comes with Kopernicus since it is locked to that particular version.** Recompiled for KSP 1.7 @@ -152,12 +174,14 @@ Voxelization correctly handles jettison transforms with part variants ([#39](htt Fix voxelization of `InflatableHeatShield` ([#39](https://github.com/dkavolis/Ferram-Aerospace-Research/pull/39)) Fixed voxelization of simple heat shields ([#37](https://github.com/dkavolis/Ferram-Aerospace-Research/pull/37)) Added additional nodes to `GeometryPartModule` ([#37](https://github.com/dkavolis/Ferram-Aerospace-Research/pull/37), [#39](https://github.com/dkavolis/Ferram-Aerospace-Research/pull/39), see PRs for more details). The new nodes should allow parts to be voxelized much closer to what is visible and handle animations better: + * `ignoreTransform` (string) * `ignoreIfNoRenderer` (bool) * `unignoreTransform` (string) * `rebuildOnAnimation` (bool) NRE fixes ([#36](https://github.com/dkavolis/Ferram-Aerospace-Research/pull/36)): + * Trying to display debug voxels with no parts in the editor * Occasional NRE when voxelizing vehicle (due to race conditions?) * When force closing the game from the editor with debug voxels displayed @@ -168,7 +192,7 @@ Enable/disable FAR speed display on the navball from FARAPI ([#33](https://githu 0.15.9.7V "Lumley"------------------------------------ -**Note for Kopernicus users: DO NOT overwrite MFI that comes with Kopernicus since it is locked to that particular version** +**Note for Kopernicus users: DO NOT overwrite MFI that comes with Kopernicus since it is locked to that particular version.** Update to MM 4.0.2 @@ -179,7 +203,7 @@ Enlarged debug voxel texture for higher fidelity ([#18](https://github.com/dkavo 0.15.9.6V "Lin"------------------------------------ -**Note for Kopernicus users: DO NOT overwrite MFI that comes with Kopernicus since it is locked to that particular version** +**Note for Kopernicus users: DO NOT overwrite MFI that comes with Kopernicus since it is locked to that particular version.** Update for KSP 1.6 Update to MM 3.1.2 @@ -210,7 +234,7 @@ material (source is in Assets) Fixed curve colors in transonic design defaulting to purple Moved asset bundle from shaders to Assets Replaced icons with new ones (source is in icons, feel free to submit better ones) - + Removed all All Rights Reserved files 0.15.9.1V "Liepmann"------------------------------------ @@ -347,7 +371,6 @@ Change units for specific excess power in the Flight Data readout to be W/kg on Fix a critical error that prevented voxelizations of Kerbals or any vehicles that had Kerbals riding in a command seat - 0.15.5.6V "Jacobs"------------------------------------ Update to MM 2.6.18 @@ -359,7 +382,6 @@ Fix unrealistically high numbers in indicated airspeed at higher Mach numbers Lower critical Mach number for slender vehicles with sudden bulges and waviness in their cross-section - 0.15.5.5V "Hugoniot"------------------------------------ Fix an inconsistency in calculations of sonic drag @@ -373,7 +395,6 @@ Fix overheat interaction on load with ModuleCoreHeat Fix FAR breaking on attempts to load Training or Scenario scenes Fix spoilers and flaps not updating with settings in the editor - 0.15.5.4V "Hoerner"------------------------------------ Adjust water drag for better splashdown performance @@ -381,7 +402,6 @@ Fix a serious voxelization issue with ModuleJettison, most notable in leading to Fix an issue where 3rd-party voxelization updates could sometimes break the editor GUI and CoL Fix a serious issue that could lead to spontaneous crashes on aero initialization (either VAB / SPH CoL, editor GUI, or going to flight) - 0.15.5.3V "von Helmholtz"------------------------------------ Upgrade to MM 2.6.13 @@ -398,7 +418,6 @@ Fix some other control surface in-flight changes oddities Fix Firehound MS example craft action groups not acting in symmetry Added E42 example craft by tetryds - 0.15.5.2V "Helmbold"------------------------------------ Compatibility with KSP 1.0.5 @@ -427,7 +446,6 @@ Fix for vehicle aerodynamics breaking under certain vessel-part configurations Updated FAR Firehound MS, FAR SkyEye, FAR Montauk Shuttle to be more useful in KSP 1.0.5 - 0.15.5.1V "Hayes"------------------------------------ Upgrade to MM 2.6.8 @@ -440,7 +458,6 @@ Fix KerbalEVAs working with Vanguard Parachutes Fix for a critical error where detached boosters, weapons, debris, etc. would not have drag properties - 0.15.5V "Haack"------------------------------------ Upgrade to MM 2.6.7 @@ -468,7 +485,6 @@ Tweaked subsonic drag downwards to get more accurate results with fixed AJE prop Tweaked wing mass downwards slightly Tweaked wing strength power to result in greater strength from lower-mass wings - 0.15.4.1V "Goldstein"------------------------------------ Re-implementation of aero viz coloration, thanks to mjn33 @@ -488,10 +504,11 @@ Update to MFI 1.1.1, fixes gimbaling bug below 750 m/s on short vehicles Update win64 check code to MM method Added internal ducted area feature: - * Area ducted through a vehicle from intakes to airbreathing engines will be removed from cross-section - * Adjusts area ruling to properly model air that flows through the vehicle as opposed to around it - * Does not count for airflow through switch-backing or reversing ducts; no benefits for intakes that feed upstream engines - * Supports stock intake part + airbreathing engine part setups, AJE intake part + airbreathing engine part setups, and combined intake + engine part setups + +* Area ducted through a vehicle from intakes to airbreathing engines will be removed from cross-section +* Adjusts area ruling to properly model air that flows through the vehicle as opposed to around it +* Does not count for airflow through switch-backing or reversing ducts; no benefits for intakes that feed upstream engines +* Supports stock intake part + airbreathing engine part setups, AJE intake part + airbreathing engine part setups, and combined intake + engine part setups Slight improvement to Flight Data readouts from mjn33 Toggle gear button now states "Raise" or "Lower" gear for clarity @@ -510,7 +527,6 @@ Fixed Firespitter gear not responding to Toggle Gear button Added support for adjustable landing gear in Toggle Gear button Stopgap fix to unintended voxelization of USI Warp Drive bubbles - 0.15.3.1V "Garabedian"------------------------------------ Compatibility with KSP v1.0.3 and thermal changes @@ -573,7 +589,6 @@ Disable control surfaces auto-response below 5 m/s to prevent wacky flailing dur Change compatibility settings to reject KSP 1.0.0, which is not compatible with RealChuteLite Updated save-load method to save more reliably and not throw exceptions - 0.15V "Euler"------------------------------------ Compatibility with KSP 1.0, 1.0.1, and 1.0.2 @@ -581,29 +596,31 @@ Upgraded to MM 2.6.3 Introduction of ModularFlightIntegrator for interfacing with KSP drag / heating systems without interference with other mods Replaced previous part-based drag model with new vessel-centered, voxel-powered model: - * Generates voxel model of vehicle using part meshes, accounting for part clipping - * Drag is calculated for vehicle as a whole, rather than linear combination of parts - * Payload fairings and cargo bays are emergent from code and do not require special treatment with configs - * Area ruling of vehicles is accounted for; unsmooth area distributions will result in very high drag at and above Mach 1 - * Body lift accounts for vehicle shape in determining potential and viscous flow contributions - * Areas exposed to outside used for stock heating calculations + +* Generates voxel model of vehicle using part meshes, accounting for part clipping +* Drag is calculated for vehicle as a whole, rather than linear combination of parts +* Payload fairings and cargo bays are emergent from code and do not require special treatment with configs +* Area ruling of vehicles is accounted for; unsmooth area distributions will result in very high drag at and above Mach 1 +* Body lift accounts for vehicle shape in determining potential and viscous flow contributions +* Areas exposed to outside used for stock heating calculations Performance optimizations in legacy wing model Jet engine windmilling drag accounted for at intakes Editor GUI improvements including: - * Greater clarity in AoA / Mach sweep tab - * Stability deriv GUI math modified for improved accuracy - * Stability deriv simulation tweaked to fix some minor issues in displaying and calculating response - * Addition of a Transonic Design tab that displays cross-section distribution and drag at Mach 1 for area ruling purposes + +* Greater clarity in AoA / Mach sweep tab +* Stability deriv GUI math modified for improved accuracy +* Stability deriv simulation tweaked to fix some minor issues in displaying and calculating response +* Addition of a Transonic Design tab that displays cross-section distribution and drag at Mach 1 for area ruling purposes Parachute methods have been replaced with RealChuteLite implementation by stupid_chris: - * Less severe parachute deployment - * Parachutes melt / break in high Mach number flows - * No interference with RealChute + * Less severe parachute deployment + * Parachutes melt / break in high Mach number flows + * No interference with RealChute Changes to FARAPI to get information faster - + FARBasicDragModel, FARPayloadFairingModule, FARCargoBayModule are now obsolete and removed from the codebase Extensive reorganizing of source to reduce spaghetti and improve maintainability @@ -634,7 +651,6 @@ Included FAR Colibri, a VTOL by Tetryds as an example craft Bugfixes: Fixed an issue preventing loading custom-defined FARBasicDragModels - 0.14.6V------------------------------------ Features: Modified skin friction variation with M and Re to closer to that expected by using the Knudsen number @@ -662,7 +678,6 @@ Bugfixes: Fix Stab Deriv GUI from breaking for altitudes above atmosphere Fix flaps and spoilers not functioning with negative deflections - 0.14.5V------------------------------------ Features: Skin friction drag now varies with Reynolds number; this means much higher skin friction drags at higher altitudes @@ -687,29 +702,26 @@ Stability Deriv tab now takes entry in terms of planet, altitude and Mach Number Stability Deriv tab now accounts for reduced gravity due to high speeds Contributed by HoneyFox: - Pitch damper now has an additional gain for greater tuning - Control surfaces can now be set to deflect in response to local AoA changes - Control surfaces are not On/Off for a given control direction; can be scaled from -100% to 100% for each + Pitch damper now has an additional gain for greater tuning + Control surfaces can now be set to deflect in response to local AoA changes + Control surfaces are not On/Off for a given control direction; can be scaled from -100% to 100% for each Contributed by Bitronic: - Full Tweakscale Support + Full Tweakscale Support BugFixes: Fixed no shielding with some payload fairings (particularly resized procedural fairings) Fixed aero tinting blocking tinting from other mods - - 0.14.3.2v------------------------------------ Features: Contributed by Da Michel: - Airspeed settings change readouts in cockpits + Airspeed settings change readouts in cockpits Bugfixes: Fixed serious issues with the wing interaction code Fixed an issue where wind velocity was applied in the opposite direction that was expected - 0.14.3.1v------------------------------------ Features: Improved performance in editor and flight for vessel configuration changes @@ -719,16 +731,15 @@ Bugfixes: Fixed neverending stall resulting from wing interactions with sudden changes in velocity vector direction Fixed flight GUI issues when passing another vehicle - 0.14.3v------------------------------------ Features: Refactored wing interaction code: - Wing interactions should be smoother - Code should be less processor intensive + Wing interactions should be smoother + Code should be less processor intensive Upgrade to ModuleManager v2.5.1 Added stall visualization to aero force visualization -Added ability to scale wing mass up or down for additional strength / weight savings (addedby NathanKell) +Added ability to scale wing mass up or down for additional strength / weight savings (addedby NathanKell) Improved cargo bay and payload fairing detection algorithm Tweaks: @@ -754,16 +765,15 @@ See and dump FAR module data in the VAB / SPH using the Editor GUI Some runtime optimizations Contributed by Da Michel: - Implement separate deflection speeds for flaps / spoilers - Allow preferred default action groups for spoilers / flaps + Implement separate deflection speeds for flaps / spoilers + Allow preferred default action groups for spoilers / flaps Contributed by regex: - Add some RPM integration + Add some RPM integration Contributed by Ippo: - FARWind class for 3rd-party wind implementation - + FARWind class for 3rd-party wind implementation Bugfixes: Fixed some vessel-switching FAR GUI issues Fixed control surface reversal on undocking or backwards root part selection Fixed some issues involving CoL position with wings when dealing with parts that have multiple colliders -Fixed some payload fairing and cargo bay part detection issues +Fixed some payload fairing and cargo bay part detection issues diff --git a/Unity/FerramAerospaceResearch/Assets/Plugins/FerramAerospaceResearch.Base.dll b/Unity/FerramAerospaceResearch/Assets/Plugins/FerramAerospaceResearch.Base.dll index b1305ab7f..f97c1e33f 100644 Binary files a/Unity/FerramAerospaceResearch/Assets/Plugins/FerramAerospaceResearch.Base.dll and b/Unity/FerramAerospaceResearch/Assets/Plugins/FerramAerospaceResearch.Base.dll differ diff --git a/buildtools b/buildtools index e9ed8fda2..aeada3e99 160000 --- a/buildtools +++ b/buildtools @@ -1 +1 @@ -Subproject commit e9ed8fda26b1d205f19525a6adb641b0614d0b6b +Subproject commit aeada3e99e6be07b71e073824153f4d8790bbbb8 diff --git a/config.json b/config.json index 1c2d39d0e..0edb9fbd7 100644 --- a/config.json +++ b/config.json @@ -7,13 +7,13 @@ "ModDir": "$(SolutionDir)$(ModDirRelative)", "PluginDir": "$(ModDir)Plugins/", "AssetDir": "$(ModDir)Assets/", - "KSP_DIR_INSTALL": "C:/Zaidimai/KSP 1.10/", + "KSP_DIR_INSTALL": "C:/Zaidimai/KSP 1.11/", "KSPGameData": "$(KSP_DIR_INSTALL)GameData/", "GameDir": "$(KSPGameData)$(ModName)/", "VersionMajor": 0, "VersionMinor": 16, "VersionBuild": 0, - "VersionRevision": 0, + "VersionRevision": 2, "VersionName": "Mader", "Year": 2020, "NumericalVersion": "$(VersionMajor).$(VersionMinor).$(VersionBuild).$(VersionRevision)", @@ -22,7 +22,7 @@ "KSPMajorMin": 1, "KSPMajorMax": 1, "KSPMinorMin": 8, - "KSPMinorMax": 10, + "KSPMinorMax": 11, "UnityDir": "$(SolutionDir)Unity/$(ModName)/", "AssetBundleDir": "$(UnityDir)AssetBundles/", "UnityAssetsDir": "$(UnityDir)Assets/", diff --git a/ferramGraph/Properties/AssemblyInfo.cs b/ferramGraph/Properties/AssemblyInfo.cs index e0a91c628..eec25b0be 100644 --- a/ferramGraph/Properties/AssemblyInfo.cs +++ b/ferramGraph/Properties/AssemblyInfo.cs @@ -1,4 +1,4 @@ -using System.Reflection; +using System.Reflection; using System.Runtime.InteropServices; // General Information about an assembly is controlled through the following diff --git a/ferramGraph/ferramGraph.csproj b/ferramGraph/ferramGraph.csproj index aec3d90cc..f1298f07a 100644 --- a/ferramGraph/ferramGraph.csproj +++ b/ferramGraph/ferramGraph.csproj @@ -1,76 +1,76 @@ - - - - Debug - AnyCPU - 8.0.30703 - 2.0 - {0CCFED24-728C-432B-9FDC-30BEF1116EDE} - Library - Properties - ferram4 - ferramGraph - v4.8 - 512 - - - 8 - - - true - portable - false - $(SolutionDir)bin\$(Configuration)\ - DEBUG;TRACE - prompt - 4 - false - - - portable - true - $(SolutionDir)bin\$(Configuration)\ - TRACE - prompt - 4 - false - - - - False - $(KSP_DIR_BUILD)KSP_x64_Data\Managed\Assembly-CSharp.dll - - - - - False - $(KSP_DIR_BUILD)KSP_x64_Data\Managed\UnityEngine.dll - - - $(KSP_DIR_BUILD)KSP_x64_Data\Managed\UnityEngine.CoreModule.dll - - - $(KSP_DIR_BUILD)KSP_x64_Data\Managed\UnityEngine.IMGUIModule.dll - - - $(KSP_DIR_BUILD)KSP_x64_Data\Managed\UnityEngine.TextRenderingModule.dll - - - - - - - - - - - $(PostBuildCommand) "$(TargetPath)" - - + + + + Debug + AnyCPU + 8.0.30703 + 2.0 + {0CCFED24-728C-432B-9FDC-30BEF1116EDE} + Library + Properties + ferram4 + ferramGraph + v4.8 + 512 + + + 9 + + + true + portable + false + $(SolutionDir)bin\$(Configuration)\ + DEBUG;TRACE + prompt + 4 + false + + + portable + true + $(SolutionDir)bin\$(Configuration)\ + TRACE + prompt + 4 + false + + + + False + $(KSP_DIR_BUILD)KSP_x64_Data\Managed\Assembly-CSharp.dll + + + + + False + $(KSP_DIR_BUILD)KSP_x64_Data\Managed\UnityEngine.dll + + + $(KSP_DIR_BUILD)KSP_x64_Data\Managed\UnityEngine.CoreModule.dll + + + $(KSP_DIR_BUILD)KSP_x64_Data\Managed\UnityEngine.IMGUIModule.dll + + + $(KSP_DIR_BUILD)KSP_x64_Data\Managed\UnityEngine.TextRenderingModule.dll + + + + + + + + + + + $(PostBuildCommand) "$(TargetPath)" + + \ No newline at end of file diff --git a/ferramGraph/ferram_graph.cs b/ferramGraph/ferram_graph.cs index d838f0549..fce387f18 100644 --- a/ferramGraph/ferram_graph.cs +++ b/ferramGraph/ferram_graph.cs @@ -1,4 +1,4 @@ -/* Name: FerramGraph (Graph GUI Plugin) +/* Name: FerramGraph (Graph GUI Plugin) * Version: 1.3 (KSP 0.22+) Copyright 2020, Michael Ferrara, aka Ferram4 diff --git a/icons/icon_button.svg b/icons/icon_button.svg index f2e200327..b186d0ffb 100644 --- a/icons/icon_button.svg +++ b/icons/icon_button.svg @@ -17,8 +17,8 @@ inkscape:version="0.92.4 (5da689c313, 2019-01-14)" sodipodi:docname="icon_button.svg" inkscape:export-filename="D:\git\Ferram-Aerospace-Research\GameData\FerramAerospaceResearch\Textures\icon_button_stock.png" - inkscape:export-xdpi="96" - inkscape:export-ydpi="96"> + inkscape:export-xdpi="161.6842" + inkscape:export-ydpi="161.6842"> image/svg+xml - +