Simplifications

This commit is contained in:
Pascal Serrarens 2026-04-17 16:34:21 +02:00
parent bc0a79688d
commit 19f929606a
9 changed files with 421 additions and 360 deletions

View File

@ -174,23 +174,24 @@ namespace NanoBrain {
memory.staticMemory = EditorGUILayout.Toggle("Static Memory", memory.staticMemory); memory.staticMemory = EditorGUILayout.Toggle("Static Memory", memory.staticMemory);
} }
if (this.currentNucleus is IReceptor receptor1) { // if (this.currentNucleus is IReceptor receptor1) {
EditorGUILayout.BeginHorizontal(); // EditorGUILayout.BeginHorizontal();
EditorGUILayout.IntField("Array size", receptor1.nucleiArray.Count()); // EditorGUILayout.IntField("Array size", receptor1.nucleiArray.Count());
if (GUILayout.Button("Add")) { // if (GUILayout.Button("Add")) {
Undo.RecordObject(prefabAsset, "Array add " + prefabAsset.name); // Undo.RecordObject(prefabAsset, "Array add " + prefabAsset.name);
receptor1.AddReceptorElement(this.prefab); // receptor1.AddReceptorElement(this.prefab);
anythingChanged = true; // anythingChanged = true;
} // }
if (GUILayout.Button("Del")) { // if (GUILayout.Button("Del")) {
Undo.RecordObject(prefabAsset, "Array delete " + prefabAsset.name); // Undo.RecordObject(prefabAsset, "Array delete " + prefabAsset.name);
receptor1.RemoveReceptorElement(); // receptor1.RemoveReceptorElement();
anythingChanged = true; // anythingChanged = true;
} // }
EditorGUILayout.EndHorizontal(); // EditorGUILayout.EndHorizontal();
} // }
else if (this.currentNucleus is Cluster cluster) { // else
if (this.currentNucleus is Cluster cluster) {
EditorGUILayout.BeginHorizontal(); EditorGUILayout.BeginHorizontal();
if (cluster.siblingClusters != null && cluster.siblingClusters.Length > 1) if (cluster.siblingClusters != null && cluster.siblingClusters.Length > 1)
EditorGUILayout.IntField("Array size", cluster.siblingClusters.Count()); EditorGUILayout.IntField("Array size", cluster.siblingClusters.Count());
@ -211,7 +212,7 @@ namespace NanoBrain {
// Synapses // Synapses
if (this.currentNucleus is not Receptor && this.currentNucleus is not ClusterReceptor) { if (this.currentNucleus is not Receptor) { //} && this.currentNucleus is not ClusterReceptor) {
showSynapses = EditorGUILayout.BeginFoldoutHeaderGroup(showSynapses, "Synapses"); showSynapses = EditorGUILayout.BeginFoldoutHeaderGroup(showSynapses, "Synapses");
if (showSynapses) { if (showSynapses) {
if (this.currentNucleus is Neuron neuron2) { if (this.currentNucleus is Neuron neuron2) {
@ -248,11 +249,11 @@ namespace NanoBrain {
continue; continue;
} }
else { else {
if (synapse.neuron.parent is IReceptor iReceptor) { // if (synapse.neuron.parent is IReceptor iReceptor) {
array = iReceptor.nucleiArray; // array = iReceptor.nucleiArray;
if (iReceptor is Cluster iCluster) // if (iReceptor is Cluster iCluster)
elementIx = Cluster.GetNucleusIndex(iCluster.clusterNuclei, synapse.neuron); // elementIx = Cluster.GetNucleusIndex(iCluster.clusterNuclei, synapse.neuron);
} // }
// else if (synapse.nucleus is Receptor receptor2) // && receptor2.array != null && receptor2.array.nuclei.Length > 1) // else if (synapse.nucleus is Receptor receptor2) // && receptor2.array != null && receptor2.array.nuclei.Length > 1)
// array = receptor2.nucleiArray; // array = receptor2.nucleiArray;
} }
@ -299,14 +300,14 @@ namespace NanoBrain {
EditorGUI.indentLevel++; EditorGUI.indentLevel++;
float newWeight = EditorGUILayout.FloatField("Weight", synapse.weight); float newWeight = EditorGUILayout.FloatField("Weight", synapse.weight);
if (newWeight != synapse.weight) { if (newWeight != synapse.weight) {
if (synapse.neuron.parent is IReceptor receptor) { // if (synapse.neuron.parent is IReceptor receptor) {
Nucleus[] receptorArray = receptor.nucleiArray; // Nucleus[] receptorArray = receptor.nucleiArray;
foreach (Synapse s in this.currentNucleus.synapses) { // foreach (Synapse s in this.currentNucleus.synapses) {
if (s.neuron.parent is IReceptor r && r.nucleiArray == receptorArray) // if (s.neuron.parent is IReceptor r && r.nucleiArray == receptorArray)
s.weight = newWeight; // s.weight = newWeight;
} // }
} // }
else // else
synapse.weight = newWeight; synapse.weight = newWeight;
anythingChanged = true; anythingChanged = true;
} }
@ -340,10 +341,10 @@ namespace NanoBrain {
neuron.curvePreset = newPreset; neuron.curvePreset = newPreset;
EditorGUILayout.EndHorizontal(); EditorGUILayout.EndHorizontal();
} }
if (neuron is Receptor receptor2) { // if (neuron is Receptor receptor2) {
if (receptor2.nucleiArray == null || receptor2.nucleiArray.Count() == 0) // if (receptor2.nucleiArray == null || receptor2.nucleiArray.Count() == 0)
receptor2.array = new NucleusArray(neuron); // receptor2.array = new NucleusArray(neuron);
} // }
} }
EditorGUILayout.Space(); EditorGUILayout.Space();
@ -377,22 +378,22 @@ namespace NanoBrain {
void OnSceneGUI(SceneView sceneView) { void OnSceneGUI(SceneView sceneView) {
if (this.gameObject != null) { if (this.gameObject != null) {
if (this.currentNucleus is IReceptor receptor) { // if (this.currentNucleus is IReceptor receptor) {
foreach (Nucleus nucleus in receptor.nucleiArray) { // foreach (Nucleus nucleus in receptor.nucleiArray) {
if (nucleus is Neuron neuron) { // if (nucleus is Neuron neuron) {
Vector3 worldVector = this.gameObject.transform.TransformVector(neuron.outputValue); // Vector3 worldVector = this.gameObject.transform.TransformVector(neuron.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);
} // }
} // }
} // }
else { // else {
if (this.currentNucleus is Neuron currentNeuron) { if (this.currentNucleus is Neuron currentNeuron) {
Vector3 worldVector = this.gameObject.transform.TransformVector(currentNeuron.outputValue); Vector3 worldVector = this.gameObject.transform.TransformVector(currentNeuron.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);
} }
} // }
} }
} }
@ -452,15 +453,15 @@ namespace NanoBrain {
BuildLayers(); BuildLayers();
} }
protected virtual void AddClusterReceptorInput(Nucleus nucleus) { // protected virtual void AddClusterReceptorInput(Nucleus nucleus) {
ClusterPickerWindow.ShowPicker(prefab => OnClusterReceptorPicked(nucleus, prefab), "Select Cluster"); // ClusterPickerWindow.ShowPicker(prefab => OnClusterReceptorPicked(nucleus, prefab), "Select Cluster");
} // }
private void OnClusterReceptorPicked(Nucleus nucleus, ClusterPrefab selectedPrefab) { // private void OnClusterReceptorPicked(Nucleus nucleus, ClusterPrefab selectedPrefab) {
ClusterReceptor clusterInstance = new(selectedPrefab, this.prefab, "New " + selectedPrefab.name); // ClusterReceptor clusterInstance = new(selectedPrefab, this.prefab, "New " + selectedPrefab.name);
clusterInstance.defaultOutput.AddReceiver(nucleus); // clusterInstance.defaultOutput.AddReceiver(nucleus);
this.currentNucleus = clusterInstance; // this.currentNucleus = clusterInstance;
BuildLayers(); // BuildLayers();
} // }
private void EditCluster(Cluster subCluster) { private void EditCluster(Cluster subCluster) {
// May be used with storedPrefab... // May be used with storedPrefab...
@ -502,9 +503,10 @@ namespace NanoBrain {
EditorGUILayout.EndHorizontal(); EditorGUILayout.EndHorizontal();
if (connecting) { if (connecting) {
Nucleus nucleus = nuclei.ElementAt(selectedConnectNucleus); Nucleus nucleus = nuclei.ElementAt(selectedConnectNucleus);
if (nucleus is IReceptor receptor) // if (nucleus is IReceptor receptor)
receptor.AddArrayReceiver(this.currentNucleus); // receptor.AddArrayReceiver(this.currentNucleus);
else if (nucleus is Neuron neuron) // else
if (nucleus is Neuron neuron)
neuron.AddReceiver(this.currentNucleus); neuron.AddReceiver(this.currentNucleus);
else if (nucleus is Cluster subCluster) else if (nucleus is Cluster subCluster)
subCluster.defaultOutput.AddReceiver(this.currentNucleus); subCluster.defaultOutput.AddReceiver(this.currentNucleus);
@ -563,37 +565,37 @@ namespace NanoBrain {
protected virtual void ChangeSynapse(Synapse synapse, Neuron newNucleus) { protected virtual void ChangeSynapse(Synapse synapse, Neuron newNucleus) {
Neuron synapseNeuron = synapse.neuron as Neuron; Neuron synapseNeuron = synapse.neuron as Neuron;
if (synapse.neuron.parent is Cluster subCluster && subCluster.prefab != this.prefab) { if (synapse.neuron.parent is Cluster subCluster && subCluster.prefab != this.prefab) {
if (synapse.neuron.parent is ClusterReceptor receptor) { // if (synapse.neuron.parent is ClusterReceptor receptor) {
// the new nucleus is part of a (cluster) receptor, // // the new nucleus is part of a (cluster) receptor,
// 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 = Cluster.GetNucleusIndex(subCluster.clusterNuclei, synapse.neuron); // int oldNucleusIx = Cluster.GetNucleusIndex(subCluster.clusterNuclei, synapse.neuron);
int newNucleusIx = Cluster.GetNucleusIndex(subCluster.clusterNuclei, newNucleus); // int newNucleusIx = Cluster.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
// of the ClusterReceptor array // // of the ClusterReceptor array
Nucleus oldElementNucleus = clusterReceptor.clusterNuclei[oldNucleusIx]; // Nucleus oldElementNucleus = clusterReceptor.clusterNuclei[oldNucleusIx];
if (oldElementNucleus is not Neuron oldElementNeuron) // if (oldElementNucleus is not Neuron oldElementNeuron)
continue; // continue;
// Get the same neuron as newNucleus in a different element // // Get the same neuron as newNucleus in a different element
// of the ClusterReceptor array // // of the ClusterReceptor array
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);
} // }
} }
else { else {
synapseNeuron.RemoveReceiver(this.currentNucleus); synapseNeuron.RemoveReceiver(this.currentNucleus);

View File

@ -186,67 +186,67 @@ namespace NanoBrain {
// Draw selected Nucleus // Draw selected Nucleus
if (expandArray) { if (expandArray) {
if (this.currentNucleus is IReceptor receptor1) { // if (this.currentNucleus is IReceptor receptor1) {
float maxValue = 0; // float maxValue = 0;
foreach (Nucleus nucleus in receptor1.nucleiArray) { // foreach (Nucleus nucleus in receptor1.nucleiArray) {
if (nucleus is Neuron neuron) { // if (nucleus is Neuron neuron) {
float value = neuron.outputMagnitude; // float value = neuron.outputMagnitude;
if (value > maxValue) // if (value > maxValue)
maxValue = value; // maxValue = value;
} // }
} // }
float spacing = 400f / receptor1.nucleiArray.Count(); // float spacing = 400f / receptor1.nucleiArray.Count();
float margin = 10 + spacing / 2; // float margin = 10 + spacing / 2;
float xMin = 150 - size; // float xMin = 150 - size;
float xMax = 150 + size; // float xMax = 150 + size;
float yMin = 10 + margin - size / 2; // float yMin = 10 + margin - size / 2;
float yMax = 400 - margin + size; // float yMax = 400 - margin + size;
Vector3[] verts = new Vector3[4] { // Vector3[] verts = new Vector3[4] {
new(xMin, yMin, 0), // new(xMin, yMin, 0),
new(xMax, yMin, 0), // new(xMax, yMin, 0),
new(xMax, yMax, 0), // new(xMax, yMax, 0),
new(xMin, yMax, 0) // new(xMin, yMax, 0)
}; // };
Handles.color = Color.black; // Handles.color = Color.black;
Handles.DrawAAConvexPolygon(verts); // Handles.DrawAAConvexPolygon(verts);
int row = 0; // int row = 0;
foreach (Nucleus nucleus in receptor1.nucleiArray) { // foreach (Nucleus nucleus in receptor1.nucleiArray) {
Vector3 pos = new(150, margin + row * spacing, 0.0f); // Vector3 pos = new(150, margin + row * spacing, 0.0f);
Handles.color = Color.white; // Handles.color = Color.white;
// The selected nucleus highlight ring // // The selected nucleus highlight ring
Handles.DrawSolidDisc(pos, Vector3.forward, size + 2); // Handles.DrawSolidDisc(pos, Vector3.forward, size + 2);
DrawNucleus(nucleus, pos, maxValue, size); // DrawNucleus(nucleus, pos, maxValue, size);
row++; // row++;
} // }
GUIStyle style = new(EditorStyles.label) { // GUIStyle style = new(EditorStyles.label) {
alignment = TextAnchor.UpperCenter, // alignment = TextAnchor.UpperCenter,
normal = { textColor = Color.white }, // normal = { textColor = Color.white },
fontStyle = FontStyle.Bold, // fontStyle = FontStyle.Bold,
}; // };
Vector3 labelPos = new(150, yMax + size + 5, 0); // Vector3 labelPos = new(150, yMax + size + 5, 0);
string receptorName = receptor1.GetName(); // string receptorName = receptor1.GetName();
int colonPos = receptorName.IndexOf(":"); // int colonPos = receptorName.IndexOf(":");
if (colonPos > 0) { // if (colonPos > 0) {
string baseName = receptorName[..colonPos]; // string baseName = receptorName[..colonPos];
Handles.Label(labelPos, baseName, style); // Handles.Label(labelPos, baseName, style);
} // }
else // else
Handles.Label(labelPos, receptorName, style); // Handles.Label(labelPos, receptorName, style);
} // }
else { // else {
Handles.color = Color.white; Handles.color = Color.white;
// The selected nucleus highlight ring // The selected nucleus highlight ring
Handles.DrawSolidDisc(position, Vector3.forward, size + 2); Handles.DrawSolidDisc(position, Vector3.forward, size + 2);
float maxValue = 1; float maxValue = 1;
if (this.currentNucleus is Neuron neuron) if (this.currentNucleus is Neuron neuron)
maxValue = neuron.outputMagnitude; maxValue = neuron.outputMagnitude;
else if (this.currentNucleus is Cluster cluster) else if (this.currentNucleus is Cluster cluster)
maxValue = cluster.defaultOutput.outputMagnitude; maxValue = cluster.defaultOutput.outputMagnitude;
DrawNucleus(this.currentNucleus, position, maxValue, 20); DrawNucleus(this.currentNucleus, position, maxValue, 20);
} // }
} }
else { else {
Handles.color = Color.white; Handles.color = Color.white;
@ -290,11 +290,11 @@ namespace NanoBrain {
int row = 0; int row = 0;
List<Nucleus[]> drawnArrays = new(); List<Nucleus[]> drawnArrays = new();
foreach (Nucleus receiver in receivers) { foreach (Nucleus receiver in receivers) {
if (receiver is Receptor receptor) { // if (receiver is Receptor receptor) {
if (drawnArrays.Contains(receptor.nucleiArray)) // if (drawnArrays.Contains(receptor.nucleiArray))
continue; // continue;
drawnArrays.Add(receptor.nucleiArray); // drawnArrays.Add(receptor.nucleiArray);
} // }
Nucleus receiverNucleus = receiver; Nucleus receiverNucleus = receiver;
if (receiverNucleus == null) if (receiverNucleus == null)
@ -321,26 +321,21 @@ namespace NanoBrain {
if (synapse.neuron == null) if (synapse.neuron == null)
continue; continue;
if (synapse.neuron is Receptor receptor) { // if (synapse.neuron is Receptor receptor) {
if (drawnArrays.Contains(receptor.nucleiArray)) // if (drawnArrays.Contains(receptor.nucleiArray))
continue; // continue;
drawnArrays.Add(receptor.nucleiArray); // drawnArrays.Add(receptor.nucleiArray);
} // }
else if (synapse.neuron.parent is ClusterReceptor clusterReceptor) { // else if (synapse.neuron.parent is ClusterReceptor clusterReceptor) {
if (drawnArrays.Contains(clusterReceptor.nucleiArray)) // if (drawnArrays.Contains(clusterReceptor.nucleiArray))
continue; // continue;
drawnArrays.Add(clusterReceptor.nucleiArray); // drawnArrays.Add(clusterReceptor.nucleiArray);
} // }
else if (synapse.neuron.parent is Cluster cluster && cluster.siblingClusters != null) { if (synapse.neuron.parent is Cluster cluster && cluster.siblingClusters != null) {
if (drawnArrays.Contains(cluster.siblingClusters)) if (drawnArrays.Contains(cluster.siblingClusters))
continue; continue;
drawnArrays.Add(cluster.siblingClusters); drawnArrays.Add(cluster.siblingClusters);
} }
// else if (synapse.neuron.parent is Cluster cluster && cluster.clusterArray != null) {
// if (drawnArrays.Contains(cluster.clusterArray.clusters))
// continue;
// drawnArrays.Add(cluster.clusterArray.clusters);
// }
if (synapse.neuron is Neuron synapseNeuron) { if (synapse.neuron is Neuron synapseNeuron) {
float value = synapseNeuron.outputMagnitude * synapse.weight; float value = synapseNeuron.outputMagnitude * synapse.weight;
// Debug.Log($"{synapse.nucleus.name}: {value} {length(synapse.nucleus.outputValue)} {synapse.weight}"); // Debug.Log($"{synapse.nucleus.name}: {value} {length(synapse.nucleus.outputValue)} {synapse.weight}");
@ -360,16 +355,16 @@ namespace NanoBrain {
if (synapse.neuron is null) if (synapse.neuron is null)
continue; continue;
if (synapse.neuron is Receptor neuron) { // if (synapse.neuron is Receptor neuron) {
if (drawnArrays.Contains(neuron.nucleiArray)) // if (drawnArrays.Contains(neuron.nucleiArray))
continue; // continue;
drawnArrays.Add(neuron.nucleiArray); // drawnArrays.Add(neuron.nucleiArray);
} // }
else if (synapse.neuron.parent is ClusterReceptor clusterReceptor) { // else if (synapse.neuron.parent is ClusterReceptor clusterReceptor) {
if (drawnArrays.Contains(clusterReceptor.nucleiArray)) // if (drawnArrays.Contains(clusterReceptor.nucleiArray))
continue; // continue;
drawnArrays.Add(clusterReceptor.nucleiArray); // drawnArrays.Add(clusterReceptor.nucleiArray);
} // }
Vector3 pos = new(250, margin + row * spacing, 0.0f); Vector3 pos = new(250, margin + row * spacing, 0.0f);
Handles.color = Color.white; Handles.color = Color.white;
Handles.DrawLine(parentPos, pos); Handles.DrawLine(parentPos, pos);
@ -384,11 +379,9 @@ namespace NanoBrain {
} }
if (synapse.neuron.parent != null && synapse.neuron.parent != this.currentNucleus.parent) { if (synapse.neuron.parent != null && synapse.neuron.parent != this.currentNucleus.parent) {
// the synapse nucleus is part of a subcluster // the synapse nucleus is part of a subcluster
DrawNucleus(synapse.neuron.parent, pos, maxValue, size, color); //DrawNucleus(synapse.neuron.parent, pos, maxValue, size, color);
DrawNucleus(synapse.neuron, pos, maxValue, size, color);
} }
// else if (synapse.nucleus.cluster != null && synapse.nucleus.cluster != this.currentNucleus.cluster) {
// DrawNucleus(synapse.nucleus.parent, pos, maxValue, size, color);
// }
else { else {
DrawNucleus(synapse.neuron, pos, maxValue, size, color); DrawNucleus(synapse.neuron, pos, maxValue, size, color);
} }
@ -428,7 +421,29 @@ namespace NanoBrain {
fontStyle = FontStyle.Bold, fontStyle = FontStyle.Bold,
}; };
if (nucleus is IReceptor receptor1) { // if (nucleus is IReceptor receptor1) {
// if (expandArray) {
// // Put array indices above elements
// style.alignment = TextAnchor.LowerCenter;
// Vector3 labelPos1 = position + Vector3.down * (size + 5); // below disc
// int colonPos1 = nucleus.name.IndexOf(":");
// if (colonPos1 > 0) {
// string extName = nucleus.name[(colonPos1 + 2)..];
// Handles.Label(labelPos1, extName, style);
// }
// }
// else {
// // draw the array size label
// if (color.grayscale > 0.5f)
// style.normal.textColor = Color.black;
// else
// style.normal.textColor = Color.white;
// Handles.Label(labelPosition, receptor1.nucleiArray.Length.ToString(), style);
// style.normal.textColor = Color.white;
// }
// }
// else
if (nucleus.parent != null && nucleus.parent is Cluster parentCluster) {
if (expandArray) { if (expandArray) {
// Put array indices above elements // Put array indices above elements
style.alignment = TextAnchor.LowerCenter; style.alignment = TextAnchor.LowerCenter;
@ -440,13 +455,15 @@ namespace NanoBrain {
} }
} }
else { else {
// draw the array size label if (parentCluster.siblingClusters != null && parentCluster.siblingClusters.Length > 1) {
if (color.grayscale > 0.5f) // draw the array size label
style.normal.textColor = Color.black; if (color.grayscale > 0.5f)
else style.normal.textColor = Color.black;
else
style.normal.textColor = Color.white;
Handles.Label(labelPosition, parentCluster.siblingClusters.Length.ToString(), style);
style.normal.textColor = Color.white; style.normal.textColor = Color.white;
Handles.Label(labelPosition, receptor1.nucleiArray.Length.ToString(), style); }
style.normal.textColor = Color.white;
} }
} }
else if (nucleus is Cluster cluster) { else if (nucleus is Cluster cluster) {
@ -478,25 +495,46 @@ namespace NanoBrain {
Vector3 labelPos = position - Vector3.down * (size + 5); // below neuron Vector3 labelPos = position - Vector3.down * (size + 5); // below neuron
style.alignment = TextAnchor.UpperCenter; style.alignment = TextAnchor.UpperCenter;
nucleus.name ??= ""; if (nucleus.parent != null && nucleus.parent is Cluster parentCluster1) {
int colonPos = nucleus.name.IndexOf(":"); parentCluster1.name ??= "";
if (colonPos > 0 && colonPos < nucleus.name.Length - 2) { string baseName = "";
// if it is an array, we should not show the :0 of the first element if (parentCluster1 != currentNucleus.parent) {
string baseName = nucleus.name[..colonPos]; int colonPos = parentCluster1.name.IndexOf(":");
Handles.Label(labelPos, baseName, style); if (colonPos > 0 && colonPos < parentCluster1.name.Length - 2)
baseName = parentCluster1.name[..colonPos] + ".";
else
baseName = parentCluster1.name + ".";
}
// if (colonPos > 0 && colonPos < parentCluster1.name.Length - 2) {
// // if it is an array, we should not show the :0 of the first element
// //baseName = baseName[..colonPos];
// Handles.Label(labelPos, baseName + nucleus.name, style);
// }
// else
Handles.Label(labelPos, baseName + nucleus.name, style);
}
else {
nucleus.name ??= "";
int colonPos = nucleus.name.IndexOf(":");
if (colonPos > 0 && colonPos < nucleus.name.Length - 2) {
// if it is an array, we should not show the :0 of the first element
string baseName = nucleus.name[..colonPos];
Handles.Label(labelPos, baseName, style);
}
else
Handles.Label(labelPos, nucleus.name, style);
} }
else
Handles.Label(labelPos, nucleus.name, style);
} }
// Draw Cluster ring // Draw Cluster ring
if (nucleus is Cluster) { if (nucleus.parent != currentNucleus.parent || nucleus is Cluster) {
Handles.color = Color.white; Handles.color = Color.white;
Handles.DrawWireDisc(position, Vector3.forward, size + 5); Handles.DrawWireDisc(position, Vector3.forward, size + 5);
} }
// Tooltip // Tooltip
Rect neuronRect = new(position.x - size, position.y - size, size * 2, size * 2); Rect neuronRect = new(position.x - size, position.y - size, size * 2, size * 2);
int id = GUIUtility.GetControlID(FocusType.Passive); int id = GUIUtility.GetControlID(FocusType.Passive);
Event e = Event.current; Event e = Event.current;
EventType et = e.GetTypeForControl(id); EventType et = e.GetTypeForControl(id);
@ -507,7 +545,10 @@ namespace NanoBrain {
if (e.type == EventType.MouseDown && e.button == 0) { if (e.type == EventType.MouseDown && e.button == 0) {
// Consume the event so the scene doesn't also handle it // Consume the event so the scene doesn't also handle it
e.Use(); e.Use();
HandleClicked(nucleus); if (nucleus.parent != null && nucleus.parent is Cluster parentCluster2)
HandleClicked(parentCluster2);
else
HandleClicked(nucleus);
} }
} }
} }
@ -533,7 +574,7 @@ namespace NanoBrain {
private void HandleClicked(Nucleus nucleus) { private void HandleClicked(Nucleus nucleus) {
if (nucleus == this.currentNucleus) { if (nucleus == this.currentNucleus) {
if (nucleus is Receptor || nucleus is ClusterReceptor) if (nucleus is Receptor) // || nucleus is ClusterReceptor)
expandArray = !expandArray; expandArray = !expandArray;
else else
expandArray = false; expandArray = false;
@ -547,22 +588,22 @@ namespace NanoBrain {
void OnSceneGUI(SceneView sceneView) { void OnSceneGUI(SceneView sceneView) {
if (this.gameObject != null) { if (this.gameObject != null) {
if (this.currentNucleus is IReceptor receptor) { // if (this.currentNucleus is IReceptor receptor) {
foreach (Nucleus nucleus in receptor.nucleiArray) { // foreach (Nucleus nucleus in receptor.nucleiArray) {
if (nucleus is Neuron neuron) { // if (nucleus is Neuron neuron) {
Vector3 worldVector = this.gameObject.transform.TransformVector(neuron.outputValue); // Vector3 worldVector = this.gameObject.transform.TransformVector(neuron.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);
} // }
} // }
} // }
else { // else {
if (this.currentNucleus is Neuron currentNeuron) { if (this.currentNucleus is Neuron currentNeuron) {
Vector3 worldVector = this.gameObject.transform.TransformVector(currentNeuron.outputValue); Vector3 worldVector = this.gameObject.transform.TransformVector(currentNeuron.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);
}
} }
// }
} }
} }

View File

@ -117,6 +117,7 @@ namespace NanoBrain {
} }
} }
/*
// Copy nucleus arrays for receptors // Copy nucleus arrays for receptors
for (int nucleusIx = 0; nucleusIx < prefabNuclei.Length; nucleusIx++) { for (int nucleusIx = 0; nucleusIx < prefabNuclei.Length; nucleusIx++) {
Nucleus prefabNucleus = prefabNuclei[nucleusIx]; Nucleus prefabNucleus = prefabNuclei[nucleusIx];
@ -152,6 +153,7 @@ namespace NanoBrain {
clonedNucleus.nucleiArray = clonedFirstNucleus.nucleiArray; clonedNucleus.nucleiArray = clonedFirstNucleus.nucleiArray;
} }
} }
*/
foreach (Nucleus nucleus in this.clusterNuclei) { foreach (Nucleus nucleus in this.clusterNuclei) {
if (nucleus is Cluster clonedSubCluster) if (nucleus is Cluster clonedSubCluster)
@ -225,16 +227,19 @@ namespace NanoBrain {
clonedSynapse.weight = synapse.weight; clonedSynapse.weight = synapse.weight;
} }
foreach (Neuron output in this.outputs) { foreach (Nucleus nucleus in this.clusterNuclei) {
foreach (Nucleus receiver in output.receivers) { if (nucleus is Neuron output) {
int ix = GetNucleusIndex(this.clusterNuclei.ToArray(), output); foreach (Nucleus receiver in output.receivers) {
if (ix < 0) int ix = GetNucleusIndex(this.clusterNuclei, output);
continue; Debug.Log($"{output.name} -> {receiver.name}: {ix}");
if (ix < 0)
continue;
if (clone.clusterNuclei[ix] is not Neuron clonedOutput) if (clone.clusterNuclei[ix] is not Neuron clonedOutput)
continue; continue;
clonedOutput.AddReceiver(receiver); clonedOutput.AddReceiver(receiver);
}
} }
} }
@ -313,43 +318,41 @@ namespace NanoBrain {
public void AddInstance(ClusterPrefab prefab) { public void AddInstance(ClusterPrefab prefab) {
// if (this.siblingClusters.Length == 0) { // Ensure siblingClusters exists
// Debug.LogError("Empty perceptoid array, cannot add");
// return;
// }
this.siblingClusters ??= new Cluster[1] { this }; this.siblingClusters ??= new Cluster[1] { this };
// Prepare the new array
int newLength = this.siblingClusters.Length + 1; int newLength = this.siblingClusters.Length + 1;
Cluster[] newSiblings = new Cluster[newLength]; Cluster[] newSiblings = new Cluster[newLength];
for (int i = 0; i < newSiblings.Length - 1; i++)
newSiblings[i] = this.siblingClusters[i];
Cluster newCluster = this.Clone(prefab) as Cluster;
string baseName = this.name; string baseName = this.name;
int colonPos = baseName.IndexOf(":"); int colonPos = baseName.IndexOf(":");
if (colonPos > 0) if (colonPos > 0)
baseName = baseName[..colonPos]; baseName = baseName[..colonPos];
for (int i = 0; i < newSiblings.Length - 1; i++)
newSiblings[i] = this.siblingClusters[i];
// Cluster sourceCluster = this.siblingClusters[0];
Cluster newCluster = this.Clone(prefab) as Cluster;
newCluster.name = $"{baseName}: {newLength - 1}"; newCluster.name = $"{baseName}: {newLength - 1}";
//newCluster.clusterArray = this;
newSiblings[newLength - 1] = newCluster; newSiblings[newLength - 1] = newCluster;
this.siblingClusters = newSiblings; // All siblingClusters need to user this array!
newCluster.siblingClusters = newSiblings; foreach (Cluster sibling in this.siblingClusters)
sibling.siblingClusters = newSiblings;
} }
public void RemoveInstance() { public void RemoveInstance() {
int newLength = this.siblingClusters.Length - 1; if (this.siblingClusters == null || this.siblingClusters.Length <= 1)
if (newLength == 0) {
Debug.LogWarning("Perceptoid array cannot be empty");
return; return;
}
// Prepare the new array
int newLength = this.siblingClusters.Length - 1;
Cluster[] newClusters = new Cluster[newLength]; Cluster[] newClusters = new Cluster[newLength];
for (int i = 0; i < newLength; i++) for (int i = 0; i < newLength; i++)
newClusters[i] = this.siblingClusters[i]; newClusters[i] = this.siblingClusters[i];
// Delete the last perception
//Cluster.Delete(nucleus); Neuron.Delete(this.siblingClusters[^1]);
this.siblingClusters = newClusters; this.siblingClusters = newClusters;
} }
@ -601,9 +604,11 @@ namespace NanoBrain {
if (startNucleus.trace) if (startNucleus.trace)
Debug.Log($"Update from {startNucleus.name}"); Debug.Log($"Update from {startNucleus.name}");
foreach (Nucleus nucleus in computeOrder) { foreach (Nucleus nucleus in computeOrder) {
nucleus.UpdateStateIsolated(); if (nucleus is not Cluster) {
if (startNucleus.trace && nucleus is Neuron neuron) nucleus.UpdateStateIsolated();
Debug.Log($" {nucleus.name}[{nucleus.GetHashCode()}] = {neuron.outputValue}"); if (startNucleus.trace && nucleus is Neuron neuron)
Debug.Log($" {nucleus.name}[{nucleus.GetHashCode()}]"); // = {neuron.outputValue}");
}
} }
// continue in parent // continue in parent

View File

@ -1,3 +1,4 @@
/*
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using UnityEngine; using UnityEngine;
@ -275,4 +276,5 @@ namespace NanoBrain {
} }
} }
*/

View File

@ -17,17 +17,17 @@ namespace NanoBrain {
/// The array of nuclei used to track multiple things sending stimuli /// The array of nuclei used to track multiple things sending stimuli
/// </summary> /// </summary>
/// The size of the array determines the maximum number of things which can be distinguished /// The size of the array determines the maximum number of things which can be distinguished
public Nucleus[] nucleiArray { get; set; } // public Nucleus[] nucleiArray { get; set; }
/// <summary> /// <summary>
/// Extends the nucleiArray with an additional element /// Extends the nucleiArray with an additional element
/// </summary> /// </summary>
/// <param name="prefab">A prefab of the nucleus to add?</param> /// <param name="prefab">A prefab of the nucleus to add?</param>
public void AddReceptorElement(ClusterPrefab prefab); // public void AddReceptorElement(ClusterPrefab prefab);
/// <summary> /// <summary>
/// Removes the last element from the nucleiArray /// Removes the last element from the nucleiArray
/// </summary> /// </summary>
public void RemoveReceptorElement(); // public void RemoveReceptorElement();
/// <summary> /// <summary>
/// Add a receiver for this receptor array /// Add a receiver for this receptor array
@ -35,7 +35,7 @@ namespace NanoBrain {
/// <param name="receiverToAdd">The receiving Nucleus</param> /// <param name="receiverToAdd">The receiving Nucleus</param>
/// <param name="weight">The initial weight to use for the synapses</param> /// <param name="weight">The initial weight to use for the synapses</param>
/// This function will add a synapse to the receiver for each element in the nucleiArray. /// This function will add a synapse to the receiver for each element in the nucleiArray.
public void AddArrayReceiver(Nucleus receiverToAdd, float weight = 1); // public void AddArrayReceiver(Nucleus receiverToAdd, float weight = 1);
/// <summary> /// <summary>
/// Process an external stimulus /// Process an external stimulus
@ -47,77 +47,78 @@ namespace NanoBrain {
} }
public static class IReceptorHelpers { public static class IReceptorHelpers {
/*
/// <summary>
/// Implementation for the NanoBrain::IReceptor::AddReceptorElement which can be used for all implementations of IReceptor
/// </summary>
/// <param name="receptor">The IReceptor which needs to extend its nucleiArray</param>
/// <param name="prefab">A prefab of the nucleus to add?</param>
public static void AddReceptorElement(IReceptor receptor, ClusterPrefab prefab) {
if (receptor.nucleiArray.Length == 0) {
Debug.LogError("Empty perceptoid array, cannot add");
}
int newLength = receptor.nucleiArray.Length + 1;
Nucleus[] newArray = new Nucleus[newLength];
/// <summary> string baseName = receptor.GetName();
/// Implementation for the NanoBrain::IReceptor::AddReceptorElement which can be used for all implementations of IReceptor int colonPos = baseName.IndexOf(":");
/// </summary> if (colonPos > 0)
/// <param name="receptor">The IReceptor which needs to extend its nucleiArray</param> baseName = baseName[..colonPos];
/// <param name="prefab">A prefab of the nucleus to add?</param>
public static void AddReceptorElement(IReceptor receptor, ClusterPrefab prefab) {
if (receptor.nucleiArray.Length == 0) {
Debug.LogError("Empty perceptoid array, cannot add");
}
int newLength = receptor.nucleiArray.Length + 1;
Nucleus[] newArray = new Nucleus[newLength];
string baseName = receptor.GetName(); for (int i = 0; i < receptor.nucleiArray.Length; i++)
int colonPos = baseName.IndexOf(":"); newArray[i] = receptor.nucleiArray[i];
if (colonPos > 0) if (receptor.nucleiArray[0] is Nucleus nucleus) {
baseName = baseName[..colonPos]; newArray[newLength - 1] = nucleus.Clone(prefab);
newArray[newLength - 1].name = $"{baseName}: {newLength - 1}";
}
for (int i = 0; i < receptor.nucleiArray.Length; i++) foreach (Nucleus element in receptor.nucleiArray) {
newArray[i] = receptor.nucleiArray[i]; if (element is IReceptor receptorElement) {
if (receptor.nucleiArray[0] is Nucleus nucleus) { receptorElement.nucleiArray = newArray;
newArray[newLength - 1] = nucleus.Clone(prefab); }
newArray[newLength - 1].name = $"{baseName}: {newLength - 1}"; }
}
foreach (Nucleus element in receptor.nucleiArray) {
if (element is IReceptor receptorElement) {
receptorElement.nucleiArray = newArray;
} }
}
}
/// <summary> /// <summary>
/// Implementation for the NanoBrain::IReceptor::RemoteReceptorElement which can be used for all implementations of IReceptor /// Implementation for the NanoBrain::IReceptor::RemoteReceptorElement which can be used for all implementations of IReceptor
/// </summary> /// </summary>
/// <param name="receptor">The IReceptor which needs to shorten its nucleiArray</param> /// <param name="receptor">The IReceptor which needs to shorten its nucleiArray</param>
public static void RemoveReceptorElement(IReceptor receptor) { public static void RemoveReceptorElement(IReceptor receptor) {
int newLength = receptor.nucleiArray.Length - 1; int newLength = receptor.nucleiArray.Length - 1;
if (newLength == 0) { if (newLength == 0) {
Debug.LogWarning("Perceptoid array cannot be empty"); Debug.LogWarning("Perceptoid array cannot be empty");
} }
Nucleus[] newArray = new Nucleus[newLength]; Nucleus[] newArray = new Nucleus[newLength];
for (int i = 0; i < newLength; i++) for (int i = 0; i < newLength; i++)
newArray[i] = receptor.nucleiArray[i]; newArray[i] = receptor.nucleiArray[i];
// Delete the last perception // Delete the last perception
if (receptor.nucleiArray[newLength] is Nucleus nucleus) if (receptor.nucleiArray[newLength] is Nucleus nucleus)
Neuron.Delete(nucleus); Neuron.Delete(nucleus);
foreach (Nucleus element in receptor.nucleiArray) {
if (element is IReceptor receptorElement) {
receptorElement.nucleiArray = newArray;
}
}
foreach (Nucleus element in receptor.nucleiArray) {
if (element is IReceptor receptorElement) {
receptorElement.nucleiArray = newArray;
} }
}
} /// <summary>
/// Implementation for the NanoBreain::IRceptor::AddArrayReceiver which can be used for all implementations of IReceptor
/// </summary>
/// <param name="receptor">The IReceptor for which a receiving nuclues needs to be added</param>
/// <param name="receiverToAdd">The nucleus to receive input from the receptor</param>
/// <param name="weight">The initial weight for the synapses</param>
public static void AddArrayReceiver(IReceptor receptor, Nucleus receiverToAdd, float weight = 1) {
foreach (Nucleus element in receptor.nucleiArray) {
if (element is Cluster cluster)
cluster.defaultOutput.AddReceiver(receiverToAdd, weight);
if (element is Neuron neuron)
neuron.AddReceiver(receiverToAdd, weight);
}
/// <summary> }
/// Implementation for the NanoBreain::IRceptor::AddArrayReceiver which can be used for all implementations of IReceptor
/// </summary>
/// <param name="receptor">The IReceptor for which a receiving nuclues needs to be added</param>
/// <param name="receiverToAdd">The nucleus to receive input from the receptor</param>
/// <param name="weight">The initial weight for the synapses</param>
public static void AddArrayReceiver(IReceptor receptor, Nucleus receiverToAdd, float weight = 1) {
foreach (Nucleus element in receptor.nucleiArray) {
if (element is Cluster cluster)
cluster.defaultOutput.AddReceiver(receiverToAdd, weight);
if (element is Neuron neuron)
neuron.AddReceiver(receiverToAdd, weight);
}
} */
} }
} }

View File

@ -171,7 +171,7 @@ namespace NanoBrain {
AnimationUtility.SetKeyRightTangentMode(curve, i, AnimationUtility.TangentMode.Linear); AnimationUtility.SetKeyRightTangentMode(curve, i, AnimationUtility.TangentMode.Linear);
} }
return curve; return curve;
} }
public static AnimationCurve Binary() { public static AnimationCurve Binary() {
return AnimationCurve.Linear(0, 0, 1, 1); return AnimationCurve.Linear(0, 0, 1, 1);
@ -270,9 +270,11 @@ namespace NanoBrain {
} }
else if (nucleus is Cluster cluster) { else if (nucleus is Cluster cluster) {
// remove all receivers for this cluster // remove all receivers for this cluster
foreach (Neuron output in cluster.outputs) { foreach (Nucleus clusterNucleus in cluster.clusterNuclei) {
foreach (Nucleus receiver in output.receivers) { if (clusterNucleus is Neuron output) {
receiver.synapses.RemoveAll(s => s.neuron == output); foreach (Nucleus receiver in output.receivers) {
receiver.synapses.RemoveAll(s => s.neuron == output);
}
} }
} }
} }
@ -426,9 +428,9 @@ namespace NanoBrain {
return float3(value, value, value); return float3(value, value, value);
} }
protected float3 ActivatorNormalized(float3 input) { protected float3 ActivatorNormalized(float3 input) {
if (lengthsq(input) == 0) if (lengthsq(input) == 0)
return input; return input;
float3 result = normalize(input); float3 result = normalize(input);
return result; return result;
} }
@ -497,31 +499,31 @@ namespace NanoBrain {
} }
public virtual void RemoveReceiver(Nucleus receiverToRemove) { public virtual void RemoveReceiver(Nucleus receiverToRemove) {
if (this is IReceptor receptor) { // if (this is IReceptor receptor) {
foreach (Nucleus element in receptor.nucleiArray) { // foreach (Nucleus element in receptor.nucleiArray) {
if (element is Neuron neuron) { // if (element is Neuron neuron) {
neuron._receivers.RemoveAll(receiver => receiver == receiverToRemove); // neuron._receivers.RemoveAll(receiver => receiver == receiverToRemove);
receiverToRemove.synapses.RemoveAll(synapse => synapse.neuron == neuron); // receiverToRemove.synapses.RemoveAll(synapse => synapse.neuron == neuron);
} // }
} // }
} // }
else { // else {
this._receivers.RemoveAll(receiver => receiver == receiverToRemove); this._receivers.RemoveAll(receiver => receiver == receiverToRemove);
receiverToRemove.synapses.RemoveAll(synapse => synapse.neuron == this); receiverToRemove.synapses.RemoveAll(synapse => synapse.neuron == this);
} // }
} }
#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) {
if (this.parent is ClusterReceptor clusterReceptor) // if (this.parent is ClusterReceptor clusterReceptor)
clusterReceptor.ProcessStimulus(this, inputValue, thingId, thingName); // clusterReceptor.ProcessStimulus(this, inputValue, thingId, thingName);
else // else
ProcessStimulusDirect(inputValue, thingId, thingName); ProcessStimulusDirect(inputValue); //, thingId, thingName);
} }
public void ProcessStimulusDirect(Vector3 inputValue, int thingId = 0, string thingName = null) { public void ProcessStimulusDirect(Vector3 inputValue) { //}, int thingId = 0, string thingName = null) {
this.stale = 0; this.stale = 0;
this.bias = inputValue; this.bias = inputValue;
this.parent.UpdateFromNucleus(this); this.parent.UpdateFromNucleus(this);

View File

@ -138,7 +138,7 @@ public abstract class Nucleus {
/// <param name="inputValue">The value of the stimulus</param> /// <param name="inputValue">The value of the stimulus</param>
/// <param name="thingId">The id of the thing causing the stimulus</param> /// <param name="thingId">The id of the thing causing the stimulus</param>
/// <param name="thingName">The name of the thing causing the stimulus</param> /// <param name="thingName">The name of the thing causing the stimulus</param>
public virtual void ProcessStimulus(Vector3 inputValue, int thingId = 0, string thingName = "") { public virtual void ProcessStimulus(Vector3 inputValue) { //, int thingId = 0, string thingName = "") {
} }
#endregion Update #endregion Update

View File

@ -1,3 +1,4 @@
/*
using System.Linq; using System.Linq;
using System.Collections.Generic; using System.Collections.Generic;
using UnityEngine; using UnityEngine;
@ -194,4 +195,5 @@ namespace NanoBrain {
} }
} }
} }
*/

View File

@ -10,16 +10,16 @@ namespace NanoBrain {
/// Basic IReceptor to receive external input /// Basic IReceptor to receive external input
/// </summary> /// </summary>
[System.Serializable] [System.Serializable]
public class Receptor : Neuron, IReceptor { public class Receptor : Neuron { //}, IReceptor {
/// <summary> /// <summary>
/// Create a new Receptor in a Cluster instance /// Create a new Receptor in a Cluster instance
/// </summary> /// </summary>
/// <param name="parent">The Cluster in which the Receptor is created</param> /// <param name="parent">The Cluster in which the Receptor is created</param>
/// <param name="name">The name of the new Receptor</param> /// <param name="name">The name of the new Receptor</param>
public Receptor(Cluster parent, string name) : base(parent, name) { public Receptor(Cluster parent, string name) : base(parent, name) {
this.array = new NucleusArray(this); //this.array = new NucleusArray(this);
if (this.name.IndexOf(":") < 0) // if (this.name.IndexOf(":") < 0)
this.name += ": 0"; // this.name += ": 0";
} }
/// <summary> /// <summary>
/// Create a new Receptor in a Cluster Prefab /// Create a new Receptor in a Cluster Prefab
@ -27,7 +27,7 @@ namespace NanoBrain {
/// <param name="prefab">The Cluster Prefab in which the Receptor is created</param> /// <param name="prefab">The Cluster Prefab in which the Receptor is created</param>
/// <param name="name">The name of the new Receptor</param> /// <param name="name">The name of the new Receptor</param>
public Receptor(ClusterPrefab prefab, string name) : base(prefab, name) { public Receptor(ClusterPrefab prefab, string name) : base(prefab, name) {
this.array = new NucleusArray(this); //this.array = new NucleusArray(this);
} }
public string GetName() { public string GetName() {
@ -45,7 +45,7 @@ namespace NanoBrain {
/// \copydoc NanoBrain::Neuron::Clone /// \copydoc NanoBrain::Neuron::Clone
public override Nucleus Clone(ClusterPrefab prefab) { public override Nucleus Clone(ClusterPrefab prefab) {
Receptor clone = new(prefab, name) { Receptor clone = new(prefab, name) {
array = this._array //array = this._array
}; };
CloneFields(clone); CloneFields(clone);
// Adding receivers will also add synapses to the receivers // Adding receivers will also add synapses to the receivers
@ -55,28 +55,30 @@ namespace NanoBrain {
return clone; return clone;
} }
[SerializeReference] /*
private NucleusArray _array; [SerializeReference]
public NucleusArray array { private NucleusArray _array;
set { _array = value; } public NucleusArray array {
} set { _array = value; }
}
public Nucleus[] nucleiArray { public Nucleus[] nucleiArray {
get { return _array.nuclei; } get { return _array.nuclei; }
set { _array.nuclei = value; } set { _array.nuclei = value; }
} }
public void AddReceptorElement(ClusterPrefab prefab) { public void AddReceptorElement(ClusterPrefab prefab) {
IReceptorHelpers.AddReceptorElement(this, prefab); IReceptorHelpers.AddReceptorElement(this, prefab);
} }
public void RemoveReceptorElement() { public void RemoveReceptorElement() {
IReceptorHelpers.RemoveReceptorElement(this); IReceptorHelpers.RemoveReceptorElement(this);
} }
public virtual void AddArrayReceiver(Nucleus receiverToAdd, float weight = 1) { public virtual void AddArrayReceiver(Nucleus receiverToAdd, float weight = 1) {
IReceptorHelpers.AddArrayReceiver(this, receiverToAdd, weight); IReceptorHelpers.AddArrayReceiver(this, receiverToAdd, weight);
} }
*/
public override void UpdateStateIsolated() { public override void UpdateStateIsolated() {
this.outputValue = this.bias; this.outputValue = this.bias;
@ -104,10 +106,14 @@ namespace NanoBrain {
#endif #endif
public override 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 ??= new NucleusArray(this.parent);
this._array.ProcessStimulus(thingId, inputValue, thingName); // this._array.ProcessStimulus(thingId, inputValue, thingName);
this.stale = 0;
this.bias = inputValue;
this.parent.UpdateFromNucleus(this);
} }
} }
} }