Skip to content

Commit

Permalink
Merge branch 'dev' into DisableMakingHistoryDLCFeatures
Browse files Browse the repository at this point in the history
  • Loading branch information
gotmachine authored Apr 4, 2024
2 parents d144b57 + b5a4006 commit b6bebd7
Show file tree
Hide file tree
Showing 9 changed files with 503 additions and 44 deletions.
2 changes: 1 addition & 1 deletion GameData/KSPCommunityFixes/KSPCommunityFixes.version
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"NAME": "KSPCommunityFixes",
"URL": "https://raw.githubusercontent.com/KSPModdingLibs/KSPCommunityFixes/master/GameData/KSPCommunityFixes/KSPCommunityFixes.version",
"DOWNLOAD": "https://github.com/KSPModdingLibs/KSPCommunityFixes/releases",
"VERSION": {"MAJOR": 1, "MINOR": 34, "PATCH": 1, "BUILD": 0},
"VERSION": {"MAJOR": 1, "MINOR": 35, "PATCH": 0, "BUILD": 0},
"KSP_VERSION": {"MAJOR": 1, "MINOR": 12, "PATCH": 5},
"KSP_VERSION_MIN": {"MAJOR": 1, "MINOR": 8, "PATCH": 0},
"KSP_VERSION_MAX": {"MAJOR": 1, "MINOR": 12, "PATCH": 5}
Expand Down
4 changes: 4 additions & 0 deletions GameData/KSPCommunityFixes/Settings.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -411,6 +411,10 @@ KSP_COMMUNITY_FIXES
// Allow a min value of 0.02 instead of 0.03 for the "Max Physics Delta-Time Per Frame" main menu setting.
LowerMinPhysicsDTPerFrame = true
// Improve engine exhaust damage and solar panel line of sight raycasts performance by avoiding extra physics
// state synchronization and caching solar panels scaled space raycasts results.
OptimizedModuleRaycasts = true
// ##########################
// Modding
// ##########################
Expand Down
1 change: 1 addition & 0 deletions KSPCommunityFixes/KSPCommunityFixes.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@
<Compile Include="Modding\ReflectionTypeLoadExceptionHandler.cs" />
<Compile Include="Performance\FewerSaves.cs" />
<Compile Include="Performance\ConfigNodePerf.cs" />
<Compile Include="Performance\OptimizedModuleRaycasts.cs" />
<Compile Include="Performance\PQSCoroutineLeak.cs" />
<Compile Include="Performance\PQSUpdateNoMemoryAlloc.cs" />
<Compile Include="Performance\ProgressTrackingSpeedBoost.cs" />
Expand Down
5 changes: 5 additions & 0 deletions KSPCommunityFixes/Library/Extensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,5 +28,10 @@ public static string AssemblyQualifiedName(this object obj)
Type type = obj.GetType();
return $"{type.Assembly.GetName().Name}:{type.Name}";
}

public static bool IsPAWOpen(this Part part)
{
return part.PartActionWindow.IsNotNullOrDestroyed() && part.PartActionWindow.isActiveAndEnabled;
}
}
}
14 changes: 13 additions & 1 deletion KSPCommunityFixes/Performance/FastLoader.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
using System.Linq;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.InteropServices;
using System.Threading;
using TMPro;
using Unity.Collections;
Expand Down Expand Up @@ -1312,7 +1313,18 @@ private TextureInfo LoadDDS()
}
else
{
texture2D.LoadRawTextureData(binaryReader.ReadBytes((int)(binaryReader.BaseStream.Length - binaryReader.BaseStream.Position)));
int position = (int)binaryReader.BaseStream.Position;
GCHandle pinnedHandle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
try
{
IntPtr ptr = Marshal.UnsafeAddrOfPinnedArrayElement(buffer, position);
texture2D.LoadRawTextureData(ptr, dataLength - position);
}
finally
{
pinnedHandle.Free();
}

texture2D.Apply(updateMipmaps: false, makeNoLongerReadable: true);
}
}
Expand Down
359 changes: 321 additions & 38 deletions KSPCommunityFixes/Performance/MemoryLeaks.cs

Large diffs are not rendered by default.

152 changes: 152 additions & 0 deletions KSPCommunityFixes/Performance/OptimizedModuleRaycasts.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
using System;
using HarmonyLib;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;
using UnityEngine;

