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() { private void ClonePrefab() {
Nucleus[] prefabNuclei = this.prefab.nuclei.ToArray(); Nucleus[] prefabNuclei = this.prefab.nuclei.ToArray();
// first clone the nuclei without their connections // 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); nucleus.ShallowCloneTo(this);
}
Debug.Log(" complete");
Nucleus[] clonedNuclei = this.clusterNuclei.ToArray(); Nucleus[] clonedNuclei = this.clusterNuclei.ToArray();
// Now clone the connections // Now clone the connections
for (int nucleusIx = 0; nucleusIx < prefabNuclei.Length; nucleusIx++) { for (int nucleusIx = 0; nucleusIx < prefabNuclei.Length; nucleusIx++) {
Nucleus prefabNucleus = prefabNuclei[nucleusIx]; Nucleus prefabNucleus = prefabNuclei[nucleusIx];
Nucleus clonedReceptor = clonedNuclei[nucleusIx]; if (prefabNucleus is not Neuron prefabNeuron)
if (clonedReceptor == null) continue;
Nucleus clonedNucleus = clonedNuclei[nucleusIx];
if (clonedNucleus == null || clonedNucleus is not Neuron clonedNeuron)
continue; continue;
// Copy the receivers, which will also create the synapses // Copy the receivers, which will also create the synapses
// Clusters do not have receivers... // Clusters do not have receivers...
// foreach (Nucleus receiver in prefabNucleus.receivers) { foreach (Nucleus receiver in prefabNeuron.receivers) {
// int ix = GetNucleusIndex(prefabNuclei, receiver); int ix = GetNucleusIndex(prefabNuclei, receiver);
// if (ix < 0) if (ix < 0)
// continue; continue;
// if (clonedNuclei[ix] is not Nucleus clonedReceiver) if (clonedNuclei[ix] is not Nucleus clonedReceiver)
// continue; continue;
// // Find the synapse for the weight // Find the synapse for the weight
// float weight = 1; float weight = 1;
// foreach (Synapse synapse in receiver.synapses) { foreach (Synapse synapse in receiver.synapses) {
// // Find the weight for this synapse // Find the weight for this synapse
// if (synapse.nucleus == prefabNucleus) { if (synapse.nucleus == prefabNucleus) {
// weight = synapse.weight; weight = synapse.weight;
// break; break;
// } }
// } }
// clonedReceptor.AddReceiver(clonedReceiver, weight); clonedNeuron.AddReceiver(clonedReceiver, weight);
// } }
} }
// Copy nucleus arrays // Copy nucleus arrays
@ -180,9 +186,50 @@ public class Cluster : Nucleus {
name = this.name, name = this.name,
clusterPrefab = this.clusterPrefab, 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; 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) { protected int GetNucleusIndex(Nucleus[] nuclei, Nucleus nucleus) {
for (int i = 0; i < nuclei.Length; i++) { for (int i = 0; i < nuclei.Length; i++) {
if (nucleus == nuclei[i]) if (nucleus == nuclei[i])

View File

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

View File

@ -20,6 +20,11 @@ public class ClusterReceptor : Cluster, IReceptor {
clusterPrefab = this.clusterPrefab, clusterPrefab = this.clusterPrefab,
array = this.array 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; return clone;
} }
@ -44,7 +49,7 @@ public class ClusterReceptor : Cluster, IReceptor {
continue; continue;
foreach (Nucleus receiver in output.receivers) foreach (Nucleus receiver in output.receivers)
clonedOutput.AddReceiver(receiver); clonedOutput.AddReceiver(receiver);
} }
return clone; return clone;
} }

View File

@ -36,7 +36,8 @@ public class NanoBrainComponent_Editor : Editor {
root.Add(brainField); 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) if (Application.isPlaying == false)
serializedObject.ApplyModifiedProperties(); serializedObject.ApplyModifiedProperties();