diff --git a/CHANGELOG.md b/CHANGELOG.md index 1f23115..79e9ed9 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ - Improved performance - SystemHeat resource converters now fully disable themselves when inactive. - Several other optimizations to make resource converters faster. + - Color animations no longer update all materials when they haven't changed. ## 0.9.0 - 2026-05-08 diff --git a/Source/Modules/ModuleSystemHeatColorAnimator.cs b/Source/Modules/ModuleSystemHeatColorAnimator.cs index dfd7c36..1a40310 100644 --- a/Source/Modules/ModuleSystemHeatColorAnimator.cs +++ b/Source/Modules/ModuleSystemHeatColorAnimator.cs @@ -34,108 +34,112 @@ public class ModuleSystemHeatColorAnimator : PartModule, IScalarModule public string includedTransformList; - public string ScalarModuleID - { - get { return moduleID; } - } - public bool CanMove - { - get { return true; } - } - public float GetScalar - { - get { return animationFraction; } - } + public string ScalarModuleID => moduleID; - public EventData OnMoving - { - get { return new EventData("OnMoving"); } - } + public bool CanMove => true; - public EventData OnStop - { - get { return new EventData("OnStop"); } - } - - - public void SetScalar(float t) - { - animationGoal = t; - } + public float GetScalar => animationFraction; - public bool IsMoving() - { - return true; - } + public EventData OnMoving => new("OnMoving"); + public EventData OnStop => new("OnStop"); + public void SetScalar(float t) => animationGoal = t; + public bool IsMoving() => true; public void SetUIWrite(bool value) { } public void SetUIRead(bool value) { } + float lastFraction = float.NaN; + float animationFraction = 0f; + float animationGoal = 0f; + Renderer[] targetRenderers = []; + int propertyID; - protected float animationFraction = 0f; - protected float animationGoal = 0f; - protected List targetRenderers; - - protected void Start() + void Start() { + if (string.IsNullOrEmpty(shaderProperty)) + { + enabled = false; + return; + } + + propertyID = Shader.PropertyToID(shaderProperty); + var renderers = new List(); - targetRenderers = new List(); if (string.IsNullOrEmpty(includedTransformList)) { - foreach (Transform x in part.GetComponentsInChildren()) + foreach (var transform in part.GetComponentsInChildren()) { - Renderer r = x.GetComponent(); + var renderer = transform.GetComponent(); + if (renderer == null) + continue; + if (!renderer.sharedMaterial.HasProperty(propertyID)) + continue; - if (r != null && r.material.HasProperty(shaderProperty)) targetRenderers.Add(r); + renderers.Add(renderer); } } else { - string[] allXformNames = includedTransformList.Split(new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries); - foreach (string xformName in allXformNames) + var names = includedTransformList.Split([','], StringSplitOptions.RemoveEmptyEntries); + foreach (var name in names) { - Transform[] xforms = part.FindModelTransforms(xformName); - foreach (Transform x in xforms) + foreach (var transform in part.FindModelTransforms(name)) { - Renderer r = x.GetComponent(); + var renderer = transform.GetComponent(); + if (renderer == null) + continue; + if (!renderer.sharedMaterial.HasProperty(propertyID)) + continue; - if (r != null && r.material.HasProperty(shaderProperty)) - targetRenderers.Add(r); + renderers.Add(renderer); } } } - if (HighLogic.LoadedSceneIsEditor && targetRenderers != null) - { - animationFraction = 0f; - Color c = new Color(redCurve.Evaluate(animationFraction) * colorScale, greenCurve.Evaluate(animationFraction) * colorScale, blueCurve.Evaluate(animationFraction) * colorScale, alphaCurve.Evaluate(animationFraction) * colorScale); - foreach (Renderer r in targetRenderers) - { - r.material.SetColor(shaderProperty, c); - } + targetRenderers = renderers.ToArray(); + if (targetRenderers.Length == 0) + { + enabled = false; + return; } - + + if (HighLogic.LoadedSceneIsEditor) + UpdateMaterials(); } - protected void Update() + void Update() { - if (HighLogic.LoadedSceneIsFlight || HighLogic.LoadedSceneIsEditor && targetRenderers != null) - { - animationFraction = Mathf.MoveTowards(animationFraction, animationGoal, TimeWarp.deltaTime * animRate); + animationFraction = Mathf.MoveTowards(animationFraction, animationGoal, TimeWarp.deltaTime * animRate); + if (Mathf.Abs(animationFraction - lastFraction) < 1e-3) + return; - Color c = new Color(redCurve.Evaluate(animationFraction) * colorScale, greenCurve.Evaluate(animationFraction) * colorScale, blueCurve.Evaluate(animationFraction) * colorScale, alphaCurve.Evaluate(animationFraction) * colorScale); + lastFraction = animationFraction; + UpdateMaterials(); + } - foreach (Renderer r in targetRenderers) - { - if (r != null && r.material != null) - r.material.SetColor(shaderProperty, c); - } + void UpdateMaterials() + { + var c = new Color( + redCurve.Evaluate(animationFraction) * colorScale, + greenCurve.Evaluate(animationFraction) * colorScale, + blueCurve.Evaluate(animationFraction) * colorScale, + alphaCurve.Evaluate(animationFraction) * colorScale + ); + + foreach (var renderer in targetRenderers) + { + if (renderer == null) + continue; + var material = renderer.material; + if (material == null) + continue; + + material.SetColor(propertyID, c); } } - } }