浏览代码

[shader graph] start porting to new graph framework.

/main
Tim Cooper 9 年前
当前提交
834fc657
共有 34 个文件被更改,包括 3775 次插入142 次删除
  1. 8
      UnityProject/Assets/UnityShaderEditor/Editor/Source/BaseMaterialGraphGUI.cs
  2. 2
      UnityProject/Assets/UnityShaderEditor/Editor/Source/MaterialGraphGUI.cs
  3. 3
      UnityProject/Assets/UnityShaderEditor/Editor/Source/MaterialSubGraphGUI.cs
  4. 2
      UnityProject/Assets/UnityShaderEditor/Graphs/FresnelSubGraph.ShaderSubGraph
  5. 2
      UnityProject/Assets/UnityShaderEditor/Graphs/SimpleGraph.ShaderGraph
  6. 9
      UnityProject/Assets/GraphFramework.meta
  7. 9
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Drawing.meta
  8. 9
      UnityProject/Assets/GraphFramework/Canvas2D.meta
  9. 9
      UnityProject/Assets/GraphFramework/Canvas2D/Editor.meta
  10. 1001
      UnityProject/Assets/GraphFramework/Canvas2D/Editor/Canvas2D.cs
  11. 12
      UnityProject/Assets/GraphFramework/Canvas2D/Editor/Canvas2D.cs.meta
  12. 602
      UnityProject/Assets/GraphFramework/Canvas2D/Editor/Graph.cs
  13. 12
      UnityProject/Assets/GraphFramework/Canvas2D/Editor/Graph.cs.meta
  14. 795
      UnityProject/Assets/GraphFramework/Canvas2D/Editor/Manipulators.cs
  15. 12
      UnityProject/Assets/GraphFramework/Canvas2D/Editor/Manipulators.cs.meta
  16. 481
      UnityProject/Assets/GraphFramework/Canvas2D/Editor/QuadTree.cs
  17. 12
      UnityProject/Assets/GraphFramework/Canvas2D/Editor/QuadTree.cs.meta
  18. 250
      UnityProject/Assets/GraphFramework/Canvas2D/Editor/UIHelpers.cs
  19. 12
      UnityProject/Assets/GraphFramework/Canvas2D/Editor/UIHelpers.cs.meta
  20. 9
      UnityProject/Assets/GraphFramework/Examples.meta
  21. 192
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Drawing/DrawableMaterialNode.cs
  22. 12
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Drawing/DrawableMaterialNode.cs.meta
  23. 37
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Drawing/MaterialGraphDataSource.cs
  24. 12
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Drawing/MaterialGraphDataSource.cs.meta
  25. 123
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Drawing/MaterialWindow.cs
  26. 12
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Drawing/MaterialWindow.cs.meta
  27. 132
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Drawing/SimpleWidgets.cs
  28. 12
      UnityProject/Assets/UnityShaderEditor/Editor/Source/Drawing/SimpleWidgets.cs.meta
  29. 126
      UnityProject/Assets/UnityShaderEditor/Editor/Source/MaterialWindow.cs
  30. 8
      UnityProject/Assets/UnityShaderEditor/Editor/Source/MaterialWindow.cs.meta

8
UnityProject/Assets/UnityShaderEditor/Editor/Source/BaseMaterialGraphGUI.cs


namespace UnityEditor.MaterialGraph
{
abstract class BaseMaterialGraphGUI : GraphGUI
abstract class BaseMaterialGraphGUI : EditorWindow
public override void OnGraphGUI()
/* public override void OnGraphGUI()
{
m_Host.BeginWindows();

}
}
}
*/
private class AddNodeCreationObject : object
{
public Vector2 m_Pos;

var node = (BaseMaterialNode)CreateInstance(posObj.m_Type);
node.Init();
node.position = new Rect(posObj.m_Pos.x, posObj.m_Pos.y, node.position.width, node.position.height);
graph.AddNode(node);
// graph.AddNode(node);
}
public virtual bool CanAddToNodeMenu(Type type) { return true; }

2
UnityProject/Assets/UnityShaderEditor/Editor/Source/MaterialGraphGUI.cs


options
}
private PixelGraph GetGraph() {return graph as PixelGraph; }
private PixelGraph GetGraph() {return null; }
public MaterialGraph materialGraph;
private SelectedOptions m_SelectedGUI = SelectedOptions.properties;

3
UnityProject/Assets/UnityShaderEditor/Editor/Source/MaterialSubGraphGUI.cs


namespace UnityEditor.MaterialGraph
{
/*
class MaterialSubGraphGUI : BaseMaterialGraphGUI
{
public override void NodeGUI(Node n)

DragNodes();
}
}
}*/
}

2
UnityProject/Assets/UnityShaderEditor/Graphs/FresnelSubGraph.ShaderSubGraph


m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: 4b00854e54a3ed940813fa47dec62d38, type: 3}
m_Name: Fresnel
m_Name: FresnelSubGraph
m_EditorClassIdentifier:
nodes:
- {fileID: 11400002}

2
UnityProject/Assets/UnityShaderEditor/Graphs/SimpleGraph.ShaderGraph


m_Enabled: 1
m_EditorHideFlags: 0
m_Script: {fileID: 11500000, guid: ef5b9f0785847b04983f907c7f016a36, type: 3}
m_Name: SImple
m_Name: SimpleGraph
m_EditorClassIdentifier:
m_MaterialProperties: {fileID: 11464382}
m_MaterialOptions: {fileID: 11415370}

9
UnityProject/Assets/GraphFramework.meta


fileFormatVersion: 2
guid: 8da2c542223390a47bf9ce62a39abff5
folderAsset: yes
timeCreated: 1445418016
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

9
UnityProject/Assets/UnityShaderEditor/Editor/Source/Drawing.meta


fileFormatVersion: 2
guid: 4f25b373dbd002b4ab7a964b2eb68494
folderAsset: yes
timeCreated: 1445419779
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

9
UnityProject/Assets/GraphFramework/Canvas2D.meta


fileFormatVersion: 2
guid: cc01a7f541cf1774e9e6991bdc84abde
folderAsset: yes
timeCreated: 1445092807
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

9
UnityProject/Assets/GraphFramework/Canvas2D/Editor.meta


fileFormatVersion: 2
guid: b90271493180a664c9362624ff106bf8
folderAsset: yes
timeCreated: 1445092807
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

1001
UnityProject/Assets/GraphFramework/Canvas2D/Editor/Canvas2D.cs
文件差异内容过多而无法显示
查看文件

12
UnityProject/Assets/GraphFramework/Canvas2D/Editor/Canvas2D.cs.meta


fileFormatVersion: 2
guid: bc982d0799f6fad408afa1498d3c2341
timeCreated: 1434119324
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

602
UnityProject/Assets/GraphFramework/Canvas2D/Editor/Graph.cs


