Repository: aphex-/BrotherhoodOfNode
Branch: master
Commit: fbe19619f046
Files: 148
Total size: 144.4 KB
Directory structure:
gitextract_511m9k8r/
├── .gitignore
├── Assets/
│ ├── Code/
│ │ ├── Bon/
│ │ │ ├── BonConfig.cs
│ │ │ ├── BonConfig.cs.meta
│ │ │ ├── BonLauncher.cs
│ │ │ ├── BonLauncher.cs.meta
│ │ │ ├── Edge.cs
│ │ │ ├── Edge.cs.meta
│ │ │ ├── EventManager.cs
│ │ │ ├── EventManager.cs.meta
│ │ │ ├── Graph.cs
│ │ │ ├── Graph.cs.meta
│ │ │ ├── Interface/
│ │ │ │ ├── IColorSampler.cs
│ │ │ │ ├── IColorSampler.cs.meta
│ │ │ │ ├── INumberSampler.cs
│ │ │ │ ├── INumberSampler.cs.meta
│ │ │ │ ├── IStringSampler.cs
│ │ │ │ ├── IStringSampler.cs.meta
│ │ │ │ ├── IUpdateable.cs
│ │ │ │ ├── IUpdateable.cs.meta
│ │ │ │ ├── IVectorSampler.cs
│ │ │ │ └── IVectorSampler.cs.meta
│ │ │ ├── Interface.meta
│ │ │ ├── Log.cs
│ │ │ ├── Log.cs.meta
│ │ │ ├── Node.cs
│ │ │ ├── Node.cs.meta
│ │ │ ├── Nodes/
│ │ │ │ ├── AbstractColorNode.cs
│ │ │ │ ├── AbstractColorNode.cs.meta
│ │ │ │ ├── AbstractNumberNode.cs
│ │ │ │ ├── AbstractNumberNode.cs.meta
│ │ │ │ ├── AbstractStringNode.cs
│ │ │ │ ├── AbstractStringNode.cs.meta
│ │ │ │ ├── AbstractVector3Node.cs
│ │ │ │ ├── AbstractVector3Node.cs.meta
│ │ │ │ ├── Color/
│ │ │ │ │ ├── ColorNode.cs
│ │ │ │ │ ├── ColorNode.cs.meta
│ │ │ │ │ ├── GradientNode.cs
│ │ │ │ │ └── GradientNode.cs.meta
│ │ │ │ ├── Color.meta
│ │ │ │ ├── Geometry/
│ │ │ │ │ ├── LandscapeNode.cs
│ │ │ │ │ ├── LandscapeNode.cs.meta
│ │ │ │ │ ├── ModelNode.cs
│ │ │ │ │ └── ModelNode.cs.meta
│ │ │ │ ├── Geometry.meta
│ │ │ │ ├── NodeUtils.cs
│ │ │ │ ├── NodeUtils.cs.meta
│ │ │ │ ├── Noise/
│ │ │ │ │ ├── AbstractNoiseNode.cs
│ │ │ │ │ ├── AbstractNoiseNode.cs.meta
│ │ │ │ │ ├── NoiseDisplayNode.cs
│ │ │ │ │ ├── NoiseDisplayNode.cs.meta
│ │ │ │ │ ├── OctaveNode.cs
│ │ │ │ │ ├── OctaveNode.cs.meta
│ │ │ │ │ ├── SineMapNode.cs
│ │ │ │ │ ├── SineMapNode.cs.meta
│ │ │ │ │ ├── Special.meta
│ │ │ │ │ ├── TextureUpdateJob.cs
│ │ │ │ │ ├── TextureUpdateJob.cs.meta
│ │ │ │ │ ├── UnityPerlinNoiseNode.cs
│ │ │ │ │ └── UnityPerlinNoiseNode.cs.meta
│ │ │ │ ├── Noise.meta
│ │ │ │ ├── Number/
│ │ │ │ │ ├── AbsNode.cs
│ │ │ │ │ ├── AbsNode.cs.meta
│ │ │ │ │ ├── ConditionNode.cs
│ │ │ │ │ ├── ConditionNode.cs.meta
│ │ │ │ │ ├── LimitNode.cs
│ │ │ │ │ ├── LimitNode.cs.meta
│ │ │ │ │ ├── MixNode.cs
│ │ │ │ │ ├── MixNode.cs.meta
│ │ │ │ │ ├── NumberDisplayNode.cs
│ │ │ │ │ ├── NumberDisplayNode.cs.meta
│ │ │ │ │ ├── NumberMultiNode.cs
│ │ │ │ │ ├── NumberMultiNode.cs.meta
│ │ │ │ │ ├── NumberOperatorNode.cs
│ │ │ │ │ ├── NumberOperatorNode.cs.meta
│ │ │ │ │ ├── PowNode.cs
│ │ │ │ │ ├── PowNode.cs.meta
│ │ │ │ │ ├── RangeNode.cs
│ │ │ │ │ ├── RangeNode.cs.meta
│ │ │ │ │ ├── SineNode.cs
│ │ │ │ │ ├── SineNode.cs.meta
│ │ │ │ │ ├── SingleNumberSampler.cs
│ │ │ │ │ └── SingleNumberSampler.cs.meta
│ │ │ │ ├── Number.meta
│ │ │ │ ├── Scatter/
│ │ │ │ │ ├── GridScatterNode.cs
│ │ │ │ │ └── GridScatterNode.cs.meta
│ │ │ │ ├── Scatter.meta
│ │ │ │ ├── String/
│ │ │ │ │ ├── StringNode.cs
│ │ │ │ │ └── StringNode.cs.meta
│ │ │ │ ├── String.meta
│ │ │ │ ├── Vector3/
│ │ │ │ │ ├── OperatorNode.cs
│ │ │ │ │ ├── OperatorNode.cs.meta
│ │ │ │ │ ├── RamdomOffsetNode.cs
│ │ │ │ │ ├── RamdomOffsetNode.cs.meta
│ │ │ │ │ ├── SplitNode.cs
│ │ │ │ │ ├── SplitNode.cs.meta
│ │ │ │ │ ├── Vector3DisplayColorSampler.cs
│ │ │ │ │ ├── Vector3DisplayColorSampler.cs.meta
│ │ │ │ │ ├── Vector3Node.cs
│ │ │ │ │ └── Vector3Node.cs.meta
│ │ │ │ └── Vector3.meta
│ │ │ ├── Nodes.meta
│ │ │ ├── Socket/
│ │ │ │ ├── AbstractSocket.cs
│ │ │ │ ├── AbstractSocket.cs.meta
│ │ │ │ ├── InputSocket.cs
│ │ │ │ ├── InputSocket.cs.meta
│ │ │ │ ├── OutputSocket.cs
│ │ │ │ └── OutputSocket.cs.meta
│ │ │ ├── Socket.meta
│ │ │ ├── StandardGraphController.cs
│ │ │ ├── StandardGraphController.cs.meta
│ │ │ ├── Thread/
│ │ │ │ ├── GUIThreadedTexture.cs
│ │ │ │ ├── GUIThreadedTexture.cs.meta
│ │ │ │ ├── ThreadedJob.cs
│ │ │ │ └── ThreadedJob.cs.meta
│ │ │ └── Thread.meta
│ │ └── Bon.meta
│ ├── Code.meta
│ ├── Editor/
│ │ ├── Bon/
│ │ │ ├── BonCanvas.cs
│ │ │ ├── BonCanvas.cs.meta
│ │ │ ├── EditorZoomArea.cs
│ │ │ ├── EditorZoomArea.cs.meta
│ │ │ ├── RectExtensions.cs
│ │ │ └── RectExtensions.cs.meta
│ │ ├── Bon.meta
│ │ ├── BonWindow.cs
│ │ └── BonWindow.cs.meta
│ ├── Editor.meta
│ ├── Untitled.unity
│ └── Untitled.unity.meta
├── LICENSE.txt
├── ProjectSettings/
│ ├── AudioManager.asset
│ ├── ClusterInputManager.asset
│ ├── DynamicsManager.asset
│ ├── EditorBuildSettings.asset
│ ├── EditorSettings.asset
│ ├── GraphicsSettings.asset
│ ├── InputManager.asset
│ ├── NavMeshAreas.asset
│ ├── NetworkManager.asset
│ ├── Physics2DSettings.asset
│ ├── ProjectSettings.asset
│ ├── ProjectVersion.txt
│ ├── QualitySettings.asset
│ ├── TagManager.asset
│ ├── TimeManager.asset
│ ├── UnityAdsSettings.asset
│ └── UnityConnectSettings.asset
└── README.md
================================================
FILE CONTENTS
================================================
================================================
FILE: .gitignore
================================================
/[Ll]ibrary/
/[Tt]emp/
/[Oo]bj/
/[Bb]uild/
/[Bb]uilds/
/Assets/AssetStoreTools*
/Assets/UnityTestTools*
/Assets/UnityTestTools.meta
# Autogenerated VS/MD solution and project files
ExportedObj/
*.csproj
*.unityproj
*.sln
*.suo
*.tmp
*.user
*.userprefs
*.pidb
*.booproj
*.svd
# Unity3D generated meta files
*.pidb.meta
# Unity3D Generated File On Crash Reports
sysinfo.txt
# Builds
*.apk
*.unitypackage
# IDE: JetBrains Rider EAP
.idea
# OSX
.DS_Store
================================================
FILE: Assets/Code/Bon/BonConfig.cs
================================================
namespace Assets.Code.Bon
{
public static class BonConfig
{
public static int Version = 1;
public static int LogLevel = 1;
public static int SocketSize = 15;
public static int SocketOffsetTop = 20;
public static int SocketMargin = 5;
public static int EdgeTangent = 50;
public static string DefaultGraphName = "default";
public static string GameObjectName = "Bon";
}
}
================================================
FILE: Assets/Code/Bon/BonConfig.cs.meta
================================================
fileFormatVersion: 2
guid: 0ddf11f69c16c460a924b58c4122315a
timeCreated: 1466621268
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Code/Bon/BonLauncher.cs
================================================
using System.Collections.Generic;
using UnityEngine;
using Assets.Code.Bon.Nodes;
using Assets.Code.Bon.Nodes.Noise;
using Assets.Code.Bon.Nodes.Number;
using Assets.Code.Bon.Socket;
namespace Assets.Code.Bon
{
///
/// A class to controll the creation of Graphs. It contains loaded Grpahs.
/// (A gameobject with this script is created by the editor if it is not in the scene)
///
[ExecuteInEditMode]
[System.Serializable]
public class BonLauncher : MonoBehaviour
{
private List _graphs = new List();
private StandardGraphController _controller;
public List Graphs
{
get { return _graphs; }
}
///
/// Loads a graph by its path, adds it to the internal list
/// and returns it.
/// (Also used by the editor to open Graphs)
///
public Graph LoadGraph(string path)
{
Graph g;
if (path.Equals(BonConfig.DefaultGraphName)) g = CreateDefaultGraph();
else g = Graph.Load(path);
g.Name = path;
Graphs.Add(g);
CreateGraphController(g);
g.UpdateNodes();
return g;
}
///
/// Saves a graph by its path.
/// (Also used by the editor to save Graphs)
///
public void SaveGraph(Graph g, string path)
{
Graph.Save(path, g);
}
///
/// Removes a Graph from the internal list.
/// (Also used by the editor to close Graphs)
///
public void RemoveGraph(Graph g)
{
Graphs.Remove(g);
}
///
/// Returns the graph at the index
///
public Graph GetGraph(int index)
{
return Graphs[index];
}
///
/// Create a controller for the assigned Graph.
///
private void CreateGraphController(Graph graph)
{
// in this case we create one controller for all graphs
// you could also create different controllers for different graphs
//if (_controller == null) _controller = new StandardGraphController();
}
public void OnEnable()
{
if (_controller == null) _controller = new StandardGraphController();
_controller.Register();
foreach (var graph in Graphs)
{
graph.ResetVisitCount();
}
}
///
/// Creates a default Graph.
/// (see: BonConfig.DefaultGraphName)
///
public Graph CreateDefaultGraph()
{
Graph graph = new Graph();
// Number Nodes
var operator01 = (NumberOperatorNode) graph.CreateNode();
operator01.X = 200;
operator01.Y = 40;
operator01.SetMode(Operator.Add);
graph.AddNode(operator01);
var diplay01 = (NumberDisplayNode) graph.CreateNode();
diplay01.X = 330;
diplay01.Y = 80;
graph.AddNode(diplay01);
graph.Link(
(InputSocket) diplay01.GetSocket(typeof(AbstractNumberNode), typeof(InputSocket), 0),
(OutputSocket) operator01.GetSocket(typeof(AbstractNumberNode), typeof(OutputSocket), 0));
// Map2D Nodes
var perlinNoise = graph.CreateNode();
perlinNoise.X = 80;
perlinNoise.Y = 250;
graph.AddNode(perlinNoise);
var displayMap = graph.CreateNode();
displayMap.X = 300;
displayMap.Y = 280;
graph.AddNode(displayMap);
graph.Link(
(InputSocket) displayMap.GetSocket(typeof(AbstractNumberNode), typeof(InputSocket), 0),
(OutputSocket) perlinNoise.GetSocket(typeof(AbstractNumberNode), typeof(OutputSocket), 0));
// == test serialization an deserialization ==
var serializedJSON = graph.ToJson();
var deserializedGraph = Graph.FromJson(serializedJSON);
// =====
return deserializedGraph;
}
}
}
================================================
FILE: Assets/Code/Bon/BonLauncher.cs.meta
================================================
fileFormatVersion: 2
guid: e38ce1fc262ac4cfc85e55f297ffc7b8
timeCreated: 1466621268
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Code/Bon/Edge.cs
================================================
using System;
using Assets.Code.Bon.Socket;
using UnityEditor;
using UnityEngine;
namespace Assets.Code.Bon
{
public class Edge
{
public InputSocket Input;
public OutputSocket Output;
// cached vectors for drawing
private Vector2 _tmpStartPos;
private Vector2 _tmpEndPos;
private Vector2 _tmpTangent01;
private Vector2 _tmpTangent02;
public Edge(OutputSocket outputSocket, InputSocket inputSocket)
{
Input = inputSocket;
Output = outputSocket;
}
public AbstractSocket GetOtherSocket(AbstractSocket socket)
{
if (socket == Input) return Output;
return Input;
}
public void Draw()
{
if (Input != null && Output != null)
{
_tmpStartPos = GetEdgePosition(Output, _tmpStartPos);
_tmpEndPos = GetEdgePosition(Input, _tmpEndPos);
_tmpTangent01 = GetTangentPosition(Output, _tmpStartPos);
_tmpTangent02 = GetTangentPosition(Input, _tmpEndPos);
DrawEdge(_tmpStartPos, _tmpTangent01, _tmpEndPos, _tmpTangent02, Output.Type);
Handles.color = Color.black;
_tmpStartPos.Set(_tmpEndPos.x - 5, _tmpEndPos.y - 5);
Handles.DrawLine(_tmpEndPos, _tmpStartPos);
_tmpStartPos.Set(_tmpEndPos.x - 5, _tmpEndPos.y + 5);
Handles.DrawLine(_tmpEndPos, _tmpStartPos);
}
}
public static void DrawEdge(Vector2 position01, Vector2 tangent01, Vector2 position02, Vector2 tangent02, Type type)
{
Handles.DrawBezier(
position01, position02,
tangent01, tangent02, Color.black, null, 6);
Handles.DrawBezier(
position01, position02,
tangent01, tangent02, Node.GetEdgeColor(type), null, 3);
}
public static Vector2 GetEdgePosition(AbstractSocket socket, Vector2 position)
{
if (socket.Parent.Collapsed)
{
float width = BonConfig.SocketSize;
if (socket.IsOutput()) width = 0;
position.Set(socket.X + width, socket.Parent.WindowRect.y + 8);
}
else
{
float width = 0;
if (socket.IsOutput()) width = BonConfig.SocketSize;
position.Set(socket.X + width, socket.Y + BonConfig.SocketSize / 2f);
}
return position;
}
public static Vector2 GetTangentPosition(AbstractSocket socket, Vector2 position)
{
if (socket.IsInput()) return position + Vector2.left*BonConfig.EdgeTangent;
return position + Vector2.right*BonConfig.EdgeTangent;
}
///Creates a serializable version of this edge.
/// A serializable version of this edge.
public SerializableEdge ToSerializedEgde()
{
SerializableEdge s = new SerializableEdge();
s.InputNodeId = Input.Parent.Id;
s.InputSocketIndex = Input.Parent.Sockets.IndexOf(Input);
s.OutputNodeId = Output.Parent.Id;
s.OutputSocketIndex = Output.Parent.Sockets.IndexOf(Output);
return s;
}
}
[Serializable] public class SerializableEdge
{
[SerializeField] public int OutputNodeId = -1;
[SerializeField] public int OutputSocketIndex = -1;
[SerializeField] public int InputNodeId = -1;
[SerializeField] public int InputSocketIndex = -1;
}
}
================================================
FILE: Assets/Code/Bon/Edge.cs.meta
================================================
fileFormatVersion: 2
guid: 2ad1c6a7475ad4b63b637085f23cc8ed
timeCreated: 1466621268
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Code/Bon/EventManager.cs
================================================
using UnityEngine;
using System.Collections;
using Assets.Code.Bon;
public class EventManager
{
public delegate void GraphAction(Graph graph);
public delegate void EdgeAction(Graph graph, Edge edge);
public delegate void SocketAction(Graph graph, AbstractSocket s01, AbstractSocket s02);
public delegate void NodeAction(Graph graph, Node node);
public delegate void WindowAction();
public static event GraphAction OnCreateGraph;
public static event GraphAction OnFocusGraph;
public static event GraphAction OnCloseGraph;
public static event EdgeAction OnLinkEdge;
public static event SocketAction OnUnLinkSockets;
public static event SocketAction OnUnLinkedSockets;
public static event NodeAction OnAddedNode;
public static event NodeAction OnChangedNode;
public static event NodeAction OnFocusNode;
public static event NodeAction OnNodeRemoved;
public static event WindowAction OnEditorWindowOpen;
public static void TriggerOnCreateGraph(Graph graph)
{
if (OnCreateGraph != null) OnCreateGraph(graph);
}
public static void TriggerOnFocusGraph(Graph graph)
{
if (OnFocusGraph != null) OnFocusGraph(graph);
}
public static void TriggerOnCloseGraph(Graph graph)
{
if (OnCloseGraph != null) OnCloseGraph(graph);
}
public static void TriggerOnLinkEdge(Graph graph, Edge edge)
{
if (OnLinkEdge != null) OnLinkEdge(graph, edge);
}
public static void TriggerOnUnLinkSockets(Graph graph, AbstractSocket socket01, AbstractSocket socket02)
{
if (OnUnLinkSockets != null) OnUnLinkSockets(graph, socket01, socket02);
}
public static void TriggerOnUnLinkedSockets(Graph graph, AbstractSocket socket01, AbstractSocket socket02)
{
if (OnUnLinkedSockets != null) OnUnLinkedSockets(graph, socket01, socket02);
}
public static void TriggerOnAddedNode(Graph graph, Node node)
{
if (OnAddedNode != null) OnAddedNode(graph, node);
}
public static void TriggerOnChangedNode(Graph graph, Node node)
{
if (OnChangedNode != null) OnChangedNode(graph, node);
}
public static void TriggerOnFocusNode(Graph graph, Node node)
{
if (OnFocusNode != null) OnFocusNode(graph, node);
}
public static void TriggerOnNodeRemoved(Graph graph, Node node)
{
if (OnNodeRemoved != null) OnNodeRemoved(graph, node);
}
public static void TriggerOnWindowOpen()
{
if (OnEditorWindowOpen != null) OnEditorWindowOpen();
}
}
================================================
FILE: Assets/Code/Bon/EventManager.cs.meta
================================================
fileFormatVersion: 2
guid: eb8c51ff08ff34381af21f090ee787a0
timeCreated: 1470310655
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Code/Bon/Graph.cs
================================================
using System;
using System.Collections.Generic;
using System.IO;
using Assets.Code.Bon.Nodes;
using Assets.Code.Bon.Socket;
using UnityEngine;
namespace Assets.Code.Bon
{
[Serializable]
public class Graph : ISerializationCallbackReceiver
{
[SerializeField] public string Name;
private List _nodes = new List();
[HideInInspector] [SerializeField] private List _serializedEdges = new List();
[HideInInspector] [SerializeField] private List _serializedNodes = new List();
[SerializeField] public int Version = BonConfig.Version;
// be warned to allow circles.. if you parse the graph you can end up in
// an endless recursion this can crash unity.
[HideInInspector] [SerializeField] public bool AllowCicles = false;
private bool _invalidating;
private bool _needsUpdate = true; [NonSerialized] public bool TriggerEvents = true;
/// Returns an id for a Node that is unique for this Graph.
/// An id for a Node that is unique for this Graph.
public int ObtainUniqueNodeId()
{
var tmpId = 0;
while (GetNode(tmpId) != null) tmpId++;
return tmpId;
}
/// Creates a Node of the given type. Type must inherit from Node.
/// Does not add the Node to the Graph.
/// The created Node of the given Type.
public Node CreateNode()
{
return CreateNode(ObtainUniqueNodeId());
}
/// Creates a Node of the given type with the assigned id. Type must inherit from Node.
/// Does not add the Node to the Graph.
/// The created Node of the given Type with the assigned id.
public Node CreateNode(int id)
{
return CreateNode(typeof(T), id);
}
/// Creates a Node of the given type. Type must inherit from Node.
/// Does not add the Node to the Graph.
/// The Type of the Node to create.
/// The created Node of the given Type.
public Node CreateNode(Type type)
{
return CreateNode(type, ObtainUniqueNodeId());
}
/// Creates a Node of the given type with the assigned id. Type must inherit from Node.
/// Does not add the Node to the Graph.
/// The Type of the Node to create.
/// The id of the Node to create.
/// The created Node of the given Type with the assigned id.
public Node CreateNode(Type type, int id)
{
if (type == null) return null;
_needsUpdate = true;
try
{
return (Node) Activator.CreateInstance(type, id, this);
}
catch (Exception exception)
{
Debug.LogErrorFormat("Node {0} could not be created " + exception.Message, type.FullName);
}
return null;
}
/// Returns the Node with the assigned id or null.
/// The id of the Node to get.
/// The Node with the assigned id or null.
public Node GetNode(int nodeId)
{
if (_nodes == null) return null;
foreach (var node in _nodes) if (node.Id == nodeId) return node;
return null;
}
/// Returns the count of Nodes in this Graph.
/// The count of Nodes in this Graph.
public int GetNodeCount()
{
return _nodes.Count;
}
/// Returns the Node at the assigned index.
/// The index of the Node to get.
/// The Node at the assigned index.
public Node GetNodeAt(int index)
{
if (index >= _nodes.Count) return null;
return _nodes[index];
}
/// Adds a node to the Graph. Does not add Nodes with an id that is already taken.
/// Triggers a 'AddedNode' event.
/// The Node to add.
/// True if the node was added.
public bool AddNode(Node node)
{
if (GetNode(node.Id) != null) return false;
_needsUpdate = true;
_nodes.Add(node);
if (TriggerEvents) EventManager.TriggerOnAddedNode(this, node);
return true;
}
/// Removes the assigned Node from this Graph.
/// The Node to remove.
/// True if the Node was removed.
public bool RemoveNode(Node node)
{
if (node == null) return false;
_needsUpdate = true;
foreach (var socket in node.Sockets) UnLink(socket);
bool removed = _nodes.Remove(node);
if (TriggerEvents) EventManager.TriggerOnNodeRemoved(this, node);
return removed;
}
/// Removes the Node with the assigned id from this Graph.
/// The id of the Node to remove.
/// True if the Node was removed.
public bool RemoveNode(int id)
{
return RemoveNode(GetNode(id));
}
public bool AreConected(InputSocket inputSocket, OutputSocket outputSocket)
{
if (inputSocket == null || outputSocket == null || inputSocket.Edge == null || outputSocket.Edges.Count == 0) return false;
return outputSocket.Edges.Contains(inputSocket.Edge);
}
/// Unlinkes the assigned sockets. Triggeres 'Unlink' events.
public void UnLink(InputSocket inputSocket, OutputSocket outputSocket)
{
_needsUpdate = true;
if (inputSocket == null || outputSocket == null || !inputSocket.IsConnected() || !outputSocket.IsConnected()) return;
if (!AreConected(inputSocket, outputSocket)) return;
if (TriggerEvents)
{
EventManager.TriggerOnUnLinkSockets(this, inputSocket, outputSocket);
}
var index = outputSocket.Edges.IndexOf(inputSocket.Edge);
if (index > -1)
{
outputSocket.Edges[index].Input = null;
outputSocket.Edges[index].Output = null;
outputSocket.Edges.RemoveAt(index);
}
inputSocket.Edge.Input = null;
inputSocket.Edge.Output = null;
inputSocket.Edge = null;
if (TriggerEvents)
{
EventManager.TriggerOnUnLinkedSockets(this, inputSocket, outputSocket);
}
}
public void UnLink(AbstractSocket socket)
{
if (socket == null || !socket.IsConnected()) return;
if (socket.IsInput())
{
InputSocket inputSocket = (InputSocket) socket;
if (inputSocket.Edge != null) UnLink(inputSocket, inputSocket.Edge.Output);
}
if (socket.IsOutput())
{
OutputSocket outputSocket = (OutputSocket) socket;
Edge[] edgeCopy = new Edge[outputSocket.Edges.Count];
outputSocket.Edges.CopyTo(edgeCopy);
foreach (var edge in edgeCopy)
{
UnLink(edge.Input, outputSocket);
}
}
}
public bool Link(InputSocket inputSocket, OutputSocket outputSocket)
{
if (!CanBeLinked(inputSocket, outputSocket))
{
Debug.LogWarning("Sockets can not be linked.");
return false;
}
_needsUpdate = true;
if (inputSocket.Type == outputSocket.Type)
{
Edge edge = new Edge(outputSocket, inputSocket);
Edge oldEdge = inputSocket.Edge;
inputSocket.Edge = edge;
outputSocket.Edges.Add(edge);
if (!AllowCicles && HasCycle())
{
// revert
inputSocket.Edge = oldEdge;
outputSocket.Edges.Remove(edge);
Log.Info("Can not link sockets. Circles are not allowed.");
return false;
}
if (TriggerEvents)
{
EventManager.TriggerOnLinkEdge(this, edge);
}
}
return true;
}
private void StartVisitRun()
{
if (_invalidating)
{
throw new UnityException ("Graph is already invalidating");
}
_invalidating = true;
ResetVisitCount();
}
public void ResetVisitCount()
{
foreach (var node in _nodes)
{
node.VisitCount = 0;
}
}
private void EndVisitRun()
{
_invalidating = false;
}
public bool HasCycle() {
foreach (var node in _nodes)
{
StartVisitRun(); // resets visit counter
bool foundCicle = IsConnectedToItself(node);
EndVisitRun();
if (foundCicle) return true;
}
return false;
}
///
/// This method returns true is a node is connected to itself along the output path.
/// Reset the 'VisitCount' counter of each node before calling! Call this
/// method ignoring the optional parameter. This is used internaly for recursion.
/// The node you want to check
/// Do not use this parameter or assign null
///
private bool IsConnectedToItself(Node searchForNode, Node recursionNode = null)
{
bool firstRun = recursionNode == null;
if (firstRun) recursionNode = searchForNode;
if (!firstRun && recursionNode == searchForNode) return true; // visited the first node after recursion
if (recursionNode.VisitCount > 0) return false; // already checked
recursionNode.VisitCount++;
foreach (var socket in recursionNode.Sockets) // follow the OutputSockets of the node
{
if (socket.IsOutput() && socket.IsConnected())
{
OutputSocket outputSocket = (OutputSocket) socket;
foreach (var edge in outputSocket.Edges) // check every edge
{
if (edge.Input.Parent != null && IsConnectedToItself(searchForNode, edge.Input.Parent)) return true;
}
}
}
return false;
}
public void UpdateDependingNodes(Node node)
{
StartVisitRun();
UpdateOutputPath(node);
EndVisitRun();
}
///
/// This method follows the ouput path of the node and updates all visited nodes.
/// Reset the 'VisitCount' counter of each node before calling!
///
/// The node to update and its ouput path nodes
private void UpdateOutputPath(Node node)
{
if (node.VisitCount > 0) return; // already updated
node.Update();
node.VisitCount++;
foreach (var socket in node.Sockets) // follow the OutputSockets of the node
{
if (socket.IsOutput() && socket.IsConnected())
{
OutputSocket outputSocket = (OutputSocket) socket;
foreach (var edge in outputSocket.Edges)
{
UpdateOutputPath(edge.Input.Parent);
}
}
}
}
/// Returns true if the sockets can be linked.
/// The input socket
/// The output socket
/// True if the sockets can be linked.
public bool CanBeLinked(InputSocket inSocket, OutputSocket outSocket)
{
return inSocket != null && outSocket != null && outSocket.Type == inSocket.Type;
}
public void LogCircleError()
{
Debug.LogError("The graph contains ciclyes.");
}
// === SERIALIZATION ===
public string ToJson()
{
return JsonUtility.ToJson(this);
}
public static Graph FromJson(string json)
{
Graph g = JsonUtility.FromJson(json);
//listener.OnCreate(g);
EventManager.TriggerOnCreateGraph(g);
return g;
}
public static bool Save(string fileName, Graph graph)
{
var file = File.CreateText(fileName);
file.Write((string) graph.ToJson());
file.Close();
return true;
}
public static Graph Load(string fileName)
{
if(File.Exists(fileName)){
var file = File.OpenText(fileName);
var json = file.ReadToEnd();
file.Close();
Graph deserializedGraph = FromJson(json);
if (deserializedGraph.Version != BonConfig.Version)
{
Debug.LogWarning("You loading a graph with a different version number: " + deserializedGraph.Version +
" the current version is " + BonConfig.Version);
}
return deserializedGraph;
} else {
Debug.Log("Could not Open the file: " + fileName);
return null;
}
}
public void UpdateNodes()
{
if (!_needsUpdate) return;
foreach (var node in _nodes)
{
node.Update();
}
_needsUpdate = false;
}
public void ForceUpdateNodes()
{
_needsUpdate = true;
UpdateNodes ();
}
/// Unity serialization callback.
public void OnBeforeSerialize()
{
if (_nodes.Count == 0) return; // nothing to serialize
bool wasTriggering = TriggerEvents;
TriggerEvents = false;
_serializedEdges.Clear();
_serializedNodes.Clear();
// serialize data
foreach (var node in _nodes)
{
_serializedNodes.Add(node.ToSerializedNode());
foreach (var socket in node.Sockets)
{
if (socket.IsInput() && socket.IsConnected()) // serialize only input socket edges to avoid double edge serialization
{
InputSocket inputSocket = (InputSocket) socket;
_serializedEdges.Add(inputSocket.Edge.ToSerializedEgde());
}
}
}
TriggerEvents = wasTriggering;
}
/// Unity serialization callback.
public void OnAfterDeserialize()
{
if (_serializedNodes.Count == 0) return; // Nothing to deserialize.
bool wasTriggering = TriggerEvents;
TriggerEvents = false;
_nodes.Clear(); // clear original data.
// deserialize nodes
foreach (var sNode in _serializedNodes)
{
Type nodeType = Type.GetType(sNode.type);
if (nodeType == null)
{
Debug.LogWarning("Unknown node type: " + sNode.type);
continue;
}
Node n = CreateNode(nodeType, sNode.id);
if (n != null)
{
JsonUtility.FromJsonOverwrite(sNode.data, n);
n.OnDeserialization(sNode);
n.X = sNode.X;
n.Y = sNode.Y;
for (var i = 0; i < sNode.directInputValues.Length; i++)
{
if (n.Sockets[i].IsInput())
{
InputSocket inputSocket = (InputSocket) n.Sockets[i];
inputSocket.SetDirectInputNumber(sNode.directInputValues[i], false);
}
}
if (sNode.Collapsed) n.Collapse();
AddNode(n);
}
}
// deserialize edges
foreach (var sEdge in _serializedEdges)
{
Node inputNode = GetNode(sEdge.InputNodeId);
Node outputNode = GetNode(sEdge.OutputNodeId);
if (inputNode == null || outputNode == null)
{
Debug.LogWarning("Try to create an edge but can not find at least on of the nodes.");
continue;
}
if (sEdge.OutputSocketIndex > outputNode.Sockets.Count || sEdge.InputSocketIndex > inputNode.Sockets.Count)
{
Debug.LogWarning("Try to create an edge but can not find at least on of the sockets.");
continue;
}
InputSocket inputSocket = (InputSocket) inputNode.Sockets[sEdge.InputSocketIndex];
OutputSocket outputSocket = (OutputSocket) outputNode.Sockets[sEdge.OutputSocketIndex];
Edge edge = new Edge(outputSocket, inputSocket);
inputSocket.Edge = edge;
outputSocket.Edges.Add(edge);
}
TriggerEvents = wasTriggering;
}
}
}
================================================
FILE: Assets/Code/Bon/Graph.cs.meta
================================================
fileFormatVersion: 2
guid: 0e28cabdc78f14b7e9bedf19aa6d2dc9
timeCreated: 1466621268
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Code/Bon/Interface/IColorSampler.cs
================================================
using Assets.Code.Bon.Socket;
using UnityEngine;
namespace Assets.Code.Bon.Interface
{
public interface IColorSampler
{
Color GetColor(OutputSocket socket, float i);
}
}
================================================
FILE: Assets/Code/Bon/Interface/IColorSampler.cs.meta
================================================
fileFormatVersion: 2
guid: 05d81a07cc9eb4cb18cde73b2154e05e
timeCreated: 1471446464
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Code/Bon/Interface/INumberSampler.cs
================================================
using Assets.Code.Bon.Socket;
namespace Assets.Code.Bon.Interface
{
public interface INumberSampler
{
float GetNumber(OutputSocket outSocket, float x, float y, float z, float seed);
}
}
================================================
FILE: Assets/Code/Bon/Interface/INumberSampler.cs.meta
================================================
fileFormatVersion: 2
guid: 02522c1480dbb432d9d377b5b267c58e
timeCreated: 1471446464
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Code/Bon/Interface/IStringSampler.cs
================================================
using Assets.Code.Bon.Socket;
namespace Assets.Code.Bon.Interface
{
public interface IStringSampler
{
string GetString(OutputSocket outSocket);
}
}
================================================
FILE: Assets/Code/Bon/Interface/IStringSampler.cs.meta
================================================
fileFormatVersion: 2
guid: ffda6b20a656b460cb435ee80c159a89
timeCreated: 1470942429
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Code/Bon/Interface/IUpdateable.cs
================================================
namespace Assets.Code.Bon.Nodes
{
public interface IUpdateable
{
void Update();
}
}
================================================
FILE: Assets/Code/Bon/Interface/IUpdateable.cs.meta
================================================
fileFormatVersion: 2
guid: 00450e3ca18e14e319c92419862b7acf
timeCreated: 1469268176
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Code/Bon/Interface/IVectorSampler.cs
================================================
using System.Collections.Generic;
using Assets.Code.Bon.Socket;
using UnityEngine;
namespace Assets.Code.Bon.Interface
{
public interface IVectorSampler
{
List GetVector3List(OutputSocket outSocket, float x, float y, float z, float sizeX, float sizeY, float sizeZ, float seed);
}
}
================================================
FILE: Assets/Code/Bon/Interface/IVectorSampler.cs.meta
================================================
fileFormatVersion: 2
guid: 69ade1b14079f4bbaa129384c316d1bb
timeCreated: 1471446464
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Code/Bon/Interface.meta
================================================
fileFormatVersion: 2
guid: 642bc3bc6e6e94bcc9b737b06fc27eac
folderAsset: yes
timeCreated: 1466621268
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Code/Bon/Log.cs
================================================
using System;
using Assets.Code.Bon;
using UnityEngine;
public static class Log {
public static void Info(String info)
{
if (BonConfig.LogLevel > 0)
{
Debug.Log(info);
}
}
}
================================================
FILE: Assets/Code/Bon/Log.cs.meta
================================================
fileFormatVersion: 2
guid: f91aaa8f65ae44387b65ffc6f5c6ea3b
timeCreated: 1471468296
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Code/Bon/Node.cs
================================================
using System;
using System.Collections.Generic;
using System.Net;
using Assets.Code.Bon.Nodes;
using Assets.Code.Bon.Socket;
using UnityEngine;
namespace Assets.Code.Bon
{
public abstract class Node : IUpdateable
{
[NonSerialized] public List Sockets = new List();
[NonSerialized] public int Id;
[NonSerialized] public string Name;
[NonSerialized] private Graph _parent;
[NonSerialized] public Rect WindowRect;
[NonSerialized] public int VisitCount = 0;
[NonSerialized] public Rect ContentRect;
[NonSerialized] public static int LastFocusedNodeId;
[NonSerialized] public bool Resizable = true;
[NonSerialized] public Rect ResizeArea;
[NonSerialized] public float SocketTopOffsetInput;
[NonSerialized] public float SocketTopOffsetOutput;
[NonSerialized] public bool Collapsed;
[NonSerialized] public float Height;
protected Node(int id, Graph parent)
{
ResizeArea = new Rect();
Id = id;
// default size
Width = 100;
Height = 100;
Name = GetNodeName(GetType());
_parent = parent;
}
public int GetId()
{
return Id;
}
public abstract void OnGUI();
public abstract void Update();
public virtual void OnSerialization(SerializableNode sNode)
{
// for overriding: gets called before this Node gets serialized
}
public virtual void OnDeserialization(SerializableNode sNode)
{
// for overriding: gets called after this Node has been deserialized
}
/// The x position of the node
public float X
{
get { return WindowRect.x; }
set { WindowRect.x = value; }
}
/// The y position of the node
public float Y
{
get { return WindowRect.y; }
set { WindowRect.y = value; }
}
/// The width of the node
public float Width
{
get { return WindowRect.width; }
set { WindowRect.width = value; }
}
/// Returns true if the node is focused.
/// True if the node is focused.
public bool HasFocus()
{
return LastFocusedNodeId == Id;
}
public virtual void OnFocus()
{
if (_parent.TriggerEvents)
{
EventManager.TriggerOnFocusNode(_parent, this);
}
}
public void Collapse()
{
WindowRect.Set(WindowRect.x, WindowRect.y, WindowRect.width, 18);
Collapsed = true;
}
public void Expand()
{
WindowRect.Set(WindowRect.x, WindowRect.y, WindowRect.width, Height);
Collapsed = false;
Update();
}
/// Returns true if this assigned position intersects the node.
/// The position in canvas coordinates.
/// True if this assigned position intersects the node.
public bool Intersects(Vector2 canvasPosition)
{
return WindowRect.Contains(canvasPosition);
}
/// Returns true if this node contains the assigned socket.
/// The socket to use.
/// True if this node contains the assigned socket.
public bool ContainsSocket(AbstractSocket socket)
{
return Sockets.Contains(socket);
}
public int GetInputSocketCount()
{
var count = 0;
foreach (var socket in Sockets) if (socket.IsInput()) count++;
return count;
}
// TODO update docu
/// Returns the socket of the type and index.
/// The type of the socket.
/// The input or output direction of the socket.
/// The index of sockets of this type.
/// You can have multiple sockets of the same type.
/// The socket of the type with the index or null.
public AbstractSocket GetSocket(Type edgeType, Type socketType, int index)
{
var searchIndex = -1;
foreach (var socket in Sockets)
{
if (socket.Type == edgeType && socket.GetType() == socketType)
{
searchIndex++;
if (searchIndex == index) return socket;
}
}
return null;
}
/// Projects the assigned position to a node relative position.
/// The position in canvas coordinates.
/// The position in node coordinates
public Vector2 ProjectToNode(Vector2 canvasPosition)
{
canvasPosition.Set(canvasPosition.x - WindowRect.x, canvasPosition.y - WindowRect.y);
return canvasPosition;
}
/// Searches for a socket that intesects the assigned position.
/// The position for intersection in canvas coordinates.
/// The at the position or null.
public AbstractSocket SearchSocketAt(Vector2 canvasPosition)
{
//Vector2 nodePosition = ProjectToNode(canvasPosition);
foreach (var socket in Sockets)
{
if (socket.Intersects(canvasPosition)) return socket;
}
return null;
}
/// Triggers the OnChangedNode event from within a Node.
/// Call this method if your nodes content has changed.
public void TriggerChangeEvent()
{
if (_parent.TriggerEvents)
{
EventManager.TriggerOnChangedNode(_parent, this);
}
}
/// Returns true if all input Sockets are connected.
/// True if all input Sockets are connected.
public bool AllInputSocketsConnected()
{
foreach (var socket in Sockets)
{
if (!socket.IsConnected() && socket.IsInput()) return false;
}
return true;
}
/// Returns the total number of input edges connected into this node.
public int GetConnectedInputCount() {
int count = 0;
foreach (var socket in Sockets)
{
if (socket.IsInput () && socket.IsConnected ())
{
count++;
}
}
return count;
}
public void GUIDrawSockets()
{
if (!Collapsed) foreach (var socket in Sockets) socket.Draw();
}
public void GUIDrawEdges()
{
foreach (var socket in Sockets)
{
if (socket.IsInput()) // draw only input sockets to avoid double drawing of edges
{
InputSocket inputSocket = (InputSocket) socket;
if (inputSocket.IsConnected()) inputSocket.Edge.Draw();
}
}
}
/// Aligns the position of the sockets of this node
public void GUIAlignSockets()
{
var leftCount = 0;
var rightCount = 0;
foreach (var socket in Sockets)
{
if (socket.IsInput())
{
socket.X = - BonConfig.SocketSize + WindowRect.x;
socket.Y = GUICalcSocketTopOffset(leftCount) + WindowRect.y + SocketTopOffsetInput;
leftCount++;
}
else
{
socket.X = WindowRect.width + WindowRect.x;
socket.Y = GUICalcSocketTopOffset(rightCount) + WindowRect.y + SocketTopOffsetOutput;
rightCount++;
}
}
}
/// Calculates the offset of a socket from the top of this node
private int GUICalcSocketTopOffset(int socketTopIndex)
{
return BonConfig.SocketOffsetTop + (socketTopIndex*BonConfig.SocketSize)
+ (socketTopIndex*BonConfig.SocketMargin);
}
/// Gets the menu entry name of this node
public static string GetNodeName(Type nodeType)
{
object[] attrs = nodeType.GetCustomAttributes(typeof(GraphContextMenuItem), true);
GraphContextMenuItem attr = (GraphContextMenuItem) attrs[0];
return string.IsNullOrEmpty(attr.Name) ? nodeType.Name : attr.Name;
}
/// Gets the menu entry path of this node
public static string GetNodePath(Type nodeType)
{
object[] attrs = nodeType.GetCustomAttributes(typeof(GraphContextMenuItem), true);
GraphContextMenuItem attr = (GraphContextMenuItem) attrs[0];
return string.IsNullOrEmpty(attr.Path) ? null : attr.Path;
}
/// Converts this node to a SerializableNode
public SerializableNode ToSerializedNode()
{
SerializableNode n = new SerializableNode();
n.type = GetType().FullName;
n.id = Id;
n.X = WindowRect.xMin;
n.Y = WindowRect.yMin;
n.Collapsed = Collapsed;
n.directInputValues = new float[Sockets.Count];
for (var i = 0; i < n.directInputValues.Length; i++)
{
if (Sockets[i].IsInput())
{
InputSocket inputSocket = (InputSocket) Sockets[i];
if (inputSocket.IsInDirectInputMode()) n.directInputValues[i] = inputSocket.GetDirectInputNumber();
}
}
n.data = JsonUtility.ToJson(this); // custom node data can be used
OnSerialization(n);
return n;
}
public static Color GetEdgeColor(Type nodeType)
{
if (nodeType == typeof(AbstractNumberNode)) return new Color(0.32f, 0.58f, 0.86f, 1);
if (nodeType == typeof(AbstractColorNode)) return new Color(0.54f, 0.70f, 0.50f, 1);
if (nodeType == typeof(AbstractStringNode)) return new Color(0.84f, 0.45f, 0.39f, 1f);
if (nodeType == typeof(AbstractVector3Node)) return new Color(0.9f, 0.9f, 0.9f, 1f);
return Color.black;
}
}
/// A class to serialize a Node.
[Serializable] public class SerializableNode
{
[SerializeField] public string type;
[SerializeField] public int id;
[SerializeField] public float X;
[SerializeField] public float Y;
[SerializeField] public string data;
[SerializeField] public float[] directInputValues;
[SerializeField] public bool Collapsed;
}
/// Annotation to register menu entries of Nodes to the editor.
[AttributeUsage(AttributeTargets.All, Inherited = false, AllowMultiple = true)]
public sealed class GraphContextMenuItem : Attribute
{
private string _menuPath;
public string Path { get { return _menuPath; } }
private string _itemName;
public string Name { get { return _itemName; } }
public GraphContextMenuItem(string menuPath) : this(menuPath, null)
{
}
public GraphContextMenuItem(string menuPath, string itemName)
{
_menuPath = menuPath;
_itemName = itemName;
}
}
}
================================================
FILE: Assets/Code/Bon/Node.cs.meta
================================================
fileFormatVersion: 2
guid: 228028896bc3f44bfb3474a8fb5f4aff
timeCreated: 1466621268
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Code/Bon/Nodes/AbstractColorNode.cs
================================================
using System;
using Assets.Code.Bon.Interface;
using Assets.Code.Bon.Socket;
namespace Assets.Code.Bon.Nodes
{
public abstract class AbstractColorNode : Node, IColorSampler
{
protected AbstractColorNode(int id, Graph parent) : base(id, parent)
{
}
public abstract UnityEngine.Color GetColor(OutputSocket socket, float i);
}
}
================================================
FILE: Assets/Code/Bon/Nodes/AbstractColorNode.cs.meta
================================================
fileFormatVersion: 2
guid: 0637e900d20f9442590599bbb8656643
timeCreated: 1470915819
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Code/Bon/Nodes/AbstractNumberNode.cs
================================================
using System;
using Assets.Code.Bon.Interface;
using Assets.Code.Bon.Socket;
namespace Assets.Code.Bon.Nodes
{
public abstract class AbstractNumberNode : Node, INumberSampler
{
[NonSerialized] protected OutputSocket _outSocket;
protected AbstractNumberNode(int id, Graph parent) : base(id, parent)
{
_outSocket = new OutputSocket(this, typeof(AbstractNumberNode));
Sockets.Add(_outSocket);
}
public abstract float GetNumber(OutputSocket outSocket, float x, float y, float z, float seed);
public static float GetInputNumber(InputSocket socket, float x, float y, float z, float seed)
{
if (socket.Type != typeof(AbstractNumberNode)) return float.NaN;
if (socket.IsInDirectInputMode()) return socket.GetDirectInputNumber();
AbstractNumberNode node = (AbstractNumberNode) socket.GetConnectedSocket().Parent;
return node.GetNumber(socket.GetConnectedSocket(), x, y, z, seed);
}
}
}
================================================
FILE: Assets/Code/Bon/Nodes/AbstractNumberNode.cs.meta
================================================
fileFormatVersion: 2
guid: 29886bc40d47c421da789822a4be51cb
timeCreated: 1470915819
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Code/Bon/Nodes/AbstractStringNode.cs
================================================
using Assets.Code.Bon.Interface;
using Assets.Code.Bon.Socket;
namespace Assets.Code.Bon.Nodes
{
public abstract class AbstractStringNode : Node, IStringSampler {
protected AbstractStringNode(int id, Graph parent) : base(id, parent)
{
}
public abstract string GetString(OutputSocket outSocket);
}
}
================================================
FILE: Assets/Code/Bon/Nodes/AbstractStringNode.cs.meta
================================================
fileFormatVersion: 2
guid: 542a024ba83a446eb9f634fced8e4ace
timeCreated: 1470940991
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Code/Bon/Nodes/AbstractVector3Node.cs
================================================
using System.Collections.Generic;
using Assets.Code.Bon.Interface;
using Assets.Code.Bon.Socket;
namespace Assets.Code.Bon.Nodes
{
public abstract class AbstractVector3Node : Node, IVectorSampler
{
protected AbstractVector3Node(int id, Graph parent) : base(id, parent)
{
}
public static List GetInputVector3List(InputSocket socket, float x, float y, float z,
float sizeX, float sizeY, float sizeZ, float seed)
{
if (socket.Type != typeof(AbstractVector3Node) || !socket.CanGetResult()) return null;
AbstractVector3Node node = (AbstractVector3Node) socket.GetConnectedSocket().Parent;
return node.GetVector3List(socket.GetConnectedSocket(), x, y, z, sizeX, sizeY, sizeZ, seed);
}
public abstract List GetVector3List(OutputSocket socket, float x, float y, float z, float sizeX, float sizeY, float sizeZ, float seed);
}
}
================================================
FILE: Assets/Code/Bon/Nodes/AbstractVector3Node.cs.meta
================================================
fileFormatVersion: 2
guid: 9b0299a938d244da3bad3c657518b184
timeCreated: 1471356154
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Code/Bon/Nodes/Color/ColorNode.cs
================================================
using System;
using Assets.Code.Bon.Socket;
using JetBrains.Annotations;
using UnityEngine;
using UnityEngine.UI;
namespace Assets.Code.Bon.Nodes.Color
{
[Serializable]
[GraphContextMenuItem("Color", "Color")]
public class ColorNode : AbstractColorNode
{
[SerializeField] private UnityEngine.Color _color;
[NonSerialized] private InputSocket _inputSocketR;
[NonSerialized] private InputSocket _inputSocketG;
[NonSerialized] private InputSocket _inputSocketB;
[NonSerialized] private InputSocket _inputSocketA;
[NonSerialized] private Rect _labelR;
[NonSerialized] private Rect _labelG;
[NonSerialized] private Rect _labelB;
[NonSerialized] private Rect _labelA;
[NonSerialized] private Rect _sliderR;
[NonSerialized] private Rect _sliderG;
[NonSerialized] private Rect _sliderB;
[NonSerialized] private Rect _sliderA;
public ColorNode(int id, Graph parent) : base(id, parent)
{
_labelR = new Rect(3, 0, 20, 20);
_labelG = new Rect(3, 20, 20, 20);
_labelB = new Rect(3, 40, 20, 20);
_labelA = new Rect(3, 60, 20, 20);
_sliderR = new Rect(23, 0, 50, 20);
_sliderG = new Rect(23, 20, 50, 20);
_sliderB = new Rect(23, 40, 50, 20);
_sliderA = new Rect(23, 60, 50, 20);
_inputSocketR = new InputSocket(this, typeof(AbstractNumberNode));
_inputSocketG = new InputSocket(this, typeof(AbstractNumberNode));
_inputSocketB = new InputSocket(this, typeof(AbstractNumberNode));
_inputSocketA = new InputSocket(this, typeof(AbstractNumberNode));
Sockets.Add(_inputSocketR);
Sockets.Add(_inputSocketG);
Sockets.Add(_inputSocketB);
Sockets.Add(_inputSocketA);
Sockets.Add(new OutputSocket(this, typeof(AbstractColorNode)));
}
public override void OnGUI()
{
var r = _color.r;
var g = _color.g;
var b = _color.b;
var a = _color.a;
GUI.Label(_labelR, "r");
GUI.Label(_labelG, "g");
GUI.Label(_labelB, "b");
GUI.Label(_labelA, "a");
r = GUI.HorizontalSlider(_sliderR, r, 0f, 1f);
g = GUI.HorizontalSlider(_sliderG, g, 0f, 1f);
b = GUI.HorizontalSlider(_sliderB, b, 0f, 1f);
a = GUI.HorizontalSlider(_sliderA, a, 0f, 1f);
var rChanged = UpdateDirectInput(_inputSocketR, _color.r, r);
var gChanged = UpdateDirectInput(_inputSocketG, _color.g, g);
var bChanged = UpdateDirectInput(_inputSocketB, _color.b, b);
var aChanged = UpdateDirectInput(_inputSocketA, _color.a, a);
if (rChanged || gChanged || bChanged || aChanged)
{
SetColor(r, g, b, a);
TriggerChangeEvent();
}
NodeUtils.GUIDrawRect(new Rect(77, 0, 20, 20), _color);
}
private bool UpdateDirectInput(InputSocket socket, float oldValue, float newValue)
{
if (oldValue != newValue && socket.IsInDirectInputMode())
{
socket.SetDirectInputNumber(newValue, false);
return true;
}
return false;
}
private void SetColor(float r, float g, float b, float a)
{
_color.r = r;
_color.g = g;
_color.b = b;
_color.a = a;
}
public override void Update()
{
_color.r = AbstractNumberNode.GetInputNumber(_inputSocketR, 0, 0, 0, 0);
_color.g = AbstractNumberNode.GetInputNumber(_inputSocketG, 0, 0, 0, 0);
_color.b = AbstractNumberNode.GetInputNumber(_inputSocketB, 0, 0, 0, 0);
_color.a = AbstractNumberNode.GetInputNumber(_inputSocketA, 0, 0, 0, 0);
}
public override UnityEngine.Color GetColor(OutputSocket outSocket, float i)
{
return _color;
}
}
}
================================================
FILE: Assets/Code/Bon/Nodes/Color/ColorNode.cs.meta
================================================
fileFormatVersion: 2
guid: eafd120e1858e44a592ecaf1fc1ee36b
timeCreated: 1470918712
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Code/Bon/Nodes/Color/GradientNode.cs
================================================
using System;
using System.Collections.Generic;
using System.Text;
using Assets.Code.Bon.Socket;
using UnityEngine;
namespace Assets.Code.Bon.Nodes.Color
{
[Serializable]
[GraphContextMenuItem("Color", "Gradient")]
public class GradientNode : AbstractColorNode
{
[SerializeField] private List _times = new List();
[NonSerialized] private Rect _tmpRect;
[NonSerialized] private Rect _addColorButton;
[NonSerialized] private List _inputSockets;
[NonSerialized] private Gradient _gradient;
[NonSerialized] private Texture2D _previewTexture;
[NonSerialized] private bool _needsUpdate = true;
public GradientNode(int id, Graph parent) : base(id, parent)
{
_inputSockets = new List();
_tmpRect = new Rect();
_addColorButton = new Rect();
_gradient = new Gradient();
Sockets.Add(new OutputSocket(this, typeof(AbstractColorNode)));
Width = 156;
}
public override void OnDeserialization(SerializableNode sNode)
{
var aditionalSocketsCount = _times.Count;
while (Sockets.Count <= aditionalSocketsCount) AddInputSocket(false);
}
private void AddInputSocket(bool addTimes)
{
InputSocket s = new InputSocket(this, typeof(AbstractColorNode));
Sockets.Add(s);
_inputSockets.Add(s);
if (addTimes) _times.Add(0);
_needsUpdate = true;
}
private void RemoveInputSocket(int i)
{
Sockets.Remove(_inputSockets[i]);
_inputSockets.Remove(_inputSockets[i]);
_times.RemoveAt(i);
_needsUpdate = true;
}
public override void OnGUI()
{
Height = _times.Count * 20 + 45;
_addColorButton.Set(28, Height - 42, 100, 18);
if (GUI.Button(_addColorButton, "add color")) AddInputSocket(true);
var socketToRemove = -1;
for (var i = 0; i < _inputSockets.Count; i++)
{
_tmpRect.Set(25, 20 * i, 100, 20);
var value = _times[i];
_times[i] = GUI.HorizontalSlider(_tmpRect, value, 0f, 1f);
if (Math.Abs(_times[i] - value) > 0.0001f) UpdateColorPreview();
_tmpRect.Set(3, (20 * i) - 2, 18, 18);
if (!_inputSockets[i].IsConnected()) if (GUI.Button(_tmpRect, "x")) socketToRemove = i;
}
if (_previewTexture != null)
{
GUI.DrawTexture(new Rect(Width - _previewTexture.width - 6, 0, _previewTexture.width, _previewTexture.height), _previewTexture);
}
if (socketToRemove != -1) RemoveInputSocket(socketToRemove);
if (_needsUpdate) UpdateColorPreview();
}
public void UpdateColorPreview()
{
_needsUpdate = false;
UpdateGradient();
if (_previewTexture != null) Texture2D.DestroyImmediate(_previewTexture);
_previewTexture = new Texture2D(20, (int) Height - 24);
for (int y = 0; y < _previewTexture.height; y++)
{
UnityEngine.Color c = _gradient.Evaluate(y / (float) _previewTexture.height);
for (int x = 0; x < _previewTexture.width; x++)
{
_previewTexture.SetPixel(x, y, c);
}
}
_previewTexture.Apply();
}
private void UpdateGradient()
{
GradientColorKey[] colorKeys = new GradientColorKey[_inputSockets.Count];
GradientAlphaKey[] alphaKeys = new GradientAlphaKey[_inputSockets.Count];
for (int i = 0; i < _inputSockets.Count; i++)
{
UnityEngine.Color c = UnityEngine.Color.black;
if (_inputSockets[i].IsConnected())
{
AbstractColorNode colorNode = (AbstractColorNode) _inputSockets[i].GetConnectedSocket().Parent;
c = colorNode.GetColor(_inputSockets[i].GetConnectedSocket(), 0);
}
colorKeys[i] = new GradientColorKey();
colorKeys[i].color = c;
colorKeys[i].time = _times[i];
alphaKeys[i] = new GradientAlphaKey();
alphaKeys[i].alpha = c.a;
alphaKeys[i].time = _times[i];
}
_gradient.SetKeys(colorKeys, alphaKeys);
}
public override void Update()
{
if (!Collapsed)
UpdateColorPreview();
}
public override UnityEngine.Color GetColor(OutputSocket outSocket, float i)
{
return _gradient.Evaluate(i);
}
}
}
================================================
FILE: Assets/Code/Bon/Nodes/Color/GradientNode.cs.meta
================================================
fileFormatVersion: 2
guid: 614d79690b0534b2986db342ac1fd827
timeCreated: 1470915115
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Code/Bon/Nodes/Color.meta
================================================
fileFormatVersion: 2
guid: c7b7935ebcbd14e3a9984a6763ec229d
folderAsset: yes
timeCreated: 1470915086
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Code/Bon/Nodes/Geometry/LandscapeNode.cs
================================================
using System;
using Assets.Code.Bon.Interface;
using Assets.Code.Bon.Socket;
using UnityEngine;
namespace Assets.Code.Bon.Nodes.Geometry
{
[Serializable]
[GraphContextMenuItem("Geometry", "Lanscape")]
public class LandscapeNode : AbstractNumberNode, IColorSampler, IStringSampler {
[NonSerialized] private Rect _heightValueLabel;
[NonSerialized] private Rect _colorRangeLabel;
[NonSerialized] private Rect _materialLabel;
[NonSerialized] private InputSocket _heightValueSocket;
[NonSerialized] private InputSocket _gradientSocket;
[NonSerialized] private InputSocket _materialSocket;
public LandscapeNode(int id, Graph parent) : base(id, parent)
{
_heightValueLabel = new Rect(8, 0, 75, 20);
_colorRangeLabel = new Rect(8, 20, 75, 20);
_materialLabel = new Rect(8, 40, 75, 20);
_heightValueSocket = new InputSocket(this, typeof(AbstractNumberNode));
Sockets.Add(_heightValueSocket);
_gradientSocket = new InputSocket(this, typeof(AbstractColorNode));
Sockets.Add(_gradientSocket);
_materialSocket = new InputSocket(this, typeof(AbstractStringNode));
Sockets.Add(_materialSocket);
}
public override void OnGUI()
{
GUI.Label(_heightValueLabel, "height map");
GUI.Label(_colorRangeLabel, "vertex color");
GUI.Label(_materialLabel, "material");
}
public override void Update()
{
}
public override float GetNumber(OutputSocket socket, float x, float y, float z, float seed)
{
return GetInputNumber(_heightValueSocket, x, y, z, seed);
}
public UnityEngine.Color GetColorFrom(float i)
{
if (!_gradientSocket.IsConnected()) return UnityEngine.Color.black;
AbstractColorNode node = (AbstractColorNode) _gradientSocket.GetConnectedSocket().Parent;
return node.GetColor(_gradientSocket.GetConnectedSocket(), i);
}
public string GetString()
{
if (!_materialSocket.IsConnected()) return "";
AbstractStringNode node = (AbstractStringNode) _materialSocket.GetConnectedSocket().Parent;
return node.GetString(_materialSocket.GetConnectedSocket());
}
public UnityEngine.Color GetColor(OutputSocket outSocket, float i)
{
return UnityEngine.Color.black;
}
public string GetString(OutputSocket outSocket)
{
return null;
}
}
}
================================================
FILE: Assets/Code/Bon/Nodes/Geometry/LandscapeNode.cs.meta
================================================
fileFormatVersion: 2
guid: 010d5a0994b59428e8856c666f4bc08b
timeCreated: 1471434156
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Code/Bon/Nodes/Geometry/ModelNode.cs
================================================
using System;
using System.Collections.Generic;
using Assets.Code.Bon;
using Assets.Code.Bon.Nodes;
using Assets.Code.Bon.Socket;
using UnityEngine;
[Serializable]
[GraphContextMenuItem("Geometry", "Model")]
public class ModelNode : Node
{
private InputSocket _inputSocketPosition;
private InputSocket _inputSocketRotation;
private InputSocket _inputSocketScale;
private InputSocket _inputSocketModelName;
private Rect _tmpRect;
public ModelNode(int id, Graph parent) : base(id, parent)
{
_inputSocketPosition = new InputSocket(this, typeof(AbstractVector3Node));
_inputSocketRotation = new InputSocket(this, typeof(AbstractVector3Node));
_inputSocketScale = new InputSocket(this, typeof(AbstractVector3Node));
_inputSocketModelName = new InputSocket(this, typeof(AbstractStringNode));
Sockets.Add(_inputSocketModelName);
Sockets.Add(_inputSocketPosition);
Sockets.Add(_inputSocketRotation);
Sockets.Add(_inputSocketScale);
Height = 100;
_tmpRect = new Rect();
}
public override void OnGUI()
{
GUI.skin.label.alignment = TextAnchor.MiddleLeft;
_tmpRect.Set(3, 0, 50, 20);
GUI.Label(_tmpRect, "file");
_tmpRect.Set(3, 20, 50, 20);
GUI.Label(_tmpRect, "position");
_tmpRect.Set(3, 40, 50, 20);
GUI.Label(_tmpRect, "rotation");
_tmpRect.Set(3, 60, 50, 20);
GUI.Label(_tmpRect, "scale");
}
public string GetModelFileName()
{
if (!_inputSocketModelName.CanGetResult()) return null;
return ((AbstractStringNode) _inputSocketModelName.GetConnectedSocket().Parent).GetString(_inputSocketModelName.GetConnectedSocket());
}
public List GetPositions(float x, float y, float z, float sizeX, float sizeY, float sizeZ, float seed)
{
if (!_inputSocketPosition.CanGetResult()) return null;
return AbstractVector3Node.GetInputVector3List(_inputSocketPosition, x, y, z, sizeX, sizeY, sizeZ, seed);
}
public override void Update()
{
}
}
================================================
FILE: Assets/Code/Bon/Nodes/Geometry/ModelNode.cs.meta
================================================
fileFormatVersion: 2
guid: 46ccb94ed99294a72abd4353ea24d7a2
timeCreated: 1471434184
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Code/Bon/Nodes/Geometry.meta
================================================
fileFormatVersion: 2
guid: b274c4e04e1c7472e811251c0c77eaa9
folderAsset: yes
timeCreated: 1470916750
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Code/Bon/Nodes/NodeUtils.cs
================================================
using UnityEngine;
using System.Collections;
using System.Collections.Generic;
using System.Text.RegularExpressions;
using Assets.Code.Bon.Interface;
public class NodeUtils {
public const string NotConnectedMessage = "not connected";
private static Texture2D _staticRectTexture;
private static GUIStyle _staticRectStyle;
/** Draws a textfield that accepts float inputs only.
Returns true if the value has changed.
**/
public static bool FloatTextField(Rect area, ref string number)
{
if (number == null) return false;
var textFieldValue = GUI.TextField(area, number);
var newTextFieldValue = GetValidNumberString(textFieldValue, number);
var numberChanged = !IsEqualFloatValue(newTextFieldValue, number);
number = newTextFieldValue;
return numberChanged;
}
public static string GetValidNumberString(string text, string defaultNumber)
{
if (text == "") text = "0";
if (Regex.Match(text, @"^-?[0-9]*(?:\.[0-9]*)?$").Success) return text;
return defaultNumber;
}
public static bool IsEqualFloatValue(string number01, string number02)
{
return !(System.Math.Abs(float.Parse(number01) - float.Parse(number02)) > 0);
}
public static Color GetMapValueColor(float value)
{
if (float.IsNaN(value)) return Color.magenta;
if (value > 1f) return Color.red;
if (value < -1f) return Color.blue;
Color c = Color.white * (value + 1f) / 2f;
c.a = 1;
return c;
}
public static Color[] ToColorMap(float[,] values, IColorSampler colorSampler = null)
{
int width = values.GetLength(0);
int height = values.GetLength(1);
Color[] colorMap = new Color[width * height];
for (int y = 0; y < height; y++)
{
for (int x = 0; x < width; x++)
{
Color c;
if (colorSampler == null) c = GetMapValueColor(values[x, y]);
else c = colorSampler.GetColor(null, (values[x, y] + 1f) / 2f);
colorMap[y * width + x] = c;
}
}
return colorMap;
}
public static void GUIDrawRect(Rect position, Color color )
{
if(_staticRectTexture == null) _staticRectTexture = new Texture2D( 1, 1 );
if(_staticRectStyle == null) _staticRectStyle = new GUIStyle();
_staticRectTexture.SetPixel(0, 0, color);
_staticRectTexture.Apply();
_staticRectStyle.normal.background = _staticRectTexture;
GUI.Box( position, GUIContent.none, _staticRectStyle );
}
public static float ModifySeed(float baseSeed, float modifierSeed)
{
if (modifierSeed == 0) return baseSeed;
return baseSeed * modifierSeed % float.MaxValue;
}
}
================================================
FILE: Assets/Code/Bon/Nodes/NodeUtils.cs.meta
================================================
fileFormatVersion: 2
guid: 719e086ad613e41e7bd9cb37ac794fe6
timeCreated: 1467725131
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Code/Bon/Nodes/Noise/AbstractNoiseNode.cs
================================================
using System.Collections.Generic;
using UnityEngine;
namespace Assets.Code.Bon.Nodes.Noise
{
public abstract class AbstractNoiseNode : AbstractNumberNode
{
protected List _textures;
private Rect _errorMessageLabel;
protected AbstractNoiseNode(int id, Graph parent) : base(id, parent)
{
_errorMessageLabel = new Rect(3, 0, 100, 15);
_textures = new List();
}
protected void DrawTextures()
{
for (var i = 0; i < _textures.Count; i++) _textures[i].OnGUI();
//if (!CanCreatePreview()) GUI.Label(_errorMessageLabel, NodeUtils.NotConnectedMessage);
if (IsUpdatingTexture()) GUI.Label(_errorMessageLabel, "updating data..");
}
protected bool IsUpdatingTexture()
{
foreach (GUIThreadedTexture t in _textures) if (t.IsUpdating) return true;
return false;
}
}
}
================================================
FILE: Assets/Code/Bon/Nodes/Noise/AbstractNoiseNode.cs.meta
================================================
fileFormatVersion: 2
guid: 85fe2ca50750244c0846c24de6db5735
timeCreated: 1471356475
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Code/Bon/Nodes/Noise/NoiseDisplayNode.cs
================================================
using System;
using System.Collections.Generic;
using Assets.Code.Bon.Interface;
using Assets.Code.Bon.Nodes.Number;
using Assets.Code.Bon.Socket;
using UnityEngine;
namespace Assets.Code.Bon.Nodes.Noise
{
[Serializable]
[GraphContextMenuItem("Noise", "Display")]
public class NoiseDisplayNode : AbstractNoiseNode
{
[SerializeField] private int _sizeModifcator;
[NonSerialized] private InputSocket _inputSocketNumber;
[NonSerialized] private InputSocket _inputSocketColor;
[NonSerialized] private InputSocket _inputSocketPosition;
[NonSerialized] private Rect _sizeLabel;
[NonSerialized] private Rect _sizePlusButton;
[NonSerialized] private Rect _sizeMinusButton;
[NonSerialized] private const int _sizeStep = 50;
private List _lastVectors;
private bool _initializedSize;
private Rect _tmpRect;
public NoiseDisplayNode(int id, Graph parent) : base(id, parent)
{
_sizeLabel = new Rect(3, 0, 25, 15);
_sizePlusButton = new Rect(28, 0, 18, 18);
_sizeMinusButton = new Rect(46, 0, 18, 18);
_inputSocketNumber = new InputSocket(this, typeof(AbstractNumberNode));
Sockets.Add(_inputSocketNumber);
_inputSocketColor = new InputSocket(this, typeof(AbstractColorNode));
Sockets.Add(_inputSocketColor);
_inputSocketPosition = new InputSocket(this, typeof(AbstractVector3Node));
Sockets.Add(_inputSocketPosition);
_textures.Add(new GUIThreadedTexture()); // heightmap
_textures.Add(new GUIThreadedTexture()); // points
_tmpRect = new Rect();
Width = 160;
Height = 220;
}
public override void OnGUI()
{
if (!_initializedSize) ChangeTextureSize(_sizeModifcator * _sizeStep);
if (!_textures[0].DoneInitialUpdate) _textures[0].StartTextureUpdateJob((int) Width -10, (int) Height - 70, GetNumberSampler(), GetColorSampler());
if (!_textures[1].DoneInitialUpdate) _textures[1].StartTextureUpdateJob((int) Width -10, (int) Height - 70, GetNumberSampler(), GetColorSampler());
if (!IsUpdatingTexture())
{
_sizeLabel.Set(_sizeLabel.x, Height - 65, _sizeLabel.width, _sizeLabel.height);
_sizePlusButton.Set(_sizePlusButton.x, Height - 65, _sizePlusButton.width, _sizePlusButton.height);
_sizeMinusButton.Set(_sizeMinusButton.x, Height - 65, _sizeMinusButton.width, _sizeMinusButton.height);
GUI.Label(_sizeLabel, "size");
if (GUI.Button(_sizePlusButton, "+"))
{
ChangeTextureSize(+_sizeStep);
_sizeModifcator++;
}
if (Width > 100 && GUI.Button(_sizeMinusButton, "-"))
{
ChangeTextureSize(-_sizeStep);
_sizeModifcator--;
}
}
DrawTextures();
//Width = CurrentTextureSize + 12;
//Height = CurrentTextureSize + 50;
GUI.skin.label.alignment = TextAnchor.MiddleLeft;
_tmpRect.Set(3, Height - 45, 100, 20);
GUI.Label(_tmpRect, "w" + _textures[0].Width + " h" + _textures[0].Height);
if (_lastVectors != null)
{
_tmpRect.Set(70, Height - 45, 100, 20);
GUI.Label(_tmpRect, "vec" + _lastVectors.Count);
}
GUI.skin.label.alignment = TextAnchor.MiddleCenter;
}
private void ChangeTextureSize(int size)
{
_initializedSize = true;
Width += size;
Height += size;
Update();
}
public override void Update()
{
if (Collapsed) return;
if (_inputSocketNumber.CanGetResult())
_textures[0].StartTextureUpdateJob((int) Width -10, (int) Height - 70, GetNumberSampler(), GetColorSampler());
else _textures[0].Hide();
if (_inputSocketPosition.CanGetResult())
{
_lastVectors = GetPositionSampler().GetVector3List(
_inputSocketPosition.GetConnectedSocket(),
0, 0, 0, (int) Width - 10, 0, (int) Height - 70, 0);
_textures[1].StartTextureUpdateJob((int) Width - 10, (int) Height - 70, _lastVectors);
}
else
{
_textures[1].Hide();
_lastVectors = null;
}
}
public override float GetNumber(OutputSocket outSocket, float x, float y, float z, float seed)
{
return GetInputNumber(_inputSocketNumber, x, y, z, seed);
}
private IColorSampler GetColorSampler()
{
if (_inputSocketColor.CanGetResult()) return (AbstractColorNode) _inputSocketColor.GetConnectedSocket().Parent;
return null;
}
private INumberSampler GetNumberSampler()
{
if (_inputSocketNumber.IsInDirectInputMode()) return new SingleNumberSampler(GetInputNumber(_inputSocketNumber, 0, 0, 0, 0));
if (_inputSocketNumber.CanGetResult()) return (AbstractNumberNode) _inputSocketNumber.GetConnectedSocket().Parent;
return null;
}
private IVectorSampler GetPositionSampler()
{
if (_inputSocketPosition.CanGetResult()) return (AbstractVector3Node) _inputSocketPosition.GetConnectedSocket().Parent;
return null;
}
}
}
================================================
FILE: Assets/Code/Bon/Nodes/Noise/NoiseDisplayNode.cs.meta
================================================
fileFormatVersion: 2
guid: e416ebb05ca314aa6a56b85d2a2f862e
timeCreated: 1471356475
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Code/Bon/Nodes/Noise/OctaveNode.cs
================================================
using System;
using Assets.Code.Bon.Socket;
using UnityEngine;
namespace Assets.Code.Bon.Nodes.Noise
{
[Serializable]
[GraphContextMenuItem("Noise", "Octave")]
public class OctaveNode : AbstractNumberNode {
[NonSerialized] private InputSocket _inputNoiseSocket;
[NonSerialized] private InputSocket _inputIterationSocket;
[NonSerialized] private InputSocket _inputLacunaritySocket;
[NonSerialized] private InputSocket _inputPersistanceSocket;
[NonSerialized] private Rect _labelNoise;
[NonSerialized] private Rect _labelIteration;
[NonSerialized] private Rect _labelLacunarity;
[NonSerialized] private Rect _labelPersistance;
public OctaveNode(int id, Graph parent) : base(id, parent)
{
_labelNoise = new Rect(3, 0, 100, 20);
_labelIteration = new Rect(3, 20, 100, 20);
_labelLacunarity = new Rect(3, 40, 100, 20);
_labelPersistance = new Rect(3, 60, 100, 20);
_inputNoiseSocket = new InputSocket(this, typeof(AbstractNumberNode));
_inputIterationSocket = new InputSocket(this, typeof(AbstractNumberNode));
_inputLacunaritySocket = new InputSocket(this, typeof(AbstractNumberNode));
_inputPersistanceSocket = new InputSocket(this, typeof(AbstractNumberNode));
_inputIterationSocket.SetDirectInputNumber(4, false);
_inputLacunaritySocket.SetDirectInputNumber(3, false);
_inputPersistanceSocket.SetDirectInputNumber(0.2f, false);
Sockets.Add(_inputNoiseSocket);
Sockets.Add(_inputIterationSocket);
Sockets.Add(_inputLacunaritySocket);
Sockets.Add(_inputPersistanceSocket);
Width = 100;
}
public override void OnGUI()
{
GUI.skin.label.alignment = TextAnchor.MiddleLeft;
GUI.Label(_labelNoise, "noise");
GUI.Label(_labelIteration, "iteration");
GUI.Label(_labelLacunarity, "lacunarity");
GUI.Label(_labelPersistance, "persistance");
GUI.skin.label.alignment = TextAnchor.MiddleCenter;
}
public override void Update()
{
}
public override float GetNumber(OutputSocket outSocker, float x, float y, float z, float seed)
{
var iterations = GetInputNumber(_inputIterationSocket, x, y, z, seed);
var lacunarity = GetInputNumber(_inputLacunaritySocket, x, y, z, seed);
var persistance = GetInputNumber(_inputPersistanceSocket, x, y, z, seed);
if (float.IsNaN(iterations) || float.IsNaN(lacunarity) || float.IsNaN(persistance)) return float.NaN;
float noiseHeight = 0;
var frequency = 1f;
var amplitude = 1f;
for (var i = 0; i < (int) iterations; i++)
{
var noise = GetInputNumber(_inputNoiseSocket, x * frequency, y * frequency, z * frequency, seed / (i + 1)) * 2 - 1;
noiseHeight += noise * amplitude;
amplitude *= persistance;
frequency *= lacunarity;
}
noiseHeight = (noiseHeight + 1f) / 2f;
return noiseHeight;
}
}
}
================================================
FILE: Assets/Code/Bon/Nodes/Noise/OctaveNode.cs.meta
================================================
fileFormatVersion: 2
guid: c18c70b602d3940c9a5d8315bde9f089
timeCreated: 1470915819
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Code/Bon/Nodes/Noise/SineMapNode.cs
================================================
using System;
using Assets.Code.Bon.Socket;
using UnityEngine;
namespace Assets.Code.Bon.Nodes.Noise
{
[Serializable]
[GraphContextMenuItem("Noise", "Sine")]
public class SineMapNode : AbstractNoiseNode {
[NonSerialized] private Rect _textLabelScaleX;
[NonSerialized] private Rect _textLabelScaleY;
[NonSerialized] private InputSocket _socketInputX;
[NonSerialized] private InputSocket _socketInputY;
public SineMapNode(int id, Graph parent) : base(id, parent)
{
_textLabelScaleX = new Rect(6, 0, 65, BonConfig.SocketSize);
_textLabelScaleY = new Rect(6, 20, 65, BonConfig.SocketSize);
_socketInputX = new InputSocket(this, typeof(AbstractNumberNode));
Sockets.Add(_socketInputX);
_socketInputY = new InputSocket(this, typeof(AbstractNumberNode));
Sockets.Add(_socketInputY);
Height = 60;
_textures.Add(new GUIThreadedTexture()); // heightmap
}
public override void OnGUI()
{
if (!_textures[0].DoneInitialUpdate) Update();
_textures[0].X = 48;
GUI.skin.label.alignment = TextAnchor.MiddleLeft;
GUI.Label(_textLabelScaleX, "scale x");
GUI.Label(_textLabelScaleY, "scale y");
GUI.skin.label.alignment = TextAnchor.MiddleCenter;
DrawTextures();
}
public override float GetNumber(OutputSocket outSocket, float x, float y, float z, float seed)
{
var scaleX = GetInputNumber(_socketInputX, x, y, z, seed);
var scaleZ = GetInputNumber(_socketInputY, x, y, z, seed);
if (float.IsNaN(scaleX) || float.IsNaN(scaleZ)) return float.NaN;
if (scaleX == 0) scaleX = 1;
if (scaleZ == 0) scaleZ = 1;
return (float) (Math.Sin(x / scaleX + seed) + Math.Sin(y / scaleZ + seed)) / 2f;
}
/*protected override IColorSampler GetColorSampler()
{
return null;
}*/
public override void Update()
{
if (!Collapsed) _textures[0].StartTextureUpdateJob(45, 35, this, null);
}
}
}
================================================
FILE: Assets/Code/Bon/Nodes/Noise/SineMapNode.cs.meta
================================================
fileFormatVersion: 2
guid: eb89bb942cd274369bfe14028e657525
timeCreated: 1470997476
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Code/Bon/Nodes/Noise/Special.meta
================================================
fileFormatVersion: 2
guid: f7f24f866023f4abe93e6f6e579862db
folderAsset: yes
timeCreated: 1470836112
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Code/Bon/Nodes/Noise/TextureUpdateJob.cs
================================================
using System;
using System.Collections.Generic;
using Assets.Code.Bon.Interface;
using Assets.Code.Bon.Nodes.Vector3;
using Assets.Code.Bon.Thread;
using UnityEngine;
namespace Assets.Code.Bon.Nodes.Noise
{
public class TextureUpdateJob : ThreadedJob
{
private INumberSampler _numberSampler;
private IColorSampler _samplerColor;
private List _positions;
private int _width;
private int _height;
private float[,] _values;
public Texture2D Texture;
public void Request(int width, int height, INumberSampler sampler, IColorSampler colorSampler = null)
{
_numberSampler = sampler;
_samplerColor = colorSampler;
_values = new float[width, height];
Init(width, height);
}
public void Request(int width, int height, List positions)
{
_positions = positions;
_samplerColor = new Vector3DisplayColorSampler();
Init(width, height);
}
private void Init(int width, int height)
{
_width = width;
_height = height;
}
protected override void ThreadFunction()
{
if (_numberSampler == null) return;
var _xStart = 0;
var _zStart = 0;
for (var x = _xStart; x < _xStart + _width; x++)
{
for (var z = _zStart; z < _zStart + _height; z++)
{
_values[x - _xStart, z - _zStart] = _numberSampler.GetNumber(null, x, 0, z, 0);
}
}
}
protected override void OnFinished()
{
if (Texture != null) Texture2D.DestroyImmediate(Texture);
Texture = new Texture2D(_width, _height, TextureFormat.RGBA32, false);
if (_numberSampler != null) Texture.SetPixels(NodeUtils.ToColorMap(_values, _samplerColor));
else if (_positions != null)
{
Texture.SetPixels(new UnityEngine.Color[_width * _height]);
foreach (var position in _positions)
{
Texture.SetPixel((int) position.x, (int) position.z, UnityEngine.Color.white);
}
}
Texture.Apply();
}
}
}
================================================
FILE: Assets/Code/Bon/Nodes/Noise/TextureUpdateJob.cs.meta
================================================
fileFormatVersion: 2
guid: 49eb64574fe7248e9829aa9999d0701a
timeCreated: 1470838738
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Code/Bon/Nodes/Noise/UnityPerlinNoiseNode.cs
================================================
using System;
using Assets.Code.Bon.Socket;
using UnityEngine;
namespace Assets.Code.Bon.Nodes.Noise
{
[Serializable]
[GraphContextMenuItem("Noise", "UnityPerlinNoise")]
public class UnityPerlinNoiseNode : AbstractNoiseNode
{
[NonSerialized] private Rect _labelScale;
[NonSerialized] private Rect _labelSeed;
[NonSerialized] private InputSocket _inputSocketScale;
[NonSerialized] private InputSocket _inputSocketSeed;
public UnityPerlinNoiseNode(int id, Graph parent) : base(id, parent)
{
_labelScale = new Rect(6, 0, 30, BonConfig.SocketSize);
_labelSeed = new Rect(6, 20, 30, BonConfig.SocketSize);
_inputSocketScale = new InputSocket(this, typeof(AbstractNumberNode));
_inputSocketSeed = new InputSocket(this, typeof(AbstractNumberNode));
_inputSocketScale.SetDirectInputNumber(5, false);
Sockets.Add(_inputSocketScale);
Sockets.Add(_inputSocketSeed);
//Height = CurrentTextureSize + 70;
_textures.Add(new GUIThreadedTexture()); // heightmap
Height = 60;
}
public override void OnGUI()
{
if (!_textures[0].DoneInitialUpdate) Update();
_textures[0].X = 40;
GUI.Label(_labelScale, "scale");
GUI.Label(_labelSeed, "seed");
DrawTextures();
}
public override float GetNumber(OutputSocket outSocket, float x, float y, float z, float seed)
{
var scale = GetInputNumber(_inputSocketScale, x, y, z, seed);
var socketSeed = GetInputNumber(_inputSocketSeed, x, y, z, seed);
if (float.IsNaN(scale) || float.IsNaN(socketSeed)) return float.NaN;
if (scale == 0) scale = 1;
var modifiedSeed = NodeUtils.ModifySeed(socketSeed, seed);
float noise = Mathf.PerlinNoise(x / scale + modifiedSeed, z / scale + modifiedSeed) * 2f - 1f;
return Math.Max(Math.Min(noise, 1), -1);
}
public override void Update()
{
if (!Collapsed) _textures[0].StartTextureUpdateJob(55, 35, this, null);
}
}
}
================================================
FILE: Assets/Code/Bon/Nodes/Noise/UnityPerlinNoiseNode.cs.meta
================================================
fileFormatVersion: 2
guid: 5b5ed417c5ae449e48a5b3c11c65ce24
timeCreated: 1471538687
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Code/Bon/Nodes/Noise.meta
================================================
fileFormatVersion: 2
guid: ce22aaa2af7374dfe8a7e3ab6a7e5e6d
folderAsset: yes
timeCreated: 1471356267
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Code/Bon/Nodes/Number/AbsNode.cs
================================================
using System;
using Assets.Code.Bon;
using Assets.Code.Bon.Nodes;
using Assets.Code.Bon.Socket;
[Serializable]
[GraphContextMenuItem("Number", "Abs")]
public class AbsNode : AbstractNumberNode
{
private InputSocket _inputSocket;
public AbsNode(int id, Graph parent) : base(id, parent)
{
_inputSocket = new InputSocket(this, typeof(AbstractNumberNode));
Sockets.Add(_inputSocket);
Width = 40;
Height = 40;
}
public override void OnGUI()
{
}
public override void Update()
{
}
public override float GetNumber(OutputSocket outSocket, float x, float y, float z, float seed)
{
var number = GetInputNumber(_inputSocket, x, y, z, seed);
if (float.IsNaN(number)) return float.NaN;
return Math.Abs(number);
}
}
================================================
FILE: Assets/Code/Bon/Nodes/Number/AbsNode.cs.meta
================================================
fileFormatVersion: 2
guid: 29c4e4095930c4081a6e9d0ca760eed7
timeCreated: 1471020772
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Code/Bon/Nodes/Number/ConditionNode.cs
================================================
using System;
using Assets.Code.Bon.Socket;
using UnityEngine;
/**
This node avoids the evaluation of the graph branch that
where the condition is not true. This can be used to improves performance.
**/
namespace Assets.Code.Bon.Nodes.Number
{
[Serializable]
[GraphContextMenuItem("Number", "Condition")]
public class ConditionNode : AbstractNumberNode
{
[NonSerialized] private Rect _labelInput01;
[NonSerialized] private Rect _labelInput02;
[NonSerialized] private Rect _labelCondition;
[NonSerialized] private InputSocket _inputSocket01;
[NonSerialized] private InputSocket _inputSocket02;
[NonSerialized] private InputSocket _conditionSocket;
public ConditionNode(int id, Graph parent) : base(id, parent)
{
_labelInput01 = new Rect(3, 0, 100, 20);
_labelInput02 = new Rect(3, 20, 100, 20);
_labelCondition = new Rect(3, 40, 100, 20);
_inputSocket01 = new InputSocket(this, typeof(AbstractNumberNode));
_inputSocket02 = new InputSocket(this, typeof(AbstractNumberNode));
_conditionSocket = new InputSocket(this, typeof(AbstractNumberNode));
Sockets.Add(_inputSocket01);
Sockets.Add(_inputSocket02);
Sockets.Add(_conditionSocket);
Sockets.Add(_outSocket);
Height = 80;
Width = 80;
}
public override void OnGUI()
{
GUI.Label(_labelInput01, "if (x < 0.0)");
GUI.Label(_labelInput02, "if (x >= 0.0)");
GUI.Label(_labelCondition, "x");
}
public override void Update()
{
}
public override float GetNumber(OutputSocket outSocket, float x, float y, float z, float seed)
{
var conditionValue02 = GetInputNumber(_conditionSocket, x, y, z, seed);
if (float.IsNaN(conditionValue02)) return float.NaN;
if (conditionValue02 < 0.0f) return GetInputNumber(_inputSocket01, x, y, z, seed);
return GetInputNumber(_inputSocket02, x, y, z, seed);
}
}
}
================================================
FILE: Assets/Code/Bon/Nodes/Number/ConditionNode.cs.meta
================================================
fileFormatVersion: 2
guid: 6c5fd74c308fc4b5b828c33cb29c5dc5
timeCreated: 1469219099
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Code/Bon/Nodes/Number/LimitNode.cs
================================================
using System;
using Assets.Code.Bon.Socket;
using UnityEngine;
namespace Assets.Code.Bon.Nodes.Number
{
[Serializable]
[GraphContextMenuItem("Number", "Limit")]
public class LimitNode : AbstractNumberNode {
[SerializeField] private bool _minActive;
[SerializeField] private bool _maxActive;
[NonSerialized] private InputSocket _inputSocket01;
[NonSerialized] private InputSocket _inputSocketMin;
[NonSerialized] private InputSocket _inputSocketMax;
[NonSerialized] private Rect _tmpRect;
public LimitNode(int id, Graph parent) : base(id, parent)
{
_inputSocket01 = new InputSocket(this, typeof(AbstractNumberNode));
Sockets.Add(_inputSocket01);
_inputSocketMin = new InputSocket(this, typeof(AbstractNumberNode));
Sockets.Add(_inputSocketMin);
_inputSocketMax = new InputSocket(this, typeof(AbstractNumberNode));
Sockets.Add(_inputSocketMax);
_tmpRect = new Rect();
Height = 80;
Width = 50;
}
public override void OnGUI()
{
_tmpRect.Set(3, 20, 50, 20);
var currentMin = GUI.Toggle(_tmpRect, _minActive, "min");
_tmpRect.Set(3, 40, 50, 20);
var currentMax = GUI.Toggle(_tmpRect, _maxActive, "max");
if (currentMin != _minActive || currentMax != _maxActive) TriggerChangeEvent();
_maxActive = currentMax;
_minActive = currentMin;
}
public override void Update()
{
}
public override float GetNumber(OutputSocket outSocket, float x, float y, float z, float seed)
{
var value01 = GetInputNumber(_inputSocket01, x, y, z, seed);
if (float.IsNaN(value01)) return float.NaN;
if (_minActive)
{
var min = GetInputNumber(_inputSocketMin, x, y, z, seed);
if (float.IsNaN(min)) return float.NaN;
value01 = Math.Min(value01, min);
}
if (_maxActive)
{
var max = GetInputNumber(_inputSocketMax, x, y, z, seed);
if (float.IsNaN(max)) return float.NaN;
value01 = Math.Max(value01, max);
}
return value01;
}
}
}
================================================
FILE: Assets/Code/Bon/Nodes/Number/LimitNode.cs.meta
================================================
fileFormatVersion: 2
guid: 89c47b920602c4967bf989ea57a6f93a
timeCreated: 1471101336
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Code/Bon/Nodes/Number/MixNode.cs
================================================
using System;
using Assets.Code.Bon.Socket;
using UnityEngine;
namespace Assets.Code.Bon.Nodes.Number
{
[Serializable]
[GraphContextMenuItem("Number", "Mix")]
public class MixNode : AbstractNumberNode
{
[NonSerialized] private Rect labelInput01;
[NonSerialized] private Rect labelInput02;
[NonSerialized] private Rect labelFactor;
[NonSerialized] private InputSocket _inputSocket01;
[NonSerialized] private InputSocket _inputSocket02;
[NonSerialized] private InputSocket _factorSocket;
public MixNode(int id, Graph parent) : base(id, parent)
{
labelInput01 = new Rect(3, 0, 100, 20);
labelInput02 = new Rect(3, 20, 100, 20);
labelFactor = new Rect(3, 40, 100, 20);
_inputSocket01 = new InputSocket(this, typeof(AbstractNumberNode));
_inputSocket02 = new InputSocket(this, typeof(AbstractNumberNode));
_factorSocket = new InputSocket(this, typeof(AbstractNumberNode));
Sockets.Add(_inputSocket01);
Sockets.Add(_inputSocket02);
Sockets.Add(_factorSocket);
Height = 80;
Width = 80;
}
public override void OnGUI()
{
GUI.Label(labelInput01, "in 1");
GUI.Label(labelInput02, "in 2");
GUI.Label(labelFactor, "factor (0 - 1)");
}
public override void Update()
{
}
public static float Clamp(float value, float min, float max)
{
return value < min ? min : value > max ? max : value;
}
public override float GetNumber(OutputSocket outSocket, float x, float y, float z, float seed)
{
var factorValue = GetInputNumber(_factorSocket, x, y, z, seed);
if (float.IsNaN(factorValue)) return float.NaN;
// to avoid calc of obsolete values here..
if (factorValue <= 0) return GetInputNumber(_inputSocket01, x, y, z, seed);
if (factorValue >= 1) return GetInputNumber(_inputSocket02, x, y, z, seed);
float v1 = GetInputNumber(_inputSocket01, x, y, z, seed);
float v2 = GetInputNumber(_inputSocket02, x, y, z, seed);
v1 = Clamp(v1, 0, 1);
v2 = Clamp(v2, 0, 1);
if (float.IsNaN(v1) || float.IsNaN(v2)) return float.NaN;
return v1 * (1 - factorValue) + v2 * factorValue;
}
}
}
================================================
FILE: Assets/Code/Bon/Nodes/Number/MixNode.cs.meta
================================================
fileFormatVersion: 2
guid: 0763470b3c68b417fb187271dbd6e67a
timeCreated: 1469222135
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Code/Bon/Nodes/Number/NumberDisplayNode.cs
================================================
using System;
using Assets.Code.Bon.Socket;
using UnityEngine;
namespace Assets.Code.Bon.Nodes.Number
{
[Serializable]
[GraphContextMenuItem("Number", "Display")]
public class NumberDisplayNode : AbstractNumberNode
{
[NonSerialized] public float Value;
[NonSerialized] private Rect _textFieldArea;
[NonSerialized] private InputSocket _inSocket;
public NumberDisplayNode(int id, Graph parent) : base(id, parent)
{
_textFieldArea = new Rect(10, 0, 80, BonConfig.SocketSize);
_inSocket = new InputSocket(this, typeof(AbstractNumberNode));
Sockets.Add(_inSocket);
Height = 20 + BonConfig.SocketOffsetTop;
}
public override void OnGUI()
{
GUI.Label(_textFieldArea, Value + "");
}
public override void Update()
{
Value = GetInputNumber(_inSocket, 0, 0, 0, 0);
}
public override float GetNumber(OutputSocket outSocket, float x, float y, float z, float seed)
{
return GetInputNumber(_inSocket, x, y, z, seed);
}
}
}
================================================
FILE: Assets/Code/Bon/Nodes/Number/NumberDisplayNode.cs.meta
================================================
fileFormatVersion: 2
guid: 1e4014aa69aa7452888559025d3201ad
timeCreated: 1471101004
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Code/Bon/Nodes/Number/NumberMultiNode.cs
================================================
using System;
using Assets.Code.Bon.Socket;
namespace Assets.Code.Bon.Nodes.Number
{
[Serializable]
[GraphContextMenuItem("Number", "Multi")]
public class NumberMultiNode : AbstractNumberNode
{
[NonSerialized] private InputSocket _inputSocket;
public NumberMultiNode(int id, Graph parent) : base(id, parent)
{
_inputSocket = new InputSocket(this, typeof(AbstractNumberNode));
Sockets.Add(_inputSocket);
Sockets.Add(new OutputSocket(this, typeof(AbstractNumberNode))); // second output
SocketTopOffsetInput = 15;
Width = 50;
Height = 60;
}
public override void OnGUI()
{
}
public override void Update()
{
}
public override float GetNumber(OutputSocket outSocket, float x, float y, float z, float seed)
{
return GetInputNumber(_inputSocket, x, y, z, seed);
}
}
}
================================================
FILE: Assets/Code/Bon/Nodes/Number/NumberMultiNode.cs.meta
================================================
fileFormatVersion: 2
guid: fd104f85215644d598756fa285ace779
timeCreated: 1471101004
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Code/Bon/Nodes/Number/NumberOperatorNode.cs
================================================
using System;
using Assets.Code.Bon.Socket;
using UnityEngine;
namespace Assets.Code.Bon.Nodes.Number
{
[Serializable]
[GraphContextMenuItem("Number", "Operator")]
public class NumberOperatorNode : AbstractNumberNode
{
[SerializeField] private int _selectedMode;
[NonSerialized] public static string[] Operations = { "add", "sub", "mul", "div" };
[NonSerialized] private InputSocket _inputSocket01;
[NonSerialized] private InputSocket _inputSocket02;
public NumberOperatorNode(int id, Graph parent) : base(id, parent)
{
_inputSocket01 = new InputSocket(this, typeof(AbstractNumberNode));
Sockets.Add(_inputSocket01);
_inputSocket02 = new InputSocket(this, typeof(AbstractNumberNode));
Sockets.Add(_inputSocket02);
Height = 95;
Width = 65;
}
public override void OnGUI()
{
GUILayout.BeginHorizontal();
GUILayout.FlexibleSpace();
int newMode = GUILayout.SelectionGrid(_selectedMode,Operations,1,"toggle");
if (newMode != _selectedMode)
{
_selectedMode = newMode;
TriggerChangeEvent();
}
GUILayout.FlexibleSpace();
GUILayout.EndHorizontal();
}
public override void Update()
{
}
public override float GetNumber(OutputSocket outSocket, float x, float y, float z, float seed)
{
var value01 = GetInputNumber(_inputSocket01, x, y, z, seed);
var value02 = GetInputNumber(_inputSocket02, x, y, z, seed);
if (!float.IsNaN(value01) && !float.IsNaN(value02)) return Calculate(value01, value02);
return float.NaN;
}
public float Calculate(float value01, float value02)
{
if (_selectedMode == 0) return value01 + value02;
if (_selectedMode == 1) return value01 - value02;
if (_selectedMode == 2) return value01 * value02;
if (_selectedMode == 3)
{
if (value02.Equals(0)) return float.NaN;
return value01 / value02;
}
return float.NaN;
}
public void SetMode(Operator o)
{
if (o == Operator.Add) _selectedMode = 0;
if (o == Operator.Substract) _selectedMode = 1;
if (o == Operator.Multiply) _selectedMode = 2;
if (o == Operator.Divide) _selectedMode = 3;
}
}
public enum Operator
{
Add,
Substract,
Multiply,
Divide
}
}
================================================
FILE: Assets/Code/Bon/Nodes/Number/NumberOperatorNode.cs.meta
================================================
fileFormatVersion: 2
guid: e74716f60a445496890a0234e0291668
timeCreated: 1470916639
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Code/Bon/Nodes/Number/PowNode.cs
================================================
using System;
using Assets.Code.Bon;
using Assets.Code.Bon.Nodes;
using Assets.Code.Bon.Socket;
using UnityEngine;
[Serializable]
[GraphContextMenuItem("Number", "Pow")]
public class PowNode : AbstractNumberNode
{
private InputSocket _valueSocket01;
private InputSocket _valueSocket02;
public PowNode(int id, Graph parent) : base(id, parent)
{
_valueSocket01 = new InputSocket(this, typeof(AbstractNumberNode));
_valueSocket02 = new InputSocket(this, typeof(AbstractNumberNode));
Sockets.Add(_valueSocket01);
Sockets.Add(_valueSocket02);
Width = 50;
Height = 60;
}
public override void OnGUI()
{
}
public override void Update()
{
}
public override float GetNumber(OutputSocket outSocket, float x, float y, float z, float seed)
{
float v1 = GetInputNumber(_valueSocket01, x, y, z, seed);
float v2 = GetInputNumber(_valueSocket02, x, y, z, seed);
if (float.IsNaN(v1) || float.IsNaN(v2)) return float.NaN;
return (float) Math.Pow(v1, v2);
}
}
================================================
FILE: Assets/Code/Bon/Nodes/Number/PowNode.cs.meta
================================================
fileFormatVersion: 2
guid: 9b267d897fee7436e84d859ffd00bd9e
timeCreated: 1471103320
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Code/Bon/Nodes/Number/RangeNode.cs
================================================
using System;
using Assets.Code.Bon;
using Assets.Code.Bon.Nodes;
using Assets.Code.Bon.Socket;
using UnityEngine;
[Serializable]
[GraphContextMenuItem("Number", "Range")]
public class RangeNode : AbstractNumberNode {
[SerializeField] private int _selectedMode;
[NonSerialized] private InputSocket _inputSocket01;
[NonSerialized] public static string[] Modes = {"[-1:1] to [0:1]", "[0:1] to [-1:1]"};
public RangeNode(int id, Graph parent) : base(id, parent)
{
_inputSocket01 = new InputSocket(this, typeof(AbstractNumberNode));
Sockets.Add(_inputSocket01);
Height = 60;
Width = 100;
}
public override void OnGUI()
{
GUILayout.BeginHorizontal();
GUILayout.FlexibleSpace();
int newMode = GUILayout.SelectionGrid(_selectedMode, Modes, 1, "toggle");
if (newMode != _selectedMode)
{
_selectedMode = newMode;
TriggerChangeEvent();
}
GUILayout.FlexibleSpace();
GUILayout.EndHorizontal();
}
public override void Update()
{
}
public override float GetNumber(OutputSocket outSocket, float x, float y, float z, float seed)
{
float value = GetInputNumber(_inputSocket01, x, y, z, seed);
if (float.IsNaN(value)) return float.NaN;
if (_selectedMode == 0) return (value + 1f) / 2f;
return value * 2f - 1f;
}
}
================================================
FILE: Assets/Code/Bon/Nodes/Number/RangeNode.cs.meta
================================================
fileFormatVersion: 2
guid: 5344d8984c423469782c8017053b0bf0
timeCreated: 1471102474
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Code/Bon/Nodes/Number/SineNode.cs
================================================
using System;
using Assets.Code.Bon;
using Assets.Code.Bon.Nodes;
using Assets.Code.Bon.Socket;
[Serializable]
[GraphContextMenuItem("Number", "Sine")]
public class SineNode : AbstractNumberNode
{
private InputSocket _inputSocket;
public SineNode(int id, Graph parent) : base(id, parent)
{
_inputSocket = new InputSocket(this, typeof(AbstractNumberNode));
Sockets.Add(_inputSocket);
Width = 50;
Height = 50;
}
public override void OnGUI()
{
}
public override void Update()
{
}
public override float GetNumber(OutputSocket outSocket, float x, float y, float z, float seed)
{
var number = GetInputNumber(_inputSocket, x, y, z, seed);
if (float.IsNaN(number)) return float.NaN;
return (float) Math.Sin(number);
}
}
================================================
FILE: Assets/Code/Bon/Nodes/Number/SineNode.cs.meta
================================================
fileFormatVersion: 2
guid: c3780a702faa849ceb9b1d9222b5c313
timeCreated: 1471100393
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Code/Bon/Nodes/Number/SingleNumberSampler.cs
================================================
using Assets.Code.Bon.Interface;
using Assets.Code.Bon.Socket;
namespace Assets.Code.Bon.Nodes.Number
{
public class SingleNumberSampler : INumberSampler
{
private float _number;
public SingleNumberSampler(float number)
{
_number = number;
}
public float GetNumber(OutputSocket s, float x, float y, float z, float seed)
{
return _number;
}
public int GetId()
{
return -1;
}
}
}
================================================
FILE: Assets/Code/Bon/Nodes/Number/SingleNumberSampler.cs.meta
================================================
fileFormatVersion: 2
guid: 72ac3326fbd1f46969e18163b78cad0f
timeCreated: 1471352812
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Code/Bon/Nodes/Number.meta
================================================
fileFormatVersion: 2
guid: 80aea065b504b4f80afc6bc9faeb6efc
folderAsset: yes
timeCreated: 1470915819
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Code/Bon/Nodes/Scatter/GridScatterNode.cs
================================================
using Assets.Code.Bon;
using System;
using System.Collections.Generic;
using Assets.Code.Bon.Nodes;
using Assets.Code.Bon.Socket;
using UnityEngine;
[Serializable]
[GraphContextMenuItem("Scatter", "Grid")]
public class GridScatterNode : AbstractVector3Node
{
private InputSocket _inputX;
private InputSocket _inputZ;
private Rect _tmpRect;
public GridScatterNode(int id, Graph parent) : base(id, parent)
{
_inputX = new InputSocket(this, typeof(AbstractNumberNode));
_inputZ = new InputSocket(this, typeof(AbstractNumberNode));
_inputX.SetDirectInputNumber(5, false);
_inputZ.SetDirectInputNumber(5, false);
Sockets.Add(_inputX);
Sockets.Add(_inputZ);
Sockets.Add(new OutputSocket(this, typeof(AbstractVector3Node)));
_tmpRect = new Rect();
Height = 60;
Width = 50;
}
public override void OnGUI()
{
GUI.skin.label.alignment = TextAnchor.MiddleLeft;
_tmpRect.Set(3, 0, 50, 20);
GUI.Label(_tmpRect, "scale x");
_tmpRect.Set(3, 20, 50, 20);
GUI.Label(_tmpRect, "scale z");
GUI.skin.label.alignment = TextAnchor.MiddleCenter;
}
public override void Update()
{
}
public override List GetVector3List(OutputSocket s, float x, float y, float z, float sizeX, float sizeY, float sizeZ, float seed)
{
float left = x;
float right = x + sizeX;
if (sizeX < 0)
{
left = x + sizeX;
right = x;
}
left = (float) Math.Floor(left);
right = (float) Math.Ceiling(right);
float bottom = z;
float top = z + sizeZ;
if (sizeZ < 0)
{
bottom = z + sizeZ;
top = z;
}
bottom = (float) Math.Floor(bottom);
top = (float) Math.Ceiling(top);
float scaleX = AbstractNumberNode.GetInputNumber(_inputX, x, y, z, seed);
float scaleZ = AbstractNumberNode.GetInputNumber(_inputZ, x, y, z, seed);
List positions = new List();
for (int leftIndex = (int) Math.Floor(left / scaleX); leftIndex <= (int) Math.Ceiling(right / scaleX); leftIndex++)
{
for (int bottomIndex = (int) Math.Floor(bottom / scaleZ); bottomIndex <= (int) Math.Ceiling(top / scaleZ); bottomIndex++)
{
if (leftIndex * scaleX >= left && leftIndex * scaleX < right)
{
if (bottomIndex * scaleZ >= bottom && bottomIndex * scaleZ < top)
{
positions.Add(new Vector3(leftIndex * scaleX, 0, bottomIndex * scaleZ));
}
}
}
}
return positions;
}
}
================================================
FILE: Assets/Code/Bon/Nodes/Scatter/GridScatterNode.cs.meta
================================================
fileFormatVersion: 2
guid: df9f5949009be4df0aa37fe487177579
timeCreated: 1471358547
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Code/Bon/Nodes/Scatter.meta
================================================
fileFormatVersion: 2
guid: e67a778ba4b7a41f39d9eeeaaf8dde83
folderAsset: yes
timeCreated: 1471358424
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Code/Bon/Nodes/String/StringNode.cs
================================================
using System;
using Assets.Code.Bon.Socket;
using UnityEngine;
namespace Assets.Code.Bon.Nodes.String
{
[Serializable]
[GraphContextMenuItem("String", "String")]
public class StringNode : AbstractStringNode {
[SerializeField] private string _text = "";
[NonSerialized] private Rect _textFieldRect;
public StringNode(int id, Graph parent) : base(id, parent)
{
_textFieldRect = new Rect(3, 0, 100, 20);
Sockets.Add(new OutputSocket(this, typeof(AbstractStringNode)));
Height = 45;
Width = 108;
}
public override void OnGUI()
{
string newText = GUI.TextField(_textFieldRect, _text);
if (!newText.Equals(_text)) TriggerChangeEvent();
_text = newText;
}
public override void Update()
{
}
public override string GetString(OutputSocket outSocket)
{
return _text;
}
}
}
================================================
FILE: Assets/Code/Bon/Nodes/String/StringNode.cs.meta
================================================
fileFormatVersion: 2
guid: 486a1e75efea448d2ab23b8d5dd84962
timeCreated: 1470941004
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Code/Bon/Nodes/String.meta
================================================
fileFormatVersion: 2
guid: 7500f91913ae945f189bab29ddbe32a7
folderAsset: yes
timeCreated: 1470940963
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Code/Bon/Nodes/Vector3/OperatorNode.cs
================================================
using System;
using System.Collections.Generic;
using Assets.Code.Bon.Socket;
using UnityEngine;
namespace Assets.Code.Bon.Nodes.Vector3
{
[Serializable]
[GraphContextMenuItem("Vector", "Operator")]
public class OperatorNode : AbstractVector3Node
{
[SerializeField] private int _selectedMode;
[NonSerialized] public static string[] Operations = {"add", "sub", "mul", "div"};
private InputSocket _inputSocketVectors;
private InputSocket _inputSocketX;
private InputSocket _inputSocketY;
private InputSocket _inputSocketZ;
private Rect _tmpRect;
public OperatorNode(int id, Graph parent) : base(id, parent)
{
_tmpRect = new Rect();
_inputSocketVectors = new InputSocket(this, typeof(AbstractVector3Node));
_inputSocketX = new InputSocket(this, typeof(AbstractNumberNode));
_inputSocketY = new InputSocket(this, typeof(AbstractNumberNode));
_inputSocketZ = new InputSocket(this, typeof(AbstractNumberNode));
Sockets.Add(_inputSocketVectors);
Sockets.Add(_inputSocketX);
Sockets.Add(_inputSocketY);
Sockets.Add(_inputSocketZ);
Sockets.Add(new OutputSocket(this, typeof(AbstractVector3Node)));
Width = 100;
}
public override void OnGUI()
{
GUI.skin.label.alignment = TextAnchor.MiddleLeft;
_tmpRect.Set(3, 0, 60, 20);
GUI.Label(_tmpRect, "vec");
_tmpRect.Set(3, 20, 60, 20);
GUI.Label(_tmpRect, "x");
_tmpRect.Set(3, 40, 60, 20);
GUI.Label(_tmpRect, "y");
_tmpRect.Set(3, 60, 60, 20);
GUI.Label(_tmpRect, "z");
_tmpRect.Set(50, 0, 40, 80);
int newMode = GUI.SelectionGrid(_tmpRect, _selectedMode, Operations, 1, "toggle");
if (newMode != _selectedMode)
{
_selectedMode = newMode;
TriggerChangeEvent();
}
GUI.skin.label.alignment = TextAnchor.MiddleCenter;
}
public override void Update()
{
}
public override List GetVector3List(OutputSocket s, float x, float y, float z, float sizeX, float sizeY, float sizeZ, float seed)
{
List vectors = GetInputVector3List(_inputSocketVectors, x, y, z, sizeX, sizeY, sizeZ, seed);
if (vectors != null)
{
for (var i = 0; i < vectors.Count; i++)
{
UnityEngine.Vector3 v = vectors[i];
float valueX = AbstractNumberNode.GetInputNumber(_inputSocketX, v.x, v.y, v.z, seed);
float valueY = AbstractNumberNode.GetInputNumber(_inputSocketY, v.x, v.y, v.z, seed);
float valueZ = AbstractNumberNode.GetInputNumber(_inputSocketZ, v.x, v.y, v.z, seed);
//Debug.Log("valueX " + valueX + " valueY " + valueY + " valueZ " + valueZ);
if (_selectedMode == 0) v.Set(v.x + valueX, v.y + valueY, v.z + valueZ);
if (_selectedMode == 1) v.Set(v.x - valueX, v.y - valueY, v.z - valueZ);
if (_selectedMode == 2) v.Set(v.x * valueX, v.y * valueY, v.z * valueZ);
if (_selectedMode == 3) v.Set(valueX != 0 ? v.x / valueX : v.x, valueY != 0 ? v.y / valueY : v.y, valueZ != 0 ? v.z / valueZ : valueZ);
vectors[i] = v;
//Debug.Log("x " + vectors[i].x + " y " + vectors[i].y + " z " + vectors[i].z + " valueY " + valueY);
}
}
return vectors;
}
}
}
================================================
FILE: Assets/Code/Bon/Nodes/Vector3/OperatorNode.cs.meta
================================================
fileFormatVersion: 2
guid: 1351590c2aa104e03ae69cfd5e0a32b1
timeCreated: 1471367739
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Code/Bon/Nodes/Vector3/RamdomOffsetNode.cs
================================================
using System;
using System.Collections.Generic;
using Assets.Code.Bon.Socket;
using UnityEngine;
namespace Assets.Code.Bon.Nodes.Vector3
{
[Serializable]
[GraphContextMenuItem("Vector", "Random Offset")]
public class RamdomOffsetNode : AbstractVector3Node
{
[SerializeField] private bool _offsetX = true;
[SerializeField] private bool _offsetY = true;
[SerializeField] private bool _offsetZ = true;
private InputSocket _inputSocketVec;
private InputSocket _inputSocketOffset;
private InputSocket _inputSocketNoise;
private Rect _tmpRect;
public RamdomOffsetNode(int id, Graph parent) : base(id, parent)
{
_inputSocketVec = new InputSocket(this, typeof(AbstractVector3Node));
_inputSocketOffset = new InputSocket(this, typeof(AbstractNumberNode));
_inputSocketNoise = new InputSocket(this, typeof(AbstractNumberNode));
Sockets.Add(_inputSocketVec);
Sockets.Add(_inputSocketOffset);
Sockets.Add(_inputSocketNoise);
Sockets.Add(new OutputSocket(this, typeof(AbstractVector3Node)));
Width = 90;
Height = 80;
}
public override void OnGUI()
{
GUI.skin.label.alignment = TextAnchor.MiddleLeft;
_tmpRect.Set(3, 0, 50, 20);
GUI.Label(_tmpRect, "vec");
_tmpRect.Set(3, 20, 50, 20);
GUI.Label(_tmpRect, "offset");
_tmpRect.Set(3, 40, 50, 20);
GUI.Label(_tmpRect, "noise");
_tmpRect.Set(50, 0, 50, 20);
var currentOffsetX = GUI.Toggle(_tmpRect, _offsetX, "x");
_tmpRect.Set(50, 20, 50, 20);
var currentOffsetY = GUI.Toggle(_tmpRect, _offsetY, "y");
_tmpRect.Set(50, 40, 50, 20);
var currentOffsetZ = GUI.Toggle(_tmpRect, _offsetZ, "z");
bool needsUpdate = currentOffsetX != _offsetX || currentOffsetY != _offsetY || currentOffsetZ != _offsetZ;
_offsetX = currentOffsetX;
_offsetY = currentOffsetY;
_offsetZ = currentOffsetZ;
if (needsUpdate) TriggerChangeEvent();
GUI.skin.label.alignment = TextAnchor.MiddleCenter;
}
public override void Update()
{
}
public override List GetVector3List(OutputSocket socket, float x, float y, float z, float sizeX, float sizeY, float sizeZ, float seed)
{
List vec = GetInputVector3List(_inputSocketVec, x, y, z, sizeX, sizeY, sizeZ, seed);
if (vec == null) return null;
for (var i = 0; i < vec.Count; i++)
{
UnityEngine.Vector3 v = vec[i];
float noise = AbstractNumberNode.GetInputNumber(_inputSocketNoise, v.x, v.y, v.z, seed);
float offset = AbstractNumberNode.GetInputNumber(_inputSocketOffset, v.x, v.y, v.z, seed);
if (float.IsNaN(noise) || float.IsNaN(offset)) continue;
if (_offsetX) v.x += offset * noise;
if (_offsetY) v.y += offset * noise;
if (_offsetZ) v.z += offset * noise;
vec[i] = v;
}
return vec;
}
}
}
================================================
FILE: Assets/Code/Bon/Nodes/Vector3/RamdomOffsetNode.cs.meta
================================================
fileFormatVersion: 2
guid: 1db8bbd50a79c450baeb1674a8a689fd
timeCreated: 1471469600
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Code/Bon/Nodes/Vector3/SplitNode.cs
================================================
using System;
using System.Collections.Generic;
using Assets.Code.Bon;
using Assets.Code.Bon.Nodes;
using Assets.Code.Bon.Socket;
using UnityEngine;
[Serializable]
[GraphContextMenuItem("Vector", "Split")]
public class SplitNode : AbstractVector3Node
{
private InputSocket _inputSocketVector;
private InputSocket _inputSocketMask;
private OutputSocket _outputSocket01;
private OutputSocket _outputSocket02;
private Rect _tmpRect;
public SplitNode(int id, Graph parent) : base(id, parent)
{
_inputSocketMask = new InputSocket(this, typeof(AbstractNumberNode));
_inputSocketVector = new InputSocket(this, typeof(AbstractVector3Node));
_outputSocket01 = new OutputSocket(this, typeof(AbstractVector3Node));
_outputSocket02 = new OutputSocket(this, typeof(AbstractVector3Node));
Sockets.Add(_inputSocketVector);
Sockets.Add(_inputSocketMask);
Sockets.Add(_outputSocket01);
Sockets.Add(_outputSocket02);
Height = 60;
}
public override void OnGUI()
{
GUI.skin.label.alignment = TextAnchor.MiddleLeft;
_tmpRect.Set(3, 0, 40, 20);
GUI.Label(_tmpRect, "vec");
_tmpRect.Set(3, 20, 40, 20);
GUI.Label(_tmpRect, "mask");
GUI.skin.label.alignment = TextAnchor.MiddleRight;
_tmpRect.Set(45, 0, 50, 20);
GUI.Label(_tmpRect, ">=0");
_tmpRect.Set(45, 20, 50, 20);
GUI.Label(_tmpRect, "<0");
GUI.skin.label.alignment = TextAnchor.MiddleCenter;
}
public override void Update()
{
}
public override List GetVector3List(OutputSocket outSocket, float x, float y, float z, float sizeX, float sizeY, float sizeZ, float seed)
{
List vec = GetInputVector3List(_inputSocketVector, x, y, z, sizeX, sizeY, sizeZ, seed);
if (vec == null) return null;
List removeList = new List();
for (var i = 0; i < vec.Count; i++)
{
float maskValue = AbstractNumberNode.GetInputNumber(_inputSocketMask, vec[i].x, vec[i].y, vec[i].z, seed);
if (maskValue < 0 && outSocket == _outputSocket01) removeList.Add(vec[i]);
if (maskValue >= 0 && outSocket == _outputSocket02) removeList.Add(vec[i]);
}
foreach (var r in removeList) vec.Remove(r);
return vec;
}
}
================================================
FILE: Assets/Code/Bon/Nodes/Vector3/SplitNode.cs.meta
================================================
fileFormatVersion: 2
guid: 6ef308653e83c459ebabea2deb766392
timeCreated: 1471436831
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Code/Bon/Nodes/Vector3/Vector3DisplayColorSampler.cs
================================================
using Assets.Code.Bon.Interface;
using Assets.Code.Bon.Socket;
namespace Assets.Code.Bon.Nodes.Vector3
{
public class Vector3DisplayColorSampler : IColorSampler {
private UnityEngine.Color transparentColor = new UnityEngine.Color(0f, 0f, 0f, 0f);
public UnityEngine.Color GetColor(OutputSocket s, float i)
{
if (i == 1f) return UnityEngine.Color.white;
return transparentColor;
}
public int GetId()
{
return -1;
}
}
}
================================================
FILE: Assets/Code/Bon/Nodes/Vector3/Vector3DisplayColorSampler.cs.meta
================================================
fileFormatVersion: 2
guid: 59aa5dff7cea342acac92a0116adb1dd
timeCreated: 1471356039
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Code/Bon/Nodes/Vector3/Vector3Node.cs
================================================
using System;
using System.Collections.Generic;
using Assets.Code.Bon.Socket;
using UnityEngine;
namespace Assets.Code.Bon.Nodes.Vector3
{
[Serializable]
[GraphContextMenuItem("Vector", "Vector3")]
public class Vector3Node : AbstractVector3Node
{
private InputSocket _inputX;
private InputSocket _inputY;
private InputSocket _inputZ;
private Rect _tmpRect;
public Vector3Node(int id, Graph parent) : base(id, parent)
{
_tmpRect = new Rect();
_inputX = new InputSocket(this, typeof(AbstractNumberNode));
_inputY = new InputSocket(this, typeof(AbstractNumberNode));
_inputZ = new InputSocket(this, typeof(AbstractNumberNode));
Sockets.Add(_inputX);
Sockets.Add(_inputY);
Sockets.Add(_inputZ);
Sockets.Add(new OutputSocket(this, typeof(AbstractVector3Node)));
Width = 60;
Height = 84;
}
public override void OnGUI()
{
GUI.skin.label.alignment = TextAnchor.MiddleLeft;
_tmpRect.Set(3, 0, 50, 20);
GUI.Label(_tmpRect, "x");
_tmpRect.Set(3, 20, 50, 20);
GUI.Label(_tmpRect, "y");
_tmpRect.Set(3, 40, 50, 20);
GUI.Label(_tmpRect, "z");
GUI.skin.label.alignment = TextAnchor.MiddleCenter;
}
public override void Update()
{
}
public override List GetVector3List(OutputSocket outSocket, float x, float y, float z,
float sizeX, float sizeY, float sizeZ, float seed)
{
float valueX = AbstractNumberNode.GetInputNumber(_inputX, x, y, z, seed);
float valueY = AbstractNumberNode.GetInputNumber(_inputY, x, y, z, seed);
float valueZ = AbstractNumberNode.GetInputNumber(_inputZ, x, y, z, seed);
List positions = new List();
positions.Add(new UnityEngine.Vector3(valueX, valueY, valueZ));
return positions;
}
}
}
================================================
FILE: Assets/Code/Bon/Nodes/Vector3/Vector3Node.cs.meta
================================================
fileFormatVersion: 2
guid: f463bf53a64ff4ed093d20ed55f06c7d
timeCreated: 1471356120
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Code/Bon/Nodes/Vector3.meta
================================================
fileFormatVersion: 2
guid: 4a7ecc73542c049ec85f1bcc9b59b82d
folderAsset: yes
timeCreated: 1471356038
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Code/Bon/Nodes.meta
================================================
fileFormatVersion: 2
guid: ab51cecbb54514cefb3e9eb846f80583
folderAsset: yes
timeCreated: 1466621268
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Code/Bon/Socket/AbstractSocket.cs
================================================
using System;
using Assets.Code.Bon.Nodes;
using Assets.Code.Bon.Socket;
using UnityEngine;
namespace Assets.Code.Bon
{
public abstract class AbstractSocket
{
public Type Type;
public Node Parent;
protected Rect BoxRect;
protected RectOffset Padding;
protected AbstractSocket(Node parent, Type type)
{
Type = type;
Padding = new RectOffset(0, 0, -2, 0);
Parent = parent;
BoxRect.width = BonConfig.SocketSize;
BoxRect.height = BonConfig.SocketSize;
}
/// The x position of the node
public float X
{
get { return BoxRect.x; }
set { BoxRect.x = value; }
}
/// The y position of the node
public float Y
{
get { return BoxRect.y; }
set { BoxRect.y = value; }
}
public abstract bool IsConnected();
protected abstract void OnDraw();
public abstract bool Intersects(Vector2 nodePosition);
public void Draw()
{
GUI.skin.box.normal.textColor = Node.GetEdgeColor(Type);
GUI.skin.box.padding = Padding;
GUI.skin.box.fontSize = 14;
GUI.skin.box.fontStyle = FontStyle.Bold;
OnDraw();
}
public bool IsInput()
{
return GetType() == typeof(InputSocket);
}
public bool IsOutput()
{
return GetType() == typeof(OutputSocket);
}
}
}
================================================
FILE: Assets/Code/Bon/Socket/AbstractSocket.cs.meta
================================================
fileFormatVersion: 2
guid: b436cb7caba1e43ea88da1432d8051d9
timeCreated: 1471525692
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Code/Bon/Socket/InputSocket.cs
================================================
using System;
using Assets.Code.Bon.Nodes;
using UnityEngine;
namespace Assets.Code.Bon.Socket
{
public class InputSocket : AbstractSocket {
public Edge Edge;
private Rect _directInputRect;
private float _directInputNumber = float.NaN;
private string _directInputString = "0";
public InputSocket(Node parent, Type type) : base(parent, type)
{
}
public bool CanGetResult()
{
if (IsInDirectInputMode()) return true;
return IsInput() && IsConnected();
}
public bool IsInDirectInputMode()
{
return Type == typeof(AbstractNumberNode) && IsInput() && Edge == null;
}
private float CalcDirectInputOffset()
{
return GUI.skin.textField.CalcSize(new GUIContent(_directInputString)).x + 5;
}
private void DrawDirectNumberInput()
{
float width = CalcDirectInputOffset();
BoxRect.x -= width;
GUI.Box(BoxRect, ">");
_directInputRect.Set(BoxRect.x + BoxRect.width, BoxRect.y, width, BoxRect.height);
if (NodeUtils.FloatTextField(_directInputRect, ref _directInputString))
{
_directInputNumber = float.Parse(_directInputString);
Parent.TriggerChangeEvent();
}
BoxRect.x += width;
}
public float GetDirectInputNumber()
{
if (float.IsNaN(_directInputNumber)) _directInputNumber = float.Parse(_directInputString);
return _directInputNumber;
}
public void SetDirectInputNumber(float number, bool triggerChangeEvent)
{
if (!float.IsNaN(number))
{
_directInputNumber = number;
_directInputString = number + "";
if (triggerChangeEvent) Parent.TriggerChangeEvent();
}
}
public override bool IsConnected()
{
return Edge != null;
}
public override bool Intersects(Vector2 nodePosition)
{
if (Parent.Collapsed) return false;
if (IsInDirectInputMode())
{
float width = CalcDirectInputOffset();
BoxRect.x -= width;
var intersects = BoxRect.Contains(nodePosition);
BoxRect.x += width;
return intersects;
}
return BoxRect.Contains(nodePosition);
}
protected override void OnDraw()
{
if (IsInDirectInputMode()) DrawDirectNumberInput();
else GUI.Box(BoxRect, ">");
}
public OutputSocket GetConnectedSocket()
{
return Edge.Output;
}
}
}
================================================
FILE: Assets/Code/Bon/Socket/InputSocket.cs.meta
================================================
fileFormatVersion: 2
guid: 2e13361cd5d234f088308b5f550258b4
timeCreated: 1471525723
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Code/Bon/Socket/OutputSocket.cs
================================================
using System;
using System.Collections.Generic;
using UnityEngine;
namespace Assets.Code.Bon.Socket
{
public class OutputSocket : AbstractSocket
{
public List Edges;
public OutputSocket(Node parent, Type type) : base(parent, type)
{
Edges = new List();
}
public override bool IsConnected()
{
return Edges.Count > 0;
}
public override bool Intersects(Vector2 nodePosition)
{
if (Parent.Collapsed) return false;
return BoxRect.Contains(nodePosition);
}
protected override void OnDraw()
{
GUI.Box(BoxRect, ">");
}
}
}
================================================
FILE: Assets/Code/Bon/Socket/OutputSocket.cs.meta
================================================
fileFormatVersion: 2
guid: d8967716d69734b8a92df22db10ad90c
timeCreated: 1471525713
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Code/Bon/Socket.meta
================================================
fileFormatVersion: 2
guid: bbfbe20d4a0f34c0482bdb14081b2251
folderAsset: yes
timeCreated: 1471525691
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Code/Bon/StandardGraphController.cs
================================================
using UnityEngine;
namespace Assets.Code.Bon
{
public class StandardGraphController
{
public StandardGraphController()
{
}
public void Register()
{
EventManager.OnCreateGraph += OnCreate;
EventManager.OnFocusGraph += OnFocus;
EventManager.OnCloseGraph += OnClose;
EventManager.OnLinkEdge += OnLink;
EventManager.OnUnLinkSockets += OnUnLink;
EventManager.OnUnLinkedSockets += OnUnLinked;
EventManager.OnAddedNode += OnNodeAdded;
EventManager.OnNodeRemoved += OnNodeRemoved;
EventManager.OnChangedNode += OnNodeChanged;
EventManager.OnFocusNode += OnFocusNode;
EventManager.OnEditorWindowOpen += OnWindowOpen;
}
private void OnWindowOpen()
{
}
public void OnCreate(Graph graph)
{
graph.UpdateNodes();
}
public void OnFocus(Graph graph)
{
Log.Info("OnFocus " + graph);
}
public void OnClose(Graph graph)
{
Log.Info("OnClose " + graph);
}
// ======= Events =======
public void OnLink(Graph graph, Edge edge)
{
Log.Info("OnLink: Node " + edge.Output.Parent.Id + " with Node " + edge.Input.Parent.Id);
graph.UpdateDependingNodes(edge.Output.Parent);
}
public void OnUnLink(Graph graph, AbstractSocket s01, AbstractSocket s02)
{
// Log.Info("OnUnLink: Node " + s01.Edge.Output.Parent.Id + " from Node " + s02.Edge.Input.Parent.Id);
}
public void OnUnLinked(Graph graph, AbstractSocket s01, AbstractSocket s02)
{
Log.Info("OnUnLinked: Socket " + s02 + " and Socket " + s02);
var input = s01.IsInput () ? s01 : s02;
graph.UpdateDependingNodes(input.Parent);
}
public void OnNodeAdded(Graph graph, Node node)
{
Log.Info("OnNodeAdded: Node " + node.GetType() + " with id " + node.Id);
}
public void OnNodeRemoved(Graph graph, Node node)
{
Log.Info("OnNodeRemoved: Node " + node.GetType() + " with id " + node.Id);
}
public void OnNodeChanged(Graph graph, Node node)
{
Log.Info("OnNodeChanged: Node " + node.GetType() + " with id " + node.Id);
graph.UpdateDependingNodes(node);
}
public void OnFocusNode(Graph graph, Node node)
{
Log.Info("OnFocus: " + node.Id);
}
}
}
================================================
FILE: Assets/Code/Bon/StandardGraphController.cs.meta
================================================
fileFormatVersion: 2
guid: cc8905af25d8c494992be201fe195601
timeCreated: 1466621268
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Code/Bon/Thread/GUIThreadedTexture.cs
================================================
using System;
using System.Collections.Generic;
using Assets.Code.Bon.Interface;
using Assets.Code.Bon.Nodes.Noise;
using UnityEngine;
using UnityEngineInternal;
public class GUIThreadedTexture {
private Rect _textureArea;
private bool _isUpdatingTexture;
private TextureUpdateJob _job;
private Texture2D _texture;
private bool _initialUpdate;
public bool IsUpdating
{
get { return _isUpdatingTexture; }
}
public bool DoneInitialUpdate
{
get { return _initialUpdate; }
}
public float X
{
get { return _textureArea.x; }
set { _textureArea.x = value; }
}
public float Y
{
get { return _textureArea.y; }
set { _textureArea.y = value; }
}
public float Width
{
get { return _textureArea.width; }
}
public float Height
{
get { return _textureArea.height; }
}
public GUIThreadedTexture()
{
_textureArea = new Rect(6, 0, 0, 0);
_job = new TextureUpdateJob();
}
public void OnGUI()
{
if (!DoneInitialUpdate) return;
_isUpdatingTexture = UpdateTextureJob();
if (_texture != null && !_isUpdatingTexture) GUI.DrawTexture(_textureArea, _texture);
}
public void StartTextureUpdateJob(int width, int height, INumberSampler numberSampler, IColorSampler samplerColor)
{
InitJob(width, height);
_job.Request(width, height, numberSampler, samplerColor);
_job.Start();
}
public void StartTextureUpdateJob(int width, int height, List vectors)
{
InitJob(width, height);
_job.Request(width, height, vectors);
_job.Start();
}
private void InitJob(int width, int height)
{
_textureArea.Set(_textureArea.x, _textureArea.y, width, height);
_job = new TextureUpdateJob();
_initialUpdate = true;
if (_texture == null) CreateTexture(width, height);
if (_job != null && !_job.IsDone) _job.Abort();
}
private bool UpdateTextureJob()
{
if (_job == null) return false;
_job.Update();
/*if (!CanCreatePreview())
{
}*/
if (!_job.IsDone) return true;
_texture = _job.Texture;
_job.Abort();
_job = null;
return false;
}
private void CreateTexture(int width, int height)
{
if (_texture != null) Texture2D.DestroyImmediate(_texture);
_texture = new Texture2D(width, height, TextureFormat.RGB24, false);
_textureArea.Set(_textureArea.x, _textureArea.y, width, height);
}
public void Hide()
{
if (_job != null) _job.Abort();
if (_texture != null) Texture2D.DestroyImmediate(_texture);
_job = null;
}
}
================================================
FILE: Assets/Code/Bon/Thread/GUIThreadedTexture.cs.meta
================================================
fileFormatVersion: 2
guid: 103d8b9b8ff8541328f034529f363aff
timeCreated: 1471345641
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Code/Bon/Thread/ThreadedJob.cs
================================================
using System.Collections;
namespace Assets.Code.Bon.Thread
{
public abstract class ThreadedJob {
private bool _IsDone;
private object _Handle = new object();
private System.Threading.Thread _Thread;
public bool IsDone
{
get
{
bool tmp;
lock (_Handle)
{
tmp = _IsDone;
}
return tmp;
}
set
{
lock (_Handle)
{
_IsDone = value;
}
}
}
public virtual void Start()
{
_Thread = new System.Threading.Thread(Run);
_Thread.Start();
}
public virtual void Abort()
{
if (_Thread != null) _Thread.Abort();
}
protected virtual void ThreadFunction() { }
protected virtual void OnFinished() { }
public virtual bool Update()
{
if (IsDone)
{
OnFinished();
return true;
}
return false;
}
public IEnumerator WaitFor()
{
while(!Update())
{
yield return null;
}
}
private void Run()
{
ThreadFunction();
IsDone = true;
}
public bool IsStarted()
{
return _Thread != null;
}
}
}
================================================
FILE: Assets/Code/Bon/Thread/ThreadedJob.cs.meta
================================================
fileFormatVersion: 2
guid: 3ed789335a32346c698923faa7decf7a
timeCreated: 1469206970
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Code/Bon/Thread.meta
================================================
fileFormatVersion: 2
guid: e8dcaa868079b4e0abd79b198fe7e2de
folderAsset: yes
timeCreated: 1469213416
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Code/Bon.meta
================================================
fileFormatVersion: 2
guid: 649bedfe243624550953701819e4a256
folderAsset: yes
timeCreated: 1466621268
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Code.meta
================================================
fileFormatVersion: 2
guid: 346fd47a331c84b6faa3f6260e3ab4f4
folderAsset: yes
timeCreated: 1466621268
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Editor/Bon/BonCanvas.cs
================================================
using System;
using System.ComponentModel;
using System.Net.NetworkInformation;
using System.Security.Cryptography;
using UnityEditor;
using UnityEngine;
using Assets.Code.Bon;
namespace Assets.Editor.Bon
{
[Serializable]
public class BonCanvas
{
public GUIStyle Style = new GUIStyle();
public const float CanvasSize = 100000;
public string FilePath;
public Rect DrawArea = new Rect();
[SerializeField]
public float Zoom = 1;
[SerializeField]
public Vector2 Position = new Vector2();
public Graph Graph;
public Rect TabButton = new Rect();
public Rect CloseTabButton = new Rect();
private Vector2 _tmpVector01 = new Vector2();
private Vector2 _tmpVector02 = new Vector2();
private Color _backgroundColor = new Color(0.18f, 0.18f, 0.18f, 1f);
private Color _backgroundLineColor01 = new Color(0.14f, 0.14f, 0.14f, 1f);
private Color _backgroundLineColor02 = new Color(0.10f, 0.10f, 0.10f, 1f);
private GUIStyle centeredLabelStyle;
public BonCanvas(Graph graph)
{
Graph = graph;
Style.normal.background = CreateBackgroundTexture();
Style.normal.background.wrapMode = TextureWrapMode.Repeat;
Style.fixedHeight = CanvasSize;
Style.fixedWidth = CanvasSize;
}
private Texture2D CreateBackgroundTexture()
{
var texture = new Texture2D(100, 100, TextureFormat.ARGB32, false);
for (var x = 0; x < texture.width; x++)
{
for (var y = 0; y < texture.width; y++)
{
bool isVerticalLine = (x%11 == 0);
bool isHorizontalLine = (y % 11 == 0);
if (x == 0 || y == 0) texture.SetPixel(x, y, _backgroundLineColor02);
else if (isVerticalLine || isHorizontalLine) texture.SetPixel(x, y, _backgroundLineColor01);
else texture.SetPixel(x, y, _backgroundColor);
}
}
texture.filterMode = FilterMode.Trilinear;
texture.wrapMode = TextureWrapMode.Repeat;
texture.Apply();
return texture;
}
public void Draw(EditorWindow window, Rect region, AbstractSocket currentDragingSocket)
{
if (centeredLabelStyle == null) centeredLabelStyle = GUI.skin.GetStyle("Label");
centeredLabelStyle.alignment = TextAnchor.MiddleCenter;
EditorZoomArea.Begin(Zoom, region);
if (Style.normal.background == null) Style.normal.background = CreateBackgroundTexture();
GUI.DrawTextureWithTexCoords(DrawArea, Style.normal.background, new Rect(0, 0, 1000, 1000));
DrawArea.Set(Position.x, Position.y, CanvasSize, CanvasSize);
GUILayout.BeginArea(DrawArea);
DrawEdges();
window.BeginWindows();
DrawNodes();
window.EndWindows();
DrawDragEdge(currentDragingSocket);
for (var i = 0; i < Graph.GetNodeCount(); i++)
{
Graph.GetNodeAt(i).GUIDrawSockets();
}
GUILayout.EndArea();
EditorZoomArea.End();
}
private void DrawDragEdge(AbstractSocket currentDragingSocket)
{
if (currentDragingSocket != null)
{
_tmpVector01 = Edge.GetEdgePosition(currentDragingSocket, _tmpVector01);
_tmpVector02 = Edge.GetTangentPosition(currentDragingSocket, _tmpVector01);
Edge.DrawEdge(_tmpVector01, _tmpVector02, Event.current.mousePosition, Event.current.mousePosition,
currentDragingSocket.Type);
}
}
public void DrawNodes()
{
for (var i = 0; i < Graph.GetNodeCount(); i++)
{
Node node = Graph.GetNodeAt(i);
if (!node.Collapsed) node.WindowRect.height = node.Height;
node.WindowRect = GUI.Window(node.Id, node.WindowRect, GUIDrawNodeWindow, node.Name + "");
if (node.Collapsed)
{
// title bar text is not visible if collapsed
GUI.Label(node.WindowRect, node.Name + "", centeredLabelStyle);
}
node.GUIAlignSockets();
}
}
void GUIDrawNodeWindow(int nodeId)
{
Node node = Graph.GetNode(nodeId);
node.ContentRect.Set(0, BonConfig.SocketOffsetTop,
node.Width, node.Height - BonConfig.SocketOffsetTop);
if (Event.current.type == EventType.MouseDown && Event.current.button == 1)
{
GenericMenu m = new GenericMenu();
m.AddDisabledItem(new GUIContent(node.Name + " (" + nodeId + ")"));
m.AddSeparator("");
m.AddItem(new GUIContent("Delete"), false, DeleteNode, nodeId);
if (node.Collapsed) m.AddItem(new GUIContent("Expand"), false, ExpandNode, nodeId);
else m.AddItem(new GUIContent("Collapse"), false, CollapseNode, nodeId);
m.ShowAsContext();
Event.current.Use();
}
if (!node.Collapsed)
{
GUILayout.BeginArea(node.ContentRect);
GUI.color = Color.white;
node.OnGUI();
GUILayout.EndArea();
}
GUI.DragWindow();
if (Event.current.GetTypeForControl(node.Id) == EventType.Used)
{
if (Node.LastFocusedNodeId != node.Id) node.OnFocus();
Node.LastFocusedNodeId = node.Id;
}
}
private void CollapseNode(object nodeId)
{
Node node = Graph.GetNode((int) nodeId);
node.Collapse();
}
private void ExpandNode(object nodeId)
{
Graph.GetNode((int) nodeId).Expand();
}
private void DeleteNode(object nodeId)
{
Graph.RemoveNode((int) nodeId);
}
public void DrawEdges()
{
for (var i = 0; i < Graph.GetNodeCount(); i++)
{
Graph.GetNodeAt(i).GUIDrawEdges();
}
}
public Node GetFocusedNode()
{
for (var i = 0; i < Graph.GetNodeCount(); i++)
{
Node node = Graph.GetNodeAt(i);
if (node.HasFocus()) return node;
}
return null;
}
/// Returns the socket at the window position.
/// The position to get the Socket from in window coordinates
/// The socket at the posiiton or null or null.
public AbstractSocket GetSocketAt(Vector2 windowPosition)
{
Vector2 projectedPosition = ProjectToCanvas(windowPosition);
for (var i = 0; i < Graph.GetNodeCount(); i++)
{
Node node = Graph.GetNodeAt(i);
AbstractSocket socket = node.SearchSocketAt(projectedPosition);
if (socket != null)
{
return socket;
}
}
return null;
}
public Node CreateNode(Type nodeType, Vector2 windowPosition)
{
Node node = (Node) Graph.CreateNode(nodeType);
var position = ProjectToCanvas(windowPosition);
node.X = position.x;
node.Y = position.y;
Graph.AddNode(node);
return node;
}
public void RemoveFocusedNode()
{
Node node = GetFocusedNode();
if (node != null) Graph.RemoveNode(node);
}
public Vector2 ProjectToCanvas(Vector2 windowPosition)
{
windowPosition.y += (21) - ((BonWindow.TopOffset*2));
windowPosition = windowPosition/this.Zoom;
windowPosition.x -= (this.DrawArea.x);
windowPosition.y -= (this.DrawArea.y);
return windowPosition;
}
}
}
================================================
FILE: Assets/Editor/Bon/BonCanvas.cs.meta
================================================
fileFormatVersion: 2
guid: 10bc549630a4a4a1aae204e1b20e5b35
timeCreated: 1466621268
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Editor/Bon/EditorZoomArea.cs
================================================
using UnityEngine;
/**
This class helps zooming in an editor window
Based on http://martinecker.com/martincodes/unity-editor-window-zooming/
**/
namespace Assets.Editor.Bon
{
public class EditorZoomArea
{
private static Matrix4x4 _prevGuiMatrix;
private static Vector3 _tmpScaleVector = new Vector3();
private static Rect _tmpRect = new Rect();
public static Rect Begin(float zoomScale, Rect screenCoordsArea)
{
GUI.EndGroup();
Rect clippedArea = screenCoordsArea.ScaleSizeBy(1.0f / zoomScale, screenCoordsArea.TopLeft());
clippedArea.y += BonWindow.TopOffset;
GUI.BeginGroup(clippedArea);
_prevGuiMatrix = GUI.matrix;
Matrix4x4 translation = Matrix4x4.TRS(clippedArea.TopLeft(), Quaternion.identity, Vector3.one);
_tmpScaleVector.Set(zoomScale, zoomScale, 1.0f);
Matrix4x4 scale = Matrix4x4.Scale(_tmpScaleVector);
GUI.matrix = translation * scale * translation.inverse * GUI.matrix;
return clippedArea;
}
public static void End()
{
GUI.matrix = _prevGuiMatrix;
GUI.EndGroup();
_tmpRect.Set(0, BonWindow.TopOffset, Screen.width, Screen.height);
GUI.BeginGroup(_tmpRect);
}
}
}
================================================
FILE: Assets/Editor/Bon/EditorZoomArea.cs.meta
================================================
fileFormatVersion: 2
guid: 1e71706962804461ca0510b04bf52324
timeCreated: 1466621268
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Editor/Bon/RectExtensions.cs
================================================
using UnityEngine;
/**
This class extends the funcitonality of a rectangle.
Based on http://martinecker.com/martincodes/unity-editor-window-zooming/
**/
namespace Assets.Editor.Bon
{
public static class RectExtensions
{
private static Vector2 _tmpTopLeft = new Vector2();
public static Vector2 TopLeft(this Rect rect)
{
_tmpTopLeft.Set(rect.xMin, rect.yMin);
return _tmpTopLeft;
}
public static Rect ScaleSizeBy(this Rect rect, float scale)
{
return rect.ScaleSizeBy(scale, rect.center);
}
public static Rect ScaleSizeBy(this Rect rect, float scale, Vector2 pivotPoint)
{
Rect result = rect;
result.x -= pivotPoint.x;
result.y -= pivotPoint.y;
result.xMin *= scale;
result.xMax *= scale;
result.yMin *= scale;
result.yMax *= scale;
result.x += pivotPoint.x;
result.y += pivotPoint.y;
return result;
}
public static Rect ScaleSizeBy(this Rect rect, Vector2 scale)
{
return rect.ScaleSizeBy(scale, rect.center);
}
public static Rect ScaleSizeBy(this Rect rect, Vector2 scale, Vector2 pivotPoint)
{
Rect result = rect;
result.x -= pivotPoint.x;
result.y -= pivotPoint.y;
result.xMin *= scale.x;
result.xMax *= scale.x;
result.yMin *= scale.y;
result.yMax *= scale.y;
result.x += pivotPoint.x;
result.y += pivotPoint.y;
return result;
}
}
}
================================================
FILE: Assets/Editor/Bon/RectExtensions.cs.meta
================================================
fileFormatVersion: 2
guid: ada984af67e5f4e7f8aed9e8f259049f
timeCreated: 1466621268
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Editor/Bon.meta
================================================
fileFormatVersion: 2
guid: dee614b21f6be490f9d087cc50e01050
folderAsset: yes
timeCreated: 1466621268
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Editor/BonWindow.cs
================================================
using System;
using System.Collections.Generic;
using System.Reflection;
using UnityEditor;
using UnityEngine;
using Assets.Code.Bon;
using Assets.Code.Bon.Socket;
using Assets.Editor.Bon;
using System.Linq;
namespace Assets.Editor
{
///
/// This class contains the logic of the editor window. It contains canvases that
/// are containing graphs. It uses the BonLauncher to load, save and close Graphs.
///
public class BonWindow : EditorWindow
{
private const string Name = "BrotherhoodOfNode";
public const int TopOffset = 32;
public const int BottomOffset = 20;
public const int TopMenuHeight = 20;
private const int TabButtonWidth = 200;
private const int TabButtonMargin = 4;
private const int TabCloseButtonSize = TopMenuHeight;
private const int WindowTitleHeight = 21;
private const float CanvasZoomMin = 0.1f;
private const float CanvasZoomMax = 1.0f;
private Rect _openButtonRect = new Rect(0, 0, 80, TopMenuHeight);
private Rect _saveButtonRect = new Rect(80, 0, 80, TopMenuHeight);
private Rect _newButtonRect = new Rect(160, 0, 80, TopMenuHeight);
private Rect _helpButtonRect = new Rect(240, 0, 80, TopMenuHeight);
private Vector2 _nextTranlationPosition;
private Color _tabColorUnselected = new Color(0.8f, 0.8f, 0.8f, 0.5f);
private Color _tabColorSelected = Color.white;
private List _canvasList = new List();
private BonCanvas _currentCanvas;
private Rect _canvasRegion = new Rect();
private AbstractSocket _dragSourceSocket = null;
private Vector2 _lastMousePosition;
private GenericMenu _menu;
private Dictionary _menuEntryToNodeType;
private Rect _tmpRect = new Rect();
[MenuItem("Window/" + Name)]
static void OnCreateWindow()
{
BonWindow window = GetWindow();
// BonWindow window = CreateInstance(); // to create a new window
window.Show();
}
public void OnEnable()
{
Init();
}
public void Init()
{
EditorApplication.playmodeStateChanged = OnPlaymodeStateChanged;
// create GameObject and the Component if it is not added to the scene
titleContent = new GUIContent(Name);
wantsMouseMove = true;
EventManager.TriggerOnWindowOpen();
_menuEntryToNodeType = CreateMenuEntries();
_menu = CreateGenericMenu();
_canvasList.Clear();
_currentCanvas = null;
if (GetLauncher().Graphs.Count > 0) LoadCanvas(GetLauncher().Graphs);
else LoadCanvas(GetLauncher().LoadGraph(BonConfig.DefaultGraphName));
UpdateGraphs();
Repaint();
}
private void OnPlaymodeStateChanged()
{
UpdateGraphs();
Repaint();
}
private void UpdateGraphs()
{
foreach (var graph in GetLauncher().Graphs)
{
graph.ForceUpdateNodes();
}
}
private void LoadCanvas(List graphs)
{
foreach (var graph in graphs) LoadCanvas(graph);
}
private void LoadCanvas(Graph graph)
{
_currentCanvas = new BonCanvas(graph);
_canvasList.Add(_currentCanvas);
}
///
/// Creates a dictonary that maps a menu entry string to a node type using reflection.
///
///
/// Dictonary that maps a menu entry string to a node type
///
public Dictionary CreateMenuEntries()
{
Dictionary menuEntries = new Dictionary();
IEnumerable classesExtendingNode = Assembly.GetAssembly(typeof(Node)).GetTypes()
.Where(myType => myType.IsClass && !myType.IsAbstract && myType.IsSubclassOf(typeof(Node)));
foreach (Type type in classesExtendingNode) menuEntries.Add(GetItemMenuName(type), type);
menuEntries.OrderBy(x => x.Key);
return menuEntries;
}
private string GetItemMenuName(Type type)
{
string path = Node.GetNodePath(type);
if (path != null) return path + "/" + Node.GetNodeName(type);
return Node.GetNodeName(type);
}
private BonLauncher GetLauncher()
{
if (GameObject.Find(BonConfig.GameObjectName) == null)
{
new GameObject(BonConfig.GameObjectName);
Log.Info("Created GameObject '" + BonConfig.GameObjectName + "'");
}
if (GameObject.Find(BonConfig.GameObjectName).GetComponent() == null)
{
Log.Info("Added BonLauncher component to the GameObject '" + BonConfig.GameObjectName + "'");
GameObject.Find(BonConfig.GameObjectName).AddComponent();
}
return GameObject.Find(BonConfig.GameObjectName).GetComponent();
}
/// Draws the UI
void OnGUI()
{
HandleCanvasTranslation();
HandleDragAndDrop();
if (Event.current.type == EventType.ContextClick)
{
_menu.ShowAsContext();
Event.current.Use();
}
HandleMenuButtons();
if (GetLauncher() == null) return;
HandleTabButtons();
if (_currentCanvas != null) {
float infoPanelY = Screen.height - TopOffset - 6;
_tmpRect.Set(5, infoPanelY, 70, 20);
GUI.Label(_tmpRect, "zoom: " + Math.Round(_currentCanvas.Zoom, 1));
_tmpRect.Set(60, infoPanelY, 70, 20);
GUI.Label(_tmpRect, "x: " + Math.Round(_currentCanvas.Position.x));
_tmpRect.Set(130, infoPanelY, 70, 20);
GUI.Label(_tmpRect, "y: " + Math.Round(_currentCanvas.Position.y));
_tmpRect.Set(200, infoPanelY, 70, 20);
GUI.Label(_tmpRect, "nodes: " + _currentCanvas.Graph.GetNodeCount());
}
if (_currentCanvas != null)
{
_canvasRegion.Set(0, TopOffset, Screen.width, Screen.height - 2 * TopOffset - BottomOffset);
_currentCanvas.Draw((EditorWindow) this, _canvasRegion, _dragSourceSocket);
}
_lastMousePosition = Event.current.mousePosition;
Repaint();
}
private void HandleTabButtons()
{
Color standardBackgroundColor = GUI.backgroundColor;
int tabIndex = 0;
BonCanvas canvasToClose = null;
foreach (BonCanvas tmpCanvas in _canvasList)
{
int width = TabButtonWidth + TabButtonMargin + TabCloseButtonSize;
int xOffset = width*tabIndex;
tmpCanvas.TabButton.Set(xOffset, TopMenuHeight + TabButtonMargin,TabButtonWidth, TopMenuHeight);
tmpCanvas.CloseTabButton.Set(xOffset + width - TabCloseButtonSize - TabButtonMargin -4,
TopMenuHeight + TabButtonMargin, TabCloseButtonSize, TabCloseButtonSize);
bool isSelected = (_currentCanvas == tmpCanvas);
string tabName = tmpCanvas.Graph.Name;
//tabName = Path.GetFileName(tmpCanvas.FilePath);
if (isSelected) GUI.backgroundColor = _tabColorSelected;
else GUI.backgroundColor = _tabColorUnselected;
if (GUI.Button(tmpCanvas.TabButton, tabName))
{
SetCurrentCanvas(tmpCanvas);
}
if (isSelected)
{
if (GUI.Button(tmpCanvas.CloseTabButton, "X"))
{
canvasToClose = tmpCanvas;
}
}
tabIndex++;
}
GUI.backgroundColor = standardBackgroundColor;
if (canvasToClose != null) CloseCanvas(canvasToClose);
}
private void SetCurrentCanvas(BonCanvas canvas)
{
UpdateGraphs();
Repaint();
if (canvas != null) EventManager.TriggerOnFocusGraph(canvas.Graph);
_currentCanvas = canvas;
}
private void CloseCanvas(BonCanvas canvas)
{
bool doSave = EditorUtility.DisplayDialog("Do you want to save.", "Do you want to save the graph " + canvas.FilePath + " ?",
"Yes", "No");
if (doSave)
{
if (canvas.FilePath == null) OpenSaveDialog();
else GetLauncher().SaveGraph(canvas.Graph, canvas.FilePath);
}
EventManager.TriggerOnCloseGraph(canvas.Graph);
GetLauncher().RemoveGraph(canvas.Graph);
_canvasList.Remove(canvas);
if (_canvasList.Count > 0) SetCurrentCanvas(_canvasList[0]);
else SetCurrentCanvas(null);
}
private GenericMenu CreateGenericMenu()
{
GenericMenu m = new GenericMenu();
foreach(KeyValuePair entry in _menuEntryToNodeType)
m.AddItem(new GUIContent(entry.Key), false, OnGenericMenuClick, entry.Value);
return m;
}
private void OnGenericMenuClick(object item)
{
if (_currentCanvas != null)
{
_currentCanvas.CreateNode((Type) item, _lastMousePosition);
}
}
private void CreateCanvas(string path)
{
BonCanvas canvas;
if (path != null) canvas = new BonCanvas(GetLauncher().LoadGraph(path));
else canvas = new BonCanvas(GetLauncher().LoadGraph(BonConfig.DefaultGraphName));
canvas.FilePath = path;
_canvasList.Add(canvas);
SetCurrentCanvas(canvas);
}
private void OpenSaveDialog()
{
var path = EditorUtility.SaveFilePanel("save graph data", "", "graph", "json");
if (!path.Equals(""))
{
GetLauncher().SaveGraph(_currentCanvas.Graph, path);
_currentCanvas.FilePath = path;
}
}
private void HandleMenuButtons()
{
if (GUI.Button(_openButtonRect, "Open"))
{
var path = EditorUtility.OpenFilePanel("load graph data", "", "json");
if (!path.Equals("")) CreateCanvas(path);
}
// Save Button
if (GUI.Button(_saveButtonRect, "Save")) OpenSaveDialog();
// New Button
if (GUI.Button(_newButtonRect, "New")) CreateCanvas(null);
// Help Button
GUI.Button(_helpButtonRect, "Help");
}
private void HandleCanvasTranslation()
{
if (_currentCanvas == null) return;
// Zoom
if (Event.current.type == EventType.ScrollWheel)
{
Vector2 zoomCoordsMousePos = ConvertScreenCoordsToZoomCoords(Event.current.mousePosition);
float zoomDelta = -Event.current.delta.y/150.0f;
float oldZoom = _currentCanvas.Zoom;
_currentCanvas.Zoom = Mathf.Clamp(_currentCanvas.Zoom + zoomDelta, CanvasZoomMin, CanvasZoomMax);
_nextTranlationPosition = _currentCanvas.Position + (zoomCoordsMousePos - _currentCanvas.Position) -
(oldZoom/_currentCanvas.Zoom)*(zoomCoordsMousePos - _currentCanvas.Position);
if (_nextTranlationPosition.x >= 0) _nextTranlationPosition.x = 0;
if (_nextTranlationPosition.y >= 0) _nextTranlationPosition.y = 0;
_currentCanvas.Position = _nextTranlationPosition;
Event.current.Use();
return;
}
// Translate
if (Event.current.type == EventType.MouseDrag &&
(Event.current.button == 0 && Event.current.modifiers == EventModifiers.Alt) ||
Event.current.button == 2)
{
Vector2 delta = Event.current.delta;
delta /= _currentCanvas.Zoom;
_nextTranlationPosition = _currentCanvas.Position + delta;
if (_nextTranlationPosition.x >= 0) _nextTranlationPosition.x = 0;
if (_nextTranlationPosition.y >= 0) _nextTranlationPosition.y = 0;
_currentCanvas.Position = _nextTranlationPosition;
Event.current.Use();
}
}
private void HandleSocketDrag(AbstractSocket dragSource)
{
if (dragSource != null)
{
if (dragSource.IsInput() && dragSource.IsConnected())
{
_dragSourceSocket = ((InputSocket) dragSource).Edge.GetOtherSocket(dragSource);
_currentCanvas.Graph.UnLink((InputSocket) dragSource, (OutputSocket) _dragSourceSocket);
}
if (dragSource.IsOutput()) _dragSourceSocket = dragSource;
Event.current.Use();
}
Repaint();
}
private void HandleSocketDrop(AbstractSocket dropTarget)
{
if (dropTarget != null && dropTarget.GetType() != _dragSourceSocket.GetType())
{
if (dropTarget.IsInput())
{
_currentCanvas.Graph.Link((InputSocket) dropTarget, (OutputSocket) _dragSourceSocket);
}
Event.current.Use();
}
_dragSourceSocket = null;
Repaint();
}
private void HandleDragAndDrop()
{
if (_currentCanvas == null) return;
if (Event.current.type == EventType.MouseDown)
{
HandleSocketDrag(_currentCanvas.GetSocketAt(Event.current.mousePosition));
}
if (Event.current.type == EventType.MouseUp && _dragSourceSocket != null)
{
HandleSocketDrop(_currentCanvas.GetSocketAt(Event.current.mousePosition));
}
if (Event.current.type == EventType.MouseDrag)
{
if (_dragSourceSocket != null) Event.current.Use();
}
}
private Vector2 ConvertScreenCoordsToZoomCoords(Vector2 screenCoords)
{
return (screenCoords - _canvasRegion.TopLeft())/_currentCanvas.Zoom + _currentCanvas.Position;
}
}
}
================================================
FILE: Assets/Editor/BonWindow.cs.meta
================================================
fileFormatVersion: 2
guid: d0e35861c4d634e37bac44b54a6fa54c
timeCreated: 1466621268
licenseType: Pro
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Editor.meta
================================================
fileFormatVersion: 2
guid: 87d3b5ebc92f9420784d5748ca012ae8
folderAsset: yes
timeCreated: 1466621268
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: Assets/Untitled.unity.meta
================================================
fileFormatVersion: 2
guid: 75deddd5a4dcb4e79a064a646b245523
timeCreated: 1466621268
licenseType: Pro
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:
================================================
FILE: LICENSE.txt
================================================
The MIT License (MIT)
Copyright (c) 2016 Luca Hofmann
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
================================================
FILE: ProjectSettings/ProjectVersion.txt
================================================
m_EditorVersion: 5.3.5p5
m_StandardAssetsVersion: 0
================================================
FILE: README.md
================================================
An improved version of this software is available at the Unity Asset Store: https://www.assetstore.unity3d.com/#!/content/72081
I am thinking about to open source the improved tool and deprecate BoN. The time investment would only make sense to me if there would be developers to contribute on GDI.
# BrotherhoodOfNode
A visual graph editor for Unity3D