namespace KSPCommunityFixes.Performance
{
internal class OptimizedModuleRaycasts : BasePatch
{
private static readonly WaitForFixedUpdate waitForFixedUpdate = new WaitForFixedUpdate();
private static bool partModulesSyncedOnceInFixedUpdate = false;

protected override Version VersionMin => new Version(1, 12, 3);

protected override void ApplyPatches(List<PatchInfo> patches)
{
patches.Add(
new PatchInfo(PatchMethodType.Transpiler,
AccessTools.Method(typeof(ModuleEngines), nameof(ModuleEngines.EngineExhaustDamage)),
this));

patches.Add(
new PatchInfo(PatchMethodType.Prefix,
AccessTools.Method(typeof(ModuleDeployableSolarPanel), nameof(ModuleDeployableSolarPanel.CalculateTrackingLOS)),
this));

KSPCommunityFixes.Instance.StartCoroutine(ResetSyncOnFixedEnd());
}

static IEnumerator ResetSyncOnFixedEnd()
{
while (true)
{
partModulesSyncedOnceInFixedUpdate = false;
lastVesselId = 0;
lastTrackingTransformId = 0;
yield return waitForFixedUpdate;
}
}

static IEnumerable<CodeInstruction> ModuleEngines_EngineExhaustDamage_Transpiler(IEnumerable<CodeInstruction> instructions)
{
MethodInfo m_Physics_RayCast = AccessTools.Method(typeof(Physics), nameof(Physics.Raycast), new[] { typeof(Vector3), typeof(Vector3), typeof(RaycastHit).MakeByRefType(), typeof(float), typeof(int) });
MethodInfo m_RaycastNoSync = AccessTools.Method(typeof(OptimizedModuleRaycasts), nameof(RaycastNoSync));

foreach (CodeInstruction instruction in instructions)
{
if (instruction.Calls(m_Physics_RayCast))
{
instruction.operand = m_RaycastNoSync;
}

yield return instruction;
}
}

private static int lastVesselId;
private static int lastTrackingTransformId;
private static bool lastHasLoS;
private static string lastBlocker;

private static bool ModuleDeployableSolarPanel_CalculateTrackingLOS_Prefix(ModuleDeployableSolarPanel __instance, Vector3 trackingDirection, ref string blocker, out bool __result)
{
if (__instance.part.ShieldedFromAirstream && __instance.applyShielding)
{
blocker = "aero shielding";
__result = false;
return false;
}

int trackingTransformId = __instance.trackingTransformLocal.GetInstanceID();
int vesselId = __instance.vessel.GetInstanceID();
if (lastTrackingTransformId == trackingTransformId && lastVesselId == vesselId)
{
if (!lastHasLoS)
{
__result = false;
blocker = lastBlocker;
return false;
}
}
else
{
lastTrackingTransformId = trackingTransformId;
lastVesselId = vesselId;

Vector3 scaledVesselPos = ScaledSpace.LocalToScaledSpace(__instance.vessel.transform.position);
Vector3 scaledDirection = (ScaledSpace.LocalToScaledSpace(__instance.trackingTransformLocal.position) - scaledVesselPos).normalized;

if (Physics.Raycast(scaledVesselPos, scaledDirection, out RaycastHit scaledHit, float.MaxValue, __instance.planetLayerMask) && scaledHit.transform.NotDestroyedRefNotEquals(__instance.trackingTransformScaled))
{
__instance.hit = scaledHit; // just to ensure this is populated
lastBlocker = scaledHit.transform.gameObject.name; // allocates a string
blocker = lastBlocker;
lastHasLoS = false;
__result = false;
return false;
}

lastHasLoS = true;
lastBlocker = null;
}

Vector3 localPanelPos = __instance.secondaryTransform.position + trackingDirection * __instance.raycastOffset;
__result = !RaycastNoSync(localPanelPos, trackingDirection, out RaycastHit localhit, float.MaxValue, __instance.defaultLayerMask);
__instance.hit = localhit; // just to ensure this is populated

if (!__result && __instance.part.IsPAWOpen() && localhit.transform.gameObject.IsNotNullOrDestroyed())
{
GameObject hitObject = localhit.transform.gameObject;
if (!ReferenceEquals(hitObject.GetComponent<PQ>(), null))
{
blocker = ModuleDeployableSolarPanel.cacheAutoLOC_438839;
}
else
{
Part partUpwardsCached = FlightGlobals.GetPartUpwardsCached(hitObject);
if (partUpwardsCached.IsNotNullOrDestroyed())
{
blocker = partUpwardsCached.partInfo.title;
}
else
{
string tag = hitObject.tag; // allocates a string
if (tag.Contains("KSC"))
blocker = ResearchAndDevelopment.GetMiniBiomedisplayNameByUnityTag(tag, true);
else
blocker = hitObject.name;
}
}
}

return false;
}

public static bool RaycastNoSync(Vector3 origin, Vector3 direction, out RaycastHit hitInfo, float maxDistance, int layerMask)
{
if (!partModulesSyncedOnceInFixedUpdate)
{
Physics.SyncTransforms();
partModulesSyncedOnceInFixedUpdate = true;
}

Physics.autoSyncTransforms = false;
bool result = Physics.defaultPhysicsScene.Raycast(origin, direction, out hitInfo, maxDistance, layerMask);
Physics.autoSyncTransforms = true;
return result;
}
}
}
4 changes: 2 additions & 2 deletions KSPCommunityFixes/Properties/AssemblyInfo.cs
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
// Revision
//
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.34.1.0")]
[assembly: AssemblyFileVersion("1.35.0.0")]

