WIP: cloning of nucleusarrays is not working yet
This commit is contained in:
parent
60e2b3e33f
commit
3cc5f56f61
48
Cluster.cs
48
Cluster.cs
@ -1,5 +1,6 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEngine;
|
||||
using Unity.Mathematics;
|
||||
using static Unity.Mathematics.math;
|
||||
@ -51,22 +52,22 @@ public class Cluster : INucleus {
|
||||
// }
|
||||
|
||||
private void ClonePrefab() {
|
||||
IReceptor[] nucleiArray = this.prefab.nuclei.ToArray();
|
||||
IReceptor[] nuclei = this.prefab.nuclei.ToArray();
|
||||
// first clone the nuclei without their connections
|
||||
foreach (IReceptor nucleus in this.prefab.nuclei)
|
||||
nucleus.ShallowCloneTo(this);
|
||||
IReceptor[] clonedNuclei = this.nuclei.ToArray();
|
||||
|
||||
// Now clone the connections
|
||||
for (int nucleusIx = 0; nucleusIx < nucleiArray.Length; nucleusIx++) {
|
||||
IReceptor receptor = nucleiArray[nucleusIx];
|
||||
for (int nucleusIx = 0; nucleusIx < nuclei.Length; nucleusIx++) {
|
||||
IReceptor receptor = nuclei[nucleusIx];
|
||||
IReceptor clonedSender = clonedNuclei[nucleusIx];
|
||||
if (clonedSender == null)
|
||||
continue;
|
||||
|
||||
// Copy the receivers, which will also create the synapses
|
||||
foreach (INucleus receiver in receptor.receivers) {
|
||||
int ix = GetNucleusIndex(nucleiArray, receiver);
|
||||
int ix = GetNucleusIndex(nuclei, receiver);
|
||||
if (ix < 0)
|
||||
continue;
|
||||
|
||||
@ -75,15 +76,42 @@ public class Cluster : INucleus {
|
||||
|
||||
// Find the synapse for the weight
|
||||
float weight = 1;
|
||||
NucleusArray nucleusArray = null;
|
||||
foreach (Synapse synapse in receiver.synapses) {
|
||||
if (synapse.nucleus == receptor) {
|
||||
if (synapse.nucleus == receptor)
|
||||
weight = synapse.weight;
|
||||
break;
|
||||
if (synapse.nucleus is INucleus synapseNucleus) {
|
||||
if (synapseNucleus.array != null && synapseNucleus.array.nuclei.Length > 0) {
|
||||
if (nucleusArray == null) {
|
||||
// copy the array
|
||||
nucleusArray = new NucleusArray(synapseNucleus.array.nuclei.Length, "array");
|
||||
for (int arrayIx = 0; arrayIx < synapseNucleus.array.nuclei.Length; arrayIx++) {
|
||||
IReceptor arrayNucleus = synapseNucleus.array.nuclei[arrayIx];
|
||||
int ix2 = GetNucleusIndex(nuclei, arrayNucleus);
|
||||
nucleusArray.nuclei[arrayIx] = clonedNuclei[ix2];
|
||||
}
|
||||
}
|
||||
synapseNucleus.array = nucleusArray;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
clonedSender.AddReceiver(clonedReceiver, weight);
|
||||
}
|
||||
|
||||
// if (receptor is INucleus nucleus) {
|
||||
// if (clonedSender is not INucleus clonedNucleus) {
|
||||
// Debug.LogError("INucleus clone is not an INucleus!");
|
||||
// continue;
|
||||
// }
|
||||
// clonedNucleus.array = new NucleusArray(nucleus.array._nuclei.Length, "array");
|
||||
// for (int arrayIx = 0; arrayIx < nucleus.array._nuclei.Length; arrayIx++) {
|
||||
// //foreach (INucleus arrayNucleus in nucleus.array.nuclei) {
|
||||
// IReceptor arrayNucleus = nucleus.array._nuclei[arrayIx];
|
||||
// int ix = GetNucleusIndex(nuclei, arrayNucleus);
|
||||
// clonedNucleus.array._nuclei[arrayIx] = clonedNuclei[ix];
|
||||
// }
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
@ -96,13 +124,13 @@ public class Cluster : INucleus {
|
||||
// Calculate in-degrees
|
||||
foreach (IReceptor node in nodes) {
|
||||
foreach (INucleus receiver in node.receivers)
|
||||
inDegree[receiver]++;
|
||||
inDegree[receiver]++;
|
||||
}
|
||||
|
||||
Queue<IReceptor> queue = new();
|
||||
foreach (IReceptor node in nodes) {
|
||||
if (inDegree[node] == 0) // Nodes with no dependencies
|
||||
queue.Enqueue(node);
|
||||
queue.Enqueue(node);
|
||||
}
|
||||
|
||||
List<IReceptor> sortedOrder = new();
|
||||
@ -119,7 +147,7 @@ public class Cluster : INucleus {
|
||||
|
||||
// Check for cycles in the graph
|
||||
if (sortedOrder.Count != nodes.Count)
|
||||
throw new InvalidOperationException("Graph is not a DAG; a cycle exists.");
|
||||
throw new InvalidOperationException("Graph is not a DAG; a cycle exists.");
|
||||
|
||||
return sortedOrder;
|
||||
}
|
||||
@ -281,7 +309,7 @@ public class Cluster : INucleus {
|
||||
// }
|
||||
|
||||
public void UpdateStateIsolated() {
|
||||
float3 bias = new(0,0,0);
|
||||
float3 bias = new(0, 0, 0);
|
||||
UpdateStateIsolated(bias);
|
||||
}
|
||||
public void UpdateStateIsolated(float3 bias) {
|
||||
|
||||
@ -210,7 +210,7 @@ public class ClusterInspector : Editor {
|
||||
// Draw selected Nucleus
|
||||
if (expandArray) {
|
||||
float maxValue = 0;
|
||||
foreach (INucleus nucleus in this.currentNucleus.array.nuclei) {
|
||||
foreach (IReceptor nucleus in this.currentNucleus.array.nuclei) {
|
||||
float value = length(nucleus.outputValue);
|
||||
if (value > maxValue)
|
||||
maxValue = value;
|
||||
@ -231,7 +231,7 @@ public class ClusterInspector : Editor {
|
||||
Handles.color = Color.black;
|
||||
Handles.DrawAAConvexPolygon(verts);
|
||||
int row = 0;
|
||||
foreach (INucleus nucleus in this.currentNucleus.array.nuclei) {
|
||||
foreach (IReceptor nucleus in this.currentNucleus.array.nuclei) {
|
||||
Vector3 pos = new(150, margin + row * spacing, 0.0f);
|
||||
Handles.color = Color.white;
|
||||
// The selected nucleus highlight ring
|
||||
@ -239,13 +239,13 @@ public class ClusterInspector : Editor {
|
||||
DrawNucleus(nucleus, pos, maxValue, size);
|
||||
row++;
|
||||
}
|
||||
GUIStyle style = new(EditorStyles.label) {
|
||||
alignment = TextAnchor.UpperCenter,
|
||||
normal = { textColor = Color.white },
|
||||
fontStyle = FontStyle.Bold,
|
||||
};
|
||||
Vector3 labelPos = new Vector3(150, yMax, 0) - Vector3.down * (size + 10); // below disc along up axis
|
||||
Handles.Label(labelPos, this.currentNucleus.name, style);
|
||||
// GUIStyle style = new(EditorStyles.label) {
|
||||
// alignment = TextAnchor.UpperCenter,
|
||||
// normal = { textColor = Color.white },
|
||||
// fontStyle = FontStyle.Bold,
|
||||
// };
|
||||
// Vector3 labelPos = new Vector3(150, yMax, 0) - Vector3.down * (size + 25); // below disc along up axis
|
||||
// Handles.Label(labelPos, this.currentNucleus.name, style);
|
||||
}
|
||||
else {
|
||||
Handles.color = Color.white;
|
||||
@ -274,7 +274,12 @@ public class ClusterInspector : Editor {
|
||||
float margin = 10 + spacing / 2;
|
||||
|
||||
int row = 0;
|
||||
List<NucleusArray> drawnArrays = new();
|
||||
foreach (INucleus receiver in nucleus.receivers) {
|
||||
if (drawnArrays.Contains(receiver.array))
|
||||
continue;
|
||||
drawnArrays.Add(receiver.array);
|
||||
|
||||
INucleus receiverNucleus = receiver;
|
||||
if (receiverNucleus == null)
|
||||
continue;
|
||||
|
||||
19
NanoBrain.cs
19
NanoBrain.cs
@ -13,17 +13,22 @@ public class NanoBrain : MonoBehaviour {
|
||||
name = defaultBrain.name + " (Instance)"
|
||||
};
|
||||
}
|
||||
SwarmControl sc = FindFirstObjectByType<SwarmControl>();
|
||||
if (sc != null) {
|
||||
UpdateWeight(brainInstance, "Containment", sc.containmentForce);
|
||||
UpdateWeight(brainInstance, "Cohesion", sc.cohesionForce);
|
||||
UpdateWeight(brainInstance, "Separation", sc.separationForce);
|
||||
UpdateWeight(brainInstance, "Alignment", sc.alignmentForce);
|
||||
}
|
||||
// SwarmControl sc = FindFirstObjectByType<SwarmControl>();
|
||||
// if (sc != null) {
|
||||
// UpdateWeight(brainInstance, "Containment", sc.containmentForce);
|
||||
// UpdateWeight(brainInstance, "Cohesion", sc.cohesionForce);
|
||||
// UpdateWeight(brainInstance, "Separation", sc.separationForce);
|
||||
// UpdateWeight(brainInstance, "Alignment", sc.alignmentForce);
|
||||
// }
|
||||
return brainInstance;
|
||||
}
|
||||
}
|
||||
|
||||
// public void Awake() {
|
||||
// brainInstance = new Cluster(defaultBrain);
|
||||
// }
|
||||
|
||||
|
||||
public static void UpdateWeight(Cluster brain, string name, float weight) {
|
||||
INucleus root = brain.output;
|
||||
foreach (Synapse synapse in root.synapses) {
|
||||
|
||||
@ -183,7 +183,7 @@ public class Neuron : INucleus {
|
||||
// this clone the nucleus without the synapses and receivers
|
||||
public virtual IReceptor ShallowCloneTo(Cluster newParent) {
|
||||
Neuron clone = new(newParent, this.name) {
|
||||
array = this.array,
|
||||
array = null,
|
||||
curve = this.curve,
|
||||
curvePreset = this.curvePreset,
|
||||
curveMax = this.curveMax,
|
||||
|
||||
@ -5,16 +5,11 @@ using UnityEngine;
|
||||
[System.Serializable]
|
||||
public class NucleusArray {
|
||||
[SerializeReference]
|
||||
private INucleus[] _nuclei;
|
||||
private ClusterPrefab[] _clusters;
|
||||
public IEnumerable<INucleus> nuclei {
|
||||
private IReceptor[] _nuclei;
|
||||
//private ClusterPrefab[] _clusters;
|
||||
public IReceptor[] nuclei {
|
||||
get {
|
||||
// if (_nuclei == null)
|
||||
// return _clusters;
|
||||
// else if (_clusters == null)
|
||||
return _nuclei;
|
||||
// else
|
||||
// return _nuclei.Concat(_clusters);
|
||||
return _nuclei;
|
||||
}
|
||||
}
|
||||
public string name;
|
||||
@ -23,14 +18,19 @@ public class NucleusArray {
|
||||
this.name = nucleus.name;
|
||||
this._nuclei = new INucleus[1];
|
||||
this._nuclei[0] = nucleus;
|
||||
this._clusters = new ClusterPrefab[0];
|
||||
//this._clusters = new ClusterPrefab[0];
|
||||
}
|
||||
public NucleusArray(ClusterPrefab cluster) {
|
||||
this.name = cluster.name;
|
||||
this._nuclei = new INucleus[0];
|
||||
this._clusters = new ClusterPrefab[1];
|
||||
this._clusters[0] = cluster;
|
||||
// this._clusters = new ClusterPrefab[1];
|
||||
// this._clusters[0] = cluster;
|
||||
}
|
||||
public NucleusArray(int size, string name) {
|
||||
this.name = name;
|
||||
this._nuclei = new INucleus[size];
|
||||
}
|
||||
|
||||
|
||||
public void AddNucleus() {
|
||||
if (this._nuclei.Length == 0) {
|
||||
@ -38,12 +38,12 @@ public class NucleusArray {
|
||||
return;
|
||||
}
|
||||
int newLength = this._nuclei.Length + 1;
|
||||
INucleus[] newArray = new INucleus[newLength];
|
||||
IReceptor[] newArray = new INucleus[newLength];
|
||||
|
||||
for (int i = 0; i < this._nuclei.Length; i++)
|
||||
newArray[i] = this._nuclei[i];
|
||||
if (this._nuclei[0] is INucleus nucleus)
|
||||
newArray[newLength - 1] = (INucleus) nucleus.Clone();
|
||||
newArray[newLength - 1] = (INucleus)nucleus.Clone();
|
||||
|
||||
this._nuclei = newArray;
|
||||
}
|
||||
@ -54,11 +54,12 @@ public class NucleusArray {
|
||||
Debug.LogWarning("Perceptoid array cannot be empty");
|
||||
return;
|
||||
}
|
||||
INucleus[] newPerceptei = new INucleus[newLength];
|
||||
IReceptor[] newPerceptei = new INucleus[newLength];
|
||||
for (int i = 0; i < newLength; i++)
|
||||
newPerceptei[i] = this._nuclei[i];
|
||||
// Delete the last perception
|
||||
Neuron.Delete(this._nuclei[newLength]);
|
||||
if (this._nuclei[newLength] is INucleus nucleus)
|
||||
Neuron.Delete(nucleus); //this._nuclei[newLength]);
|
||||
|
||||
this._nuclei = newPerceptei;
|
||||
}
|
||||
|
||||
10
Receptor.cs
10
Receptor.cs
@ -6,8 +6,6 @@ using static Unity.Mathematics.math;
|
||||
|
||||
public class Receptor : IReceptor {
|
||||
|
||||
private ClusterPrefab cluster;
|
||||
private Cluster parent;
|
||||
|
||||
[SerializeField]
|
||||
protected string _name;
|
||||
@ -63,6 +61,9 @@ public class Receptor : IReceptor {
|
||||
// return receptor;
|
||||
}
|
||||
|
||||
private ClusterPrefab cluster;
|
||||
private Cluster parent;
|
||||
|
||||
public virtual IReceptor ShallowCloneTo(Cluster parent) {
|
||||
Receptor clone = new(parent);
|
||||
return clone;
|
||||
@ -188,7 +189,9 @@ public class Receptor : IReceptor {
|
||||
}
|
||||
receiverIx++;
|
||||
}
|
||||
Debug.Log($"Receiver {selectedReceiver.name}[{selectedReceiverIx}] for thing {thingId}");
|
||||
if (selectedReceiverIx >= thingIds.Length)
|
||||
return;
|
||||
|
||||
thingIds[selectedReceiverIx] = thingId;
|
||||
if (thingName != null) {
|
||||
string baseName = selectedReceiver.name;
|
||||
@ -197,6 +200,7 @@ public class Receptor : IReceptor {
|
||||
baseName = selectedReceiver.name.Substring(0, colonPos);
|
||||
selectedReceiver.name = baseName + ": " + thingName;
|
||||
}
|
||||
Debug.Log($"Receiver {selectedReceiver.name}[{selectedReceiverIx}] for thing {thingId}");
|
||||
selectedReceiver.parent.UpdateStateIsolated();
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user