using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.IO;
using System.Reflection;
using System.Runtime.CompilerServices;
using UnityEngine;
using UnityEditorInternal;
using Object = UnityEngine.Object;
//#pragma warning disable 0414
//#pragma warning disable 0219
namespace UnityEditor
{
namespace Experimental
{
namespace Graph
{
class TypeAdapter : Attribute
{
}
public enum Direction
{
eInput = 0,
eOutput = 1,
eBidirectional = 2
};
public interface IConnect
{
Direction GetDirection();
void Highlight(bool highlighted);
void RenderOverlay(Canvas2D canvas);
object Source();
Vector3 ConnectPosition();
void OnConnect(IConnect other);
};
public class NodeAdapter
{
private static List<MethodInfo> m_TypeAdapters = null;
private static Dictionary<int, System.Reflection.MethodInfo> m_NodeAdapterDictionary;
public bool CanAdapt(object a, object b)
{
if (a == b)
return false; // self connections are not permitted
if (a == null || b == null)
return false;
MethodInfo mi = GetAdapter(a, b);
if (mi == null)
{
Debug.Log("adapter node not found for: " + a.GetType().ToString() + " -> " + b.GetType().ToString());
}
return mi != null ? true : false;
}
public bool Connect(object a, object b)
{
MethodInfo mi = GetAdapter(a, b);
if (mi == null)
{
Debug.LogError("Attempt to connect 2 unadaptable types: " + a.GetType().ToString() + " -> " + b.GetType().ToString());
return false;
}
object retVal = mi.Invoke(this, new object[] { this, a, b });
return (bool)retVal;
}
IEnumerable<MethodInfo> GetExtensionMethods(Assembly assembly, Type extendedType)
{
var query = from type in assembly.GetTypes()
where type.IsSealed && !type.IsGenericType && !type.IsNested
from method in type.GetMethods(BindingFlags.Static
| BindingFlags.Public | BindingFlags.NonPublic)
where method.IsDefined(typeof(ExtensionAttribute), false)
where method.GetParameters()[0].ParameterType == extendedType
select method;
return query;
}
public MethodInfo GetAdapter(object a, object b)
{
if (a == null || b == null)
return null;
if (m_NodeAdapterDictionary == null)
{
m_NodeAdapterDictionary = new Dictionary<int, System.Reflection.MethodInfo>();
// add extension methods
AppDomain currentDomain = AppDomain.CurrentDomain;
foreach (System.Reflection.Assembly assembly in currentDomain.GetAssemblies())
{
foreach (MethodInfo method in GetExtensionMethods(assembly, typeof(NodeAdapter)))
{
System.Reflection.ParameterInfo[] methodParams = method.GetParameters();
if (methodParams.Count() == 3)
{
string pa = methodParams[1].ParameterType.ToString() + methodParams[2].ParameterType.ToString();
m_NodeAdapterDictionary.Add(pa.GetHashCode(), method);
}
}
}
}
string s = a.GetType().ToString() + b.GetType().ToString();
try
{
return m_NodeAdapterDictionary[s.GetHashCode()];
}
catch (Exception)
{
}
return null;
}
public MethodInfo GetTypeAdapter(Type from, Type to)
{
if (m_TypeAdapters == null)
{
m_TypeAdapters = new List<MethodInfo>();
AppDomain currentDomain = AppDomain.CurrentDomain;
foreach (System.Reflection.Assembly assembly in currentDomain.GetAssemblies())
{
try
{
foreach (Type temptype in assembly.GetTypes())
{
MethodInfo[] methodInfos = temptype.GetMethods(BindingFlags.Public | BindingFlags.Static);
foreach (MethodInfo i in methodInfos)
{
object[] allAttrs = i.GetCustomAttributes(typeof(TypeAdapter), false);
if (allAttrs.Count() > 0)
{
m_TypeAdapters.Add(i);
}
}
}
}
catch (Exception ex)
{
Debug.Log(ex);
}
}
}
foreach (MethodInfo i in m_TypeAdapters)
{
if (i.ReturnType == to)
{
ParameterInfo[] allParams = i.GetParameters();
if (allParams.Count() == 1)
{
if (allParams[0].ParameterType == from)
return i;
}
}
}
return null;
}
};
internal class EdgeConnector<T> : IManipulate where T : IConnect
{
private static Color s_EdgeColor = new Color(1.0f, 1.0f, 1.0f, 0.8f);
private static Color s_ActiveEdgeColor = new Color(0.2f, 0.4f, 1.0f, 0.8f);
private Vector2 m_Start = Vector2.zero;
private Vector2 m_End = Vector2.zero;
private Color m_Color = s_EdgeColor;
private IConnect m_SnappedTarget = null;
private IConnect m_SnappedSource = null;
List<IConnect> m_CompatibleAnchors = new List<IConnect>();
public EdgeConnector()
{
}
public bool GetCaps(ManipulatorCapability cap)
{
return false;
}
public void AttachTo(CanvasElement element)
{
element.MouseUp += EndDrag;
element.MouseDown += StartDrag;
element.MouseDrag += MouseDrag;
}
private bool StartDrag(CanvasElement element, Event e, Canvas2D canvas)
{
if (e.type == EventType.Used)
{
return false;
}
if (e.button != 0)
{
return false;
}
element.OnWidget += DrawEdge;
IConnect cnx = element as IConnect;
if (element.collapsed)
return false;
canvas.StartCapture(this, element);
m_Start = m_End = element.canvasBoundingRect.center;
e.Use();
if (cnx != null)
{
cnx.Highlight(true);
}
EndSnap();
// find compatible anchors
m_CompatibleAnchors.Clear();
Rect screenRect = new Rect();
screenRect.min = canvas.MouseToCanvas(new Vector2(0.0f, 0.0f));
screenRect.max = canvas.MouseToCanvas(new Vector2(Screen.width, Screen.height));
CanvasElement[] visibleAnchors = canvas.Pick<T>(screenRect);
NodeAdapter nodeAdapter = new NodeAdapter();
foreach (CanvasElement anchor in visibleAnchors)
{
IConnect toCnx = anchor as IConnect;
if (toCnx == null)
continue;
bool isBidirectional = ((cnx.GetDirection() == Direction.eBidirectional) ||
(toCnx.GetDirection() == Direction.eBidirectional));
if (cnx.GetDirection() != toCnx.GetDirection() || isBidirectional)
{
if (nodeAdapter.GetAdapter(cnx.Source(), toCnx.Source()) != null)
{
m_CompatibleAnchors.Add(toCnx);
}
}
}
canvas.OnOverlay += HighlightCompatibleAnchors;
return true;
}
private bool EndDrag(CanvasElement element, Event e, Canvas2D canvas)
{
if (e.type == EventType.Used)
return false;
if (!canvas.IsCaptured(this))
{
return false;
}
element.OnWidget -= DrawEdge;
canvas.EndCapture();
IConnect cnx = element as IConnect;
if (cnx != null)
{
cnx.Highlight(false);
}
if (m_SnappedSource == null && m_SnappedTarget == null)
{
cnx.OnConnect(null);
}
else if (m_SnappedSource != null && m_SnappedTarget != null)
{
NodeAdapter nodeAdapter = new NodeAdapter();
if (nodeAdapter.CanAdapt(m_SnappedSource.Source(), m_SnappedTarget.Source()))
{
nodeAdapter.Connect(m_SnappedSource.Source(), m_SnappedTarget.Source());
cnx.OnConnect(m_SnappedTarget);
}
}
EndSnap();
e.Use();
canvas.OnOverlay -= HighlightCompatibleAnchors;
return true;
}
private bool MouseDrag(CanvasElement element, Event e, Canvas2D canvas)
{
if (e.type == EventType.Used)
{
return false;
}
if (!canvas.IsCaptured(this))
{
return false;
}
m_End = canvas.MouseToCanvas(e.mousePosition);
e.Use();
m_Color = s_EdgeColor;
IConnect thisCnx = (element as IConnect);
// find target anchor under us
CanvasElement elementUnderMouse = canvas.PickSingle<T>(e.mousePosition);
if (elementUnderMouse != null)
{
IConnect cnx = elementUnderMouse as IConnect;
if (cnx == null)
{
Debug.LogError("PickSingle returned an incompatible element: does not support IConnect interface");
return true;
}
if (m_CompatibleAnchors.Exists(ic => ic == cnx))
{
StartSnap(thisCnx, cnx);
m_Color = s_ActiveEdgeColor;
}
}
else
{
EndSnap();
}
return true;
}
private void StartSnap(IConnect from, IConnect to)
{
EndSnap();
m_SnappedTarget = to;
m_SnappedSource = from;
m_SnappedTarget.Highlight(true);
}
private void EndSnap()
{
if (m_SnappedTarget != null)
{
m_SnappedTarget.Highlight(false);
m_SnappedTarget = null;
}
}
private bool DrawEdge(CanvasElement element, Event e, Canvas2D canvas)
{
if (!canvas.IsCaptured(this))
{
return false;
}
bool invert = false;
if (m_End.x < m_Start.x)
invert = true;
Vector3[] points, tangents;
GetTangents(invert ? m_End : m_Start, invert ? m_Start : m_End, out points, out tangents);
Handles.DrawBezier(points[0], points[1], tangents[0], tangents[1], m_Color, null, 5f);
// little widget on the middle of the edge
Vector3[] allPoints = Handles.MakeBezierPoints(points[0], points[1], tangents[0], tangents[1], 20);
Color oldColor = Handles.color;
Handles.color = m_Color;
Handles.DrawSolidDisc(allPoints[10], new Vector3(0.0f, 0.0f, -1.0f), 6f);
Handles.color = oldColor;
return true;
}
private bool HighlightCompatibleAnchors(CanvasElement element, Event e, Canvas2D canvas)
{
foreach (IConnect visible in m_CompatibleAnchors)
{
visible.RenderOverlay(canvas);
}
return false;
}
public static void GetTangents(Vector2 start, Vector2 end, out Vector3[] points, out Vector3[] tangents)
{
points = new Vector3[] { start, end };
tangents = new Vector3[2];
const float minTangent = 30;
float weight = (start.y < end.y) ? .3f : .7f;
weight = .5f;
float weight2 = 1 - weight;
float y = 0;
if (start.x > end.x)
{
weight2 = weight = -.25f;
float aspect = (start.x - end.x) / (start.y - end.y);
if (Mathf.Abs(aspect) > .5f)
{
float asp = (Mathf.Abs(aspect) - .5f) / 8;
asp = Mathf.Sqrt(asp);
y = Mathf.Min(asp * 80, 80);
if (start.y > end.y)
y = -y;
}
}
float cleverness = Mathf.Clamp01(((start - end).magnitude - 10) / 50);
tangents[0] = start + new Vector2((end.x - start.x) * weight + minTangent, y) * cleverness;
tangents[1] = end + new Vector2((end.x - start.x) * -weight2 - minTangent, -y) * cleverness;
}
};
internal class Edge<T> : CanvasElement where T : CanvasElement, IConnect
{
private T Left = null;
private T Right = null;
private ICanvasDataSource m_Data;
public Edge(ICanvasDataSource data, T left, T right)
{
m_Data = data;
zIndex = 9999;
m_SupportsRenderToTexture = false;
left.AddDependency(this);
right.AddDependency(this);
Left = left;
Right = right;
UpdateModel(UpdateType.eUpdate);
KeyDown += OnDeleteEdge;
}
private bool OnDeleteEdge(CanvasElement element, Event e, Canvas2D canvas)
{
if (e.type == EventType.Used)
return false;
if (e.keyCode == KeyCode.Delete)
{
m_Data.DeleteElement(this);
return true;
}
return false;
}
public override bool Intersects(Rect rect)
{
// first check coarse bounding box
if (!base.Intersects(rect))
return false;
// bounding box check succeeded, do more fine grained check by checking intersection between the rectangles' diagonal
// and the line segments
Vector3 from = Left.ConnectPosition();
Vector3 to = Right.ConnectPosition();
if (to.x < from.x)
{
Vector3 t = from;
from = to;
to = t;
}
Vector3[] points, tangents;
EdgeConnector<T>.GetTangents(from, to, out points, out tangents);
Vector3[] allPoints = Handles.MakeBezierPoints(points[0], points[1], tangents[0], tangents[1], 20);
for (int a = 0; a < allPoints.Length; a++)
{
if (a >= allPoints.Length - 1)
{
break;
}
Vector2 segmentA = new Vector2(allPoints[a].x, allPoints[a].y);
Vector2 segmentB = new Vector2(allPoints[a + 1].x, allPoints[a + 1].y);
if (RectUtils.IntersectsSegment(rect, segmentA, segmentB))
return true;
}
return false;
}
public override bool Contains(Vector2 canvasPosition)
{
// first check coarse bounding box
if (!base.Contains(canvasPosition))
return false;
// bounding box check succeeded, do more fine grained check by measuring distance to bezier points
Vector3 from = Left.ConnectPosition();
Vector3 to = Right.ConnectPosition();
if (to.x < from.x)
{
Vector3 t = from;
from = to;
to = t;
}
Vector3[] points, tangents;
EdgeConnector<T>.GetTangents(from, to, out points, out tangents);
Vector3[] allPoints = Handles.MakeBezierPoints(points[0], points[1], tangents[0], tangents[1], 20);
float minDistance = Mathf.Infinity;
foreach (Vector3 currentPoint in allPoints)
{
float distance = Vector3.Distance(currentPoint, canvasPosition);
minDistance = Mathf.Min(minDistance, distance);
if (minDistance < 15.0f)
{
return true;
}
}
return false;
}
public override void Render(Rect parentRect, Canvas2D canvas)
{
Color edgeColor = selected ? Color.yellow : Color.white;
Vector3 from = Left.ConnectPosition();
Vector3 to = Right.ConnectPosition();
if (to.x < from.x)
{
Vector3 t = from;
from = to;
to = t;
}
Vector3[] points, tangents;
EdgeConnector<T>.GetTangents(from, to, out points, out tangents);
Handles.DrawBezier(points[0], points[1], tangents[0], tangents[1], edgeColor, null, 5f);
// little widget on the middle of the edge
Vector3[] allPoints = Handles.MakeBezierPoints(points[0], points[1], tangents[0], tangents[1], 20);
Color oldColor = Handles.color;
Handles.color = Color.blue;
Handles.DrawSolidDisc(allPoints[10], new Vector3(0.0f, 0.0f, -1.0f), 6f);
Handles.color = edgeColor;
Handles.DrawWireDisc(allPoints[10], new Vector3(0.0f, 0.0f, -1.0f), 6f);
Handles.DrawWireDisc(allPoints[10], new Vector3(0.0f, 0.0f, -1.0f), 5f);
// dot on top of anchor showing it's connected
Handles.color = new Color(0.3f, 0.4f, 1.0f, 1.0f);
Handles.DrawSolidDisc(from, new Vector3(0.0f, 0.0f, -1.0f), 4f);
Handles.DrawSolidDisc(to, new Vector3(0.0f, 0.0f, -1.0f), 4f);
/*if (EditorApplication.isPlaying)
{
Handles.color = Color.red;
Handles.DrawSolidDisc(allPoints[m_RealtimeFeedbackPointIndex], new Vector3(0.0f, 0.0f, -1.0f), 6f);
m_RealtimeFeedbackPointIndex++;
if (m_RealtimeFeedbackPointIndex >= 20)
{
m_RealtimeFeedbackPointIndex = 0;
}
}*/
Handles.color = oldColor;
}
public override void UpdateModel(UpdateType t)
{
Vector3 from = Left.ConnectPosition();
Vector3 to = Right.ConnectPosition();
Rect r = new Rect();
r.min = new Vector2(Math.Min(from.x, to.x), Math.Min(from.y, to.y));
r.max = new Vector2(Math.Max(from.x, to.x), Math.Max(from.y, to.y));
translation = r.min;
scale = new Vector3(r.width, r.height, 1.0f);
base.UpdateModel(t);
}
}
}
}
}

