Added curves
This commit is contained in:
parent
0adb71f306
commit
76af037a01
@ -6,13 +6,6 @@ public class Neuroid : Nucleus {
|
|||||||
public bool inverse = false;
|
public bool inverse = false;
|
||||||
public float exponent = 1.0f;
|
public float exponent = 1.0f;
|
||||||
|
|
||||||
// public Neuroid(NanoBrain brain, string name) : base(null, name) {
|
|
||||||
// this.brain = brain;
|
|
||||||
// if (this.brain != null)
|
|
||||||
// this.brain.neuroids.Add(this);
|
|
||||||
// else
|
|
||||||
// Debug.LogError("No neuroid network");
|
|
||||||
// }
|
|
||||||
|
|
||||||
public Neuroid(NanoBrainObj brain, string name) : base(name) {
|
public Neuroid(NanoBrainObj brain, string name) : base(name) {
|
||||||
this.brain = brain;
|
this.brain = brain;
|
||||||
@ -26,16 +19,9 @@ public class Neuroid : Nucleus {
|
|||||||
public Neuroid(string name): base(name) {}
|
public Neuroid(string name): base(name) {}
|
||||||
|
|
||||||
public void SetWeight(Neuroid input, float weight) {
|
public void SetWeight(Neuroid input, float weight) {
|
||||||
//this.synapses[input] = weight;
|
|
||||||
this.SetWeight((Nucleus)input, weight);
|
this.SetWeight((Nucleus)input, weight);
|
||||||
}
|
}
|
||||||
|
|
||||||
// public void GetInputFrom(Neuroid input, float weight = 1.0f) {
|
|
||||||
// input.AddReceiver(this);
|
|
||||||
// //this.synapses[input] = weight;
|
|
||||||
// this.SetWeight((Nucleus)input, weight);
|
|
||||||
// }
|
|
||||||
|
|
||||||
public void SetInput(Neuroid input) {
|
public void SetInput(Neuroid input) {
|
||||||
// if (this.synapses.ContainsKey(input) == false)
|
// if (this.synapses.ContainsKey(input) == false)
|
||||||
// this.synapses[input] = 1.0f;
|
// this.synapses[input] = 1.0f;
|
||||||
|
|||||||
@ -1,6 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
|
using UnityEditor;
|
||||||
|
|
||||||
[System.Serializable]
|
[System.Serializable]
|
||||||
public class Nucleus {
|
public class Nucleus {
|
||||||
@ -54,7 +55,7 @@ public class Nucleus {
|
|||||||
return nucleus;
|
return nucleus;
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual void Deserialize(Nucleus nucleus) { }
|
public virtual void Deserialize(Nucleus nucleus) { }
|
||||||
|
|
||||||
#endregion Serialization
|
#endregion Serialization
|
||||||
|
|
||||||
@ -152,6 +153,17 @@ public class Synapse {
|
|||||||
public int nucleusId;
|
public int nucleusId;
|
||||||
public float weight;
|
public float weight;
|
||||||
|
|
||||||
|
public enum CurvePresets {
|
||||||
|
Linear,
|
||||||
|
Power,
|
||||||
|
Sqrt,
|
||||||
|
Reciprocal,
|
||||||
|
Custom
|
||||||
|
}
|
||||||
|
public CurvePresets curvePreset;
|
||||||
|
public AnimationCurve curve;
|
||||||
|
public float curveMax = 1.0f;
|
||||||
|
|
||||||
public Synapse(Nucleus nucleus, float weight) {
|
public Synapse(Nucleus nucleus, float weight) {
|
||||||
this.nucleus = nucleus;
|
this.nucleus = nucleus;
|
||||||
this.nucleusId = nucleus.id;
|
this.nucleusId = nucleus.id;
|
||||||
@ -177,6 +189,70 @@ public class Synapse {
|
|||||||
}
|
}
|
||||||
Debug.LogError($"Synapse deserialization error: could not find nucleus with id {this.nucleusId}");
|
Debug.LogError($"Synapse deserialization error: could not find nucleus with id {this.nucleusId}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public AnimationCurve GenerateCurve() {
|
||||||
|
switch (this.curvePreset) {
|
||||||
|
case CurvePresets.Linear:
|
||||||
|
this.curveMax = this.weight;
|
||||||
|
return Presets.Linear(this.weight);
|
||||||
|
case CurvePresets.Power:
|
||||||
|
this.curveMax = this.weight;
|
||||||
|
return Presets.Power(2.0f, this.weight);
|
||||||
|
case CurvePresets.Sqrt:
|
||||||
|
this.curveMax = this.weight;
|
||||||
|
return Presets.Power(0.5f, this.weight);
|
||||||
|
case CurvePresets.Reciprocal:
|
||||||
|
this.curveMax = 1 / 0.01f * this.weight;
|
||||||
|
return Presets.Reciprocal(this.weight);
|
||||||
|
default:
|
||||||
|
this.curveMax = weight;
|
||||||
|
return AnimationCurve.Constant(0, 1, weight);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class Presets {
|
||||||
|
private const int samples = 32;
|
||||||
|
public static AnimationCurve Linear(float weight) {
|
||||||
|
return AnimationCurve.Linear(0f, 0f, 1f, weight);
|
||||||
|
}
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
[System.Serializable]
|
[System.Serializable]
|
||||||
|
|||||||
@ -403,33 +403,31 @@ public class NanoBrainInspector : Editor {
|
|||||||
EditorGUILayout.Vector3Field(GUIContent.none, this.currentNucleus.outputValue);
|
EditorGUILayout.Vector3Field(GUIContent.none, this.currentNucleus.outputValue);
|
||||||
EditorGUILayout.EndHorizontal();
|
EditorGUILayout.EndHorizontal();
|
||||||
if (this.currentNucleus.synapses.Count > 0) {
|
if (this.currentNucleus.synapses.Count > 0) {
|
||||||
EditorGUILayout.LabelField("Synapses");
|
|
||||||
EditorGUI.indentLevel++;
|
|
||||||
|
|
||||||
foreach (Synapse synapse in this.currentNucleus.synapses) {
|
foreach (Synapse synapse in this.currentNucleus.synapses) {
|
||||||
if (synapse.nucleus != null) {
|
if (synapse.nucleus != null) {
|
||||||
EditorGUI.BeginDisabledGroup(synapse.nucleus.isSleeping);
|
EditorGUI.BeginDisabledGroup(synapse.nucleus.isSleeping);
|
||||||
|
|
||||||
EditorGUILayout.BeginHorizontal();
|
EditorGUILayout.BeginHorizontal();
|
||||||
EditorGUILayout.LabelField(synapse.nucleus.name, GUILayout.Width(120));
|
EditorGUILayout.LabelField(synapse.nucleus.name, GUILayout.Width(150));
|
||||||
EditorGUI.indentLevel--;
|
EditorGUILayout.Vector3Field(GUIContent.none, synapse.nucleus.outputValue); //, GUILayout.Width(180));
|
||||||
// if (synapse.nucleus is Perceptoid perceptoid) {
|
|
||||||
// EditorGUILayout.LabelField("Thing", GUILayout.Width(45));
|
|
||||||
// perceptoid.thingType = EditorGUILayout.IntField(perceptoid.thingType, GUILayout.Width(40));
|
|
||||||
|
|
||||||
// }
|
|
||||||
// else {
|
|
||||||
EditorGUILayout.LabelField("Weight", GUILayout.Width(45));
|
|
||||||
synapse.weight = EditorGUILayout.FloatField(synapse.weight, GUILayout.Width(40));
|
|
||||||
// }
|
|
||||||
EditorGUI.indentLevel++;
|
|
||||||
EditorGUILayout.Vector3Field(GUIContent.none, synapse.nucleus.outputValue, GUILayout.Width(180));
|
|
||||||
EditorGUILayout.EndHorizontal();
|
EditorGUILayout.EndHorizontal();
|
||||||
|
EditorGUI.indentLevel++;
|
||||||
|
EditorGUI.BeginChangeCheck();
|
||||||
|
synapse.weight = EditorGUILayout.FloatField("Weight", synapse.weight);
|
||||||
|
|
||||||
|
synapse.curvePreset = (Synapse.CurvePresets)EditorGUILayout.EnumPopup("Preset", synapse.curvePreset);
|
||||||
|
if (EditorGUI.EndChangeCheck()) {
|
||||||
|
synapse.curve = synapse.GenerateCurve();
|
||||||
|
}
|
||||||
|
if (synapse.curveMax > 0)
|
||||||
|
EditorGUILayout.CurveField("Curve", synapse.curve, Color.cyan, new Rect(0, 0, 1, synapse.curveMax));
|
||||||
|
else
|
||||||
|
EditorGUILayout.CurveField("Curve", synapse.curve, Color.cyan, new Rect(0, synapse.curveMax, 1, -synapse.curveMax));
|
||||||
|
EditorGUI.indentLevel--;
|
||||||
EditorGUI.EndDisabledGroup();
|
EditorGUI.EndDisabledGroup();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
EditorGUI.indentLevel--;
|
//EditorGUI.indentLevel--;
|
||||||
}
|
}
|
||||||
if (GUILayout.Button("Add Neuron"))
|
if (GUILayout.Button("Add Neuron"))
|
||||||
AddInputNeuron(this.currentNucleus);
|
AddInputNeuron(this.currentNucleus);
|
||||||
@ -437,24 +435,9 @@ public class NanoBrainInspector : Editor {
|
|||||||
AddPerceptoid(this.currentNucleus);
|
AddPerceptoid(this.currentNucleus);
|
||||||
if (GUILayout.Button("Delete this neuron"))
|
if (GUILayout.Button("Delete this neuron"))
|
||||||
DeleteNeuron(this.currentNucleus);
|
DeleteNeuron(this.currentNucleus);
|
||||||
// if (GUILayout.Button("Connect to..."))
|
|
||||||
// ConnectNucleus(this.currentNucleus);
|
|
||||||
|
|
||||||
ConnectNucleus(this.currentNucleus);
|
ConnectNucleus(this.currentNucleus);
|
||||||
DisconnectNucleus(this.currentNucleus);
|
DisconnectNucleus(this.currentNucleus);
|
||||||
// GUIStyle toggleButton = new("Button");
|
|
||||||
// if (connecting) {
|
|
||||||
// toggleButton.normal = toggleButton.active;
|
|
||||||
// }
|
|
||||||
// if (GUILayout.Button(connecting ? "Connecting..." : "Connect to...", toggleButton)) {
|
|
||||||
// connecting = !connecting;
|
|
||||||
// if (connecting) {
|
|
||||||
// names = this.currentNucleus.brain.perceptei.Select(i => i.name).ToArray();
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// if (connecting)
|
|
||||||
// ConnectNucleus(this.currentNucleus);
|
|
||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
inspectorContainer.Add(container);
|
inspectorContainer.Add(container);
|
||||||
@ -503,10 +486,8 @@ public class NanoBrainInspector : Editor {
|
|||||||
int selectedIndex = -1;
|
int selectedIndex = -1;
|
||||||
selectedIndex = EditorGUILayout.Popup("Disconnect from", selectedIndex, names);
|
selectedIndex = EditorGUILayout.Popup("Disconnect from", selectedIndex, names);
|
||||||
if (selectedIndex >= 0 && selectedIndex < this.currentNucleus.brain.perceptei.Count) {
|
if (selectedIndex >= 0 && selectedIndex < this.currentNucleus.brain.perceptei.Count) {
|
||||||
Synapse synapse =this.currentNucleus.synapses[selectedIndex];
|
Synapse synapse = this.currentNucleus.synapses[selectedIndex];
|
||||||
//n.AddReceiver(this.currentNucleus);
|
|
||||||
synapse.nucleus.RemoveReceiver(this.currentNucleus);
|
synapse.nucleus.RemoveReceiver(this.currentNucleus);
|
||||||
//BuildLayers();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -24,6 +24,8 @@ MonoBehaviour:
|
|||||||
weight: 1
|
weight: 1
|
||||||
- nucleusId: 1938577052
|
- nucleusId: 1938577052
|
||||||
weight: 10
|
weight: 10
|
||||||
|
- nucleusId: 1641120128
|
||||||
|
weight: -5
|
||||||
receivers: []
|
receivers: []
|
||||||
nucleusType:
|
nucleusType:
|
||||||
average: 0
|
average: 0
|
||||||
@ -53,6 +55,19 @@ MonoBehaviour:
|
|||||||
average: 0
|
average: 0
|
||||||
inverse: 0
|
inverse: 0
|
||||||
exponent: 1
|
exponent: 1
|
||||||
|
- id: 1641120128
|
||||||
|
_name: Separation
|
||||||
|
synapses:
|
||||||
|
- nucleusId: -1420275136
|
||||||
|
weight: 1
|
||||||
|
- nucleusId: -1266532688
|
||||||
|
weight: 1
|
||||||
|
receivers:
|
||||||
|
- nucleusId: -1707533328
|
||||||
|
nucleusType:
|
||||||
|
average: 0
|
||||||
|
inverse: 0
|
||||||
|
exponent: 1
|
||||||
perceptei:
|
perceptei:
|
||||||
- id: 407735232
|
- id: 407735232
|
||||||
_name: Boundary
|
_name: Boundary
|
||||||
@ -70,6 +85,7 @@ MonoBehaviour:
|
|||||||
synapses: []
|
synapses: []
|
||||||
receivers:
|
receivers:
|
||||||
- nucleusId: 1938577052
|
- nucleusId: 1938577052
|
||||||
|
- nucleusId: 1641120128
|
||||||
nucleusType: Perceptoid
|
nucleusType: Perceptoid
|
||||||
average: 0
|
average: 0
|
||||||
inverse: 0
|
inverse: 0
|
||||||
@ -81,6 +97,7 @@ MonoBehaviour:
|
|||||||
synapses: []
|
synapses: []
|
||||||
receivers:
|
receivers:
|
||||||
- nucleusId: 1938577052
|
- nucleusId: 1938577052
|
||||||
|
- nucleusId: 1641120128
|
||||||
nucleusType: Perceptoid
|
nucleusType: Perceptoid
|
||||||
average: 0
|
average: 0
|
||||||
inverse: 0
|
inverse: 0
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user