[assembly: KSPAssembly("KSPCommunityFixes", 1, 34, 1)]
[assembly: KSPAssembly("KSPCommunityFixes", 1, 35, 0)]
[assembly: KSPAssemblyDependency("MultipleModulePartAPI", 1, 0, 0)]
6 changes: 4 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,7 @@ User options are available from the "ESC" in-game settings menu :<br/><img src="
- **IMGUIOptimization** [KSP 1.8.0 - 1.12.5]<br/>Eliminate structural GC allocations and reduce performance overhead of OnGUI() methods. Can provide significant performance gains when having many mods using IMGUI heavily.
- [**CollisionManagerFastUpdate**](https://github.com/KSPModdingLibs/KSPCommunityFixes/issues/174) [KSP 1.11.0 - 1.12.5]<br/>3-4 times faster update of parts inter-collision state, significantly reduce stutter on docking, undocking, decoupling and joint failure events.
- [**LowerMinPhysicsDTPerFrame**](https://github.com/KSPModdingLibs/KSPCommunityFixes/issues/175) [KSP 1.12.3 - 1.12.5]<br/>Allow a min value of 0.02 instead of 0.03 for the "Max Physics Delta-Time Per Frame" main menu setting. This allows for higher and smoother framerate at the expense of the game lagging behind real time.

- [**OptimizedModuleRaycasts**](https://github.com/KSPModdingLibs/KSPCommunityFixes/issues/216) [KSP 1.12.3 - 1.12.5]<br/>Improve engine exhaust damage and solar panel line of sight raycasts performance by avoiding extra physics state synchronization and caching solar panels scaled space raycasts results.

#### API and modding tools
- **MultipleModuleInPartAPI** [KSP 1.8.0 - 1.12.5]<br/>This API allow other plugins to implement PartModules that can exist in multiple occurrence in a single part and won't suffer "module indexing mismatch" persistent data losses following part configuration changes. [See documentation on the wiki](https://github.com/KSPModdingLibs/KSPCommunityFixes/wiki/MultipleModuleInPartAPI).
Expand Down Expand Up @@ -189,8 +189,10 @@ If doing so in the `Debug` configuration and if your KSP install is modified to

### Changelog

##### next
##### 1.35.0
- New KSP performance patch : [**OptimizedModuleRaycasts**](https://github.com/KSPModdingLibs/KSPCommunityFixes/issues/216) [KSP 1.12.3 - 1.12.5] : Improve engine exhaust damage and solar panel line of sight raycasts performance by avoiding extra physics state synchronization and caching solar panels scaled space raycasts results.
- New KSP QoL/performance patch : [**OptionalMakingHistoryDLCFeatures**](https://github.com/KSPModdingLibs/KSPCommunityFixes/issues/218) [KSP 1.12.3 - 1.12.5] : Allow to disable the Making History DLC mission editor and additional launch sites features to decrease memory usage and increase loading speed. The Making History parts will still be available. Can be toggled from the KSPCF in-game settings (requires a restart), or from a MM patch (see `Settings.cfg`)
- **FastLoader** : Improved DDS loading performance by avoiding an extra copy of the DDS data

##### 1.34.1
- Disable BetterEditorUndoRedo when TweakScale/L is installed due to introducing a bug with part attachments in the editor.
Expand Down

0 comments on commit b6bebd7

Please sign in to comment.