当前提交
834fc657
共有 34 个文件被更改,包括 3775 次插入 和 142 次删除
-
8UnityProject/Assets/UnityShaderEditor/Editor/Source/BaseMaterialGraphGUI.cs
-
2UnityProject/Assets/UnityShaderEditor/Editor/Source/MaterialGraphGUI.cs
-
3UnityProject/Assets/UnityShaderEditor/Editor/Source/MaterialSubGraphGUI.cs
-
2UnityProject/Assets/UnityShaderEditor/Graphs/FresnelSubGraph.ShaderSubGraph
-
2UnityProject/Assets/UnityShaderEditor/Graphs/SimpleGraph.ShaderGraph
-
9UnityProject/Assets/GraphFramework.meta
-
9UnityProject/Assets/UnityShaderEditor/Editor/Source/Drawing.meta
-
9UnityProject/Assets/GraphFramework/Canvas2D.meta
-
9UnityProject/Assets/GraphFramework/Canvas2D/Editor.meta
-
1001UnityProject/Assets/GraphFramework/Canvas2D/Editor/Canvas2D.cs
-
12UnityProject/Assets/GraphFramework/Canvas2D/Editor/Canvas2D.cs.meta
-
602UnityProject/Assets/GraphFramework/Canvas2D/Editor/Graph.cs
-
12UnityProject/Assets/GraphFramework/Canvas2D/Editor/Graph.cs.meta
-
795UnityProject/Assets/GraphFramework/Canvas2D/Editor/Manipulators.cs
-
12UnityProject/Assets/GraphFramework/Canvas2D/Editor/Manipulators.cs.meta
-
481UnityProject/Assets/GraphFramework/Canvas2D/Editor/QuadTree.cs
-
12UnityProject/Assets/GraphFramework/Canvas2D/Editor/QuadTree.cs.meta
-
250UnityProject/Assets/GraphFramework/Canvas2D/Editor/UIHelpers.cs
-
12UnityProject/Assets/GraphFramework/Canvas2D/Editor/UIHelpers.cs.meta
-
9UnityProject/Assets/GraphFramework/Examples.meta
-
192UnityProject/Assets/UnityShaderEditor/Editor/Source/Drawing/DrawableMaterialNode.cs
-
12UnityProject/Assets/UnityShaderEditor/Editor/Source/Drawing/DrawableMaterialNode.cs.meta
-
37UnityProject/Assets/UnityShaderEditor/Editor/Source/Drawing/MaterialGraphDataSource.cs
-
12UnityProject/Assets/UnityShaderEditor/Editor/Source/Drawing/MaterialGraphDataSource.cs.meta
-
123UnityProject/Assets/UnityShaderEditor/Editor/Source/Drawing/MaterialWindow.cs
-
12UnityProject/Assets/UnityShaderEditor/Editor/Source/Drawing/MaterialWindow.cs.meta
-
132UnityProject/Assets/UnityShaderEditor/Editor/Source/Drawing/SimpleWidgets.cs
-
12UnityProject/Assets/UnityShaderEditor/Editor/Source/Drawing/SimpleWidgets.cs.meta
-
126UnityProject/Assets/UnityShaderEditor/Editor/Source/MaterialWindow.cs
-
8UnityProject/Assets/UnityShaderEditor/Editor/Source/MaterialWindow.cs.meta
|
|||
fileFormatVersion: 2 |
|||
guid: 8da2c542223390a47bf9ce62a39abff5 |
|||
folderAsset: yes |
|||
timeCreated: 1445418016 |
|||
licenseType: Pro |
|||
DefaultImporter: |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
fileFormatVersion: 2 |
|||
guid: 4f25b373dbd002b4ab7a964b2eb68494 |
|||
folderAsset: yes |
|||
timeCreated: 1445419779 |
|||
licenseType: Pro |
|||
DefaultImporter: |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
fileFormatVersion: 2 |
|||
guid: cc01a7f541cf1774e9e6991bdc84abde |
|||
folderAsset: yes |
|||
timeCreated: 1445092807 |
|||
licenseType: Pro |
|||
DefaultImporter: |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
fileFormatVersion: 2 |
|||
guid: b90271493180a664c9362624ff106bf8 |
|||
folderAsset: yes |
|||
timeCreated: 1445092807 |
|||
licenseType: Pro |
|||
DefaultImporter: |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
1001
UnityProject/Assets/GraphFramework/Canvas2D/Editor/Canvas2D.cs
文件差异内容过多而无法显示
查看文件
文件差异内容过多而无法显示
查看文件
|
|||
fileFormatVersion: 2 |
|||
guid: bc982d0799f6fad408afa1498d3c2341 |
|||
timeCreated: 1434119324 |
|||
licenseType: Pro |
|||
MonoImporter: |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
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); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: b38b5846fc01eb6428cd956646e8f9ca |
|||
timeCreated: 1430064400 |
|||
licenseType: Pro |
|||
MonoImporter: |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
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; |
|||
}; |
|||
} |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 7dcc2b6a82194dc4cb371cc18fad3b73 |
|||
timeCreated: 1430064400 |
|||
licenseType: Pro |
|||
MonoImporter: |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
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); |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: e371b96fe2e47f14a9210c5129c1e42f |
|||
timeCreated: 1445092875 |
|||
licenseType: Pro |
|||
MonoImporter: |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
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); |
|||
} |
|||
} |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: ee2df75d146c4ae4298b06e4f1d58da0 |
|||
timeCreated: 1430064400 |
|||
licenseType: Pro |
|||
MonoImporter: |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
fileFormatVersion: 2 |
|||
guid: e2cbda12d8ee5324ba86a9be383f8e89 |
|||
folderAsset: yes |
|||
timeCreated: 1445093418 |
|||
licenseType: Pro |
|||
DefaultImporter: |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
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; |
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 476f6813876d1d04387dfa9640d44324 |
|||
timeCreated: 1445419780 |
|||
licenseType: Pro |
|||
MonoImporter: |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
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));
|
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 194f855484623804c819a9132a24268f |
|||
timeCreated: 1445419780 |
|||
licenseType: Pro |
|||
MonoImporter: |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
#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
|
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 6f78144783978984fbcfe74ef28bd314 |
|||
timeCreated: 1445419780 |
|||
licenseType: Pro |
|||
MonoImporter: |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
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; |
|||
|
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: 3b7b58fd48ad82c49916e721dd90507a |
|||
timeCreated: 1445420224 |
|||
licenseType: Pro |
|||
MonoImporter: |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
|||
assetBundleName: |
|||
assetBundleVariant: |
|
|||
#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
|
|||
} |
|||
} |
|||
} |
|
|||
fileFormatVersion: 2 |
|||
guid: efbdf650af539bf4f872f46d9af5d72e |
|||
MonoImporter: |
|||
serializedVersion: 2 |
|||
defaultReferences: [] |
|||
executionOrder: 0 |
|||
icon: {instanceID: 0} |
|||
userData: |
撰写
预览
正在加载...
取消
保存
Reference in new issue