12
UnityProject/Assets/GraphFramework/Canvas2D/Editor/Graph.cs.meta


fileFormatVersion: 2
guid: b38b5846fc01eb6428cd956646e8f9ca
timeCreated: 1430064400
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

795
UnityProject/Assets/GraphFramework/Canvas2D/Editor/Manipulators.cs


using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Text;
using System.IO;
using System.Reflection;
using UnityEngine;
using UnityEditorInternal;
using Object = UnityEngine.Object;
#pragma warning disable 0414
#pragma warning disable 0219
namespace UnityEditor
{
namespace Experimental
{
public enum ManipulatorCapability
{
eMultiSelection = 0
};
public interface IManipulate
{
bool GetCaps(ManipulatorCapability cap);
void AttachTo(CanvasElement e);
}
internal delegate bool ManipulateDelegate(Event e, Canvas2D parent, Object customData);
internal class Draggable : IManipulate
{
private EventModifiers m_ActivatorModifiers;
private int m_ActivatorButton = 0;
public Draggable()
{
m_ActivatorButton = 0;
m_ActivatorModifiers = EventModifiers.None;
}
public Draggable(int button, EventModifiers activator)
{
m_ActivatorButton = button;
m_ActivatorModifiers = activator;
}
public bool GetCaps(ManipulatorCapability cap)
{
if (cap == ManipulatorCapability.eMultiSelection)
return true;
return false;
}
public void AttachTo(CanvasElement element)
{
element.MouseDrag += MouseDrag;
element.MouseUp += EndDrag;
element.MouseDown += StartDrag;
}
private bool StartDrag(CanvasElement element, Event e, Canvas2D canvas)
{
if (e.type == EventType.Used)
return false;
if (e.button != m_ActivatorButton || m_ActivatorModifiers != e.modifiers)
{
return false;
}
canvas.StartCapture(this, element);
e.Use();
return true;
}
private bool EndDrag(CanvasElement element, Event e, Canvas2D canvas)
{
if (e.type == EventType.Used)
return false;
if (!canvas.IsCaptured(this))
{
return false;
}
canvas.EndCapture();
if (canvas.Selection.Count == 0)
{
canvas.AddToSelection(element);
}
element.UpdateModel(UpdateType.eUpdate);
e.Use();
return true;
}
private bool MouseDrag(CanvasElement element, Event e, Canvas2D canvas)
{
if (e.type == EventType.Used)
return false;
if (!canvas.IsCaptured(this))
{
return false;
}
float scaleFactorX = element == canvas ? 1.0f : 1.0f/canvas.scale.x;
float scaleFactorY = element == canvas ? 1.0f : 1.0f/canvas.scale.y;
Vector3 tx = element.translation;
tx.x += e.delta.x*scaleFactorX;
tx.y += e.delta.y*scaleFactorY;
element.translation = tx;
element.UpdateModel(UpdateType.eCandidate);
e.Use();
return true;
}
};
internal class Zoomable : IManipulate
{
public enum ZoomType
{
eAroundMouse = 0,
eLastClick = 1
};
public Zoomable()
{
m_Type = ZoomType.eAroundMouse;
}
public Zoomable(ZoomType type)
{
m_Type = type;
}
private Vector2 m_ZoomLocation = Vector2.zero;
private ZoomType m_Type = ZoomType.eAroundMouse;
private float m_MinimumZoom = 0.08f;
private float m_MaximumZoom = 1.0f;
public bool GetCaps(ManipulatorCapability cap)
{
return false;
}
public void AttachTo(CanvasElement element)
{
element.ScrollWheel += OnZoom;
element.KeyDown += OnKeyDown;
if (m_Type == ZoomType.eLastClick)
{
element.MouseDown += OnMouseDown;
}
}
private bool OnMouseDown(CanvasElement element, Event e, Canvas2D parent)
{
m_ZoomLocation = e.mousePosition;
m_ZoomLocation.x -= element.translation.x;
m_ZoomLocation.y -= element.translation.y;
return true;
}
private bool OnKeyDown(CanvasElement element, Event e, Canvas2D canvas)
{
if (e.type == EventType.Used)
return false;
if (e.keyCode == KeyCode.R)
{
element.scale = Vector3.one;
e.Use();
return true;
}
return false;
}
private bool OnZoom(CanvasElement element, Event e, Canvas2D parent)
{
if (m_Type == ZoomType.eAroundMouse)
{
m_ZoomLocation = e.mousePosition;
m_ZoomLocation.x -= element.translation.x;
m_ZoomLocation.y -= element.translation.y;
}
float delta = 0;
delta += Event.current.delta.y;
delta += Event.current.delta.x;
delta = -delta;
Vector3 currentScale = element.scale;
Vector3 currentTranslation = element.translation;
// Scale multiplier. Don't allow scale of zero or below!
float scale = Mathf.Max(0.01F, 1 + delta*0.01F);
currentTranslation.x -= m_ZoomLocation.x*(scale - 1)*currentScale.x;
currentScale.x *= scale;
currentTranslation.y -= m_ZoomLocation.y*(scale - 1)*currentScale.y;
currentScale.y *= scale;
currentScale.z = 1.0f;
bool outOfZoomBounds = false;
if (((currentScale.x < m_MinimumZoom) || (currentScale.x > m_MaximumZoom)) ||
((currentScale.y < m_MinimumZoom) || (currentScale.y > m_MaximumZoom)))
{
outOfZoomBounds = true;
}
currentScale.x = Mathf.Clamp(currentScale.x, m_MinimumZoom, m_MaximumZoom);
currentScale.y = Mathf.Clamp(currentScale.y, m_MinimumZoom, m_MaximumZoom);
element.scale = currentScale;
if (!outOfZoomBounds)
{
element.translation = currentTranslation;
}
e.Use();
return true;
}
};
internal class Resizable : IManipulate
{
private bool m_Active = false;
private Vector2 m_Start = new Vector2();
public Resizable()
{
}
public bool GetCaps(ManipulatorCapability cap)
{
return false;
}
public void AttachTo(CanvasElement element)
{
element.MouseDown += OnMouseDown;
element.MouseDrag += OnMouseDrag;
element.MouseUp += OnMouseUp;
element.OnWidget += DrawResizeWidget;
}
private bool OnMouseDown(CanvasElement element, Event e, Canvas2D parent)
{
Rect r = element.boundingRect;
Rect widget = r;
widget.min = new Vector2(r.max.x - 30.0f, r.max.y - 30.0f);
if (widget.Contains(parent.MouseToCanvas(e.mousePosition)))
{
parent.StartCapture(this, element);
parent.ClearSelection();
m_Active = true;
m_Start = parent.MouseToCanvas(e.mousePosition);
e.Use();
}
return true;
}
private bool OnMouseDrag(CanvasElement element, Event e, Canvas2D parent)
{
if (!m_Active || e.type != EventType.MouseDrag)
return false;
Vector2 newPosition = parent.MouseToCanvas(e.mousePosition);
Vector2 diff = newPosition - m_Start;
m_Start = newPosition;
Vector3 newScale = element.scale;
newScale.x = Mathf.Max(0.1f, newScale.x + diff.x);
newScale.y = Mathf.Max(0.1f, newScale.y + diff.y);
element.scale = newScale;
element.DeepInvalidate();
e.Use();
return true;
}
private bool OnMouseUp(CanvasElement element, Event e, Canvas2D parent)
{
if (m_Active == true)
{
parent.EndCapture();
parent.RebuildQuadTree();
}
m_Active = false;
return true;
}
private bool DrawResizeWidget(CanvasElement element, Event e, Canvas2D parent)
{
GUIStyle style = new GUIStyle("WindowBottomResize");
Rect r = element.boundingRect;
Rect widget = r;
widget.min = new Vector2(r.max.x - 10.0f, r.max.y - 7.0f);
GUI.Label(widget, GUIContent.none, style);
return true;
}
};
internal class RectangleSelect : IManipulate
{
private Vector2 m_Start = Vector2.zero;
private Vector2 m_End = Vector2.zero;
private bool m_SelectionActive = false;
public bool GetCaps(ManipulatorCapability cap)
{
return false;
}
public void AttachTo(CanvasElement element)
{
element.MouseDown += MouseDown;
element.MouseUp += MouseUp;
element.MouseDrag += MouseDrag;
}
private bool MouseDown(CanvasElement element, Event e, Canvas2D parent)
{
if (e.type == EventType.Used)
return false;
parent.ClearSelection();
if (e.button == 0)
{
element.OnWidget += DrawSelection;
m_Start = parent.MouseToCanvas(e.mousePosition);
m_End = m_Start;
m_SelectionActive = true;
e.Use();
return true;
}
return false;
}
private bool MouseUp(CanvasElement element, Event e, Canvas2D parent)
{
if (e.type == EventType.Used)
return false;
bool handled = false;
if (m_SelectionActive)
{
element.OnWidget -= DrawSelection;
m_End = parent.MouseToCanvas(e.mousePosition);
Rect selection = new Rect();
selection.min = new Vector2(Math.Min(m_Start.x, m_End.x), Math.Min(m_Start.y, m_End.y));
selection.max = new Vector2(Math.Max(m_Start.x, m_End.x), Math.Max(m_Start.y, m_End.y));
selection.width = Mathf.Max(selection.width, 5.0f);
selection.height = Mathf.Max(selection.height, 5.0f);
foreach (CanvasElement child in parent.Elements)
{
if (child.Intersects(selection))
{
parent.AddToSelection(child);
}
}
handled = true;
e.Use();
}
m_SelectionActive = false;
return handled;
}
private bool MouseDrag(CanvasElement element, Event e, Canvas2D parent)
{
if (e.button == 0)
{
m_End = parent.MouseToCanvas(e.mousePosition);
e.Use();
return true;
}
return false;
}
private bool DrawSelection(CanvasElement element, Event e, Canvas2D parent)
{
if (!m_SelectionActive)
return false;
Rect r = new Rect();
r.min = new Vector2(Math.Min(m_Start.x, m_End.x), Math.Min(m_Start.y, m_End.y));
r.max = new Vector2(Math.Max(m_Start.x, m_End.x), Math.Max(m_Start.y, m_End.y));
Color lineColor = new Color(1.0f, 0.6f, 0.0f, 1.0f);
float segmentSize = 5f;
Vector3[] points =
{
new Vector3(r.xMin, r.yMin, 0.0f),
new Vector3(r.xMax, r.yMin, 0.0f),
new Vector3(r.xMax, r.yMax, 0.0f),
new Vector3(r.xMin, r.yMax, 0.0f)
};
DrawDottedLine(points[0], points[1], segmentSize, lineColor);
DrawDottedLine(points[1], points[2], segmentSize, lineColor);
DrawDottedLine(points[2], points[3], segmentSize, lineColor);
DrawDottedLine(points[3], points[0], segmentSize, lineColor);
return true;
}
private void DrawDottedLine(Vector3 p1, Vector3 p2, float segmentsLength, Color col)
{
UIHelpers.ApplyWireMaterial();
GL.Begin(GL.LINES);
GL.Color(col);
float length = Vector3.Distance(p1, p2); // ignore z component
int count = Mathf.CeilToInt(length/segmentsLength);
for (int i = 0; i < count; i += 2)
{
GL.Vertex((Vector3.Lerp(p1, p2, i*segmentsLength/length)));
GL.Vertex((Vector3.Lerp(p1, p2, (i + 1)*segmentsLength/length)));
}
GL.End();
}
};
internal class Frame : IManipulate
{
public enum FrameType
{
eAll = 0,
eSelection = 1
};
private FrameType m_Type = FrameType.eAll;
public Frame(FrameType type)
{
m_Type = type;
}
public bool GetCaps(ManipulatorCapability cap)
{
return false;
}
public void AttachTo(CanvasElement element)
{
element.KeyDown += KeyDown;
}
private bool KeyDown(CanvasElement element, Event e, Canvas2D parent)
{
if (e.type == EventType.Used)
return false;
if ((m_Type == FrameType.eAll && e.keyCode == KeyCode.A) ||
(m_Type == FrameType.eSelection && e.keyCode == KeyCode.F))
{
Rect rectToFit = parent.CanvasRect;
if (m_Type == FrameType.eSelection)
{
List<CanvasElement> s = parent.Selection;
if (s.Count == 0)
return false;
rectToFit = s[0].boundingRect;
foreach (CanvasElement c in s)
{
rectToFit = RectUtils.Encompass(rectToFit, c.boundingRect);
}
}
// bring slightly smaller screen rect into GUI space
Rect screenRect = new Rect();
screenRect.xMin = 50;
screenRect.xMax = Screen.width - 50;
screenRect.yMin = 50;
screenRect.yMax = Screen.height - 50;
Matrix4x4 m = GUI.matrix;
GUI.matrix = Matrix4x4.TRS(Vector3.zero, Quaternion.identity, Vector3.one);
Rect identity = GUIUtility.ScreenToGUIRect(screenRect);
// measure zoom level necessary to fit the canvas rect into the screen rect
float zoomLevel = Math.Min(identity.width/rectToFit.width, identity.height/rectToFit.height);
// clamp
zoomLevel = Mathf.Clamp(zoomLevel, 0.08f, 1.0f);
parent.scale = new Vector3(zoomLevel, zoomLevel, 1.0f);
parent.translation = Vector3.zero;
// make a rect of the screen in GUI space and measure the distance between that rect
// and the canvas rect. Multiply this by the scale level to get the offset to center the view
Vector2 edge = parent.MouseToCanvas(new Vector2(Screen.width, Screen.height));
Vector2 origin = parent.MouseToCanvas(new Vector2(0.0f, 0.0f));
Rect r = new Rect();
r.min = origin;
r.max = edge;
Vector2 offset = (r.center - rectToFit.center)*parent.scale.x;
parent.translation = new Vector3(offset.x, offset.y, 0.0f);
GUI.matrix = m;
e.Use();
return true;
}
return false;
}
};
internal class ContextualMenu : IManipulate
{
private ManipulateDelegate m_Callback = null;
private Object m_CustomData = null;
public ContextualMenu(ManipulateDelegate callback)
{
m_Callback = callback;
m_CustomData = null;
}
public ContextualMenu(ManipulateDelegate callback, Object customData)
{
m_Callback = callback;
m_CustomData = customData;
}
public bool GetCaps(ManipulatorCapability cap)
{
return false;
}
public void AttachTo(CanvasElement element)
{
element.ContextClick += OnContextMenu;
}
private bool OnContextMenu(CanvasElement element, Event e, Canvas2D parent)
{
if (e.type == EventType.Used)
return false;
e.Use();
return m_Callback(e, parent, m_CustomData);
}
};
internal class DragDrop : IManipulate
{
private ManipulateDelegate m_Callback = null;
private Object m_CustomData = null;
public DragDrop(ManipulateDelegate callback)
{
m_Callback = callback;
m_CustomData = null;
}
public DragDrop(ManipulateDelegate callback, Object customData)
{
m_Callback = callback;
m_CustomData = customData;
}
public bool GetCaps(ManipulatorCapability cap)
{
return false;
}
public void AttachTo(CanvasElement element)
{
element.DragPerform += OnDragAndDropEvent;
element.DragUpdated += OnDragAndDropEvent;
element.DragExited += OnDragAndDropEvent;
}
private bool OnDragAndDropEvent(CanvasElement element, Event e, Canvas2D parent)
{
if (e.type == EventType.Used)
return false;
return m_Callback(e, parent, m_CustomData);
}
};
internal class ScreenSpaceGrid : IManipulate
{
private float m_Spacing = 50f;
private int m_ThickLines = 10;
private Color m_LineColor = new Color(0f, 0f, 0f, 0.18f);
private Color m_ThickLineColor = new Color(0f, 0f, 0f, 0.38f);
private Color m_Background = new Color(0.17f, 0.17f, 0.17f, 1.0f);
//private Color m_Background = new Color(1.0f, 1.0f, 1.0f, 1.0f);
public ScreenSpaceGrid()
{
}
public ScreenSpaceGrid(float spacing, int thickLineFrequency, Color lineColor, Color thickLineColor, Color background)
{
m_Spacing = spacing;
m_ThickLines = thickLineFrequency;
m_LineColor = lineColor;
m_ThickLineColor = thickLineColor;
m_Background = background;
}
public bool GetCaps(ManipulatorCapability cap)
{
return false;
}
public void AttachTo(CanvasElement element)
{
if (element is Canvas2D)
{
(element as Canvas2D).OnBackground += DrawGrid;
}
}
public static bool nearlyEqual(float a, float b, float epsilon)
{
if ((Math.Abs(a) - Math.Abs(b)) > epsilon)
return false;
return true;
}
private Vector3 Clip(Rect clipRect, Vector3 _in)
{
if (_in.x < clipRect.xMin)
_in.x = clipRect.xMin;
if (_in.x > clipRect.xMax)
_in.x = clipRect.xMax;
if (_in.y < clipRect.yMin)
_in.y = clipRect.yMin;
if (_in.y > clipRect.yMax)
_in.y = clipRect.yMax;
return _in;
}
private bool DrawGrid(CanvasElement element, Event e, Canvas2D canvas)
{
Rect clientRect = new Rect(0, canvas.clientRect.y, Screen.width, Screen.height);
// background
UIHelpers.ApplyWireMaterial();
GL.Begin(GL.QUADS);
GL.Color(m_Background);
GL.Vertex(Clip(clientRect, new Vector3(clientRect.x, clientRect.y + canvas.viewOffset.y, 0.0f)));
GL.Vertex(Clip(clientRect, new Vector3(clientRect.x + clientRect.width, clientRect.y + canvas.viewOffset.y, 0.0f)));
GL.Vertex(Clip(clientRect, new Vector3(clientRect.x + clientRect.width, clientRect.y + clientRect.height, 0.0f)));
GL.Vertex(Clip(clientRect, new Vector3(clientRect.x, clientRect.y + clientRect.height, 0.0f)));
GL.End();
Vector3 from = new Vector3(0.0f, 0.0f, 0.0f);
Vector3 to = new Vector3(0.0f, clientRect.height, 0.0f);
Matrix4x4 tx = Matrix4x4.TRS(canvas.translation, Quaternion.identity, Vector3.one);
// vertical lines
from = tx.MultiplyPoint(from);
to = tx.MultiplyPoint(to);
float thickGridLineX = from.x;
float thickGridLineY = from.y;
from.x = (from.x%(m_Spacing*(canvas.scale.x)) - (m_Spacing*(canvas.scale.x)));
to.x = from.x;
from.y = 0.0f;
to.y = clientRect.y + clientRect.height;
while (from.x < clientRect.width)
{
from.x += m_Spacing*(canvas.scale.x);
to.x += m_Spacing*(canvas.scale.x);
GL.Begin(GL.LINES);
GL.Color(m_LineColor);
GL.Vertex(Clip(clientRect,from));
GL.Vertex(Clip(clientRect, to));
GL.End();
}
float thickLineSpacing = (m_Spacing*m_ThickLines);
from.x = to.x = (thickGridLineX%(thickLineSpacing*(canvas.scale.x)) - (thickLineSpacing*(canvas.scale.x)));
while (from.x < clientRect.width)
{
GL.Begin(GL.LINES);
GL.Color(m_ThickLineColor);
GL.Vertex(Clip(clientRect, from));
GL.Vertex(Clip(clientRect, to));
GL.End();
from.x += (m_Spacing*(canvas.scale.x)*m_ThickLines);
to.x += (m_Spacing*(canvas.scale.x)*m_ThickLines);
}
// horizontal lines
from = new Vector3(0.0f, 0.0f, 0.0f);
to = new Vector3(clientRect.width, 0.0f, 0.0f);
from = tx.MultiplyPoint(from);
to = tx.MultiplyPoint(to);
from.y = (from.y%(m_Spacing*(canvas.scale.y)) - (m_Spacing*(canvas.scale.y)));
to.y = from.y;
from.x = 0.0f;
to.x = clientRect.width;
while (from.y < clientRect.height)
{
from.y += m_Spacing*(canvas.scale.y);
to.y += m_Spacing*(canvas.scale.y);
GL.Begin(GL.LINES);
GL.Color(m_LineColor);
GL.Vertex(Clip(clientRect, from));
GL.Vertex(Clip(clientRect, to));
GL.End();
}
thickLineSpacing = (m_Spacing*m_ThickLines);
from.y = to.y = (thickGridLineY%(thickLineSpacing*(canvas.scale.y)) - (thickLineSpacing*(canvas.scale.y)));
while (from.y < clientRect.height)
{
GL.Begin(GL.LINES);
GL.Color(m_ThickLineColor);
GL.Vertex(Clip(clientRect, from));
GL.Vertex(Clip(clientRect, to));
GL.End();
from.y += (m_Spacing*(canvas.scale.y)*m_ThickLines);
to.y += (m_Spacing*(canvas.scale.y)*m_ThickLines);
}
return true;
}
};
internal class IMGUIContainer : IManipulate
{
public bool GetCaps(ManipulatorCapability cap)
{
return false;
}
public void AttachTo(CanvasElement element)
{
element.AllEvents += (target, evt, canvas) =>
{
Vector2 canvasPos = canvas.MouseToCanvas(evt.mousePosition);
Rect rect = canvas.CanvasToScreen(element.boundingRect);
GUI.BeginGroup(rect);
element.Render(canvas.boundingRect, canvas);
GUI.EndGroup();
canvas.Repaint();
element.Invalidate();
return false;
};
}
}
}
}

