diff --git a/Editor/ClusterViewer.cs b/Editor/ClusterViewer.cs index e34e63f..925cfb0 100644 --- a/Editor/ClusterViewer.cs +++ b/Editor/ClusterViewer.cs @@ -58,7 +58,6 @@ namespace NanoBrain { outputsPopup.RegisterValueChangedCallback(evt => OnOutputChanged(evt.newValue)); topMenuContainer.Add(outputsPopup); } - Add(topMenuContainer); scrollView = new(ScrollViewMode.Horizontal); scrollView.style.position = Position.Absolute; @@ -80,6 +79,7 @@ namespace NanoBrain { scrollView.contentContainer.Add(graphContainer); Add(scrollView); + Add(topMenuContainer); // Subscribe when added to panel (editor UI ready) @@ -437,17 +437,21 @@ namespace NanoBrain { // This is used to 'scale' the output value colors of the nuclei float maxValue = 0; int neuronCount = 0; - List drawnArrays = new(); + //List drawnArrays = new(); + Cluster[] drawnCluster = null; foreach (Synapse synapse in nucleus.synapses) { if (synapse.neuron == null) continue; if (synapse.neuron.parent is Cluster cluster && - cluster.siblingClusters != null && + //cluster.siblingClusters != null && synapse.neuron.parent != nucleus.parent) { - if (drawnArrays.Contains(cluster.siblingClusters)) + + //if (drawnArrays.Contains(cluster.siblingClusters)) + if (drawnCluster is not null && cluster.SameSiblingsAs(drawnCluster)) continue; - drawnArrays.Add(cluster.siblingClusters); + //drawnArrays.Add(cluster.siblingClusters); + drawnCluster = cluster.siblingClusters; } if (synapse.neuron is Neuron synapseNeuron) { float value = synapseNeuron.outputMagnitude * synapse.weight; @@ -463,25 +467,22 @@ namespace NanoBrain { float margin = 10 + spacing / 2; int row = 0; - drawnArrays = new(); + //drawnArrays = new(); + drawnCluster = null; foreach (Synapse synapse in nucleus.synapses) { if (synapse.neuron is null) continue; - // if (synapse.neuron is Receptor neuron) { - // if (drawnArrays.Contains(neuron.nucleiArray)) - // continue; - // drawnArrays.Add(neuron.nucleiArray); - // } - // else if (synapse.neuron.parent is ClusterReceptor clusterReceptor) { - // if (drawnArrays.Contains(clusterReceptor.nucleiArray)) - // continue; - // drawnArrays.Add(clusterReceptor.nucleiArray); - // } - if (synapse.neuron.parent is Cluster cluster) { - if (drawnArrays.Contains(cluster.siblingClusters)) + if (synapse.neuron.parent is Cluster cluster && + //cluster.siblingClusters != null && + synapse.neuron.parent != nucleus.parent) { + + // if (drawnArrays.Contains(cluster.siblingClusters)) + // continue; + // drawnArrays.Add(cluster.siblingClusters); + if (drawnCluster is not null && cluster.SameSiblingsAs(drawnCluster)) continue; - drawnArrays.Add(cluster.siblingClusters); + drawnCluster = cluster.siblingClusters; } Vector3 pos = new(250, margin + row * spacing, 0.0f); Handles.color = Color.white; @@ -547,7 +548,7 @@ namespace NanoBrain { fontStyle = FontStyle.Bold, }; - if (nucleus.parent is Cluster parentCluster) { + if (nucleus.parent is Cluster parentCluster && parentCluster != currentNucleus.parent) { if (expandArray) { // Put array indices above elements style.alignment = TextAnchor.LowerCenter; diff --git a/Runtime/Scripts/Core/Cluster.cs b/Runtime/Scripts/Core/Cluster.cs index 2482247..4159793 100644 --- a/Runtime/Scripts/Core/Cluster.cs +++ b/Runtime/Scripts/Core/Cluster.cs @@ -28,8 +28,6 @@ namespace NanoBrain { } } - //[SerializeReference] - //public ClusterArray clusterArray; [SerializeReference] public Cluster[] siblingClusters; public Dictionary thingClusters = new(); @@ -117,6 +115,44 @@ namespace NanoBrain { } } + // Copy the siblings for clusters + for (int nucleusIx = 0; nucleusIx < prefabNuclei.Length; nucleusIx++) { + Nucleus prefabNucleus = prefabNuclei[nucleusIx]; + if (prefabNucleus is not Cluster prefabCluster) + continue; + + if (prefabCluster.siblingClusters == null || prefabCluster.siblingClusters.Length == 0) + continue; + + Cluster clonedNucleus = clonedNuclei[nucleusIx] as Cluster; + if (prefabCluster == prefabCluster.siblingClusters[0]) { + // We clone the array only for the first entry + //NucleusArray clonedArray = new(prefabReceptor.nucleiArray.Length); + Cluster[] clonedArray = new Cluster[prefabCluster.siblingClusters.Length]; + int arrayIx = 0; + foreach (Cluster prefabArrayNucleus in prefabCluster.siblingClusters) { + int arrayNucleusIx = GetNucleusIndex(prefabNuclei, prefabArrayNucleus); + if (arrayNucleusIx >= 0) { + Cluster clonedArrayNucleus = clonedNuclei[arrayNucleusIx] as Cluster; + clonedArray[arrayIx] = clonedArrayNucleus; + } + else { + Debug.LogError($" Could not find prefab nucleus {prefabNucleus.name} in the clones"); + } + arrayIx++; + } + //clonedNucleus.array = clonedArray; + clonedNucleus.siblingClusters = clonedArray; + } + else { + // The others will refer to the array created for the first nucleus in the array + int firstNucleusIx = GetNucleusIndex(prefabNuclei, prefabCluster.siblingClusters[0]); + Cluster clonedFirstNucleus = clonedNuclei[firstNucleusIx] as Cluster; + clonedNucleus.siblingClusters = clonedFirstNucleus.siblingClusters; + } + } + + foreach (Nucleus nucleus in this.clusterNuclei) { if (nucleus is Cluster clonedSubCluster) RestoreAllExternalReceivers(clonedSubCluster, this.prefab, this); @@ -278,7 +314,6 @@ namespace NanoBrain { #region Cluster Array - public void AddInstance(ClusterPrefab prefab) { // Ensure siblingClusters exists if (this.siblingClusters == null || this.siblingClusters.Length == 0) @@ -366,6 +401,14 @@ namespace NanoBrain { thingClusters.Remove(thingId); } + public bool SameSiblingsAs(Cluster[] otherSiblingClusters) { + for (int ix = 0; ix < this.siblingClusters.Length; ix++) { + if (this.siblingClusters[ix] != otherSiblingClusters[ix]) + return false; + } + return true; + } + #endregion ClusterArray public ClusterPrefab prefab;