clone subcluster

This commit is contained in:
Pascal Serrarens 2026-02-18 15:22:49 +01:00
parent b644d0fd5b
commit 76d8714778
4 changed files with 76 additions and 23 deletions

View File

@ -38,39 +38,45 @@ public class Cluster : Nucleus {
private void ClonePrefab() {
Nucleus[] prefabNuclei = this.prefab.nuclei.ToArray();
// first clone the nuclei without their connections
foreach (Nucleus nucleus in this.prefab.nuclei)
foreach (Nucleus nucleus in this.prefab.nuclei) {
Debug.Log($"prefab clone {nucleus.name}");
nucleus.ShallowCloneTo(this);
}
Debug.Log(" complete");
Nucleus[] clonedNuclei = this.clusterNuclei.ToArray();
// Now clone the connections
for (int nucleusIx = 0; nucleusIx < prefabNuclei.Length; nucleusIx++) {
Nucleus prefabNucleus = prefabNuclei[nucleusIx];
Nucleus clonedReceptor = clonedNuclei[nucleusIx];
if (clonedReceptor == null)
if (prefabNucleus is not Neuron prefabNeuron)
continue;
Nucleus clonedNucleus = clonedNuclei[nucleusIx];
if (clonedNucleus == null || clonedNucleus is not Neuron clonedNeuron)
continue;
// Copy the receivers, which will also create the synapses
// Clusters do not have receivers...
// foreach (Nucleus receiver in prefabNucleus.receivers) {
// int ix = GetNucleusIndex(prefabNuclei, receiver);
// if (ix < 0)
// continue;
foreach (Nucleus receiver in prefabNeuron.receivers) {
int ix = GetNucleusIndex(prefabNuclei, receiver);
if (ix < 0)
continue;
// if (clonedNuclei[ix] is not Nucleus clonedReceiver)
// continue;
if (clonedNuclei[ix] is not Nucleus clonedReceiver)
continue;
// // Find the synapse for the weight
// float weight = 1;
// foreach (Synapse synapse in receiver.synapses) {
// // Find the weight for this synapse
// if (synapse.nucleus == prefabNucleus) {
// weight = synapse.weight;
// break;
// }
// }
// Find the synapse for the weight
float weight = 1;
foreach (Synapse synapse in receiver.synapses) {
// Find the weight for this synapse
if (synapse.nucleus == prefabNucleus) {
weight = synapse.weight;
break;
}
}
// clonedReceptor.AddReceiver(clonedReceiver, weight);
// }
clonedNeuron.AddReceiver(clonedReceiver, weight);
}
}
// Copy nucleus arrays
@ -180,9 +186,50 @@ public class Cluster : Nucleus {
name = this.name,
clusterPrefab = this.clusterPrefab,
};
// This cloned the prefab with the clusternuclei,
// but did not clone the receivers outside the cluster
RestoreExternalReceivers(clone, this.clusterPrefab, parent);
return clone;
}
protected void RestoreExternalReceivers(Cluster clone, ClusterPrefab prefabParent, Cluster clonedParent) {
for (int nucleusIx = 0; nucleusIx < this.clusterNuclei.Count; nucleusIx++) {
Nucleus prefabNucleus = this.clusterNuclei[nucleusIx];
if (prefabNucleus is not Neuron prefabNeuron)
continue;
Nucleus clonedNucleus = clone.clusterNuclei[nucleusIx];
if (clonedNucleus == null || clonedNucleus is not Neuron clonedNeuron)
continue;
// Copy the receivers, which will also create the synapses
foreach (Nucleus receiver in prefabNeuron.receivers) {
int ix = GetNucleusIndex(prefabParent.nuclei, receiver);
if (ix < 0)
continue;
//if (clone.clusterNuclei[ix] is not Nucleus clonedReceiver)
if (clonedParent.clusterNuclei[ix] is not Nucleus clonedReceiver)
continue;
// Find the synapse for the weight
float weight = 1;
foreach (Synapse synapse in receiver.synapses) {
// Find the weight for this synapse
if (synapse.nucleus == prefabNucleus) {
weight = synapse.weight;
break;
}
}
clonedNeuron.AddReceiver(clonedReceiver, weight);
}
}
}
protected int GetNucleusIndex(Nucleus[] nuclei, Nucleus nucleus) {
for (int i = 0; i < nuclei.Length; i++) {
if (nucleus == nuclei[i])

View File

@ -114,4 +114,4 @@ public class ClusterPrefab : ScriptableObject {
}
return -1;
}
}
}

View File

@ -20,6 +20,11 @@ public class ClusterReceptor : Cluster, IReceptor {
clusterPrefab = this.clusterPrefab,
array = this.array
};
// This cloned the prefab with the clusternuclei,
// but did not clone the receivers outside the cluster
RestoreExternalReceivers(clone, this.clusterPrefab, parent);
return clone;
}
@ -44,7 +49,7 @@ public class ClusterReceptor : Cluster, IReceptor {
continue;
foreach (Nucleus receiver in output.receivers)
clonedOutput.AddReceiver(receiver);
clonedOutput.AddReceiver(receiver);
}
return clone;
}

View File

@ -36,7 +36,8 @@ public class NanoBrainComponent_Editor : Editor {
root.Add(brainField);
}
ClusterInspector.CreateInspector(root, brain.prefab, brain.defaultOutput, component.gameObject);
if (brain != null)
ClusterInspector.CreateInspector(root, brain.prefab, brain.defaultOutput, component.gameObject);
if (Application.isPlaying == false)
serializedObject.ApplyModifiedProperties();