Skip to content

Commit

Permalink
Optimize rotation code: use got's improvements to SetPosRot and use a…
Browse files Browse the repository at this point in the history
… cache for modules so we don't have to look up each time.
  • Loading branch information
NathanKell committed Nov 6, 2023
1 parent be93708 commit bda429b
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 35 deletions.
23 changes: 23 additions & 0 deletions Source/Harmony/FlightGlobals.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
using HarmonyLib;
using UnityEngine;

namespace RealismOverhaul.Harmony
{
[HarmonyPatch(typeof(FlightGlobals))]
internal class PatchFlightGlobals
{
[HarmonyPostfix]
[HarmonyPatch(nameof(FlightGlobals.OnSceneChange))]
internal static void Postfix_OnSceneChange()
{
VesselModuleRotationRO.ClearCache();
}

[HarmonyPostfix]
[HarmonyPatch(nameof(FlightGlobals.RemoveVessel))]
internal static void Postfix_RemoveVessel(Vessel vessel)
{
VesselModuleRotationRO.RemoveVessel(vessel);
}
}
}
18 changes: 5 additions & 13 deletions Source/Harmony/OrbitDriver.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,29 +34,21 @@ internal static bool Prefix_updateFromParameters(OrbitDriver __instance, bool se
UnityEngine.Object.Destroy(__instance.vessel.gameObject);
return false;
}
VesselModuleRotationRO mod = null;
foreach (var vm in __instance.vessel.vesselModules)
{
if (vm is VesselModuleRotationRO vmr)
{
mod = vmr;
break;
}
}
VesselModuleRotationRO vmr = VesselModuleRotationRO.GetModule(__instance.vessel);
if (!__instance.reverse)
{
Vector3d offset = (QuaternionD)__instance.driverTransform.rotation * (Vector3d)__instance.vessel.localCoM;
Vector3d pos = __instance.referenceBody.position + __instance.pos - offset;
if (mod != null)
mod.RailsUpdate(pos);
if (vmr != null)
vmr.RailsUpdate(pos);
else
__instance.vessel.SetPosition(pos);
}
else
{
__instance.referenceBody.position = ((Vector3d)__instance.driverTransform.position) - __instance.pos;
if (mod != null)
mod.RailsUpdate(__instance.vessel.vesselTransform.position);
if (vmr != null)
vmr.RailsUpdate(__instance.vessel.vesselTransform.position);
}

return false;
Expand Down
16 changes: 4 additions & 12 deletions Source/Harmony/Vessel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,15 @@ internal class PatchVessel
[HarmonyPatch(nameof(Vessel.SetRotation), typeof(Quaternion), typeof(bool))]
internal static bool Prefix_SetRotation(Vessel __instance, Quaternion rotation, bool setPos)
{
VesselModuleRotationRO mod = null;
foreach (var vm in __instance.vesselModules)
{
if (vm is VesselModuleRotationRO vmr)
{
mod = vmr;
break;
}
}
if (mod == null)
VesselModuleRotationRO vmr = VesselModuleRotationRO.GetModule(__instance);
if (vmr == null)
return true;

mod.StoreRot(rotation);
vmr.StoreRot(rotation);
if (!setPos)
return true;

mod.SetPosRot(rotation, __instance.transform.position);
vmr.SetPosRot(rotation, __instance.transform.position);

return false;
}
Expand Down
1 change: 1 addition & 0 deletions Source/RealismOverhaul.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
<Compile Include="DebugTools\DrawTools.cs" />
<Compile Include="Harmony\ModuleEngines.cs" />
<Compile Include="Harmony\KSPUtil.cs" />
<Compile Include="Harmony\FlightGlobals.cs" />
<Compile Include="Harmony\Vessel.cs" />
<Compile Include="Harmony\PartLoader.cs" />
<Compile Include="Harmony\OrbitDriver.cs" />
Expand Down
47 changes: 37 additions & 10 deletions Source/VesselModuleRotationRO.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using UnityEngine;
using System.Collections.Generic;


// Modified version of the VesselModule of the same name in MandatoryRCS by gotmachine
Expand Down Expand Up @@ -125,24 +126,22 @@ private void SetRot()
if (IgnoreRot(vessel))
return;

vessel.SetRotation(UnityRot(), true);
SetPosRot(UnityRot(), vessel.transform.position);
}

public void SetPosRot(Quaternion rotation, Vector3d position)
public void SetPosRot(Quaternion rotation, Vector3 position)
{
if (!vessel.loaded)
{
vessel.vesselTransform.rotation = rotation;
vessel.vesselTransform.position = position;
vessel.vesselTransform.SetPositionAndRotation(position, rotation);
return;
}
int count = vessel.parts.Count;
QuaternionD rotD = rotation;
for (int i = 0; i < count; i++)

List<Part> parts = vessel.parts;
for (int i = parts.Count; i-- > 0;)
{
Part part = vessel.parts[i];
part.partTransform.rotation = rotation * part.orgRot;
part.partTransform.position = position + rotD * part.orgPos;
Part part = parts[i];
part.transform.SetPositionAndRotation(position + rotation * part.orgPos, rotation * part.orgRot);
}
}

Expand Down Expand Up @@ -654,5 +653,33 @@ private Quaternion FromToRotation(Vector3d fromv, Vector3d tov) //Stock FromToRo
double norm = 1.0 / Math.Sqrt(cross.sqrMagnitude + wval * wval);
return new QuaternionD(cross.x * norm, cross.y * norm, cross.z * norm, wval * norm);
}

private static readonly Dictionary<Vessel, VesselModuleRotationRO> _vesselCache = new Dictionary<Vessel, VesselModuleRotationRO>();

public static void ClearCache() { _vesselCache.Clear(); }
public static void RemoveVessel(Vessel v) { _vesselCache.Remove(v); }

public static VesselModuleRotationRO GetModule(Vessel v)
{
if (_vesselCache.TryGetValue(v, out var vmr))
return vmr;

foreach (var vm in v.vesselModules)
{
if (vm is VesselModuleRotationRO vmr2)
{
vmr = vmr2;
break;
}
}

// We only store if non-null. This is because the VM is added
// to all vessels, so if it's ever null this must be being run
// before the VM gets added, and we want to store it on next
// cache hit (i.e. after it's been added).
if (vmr != null)
_vesselCache[v] = vmr;
return vmr;
}
}
}

0 comments on commit bda429b

Please sign in to comment.