From 84c2107288a38fa9d8cf66f181c8e1c7ead9d3a8 Mon Sep 17 00:00:00 2001 From: drewcassidy Date: Tue, 26 May 2020 23:04:19 -0700 Subject: [PATCH] Begin writing material data parsing code --- Source/ConformalDecals/ConformalDecals.csproj | 9 ++- Source/ConformalDecals/Logging.cs | 23 ++++++ .../ColorPropertyMaterialModifier.cs | 16 ++++ .../FloatPropertyMaterialModifier.cs | 16 ++++ .../MaterialModifiers/MaterialModifier.cs | 78 +++++++++++++++++++ .../TexturePropertyMaterialModifier.cs | 55 +++++++++++++ .../ConformalDecals/ModuleConformalDecal.cs | 5 ++ 7 files changed, 201 insertions(+), 1 deletion(-) create mode 100644 Source/ConformalDecals/Logging.cs create mode 100644 Source/ConformalDecals/MaterialModifiers/ColorPropertyMaterialModifier.cs create mode 100644 Source/ConformalDecals/MaterialModifiers/FloatPropertyMaterialModifier.cs create mode 100644 Source/ConformalDecals/MaterialModifiers/MaterialModifier.cs create mode 100644 Source/ConformalDecals/MaterialModifiers/TexturePropertyMaterialModifier.cs create mode 100644 Source/ConformalDecals/ModuleConformalDecal.cs diff --git a/Source/ConformalDecals/ConformalDecals.csproj b/Source/ConformalDecals/ConformalDecals.csproj index 5901447..3b85b28 100644 --- a/Source/ConformalDecals/ConformalDecals.csproj +++ b/Source/ConformalDecals/ConformalDecals.csproj @@ -10,7 +10,8 @@ v4.6 512 true - 7 + 7.3 + ConformalDecals true @@ -43,6 +44,12 @@ + + + + + + diff --git a/Source/ConformalDecals/Logging.cs b/Source/ConformalDecals/Logging.cs new file mode 100644 index 0000000..ccebab3 --- /dev/null +++ b/Source/ConformalDecals/Logging.cs @@ -0,0 +1,23 @@ +using System; +using UnityEngine; + +namespace ConformalDecals { + public static class Logging { + public static void Log(this PartModule module, string message) => Debug.Log(FormatMessage(module, message)); + + public static void LogWarning(this PartModule module, string message) => + Debug.LogWarning(FormatMessage(module, message)); + + public static void LogError(this PartModule module, string message) => + Debug.LogError(FormatMessage(module, message)); + + public static void LogException(this PartModule module, string message, Exception exception) => + Debug.LogException(new Exception(FormatMessage(module, message), exception)); + + + private static string FormatMessage(PartModule module, string message) => + $"[{GetPartName(module.part)} {module.GetType()}] {message}"; + + private static string GetPartName(Part part) => part.partInfo?.name ?? part.name; + } +} \ No newline at end of file diff --git a/Source/ConformalDecals/MaterialModifiers/ColorPropertyMaterialModifier.cs b/Source/ConformalDecals/MaterialModifiers/ColorPropertyMaterialModifier.cs new file mode 100644 index 0000000..6cda4e2 --- /dev/null +++ b/Source/ConformalDecals/MaterialModifiers/ColorPropertyMaterialModifier.cs @@ -0,0 +1,16 @@ +using System; +using UnityEngine; + +namespace ConformalDecals.MaterialModifiers { + public class ColorPropertyMaterialModifier : MaterialModifier { + private readonly Color _color; + + public ColorPropertyMaterialModifier(ConfigNode node) : base(node) { + _color = ParsePropertyColor(node, "color", false); + } + + public override void Modify(Material material) { + material.SetColor(_propertyID, _color); + } + } +} \ No newline at end of file diff --git a/Source/ConformalDecals/MaterialModifiers/FloatPropertyMaterialModifier.cs b/Source/ConformalDecals/MaterialModifiers/FloatPropertyMaterialModifier.cs new file mode 100644 index 0000000..bf9ea66 --- /dev/null +++ b/Source/ConformalDecals/MaterialModifiers/FloatPropertyMaterialModifier.cs @@ -0,0 +1,16 @@ +using System; +using UnityEngine; + +namespace ConformalDecals.MaterialModifiers { + public class FloatPropertyMaterialModifier : MaterialModifier { + private readonly float _value; + + public FloatPropertyMaterialModifier(ConfigNode node) : base(node) { + _value = ParsePropertyFloat(node, "value", false); + } + + public override void Modify(Material material) { + material.SetFloat(_propertyID, _value); + } + } +} \ No newline at end of file diff --git a/Source/ConformalDecals/MaterialModifiers/MaterialModifier.cs b/Source/ConformalDecals/MaterialModifiers/MaterialModifier.cs new file mode 100644 index 0000000..6cdc711 --- /dev/null +++ b/Source/ConformalDecals/MaterialModifiers/MaterialModifier.cs @@ -0,0 +1,78 @@ +using System; +using UnityEngine; + +namespace ConformalDecals.MaterialModifiers { + public abstract class MaterialModifier { + public string Name { get; } + + protected readonly int _propertyID; + + + protected MaterialModifier(ConfigNode node) { + Name = node.GetValue("name"); + + if (Name == null) + throw new FormatException("name not found, cannot create material modifier"); + + if (Name == string.Empty) + throw new FormatException("name is empty, cannot create material modifier"); + + _propertyID = Shader.PropertyToID(Name); + } + + public abstract void Modify(Material material); + + private delegate bool TryParseDelegate(string valueString, out T value); + + protected bool ParsePropertyBool(ConfigNode node, string valueName, bool isOptional = false, bool defaultValue = false) { + return ParseProperty(node, valueName, bool.TryParse, isOptional, defaultValue); + } + + protected float ParsePropertyFloat(ConfigNode node, string valueName, bool isOptional = false, float defaultValue = 0.0f) { + return ParseProperty(node, valueName, float.TryParse, isOptional, defaultValue); + } + + protected int ParsePropertyInt(ConfigNode node, string valueName, bool isOptional = false, int defaultValue = 0) { + return ParseProperty(node, valueName, int.TryParse, isOptional, defaultValue); + } + + protected Color ParsePropertyColor(ConfigNode node, string valueName, bool isOptional = false, Color defaultValue = default(Color)) { + return ParseProperty(node, valueName, ParseExtensions.TryParseColor, isOptional, defaultValue); + } + + protected Rect ParsePropertyRect(ConfigNode node, string valueName, bool isOptional = false, Rect defaultValue = default(Rect)) { + return ParseProperty(node, valueName, ParseExtensions.TryParseRect, isOptional, defaultValue); + } + + protected Vector2 ParsePropertyVector2(ConfigNode node, string valueName, bool isOptional = false, Vector2 defaultValue = default(Vector2)) { + return ParseProperty(node, valueName, ParseExtensions.TryParseVector2, isOptional, defaultValue); + } + + private T ParseProperty(ConfigNode node, string valueName, TryParseDelegate tryParse, bool isOptional = false, T defaultValue = default(T)) { + string valueString = node.GetValue(valueName); + + if (isOptional) { + if (string.IsNullOrEmpty(valueString)) return defaultValue; + } + else { + if (valueString == null) + throw new FormatException($"Missing {typeof(T)} value {valueName} in property '{Name}'"); + + if (valueString == string.Empty) + throw new FormatException($"Empty {typeof(T)} value {valueName} in property '{Name}'"); + } + + if (tryParse(valueString, out var value)) { + return value; + } + + if (isOptional) { + return defaultValue; + } + + else { + throw new FormatException($"Improperly formatted {typeof(T)} value {valueName} in property '{Name}'"); + } + } + } +} \ No newline at end of file diff --git a/Source/ConformalDecals/MaterialModifiers/TexturePropertyMaterialModifier.cs b/Source/ConformalDecals/MaterialModifiers/TexturePropertyMaterialModifier.cs new file mode 100644 index 0000000..4fff832 --- /dev/null +++ b/Source/ConformalDecals/MaterialModifiers/TexturePropertyMaterialModifier.cs @@ -0,0 +1,55 @@ +using System; +using UnityEngine; + +namespace ConformalDecals.MaterialModifiers { + public class TexturePropertyMaterialModifier : MaterialModifier { + private readonly string _textureURL; + private readonly Texture2D _texture; + + private Vector2 _textureOffset; + private Vector2 _textureScale; + + public bool IsNormal { get; } + public bool IsMain { get; } + public bool AutoScale { get; } + + public Rect TileRect { get; } + + public TexturePropertyMaterialModifier(ConfigNode node) : base(node) { + _textureURL = node.GetValue("textureURL"); + + var textureInfo = GameDatabase.Instance.GetTextureInfo(_textureURL); + + if (textureInfo == null) + throw new Exception($"Cannot find texture: '{_textureURL}'"); + + _texture = IsNormal ? textureInfo.normalMap : textureInfo.texture; + + if (_texture == null) + throw new Exception($"Cannot get texture from texture info '{_textureURL}' isNormalMap = {IsNormal}"); + + IsNormal = ParsePropertyBool(node, "isNormalMap", true, false); + IsMain = ParsePropertyBool(node, "isMain", true, false); + AutoScale = ParsePropertyBool(node, "autoScale", true, false); + TileRect = ParsePropertyRect(node, "tileRect", true, new Rect(0, 0, _texture.width, _texture.height)); + + _textureScale.x = TileRect.width / _texture.width; + _textureScale.y = TileRect.height / _texture.height; + + _textureOffset.x = TileRect.x / _texture.width; + _textureOffset.y = TileRect.y / _texture.height; + } + + public override void Modify(Material material) { + material.SetTexture(_propertyID, _texture); + material.SetTextureOffset(_propertyID, _textureOffset); + material.SetTextureScale(_propertyID, _textureScale); + } + + public void UpdateScale(Material material, Vector2 scale) { + if (AutoScale) { + material.SetTextureScale(_propertyID, new Vector2(_textureScale.x * scale.x, _textureScale.y * scale.y)); + } + } + } +} \ No newline at end of file diff --git a/Source/ConformalDecals/ModuleConformalDecal.cs b/Source/ConformalDecals/ModuleConformalDecal.cs new file mode 100644 index 0000000..1904e83 --- /dev/null +++ b/Source/ConformalDecals/ModuleConformalDecal.cs @@ -0,0 +1,5 @@ +namespace ConformalDecals { + public class ModuleConformalDecal : PartModule { + [KSPField] public string decalPreviewTransform = ""; + } +} \ No newline at end of file