mirror of
https://github.com/drewcassidy/KSP-Conformal-Decals.git
synced 2024-09-01 18:23:54 +00:00
Fix scaling issues when part is created
• KSP rescales the model object back to 1,1,1 on start, so don't use that for the model that gets scaled • Some refactoring to consolidate property IDs • rename some classes because I am indecisive • Add and Get methods for MaterialPropertyCollection • Make an attempt at a scale culling fix
This commit is contained in:
@ -3,11 +3,19 @@ using System.Collections.Generic;
|
||||
using System.Runtime.Serialization;
|
||||
using UniLinq;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering;
|
||||
|
||||
namespace ConformalDecals.MaterialModifiers {
|
||||
public class MaterialPropertyCollection : ScriptableObject, ISerializationCallbackReceiver {
|
||||
private static readonly int OpacityId = Shader.PropertyToID("_DecalOpacity");
|
||||
private static readonly int CutoffId = Shader.PropertyToID("_Cutoff");
|
||||
[SerializeField] private Shader _shader;
|
||||
[SerializeField] private MaterialTextureProperty _mainTexture;
|
||||
[SerializeField] private string[] _serializedNames;
|
||||
[SerializeField] private MaterialProperty[] _serializedProperties;
|
||||
|
||||
private Dictionary<string, MaterialProperty> _materialProperties;
|
||||
|
||||
private Material _decalMaterial;
|
||||
private Material _previewMaterial;
|
||||
|
||||
public Shader DecalShader => _shader;
|
||||
|
||||
@ -16,6 +24,8 @@ namespace ConformalDecals.MaterialModifiers {
|
||||
if (_decalMaterial == null) {
|
||||
_decalMaterial = new Material(_shader);
|
||||
UpdateMaterial(_decalMaterial);
|
||||
|
||||
_previewMaterial.SetInt(DecalPropertyIDs._Cull, (int) CullMode.Off);
|
||||
}
|
||||
|
||||
return _decalMaterial;
|
||||
@ -27,7 +37,9 @@ namespace ConformalDecals.MaterialModifiers {
|
||||
if (_previewMaterial == null) {
|
||||
_previewMaterial = new Material(_shader);
|
||||
UpdateMaterial(_previewMaterial);
|
||||
|
||||
_previewMaterial.EnableKeyword("DECAL_PREVIEW");
|
||||
_previewMaterial.SetInt(DecalPropertyIDs._Cull, (int) CullMode.Back);
|
||||
}
|
||||
|
||||
return _previewMaterial;
|
||||
@ -50,41 +62,31 @@ namespace ConformalDecals.MaterialModifiers {
|
||||
Debug.Log("No main texture specified! returning 1 for aspect ratio");
|
||||
return 1;
|
||||
}
|
||||
|
||||
return MainTexture.AspectRatio;
|
||||
}
|
||||
}
|
||||
|
||||
[SerializeField] private string[] _serializedIDs;
|
||||
[SerializeField] private MaterialProperty[] _serializedProperties;
|
||||
|
||||
[SerializeField] private Shader _shader;
|
||||
[SerializeField] private MaterialTextureProperty _mainTexture;
|
||||
|
||||
private Dictionary<string, MaterialProperty> _materialProperties;
|
||||
|
||||
private Material _decalMaterial;
|
||||
private Material _previewMaterial;
|
||||
|
||||
public void OnBeforeSerialize() {
|
||||
Debug.Log($"Serializing MaterialPropertyCollection {this.GetInstanceID()}");
|
||||
if (_materialProperties == null) throw new SerializationException("Tried to serialize an unininitalized MaterialPropertyCollection");
|
||||
if (_materialProperties == null) throw new SerializationException("Tried to serialize an uninitialized MaterialPropertyCollection");
|
||||
|
||||
_serializedIDs = _materialProperties.Keys.ToArray();
|
||||
_serializedNames = _materialProperties.Keys.ToArray();
|
||||
_serializedProperties = _materialProperties.Values.ToArray();
|
||||
}
|
||||
|
||||
public void OnAfterDeserialize() {
|
||||
Debug.Log($"Deserializing MaterialPropertyCollection {this.GetInstanceID()}");
|
||||
if (_serializedIDs == null) throw new SerializationException("ID array is null");
|
||||
if (_serializedNames == null) throw new SerializationException("ID array is null");
|
||||
if (_serializedProperties == null) throw new SerializationException("Property array is null");
|
||||
if (_serializedProperties.Length != _serializedIDs.Length) throw new SerializationException("Material property arrays are different lengths.");
|
||||
if (_serializedProperties.Length != _serializedNames.Length) throw new SerializationException("Material property arrays are different lengths.");
|
||||
|
||||
_materialProperties ??= new Dictionary<string, MaterialProperty>();
|
||||
|
||||
for (var i = 0; i < _serializedIDs.Length; i++) {
|
||||
for (var i = 0; i < _serializedNames.Length; i++) {
|
||||
var property = MaterialProperty.Instantiate(_serializedProperties[i]);
|
||||
Debug.Log($"insantiating {property.GetType().Name} {property.GetInstanceID()}");
|
||||
_materialProperties.Add(_serializedIDs[i], property);
|
||||
_materialProperties.Add(_serializedNames[i], property);
|
||||
|
||||
if (property is MaterialTextureProperty textureProperty) {
|
||||
_mainTexture = textureProperty;
|
||||
@ -98,7 +100,7 @@ namespace ConformalDecals.MaterialModifiers {
|
||||
}
|
||||
|
||||
public void AddProperty(MaterialProperty property) {
|
||||
if (property == null) throw new ArgumentNullException("Tried to add a null property");
|
||||
if (property == null) throw new ArgumentNullException(nameof(property));
|
||||
|
||||
_materialProperties.Add(property.name, property);
|
||||
|
||||
@ -107,16 +109,61 @@ namespace ConformalDecals.MaterialModifiers {
|
||||
}
|
||||
}
|
||||
|
||||
public void ParseProperty<T>(ConfigNode node) where T : MaterialProperty {
|
||||
var name = node.GetValue("name");
|
||||
if (string.IsNullOrEmpty(name)) throw new ArgumentException("node has no name");
|
||||
public T AddProperty<T>(string propertyName) where T : MaterialProperty {
|
||||
if (_materialProperties.ContainsKey(propertyName)) throw new ArgumentException("property with that name already exists!");
|
||||
var newProperty = MaterialProperty.CreateInstance<T>();
|
||||
newProperty.PropertyName = propertyName;
|
||||
_materialProperties.Add(propertyName, newProperty);
|
||||
return newProperty;
|
||||
}
|
||||
|
||||
Debug.Log($"Parsing material property {name}");
|
||||
public T GetProperty<T>(string propertyName) where T : MaterialProperty {
|
||||
if (_materialProperties.ContainsKey(propertyName) && _materialProperties[propertyName] is T property) {
|
||||
return property;
|
||||
}
|
||||
else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
public T AddOrGetProperty<T>(string propertyName) where T : MaterialProperty {
|
||||
if (_materialProperties.ContainsKey(propertyName) && _materialProperties[propertyName] is T property) {
|
||||
return property;
|
||||
}
|
||||
else {
|
||||
return AddProperty<T>(propertyName);
|
||||
}
|
||||
}
|
||||
|
||||
public MaterialTextureProperty AddTextureProperty(string propertyName, bool isMain = false) {
|
||||
var newProperty = AddProperty<MaterialTextureProperty>(propertyName);
|
||||
if (isMain) MainTexture = newProperty;
|
||||
return newProperty;
|
||||
}
|
||||
|
||||
public MaterialTextureProperty GetTextureProperty(string propertyName) {
|
||||
return GetProperty<MaterialTextureProperty>(propertyName);
|
||||
}
|
||||
|
||||
public MaterialTextureProperty AddOrGetTextureProperty(string propertyName, bool isMain = false) {
|
||||
if (_materialProperties.ContainsKey(propertyName) && _materialProperties[propertyName] is MaterialTextureProperty property) {
|
||||
return property;
|
||||
}
|
||||
else {
|
||||
return AddTextureProperty(propertyName, isMain);
|
||||
}
|
||||
}
|
||||
|
||||
public void ParseProperty<T>(ConfigNode node) where T : MaterialProperty {
|
||||
var propertyName = node.GetValue("name");
|
||||
if (string.IsNullOrEmpty(propertyName)) throw new ArgumentException("node has no name");
|
||||
|
||||
Debug.Log($"Parsing material property {propertyName}");
|
||||
|
||||
T newProperty;
|
||||
|
||||
if (_materialProperties.ContainsKey(name)) {
|
||||
if (_materialProperties[name] is T property) {
|
||||
if (_materialProperties.ContainsKey(propertyName)) {
|
||||
if (_materialProperties[propertyName] is T property) {
|
||||
newProperty = property;
|
||||
property.ParseNode(node);
|
||||
}
|
||||
@ -128,7 +175,7 @@ namespace ConformalDecals.MaterialModifiers {
|
||||
newProperty = MaterialProperty.CreateInstance<T>();
|
||||
Debug.Log($"Adding new material property of type {newProperty.GetType().Name} {newProperty.GetInstanceID()}");
|
||||
newProperty.ParseNode(node);
|
||||
_materialProperties.Add(name, newProperty);
|
||||
_materialProperties.Add(propertyName, newProperty);
|
||||
}
|
||||
|
||||
if (newProperty is MaterialTextureProperty textureProperty && textureProperty.isMain) {
|
||||
@ -170,11 +217,13 @@ namespace ConformalDecals.MaterialModifiers {
|
||||
}
|
||||
|
||||
public void SetOpacity(float opacity) {
|
||||
DecalMaterial.SetFloat(OpacityId, opacity);
|
||||
DecalMaterial.SetFloat(DecalPropertyIDs._DecalOpacity, opacity);
|
||||
PreviewMaterial.SetFloat(DecalPropertyIDs._DecalOpacity, opacity);
|
||||
}
|
||||
|
||||
public void SetCutoff(float cutoff) {
|
||||
DecalMaterial.SetFloat(CutoffId, cutoff);
|
||||
DecalMaterial.SetFloat(DecalPropertyIDs._Cutoff, cutoff);
|
||||
PreviewMaterial.SetFloat(DecalPropertyIDs._Cutoff, cutoff);
|
||||
}
|
||||
|
||||
public void UpdateMaterials() {
|
||||
@ -195,8 +244,11 @@ namespace ConformalDecals.MaterialModifiers {
|
||||
|
||||
public void UpdateMaterial(Material material) {
|
||||
if (material == null) throw new ArgumentNullException(nameof(material));
|
||||
|
||||
|
||||
foreach (var entry in _materialProperties) {
|
||||
Debug.Log($"Applying material property {entry.Key} {entry.Value.PropertyName} {entry.Value.GetInstanceID()}");
|
||||
|
||||
entry.Value.Modify(material);
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user