WIp pheromone selection in brain

This commit is contained in:
Pascal Serrarens 2026-02-09 17:49:19 +01:00
parent a95c685e1e
commit 76c5372089
4 changed files with 99 additions and 38 deletions

View File

@ -19,6 +19,9 @@ public class Cluster : Nucleus {
ClonePrefab();
this.sortedNuclei = TopologicalSort(this.nuclei);
// Does not work because we have nuclei with the same names in an nucleusArray
// 'Pheromone steering'
//this.nucleiDict = nuclei.ToDictionary(nucleus => nucleus.name);
}
public Cluster(ClusterPrefab prefab, ClusterPrefab parent = null) {
@ -31,6 +34,7 @@ public class Cluster : Nucleus {
ClonePrefab();
this.sortedNuclei = TopologicalSort(this.nuclei);
//this.nucleiDict = nuclei.ToDictionary(nucleus => nucleus.name);
}
private void ClonePrefab() {
@ -183,6 +187,7 @@ public class Cluster : Nucleus {
// the nuclei sorted using topological sorting
// to ensure that the cluster is computer in the right order
public List<Nucleus> sortedNuclei;
//public Dictionary<string, Nucleus> nucleiDict = new();
public List<Nucleus> _inputs = null;
public virtual List<Nucleus> inputs {

View File

@ -497,6 +497,7 @@ public class ClusterInspector : Editor {
}
private bool showSynapses = true;
private bool showActivation = true;
protected bool breakOnWake = false;
void DrawInspector(VisualElement inspectorContainer) {
if (inspectorContainer == null)
@ -525,34 +526,43 @@ public class ClusterInspector : Editor {
};
GUILayout.Label(this.currentNucleus.GetType().ToString(), headerStyle);
this.currentNucleus.name = EditorGUILayout.TextField(this.currentNucleus.name, boldTextFieldStyle);
if (this.currentNucleus is Neuron neuroid) {
if (this.currentNucleus is MemoryCell memory) {
}
else {
EditorGUILayout.BeginHorizontal();
EditorGUILayout.LabelField("Activation Curve", GUILayout.Width(150));
if (neuroid.curveMax > 0)
EditorGUILayout.CurveField(neuroid.curve, Color.cyan, new Rect(0, 0, 1, neuroid.curveMax));
else
EditorGUILayout.CurveField(neuroid.curve, Color.cyan, new Rect(0, neuroid.curveMax, 1, -neuroid.curveMax));
neuroid.curvePreset = (Neuron.CurvePresets)EditorGUILayout.EnumPopup(neuroid.curvePreset, GUILayout.Width(100));
EditorGUILayout.EndHorizontal();
}
if (neuroid.array == null || neuroid.array.nuclei == null || neuroid.array.nuclei.Count() == 0)
neuroid.array = new NucleusArray(neuroid);
EditorGUILayout.BeginHorizontal();
EditorGUILayout.IntField("Array size", neuroid.array.nuclei.Count());
if (GUILayout.Button("Add"))
neuroid.array.AddNucleus(this.prefab);
if (GUILayout.Button("Del"))
neuroid.array.RemoveNucleus();
EditorGUILayout.EndHorizontal();
string newName = EditorGUILayout.TextField(this.currentNucleus.name, boldTextFieldStyle);
if (newName != this.currentNucleus.name) {
this.currentNucleus.name = newName;
this.prefab.RefreshOutputs();
outputsField.choices = this.prefab.outputs.Select(output => output.name).ToList();
//outputsField.value = newName;
}
//if (this.currentNucleus is Neuron neuron) {
// if (this.currentNucleus is MemoryCell memory) {
// }
// else {
// EditorGUILayout.BeginHorizontal();
// EditorGUILayout.LabelField("Activation Curve", GUILayout.Width(150));
// if (neuron.curveMax > 0)
// 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.curvePreset = (Neuron.CurvePresets)EditorGUILayout.EnumPopup(neuron.curvePreset, GUILayout.Width(100));
// EditorGUILayout.EndHorizontal();
// }
if (Application.isPlaying)
EditorGUILayout.FloatField("Output", length(this.currentNucleus.outputValue));
// if (neuron.array == null || neuron.array.nuclei == null || neuron.array.nuclei.Count() == 0)
// neuron.array = new NucleusArray(neuron);
// EditorGUILayout.BeginHorizontal();
// EditorGUILayout.IntField("Array size", neuron.array.nuclei.Count());
// if (GUILayout.Button("Add"))
// neuron.array.AddNucleus(this.prefab);
// if (GUILayout.Button("Del"))
// neuron.array.RemoveNucleus();
// EditorGUILayout.EndHorizontal();
//}
if (Application.isPlaying) {
GUIContent nameLabel = new("Output", this.currentNucleus.outputValue.ToString());
EditorGUILayout.FloatField(nameLabel, length(this.currentNucleus.outputValue));
}
else
EditorGUILayout.LabelField(" ");
@ -561,16 +571,29 @@ public class ClusterInspector : Editor {
ConnectNucleus(this.prefab, this.currentNucleus);
AddSynapse(this.prefab, this.currentNucleus);
this.currentNucleus.bias = EditorGUILayout.Vector3Field("Bias", this.currentNucleus.bias);
NucleusArray array = null;
if (this.currentNucleus.synapses.Count > 0) {
Synapse[] synapses = this.currentNucleus.synapses.ToArray();
foreach (Synapse synapse in synapses) {
if (synapse.nucleus != null) {
if (array != null) {
if (array.nuclei.Contains(synapse.nucleus))
continue;
}
else {
if (synapse.nucleus.array != null && synapse.nucleus.array.nuclei.Length > 1)
array = synapse.nucleus.array;
}
EditorGUILayout.Space();
//EditorGUI.BeginDisabledGroup(synapse.nucleus.isSleeping);
if (Application.isPlaying)
EditorGUILayout.FloatField(synapse.nucleus.name, length(synapse.nucleus.outputValue) * synapse.weight);
else {
if (Application.isPlaying) {
Vector3 value = synapse.nucleus.outputValue * synapse.weight;
GUIContent synapseValueLabel = new(synapse.nucleus.name, synapse.nucleus.outputValue.ToString());
EditorGUILayout.FloatField(synapseValueLabel, length(synapse.nucleus.outputValue));
} else {
EditorGUILayout.BeginHorizontal();
EditorGUILayout.LabelField(synapse.nucleus.name);
if (GUILayout.Button("Disconnect"))
@ -588,6 +611,35 @@ public class ClusterInspector : Editor {
EditorGUILayout.EndFoldoutHeaderGroup();
EditorGUILayout.Space();
showActivation = EditorGUILayout.BeginFoldoutHeaderGroup(showActivation, "Activation");
if (showActivation) {
if (this.currentNucleus is Neuron neuron) {
if (this.currentNucleus is not MemoryCell memory) {
EditorGUILayout.BeginHorizontal();
EditorGUILayout.LabelField("Activation Curve", GUILayout.Width(150));
if (neuron.curveMax > 0)
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.curvePreset = (Neuron.CurvePresets)EditorGUILayout.EnumPopup(neuron.curvePreset, GUILayout.Width(100));
EditorGUILayout.EndHorizontal();
}
if (neuron.array == null || neuron.array.nuclei == null || neuron.array.nuclei.Count() == 0)
neuron.array = new NucleusArray(neuron);
EditorGUILayout.BeginHorizontal();
EditorGUILayout.IntField("Array size", neuron.array.nuclei.Count());
if (GUILayout.Button("Add"))
neuron.array.AddNucleus(this.prefab);
if (GUILayout.Button("Del"))
neuron.array.RemoveNucleus();
EditorGUILayout.EndHorizontal();
}
EditorGUILayout.Space();
}
EditorGUILayout.EndFoldoutHeaderGroup();
if (GUILayout.Button("Delete this neuron"))
DeleteNeuron(this.currentNucleus);

View File

@ -131,6 +131,7 @@ public class Neuron : Nucleus {
public override Nucleus ShallowCloneTo(Cluster newParent) {
Neuron clone = new(newParent, this.name) {
array = null,
bias = this.bias,
curve = this.curve,
curvePreset = this.curvePreset,
curveMax = this.curveMax,
@ -185,7 +186,7 @@ public class Neuron : Nucleus {
}
}
public float3 bias = float3(0, 0, 0);
//public float3 bias = float3(0, 0, 0);
public override void UpdateStateIsolated(float3 bias_unused) {
Vector3 sum = this.bias;
int n = 0;

View File

@ -6,13 +6,14 @@ using static Unity.Mathematics.math;
[Serializable]
public abstract class Nucleus {
[SerializeField]
protected string _name;
public virtual string name {
get => _name;
set => _name = value;
}
// [SerializeField]
// protected string _name;
// public virtual string name {
// get => _name;
// set => _name = value;
// }
public string name;
//[Obsolete]
public ClusterPrefab cluster { get; set; }
public Cluster parent { get; set; }
@ -39,6 +40,8 @@ public abstract class Nucleus {
#region Synapses
public Vector3 bias = Vector3.zero;
[SerializeField]
private List<Synapse> _synapses = new();
public List<Synapse> synapses => _synapses;