2020-05-27 06:04:19 +00:00
|
|
|
using System;
|
|
|
|
using UnityEngine;
|
|
|
|
|
|
|
|
namespace ConformalDecals.MaterialModifiers {
|
2020-06-02 07:53:17 +00:00
|
|
|
public class MaterialTextureProperty : MaterialProperty {
|
2020-06-04 07:12:09 +00:00
|
|
|
[SerializeField] public Texture2D texture;
|
|
|
|
|
|
|
|
[SerializeField] public bool isNormal;
|
|
|
|
[SerializeField] public bool isMain;
|
|
|
|
[SerializeField] public bool autoScale;
|
2020-06-06 20:20:50 +00:00
|
|
|
[SerializeField] public bool autoTile;
|
2020-06-04 07:12:09 +00:00
|
|
|
|
|
|
|
[SerializeField] private bool _hasTile;
|
|
|
|
[SerializeField] private Rect _tileRect;
|
2020-06-06 20:20:50 +00:00
|
|
|
[SerializeField] private Vector2 _baseTextureScale = Vector2.one;
|
|
|
|
|
2020-06-04 07:12:09 +00:00
|
|
|
[SerializeField] private Vector2 _textureOffset = Vector2.zero;
|
|
|
|
[SerializeField] private Vector2 _textureScale = Vector2.one;
|
|
|
|
|
|
|
|
public float AspectRatio {
|
|
|
|
get {
|
2020-06-06 19:33:51 +00:00
|
|
|
if (texture == null) return 1;
|
2020-06-05 07:29:23 +00:00
|
|
|
|
2020-06-06 19:33:51 +00:00
|
|
|
if (!_hasTile) return ((float) texture.height) / texture.width;
|
2020-06-05 07:29:23 +00:00
|
|
|
|
2020-06-04 07:12:09 +00:00
|
|
|
return _tileRect.height / _tileRect.width;
|
|
|
|
}
|
|
|
|
}
|
2020-05-30 06:26:33 +00:00
|
|
|
|
2020-06-04 07:12:09 +00:00
|
|
|
public Rect TileRect {
|
|
|
|
get => _tileRect;
|
|
|
|
set {
|
2020-06-06 20:20:50 +00:00
|
|
|
if (autoTile) return;
|
2020-06-04 07:12:09 +00:00
|
|
|
_hasTile = !(Mathf.Abs(value.width) < 0.1) || !(Mathf.Abs(value.height) < 0.1);
|
2020-05-27 06:04:19 +00:00
|
|
|
|
2020-06-04 07:12:09 +00:00
|
|
|
_tileRect = value;
|
|
|
|
UpdateTiling();
|
|
|
|
}
|
|
|
|
}
|
2020-05-30 06:26:33 +00:00
|
|
|
|
2020-06-04 07:12:09 +00:00
|
|
|
public override void ParseNode(ConfigNode node) {
|
|
|
|
base.ParseNode(node);
|
2020-05-30 04:02:58 +00:00
|
|
|
|
2020-06-06 05:54:55 +00:00
|
|
|
isNormal = ParsePropertyBool(node, "isNormalMap", true, (PropertyName == "_BumpMap") || (PropertyName == "_DecalBumpMap") || isNormal);
|
2020-06-04 07:12:09 +00:00
|
|
|
isMain = ParsePropertyBool(node, "isMain", true, isMain);
|
|
|
|
autoScale = ParsePropertyBool(node, "autoScale", true, autoScale);
|
2020-06-06 20:20:50 +00:00
|
|
|
autoTile = ParsePropertyBool(node, "autoTile", true, autoTile);
|
2020-05-27 06:04:19 +00:00
|
|
|
|
2020-06-04 07:12:09 +00:00
|
|
|
SetTexture(node.GetValue("textureUrl"));
|
|
|
|
|
2020-06-06 20:20:50 +00:00
|
|
|
if (node.HasValue("tileRect") && !autoTile) {
|
2020-06-04 07:12:09 +00:00
|
|
|
TileRect = ParsePropertyRect(node, "tileRect", true, _tileRect);
|
|
|
|
}
|
|
|
|
}
|
2020-05-27 06:04:19 +00:00
|
|
|
|
2020-06-04 07:12:09 +00:00
|
|
|
public void SetTexture(string textureUrl) {
|
|
|
|
if ((textureUrl == null && isNormal) || textureUrl == "Bump") {
|
2020-06-03 03:36:45 +00:00
|
|
|
texture = Texture2D.normalTexture;
|
2020-06-03 00:11:38 +00:00
|
|
|
}
|
2020-06-04 07:12:09 +00:00
|
|
|
else if ((textureUrl == null && !isNormal) || textureUrl == "White") {
|
2020-06-03 03:36:45 +00:00
|
|
|
texture = Texture2D.whiteTexture;
|
2020-06-03 00:11:38 +00:00
|
|
|
}
|
|
|
|
else if (textureUrl == "Black") {
|
2020-06-03 03:36:45 +00:00
|
|
|
texture = Texture2D.blackTexture;
|
2020-06-03 00:11:38 +00:00
|
|
|
}
|
|
|
|
else {
|
|
|
|
var textureInfo = GameDatabase.Instance.GetTextureInfo(textureUrl);
|
2020-05-27 06:04:19 +00:00
|
|
|
|
2020-06-03 00:11:38 +00:00
|
|
|
if (textureInfo == null) throw new Exception($"Cannot find texture: '{textureUrl}'");
|
2020-05-27 06:04:19 +00:00
|
|
|
|
2020-06-04 07:12:09 +00:00
|
|
|
texture = isNormal ? textureInfo.normalMap : textureInfo.texture;
|
2020-06-03 00:11:38 +00:00
|
|
|
}
|
2020-05-27 06:04:19 +00:00
|
|
|
|
2020-06-04 07:12:09 +00:00
|
|
|
if (texture == null) throw new Exception($"Cannot get texture from texture info '{textureUrl}', isNormalMap = {isNormal}");
|
|
|
|
UpdateTiling();
|
2020-06-03 00:11:38 +00:00
|
|
|
}
|
|
|
|
|
2020-05-27 06:04:19 +00:00
|
|
|
public override void Modify(Material material) {
|
2020-06-04 07:12:09 +00:00
|
|
|
if (material == null) throw new ArgumentNullException(nameof(material));
|
|
|
|
if (texture == null) {
|
|
|
|
texture = Texture2D.whiteTexture;
|
|
|
|
throw new NullReferenceException("texture is null, but should not be");
|
|
|
|
}
|
|
|
|
|
2020-06-03 03:36:45 +00:00
|
|
|
material.SetTexture(_propertyID, texture);
|
2020-05-27 06:04:19 +00:00
|
|
|
material.SetTextureOffset(_propertyID, _textureOffset);
|
|
|
|
material.SetTextureScale(_propertyID, _textureScale);
|
|
|
|
}
|
|
|
|
|
2020-06-06 20:20:50 +00:00
|
|
|
public void UpdateScale(Vector2 scale) {
|
2020-06-04 07:12:09 +00:00
|
|
|
if (autoScale) {
|
2020-06-06 20:20:50 +00:00
|
|
|
_textureScale = _baseTextureScale * scale;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public void UpdateTiling(Vector2 textureScale, Vector2 textureOffset) {
|
|
|
|
if (autoTile) {
|
|
|
|
_textureScale = textureScale;
|
|
|
|
_textureOffset = textureOffset;
|
2020-05-27 06:04:19 +00:00
|
|
|
}
|
|
|
|
}
|
2020-06-04 07:12:09 +00:00
|
|
|
|
|
|
|
private void UpdateTiling() {
|
|
|
|
if (_hasTile) {
|
2020-06-06 20:20:50 +00:00
|
|
|
_baseTextureScale.x = Mathf.Approximately(0, _tileRect.width) ? 1 : _tileRect.width / texture.width;
|
|
|
|
_baseTextureScale.y = Mathf.Approximately(0, _tileRect.height) ? 1 : _tileRect.height / texture.height;
|
2020-06-04 07:12:09 +00:00
|
|
|
}
|
|
|
|
else {
|
2020-06-06 20:20:50 +00:00
|
|
|
_baseTextureScale = Vector2.one;
|
2020-06-04 07:12:09 +00:00
|
|
|
}
|
|
|
|
}
|
2020-05-27 06:04:19 +00:00
|
|
|
}
|
|
|
|
}
|