Enable stimulus processing in any nucleus

This commit is contained in:
Pascal Serrarens 2026-02-19 16:35:57 +01:00
parent d2b5d2feac
commit 2ef9629e4d
10 changed files with 46 additions and 133 deletions

View File

@ -412,23 +412,21 @@ public class Cluster : Nucleus {
}
public Nucleus GetNucleus(string nucleusName) {
string nucleusName0 = nucleusName + ": 0";
foreach (Nucleus nucleus in this.clusterNuclei) {
if (nucleus.name == nucleusName)
if (nucleus is IReceptor receptor) {
if (nucleus.name == nucleusName | nucleus.name == nucleusName0)
return nucleus;
}
else if (nucleus.name == nucleusName)
return nucleus;
}
return null;
}
[Obsolete("Use GetNucleus instead")]
public IReceptor GetReceptor(string receptorName) {
string receptorName0 = receptorName + ": 0";
foreach (Nucleus nucleus in this.clusterNuclei) {
if (nucleus is IReceptor receptor) {
if (nucleus.name == receptorName | nucleus.name == receptorName0)
//if (receptor.GetName() == receptorName)
return receptor;
}
}
return null;
return GetNucleus(receptorName) as IReceptor;
}
#region Receivers

View File

@ -507,9 +507,9 @@ public class ClusterInspector : Editor {
if (nucleus is Receptor receptor1) {
// draw the array size label
if (expandArray) { //} && receptor1.array.nuclei.First() == this.currentNucleus) {
if (expandArray) {
style.alignment = TextAnchor.LowerCenter;
Vector3 labelPos1 = position + Vector3.down * (size + 5); // below disc along up axis
Vector3 labelPos1 = position + Vector3.down * (size + 5); // below disc
int colonPos1 = nucleus.name.IndexOf(":");
if (colonPos1 > 0) {
string extName = nucleus.name[(colonPos1 + 2)..];
@ -525,19 +525,12 @@ public class ClusterInspector : Editor {
style.normal.textColor = Color.white;
}
}
// if (nucleus is ReceptorArray receptor) {
// if (color.grayscale > 0.5f)
// style.normal.textColor = Color.black;
// else
// style.normal.textColor = Color.white;
// Handles.Label(labelPosition, receptor.instances.Count().ToString(), style);
// }
if (nucleus is ClusterReceptor clusterReceptor) {
// draw the array size label
if (expandArray && clusterReceptor.array.nuclei.First() == this.currentNucleus) {
style.alignment = TextAnchor.LowerCenter;
Vector3 labelPos2 = position + Vector3.down * (size + 5); // below disc along up axis
Vector3 labelPos2 = position + Vector3.down * (size + 5); // below disc
int colonPos2 = nucleus.name.IndexOf(":");
if (colonPos2 > 0) {
string extName = nucleus.name[(colonPos2 + 2)..];
@ -554,25 +547,19 @@ public class ClusterInspector : Editor {
}
}
// if (expandArray && nucleus is Receptor receptor2 && receptor2.array.nuclei.First() == this.currentNucleus) {
// style.alignment = TextAnchor.LowerCenter;
// Vector3 labelPos = position + Vector3.down * (size + 5); // below disc along up axis
// int colonPos = nucleus.name.IndexOf(":");
// if (colonPos > 0) {
// string extName = nucleus.name[(colonPos + 2)..];
// Handles.Label(labelPos, extName, style);
// }
// }
// else {
style.alignment = TextAnchor.UpperCenter;
Vector3 labelPos = position - Vector3.down * (size + 5); // below disc along up axis
int colonPos = nucleus.name.IndexOf(":");
if (expandArray && nucleus is Receptor) { //} || (colonPos > 0 && colonPos < nucleus.name.Length - 2)) {
// string baseName = nucleus.name[..colonPos];
// Handles.Label(labelPos, baseName, style);
if (!expandArray || nucleus is not Receptor) {
Vector3 labelPos = position - Vector3.down * (size + 5); // below neuron
style.alignment = TextAnchor.UpperCenter;
int colonPos = nucleus.name.IndexOf(":");
if (colonPos > 0 && colonPos < nucleus.name.Length - 2) {
string baseName = nucleus.name[..colonPos];
Handles.Label(labelPos, baseName, style);
}
else
Handles.Label(labelPos, nucleus.name, style);
}
else
Handles.Label(labelPos, nucleus.name, style);
// }
if (nucleus is Cluster) {

View File

@ -17,8 +17,10 @@ public class NanoBrainComponent_Editor : Editor {
public void OnEnable() {
component = target as NanoBrain;
if (Application.isPlaying == false)
brainProp = serializedObject.FindProperty(nameof(NanoBrain.defaultBrain));
if (Application.isPlaying == false && serializedObject != null) {
string propertyName = nameof(NanoBrain.defaultBrain);
brainProp = serializedObject.FindProperty(propertyName);
}
}
public override VisualElement CreateInspectorGUI() {

View File

@ -1,82 +0,0 @@
/*
using UnityEngine;
using Unity.Mathematics;
using static Unity.Mathematics.math;
[System.Serializable]
public class Neuroid : Neuron {
public bool average = false;
public Neuroid(Cluster brain, string name) : base(name) {
this.cluster = brain;
if (this.cluster != null) {
this.cluster.nuclei.Add(this);
}
else
Debug.LogError("No neuroid network");
}
public Neuroid(string name) : base(name) { }
public override INucleus Clone() {
Neuroid clone = new(this.name) {
cluster = this.cluster,
array = this.array,
curve = this.curve,
curvePreset = this.curvePreset,
curveMax = this.curveMax,
average = this.average
};
if (clone.cluster != null)
clone.cluster.nuclei.Add(clone);
foreach (Synapse synapse in this.synapses) {
Synapse clonedSynapse = clone.AddSynapse(synapse.nucleus);
clonedSynapse.weight = synapse.weight;
}
foreach (INucleus receiver in this.receivers) {
clone.AddReceiver(receiver);
}
return clone;
}
public override void UpdateState() {
float3 sum = new(0, 0, 0);
int n = 0;
//Applying the weight factgors
foreach (Synapse synapse in this.synapses) {
sum = sum + (synapse.weight * synapse.nucleus.outputValue);
if (lengthsq(synapse.nucleus.outputValue) != 0)
n++;
}
if (average)
sum /= n;
// Activation function
Vector3 result;
switch (this.curvePreset) {
case CurvePresets.Linear:
result = sum;
break;
case CurvePresets.Sqrt:
result = normalize(sum) * System.MathF.Sqrt(length(sum));
break;
case CurvePresets.Power:
result = normalize(sum) * System.MathF.Pow(length(sum), 2);
break;
case CurvePresets.Reciprocal:
result = normalize(sum) * (1 / length(sum));
break;
default:
float activatedValue = this.curve.Evaluate(length(sum));
result = normalize(sum) * activatedValue;
break;
}
UpdateResult(result);
}
}
*/

View File

@ -1,2 +0,0 @@
fileFormatVersion: 2
guid: 771f64aec709af240a39b1d918bbc829

View File

@ -230,7 +230,7 @@ public class Neuron : Nucleus {
#region Activator
protected Func<float3, float3> Activator => this.curvePreset switch {
public Func<float3, float3> Activator => this.curvePreset switch {
CurvePresets.Linear => ActivatorLinear,
CurvePresets.Sqrt => ActivatorSqrt,
CurvePresets.Power => ActivatorPower,
@ -311,10 +311,16 @@ public class Neuron : Nucleus {
#endregion Receivers
public virtual void ProcessStimulus(Vector3 inputValue, string thingName = null) {
public override void ProcessStimulus(Vector3 inputValue, int thingId = 0, string thingName = null) {
ProcessStimulusDirect(inputValue, thingId, thingName);
// this.stale = 0;
// this.bias = inputValue;
// this.parent.UpdateFromNucleus(this);
}
public void ProcessStimulusDirect(Vector3 inputValue, int thingId = 0, string thingName = null) {
this.stale = 0;
this.bias = inputValue;
this.parent.UpdateFromNucleus(this);
}
}

View File

@ -73,8 +73,6 @@ public abstract class Nucleus {
#endregion Synapses
#region Update
public abstract void UpdateStateIsolated();
@ -88,6 +86,9 @@ public abstract class Nucleus {
this.parent.UpdateFromNucleus(this);
}
public virtual void ProcessStimulus(Vector3 inputValue, int thingId = 0, string thingName = "") {
}
#endregion Update
}

View File

@ -111,6 +111,10 @@ public class NucleusArray {
public virtual void ProcessStimulus(int thingId, Vector3 inputValue, string thingName = null) {
CleanupReceivers();
if (this._nuclei[0] is Neuron neuron)
inputValue = neuron.Activator(inputValue);
if (!thingReceivers.TryGetValue(thingId, out Nucleus selectedReceiver)) {
// No existing nucleus for this thing
selectedReceiver = FindReceiver(thingId, inputValue);
@ -127,8 +131,7 @@ public class NucleusArray {
}
if (selectedReceiver is Neuron selectedNucleus)
selectedNucleus.ProcessStimulus(inputValue);
//selectedReceiver.parent.UpdateFromNucleus(selectedReceiver);
selectedNucleus.ProcessStimulusDirect(inputValue);
}
private void CleanupReceivers() {

View File

@ -76,7 +76,7 @@ public class Receptor : Neuron, IReceptor {
}
}
public virtual void ProcessStimulus(Vector3 inputValue, int thingId = 0, string thingName = null) {
public override void ProcessStimulus(Vector3 inputValue, int thingId = 0, string thingName = null) {
this._array ??= new NucleusArray(this.parent);
this._array.ProcessStimulus(thingId, inputValue, thingName);
}

View File

@ -141,7 +141,7 @@ public class ReceptorArray : Nucleus {
// public override void ProcessStimulus(int thingId, Vector3 inputValue, string thingName = null) {
// ProcessStimulus(inputValue, thingId, thingName);
// }
public virtual void ProcessStimulus(Vector3 inputValue, int thingId = 0, string thingName = null) {
public override void ProcessStimulus(Vector3 inputValue, int thingId = 0, string thingName = null) {
CleanupReceivers();
if (!thingReceivers.TryGetValue(thingId, out Nucleus selectedReceiver)) {
//Debug.Log($" no receiver found for {thingId}");