From 0023920ffa6d3798ca2b6a80bee1f487508d9b50 Mon Sep 17 00:00:00 2001 From: Pascal Serrarens Date: Wed, 15 Apr 2026 12:23:52 +0200 Subject: [PATCH] Cover seeking(-ish) behaviour --- Editor/Brain_Editor.cs | 26 ++++++++--------- Editor/ClusterInspector.cs | 2 +- Runtime/Scripts/Brain.cs | 10 ++++--- Runtime/Scripts/Core/Neuron.cs | 51 +++++++++++++++++++++++++--------- 4 files changed, 58 insertions(+), 31 deletions(-) diff --git a/Editor/Brain_Editor.cs b/Editor/Brain_Editor.cs index 426990b..a0de070 100644 --- a/Editor/Brain_Editor.cs +++ b/Editor/Brain_Editor.cs @@ -14,13 +14,11 @@ namespace NanoBrain { protected Brain component; private SerializedProperty brainProp; - //ClusterInspector.GraphView board; - public void OnEnable() { component = target as Brain; if (Application.isPlaying == false && serializedObject != null) { - string propertyName = nameof(Brain.defaultBrain); + string propertyName = nameof(Brain.brainPrefab); brainProp = serializedObject.FindProperty(propertyName); } } @@ -32,13 +30,22 @@ namespace NanoBrain { serializedObject.Update(); - VisualElement root = new(); - if (Application.isPlaying == false) { + VisualElement root = new() { + style = { + paddingLeft = 0, + paddingRight = 0, + paddingTop = 0, + paddingBottom = 0 + } + }; + root.styleSheets.Add(Resources.Load("GraphStyles")); + + //if (Application.isPlaying == false) { PropertyField brainField = new(brainProp) { label = "Cluster Prefab" }; root.Add(brainField); - } + //} if (brain != null) CreateViewer(root, brain.prefab, brain.defaultOutput, component.gameObject); @@ -49,13 +56,6 @@ namespace NanoBrain { } public static ClusterViewer.GraphView CreateViewer(VisualElement root, ClusterPrefab cluster, Nucleus output, GameObject gameObject) { - root.style.paddingLeft = 0; - root.style.paddingRight = 0; - root.style.paddingTop = 0; - root.style.paddingBottom = 0; - - root.styleSheets.Add(Resources.Load("GraphStyles")); - VisualElement mainContainer = new() { style = { flexDirection = FlexDirection.Row, diff --git a/Editor/ClusterInspector.cs b/Editor/ClusterInspector.cs index d7a4008..a534b6d 100644 --- a/Editor/ClusterInspector.cs +++ b/Editor/ClusterInspector.cs @@ -316,7 +316,7 @@ namespace NanoBrain { EditorGUILayout.CurveField(neuron.curve, Color.cyan, new Rect(0, 0, 1, neuron.curveMax)); else EditorGUILayout.CurveField(neuron.curve, Color.cyan, new Rect(0, neuron.curveMax, 1, -neuron.curveMax)); - Neuron.ActivationFunction newPreset = (Neuron.ActivationFunction)EditorGUILayout.EnumPopup(neuron.curvePreset, GUILayout.Width(100)); + Neuron.ActivationType newPreset = (Neuron.ActivationType)EditorGUILayout.EnumPopup(neuron.curvePreset, GUILayout.Width(100)); anythingChanged |= newPreset != neuron.curvePreset; neuron.curvePreset = newPreset; EditorGUILayout.EndHorizontal(); diff --git a/Runtime/Scripts/Brain.cs b/Runtime/Scripts/Brain.cs index cd0c668..93b05a7 100644 --- a/Runtime/Scripts/Brain.cs +++ b/Runtime/Scripts/Brain.cs @@ -11,7 +11,7 @@ namespace NanoBrain { /// /// The Cluster prefab from which the cluster is created /// - public ClusterPrefab defaultBrain; + public ClusterPrefab brainPrefab; [NonSerialized] private Cluster brainInstance; @@ -20,10 +20,12 @@ namespace NanoBrain { /// public Cluster brain { get { - if (brainInstance == null && defaultBrain != null) { - brainInstance = new Cluster(defaultBrain) { - name = defaultBrain.name + " (Instance)" + if (brainInstance == null && brainPrefab != null) { + brainInstance = new Cluster(brainPrefab) { + name = brainPrefab.name + " (Instance)" }; + } else if (brainInstance != null && brainPrefab == null) { + brainInstance = null; } return brainInstance; } diff --git a/Runtime/Scripts/Core/Neuron.cs b/Runtime/Scripts/Core/Neuron.cs index 9cc021f..fa48b56 100644 --- a/Runtime/Scripts/Core/Neuron.cs +++ b/Runtime/Scripts/Core/Neuron.cs @@ -61,17 +61,19 @@ namespace NanoBrain { /// /// The type of /// - public enum ActivationFunction { + public enum ActivationType { Linear, Power, Sqrt, Reciprocal, Tanh, + Binary, + Normalized, Custom } [SerializeField] - public ActivationFunction _curvePreset; - public ActivationFunction curvePreset { + public ActivationType _curvePreset; + public ActivationType curvePreset { get { return _curvePreset; } set { _curvePreset = value; @@ -83,21 +85,27 @@ namespace NanoBrain { public AnimationCurve GenerateCurve() { switch (this.curvePreset) { - case ActivationFunction.Linear: + case ActivationType.Linear: this.curveMax = 1; return Presets.Linear(1); - case ActivationFunction.Power: + case ActivationType.Power: this.curveMax = 1; return Presets.Power(2.0f, 1); - case ActivationFunction.Sqrt: + case ActivationType.Sqrt: this.curveMax = 1; return Presets.Power(0.5f, 1); - case ActivationFunction.Reciprocal: + case ActivationType.Reciprocal: this.curveMax = 1 / 0.01f * 1; return Presets.Reciprocal(1); - case ActivationFunction.Tanh: + case ActivationType.Tanh: this.curveMax = 1; return Presets.Tanh(1); + case ActivationType.Binary: + this.curveMax = 1; + return Presets.Binary(); + case ActivationType.Normalized: + this.curveMax = 1; + return Presets.Binary(); default: this.curveMax = 1; return this.curve; @@ -165,6 +173,9 @@ namespace NanoBrain { return curve; } + public static AnimationCurve Binary() { + return AnimationCurve.Linear(0, 0, 1, 1); + } } #endregion Serialization @@ -371,11 +382,13 @@ namespace NanoBrain { #if UNITY_MATHEMATICS public Func Activator => this.curvePreset switch { - ActivationFunction.Linear => ActivatorLinear, - ActivationFunction.Sqrt => ActivatorSqrt, - ActivationFunction.Power => ActivatorPower, - ActivationFunction.Reciprocal => ActivatorReciprocal, - ActivationFunction.Tanh => ActivatorTanh, + ActivationType.Linear => ActivatorLinear, + ActivationType.Sqrt => ActivatorSqrt, + ActivationType.Power => ActivatorPower, + ActivationType.Reciprocal => ActivatorReciprocal, + ActivationType.Tanh => ActivatorTanh, + ActivationType.Binary => ActivatorBinary, + ActivationType.Normalized => ActivatorNormalized, _ => ActivatorCustom }; @@ -407,6 +420,18 @@ namespace NanoBrain { float3 result = normalize(input) * MathF.Tanh(magnitude); return result; } + protected float3 ActivatorBinary(float3 input) { + float magnitude = length(input); + float value = Mathf.Clamp01(magnitude); + return float3(value, value, value); + } + + protected float3 ActivatorNormalized(float3 input) { + if (lengthsq(input) == 0) + return input; + float3 result = normalize(input); + return result; + } protected float3 ActivatorCustom(float3 input) { float activatedValue = this.curve.Evaluate(length(input));