portals and dash. Also a bit of terrain building and level design
This commit is contained in:
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e2e79226797075a45be41f310764c3f8
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ee8095bc36ba5914f80cdd18953adb0c
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 99e39b12ec2e89a438a159023c314b4a
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,20 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
|
||||
namespace Pinwheel.TextureGraph
|
||||
{
|
||||
[AttributeUsage(AttributeTargets.Class)]
|
||||
public class TCustomParametersDrawerAttribute : Attribute
|
||||
{
|
||||
public Type type { get; set; }
|
||||
|
||||
public TCustomParametersDrawerAttribute(Type t)
|
||||
{
|
||||
if (t == null)
|
||||
throw new ArgumentException("Target type cannot be null.");
|
||||
type = t;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: be0ab16a15aa1c8489df34c16cf13d4b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d84c5022acef8624994a5e55656ce716
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b5c73cb30e9f76a46ba1248a813e39fa
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,14 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Pinwheel.TextureGraph
|
||||
{
|
||||
//[CreateAssetMenu(menuName = "Texture Graph/Editor Settings")]
|
||||
public class TEditorSettings : ScriptableObject
|
||||
{
|
||||
public void Reset()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 79c61fdffa109b548a3ce5572f76d90f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,22 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
|
||||
namespace Pinwheel.TextureGraph
|
||||
{
|
||||
public static class TGenericMenuExtensions
|
||||
{
|
||||
public static void AddMenuItem(this GenericMenu menu, bool enabled, string text, GenericMenu.MenuFunction callback)
|
||||
{
|
||||
if (!enabled)
|
||||
{
|
||||
menu.AddDisabledItem(new GUIContent(text));
|
||||
}
|
||||
else
|
||||
{
|
||||
menu.AddItem(new GUIContent(text), false, callback);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2c10945eca3178848b042664002e0322
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,19 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Pinwheel.TextureGraph
|
||||
{
|
||||
public static class TLink
|
||||
{
|
||||
public const string USER_GUIDE = "https://docs.google.com/document/d/1kDkFHAmuMNFTbfnBpYPkjw99CrVvUNr8_gFAJH2o-7s";
|
||||
public const string SCRIPTING_API = "https://docs.google.com/document/d/16yrSJV-TnQ1sK1S2767v426AsfzJxUi5ewvbHSneM9Q";
|
||||
public const string FACEBOOK = "https://www.facebook.com/gaming/polaris.terrain/";
|
||||
public const string DISCORD = "https://discord.gg/ZzVBWsm34W";
|
||||
public const string SUPPORT_EMAIL = "pinwheel.customer@gmail.com";
|
||||
public const string STORE_PAGE = "https://assetstore.unity.com/packages/slug/185542";
|
||||
public const string YOUTUBE = "https://www.youtube.com/channel/UCebwuk5CfIe5kolBI9nuBTg";
|
||||
public const string RELEASE_LOG = "https://docs.google.com/document/d/1kDkFHAmuMNFTbfnBpYPkjw99CrVvUNr8_gFAJH2o-7s/edit#heading=h.jtfc91orfmhs";
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e13752f1a0a1ad24b9e8071dd5ef42e9
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,97 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Pinwheel.TextureGraph
|
||||
{
|
||||
public class TMenuTree<T>
|
||||
{
|
||||
public TMenuEntryGroup<T> RootEntry { get; set; }
|
||||
|
||||
public TMenuTree(string rootIcon, string rootText, T rootData)
|
||||
{
|
||||
RootEntry = new TMenuEntryGroup<T>();
|
||||
RootEntry.Level = 0;
|
||||
RootEntry.Icon = rootIcon;
|
||||
RootEntry.Path = rootText;
|
||||
RootEntry.Text = rootText;
|
||||
RootEntry.Data = rootData;
|
||||
}
|
||||
|
||||
public void AddEntry(string icon, string menuPath, T data)
|
||||
{
|
||||
string[] paths = menuPath.Split(new string[] { "/" }, System.StringSplitOptions.RemoveEmptyEntries);
|
||||
TMenuEntryGroup<T> parentEntry = RootEntry;
|
||||
|
||||
for (int i = 0; i < paths.Length; ++i)
|
||||
{
|
||||
TMenuEntryGroup<T> currentEntry = parentEntry.SubEntries.Find(e => string.Compare(paths[i], e.Text) == 0);
|
||||
if (currentEntry != null)
|
||||
{
|
||||
parentEntry = currentEntry;
|
||||
}
|
||||
else
|
||||
{
|
||||
currentEntry = new TMenuEntryGroup<T>();
|
||||
currentEntry.Level = i + 1;
|
||||
currentEntry.Text = paths[i];
|
||||
|
||||
parentEntry.SubEntries.Add(currentEntry);
|
||||
|
||||
parentEntry = currentEntry;
|
||||
}
|
||||
|
||||
if (i == paths.Length - 1)
|
||||
{
|
||||
currentEntry.Icon = icon;
|
||||
currentEntry.Data = data;
|
||||
currentEntry.Path = menuPath;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public List<TMenuEntryGroup<T>> ToList()
|
||||
{
|
||||
List<TMenuEntryGroup<T>> list = new List<TMenuEntryGroup<T>>();
|
||||
Stack<TMenuEntryGroup<T>> entryStack = new Stack<TMenuEntryGroup<T>>();
|
||||
entryStack.Push(RootEntry);
|
||||
while (entryStack.Count > 0)
|
||||
{
|
||||
TMenuEntryGroup<T> entry = entryStack.Pop();
|
||||
List<TMenuEntryGroup<T>> subEntries = entry.SubEntries;
|
||||
for (int i = subEntries.Count - 1; i >= 0; --i)
|
||||
{
|
||||
entryStack.Push(subEntries[i]);
|
||||
}
|
||||
list.Add(entry);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
}
|
||||
|
||||
public class TMenuEntryGroup<T>
|
||||
{
|
||||
public int Level { get; internal set; }
|
||||
public string Icon { get; set; }
|
||||
public string Text { get; set; }
|
||||
public string Path { get; set; }
|
||||
public T Data { get; set; }
|
||||
|
||||
private List<TMenuEntryGroup<T>> subEntries;
|
||||
public List<TMenuEntryGroup<T>> SubEntries
|
||||
{
|
||||
get
|
||||
{
|
||||
if (subEntries == null)
|
||||
{
|
||||
subEntries = new List<TMenuEntryGroup<T>>();
|
||||
}
|
||||
return subEntries;
|
||||
}
|
||||
set
|
||||
{
|
||||
subEntries = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: a03e56db461b28449b615938d071296f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,154 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using UnityEditor.Callbacks;
|
||||
using System;
|
||||
using UnityEditor.PackageManager;
|
||||
using UnityEditor.PackageManager.Requests;
|
||||
|
||||
namespace Pinwheel.TextureGraph
|
||||
{
|
||||
public static class TPackageInitializer
|
||||
{
|
||||
public delegate void InitCompletedHandler();
|
||||
public static event InitCompletedHandler Completed;
|
||||
|
||||
public static string TEXTURE_GRAPH_KW = "TEXTURE_GRAPH";
|
||||
public static string TG_SEARCHER_KW = "TG_SEARCHER";
|
||||
|
||||
private static ListRequest listPackageRequest = null;
|
||||
private static AddRequest addPackageRequest = null;
|
||||
|
||||
#pragma warning disable 0414
|
||||
private static bool isSearcherInstalled = false;
|
||||
#pragma warning restore 0414
|
||||
|
||||
[DidReloadScripts]
|
||||
public static void Init()
|
||||
{
|
||||
isSearcherInstalled = false;
|
||||
CheckThirdPartyPackages();
|
||||
CheckUnityPackagesAndInit();
|
||||
}
|
||||
|
||||
private static void CheckThirdPartyPackages()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
private static void CheckUnityPackagesAndInit()
|
||||
{
|
||||
#if !TG_SEARCHER
|
||||
addPackageRequest = Client.Add("com.unity.searcher");
|
||||
EditorApplication.update += OnRequestingPackageAdd;
|
||||
#endif
|
||||
listPackageRequest = Client.List(true);
|
||||
EditorApplication.update += OnRequestingPackageList;
|
||||
}
|
||||
|
||||
private static void OnRequestingPackageList()
|
||||
{
|
||||
if (listPackageRequest == null)
|
||||
return;
|
||||
if (!listPackageRequest.IsCompleted)
|
||||
return;
|
||||
if (listPackageRequest.Error != null)
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (UnityEditor.PackageManager.PackageInfo p in listPackageRequest.Result)
|
||||
{
|
||||
if (p.name.Equals("com.unity.searcher"))
|
||||
{
|
||||
isSearcherInstalled = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
EditorApplication.update -= OnRequestingPackageList;
|
||||
InitPackage();
|
||||
}
|
||||
|
||||
private static void OnRequestingPackageAdd()
|
||||
{
|
||||
if (addPackageRequest == null)
|
||||
return;
|
||||
if (!addPackageRequest.IsCompleted)
|
||||
return;
|
||||
if (addPackageRequest.Error != null)
|
||||
{
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
Debug.Log("TEXTURE GRAPH: Dependency package installed [com.unity.searcher]");
|
||||
}
|
||||
listPackageRequest = Client.List(true);
|
||||
EditorApplication.update += OnRequestingPackageList;
|
||||
EditorApplication.update -= OnRequestingPackageAdd;
|
||||
}
|
||||
|
||||
private static void InitPackage()
|
||||
{
|
||||
BuildTarget buildTarget = EditorUserBuildSettings.activeBuildTarget;
|
||||
BuildTargetGroup buildGroup = BuildPipeline.GetBuildTargetGroup(buildTarget);
|
||||
|
||||
string symbols = PlayerSettings.GetScriptingDefineSymbolsForGroup(buildGroup);
|
||||
List<string> symbolList = new List<string>(symbols.Split(new string[] { ";" }, StringSplitOptions.RemoveEmptyEntries));
|
||||
|
||||
bool isDirty = false;
|
||||
if (!symbolList.Contains(TEXTURE_GRAPH_KW))
|
||||
{
|
||||
symbolList.Add(TEXTURE_GRAPH_KW);
|
||||
isDirty = true;
|
||||
}
|
||||
isDirty = isDirty || SetKeywordActive(symbolList, TG_SEARCHER_KW, isSearcherInstalled);
|
||||
|
||||
if (isDirty)
|
||||
{
|
||||
symbols = symbolList.ListElementsToString(";");
|
||||
PlayerSettings.SetScriptingDefineSymbolsForGroup(buildGroup, symbols);
|
||||
}
|
||||
|
||||
if (Completed != null)
|
||||
{
|
||||
Completed.Invoke();
|
||||
}
|
||||
}
|
||||
|
||||
private static bool SetKeywordActive(List<string> kwList, string keyword, bool active)
|
||||
{
|
||||
bool isDirty = false;
|
||||
if (active && !kwList.Contains(keyword))
|
||||
{
|
||||
kwList.Add(keyword);
|
||||
isDirty = true;
|
||||
}
|
||||
else if (!active && kwList.Contains(keyword))
|
||||
{
|
||||
kwList.RemoveAll(s => s.Equals(keyword));
|
||||
isDirty = true;
|
||||
}
|
||||
return isDirty;
|
||||
}
|
||||
|
||||
public static List<System.Type> GetAllLoadedTypes()
|
||||
{
|
||||
List<System.Type> loadedTypes = new List<System.Type>();
|
||||
List<string> typeName = new List<string>();
|
||||
foreach (var assembly in System.AppDomain.CurrentDomain.GetAssemblies())
|
||||
{
|
||||
foreach (var t in assembly.GetTypes())
|
||||
{
|
||||
if (t.IsVisible && !t.IsGenericType)
|
||||
{
|
||||
typeName.Add(t.Name);
|
||||
loadedTypes.Add(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
return loadedTypes;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b68af1a47852c14489baafd7f0385dcd
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,140 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using System;
|
||||
|
||||
namespace Pinwheel.TextureGraph
|
||||
{
|
||||
public class TPointsDragger
|
||||
{
|
||||
public struct TArguments
|
||||
{
|
||||
public Texture background;
|
||||
public Material backgroundMaterial;
|
||||
public Action<Vector2> pointGizmosFunction;
|
||||
public Action<Vector2[]> drawConnectorFunction;
|
||||
public Color gizmosColor;
|
||||
|
||||
public static TArguments Create()
|
||||
{
|
||||
TArguments args = new TArguments()
|
||||
{
|
||||
background = null,
|
||||
backgroundMaterial = null,
|
||||
pointGizmosFunction = null,
|
||||
drawConnectorFunction = null,
|
||||
gizmosColor = new Color(0f, 0.9f, 0f, 1f),
|
||||
};
|
||||
return args;
|
||||
}
|
||||
}
|
||||
|
||||
private static readonly float HANDLE_SIZE = 10;
|
||||
private static int draggedPointsIndex = -1;
|
||||
|
||||
/// <summary>
|
||||
///
|
||||
/// </summary>
|
||||
/// <param name="background"></param>
|
||||
/// <param name="points">In UV space</param>
|
||||
public static void DrawCanvas(TArguments args, params TVector2Parameter[] points)
|
||||
{
|
||||
Rect r = GUILayoutUtility.GetAspectRect(1);
|
||||
if (args.background != null)
|
||||
{
|
||||
EditorGUI.DrawPreviewTexture(r, args.background, args.backgroundMaterial);
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorGUI.DrawRect(r, Color.black);
|
||||
}
|
||||
GUI.BeginClip(r);
|
||||
Rect canvas = new Rect(0, 0, r.width, r.height);
|
||||
Handles.BeginGUI();
|
||||
Color color = Handles.color;
|
||||
Handles.color = args.gizmosColor;
|
||||
HandlePointDragging(canvas, args, points);
|
||||
Handles.color = color;
|
||||
Handles.EndGUI();
|
||||
GUI.EndClip();
|
||||
TEditorCommon.DrawOutlineBox(r, TEditorCommon.boxBorderColor);
|
||||
}
|
||||
|
||||
private static Vector2 FlipY(Vector2 v)
|
||||
{
|
||||
return new Vector2(v.x, 1 - v.y);
|
||||
}
|
||||
|
||||
private static void HandlePointDragging(Rect canvas, TArguments args, params TVector2Parameter[] points)
|
||||
{
|
||||
Vector2[] uvSpaceCorners = new Vector2[points.Length];
|
||||
for (int i = 0; i < uvSpaceCorners.Length; ++i)
|
||||
{
|
||||
uvSpaceCorners[i] = points[i].value;
|
||||
}
|
||||
|
||||
Matrix4x4 uvToCanvas = Matrix4x4.TRS(new Vector3(canvas.position.x, canvas.position.y, 0), Quaternion.identity, new Vector3(canvas.width, canvas.height, 1));
|
||||
Vector2[] canvasSpaceCorners = new Vector2[points.Length];
|
||||
Rect[] cornersHandleRect = new Rect[points.Length];
|
||||
for (int i = 0; i < uvSpaceCorners.Length; ++i)
|
||||
{
|
||||
canvasSpaceCorners[i] = uvToCanvas.MultiplyPoint(FlipY(uvSpaceCorners[i]));
|
||||
cornersHandleRect[i] = new Rect() { size = Vector2.one * HANDLE_SIZE, center = canvasSpaceCorners[i] };
|
||||
EditorGUIUtility.AddCursorRect(cornersHandleRect[i], MouseCursor.MoveArrow);
|
||||
}
|
||||
|
||||
for (int i = 0; i < canvasSpaceCorners.Length; ++i)
|
||||
{
|
||||
if (args.pointGizmosFunction != null)
|
||||
{
|
||||
args.pointGizmosFunction.Invoke(canvasSpaceCorners[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
Handles.DrawSolidDisc(canvasSpaceCorners[i], Vector3.forward, HANDLE_SIZE * 0.5f);
|
||||
}
|
||||
}
|
||||
|
||||
if (args.drawConnectorFunction != null)
|
||||
{
|
||||
args.drawConnectorFunction.Invoke(canvasSpaceCorners);
|
||||
}
|
||||
else
|
||||
{
|
||||
Vector3[] p = new Vector3[canvasSpaceCorners.Length + 1];
|
||||
for (int i = 0; i < p.Length-1; ++i)
|
||||
{
|
||||
p[i] = canvasSpaceCorners[i];
|
||||
}
|
||||
p[p.Length - 1] = canvasSpaceCorners[0];
|
||||
Handles.DrawPolyLine(p);
|
||||
}
|
||||
if (Event.current.type == EventType.MouseDown)
|
||||
{
|
||||
for (int i = 0; i < cornersHandleRect.Length; ++i)
|
||||
{
|
||||
if (cornersHandleRect[i].Contains(Event.current.mousePosition))
|
||||
{
|
||||
draggedPointsIndex = i;
|
||||
break;
|
||||
}
|
||||
draggedPointsIndex = -1;
|
||||
}
|
||||
}
|
||||
else if (Event.current.type == EventType.MouseDrag)
|
||||
{
|
||||
if (draggedPointsIndex == -1)
|
||||
return;
|
||||
int index = draggedPointsIndex;
|
||||
points[index].value = FlipY(uvToCanvas.inverse.MultiplyPoint(Event.current.mousePosition));
|
||||
|
||||
GUI.changed = true;
|
||||
}
|
||||
else if (Event.current.type == EventType.MouseUp)
|
||||
{
|
||||
draggedPointsIndex = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 69df05e43c224ac48ae60ab77bf7c36b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b3b92362aa7cbc24d9da2ffcf464a724
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,88 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using UnityEditor.UIElements;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace Pinwheel.TextureGraph
|
||||
{
|
||||
[CustomEditor(typeof(TGraph))]
|
||||
public class TGraphInspector : Editor
|
||||
{
|
||||
private TGraph instance;
|
||||
private void OnEnable()
|
||||
{
|
||||
instance = target as TGraph;
|
||||
}
|
||||
|
||||
public override VisualElement CreateInspectorGUI()
|
||||
{
|
||||
VisualElement ve = new VisualElement();
|
||||
Button openEditorButton = new Button()
|
||||
{
|
||||
text = "Open Editor"
|
||||
};
|
||||
openEditorButton.clicked += OpenEditorButton_clicked;
|
||||
ve.Add(openEditorButton);
|
||||
|
||||
IMGUIContainer imgui = new IMGUIContainer(() =>
|
||||
{
|
||||
List<TAbstractTextureNode> nodes = instance.GraphData.Nodes;
|
||||
EditorGUILayout.LabelField("NODES: " + nodes.Count);
|
||||
for (int i = 0; i < nodes.Count; ++i)
|
||||
{
|
||||
TAbstractTextureNode n = nodes[i];
|
||||
EditorGUILayout.LabelField(n.GetType().Name);
|
||||
List<TSlot> outputSlot = n.GetOutputSlots();
|
||||
foreach (TSlot s in outputSlot)
|
||||
{
|
||||
Texture t = instance.GetRT(TSlotReference.Create(n.GUID, s.Id));
|
||||
if (t != null)
|
||||
{
|
||||
EditorGUILayout.ObjectField(t.GetInstanceID().ToString(), t, typeof(Texture), false);
|
||||
}
|
||||
}
|
||||
EditorGUILayout.Space();
|
||||
}
|
||||
|
||||
EditorGUILayout.Space();
|
||||
List<ITEdge> edges = instance.GraphData.Edges;
|
||||
EditorGUILayout.LabelField("EDGES: " + edges.Count);
|
||||
float width = EditorGUIUtility.labelWidth;
|
||||
EditorGUIUtility.labelWidth = 500;
|
||||
for (int i = 0; i < edges.Count; ++i)
|
||||
{
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
EditorGUILayout.LabelField(edges[i].OutputSlot.ToString(), GUILayout.Height(EditorGUIUtility.singleLineHeight * 2));
|
||||
EditorGUILayout.LabelField(edges[i].InputSlot.ToString(), GUILayout.Height(EditorGUIUtility.singleLineHeight * 2));
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
EditorGUILayout.Space();
|
||||
EditorGUILayout.LabelField("RT POOL");
|
||||
foreach (var rt in instance.RtPool.Values)
|
||||
{
|
||||
if (rt == null)
|
||||
{
|
||||
EditorGUILayout.LabelField("Null");
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorGUILayout.LabelField(rt.name, TEditorCommon.WordWrapLeftLabel);
|
||||
}
|
||||
}
|
||||
|
||||
EditorGUIUtility.labelWidth = width;
|
||||
});
|
||||
ve.Add(imgui);
|
||||
|
||||
return ve;
|
||||
}
|
||||
|
||||
private void OpenEditorButton_clicked()
|
||||
{
|
||||
TGraphEditor.OpenGraph(instance);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f3033686cf2e97c42bc35f225b4f7fe3
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,27 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor.Callbacks;
|
||||
using UnityEditor;
|
||||
|
||||
namespace Pinwheel.TextureGraph
|
||||
{
|
||||
public class TGraphOpenHandler
|
||||
{
|
||||
[OnOpenAssetAttribute(0)]
|
||||
public static bool HandleOpenGraphAsset(int instanceID, int line)
|
||||
{
|
||||
Object asset = EditorUtility.InstanceIDToObject(instanceID);
|
||||
if (asset is TGraph)
|
||||
{
|
||||
TGraph graph = asset as TGraph;
|
||||
TGraphEditor.OpenGraph(graph);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c28da48bfa353704fb29c82ecb692501
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0705c78a27fa7d444855269c3db01f8f
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,16 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
|
||||
namespace Pinwheel.TextureGraph
|
||||
{
|
||||
public interface ITManagedView : IDisposable
|
||||
{
|
||||
void Show();
|
||||
void Hide();
|
||||
void OnEnable();
|
||||
void OnDisable();
|
||||
void OnDestroy();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b4a15d1e1d1fe9c4d804a8cc2e988dd9
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,82 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using TSerializedElement = Pinwheel.TextureGraph.TGraphSerializer.TSerializedElement;
|
||||
|
||||
namespace Pinwheel.TextureGraph
|
||||
{
|
||||
public static class TClipboard
|
||||
{
|
||||
private static List<TSerializedElement> nodeData;
|
||||
private static List<TSerializedElement> NodeData
|
||||
{
|
||||
get
|
||||
{
|
||||
if (nodeData == null)
|
||||
{
|
||||
nodeData = new List<TSerializedElement>();
|
||||
}
|
||||
return nodeData;
|
||||
}
|
||||
}
|
||||
|
||||
private static List<TSerializedElement> edgeData;
|
||||
private static List<TSerializedElement> EdgeData
|
||||
{
|
||||
get
|
||||
{
|
||||
if (edgeData == null)
|
||||
{
|
||||
edgeData = new List<TSerializedElement>();
|
||||
}
|
||||
return edgeData;
|
||||
}
|
||||
}
|
||||
|
||||
public static bool IsCut { get; private set; }
|
||||
|
||||
public static bool HasData()
|
||||
{
|
||||
return NodeData.Count > 0 || EdgeData.Count > 0;
|
||||
}
|
||||
|
||||
public static void SetData(IEnumerable<ITGraphSerializeCallbackReceiver> element, bool isCut = false)
|
||||
{
|
||||
Clear();
|
||||
foreach (ITGraphSerializeCallbackReceiver e in element)
|
||||
{
|
||||
e.OnBeforeSerialize();
|
||||
TSerializedElement serializedData = TGraphSerializer.Serialize(e);
|
||||
if (e is TAbstractTextureNode)
|
||||
{
|
||||
NodeData.Add(serializedData);
|
||||
}
|
||||
else if (e is ITEdge)
|
||||
{
|
||||
EdgeData.Add(serializedData);
|
||||
}
|
||||
}
|
||||
IsCut = isCut;
|
||||
}
|
||||
|
||||
public static void Clear()
|
||||
{
|
||||
NodeData.Clear();
|
||||
EdgeData.Clear();
|
||||
}
|
||||
|
||||
public static void GetData(List<TSerializedElement> nodes = null, List<TSerializedElement> edges = null)
|
||||
{
|
||||
if (nodes != null)
|
||||
{
|
||||
nodes.Clear();
|
||||
nodes.AddRange(NodeData);
|
||||
}
|
||||
if (edges != null)
|
||||
{
|
||||
edges.Clear();
|
||||
edges.AddRange(EdgeData);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f39a04c9cd9bb9143bc1b5399dbe46be
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,60 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor.Experimental.GraphView;
|
||||
using System;
|
||||
using UnityEditor;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Pinwheel.TextureGraph
|
||||
{
|
||||
public class TCreateNodeWindow : ScriptableObject, ISearchWindowProvider
|
||||
{
|
||||
public TGraphEditor GraphWindow { get; internal set; }
|
||||
|
||||
public List<SearchTreeEntry> CreateSearchTree(SearchWindowContext context)
|
||||
{
|
||||
List<SearchTreeEntry> searchEntries = new List<SearchTreeEntry>();
|
||||
List<TMenuEntryGroup<Type>> flattenedMenu = TNodeCreationMenu.GetFlattenMenu();
|
||||
for (int i = 0; i < flattenedMenu.Count; ++i)
|
||||
{
|
||||
TMenuEntryGroup<Type> entry = flattenedMenu[i];
|
||||
if (entry.Data == null)
|
||||
{
|
||||
searchEntries.Add(new SearchTreeGroupEntry(new GUIContent(entry.Text), entry.Level));
|
||||
}
|
||||
else
|
||||
{
|
||||
Texture icon = Texture2D.blackTexture;
|
||||
if (!string.IsNullOrEmpty(entry.Icon))
|
||||
{
|
||||
Texture t = Resources.Load<Texture>(entry.Icon);
|
||||
if (t != null)
|
||||
{
|
||||
icon = t;
|
||||
}
|
||||
}
|
||||
searchEntries.Add(new SearchTreeEntry(new GUIContent(entry.Text, icon))
|
||||
{
|
||||
userData = entry.Data,
|
||||
level = entry.Level
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
return searchEntries;
|
||||
}
|
||||
|
||||
public bool OnSelectEntry(SearchTreeEntry entry, SearchWindowContext context)
|
||||
{
|
||||
Type type = entry.userData as Type;
|
||||
if (GraphWindow != null)
|
||||
{
|
||||
GraphWindow.CreateNodeOfType(type, context.screenMousePosition);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3518102001f777643a193e4f0c2123b6
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,39 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using TSerializedElement = Pinwheel.TextureGraph.TGraphSerializer.TSerializedElement;
|
||||
|
||||
namespace Pinwheel.TextureGraph
|
||||
{
|
||||
public class TDebugWindow : EditorWindow
|
||||
{
|
||||
//[MenuItem("Window/Texture Graph/Internal/Debug")]
|
||||
public static void ShowWindow()
|
||||
{
|
||||
TDebugWindow window = GetWindow<TDebugWindow>();
|
||||
window.titleContent = new GUIContent("TDebug");
|
||||
window.Show();
|
||||
}
|
||||
|
||||
public void OnGUI()
|
||||
{
|
||||
List<TSerializedElement> nodes = new List<TSerializedElement>();
|
||||
List<TSerializedElement> edges = new List<TSerializedElement>();
|
||||
TClipboard.GetData(nodes, edges);
|
||||
|
||||
TEditorCommon.Header($"NODES: {nodes.Count}");
|
||||
foreach(var d in nodes)
|
||||
{
|
||||
EditorGUILayout.LabelField(d.ToString(), TEditorCommon.WordWrapLeftLabel);
|
||||
TEditorCommon.Separator();
|
||||
}
|
||||
TEditorCommon.Header($"EDGES: {edges.Count}");
|
||||
foreach (var d in edges)
|
||||
{
|
||||
EditorGUILayout.LabelField(d.ToString(), TEditorCommon.WordWrapLeftLabel);
|
||||
TEditorCommon.Separator();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 23e8d8586cf6bf941a439c777ee4f679
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,76 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine.UIElements;
|
||||
using System;
|
||||
|
||||
namespace Pinwheel.TextureGraph
|
||||
{
|
||||
public class TDraggable : MouseManipulator
|
||||
{
|
||||
public struct TDragInfo
|
||||
{
|
||||
public Vector2 delta;
|
||||
public bool isShift;
|
||||
public bool isCtrl;
|
||||
public bool isAlt;
|
||||
}
|
||||
|
||||
public Action<TDragInfo> OnDrag;
|
||||
public bool IsDragging;
|
||||
|
||||
public TDraggable(Action<TDragInfo> onDrag)
|
||||
{
|
||||
OnDrag = onDrag;
|
||||
}
|
||||
|
||||
protected override void RegisterCallbacksOnTarget()
|
||||
{
|
||||
target.RegisterCallback<MouseDownEvent>(OnMouseDown, TrickleDown.NoTrickleDown);
|
||||
target.RegisterCallback<MouseMoveEvent>(OnMouseMove, TrickleDown.NoTrickleDown);
|
||||
target.RegisterCallback<MouseUpEvent>(OnMouseUp, TrickleDown.NoTrickleDown);
|
||||
}
|
||||
|
||||
protected override void UnregisterCallbacksFromTarget()
|
||||
{
|
||||
target.UnregisterCallback<MouseDownEvent>(OnMouseDown, TrickleDown.NoTrickleDown);
|
||||
target.UnregisterCallback<MouseMoveEvent>(OnMouseMove, TrickleDown.NoTrickleDown);
|
||||
target.UnregisterCallback<MouseUpEvent>(OnMouseUp, TrickleDown.NoTrickleDown);
|
||||
}
|
||||
|
||||
private void OnMouseDown(MouseDownEvent e)
|
||||
{
|
||||
if (e.button == 0)
|
||||
{
|
||||
target.CaptureMouse();
|
||||
IsDragging = true;
|
||||
e.StopPropagation();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnMouseMove(MouseMoveEvent e)
|
||||
{
|
||||
if (!IsDragging)
|
||||
return;
|
||||
if (OnDrag != null)
|
||||
{
|
||||
TDragInfo d = new TDragInfo();
|
||||
d.delta = e.mouseDelta;
|
||||
d.isShift = e.shiftKey;
|
||||
d.isCtrl = e.ctrlKey;
|
||||
d.isAlt = e.altKey;
|
||||
OnDrag.Invoke(d);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnMouseUp(MouseUpEvent e)
|
||||
{
|
||||
if (target.HasMouseCapture())
|
||||
{
|
||||
target.ReleaseMouse();
|
||||
e.StopPropagation();
|
||||
}
|
||||
IsDragging = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 21fc4be247769d743af6be8b130783e1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,336 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using System;
|
||||
using System.IO;
|
||||
|
||||
namespace Pinwheel.TextureGraph
|
||||
{
|
||||
public class TExportWindow : EditorWindow
|
||||
{
|
||||
private TGraphEditor GraphEditor { get; set; }
|
||||
private string ExportDirectory { get; set; }
|
||||
private string NameTemplate { get; set; }
|
||||
|
||||
private const string DIRECTORY_KEY = "texture-graph-export-directory";
|
||||
private const string NAME_TEMPLATE_KEY = "texture-graph-export-name-template";
|
||||
private const string EXTENSION_KEY = "texture-graph-export-ext";
|
||||
private const string SELECTED_KEY = "texture-graph-export-selected";
|
||||
|
||||
public const string WC_ID = "<id>";
|
||||
public const string WC_GUID = "<guid>";
|
||||
public const string WC_WIDTH = "<width>";
|
||||
public const string WC_HEIGHT = "<height>";
|
||||
public const string WC_USAGE = "<usage>";
|
||||
public const string WC_TIME = "<time>";
|
||||
public const string WC_TICK = "<tick>";
|
||||
|
||||
private const int NO_ERROR = 0;
|
||||
private const int ERROR_DIRECTORY_NOT_EXIST = 1;
|
||||
private const int ERROR_NAME_EMPTY = 2;
|
||||
private const int ERROR_NAME_NO_START_WITH_LETTER = 3;
|
||||
private const int ERROR_NAME_NO_WILDCARD = 4;
|
||||
|
||||
private static readonly string[] ERROR_MESSAGES = new string[]
|
||||
{
|
||||
"No error",
|
||||
"The selected directory is not exist.",
|
||||
"Name Template cannot be empty.",
|
||||
"Name Template must begin with a letter.",
|
||||
"Name Template must has at least one valid wildcard."
|
||||
};
|
||||
|
||||
private const int SELECTION_TOGGLE_WIDTH = 30;
|
||||
|
||||
private static readonly GUIContent idGUI = new GUIContent("Id", "User define id for each output node. You can change this value by selecting the output node and use the Parameters panel. This value should not be duplicated.");
|
||||
private static readonly GUIContent extGUI = new GUIContent("Extension", "File extension for exported image.");
|
||||
|
||||
private Vector2 scrollPos;
|
||||
|
||||
public static TExportWindow ShowWindow(TGraphEditor graphEditor)
|
||||
{
|
||||
TExportWindow window = CreateInstance<TExportWindow>();
|
||||
window.titleContent = new GUIContent("Export");
|
||||
window.GraphEditor = graphEditor;
|
||||
window.ShowUtility();
|
||||
return window;
|
||||
}
|
||||
|
||||
public void OnEnable()
|
||||
{
|
||||
ExportDirectory = EditorPrefs.GetString(DIRECTORY_KEY, Application.dataPath);
|
||||
NameTemplate = EditorPrefs.GetString(NAME_TEMPLATE_KEY, "Output_<guid>");
|
||||
}
|
||||
|
||||
public void OnDisable()
|
||||
{
|
||||
EditorPrefs.SetString(DIRECTORY_KEY, ExportDirectory);
|
||||
EditorPrefs.SetString(NAME_TEMPLATE_KEY, NameTemplate);
|
||||
}
|
||||
|
||||
public void OnGUI()
|
||||
{
|
||||
EditorGUI.indentLevel += 1;
|
||||
|
||||
scrollPos = EditorGUILayout.BeginScrollView(scrollPos);
|
||||
DrawDirectoryAndNamingGUI();
|
||||
DrawOutputGUI();
|
||||
EditorGUILayout.EndScrollView();
|
||||
|
||||
TEditorCommon.Separator();
|
||||
EditorGUILayout.Space();
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
GUILayout.FlexibleSpace();
|
||||
if (GUILayout.Button("Export All", GUILayout.Width(100)))
|
||||
{
|
||||
DoExportAll();
|
||||
}
|
||||
if (GUILayout.Button("Export Selected", GUILayout.Width(100)))
|
||||
{
|
||||
DoExportSelected();
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
EditorGUILayout.Space();
|
||||
EditorGUI.indentLevel -= 1;
|
||||
}
|
||||
|
||||
private void DrawDirectoryAndNamingGUI()
|
||||
{
|
||||
TEditorCommon.Header("Directory & Naming");
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
ExportDirectory = EditorGUILayout.TextField("Directory", ExportDirectory);
|
||||
if (GUILayout.Button("Browse", GUILayout.Width(100)))
|
||||
{
|
||||
EditorGUI.FocusTextInControl("");
|
||||
ExportDirectory = EditorUtility.SaveFolderPanel("Export To...", ExportDirectory, "");
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
NameTemplate = EditorGUILayout.TextField("Name Template", NameTemplate);
|
||||
Rect r = EditorGUILayout.GetControlRect(GUILayout.Width(100));
|
||||
if (GUI.Button(r, "Wildcards"))
|
||||
{
|
||||
GenericMenu wildcardsMenu = new GenericMenu();
|
||||
wildcardsMenu.AddItem(new GUIContent("Id"), false, () => { AddWildcard(WC_ID); });
|
||||
wildcardsMenu.AddItem(new GUIContent("Guid"), false, () => { AddWildcard(WC_GUID); });
|
||||
wildcardsMenu.AddItem(new GUIContent("Width"), false, () => { AddWildcard(WC_WIDTH); });
|
||||
wildcardsMenu.AddItem(new GUIContent("Height"), false, () => { AddWildcard(WC_HEIGHT); });
|
||||
wildcardsMenu.AddItem(new GUIContent("Usage"), false, () => { AddWildcard(WC_USAGE); });
|
||||
wildcardsMenu.AddItem(new GUIContent("Time"), false, () => { AddWildcard(WC_TIME); });
|
||||
wildcardsMenu.AddItem(new GUIContent("Tick"), false, () => { AddWildcard(WC_TICK); });
|
||||
|
||||
EditorGUI.FocusTextInControl("");
|
||||
wildcardsMenu.DropDown(r);
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
private void AddWildcard(string t)
|
||||
{
|
||||
NameTemplate += t;
|
||||
}
|
||||
|
||||
private void DrawOutputGUI()
|
||||
{
|
||||
TEditorCommon.Header("Outputs");
|
||||
List<TOutputNode> outputNodes = new List<TOutputNode>();
|
||||
foreach (TAbstractTextureNode n in GraphEditor.ClonedGraph.GraphData.Nodes)
|
||||
{
|
||||
if (n is TOutputNode output)
|
||||
{
|
||||
outputNodes.Add(output);
|
||||
}
|
||||
}
|
||||
|
||||
if (outputNodes.Count == 0)
|
||||
{
|
||||
EditorGUILayout.LabelField("You must have at least one Output node in your graph.", TEditorCommon.WordWrapItalicLabel);
|
||||
}
|
||||
|
||||
foreach (TOutputNode n in outputNodes)
|
||||
{
|
||||
string id = n.OutputId.value;
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
bool selected = GetSelectedState(n.GUID);
|
||||
EditorGUI.BeginChangeCheck();
|
||||
selected = EditorGUILayout.Toggle(selected, GUILayout.Width(SELECTION_TOGGLE_WIDTH));
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
SetSelectedState(n.GUID, selected);
|
||||
}
|
||||
|
||||
EditorGUILayout.BeginVertical();
|
||||
float labelWidth = EditorGUIUtility.labelWidth;
|
||||
EditorGUIUtility.labelWidth = labelWidth - SELECTION_TOGGLE_WIDTH;
|
||||
n.OutputId.value = EditorGUILayout.TextField(idGUI, n.OutputId.value);
|
||||
TImageExtension ext = GetExtension(n.GUID);
|
||||
EditorGUI.BeginChangeCheck();
|
||||
ext = (TImageExtension)EditorGUILayout.EnumPopup(extGUI, ext);
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
SetExtension(n.GUID, ext);
|
||||
}
|
||||
EditorGUIUtility.labelWidth = labelWidth;
|
||||
EditorGUILayout.EndVertical();
|
||||
|
||||
Rect previewRect = (EditorGUILayout.GetControlRect(GUILayout.Width(100), GUILayout.Height(100)));
|
||||
Texture preview = null;
|
||||
TSlot previewSlot = n.GetMainOutputSlot();
|
||||
if (previewSlot != null)
|
||||
{
|
||||
preview = GraphEditor.ClonedGraph.GetRT(TSlotReference.Create(n.GUID, previewSlot.Id));
|
||||
}
|
||||
if (preview == null)
|
||||
{
|
||||
EditorGUI.DrawRect(previewRect, Color.black);
|
||||
EditorGUI.LabelField(previewRect, "No preview available.", TEditorCommon.CenteredWhiteLabel);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (TUtilities.IsGrayscaleFormat(preview.graphicsFormat))
|
||||
{
|
||||
Material mat = TEditorCommon.PreviewRedToGrayMaterial;
|
||||
EditorGUI.DrawPreviewTexture(previewRect, preview, mat, ScaleMode.ScaleToFit, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
EditorGUI.DrawTextureTransparent(previewRect, preview, ScaleMode.ScaleToFit);
|
||||
}
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
EditorGUILayout.Space();
|
||||
}
|
||||
}
|
||||
|
||||
private TImageExtension GetExtension(Guid nodeGuid)
|
||||
{
|
||||
string key = EXTENSION_KEY + nodeGuid.ToString();
|
||||
int value = EditorPrefs.GetInt(key, 0);
|
||||
return (TImageExtension)value;
|
||||
}
|
||||
|
||||
private void SetExtension(Guid nodeGuid, TImageExtension ext)
|
||||
{
|
||||
string key = EXTENSION_KEY + nodeGuid.ToString();
|
||||
EditorPrefs.SetInt(key, (int)ext);
|
||||
}
|
||||
|
||||
private bool GetSelectedState(Guid nodeGuid)
|
||||
{
|
||||
string key = SELECTED_KEY + nodeGuid.ToString();
|
||||
return EditorPrefs.GetBool(key, true);
|
||||
}
|
||||
|
||||
private void SetSelectedState(Guid nodeGuid, bool value)
|
||||
{
|
||||
string key = SELECTED_KEY + nodeGuid.ToString();
|
||||
EditorPrefs.SetBool(key, value);
|
||||
}
|
||||
|
||||
private int PreExportCheck()
|
||||
{
|
||||
if (!Directory.Exists(ExportDirectory))
|
||||
{
|
||||
return ERROR_DIRECTORY_NOT_EXIST;
|
||||
}
|
||||
if (string.IsNullOrEmpty(NameTemplate))
|
||||
{
|
||||
return ERROR_NAME_EMPTY;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!Char.IsLetter(NameTemplate[0]))
|
||||
{
|
||||
return ERROR_NAME_NO_START_WITH_LETTER;
|
||||
}
|
||||
}
|
||||
|
||||
if (!NameTemplate.Contains(WC_ID) &&
|
||||
!NameTemplate.Contains(WC_GUID) &&
|
||||
!NameTemplate.Contains(WC_WIDTH) &&
|
||||
!NameTemplate.Contains(WC_HEIGHT) &&
|
||||
!NameTemplate.Contains(WC_USAGE) &&
|
||||
!NameTemplate.Contains(WC_TIME) &&
|
||||
!NameTemplate.Contains(WC_TICK))
|
||||
{
|
||||
return ERROR_NAME_NO_WILDCARD;
|
||||
}
|
||||
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
private void DoExportAll()
|
||||
{
|
||||
int error = PreExportCheck();
|
||||
if (error != 0)
|
||||
{
|
||||
string msg = ERROR_MESSAGES[error];
|
||||
EditorUtility.DisplayDialog("Error", msg, "OK");
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
List<TOutputNode> outputNodes = new List<TOutputNode>();
|
||||
foreach (TAbstractTextureNode n in GraphEditor.ClonedGraph.GraphData.Nodes)
|
||||
{
|
||||
if (n is TOutputNode output)
|
||||
{
|
||||
outputNodes.Add(output);
|
||||
}
|
||||
}
|
||||
ExportNodes(outputNodes);
|
||||
}
|
||||
}
|
||||
|
||||
private void DoExportSelected()
|
||||
{
|
||||
int error = PreExportCheck();
|
||||
if (error != 0)
|
||||
{
|
||||
string msg = ERROR_MESSAGES[error];
|
||||
EditorUtility.DisplayDialog("Error", msg, "OK");
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
List<TOutputNode> outputNodes = new List<TOutputNode>();
|
||||
foreach (TAbstractTextureNode n in GraphEditor.ClonedGraph.GraphData.Nodes)
|
||||
{
|
||||
if (n is TOutputNode output)
|
||||
{
|
||||
if (GetSelectedState(n.GUID) == true)
|
||||
{
|
||||
outputNodes.Add(output);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ExportNodes(outputNodes);
|
||||
}
|
||||
}
|
||||
|
||||
private void ExportNodes(List<TOutputNode> outputNodes)
|
||||
{
|
||||
TGraphContext context = TGraphContext.Create(GraphEditor.ClonedGraph);
|
||||
foreach (TOutputNode n in outputNodes)
|
||||
{
|
||||
DateTime now = DateTime.Now;
|
||||
Vector2Int resolution = n.GetOutputResolution(context);
|
||||
string fileNameNoExt = NameTemplate
|
||||
.Replace(WC_GUID, n.GUID.ToString())
|
||||
.Replace(WC_ID, n.OutputId.value)
|
||||
.Replace(WC_WIDTH, resolution.x.ToString())
|
||||
.Replace(WC_HEIGHT, resolution.y.ToString())
|
||||
.Replace(WC_USAGE, n.Usage.value.ToString())
|
||||
.Replace(WC_TIME, $"{now.Hour}-{now.Minute}-{now.Second}")
|
||||
.Replace(WC_TICK, DateTime.Now.Ticks.ToString());
|
||||
string filePathNoExt = Path.Combine(ExportDirectory, fileNameNoExt);
|
||||
TImageExtension ext = GetExtension(n.GUID);
|
||||
n.SaveToImage(context, filePathNoExt, ext);
|
||||
}
|
||||
AssetDatabase.Refresh();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e37176902fd808d4abab60cc9241f49a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,14 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using System;
|
||||
|
||||
namespace Pinwheel.TextureGraph
|
||||
{
|
||||
public class TExporter
|
||||
{
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0887666ce7b884a43bde575a35f147aa
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,625 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using UnityEditor.Experimental.GraphView;
|
||||
using UnityEditor.UIElements;
|
||||
using UnityEngine.UIElements;
|
||||
using System;
|
||||
using Object = UnityEngine.Object;
|
||||
using Pinwheel.TextureGraph.UIElements;
|
||||
#if TG_SEARCHER
|
||||
using UnityEditor.Searcher;
|
||||
#endif
|
||||
|
||||
namespace Pinwheel.TextureGraph
|
||||
{
|
||||
public partial class TGraphEditor : EditorWindow
|
||||
{
|
||||
public static readonly string UNDO_NAME_GRAPH_EDITING = "Graph Editing";
|
||||
|
||||
private static List<TGraphEditor> openedEditors;
|
||||
public static List<TGraphEditor> OpenedEditors
|
||||
{
|
||||
get
|
||||
{
|
||||
if (openedEditors == null)
|
||||
{
|
||||
openedEditors = new List<TGraphEditor>();
|
||||
}
|
||||
return openedEditors;
|
||||
}
|
||||
}
|
||||
|
||||
private static List<TGraph> graphDirtyState;
|
||||
public static List<TGraph> GraphDirtyState
|
||||
{
|
||||
get
|
||||
{
|
||||
if (graphDirtyState == null)
|
||||
{
|
||||
graphDirtyState = new List<TGraph>();
|
||||
}
|
||||
return graphDirtyState;
|
||||
}
|
||||
set
|
||||
{
|
||||
graphDirtyState = value;
|
||||
}
|
||||
}
|
||||
|
||||
private static TGraph openingGraph;
|
||||
public TGraph SourceGraph { get; set; }
|
||||
public TGraph ClonedGraph { get; set; }
|
||||
|
||||
public VisualElement MainContainer;
|
||||
public TGraphEditorToolbar Toolbar;
|
||||
public TGraphView GraphView;
|
||||
public ScrollView ParameterScrollView;
|
||||
#if TG_SEARCHER
|
||||
private TNodeSearcherWindow nodeSearcherWindow;
|
||||
#endif
|
||||
|
||||
public TView2DWindow view2DWindow;
|
||||
public const string SUB_WINDOW_2D_VIEW_DATA_KEY = "view2D";
|
||||
|
||||
public TView3DWindow view3DWindow;
|
||||
public const string SUB_WINDOW_3D_VIEW_DATA_KEY = "view3D";
|
||||
|
||||
public TGraphSettingsWindow settingsWindow;
|
||||
public TExportWindow exportWindow;
|
||||
|
||||
public static void OpenGraph(TGraph graph)
|
||||
{
|
||||
TGraphEditor window = OpenedEditors.Find(e => e.SourceGraph == graph);
|
||||
if (window == null)
|
||||
{
|
||||
openingGraph = graph;
|
||||
window = ScriptableObject.CreateInstance<TGraphEditor>();
|
||||
window.titleContent = new GUIContent(graph.name);
|
||||
window.SourceGraph = graph;
|
||||
}
|
||||
window.Show();
|
||||
window.Focus();
|
||||
}
|
||||
|
||||
public void OnEnable()
|
||||
{
|
||||
OpenedEditors.Add(this);
|
||||
CreateGUI();
|
||||
RegisterCallbacks();
|
||||
}
|
||||
|
||||
public void OnDisable()
|
||||
{
|
||||
UnregisterCallbacks();
|
||||
RemoveGUI();
|
||||
OpenedEditors.Remove(this);
|
||||
}
|
||||
|
||||
private void OnDestroy()
|
||||
{
|
||||
if (view2DWindow != null)
|
||||
{
|
||||
view2DWindow.OnDestroy();
|
||||
}
|
||||
if (view3DWindow != null)
|
||||
{
|
||||
view3DWindow.OnDestroy();
|
||||
}
|
||||
|
||||
if (ClonedGraph != null && SourceGraph != null && IsGraphDirty(SourceGraph))
|
||||
{
|
||||
if (EditorUtility.DisplayDialog(
|
||||
"Texture Graph has been modified",
|
||||
$"Do you want to save change(s) made to your graph?\n{AssetDatabase.GetAssetPath(SourceGraph)}\n\nIf you don't save, all changes will be lost!",
|
||||
"Save", "Don't Save"))
|
||||
{
|
||||
TGraphSaver.Save(ClonedGraph, SourceGraph);
|
||||
}
|
||||
SetGraphDirty(SourceGraph, false);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnGUI()
|
||||
{
|
||||
if (IsGraphDirty(SourceGraph))
|
||||
{
|
||||
titleContent = new GUIContent(SourceGraph.name + "*");
|
||||
}
|
||||
else
|
||||
{
|
||||
titleContent = new GUIContent(SourceGraph.name);
|
||||
}
|
||||
|
||||
if (Event.current != null && Event.current.isKey)
|
||||
{
|
||||
HandleShortcutKeys(Event.current.keyCode, Event.current.control, Event.current.shift, Event.current.alt);
|
||||
}
|
||||
}
|
||||
|
||||
private void RegisterCallbacks()
|
||||
{
|
||||
TGraphView.NodeToInspectChanged += OnNodeToInspectChanged;
|
||||
TGraphView.NodeDoubleClicked += OnNodeDoubleClicked;
|
||||
TAbstractTextureNode.OnAfterExecuting += OnAfterExecutingNode;
|
||||
|
||||
if (GraphView != null)
|
||||
{
|
||||
//GraphView.graphViewChanged += OnGraphViewChanged;
|
||||
GraphView.RegisterCallback<KeyDownEvent>(HandleShortcutKeysOnGraphView);
|
||||
}
|
||||
|
||||
Undo.undoRedoPerformed += OnUndoRedo;
|
||||
}
|
||||
|
||||
private void UnregisterCallbacks()
|
||||
{
|
||||
TGraphView.NodeToInspectChanged -= OnNodeToInspectChanged;
|
||||
TGraphView.NodeDoubleClicked -= OnNodeDoubleClicked;
|
||||
TAbstractTextureNode.OnAfterExecuting -= OnAfterExecutingNode;
|
||||
|
||||
if (GraphView != null)
|
||||
{
|
||||
//GraphView.graphViewChanged -= OnGraphViewChanged;
|
||||
GraphView.UnregisterCallback<KeyDownEvent>(HandleShortcutKeysOnGraphView);
|
||||
}
|
||||
|
||||
Undo.undoRedoPerformed -= OnUndoRedo;
|
||||
}
|
||||
|
||||
private void CreateGUI()
|
||||
{
|
||||
if (ClonedGraph == null)
|
||||
{
|
||||
if (SourceGraph == null && openingGraph != null)
|
||||
{
|
||||
SourceGraph = openingGraph;
|
||||
openingGraph = null;
|
||||
}
|
||||
if (SourceGraph != null)
|
||||
{
|
||||
ClonedGraph = ScriptableObject.Instantiate<TGraph>(SourceGraph);
|
||||
//ClonedGraph = SourceGraph;
|
||||
ClonedGraph.name = SourceGraph.name;
|
||||
}
|
||||
else
|
||||
{
|
||||
Close();
|
||||
return;
|
||||
}
|
||||
}
|
||||
StyleSheet styles = Resources.Load<StyleSheet>("TextureGraph/USS/TextureGraphStyles");
|
||||
|
||||
MainContainer = new VisualElement() { name = "MainContainer" };
|
||||
rootVisualElement.Add(MainContainer);
|
||||
MainContainer.StretchToParentSize();
|
||||
MainContainer.styleSheets.Add(styles);
|
||||
|
||||
Toolbar = new TGraphEditorToolbar();
|
||||
MainContainer.Add(Toolbar);
|
||||
|
||||
VisualElement bodyContainer = new VisualElement() { name = "BodyContainer" };
|
||||
bodyContainer.AddToClassList(TConst.USS_STRETCH);
|
||||
bodyContainer.AddToClassList(TConst.USS_ROW);
|
||||
MainContainer.Add(bodyContainer);
|
||||
|
||||
VisualElement leftContainer = new VisualElement() { name = "LeftContainer" };
|
||||
leftContainer.AddToClassList(TConst.USS_STRETCH);
|
||||
leftContainer.AddToClassList(TConst.USS_LEFT_CONTAINER);
|
||||
bodyContainer.Add(leftContainer);
|
||||
|
||||
GraphView = new TGraphView();
|
||||
GraphView.GraphEditor = this;
|
||||
leftContainer.Add(GraphView);
|
||||
GraphView.AddToClassList(TConst.USS_STRETCH);
|
||||
GraphView.graphViewChanged = OnGraphViewChanged;
|
||||
|
||||
VisualElement rightContainer = new VisualElement() { name = "RightContainer" };
|
||||
rightContainer.AddToClassList(TConst.USS_RIGHT_CONTAINER);
|
||||
TResizer resizer = new TResizer() { Target = rightContainer };
|
||||
rightContainer.Add(resizer);
|
||||
bodyContainer.Add(rightContainer);
|
||||
|
||||
ParameterScrollView = new ScrollView(ScrollViewMode.VerticalAndHorizontal);
|
||||
ParameterScrollView.AddToClassList(TConst.USS_STRETCH);
|
||||
rightContainer.Add(ParameterScrollView);
|
||||
|
||||
#if TG_SEARCHER
|
||||
nodeSearcherWindow = ScriptableObject.CreateInstance<TNodeSearcherWindow>();
|
||||
nodeSearcherWindow.Host = this;
|
||||
GraphView.nodeCreationRequest = OnNodeCreationRequest;
|
||||
#endif
|
||||
|
||||
GraphView.CreateViews(ClonedGraph);
|
||||
GraphView.viewDataKey = "texture-graph-view" + SourceGraph.name;
|
||||
|
||||
string view2DKey = ClonedGraph.name + SUB_WINDOW_2D_VIEW_DATA_KEY;
|
||||
view2DWindow = new TView2DWindow(view2DKey);
|
||||
view2DWindow.GraphEditor = this;
|
||||
view2DWindow.OnEnable();
|
||||
bodyContainer.Add(view2DWindow);
|
||||
view2DWindow.SetImage(ClonedGraph.GetMainRT(view2DWindow.viewData.nodeGuid));
|
||||
if (TViewManager.IsViewVisible(view2DKey))
|
||||
{
|
||||
TViewManager.ShowView(view2DWindow, view2DKey);
|
||||
}
|
||||
else
|
||||
{
|
||||
TViewManager.HideView(view2DWindow, view2DKey);
|
||||
}
|
||||
|
||||
string view3DKey = ClonedGraph.name + SUB_WINDOW_3D_VIEW_DATA_KEY;
|
||||
view3DWindow = new TView3DWindow(view3DKey);
|
||||
view3DWindow.GraphEditor = this;
|
||||
view3DWindow.OnEnable();
|
||||
bodyContainer.Add(view3DWindow);
|
||||
if (TViewManager.IsViewVisible(view3DKey))
|
||||
{
|
||||
TViewManager.ShowView(view3DWindow, view3DKey);
|
||||
}
|
||||
else
|
||||
{
|
||||
TViewManager.HideView(view3DWindow, view3DKey);
|
||||
}
|
||||
Toolbar.GraphEditor = this;
|
||||
|
||||
if (ClonedGraph != null)
|
||||
{
|
||||
ClonedGraph.OnAfterExecuting = OnAfterExecutingGraph;
|
||||
ClonedGraph.Execute();
|
||||
}
|
||||
}
|
||||
|
||||
private void RemoveGUI()
|
||||
{
|
||||
if (MainContainer != null)
|
||||
{
|
||||
rootVisualElement.Remove(MainContainer);
|
||||
}
|
||||
#if TG_SEARCHER
|
||||
if (nodeSearcherWindow != null)
|
||||
{
|
||||
Object.DestroyImmediate(nodeSearcherWindow);
|
||||
}
|
||||
#endif
|
||||
if (SourceGraph != null)
|
||||
{
|
||||
CleanUp(SourceGraph);
|
||||
}
|
||||
if (ClonedGraph != null)
|
||||
{
|
||||
CleanUp(ClonedGraph);
|
||||
}
|
||||
if (view2DWindow != null)
|
||||
{
|
||||
view2DWindow.OnDisable();
|
||||
}
|
||||
if (view3DWindow != null)
|
||||
{
|
||||
view2DWindow.OnDisable();
|
||||
}
|
||||
}
|
||||
|
||||
private void CleanUp(TGraph graph)
|
||||
{
|
||||
List<TAbstractTextureNode> nodes = graph.GraphData.Nodes;
|
||||
foreach (TAbstractTextureNode n in nodes)
|
||||
{
|
||||
n.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
#if TG_SEARCHER
|
||||
private void OnNodeCreationRequest(NodeCreationContext context)
|
||||
{
|
||||
SearcherWindow.Show(
|
||||
this,
|
||||
nodeSearcherWindow.GetItems(),
|
||||
"Create Node",
|
||||
item =>
|
||||
{
|
||||
if (item == null)
|
||||
return false;
|
||||
TNodeSearcherWindow.TNodeSearcherItem i = item as TNodeSearcherWindow.TNodeSearcherItem;
|
||||
if (i.Type == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
CreateNodeOfType(i.Type, context.screenMousePosition);
|
||||
return true;
|
||||
}
|
||||
},
|
||||
context.screenMousePosition - this.position.position,
|
||||
new SearcherWindow.Alignment(SearcherWindow.Alignment.Vertical.Top, SearcherWindow.Alignment.Horizontal.Left));
|
||||
}
|
||||
#endif
|
||||
|
||||
private GraphViewChange OnGraphViewChanged(GraphViewChange change)
|
||||
{
|
||||
HandleMoveElements(change);
|
||||
HandleRemoveEdges(change);
|
||||
HandleAddEdges(change);
|
||||
HandleRemoveNodes(ref change);
|
||||
|
||||
SetGraphDirty(SourceGraph, true);
|
||||
return change;
|
||||
}
|
||||
|
||||
private void HandleMoveElements(GraphViewChange change)
|
||||
{
|
||||
if (change.movedElements == null)
|
||||
return;
|
||||
List<GraphElement> movedElements = change.movedElements;
|
||||
List<Guid> movedNodeGuids = new List<Guid>();
|
||||
foreach (GraphElement e in movedElements)
|
||||
{
|
||||
if (e is Node nodeView)
|
||||
{
|
||||
movedNodeGuids.Add((Guid)nodeView.userData);
|
||||
}
|
||||
}
|
||||
|
||||
Undo.RegisterCompleteObjectUndo(ClonedGraph, UNDO_NAME_GRAPH_EDITING);
|
||||
ClonedGraph.GraphData.MoveNodes(movedNodeGuids, change.moveDelta);
|
||||
}
|
||||
|
||||
private void HandleRemoveEdges(GraphViewChange change)
|
||||
{
|
||||
if (change.elementsToRemove == null)
|
||||
return;
|
||||
List<GraphElement> removedElements = change.elementsToRemove;
|
||||
List<Guid> removedEdgeGuids = new List<Guid>();
|
||||
List<TSlotReference> inputRefs = new List<TSlotReference>();
|
||||
foreach (GraphElement e in removedElements)
|
||||
{
|
||||
if (e is Edge edge)
|
||||
{
|
||||
if (edge != null && edge.userData != null)
|
||||
{
|
||||
removedEdgeGuids.Add((Guid)edge.userData);
|
||||
|
||||
Port inputPort = edge.input;
|
||||
if (inputPort != null && inputPort.userData != null)
|
||||
{
|
||||
TSlotReference inputRef = (TSlotReference)inputPort.userData;
|
||||
inputRefs.Add(inputRef);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (removedEdgeGuids.Count > 0)
|
||||
{
|
||||
Undo.RegisterCompleteObjectUndo(ClonedGraph, UNDO_NAME_GRAPH_EDITING);
|
||||
ClonedGraph.GraphData.RemoveEdges(removedEdgeGuids);
|
||||
foreach (TSlotReference r in inputRefs)
|
||||
{
|
||||
ClonedGraph.ExecuteAt(r.NodeGuid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleAddEdges(GraphViewChange change)
|
||||
{
|
||||
if (change.edgesToCreate == null)
|
||||
return;
|
||||
List<Edge> edgesToCreate = change.edgesToCreate;
|
||||
foreach (Edge edgeView in edgesToCreate)
|
||||
{
|
||||
if (edgeView.isGhostEdge)
|
||||
{
|
||||
Debug.Log("Not adding a ghost edge");
|
||||
continue;
|
||||
}
|
||||
|
||||
Port outputPort = edgeView.output;
|
||||
Port inputPort = edgeView.input;
|
||||
TSlotReference outputRef = (TSlotReference)outputPort.userData;
|
||||
TSlotReference inputRef = (TSlotReference)inputPort.userData;
|
||||
|
||||
Undo.RegisterCompleteObjectUndo(ClonedGraph, UNDO_NAME_GRAPH_EDITING);
|
||||
TEdge edge = new TEdge(outputRef, inputRef);
|
||||
ClonedGraph.GraphData.AddEdge(edge);
|
||||
edgeView.userData = edge.GUID;
|
||||
ClonedGraph.ExecuteAt(inputRef.NodeGuid);
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleRemoveNodes(ref GraphViewChange change)
|
||||
{
|
||||
if (change.elementsToRemove == null)
|
||||
return;
|
||||
|
||||
List<GraphElement> elementsToRemove = change.elementsToRemove;
|
||||
List<GraphElement> connectedEdgeViewToRemove = new List<GraphElement>();
|
||||
List<Guid> removedNodeGuids = new List<Guid>();
|
||||
List<Guid> removedEdgeGuids = new List<Guid>();
|
||||
|
||||
foreach (GraphElement element in elementsToRemove)
|
||||
{
|
||||
if (element is Node node)
|
||||
{
|
||||
removedNodeGuids.Add((Guid)node.userData);
|
||||
GraphView.edges.ForEach(e =>
|
||||
{
|
||||
if (e.input.node == node || e.output.node == node)
|
||||
{
|
||||
removedEdgeGuids.Add((Guid)e.userData);
|
||||
connectedEdgeViewToRemove.Add(e);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (removedNodeGuids.Count > 0)
|
||||
{
|
||||
Undo.RegisterCompleteObjectUndo(ClonedGraph, UNDO_NAME_GRAPH_EDITING);
|
||||
ClonedGraph.GraphData.RemoveNodes(removedNodeGuids);
|
||||
ClonedGraph.GraphData.RemoveEdges(removedEdgeGuids);
|
||||
|
||||
elementsToRemove.AddRange(connectedEdgeViewToRemove);
|
||||
OnNodeToInspectChanged(GraphView, null);
|
||||
}
|
||||
}
|
||||
|
||||
public TNodeView CreateNodeOfType(Type type, Vector2 screenMousePosition)
|
||||
{
|
||||
Undo.RegisterCompleteObjectUndo(ClonedGraph, UNDO_NAME_GRAPH_EDITING);
|
||||
TAbstractTextureNode newNode = Activator.CreateInstance(type) as TAbstractTextureNode;
|
||||
ClonedGraph.GraphData.AddNode(newNode);
|
||||
|
||||
TNodeView newNodeView = TNodeViewCreator.Create(newNode, ClonedGraph);
|
||||
GraphView.AddElement(newNodeView);
|
||||
|
||||
Vector2 mouseWorldPos = screenMousePosition - this.position.position; ;
|
||||
Vector2 mouseLocalPos = GraphView.contentViewContainer.WorldToLocal(mouseWorldPos);
|
||||
Vector2 nodePos = mouseLocalPos - TConst.NODE_CREATION_POSITION_OFFSET;
|
||||
Rect pos = new Rect(nodePos.x, nodePos.y, 0, 0);
|
||||
newNodeView.SetPosition(pos);
|
||||
TNodeDrawState newState = newNode.DrawState;
|
||||
newState.position = pos;
|
||||
newNode.DrawState = newState;
|
||||
|
||||
ClonedGraph.ExecuteAt(newNode.GUID);
|
||||
SetGraphDirty(SourceGraph, true);
|
||||
|
||||
GraphView.ClearSelection();
|
||||
GraphView.AddToSelection(newNodeView);
|
||||
GraphView.HandleNodeToInspect();
|
||||
|
||||
return newNodeView;
|
||||
}
|
||||
|
||||
private void OnNodeToInspectChanged(TGraphView gv, Node n)
|
||||
{
|
||||
if (gv != GraphView)
|
||||
return;
|
||||
ParameterScrollView.contentContainer.Clear();
|
||||
if (n == null)
|
||||
return;
|
||||
|
||||
Foldout paramFoldout = new Foldout() { text = "PARAMETERS" };
|
||||
paramFoldout.AddToClassList("unity-toolbar");
|
||||
paramFoldout.viewDataKey = "params-foldout";
|
||||
ParameterScrollView.Add(paramFoldout);
|
||||
|
||||
TAbstractTextureNode node = ClonedGraph.GraphData.GetNodeByGUID((Guid)n.userData);
|
||||
TParametersDrawer paramsDrawer = TParameterDrawerInitializer.GetDrawer(node.GetType());
|
||||
|
||||
if (paramsDrawer != null)
|
||||
{
|
||||
paramsDrawer.Graph = ClonedGraph;
|
||||
VisualElement paramGui = new IMGUIContainer(() =>
|
||||
{
|
||||
float labelWidth = EditorGUIUtility.labelWidth;
|
||||
EditorGUIUtility.labelWidth = 110;
|
||||
EditorGUI.BeginChangeCheck();
|
||||
paramsDrawer.DrawGUI(node);
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
//Undo.RegisterCompleteObjectUndo(ClonedGraph, UNDO_NAME_GRAPH_EDITING);
|
||||
ClonedGraph.ExecuteAt(node.GUID);
|
||||
SetGraphDirty(SourceGraph, true);
|
||||
}
|
||||
EditorGUIUtility.labelWidth = labelWidth;
|
||||
});
|
||||
|
||||
paramFoldout.contentContainer.Add(paramGui);
|
||||
}
|
||||
|
||||
//VisualElement internalFunctionVE = new VisualElement();
|
||||
//internalFunctionVE.style.marginTop = new StyleLength(10);
|
||||
//internalFunctionVE.style.borderTopColor = new StyleColor(Color.black);
|
||||
//internalFunctionVE.style.borderTopWidth = new StyleFloat(1);
|
||||
|
||||
//IMGUIContainer internalIMGUI = new IMGUIContainer(() =>
|
||||
//{
|
||||
// float labelWidth = EditorGUIUtility.labelWidth;
|
||||
// EditorGUIUtility.labelWidth = 110;
|
||||
|
||||
// EditorGUILayout.LabelField("Node position", node.DrawState.position.position.ToString());
|
||||
// EditorGUILayout.LabelField("Node view position", n.GetPosition().position.ToString());
|
||||
|
||||
// EditorGUIUtility.labelWidth = labelWidth;
|
||||
//});
|
||||
//internalFunctionVE.Add(internalIMGUI);
|
||||
//parameterScrollView.Add(internalFunctionVE);
|
||||
}
|
||||
|
||||
private void OnNodeDoubleClicked(TGraphView gv, Node n)
|
||||
{
|
||||
if (gv != GraphView)
|
||||
return;
|
||||
TAbstractTextureNode node = ClonedGraph.GraphData.GetNodeByGUID((Guid)n.userData);
|
||||
if (node != null)
|
||||
{
|
||||
view2DWindow.viewData.nodeGuid = node.GUID;
|
||||
ClonedGraph.ExecuteAt(node.GUID);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnAfterExecutingNode(TAbstractTextureNode n, TAbstractTextureNode.TExecutionMetadata meta)
|
||||
{
|
||||
if (GraphView != null)
|
||||
{
|
||||
TNodeView nodeView = GraphView.FindNode(n.GUID);
|
||||
if (nodeView != null)
|
||||
{
|
||||
string metaText = $"{meta.resolution.x}x{meta.resolution.y}\n{meta.format}";
|
||||
nodeView.SetMetadata(metaText);
|
||||
|
||||
if (n.GUID == view2DWindow.viewData.nodeGuid)
|
||||
{
|
||||
TSlot previewSlot = n.GetMainOutputSlot();
|
||||
if (previewSlot != null)
|
||||
{
|
||||
RenderTexture tex = ClonedGraph.GetRT(TSlotReference.Create(n.GUID, previewSlot.Id));
|
||||
view2DWindow.SetImage(tex);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void OnAfterExecutingGraph(TGraph graph) //Cloned Graph execution callback
|
||||
{
|
||||
if (view3DWindow != null)
|
||||
{
|
||||
if (TViewManager.IsViewVisible(view3DWindow.viewDataKey))
|
||||
{
|
||||
view3DWindow.RenderPreviewScene();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static void SetGraphDirty(TGraph graph, bool isDirty)
|
||||
{
|
||||
if (isDirty)
|
||||
{
|
||||
if (!GraphDirtyState.Contains(graph))
|
||||
{
|
||||
GraphDirtyState.Add(graph);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
GraphDirtyState.RemoveAll(g => g == graph);
|
||||
}
|
||||
}
|
||||
|
||||
public static bool IsGraphDirty(TGraph graph)
|
||||
{
|
||||
bool isDirty = GraphDirtyState.Contains(graph);
|
||||
return isDirty;
|
||||
}
|
||||
|
||||
private void OnUndoRedo()
|
||||
{
|
||||
GraphView.UpdateViewOnUndoRedo(ClonedGraph);
|
||||
view3DWindow.RenderPreviewScene();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 01e8d4bc7509a5e4ca0fb63d0ea91fad
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,269 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using UnityEditor.UIElements;
|
||||
using UnityEngine.UIElements;
|
||||
using UnityEditor.Experimental.GraphView;
|
||||
using System;
|
||||
using TSerializedElement = Pinwheel.TextureGraph.TGraphSerializer.TSerializedElement;
|
||||
|
||||
namespace Pinwheel.TextureGraph
|
||||
{
|
||||
public partial class TGraphEditor : EditorWindow
|
||||
{
|
||||
private void HandleShortcutKeys(KeyCode k, bool isControl, bool isShift, bool isAlt)
|
||||
{
|
||||
k = Event.current.keyCode;
|
||||
if (isControl && k == KeyCode.S)
|
||||
{
|
||||
if (SourceGraph != null && ClonedGraph != null)
|
||||
{
|
||||
HandleSave();
|
||||
}
|
||||
}
|
||||
else if (isControl && k == KeyCode.X)
|
||||
{
|
||||
if (ClonedGraph != null)
|
||||
{
|
||||
HandleCut();
|
||||
}
|
||||
}
|
||||
else if (isControl && k == KeyCode.C)
|
||||
{
|
||||
if (ClonedGraph != null)
|
||||
{
|
||||
HandleCopy();
|
||||
}
|
||||
}
|
||||
else if (isControl && k == KeyCode.V)
|
||||
{
|
||||
if (ClonedGraph != null)
|
||||
{
|
||||
HandlePaste();
|
||||
}
|
||||
}
|
||||
else if (isControl && k == KeyCode.D)
|
||||
{
|
||||
if (ClonedGraph != null)
|
||||
{
|
||||
HandleCopy();
|
||||
HandlePaste();
|
||||
}
|
||||
}
|
||||
else if (isControl && k == KeyCode.Z)
|
||||
{
|
||||
if (ClonedGraph != null)
|
||||
{
|
||||
HandleUndo();
|
||||
}
|
||||
}
|
||||
else if (isControl && k == KeyCode.Y)
|
||||
{
|
||||
if (ClonedGraph != null)
|
||||
{
|
||||
HandleRedo();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleShortcutKeysOnGraphView(KeyDownEvent e)
|
||||
{
|
||||
HandleShortcutKeys(e.keyCode, e.ctrlKey, e.shiftKey, e.altKey);
|
||||
}
|
||||
|
||||
public void HandleSave()
|
||||
{
|
||||
TGraphSaver.Save(ClonedGraph, SourceGraph);
|
||||
}
|
||||
|
||||
public void HandleCut()
|
||||
{
|
||||
if (!HasSelection())
|
||||
return;
|
||||
|
||||
HandleCopy(true);
|
||||
GraphView.DeleteSelection();
|
||||
}
|
||||
|
||||
public void HandleCopy(bool isCut = false)
|
||||
{
|
||||
if (!HasSelection())
|
||||
return;
|
||||
|
||||
List<ITGraphSerializeCallbackReceiver> serializedElements = new List<ITGraphSerializeCallbackReceiver>();
|
||||
foreach (ISelectable s in GraphView.selection)
|
||||
{
|
||||
if (s is Node n)
|
||||
{
|
||||
Guid guid = (Guid)n.userData;
|
||||
TAbstractTextureNode node = ClonedGraph.GraphData.GetNodeByGUID(guid);
|
||||
if (node != null)
|
||||
{
|
||||
serializedElements.Add(node);
|
||||
}
|
||||
}
|
||||
if (s is Edge e)
|
||||
{
|
||||
Guid guid = (Guid)e.userData;
|
||||
ITEdge edge = ClonedGraph.GraphData.GetEdgeByGUID(guid);
|
||||
if (edge != null)
|
||||
{
|
||||
serializedElements.Add(edge);
|
||||
}
|
||||
}
|
||||
}
|
||||
TClipboard.SetData(serializedElements, isCut);
|
||||
}
|
||||
|
||||
public void HandlePaste()
|
||||
{
|
||||
if (!CanPaste())
|
||||
return;
|
||||
|
||||
List<TSerializedElement> nodeData = new List<TSerializedElement>();
|
||||
List<TSerializedElement> edgeData = new List<TSerializedElement>();
|
||||
TClipboard.GetData(nodeData, edgeData);
|
||||
if (TClipboard.IsCut)
|
||||
{
|
||||
TClipboard.Clear();
|
||||
}
|
||||
|
||||
List<TAbstractTextureNode> nodes = new List<TAbstractTextureNode>();
|
||||
List<ITEdge> edges = new List<ITEdge>();
|
||||
|
||||
Dictionary<Guid, Guid> guidRemap = new Dictionary<Guid, Guid>();
|
||||
|
||||
Vector2 avgNodePos = Vector2.zero;
|
||||
foreach (TSerializedElement data in nodeData)
|
||||
{
|
||||
TAbstractTextureNode n = TGraphSerializer.Deserialize<TAbstractTextureNode>(data);
|
||||
n.OnAfterDeserialize();
|
||||
Guid oldGuid = n.GUID;
|
||||
Guid newGuid = Guid.NewGuid();
|
||||
guidRemap.Add(oldGuid, newGuid);
|
||||
TGuidSetter.Set(n, newGuid);
|
||||
nodes.Add(n);
|
||||
|
||||
avgNodePos += n.DrawState.position.position + TConst.NODE_CREATION_POSITION_OFFSET;
|
||||
}
|
||||
|
||||
avgNodePos = avgNodePos / nodes.Count;
|
||||
Vector2 mousePosInGraphView = GraphView.LocalMousePosition;
|
||||
Vector2 worldMousePos = GraphView.LocalToWorld(mousePosInGraphView);
|
||||
Vector2 newCenterPoint = GraphView.contentViewContainer.WorldToLocal(worldMousePos);
|
||||
Vector2 offset = newCenterPoint - avgNodePos;
|
||||
foreach (TAbstractTextureNode n in nodes)
|
||||
{
|
||||
TNodeDrawState state = n.DrawState;
|
||||
state.position.position += offset;
|
||||
n.DrawState = state;
|
||||
}
|
||||
|
||||
foreach (TSerializedElement data in edgeData)
|
||||
{
|
||||
ITEdge e = TGraphSerializer.Deserialize<ITEdge>(data);
|
||||
e.OnAfterDeserialize();
|
||||
Guid newGuid = Guid.NewGuid();
|
||||
TGuidSetter.Set(e, newGuid);
|
||||
|
||||
TSlotReference inputRef = e.InputSlot;
|
||||
Guid inputGUID = inputRef.NodeGuid;
|
||||
if (!guidRemap.TryGetValue(inputGUID, out inputGUID))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
TSlotReference outputRef = e.OutputSlot;
|
||||
Guid outputGUID = outputRef.NodeGuid;
|
||||
if (!guidRemap.TryGetValue(outputGUID, out outputGUID))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
TEdge newEdge = new TEdge(TSlotReference.Create(outputGUID, outputRef.SlotId), TSlotReference.Create(inputGUID, inputRef.SlotId));
|
||||
edges.Add(newEdge);
|
||||
}
|
||||
|
||||
foreach (TAbstractTextureNode n in nodes)
|
||||
{
|
||||
ClonedGraph.GraphData.AddNode(n);
|
||||
}
|
||||
foreach (ITEdge e in edges)
|
||||
{
|
||||
ClonedGraph.GraphData.AddEdge(e);
|
||||
}
|
||||
|
||||
SetGraphDirty(SourceGraph, true);
|
||||
|
||||
int nodeStartIndex = ClonedGraph.GraphData.Nodes.Count - nodes.Count;
|
||||
int edgeStartIndex = ClonedGraph.GraphData.Edges.Count - edges.Count;
|
||||
int[] nodeIndices = TUtilities.GetIndicesArray(nodeStartIndex, ClonedGraph.GraphData.Nodes.Count - 1);
|
||||
int[] edgeIndices = TUtilities.GetIndicesArray(edgeStartIndex, ClonedGraph.GraphData.Edges.Count - 1);
|
||||
List<GraphElement> newViews = GraphView.CreateViews(ClonedGraph, nodeIndices, edgeIndices);
|
||||
GraphView.ClearSelection();
|
||||
foreach (ISelectable v in newViews)
|
||||
{
|
||||
GraphView.AddToSelection(v);
|
||||
}
|
||||
}
|
||||
|
||||
public bool HasSelection()
|
||||
{
|
||||
return GraphView.selection.Count > 0;
|
||||
}
|
||||
|
||||
public bool CanPaste()
|
||||
{
|
||||
return TClipboard.HasData();
|
||||
}
|
||||
|
||||
public void HandleUndo()
|
||||
{
|
||||
Undo.PerformUndo();
|
||||
}
|
||||
|
||||
public void HandleRedo()
|
||||
{
|
||||
Undo.PerformRedo();
|
||||
}
|
||||
|
||||
public void OpenGraphSettings()
|
||||
{
|
||||
if (settingsWindow == null)
|
||||
{
|
||||
settingsWindow = TGraphSettingsWindow.ShowWindow(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
settingsWindow.Focus();
|
||||
}
|
||||
}
|
||||
|
||||
public void OpenExportWindow()
|
||||
{
|
||||
if (exportWindow == null)
|
||||
{
|
||||
exportWindow = TExportWindow.ShowWindow(this);
|
||||
}
|
||||
else
|
||||
{
|
||||
exportWindow.Focus();
|
||||
}
|
||||
}
|
||||
|
||||
public void OpenDocumentation(TNodeView nv)
|
||||
{
|
||||
Guid nodeGuid = (Guid)nv.userData;
|
||||
TAbstractTextureNode n = ClonedGraph.GraphData.GetNodeByGUID(nodeGuid);
|
||||
if (n != null)
|
||||
{
|
||||
TNodeMetadataAttribute meta = TNodeMetadataInitializer.GetMetadata(n.GetType());
|
||||
if (!string.IsNullOrEmpty(meta.Documentation))
|
||||
{
|
||||
Application.OpenURL(meta.Documentation);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b8afa9cb62eb11b48b755a7f951200ab
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,242 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor.UIElements;
|
||||
using UnityEditor;
|
||||
using UnityEngine.UIElements;
|
||||
using System;
|
||||
|
||||
namespace Pinwheel.TextureGraph
|
||||
{
|
||||
public class TGraphEditorToolbar : Toolbar
|
||||
{
|
||||
public enum TToolbarMenu
|
||||
{
|
||||
File, Edit, Create, Module, View, Help
|
||||
}
|
||||
|
||||
public TGraphEditor GraphEditor { get; set; }
|
||||
|
||||
public TGraphEditorToolbar() : base()
|
||||
{
|
||||
StyleSheet styles = Resources.Load<StyleSheet>("TextureGraph/USS/ToolbarStyles");
|
||||
this.styleSheets.Add(styles);
|
||||
|
||||
AddMenus();
|
||||
}
|
||||
|
||||
private void AddMenus()
|
||||
{
|
||||
foreach (object m in System.Enum.GetValues(typeof(TToolbarMenu)))
|
||||
{
|
||||
AddMenu((TToolbarMenu)m);
|
||||
}
|
||||
}
|
||||
|
||||
private void AddMenu(TToolbarMenu menuType)
|
||||
{
|
||||
ToolbarButton button = new ToolbarButton();
|
||||
button.text = menuType.ToString();
|
||||
|
||||
button.clicked += () =>
|
||||
{
|
||||
Rect r = button.layout;
|
||||
r.position = new Vector2(r.min.x, r.max.y);
|
||||
|
||||
GenericMenu menu = GetMenu(menuType);
|
||||
if (menu != null)
|
||||
{
|
||||
menu.DropDown(r);
|
||||
}
|
||||
};
|
||||
|
||||
this.Add(button);
|
||||
}
|
||||
|
||||
private GenericMenu GetMenu(TToolbarMenu menuType)
|
||||
{
|
||||
if (menuType == TToolbarMenu.File)
|
||||
return GetFileMenu();
|
||||
else if (menuType == TToolbarMenu.Edit)
|
||||
return GetEditMenu();
|
||||
else if (menuType == TToolbarMenu.Create)
|
||||
return GetCreateMenu();
|
||||
else if (menuType == TToolbarMenu.Module)
|
||||
return GetModuleMenu();
|
||||
else if (menuType == TToolbarMenu.View)
|
||||
return GetViewMenu();
|
||||
else if (menuType == TToolbarMenu.Help)
|
||||
return GetHelpMenu();
|
||||
return null;
|
||||
}
|
||||
|
||||
private GenericMenu GetFileMenu()
|
||||
{
|
||||
GenericMenu menu = new GenericMenu();
|
||||
menu.AddMenuItem(
|
||||
true,
|
||||
"Save %S",
|
||||
() => { GraphEditor.HandleSave(); });
|
||||
menu.AddMenuItem(
|
||||
true,
|
||||
"Export",
|
||||
() => { GraphEditor.OpenExportWindow(); });
|
||||
|
||||
return menu;
|
||||
}
|
||||
|
||||
private GenericMenu GetEditMenu()
|
||||
{
|
||||
GenericMenu menu = new GenericMenu();
|
||||
menu.AddMenuItem(
|
||||
true,
|
||||
"Undo %Z",
|
||||
() => { GraphEditor.HandleUndo(); });
|
||||
menu.AddMenuItem(
|
||||
true,
|
||||
"Redo %Y",
|
||||
() => { GraphEditor.HandleRedo(); });
|
||||
menu.AddSeparator(null);
|
||||
menu.AddMenuItem(
|
||||
GraphEditor.HasSelection(),
|
||||
"Cut %X",
|
||||
() => { GraphEditor.HandleCut(); });
|
||||
menu.AddMenuItem(
|
||||
GraphEditor.HasSelection(),
|
||||
"Copy %C",
|
||||
() => { GraphEditor.HandleCopy(); });
|
||||
menu.AddMenuItem(
|
||||
GraphEditor.CanPaste(),
|
||||
"Paste %V",
|
||||
() => { GraphEditor.HandlePaste(); });
|
||||
menu.AddSeparator(null);
|
||||
menu.AddMenuItem(
|
||||
GraphEditor.HasSelection(),
|
||||
"Duplicate %D",
|
||||
() => { GraphEditor.HandleCopy(); GraphEditor.HandlePaste(); });
|
||||
menu.AddSeparator(null);
|
||||
menu.AddMenuItem(
|
||||
GraphEditor.HasSelection(),
|
||||
"Delete",
|
||||
() => { GraphEditor.GraphView.DeleteSelection(); });
|
||||
|
||||
menu.AddSeparator(null);
|
||||
menu.AddMenuItem(
|
||||
true,
|
||||
"Graph Settings",
|
||||
() => { GraphEditor.OpenGraphSettings(); });
|
||||
|
||||
return menu;
|
||||
}
|
||||
|
||||
private GenericMenu GetCreateMenu()
|
||||
{
|
||||
GenericMenu menu = new GenericMenu();
|
||||
List<TMenuEntryGroup<Type>> flattenMenu = TNodeCreationMenu.GetFlattenMenu();
|
||||
for (int i = 0; i < flattenMenu.Count; ++i)
|
||||
{
|
||||
TMenuEntryGroup<Type> entry = flattenMenu[i];
|
||||
if (entry.Data == null)
|
||||
continue;
|
||||
|
||||
menu.AddItem(
|
||||
new GUIContent("Node/" + entry.Path),
|
||||
false,
|
||||
() =>
|
||||
{
|
||||
Vector2 screenPos = GraphEditor.position.position + GraphEditor.GraphView.LocalToWorld(GraphEditor.GraphView.layout.center);
|
||||
GraphEditor.CreateNodeOfType(entry.Data, screenPos);
|
||||
});
|
||||
}
|
||||
return menu;
|
||||
}
|
||||
|
||||
private GenericMenu GetModuleMenu()
|
||||
{
|
||||
GenericMenu menu = new GenericMenu();
|
||||
// bool isHighResModuleInstalled = false;
|
||||
//#if TEXTURE_GRAPH_HIGH_RESOLUTION
|
||||
// isHighResModuleInstalled = true;
|
||||
//#endif
|
||||
//menu.AddItem(
|
||||
// new GUIContent("High Resolution"),
|
||||
// isHighResModuleInstalled,
|
||||
// () => { Application.OpenURL(TLink.HIGH_RESOLUTION_MODULE); });
|
||||
|
||||
return menu;
|
||||
}
|
||||
|
||||
private GenericMenu GetViewMenu()
|
||||
{
|
||||
GenericMenu menu = new GenericMenu();
|
||||
|
||||
string view2Dkey = GraphEditor.ClonedGraph.name + TGraphEditor.SUB_WINDOW_2D_VIEW_DATA_KEY;
|
||||
menu.AddItem(
|
||||
new GUIContent("2D View"),
|
||||
TViewManager.IsViewVisible(view2Dkey),
|
||||
() =>
|
||||
{
|
||||
TViewManager.ToggleViewVisibility(GraphEditor.view2DWindow, view2Dkey);
|
||||
});
|
||||
|
||||
string view3Dkey = GraphEditor.ClonedGraph.name + TGraphEditor.SUB_WINDOW_3D_VIEW_DATA_KEY;
|
||||
menu.AddItem(
|
||||
new GUIContent("3D View"),
|
||||
TViewManager.IsViewVisible(view3Dkey),
|
||||
() =>
|
||||
{
|
||||
TViewManager.ToggleViewVisibility(GraphEditor.view3DWindow, view3Dkey);
|
||||
});
|
||||
|
||||
|
||||
return menu;
|
||||
}
|
||||
|
||||
private GenericMenu GetHelpMenu()
|
||||
{
|
||||
GenericMenu menu = new GenericMenu();
|
||||
menu.AddItem(
|
||||
new GUIContent("User Guide"),
|
||||
false,
|
||||
() => { Application.OpenURL(TLink.USER_GUIDE); });
|
||||
menu.AddItem(
|
||||
new GUIContent("Scripting API"),
|
||||
false,
|
||||
() => { Application.OpenURL(TLink.SCRIPTING_API); });
|
||||
menu.AddSeparator(null);
|
||||
menu.AddItem(
|
||||
new GUIContent("Facebook"),
|
||||
false,
|
||||
() => { Application.OpenURL(TLink.FACEBOOK); });
|
||||
menu.AddItem(
|
||||
new GUIContent("Youtube"),
|
||||
false,
|
||||
() => { Application.OpenURL(TLink.YOUTUBE); });
|
||||
menu.AddItem(
|
||||
new GUIContent("Have A Chat"),
|
||||
false,
|
||||
() => { Application.OpenURL(TLink.DISCORD); });
|
||||
menu.AddItem(
|
||||
new GUIContent("Send Support Email"),
|
||||
false,
|
||||
() => { TEditorCommon.OpenEmailEditor(TLink.SUPPORT_EMAIL, "[Texture Graph] SUBJECT_HERE", "MESSAGE_HERE"); });
|
||||
menu.AddSeparator(null);
|
||||
menu.AddItem(
|
||||
new GUIContent("Version Info"),
|
||||
false,
|
||||
() => { EditorUtility.DisplayDialog("Version Info", TVersionInfo.ProductNameAndVersion, "OK"); });
|
||||
menu.AddItem(
|
||||
new GUIContent("Release Logs"),
|
||||
false,
|
||||
() => { Application.OpenURL(TLink.RELEASE_LOG); });
|
||||
menu.AddItem(
|
||||
new GUIContent("Leave A Review"),
|
||||
false,
|
||||
() => { Application.OpenURL(TLink.STORE_PAGE); });
|
||||
|
||||
return menu;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4c52188ebb40ac74a83ab98893e1aa14
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,18 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor.Experimental.GraphView;
|
||||
using System;
|
||||
|
||||
namespace Pinwheel.TextureGraph
|
||||
{
|
||||
public static class TGraphEditorUtilities
|
||||
{
|
||||
public static bool SlotRefEqual(Port p0, Port p1)
|
||||
{
|
||||
TSlotReference id0 = (TSlotReference)p0.userData;
|
||||
TSlotReference id1 = (TSlotReference)p1.userData;
|
||||
return id0.Equals(id1);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ee571306f529a1244841dd600a4b4969
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,19 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
|
||||
namespace Pinwheel.TextureGraph
|
||||
{
|
||||
public static class TGraphSaver
|
||||
{
|
||||
public static void Save(TGraph clonedGraph, TGraph sourceGraph)
|
||||
{
|
||||
clonedGraph.CopySerializeDataTo(sourceGraph);
|
||||
EditorUtility.SetDirty(sourceGraph);
|
||||
AssetDatabase.SaveAssets();
|
||||
TGraphEditor.SetGraphDirty(sourceGraph, false);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7e8b0faa35085704591b395458fdc1ae
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,107 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
|
||||
namespace Pinwheel.TextureGraph
|
||||
{
|
||||
public class TGraphSettingsWindow : EditorWindow
|
||||
{
|
||||
public TGraphEditor GraphEditor { get; set; }
|
||||
private Vector2Int BaseResolution { get; set; }
|
||||
private bool UseHighPrecision { get; set; }
|
||||
|
||||
private static readonly GUIContent baseResolutionGUI = new GUIContent("Base Resolution", "Default resolution for all nodes");
|
||||
private static readonly GUIContent useHighPrecisionGUI = new GUIContent("High Precision", "Presicion for texture data");
|
||||
|
||||
private static readonly GUIContent lightColor0GUI = new GUIContent("Light Color 0", "Color of the first light");
|
||||
private static readonly GUIContent lightIntensity0GUI = new GUIContent("Light Intensity 0", "Intensity of the first light");
|
||||
private static readonly GUIContent lightColor1GUI = new GUIContent("Light Color 1", "Color of the second light");
|
||||
private static readonly GUIContent lightIntensity1GUI = new GUIContent("Light Intensity 1", "Intensity of the second light");
|
||||
private static readonly GUIContent customMeshGUI = new GUIContent("Custom Mesh", "User-selected mesh to render preview");
|
||||
private static readonly GUIContent tessLevelGUI = new GUIContent("Tessellation Level", "Add more detail to the preview mesh");
|
||||
private static readonly GUIContent displacementStrengthGUI = new GUIContent("Displacement Strength", "How much to displace the mesh based on the height map");
|
||||
|
||||
private Vector2 scrollPos;
|
||||
|
||||
public static TGraphSettingsWindow ShowWindow(TGraphEditor graphEditor)
|
||||
{
|
||||
TGraphSettingsWindow window = TGraphSettingsWindow.CreateInstance<TGraphSettingsWindow>();
|
||||
window.titleContent = new GUIContent($"{graphEditor.ClonedGraph.name} Settings");
|
||||
window.GraphEditor = graphEditor;
|
||||
window.LoadSettings();
|
||||
window.ShowUtility();
|
||||
return window;
|
||||
}
|
||||
|
||||
public void LoadSettings()
|
||||
{
|
||||
BaseResolution = GraphEditor.ClonedGraph.BaseResolution;
|
||||
UseHighPrecision = GraphEditor.ClonedGraph.UseHighPrecision;
|
||||
}
|
||||
|
||||
private void OnGUI()
|
||||
{
|
||||
EditorGUI.indentLevel += 1;
|
||||
scrollPos = EditorGUILayout.BeginScrollView(scrollPos);
|
||||
DrawGraphSettings();
|
||||
Draw3DEnvironmentSettings();
|
||||
EditorGUILayout.EndScrollView();
|
||||
|
||||
TEditorCommon.Separator();
|
||||
EditorGUILayout.Space();
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
GUILayout.FlexibleSpace();
|
||||
if (GUILayout.Button("OK", GUILayout.Width(100)))
|
||||
{
|
||||
ApplySettings();
|
||||
Close();
|
||||
}
|
||||
if (GUILayout.Button("Cancel", GUILayout.Width(100)))
|
||||
{
|
||||
Close();
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
EditorGUILayout.Space();
|
||||
EditorGUI.indentLevel -= 1;
|
||||
}
|
||||
|
||||
private void DrawGraphSettings()
|
||||
{
|
||||
TEditorCommon.Header("Graph");
|
||||
BaseResolution = TEditorCommon.InlineVector2IntField(baseResolutionGUI, BaseResolution);
|
||||
BaseResolution = new Vector2Int(
|
||||
Mathf.Clamp(BaseResolution.x, TConst.TEXTURE_SIZE_MIN.x, TConst.TEXTURE_SIZE_MAX.x),
|
||||
Mathf.Clamp(BaseResolution.y, TConst.TEXTURE_SIZE_MIN.y, TConst.TEXTURE_SIZE_MAX.y));
|
||||
UseHighPrecision = EditorGUILayout.Toggle(useHighPrecisionGUI, UseHighPrecision);
|
||||
}
|
||||
|
||||
private void ApplySettings()
|
||||
{
|
||||
GraphEditor.ClonedGraph.BaseResolution = BaseResolution;
|
||||
GraphEditor.ClonedGraph.UseHighPrecision = UseHighPrecision;
|
||||
GraphEditor.ClonedGraph.Execute();
|
||||
}
|
||||
|
||||
private void Draw3DEnvironmentSettings()
|
||||
{
|
||||
TEditorCommon.Header("3D Environment");
|
||||
TView3DEnvironmentSettings envSettings = GraphEditor.ClonedGraph.View3DEnvironmentSettings;
|
||||
EditorGUI.BeginChangeCheck();
|
||||
envSettings.Light0.LightColor = EditorGUILayout.ColorField(lightColor0GUI, envSettings.Light0.LightColor, true, false, true);
|
||||
envSettings.Light0.Intensity = EditorGUILayout.FloatField(lightIntensity0GUI, envSettings.Light0.Intensity);
|
||||
envSettings.Light1.LightColor = EditorGUILayout.ColorField(lightColor1GUI, envSettings.Light1.LightColor, true, false, true);
|
||||
envSettings.Light1.Intensity = EditorGUILayout.FloatField(lightIntensity1GUI, envSettings.Light1.Intensity);
|
||||
envSettings.CustomMesh = EditorGUILayout.ObjectField(customMeshGUI, envSettings.CustomMesh, typeof(Mesh), false) as Mesh;
|
||||
envSettings.TessellationLevel = EditorGUILayout.IntSlider(tessLevelGUI, envSettings.TessellationLevel, 1, 64);
|
||||
envSettings.DisplacementStrength = EditorGUILayout.Slider(displacementStrengthGUI, envSettings.DisplacementStrength, 0f, 1f);
|
||||
if (EditorGUI.EndChangeCheck())
|
||||
{
|
||||
if (TViewManager.IsViewVisible(GraphEditor.view3DWindow.viewDataKey))
|
||||
{
|
||||
GraphEditor.view3DWindow.RenderPreviewScene();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f104afb3a73264b4eb6acdea60b1f3f1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,319 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor.Experimental.GraphView;
|
||||
using UnityEditor.UIElements;
|
||||
using UnityEngine.UIElements;
|
||||
using System;
|
||||
|
||||
namespace Pinwheel.TextureGraph
|
||||
{
|
||||
public class TGraphView : GraphView
|
||||
{
|
||||
public delegate void NodeToInspectChangedHandler(TGraphView graphView, Node node);
|
||||
public static event NodeToInspectChangedHandler NodeToInspectChanged;
|
||||
|
||||
public delegate void NodeDoubleClickedHandler(TGraphView graphView, Node node);
|
||||
public static event NodeDoubleClickedHandler NodeDoubleClicked;
|
||||
|
||||
public static readonly Color32 backgroundColor = new Color32(32, 32, 32, 255);
|
||||
|
||||
public TGraphEditor GraphEditor { get; set; }
|
||||
public Vector2 LocalMousePosition { get; set; }
|
||||
|
||||
private Node nodeToInspect;
|
||||
|
||||
public TGraphView()
|
||||
{
|
||||
SetupZoom(0.2f, 10f, ContentZoomer.DefaultScaleStep, ContentZoomer.DefaultReferenceScale);
|
||||
this.AddManipulator(new ContentDragger());
|
||||
this.AddManipulator(new SelectionDragger());
|
||||
this.AddManipulator(new RectangleSelector());
|
||||
this.AddManipulator(new ClickSelector());
|
||||
|
||||
this.style.backgroundColor = new StyleColor(backgroundColor);
|
||||
}
|
||||
|
||||
public List<GraphElement> CreateViews(TGraph graph)
|
||||
{
|
||||
int[] nodeIndices = TUtilities.GetIndicesArray(graph.GraphData.Nodes.Count);
|
||||
int[] edgeIndices = TUtilities.GetIndicesArray(graph.GraphData.Edges.Count);
|
||||
return CreateViews(graph, nodeIndices, edgeIndices);
|
||||
}
|
||||
|
||||
public List<GraphElement> CreateViews(TGraph graph, IEnumerable<int> nodeIndices, IEnumerable<int> edgeIndices)
|
||||
{
|
||||
graph.GraphData.Validate();
|
||||
List<GraphElement> createdViews = new List<GraphElement>();
|
||||
List<Guid> nodeGuids = new List<Guid>();
|
||||
|
||||
foreach (int i in nodeIndices)
|
||||
{
|
||||
TAbstractTextureNode n = graph.GraphData.Nodes[i];
|
||||
Node nv = TNodeViewCreator.Create(n, graph);
|
||||
AddElement(nv);
|
||||
createdViews.Add(nv);
|
||||
nodeGuids.Add(n.GUID);
|
||||
}
|
||||
|
||||
Dictionary<TSlotReference, Port> slotRefToPortRemap = new Dictionary<TSlotReference, Port>();
|
||||
ports.ForEach(p =>
|
||||
{
|
||||
TSlotReference slotRef = (TSlotReference)p.userData;
|
||||
slotRefToPortRemap[slotRef] = p;
|
||||
});
|
||||
|
||||
foreach (int i in edgeIndices)
|
||||
{
|
||||
ITEdge e = graph.GraphData.Edges[i];
|
||||
Port outPort = slotRefToPortRemap[e.OutputSlot];
|
||||
Port inPort = slotRefToPortRemap[e.InputSlot];
|
||||
Edge ev = outPort.ConnectTo(inPort);
|
||||
ev.userData = e.GUID;
|
||||
AddElement(ev);
|
||||
createdViews.Add(ev);
|
||||
}
|
||||
|
||||
graph.ExecuteAt(nodeGuids);
|
||||
|
||||
return createdViews;
|
||||
}
|
||||
|
||||
public override List<Port> GetCompatiblePorts(Port startPort, NodeAdapter nodeAdapter)
|
||||
{
|
||||
List<Port> compatiblePorts = new List<Port>();
|
||||
ports.ForEach(p =>
|
||||
{
|
||||
if (p != startPort && p.node != startPort.node && p.direction != startPort.direction)
|
||||
compatiblePorts.Add(p);
|
||||
});
|
||||
return compatiblePorts;
|
||||
}
|
||||
|
||||
public override void HandleEvent(EventBase evt)
|
||||
{
|
||||
base.HandleEvent(evt);
|
||||
if (evt is MouseDownEvent || evt is MouseUpEvent)
|
||||
{
|
||||
HandleNodeToInspect();
|
||||
}
|
||||
if (evt is MouseDownEvent mde)
|
||||
{
|
||||
if (mde.clickCount >= 2)
|
||||
{
|
||||
HandleNodeDoubleClick();
|
||||
}
|
||||
}
|
||||
if (evt is MouseMoveEvent mme)
|
||||
{
|
||||
LocalMousePosition = mme.localMousePosition;
|
||||
}
|
||||
}
|
||||
|
||||
public void HandleNodeToInspect()
|
||||
{
|
||||
Node n = null;
|
||||
if (selection != null)
|
||||
{
|
||||
if (selection.Count == 1)
|
||||
{
|
||||
if (selection[0] is Node selectedNode)
|
||||
{
|
||||
n = selectedNode;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (n != nodeToInspect)
|
||||
{
|
||||
nodeToInspect = n;
|
||||
if (NodeToInspectChanged != null)
|
||||
{
|
||||
NodeToInspectChanged.Invoke(this, nodeToInspect);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleNodeDoubleClick()
|
||||
{
|
||||
if (nodeToInspect != null)
|
||||
{
|
||||
if (NodeDoubleClicked != null)
|
||||
{
|
||||
NodeDoubleClicked.Invoke(this, nodeToInspect);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public TNodeView FindNode(Guid guid)
|
||||
{
|
||||
TNodeView node = null;
|
||||
nodes.ForEach(nv =>
|
||||
{
|
||||
Guid nodeGuid = (Guid)nv.userData;
|
||||
if (nodeGuid.Equals(guid))
|
||||
{
|
||||
node = nv as TNodeView;
|
||||
return;
|
||||
}
|
||||
});
|
||||
return node;
|
||||
}
|
||||
|
||||
public Edge FindEdge(Guid guid)
|
||||
{
|
||||
Edge edge = null;
|
||||
edges.ForEach(ev =>
|
||||
{
|
||||
Guid edgeGuid = (Guid)ev.userData;
|
||||
if (edgeGuid.Equals(guid))
|
||||
{
|
||||
edge = ev;
|
||||
return;
|
||||
}
|
||||
});
|
||||
return edge;
|
||||
}
|
||||
|
||||
public void UpdateViewOnUndoRedo(TGraph graph)
|
||||
{
|
||||
//Remove views that binding data doesn't exist
|
||||
List<GraphElement> elementToRemove = new List<GraphElement>();
|
||||
nodes.ForEach(nv =>
|
||||
{
|
||||
Guid nodeGuid = (Guid)nv.userData;
|
||||
TAbstractTextureNode n = graph.GraphData.GetNodeByGUID(nodeGuid);
|
||||
if (n == null)
|
||||
{
|
||||
elementToRemove.Add(nv);
|
||||
}
|
||||
});
|
||||
edges.ForEach(ev =>
|
||||
{
|
||||
Guid edgeGuid = (Guid)ev.userData;
|
||||
ITEdge e = graph.GraphData.GetEdgeByGUID(edgeGuid);
|
||||
if (e == null)
|
||||
{
|
||||
elementToRemove.Add(ev);
|
||||
}
|
||||
});
|
||||
DeleteElements(elementToRemove);
|
||||
|
||||
//Create views for data that doesn't have view
|
||||
List<TAbstractTextureNode> nodeData = graph.GraphData.Nodes;
|
||||
List<ITEdge> edgeData = graph.GraphData.Edges;
|
||||
List<int> nodeIndices = new List<int>();
|
||||
List<int> edgeIndices = new List<int>();
|
||||
|
||||
for (int i = 0; i < nodeData.Count; ++i)
|
||||
{
|
||||
Node nv = FindNode(nodeData[i].GUID);
|
||||
if (nv == null)
|
||||
{
|
||||
nodeIndices.Add(i);
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < edgeData.Count; ++i)
|
||||
{
|
||||
Edge ev = FindEdge(edgeData[i].GUID);
|
||||
if (ev == null)
|
||||
{
|
||||
edgeIndices.Add(i);
|
||||
}
|
||||
}
|
||||
|
||||
if (nodeIndices.Count > 0 || edgeIndices.Count > 0)
|
||||
{
|
||||
CreateViews(graph, nodeIndices, edgeIndices);
|
||||
}
|
||||
|
||||
//Update elements position
|
||||
nodes.ForEach(nv =>
|
||||
{
|
||||
Guid nodeGuid = (Guid)nv.userData;
|
||||
TAbstractTextureNode n = graph.GraphData.GetNodeByGUID(nodeGuid);
|
||||
if (n != null)
|
||||
{
|
||||
nv.SetPosition(n.DrawState.position);
|
||||
}
|
||||
});
|
||||
|
||||
ClearSelection();
|
||||
HandleNodeToInspect();
|
||||
}
|
||||
|
||||
public override void BuildContextualMenu(ContextualMenuPopulateEvent evt)
|
||||
{
|
||||
if (evt.target is TGraphView && nodeCreationRequest != null)
|
||||
{
|
||||
evt.menu.AppendAction(
|
||||
"Create Node",
|
||||
(a) =>
|
||||
{
|
||||
Vector2 mousePos = a.eventInfo.localMousePosition + GraphEditor.position.position;
|
||||
NodeCreationContext context = new NodeCreationContext() { screenMousePosition = mousePos };
|
||||
nodeCreationRequest.Invoke(context);
|
||||
|
||||
});
|
||||
}
|
||||
evt.menu.AppendSeparator();
|
||||
|
||||
if (evt.target is TGraphView || evt.target is TNodeView)
|
||||
{
|
||||
evt.menu.AppendAction(
|
||||
"Cut",
|
||||
(a) =>
|
||||
{
|
||||
GraphEditor.HandleCut();
|
||||
},
|
||||
GraphEditor.HasSelection() ? DropdownMenuAction.Status.Normal : DropdownMenuAction.Status.Disabled);
|
||||
evt.menu.AppendAction(
|
||||
"Copy",
|
||||
(a) =>
|
||||
{
|
||||
GraphEditor.HandleCopy();
|
||||
},
|
||||
GraphEditor.HasSelection() ? DropdownMenuAction.Status.Normal : DropdownMenuAction.Status.Disabled);
|
||||
evt.menu.AppendAction(
|
||||
"Paste",
|
||||
(a) =>
|
||||
{
|
||||
GraphEditor.HandlePaste();
|
||||
},
|
||||
GraphEditor.CanPaste() ? DropdownMenuAction.Status.Normal : DropdownMenuAction.Status.Disabled);
|
||||
evt.menu.AppendSeparator(null);
|
||||
evt.menu.AppendAction(
|
||||
"Duplicate",
|
||||
(a) =>
|
||||
{
|
||||
GraphEditor.HandleCopy();
|
||||
GraphEditor.HandlePaste();
|
||||
TClipboard.Clear();
|
||||
},
|
||||
GraphEditor.HasSelection() ? DropdownMenuAction.Status.Normal : DropdownMenuAction.Status.Disabled);
|
||||
}
|
||||
|
||||
if (evt.target is TGraphView || evt.target is TNodeView || evt.target is Edge)
|
||||
{
|
||||
evt.menu.AppendSeparator(null);
|
||||
evt.menu.AppendAction(
|
||||
"Delete",
|
||||
(a) =>
|
||||
{
|
||||
DeleteSelection();
|
||||
},
|
||||
GraphEditor.HasSelection() ? DropdownMenuAction.Status.Normal : DropdownMenuAction.Status.Disabled);
|
||||
}
|
||||
|
||||
if (evt.target is TNodeView nv)
|
||||
{
|
||||
evt.menu.AppendSeparator(null);
|
||||
evt.menu.AppendAction(
|
||||
"Open Documentation",
|
||||
(a) =>
|
||||
{
|
||||
GraphEditor.OpenDocumentation(nv);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 170151071e9644447ba8c15a6b791b31
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,26 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Pinwheel.TextureGraph
|
||||
{
|
||||
public static class TGuidSetter
|
||||
{
|
||||
public static bool Set(object o, Guid guid)
|
||||
{
|
||||
Type t = o.GetType();
|
||||
FieldInfo guidField = t.GetField("guid", BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
|
||||
if (guidField == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
else
|
||||
{
|
||||
guidField.SetValue(o, guid);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cc7e902aa7f9cf34e9795efbabbcd8b5
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,64 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using System;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Pinwheel.TextureGraph
|
||||
{
|
||||
[InitializeOnLoad]
|
||||
public class TNodeCreationMenu
|
||||
{
|
||||
private static TMenuTree<Type> menuTree;
|
||||
public static TMenuTree<Type> MenuTree
|
||||
{
|
||||
get
|
||||
{
|
||||
if (menuTree == null)
|
||||
{
|
||||
menuTree = new TMenuTree<Type>("", "Node", null);
|
||||
}
|
||||
return menuTree;
|
||||
}
|
||||
private set
|
||||
{
|
||||
menuTree = value;
|
||||
}
|
||||
}
|
||||
|
||||
[InitializeOnLoadMethod]
|
||||
//[MenuItem("Window/Texture Graph/Init Node Creation Menu")]
|
||||
public static void InitNodeMenus()
|
||||
{
|
||||
List<Type> nodeTypes = new List<Type>();
|
||||
Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
|
||||
foreach (Assembly assembly in assemblies)
|
||||
{
|
||||
Type[] types = assembly.GetTypes();
|
||||
foreach (Type t in types)
|
||||
{
|
||||
if (t.IsSubclassOf(typeof(TAbstractTextureNode)))
|
||||
{
|
||||
nodeTypes.Add(t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
MenuTree = new TMenuTree<Type>("", "Node", null);
|
||||
foreach (Type t in nodeTypes)
|
||||
{
|
||||
TNodeMetadataAttribute meta = t.GetCustomAttribute<TNodeMetadataAttribute>(false);
|
||||
if (meta != null && !string.IsNullOrEmpty(meta.CreationMenu))
|
||||
{
|
||||
MenuTree.AddEntry(meta.Icon, meta.CreationMenu, t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static List<TMenuEntryGroup<Type>> GetFlattenMenu()
|
||||
{
|
||||
return MenuTree.ToList();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: dfcffd85b960a8847a271a5a7b547453
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,64 @@
|
||||
#if TG_SEARCHER
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor.Searcher;
|
||||
using UnityEngine.UIElements;
|
||||
using UnityEditor;
|
||||
using System;
|
||||
|
||||
namespace Pinwheel.TextureGraph
|
||||
{
|
||||
public class TNodeSearcherWindow : ScriptableObject
|
||||
{
|
||||
public class TNodeSearcherItem : SearcherItem
|
||||
{
|
||||
public Type Type;
|
||||
|
||||
public TNodeSearcherItem(string name, string help = "", List<SearcherItem> children = null) : base(name, help, children)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
public EditorWindow Host { get; set; }
|
||||
|
||||
public List<SearcherItem> GetItems()
|
||||
{
|
||||
TMenuTree<Type> trees = TNodeCreationMenu.MenuTree;
|
||||
Stack<TMenuEntryGroup<Type>> s0 = new Stack<TMenuEntryGroup<Type>>();
|
||||
for (int i = 0; i < trees.RootEntry.SubEntries.Count; ++i)
|
||||
{
|
||||
s0.Push(trees.RootEntry.SubEntries[i]);
|
||||
}
|
||||
|
||||
List<SearcherItem> items = new List<SearcherItem>();
|
||||
Stack<SearcherItem> s1 = new Stack<SearcherItem>();
|
||||
for (int i = 0; i < trees.RootEntry.SubEntries.Count; ++i)
|
||||
{
|
||||
TMenuEntryGroup<Type> entry = trees.RootEntry.SubEntries[i];
|
||||
TNodeSearcherItem childItems = new TNodeSearcherItem(entry.Text);
|
||||
childItems.Type = entry.Data;
|
||||
items.Add(childItems);
|
||||
s1.Push(childItems);
|
||||
}
|
||||
|
||||
while (s0.Count > 0)
|
||||
{
|
||||
TMenuEntryGroup<Type> treeEntry = s0.Pop();
|
||||
SearcherItem item = s1.Pop();
|
||||
|
||||
for (int i = 0; i < treeEntry.SubEntries.Count; ++i)
|
||||
{
|
||||
TNodeSearcherItem childItem = new TNodeSearcherItem(treeEntry.SubEntries[i].Text);
|
||||
childItem.Type = treeEntry.SubEntries[i].Data;
|
||||
item.AddChild(childItem);
|
||||
s0.Push(treeEntry.SubEntries[i]);
|
||||
s1.Push(childItem);
|
||||
}
|
||||
}
|
||||
|
||||
return items;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 89bc37ec6d385d84c8e3cd30cd4637b2
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,56 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor.Experimental.GraphView;
|
||||
using System;
|
||||
using UnityEditor;
|
||||
using UnityEngine.Rendering;
|
||||
using UnityEngine.Experimental.Rendering;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace Pinwheel.TextureGraph
|
||||
{
|
||||
public class TNodeView : Node
|
||||
{
|
||||
public TGraph Graph { get; set; }
|
||||
public Guid NodeDataGuid { get; set; }
|
||||
|
||||
public void DrawPreviewCallback()
|
||||
{
|
||||
TAbstractTextureNode n = Graph.GraphData.GetNodeByGUID(NodeDataGuid);
|
||||
if (n == null)
|
||||
return;
|
||||
Texture preview = null;
|
||||
TSlot previewSlot = n.GetMainOutputSlot();
|
||||
if (previewSlot != null)
|
||||
{
|
||||
preview = Graph.GetRT(TSlotReference.Create(n.GUID, previewSlot.Id));
|
||||
}
|
||||
|
||||
Rect r = new Rect(0, 0, TextureGraph.TConst.NODE_PREVIEW_SIZE.x, TextureGraph.TConst.NODE_PREVIEW_SIZE.y);
|
||||
if (preview == null)
|
||||
{
|
||||
EditorGUI.DrawRect(r, Color.black);
|
||||
EditorGUI.LabelField(r, "No preview available.", TEditorCommon.CenteredWhiteLabel);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (TUtilities.IsGrayscaleFormat(preview.graphicsFormat))
|
||||
{
|
||||
Material mat = TEditorCommon.PreviewRedToGrayMaterial;
|
||||
EditorGUI.DrawPreviewTexture(r, preview, mat, ScaleMode.ScaleToFit, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
GUI.DrawTexture(r, preview, ScaleMode.ScaleToFit, true, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void SetMetadata(string text)
|
||||
{
|
||||
Label metaLabel = this.Q<Label>("metaLabel");
|
||||
metaLabel.text = text;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 86abd9bc1f7b63f4789024cd7e026c98
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,134 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor.Experimental.GraphView;
|
||||
using UnityEditor.UIElements;
|
||||
using UnityEngine.UIElements;
|
||||
using UnityEditor;
|
||||
using System.Reflection;
|
||||
using System;
|
||||
using GraphicsFormat = UnityEngine.Experimental.Rendering.GraphicsFormat;
|
||||
|
||||
namespace Pinwheel.TextureGraph
|
||||
{
|
||||
public class TNodeViewCreator
|
||||
{
|
||||
private static class TConst
|
||||
{
|
||||
public static readonly Color portColorRGBA = new Color(1f, 0.5f, 0f, 1f);
|
||||
public static readonly Color portColorGray = new Color(0.75f, 0.75f, 0.75f, 1f);
|
||||
}
|
||||
|
||||
private static string GetNodeTitle(Type t)
|
||||
{
|
||||
TNodeMetadataAttribute meta = TNodeMetadataInitializer.GetMetadata(t);
|
||||
if (meta != null && !string.IsNullOrEmpty(meta.Title))
|
||||
{
|
||||
return meta.Title;
|
||||
}
|
||||
else
|
||||
{
|
||||
return ObjectNames.NicifyVariableName(t.Name);
|
||||
}
|
||||
}
|
||||
|
||||
public static TNodeView Create(TAbstractTextureNode n, TGraph parentGraph)
|
||||
{
|
||||
TNodeView nodeView = new TNodeView();
|
||||
nodeView.NodeDataGuid = n.GUID;
|
||||
nodeView.Graph = parentGraph;
|
||||
|
||||
nodeView.title = GetNodeTitle(n.GetType());
|
||||
nodeView.SetPosition(n.DrawState.position);
|
||||
|
||||
List<TSlot> inputSlots = n.GetInputSlots();
|
||||
for (int i = 0; i < inputSlots.Count; ++i)
|
||||
{
|
||||
Port p = nodeView.InstantiatePort(Orientation.Horizontal, Direction.Input, Port.Capacity.Single, null);
|
||||
p.portName = null;
|
||||
TSlotReference slotRef = TSlotReference.Create(n.GUID, inputSlots[i].Id);
|
||||
p.userData = slotRef;
|
||||
p.tooltip = inputSlots[i].Name;
|
||||
SetPortCustomStyles(p, inputSlots[i]);
|
||||
nodeView.inputContainer.Add(p);
|
||||
}
|
||||
|
||||
List<TSlot> outputSlots = n.GetOutputSlots();
|
||||
for (int i = 0; i < outputSlots.Count; ++i)
|
||||
{
|
||||
Port p = nodeView.InstantiatePort(Orientation.Horizontal, Direction.Output, Port.Capacity.Multi, null);
|
||||
p.portName = null;
|
||||
TSlotReference slotRef = TSlotReference.Create(n.GUID, outputSlots[i].Id);
|
||||
p.userData = slotRef;
|
||||
p.tooltip = outputSlots[i].Name;
|
||||
nodeView.outputContainer.Add(p);
|
||||
SetPortCustomStyles(p, outputSlots[i]);
|
||||
}
|
||||
|
||||
IMGUIContainer previewIMGUI = new IMGUIContainer() { name = "previewIMGUI" };
|
||||
previewIMGUI.style.width = new StyleLength(TextureGraph.TConst.NODE_PREVIEW_SIZE.x);
|
||||
previewIMGUI.style.height = new StyleLength(TextureGraph.TConst.NODE_PREVIEW_SIZE.y);
|
||||
previewIMGUI.style.backgroundImage = new StyleBackground(Resources.Load<Texture2D>("TextureGraph/Textures/Checkerboard"));
|
||||
previewIMGUI.onGUIHandler = () =>
|
||||
{
|
||||
nodeView.DrawPreviewCallback();
|
||||
};
|
||||
previewIMGUI.pickingMode = PickingMode.Ignore;
|
||||
|
||||
VisualElement previewContainer = new VisualElement() { name = "preview" };
|
||||
previewContainer.Add(previewIMGUI);
|
||||
nodeView.topContainer.Clear();
|
||||
nodeView.topContainer.Add(previewContainer);
|
||||
nodeView.topContainer.Add(nodeView.inputContainer);
|
||||
nodeView.topContainer.Add(nodeView.outputContainer);
|
||||
|
||||
StyleColor inputOutputBG = new StyleColor(Color.clear);
|
||||
nodeView.inputContainer.style.backgroundColor = inputOutputBG;
|
||||
nodeView.outputContainer.style.backgroundColor = inputOutputBG;
|
||||
|
||||
nodeView.userData = n.GUID;
|
||||
nodeView.RefreshPorts();
|
||||
nodeView.RefreshExpandedState();
|
||||
|
||||
nodeView.Q("node-border").style.overflow = new StyleEnum<Overflow>(Overflow.Visible);
|
||||
nodeView.Q("selection-border").SendToBack();
|
||||
|
||||
VisualElement metaContainer = new VisualElement() { name = "metaContainer" };
|
||||
Label metaLabel = new Label() { name = "metaLabel" };
|
||||
metaContainer.Add(metaLabel);
|
||||
nodeView.Add(metaContainer);
|
||||
|
||||
StyleSheet styles = Resources.Load<StyleSheet>("TextureGraph/USS/NodeStyles");
|
||||
nodeView.styleSheets.Add(styles);
|
||||
|
||||
return nodeView;
|
||||
}
|
||||
|
||||
private static void SetPortCustomStyles(Port p, TSlot slot)
|
||||
{
|
||||
VisualElement connector = p.Q("connector");
|
||||
StyleLength size = new StyleLength(12f);
|
||||
connector.style.width = size;
|
||||
connector.style.height = size;
|
||||
|
||||
StyleLength margin = new StyleLength(0f);
|
||||
connector.style.marginLeft = margin;
|
||||
connector.style.marginTop = margin;
|
||||
connector.style.marginRight = margin;
|
||||
connector.style.marginBottom = margin;
|
||||
|
||||
StyleFloat borderWidth = new StyleFloat(2);
|
||||
connector.style.borderLeftWidth = borderWidth;
|
||||
connector.style.borderTopWidth = borderWidth;
|
||||
connector.style.borderRightWidth = borderWidth;
|
||||
connector.style.borderBottomWidth = borderWidth;
|
||||
|
||||
StyleLength capSize = new StyleLength(4f);
|
||||
VisualElement cap = p.Q("cap");
|
||||
cap.style.width = capSize;
|
||||
cap.style.height = capSize;
|
||||
|
||||
p.portColor = slot.DataType == TSlotDataType.RGBA ? TConst.portColorRGBA : TConst.portColorGray;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7dc76bffe89a6d64bb7a929b086a32d1
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,14 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor.Experimental.GraphView;
|
||||
using UnityEditor.UIElements;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace Pinwheel.TextureGraph
|
||||
{
|
||||
public static class TNodeViewExtension
|
||||
{
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ae9b26553357c0047ac9bc23ea55265a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,77 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine.UIElements;
|
||||
using UnityEditor;
|
||||
using System;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Pinwheel.TextureGraph
|
||||
{
|
||||
public abstract class TParametersDrawer
|
||||
{
|
||||
public TGraph Graph { get; set; }
|
||||
public abstract void DrawGUI(TAbstractTextureNode target);
|
||||
}
|
||||
|
||||
[InitializeOnLoad]
|
||||
public class TParameterDrawerInitializer
|
||||
{
|
||||
private static Dictionary<Type, Type> drawerTypeRemap;
|
||||
private static Dictionary<Type, Type> DrawerTypeRemap
|
||||
{
|
||||
get
|
||||
{
|
||||
if (drawerTypeRemap == null)
|
||||
{
|
||||
drawerTypeRemap = new Dictionary<Type, Type>();
|
||||
}
|
||||
return drawerTypeRemap;
|
||||
}
|
||||
set
|
||||
{
|
||||
drawerTypeRemap = value;
|
||||
}
|
||||
}
|
||||
|
||||
//[MenuItem("Window/Texture Graph/Init Drawer")]
|
||||
[InitializeOnLoadMethod]
|
||||
public static void InitDrawers()
|
||||
{
|
||||
DrawerTypeRemap.Clear();
|
||||
Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies();
|
||||
foreach (Assembly assembly in assemblies)
|
||||
{
|
||||
Type[] types = assembly.GetTypes();
|
||||
foreach (Type t in types)
|
||||
{
|
||||
if (!t.IsSubclassOf(typeof(TParametersDrawer)))
|
||||
continue;
|
||||
TCustomParametersDrawerAttribute drawerAttribute = t.GetCustomAttribute<TCustomParametersDrawerAttribute>();
|
||||
if (drawerAttribute == null)
|
||||
continue;
|
||||
DrawerTypeRemap.Add(drawerAttribute.type, t);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static Type GetDrawerType(Type nodeType)
|
||||
{
|
||||
Type t = null;
|
||||
DrawerTypeRemap.TryGetValue(nodeType, out t);
|
||||
return t;
|
||||
}
|
||||
|
||||
public static TParametersDrawer GetDrawer(Type nodeType)
|
||||
{
|
||||
Type drawerType = GetDrawerType(nodeType);
|
||||
if (drawerType == null)
|
||||
{
|
||||
drawerType = typeof(TDefaultParamsDrawer);
|
||||
}
|
||||
|
||||
TParametersDrawer drawer = Activator.CreateInstance(drawerType) as TParametersDrawer;
|
||||
return drawer;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 23e1033b440ab394385767672bd8dca4
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,85 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System;
|
||||
using UnityEditor.SceneManagement;
|
||||
using UnityEngine.SceneManagement;
|
||||
using UnityEditor;
|
||||
|
||||
namespace Pinwheel.TextureGraph
|
||||
{
|
||||
public class TPreviewSceneData : IDisposable
|
||||
{
|
||||
public Scene PreviewScene { get; set; }
|
||||
public Camera Camera { get; set; }
|
||||
public Material Material { get; set; }
|
||||
public RenderTexture RenderTarget { get; set; }
|
||||
|
||||
public TPreviewSceneData()
|
||||
{
|
||||
Material = new Material(Shader.Find("Hidden/TextureGraph/Preview3D"));
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (RenderTarget != null)
|
||||
{
|
||||
RenderTarget.Release();
|
||||
TUtilities.DestroyObject(RenderTarget);
|
||||
}
|
||||
if (Material != null)
|
||||
{
|
||||
TUtilities.DestroyObject(Material);
|
||||
}
|
||||
}
|
||||
|
||||
public void PrepareScene()
|
||||
{
|
||||
PreviewScene = EditorSceneManager.NewPreviewScene();
|
||||
GameObject cameraObject = new GameObject("Camera") { hideFlags = HideFlags.HideAndDontSave };
|
||||
SceneManager.MoveGameObjectToScene(cameraObject, PreviewScene);
|
||||
Camera = cameraObject.AddComponent<Camera>();
|
||||
Camera.transform.position = new Vector3(0, 0, -1);
|
||||
Camera.transform.rotation = Quaternion.identity;
|
||||
Camera.transform.localScale = Vector3.one;
|
||||
Camera.nearClipPlane = 0.01f;
|
||||
Camera.farClipPlane = 1000;
|
||||
Camera.clearFlags = CameraClearFlags.SolidColor;
|
||||
Camera.backgroundColor = Color.clear;
|
||||
Camera.cameraType = CameraType.Preview;
|
||||
Camera.useOcclusionCulling = false;
|
||||
Camera.scene = PreviewScene;
|
||||
Camera.enabled = false;
|
||||
}
|
||||
|
||||
public void CloseScene()
|
||||
{
|
||||
if (Camera != null)
|
||||
{
|
||||
Camera.targetTexture = null;
|
||||
TUtilities.DestroyGameobject(Camera.gameObject);
|
||||
}
|
||||
EditorSceneManager.ClosePreviewScene(PreviewScene);
|
||||
}
|
||||
|
||||
public void PrepareRenderTarget(int width, int height)
|
||||
{
|
||||
if (RenderTarget != null)
|
||||
{
|
||||
if (RenderTarget.width != width ||
|
||||
RenderTarget.height != height)
|
||||
{
|
||||
RenderTarget.Release();
|
||||
TUtilities.DestroyObject(RenderTarget);
|
||||
RenderTarget = null;
|
||||
}
|
||||
}
|
||||
|
||||
if (RenderTarget == null)
|
||||
{
|
||||
RenderTarget = new RenderTexture(width, height, 16, RenderTextureFormat.ARGB32, 0);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: eb4026eb8721dc8498e5195bcc002e5f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,62 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace Pinwheel.TextureGraph.UIElements
|
||||
{
|
||||
public class TResizer : VisualElement
|
||||
{
|
||||
public static readonly string USS_RESIZER = "resizer";
|
||||
public static readonly string USS_RESIZER_LEFT = "resizer-left";
|
||||
|
||||
private bool isDragging;
|
||||
|
||||
public VisualElement Target { get; set; }
|
||||
|
||||
public TResizer()
|
||||
{
|
||||
StyleSheet styles = Resources.Load<StyleSheet>("TextureGraph/USS/ResizerStyles");
|
||||
styleSheets.Add(styles);
|
||||
|
||||
AddToClassList(USS_RESIZER);
|
||||
AddToClassList(USS_RESIZER_LEFT);
|
||||
}
|
||||
|
||||
protected override void ExecuteDefaultAction(EventBase evt)
|
||||
{
|
||||
base.ExecuteDefaultAction(evt);
|
||||
|
||||
if (Target == null)
|
||||
return;
|
||||
|
||||
long eventTypeId = evt.eventTypeId;
|
||||
if (eventTypeId == MouseDownEvent.TypeId())
|
||||
{
|
||||
isDragging = true;
|
||||
evt.target.CaptureMouse();
|
||||
}
|
||||
else if (eventTypeId == MouseMoveEvent.TypeId())
|
||||
{
|
||||
if (!isDragging)
|
||||
return;
|
||||
MouseMoveEvent mouseMoveEvt = evt as MouseMoveEvent;
|
||||
float currentWidth = Target.resolvedStyle.width;
|
||||
Target.style.width = new StyleLength(currentWidth - mouseMoveEvt.mouseDelta.x);
|
||||
}
|
||||
else if (eventTypeId == MouseLeaveEvent.TypeId())
|
||||
{
|
||||
if (!isDragging)
|
||||
return;
|
||||
MouseLeaveEvent mouseLeaveEvt = evt as MouseLeaveEvent;
|
||||
float currentWidth = Target.resolvedStyle.width;
|
||||
Target.style.width = new StyleLength(currentWidth - mouseLeaveEvt.mouseDelta.x);
|
||||
}
|
||||
else if (eventTypeId == MouseUpEvent.TypeId())
|
||||
{
|
||||
isDragging = false;
|
||||
evt.target.ReleaseMouse();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d941afe9a445f804786a447f525db045
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,37 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine.UIElements;
|
||||
using System;
|
||||
|
||||
namespace Pinwheel.TextureGraph
|
||||
{
|
||||
public class TScrollable : MouseManipulator
|
||||
{
|
||||
public Action<Vector2> OnScroll;
|
||||
|
||||
public TScrollable(Action<Vector2> onScroll)
|
||||
{
|
||||
OnScroll = onScroll;
|
||||
}
|
||||
|
||||
protected override void RegisterCallbacksOnTarget()
|
||||
{
|
||||
target.RegisterCallback<WheelEvent>(OnMouseWheelEvent, TrickleDown.NoTrickleDown);
|
||||
}
|
||||
|
||||
protected override void UnregisterCallbacksFromTarget()
|
||||
{
|
||||
target.UnregisterCallback<WheelEvent>(OnMouseWheelEvent, TrickleDown.NoTrickleDown);
|
||||
}
|
||||
|
||||
private void OnMouseWheelEvent(WheelEvent e)
|
||||
{
|
||||
if (OnScroll != null)
|
||||
{
|
||||
OnScroll.Invoke(e.delta);
|
||||
e.StopPropagation();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 90bea9d2ed04fad47850c10055a9fc95
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,127 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine.UIElements;
|
||||
using UnityEditor.UIElements;
|
||||
using UnityEditor;
|
||||
using System;
|
||||
|
||||
namespace Pinwheel.TextureGraph
|
||||
{
|
||||
public class TSubWindow : VisualElement, ITManagedView
|
||||
{
|
||||
public TGraphEditor GraphEditor { get; set; }
|
||||
|
||||
public VisualElement mainContainer;
|
||||
public VisualElement topContainer;
|
||||
public VisualElement bodyContainer;
|
||||
public VisualElement resizeHandleContainer;
|
||||
public Button closeButton;
|
||||
|
||||
protected TWindowDragZone dragZone;
|
||||
protected TSubWindowResizer resizer;
|
||||
|
||||
protected TextElement titleLabel;
|
||||
|
||||
public TSubWindow(string viewKey)
|
||||
{
|
||||
viewDataKey = viewKey;
|
||||
styleSheets.Add(Resources.Load<StyleSheet>("TextureGraph/USS/SubWindow"));
|
||||
|
||||
mainContainer = new VisualElement() { name = "mainContainer" };
|
||||
this.Add(mainContainer);
|
||||
|
||||
topContainer = new VisualElement() { name = "topContainer" };
|
||||
titleLabel = new TextElement() { name = "titleLabel" };
|
||||
topContainer.Add(titleLabel);
|
||||
mainContainer.Add(topContainer);
|
||||
|
||||
closeButton = new Button() { name = "closeButton", text = "X" };
|
||||
closeButton.clicked += () => { TViewManager.HideView(this, viewDataKey); };
|
||||
topContainer.Add(closeButton);
|
||||
|
||||
bodyContainer = new VisualElement() { name = "bodyContainer" };
|
||||
mainContainer.Add(bodyContainer);
|
||||
|
||||
resizeHandleContainer = new VisualElement() { name = "resizeHandleContainer" };
|
||||
mainContainer.Add(resizeHandleContainer);
|
||||
}
|
||||
|
||||
public void SetTitle(string t)
|
||||
{
|
||||
TextElement titleLabel = topContainer.Q<TextElement>("titleLabel");
|
||||
titleLabel.text = t;
|
||||
}
|
||||
|
||||
public void SetPosition(Vector2 pos)
|
||||
{
|
||||
style.left = new StyleLength(pos.x);
|
||||
style.top = new StyleLength(pos.y);
|
||||
style.right = new StyleLength(float.NaN);
|
||||
style.bottom = new StyleLength(float.NaN);
|
||||
}
|
||||
|
||||
public void SetSize(Vector2 size)
|
||||
{
|
||||
style.width = new StyleLength(size.x);
|
||||
style.height = new StyleLength(size.y);
|
||||
}
|
||||
|
||||
public void EnableWindowDragging(Action<Vector2> onPositionChanged = null)
|
||||
{
|
||||
dragZone = new TWindowDragZone(this, this.parent);
|
||||
dragZone.OnPositionChanged = onPositionChanged;
|
||||
topContainer.AddManipulator(dragZone);
|
||||
}
|
||||
|
||||
public void DisableWindowDragging()
|
||||
{
|
||||
topContainer.RemoveManipulator(dragZone);
|
||||
}
|
||||
|
||||
public void EnableWindowResizing(Vector2 minSize, Vector2 maxSize, Action<Vector2> onSizeChanged = null)
|
||||
{
|
||||
resizer = new TSubWindowResizer(this)
|
||||
{
|
||||
MinSize = minSize,
|
||||
MaxSize = maxSize,
|
||||
OnSizeChanged = onSizeChanged
|
||||
};
|
||||
resizeHandleContainer.AddManipulator(resizer);
|
||||
}
|
||||
|
||||
public void DisableWindowResizing()
|
||||
{
|
||||
resizeHandleContainer.RemoveManipulator(resizer);
|
||||
}
|
||||
|
||||
public virtual void Show()
|
||||
{
|
||||
style.display = new StyleEnum<DisplayStyle>(DisplayStyle.Flex);
|
||||
}
|
||||
|
||||
public virtual void Hide()
|
||||
{
|
||||
style.display = new StyleEnum<DisplayStyle>(DisplayStyle.None);
|
||||
}
|
||||
|
||||
public virtual void OnEnable()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public virtual void OnDisable()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public virtual void OnDestroy()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public virtual void Dispose()
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b1b36cb39bd5bbf409db8d2bbb2226c6
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,94 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine.UIElements;
|
||||
using System;
|
||||
|
||||
namespace Pinwheel.TextureGraph
|
||||
{
|
||||
public class TSubWindowResizer : MouseManipulator
|
||||
{
|
||||
public VisualElement Window { get; set; }
|
||||
public Vector2 MinSize { get; set; }
|
||||
public Vector2 MaxSize { get; set; }
|
||||
private bool IsDragging { get; set; }
|
||||
|
||||
public Action<Vector2> OnSizeChanged;
|
||||
|
||||
public TSubWindowResizer(VisualElement window)
|
||||
{
|
||||
Window = window;
|
||||
MinSize = Vector2.zero;
|
||||
MaxSize = Vector2.one * 10000;
|
||||
}
|
||||
|
||||
protected override void RegisterCallbacksOnTarget()
|
||||
{
|
||||
target.RegisterCallback<MouseDownEvent>(OnMouseDown, TrickleDown.NoTrickleDown);
|
||||
target.RegisterCallback<MouseMoveEvent>(OnMouseMove, TrickleDown.NoTrickleDown);
|
||||
target.RegisterCallback<MouseUpEvent>(OnMouseUp, TrickleDown.NoTrickleDown);
|
||||
}
|
||||
|
||||
protected override void UnregisterCallbacksFromTarget()
|
||||
{
|
||||
target.UnregisterCallback<MouseDownEvent>(OnMouseDown, TrickleDown.NoTrickleDown);
|
||||
target.UnregisterCallback<MouseMoveEvent>(OnMouseMove, TrickleDown.NoTrickleDown);
|
||||
target.UnregisterCallback<MouseUpEvent>(OnMouseUp, TrickleDown.NoTrickleDown);
|
||||
}
|
||||
|
||||
private void OnMouseDown(MouseDownEvent e)
|
||||
{
|
||||
target.CaptureMouse();
|
||||
if (e.button == 0)
|
||||
{
|
||||
IsDragging = true;
|
||||
}
|
||||
e.StopPropagation();
|
||||
}
|
||||
|
||||
private void OnMouseMove(MouseMoveEvent e)
|
||||
{
|
||||
if (!IsDragging)
|
||||
return;
|
||||
Vector2 delta = e.mouseDelta;
|
||||
ResizeAndClamp(delta, e.shiftKey);
|
||||
}
|
||||
|
||||
private void OnMouseUp(MouseUpEvent e)
|
||||
{
|
||||
if (target.HasMouseCapture())
|
||||
{
|
||||
target.ReleaseMouse();
|
||||
}
|
||||
IsDragging = false;
|
||||
e.StopPropagation();
|
||||
}
|
||||
|
||||
private void ResizeAndClamp(Vector2 delta, bool maintainAspect = false)
|
||||
{
|
||||
float width = Window.style.width.value.value;
|
||||
float height = Window.style.height.value.value;
|
||||
|
||||
width += delta.x;
|
||||
height += delta.y;
|
||||
|
||||
width = Mathf.Clamp(width, MinSize.x, MaxSize.x);
|
||||
height = Mathf.Clamp(height, MinSize.y, MaxSize.y);
|
||||
|
||||
if (maintainAspect)
|
||||
{
|
||||
float max = Mathf.Max(width, height);
|
||||
width = max;
|
||||
height = max;
|
||||
}
|
||||
|
||||
Window.style.width = new StyleLength(width);
|
||||
Window.style.height = new StyleLength(height);
|
||||
|
||||
if (OnSizeChanged != null)
|
||||
{
|
||||
OnSizeChanged.Invoke(new Vector2(width, height));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3ffa21e3a2c86b84984117671eef2c07
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,296 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Pinwheel.TextureGraph;
|
||||
using UnityEditor;
|
||||
using UnityEditor.UIElements;
|
||||
using UnityEngine.UIElements;
|
||||
using System;
|
||||
|
||||
|
||||
namespace Pinwheel.TextureGraph
|
||||
{
|
||||
public class TView2DWindow : TSubWindow
|
||||
{
|
||||
public struct TViewData
|
||||
{
|
||||
public const string KEY_POSITION_X = "position-x";
|
||||
public const string KEY_POSITION_Y = "position-y";
|
||||
public const string KEY_SIZE_X = "size-x";
|
||||
public const string KEY_SIZE_Y = "size-y";
|
||||
public const string KEY_TILING_X = "tiling-x";
|
||||
public const string KEY_TILING_Y = "tiling-y";
|
||||
public const string KEY_OFFSET_X = "offset-x";
|
||||
public const string KEY_OFFSET_Y = "offset-y";
|
||||
public const string KEY_GUID = "guid";
|
||||
public const string KEY_CHANNEL = "channel";
|
||||
|
||||
public Vector2 position;
|
||||
public Vector2 size;
|
||||
public Vector2 imageTiling;
|
||||
public Vector2 imageOffset;
|
||||
public Guid nodeGuid;
|
||||
public int channel;
|
||||
|
||||
public void Load(string key)
|
||||
{
|
||||
position = new Vector2(EditorPrefs.GetFloat(key + KEY_POSITION_X, 0), EditorPrefs.GetFloat(key + KEY_POSITION_Y, 0));
|
||||
size = new Vector2(EditorPrefs.GetFloat(key + KEY_SIZE_X, 200), EditorPrefs.GetFloat(key + KEY_SIZE_Y, 200));
|
||||
imageTiling = new Vector2(EditorPrefs.GetFloat(key + KEY_TILING_X, 1), EditorPrefs.GetFloat(key + KEY_TILING_Y, 1));
|
||||
imageOffset = new Vector2(EditorPrefs.GetFloat(key + KEY_OFFSET_X, 0), EditorPrefs.GetFloat(key + KEY_OFFSET_Y, 0));
|
||||
string guidString = EditorPrefs.GetString(key + KEY_GUID, "");
|
||||
if (!string.IsNullOrEmpty(guidString))
|
||||
{
|
||||
nodeGuid = new Guid(guidString);
|
||||
}
|
||||
else
|
||||
{
|
||||
nodeGuid = new Guid();
|
||||
}
|
||||
channel = EditorPrefs.GetInt(key + KEY_CHANNEL, 0);
|
||||
}
|
||||
|
||||
public void Save(string key)
|
||||
{
|
||||
EditorPrefs.SetFloat(key + KEY_POSITION_X, position.x);
|
||||
EditorPrefs.SetFloat(key + KEY_POSITION_Y, position.y);
|
||||
EditorPrefs.SetFloat(key + KEY_SIZE_X, size.x);
|
||||
EditorPrefs.SetFloat(key + KEY_SIZE_Y, size.y);
|
||||
EditorPrefs.SetFloat(key + KEY_TILING_X, imageTiling.x);
|
||||
EditorPrefs.SetFloat(key + KEY_TILING_Y, imageTiling.y);
|
||||
EditorPrefs.SetFloat(key + KEY_OFFSET_X, imageOffset.x);
|
||||
EditorPrefs.SetFloat(key + KEY_OFFSET_Y, imageOffset.y);
|
||||
EditorPrefs.SetString(key + KEY_GUID, nodeGuid.ToString());
|
||||
EditorPrefs.SetInt(key + KEY_CHANNEL, channel);
|
||||
}
|
||||
}
|
||||
|
||||
private static Material imageMaterial;
|
||||
private static Material ImageMaterial
|
||||
{
|
||||
get
|
||||
{
|
||||
if (imageMaterial == null)
|
||||
{
|
||||
imageMaterial = new Material(Shader.Find("Hidden/TextureGraph/View2DImage"));
|
||||
}
|
||||
return imageMaterial;
|
||||
}
|
||||
}
|
||||
|
||||
private static readonly int TILING = Shader.PropertyToID("_Tiling");
|
||||
private static readonly int OFFSET = Shader.PropertyToID("_Offset");
|
||||
private static readonly int RRR = Shader.PropertyToID("_RRR");
|
||||
private static readonly int CHANNEL = Shader.PropertyToID("_Channel");
|
||||
|
||||
public TViewData viewData;
|
||||
|
||||
private VisualElement headerToolbar;
|
||||
private Button rgbButton;
|
||||
private Button rButton;
|
||||
private Button gButton;
|
||||
private Button bButton;
|
||||
private Button aButton;
|
||||
|
||||
public TView2DWindow(string viewKey) : base(viewKey)
|
||||
{
|
||||
this.viewDataKey = viewKey;
|
||||
viewData.Load(viewKey);
|
||||
|
||||
styleSheets.Add(Resources.Load<StyleSheet>("TextureGraph/USS/View2DWindow"));
|
||||
|
||||
headerToolbar = new VisualElement() { name = "headerToolbar" };
|
||||
topContainer.Add(headerToolbar);
|
||||
rgbButton = new Button() { name = "rgbButton", text = "RGB" };
|
||||
rgbButton.clicked += () => { SetActiveChannel(0); };
|
||||
|
||||
rButton = new Button() { name = "rButton", text = "R" };
|
||||
rButton.clicked += () => { SetActiveChannel(1); };
|
||||
|
||||
gButton = new Button() { name = "gButton", text = "G" };
|
||||
gButton.clicked += () => { SetActiveChannel(2); };
|
||||
|
||||
bButton = new Button() { name = "bButton", text = "B" };
|
||||
bButton.clicked += () => { SetActiveChannel(3); };
|
||||
|
||||
aButton = new Button() { name = "aButton", text = "A" };
|
||||
aButton.clicked += () => { SetActiveChannel(4); };
|
||||
|
||||
headerToolbar.Add(rgbButton);
|
||||
headerToolbar.Add(rButton);
|
||||
headerToolbar.Add(gButton);
|
||||
headerToolbar.Add(bButton);
|
||||
headerToolbar.Add(aButton);
|
||||
|
||||
IMGUIContainer img = new IMGUIContainer() { name = "image" };
|
||||
img.AddManipulator(new TScrollable(OnImageScroll));
|
||||
img.AddManipulator(new TDraggable(OnImageDrag));
|
||||
this.AddManipulator(new ContextualMenuManipulator(BuildContextualMenu));
|
||||
bodyContainer.Add(img);
|
||||
|
||||
SetTitle("2D View");
|
||||
}
|
||||
|
||||
public override void Show()
|
||||
{
|
||||
style.display = new StyleEnum<DisplayStyle>(DisplayStyle.Flex);
|
||||
SetPosition(viewData.position);
|
||||
SetSize(viewData.size);
|
||||
EnableWindowDragging((v) => { viewData.position = v; });
|
||||
EnableWindowResizing(Vector2.one * 100, Vector2.one * 1000, OnResize);
|
||||
SetActiveChannel(viewData.channel);
|
||||
MarkDirtyRepaint();
|
||||
}
|
||||
|
||||
public override void Hide()
|
||||
{
|
||||
style.display = new StyleEnum<DisplayStyle>(DisplayStyle.None);
|
||||
DisableWindowDragging();
|
||||
DisableWindowResizing();
|
||||
viewData.Save(viewDataKey);
|
||||
}
|
||||
|
||||
public override void OnEnable()
|
||||
{
|
||||
viewData.Load(viewDataKey);
|
||||
}
|
||||
|
||||
public override void OnDisable()
|
||||
{
|
||||
viewData.Save(viewDataKey);
|
||||
Dispose();
|
||||
}
|
||||
|
||||
public override void OnDestroy()
|
||||
{
|
||||
viewData.Save(viewDataKey);
|
||||
Dispose();
|
||||
}
|
||||
|
||||
public void SetImage(Texture tex)
|
||||
{
|
||||
IMGUIContainer img = bodyContainer.Q<IMGUIContainer>("image");
|
||||
img.onGUIHandler = () =>
|
||||
{
|
||||
Rect r = new Rect(0, 0, img.layout.width, img.layout.height);
|
||||
if (tex == null)
|
||||
{
|
||||
EditorGUI.DrawRect(r, Color.black);
|
||||
EditorGUI.LabelField(r, "No preview available.", TEditorCommon.CenteredWhiteLabel);
|
||||
}
|
||||
else
|
||||
{
|
||||
ImageMaterial.SetVector(TILING, viewData.imageTiling);
|
||||
ImageMaterial.SetVector(OFFSET, viewData.imageOffset);
|
||||
if (TUtilities.IsGrayscaleFormat(tex.graphicsFormat))
|
||||
{
|
||||
ImageMaterial.SetFloat(RRR, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
ImageMaterial.SetFloat(RRR, 0);
|
||||
}
|
||||
ImageMaterial.SetFloat(CHANNEL, viewData.channel);
|
||||
|
||||
EditorGUI.DrawPreviewTexture(r, tex, ImageMaterial, ScaleMode.ScaleAndCrop);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private void OnImageScroll(Vector2 delta)
|
||||
{
|
||||
viewData.imageTiling -= Vector2.one * delta.y * 0.005f;
|
||||
viewData.imageTiling.x = Mathf.Max(0.01f, viewData.imageTiling.x);
|
||||
viewData.imageTiling.y = Mathf.Max(0.01f, viewData.imageTiling.y);
|
||||
}
|
||||
|
||||
private void OnImageDrag(TDraggable.TDragInfo drag)
|
||||
{
|
||||
float fx = drag.delta.x / layout.width;
|
||||
float fy = drag.delta.y / layout.height;
|
||||
float ox = -fx / viewData.imageTiling.x;
|
||||
float oy = fy / viewData.imageTiling.y;
|
||||
|
||||
viewData.imageOffset += new Vector2(ox, oy);
|
||||
this.MarkDirtyRepaint();
|
||||
}
|
||||
|
||||
private void BuildContextualMenu(ContextualMenuPopulateEvent evt)
|
||||
{
|
||||
evt.menu.AppendAction(
|
||||
"Reset View",
|
||||
(a) =>
|
||||
{
|
||||
ResetView();
|
||||
});
|
||||
}
|
||||
|
||||
public void ResetView()
|
||||
{
|
||||
viewData.imageTiling = Vector2.one;
|
||||
viewData.imageOffset = Vector2.zero;
|
||||
SetActiveChannel(0);
|
||||
MarkDirtyRepaint();
|
||||
}
|
||||
|
||||
private void OnResize(Vector2 s)
|
||||
{
|
||||
viewData.size = s;
|
||||
|
||||
if (s.x < 210)
|
||||
{
|
||||
headerToolbar.style.display = new StyleEnum<DisplayStyle>(DisplayStyle.None);
|
||||
}
|
||||
else
|
||||
{
|
||||
headerToolbar.style.display = new StyleEnum<DisplayStyle>(DisplayStyle.Flex);
|
||||
}
|
||||
}
|
||||
|
||||
private void SetActiveChannel(int channel)
|
||||
{
|
||||
viewData.channel = channel;
|
||||
const string CLASS_ACTIVE = "active-button";
|
||||
if (channel == 0)
|
||||
{
|
||||
rgbButton.AddToClassList(CLASS_ACTIVE);
|
||||
rButton.RemoveFromClassList(CLASS_ACTIVE);
|
||||
gButton.RemoveFromClassList(CLASS_ACTIVE);
|
||||
bButton.RemoveFromClassList(CLASS_ACTIVE);
|
||||
aButton.RemoveFromClassList(CLASS_ACTIVE);
|
||||
}
|
||||
else if (channel == 1)
|
||||
{
|
||||
rgbButton.RemoveFromClassList(CLASS_ACTIVE);
|
||||
rButton.AddToClassList(CLASS_ACTIVE);
|
||||
gButton.RemoveFromClassList(CLASS_ACTIVE);
|
||||
bButton.RemoveFromClassList(CLASS_ACTIVE);
|
||||
aButton.RemoveFromClassList(CLASS_ACTIVE);
|
||||
}
|
||||
else if (channel == 2)
|
||||
{
|
||||
rgbButton.RemoveFromClassList(CLASS_ACTIVE);
|
||||
rButton.RemoveFromClassList(CLASS_ACTIVE);
|
||||
gButton.AddToClassList(CLASS_ACTIVE);
|
||||
bButton.RemoveFromClassList(CLASS_ACTIVE);
|
||||
aButton.RemoveFromClassList(CLASS_ACTIVE);
|
||||
}
|
||||
else if (channel == 3)
|
||||
{
|
||||
rgbButton.RemoveFromClassList(CLASS_ACTIVE);
|
||||
rButton.RemoveFromClassList(CLASS_ACTIVE);
|
||||
gButton.RemoveFromClassList(CLASS_ACTIVE);
|
||||
bButton.AddToClassList(CLASS_ACTIVE);
|
||||
aButton.RemoveFromClassList(CLASS_ACTIVE);
|
||||
}
|
||||
else if (channel == 4)
|
||||
{
|
||||
rgbButton.RemoveFromClassList(CLASS_ACTIVE);
|
||||
rButton.RemoveFromClassList(CLASS_ACTIVE);
|
||||
gButton.RemoveFromClassList(CLASS_ACTIVE);
|
||||
bButton.RemoveFromClassList(CLASS_ACTIVE);
|
||||
aButton.AddToClassList(CLASS_ACTIVE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 637c1d830b628ad46a49a19560704fc6
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,284 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Pinwheel.TextureGraph;
|
||||
using UnityEditor;
|
||||
using UnityEngine.UIElements;
|
||||
using UnityEditor.UIElements;
|
||||
using System;
|
||||
using UnityEngine.Rendering;
|
||||
|
||||
namespace Pinwheel.TextureGraph
|
||||
{
|
||||
public class TView3DWindow : TSubWindow, ITManagedView
|
||||
{
|
||||
public struct TViewData
|
||||
{
|
||||
public const string KEY_POSITION_X = "position-x";
|
||||
public const string KEY_POSITION_Y = "position-y";
|
||||
public const string KEY_SIZE_X = "size-x";
|
||||
public const string KEY_SIZE_Y = "size-y";
|
||||
|
||||
public static readonly Vector2 MIN_SIZE = new Vector2(200, 200);
|
||||
public static readonly Vector2 MAX_SIZE = new Vector2(1000, 1000);
|
||||
|
||||
public static readonly float CAMERA_MIN_DISTANCE = 0.1f;
|
||||
public static readonly float CAMERA_MAX_DISTANCE = 10;
|
||||
|
||||
public Vector2 position;
|
||||
public Vector2 size;
|
||||
|
||||
public void Load(string key)
|
||||
{
|
||||
position = new Vector2(EditorPrefs.GetFloat(key + KEY_POSITION_X, 0), EditorPrefs.GetFloat(key + KEY_POSITION_Y, 0));
|
||||
size = new Vector2(EditorPrefs.GetFloat(key + KEY_SIZE_X, 200), EditorPrefs.GetFloat(key + KEY_SIZE_Y, 200));
|
||||
}
|
||||
|
||||
public void Save(string key)
|
||||
{
|
||||
EditorPrefs.SetFloat(key + KEY_POSITION_X, position.x);
|
||||
EditorPrefs.SetFloat(key + KEY_POSITION_Y, position.y);
|
||||
EditorPrefs.SetFloat(key + KEY_SIZE_X, size.x);
|
||||
EditorPrefs.SetFloat(key + KEY_SIZE_Y, size.y);
|
||||
}
|
||||
}
|
||||
|
||||
private static Material imageMaterial;
|
||||
private static Material ImageMaterial
|
||||
{
|
||||
get
|
||||
{
|
||||
if (imageMaterial == null)
|
||||
{
|
||||
imageMaterial = new Material(Shader.Find("Hidden/TextureGraph/View3DImage"));
|
||||
}
|
||||
return imageMaterial;
|
||||
}
|
||||
}
|
||||
|
||||
public TViewData viewData;
|
||||
public TPreviewSceneData previewSceneData;
|
||||
|
||||
public IMGUIContainer image;
|
||||
|
||||
public TView3DWindow(string viewKey) : base(viewKey)
|
||||
{
|
||||
this.viewDataKey = viewKey;
|
||||
viewData.Load(viewKey);
|
||||
|
||||
styleSheets.Add(Resources.Load<StyleSheet>("TextureGraph/USS/View3DWindow"));
|
||||
image = new IMGUIContainer() { name = "image" };
|
||||
image.onGUIHandler = HandleDisplayImage;
|
||||
image.AddManipulator(new TScrollable(OnImageScroll));
|
||||
image.AddManipulator(new TDraggable(OnImageDrag));
|
||||
this.AddManipulator(new ContextualMenuManipulator(BuildContextualMenu));
|
||||
bodyContainer.Add(image);
|
||||
|
||||
image.RegisterCallback<DragUpdatedEvent>(OnDragUpdated);
|
||||
image.RegisterCallback<DragPerformEvent>(OnDragPerform);
|
||||
|
||||
SetTitle("3D View");
|
||||
}
|
||||
|
||||
public override void Show()
|
||||
{
|
||||
style.display = new StyleEnum<DisplayStyle>(DisplayStyle.Flex);
|
||||
SetPosition(viewData.position);
|
||||
SetSize(viewData.size);
|
||||
EnableWindowDragging((v) => { viewData.position = v; });
|
||||
EnableWindowResizing(TViewData.MIN_SIZE, TViewData.MAX_SIZE, OnResize);
|
||||
MarkDirtyRepaint();
|
||||
|
||||
previewSceneData = new TPreviewSceneData();
|
||||
RenderPreviewScene();
|
||||
MarkDirtyRepaint();
|
||||
}
|
||||
|
||||
public override void Hide()
|
||||
{
|
||||
style.display = new StyleEnum<DisplayStyle>(DisplayStyle.None);
|
||||
DisableWindowDragging();
|
||||
DisableWindowResizing();
|
||||
Dispose();
|
||||
viewData.Save(viewDataKey);
|
||||
}
|
||||
|
||||
public override void OnEnable()
|
||||
{
|
||||
viewData.Load(viewDataKey);
|
||||
}
|
||||
|
||||
public override void OnDisable()
|
||||
{
|
||||
viewData.Save(viewDataKey);
|
||||
OnDisable();
|
||||
}
|
||||
|
||||
public override void OnDestroy()
|
||||
{
|
||||
viewData.Save(viewDataKey);
|
||||
Dispose();
|
||||
}
|
||||
|
||||
private void OnResize(Vector2 s)
|
||||
{
|
||||
viewData.size = s;
|
||||
RenderPreviewScene();
|
||||
}
|
||||
|
||||
public void RenderPreviewScene()
|
||||
{
|
||||
if (previewSceneData == null)
|
||||
return;
|
||||
|
||||
int width = (int)Mathf.Max(TViewData.MIN_SIZE.x, image.layout.width) * 2;
|
||||
int height = (int)Mathf.Max(TViewData.MIN_SIZE.y, image.layout.height) * 2;
|
||||
if (width <= 0 || height <= 0)
|
||||
return;
|
||||
|
||||
previewSceneData.PrepareScene();
|
||||
try
|
||||
{
|
||||
previewSceneData.PrepareRenderTarget(width, height);
|
||||
|
||||
Camera cam = previewSceneData.Camera;
|
||||
cam.renderingPath = RenderingPath.Forward;
|
||||
cam.targetTexture = previewSceneData.RenderTarget;
|
||||
TView3DEnvironmentSettings envSettings = GraphEditor.ClonedGraph.View3DEnvironmentSettings;
|
||||
cam.transform.position = envSettings.GetCameraPosition();
|
||||
cam.transform.rotation = envSettings.GetCameraRotation();
|
||||
cam.transform.localScale = Vector3.one;
|
||||
|
||||
Mesh mesh = envSettings.GetMesh();
|
||||
Material mat = previewSceneData.Material;
|
||||
envSettings.Setup(mat, GraphEditor.ClonedGraph);
|
||||
|
||||
Matrix4x4 trs = Matrix4x4.identity;
|
||||
Graphics.DrawMesh(mesh, trs, mat, 1, cam, 0, null, ShadowCastingMode.Off, false, null, false);
|
||||
cam.Render();
|
||||
MarkDirtyRepaint();
|
||||
}
|
||||
catch { }
|
||||
previewSceneData.CloseScene();
|
||||
}
|
||||
|
||||
public override void Dispose()
|
||||
{
|
||||
if (previewSceneData != null)
|
||||
{
|
||||
previewSceneData.Dispose();
|
||||
}
|
||||
}
|
||||
|
||||
private void OnImageScroll(Vector2 delta)
|
||||
{
|
||||
if (previewSceneData == null)
|
||||
return;
|
||||
TView3DEnvironmentSettings envSettings = GraphEditor.ClonedGraph.View3DEnvironmentSettings;
|
||||
float d = envSettings.GetCameraDistance();
|
||||
d += delta.y * 0.05f;
|
||||
d = Mathf.Clamp(d, TViewData.CAMERA_MIN_DISTANCE, TViewData.CAMERA_MAX_DISTANCE);
|
||||
envSettings.SetCameraDistance(d);
|
||||
RenderPreviewScene();
|
||||
}
|
||||
|
||||
private void HandleDisplayImage()
|
||||
{
|
||||
if (previewSceneData == null || previewSceneData.RenderTarget == null || !previewSceneData.RenderTarget.IsCreated())
|
||||
{
|
||||
RenderPreviewScene();
|
||||
}
|
||||
|
||||
Rect r = new Rect(0, 0, image.layout.width, image.layout.height);
|
||||
if (previewSceneData == null || previewSceneData.RenderTarget == null || !previewSceneData.RenderTarget.IsCreated())
|
||||
{
|
||||
EditorGUI.DrawRect(r, Color.black);
|
||||
EditorGUI.LabelField(r, "No preview available.", TEditorCommon.CenteredWhiteLabel);
|
||||
}
|
||||
else
|
||||
{
|
||||
Texture tex = previewSceneData.RenderTarget;
|
||||
EditorGUI.DrawPreviewTexture(r, tex, ImageMaterial, ScaleMode.ScaleAndCrop);
|
||||
}
|
||||
}
|
||||
|
||||
private void OnImageDrag(TDraggable.TDragInfo drag)
|
||||
{
|
||||
if (previewSceneData == null)
|
||||
return;
|
||||
TView3DEnvironmentSettings envSettings = GraphEditor.ClonedGraph.View3DEnvironmentSettings;
|
||||
float d = envSettings.GetCameraDistance();
|
||||
float fd = Mathf.InverseLerp(TViewData.CAMERA_MIN_DISTANCE, TViewData.CAMERA_MAX_DISTANCE, d);
|
||||
float speed = 0.15f;
|
||||
Vector2 offset = new Vector2(-drag.delta.x, drag.delta.y) * speed;
|
||||
|
||||
if (drag.isShift)
|
||||
{
|
||||
envSettings.RotateLight(offset);
|
||||
}
|
||||
else
|
||||
{
|
||||
envSettings.RotateCamera(offset);
|
||||
}
|
||||
RenderPreviewScene();
|
||||
}
|
||||
|
||||
private void BuildContextualMenu(ContextualMenuPopulateEvent e)
|
||||
{
|
||||
e.menu.AppendAction(
|
||||
"Reset View",
|
||||
(a) =>
|
||||
{
|
||||
ResetEnvironmentView();
|
||||
});
|
||||
|
||||
foreach (string n in Enum.GetNames(typeof(TPremitives.TMeshType)))
|
||||
{
|
||||
TPremitives.TMeshType meshType;
|
||||
if (Enum.TryParse<TPremitives.TMeshType>(n, out meshType))
|
||||
{
|
||||
e.menu.AppendAction(
|
||||
"Mesh/" + n,
|
||||
(a) =>
|
||||
{
|
||||
GraphEditor.ClonedGraph.View3DEnvironmentSettings.MeshType = meshType;
|
||||
RenderPreviewScene();
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ResetEnvironmentView()
|
||||
{
|
||||
GraphEditor.ClonedGraph.View3DEnvironmentSettings = new TView3DEnvironmentSettings();
|
||||
RenderPreviewScene();
|
||||
}
|
||||
|
||||
private void OnDragUpdated(DragUpdatedEvent e)
|
||||
{
|
||||
UnityEngine.Object[] dragged = DragAndDrop.objectReferences;
|
||||
if (dragged.Length > 1)
|
||||
{
|
||||
DragAndDrop.visualMode = DragAndDropVisualMode.Rejected;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dragged[0] is Mesh m)
|
||||
{
|
||||
DragAndDrop.visualMode = DragAndDropVisualMode.Link;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void OnDragPerform(DragPerformEvent e)
|
||||
{
|
||||
UnityEngine.Object[] dragged = DragAndDrop.objectReferences;
|
||||
if (dragged.Length == 1 && dragged[0] is Mesh m)
|
||||
{
|
||||
GraphEditor.ClonedGraph.View3DEnvironmentSettings.MeshType = TPremitives.TMeshType.Custom;
|
||||
GraphEditor.ClonedGraph.View3DEnvironmentSettings.CustomMesh = m;
|
||||
RenderPreviewScene();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c1fd148a96427c34394407b96c684a17
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,43 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine.UIElements;
|
||||
using UnityEditor.UIElements;
|
||||
using UnityEditor;
|
||||
|
||||
namespace Pinwheel.TextureGraph
|
||||
{
|
||||
public static class TViewManager
|
||||
{
|
||||
public const string KEY_VISIBLE = "visible";
|
||||
|
||||
public static bool IsViewVisible(string key)
|
||||
{
|
||||
return EditorPrefs.GetBool(key + KEY_VISIBLE, false);
|
||||
}
|
||||
|
||||
public static void ToggleViewVisibility(ITManagedView view, string key)
|
||||
{
|
||||
if (IsViewVisible(key))
|
||||
{
|
||||
HideView(view, key);
|
||||
}
|
||||
else
|
||||
{
|
||||
ShowView(view, key);
|
||||
}
|
||||
}
|
||||
|
||||
public static void ShowView(ITManagedView view, string key)
|
||||
{
|
||||
view.Show();
|
||||
EditorPrefs.SetBool(key + KEY_VISIBLE, true);
|
||||
}
|
||||
|
||||
public static void HideView(ITManagedView view, string key)
|
||||
{
|
||||
view.Hide();
|
||||
EditorPrefs.SetBool(key + KEY_VISIBLE, false);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b2c7a7ac89bdd444c984769cbc02d7dc
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,100 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using UnityEngine.UIElements;
|
||||
using System;
|
||||
|
||||
namespace Pinwheel.TextureGraph
|
||||
{
|
||||
public class TWindowDragZone : MouseManipulator
|
||||
{
|
||||
public VisualElement Window { get; set; }
|
||||
public VisualElement WindowParent { get; set; }
|
||||
private bool IsDragging { get; set; }
|
||||
|
||||
public Action<Vector2> OnPositionChanged;
|
||||
|
||||
public TWindowDragZone(VisualElement window, VisualElement windowParent)
|
||||
{
|
||||
Window = window;
|
||||
WindowParent = windowParent;
|
||||
}
|
||||
|
||||
protected override void RegisterCallbacksOnTarget()
|
||||
{
|
||||
target.RegisterCallback<MouseDownEvent>(OnMouseDown, TrickleDown.NoTrickleDown);
|
||||
target.RegisterCallback<MouseMoveEvent>(OnMouseMove, TrickleDown.NoTrickleDown);
|
||||
target.RegisterCallback<MouseUpEvent>(OnMouseUp, TrickleDown.NoTrickleDown);
|
||||
WindowParent.RegisterCallback<GeometryChangedEvent>(OnGeometryChanged, TrickleDown.NoTrickleDown);
|
||||
}
|
||||
|
||||
protected override void UnregisterCallbacksFromTarget()
|
||||
{
|
||||
target.UnregisterCallback<MouseDownEvent>(OnMouseDown, TrickleDown.NoTrickleDown);
|
||||
target.UnregisterCallback<MouseMoveEvent>(OnMouseMove, TrickleDown.NoTrickleDown);
|
||||
target.UnregisterCallback<MouseUpEvent>(OnMouseUp, TrickleDown.NoTrickleDown);
|
||||
WindowParent.RegisterCallback<GeometryChangedEvent>(OnGeometryChanged, TrickleDown.NoTrickleDown);
|
||||
}
|
||||
|
||||
private void OnMouseDown(MouseDownEvent e)
|
||||
{
|
||||
target.CaptureMouse();
|
||||
if (e.button == 0)
|
||||
{
|
||||
IsDragging = true;
|
||||
Window.BringToFront();
|
||||
}
|
||||
e.StopPropagation();
|
||||
}
|
||||
|
||||
private void OnMouseMove(MouseMoveEvent e)
|
||||
{
|
||||
if (!IsDragging)
|
||||
return;
|
||||
Vector2 delta = e.mouseDelta;
|
||||
MoveAndClampPosition(delta);
|
||||
Window.BringToFront();
|
||||
}
|
||||
|
||||
private void OnMouseUp(MouseUpEvent e)
|
||||
{
|
||||
if (target.HasMouseCapture())
|
||||
{
|
||||
target.ReleaseMouse();
|
||||
}
|
||||
IsDragging = false;
|
||||
e.StopPropagation();
|
||||
}
|
||||
|
||||
private void MoveAndClampPosition(Vector2 delta)
|
||||
{
|
||||
float left = Window.style.left.value.value + delta.x;
|
||||
float top = Window.style.top.value.value + delta.y;
|
||||
float right = float.NaN;
|
||||
float bottom = float.NaN;
|
||||
|
||||
float minLeft = 0;
|
||||
float maxLeft = Window.parent.layout.width - Window.layout.width;
|
||||
float minTop = 0;
|
||||
float maxTop = Window.parent.layout.height - Window.layout.height;
|
||||
|
||||
left = Mathf.Clamp(left, minLeft, maxLeft);
|
||||
top = Mathf.Clamp(top, minTop, maxTop);
|
||||
|
||||
Window.style.left = new StyleLength(left);
|
||||
Window.style.top = new StyleLength(top);
|
||||
Window.style.right = new StyleLength(right);
|
||||
Window.style.bottom = new StyleLength(bottom);
|
||||
|
||||
if (OnPositionChanged != null)
|
||||
{
|
||||
OnPositionChanged.Invoke(new Vector2(left, top));
|
||||
}
|
||||
}
|
||||
|
||||
private void OnGeometryChanged(GeometryChangedEvent e)
|
||||
{
|
||||
MoveAndClampPosition(Vector2.zero);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b47622315cf063f45a4c68c368f0484c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 79c4f575f2375df46b9853b99c3f7abf
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,15 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Pinwheel.TextureGraph;
|
||||
|
||||
namespace Pinwheel.TextureGraph
|
||||
{
|
||||
[TCustomParametersDrawer(typeof(TAlphaMergeNode))]
|
||||
public class TAlphaMergeNodeParamsDrawer : TParametersDrawer
|
||||
{
|
||||
public override void DrawGUI(TAbstractTextureNode target)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 12473da5a096f3b46b3e0a6ae2b9136f
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,15 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Pinwheel.TextureGraph;
|
||||
|
||||
namespace Pinwheel.TextureGraph
|
||||
{
|
||||
[TCustomParametersDrawer(typeof(TAlphaSplitNode))]
|
||||
public class TAlphaSplitNodeParamsDrawer : TParametersDrawer
|
||||
{
|
||||
public override void DrawGUI(TAbstractTextureNode target)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6f4d07c791b8c3b4b9a25a856033d31e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,24 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Pinwheel.TextureGraph;
|
||||
using UnityEditor;
|
||||
|
||||
namespace Pinwheel.TextureGraph
|
||||
{
|
||||
[TCustomParametersDrawer(typeof(TBillowNoiseNode))]
|
||||
public class TBillowNoiseNodeParamsDrawer : TParametersDrawer
|
||||
{
|
||||
private static readonly GUIContent scaleGUI = new GUIContent("Scale", "Scale/Density of the noise map");
|
||||
private static readonly GUIContent seedGUI = new GUIContent("Seed", "Value to randomize the noise");
|
||||
private static readonly GUIContent variantGUI = new GUIContent("Variant", "Create a slightly different noise");
|
||||
|
||||
public override void DrawGUI(TAbstractTextureNode target)
|
||||
{
|
||||
TBillowNoiseNode n = target as TBillowNoiseNode;
|
||||
n.Scale = TParamGUI.IntField(scaleGUI, n.Scale);
|
||||
n.Seed = TParamGUI.IntField(seedGUI, n.Seed);
|
||||
n.Variant = TParamGUI.FloatSlider(variantGUI, n.Variant, 0f, 1f);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4081a53eff6c1db4390ca5b0c714cf86
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,24 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Pinwheel.TextureGraph;
|
||||
using UnityEditor;
|
||||
|
||||
namespace Pinwheel.TextureGraph
|
||||
{
|
||||
[TCustomParametersDrawer(typeof(TBlendNode))]
|
||||
public class TBlendNodeParamsDrawer : TParametersDrawer
|
||||
{
|
||||
private static readonly GUIContent blendModeGUI = new GUIContent("Blend Mode", "Blend function to apply to RGB channels");
|
||||
private static readonly GUIContent alphaBlendModeGUI = new GUIContent("Alpha Blend Mode", "Blend function to apply to A channel");
|
||||
private static readonly GUIContent opacityGUI = new GUIContent("Opacity", "Strength of the blend operation. This will be used to interpolate between the background and the blend result.");
|
||||
|
||||
public override void DrawGUI(TAbstractTextureNode target)
|
||||
{
|
||||
TBlendNode n = target as TBlendNode;
|
||||
n.ColorBlendMode.value = (TBlendNode.TBlendMode)EditorGUILayout.EnumPopup(blendModeGUI, n.ColorBlendMode.value);
|
||||
n.AlphaBlendMode.value = (TBlendNode.TAlphaBlendMode)EditorGUILayout.EnumPopup(alphaBlendModeGUI, n.AlphaBlendMode.value);
|
||||
n.Opacity = TParamGUI.FloatSlider(opacityGUI, n.Opacity, 0f, 1f);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e4482f81cb8eefd4eaafb230fc94bd12
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,34 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Pinwheel.TextureGraph;
|
||||
using UnityEngine.Rendering;
|
||||
using UnityEditor;
|
||||
|
||||
namespace Pinwheel.TextureGraph
|
||||
{
|
||||
[TCustomParametersDrawer(typeof(TBlendSrcDstNode))]
|
||||
public class TBlendSrcDstNodeParamsDrawer : TParametersDrawer
|
||||
{
|
||||
private static readonly GUIContent srcColorGUI = new GUIContent("Source Color", "Blend factor for foreground color");
|
||||
private static readonly GUIContent dstColorGUI = new GUIContent("Dest. Color", "Blend factor for background color");
|
||||
private static readonly GUIContent srcAlphaGUI = new GUIContent("Source Alpha", "Blend factor for foreground alpha");
|
||||
private static readonly GUIContent dstAlphaGUI = new GUIContent("Dest. Alpha", "Blend factor for background alpha");
|
||||
private static readonly GUIContent opsGUI = new GUIContent("Color Ops", "Blend operation for color");
|
||||
private static readonly GUIContent opsAlphaGUI = new GUIContent("Alpha Ops", "Blend operation for alpha");
|
||||
|
||||
public override void DrawGUI(TAbstractTextureNode target)
|
||||
{
|
||||
TBlendSrcDstNode n = target as TBlendSrcDstNode;
|
||||
TEditorCommon.Header("Color");
|
||||
n.SrcColor.value = (BlendMode)EditorGUILayout.EnumPopup(srcColorGUI, n.SrcColor.value);
|
||||
n.DstColor.value = (BlendMode)EditorGUILayout.EnumPopup(dstColorGUI, n.DstColor.value);
|
||||
n.ColorOps.value = (BlendOp)EditorGUILayout.EnumPopup(opsGUI, n.ColorOps.value);
|
||||
|
||||
TEditorCommon.Header("Alpha");
|
||||
n.SrcAlpha.value = (BlendMode)EditorGUILayout.EnumPopup(srcAlphaGUI, n.SrcAlpha.value);
|
||||
n.DstAlpha.value = (BlendMode)EditorGUILayout.EnumPopup(dstAlphaGUI, n.DstAlpha.value);
|
||||
n.AlphaOps.value = (BlendOp)EditorGUILayout.EnumPopup(opsAlphaGUI, n.AlphaOps.value);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 95cb7d5d2d63c5c4a9fd29e77eaef6e5
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,20 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Pinwheel.TextureGraph;
|
||||
using UnityEditor;
|
||||
|
||||
namespace Pinwheel.TextureGraph
|
||||
{
|
||||
[TCustomParametersDrawer(typeof(TBlurNode))]
|
||||
public class TBlurNodeParamsDrawer : TParametersDrawer
|
||||
{
|
||||
private static readonly GUIContent radiusGUI = new GUIContent("Radius", "Radius of the blur");
|
||||
|
||||
public override void DrawGUI(TAbstractTextureNode target)
|
||||
{
|
||||
TBlurNode n = target as TBlurNode;
|
||||
n.Radius = TParamGUI.IntSlider(radiusGUI, n.Radius, 0, 100);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7318bd70343795140969b4688112ea81
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,23 @@
|
||||
using UnityEngine;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using Pinwheel.TextureGraph;
|
||||
|
||||
namespace Pinwheel.TextureGraph
|
||||
{
|
||||
[TCustomParametersDrawer(typeof(TBrickNode))]
|
||||
public class TBrickNodeParamsDrawer : TParametersDrawer
|
||||
{
|
||||
private static readonly GUIContent tilingGUI = new GUIContent("Tiling", "Tile the pattern multiple times");
|
||||
private static readonly GUIContent gapSizeGUI = new GUIContent("Gap Size", "Size of the gap between blocks");
|
||||
private static readonly GUIContent innerSizeGUI = new GUIContent("Inner Size", "Size of the inner part of each block, to make the feel of extrusion");
|
||||
|
||||
public override void DrawGUI(TAbstractTextureNode target)
|
||||
{
|
||||
TBrickNode n = target as TBrickNode;
|
||||
n.Tiling = TParamGUI.IntField(tilingGUI, n.Tiling);
|
||||
n.GapSize = TParamGUI.FloatSlider(gapSizeGUI, n.GapSize, 0f, 1f);
|
||||
n.InnerSize = TParamGUI.FloatSlider(innerSizeGUI, n.InnerSize, 0f, 1f);
|
||||
}
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user