Refactor yet again and add autotiling

feature-multiSDF
Andrew Cassidy 4 years ago
parent a6fa2dd61c
commit d2f81058f8

@ -43,15 +43,13 @@ PART
MODULE MODULE
{ {
name = ModuleConformalDecalGeneric name = ModuleConformalDecal
decalFront = Decal-Front decalFront = Decal-Front
decalBack = Decal-Back decalBack = Decal-Back
decalModel = Decal-Model decalModel = Decal-Model
useBaseNormal = false useBaseNormal = false
} }
MODULE { MODULE {
@ -62,7 +60,7 @@ PART
MODULE { MODULE {
IDENTIFIER { IDENTIFIER {
name = ModuleConformalDecalGeneric name = ModuleConformalDecal
} }
DATA { DATA {
shader = ConformalDecals/Feature/Bumped shader = ConformalDecals/Feature/Bumped
@ -88,7 +86,7 @@ PART
MODULE { MODULE {
IDENTIFIER { IDENTIFIER {
name = ModuleConformalDecalGeneric name = ModuleConformalDecal
} }
DATA { DATA {
shader = ConformalDecals/Paint/Diffuse shader = ConformalDecals/Paint/Diffuse

@ -44,7 +44,7 @@ PART
MODULE MODULE
{ {
name = ModuleConformalDecalFlag name = ModuleConformalFlag
decalFront = Decal-Front decalFront = Decal-Front
decalBack = Decal-Back decalBack = Decal-Back

@ -57,10 +57,9 @@
<Compile Include="MaterialModifiers\MaterialProperty.cs" /> <Compile Include="MaterialModifiers\MaterialProperty.cs" />
<Compile Include="MaterialModifiers\MaterialPropertyCollection.cs" /> <Compile Include="MaterialModifiers\MaterialPropertyCollection.cs" />
<Compile Include="MaterialModifiers\MaterialTextureProperty.cs" /> <Compile Include="MaterialModifiers\MaterialTextureProperty.cs" />
<Compile Include="ModuleConformalDecalFlag.cs" /> <Compile Include="ModuleConformalFlag.cs" />
<Compile Include="ModuleConformalDecalGeneric.cs" />
<Compile Include="ProjectionTarget.cs" /> <Compile Include="ProjectionTarget.cs" />
<Compile Include="ModuleConformalDecalBase.cs" /> <Compile Include="ModuleConformalDecal.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Util\Logging.cs" /> <Compile Include="Util\Logging.cs" />
<Compile Include="Util\OrientedBounds.cs" /> <Compile Include="Util\OrientedBounds.cs" />

@ -22,7 +22,7 @@ namespace ConformalDecals {
var icon = partInfo.iconPrefab; var icon = partInfo.iconPrefab;
var decalModule = partInfo.partPrefab.FindModuleImplementing<ModuleConformalDecalBase>(); var decalModule = partInfo.partPrefab.FindModuleImplementing<ModuleConformalDecal>();
var frontTransform = Part.FindHeirarchyTransform(icon.transform, decalModule.decalFront); var frontTransform = Part.FindHeirarchyTransform(icon.transform, decalModule.decalFront);
var backTransform = Part.FindHeirarchyTransform(icon.transform, decalModule.decalBack); var backTransform = Part.FindHeirarchyTransform(icon.transform, decalModule.decalBack);

@ -1,6 +1,5 @@
using System; using System;
using UnityEngine; using UnityEngine;
using Object = UnityEngine.Object;
namespace ConformalDecals.MaterialModifiers { namespace ConformalDecals.MaterialModifiers {
public abstract class MaterialProperty : ScriptableObject { public abstract class MaterialProperty : ScriptableObject {
@ -16,7 +15,7 @@ namespace ConformalDecals.MaterialModifiers {
[SerializeField] protected string _propertyName; [SerializeField] protected string _propertyName;
public virtual void ParseNode(ConfigNode node) { 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"); PropertyName = node.GetValue("name");
} }

@ -210,12 +210,33 @@ namespace ConformalDecals.MaterialModifiers {
public void UpdateScale(Vector2 scale) { public void UpdateScale(Vector2 scale) {
foreach (var entry in _materialProperties) { foreach (var entry in _materialProperties) {
if (entry.Value is MaterialTextureProperty textureProperty) { if (entry.Value is MaterialTextureProperty textureProperty) {
textureProperty.UpdateScale(DecalMaterial, scale); textureProperty.UpdateScale(scale);
textureProperty.UpdateScale(PreviewMaterial, 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) { public void SetOpacity(float opacity) {
DecalMaterial.SetFloat(DecalPropertyIDs._DecalOpacity, opacity); DecalMaterial.SetFloat(DecalPropertyIDs._DecalOpacity, opacity);
PreviewMaterial.SetFloat(DecalPropertyIDs._DecalOpacity, opacity); PreviewMaterial.SetFloat(DecalPropertyIDs._DecalOpacity, opacity);

@ -8,9 +8,12 @@ namespace ConformalDecals.MaterialModifiers {
[SerializeField] public bool isNormal; [SerializeField] public bool isNormal;
[SerializeField] public bool isMain; [SerializeField] public bool isMain;
[SerializeField] public bool autoScale; [SerializeField] public bool autoScale;
[SerializeField] public bool autoTile;
[SerializeField] private bool _hasTile; [SerializeField] private bool _hasTile;
[SerializeField] private Rect _tileRect; [SerializeField] private Rect _tileRect;
[SerializeField] private Vector2 _baseTextureScale = Vector2.one;
[SerializeField] private Vector2 _textureOffset = Vector2.zero; [SerializeField] private Vector2 _textureOffset = Vector2.zero;
[SerializeField] private Vector2 _textureScale = Vector2.one; [SerializeField] private Vector2 _textureScale = Vector2.one;
@ -27,6 +30,7 @@ namespace ConformalDecals.MaterialModifiers {
public Rect TileRect { public Rect TileRect {
get => _tileRect; get => _tileRect;
set { set {
if (autoTile) return;
_hasTile = !(Mathf.Abs(value.width) < 0.1) || !(Mathf.Abs(value.height) < 0.1); _hasTile = !(Mathf.Abs(value.width) < 0.1) || !(Mathf.Abs(value.height) < 0.1);
_tileRect = value; _tileRect = value;
@ -40,10 +44,11 @@ namespace ConformalDecals.MaterialModifiers {
isNormal = ParsePropertyBool(node, "isNormalMap", true, (PropertyName == "_BumpMap") || (PropertyName == "_DecalBumpMap") || isNormal); isNormal = ParsePropertyBool(node, "isNormalMap", true, (PropertyName == "_BumpMap") || (PropertyName == "_DecalBumpMap") || isNormal);
isMain = ParsePropertyBool(node, "isMain", true, isMain); isMain = ParsePropertyBool(node, "isMain", true, isMain);
autoScale = ParsePropertyBool(node, "autoScale", true, autoScale); autoScale = ParsePropertyBool(node, "autoScale", true, autoScale);
autoTile = ParsePropertyBool(node, "autoTile", true, autoTile);
SetTexture(node.GetValue("textureUrl")); SetTexture(node.GetValue("textureUrl"));
if (node.HasValue("tileRect")) { if (node.HasValue("tileRect") && !autoTile) {
TileRect = ParsePropertyRect(node, "tileRect", true, _tileRect); TileRect = ParsePropertyRect(node, "tileRect", true, _tileRect);
} }
} }
@ -82,23 +87,26 @@ namespace ConformalDecals.MaterialModifiers {
material.SetTextureScale(_propertyID, _textureScale); material.SetTextureScale(_propertyID, _textureScale);
} }
public void UpdateScale(Material material, Vector2 scale) { public void UpdateScale(Vector2 scale) {
if (autoScale) { 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() { private void UpdateTiling() {
if (_hasTile) { if (_hasTile) {
_textureScale.x = Mathf.Approximately(0, _tileRect.width) ? 1 : _tileRect.width / texture.width; _baseTextureScale.x = Mathf.Approximately(0, _tileRect.width) ? 1 : _tileRect.width / texture.width;
_textureScale.y = Mathf.Approximately(0, _tileRect.height) ? 1 : _tileRect.height / texture.height; _baseTextureScale.y = Mathf.Approximately(0, _tileRect.height) ? 1 : _tileRect.height / texture.height;
_textureOffset.x = _tileRect.x / texture.width;
_textureOffset.y = _tileRect.y / texture.height;
} }
else { else {
_textureScale = Vector2.one; _baseTextureScale = Vector2.one;
_textureOffset = Vector2.zero;
} }
} }
} }

@ -5,7 +5,7 @@ using ConformalDecals.Util;
using UnityEngine; using UnityEngine;
namespace ConformalDecals { 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"), [KSPField(guiName = "#LOC_ConformalDecals_gui-scale", guiActive = false, guiActiveEditor = true, isPersistant = true, guiFormat = "F2", guiUnits = "m"),
UI_FloatRange(stepIncrement = 0.05f)] UI_FloatRange(stepIncrement = 0.05f)]
public float scale = 1.0f; public float scale = 1.0f;
@ -76,10 +76,23 @@ namespace ConformalDecals {
return _decalQueueCounter; return _decalQueueCounter;
} }
} }
public override void OnAwake() {
base.OnAwake();
if (materialProperties == null) {
materialProperties = ScriptableObject.CreateInstance<MaterialPropertyCollection>();
}
else {
materialProperties = ScriptableObject.Instantiate(materialProperties);
}
}
public override void OnLoad(ConfigNode node) { public override void OnLoad(ConfigNode node) {
this.Log("Loading module"); this.Log("Loading module");
try { try {
// SETUP TRANSFORMS
// find front transform // find front transform
decalFrontTransform = part.FindModelTransform(decalFront); decalFrontTransform = part.FindModelTransform(decalFront);
if (decalFrontTransform == null) throw new FormatException($"Could not find decalFront transform: '{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 // set shader
materialProperties.SetShader(shader); materialProperties.SetShader(shader);
// add texture nodes
foreach (var textureNode in node.GetNodes("TEXTURE")) {
materialProperties.ParseProperty<MaterialTextureProperty>(textureNode);
}
// add float nodes
foreach (var floatNode in node.GetNodes("FLOAT")) {
materialProperties.ParseProperty<MaterialTextureProperty>(floatNode);
}
// add color nodes
foreach (var colorNode in node.GetNodes("COLOR")) {
materialProperties.ParseProperty<MaterialColorProperty>(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) { catch (Exception e) {
this.LogException("Exception parsing partmodule", e); this.LogException("Exception parsing partmodule", e);
} }
if (HighLogic.LoadedSceneIsGame) { if (HighLogic.LoadedSceneIsGame) {
UpdateMaterials(); UpdateMaterials();
UpdateScale(); UpdateScale();
UpdateProjection(); UpdateProjection();
} }
else {
UpdateScale();
}
} }
public override void OnAwake() { public override void OnIconCreate() {
base.OnAwake(); UpdateScale();
if (materialProperties == null) {
materialProperties = ScriptableObject.CreateInstance<MaterialPropertyCollection>();
}
else {
materialProperties = ScriptableObject.Instantiate(materialProperties);
}
} }
public override void OnStart(StartState state) { public override void OnStart(StartState state) {
@ -175,11 +206,11 @@ namespace ConformalDecals {
UpdateTweakables(); UpdateTweakables();
} }
materialProperties.SetRenderQueue(DecalQueue); materialProperties.SetRenderQueue(DecalQueue);
UpdateMaterials(); UpdateMaterials();
if (HighLogic.LoadedSceneIsGame) { if (HighLogic.LoadedSceneIsGame) {
// set initial attachment state // set initial attachment state
if (part.parent == null) { if (part.parent == null) {
@ -312,7 +343,7 @@ namespace ConformalDecals {
materialProperties.UpdateMaterials(); materialProperties.UpdateMaterials();
materialProperties.SetOpacity(opacity); materialProperties.SetOpacity(opacity);
materialProperties.SetCutoff(cutoff); materialProperties.SetCutoff(cutoff);
_decalMaterial = materialProperties.DecalMaterial; _decalMaterial = materialProperties.DecalMaterial;
_previewMaterial = materialProperties.PreviewMaterial; _previewMaterial = materialProperties.PreviewMaterial;

@ -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<MaterialTextureProperty>(textureNode);
}
// add float nodes
foreach (var floatNode in node.GetNodes("FLOAT")) {
materialProperties.ParseProperty<MaterialTextureProperty>(floatNode);
}
// add color nodes
foreach (var colorNode in node.GetNodes("COLOR")) {
materialProperties.ParseProperty<MaterialColorProperty>(colorNode);
}
base.OnLoad(node);
}
public override void OnIconCreate() {
this.Log("called OnIconCreate");
UpdateScale();
}
}
}

@ -1,7 +1,7 @@
using ConformalDecals.Util; using ConformalDecals.Util;
namespace ConformalDecals { namespace ConformalDecals {
public class ModuleConformalDecalFlag : ModuleConformalDecalBase { public class ModuleConformalFlag : ModuleConformalDecal {
private const string DefaultFlag = "Squad/Flags/default"; private const string DefaultFlag = "Squad/Flags/default";
public override void OnLoad(ConfigNode node) { public override void OnLoad(ConfigNode node) {
@ -20,11 +20,6 @@ namespace ConformalDecals {
UpdateFlag(GetDefaultFlag()); UpdateFlag(GetDefaultFlag());
} }
public override void OnIconCreate() {
this.Log("called OnIconCreate");
UpdateScale();
}
public override void OnDestroy() { public override void OnDestroy() {
GameEvents.onMissionFlagSelect.Remove(UpdateFlag); GameEvents.onMissionFlagSelect.Remove(UpdateFlag);
base.OnDestroy(); base.OnDestroy();
Loading…
Cancel
Save