diff --git a/Distribution/GameData/ConformalDecals/Parts/decal-blank.cfg b/Distribution/GameData/ConformalDecals/Parts/decal-blank.cfg index 3f2e4a0..11d5087 100644 --- a/Distribution/GameData/ConformalDecals/Parts/decal-blank.cfg +++ b/Distribution/GameData/ConformalDecals/Parts/decal-blank.cfg @@ -43,15 +43,13 @@ PART MODULE { - name = ModuleConformalDecalGeneric + name = ModuleConformalDecal decalFront = Decal-Front decalBack = Decal-Back decalModel = Decal-Model useBaseNormal = false - - } MODULE { @@ -62,7 +60,7 @@ PART MODULE { IDENTIFIER { - name = ModuleConformalDecalGeneric + name = ModuleConformalDecal } DATA { shader = ConformalDecals/Feature/Bumped @@ -88,7 +86,7 @@ PART MODULE { IDENTIFIER { - name = ModuleConformalDecalGeneric + name = ModuleConformalDecal } DATA { shader = ConformalDecals/Paint/Diffuse diff --git a/Distribution/GameData/ConformalDecals/Parts/decal-flag.cfg b/Distribution/GameData/ConformalDecals/Parts/decal-flag.cfg index 7b1a828..a62e727 100644 --- a/Distribution/GameData/ConformalDecals/Parts/decal-flag.cfg +++ b/Distribution/GameData/ConformalDecals/Parts/decal-flag.cfg @@ -44,7 +44,7 @@ PART MODULE { - name = ModuleConformalDecalFlag + name = ModuleConformalFlag decalFront = Decal-Front decalBack = Decal-Back diff --git a/Distribution/GameData/ConformalDecals/Plugins/ConformalDecals.dll b/Distribution/GameData/ConformalDecals/Plugins/ConformalDecals.dll index 9c94dcc..5e4bdd4 100644 Binary files a/Distribution/GameData/ConformalDecals/Plugins/ConformalDecals.dll and b/Distribution/GameData/ConformalDecals/Plugins/ConformalDecals.dll differ diff --git a/Source/ConformalDecals/ConformalDecals.csproj b/Source/ConformalDecals/ConformalDecals.csproj index c70863f..3372882 100644 --- a/Source/ConformalDecals/ConformalDecals.csproj +++ b/Source/ConformalDecals/ConformalDecals.csproj @@ -57,10 +57,9 @@ - - + - + diff --git a/Source/ConformalDecals/DecalIconFixer.cs b/Source/ConformalDecals/DecalIconFixer.cs index 9255f85..d0f9b8a 100644 --- a/Source/ConformalDecals/DecalIconFixer.cs +++ b/Source/ConformalDecals/DecalIconFixer.cs @@ -22,7 +22,7 @@ namespace ConformalDecals { var icon = partInfo.iconPrefab; - var decalModule = partInfo.partPrefab.FindModuleImplementing(); + var decalModule = partInfo.partPrefab.FindModuleImplementing(); var frontTransform = Part.FindHeirarchyTransform(icon.transform, decalModule.decalFront); var backTransform = Part.FindHeirarchyTransform(icon.transform, decalModule.decalBack); diff --git a/Source/ConformalDecals/MaterialModifiers/MaterialProperty.cs b/Source/ConformalDecals/MaterialModifiers/MaterialProperty.cs index 61ac6ef..8f6e9de 100644 --- a/Source/ConformalDecals/MaterialModifiers/MaterialProperty.cs +++ b/Source/ConformalDecals/MaterialModifiers/MaterialProperty.cs @@ -1,6 +1,5 @@ using System; using UnityEngine; -using Object = UnityEngine.Object; namespace ConformalDecals.MaterialModifiers { public abstract class MaterialProperty : ScriptableObject { @@ -16,7 +15,7 @@ namespace ConformalDecals.MaterialModifiers { [SerializeField] protected string _propertyName; public virtual void ParseNode(ConfigNode node) { - if (node == null) throw new ArgumentNullException("node cannot be null"); + if (node == null) throw new ArgumentNullException(nameof(node)); PropertyName = node.GetValue("name"); } diff --git a/Source/ConformalDecals/MaterialModifiers/MaterialPropertyCollection.cs b/Source/ConformalDecals/MaterialModifiers/MaterialPropertyCollection.cs index 764b0f9..f0b7e14 100644 --- a/Source/ConformalDecals/MaterialModifiers/MaterialPropertyCollection.cs +++ b/Source/ConformalDecals/MaterialModifiers/MaterialPropertyCollection.cs @@ -210,12 +210,33 @@ namespace ConformalDecals.MaterialModifiers { public void UpdateScale(Vector2 scale) { foreach (var entry in _materialProperties) { if (entry.Value is MaterialTextureProperty textureProperty) { - textureProperty.UpdateScale(DecalMaterial, scale); - textureProperty.UpdateScale(PreviewMaterial, scale); + textureProperty.UpdateScale(scale); + textureProperty.Modify(_decalMaterial); + textureProperty.Modify(_previewMaterial); } } } + public void UpdateTile(Rect tile) { + if (_mainTexture == null) throw new InvalidOperationException("UpdateTile called but no main texture is specified!"); + Vector2 scale; + Vector2 offset; + + scale.x = tile.width / _mainTexture.texture.width; + scale.y = tile.height / _mainTexture.texture.height; + + offset.x = tile.x / _mainTexture.texture.width; + offset.y = tile.y / _mainTexture.texture.height; + + foreach (var entry in _materialProperties) { + if (entry.Value is MaterialTextureProperty textureProperty) { + textureProperty.UpdateTiling(scale, offset); + textureProperty.Modify(_decalMaterial); + textureProperty.Modify(_previewMaterial); + } + } + } + public void SetOpacity(float opacity) { DecalMaterial.SetFloat(DecalPropertyIDs._DecalOpacity, opacity); PreviewMaterial.SetFloat(DecalPropertyIDs._DecalOpacity, opacity); diff --git a/Source/ConformalDecals/MaterialModifiers/MaterialTextureProperty.cs b/Source/ConformalDecals/MaterialModifiers/MaterialTextureProperty.cs index 8f6ad4e..d5c7681 100644 --- a/Source/ConformalDecals/MaterialModifiers/MaterialTextureProperty.cs +++ b/Source/ConformalDecals/MaterialModifiers/MaterialTextureProperty.cs @@ -8,9 +8,12 @@ namespace ConformalDecals.MaterialModifiers { [SerializeField] public bool isNormal; [SerializeField] public bool isMain; [SerializeField] public bool autoScale; + [SerializeField] public bool autoTile; [SerializeField] private bool _hasTile; [SerializeField] private Rect _tileRect; + [SerializeField] private Vector2 _baseTextureScale = Vector2.one; + [SerializeField] private Vector2 _textureOffset = Vector2.zero; [SerializeField] private Vector2 _textureScale = Vector2.one; @@ -27,6 +30,7 @@ namespace ConformalDecals.MaterialModifiers { public Rect TileRect { get => _tileRect; set { + if (autoTile) return; _hasTile = !(Mathf.Abs(value.width) < 0.1) || !(Mathf.Abs(value.height) < 0.1); _tileRect = value; @@ -40,10 +44,11 @@ namespace ConformalDecals.MaterialModifiers { isNormal = ParsePropertyBool(node, "isNormalMap", true, (PropertyName == "_BumpMap") || (PropertyName == "_DecalBumpMap") || isNormal); isMain = ParsePropertyBool(node, "isMain", true, isMain); autoScale = ParsePropertyBool(node, "autoScale", true, autoScale); + autoTile = ParsePropertyBool(node, "autoTile", true, autoTile); SetTexture(node.GetValue("textureUrl")); - if (node.HasValue("tileRect")) { + if (node.HasValue("tileRect") && !autoTile) { TileRect = ParsePropertyRect(node, "tileRect", true, _tileRect); } } @@ -82,23 +87,26 @@ namespace ConformalDecals.MaterialModifiers { material.SetTextureScale(_propertyID, _textureScale); } - public void UpdateScale(Material material, Vector2 scale) { + public void UpdateScale(Vector2 scale) { if (autoScale) { - material.SetTextureScale(_propertyID, new Vector2(_textureScale.x * scale.x, _textureScale.y * scale.y)); + _textureScale = _baseTextureScale * scale; + } + } + + public void UpdateTiling(Vector2 textureScale, Vector2 textureOffset) { + if (autoTile) { + _textureScale = textureScale; + _textureOffset = textureOffset; } } private void UpdateTiling() { if (_hasTile) { - _textureScale.x = Mathf.Approximately(0, _tileRect.width) ? 1 : _tileRect.width / texture.width; - _textureScale.y = Mathf.Approximately(0, _tileRect.height) ? 1 : _tileRect.height / texture.height; - - _textureOffset.x = _tileRect.x / texture.width; - _textureOffset.y = _tileRect.y / texture.height; + _baseTextureScale.x = Mathf.Approximately(0, _tileRect.width) ? 1 : _tileRect.width / texture.width; + _baseTextureScale.y = Mathf.Approximately(0, _tileRect.height) ? 1 : _tileRect.height / texture.height; } else { - _textureScale = Vector2.one; - _textureOffset = Vector2.zero; + _baseTextureScale = Vector2.one; } } } diff --git a/Source/ConformalDecals/ModuleConformalDecalBase.cs b/Source/ConformalDecals/ModuleConformalDecal.cs similarity index 92% rename from Source/ConformalDecals/ModuleConformalDecalBase.cs rename to Source/ConformalDecals/ModuleConformalDecal.cs index da7445c..9c6e425 100644 --- a/Source/ConformalDecals/ModuleConformalDecalBase.cs +++ b/Source/ConformalDecals/ModuleConformalDecal.cs @@ -5,7 +5,7 @@ using ConformalDecals.Util; using UnityEngine; namespace ConformalDecals { - public abstract class ModuleConformalDecalBase : PartModule { + public class ModuleConformalDecal : PartModule { [KSPField(guiName = "#LOC_ConformalDecals_gui-scale", guiActive = false, guiActiveEditor = true, isPersistant = true, guiFormat = "F2", guiUnits = "m"), UI_FloatRange(stepIncrement = 0.05f)] public float scale = 1.0f; @@ -76,10 +76,23 @@ namespace ConformalDecals { return _decalQueueCounter; } } + + public override void OnAwake() { + base.OnAwake(); + if (materialProperties == null) { + materialProperties = ScriptableObject.CreateInstance(); + } + else { + materialProperties = ScriptableObject.Instantiate(materialProperties); + } + } + public override void OnLoad(ConfigNode node) { this.Log("Loading module"); try { + // SETUP TRANSFORMS + // find front transform decalFrontTransform = part.FindModelTransform(decalFront); if (decalFrontTransform == null) throw new FormatException($"Could not find decalFront transform: '{decalFront}'."); @@ -135,34 +148,52 @@ namespace ConformalDecals { } } - DecalIconFixer.QueuePart(part.name); - + // PARSE MATERIAL PROPERTIES + // set shader materialProperties.SetShader(shader); + + // add texture nodes + foreach (var textureNode in node.GetNodes("TEXTURE")) { + materialProperties.ParseProperty(textureNode); + } + + // add float nodes + foreach (var floatNode in node.GetNodes("FLOAT")) { + materialProperties.ParseProperty(floatNode); + } + + // add color nodes + foreach (var colorNode in node.GetNodes("COLOR")) { + materialProperties.ParseProperty(colorNode); + } + + var tileString = node.GetValue("tile"); + if (!string.IsNullOrEmpty(tileString)) { + var tileValid = ParseExtensions.TryParseRect(tileString, out var tile); + + if (!tileValid) throw new FormatException($"Improperly formatted value for tile '{tileString}"); + else { + materialProperties.UpdateTile(tile); + } + } + + // QUEUE PART FOR ICON FIXING IN VAB + DecalIconFixer.QueuePart(part.name); } catch (Exception e) { this.LogException("Exception parsing partmodule", e); } - + if (HighLogic.LoadedSceneIsGame) { UpdateMaterials(); UpdateScale(); UpdateProjection(); } - else { - UpdateScale(); - } } - - public override void OnAwake() { - base.OnAwake(); - - if (materialProperties == null) { - materialProperties = ScriptableObject.CreateInstance(); - } - else { - materialProperties = ScriptableObject.Instantiate(materialProperties); - } + + public override void OnIconCreate() { + UpdateScale(); } public override void OnStart(StartState state) { @@ -175,11 +206,11 @@ namespace ConformalDecals { UpdateTweakables(); } - + materialProperties.SetRenderQueue(DecalQueue); UpdateMaterials(); - + if (HighLogic.LoadedSceneIsGame) { // set initial attachment state if (part.parent == null) { @@ -312,7 +343,7 @@ namespace ConformalDecals { materialProperties.UpdateMaterials(); materialProperties.SetOpacity(opacity); materialProperties.SetCutoff(cutoff); - + _decalMaterial = materialProperties.DecalMaterial; _previewMaterial = materialProperties.PreviewMaterial; diff --git a/Source/ConformalDecals/ModuleConformalDecalGeneric.cs b/Source/ConformalDecals/ModuleConformalDecalGeneric.cs deleted file mode 100644 index 5960578..0000000 --- a/Source/ConformalDecals/ModuleConformalDecalGeneric.cs +++ /dev/null @@ -1,34 +0,0 @@ -using ConformalDecals.MaterialModifiers; -using ConformalDecals.Util; -using UnityEngine; - -namespace ConformalDecals { - public class ModuleConformalDecalGeneric : ModuleConformalDecalBase { - public override void OnLoad(ConfigNode node) { - - // set shader - materialProperties.SetShader(shader); - // add texture nodes - foreach (var textureNode in node.GetNodes("TEXTURE")) { - materialProperties.ParseProperty(textureNode); - } - - // add float nodes - foreach (var floatNode in node.GetNodes("FLOAT")) { - materialProperties.ParseProperty(floatNode); - } - - // add color nodes - foreach (var colorNode in node.GetNodes("COLOR")) { - materialProperties.ParseProperty(colorNode); - } - - base.OnLoad(node); - } - - public override void OnIconCreate() { - this.Log("called OnIconCreate"); - UpdateScale(); - } - } -} \ No newline at end of file diff --git a/Source/ConformalDecals/ModuleConformalDecalFlag.cs b/Source/ConformalDecals/ModuleConformalFlag.cs similarity index 87% rename from Source/ConformalDecals/ModuleConformalDecalFlag.cs rename to Source/ConformalDecals/ModuleConformalFlag.cs index 8aa5bea..0e12811 100644 --- a/Source/ConformalDecals/ModuleConformalDecalFlag.cs +++ b/Source/ConformalDecals/ModuleConformalFlag.cs @@ -1,7 +1,7 @@ using ConformalDecals.Util; namespace ConformalDecals { - public class ModuleConformalDecalFlag : ModuleConformalDecalBase { + public class ModuleConformalFlag : ModuleConformalDecal { private const string DefaultFlag = "Squad/Flags/default"; public override void OnLoad(ConfigNode node) { @@ -20,11 +20,6 @@ namespace ConformalDecals { UpdateFlag(GetDefaultFlag()); } - public override void OnIconCreate() { - this.Log("called OnIconCreate"); - UpdateScale(); - } - public override void OnDestroy() { GameEvents.onMissionFlagSelect.Remove(UpdateFlag); base.OnDestroy();