12
UnityProject/Assets/GraphFramework/Canvas2D/Editor/Manipulators.cs.meta


fileFormatVersion: 2
guid: 7dcc2b6a82194dc4cb371cc18fad3b73
timeCreated: 1430064400
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

481
UnityProject/Assets/GraphFramework/Canvas2D/Editor/QuadTree.cs


using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using UnityEngine;
using UnityEditor;
using Object = UnityEngine.Object;
namespace UnityEditorInternal
{
internal class RectUtils
{
public static bool Contains(Rect a, Rect b)
{
if (a.xMin > b.xMin)
return false;
if (a.xMax < b.xMax)
return false;
if (a.yMin > b.yMin)
return false;
if (a.yMax < b.yMax)
return false;
return true;
}
public static Rect Encompass(Rect a, Rect b)
{
Rect newRect = a;
newRect.xMin = Math.Min(a.xMin, b.xMin);
newRect.yMin = Math.Min(a.yMin, b.yMin);
newRect.xMax = Math.Max(a.xMax, b.xMax);
newRect.yMax = Math.Max(a.yMax, b.yMax);
return newRect;
}
public static Rect Inflate(Rect a, float factor)
{
return Inflate(a, factor, factor);
}
public static Rect Inflate(Rect a, float factorX, float factorY)
{
float newWidth = a.width * factorX;
float newHeight = a.height * factorY;
float offsetWidth = (newWidth - a.width) / 2.0f;
float offsetHeight = (newHeight - a.height) / 2.0f;
Rect r = a;
r.xMin -= offsetWidth;
r.yMin -= offsetHeight;
r.xMax += offsetWidth;
r.yMax += offsetHeight;
return r;
}
public static bool Intersects(Rect r1, Rect r2)
{
if (!r1.Overlaps(r2) && !r2.Overlaps(r1))
return false;
return true;
}
public static bool Intersection(Rect r1, Rect r2, out Rect intersection)
{
if (!r1.Overlaps(r2) && !r2.Overlaps(r1))
{
intersection = new Rect(0, 0, 0, 0);
return false;
}
float left = Mathf.Max(r1.xMin, r2.xMin);
float top = Mathf.Max(r1.yMin, r2.yMin);
float right = Mathf.Min(r1.xMax, r2.xMax);
float bottom = Mathf.Min(r1.yMax, r2.yMax);
intersection = new Rect(left, top, right - left, bottom - top);
return true;
}
public static bool IntersectsSegment(Rect rect, Vector2 p1, Vector2 p2)
{
float minX = Mathf.Min(p1.x, p2.x);
float maxX = Mathf.Max(p1.x, p2.x);
if (maxX > rect.xMax)
{
maxX = rect.xMax;
}
if (minX < rect.xMin)
{
minX = rect.xMin;
}
if (minX > maxX)
{
return false;
}
float minY = Mathf.Min(p1.y, p2.y);
float maxY = Mathf.Max(p1.y, p2.y);
float dx = p2.x - p1.x;
if (Mathf.Abs(dx) > 0.0000001f)
{
float a = (p2.y - p1.y) / dx;
float b = p1.y - a * p1.x;
minY = a * minX + b;
maxY = a * maxX + b;
}
if (minY > maxY)
{
float tmp = maxY;
maxY = minY;
minY = tmp;
}
if (maxY > rect.yMax)
{
maxY = rect.yMax;
}
if (minY < rect.yMin)
{
minY = rect.yMin;
}
if (minY > maxY)
{
return false;
}
return true;
}
public static Rect OffsetX(Rect r, float offsetX)
{
return Offset(r, offsetX, 0.0f);
}
public static Rect Offset(Rect r, float offsetX, float offsetY)
{
Rect nr = r;
nr.xMin += offsetX;
nr.yMin += offsetY;
return nr;
}
public static Rect Offset(Rect a, Rect b)
{
Rect nr = a;
nr.xMin += b.xMin;
nr.yMin += b.yMin;
return nr;
}
public static Rect Move(Rect r, Vector2 delta)
{
Rect nr = r;
nr.xMin += delta.x;
nr.yMin += delta.y;
nr.xMax += delta.x;
nr.yMax += delta.y;
return nr;
}
}
internal interface IBounds
{
Rect boundingRect { get; }
}
internal class QuadTreeNode<T> where T : IBounds
{
private Rect m_BoundingRect;
private static Color m_DebugFillColor = new Color(1.0f, 1.0f, 1.0f, 0.01f);
private static Color m_DebugWireColor = new Color(1.0f, 0.0f, 0.0f, 0.5f);
private static Color m_DebugBoxFillColor = new Color(1.0f, 0.0f, 0.0f, 0.01f);
private const float kSmallestAreaForQuadTreeNode = 10.0f;
List<T> m_Elements = new List<T>();
List<QuadTreeNode<T>> m_ChildrenNodes = new List<QuadTreeNode<T>>(4);
public QuadTreeNode(Rect r)
{
m_BoundingRect = r;
}
public bool IsEmpty { get { return (m_BoundingRect.width == 0 && m_BoundingRect.height == 0) || m_ChildrenNodes.Count == 0; } }
public Rect BoundingRect { get { return m_BoundingRect; } }
public int CountItemsIncludingChildren()
{
return Count (true);
}
public int CountLocalItems()
{
return Count(false);
}
private int Count(bool recursive)
{
int count = m_Elements.Count;
if (recursive)
{
foreach (QuadTreeNode<T> node in m_ChildrenNodes)
count += node.Count(recursive);
}
return count;
}
public List<T> GetElementsIncludingChildren()
{
return Elements (true);
}
public List<T> GetElements()
{
return Elements(false);
}
private List<T> Elements(bool recursive)
{
List<T> results = new List<T>();
if (recursive)
{
foreach (QuadTreeNode<T> node in m_ChildrenNodes)
results.AddRange(node.Elements(recursive));
}
results.AddRange(m_Elements);
return results;
}
public List<T> IntersectsWith(Rect queryArea)
{
List<T> results = new List<T>();
foreach (T item in m_Elements)
{
if (RectUtils.Intersects(item.boundingRect, queryArea))
{
results.Add(item);
}
}
foreach (QuadTreeNode<T> node in m_ChildrenNodes)
{
if (node.IsEmpty)
continue;
if (RectUtils.Intersects(node.BoundingRect, queryArea))
{
// the node completely contains the queryArea
// recurse down and stop
results.AddRange(node.IntersectsWith(queryArea));
break;
}
}
return results;
}
public List<T> ContainedBy(Rect queryArea)
{
List<T> results = new List<T>();
foreach (T item in m_Elements)
{
if (RectUtils.Contains(item.boundingRect, queryArea))
{
results.Add(item);
}
else if (queryArea.Overlaps(item.boundingRect))
{
results.Add(item);
}
}
foreach (QuadTreeNode<T> node in m_ChildrenNodes)
{
if (node.IsEmpty)
continue;
if (RectUtils.Contains(node.BoundingRect, queryArea))
{
// the node completely contains the queryArea
// recurse down and stop
results.AddRange(node.ContainedBy(queryArea));
break;
}
if (RectUtils.Contains(queryArea, node.BoundingRect))
{
// the queryArea completely contains this node
// just add everything under this node, recursively
results.AddRange(node.Elements(true));
continue;
}
if (node.BoundingRect.Overlaps(queryArea))
{
// the node intesects
// recurse and continue iterating siblings
results.AddRange(node.ContainedBy(queryArea));
}
}
return results;
}
public void Remove(T item)
{
m_Elements.Remove(item);
foreach (QuadTreeNode<T> node in m_ChildrenNodes)
{
node.Remove(item);
}
}
public void Insert(T item)
{
if (!RectUtils.Contains(m_BoundingRect, item.boundingRect))
{
Rect intersection = new Rect();
if (!RectUtils.Intersection(item.boundingRect, m_BoundingRect, out intersection))
{
// Ignore elements completely outside the quad tree
return;
}
}
if (m_ChildrenNodes.Count == 0)
Subdivide();
// insert into children nodes
foreach (QuadTreeNode<T> node in m_ChildrenNodes)
{
if (RectUtils.Contains(node.BoundingRect, item.boundingRect))
{
node.Insert(item);
return;
}
}
// item is not completely contained in any of the children nodes
// insert here
this.m_Elements.Add(item);
}
private void Subdivide()
{
if ((m_BoundingRect.height * m_BoundingRect.width) <= kSmallestAreaForQuadTreeNode)
return;
float halfWidth = (m_BoundingRect.width / 2f);
float halfHeight = (m_BoundingRect.height / 2f);
m_ChildrenNodes.Add(new QuadTreeNode<T>(new Rect(m_BoundingRect.position.x, m_BoundingRect.position.y, halfWidth, halfHeight)));
m_ChildrenNodes.Add(new QuadTreeNode<T>(new Rect(m_BoundingRect.xMin, m_BoundingRect.yMin + halfHeight, halfWidth, halfHeight)));
m_ChildrenNodes.Add(new QuadTreeNode<T>(new Rect(m_BoundingRect.xMin + halfWidth, m_BoundingRect.yMin, halfWidth, halfHeight)));
m_ChildrenNodes.Add(new QuadTreeNode<T>(new Rect(m_BoundingRect.xMin + halfWidth, m_BoundingRect.yMin + halfHeight, halfWidth, halfHeight)));
}
public void DebugDraw(Vector2 offset)
{
UnityEditor.Experimental.UIHelpers.ApplyWireMaterial();
Rect screenSpaceRect = m_BoundingRect;
screenSpaceRect.x += offset.x;
screenSpaceRect.y += offset.y;
Handles.DrawSolidRectangleWithOutline(screenSpaceRect, m_DebugFillColor, m_DebugWireColor);
foreach (QuadTreeNode<T> node in m_ChildrenNodes)
{
node.DebugDraw(offset);
}
foreach (IBounds i in Elements(false))
{
Rect o = i.boundingRect;
o.x += offset.x;
o.y += offset.y;
Handles.DrawSolidRectangleWithOutline(o, m_DebugBoxFillColor, Color.yellow);
}
}
};
internal class QuadTree<T> where T : IBounds
{
private QuadTreeNode<T> m_Root = null;
private Rect m_Rectangle;
private Vector2 m_ScreenSpaceOffset = Vector2.zero;
public QuadTree()
{
Clear();
}
public Vector2 screenSpaceOffset
{
get { return m_ScreenSpaceOffset; }
set
{
m_ScreenSpaceOffset = value;
}
}
public Rect rectangle
{
get { return m_Rectangle; }
}
public void Clear()
{
SetSize(new Rect(0, 0, 1, 1));
}
public void SetSize(Rect rectangle)
{
m_Root = null;
m_Rectangle = rectangle;
m_Root = new QuadTreeNode<T>(m_Rectangle);
}
public int Count { get { return m_Root.CountItemsIncludingChildren(); } }
public void Insert(List<T> items)
{
foreach (T i in items)
{
Insert(i);
}
}
public void Insert(T item)
{
m_Root.Insert(item);
}
public void Remove(T item)
{
m_Root.Remove(item);
}
public List<T> IntersectsWith(Rect area)
{
area.x -= m_ScreenSpaceOffset.x;
area.y -= m_ScreenSpaceOffset.y;
return m_Root.IntersectsWith(area);
}
public List<T> ContainedBy(Rect area)
{
area.x -= m_ScreenSpaceOffset.x;
area.y -= m_ScreenSpaceOffset.y;
return m_Root.ContainedBy(area);
}
public List<T> Elements()
{
return m_Root.GetElementsIncludingChildren();
}
public void DebugDraw()
{
m_Root.DebugDraw(m_ScreenSpaceOffset);
}
}
}

