Process clusterreceptor per thingId

This commit is contained in:
Pascal Serrarens 2026-03-03 12:19:41 +01:00
parent 3cdca017d6
commit abbce40992
3 changed files with 81 additions and 17 deletions

View File

@ -3,6 +3,7 @@ using System.Collections.Generic;
using UnityEngine;
using Unity.Mathematics;
using static Unity.Mathematics.math;
using System.Linq;
[Serializable]
public class ClusterReceptor : Cluster, IReceptor {
@ -138,4 +139,73 @@ public class ClusterReceptor : Cluster, IReceptor {
this._array ??= new NucleusArray(this.parent);
this._array.ProcessStimulus(thingId, inputValue, thingName);
}
private Dictionary<int, ClusterReceptor> thingReceivers = new();
public virtual void ProcessStimulus(Neuron input, Vector3 inputValue, int thingId = 0, string thingName = null) {
inputValue = input.Activator(inputValue);
if (!thingReceivers.TryGetValue(thingId, out ClusterReceptor selectedReceiver))
selectedReceiver = FindReceiver(thingId, inputValue);
if (selectedReceiver == null)
return;
if (thingName != null) {
string baseName = selectedReceiver.name;
int colonPos = selectedReceiver.name.IndexOf(":");
if (colonPos > 0)
baseName = selectedReceiver.name[..colonPos];
selectedReceiver.name = baseName + ": " + thingName;
}
int inputIx = this.GetNucleusIndex(this.clusterNuclei, input);
if (inputIx < 0)
return;
if (selectedReceiver.clusterNuclei[inputIx] is Neuron selectedNeuron)
selectedNeuron.ProcessStimulusDirect(inputValue);
}
private ClusterReceptor FindReceiver(int thingId, float3 inputValue) {
// No existing nucleus for this thing
float inputMagnitude = length(inputValue);
ClusterReceptor selectedReceiver = null;
float selectedMagnitude = 0;
foreach (ClusterReceptor receiver in nucleiArray.Cast<ClusterReceptor>()) {
if (thingReceivers.ContainsValue(receiver) == false) {
// We found an unusued receiver
thingReceivers.Add(thingId, receiver);
return receiver;
}
else if (receiver.isSleeping) {
// A sleeping receiver is not active and can therefore always be used
thingReceivers.Add(thingId, receiver);
return receiver;
}
else if (selectedReceiver == null) {
// If we haven't found a receiver yet, just start by taking the first
selectedReceiver = receiver;
selectedMagnitude = length(selectedReceiver.outputValue);
}
// Look for the receiver with the lowest magnitude
else {
float magnitude = length(receiver.outputValue);
if (magnitude < inputMagnitude && length(receiver.outputValue) < selectedMagnitude) {
selectedReceiver = receiver;
selectedMagnitude = length(selectedReceiver.outputValue);
}
}
}
if (selectedReceiver != null) {
// Replace the receiver
// Find the thingId current associated with the receiver
int keyToRemove = thingReceivers.FirstOrDefault(r => r.Value.Equals(selectedReceiver)).Key;
if (keyToRemove != 0 || thingReceivers.ContainsKey(keyToRemove))
thingReceivers.Remove(keyToRemove);
// And add the new association
thingReceivers.Add(thingId, selectedReceiver);
}
return selectedReceiver;
}
}

View File

@ -806,16 +806,8 @@ public class ClusterInspector : Editor {
void OnSceneGUI(SceneView sceneView) {
if (this.gameObject != null) {
// if (this.currentNucleus is ReceptorArray receptor && expandArray) {
// foreach (Nucleus nucleus in receptor.instances) {
// Vector3 worldVector = this.gameObject.transform.TransformVector(nucleus.outputValue);
// Handles.color = Color.yellow;
// Handles.DrawLine(this.gameObject.transform.position, this.gameObject.transform.position + worldVector);
// }
// }
// else {
if (this.currentNucleus is Receptor receptor1) {
foreach (Nucleus nucleus in receptor1.nucleiArray) {
if (this.currentNucleus is IReceptor receptor) {
foreach (Nucleus nucleus in receptor.nucleiArray) {
Vector3 worldVector = this.gameObject.transform.TransformVector(nucleus.outputValue);
Handles.color = Color.yellow;
Handles.DrawLine(this.gameObject.transform.position, this.gameObject.transform.position + worldVector);
@ -825,9 +817,7 @@ public class ClusterInspector : Editor {
Vector3 worldVector = this.gameObject.transform.TransformVector(this.currentNucleus.outputValue);
Handles.color = Color.yellow;
Handles.DrawLine(this.gameObject.transform.position, this.gameObject.transform.position + worldVector);
}
// }
}
}
@ -1036,7 +1026,8 @@ public class ClusterInspector : Editor {
// Synapse synapseForUpdate = this.currentNucleus.GetSynapse(oldElementNeuron);
// synapseForUpdate.nucleus = newElementNeuron;
}
} else {
}
else {
// it is a neuron in a subcluster
synapseNeuron.RemoveReceiver(this.currentNucleus);
newNucleus.AddReceiver(this.currentNucleus);

View File

@ -312,6 +312,9 @@ public class Neuron : Nucleus {
#endregion Receivers
public override void ProcessStimulus(Vector3 inputValue, int thingId = 0, string thingName = null) {
if (this.parent is ClusterReceptor clusterReceptor) {
clusterReceptor.ProcessStimulus(this, inputValue, thingId, thingName);
} else
ProcessStimulusDirect(inputValue, thingId, thingName);
// this.stale = 0;
// this.bias = inputValue;