SO MUCH SCUFFEDNESS
This commit is contained in:
@ -0,0 +1,66 @@
|
||||
using Adobe.Substance;
|
||||
using System.IO;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Adobe.SubstanceEditor
|
||||
{
|
||||
/// <summary>
|
||||
/// General utilites for material creating and output texture assignment.
|
||||
/// </summary>
|
||||
internal static class AssetCreationUtils
|
||||
{
|
||||
/// <summary>
|
||||
/// Creates a Unity material and set its textures according to the currently in use Unity render pipeline.//
|
||||
/// </summary>
|
||||
/// <param name="graph"></param>
|
||||
/// <returns></returns>
|
||||
public static void CreateMaterialOrUpdateMaterial(SubstanceGraphSO graph, string instanceName)
|
||||
{
|
||||
var materialOutput = graph.GetAssociatedAssetPath($"{instanceName}_material", "mat");
|
||||
var oldMaterial = AssetDatabase.LoadAssetAtPath<Material>(materialOutput);
|
||||
|
||||
if (oldMaterial != null)
|
||||
{
|
||||
graph.OutputMaterial = oldMaterial;
|
||||
}
|
||||
|
||||
bool createMaterial = graph.OutputMaterial == null;
|
||||
|
||||
if (createMaterial)
|
||||
{
|
||||
graph.OutputMaterial = new Material(MaterialUtils.GetStandardShader())
|
||||
{
|
||||
name = Path.GetFileNameWithoutExtension(materialOutput)
|
||||
};
|
||||
}
|
||||
|
||||
MaterialUtils.AssignOutputTexturesToMaterial(graph);
|
||||
|
||||
if (createMaterial)
|
||||
AssetDatabase.CreateAsset(graph.OutputMaterial, materialOutput);
|
||||
else
|
||||
EditorUtility.SetDirty(graph.OutputMaterial);
|
||||
|
||||
graph.MaterialShader = graph.OutputMaterial.shader.name;
|
||||
}
|
||||
|
||||
public static void UpdateMeterialAssignment(SubstanceGraphSO graph)
|
||||
{
|
||||
graph.MaterialShader = graph.OutputMaterial.shader.name;
|
||||
|
||||
foreach (var output in graph.Output)
|
||||
{
|
||||
if (!output.IsStandardOutput(graph.OutputMaterial) && (!graph.GenerateAllOutputs))
|
||||
{
|
||||
var texturePath = AssetDatabase.GetAssetPath(output.OutputTexture);
|
||||
|
||||
if (File.Exists(texturePath))
|
||||
AssetDatabase.DeleteAsset(texturePath);
|
||||
|
||||
output.OutputTexture = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: dc9df0d9c52231245aa194e418a9c115
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,67 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Adobe.SubstanceEditor
|
||||
{
|
||||
/// <summary>
|
||||
/// Static class with utility methods commonly used to draw substance properties and UI.
|
||||
/// </summary>
|
||||
internal static class EditorDrawUtilities
|
||||
{
|
||||
private static readonly string[] _resolutions = { "256", "512", "1024", "2048", "4096" };
|
||||
|
||||
public static void DrawResolutionSelection(SerializedProperty property, GUIContent content, params GUILayoutOption[] options)
|
||||
{
|
||||
Vector2Int oldValue = property.vector2IntValue;
|
||||
var currentIndex = GetEnumIndex(oldValue);
|
||||
int newIndex = EditorGUILayout.Popup(content, currentIndex, _resolutions, options);
|
||||
|
||||
if (currentIndex != newIndex)
|
||||
{
|
||||
Vector2Int newValue = GetValueFromIndex(newIndex);
|
||||
property.vector2IntValue = newValue;
|
||||
}
|
||||
}
|
||||
|
||||
private static int GetEnumIndex(Vector2Int data)
|
||||
{
|
||||
switch (data.x)
|
||||
{
|
||||
case 8:
|
||||
return 0;
|
||||
|
||||
case 9:
|
||||
return 1;
|
||||
|
||||
case 10:
|
||||
return 2;
|
||||
|
||||
case 11:
|
||||
return 3;
|
||||
|
||||
case 12:
|
||||
return 4;
|
||||
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
private static Vector2Int GetValueFromIndex(int index)
|
||||
{
|
||||
switch (index)
|
||||
{
|
||||
case 0: return new Vector2Int(8, 8);
|
||||
case 1: return new Vector2Int(9, 9);
|
||||
case 2: return new Vector2Int(10, 10);
|
||||
case 3: return new Vector2Int(11, 11);
|
||||
case 4: return new Vector2Int(12, 12);
|
||||
|
||||
default:
|
||||
return new Vector2Int(8, 8);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7fb287e26604e6d4493b8ad922d4b790
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,353 @@
|
||||
using Adobe.Substance;
|
||||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Adobe.SubstanceEditor
|
||||
{
|
||||
internal static class EditorTools
|
||||
{
|
||||
/// <summary>
|
||||
/// Makes an object editable. (Usefull for object managed by Importers)
|
||||
/// </summary>
|
||||
/// <param name="pObject"></param>
|
||||
public static void OverrideReadOnlyFlag(UnityEngine.Object unityObject)
|
||||
{
|
||||
unityObject.hideFlags &= ~HideFlags.NotEditable;
|
||||
}
|
||||
|
||||
public static SubstanceGraphSO CreateSubstanceInstance(string assetPath, SubstanceFileRawData fileData, string name, int index, string guid, bool isRoot = false, SubstanceGraphSO copy = null)
|
||||
{
|
||||
var instanceAsset = ScriptableObject.CreateInstance<SubstanceGraphSO>();
|
||||
instanceAsset.AssetPath = assetPath;
|
||||
instanceAsset.RawData = fileData;
|
||||
instanceAsset.Name = name;
|
||||
instanceAsset.IsRoot = isRoot;
|
||||
instanceAsset.GUID = guid;
|
||||
instanceAsset.OutputPath = CreateGraphFolder(assetPath, name);
|
||||
instanceAsset.SetNativeID(index);
|
||||
instanceAsset.GenerateAllMipmaps = true;
|
||||
var instancePath = MakeRootGraphAssetPath(instanceAsset);
|
||||
SubstanceEditorEngine.instance.InitializeInstance(instanceAsset, instancePath, out SubstanceGraphSO _);
|
||||
SubstanceEditorEngine.instance.CreateGraphObject(instanceAsset, copy);
|
||||
AssetDatabase.CreateAsset(instanceAsset, instancePath);
|
||||
return instanceAsset;
|
||||
}
|
||||
|
||||
public static void UpdateSubstanceInstance(SubstanceGraphSO instanceAsset, SubstanceFileRawData newFileData)
|
||||
{
|
||||
instanceAsset.RawData = newFileData;
|
||||
var inputState = SubstanceEditorEngine.instance.SerializeCurrentState(instanceAsset);
|
||||
SubstanceEditorEngine.instance.ReleaseInstance(instanceAsset);
|
||||
SubstanceEditorEngine.instance.InitializeInstance(instanceAsset, null, out SubstanceGraphSO _);
|
||||
SubstanceEditorEngine.instance.SetStateFromSerializedData(instanceAsset, inputState);
|
||||
SubstanceEditorEngine.instance.CreateGraphObject(instanceAsset, null);
|
||||
}
|
||||
|
||||
public class SubstanceInstanceInfo
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public int Index { get; set; }
|
||||
public string GUID { get; set; }
|
||||
public bool IsRoot { get; set; }
|
||||
|
||||
public SubstanceInstanceInfo()
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public static void CreateSubstanceInstanceAsync(string assetPath, SubstanceFileRawData fileData, IEnumerable<SubstanceInstanceInfo> infos)
|
||||
{
|
||||
var instances = new List<Tuple<SubstanceGraphSO, string>>();
|
||||
|
||||
foreach (var item in infos)
|
||||
{
|
||||
var instanceAsset = ScriptableObject.CreateInstance<SubstanceGraphSO>();
|
||||
instanceAsset.AssetPath = assetPath;
|
||||
instanceAsset.RawData = fileData;
|
||||
instanceAsset.Name = item.Name;
|
||||
instanceAsset.IsRoot = item.IsRoot;
|
||||
instanceAsset.GUID = item.GUID;
|
||||
instanceAsset.OutputPath = CreateGraphFolder(assetPath, item.Name);
|
||||
instanceAsset.SetNativeID(item.Index);
|
||||
instanceAsset.GenerateAllMipmaps = true;
|
||||
var instancePath = MakeRootGraphAssetPath(instanceAsset);
|
||||
SubstanceEditorEngine.instance.InitializeInstance(instanceAsset, instancePath, out SubstanceGraphSO matchingInstance);
|
||||
|
||||
SubstanceEditorEngine.instance.CreateGraphObject(instanceAsset, matchingInstance);
|
||||
instances.Add(new Tuple<SubstanceGraphSO, string>(instanceAsset, instancePath));
|
||||
}
|
||||
|
||||
foreach (var instance in instances)
|
||||
{
|
||||
SubstanceEditorEngine.instance.DelayAssetCreation(instance.Item1, instance.Item2);
|
||||
}
|
||||
}
|
||||
|
||||
public static void Rename(this SubstanceGraphSO substanceMaterial, string name)
|
||||
{
|
||||
var oldFolder = substanceMaterial.OutputPath;
|
||||
|
||||
if (substanceMaterial.Name == name)
|
||||
return;
|
||||
|
||||
substanceMaterial.Name = name;
|
||||
|
||||
var dir = Path.GetDirectoryName(substanceMaterial.AssetPath);
|
||||
var assetName = Path.GetFileNameWithoutExtension(substanceMaterial.AssetPath);
|
||||
var newFolder = Path.Combine(dir, $"{assetName}_{name}");
|
||||
substanceMaterial.OutputPath = newFolder;
|
||||
|
||||
FileUtil.MoveFileOrDirectory(oldFolder, substanceMaterial.OutputPath);
|
||||
File.Delete($"{oldFolder}.meta");
|
||||
|
||||
EditorUtility.SetDirty(substanceMaterial);
|
||||
AssetDatabase.Refresh();
|
||||
|
||||
var oldPath = AssetDatabase.GetAssetPath(substanceMaterial);
|
||||
var error = AssetDatabase.RenameAsset(oldPath, $"{name}.asset");
|
||||
|
||||
if (!string.IsNullOrEmpty(error))
|
||||
Debug.LogError(error);
|
||||
|
||||
var materialOldName = AssetDatabase.GetAssetPath(substanceMaterial.OutputMaterial);
|
||||
var materialNewName = Path.GetFileName(substanceMaterial.GetAssociatedAssetPath($"{name}_material", "mat"));
|
||||
error = AssetDatabase.RenameAsset(materialOldName, materialNewName);
|
||||
EditorUtility.SetDirty(substanceMaterial.OutputMaterial);
|
||||
|
||||
if (!string.IsNullOrEmpty(error))
|
||||
Debug.LogError(error);
|
||||
|
||||
AssetDatabase.Refresh();
|
||||
}
|
||||
|
||||
public static void Move(this SubstanceGraphSO substanceMaterial, string to)
|
||||
{
|
||||
substanceMaterial.OutputPath = Path.GetDirectoryName(to);
|
||||
|
||||
var oldMaterialPath = AssetDatabase.GetAssetPath(substanceMaterial.OutputMaterial);
|
||||
AssetDatabase.MoveAsset(oldMaterialPath, Path.Combine(substanceMaterial.OutputPath, Path.GetFileName(oldMaterialPath)));
|
||||
|
||||
foreach (var output in substanceMaterial.Output)
|
||||
{
|
||||
var textureAssetPath = AssetDatabase.GetAssetPath(output.OutputTexture);
|
||||
var textureFileName = Path.GetFileName(textureAssetPath);
|
||||
var newTexturePath = Path.Combine(substanceMaterial.OutputPath, textureFileName);
|
||||
AssetDatabase.MoveAsset(textureAssetPath, newTexturePath);
|
||||
}
|
||||
|
||||
EditorUtility.SetDirty(substanceMaterial);
|
||||
AssetDatabase.Refresh();
|
||||
}
|
||||
|
||||
private static string CreateGraphFolder(string assetPath, string graphName)
|
||||
{
|
||||
var dir = Path.GetDirectoryName(assetPath);
|
||||
var assetName = Path.GetFileNameWithoutExtension(assetPath);
|
||||
|
||||
var newFolder = Path.Combine(dir, $"{assetName}_{graphName}");
|
||||
|
||||
if (Directory.Exists(newFolder))
|
||||
return newFolder;
|
||||
|
||||
string guid = AssetDatabase.CreateFolder(dir, $"{assetName}_{graphName}");
|
||||
return AssetDatabase.GUIDToAssetPath(guid);
|
||||
}
|
||||
|
||||
private static string MakeRootGraphAssetPath(SubstanceGraphSO substanceMaterial)
|
||||
{
|
||||
return Path.Combine(substanceMaterial.OutputPath, $"{substanceMaterial.Name}.asset");
|
||||
}
|
||||
}
|
||||
|
||||
public static class SubstanceEditorTools
|
||||
{
|
||||
public static void SetGraphFloatInput(SubstanceGraphSO graph, int inputId, float value)
|
||||
{
|
||||
var so = new SerializedObject(graph);
|
||||
var graphInputs = so.FindProperty("Input");
|
||||
var graphInput = graphInputs.GetArrayElementAtIndex(inputId);
|
||||
var dataProp = graphInput.FindPropertyRelative("Data");
|
||||
dataProp.floatValue = value;
|
||||
|
||||
so.ApplyModifiedProperties();
|
||||
|
||||
UpdateNativeInput(graph, inputId);
|
||||
}
|
||||
|
||||
public static void SetGraphFloat2Input(SubstanceGraphSO graph, int inputId, Vector2 value)
|
||||
{
|
||||
var so = new SerializedObject(graph);
|
||||
|
||||
var graphInputs = so.FindProperty("Input");
|
||||
var graphInput = graphInputs.GetArrayElementAtIndex(inputId);
|
||||
var dataProp = graphInput.FindPropertyRelative("Data");
|
||||
dataProp.vector2Value = value;
|
||||
|
||||
so.ApplyModifiedProperties();
|
||||
|
||||
UpdateNativeInput(graph, inputId);
|
||||
}
|
||||
|
||||
public static void SetGraphFloat3Input(SubstanceGraphSO graph, int inputId, Vector3 value)
|
||||
{
|
||||
var so = new SerializedObject(graph);
|
||||
var graphInputs = so.FindProperty("Input");
|
||||
var graphInput = graphInputs.GetArrayElementAtIndex(inputId);
|
||||
var dataProp = graphInput.FindPropertyRelative("Data");
|
||||
dataProp.vector3Value = value;
|
||||
|
||||
so.ApplyModifiedProperties();
|
||||
|
||||
UpdateNativeInput(graph, inputId);
|
||||
}
|
||||
|
||||
public static void SetGraphFloat4Input(SubstanceGraphSO graph, int inputId, Vector3 value)
|
||||
{
|
||||
var so = new SerializedObject(graph);
|
||||
var graphInputs = so.FindProperty("Input");
|
||||
var graphInput = graphInputs.GetArrayElementAtIndex(inputId);
|
||||
var dataProp = graphInput.FindPropertyRelative("Data");
|
||||
dataProp.vector4Value = value;
|
||||
|
||||
so.ApplyModifiedProperties();
|
||||
|
||||
UpdateNativeInput(graph, inputId);
|
||||
}
|
||||
|
||||
public static void SetGraphIntInput(SubstanceGraphSO graph, int inputId, int value)
|
||||
{
|
||||
var so = new SerializedObject(graph);
|
||||
var graphInputs = so.FindProperty("Input");
|
||||
var graphInput = graphInputs.GetArrayElementAtIndex(inputId);
|
||||
var dataProp = graphInput.FindPropertyRelative("Data");
|
||||
dataProp.intValue = value;
|
||||
|
||||
so.ApplyModifiedProperties();
|
||||
|
||||
UpdateNativeInput(graph, inputId);
|
||||
}
|
||||
|
||||
public static void SetGraphInt2Input(SubstanceGraphSO graph, int inputId, Vector2Int value)
|
||||
{
|
||||
var so = new SerializedObject(graph);
|
||||
var graphInputs = so.FindProperty("Input");
|
||||
var graphInput = graphInputs.GetArrayElementAtIndex(inputId);
|
||||
var dataProp = graphInput.FindPropertyRelative("Data");
|
||||
dataProp.vector2IntValue = value;
|
||||
|
||||
so.ApplyModifiedProperties();
|
||||
|
||||
UpdateNativeInput(graph, inputId);
|
||||
}
|
||||
|
||||
public static void SetGraphInt3Input(SubstanceGraphSO graph, int inputId, Vector3Int value)
|
||||
{
|
||||
var so = new SerializedObject(graph);
|
||||
var graphInputs = so.FindProperty("Input");
|
||||
var graphInput = graphInputs.GetArrayElementAtIndex(inputId);
|
||||
var dataProp = graphInput.FindPropertyRelative("Data");
|
||||
dataProp.vector3IntValue = value;
|
||||
|
||||
so.ApplyModifiedProperties();
|
||||
|
||||
UpdateNativeInput(graph, inputId);
|
||||
}
|
||||
|
||||
public static void SetGraphInt4Input(SubstanceGraphSO graph, int inputId, int value0, int value1, int value2, int value3)
|
||||
{
|
||||
var so = new SerializedObject(graph);
|
||||
var graphInputs = so.FindProperty("Input");
|
||||
var graphInput = graphInputs.GetArrayElementAtIndex(inputId);
|
||||
var dataProp0 = graphInput.FindPropertyRelative("Data0");
|
||||
var dataProp1 = graphInput.FindPropertyRelative("Data1");
|
||||
var dataProp2 = graphInput.FindPropertyRelative("Data2");
|
||||
var dataProp3 = graphInput.FindPropertyRelative("Data3");
|
||||
dataProp0.intValue = value0;
|
||||
dataProp1.intValue = value1;
|
||||
dataProp2.intValue = value2;
|
||||
dataProp3.intValue = value3;
|
||||
|
||||
so.ApplyModifiedProperties();
|
||||
|
||||
UpdateNativeInput(graph, inputId);
|
||||
}
|
||||
|
||||
public static void SetGraphInputString(SubstanceGraphSO graph, int inputId, string value)
|
||||
{
|
||||
var so = new SerializedObject(graph);
|
||||
var graphInputs = so.FindProperty("Input");
|
||||
var graphInput = graphInputs.GetArrayElementAtIndex(inputId);
|
||||
var dataProp = graphInput.FindPropertyRelative("Data");
|
||||
dataProp.stringValue = value;
|
||||
|
||||
so.ApplyModifiedProperties();
|
||||
|
||||
UpdateNativeInput(graph, inputId);
|
||||
}
|
||||
|
||||
public static void SetGraphInputTexture(SubstanceGraphSO graph, int inputId, Texture2D value)
|
||||
{
|
||||
var so = new SerializedObject(graph);
|
||||
var graphInputs = so.FindProperty("Input");
|
||||
var graphInput = graphInputs.GetArrayElementAtIndex(inputId);
|
||||
var dataProp = graphInput.FindPropertyRelative("Data");
|
||||
dataProp.objectReferenceValue = value;
|
||||
|
||||
so.ApplyModifiedProperties();
|
||||
|
||||
UpdateNativeInput(graph, inputId);
|
||||
}
|
||||
|
||||
private static void UpdateNativeInput(SubstanceGraphSO graph, int inputId)
|
||||
{
|
||||
if (!SubstanceEditorEngine.instance.TryGetHandlerFromInstance(graph, out SubstanceNativeGraph _nativeGraph))
|
||||
{
|
||||
if (!SubstanceEditorEngine.instance.IsInitialized)
|
||||
return;
|
||||
|
||||
SubstanceEditorEngine.instance.InitializeInstance(graph, null, out SubstanceGraphSO _);
|
||||
}
|
||||
|
||||
if (SubstanceEditorEngine.instance.TryGetHandlerFromInstance(graph, out _nativeGraph))
|
||||
graph.RuntimeInitialize(_nativeGraph, graph.IsRuntimeOnly);
|
||||
|
||||
graph.Input[inputId].UpdateNativeHandle(_nativeGraph);
|
||||
}
|
||||
|
||||
public static void RenderGraph(SubstanceGraphSO graph)
|
||||
{
|
||||
if (!SubstanceEditorEngine.instance.TryGetHandlerFromInstance(graph, out SubstanceNativeGraph _nativeGraph))
|
||||
{
|
||||
if (!SubstanceEditorEngine.instance.IsInitialized)
|
||||
return;
|
||||
|
||||
SubstanceEditorEngine.instance.InitializeInstance(graph, null, out SubstanceGraphSO _);
|
||||
}
|
||||
|
||||
if (SubstanceEditorEngine.instance.TryGetHandlerFromInstance(graph, out _nativeGraph))
|
||||
{
|
||||
SubstanceEditorEngine.instance.SubmitAsyncRenderWork(_nativeGraph, graph);
|
||||
}
|
||||
}
|
||||
|
||||
public static string CreatePresetFromCurrentState(SubstanceGraphSO graph)
|
||||
{
|
||||
if (!SubstanceEditorEngine.instance.TryGetHandlerFromInstance(graph, out SubstanceNativeGraph _nativeGraph))
|
||||
{
|
||||
if (!SubstanceEditorEngine.instance.IsInitialized)
|
||||
return string.Empty;
|
||||
|
||||
SubstanceEditorEngine.instance.InitializeInstance(graph, null, out SubstanceGraphSO _);
|
||||
}
|
||||
|
||||
if (SubstanceEditorEngine.instance.TryGetHandlerFromInstance(graph, out _nativeGraph))
|
||||
graph.RuntimeInitialize(_nativeGraph, graph.IsRuntimeOnly);
|
||||
|
||||
return _nativeGraph.CreatePresetFromCurrentState();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9501269c4defb994083f07343a9de616
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,165 @@
|
||||
using Adobe.Substance;
|
||||
using Adobe.Substance.Input.Description;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
|
||||
namespace Adobe.SubstanceEditor
|
||||
{
|
||||
/// <summary>
|
||||
/// Cached info for a substance input. Allow drawing UI without having to query description values from the SerializedProperty object.
|
||||
/// </summary>
|
||||
internal class SubstanceInputCachedInfo
|
||||
{
|
||||
/// <summary>
|
||||
/// Input serialized property.
|
||||
/// </summary>
|
||||
public SerializedProperty InputProperty { get; }
|
||||
|
||||
/// <summary>
|
||||
/// GUIContent for the drawing the input.
|
||||
/// </summary>
|
||||
public SubstanceInputGUIContent GUIContent { get; }
|
||||
|
||||
public int Index { get; }
|
||||
|
||||
public SubstanceInputCachedInfo(SerializedProperty inputProperty, SubstanceInputGUIContent GUIContent, int index)
|
||||
{
|
||||
this.InputProperty = inputProperty;
|
||||
this.GUIContent = GUIContent;
|
||||
Index = index;
|
||||
}
|
||||
}
|
||||
|
||||
internal class SubstanceInputGroupCachedInfo
|
||||
{
|
||||
public string Name { get; }
|
||||
|
||||
public List<SubstanceInputCachedInfo> Inputs { get; }
|
||||
|
||||
public bool ShowGroup { get; set; }
|
||||
|
||||
public SubstanceInputGroupCachedInfo(string groupName)
|
||||
{
|
||||
Name = groupName;
|
||||
Inputs = new List<SubstanceInputCachedInfo>();
|
||||
ShowGroup = false;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Helper class for caching grouping information for inputs so we don't have to query them every UI draw.
|
||||
/// </summary>
|
||||
internal class GraphInputsGroupingHelper
|
||||
{
|
||||
/// <summary>
|
||||
/// Readonly list with all input groups and their elements info.
|
||||
/// </summary>
|
||||
public IReadOnlyList<SubstanceInputGroupCachedInfo> InputGroups { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Groups with inputs that don't have grouping information.
|
||||
/// </summary>
|
||||
public SubstanceInputGroupCachedInfo GrouplessInputs { get; }
|
||||
|
||||
public GraphInputsGroupingHelper(SubstanceGraphSO graph, SerializedObject targetObject)
|
||||
{
|
||||
var GUIgroups = new List<SubstanceInputGroupCachedInfo>();
|
||||
var graphInputs = targetObject.FindProperty("Input");
|
||||
var groups = graph.Input.Select(a => a.Description.GuiGroup).Distinct();
|
||||
|
||||
foreach (var group in groups)
|
||||
{
|
||||
var groupInfo = new SubstanceInputGroupCachedInfo(group);
|
||||
|
||||
for (int i = 0; i < graph.Input.Count; i++)
|
||||
{
|
||||
var target = graph.Input[i];
|
||||
|
||||
if (target.Description.GuiGroup == group)
|
||||
{
|
||||
SubstanceInputGUIContent guiContent;
|
||||
|
||||
var graphInput = graphInputs.GetArrayElementAtIndex(i);
|
||||
var dataProp = graphInput.FindPropertyRelative("Data");
|
||||
|
||||
target.TryGetNumericalDescription(out ISubstanceInputDescNumerical descNumerical);
|
||||
|
||||
switch (target.Description.Type)
|
||||
{
|
||||
case SubstanceValueType.Float:
|
||||
guiContent = new SubstanceFloatGUIContent(target.Description, dataProp, descNumerical as SubstanceInputDescNumericalFloat);
|
||||
break;
|
||||
|
||||
case SubstanceValueType.Float2:
|
||||
guiContent = new SubstanceFloat2GUIContent(target.Description, dataProp, descNumerical as SubstanceInputDescNumericalFloat2);
|
||||
break;
|
||||
|
||||
case SubstanceValueType.Float3:
|
||||
guiContent = new SubstanceFloat3GUIContent(target.Description, dataProp, descNumerical as SubstanceInputDescNumericalFloat3);
|
||||
break;
|
||||
|
||||
case SubstanceValueType.Float4:
|
||||
guiContent = new SubstanceFloat4GUIContent(target.Description, dataProp, descNumerical as SubstanceInputDescNumericalFloat4);
|
||||
break;
|
||||
|
||||
case SubstanceValueType.Int:
|
||||
guiContent = (target.Description.WidgetType == SubstanceWidgetType.ComboBox) ? new SubstanceIntComboBoxGUIContent(target.Description, descNumerical as SubstanceInputDescNumericalInt, dataProp) : new SubstanceIntGUIContent(target.Description, dataProp, descNumerical as SubstanceInputDescNumericalInt);
|
||||
break;
|
||||
|
||||
case SubstanceValueType.Int2:
|
||||
guiContent = new SubstanceInt2GUIContent(target.Description, dataProp, descNumerical as SubstanceInputDescNumericalInt2);
|
||||
break;
|
||||
|
||||
case SubstanceValueType.Int3:
|
||||
guiContent = new SubstanceInt3GUIContent(target.Description, dataProp, descNumerical as SubstanceInputDescNumericalInt3);
|
||||
break;
|
||||
|
||||
case SubstanceValueType.Int4:
|
||||
guiContent = new SubstanceInt4GUIContent(target.Description, dataProp, descNumerical as SubstanceInputDescNumericalInt4);
|
||||
break;
|
||||
|
||||
default:
|
||||
guiContent = new SubstanceInputGUIContent(target.Description, dataProp);
|
||||
break;
|
||||
}
|
||||
|
||||
groupInfo.Inputs.Add(new SubstanceInputCachedInfo(graphInput, guiContent, i));
|
||||
}
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(groupInfo.Name))
|
||||
{
|
||||
if (GrouplessInputs == null)
|
||||
GrouplessInputs = groupInfo;
|
||||
else
|
||||
GrouplessInputs.Inputs.AddRange(groupInfo.Inputs);
|
||||
}
|
||||
else
|
||||
{
|
||||
GUIgroups.Add(groupInfo);
|
||||
}
|
||||
}
|
||||
|
||||
InputGroups = GUIgroups;
|
||||
}
|
||||
}
|
||||
|
||||
internal class GraphOutputAlphaChannelsHelper
|
||||
{
|
||||
private readonly List<string> _channels;
|
||||
|
||||
public GraphOutputAlphaChannelsHelper(SubstanceGraphSO graph)
|
||||
{
|
||||
_channels = new List<string> { "source" };
|
||||
|
||||
foreach (var item in graph.Output.Where(a => a.IsAlphaAssignable).Select(b => b.Description.Label))
|
||||
_channels.Add(item);
|
||||
}
|
||||
|
||||
public string[] GetAlphaChannels(string label)
|
||||
{
|
||||
return _channels.Where(a => a != label).ToArray();
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 613ef46be9575f44fbcb243ab26b4db4
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,19 @@
|
||||
using Adobe.Substance;
|
||||
using System.IO;
|
||||
|
||||
namespace Adobe.SubstanceEditor
|
||||
{
|
||||
public static class NamingExtensions
|
||||
{
|
||||
public static string GetAssociatedAssetPath(this SubstanceGraphSO graph, string name, string extension)
|
||||
{
|
||||
var fileName = Path.GetFileNameWithoutExtension(graph.AssetPath);
|
||||
return Path.Combine(graph.OutputPath, $"{fileName}_{name}.{extension}");
|
||||
}
|
||||
|
||||
public static string GetAssetFileName(this SubstanceGraphSO graph)
|
||||
{
|
||||
return Path.GetFileNameWithoutExtension(graph.AssetPath);
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5bf22d7a02c9e744483e24b116112bb8
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,68 @@
|
||||
using UnityEditor;
|
||||
using UnityEditor.Callbacks;
|
||||
using System.IO;
|
||||
using Adobe.Substance;
|
||||
|
||||
namespace Adobe.SubstanceEditor
|
||||
{
|
||||
public class SubstanceBuildUtils
|
||||
{
|
||||
[PostProcessBuildAttribute(1)]
|
||||
public static void OnPostprocessBuild(BuildTarget target, string pathToBuiltProject)
|
||||
{
|
||||
if (target == BuildTarget.StandaloneLinux64)
|
||||
OnPostprocessBuildLinux(pathToBuiltProject);
|
||||
else if (target == BuildTarget.StandaloneOSX)
|
||||
OnPostprocessBuildMac(pathToBuiltProject);
|
||||
|
||||
SubstanceEditorEngine.instance.RefreshActiveInstances();
|
||||
}
|
||||
|
||||
private static void OnPostprocessBuildLinux(string pathToBuiltProject)
|
||||
{
|
||||
var dataPath = pathToBuiltProject.Replace(".x86_64", "_Data");
|
||||
var pluginsPath = Path.Combine(dataPath, "Plugins");
|
||||
|
||||
if (!Directory.Exists(pluginsPath))
|
||||
Directory.CreateDirectory(pluginsPath);
|
||||
|
||||
var enginePath = Path.GetDirectoryName(PlatformUtils.GetEnginePath());
|
||||
string[] files = Directory.GetFiles(enginePath);
|
||||
|
||||
foreach (string s in files)
|
||||
{
|
||||
var extension = Path.GetExtension(s);
|
||||
|
||||
if (string.Equals(extension, ".so") || string.Equals(extension, ".1"))
|
||||
{
|
||||
var fileName = Path.GetFileName(s);
|
||||
var testination = Path.Combine(pluginsPath, fileName);
|
||||
File.Copy(s, testination, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void OnPostprocessBuildMac(string pathToBuiltProject)
|
||||
{
|
||||
var pluginsPath = Path.Combine(Path.Combine(pathToBuiltProject, "Contents"), "PlugIns");
|
||||
|
||||
if (!Directory.Exists(pluginsPath))
|
||||
Directory.CreateDirectory(pluginsPath);
|
||||
|
||||
var enginePath = Path.GetDirectoryName(PlatformUtils.GetEnginePath());
|
||||
string[] files = Directory.GetFiles(enginePath);
|
||||
|
||||
foreach (string s in files)
|
||||
{
|
||||
var extension = Path.GetExtension(s);
|
||||
|
||||
if (string.Equals(extension, ".dylib") || string.Equals(extension, ".1"))
|
||||
{
|
||||
var fileName = Path.GetFileName(s);
|
||||
var testination = Path.Combine(pluginsPath, fileName);
|
||||
File.Copy(s, testination, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 18d63636c53acdc4680dd008426e63f6
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,39 @@
|
||||
using Adobe.Substance;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Adobe.SubstanceEditor
|
||||
{
|
||||
internal static class SubstanceFileExtensions
|
||||
{
|
||||
internal static List<SubstanceGraphSO> GetGraphs(this SubstanceFileSO fileSO)
|
||||
{
|
||||
var result = new List<SubstanceGraphSO>();
|
||||
|
||||
var path = AssetDatabase.GetAssetPath(fileSO);
|
||||
|
||||
string[] guids = AssetDatabase.FindAssets(string.Format("t:{0}", typeof(SubstanceGraphSO)));
|
||||
|
||||
for (int i = 0; i < guids.Length; i++)
|
||||
{
|
||||
string assetPath = AssetDatabase.GUIDToAssetPath(guids[i]);
|
||||
SubstanceGraphSO graph = AssetDatabase.LoadAssetAtPath<SubstanceGraphSO>(assetPath);
|
||||
|
||||
if (graph != null)
|
||||
{
|
||||
var filePath = AssetDatabase.GetAssetPath(graph.RawData);
|
||||
|
||||
if (filePath.Equals(path, System.StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
result.Add(graph);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d88a151702771984bb824b8639661be1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
@ -0,0 +1,121 @@
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace Adobe.SubstanceEditor
|
||||
{
|
||||
internal static class TextureUtils
|
||||
{
|
||||
public static bool IsCompressed(this TextureFormat unityFormat)
|
||||
{
|
||||
switch (unityFormat)
|
||||
{
|
||||
case TextureFormat.RGBA32:
|
||||
case TextureFormat.RGBA64:
|
||||
case TextureFormat.RGB24:
|
||||
case TextureFormat.BGRA32:
|
||||
case TextureFormat.R8:
|
||||
case TextureFormat.R16:
|
||||
case TextureFormat.RFloat:
|
||||
return false;
|
||||
|
||||
default:
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
public static Texture2D SetReadableFlag(Texture2D pTexture, bool pReadable)
|
||||
{
|
||||
Texture2D texture = pTexture;
|
||||
|
||||
if (pTexture == null)
|
||||
return null;
|
||||
|
||||
string assetPath = AssetDatabase.GetAssetPath(pTexture);
|
||||
|
||||
var textureImporter = AssetImporter.GetAtPath(assetPath) as TextureImporter;
|
||||
if (textureImporter != null)
|
||||
{
|
||||
if (textureImporter.isReadable == pReadable)
|
||||
return pTexture;
|
||||
|
||||
textureImporter.isReadable = pReadable;
|
||||
Debug.LogWarning(string.Format("Setting {0}'s 'Read/Write Enabled' flag to {1}",
|
||||
pTexture.name, (pReadable ? "true" : "false")));
|
||||
|
||||
EditorUtility.SetDirty(textureImporter);
|
||||
AssetDatabase.ImportAsset(assetPath);
|
||||
AssetDatabase.Refresh();
|
||||
|
||||
texture = AssetDatabase.LoadMainAssetAtPath(assetPath) as Texture2D;
|
||||
}
|
||||
|
||||
return texture;
|
||||
}
|
||||
|
||||
public static Texture2D EnsureTextureCorrectness(Texture2D pTexture, bool ensureRGBA, bool enableMipMaps)
|
||||
{
|
||||
Texture2D texture = pTexture;
|
||||
|
||||
if (pTexture == null)
|
||||
return null;
|
||||
|
||||
string assetPath = AssetDatabase.GetAssetPath(pTexture);
|
||||
|
||||
var textureImporter = AssetImporter.GetAtPath(assetPath) as TextureImporter;
|
||||
|
||||
if (textureImporter != null)
|
||||
{
|
||||
bool changed = false;
|
||||
|
||||
if (textureImporter.textureCompression != TextureImporterCompression.Uncompressed)
|
||||
{
|
||||
textureImporter.textureCompression = TextureImporterCompression.Uncompressed;
|
||||
Debug.LogWarning(string.Format("Setting {0}'s 'Compression' flag to Uncompressed", pTexture.name));
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (textureImporter.isReadable != true)
|
||||
{
|
||||
textureImporter.isReadable = true;
|
||||
Debug.LogWarning(string.Format("Setting {0}'s 'Read/Write Enabled' flag to {1}",
|
||||
pTexture.name, (true ? "true" : "false")));
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (textureImporter.maxTextureSize < 4096)
|
||||
{
|
||||
textureImporter.maxTextureSize = 4096;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (enableMipMaps != textureImporter.mipmapEnabled)
|
||||
{
|
||||
textureImporter.mipmapEnabled = enableMipMaps;
|
||||
changed = true;
|
||||
}
|
||||
|
||||
if (ensureRGBA)
|
||||
{
|
||||
var defaultSettings = textureImporter.GetDefaultPlatformTextureSettings();
|
||||
|
||||
if (defaultSettings.format != TextureImporterFormat.RGBA32)
|
||||
{
|
||||
defaultSettings.format = TextureImporterFormat.RGBA32;
|
||||
textureImporter.SetPlatformTextureSettings(defaultSettings);
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (changed)
|
||||
{
|
||||
AssetDatabase.ImportAsset(assetPath);
|
||||
texture = AssetDatabase.LoadMainAssetAtPath(assetPath) as Texture2D;
|
||||
}
|
||||
}
|
||||
|
||||
return texture;
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3f50142101ff97a409b03240bd12d0b6
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Reference in New Issue
Block a user