12
UnityProject/Assets/GraphFramework/Canvas2D/Editor/QuadTree.cs.meta


fileFormatVersion: 2
guid: e371b96fe2e47f14a9210c5129c1e42f
timeCreated: 1445092875
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

250
UnityProject/Assets/GraphFramework/Canvas2D/Editor/UIHelpers.cs


using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using UnityEngine;
using UnityEditorInternal;
using System.Reflection;
using Object = UnityEngine.Object;
namespace UnityEditor
{
namespace Experimental
{
/// <summary>
/// CanvasLayout : the base class for vertical and horizontal layouts
/// WARNING: these layout classes have pretty limited usage.
/// </summary>
/// <remarks>
/// Do not use this class directly. Use on of the specializations or derive your own
/// </remarks>
internal class CanvasLayout
{
protected CanvasElement m_Owner = null;
protected CanvasLayout m_Parent = null;
protected Vector4 m_Padding = Vector4.zero;
protected float m_Left = 0;
protected float m_Height = 0;
protected float m_Width = 0;
protected List<CanvasLayout> m_Children = new List<CanvasLayout>();
protected List<CanvasElement> m_Elements = new List<CanvasElement>();
public float Height
{
get
{
float maxHeight = m_Height;
foreach (CanvasLayout l in m_Children)
{
maxHeight = Mathf.Max(maxHeight, l.Height);
}
return maxHeight + PaddingTop + PaddingBottom;
}
}
public float Width
{
get
{
float maxWidth = m_Width;
foreach (CanvasLayout l in m_Children)
{
maxWidth = Mathf.Max(maxWidth, l.Width);
}
return maxWidth + PaddingLeft + PaddingRight;
}
}
public CanvasLayout(CanvasElement e)
{
m_Owner = e;
}
public CanvasLayout(CanvasLayout p)
{
m_Parent = p;
m_Owner = p.Owner();
}
public CanvasElement Owner()
{
if (m_Owner != null)
return m_Owner;
if (m_Parent != null)
return m_Parent.Owner();
return null;
}
public float Left
{
get { return m_Left; }
set { m_Left = value; }
}
public float PaddingLeft
{
get { return m_Padding.w; }
set { m_Padding.w = value; }
}
public float PaddingRight
{
get { return m_Padding.y; }
set { m_Padding.y = value; }
}
public float PaddingTop
{
get { return m_Padding.x; }
set { m_Padding.x = value; }
}
public float PaddingBottom
{
get { return m_Padding.z; }
set { m_Padding.z = value; }
}
public virtual void LayoutElement(CanvasElement c)
{
m_Elements.Add(c);
}
public virtual void LayoutElements(CanvasElement[] arrayOfElements)
{
for (int a = 0; a < arrayOfElements.Length; a++)
{
m_Elements.Add(arrayOfElements[a]);
}
}
public void AddSpacer(int pixels)
{
float collapsedFactor = m_Owner.IsCollapsed() ? 0.0f : 1.0f;
m_Height += pixels*collapsedFactor;
}
public virtual void DebugDraw()
{
}
};
/// <summary>
/// CanvasVerticalLayout : Helps layouting a group of canvas elements vertically
/// </summary>
internal class CanvasVerticalLayout : CanvasLayout
{
public CanvasVerticalLayout(CanvasElement e)
: base(e)
{
}
public override void LayoutElements(CanvasElement[] arrayOfElements)
{
for (int a = 0; a < arrayOfElements.Length; a++)
{
LayoutElement(arrayOfElements[a]);
}
base.LayoutElements(arrayOfElements);
}
public override void LayoutElement(CanvasElement c)
{
float collapsedFactor = m_Owner.IsCollapsed() ? 0.0f : 1.0f;
if ((c.Caps & CanvasElement.Capabilities.DoesNotCollapse) == CanvasElement.Capabilities.DoesNotCollapse)
{
collapsedFactor = 1.0f;
}
m_Height += m_Padding.x*collapsedFactor;
//c.translation = new Vector3(m_Padding.y + c.translation.x, Height*collapsedFactor, 0.0f);
c.translation = new Vector3(c.translation.x, Height * collapsedFactor, 0.0f);
c.scale = new Vector3(c.scale.x, c.scale.y*collapsedFactor, 1.0f);
m_Height += (c.scale.y + m_Padding.z)*collapsedFactor;
m_Width = Mathf.Max(m_Width, c.scale.x);
Owner().AddChild(c);
base.LayoutElement(c);
}
public override void DebugDraw()
{
if (m_Elements.Count() == 0)
return;
Rect encompassingRect = m_Elements[0].canvasBoundingRect;
List<Rect> elementRects = new List<Rect>();
foreach (CanvasElement e in m_Elements)
{
elementRects.Add(e.canvasBoundingRect);
encompassingRect = RectUtils.Encompass(encompassingRect, e.canvasBoundingRect);
}
Vector3[] points =
{
new Vector3(encompassingRect.xMin, encompassingRect.yMin, 0.0f),
new Vector3(encompassingRect.xMax, encompassingRect.yMin, 0.0f),
new Vector3(encompassingRect.xMax, encompassingRect.yMax, 0.0f),
new Vector3(encompassingRect.xMin, encompassingRect.yMax, 0.0f)
};
Color prevColor = GUI.color;
GUI.color = new Color(1.0f, 0.6f, 0.0f, 1.0f);
Handles.DrawDottedLine(points[0], points[1], 5.0f);
Handles.DrawDottedLine(points[1], points[2], 5.0f);
Handles.DrawDottedLine(points[2], points[3], 5.0f);
Handles.DrawDottedLine(points[3], points[0], 5.0f);
GUI.color = prevColor;
foreach (Rect r in elementRects)
{
Vector2 from = new Vector2(r.xMin, r.yMax);
Vector2 to = new Vector2(encompassingRect.xMax, r.yMax);
DrawDottedLine(from, to, 5.0f, new Color(1.0f, 0.6f, 0.0f, 1.0f));
}
}
private void DrawDottedLine(Vector3 p1, Vector3 p2, float segmentsLength, Color col)
{
UIHelpers.ApplyWireMaterial();
GL.Begin(GL.LINES);
GL.Color(col);
float length = Vector3.Distance(p1, p2); // ignore z component
int count = Mathf.CeilToInt(length/segmentsLength);
for (int i = 0; i < count; i += 2)
{
GL.Vertex((Vector3.Lerp(p1, p2, i*segmentsLength/length)));
GL.Vertex((Vector3.Lerp(p1, p2, (i + 1)*segmentsLength/length)));
}
GL.End();
}
};
internal class UIHelpers
{
static MethodInfo ApplyWireMaterialMI = null;
public static void ApplyWireMaterial()
{
if (ApplyWireMaterialMI == null)
{
ApplyWireMaterialMI = typeof(HandleUtility).GetMethod("ApplyWireMaterial", BindingFlags.Instance | BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Static | BindingFlags.FlattenHierarchy);
}
if (ApplyWireMaterialMI != null)
{
ApplyWireMaterialMI.Invoke(null, null);
}
}
}
}
}

