Fix links to multiple cluster neurons & cleanup
This commit is contained in:
parent
e17a249743
commit
04bab9264f
@ -153,15 +153,11 @@ namespace NanoBrain {
|
||||
fontStyle = FontStyle.Bold
|
||||
};
|
||||
|
||||
// Nucleus type
|
||||
string nucleusType = this.currentNucleus.GetType().Name;
|
||||
// if (this.currentNucleus.parent != null) {
|
||||
// string clusterName = this.currentNucleus.parent.name;
|
||||
// GUILayout.Label(clusterName + ": " + nucleusType, headerStyle);
|
||||
// }
|
||||
// else
|
||||
GUILayout.Label(nucleusType, headerStyle);
|
||||
|
||||
|
||||
// Nucleus name
|
||||
if (this.currentNucleus.parent is Cluster parentCluster) {
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
if (GUILayout.Button(this.currentNucleus.parent.name))
|
||||
@ -183,6 +179,7 @@ namespace NanoBrain {
|
||||
}
|
||||
}
|
||||
|
||||
// Current output value
|
||||
if (Application.isPlaying) {
|
||||
if (currentNucleus is Neuron currentNeuron1) {
|
||||
GUIContent nameLabel = new("Output", currentNeuron1.outputValue.ToString());
|
||||
@ -194,44 +191,63 @@ namespace NanoBrain {
|
||||
else
|
||||
EditorGUILayout.LabelField(" ");
|
||||
|
||||
if (this.currentNucleus is MemoryCell memory) {
|
||||
memory.staticMemory = EditorGUILayout.Toggle("Static Memory", memory.staticMemory);
|
||||
}
|
||||
// Memory cell
|
||||
if (this.currentNucleus is MemoryCell memory)
|
||||
MemoryCellInspector(memory, ref anythingChanged);
|
||||
// Cluster
|
||||
else if (this.currentNucleus is Cluster cluster)
|
||||
ClusterInspector(cluster, ref anythingChanged);
|
||||
// Other
|
||||
else
|
||||
NucleusInspector(this.currentNucleus, ref anythingChanged);
|
||||
|
||||
if (this.currentNucleus is Cluster cluster) {
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
if (cluster.instanceCount > 1)
|
||||
EditorGUILayout.IntField("Array size", cluster.instanceCount, GUILayout.MinWidth(150));
|
||||
else if (cluster.siblingClusters != null && cluster.siblingClusters.Length > 1)
|
||||
EditorGUILayout.IntField("Array size", cluster.siblingClusters.Count(), GUILayout.MinWidth(150));
|
||||
else
|
||||
EditorGUILayout.IntField("Array size", 1, GUILayout.MinWidth(150));
|
||||
if (GUILayout.Button("Add")) {
|
||||
Undo.RecordObject(prefabAsset, "Array add " + prefabAsset.name);
|
||||
//cluster.AddInstance(this.prefab);
|
||||
cluster.AddInstance();
|
||||
anythingChanged = true;
|
||||
}
|
||||
if (GUILayout.Button("Del")) {
|
||||
Undo.RecordObject(prefabAsset, "Array delete " + prefabAsset.name);
|
||||
cluster.RemoveInstance();
|
||||
anythingChanged = true;
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
SynapsesInspector(ref anythingChanged);
|
||||
ActivationInspector(ref anythingChanged);
|
||||
|
||||
if (GUILayout.Button("Delete this neuron"))
|
||||
if (GUILayout.Button("Delete"))
|
||||
DeleteNucleus(this.currentNucleus);
|
||||
|
||||
if (this.currentNucleus is Cluster subCluster) {
|
||||
if (GUILayout.Button("Reimport Cluster"))
|
||||
ReimportCluster(subCluster);
|
||||
if (GUILayout.Button("Edit Cluster"))
|
||||
EditCluster(subCluster);
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
if (anythingChanged) {
|
||||
EditorUtility.SetDirty(prefabAsset);
|
||||
AssetDatabase.SaveAssets();
|
||||
}
|
||||
}
|
||||
|
||||
protected void MemoryCellInspector(MemoryCell memoryCell, ref bool anythingChanged) {
|
||||
memoryCell.staticMemory = EditorGUILayout.Toggle("Static Memory", memoryCell.staticMemory);
|
||||
NucleusInspector(memoryCell, ref anythingChanged);
|
||||
}
|
||||
|
||||
protected void ClusterInspector(Cluster cluster, ref bool anythingChanged) {
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
|
||||
int instanceCount = cluster.instanceCount;
|
||||
if (instanceCount <= 1) {
|
||||
if (cluster.siblingClusters != null && cluster.siblingClusters.Length > 1)
|
||||
instanceCount = cluster.siblingClusters.Count();
|
||||
else
|
||||
instanceCount = 1;
|
||||
}
|
||||
EditorGUILayout.IntField("Instances", instanceCount, GUILayout.MinWidth(150));
|
||||
|
||||
if (GUILayout.Button("Add")) {
|
||||
Undo.RecordObject(prefabAsset, "Array add " + prefabAsset.name);
|
||||
//cluster.AddInstance(this.prefab);
|
||||
cluster.AddInstance();
|
||||
anythingChanged = true;
|
||||
}
|
||||
if (GUILayout.Button("Del")) {
|
||||
Undo.RecordObject(prefabAsset, "Array delete " + prefabAsset.name);
|
||||
cluster.RemoveInstance();
|
||||
anythingChanged = true;
|
||||
}
|
||||
EditorGUILayout.EndHorizontal();
|
||||
|
||||
if (GUILayout.Button("Reimport Cluster"))
|
||||
ReimportCluster(cluster);
|
||||
}
|
||||
|
||||
protected void NucleusInspector(Nucleus nucleus, ref bool anythingChanged) {
|
||||
SynapsesInspector(ref anythingChanged);
|
||||
ActivationInspector(ref anythingChanged);
|
||||
|
||||
EditorGUILayout.Space();
|
||||
breakOnWake = EditorGUILayout.Toggle("Break on wake", breakOnWake);
|
||||
@ -242,11 +258,6 @@ namespace NanoBrain {
|
||||
trace = EditorGUILayout.Toggle("Trace", trace);
|
||||
this.currentNucleus.trace = trace;
|
||||
|
||||
serializedObject.ApplyModifiedProperties();
|
||||
if (anythingChanged) {
|
||||
EditorUtility.SetDirty(prefabAsset);
|
||||
AssetDatabase.SaveAssets();
|
||||
}
|
||||
}
|
||||
|
||||
protected void SynapsesInspector(ref bool anythingChanged) {
|
||||
@ -361,35 +372,31 @@ namespace NanoBrain {
|
||||
}
|
||||
|
||||
protected void ActivationInspector(ref bool anythingChanged) {
|
||||
|
||||
if (this.currentNucleus is not Cluster) {
|
||||
EditorGUILayout.Space();
|
||||
showActivation = EditorGUILayout.BeginFoldoutHeaderGroup(showActivation, "Activation");
|
||||
if (showActivation) {
|
||||
if (this.currentNucleus is Neuron neuron) {
|
||||
if (this.currentNucleus is not MemoryCell) {
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
EditorGUILayout.LabelField("Activation Curve", GUILayout.MinWidth(60));
|
||||
if (neuron.curveMax > 0)
|
||||
EditorGUILayout.CurveField(neuron.curve, Color.cyan, new Rect(0, 0, 1, neuron.curveMax), GUILayout.Width(40));
|
||||
else
|
||||
EditorGUILayout.CurveField(neuron.curve, Color.cyan, new Rect(0, neuron.curveMax, 1, -neuron.curveMax), GUILayout.Width(40));
|
||||
Neuron.ActivationType newPreset = (Neuron.ActivationType)EditorGUILayout.EnumPopup(neuron.curvePreset, GUILayout.MinWidth(50));
|
||||
anythingChanged |= newPreset != neuron.curvePreset;
|
||||
neuron.curvePreset = newPreset;
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
// if (neuron is Receptor receptor2) {
|
||||
// if (receptor2.nucleiArray == null || receptor2.nucleiArray.Count() == 0)
|
||||
// receptor2.array = new NucleusArray(neuron);
|
||||
// }
|
||||
EditorGUILayout.Space();
|
||||
showActivation = EditorGUILayout.BeginFoldoutHeaderGroup(showActivation, "Activation");
|
||||
if (showActivation) {
|
||||
if (this.currentNucleus is Neuron neuron) {
|
||||
if (this.currentNucleus is not MemoryCell) {
|
||||
EditorGUILayout.BeginHorizontal();
|
||||
EditorGUILayout.LabelField("Activation Curve", GUILayout.MinWidth(60));
|
||||
if (neuron.curveMax > 0)
|
||||
EditorGUILayout.CurveField(neuron.curve, Color.cyan, new Rect(0, 0, 1, neuron.curveMax), GUILayout.Width(40));
|
||||
else
|
||||
EditorGUILayout.CurveField(neuron.curve, Color.cyan, new Rect(0, neuron.curveMax, 1, -neuron.curveMax), GUILayout.Width(40));
|
||||
Neuron.ActivationType newPreset = (Neuron.ActivationType)EditorGUILayout.EnumPopup(neuron.curvePreset, GUILayout.MinWidth(50));
|
||||
anythingChanged |= newPreset != neuron.curvePreset;
|
||||
neuron.curvePreset = newPreset;
|
||||
EditorGUILayout.EndHorizontal();
|
||||
}
|
||||
|
||||
EditorGUILayout.Space();
|
||||
// if (neuron is Receptor receptor2) {
|
||||
// if (receptor2.nucleiArray == null || receptor2.nucleiArray.Count() == 0)
|
||||
// receptor2.array = new NucleusArray(neuron);
|
||||
// }
|
||||
}
|
||||
EditorGUILayout.EndFoldoutHeaderGroup();
|
||||
}
|
||||
|
||||
EditorGUILayout.Space();
|
||||
}
|
||||
EditorGUILayout.EndFoldoutHeaderGroup();
|
||||
}
|
||||
|
||||
#region Synapses
|
||||
|
||||
@ -447,28 +447,20 @@ namespace NanoBrain {
|
||||
// This is used to 'scale' the output value colors of the nuclei
|
||||
float maxValue = 0;
|
||||
int neuronCount = 0;
|
||||
//List<Nucleus[]> drawnArrays = new();
|
||||
Cluster[] drawnCluster = null;
|
||||
List<Neuron> drawnNeurons = new();
|
||||
foreach (Synapse synapse in nucleus.synapses) {
|
||||
if (synapse.neuron == null)
|
||||
continue;
|
||||
|
||||
if (synapse.neuron.parent is Cluster cluster &&
|
||||
//cluster.siblingClusters != null &&
|
||||
synapse.neuron.parent != nucleus.parent) {
|
||||
// Draw multiple synapses to the same neuron only once
|
||||
if (drawnNeurons.Contains(synapse.neuron))
|
||||
continue;
|
||||
drawnNeurons.Add(synapse.neuron);
|
||||
|
||||
float value = synapse.neuron.outputMagnitude * synapse.weight;
|
||||
if (value > maxValue)
|
||||
maxValue = value;
|
||||
|
||||
//if (drawnArrays.Contains(cluster.siblingClusters))
|
||||
if (drawnCluster is not null && cluster.SameSiblingsAs(drawnCluster))
|
||||
continue;
|
||||
//drawnArrays.Add(cluster.siblingClusters);
|
||||
drawnCluster = cluster.siblingClusters;
|
||||
}
|
||||
if (synapse.neuron is Neuron synapseNeuron) {
|
||||
float value = synapseNeuron.outputMagnitude * synapse.weight;
|
||||
// Debug.Log($"{synapse.nucleus.name}: {value} {length(synapse.nucleus.outputValue)} {synapse.weight}");
|
||||
if (value > maxValue)
|
||||
maxValue = value;
|
||||
}
|
||||
neuronCount++;
|
||||
}
|
||||
|
||||
@ -477,23 +469,15 @@ namespace NanoBrain {
|
||||
float margin = 10 + spacing / 2;
|
||||
|
||||
int row = 0;
|
||||
//drawnArrays = new();
|
||||
drawnCluster = null;
|
||||
drawnNeurons = new();
|
||||
foreach (Synapse synapse in nucleus.synapses) {
|
||||
if (synapse.neuron is null)
|
||||
continue;
|
||||
|
||||
if (synapse.neuron.parent is Cluster cluster &&
|
||||
//cluster.siblingClusters != null &&
|
||||
synapse.neuron.parent != nucleus.parent) {
|
||||
if (drawnNeurons.Contains(synapse.neuron))
|
||||
continue;
|
||||
drawnNeurons.Add(synapse.neuron);
|
||||
|
||||
// if (drawnArrays.Contains(cluster.siblingClusters))
|
||||
// continue;
|
||||
// drawnArrays.Add(cluster.siblingClusters);
|
||||
if (drawnCluster is not null && cluster.SameSiblingsAs(drawnCluster))
|
||||
continue;
|
||||
drawnCluster = cluster.siblingClusters;
|
||||
}
|
||||
Vector3 pos = new(250, margin + row * spacing, 0.0f);
|
||||
Handles.color = Color.white;
|
||||
Handles.DrawLine(parentPos, pos);
|
||||
@ -502,18 +486,10 @@ namespace NanoBrain {
|
||||
if (maxValue == 0 || !float.IsFinite(maxValue))
|
||||
maxValue = 1;
|
||||
float brightness = 0;
|
||||
if (synapse.neuron is Neuron synapseNeuron)
|
||||
brightness = synapseNeuron.outputMagnitude * synapse.weight / maxValue;
|
||||
brightness = synapse.neuron.outputMagnitude * synapse.weight / maxValue;
|
||||
color = new Color(brightness, brightness, brightness, 1f);
|
||||
}
|
||||
if (synapse.neuron.parent != null && synapse.neuron.parent != this.currentNucleus.parent) {
|
||||
// the synapse nucleus is part of a subcluster
|
||||
//DrawNucleus(synapse.neuron.parent, pos, maxValue, size, color);
|
||||
DrawNucleus(synapse.neuron, pos, size, color);
|
||||
}
|
||||
else {
|
||||
DrawNucleus(synapse.neuron, pos, size, color);
|
||||
}
|
||||
DrawNucleus(synapse.neuron, pos, size, color);
|
||||
row++;
|
||||
}
|
||||
}
|
||||
@ -619,7 +595,7 @@ namespace NanoBrain {
|
||||
}
|
||||
}
|
||||
|
||||
private void DrawCluster(Cluster cluster, Vector3 position, Color color, float size) {
|
||||
protected void DrawCluster(Cluster cluster, Vector3 position, Color color, float size) {
|
||||
GUIStyle labelTextStyle = new(EditorStyles.label) {
|
||||
normal = { textColor = Color.white },
|
||||
fontStyle = FontStyle.Bold,
|
||||
@ -704,7 +680,7 @@ namespace NanoBrain {
|
||||
Handles.DrawLine(from, to);
|
||||
}
|
||||
|
||||
private void HandleMouseHover(Nucleus nucleus, Rect rect) {
|
||||
protected void HandleMouseHover(Nucleus nucleus, Rect rect) {
|
||||
GUIContent tooltip;
|
||||
if (nucleus is Neuron neuron) {
|
||||
tooltip = new(
|
||||
|
||||
@ -468,9 +468,10 @@ namespace NanoBrain {
|
||||
}
|
||||
|
||||
public void AddArrayReceiver(Nucleus receiverToAdd, float weight = 1) {
|
||||
foreach (Cluster cluster in this.siblingClusters) {
|
||||
cluster.defaultOutput.AddReceiver(receiverToAdd, weight);
|
||||
}
|
||||
this.defaultOutput.AddReceiver(receiverToAdd, weight);
|
||||
// foreach (Cluster cluster in this.siblingClusters) {
|
||||
// cluster.defaultOutput.AddReceiver(receiverToAdd, weight);
|
||||
// }
|
||||
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user