diff --git a/Source/Harmony/FlightGlobals.cs b/Source/Harmony/FlightGlobals.cs
new file mode 100644
index 0000000000..be4dda3ec0
--- /dev/null
+++ b/Source/Harmony/FlightGlobals.cs
@@ -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);
+ }
+ }
+}
diff --git a/Source/Harmony/OrbitDriver.cs b/Source/Harmony/OrbitDriver.cs
index 300cf359f3..af5a7781a8 100644
--- a/Source/Harmony/OrbitDriver.cs
+++ b/Source/Harmony/OrbitDriver.cs
@@ -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;
diff --git a/Source/Harmony/Vessel.cs b/Source/Harmony/Vessel.cs
index 8bd3747a8d..11dea1cc60 100644
--- a/Source/Harmony/Vessel.cs
+++ b/Source/Harmony/Vessel.cs
@@ -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;
}
diff --git a/Source/RealismOverhaul.csproj b/Source/RealismOverhaul.csproj
index bfc6088044..db2c6ae5cb 100644
--- a/Source/RealismOverhaul.csproj
+++ b/Source/RealismOverhaul.csproj
@@ -39,6 +39,7 @@
+
diff --git a/Source/VesselModuleRotationRO.cs b/Source/VesselModuleRotationRO.cs
index 8fed2605ed..26cba87d59 100644
--- a/Source/VesselModuleRotationRO.cs
+++ b/Source/VesselModuleRotationRO.cs
@@ -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
@@ -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 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);
}
}
@@ -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 _vesselCache = new Dictionary();
+
+ 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;
+ }
}
}
\ No newline at end of file