diff --git a/Assets/NanoBrain/Cluster.cs b/Assets/NanoBrain/Cluster.cs index f5c31c9..cae5110 100644 --- a/Assets/NanoBrain/Cluster.cs +++ b/Assets/NanoBrain/Cluster.cs @@ -4,7 +4,7 @@ using Unity.Mathematics; using static Unity.Mathematics.math; [CreateAssetMenu(menuName = "Passer/Cluster")] -public class Cluster : ScriptableObject, INucleus { +public class Cluster : ScriptableObject { public Cluster cluster => this; @@ -14,9 +14,9 @@ public class Cluster : ScriptableObject, INucleus { [SerializeReference] public List nuclei = new(); - public List subClusters = new(); - public void AddSubCluster(Cluster subCluster) { - this.subClusters.Add(subCluster); + // public List subClusters = new(); + public void AddSubCluster(ClusterInstance subCluster) { + this.nuclei.Add(subCluster); } public INucleus output => this.nuclei[0] as INucleus; @@ -45,19 +45,19 @@ public class Cluster : ScriptableObject, INucleus { get { return this.output.receivers; } set { this.output.receivers = value; } } - public List clusterReceivers { - get { return this.output.clusterReceivers; } - set { this.output.clusterReceivers = clusterReceivers; } - } - public IEnumerable allReceivers { - get => output.allReceivers; - } + // public List clusterReceivers { + // get { return this.output.clusterReceivers; } + // set { this.output.clusterReceivers = clusterReceivers; } + // } + // public IEnumerable allReceivers { + // get => output.allReceivers; + // } - public INucleus Clone() { - Cluster clone = CreateInstance(); - // Lots to add here... - return clone; - } + // public INucleus Clone() { + // Cluster clone = CreateInstance(); + // // Lots to add here... + // return clone; + // } // Call this function to ensure that there is at least one nucleus // This is an invariant and should be ensured before the nucleus is used @@ -67,7 +67,7 @@ public class Cluster : ScriptableObject, INucleus { if (nuclei.Count == 0) new Neuron(this, "Output"); // Every cluster should have at least 1 neuron } - +/* public void AddReceiver(INucleus receivingNucleus) { //output.AddReceiver(receiver); this.output.receivers.Add(receivingNucleus); @@ -92,7 +92,7 @@ public class Cluster : ScriptableObject, INucleus { synapses.Add(synapse); return synapse; } - +*/ public void GarbageCollection() { HashSet visitedNuclei = new(); MarkNuclei(visitedNuclei, this.output); @@ -117,9 +117,9 @@ public class Cluster : ScriptableObject, INucleus { } nucleus.synapses.RemoveAll(synapse => visitedSynapses.Contains(synapse) == false); } - if (nucleus.allReceivers != null) { + if (nucleus.receivers != null) { HashSet visitedReceivers = new(); - foreach (INucleus receiver in nucleus.allReceivers) { + foreach (INucleus receiver in nucleus.receivers) { if (receiver != null && receiver != null) { visitedReceivers.Add(receiver); visitedNuclei.Add(receiver); diff --git a/Assets/NanoBrain/ClusterInstance.cs b/Assets/NanoBrain/ClusterInstance.cs index dd9c4c4..e54254d 100644 --- a/Assets/NanoBrain/ClusterInstance.cs +++ b/Assets/NanoBrain/ClusterInstance.cs @@ -1,51 +1,90 @@ -public class ClusterInstance { - // The ScriptableObject asset from which the runtime object has been created - public readonly Cluster asset; +using System; +using System.Collections.Generic; +using UnityEngine; +using Unity.Mathematics; +using static Unity.Mathematics.math; - public ClusterInstance parent; +[System.Serializable] +public class ClusterInstance : INucleus { + // The ScriptableObject asset from which the runtime object has been created + public Cluster asset; + + public Cluster cluster => this.asset; + + public INucleus output => this.asset.nuclei[0] as INucleus; + public float3 outputValue => this.output.outputValue; public ClusterInstance(Cluster asset) { this.asset = asset; } - public NucleusArray array; + public INucleus Clone() { + ClusterInstance clone = new(this.asset); + return clone; + } + + #region Properties + + public string name { + get { return asset.name; } + set { asset.name = value; } + } + + public bool isSleeping => lengthsq(this.outputValue) == 0; + + public NucleusArray array { get; set; } + + #endregion Properties #region Synapses private Synapse[] _synapses = new Synapse[0]; - public Synapse[] synapses => _synapses; + public List synapses => new(_synapses); - public void AddSynapse(IReceptor sendingNucleus) { - + public Synapse AddSynapse(IReceptor sendingNucleus, string nucleusName = null) { + if (nucleusName == null) { + this.asset.inputs[0].AddSynapse(sendingNucleus); + } else { + INucleus receptor = (INucleus)this.asset.nuclei.Find(nucleus => nucleus is INucleus n && nucleus.name == nucleusName); + receptor.AddSynapse(sendingNucleus); + } + // Add synapse to which neuron? + return null; } // Does this even exist already? public void RemoveSynapse() { - + } #endregion Synapses #region Receivers - private INucleus[] _nucleiReceivers = new INucleus[0]; - public INucleus[] nucleiReceivers => _nucleiReceivers; + [SerializeReference] + private List _receivers = new(); + public List receivers { + get { return _receivers; } + set { _receivers = value; } + } public void AddReceiver(INucleus receivingNucleus) { - int newLength = this._nucleiReceivers.Length + 1; + int newLength = this._receivers.Count + 1; INucleus[] newReceivers = new INucleus[newLength]; // Copy the existing receivers - for (int ix = 0; ix < this._nucleiReceivers.Length; ix++) - newReceivers[ix] = this._nucleiReceivers[ix]; + for (int ix = 0; ix < this._receivers.Count; ix++) + newReceivers[ix] = this._receivers[ix]; // Add the new receivers - newReceivers[this._nucleiReceivers.Length] = receivingNucleus; + newReceivers[this._receivers.Count] = receivingNucleus; // Replace the receivers with the new receivers - this._nucleiReceivers = newReceivers; + this._receivers = new(newReceivers); + + receivingNucleus.AddSynapse(this); } public void RemoveReceiver(INucleus receivingNucleus) { - int newLength = this._nucleiReceivers.Length - 1; + int newLength = this._receivers.Count - 1; if (newLength < 0) // Array was empty, so we cannot remove anything return; @@ -54,8 +93,8 @@ public class ClusterInstance { int newIx = 0; // Copy all receivers except receivingNucleus - for (int ix = 0; ix < this._nucleiReceivers.Length; ix++) { - if (this._nucleiReceivers[ix] == receivingNucleus) + for (int ix = 0; ix < this._receivers.Count; ix++) { + if (this._receivers[ix] == receivingNucleus) // skip the receiver we want to remote continue; @@ -64,11 +103,22 @@ public class ClusterInstance { // the receivingNucleus is not found // and the original array is returned return; - newReceivers[newIx] = this._nucleiReceivers[ix]; + newReceivers[newIx] = this._receivers[ix]; newIx++; } - this._nucleiReceivers = newReceivers; + this._receivers = new(newReceivers); } #endregion Receivers + + #region Update + + public void UpdateState() { } + + public void UpdateNuclei() { + foreach (IReceptor nucleus in this.asset.nuclei) + nucleus.UpdateNuclei(); + } + + #endregion Update } diff --git a/Assets/NanoBrain/INucleus.cs b/Assets/NanoBrain/INucleus.cs index 19938ed..0dde236 100644 --- a/Assets/NanoBrain/INucleus.cs +++ b/Assets/NanoBrain/INucleus.cs @@ -10,8 +10,8 @@ public interface INucleus : IReceptor { // Senders public List synapses { get; } - public Synapse AddSynapse(IReceptor sender); - public Synapse AddClusterSynapse(Cluster clusterSender); + public Synapse AddSynapse(IReceptor sender, string nucleusName = null); + // public Synapse AddClusterSynapse(Cluster clusterSender); public NucleusArray array { get; set; } @@ -34,11 +34,11 @@ public interface IReceptor { // Receivers public List receivers { get; set; } - public List clusterReceivers { get; set; } - public IEnumerable allReceivers { get; } + // public List clusterReceivers { get; set; } + // public IEnumerable allReceivers { get; } public void AddReceiver(INucleus receiver); - public void AddClusterReceiver(Cluster clusterReceiver); + // public void AddClusterReceiver(Cluster clusterReceiver); public void RemoveReceiver(INucleus receiverNucleus); #endregion static diff --git a/Assets/NanoBrain/Identity.asset b/Assets/NanoBrain/Identity.asset index efe44e6..ea38020 100644 --- a/Assets/NanoBrain/Identity.asset +++ b/Assets/NanoBrain/Identity.asset @@ -12,6 +12,7 @@ MonoBehaviour: m_Script: {fileID: 11500000, guid: 60a957541c24c57e78018c202ebb1d9b, type: 3} m_Name: Identity m_EditorClassIdentifier: Assembly-CSharp::Cluster + asset: {fileID: 0} nuclei: - rid: 2243601242842202241 subClusters: [] diff --git a/Assets/NanoBrain/Neuron.cs b/Assets/NanoBrain/Neuron.cs index 2d5d5aa..b6e6a87 100644 --- a/Assets/NanoBrain/Neuron.cs +++ b/Assets/NanoBrain/Neuron.cs @@ -25,21 +25,21 @@ public class Neuron : INucleus { get { return _receivers; } set { _receivers = value; } } - private List _clusterReceivers = new(); - public List clusterReceivers { - get { return _clusterReceivers; } - set { _clusterReceivers = value; } - } - public IEnumerable allReceivers { //=> _receivers.Concat(_clusterReceivers); - get { - if (_receivers == null) - return _clusterReceivers; - else if (_clusterReceivers == null) - return _receivers; - else - return _receivers.Concat(_clusterReceivers); - } - } + // private List _clusterReceivers = new(); + // public List clusterReceivers { + // get { return _clusterReceivers; } + // set { _clusterReceivers = value; } + // } + // public IEnumerable allReceivers { //=> _receivers.Concat(_clusterReceivers); + // get { + // if (_receivers == null) + // return _clusterReceivers; + // else if (_clusterReceivers == null) + // return _receivers; + // else + // return _receivers.Concat(_clusterReceivers); + // } + // } [SerializeReference] private NucleusArray _array; @@ -152,7 +152,7 @@ public class Neuron : INucleus { Synapse clonedSynapse = clone.AddSynapse(synapse.nucleus); clonedSynapse.weight = synapse.weight; } - foreach (INucleus receiver in this.allReceivers) { + foreach (INucleus receiver in this.receivers) { clone.AddReceiver(receiver); } return clone; @@ -162,10 +162,10 @@ public class Neuron : INucleus { this._receivers.Add(receivingNucleus); receivingNucleus.AddSynapse(this); } - public void AddClusterReceiver(Cluster receivingCluster) { - this._clusterReceivers.Add(receivingCluster); - receivingCluster.AddSynapse(this); - } + // public void AddClusterReceiver(Cluster receivingCluster) { + // this._clusterReceivers.Add(receivingCluster); + // receivingCluster.AddSynapse(this); + // } public void RemoveReceiver(INucleus receiverNucleus) { this._receivers.RemoveAll(receiver => receiver == receiverNucleus); @@ -185,7 +185,7 @@ public class Neuron : INucleus { } } } - foreach (INucleus receiver in nucleus.allReceivers) { + foreach (INucleus receiver in nucleus.receivers) { if (receiver != null && receiver.synapses != null) receiver.synapses.RemoveAll(s => s.nucleus == nucleus); } @@ -196,16 +196,16 @@ public class Neuron : INucleus { } } - public Synapse AddSynapse(IReceptor sendingNucleus) { + public Synapse AddSynapse(IReceptor sendingNucleus, string nucleusName = null) { Synapse synapse = new(sendingNucleus); this.synapses.Add(synapse); return synapse; } - public Synapse AddClusterSynapse(Cluster sendingCluster) { - Synapse synapse = new(sendingCluster); - this.synapses.Add(synapse); - return synapse; - } + // public Synapse AddClusterSynapse(Cluster sendingCluster) { + // Synapse synapse = new(sendingCluster); + // this.synapses.Add(synapse); + // return synapse; + // } public virtual void UpdateState() { float3 sum = new(0, 0, 0); @@ -250,7 +250,7 @@ public class Neuron : INucleus { // } this.outputValue = result; - foreach (INucleus receiver in this.allReceivers) + foreach (INucleus receiver in this.receivers) receiver.UpdateState(); } diff --git a/Assets/NanoBrain/NucleusArray.cs b/Assets/NanoBrain/NucleusArray.cs index 5e10510..bf46995 100644 --- a/Assets/NanoBrain/NucleusArray.cs +++ b/Assets/NanoBrain/NucleusArray.cs @@ -9,12 +9,12 @@ public class NucleusArray { private Cluster[] _clusters; public IEnumerable nuclei { get { - if (_nuclei == null) - return _clusters; - else if (_clusters == null) + // if (_nuclei == null) + // return _clusters; + // else if (_clusters == null) return _nuclei; - else - return _nuclei.Concat(_clusters); + // else + // return _nuclei.Concat(_clusters); } } public string name; diff --git a/Assets/NanoBrain/Receptor.cs b/Assets/NanoBrain/Receptor.cs index cd3bdbf..c9233c5 100644 --- a/Assets/NanoBrain/Receptor.cs +++ b/Assets/NanoBrain/Receptor.cs @@ -30,12 +30,12 @@ public class Receptor : IReceptor { get { return _receivers; } set { _receivers = value; } } - private List _clusterReceivers = new(); - public List clusterReceivers { - get { return _clusterReceivers; } - set { _clusterReceivers = value; } - } - public IEnumerable allReceivers => _receivers.Concat(_clusterReceivers); + // private List _clusterReceivers = new(); + // public List clusterReceivers { + // get { return _clusterReceivers; } + // set { _clusterReceivers = value; } + // } + // public IEnumerable allReceivers => _receivers.Concat(_clusterReceivers); protected int[] thingIds; // every receiver can handle a thing with this id @@ -43,10 +43,10 @@ public class Receptor : IReceptor { this._receivers.Add(receivingNucleus); receivingNucleus.AddSynapse(this); } - public void AddClusterReceiver(Cluster receivingCluster) { - this._clusterReceivers.Add(receivingCluster); - receivingCluster.AddSynapse(this); - } + // public void AddClusterReceiver(Cluster receivingCluster) { + // this._clusterReceivers.Add(receivingCluster); + // receivingCluster.AddSynapse(this); + // } public void RemoveReceiver(INucleus receiverNucleus) { this._receivers.RemoveAll(receiver => receiver == receiverNucleus); @@ -116,7 +116,7 @@ public class Receptor : IReceptor { int receiverIx = 0; INucleus selectedReceiver = null; int selectedReceiverIx = 0; - foreach (INucleus receiver in this.allReceivers) { + foreach (INucleus receiver in this.receivers) { // selectedReceiver = receiver; // receiverIx++; diff --git a/Assets/NanoBrain/Synapse.cs b/Assets/NanoBrain/Synapse.cs index 371dd27..6772d06 100644 --- a/Assets/NanoBrain/Synapse.cs +++ b/Assets/NanoBrain/Synapse.cs @@ -5,14 +5,15 @@ using UnityEditor; [Serializable] public class Synapse { // Support access to cluster of basic nucleus - public IReceptor nucleus => clusterNucleus != null ? clusterNucleus : basicNucleus; + public IReceptor nucleus => basicNucleus; // clusterNucleus != null ? clusterNucleus : basicNucleus; [SerializeReference] private IReceptor basicNucleus; // The Cluster is a ScriptableObject and can therefore not be serialized using [SerializeReference] - private Cluster clusterNucleus; + // private ClusterInstance clusterNucleus; - public Cluster cluster; + [SerializeReference] + public ClusterInstance cluster; public float weight; @@ -29,10 +30,10 @@ public class Synapse { this.basicNucleus = nucleus; this.weight = weight; } - public Synapse(Cluster cluster, float weight = 1.0f) { - this.clusterNucleus = cluster.asset; - this.weight = weight; - } + // public Synapse(ClusterInstance cluster, float weight = 1.0f) { + // this.clusterNucleus = cluster; + // this.weight = weight; + // } public static class Presets { private const int samples = 32; diff --git a/Assets/NanoBrain/VisualEditor/Editor/ClusterInspector.cs b/Assets/NanoBrain/VisualEditor/Editor/ClusterInspector.cs index 2243fce..86a09fd 100644 --- a/Assets/NanoBrain/VisualEditor/Editor/ClusterInspector.cs +++ b/Assets/NanoBrain/VisualEditor/Editor/ClusterInspector.cs @@ -156,8 +156,8 @@ public class ClusterInspector : Editor { return; NeuroidLayer currentLayer = new() { ix = layerIx }; - if (selectedNucleus.allReceivers != null) { - foreach (INucleus receiver in selectedNucleus.allReceivers) { + if (selectedNucleus.receivers != null) { + foreach (INucleus receiver in selectedNucleus.receivers) { INucleus outputNeuroid = receiver; if (outputNeuroid != null) { AddToLayer(currentLayer, outputNeuroid); @@ -272,12 +272,12 @@ public class ClusterInspector : Editor { } private void DrawReceivers(INucleus nucleus, Vector3 parentPos, float size) { - int nodeCount = nucleus.allReceivers.Count(); + int nodeCount = nucleus.receivers.Count(); // Determine the maximum value in this layer // This is used to 'scale' the output value colors of the nuclei float maxValue = 0; - foreach (INucleus receiver in nucleus.allReceivers) { + foreach (INucleus receiver in nucleus.receivers) { if (receiver is Neuron neuroid) { float value = length(neuroid.outputValue); if (value > maxValue) @@ -290,7 +290,7 @@ public class ClusterInspector : Editor { float margin = 10 + spacing / 2; int row = 0; - foreach (INucleus receiver in nucleus.allReceivers) { + foreach (INucleus receiver in nucleus.receivers) { INucleus receiverNucleus = receiver; if (receiverNucleus == null) continue; @@ -405,7 +405,7 @@ public class ClusterInspector : Editor { Handles.Label(labelPos, nucleus.name, style); } - if (nucleus is Cluster cluster) { + if (nucleus is ClusterInstance cluster) { Handles.color = Color.white; Handles.DrawWireDisc(position, Vector3.forward, size + 10); } @@ -552,7 +552,7 @@ public class ClusterInspector : Editor { if (GUILayout.Button("Delete this neuron")) DeleteNeuron(this.currentNucleus); - if (this.currentNucleus is Cluster subCluster) { + if (this.currentNucleus is ClusterInstance subCluster) { if (GUILayout.Button("Edit Cluster")) EditCluster(subCluster); } @@ -588,7 +588,7 @@ public class ClusterInspector : Editor { return; if (nucleus.cluster != null) this.currentNucleus = nucleus.cluster.output; - foreach (INucleus receiver in nucleus.allReceivers) { + foreach (INucleus receiver in nucleus.receivers) { if (receiver != null) { this.currentNucleus = receiver; break; @@ -603,17 +603,16 @@ public class ClusterInspector : Editor { } private void OnClusterPicked(INucleus nucleus, Cluster subCluster) { - Cluster clusterInstance = Instantiate(subCluster); - clusterInstance.asset = subCluster; - this.cluster.AddSubCluster(subCluster); + ClusterInstance clusterInstance = new(subCluster); + this.cluster.AddSubCluster(clusterInstance); clusterInstance.AddReceiver(nucleus); } - private void EditCluster(Cluster subCluster) { + private void EditCluster(ClusterInstance subCluster) { //var currentActiveObject = Selection.activeObject; - Selection.activeObject = subCluster; - EditorGUIUtility.PingObject(subCluster); - var editor = Editor.CreateEditor(subCluster); + Selection.activeObject = subCluster.asset; + EditorGUIUtility.PingObject(subCluster.asset); + var editor = Editor.CreateEditor(subCluster.asset); //Selection.activeObject = currentActiveObject; } diff --git a/Assets/Scenes/Boids/New Cluster.asset b/Assets/Scenes/Boids/New Cluster.asset index 6b60702..cdf9f20 100644 --- a/Assets/Scenes/Boids/New Cluster.asset +++ b/Assets/Scenes/Boids/New Cluster.asset @@ -14,19 +14,18 @@ MonoBehaviour: m_EditorClassIdentifier: Assembly-CSharp::Cluster asset: {fileID: 0} nuclei: - - rid: 2243601242842202259 - subClusters: [] + - rid: 2243601249170358341 references: version: 2 RefIds: - - rid: 2243601242842202259 + - rid: 2243601249170358341 type: {class: Neuron, ns: , asm: Assembly-CSharp} data: _name: Output _synapses: [] _receivers: [] _array: - rid: 2243601242842202260 + rid: 2243601249170358342 _curvePreset: 0 curve: serializedVersion: 2 @@ -54,9 +53,9 @@ MonoBehaviour: m_RotationOrder: 4 curveMax: 1 average: 0 - - rid: 2243601242842202260 + - rid: 2243601249170358342 type: {class: NucleusArray, ns: , asm: Assembly-CSharp} data: _nuclei: - - rid: 2243601242842202259 + - rid: 2243601249170358341 name: Output