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();