Simplifications
This commit is contained in:
parent
bc0a79688d
commit
19f929606a
@ -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);
|
||||||
|
|||||||
@ -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);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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 {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
@ -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);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -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);
|
||||||
|
|||||||
@ -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
|
||||||
|
|||||||
@ -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 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user