12
UnityProject/Assets/GraphFramework/Canvas2D/Editor/UIHelpers.cs.meta


fileFormatVersion: 2
guid: ee2df75d146c4ae4298b06e4f1d58da0
timeCreated: 1430064400
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

9
UnityProject/Assets/GraphFramework/Examples.meta


fileFormatVersion: 2
guid: e2cbda12d8ee5324ba86a9be383f8e89
folderAsset: yes
timeCreated: 1445093418
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

192
UnityProject/Assets/UnityShaderEditor/Editor/Source/Drawing/DrawableMaterialNode.cs


using System;
using UnityEditor.Experimental;
using UnityEditor.Experimental.Graph;
using UnityEngine;
namespace UnityEditor.MaterialGraph
{
internal class PortSource<T>
{
}
public class DrawableMaterialNode : MoveableBox
{
private Type m_OutputType;
public DrawableMaterialNode(BaseMaterialNode node, float size, Type outputType, MaterialGraphDataSource data)
: base(node.position.min, size)
{
m_Title = node.name;
m_OutputType = outputType;
Vector3 pos = new Vector3(5.0f, 32.0f, 0.0f);
AddChild(new NodeAnchor(0, pos, typeof (int), this, data));
pos.y += 22;
AddChild(new NodeAnchor(1, pos, typeof (float), this, data));
pos.y += 22;
AddChild(new NodeAnchor(2, pos, typeof (Vector3), this, data));
pos.y += 22;
AddChild(new NodeAnchor(3, pos, typeof (Texture2D), this, data));
pos.y += 22;
AddChild(new NodeAnchor(4, pos, typeof (Color), this, data));
pos.y += 22;
// output port
pos.x = size - 20.0f;
AddChild(new NodeOutputAnchor(pos, m_OutputType, this, data));
pos.y += 22;
scale = new Vector3(scale.x, pos.y + 12.0f, 0.0f);
}
}
public class NodeAnchor : CanvasElement, IConnect
{
protected Type m_Type;
protected object m_Source;
protected Direction m_Direction;
private MaterialGraphDataSource m_Data;
public DrawableMaterialNode m_Node;
public int m_PortIndex;
public NodeAnchor(int portIndex, Vector3 position, Type type, DrawableMaterialNode node, MaterialGraphDataSource data)
{
m_Type = type;
scale = new Vector3(15.0f, 15.0f, 1.0f);
translation = position;
AddManipulator(new EdgeConnector<NodeAnchor>());
m_Direction = Direction.eInput;
Type genericClass = typeof (PortSource<>);
Type constructedClass = genericClass.MakeGenericType(type);
m_Source = Activator.CreateInstance(constructedClass);
m_Data = data;
m_Node = node;
m_PortIndex = portIndex;
}
public override void Render(Rect parentRect, Canvas2D canvas)
{
var anchorColor = Color.yellow;
anchorColor.a = 0.7f;
base.Render(parentRect, canvas);
EditorGUI.DrawRect(new Rect(translation.x, translation.y, scale.x, scale.y), anchorColor);
Rect labelRect = new Rect(translation.x + scale.x + 10.0f, translation.y, parentRect.width, 20.0f);
GUI.Label(labelRect, m_Type.Name);
}
// IConnect
public Direction GetDirection()
{
return m_Direction;
}
public void Highlight(bool highlighted)
{
}
public void RenderOverlay(Canvas2D canvas)
{
Rect thisRect = canvasBoundingRect;
thisRect.x += 4;
thisRect.y += 4;
thisRect.width -= 8;
thisRect.height -= 8;
thisRect = canvas.CanvasToScreen(thisRect);
EditorGUI.DrawRect(thisRect, new Color(0.0f, 0.0f, 0.8f));
}
public object Source()
{
return m_Source;
}
public Vector3 ConnectPosition()
{
return canvasBoundingRect.center;
}
public void OnConnect(IConnect other)
{
if (other == null)
return;
NodeAnchor otherAnchor = other as NodeAnchor;
m_Data.Connect(this, otherAnchor);
ParentCanvas().ReloadData();
}
};
public class NodeOutputAnchor : NodeAnchor
{
public NodeOutputAnchor(Vector3 position, Type type, DrawableMaterialNode node, MaterialGraphDataSource data)
: base(-1, position, type, node, data)
{
m_Direction = Direction.eOutput;
}
public override void Render(Rect parentRect, Canvas2D canvas)
{
var anchorColor = Color.yellow;
anchorColor.a = 0.7f;
base.Render(parentRect, canvas);
EditorGUI.DrawRect(new Rect(translation.x, translation.y, scale.x, scale.y), anchorColor);
Vector2 sizeOfText = GUIStyle.none.CalcSize(new GUIContent(m_Type.Name));
Rect labelRect = new Rect(translation.x - sizeOfText.x - 4.0f, translation.y, sizeOfText.x + 4.0f, sizeOfText.y + 4.0f);
GUI.Label(labelRect, m_Type.Name);
}
};
internal static class MyNodeAdapters
{
internal static bool Adapt(this NodeAdapter value, PortSource<int> a, PortSource<int> b)
{
// run adapt code for int to int connections
return true;
}
internal static bool Adapt(this NodeAdapter value, PortSource<float> a, PortSource<float> b)
{
// run adapt code for float to float connections
return true;
}
internal static bool Adapt(this NodeAdapter value, PortSource<int> a, PortSource<float> b)
{
// run adapt code for int to float connections, perhaps by insertion a conversion node
return true;
}
internal static bool Adapt(this NodeAdapter value, PortSource<Vector3> a, PortSource<Vector3> b)
{
// run adapt code for vec3 to vec3 connections
return true;
}
internal static bool Adapt(this NodeAdapter value, PortSource<Color> a, PortSource<Color> b)
{
// run adapt code for Color to Color connections
return true;
}
internal static bool Adapt(this NodeAdapter value, PortSource<Vector3> a, PortSource<Color> b)
{
// run adapt code for vec3 to Color connections
return true;
}
internal static bool Adapt(this NodeAdapter value, PortSource<Color> a, PortSource<Vector3> b)
{
// run adapt code for Color to vec3 connections
return true;
}
}
}

