diff --git a/GameData/ConformalDecals/Plugins/ConformalDecals.dll b/GameData/ConformalDecals/Plugins/ConformalDecals.dll index efb093e..d2842a2 100644 Binary files a/GameData/ConformalDecals/Plugins/ConformalDecals.dll and b/GameData/ConformalDecals/Plugins/ConformalDecals.dll differ diff --git a/Source/ConformalDecals/ModuleConformalDecal.cs b/Source/ConformalDecals/ModuleConformalDecal.cs index 1ff3b53..96db4b7 100644 --- a/Source/ConformalDecals/ModuleConformalDecal.cs +++ b/Source/ConformalDecals/ModuleConformalDecal.cs @@ -79,7 +79,7 @@ namespace ConformalDecals { UI_FloatRange()] public float wear = 100; - [KSPField(isPersistant = true)] public bool projectMultiple; // reserved for future features. do not modify + [KSPField(isPersistant = true)] public bool projectMultiple = true; [KSPField] public MaterialPropertyCollection materialProperties; @@ -215,13 +215,13 @@ namespace ConformalDecals { foreach (var keyword in _decalMaterial.shaderKeywords) { this.Log($"keyword: {keyword}"); } - + if (HighLogic.LoadedSceneIsEditor) { UpdateTweakables(); } if (HighLogic.LoadedSceneIsGame) { - UpdateScale(); + UpdateProjection(); } else { scale = defaultScale; @@ -237,7 +237,7 @@ namespace ConformalDecals { /// public override void OnIconCreate() { - UpdateScale(); + UpdateProjection(); } /// @@ -304,11 +304,11 @@ namespace ConformalDecals { protected void OnSizeTweakEvent(BaseField field, object obj) { // scale or depth values have been changed, so update scale // and update projection matrices if attached - UpdateScale(); + UpdateProjection(); foreach (var counterpart in part.symmetryCounterparts) { var decal = counterpart.GetComponent(); - decal.UpdateScale(); + decal.UpdateProjection(); } } @@ -331,7 +331,7 @@ namespace ConformalDecals { protected void OnVariantApplied(Part eventPart, PartVariant variant) { if (_isAttached && eventPart == part.parent) { - UpdateTargets(); + UpdateProjection(); } } @@ -346,7 +346,7 @@ namespace ConformalDecals { break; case ConstructionEventType.PartOffsetting: case ConstructionEventType.PartRotating: - UpdateScale(); + UpdateProjection(); break; } } @@ -377,8 +377,7 @@ namespace ConformalDecals { Camera.onPreCull += Render; UpdateMaterials(); - UpdateTargets(); - UpdateScale(); + UpdateProjection(); } protected virtual void OnDetach() { @@ -394,10 +393,57 @@ namespace ConformalDecals { Camera.onPreCull -= Render; UpdateMaterials(); - UpdateScale(); + UpdateProjection(); } - protected void UpdateScale() { + protected void UpdateProjection() { + // Update projection targets + if (_targets == null) { + _targets = new List(); + } + else { + _targets.Clear(); + } + + if (_isAttached) { + IEnumerable targetParts; + if (projectMultiple) { + if (HighLogic.LoadedSceneIsFlight) { + targetParts = part.vessel.parts; + } + else { + targetParts = EditorLogic.fetch.ship.parts; + } + } + else { + targetParts = new[] {part.parent}; + } + + foreach (var targetPart in targetParts) { + if (targetPart.GetComponent() != null) continue; // skip other decals + + foreach (var targetRenderer in targetPart.FindModelComponents()) { + // skip disabled renderers + if (targetRenderer.gameObject.activeInHierarchy == false) continue; + + // skip blacklisted shaders + if (DecalConfig.IsBlacklisted(targetRenderer.material.shader)) continue; + + var meshFilter = targetRenderer.GetComponent(); + if (meshFilter == null) continue; // object has a meshRenderer with no filter, invalid + var mesh = meshFilter.sharedMesh; + if (mesh == null) continue; // object has a null mesh, invalid + + // create new ProjectionTarget to represent the renderer + var target = new ProjectionTarget(targetPart, targetRenderer, mesh); + + // add the target to the list + _targets.Add(target); + } + } + } + + // Update projection matrix scale = Mathf.Max(0.01f, scale); depth = Mathf.Max(0.01f, depth); var aspectRatio = materialProperties.AspectRatio; @@ -468,36 +514,6 @@ namespace ConformalDecals { if (!_isAttached) decalFrontTransform.GetComponent().material = _previewMaterial; } - protected void UpdateTargets() { - if (_targets == null) { - _targets = new List(); - } - else { - _targets.Clear(); - } - - // find all valid renderers - var renderers = part.parent.FindModelComponents(); - foreach (var renderer in renderers) { - // skip disabled renderers - if (renderer.gameObject.activeInHierarchy == false) continue; - - // skip blacklisted shaders - if (DecalConfig.IsBlacklisted(renderer.material.shader)) continue; - - var meshFilter = renderer.GetComponent(); - if (meshFilter == null) continue; // object has a meshRenderer with no filter, invalid - var mesh = meshFilter.mesh; - if (mesh == null) continue; // object has a null mesh, invalid - - // create new ProjectionTarget to represent the renderer - var target = new ProjectionTarget(renderer, mesh); - - // add the target to the list - _targets.Add(target); - } - } - protected virtual void UpdateTweakables() { // setup tweakable fields var scaleField = Fields[nameof(scale)]; diff --git a/Source/ConformalDecals/ModuleConformalFlag.cs b/Source/ConformalDecals/ModuleConformalFlag.cs index 4ce228b..4142a9a 100644 --- a/Source/ConformalDecals/ModuleConformalFlag.cs +++ b/Source/ConformalDecals/ModuleConformalFlag.cs @@ -95,7 +95,7 @@ namespace ConformalDecals { materialProperties.AddOrGetTextureProperty("_Decal", true).TextureUrl = newFlagUrl; UpdateMaterials(); - UpdateScale(); + UpdateProjection(); } private void SetFlagSymmetryCounterparts(string newFlagUrl) { diff --git a/Source/ConformalDecals/ModuleConformalText.cs b/Source/ConformalDecals/ModuleConformalText.cs index 3b8e5d2..7d97e2f 100644 --- a/Source/ConformalDecals/ModuleConformalText.cs +++ b/Source/ConformalDecals/ModuleConformalText.cs @@ -271,7 +271,7 @@ namespace ConformalDecals { _decalTextureProperty.SetTile(output.Window); UpdateMaterials(); - UpdateScale(); + UpdateProjection(); } protected override void UpdateMaterials() { diff --git a/Source/ConformalDecals/ProjectionTarget.cs b/Source/ConformalDecals/ProjectionTarget.cs index 621c56b..95ca253 100644 --- a/Source/ConformalDecals/ProjectionTarget.cs +++ b/Source/ConformalDecals/ProjectionTarget.cs @@ -5,6 +5,7 @@ namespace ConformalDecals { public class ProjectionTarget { // Target object data public readonly Transform target; + public readonly Part targetPart; private readonly Renderer _targetRenderer; private readonly Mesh _targetMesh; @@ -13,8 +14,9 @@ namespace ConformalDecals { // property block private readonly MaterialPropertyBlock _decalMPB; - public ProjectionTarget(MeshRenderer targetRenderer, Mesh targetMesh) { - target = targetRenderer.transform; + public ProjectionTarget(Part targetPart, MeshRenderer targetRenderer, Mesh targetMesh) { + this.targetPart = targetPart; + this.target = targetRenderer.transform; _targetRenderer = targetRenderer; _targetMesh = targetMesh; _decalMPB = new MaterialPropertyBlock();