### Install
#### This project is still under development... But you can use it already!
1. copy the files from the asset folder to your unity project asset folder
2. in unity click on window->BrotherhoodOfNode to open the editor window
3. continue reading and afterwards take a look at Assets.Code.Bon.BonLauncher.cs to learn how the project works
4. help us make it even better
### Features
* user friendly editor UI
* human readable JSON serialization of the graph
* easy creation of custom nodes (extend Node.cs)
* tab pages for multiple graphs
* noise creation/manipulation, color gradient, point scattering, masking

### Non-Features
* ~~nothing but a tool to create graphs and make them persitent (ok.. there are some math related Nodes now..)~~
Ok.. there are several useful node types now..
### Usage
Right click to add a node. Middle mouse button to scroll. Right click on a node to delete a node. Click/Drag to connect Sockets. Mouse wheel to zoom.
## How To Create A Custom Node
To create your own nodes you need to create a new class. Let's call it MyNode.cs
for this example. **MyNode** now needs to inherit from the class **Node** (or from its abstract subclasses). And this
class needs the annotation **[Serializable]** in order to save it as a json file.
Notice that our **Node** is extending **AbstractNumberNode** and contains an **OutputSocket** for numbers.
```cs
using System;
using UnityEngine;
namespace Assets.Code.Bon.Graph.Custom
{
[Serializable]
[GraphContextMenuItem("Standard", "MyNode")]
public class MyNode : AbstractNumberNode {
[SerializeField]
private int myNumber;
public MyNode(int id, Graph parent) : base(id, parent)
{
// Add the input / output sockets of this Node
Sockets.Add(new OutputSocket(this, typeof(AbstractNumberNode));
Sockets.Add(new InputSocket(this, typeof(AbstractColorNode));
Sockets.Add(new InputSocket(this, typeof(AbstractNumberNode));
Height = 65;
}
// To create your custom UI elements in the Node.
public override void OnGUI()
{
// Use GUI or GUILayout as usual
// (if your nodes content has changed call: TriggerChangeEvent())
}
// This method comes from the AbstractNumberNode. It makes sure that all classes of
// this type can return a number. Return your number here depending on the parameters.
// Your number is usually also depending on the InputSockets of this Node. The assigned
// OutputSocket can be igrnored as long as you only have one output.
public override float GetNumber(OutputSocket outSocket, float x, float y, float z, float seed)
{
return myNumber;
}
}
}
```
The anotation **[GraphContextMenuItem]** tells the editor where to add the menu entry for our **Node**.
### Add UI elememts
To add custom UI elements to your node simply use the **OnGUI** method as usual.
## How To Receive Graph Events
The editor (now) uses the **EventManager** and its static methods to trigger events.
To receive the events simply subscribe to the **EventManager**.
```cs
public Awake()
{
EventManager.OnCreateGraph += OnCreate;
EventManager.OnChangedNode += OnNodeChanged;
// .. there are more events
}
public void OnCreate(Graph graph)
{
Debug.Log("OnCreateGraph");
graph.UpdateNodes();
}
public void OnNodeChanged(Graph graph, Node node)
{
Debug.Log("OnNodeChanged: Node " + node.GetType() + " with id " + node.Id);
graph.ForceUpdateNodes();
}
```
## How To Update The Graphs
You can find the standard implementation for updating the Graphs in the **StandardGraphController**. This class subscribes to the *EventManager* to update the Graph on the events. You maybe want to extend its logic to also update objects in your scene. You could also alter the update mechanism or something.
### Save nodes as json (serialization / deserializaiton)
If we have got class members (like myNumber) we want to make persistent
we need to prefix the annotation **[SerializeField]**
to it. You may also need **[System.NonSerialized]** to avoid serialization for your memners.
Also take a look at: http://docs.unity3d.com/Manual/JSONSerialization.html
If you really need a more complex way to serialize your **Node** you can use
the methods **OnSerialization** and **OnDeserialization** to add your logic.
### Next Up..
* Remove the tab-pages and implement the possibility of multiple editor windows
* Unit tests
* A help dialog to explain the controls.
* Code style and code documentation (no idea whats the state of the art. Following microsofts or unitys recommendations?)