From 5ce379243a4bf5e9dac9ab33dac65a08beb0754b Mon Sep 17 00:00:00 2001 From: MOARdV Date: Tue, 24 Nov 2015 07:29:09 -0600 Subject: [PATCH 01/16] Fix looping audio when entering IVA Issue #446. --- .../Auxiliary modules/JSIVariableAnimator.cs | 23 ++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/RasterPropMonitor/Auxiliary modules/JSIVariableAnimator.cs b/RasterPropMonitor/Auxiliary modules/JSIVariableAnimator.cs index 721baaab..d59e630b 100644 --- a/RasterPropMonitor/Auxiliary modules/JSIVariableAnimator.cs +++ b/RasterPropMonitor/Auxiliary modules/JSIVariableAnimator.cs @@ -32,6 +32,7 @@ public class JSIVariableAnimator : InternalModule private int updateCountdown; private readonly List variableSets = new List(); private bool alwaysActive; + private bool muted = false; private bool UpdateCheck() { @@ -121,11 +122,23 @@ public void Update() } if (!JUtil.VesselIsInIVA(vessel)) + { + if (!muted) + { + for (int unit = 0; unit < variableSets.Count; ++unit) + { + variableSets[unit].MuteSoundWhileOutOfIVA(); + } + } + muted = true; + } + else if (muted) { for (int unit = 0; unit < variableSets.Count; ++unit) { - variableSets[unit].MuteSoundWhileOutOfIVA(); + variableSets[unit].UnmuteSoundWhileInIVA(); } + muted = false; } if ((!alwaysActive && !JUtil.VesselIsInIVA(vessel)) || !UpdateCheck()) @@ -754,6 +767,14 @@ public void MuteSoundWhileOutOfIVA() } } + public void UnmuteSoundWhileInIVA() + { + if (audioOutput != null && alarmActive) + { + audioOutput.audio.volume = alarmSoundVolume * GameSettings.SHIP_VOLUME; + } + } + public void AlarmShutdown() { if (audioOutput != null && alarmActive && audioOutput.audio.isPlaying) From b52cbc3d81e80e82c6ae5cc9e570f152b6072b37 Mon Sep 17 00:00:00 2001 From: MOARdV Date: Tue, 24 Nov 2015 08:45:19 -0600 Subject: [PATCH 02/16] JSIEngine phase one JSIEngineMonitor, plus MultiModeEngine toggle. Issue #430 --- .../Auxiliary modules/JSIEngineMonitor.cs | 166 ++++++++++++++++++ RasterPropMonitor/Handlers/JSIEngine.cs | 80 +++++++-- RasterPropMonitor/RasterPropMonitor.csproj | 1 + 3 files changed, 229 insertions(+), 18 deletions(-) create mode 100644 RasterPropMonitor/Auxiliary modules/JSIEngineMonitor.cs diff --git a/RasterPropMonitor/Auxiliary modules/JSIEngineMonitor.cs b/RasterPropMonitor/Auxiliary modules/JSIEngineMonitor.cs new file mode 100644 index 00000000..bc14bce2 --- /dev/null +++ b/RasterPropMonitor/Auxiliary modules/JSIEngineMonitor.cs @@ -0,0 +1,166 @@ +/***************************************************************************** + * RasterPropMonitor + * ================= + * Plugin for Kerbal Space Program + * + * by Mihara (Eugene Medvedev), MOARdV, and other contributors + * + * RasterPropMonitor 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, revision + * date 29 June 2007, or (at your option) any later version. + * + * RasterPropMonitor 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 RasterPropMonitor. If not, see . + ****************************************************************************/ +using System; +using System.Collections.Generic; + +namespace JSI +{ + /// + /// Provides a module for RasterPropMonitor to use for providing granular + /// control of an engine as well as detailed information. + /// + class JSIEngineMonitor : PartModule + { + // Internal data storage. + [KSPField(isPersistant = true)] + public int enginedID = 0; + + // Fields to handle right-click GUI. + [KSPField(guiActive = true, guiActiveEditor = true, guiName = "Engine ID: ")] + public string engineDisplayName; + + [KSPEvent(guiActive = true, guiActiveEditor = true, guiName = "ID +")] + public void IdPlus() + { + enginedID++; + UpdateName(); + } + + [KSPEvent(guiActive = true, guiActiveEditor = true, guiName = "ID -")] + public void IdMinus() + { + enginedID--; + if (enginedID <= 0) + enginedID = 0; + UpdateName(); + } + + private void UpdateName() + { + engineDisplayName = (enginedID > 0) ? enginedID.ToString() : "Untracked"; + } + + private int mmeIndex = -1; + private int engineMode1Index = -1; + private int engineMode2Index = -1; + + public void Start() + { + if (!HighLogic.LoadedSceneIsFlight) + { + return; + } + + for(int i=0; i -1) + { + MultiModeEngine mme = part.Modules[mmeIndex] as MultiModeEngine; + + // There doesn't appear to be a simpler way to switch modes. + // One this I could do is store the even index instead of looping + // over it every time we change modes. + if (mme.runningPrimary != state) + { + var ev = mme.Events["ModeEvent"]; + if (ev != null) + { + ev.Invoke(); + } + } + } + } + catch + { + // no-op + } + } + } +} diff --git a/RasterPropMonitor/Handlers/JSIEngine.cs b/RasterPropMonitor/Handlers/JSIEngine.cs index 00c1afbb..ff26708d 100644 --- a/RasterPropMonitor/Handlers/JSIEngine.cs +++ b/RasterPropMonitor/Handlers/JSIEngine.cs @@ -1,4 +1,24 @@ -using System; +/***************************************************************************** + * RasterPropMonitor + * ================= + * Plugin for Kerbal Space Program + * + * by Mihara (Eugene Medvedev), MOARdV, and other contributors + * + * RasterPropMonitor 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, revision + * date 29 June 2007, or (at your option) any later version. + * + * RasterPropMonitor 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 RasterPropMonitor. If not, see . + ****************************************************************************/ +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -7,22 +27,46 @@ namespace JSI { public class JSIEngine:IJSIModule { - //else if (pm is MultiModeEngine) - //{ - // var thatMME = pm as MultiModeEngine; - // JUtil.LogMessage(this, "Set running primary? Is {0}, should be {1}; mode {2}", thatMME.runningPrimary, !vessel.ActionGroups.groups[actionGroupID[0]], thatMME.mode); - // var events = thatMME.Events; - // foreach (var ev in events) - // { - // JUtil.LogMessage(this, "... event {0} / {1}", ev.name, ev.guiName); - // if(ev.name == "ModeEvent") - // { - // if(thatMME.runningPrimary != vessel.ActionGroups.groups[actionGroupID[0]]) - // { - // ev.Invoke(); - // } - // } - // } - //} + public JSIEngine() + { + + } + + public bool GetRunningPrimary() + { + // TODO: select which engine + bool runningPrimary = true; + foreach (JSIEngineMonitor mon in FindEngineMonitorIn(vessel)) + { + if(!mon.GetRunningPrimary()) + { + runningPrimary = false; + } + } + + return runningPrimary; + } + + public void SetRunningPrimary(bool state) + { + foreach(JSIEngineMonitor mon in FindEngineMonitorIn(vessel)) + { + mon.SetRunningPrimary(state); + } + } + + private static IEnumerable FindEngineMonitorIn(Vessel vessel) + { + for (int i = 0; i < vessel.Parts.Count; ++i ) + { + for (int j = 0; j < vessel.Parts[i].Modules.Count; ++j ) + { + if (vessel.Parts[i].Modules[j] is JSIEngineMonitor) + { + yield return vessel.Parts[i].Modules[j] as JSIEngineMonitor; + } + } + } + } } } diff --git a/RasterPropMonitor/RasterPropMonitor.csproj b/RasterPropMonitor/RasterPropMonitor.csproj index 433798fd..d96076c4 100644 --- a/RasterPropMonitor/RasterPropMonitor.csproj +++ b/RasterPropMonitor/RasterPropMonitor.csproj @@ -54,6 +54,7 @@ + From 43044b589f05e28f93cdf18d5cd60d4c852cb8dc Mon Sep 17 00:00:00 2001 From: MOARdV Date: Sat, 28 Nov 2015 18:29:57 -0600 Subject: [PATCH 03/16] Clamp lower bound of GetLandingTime Disallow negative numbers. --- RasterPropMonitor/Handlers/JSIMechJeb.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RasterPropMonitor/Handlers/JSIMechJeb.cs b/RasterPropMonitor/Handlers/JSIMechJeb.cs index 92080a98..986abc10 100644 --- a/RasterPropMonitor/Handlers/JSIMechJeb.cs +++ b/RasterPropMonitor/Handlers/JSIMechJeb.cs @@ -1189,7 +1189,7 @@ public double GetLandingTime() { UpdateLandingStats(activeJeb); - return landingTime - Planetarium.GetUniversalTime(); + return Math.Max(0.0, landingTime - Planetarium.GetUniversalTime()); } else { From 2f761ff7913fb7709b7a33632f4035867d0acba8 Mon Sep 17 00:00:00 2001 From: MOARdV Date: Sat, 28 Nov 2015 18:30:28 -0600 Subject: [PATCH 04/16] ENCOUNTERTIME returns 0 When no data, not NaN. --- RasterPropMonitor/Core/RPMVCVariableToObject.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RasterPropMonitor/Core/RPMVCVariableToObject.cs b/RasterPropMonitor/Core/RPMVCVariableToObject.cs index 76dbae4f..c817a3f4 100644 --- a/RasterPropMonitor/Core/RPMVCVariableToObject.cs +++ b/RasterPropMonitor/Core/RPMVCVariableToObject.cs @@ -835,7 +835,7 @@ VariableEvaluator GetEvaluator(string input, int propId, out bool cacheable) { return vessel.orbit.UTsoi - Planetarium.GetUniversalTime(); } - return double.NaN; + return 0.0; }; case "ENCOUNTERBODY": return (string variable) => From f149ea4c6be5d74ec8389894baccb97d933cbd3f Mon Sep 17 00:00:00 2001 From: MOARdV Date: Sat, 28 Nov 2015 18:31:30 -0600 Subject: [PATCH 05/16] Change Color mode No need for the colorShiftRenderer when all we want is its material. --- .../Auxiliary modules/JSIVariableAnimator.cs | 31 ++++++++++++++----- 1 file changed, 23 insertions(+), 8 deletions(-) diff --git a/RasterPropMonitor/Auxiliary modules/JSIVariableAnimator.cs b/RasterPropMonitor/Auxiliary modules/JSIVariableAnimator.cs index d59e630b..f2dab864 100644 --- a/RasterPropMonitor/Auxiliary modules/JSIVariableAnimator.cs +++ b/RasterPropMonitor/Auxiliary modules/JSIVariableAnimator.cs @@ -112,6 +112,11 @@ public void Start() public void OnDestroy() { //JUtil.LogMessage(this, "OnDestroy()"); + for (int i=0; i(node.GetValue("coloredObject")); - colorShiftRenderer.material.SetColor(colorName, reverse ? activeColor : passiveColor); + Renderer colorShiftRenderer = thisProp.FindModelComponent(node.GetValue("coloredObject")); + affectedMaterial = colorShiftRenderer.material; + affectedMaterial.SetColor(colorName, reverse ? activeColor : passiveColor); mode = Mode.Color; } else if (node.HasValue("controlledTransform") && node.HasValue("localRotationStart") && node.HasValue("localRotationEnd")) @@ -496,6 +502,15 @@ public VariableAnimationSet(ConfigNode node, InternalProp thisProp) } } + // Some things need to be explicitly destroyed due to Unity quirks. + internal void TearDown() + { + if (affectedMaterial != null) + { + UnityEngine.Object.Destroy(affectedMaterial); + } + } + private void TurnOn(double universalTime) { if (!currentState) @@ -503,7 +518,7 @@ private void TurnOn(double universalTime) switch (mode) { case Mode.Color: - colorShiftRenderer.material.SetColor(colorName, (reverse ? passiveColor : activeColor)); + affectedMaterial.SetColor(colorName, (reverse ? passiveColor : activeColor)); break; case Mode.Animation: onAnim[animationName].normalizedTime = reverse ? 0f : 1f; @@ -564,7 +579,7 @@ private void TurnOff(double universalTime) switch (mode) { case Mode.Color: - colorShiftRenderer.material.SetColor(colorName, (reverse ? activeColor : passiveColor)); + affectedMaterial.SetColor(colorName, (reverse ? activeColor : passiveColor)); break; case Mode.Animation: onAnim[animationName].normalizedTime = reverse ? 1f : 0f; @@ -732,7 +747,7 @@ public void Update(RPMVesselComputer comp, double universalTime) controlledTransform.localScale = initialScale + Vector3.Lerp(reverse ? vectorEnd : vectorStart, reverse ? vectorStart : vectorEnd, scaledValue); break; case Mode.Color: - colorShiftRenderer.material.SetColor(colorName, Color.Lerp(reverse ? activeColor : passiveColor, reverse ? passiveColor : activeColor, scaledValue)); + affectedMaterial.SetColor(colorName, Color.Lerp(reverse ? activeColor : passiveColor, reverse ? passiveColor : activeColor, scaledValue)); break; case Mode.TextureShift: foreach (string token in textureLayer.Split(',')) From 4251495bc308c437627cb57213d4ee89023edfcf Mon Sep 17 00:00:00 2001 From: MOARdV Date: Sat, 28 Nov 2015 20:40:13 -0600 Subject: [PATCH 06/16] Eliminate use of 'reverse' in JSIVarAnim Color path Common use case, no need to test 'if reverse' every update. Arguably related to Issue #254. --- .../Auxiliary modules/JSIVariableAnimator.cs | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/RasterPropMonitor/Auxiliary modules/JSIVariableAnimator.cs b/RasterPropMonitor/Auxiliary modules/JSIVariableAnimator.cs index f2dab864..1888fb92 100644 --- a/RasterPropMonitor/Auxiliary modules/JSIVariableAnimator.cs +++ b/RasterPropMonitor/Auxiliary modules/JSIVariableAnimator.cs @@ -360,11 +360,19 @@ public VariableAnimationSet(ConfigNode node, InternalProp thisProp) { colorName = node.GetValue("colorName"); } - passiveColor = ConfigNode.ParseColor32(node.GetValue("passiveColor")); - activeColor = ConfigNode.ParseColor32(node.GetValue("activeColor")); + if (reverse) + { + activeColor = ConfigNode.ParseColor32(node.GetValue("passiveColor")); + passiveColor = ConfigNode.ParseColor32(node.GetValue("activeColor")); + } + else + { + passiveColor = ConfigNode.ParseColor32(node.GetValue("passiveColor")); + activeColor = ConfigNode.ParseColor32(node.GetValue("activeColor")); + } Renderer colorShiftRenderer = thisProp.FindModelComponent(node.GetValue("coloredObject")); affectedMaterial = colorShiftRenderer.material; - affectedMaterial.SetColor(colorName, reverse ? activeColor : passiveColor); + affectedMaterial.SetColor(colorName, passiveColor); mode = Mode.Color; } else if (node.HasValue("controlledTransform") && node.HasValue("localRotationStart") && node.HasValue("localRotationEnd")) @@ -518,7 +526,7 @@ private void TurnOn(double universalTime) switch (mode) { case Mode.Color: - affectedMaterial.SetColor(colorName, (reverse ? passiveColor : activeColor)); + affectedMaterial.SetColor(colorName, activeColor); break; case Mode.Animation: onAnim[animationName].normalizedTime = reverse ? 0f : 1f; @@ -579,7 +587,7 @@ private void TurnOff(double universalTime) switch (mode) { case Mode.Color: - affectedMaterial.SetColor(colorName, (reverse ? activeColor : passiveColor)); + affectedMaterial.SetColor(colorName, passiveColor); break; case Mode.Animation: onAnim[animationName].normalizedTime = reverse ? 1f : 0f; @@ -747,7 +755,7 @@ public void Update(RPMVesselComputer comp, double universalTime) controlledTransform.localScale = initialScale + Vector3.Lerp(reverse ? vectorEnd : vectorStart, reverse ? vectorStart : vectorEnd, scaledValue); break; case Mode.Color: - affectedMaterial.SetColor(colorName, Color.Lerp(reverse ? activeColor : passiveColor, reverse ? passiveColor : activeColor, scaledValue)); + affectedMaterial.SetColor(colorName, Color.Lerp(passiveColor, activeColor, scaledValue)); break; case Mode.TextureShift: foreach (string token in textureLayer.Split(',')) From 84401225013812254d1214ca76f12b60aabd12e1 Mon Sep 17 00:00:00 2001 From: MOARdV Date: Sat, 28 Nov 2015 21:15:59 -0600 Subject: [PATCH 07/16] Add TIMETOATMOSPHERESECS Issue #447 --- .../Core/RPMVCVariableToObject.cs | 20 ++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/RasterPropMonitor/Core/RPMVCVariableToObject.cs b/RasterPropMonitor/Core/RPMVCVariableToObject.cs index c817a3f4..47112feb 100644 --- a/RasterPropMonitor/Core/RPMVCVariableToObject.cs +++ b/RasterPropMonitor/Core/RPMVCVariableToObject.cs @@ -475,7 +475,6 @@ VariableEvaluator GetEvaluator(string input, int propId, out bool cacheable) }; case "TIMETOIMPACTSECS": - // TODO: return (string variable) => { return TimeToImpact(); }; case "SPEEDATIMPACT": return (string variable) => { return SpeedAtImpact(totalCurrentThrust); }; @@ -809,6 +808,25 @@ VariableEvaluator GetEvaluator(string input, int propId, out bool cacheable) return vessel.orbit.TimeOfDescendingNodeEquatorial(Planetarium.GetUniversalTime()) - Planetarium.GetUniversalTime(); return double.NaN; }; + case "TIMETOATMOSPHERESECS": + return (string variable) => + { + double timeToAtm = 0.0; + if (orbitSensibility && vessel.orbit.referenceBody.atmosphere == true) + { + try + { + double now = Planetarium.GetUniversalTime(); + timeToAtm = vessel.orbit.NextTimeOfRadius(now, vessel.orbit.referenceBody.atmosphereDepth + vessel.orbit.referenceBody.Radius) - now; + timeToAtm = Math.Max(timeToAtm, 0.0); + } + catch + { + //... + } + } + return timeToAtm; + }; // SOI changes in orbits. case "ENCOUNTEREXISTS": From 3b64e25e449f145d0a2e3c983023be3c7cd12710 Mon Sep 17 00:00:00 2001 From: MOARdV Date: Sat, 28 Nov 2015 22:20:47 -0600 Subject: [PATCH 08/16] Finish JSIVariableAnimator reverse purge Only used for animation. Notionally Issue #254 --- .../Auxiliary modules/JSIVariableAnimator.cs | 141 ++++++++++++------ 1 file changed, 98 insertions(+), 43 deletions(-) diff --git a/RasterPropMonitor/Auxiliary modules/JSIVariableAnimator.cs b/RasterPropMonitor/Auxiliary modules/JSIVariableAnimator.cs index 1888fb92..7416eb81 100644 --- a/RasterPropMonitor/Auxiliary modules/JSIVariableAnimator.cs +++ b/RasterPropMonitor/Auxiliary modules/JSIVariableAnimator.cs @@ -112,7 +112,7 @@ public void Start() public void OnDestroy() { //JUtil.LogMessage(this, "OnDestroy()"); - for (int i=0; i textureLayer = new List(); private readonly Mode mode; private readonly float resourceAmount; private readonly string resourceName; @@ -382,13 +379,29 @@ public VariableAnimationSet(ConfigNode node, InternalProp thisProp) if (node.HasValue("longPath")) { longPath = true; - vectorStart = ConfigNode.ParseVector3(node.GetValue("localRotationStart")); - vectorEnd = ConfigNode.ParseVector3(node.GetValue("localRotationEnd")); + if (reverse) + { + vectorEnd = ConfigNode.ParseVector3(node.GetValue("localRotationStart")); + vectorStart = ConfigNode.ParseVector3(node.GetValue("localRotationEnd")); + } + else + { + vectorStart = ConfigNode.ParseVector3(node.GetValue("localRotationStart")); + vectorEnd = ConfigNode.ParseVector3(node.GetValue("localRotationEnd")); + } } else { - rotationStart = Quaternion.Euler(ConfigNode.ParseVector3(node.GetValue("localRotationStart"))); - rotationEnd = Quaternion.Euler(ConfigNode.ParseVector3(node.GetValue("localRotationEnd"))); + if (reverse) + { + rotationEnd = Quaternion.Euler(ConfigNode.ParseVector3(node.GetValue("localRotationStart"))); + rotationStart = Quaternion.Euler(ConfigNode.ParseVector3(node.GetValue("localRotationEnd"))); + } + else + { + rotationStart = Quaternion.Euler(ConfigNode.ParseVector3(node.GetValue("localRotationStart"))); + rotationEnd = Quaternion.Euler(ConfigNode.ParseVector3(node.GetValue("localRotationEnd"))); + } } mode = Mode.Rotation; } @@ -396,32 +409,74 @@ public VariableAnimationSet(ConfigNode node, InternalProp thisProp) { controlledTransform = thisProp.FindModelTransform(node.GetValue("controlledTransform").Trim()); initialPosition = controlledTransform.localPosition; - vectorStart = ConfigNode.ParseVector3(node.GetValue("localTranslationStart")); - vectorEnd = ConfigNode.ParseVector3(node.GetValue("localTranslationEnd")); + if (reverse) + { + vectorEnd = ConfigNode.ParseVector3(node.GetValue("localTranslationStart")); + vectorStart = ConfigNode.ParseVector3(node.GetValue("localTranslationEnd")); + } + else + { + vectorStart = ConfigNode.ParseVector3(node.GetValue("localTranslationStart")); + vectorEnd = ConfigNode.ParseVector3(node.GetValue("localTranslationEnd")); + } mode = Mode.Translation; } else if (node.HasValue("controlledTransform") && node.HasValue("localScaleStart") && node.HasValue("localScaleEnd")) { controlledTransform = thisProp.FindModelTransform(node.GetValue("controlledTransform").Trim()); initialScale = controlledTransform.localScale; - vectorStart = ConfigNode.ParseVector3(node.GetValue("localScaleStart")); - vectorEnd = ConfigNode.ParseVector3(node.GetValue("localScaleEnd")); + if (reverse) + { + vectorEnd = ConfigNode.ParseVector3(node.GetValue("localScaleStart")); + vectorStart = ConfigNode.ParseVector3(node.GetValue("localScaleEnd")); + } + else + { + vectorStart = ConfigNode.ParseVector3(node.GetValue("localScaleStart")); + vectorEnd = ConfigNode.ParseVector3(node.GetValue("localScaleEnd")); + } mode = Mode.Scale; } else if (node.HasValue("controlledTransform") && node.HasValue("textureLayers") && node.HasValue("textureShiftStart") && node.HasValue("textureShiftEnd")) { affectedMaterial = thisProp.FindModelTransform(node.GetValue("controlledTransform").Trim()).renderer.material; - textureLayer = node.GetValue("textureLayers"); - textureShiftStart = ConfigNode.ParseVector2(node.GetValue("textureShiftStart")); - textureShiftEnd = ConfigNode.ParseVector2(node.GetValue("textureShiftEnd")); + var textureLayers = node.GetValue("textureLayers").Split(','); + for (int i = 0; i < textureLayers.Length; ++i) + { + textureLayer.Add(textureLayers[i].Trim()); + } + + if (reverse) + { + textureShiftEnd = ConfigNode.ParseVector2(node.GetValue("textureShiftStart")); + textureShiftStart = ConfigNode.ParseVector2(node.GetValue("textureShiftEnd")); + } + else + { + textureShiftStart = ConfigNode.ParseVector2(node.GetValue("textureShiftStart")); + textureShiftEnd = ConfigNode.ParseVector2(node.GetValue("textureShiftEnd")); + } mode = Mode.TextureShift; } else if (node.HasValue("controlledTransform") && node.HasValue("textureLayers") && node.HasValue("textureScaleStart") && node.HasValue("textureScaleEnd")) { affectedMaterial = thisProp.FindModelTransform(node.GetValue("controlledTransform").Trim()).renderer.material; - textureLayer = node.GetValue("textureLayers"); - textureScaleStart = ConfigNode.ParseVector2(node.GetValue("textureScaleStart")); - textureScaleEnd = ConfigNode.ParseVector2(node.GetValue("textureScaleEnd")); + var textureLayers = node.GetValue("textureLayers").Split(','); + for (int i = 0; i < textureLayers.Length; ++i) + { + textureLayer.Add(textureLayers[i].Trim()); + } + + if (reverse) + { + textureScaleEnd = ConfigNode.ParseVector2(node.GetValue("textureScaleStart")); + textureScaleStart = ConfigNode.ParseVector2(node.GetValue("textureScaleEnd")); + } + else + { + textureScaleStart = ConfigNode.ParseVector2(node.GetValue("textureScaleStart")); + textureScaleEnd = ConfigNode.ParseVector2(node.GetValue("textureScaleEnd")); + } mode = Mode.TextureScale; } else @@ -539,24 +594,24 @@ private void TurnOn(double universalTime) } break; case Mode.Rotation: - controlledTransform.localRotation = initialRotation * (reverse ? rotationEnd : rotationStart); + controlledTransform.localRotation = initialRotation * (longPath ? Quaternion.Euler(vectorStart) : rotationStart); break; case Mode.Translation: - controlledTransform.localPosition = initialPosition + (reverse ? vectorEnd : vectorStart); + controlledTransform.localPosition = initialPosition + vectorStart; break; case Mode.Scale: - controlledTransform.localScale = initialScale + (reverse ? vectorEnd : vectorStart); + controlledTransform.localScale = initialScale + vectorStart; break; case Mode.TextureShift: - foreach (string token in textureLayer.Split(',')) + for (int i = 0; i < textureLayer.Count; ++i) { - affectedMaterial.SetTextureOffset(token.Trim(), reverse ? textureShiftEnd : textureShiftStart); + affectedMaterial.SetTextureOffset(textureLayer[i], textureShiftStart); } break; case Mode.TextureScale: - foreach (string token in textureLayer.Split(',')) + for (int i = 0; i < textureLayer.Count; ++i) { - affectedMaterial.SetTextureScale(token.Trim(), reverse ? textureScaleEnd : textureScaleStart); + affectedMaterial.SetTextureScale(textureLayer[i], textureScaleStart); } break; } @@ -608,24 +663,24 @@ private void TurnOff(double universalTime) } break; case Mode.Rotation: - controlledTransform.localRotation = initialRotation * (reverse ? rotationStart : rotationEnd); + controlledTransform.localRotation = initialRotation * (longPath ? Quaternion.Euler(vectorEnd) : rotationEnd); break; case Mode.Translation: - controlledTransform.localPosition = initialPosition + (reverse ? vectorStart : vectorEnd); + controlledTransform.localPosition = initialPosition + vectorEnd; break; case Mode.Scale: - controlledTransform.localScale = initialScale + (reverse ? vectorStart : vectorEnd); + controlledTransform.localScale = initialScale + vectorEnd; break; case Mode.TextureShift: - foreach (string token in textureLayer.Split(',')) + for (int i = 0; i < textureLayer.Count; ++i) { - affectedMaterial.SetTextureOffset(token.Trim(), reverse ? textureShiftStart : textureShiftEnd); + affectedMaterial.SetTextureOffset(textureLayer[i], textureShiftEnd); } break; case Mode.TextureScale: - foreach (string token in textureLayer.Split(',')) + for (int i = 0; i < textureLayer.Count; ++i) { - affectedMaterial.SetTextureScale(token.Trim(), reverse ? textureScaleStart : textureScaleEnd); + affectedMaterial.SetTextureScale(textureLayer[i], textureScaleEnd); } break; } @@ -744,31 +799,31 @@ public void Update(RPMVesselComputer comp, double universalTime) switch (mode) { case Mode.Rotation: - Quaternion newRotation = longPath ? Quaternion.Euler(Vector3.Lerp(reverse ? vectorEnd : vectorStart, reverse ? vectorStart : vectorEnd, scaledValue)) : - Quaternion.Slerp(reverse ? rotationEnd : rotationStart, reverse ? rotationStart : rotationEnd, scaledValue); + Quaternion newRotation = longPath ? Quaternion.Euler(Vector3.Lerp(vectorStart, vectorEnd, scaledValue)) : + Quaternion.Slerp(rotationStart, rotationEnd, scaledValue); controlledTransform.localRotation = initialRotation * newRotation; break; case Mode.Translation: - controlledTransform.localPosition = initialPosition + Vector3.Lerp(reverse ? vectorEnd : vectorStart, reverse ? vectorStart : vectorEnd, scaledValue); + controlledTransform.localPosition = initialPosition + Vector3.Lerp(vectorStart, vectorEnd, scaledValue); break; case Mode.Scale: - controlledTransform.localScale = initialScale + Vector3.Lerp(reverse ? vectorEnd : vectorStart, reverse ? vectorStart : vectorEnd, scaledValue); + controlledTransform.localScale = initialScale + Vector3.Lerp(vectorStart, vectorEnd, scaledValue); break; case Mode.Color: affectedMaterial.SetColor(colorName, Color.Lerp(passiveColor, activeColor, scaledValue)); break; case Mode.TextureShift: - foreach (string token in textureLayer.Split(',')) + for (int i = 0; i < textureLayer.Count; ++i) { - affectedMaterial.SetTextureOffset(token.Trim(), - Vector2.Lerp(reverse ? textureShiftEnd : textureShiftStart, reverse ? textureShiftStart : textureShiftEnd, scaledValue)); + affectedMaterial.SetTextureOffset(textureLayer[i], + Vector2.Lerp(textureShiftStart, textureShiftEnd, scaledValue)); } break; case Mode.TextureScale: - foreach (string token in textureLayer.Split(',')) + for (int i = 0; i < textureLayer.Count; ++i) { - affectedMaterial.SetTextureScale(token.Trim(), - Vector2.Lerp(reverse ? textureScaleEnd : textureScaleStart, reverse ? textureScaleStart : textureScaleEnd, scaledValue)); + affectedMaterial.SetTextureScale(textureLayer[i], + Vector2.Lerp(textureScaleStart, textureScaleEnd, scaledValue)); } break; case Mode.LoopingAnimation: From dacdfe3c930c56b9ef00267595eafc1966f32fd9 Mon Sep 17 00:00:00 2001 From: MOARdV Date: Sun, 29 Nov 2015 10:01:39 -0600 Subject: [PATCH 09/16] Store Material instead of Renderer Need to destroy the Material manually. --- .../Auxiliary modules/JSIActionGroupSwitch.cs | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/RasterPropMonitor/Auxiliary modules/JSIActionGroupSwitch.cs b/RasterPropMonitor/Auxiliary modules/JSIActionGroupSwitch.cs index 6a360772..45948a72 100644 --- a/RasterPropMonitor/Auxiliary modules/JSIActionGroupSwitch.cs +++ b/RasterPropMonitor/Auxiliary modules/JSIActionGroupSwitch.cs @@ -136,7 +136,7 @@ internal enum CustomActions private int lightCheckCountdown; private RasterPropMonitorComputer rpmComp; private bool startupComplete; - private Renderer colorShiftRenderer; + private Material colorShiftMaterial; private string stateVariable = string.Empty; private Action actionHandler; private bool isPluginAction; @@ -536,10 +536,11 @@ public void Start() else if (!string.IsNullOrEmpty(coloredObject)) { // Set up the color shift. - colorShiftRenderer = internalProp.FindModelComponent(coloredObject); + Renderer colorShiftRenderer = internalProp.FindModelComponent(coloredObject); disabledColorValue = ConfigNode.ParseColor32(disabledColor); enabledColorValue = ConfigNode.ParseColor32(enabledColor); - colorShiftRenderer.material.SetColor(colorName, (currentState ^ reverse ? enabledColorValue : disabledColorValue)); + colorShiftMaterial = colorShiftRenderer.material; + colorShiftMaterial.SetColor(colorName, (currentState ^ reverse ? enabledColorValue : disabledColorValue)); } else { @@ -567,6 +568,14 @@ public void OnDestroy() { //JUtil.LogMessage(this, "OnDestroy()"); rpmComp = null; + if (colorShiftMaterial != null) + { + UnityEngine.Object.Destroy(colorShiftMaterial); + colorShiftMaterial = null; + } + actionHandler = null; + transferGetter = null; + transferSetter = null; } private void SetInternalLights(bool value) @@ -860,9 +869,9 @@ public override void OnUpdate() anim.Play(animationName); } } - else if (colorShiftRenderer != null) + else if (colorShiftMaterial != null) { - colorShiftRenderer.material.SetColor(colorName, (newState ^ reverse ? enabledColorValue : disabledColorValue)); + colorShiftMaterial.SetColor(colorName, (newState ^ reverse ? enabledColorValue : disabledColorValue)); } currentState = newState; } From 9bc50b9c97c176d091201cbaabdbfa31def0f4a9 Mon Sep 17 00:00:00 2001 From: MOARdV Date: Sun, 29 Nov 2015 10:01:56 -0600 Subject: [PATCH 10/16] Tinkering at the edges --- .../Auxiliary modules/JSIVariableAnimator.cs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/RasterPropMonitor/Auxiliary modules/JSIVariableAnimator.cs b/RasterPropMonitor/Auxiliary modules/JSIVariableAnimator.cs index 7416eb81..ffc4dd04 100644 --- a/RasterPropMonitor/Auxiliary modules/JSIVariableAnimator.cs +++ b/RasterPropMonitor/Auxiliary modules/JSIVariableAnimator.cs @@ -185,15 +185,15 @@ public class VariableAnimationSet private readonly bool alarmSoundLooping; private readonly bool alarmMustPlayOnce; private readonly Color passiveColor, activeColor; - private readonly Transform controlledTransform; + private Transform controlledTransform; private readonly Vector3 initialPosition, initialScale, vectorStart, vectorEnd; private readonly Quaternion initialRotation, rotationStart, rotationEnd; private readonly bool longPath; private readonly double flashingDelay; private readonly string colorName = "_EmissiveColor"; private readonly Vector2 textureShiftStart, textureShiftEnd, textureScaleStart, textureScaleEnd; - private readonly Material affectedMaterial; - private readonly List textureLayer = new List(); + private Material affectedMaterial; + private List textureLayer = new List(); private readonly Mode mode; private readonly float resourceAmount; private readonly string resourceName; @@ -571,7 +571,11 @@ internal void TearDown() if (affectedMaterial != null) { UnityEngine.Object.Destroy(affectedMaterial); + affectedMaterial = null; } + textureLayer = null; + controlledTransform = null; + part = null; } private void TurnOn(double universalTime) From 1034e7e0aee529d865da6c8b1004d8040523d843 Mon Sep 17 00:00:00 2001 From: MOARdV Date: Sun, 29 Nov 2015 10:34:08 -0600 Subject: [PATCH 11/16] Change Resource consumption computation to update every time Instead of once per second, which creates unresponsive gauges. --- RasterPropMonitor/Core/ResourceDataStorage.cs | 21 +++++-------------- 1 file changed, 5 insertions(+), 16 deletions(-) diff --git a/RasterPropMonitor/Core/ResourceDataStorage.cs b/RasterPropMonitor/Core/ResourceDataStorage.cs index d60ad266..c81324e2 100644 --- a/RasterPropMonitor/Core/ResourceDataStorage.cs +++ b/RasterPropMonitor/Core/ResourceDataStorage.cs @@ -62,21 +62,13 @@ public ResourceDataStorage() public void StartLoop(double time) { - bool updateDeltas = false; - float invDeltaT = 1.0f; - if (time - lastcheck > secondsBetweenSamples) - { - updateDeltas = true; - invDeltaT = (float)(1.0 / (time - lastcheck)); - } + float invDeltaT = (float)(1.0 / (time - lastcheck)); for (int i = 0; i < rs.Length; ++i) { - if (updateDeltas) - { - rs[i].delta = (rs[i].previous - rs[i].current) * invDeltaT; - rs[i].previous = rs[i].current; - } + rs[i].delta = (rs[i].previous - rs[i].current) * invDeltaT; + rs[i].previous = rs[i].current; + rs[i].current = 0.0f; rs[i].max = 0.0f; rs[i].stage = 0.0f; @@ -85,10 +77,7 @@ public void StartLoop(double time) } - if (updateDeltas) - { - lastcheck = time; - } + lastcheck = time; } public void MarkPropellant(Propellant propel) From 311ff115363e0a7dd7d8f5e0c869c6ac8ab3a824 Mon Sep 17 00:00:00 2001 From: MOARdV Date: Mon, 30 Nov 2015 08:38:09 -0600 Subject: [PATCH 12/16] More tinkering --- RasterPropMonitor/Auxiliary modules/JSIActionGroupSwitch.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/RasterPropMonitor/Auxiliary modules/JSIActionGroupSwitch.cs b/RasterPropMonitor/Auxiliary modules/JSIActionGroupSwitch.cs index 45948a72..50d9de8f 100644 --- a/RasterPropMonitor/Auxiliary modules/JSIActionGroupSwitch.cs +++ b/RasterPropMonitor/Auxiliary modules/JSIActionGroupSwitch.cs @@ -576,6 +576,8 @@ public void OnDestroy() actionHandler = null; transferGetter = null; transferSetter = null; + audioOutput = null; + loopingOutput = null; } private void SetInternalLights(bool value) From 3ea13496974cf6f8d16aa8b364ebe0d454fc4245 Mon Sep 17 00:00:00 2001 From: MOARdV Date: Mon, 30 Nov 2015 08:38:24 -0600 Subject: [PATCH 13/16] Set up v0.24.1 release --- GameData/JSI/RasterPropMonitor/RasterPropMonitor.version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/GameData/JSI/RasterPropMonitor/RasterPropMonitor.version b/GameData/JSI/RasterPropMonitor/RasterPropMonitor.version index 2d6d332c..6d553006 100644 --- a/GameData/JSI/RasterPropMonitor/RasterPropMonitor.version +++ b/GameData/JSI/RasterPropMonitor/RasterPropMonitor.version @@ -5,7 +5,7 @@ "VERSION": { "MAJOR": 0, "MINOR": 24, - "PATCH": 0 + "PATCH": 1 }, "KSP_VERSION": { "MAJOR": 1, From 78bf98335faaab504f55fd06b3ab25c853887f84 Mon Sep 17 00:00:00 2001 From: MOARdV Date: Mon, 30 Nov 2015 13:26:32 -0600 Subject: [PATCH 14/16] Fix links borked by the "new & improved" forum --- FAQ.md | 8 ++++---- README.md | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/FAQ.md b/FAQ.md index 474e1ca8..8ebff153 100644 --- a/FAQ.md +++ b/FAQ.md @@ -2,7 +2,7 @@ ### Can you make RPM work outside the command pod / on pop-up screens? -No. RasterPropMonitor was designed to provide an interactive IVA experience. It can not be used to run "monitors" placed outside the craft, and it can not be used to draw on windows/overlays either. There are no plans to change that. The license for RPM is very open, so if someone wants to use RPM as a basis to make something similar for outside-of-IVA use, they're more than welcome to try. +No. RasterPropMonitor was designed to provide an interactive IVA experience. It was not designed to run "monitors" placed outside the craft, and it can not be used to draw on windows/overlays either. There are no plans to change that. The license for RPM is very open, so if someone wants to use RPM as a basis to make something similar for outside-of-IVA use, they're more than welcome to try. ### Where is the IVA for X? @@ -14,7 +14,7 @@ I do not actively support CKAN versioning information. KerbalStuff has an optio I make efforts to keep the RasterPropMonitor.version file accurate (which affects AVC, and maybe CKAN), but due to the way my release cycles work, there is always a chance that version info on GitHub will be changed before a release takes place. -TL;DR: The current version is always identified on the [forum](http://forum.kerbalspaceprogram.com/threads/117471), [KerbalStuff](https://kerbalstuff.com/mod/734/RasterPropMonitor), and [GitHub](https://github.com/Mihara/RasterPropMonitor/releases) . Any other sources of versioning are secondary, and not authorative. +TL;DR: The current version is always identified on the [forum](http://forum.kerbalspaceprogram.com/index.php?/topic/105821-105-rasterpropmonitor-still-putting-the-a-in-iva-v0240-10-november-2015/), [KerbalStuff](https://kerbalstuff.com/mod/734/RasterPropMonitor), and [GitHub](https://github.com/Mihara/RasterPropMonitor/releases) . Any other sources of versioning are secondary, and not authorative. ### Half the buttons don't work! @@ -28,7 +28,7 @@ It's sort of an approximation of how actual MFDs work, though they typically use * Make sure that there is only one RasterPropMonitor.dll and that it is located at GameData/JSI/RasterPropMonitor/Plugins/RasterPropMonitor.dll -- several earlier third-party capsules distributed old versions incorrectly. They *will* fail to work in 0.23. * Make sure that you're using the appropriate versions of every other plugin, in particular SCANsat and MechJeb -- failures of loading the interface DLLs for those can cause RasterPropMonitor to stop working, and there's little I can do about this. Blame Squad and be sure to eradicate MechJebRPM.dll if you do not use MechJeb / delete SCANsatRPM.dll if you do not use SCANsat. -If these steps do not solve your problem, please follow the steps in (this post on the forum)[http://forum.kerbalspaceprogram.com/threads/92229] and post the required information on the (RPM forum)[http://forum.kerbalspaceprogram.com/threads/117471] or open an issue on (GitHub)[https://github.com/Mihara/RasterPropMonitor/issues]. +If these steps do not solve your problem, please follow the steps in (this post on the forum)[http://forum.kerbalspaceprogram.com/index.php?/topic/105821-105-rasterpropmonitor-still-putting-the-a-in-iva-v0240-10-november-2015/] and post the required information on the (RPM forum)[http://forum.kerbalspaceprogram.com/threads/117471] or open an issue on (GitHub)[https://github.com/Mihara/RasterPropMonitor/issues]. ### I get lots of exclamation signs and gibberish all over my screens! @@ -42,7 +42,7 @@ I want your KSP_Data/output_log.txt and as precise a description of what you wer ### How do I get the map to show? It says "No satellite connection" -RasterPropMonitor relies on [SCANsat](http://forum.kerbalspaceprogram.com/threads/55832) for mapping data. These are the precise satellites it means to have a connection to -- install it and launch some, they're quite a lot of fun. It's one of those things that makes probes more than just a practice launch. +RasterPropMonitor relies on [SCANsat](http://forum.kerbalspaceprogram.com/index.php?/topic/72679-105-scansat-v144-real-scanning-real-science-at-warp-speed-november-14/) for mapping data. These are the precise satellites it means to have a connection to -- install it and launch some, they're quite a lot of fun. It's one of those things that makes probes more than just a practice launch. ### RasterPropMonitor breaks Kethane map! diff --git a/README.md b/README.md index 284bbfce..1ac8f33b 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ Plugin for Kerbal Space Program enabling creation of advanced display monitors and other useful and informative props for internal capsule view. -See [the forum support thread](http://forum.kerbalspaceprogram.com/threads/117471) for support. +See [the forum support thread](http://forum.kerbalspaceprogram.com/index.php?/topic/105821-105-rasterpropmonitor-still-putting-the-a-in-iva-v0240-10-november-2015/) for support. See [the dull^H^H^H^ full documentation](https://github.com/Mihara/RasterPropMonitor/wiki) in the wiki on GitHub. From 7de88fdfa5b48fec9e9027f2bd386d1305165d79 Mon Sep 17 00:00:00 2001 From: MOARdV Date: Mon, 30 Nov 2015 16:49:42 -0600 Subject: [PATCH 15/16] Add ACCEL variable family Decomposes the acceleration vector into prograde, radial, normal, surface prograde, forward, right, and top components. Issue #420. --- RasterPropMonitor/Core/RPMVCVariableToObject.cs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/RasterPropMonitor/Core/RPMVCVariableToObject.cs b/RasterPropMonitor/Core/RPMVCVariableToObject.cs index 47112feb..9b04465c 100644 --- a/RasterPropMonitor/Core/RPMVCVariableToObject.cs +++ b/RasterPropMonitor/Core/RPMVCVariableToObject.cs @@ -632,6 +632,20 @@ VariableEvaluator GetEvaluator(string input, int propId, out bool cacheable) return LiftForce(); case "LIFTACCEL": return LiftAccel(); + case "ACCELPROGRADE": + return (string variable) => { return Vector3.Dot(vessel.acceleration, prograde); }; + case "ACCELRADIAL": + return (string variable) => { return Vector3.Dot(vessel.acceleration, radialOut); }; + case "ACCELNORMAL": + return (string variable) => { return Vector3.Dot(vessel.acceleration, normalPlus); }; + case "ACCELSURFPROGRADE": + return (string variable) => { return Vector3.Dot(vessel.acceleration, vessel.srf_velocity.normalized); }; + case "ACCELFORWARD": + return (string variable) => { return Vector3.Dot(vessel.acceleration, forward); }; + case "ACCELRIGHT": + return (string variable) => { return Vector3.Dot(vessel.acceleration, right); }; + case "ACCELTOP": + return (string variable) => { return Vector3.Dot(vessel.acceleration, top); }; // Maneuvers case "MNODETIMESECS": From 753ec07c7e227bce68c6040fa091cfd941128e65 Mon Sep 17 00:00:00 2001 From: MOARdV Date: Mon, 30 Nov 2015 16:53:09 -0600 Subject: [PATCH 16/16] Add JSINavBall Replacement for InternalNavBall with the ability to switch it off and to limit its maximum rate of change. Issue #403. --- .../Auxiliary modules/JSINavBall.cs | 100 ++++++++++++++++++ RasterPropMonitor/RasterPropMonitor.csproj | 1 + 2 files changed, 101 insertions(+) create mode 100644 RasterPropMonitor/Auxiliary modules/JSINavBall.cs diff --git a/RasterPropMonitor/Auxiliary modules/JSINavBall.cs b/RasterPropMonitor/Auxiliary modules/JSINavBall.cs new file mode 100644 index 00000000..d50ff313 --- /dev/null +++ b/RasterPropMonitor/Auxiliary modules/JSINavBall.cs @@ -0,0 +1,100 @@ +/***************************************************************************** + * RasterPropMonitor + * ================= + * Plugin for Kerbal Space Program + * + * by Mihara (Eugene Medvedev), MOARdV, and other contributors + * + * RasterPropMonitor 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, revision + * date 29 June 2007, or (at your option) any later version. + * + * RasterPropMonitor 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 RasterPropMonitor. If not, see . + ****************************************************************************/ +using System; +using UnityEngine; + +namespace JSI +{ + class JSINavBall : InternalNavBall + { + /// + /// Name of the enabling variable. Required. + /// + [KSPField] + public string variableName = string.Empty; + + /// + /// vec2 containing the 'enabled' range. May be numeric or varibles. Required. + /// + [KSPField] + public string range = string.Empty; + + /// + /// Maximum angle that the navball can change per second, in degrees. Defaults to 180. + /// + [KSPField] + public float maxAngleChange = 180.0f; + + private VariableOrNumberRange enablingVariable; + + private Quaternion lastOrientation; + + public override void OnAwake() + { + base.OnAwake(); + + lastOrientation = navBall.rotation; + + if (string.IsNullOrEmpty(variableName) || string.IsNullOrEmpty(range)) + { + JUtil.LogErrorMessage(this, "variableName or range was null!"); + return; + } + string[] tokens = range.Split(','); + if (tokens.Length != 2) + { + JUtil.LogErrorMessage(this, "range '{0}' did not have exactly two values!", range); + return; + } + + enablingVariable = new VariableOrNumberRange(variableName, tokens[0], tokens[1]); + } + + public override void OnUpdate() + { + if (enablingVariable == null) + { + return; + } + + RPMVesselComputer comp = RPMVesselComputer.Instance(vessel); + if (enablingVariable.IsInRange(comp)) + { + base.OnUpdate(); + Quaternion post = navBall.rotation; + float deltaAngle = Quaternion.Angle(lastOrientation, post); + float maxAngle = maxAngleChange * Time.deltaTime; + + // If the rotation angle exceeds what we can do, slow it down + if (deltaAngle > maxAngle) + { + Quaternion newRotation = Quaternion.Slerp(lastOrientation, post, maxAngle / deltaAngle); + lastOrientation = newRotation; + navBall.rotation = newRotation; + } + else + { + lastOrientation = post; + } + } + } + } +} diff --git a/RasterPropMonitor/RasterPropMonitor.csproj b/RasterPropMonitor/RasterPropMonitor.csproj index d96076c4..8864c802 100644 --- a/RasterPropMonitor/RasterPropMonitor.csproj +++ b/RasterPropMonitor/RasterPropMonitor.csproj @@ -55,6 +55,7 @@ +