Process clusterreceptor per thingId
This commit is contained in:
parent
3cdca017d6
commit
abbce40992
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
|||||||
using UnityEngine;
|
using UnityEngine;
|
||||||
using Unity.Mathematics;
|
using Unity.Mathematics;
|
||||||
using static Unity.Mathematics.math;
|
using static Unity.Mathematics.math;
|
||||||
|
using System.Linq;
|
||||||
|
|
||||||
[Serializable]
|
[Serializable]
|
||||||
public class ClusterReceptor : Cluster, IReceptor {
|
public class ClusterReceptor : Cluster, IReceptor {
|
||||||
@ -71,7 +72,7 @@ public class ClusterReceptor : Cluster, IReceptor {
|
|||||||
foreach (Nucleus outputNucleus in clusterElement.clusterNuclei) {
|
foreach (Nucleus outputNucleus in clusterElement.clusterNuclei) {
|
||||||
if (outputNucleus is not Neuron output)
|
if (outputNucleus is not Neuron output)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
// this should be clusterElement.outputs,
|
// this should be clusterElement.outputs,
|
||||||
// but outputs is not updated when correctly and may contain old data...
|
// but outputs is not updated when correctly and may contain old data...
|
||||||
foreach (Nucleus receiver in output.receivers) {
|
foreach (Nucleus receiver in output.receivers) {
|
||||||
@ -138,4 +139,73 @@ public class ClusterReceptor : Cluster, IReceptor {
|
|||||||
this._array ??= new NucleusArray(this.parent);
|
this._array ??= new NucleusArray(this.parent);
|
||||||
this._array.ProcessStimulus(thingId, inputValue, thingName);
|
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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@ -806,16 +806,8 @@ public class ClusterInspector : Editor {
|
|||||||
|
|
||||||
void OnSceneGUI(SceneView sceneView) {
|
void OnSceneGUI(SceneView sceneView) {
|
||||||
if (this.gameObject != null) {
|
if (this.gameObject != null) {
|
||||||
// if (this.currentNucleus is ReceptorArray receptor && expandArray) {
|
if (this.currentNucleus is IReceptor receptor) {
|
||||||
// foreach (Nucleus nucleus in receptor.instances) {
|
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);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// else {
|
|
||||||
if (this.currentNucleus is Receptor receptor1) {
|
|
||||||
foreach (Nucleus nucleus in receptor1.nucleiArray) {
|
|
||||||
Vector3 worldVector = this.gameObject.transform.TransformVector(nucleus.outputValue);
|
Vector3 worldVector = this.gameObject.transform.TransformVector(nucleus.outputValue);
|
||||||
Handles.color = Color.yellow;
|
Handles.color = Color.yellow;
|
||||||
Handles.DrawLine(this.gameObject.transform.position, this.gameObject.transform.position + worldVector);
|
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);
|
Vector3 worldVector = this.gameObject.transform.TransformVector(this.currentNucleus.outputValue);
|
||||||
Handles.color = Color.yellow;
|
Handles.color = Color.yellow;
|
||||||
Handles.DrawLine(this.gameObject.transform.position, this.gameObject.transform.position + worldVector);
|
Handles.DrawLine(this.gameObject.transform.position, this.gameObject.transform.position + worldVector);
|
||||||
|
|
||||||
}
|
}
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1016,7 +1006,7 @@ public class ClusterInspector : Editor {
|
|||||||
// so we have to change all synapses to this nucleus array elements
|
// so we have to change all synapses to this nucleus array elements
|
||||||
int oldNucleusIx = subCluster.GetNucleusIndex(subCluster.clusterNuclei, synapse.nucleus);
|
int oldNucleusIx = subCluster.GetNucleusIndex(subCluster.clusterNuclei, synapse.nucleus);
|
||||||
int newNucleusIx = subCluster.GetNucleusIndex(subCluster.clusterNuclei, newNucleus);
|
int newNucleusIx = subCluster.GetNucleusIndex(subCluster.clusterNuclei, newNucleus);
|
||||||
foreach(Nucleus element in receptor.nucleiArray) {
|
foreach (Nucleus element in receptor.nucleiArray) {
|
||||||
if (element is not ClusterReceptor clusterReceptor)
|
if (element is not ClusterReceptor clusterReceptor)
|
||||||
continue;
|
continue;
|
||||||
// Get the same neuron as the synapse.nucleus in a different element
|
// Get the same neuron as the synapse.nucleus in a different element
|
||||||
@ -1029,14 +1019,15 @@ public class ClusterInspector : Editor {
|
|||||||
Nucleus newElementNucleus = clusterReceptor.clusterNuclei[newNucleusIx];
|
Nucleus newElementNucleus = clusterReceptor.clusterNuclei[newNucleusIx];
|
||||||
if (newElementNucleus is not Neuron newElementNeuron)
|
if (newElementNucleus is not Neuron newElementNeuron)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
oldElementNeuron.RemoveReceiver(this.currentNucleus);
|
oldElementNeuron.RemoveReceiver(this.currentNucleus);
|
||||||
newElementNeuron.AddReceiver(this.currentNucleus);
|
newElementNeuron.AddReceiver(this.currentNucleus);
|
||||||
// Now find the synapse which pointed to the old Neuron
|
// Now find the synapse which pointed to the old Neuron
|
||||||
// Synapse synapseForUpdate = this.currentNucleus.GetSynapse(oldElementNeuron);
|
// Synapse synapseForUpdate = this.currentNucleus.GetSynapse(oldElementNeuron);
|
||||||
// synapseForUpdate.nucleus = newElementNeuron;
|
// synapseForUpdate.nucleus = newElementNeuron;
|
||||||
}
|
}
|
||||||
} else {
|
}
|
||||||
|
else {
|
||||||
// it is a neuron in a subcluster
|
// it is a neuron in a subcluster
|
||||||
synapseNeuron.RemoveReceiver(this.currentNucleus);
|
synapseNeuron.RemoveReceiver(this.currentNucleus);
|
||||||
newNucleus.AddReceiver(this.currentNucleus);
|
newNucleus.AddReceiver(this.currentNucleus);
|
||||||
|
|||||||
@ -312,7 +312,10 @@ public class Neuron : Nucleus {
|
|||||||
#endregion Receivers
|
#endregion Receivers
|
||||||
|
|
||||||
public override void ProcessStimulus(Vector3 inputValue, int thingId = 0, string thingName = null) {
|
public override void ProcessStimulus(Vector3 inputValue, int thingId = 0, string thingName = null) {
|
||||||
ProcessStimulusDirect(inputValue, thingId, thingName);
|
if (this.parent is ClusterReceptor clusterReceptor) {
|
||||||
|
clusterReceptor.ProcessStimulus(this, inputValue, thingId, thingName);
|
||||||
|
} else
|
||||||
|
ProcessStimulusDirect(inputValue, thingId, thingName);
|
||||||
// this.stale = 0;
|
// this.stale = 0;
|
||||||
// this.bias = inputValue;
|
// this.bias = inputValue;
|
||||||
// this.parent.UpdateFromNucleus(this);
|
// this.parent.UpdateFromNucleus(this);
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user