12
UnityProject/Assets/UnityShaderEditor/Editor/Source/Drawing/DrawableMaterialNode.cs.meta


fileFormatVersion: 2
guid: 476f6813876d1d04387dfa9640d44324
timeCreated: 1445419780
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

37
UnityProject/Assets/UnityShaderEditor/Editor/Source/Drawing/MaterialGraphDataSource.cs


using System.Collections.Generic;
using UnityEditor.Experimental;
using UnityEditor.Experimental.Graph;
using UnityEngine;
namespace UnityEditor.MaterialGraph
{
public class MaterialGraphDataSource : ICanvasDataSource
{
public MaterialGraph graph { get; set; }
public CanvasElement[] FetchElements()
{
var elements = new List<CanvasElement>();
Debug.Log("trying to convert");
var pixelGraph = graph.currentGraph;
foreach (var node in pixelGraph.nodes)
{
var bmn = node as BaseMaterialNode;
elements.Add(new DrawableMaterialNode(bmn, 200.0f, typeof(Vector4), this));
}
Debug.LogFormat("REturning {0} nodes", elements.Count);
return elements.ToArray();
}
public void DeleteElement(CanvasElement e)
{
//m_Elements.Remove(e);
}
public void Connect(NodeAnchor a, NodeAnchor b)
{
//m_Elements.Add(new Edge<NodeAnchor>(this, a, b));
}
}
}

12
UnityProject/Assets/UnityShaderEditor/Editor/Source/Drawing/MaterialGraphDataSource.cs.meta


fileFormatVersion: 2
guid: 194f855484623804c819a9132a24268f
timeCreated: 1445419780
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

123
UnityProject/Assets/UnityShaderEditor/Editor/Source/Drawing/MaterialWindow.cs


