Skip to content

Commit 19b280c

Browse files
authored
Remove constant overhead from ModuleSurfaceFX.Update() (#303)
Fix issue #301 : As a part of the OptimizedModuleRaycasts patch, fix ModuleSurfaceFX.Update() performing raycasts (and PhysX-Transform syncs) and other useless computations even when the effects have no chance of appearing. Also fix a bug with the effects not appearing at negative altitudes on ocean-less bodies.
1 parent 431769f commit 19b280c

File tree

2 files changed

+112
-4
lines changed

2 files changed

+112
-4
lines changed

GameData/KSPCommunityFixes/Settings.cfg

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -441,7 +441,8 @@ KSP_COMMUNITY_FIXES
441441
LowerMinPhysicsDTPerFrame = true
442442

443443
// Improve engine exhaust damage and solar panel line of sight raycasts performance by avoiding extra physics
444-
// state synchronization and caching solar panels scaled space raycasts results.
444+
// state synchronization and caching solar panels scaled space raycasts results. Also prevent useless raycasts
445+
// from exhaust ground effects (ModuleSurfaceFX).
445446
OptimizedModuleRaycasts = true
446447

447448
// Faster and minimal GC allocation replacements for Part FindModelTransform*() and FindHeirarchyTransform*()

KSPCommunityFixes/Performance/OptimizedModuleRaycasts.cs

Lines changed: 110 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
using System;
2-
using HarmonyLib;
1+
using HarmonyLib;
2+
using KSPCommunityFixes.Library;
3+
using System;
34
using System.Collections;
45
using System.Collections.Generic;
56
using System.Reflection;
@@ -16,11 +17,13 @@ internal class OptimizedModuleRaycasts : BasePatch
1617

1718
protected override void ApplyPatches()
1819
{
20+
KSPCommunityFixes.Instance.StartCoroutine(ResetSyncOnFixedEnd());
21+
1922
AddPatch(PatchType.Transpiler, typeof(ModuleEngines), nameof(ModuleEngines.EngineExhaustDamage));
2023

2124
AddPatch(PatchType.Prefix, typeof(ModuleDeployableSolarPanel), nameof(ModuleDeployableSolarPanel.CalculateTrackingLOS));
2225

23-
KSPCommunityFixes.Instance.StartCoroutine(ResetSyncOnFixedEnd());
26+
AddPatch(PatchType.Override, typeof(ModuleSurfaceFX), nameof(ModuleSurfaceFX.Update));
2427
}
2528

2629
static IEnumerator ResetSyncOnFixedEnd()
@@ -142,5 +145,109 @@ public static bool RaycastNoSync(Vector3 origin, Vector3 direction, out RaycastH
142145
Physics.autoSyncTransforms = true;
143146
return result;
144147
}
148+
149+
static void ModuleSurfaceFX_Update_Override(ModuleSurfaceFX msFX)
150+
{
151+
if (!HighLogic.LoadedSceneIsFlight || !GameSettings.SURFACE_FX)
152+
return;
153+
154+
if (msFX.engineModule != null)
155+
msFX.fxScale = msFX.engineModule.GetCurrentThrust() / msFX.engineModule.GetMaxThrust() * msFX.fxMax;
156+
else
157+
msFX.fxScale = 0f;
158+
159+
if (msFX.fxScale <= 0f)
160+
{
161+
ModuleSurfaceFX_ResetSrfFX(msFX);
162+
return;
163+
}
164+
165+
if (msFX.vessel.radarAltitude > (msFX.vessel.vesselSize.magnitude + msFX.maxDistance) * 2.5f)
166+
{
167+
ModuleSurfaceFX_ResetSrfFX(msFX);
168+
return;
169+
}
170+
171+
float transformAltitude = 0f;
172+
173+
if (msFX.vessel.mainBody.ocean)
174+
{
175+
transformAltitude = FlightGlobals.getAltitudeAtPos(msFX.trf.position, msFX.vessel.mainBody);
176+
if (transformAltitude < 0f)
177+
{
178+
ModuleSurfaceFX_ResetSrfFX(msFX);
179+
return;
180+
}
181+
}
182+
183+
msFX.raycastHit = Physics.Raycast(msFX.trf.position, msFX.trf.forward, out msFX.hitInfo, msFX.maxDistance, 1073774592);
184+
185+
// added the ocean condition here, fixing the bug where the effect wouldn't show up on non-ocean bodies at negative altitudes
186+
if (msFX.raycastHit && (!msFX.vessel.mainBody.ocean || FlightGlobals.GetSqrAltitude(msFX.hitInfo.point, msFX.vessel.mainBody) >= 0.0))
187+
{
188+
if (msFX.hitInfo.collider.CompareTag("LaunchpadFX"))
189+
{
190+
msFX.hit = ModuleSurfaceFX.SurfaceType.Launchpad;
191+
}
192+
else if (msFX.hitInfo.collider.CompareTag("Wheel_Piston_Collider"))
193+
{
194+
ModuleSurfaceFX_ResetSrfFX(msFX);
195+
return;
196+
}
197+
else
198+
{
199+
msFX.hit = ModuleSurfaceFX.SurfaceType.Terrain;
200+
}
201+
msFX.point = msFX.hitInfo.point;
202+
msFX.normal = msFX.hitInfo.normal;
203+
msFX.distance = msFX.hitInfo.distance;
204+
}
205+
else if (msFX.vessel.mainBody.ocean)
206+
{
207+
if (transformAltitude > msFX.maxDistance)
208+
{
209+
ModuleSurfaceFX_ResetSrfFX(msFX);
210+
return;
211+
}
212+
213+
float downDot = Vector3.Dot(msFX.trf.forward, -msFX.vessel.upAxis);
214+
if (downDot <= 0f)
215+
{
216+
ModuleSurfaceFX_ResetSrfFX(msFX);
217+
return;
218+
}
219+
220+
msFX.normal = msFX.vessel.upAxis;
221+
msFX.distance = transformAltitude / downDot;
222+
msFX.point = msFX.trf.position + msFX.trf.forward * msFX.distance;
223+
msFX.hit = ModuleSurfaceFX.SurfaceType.Water;
224+
}
225+
else
226+
{
227+
ModuleSurfaceFX_ResetSrfFX(msFX);
228+
return;
229+
}
230+
231+
msFX.scaledDistance = Mathf.Pow(1f - msFX.distance / msFX.maxDistance, msFX.falloff);
232+
msFX.ScaledFX = msFX.fxScale * msFX.scaledDistance;
233+
msFX.rDir = msFX.point - msFX.trf.position;
234+
msFX.Vsrf = Vector3.ProjectOnPlane(msFX.rDir, msFX.normal).normalized * msFX.fxScale;
235+
236+
msFX.UpdateSrfFX(msFX.hitInfo);
237+
}
238+
239+
static void ModuleSurfaceFX_ResetSrfFX(ModuleSurfaceFX msFX)
240+
{
241+
msFX.hit = ModuleSurfaceFX.SurfaceType.None;
242+
msFX.Vsrf.MutateZero();
243+
msFX.ScaledFX = 0f;
244+
msFX.srfFXnext = null;
245+
msFX.padFX = null;
246+
if (msFX.srfFX.IsNotNullRef())
247+
{
248+
msFX.srfFX.RemoveSource(msFX);
249+
msFX.srfFX = null;
250+
}
251+
}
145252
}
146253
}

0 commit comments

Comments
 (0)