diff --git a/Assets/NanoBrain/Neuron.cs b/Assets/NanoBrain/Neuron.cs index f288d7f..3ccaaa6 100644 --- a/Assets/NanoBrain/Neuron.cs +++ b/Assets/NanoBrain/Neuron.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Linq; using UnityEngine; +using UnityEditor; using Unity.Mathematics; using static Unity.Mathematics.math; @@ -59,16 +60,16 @@ public class Neuron : INucleus { switch (this.curvePreset) { case CurvePresets.Linear: this.curveMax = 1; - return Synapse.Presets.Linear(1); + return Presets.Linear(1); case CurvePresets.Power: this.curveMax = 1; - return Synapse.Presets.Power(2.0f, 1); + return Presets.Power(2.0f, 1); case CurvePresets.Sqrt: this.curveMax = 1; - return Synapse.Presets.Power(0.5f, 1); + return Presets.Power(0.5f, 1); case CurvePresets.Reciprocal: this.curveMax = 1 / 0.01f * 1; - return Synapse.Presets.Reciprocal(1); + return Presets.Reciprocal(1); default: this.curveMax = 1; return this.curve; @@ -83,6 +84,54 @@ public class Neuron : INucleus { public Cluster cluster { get; set; } + #region Activation + + public static class Presets { + private const int samples = 32; + public static AnimationCurve Linear(float weight) { + return AnimationCurve.Linear(0f, 0f, 1000f, weight * 1000); + } + public static AnimationCurve Power(float exponent, float weight) { + // build keyframes + Keyframe[] keys = new Keyframe[samples]; + for (int i = 0; i < samples; i++) { + float t = i / (float)(samples - 1); + float v = Mathf.Pow(t, exponent) * weight; + keys[i] = new Keyframe(t, v); + } + + AnimationCurve curve = new(keys); + + // set tangent modes for each key to Auto (smooth). Use Linear if you prefer straight segments. + for (int i = 0; i < curve.length; i++) { + AnimationUtility.SetKeyLeftTangentMode(curve, i, AnimationUtility.TangentMode.Auto); + AnimationUtility.SetKeyRightTangentMode(curve, i, AnimationUtility.TangentMode.Auto); + } + + return curve; + } + public static AnimationCurve Reciprocal(float weight) { + int samples = 128; + float xMin = 0.001f; + float xMax = 1; + var keys = new Keyframe[samples]; + for (int i = 0; i < samples; i++) { + float t = i / (float)(samples - 1); + float x = Mathf.Lerp(xMin, xMax, t); + float y = 1f / x * weight; + keys[i] = new Keyframe(x, y); + } + var curve = new AnimationCurve(keys); + for (int i = 0; i < curve.length; i++) { + AnimationUtility.SetKeyLeftTangentMode(curve, i, AnimationUtility.TangentMode.Linear); + AnimationUtility.SetKeyRightTangentMode(curve, i, AnimationUtility.TangentMode.Linear); + } + return curve; + } + } + + #endregion Activation + private float3 _outputValue; public float3 outputValue { get { return _outputValue; } diff --git a/Assets/NanoBrain/Synapse.cs b/Assets/NanoBrain/Synapse.cs index 6772d06..40580c0 100644 --- a/Assets/NanoBrain/Synapse.cs +++ b/Assets/NanoBrain/Synapse.cs @@ -1,81 +1,21 @@ using System; using UnityEngine; -using UnityEditor; [Serializable] public class Synapse { // Support access to cluster of basic nucleus - public IReceptor nucleus => basicNucleus; // clusterNucleus != null ? clusterNucleus : basicNucleus; + public IReceptor nucleus => basicNucleus; [SerializeReference] private IReceptor basicNucleus; - // The Cluster is a ScriptableObject and can therefore not be serialized using [SerializeReference] - // private ClusterInstance clusterNucleus; [SerializeReference] public ClusterInstance cluster; public float weight; - public enum CurvePresets { - Linear, - Power, - Sqrt, - Reciprocal, - Custom - } - public float curveMax = 1.0f; - public Synapse(IReceptor nucleus, float weight = 1.0f) { this.basicNucleus = nucleus; this.weight = weight; } - // public Synapse(ClusterInstance cluster, float weight = 1.0f) { - // this.clusterNucleus = cluster; - // this.weight = weight; - // } - - public static class Presets { - private const int samples = 32; - public static AnimationCurve Linear(float weight) { - return AnimationCurve.Linear(0f, 0f, 1000f, weight * 1000); - } - public static AnimationCurve Power(float exponent, float weight) { - // build keyframes - Keyframe[] keys = new Keyframe[samples]; - for (int i = 0; i < samples; i++) { - float t = i / (float)(samples - 1); - float v = Mathf.Pow(t, exponent) * weight; - keys[i] = new Keyframe(t, v); - } - - AnimationCurve curve = new(keys); - - // set tangent modes for each key to Auto (smooth). Use Linear if you prefer straight segments. - for (int i = 0; i < curve.length; i++) { - AnimationUtility.SetKeyLeftTangentMode(curve, i, AnimationUtility.TangentMode.Auto); - AnimationUtility.SetKeyRightTangentMode(curve, i, AnimationUtility.TangentMode.Auto); - } - - return curve; - } - public static AnimationCurve Reciprocal(float weight) { - int samples = 128; - float xMin = 0.001f; - float xMax = 1; - var keys = new Keyframe[samples]; - for (int i = 0; i < samples; i++) { - float t = i / (float)(samples - 1); - float x = Mathf.Lerp(xMin, xMax, t); - float y = 1f / x * weight; - keys[i] = new Keyframe(x, y); - } - var curve = new AnimationCurve(keys); - for (int i = 0; i < curve.length; i++) { - AnimationUtility.SetKeyLeftTangentMode(curve, i, AnimationUtility.TangentMode.Linear); - AnimationUtility.SetKeyRightTangentMode(curve, i, AnimationUtility.TangentMode.Linear); - } - return curve; - } - } } \ No newline at end of file