initial commit
This commit is contained in:
parent
6715289efe
commit
788c3389af
37645 changed files with 2526849 additions and 80 deletions
|
@ -0,0 +1,21 @@
|
|||
using UnityEngine.Assertions;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
static class AssertHelpers
|
||||
{
|
||||
public static void IsNotNull(object anObject, string message)
|
||||
{
|
||||
#if SG_ASSERTIONS
|
||||
Assert.IsNotNull(anObject, message);
|
||||
#endif
|
||||
}
|
||||
|
||||
public static void Fail(string message)
|
||||
{
|
||||
#if SG_ASSERTIONS
|
||||
throw new AssertionException(message, null);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 67a39d09a4be41f686550822af7da95e
|
||||
timeCreated: 1615243771
|
|
@ -0,0 +1,51 @@
|
|||
using System;
|
||||
using UnityEngine;
|
||||
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace UnityEditor.ShaderGraph.Drawing
|
||||
{
|
||||
static class CompatibilityExtensions
|
||||
{
|
||||
#if !UNITY_2018_3_OR_NEWER
|
||||
public static void MarkDirtyRepaint(this VisualElement element)
|
||||
{
|
||||
element.Dirty(ChangeType.Repaint);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#if !UNITY_2018_3_OR_NEWER
|
||||
public static void CaptureMouse(this VisualElement element)
|
||||
{
|
||||
element.TakeMouseCapture();
|
||||
}
|
||||
|
||||
public static void ReleaseMouse(this VisualElement element)
|
||||
{
|
||||
element.ReleaseMouseCapture();
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
public static void OnToggleChanged(this Toggle toggle, EventCallback<ChangeEvent<bool>> callback)
|
||||
{
|
||||
#if UNITY_2018_3_OR_NEWER
|
||||
toggle.RegisterValueChangedCallback(callback);
|
||||
#else
|
||||
toggle.OnToggle(() => callback(ChangeEvent<bool>.GetPooled(!toggle.value, toggle.value)));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
static class TrickleDownEnum
|
||||
{
|
||||
#if UNITY_2018_3_OR_NEWER
|
||||
public static readonly TrickleDown NoTrickleDown = TrickleDown.NoTrickleDown;
|
||||
public static readonly TrickleDown TrickleDown = TrickleDown.TrickleDown;
|
||||
#else
|
||||
public static readonly Capture NoTrickleDown = Capture.NoCapture;
|
||||
public static readonly Capture TrickleDown = Capture.Capture;
|
||||
#endif
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 7c1717b624ad45ccbb3fa6bec28af711
|
||||
timeCreated: 1519741123
|
|
@ -0,0 +1,304 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEditor.Graphing;
|
||||
using UnityEngine;
|
||||
using UnityEditor.ShaderGraph;
|
||||
using UnityEditor.ShaderGraph.Internal;
|
||||
using UnityEditor.ShaderGraph.Serialization;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
enum CopyPasteGraphSource
|
||||
{
|
||||
Default,
|
||||
Duplicate
|
||||
}
|
||||
|
||||
[Serializable]
|
||||
sealed class CopyPasteGraph : JsonObject
|
||||
{
|
||||
CopyPasteGraphSource m_CopyPasteGraphSource;
|
||||
|
||||
[SerializeField]
|
||||
List<Edge> m_Edges = new List<Edge>();
|
||||
|
||||
[SerializeField]
|
||||
List<JsonData<AbstractMaterialNode>> m_Nodes = new List<JsonData<AbstractMaterialNode>>();
|
||||
|
||||
[SerializeField]
|
||||
List<JsonData<GroupData>> m_Groups = new List<JsonData<GroupData>>();
|
||||
|
||||
[SerializeField]
|
||||
List<JsonData<StickyNoteData>> m_StickyNotes = new List<JsonData<StickyNoteData>>();
|
||||
|
||||
[SerializeField]
|
||||
List<JsonRef<ShaderInput>> m_Inputs = new List<JsonRef<ShaderInput>>();
|
||||
|
||||
[SerializeField]
|
||||
List<JsonData<CategoryData>> m_Categories = new List<JsonData<CategoryData>>();
|
||||
|
||||
// The meta properties are properties that are not copied into the target graph
|
||||
// but sent along to allow property nodes to still hvae the data from the original
|
||||
// property present.
|
||||
[SerializeField]
|
||||
List<JsonData<AbstractShaderProperty>> m_MetaProperties = new List<JsonData<AbstractShaderProperty>>();
|
||||
|
||||
[SerializeField]
|
||||
List<string> m_MetaPropertyIds = new List<string>();
|
||||
|
||||
// The meta keywords are keywords that are required by keyword nodes
|
||||
// These are copied into the target graph when there is no collision
|
||||
[SerializeField]
|
||||
List<JsonData<ShaderKeyword>> m_MetaKeywords = new List<JsonData<ShaderKeyword>>();
|
||||
|
||||
[SerializeField]
|
||||
List<string> m_MetaKeywordIds = new List<string>();
|
||||
|
||||
[SerializeField]
|
||||
List<JsonData<ShaderDropdown>> m_MetaDropdowns = new List<JsonData<ShaderDropdown>>();
|
||||
|
||||
[SerializeField]
|
||||
List<string> m_MetaDropdownIds = new List<string>();
|
||||
|
||||
public CopyPasteGraph() { }
|
||||
|
||||
public CopyPasteGraph(IEnumerable<GroupData> groups,
|
||||
IEnumerable<AbstractMaterialNode> nodes,
|
||||
IEnumerable<Edge> edges,
|
||||
IEnumerable<ShaderInput> inputs,
|
||||
IEnumerable<CategoryData> categories,
|
||||
IEnumerable<AbstractShaderProperty> metaProperties,
|
||||
IEnumerable<ShaderKeyword> metaKeywords,
|
||||
IEnumerable<ShaderDropdown> metaDropdowns,
|
||||
IEnumerable<StickyNoteData> notes,
|
||||
bool keepOutputEdges = false,
|
||||
bool removeOrphanEdges = true,
|
||||
CopyPasteGraphSource copyPasteGraphSource = CopyPasteGraphSource.Default)
|
||||
{
|
||||
m_CopyPasteGraphSource = copyPasteGraphSource;
|
||||
if (groups != null)
|
||||
{
|
||||
foreach (var groupData in groups)
|
||||
AddGroup(groupData);
|
||||
}
|
||||
|
||||
if (notes != null)
|
||||
{
|
||||
foreach (var stickyNote in notes)
|
||||
AddNote(stickyNote);
|
||||
}
|
||||
|
||||
var nodeSet = new HashSet<AbstractMaterialNode>();
|
||||
|
||||
if (nodes != null)
|
||||
{
|
||||
foreach (var node in nodes.Distinct())
|
||||
{
|
||||
if (!node.canCopyNode)
|
||||
{
|
||||
throw new InvalidOperationException($"Cannot copy node {node.name} ({node.objectId}).");
|
||||
}
|
||||
|
||||
nodeSet.Add(node);
|
||||
AddNode(node);
|
||||
foreach (var edge in NodeUtils.GetAllEdges(node))
|
||||
AddEdge((Edge)edge);
|
||||
}
|
||||
}
|
||||
|
||||
if (edges != null)
|
||||
{
|
||||
foreach (var edge in edges)
|
||||
AddEdge(edge);
|
||||
}
|
||||
|
||||
if (inputs != null)
|
||||
{
|
||||
foreach (var input in inputs)
|
||||
AddInput(input);
|
||||
}
|
||||
|
||||
if (categories != null)
|
||||
{
|
||||
foreach (var category in categories)
|
||||
AddCategory(category);
|
||||
}
|
||||
|
||||
if (metaProperties != null)
|
||||
{
|
||||
foreach (var metaProperty in metaProperties.Distinct())
|
||||
AddMetaProperty(metaProperty);
|
||||
}
|
||||
|
||||
if (metaKeywords != null)
|
||||
{
|
||||
foreach (var metaKeyword in metaKeywords.Distinct())
|
||||
AddMetaKeyword(metaKeyword);
|
||||
}
|
||||
|
||||
if (metaDropdowns != null)
|
||||
{
|
||||
foreach (var metaDropdown in metaDropdowns.Distinct())
|
||||
AddMetaDropdown(metaDropdown);
|
||||
}
|
||||
|
||||
var distinct = m_Edges.Distinct();
|
||||
if (removeOrphanEdges)
|
||||
{
|
||||
distinct = distinct.Where(edge => nodeSet.Contains(edge.inputSlot.node) || (keepOutputEdges && nodeSet.Contains(edge.outputSlot.node)));
|
||||
}
|
||||
m_Edges = distinct.ToList();
|
||||
}
|
||||
|
||||
public bool IsInputCategorized(ShaderInput shaderInput)
|
||||
{
|
||||
foreach (var category in categories)
|
||||
{
|
||||
if (category.IsItemInCategory(shaderInput))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// The only situation in which an input has an identical reference name to another input in a category, while not being the same instance, is if they are duplicates
|
||||
public bool IsInputDuplicatedFromCategory(ShaderInput shaderInput, CategoryData inputCategory, GraphData targetGraphData)
|
||||
{
|
||||
foreach (var child in inputCategory.Children)
|
||||
{
|
||||
if (child.referenceName.Equals(shaderInput.referenceName, StringComparison.Ordinal) && child.objectId != shaderInput.objectId)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// Need to check if they share same graph owner as well, if not then we can early out
|
||||
bool inputBelongsToTargetGraph = targetGraphData.ContainsInput(shaderInput);
|
||||
if (inputBelongsToTargetGraph == false)
|
||||
return false;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void AddGroup(GroupData group)
|
||||
{
|
||||
m_Groups.Add(group);
|
||||
}
|
||||
|
||||
void AddNote(StickyNoteData stickyNote)
|
||||
{
|
||||
m_StickyNotes.Add(stickyNote);
|
||||
}
|
||||
|
||||
void AddNode(AbstractMaterialNode node)
|
||||
{
|
||||
m_Nodes.Add(node);
|
||||
}
|
||||
|
||||
void AddEdge(Edge edge)
|
||||
{
|
||||
m_Edges.Add(edge);
|
||||
}
|
||||
|
||||
void AddInput(ShaderInput input)
|
||||
{
|
||||
m_Inputs.Add(input);
|
||||
}
|
||||
|
||||
void AddCategory(CategoryData category)
|
||||
{
|
||||
m_Categories.Add(category);
|
||||
}
|
||||
|
||||
void AddMetaProperty(AbstractShaderProperty metaProperty)
|
||||
{
|
||||
m_MetaProperties.Add(metaProperty);
|
||||
m_MetaPropertyIds.Add(metaProperty.objectId);
|
||||
}
|
||||
|
||||
void AddMetaKeyword(ShaderKeyword metaKeyword)
|
||||
{
|
||||
m_MetaKeywords.Add(metaKeyword);
|
||||
m_MetaKeywordIds.Add(metaKeyword.objectId);
|
||||
}
|
||||
|
||||
void AddMetaDropdown(ShaderDropdown metaDropdown)
|
||||
{
|
||||
m_MetaDropdowns.Add(metaDropdown);
|
||||
m_MetaDropdownIds.Add(metaDropdown.objectId);
|
||||
}
|
||||
|
||||
public IEnumerable<T> GetNodes<T>()
|
||||
{
|
||||
return m_Nodes.SelectValue().OfType<T>();
|
||||
}
|
||||
|
||||
public DataValueEnumerable<GroupData> groups => m_Groups.SelectValue();
|
||||
|
||||
public DataValueEnumerable<StickyNoteData> stickyNotes => m_StickyNotes.SelectValue();
|
||||
|
||||
public IEnumerable<Edge> edges
|
||||
{
|
||||
get { return m_Edges; }
|
||||
}
|
||||
|
||||
public RefValueEnumerable<ShaderInput> inputs
|
||||
{
|
||||
get { return m_Inputs.SelectValue(); }
|
||||
}
|
||||
|
||||
public DataValueEnumerable<CategoryData> categories
|
||||
{
|
||||
get { return m_Categories.SelectValue(); }
|
||||
}
|
||||
|
||||
public DataValueEnumerable<AbstractShaderProperty> metaProperties
|
||||
{
|
||||
get { return m_MetaProperties.SelectValue(); }
|
||||
}
|
||||
|
||||
public DataValueEnumerable<ShaderKeyword> metaKeywords
|
||||
{
|
||||
get { return m_MetaKeywords.SelectValue(); }
|
||||
}
|
||||
|
||||
public DataValueEnumerable<ShaderDropdown> metaDropdowns
|
||||
{
|
||||
get { return m_MetaDropdowns.SelectValue(); }
|
||||
}
|
||||
|
||||
public IEnumerable<string> metaPropertyIds => m_MetaPropertyIds;
|
||||
|
||||
public IEnumerable<string> metaKeywordIds => m_MetaKeywordIds;
|
||||
|
||||
public CopyPasteGraphSource copyPasteGraphSource => m_CopyPasteGraphSource;
|
||||
|
||||
public override void OnAfterMultiDeserialize(string json)
|
||||
{
|
||||
// should we add support for versioning old CopyPasteGraphs from old versions of Unity?
|
||||
// so you can copy from old paste to new
|
||||
|
||||
foreach (var node in m_Nodes.SelectValue())
|
||||
{
|
||||
node.UpdateNodeAfterDeserialization();
|
||||
node.SetupSlots();
|
||||
}
|
||||
}
|
||||
|
||||
internal static CopyPasteGraph FromJson(string copyBuffer, GraphData targetGraph)
|
||||
{
|
||||
try
|
||||
{
|
||||
var graph = new CopyPasteGraph();
|
||||
MultiJson.Deserialize(graph, copyBuffer, targetGraph, true);
|
||||
return graph;
|
||||
}
|
||||
catch
|
||||
{
|
||||
// ignored. just means copy buffer was not a graph :(
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 187365d075d49dc46a3e09b81f0d6fdd
|
||||
timeCreated: 1483699278
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,3 @@
|
|||
namespace UnityEditor.Graphing
|
||||
{
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 2a64b792c8859f74281b897c2a1d659c
|
||||
timeCreated: 1464601236
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,22 @@
|
|||
using System.Runtime.CompilerServices;
|
||||
|
||||
[assembly: InternalsVisibleTo("Unity.ShaderGraph.Editor.Tests")]
|
||||
|
||||
namespace UnityEngine.Rendering.ShaderGraph
|
||||
{
|
||||
//Need to live in Runtime as Attribute of documentation is on Runtime classes \o/
|
||||
class Documentation : DocumentationInfo
|
||||
{
|
||||
//This must be used like
|
||||
//[HelpURL(Documentation.baseURL + Documentation.version + Documentation.subURL + "some-page" + Documentation.endURL)]
|
||||
//It cannot support String.Format nor string interpolation
|
||||
internal const string baseURL = "https://docs.unity3d.com/Packages/com.unity.shadergraph@";
|
||||
internal const string subURL = "/manual/";
|
||||
internal const string endURL = ".html";
|
||||
|
||||
internal static string GetPageLink(string pageName)
|
||||
{
|
||||
return baseURL + version + subURL + pageName + endURL;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: a567520c18010479aaafcdc0b5a358b6
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,105 @@
|
|||
using System;
|
||||
using System.IO;
|
||||
using UnityEditor.ShaderGraph.Serialization;
|
||||
using Debug = UnityEngine.Debug;
|
||||
using UnityEditor.VersionControl;
|
||||
using System.Text;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
static class FileUtilities
|
||||
{
|
||||
// if successfully written to disk, returns the serialized file contents as a string
|
||||
// on failure, returns null
|
||||
public static string WriteShaderGraphToDisk(string path, GraphData data)
|
||||
{
|
||||
if (data == null)
|
||||
{
|
||||
// Returning false may be better than throwing this exception, in terms of preserving data.
|
||||
// But if GraphData is null, it's likely we don't have any data to preserve anyways.
|
||||
// So this exception seems fine for now.
|
||||
throw new ArgumentNullException(nameof(data));
|
||||
}
|
||||
|
||||
var text = MultiJson.Serialize(data);
|
||||
if (WriteToDisk(path, text))
|
||||
return text;
|
||||
else
|
||||
return null;
|
||||
}
|
||||
|
||||
// returns true if successfully written to disk
|
||||
public static bool WriteToDisk(string path, string text)
|
||||
{
|
||||
CheckoutIfValid(path);
|
||||
|
||||
while (true)
|
||||
{
|
||||
try
|
||||
{
|
||||
File.WriteAllText(path, text);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
if (e.GetBaseException() is UnauthorizedAccessException &&
|
||||
(File.GetAttributes(path) & FileAttributes.ReadOnly) == FileAttributes.ReadOnly)
|
||||
{
|
||||
if (EditorUtility.DisplayDialog("File is Read-Only", path, "Make Writeable", "Cancel Save"))
|
||||
{
|
||||
// make writeable
|
||||
FileInfo fileInfo = new FileInfo(path);
|
||||
fileInfo.IsReadOnly = false;
|
||||
continue; // retry save
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
Debug.LogException(e);
|
||||
|
||||
if (EditorUtility.DisplayDialog("Exception While Saving", e.ToString(), "Retry", "Cancel"))
|
||||
continue; // retry save
|
||||
else
|
||||
return false;
|
||||
}
|
||||
break; // no exception, file save success!
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// returns contents of the asset file as a string, or null if any error or exception occurred
|
||||
public static string SafeReadAllText(string assetPath)
|
||||
{
|
||||
string result = null;
|
||||
try
|
||||
{
|
||||
result = File.ReadAllText(assetPath, Encoding.UTF8);
|
||||
}
|
||||
catch
|
||||
{
|
||||
result = null;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static void CheckoutIfValid(string path)
|
||||
{
|
||||
if (VersionControl.Provider.enabled && VersionControl.Provider.isActive)
|
||||
{
|
||||
var asset = VersionControl.Provider.GetAssetByPath(path);
|
||||
if (asset != null)
|
||||
{
|
||||
if (!VersionControl.Provider.IsOpenForEdit(asset))
|
||||
{
|
||||
var task = VersionControl.Provider.Checkout(asset, VersionControl.CheckoutMode.Asset);
|
||||
task.Wait();
|
||||
|
||||
if (!task.success)
|
||||
Debug.Log(task.text + " " + task.resultCode);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 0970d6d44fd28864389bbdd8dbddbf03
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,356 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace UnityEditor.ShaderGraph.Drawing
|
||||
{
|
||||
sealed class IndexSet : ICollection<int>
|
||||
{
|
||||
List<uint> m_Masks = new List<uint>();
|
||||
|
||||
public IndexSet() { }
|
||||
|
||||
public IndexSet(IEnumerable<int> indices)
|
||||
{
|
||||
foreach (var index in indices)
|
||||
Add(index);
|
||||
}
|
||||
|
||||
public IEnumerator<int> GetEnumerator()
|
||||
{
|
||||
for (var i = 0; i < m_Masks.Count; i++)
|
||||
{
|
||||
var mask = m_Masks[i];
|
||||
if (mask == 0)
|
||||
continue;
|
||||
for (var j = 0; j < 32; j++)
|
||||
{
|
||||
if ((mask & (1 << j)) > 0)
|
||||
yield return i * 32 + j;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return GetEnumerator();
|
||||
}
|
||||
|
||||
public void UnionWith(IEnumerable<int> other)
|
||||
{
|
||||
var otherSet = other as IndexSet;
|
||||
if (otherSet != null)
|
||||
{
|
||||
UnionWith(otherSet);
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var index in other)
|
||||
Add(index);
|
||||
}
|
||||
}
|
||||
|
||||
public void UnionWith(IndexSet other)
|
||||
{
|
||||
for (var i = 0; i < Math.Min(m_Masks.Count, other.m_Masks.Count); i++)
|
||||
m_Masks[i] |= other.m_Masks[i];
|
||||
for (var i = m_Masks.Count; i < other.m_Masks.Count; i++)
|
||||
m_Masks.Add(other.m_Masks[i]);
|
||||
}
|
||||
|
||||
public void IntersectWith(IEnumerable<int> other)
|
||||
{
|
||||
IntersectWith(other as IndexSet ?? new IndexSet(other));
|
||||
}
|
||||
|
||||
public void IntersectWith(IndexSet other)
|
||||
{
|
||||
for (var i = 0; i < Math.Min(m_Masks.Count, other.m_Masks.Count); i++)
|
||||
m_Masks[i] &= other.m_Masks[i];
|
||||
}
|
||||
|
||||
public void ExceptWith(IEnumerable<int> other)
|
||||
{
|
||||
var otherSet = other as IndexSet;
|
||||
if (otherSet != null)
|
||||
{
|
||||
ExceptWith(otherSet);
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var index in other)
|
||||
Remove(index);
|
||||
}
|
||||
}
|
||||
|
||||
public void ExceptWith(IndexSet other)
|
||||
{
|
||||
for (var i = 0; i < Math.Min(m_Masks.Count, other.m_Masks.Count); i++)
|
||||
m_Masks[i] &= ~other.m_Masks[i];
|
||||
}
|
||||
|
||||
public void SymmetricExceptWith(IEnumerable<int> other)
|
||||
{
|
||||
SymmetricExceptWith(other as IndexSet ?? new IndexSet(other));
|
||||
}
|
||||
|
||||
public void SymmetricExceptWith(IndexSet other)
|
||||
{
|
||||
for (var i = 0; i < Math.Min(m_Masks.Count, other.m_Masks.Count); i++)
|
||||
m_Masks[i] ^= other.m_Masks[i];
|
||||
}
|
||||
|
||||
public bool IsSubsetOf(IEnumerable<int> other)
|
||||
{
|
||||
return IsSubsetOf(other as IndexSet ?? new IndexSet(other));
|
||||
}
|
||||
|
||||
public bool IsSubsetOf(IndexSet other)
|
||||
{
|
||||
for (var i = 0; i < Math.Min(m_Masks.Count, other.m_Masks.Count); i++)
|
||||
{
|
||||
var mask = m_Masks[i];
|
||||
var otherMask = other.m_Masks[i];
|
||||
if ((mask & otherMask) != mask)
|
||||
return false;
|
||||
}
|
||||
|
||||
for (var i = other.m_Masks.Count; i < m_Masks.Count; i++)
|
||||
{
|
||||
if (m_Masks[i] > 0)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool IsSupersetOf(IEnumerable<int> other)
|
||||
{
|
||||
return IsSupersetOf(other as IndexSet ?? new IndexSet(other));
|
||||
}
|
||||
|
||||
public bool IsSupersetOf(IndexSet other)
|
||||
{
|
||||
for (var i = 0; i < Math.Min(m_Masks.Count, other.m_Masks.Count); i++)
|
||||
{
|
||||
var otherMask = other.m_Masks[i];
|
||||
var mask = m_Masks[i];
|
||||
if ((otherMask & mask) != otherMask)
|
||||
return false;
|
||||
}
|
||||
|
||||
for (var i = m_Masks.Count; i < other.m_Masks.Count; i++)
|
||||
{
|
||||
if (other.m_Masks[i] > 0)
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool IsProperSupersetOf(IEnumerable<int> other)
|
||||
{
|
||||
return IsProperSupersetOf(other as IndexSet ?? new IndexSet(other));
|
||||
}
|
||||
|
||||
public bool IsProperSupersetOf(IndexSet other)
|
||||
{
|
||||
var isProper = false;
|
||||
|
||||
for (var i = 0; i < Math.Min(m_Masks.Count, other.m_Masks.Count); i++)
|
||||
{
|
||||
var mask = m_Masks[i];
|
||||
var otherMask = other.m_Masks[i];
|
||||
if ((otherMask & mask) != otherMask)
|
||||
return false;
|
||||
if ((~otherMask & mask) > 0)
|
||||
isProper = true;
|
||||
}
|
||||
|
||||
for (var i = m_Masks.Count; i < other.m_Masks.Count; i++)
|
||||
{
|
||||
if (other.m_Masks[i] > 0)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!isProper)
|
||||
{
|
||||
for (var i = other.m_Masks.Count; i < m_Masks.Count; i++)
|
||||
{
|
||||
if (m_Masks[i] > 0)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return isProper;
|
||||
}
|
||||
|
||||
public bool IsProperSubsetOf(IEnumerable<int> other)
|
||||
{
|
||||
return IsProperSubsetOf(other as IndexSet ?? new IndexSet(other));
|
||||
}
|
||||
|
||||
public bool IsProperSubsetOf(IndexSet other)
|
||||
{
|
||||
var isProper = false;
|
||||
|
||||
for (var i = 0; i < Math.Min(m_Masks.Count, other.m_Masks.Count); i++)
|
||||
{
|
||||
var mask = m_Masks[i];
|
||||
var otherMask = other.m_Masks[i];
|
||||
if ((mask & otherMask) != mask)
|
||||
return false;
|
||||
if ((~mask & otherMask) > 0)
|
||||
isProper = true;
|
||||
}
|
||||
|
||||
for (var i = other.m_Masks.Count; i < m_Masks.Count; i++)
|
||||
{
|
||||
if (m_Masks[i] > 0)
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!isProper)
|
||||
{
|
||||
for (var i = m_Masks.Count; i < other.m_Masks.Count; i++)
|
||||
{
|
||||
if (other.m_Masks[i] > 0)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return isProper;
|
||||
}
|
||||
|
||||
public bool Overlaps(IEnumerable<int> other)
|
||||
{
|
||||
var otherSet = other as IndexSet;
|
||||
if (otherSet != null)
|
||||
return Overlaps(otherSet);
|
||||
|
||||
foreach (var index in other)
|
||||
{
|
||||
if (Contains(index))
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool Overlaps(IndexSet other)
|
||||
{
|
||||
for (var i = 0; i < Math.Min(m_Masks.Count, other.m_Masks.Count); i++)
|
||||
{
|
||||
if ((m_Masks[i] & other.m_Masks[i]) > 0)
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public bool SetEquals(IEnumerable<int> other)
|
||||
{
|
||||
var otherSet = other as IndexSet;
|
||||
if (otherSet != null)
|
||||
return SetEquals(otherSet);
|
||||
|
||||
foreach (var index in other)
|
||||
{
|
||||
if (!Contains(index))
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool SetEquals(IndexSet other)
|
||||
{
|
||||
for (var i = 0; i < Math.Min(m_Masks.Count, other.m_Masks.Count); i++)
|
||||
{
|
||||
if (m_Masks[i] != other.m_Masks[i])
|
||||
return false;
|
||||
}
|
||||
|
||||
for (var i = other.m_Masks.Count; i < m_Masks.Count; i++)
|
||||
{
|
||||
if (m_Masks[i] > 0)
|
||||
return false;
|
||||
}
|
||||
|
||||
for (var i = m_Masks.Count; i < other.m_Masks.Count; i++)
|
||||
{
|
||||
if (other.m_Masks[i] > 0)
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public bool Add(int index)
|
||||
{
|
||||
var maskIndex = index >> 5;
|
||||
var bitIndex = index & 31;
|
||||
|
||||
for (var i = m_Masks.Count; i <= maskIndex; i++)
|
||||
m_Masks.Add(0);
|
||||
|
||||
var mask = (uint)1 << bitIndex;
|
||||
var isNew = (m_Masks[maskIndex] & mask) == 0;
|
||||
m_Masks[maskIndex] |= mask;
|
||||
return isNew;
|
||||
}
|
||||
|
||||
void ICollection<int>.Add(int index)
|
||||
{
|
||||
Add(index);
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
m_Masks.Clear();
|
||||
}
|
||||
|
||||
public bool Contains(int index)
|
||||
{
|
||||
var maskIndex = index >> 5;
|
||||
var bitIndex = index & 31;
|
||||
return maskIndex < m_Masks.Count && (m_Masks[maskIndex] & ((uint)1 << bitIndex)) > 0;
|
||||
}
|
||||
|
||||
public void CopyTo(int[] array, int arrayIndex)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
public bool Remove(int index)
|
||||
{
|
||||
var maskIndex = index >> 5;
|
||||
var bitIndex = index & 31;
|
||||
if (maskIndex >= m_Masks.Count)
|
||||
return false;
|
||||
var mask = (uint)1 << bitIndex;
|
||||
var exists = (m_Masks[maskIndex] & mask) > 0;
|
||||
m_Masks[maskIndex] &= ~mask;
|
||||
return exists;
|
||||
}
|
||||
|
||||
public int Count
|
||||
{
|
||||
get
|
||||
{
|
||||
var count = 0;
|
||||
foreach (var mask in m_Masks)
|
||||
{
|
||||
for (var j = 0; j < 32; j++)
|
||||
{
|
||||
if ((mask & (1 << j)) > 0)
|
||||
count++;
|
||||
}
|
||||
}
|
||||
return count;
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsReadOnly
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 41c67c52dd54464fa78d8ab286eb501b
|
||||
timeCreated: 1514376310
|
|
@ -0,0 +1,51 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
static class ListUtilities
|
||||
{
|
||||
// Ideally, we should build a non-yield return, struct version of Slice
|
||||
public static IEnumerable<T> Slice<T>(this List<T> list, int start, int end)
|
||||
{
|
||||
for (int i = start; i < end; i++)
|
||||
yield return list[i];
|
||||
}
|
||||
|
||||
public static int RemoveAllFromRange<T>(this List<T> list, Predicate<T> match, int startIndex, int count)
|
||||
{
|
||||
// match behavior of RemoveRange
|
||||
if ((startIndex < 0) || (count < 0))
|
||||
throw new ArgumentOutOfRangeException();
|
||||
|
||||
int endIndex = startIndex + count;
|
||||
if (endIndex > list.Count)
|
||||
throw new ArgumentException();
|
||||
|
||||
int readIndex = startIndex;
|
||||
int writeIndex = startIndex;
|
||||
while (readIndex < endIndex)
|
||||
{
|
||||
T element = list[readIndex];
|
||||
bool remove = match(element);
|
||||
if (!remove)
|
||||
{
|
||||
// skip some work if nothing removed (especially if T is a large struct)
|
||||
if (writeIndex < readIndex)
|
||||
list[writeIndex] = element;
|
||||
writeIndex++;
|
||||
}
|
||||
readIndex++;
|
||||
}
|
||||
|
||||
// once we're done, we can remove the entries at the end in one operation
|
||||
int numberRemoved = readIndex - writeIndex;
|
||||
if (numberRemoved > 0)
|
||||
{
|
||||
list.RemoveRange(writeIndex, numberRemoved);
|
||||
}
|
||||
|
||||
return numberRemoved;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 8c48f9c41990b0242bcf63d2db521237
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,220 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Text;
|
||||
using UnityEditor.Rendering;
|
||||
using UnityEditor.ShaderGraph;
|
||||
using UnityEngine;
|
||||
using Object = UnityEngine.Object;
|
||||
|
||||
namespace UnityEditor.Graphing.Util
|
||||
{
|
||||
class MessageManager
|
||||
{
|
||||
public interface IErrorLog
|
||||
{
|
||||
void LogError(string message, Object context);
|
||||
void LogWarning(string message, Object context);
|
||||
}
|
||||
|
||||
protected Dictionary<object, Dictionary<string, List<ShaderMessage>>> m_Messages =
|
||||
new Dictionary<object, Dictionary<string, List<ShaderMessage>>>();
|
||||
|
||||
Dictionary<string, List<ShaderMessage>> m_Combined = new Dictionary<string, List<ShaderMessage>>();
|
||||
|
||||
public bool nodeMessagesChanged { get; private set; }
|
||||
|
||||
Dictionary<string, List<ShaderMessage>> m_FoundMessages;
|
||||
|
||||
public void AddOrAppendError(object errorProvider, string nodeId, ShaderMessage error)
|
||||
{
|
||||
if (!m_Messages.TryGetValue(errorProvider, out var messages))
|
||||
{
|
||||
messages = new Dictionary<string, List<ShaderMessage>>();
|
||||
m_Messages[errorProvider] = messages;
|
||||
}
|
||||
|
||||
List<ShaderMessage> messageList;
|
||||
if (messages.TryGetValue(nodeId, out messageList))
|
||||
{
|
||||
messageList.Add(error);
|
||||
}
|
||||
else
|
||||
{
|
||||
messages[nodeId] = new List<ShaderMessage>() { error };
|
||||
}
|
||||
|
||||
nodeMessagesChanged = true;
|
||||
}
|
||||
|
||||
// Sort messages so errors come before warnings in the list
|
||||
static int CompareMessages(ShaderMessage m1, ShaderMessage m2)
|
||||
{
|
||||
return m1.severity > m2.severity ? 1 : m2.severity > m1.severity ? -1 : 0;
|
||||
}
|
||||
|
||||
public IEnumerable<KeyValuePair<string, List<ShaderMessage>>> GetNodeMessages()
|
||||
{
|
||||
var fixedNodes = new List<string>();
|
||||
m_Combined.Clear();
|
||||
foreach (var messageMap in m_Messages)
|
||||
{
|
||||
foreach (var messageList in messageMap.Value)
|
||||
{
|
||||
if (!m_Combined.TryGetValue(messageList.Key, out var foundList))
|
||||
{
|
||||
foundList = new List<ShaderMessage>();
|
||||
m_Combined.Add(messageList.Key, foundList);
|
||||
}
|
||||
foundList.AddRange(messageList.Value);
|
||||
|
||||
if (messageList.Value.Count == 0)
|
||||
{
|
||||
fixedNodes.Add(messageList.Key);
|
||||
}
|
||||
}
|
||||
|
||||
// If all the messages from a provider for a node are gone,
|
||||
// we can now remove it from the list since that will be reported in m_Combined
|
||||
fixedNodes.ForEach(nodeId => messageMap.Value.Remove(nodeId));
|
||||
}
|
||||
|
||||
foreach (var nodeList in m_Combined)
|
||||
{
|
||||
nodeList.Value.Sort(CompareMessages);
|
||||
}
|
||||
|
||||
nodeMessagesChanged = false;
|
||||
return m_Combined;
|
||||
}
|
||||
|
||||
public void RemoveNode(string nodeId)
|
||||
{
|
||||
foreach (var messageMap in m_Messages)
|
||||
{
|
||||
nodeMessagesChanged |= messageMap.Value.Remove(nodeId);
|
||||
}
|
||||
}
|
||||
|
||||
public void ClearAllFromProvider(object messageProvider)
|
||||
{
|
||||
if (m_Messages.TryGetValue(messageProvider, out m_FoundMessages))
|
||||
{
|
||||
foreach (var messageList in m_FoundMessages)
|
||||
{
|
||||
nodeMessagesChanged |= messageList.Value.Count > 0;
|
||||
messageList.Value.Clear();
|
||||
}
|
||||
|
||||
m_FoundMessages = null;
|
||||
}
|
||||
}
|
||||
|
||||
public void ClearNodesFromProvider(object messageProvider, IEnumerable<AbstractMaterialNode> nodes)
|
||||
{
|
||||
if (m_Messages.TryGetValue(messageProvider, out m_FoundMessages))
|
||||
{
|
||||
foreach (var node in nodes)
|
||||
{
|
||||
if (m_FoundMessages.TryGetValue(node.objectId, out var messages))
|
||||
{
|
||||
nodeMessagesChanged |= messages.Count > 0;
|
||||
messages.Clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void ClearAll()
|
||||
{
|
||||
m_Messages.Clear();
|
||||
m_Combined.Clear();
|
||||
nodeMessagesChanged = false;
|
||||
}
|
||||
|
||||
void DebugPrint()
|
||||
{
|
||||
StringBuilder output = new StringBuilder("MessageMap:\n");
|
||||
foreach (var messageMap in m_Messages)
|
||||
{
|
||||
output.AppendFormat("\tFrom Provider {0}:\n", messageMap.Key.GetType());
|
||||
foreach (var messageList in messageMap.Value)
|
||||
{
|
||||
output.AppendFormat("\t\tNode {0} has {1} messages:\n", messageList.Key, messageList.Value.Count);
|
||||
foreach (var message in messageList.Value)
|
||||
{
|
||||
output.AppendFormat("\t\t\t{0}\n", message.message);
|
||||
}
|
||||
}
|
||||
}
|
||||
Debug.Log(output.ToString());
|
||||
}
|
||||
|
||||
public static void Log(string path, ShaderMessage message, Object context, IErrorLog log)
|
||||
{
|
||||
var errString = $"{message.severity} in Graph at {path} on line {message.line}: {message.message}";
|
||||
if (message.severity == ShaderCompilerMessageSeverity.Error)
|
||||
{
|
||||
log.LogError(errString, context);
|
||||
}
|
||||
else
|
||||
{
|
||||
log.LogWarning(errString, context);
|
||||
}
|
||||
}
|
||||
|
||||
public bool AnyError(Func<string, bool> nodeFilter = null)
|
||||
{
|
||||
if (m_Messages == null)
|
||||
return false;
|
||||
|
||||
foreach (var kvp in m_Messages)
|
||||
{
|
||||
var errorProvider = kvp.Key;
|
||||
var messageMap = kvp.Value;
|
||||
foreach (var kvp2 in messageMap)
|
||||
{
|
||||
var nodeId = kvp2.Key;
|
||||
List<ShaderMessage> messageList = kvp2.Value;
|
||||
if ((nodeFilter == null) || nodeFilter(nodeId))
|
||||
{
|
||||
foreach (var message in messageList)
|
||||
{
|
||||
if (message.severity == ShaderCompilerMessageSeverity.Error)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public IEnumerable<string> ErrorStrings(Func<string, bool> nodeFilter = null, ShaderCompilerMessageSeverity severity = ShaderCompilerMessageSeverity.Error)
|
||||
{
|
||||
if (m_Messages == null)
|
||||
yield break;
|
||||
|
||||
foreach (var kvp in m_Messages)
|
||||
{
|
||||
var errorProvider = kvp.Key;
|
||||
var messageMap = kvp.Value;
|
||||
foreach (var kvp2 in messageMap)
|
||||
{
|
||||
var nodeId = kvp2.Key;
|
||||
if ((nodeFilter == null) || nodeFilter(nodeId))
|
||||
{
|
||||
List<ShaderMessage> messageList = kvp2.Value;
|
||||
foreach (var message in messageList)
|
||||
{
|
||||
if (message.severity == severity)
|
||||
{
|
||||
yield return message.message;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 3536b8f2543044f72bb45c2e5dd889e9
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,68 @@
|
|||
using System;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
|
||||
namespace UnityEditor.Graphing.Util
|
||||
{
|
||||
class TypeMapper : IEnumerable<TypeMapping>
|
||||
{
|
||||
readonly Type m_FromBaseType;
|
||||
readonly Type m_ToBaseType;
|
||||
readonly Type m_FallbackType;
|
||||
readonly Dictionary<Type, Type> m_Mappings = new Dictionary<Type, Type>();
|
||||
|
||||
public TypeMapper(Type fromBaseType = null, Type toBaseType = null, Type fallbackType = null)
|
||||
{
|
||||
if (fallbackType != null && toBaseType != null && !toBaseType.IsAssignableFrom(fallbackType))
|
||||
throw new ArgumentException(string.Format("{0} does not implement or derive from {1}.", fallbackType.Name, toBaseType.Name), "fallbackType");
|
||||
m_FromBaseType = fromBaseType ?? typeof(object);
|
||||
m_ToBaseType = toBaseType;
|
||||
m_FallbackType = fallbackType;
|
||||
}
|
||||
|
||||
public void Add(TypeMapping mapping)
|
||||
{
|
||||
Add(mapping.fromType, mapping.toType);
|
||||
}
|
||||
|
||||
public void Add(Type fromType, Type toType)
|
||||
{
|
||||
if (m_FromBaseType != typeof(object) && !m_FromBaseType.IsAssignableFrom(fromType))
|
||||
{
|
||||
throw new ArgumentException(string.Format("{0} does not implement or derive from {1}.", fromType.Name, m_FromBaseType.Name), "fromType");
|
||||
}
|
||||
|
||||
if (m_ToBaseType != null && !m_ToBaseType.IsAssignableFrom(toType))
|
||||
{
|
||||
throw new ArgumentException(string.Format("{0} does not derive from {1}.", toType.Name, m_ToBaseType.Name), "toType");
|
||||
}
|
||||
|
||||
m_Mappings[fromType] = toType;
|
||||
}
|
||||
|
||||
public Type MapType(Type fromType)
|
||||
{
|
||||
Type toType = null;
|
||||
|
||||
while (toType == null && fromType != null && fromType != m_FromBaseType)
|
||||
{
|
||||
if (!m_Mappings.TryGetValue(fromType, out toType))
|
||||
fromType = fromType.BaseType;
|
||||
}
|
||||
|
||||
return toType ?? m_FallbackType;
|
||||
}
|
||||
|
||||
public IEnumerator<TypeMapping> GetEnumerator()
|
||||
{
|
||||
return m_Mappings.Select(kvp => new TypeMapping(kvp.Key, kvp.Value)).GetEnumerator();
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return GetEnumerator();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
fileFormatVersion: 2
|
||||
guid: f9c0c57b328abb94982f26ec960996d2
|
||||
timeCreated: 1485161458
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,16 @@
|
|||
using System;
|
||||
|
||||
namespace UnityEditor.Graphing.Util
|
||||
{
|
||||
class TypeMapping
|
||||
{
|
||||
public Type fromType { get; private set; }
|
||||
public Type toType { get; private set; }
|
||||
|
||||
public TypeMapping(Type fromType, Type toType)
|
||||
{
|
||||
this.fromType = fromType;
|
||||
this.toType = toType;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 53ba6b433697da6468377c205573f728
|
||||
timeCreated: 1485164640
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,81 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using UnityEngine;
|
||||
using UnityEngine.UIElements;
|
||||
|
||||
namespace UnityEditor.Graphing.Util
|
||||
{
|
||||
static class UIUtilities
|
||||
{
|
||||
public static bool ItemsReferenceEquals<T>(this IList<T> first, IList<T> second)
|
||||
{
|
||||
if (first.Count != second.Count)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
for (int i = 0; i < first.Count; i++)
|
||||
{
|
||||
if (!ReferenceEquals(first[i], second[i]))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public static int GetHashCode(params object[] objects)
|
||||
{
|
||||
return GetHashCode(objects.AsEnumerable());
|
||||
}
|
||||
|
||||
public static int GetHashCode<T>(IEnumerable<T> objects)
|
||||
{
|
||||
var hashCode = 17;
|
||||
foreach (var @object in objects)
|
||||
{
|
||||
hashCode = hashCode * 31 + (@object == null ? 79 : @object.GetHashCode());
|
||||
}
|
||||
return hashCode;
|
||||
}
|
||||
|
||||
public static IEnumerable<T> ToEnumerable<T>(this T item)
|
||||
{
|
||||
yield return item;
|
||||
}
|
||||
|
||||
public static void Add<T>(this VisualElement visualElement, T elementToAdd, Action<T> action)
|
||||
where T : VisualElement
|
||||
{
|
||||
visualElement.Add(elementToAdd);
|
||||
action(elementToAdd);
|
||||
}
|
||||
|
||||
public static IEnumerable<Type> GetTypesOrNothing(this Assembly assembly)
|
||||
{
|
||||
try
|
||||
{
|
||||
return assembly.GetTypes();
|
||||
}
|
||||
catch
|
||||
{
|
||||
return Enumerable.Empty<Type>();
|
||||
}
|
||||
}
|
||||
|
||||
public static Vector2 CalculateCentroid(IEnumerable<Vector2> nodePositions)
|
||||
{
|
||||
Vector2 centroid = Vector2.zero;
|
||||
int count = 1;
|
||||
foreach (var position in nodePositions)
|
||||
{
|
||||
centroid = centroid + (position - centroid) / count;
|
||||
++count;
|
||||
}
|
||||
return centroid;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,12 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 60ebb16e194464bce8a4975da8fd215a
|
||||
timeCreated: 1476782702
|
||||
licenseType: Pro
|
||||
MonoImporter:
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
|
@ -0,0 +1,56 @@
|
|||
using System;
|
||||
using UnityEditor.ShaderGraph.Internal;
|
||||
|
||||
namespace UnityEditor.ShaderGraph
|
||||
{
|
||||
static class ValueUtilities
|
||||
{
|
||||
public static string ToShaderString(this ShaderValueType type, string precisionToken = PrecisionUtil.Token)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case ShaderValueType.Boolean:
|
||||
return precisionToken;
|
||||
case ShaderValueType.Float:
|
||||
return precisionToken;
|
||||
case ShaderValueType.Float2:
|
||||
return $"{precisionToken}2";
|
||||
case ShaderValueType.Float3:
|
||||
return $"{precisionToken}3";
|
||||
case ShaderValueType.Float4:
|
||||
return $"{precisionToken}4";
|
||||
case ShaderValueType.Matrix2:
|
||||
return $"{precisionToken}2x2";
|
||||
case ShaderValueType.Matrix3:
|
||||
return $"{precisionToken}3x3";
|
||||
case ShaderValueType.Matrix4:
|
||||
return $"{precisionToken}4x4";
|
||||
case ShaderValueType.Integer:
|
||||
return "int";
|
||||
case ShaderValueType.Uint:
|
||||
return "uint";
|
||||
case ShaderValueType.Uint4:
|
||||
return "uint4";
|
||||
default:
|
||||
return "Error";
|
||||
}
|
||||
}
|
||||
|
||||
public static int GetVectorCount(this ShaderValueType type)
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case ShaderValueType.Float:
|
||||
return 1;
|
||||
case ShaderValueType.Float2:
|
||||
return 2;
|
||||
case ShaderValueType.Float3:
|
||||
return 3;
|
||||
case ShaderValueType.Float4:
|
||||
return 4;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
fileFormatVersion: 2
|
||||
guid: 9e9a618319be6a04bada8d206987f1e4
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
Loading…
Add table
Add a link
Reference in a new issue