#define DEBUG_MAT_GEN
using UnityEditor.Experimental;
using UnityEditor.Graphs;
using UnityEngine;
namespace UnityEditor.MaterialGraph
{
class MaterialWindow : EditorWindow
{
[MenuItem("Window/Material")]
public static void OpenMenu()
{
GetWindow<MaterialWindow>();
}
private MaterialGraph m_MaterialGraph;
private Canvas2D m_Canvas = null;
private EditorWindow m_HostWindow = null;
private MaterialGraphDataSource m_DataSource;
private bool shouldRepaint
{
get
{
return m_MaterialGraph != null && m_MaterialGraph.currentGraph != null && m_MaterialGraph.currentGraph.requiresRepaint;
}
}
void Update()
{
if (shouldRepaint)
Repaint();
}
void OnSelectionChange()
{
DebugMaterialGraph("Got OnSelection Change: " + Selection.activeObject);
if (Selection.activeObject == null || !EditorUtility.IsPersistent(Selection.activeObject))
return;
if (Selection.activeObject is MaterialGraph)
{
var selection = Selection.activeObject as MaterialGraph;
DebugMaterialGraph("Selection: " + selection);
DebugMaterialGraph("Existing: " + m_MaterialGraph);
if (selection != m_MaterialGraph)
{
m_MaterialGraph = selection;
m_MaterialGraph.currentGraph.GeneratePreviewShaders();
}
}
Rebuild();
Repaint();
}
private void InitializeCanvas()
{
if (m_Canvas == null)
{
m_DataSource = new MaterialGraphDataSource();
m_Canvas = new Canvas2D(this, m_HostWindow, m_DataSource);
// draggable manipulator allows to move the canvas around. Note that individual elements can have the draggable manipulator on themselves
m_Canvas.AddManipulator(new Draggable(2, EventModifiers.None));
m_Canvas.AddManipulator(new Draggable(0, EventModifiers.Alt));
// make the canvas zoomable
m_Canvas.AddManipulator(new Zoomable());
// allow framing the selection when hitting "F" (frame) or "A" (all). Basically shows how to trap a key and work with the canvas selection
m_Canvas.AddManipulator(new Frame(Frame.FrameType.eAll));
m_Canvas.AddManipulator(new Frame(Frame.FrameType.eSelection));
// The following manipulator show how to work with canvas2d overlay and background rendering
m_Canvas.AddManipulator(new RectangleSelect());
m_Canvas.AddManipulator(new ScreenSpaceGrid());
}
Rebuild();
}
private void Rebuild()
{
if (m_Canvas == null)
return;
m_DataSource.graph = m_MaterialGraph;
m_Canvas.Clear();
m_Canvas.ReloadData();
m_Canvas.ZSort();
}
void OnGUI()
{
m_HostWindow = this;
if (m_Canvas == null)
{
InitializeCanvas();
}
if (m_MaterialGraph == null)
{
GUILayout.Label("No Graph selected");
return;
}
//m_Canvas.dataSource = m_ActiveGraph;
m_Canvas.OnGUI(this, new Rect(0, 0, position.width, position.height));
}
public static void DebugMaterialGraph(string s)
{
#if DEBUG_MAT_GEN
Debug.Log(s);
#endif
}
}
}

12
UnityProject/Assets/UnityShaderEditor/Editor/Source/Drawing/MaterialWindow.cs.meta


fileFormatVersion: 2
guid: 6f78144783978984fbcfe74ef28bd314
timeCreated: 1445419780
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

132
UnityProject/Assets/UnityShaderEditor/Editor/Source/Drawing/SimpleWidgets.cs


using UnityEditor.Experimental;
using UnityEngine;
namespace UnityEditor.MaterialGraph
{
public class SimpleBox : CanvasElement
{
protected string m_Title = "simpleBox";
public SimpleBox(Vector2 position, float size)
{
translation = position;
scale = new Vector2(size, size);
}
public override void Render(Rect parentRect, Canvas2D canvas)
{
Color backgroundColor = new Color(0.0f, 0.0f, 0.0f, 0.7f);
Color selectedColor = new Color(1.0f, 0.7f, 0.0f, 0.7f);
EditorGUI.DrawRect(new Rect(0, 0, scale.x, scale.y), selected ? selectedColor : backgroundColor );
GUI.Label(new Rect(0, 0, scale.x, 26f), GUIContent.none, new GUIStyle("preToolbar"));
GUI.Label(new Rect(10, 2, scale.x - 20.0f, 16.0f), m_Title, EditorStyles.toolbarTextField);
base.Render(parentRect, canvas);
}
}
public class MoveableBox : SimpleBox
{
public MoveableBox(Vector2 position, float size)
: base(position,size)
{
m_Title = "Drag me!";
AddManipulator(new Draggable());
}
public override void Render(Rect parentRect, Canvas2D canvas)
{
base.Render(parentRect, canvas);
}
}
class ResizableBox : SimpleBox
{
public ResizableBox(Vector2 position, float size)
: base(position, size)
{
m_Title = "Resize me!";
AddManipulator(new Resizable());
AddManipulator(new Draggable());
}
public override void Render(Rect parentRect, Canvas2D canvas)
{
base.Render(parentRect, canvas);
}
}
class WWWImageBox : SimpleBox
{
Texture2D m_WWWTexture = new Texture2D(4, 4, TextureFormat.DXT1, false);
WWW www = null;
private float timeToNextPicture = 0.0f;
public WWWImageBox(Vector2 position, float size)
: base(position, size)
{
m_Title = "I cause repaints every frame!";
AddManipulator(new Draggable());
}
public override void Render(Rect parentRect, Canvas2D canvas)
{
if (www != null && www.isDone)
{
www.LoadImageIntoTexture(m_WWWTexture);
www = null;
timeToNextPicture = 3.0f;
}
timeToNextPicture -= Time.deltaTime;
if (timeToNextPicture < 0.0f)
{
timeToNextPicture = 99999.0f;
www = new WWW("http://lorempixel.com/200/200");
}
base.Render(parentRect, canvas);
GUI.DrawTexture(new Rect(0, 20, 200, 200), m_WWWTexture);
Invalidate();
canvas.Repaint();
}
}
class IMGUIControls : SimpleBox
{
private string m_Text1 = "this is a text field";
private string m_Text2 = "this is a text field";
private bool m_Toggle = true;
private Texture2D m_aTexture = null;
public IMGUIControls(Vector2 position, float size)
: base(position, size)
{
m_Caps = Capabilities.Unselectable;
m_Title = "modal";
AddManipulator(new Draggable());
AddManipulator(new Resizable());
AddManipulator(new IMGUIContainer());
}
public override void Render(Rect parentRect, Canvas2D canvas)
{
base.Render(parentRect, canvas);
int currentY = 22;
m_Text1 = GUI.TextField(new Rect(0, currentY, 80, 20), m_Text1);
currentY += 22;
m_Toggle = GUI.Toggle(new Rect(0, currentY, 10, 10), m_Toggle, GUIContent.none);
currentY += 22;
m_Text2 = GUI.TextField(new Rect(0, currentY, 80, 20), m_Text2);
currentY += 22;
m_aTexture = EditorGUI.ObjectField(new Rect(0, currentY, 80, 100), m_aTexture, typeof(Texture2D), false) as Texture2D;
}
}
}

12
UnityProject/Assets/UnityShaderEditor/Editor/Source/Drawing/SimpleWidgets.cs.meta


fileFormatVersion: 2
guid: 3b7b58fd48ad82c49916e721dd90507a
timeCreated: 1445420224
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

126
UnityProject/Assets/UnityShaderEditor/Editor/Source/MaterialWindow.cs


#define DEBUG_MAT_GEN
using UnityEngine;
namespace UnityEditor.MaterialGraph
{
class MaterialWindow : EditorWindow
{
[MenuItem("Window/Material")]
public static void OpenMenu()
{
GetWindow<MaterialWindow>();
}
private MaterialGraph m_MaterialGraph;
private MaterialGraphGUI m_MaterialGraphGUI;
private MaterialSubGraph m_MaterialSubGraph;
private MaterialSubGraphGUI m_MaterialSubGraphGUI;
private BaseMaterialGraphGUI m_ActiveGUI;
private ScriptableObject m_ActiveGraph;
private bool shouldRepaint
{
get
{
return m_MaterialGraph != null && m_MaterialGraph.currentGraph != null && m_MaterialGraph.currentGraph.requiresRepaint
|| m_MaterialSubGraph != null && m_MaterialSubGraph.requiresRepaint;
}
}
void Update()
{
if (shouldRepaint)
Repaint();
}
void OnSelectionChange()
{
MaterialWindow.DebugMaterialGraph("Got OnSelection Change: " + Selection.activeObject);
if (Selection.activeObject == null || !EditorUtility.IsPersistent(Selection.activeObject))
return;
if (Selection.activeObject is MaterialSubGraph)
{
var selection = Selection.activeObject as MaterialSubGraph;
if (selection != m_MaterialSubGraph)
{
m_MaterialSubGraph = selection;
m_MaterialSubGraphGUI = null;
m_MaterialGraph = null;
m_MaterialSubGraph.GeneratePreviewShaders();
}
if (m_MaterialSubGraphGUI == null)
{
m_MaterialSubGraphGUI = CreateInstance<MaterialSubGraphGUI>();
m_MaterialSubGraphGUI.hideFlags = HideFlags.HideAndDontSave;
m_MaterialSubGraphGUI.graph = m_MaterialSubGraph;
}
m_ActiveGUI = m_MaterialSubGraphGUI;
m_ActiveGraph = m_MaterialSubGraph;
}
else if (Selection.activeObject is MaterialGraph)
{
var selection = Selection.activeObject as MaterialGraph;
MaterialWindow.DebugMaterialGraph("Selection: " + selection);
MaterialWindow.DebugMaterialGraph("Existing: " + m_MaterialGraph);
if (selection != m_MaterialGraph)
{
m_MaterialGraph = selection;
m_MaterialSubGraph = null;
m_MaterialGraphGUI = null;
m_MaterialGraph.currentGraph.GeneratePreviewShaders();
}
if (m_MaterialGraphGUI == null)
{
m_MaterialGraphGUI = CreateInstance<MaterialGraphGUI>();
m_MaterialGraphGUI.hideFlags = HideFlags.HideAndDontSave;
m_MaterialGraphGUI.graph = m_MaterialGraph.currentGraph;
m_MaterialGraphGUI.materialGraph = m_MaterialGraph;
}
m_ActiveGUI = m_MaterialGraphGUI;
m_ActiveGraph = m_MaterialGraph;
}
Repaint();
}
void OnGUI()
{
if (m_ActiveGraph == null || m_ActiveGUI == null)
{
GUILayout.Label("No Graph selected");
return;
}
if (m_ActiveGUI == m_MaterialGraphGUI)
{
m_MaterialGraphGUI.graph = m_MaterialGraph.currentGraph;
m_MaterialGraphGUI.materialGraph = m_MaterialGraph;
}
else if (m_ActiveGUI == m_MaterialSubGraphGUI)
{
m_MaterialSubGraphGUI.graph = m_MaterialSubGraph;
}
m_ActiveGUI.BeginGraphGUI(this, new Rect(0, 0, position.width - 300, position.height));
m_ActiveGUI.OnGraphGUI();
m_ActiveGUI.EndGraphGUI();
if (m_ActiveGUI == m_MaterialGraphGUI)
m_MaterialGraphGUI.RenderOptions(new Rect(position.width - 300, 0, 300, position.height), m_MaterialGraph);
}
public static void DebugMaterialGraph(string s)
{
#if DEBUG_MAT_GEN
Debug.Log(s);
#endif
}
}
}

8
UnityProject/Assets/UnityShaderEditor/Editor/Source/MaterialWindow.cs.meta


fileFormatVersion: 2
guid: efbdf650af539bf4f872f46d9af5d72e
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
正在加载...
取消
保存