Refactor material parsing and loading

This should hopefully pave the way for usable module switching using B9PS
This commit is contained in:
2020-06-02 00:53:17 -07:00
parent 114fc745f0
commit 7e520f97ca
9 changed files with 133 additions and 151 deletions

View File

@ -2,10 +2,10 @@ using System;
using UnityEngine;
namespace ConformalDecals.MaterialModifiers {
public class ColorMaterialProperty : MaterialProperty {
public class MaterialColorProperty : MaterialProperty {
private readonly Color _color;
public ColorMaterialProperty(ConfigNode node) : base(node) {
public MaterialColorProperty(ConfigNode node) : base(node) {
_color = ParsePropertyColor(node, "color", false);
}

View File

@ -2,10 +2,10 @@ using System;
using UnityEngine;
namespace ConformalDecals.MaterialModifiers {
public class FloatMaterialProperty : MaterialProperty {
public class MaterialFloatProperty : MaterialProperty {
private readonly float _value;
public FloatMaterialProperty(ConfigNode node) : base(node) {
public MaterialFloatProperty(ConfigNode node) : base(node) {
_value = ParsePropertyFloat(node, "value", false);
}

View File

@ -1,22 +1,16 @@
using System;
using System.Collections.Generic;
using Smooth.Delegates;
using UnityEngine;
namespace ConformalDecals.MaterialModifiers {
public class MaterialPropertyCollection : ScriptableObject {
private static int _opacityID = Shader.PropertyToID("_Opacity");
private static int _cutoffID = Shader.PropertyToID("_Cutoff");
private static readonly int OpacityId = Shader.PropertyToID("_Opacity");
private static readonly int CutoffId = Shader.PropertyToID("_Cutoff");
public TextureMaterialProperty MainTextureProperty { get; set; }
public bool UseBaseNormal { get; private set; }
public MaterialTextureProperty MainMaterialTextureProperty { get; set; }
private List<MaterialProperty> _materialProperties;
private List<TextureMaterialProperty> _textureMaterialProperties;
public String BaseNormalSrc { get; private set; }
public String BaseNormalDest { get; private set; }
private List<MaterialTextureProperty> _textureMaterialProperties;
public Material DecalMaterial {
get {
@ -28,107 +22,60 @@ namespace ConformalDecals.MaterialModifiers {
}
}
private Shader _decalShader;
private Shader _decalShader;
private Material _protoDecalMaterial;
private const string _normalTextureName = "_BumpMap";
public void Initialize(ConfigNode node, PartModule module) {
// Initialize fields
public void Initialize() {
_materialProperties = new List<MaterialProperty>();
_textureMaterialProperties = new List<TextureMaterialProperty>();
// Get shader
var shaderString = node.GetValue("shader") ?? throw new FormatException("Missing shader name in material");
_decalShader = Shabby.Shabby.FindShader(shaderString);
// note to self: null coalescing does not work on UnityEngine classes
if (_decalShader == null) {
throw new FormatException($"Shader not found: '{shaderString}'");
}
// Get useBaseNormal value
var useBaseNormalString = node.GetValue("useBaseNormal");
if (useBaseNormalString != null) {
if (bool.TryParse(useBaseNormalString, out var useBaseNormalRef)) {
UseBaseNormal = useBaseNormalRef;
}
else {
throw new FormatException($"Improperly formatted bool value for 'useBaseNormal' : {useBaseNormalString}");
}
}
else {
UseBaseNormal = false;
}
// Get basenormal source and destination property names
BaseNormalSrc = node.GetValue("baseNormalSource") ?? _normalTextureName;
BaseNormalDest = node.GetValue("baseNormalDestination") ?? _normalTextureName;
// Parse all materialProperties
foreach (ConfigNode propertyNode in node.nodes) {
try {
MaterialProperty property;
switch (propertyNode.name) {
case "FLOAT":
property = new FloatMaterialProperty(propertyNode);
break;
case "COLOR":
property = new ColorMaterialProperty(propertyNode);
break;
case "TEXTURE":
property = new TextureMaterialProperty(propertyNode);
var textureModifier = (TextureMaterialProperty) property;
if (textureModifier.IsMain) {
if (MainTextureProperty == null) {
MainTextureProperty = textureModifier;
}
else {
// multiple textures have been marked as main!
// non-fatal issue, ignore this one and keep using current main texture
module.LogWarning(
$"Material texture property {textureModifier.TextureUrl} is marked as main, but material already has a main texture! \n" +
$"Defaulting to {MainTextureProperty.TextureUrl}");
}
}
_textureMaterialProperties.Add(textureModifier);
break;
default:
throw new FormatException($"Invalid property type '{propertyNode.name}' in material");
}
_materialProperties.Add(property);
}
catch (Exception e) {
// Catch exception from parsing current material property
// And print it to the log as an Error
module.LogException("Exception while parsing material node", e);
}
}
module.Log($"Parsed {_materialProperties.Count} properties");
_textureMaterialProperties = new List<MaterialTextureProperty>();
}
public void AddProperty(MaterialProperty property) {
foreach (var p in _materialProperties) {
if (p.PropertyName == property.PropertyName) {
_materialProperties.Remove(property);
}
}
_materialProperties.Add(property);
if (property is MaterialTextureProperty textureProperty) {
foreach (var p in _textureMaterialProperties) {
if (p.PropertyName == textureProperty.PropertyName) {
_textureMaterialProperties.Remove(textureProperty);
}
}
_textureMaterialProperties.Add(textureProperty);
if (textureProperty.IsMain) MainMaterialTextureProperty ??= textureProperty;
}
}
public void SetShader(string shaderName) {
if (_decalShader == null && string.IsNullOrEmpty(shaderName)) {
throw new FormatException("Shader name not provided");
}
var shader = Shabby.Shabby.FindShader(shaderName);
if (shader == null) throw new FormatException($"Unable to find specified shader '{shaderName}'");
_decalShader = shader;
}
public void SetScale(Material material, Vector2 scale) {
foreach (var textureProperty in _textureMaterialProperties) {
textureProperty.UpdateScale(material, scale);
}
}
public void SetOpacity(Material material, float opacity) {
material.SetFloat(_opacityID, opacity);
material.SetFloat(OpacityId, opacity);
}
public void SetCutoff(Material material, float cutoff) {
material.SetFloat(_cutoffID, cutoff);
material.SetFloat(CutoffId, cutoff);
}
private Material MakeMaterial(Shader shader) {

View File

@ -2,7 +2,7 @@ using System;
using UnityEngine;
namespace ConformalDecals.MaterialModifiers {
public class TextureMaterialProperty : MaterialProperty {
public class MaterialTextureProperty : MaterialProperty {
public string TextureUrl { get; }
public Texture2D TextureRef { get; }
@ -17,7 +17,7 @@ namespace ConformalDecals.MaterialModifiers {
private readonly Vector2 _textureOffset;
private readonly Vector2 _textureScale;
public TextureMaterialProperty(ConfigNode node) : base(node) {
public MaterialTextureProperty(ConfigNode node) : base(node) {
TextureUrl = node.GetValue("textureURL");
var textureInfo = GameDatabase.Instance.GetTextureInfo(TextureUrl);