This commit is contained in:
Pascal Serrarens 2026-01-30 11:33:52 +01:00
parent 8a414816e5
commit 9ae3607911
5 changed files with 8 additions and 256 deletions

View File

@ -4,7 +4,7 @@ using UnityEngine;
using Unity.Mathematics; using Unity.Mathematics;
using static Unity.Mathematics.math; using static Unity.Mathematics.math;
[System.Serializable] [Serializable]
public class Cluster : INucleus { public class Cluster : INucleus {
// The ScriptableObject asset from which the runtime object has been created // The ScriptableObject asset from which the runtime object has been created
@ -16,10 +16,7 @@ public class Cluster : INucleus {
} }
public ClusterPrefab storedPrefab; public ClusterPrefab storedPrefab;
//public ClusterPrefab prefab;
// public Cluster() {
// }
public Cluster(Cluster parent, ClusterPrefab realPrefab) { public Cluster(Cluster parent, ClusterPrefab realPrefab) {
this.storedPrefab = realPrefab; this.storedPrefab = realPrefab;
this.parent = parent; this.parent = parent;
@ -30,38 +27,12 @@ public class Cluster : INucleus {
public Cluster(ClusterPrefab realPrefab) { public Cluster(ClusterPrefab realPrefab) {
this.storedPrefab = realPrefab; this.storedPrefab = realPrefab;
//this.prefab = prefab.Clone();
this.name = realPrefab.name; this.name = realPrefab.name;
this.cluster = null; this.cluster = null;
if (this.cluster != null) if (this.cluster != null)
this.cluster.nuclei.Add(this); this.cluster.nuclei.Add(this);
ClonePrefab(); ClonePrefab();
// IReceptor[] nucleiArray = this.storedPrefab.nuclei.ToArray();
// // first clone the nuclei without their connections
// foreach (IReceptor nucleus in this.storedPrefab.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];
// IReceptor clonedReceptor = clonedNuclei[nucleusIx];
// if (clonedReceptor == null)
// continue;
// // Copy the receivers, which will also create the synapses
// foreach (INucleus receiver in nucleiArray[nucleusIx].receivers) {
// int ix = GetNucleusIndex(nucleiArray, receiver);
// if (ix < 0)
// continue;
// if (clonedNuclei[ix] is not INucleus clonedReceiver)
// continue;
// clonedReceptor.AddReceiver(clonedReceiver);
// }
// }
} }
public Cluster(ClusterPrefab parent, ClusterPrefab realPrefab) { public Cluster(ClusterPrefab parent, ClusterPrefab realPrefab) {
@ -73,31 +44,6 @@ public class Cluster : INucleus {
this.cluster.nuclei.Add(this); this.cluster.nuclei.Add(this);
ClonePrefab(); ClonePrefab();
// IReceptor[] nucleiArray = this.storedPrefab.nuclei.ToArray();
// // first clone the nuclei without their connections
// foreach (IReceptor nucleus in this.storedPrefab.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];
// IReceptor clonedReceptor = clonedNuclei[nucleusIx];
// if (clonedReceptor == null)
// continue;
// // Copy the receivers, which will also create the synapses
// foreach (INucleus receiver in nucleiArray[nucleusIx].receivers) {
// int ix = GetNucleusIndex(nucleiArray, receiver);
// if (ix < 0)
// continue;
// if (clonedNuclei[ix] is not INucleus clonedReceiver)
// continue;
// clonedReceptor.AddReceiver(clonedReceiver);
// }
// }
} }
private void ClonePrefab() { private void ClonePrefab() {
@ -152,11 +98,6 @@ public class Cluster : INucleus {
return clone; return clone;
} }
// public IReceptor CloneTo(ClusterPrefab parent) {
// Cluster clone = new(parent, this.prefab);
// return clone;
// }
public IReceptor ShallowCloneTo(Cluster parent) { public IReceptor ShallowCloneTo(Cluster parent) {
Cluster clone = new(parent, this.storedPrefab) { Cluster clone = new(parent, this.storedPrefab) {
name = this.name, name = this.name,
@ -164,62 +105,6 @@ public class Cluster : INucleus {
return clone; return clone;
} }
// public IReceptor ShallowCloneTo(ClusterPrefab parent) {
// Cluster clone = new(parent, this.prefab);
// return clone;
// }
// Deep clone a nucleus with its connections
// public virtual Cluster InstantiatePrefab(ClusterPrefab prefab) {
// Cluster clone = new Cluster {
// nuclei = new()
// };
// IReceptor[] nucleiArray = this.nuclei.ToArray();
// // first clone the nuclei without their connections
// foreach (IReceptor nucleus in this.nuclei)
// nucleus.ShallowCloneTo(clone);
// IReceptor[] clonedNuclei = clone.nuclei.ToArray();
// // Now clone the connections
// for (int nucleusIx = 0; nucleusIx < nucleiArray.Length; nucleusIx++) {
// IReceptor receptor = nucleiArray[nucleusIx];
// IReceptor clonedReceptor = clonedNuclei[nucleusIx];
// if (clonedReceptor == null)
// continue;
// // Copy the synapses
// if (receptor is INucleus nucleus) {
// foreach (Synapse synapse in nucleus.synapses) {
// if (clonedReceptor is not INucleus clonedNucleus)
// continue;
// int ix = GetNucleusIndex(nucleiArray, synapse.nucleus);
// if (ix < 0)
// continue;
// IReceptor clonedSynapseNucleus = clonedNuclei[ix];
// if (clonedSynapseNucleus == null)
// continue;
// clonedNucleus.AddSynapse(clonedSynapseNucleus, synapse.weight);
// }
// }
// // Copy the receivers
// foreach (INucleus receiver in nucleiArray[nucleusIx].receivers) {
// int ix = GetNucleusIndex(nucleiArray, receiver);
// if (ix < 0)
// continue;
// if (clonedNuclei[ix] is not INucleus clonedReceiver)
// continue;
// clonedReceptor.AddReceiver(clonedReceiver);
// }
// }
// return clone;
// }
private int GetNucleusIndex(IReceptor[] nucleiArray, IReceptor nucleus) { private int GetNucleusIndex(IReceptor[] nucleiArray, IReceptor nucleus) {
for (int i = 0; i < nucleiArray.Length; i++) { for (int i = 0; i < nucleiArray.Length; i++) {
if (nucleus == nucleiArray[i]) if (nucleus == nucleiArray[i])
@ -251,7 +136,6 @@ public class Cluster : INucleus {
} }
} }
//public INucleus output => prefab.output;
public virtual INucleus output {//=> this.nuclei[0] as INucleus; public virtual INucleus output {//=> this.nuclei[0] as INucleus;
get { get {
if (this.nuclei.Count > 0) if (this.nuclei.Count > 0)
@ -275,7 +159,7 @@ public class Cluster : INucleus {
public List<Synapse> synapses => _synapses; public List<Synapse> synapses => _synapses;
public Synapse AddSynapse(IReceptor sendingNucleus, float weight = 1.0f) { public Synapse AddSynapse(IReceptor sendingNucleus, float weight = 1.0f) {
Synapse synapse = new(sendingNucleus, weight); //, this.prefab.inputs[0]); Synapse synapse = new(sendingNucleus, weight);
this._synapses.Add(synapse); this._synapses.Add(synapse);
return synapse; return synapse;
} }
@ -369,65 +253,4 @@ public class Cluster : INucleus {
#endregion Update #endregion Update
#endregion Runtime #endregion Runtime
/*
[SerializeField]
private List<IReceptor> _dynamicNuclei;
public List<IReceptor> dynamicNuclei {// = new();
get {
if (_dynamicNuclei == null) {
this._dynamicNuclei = new();
foreach (IReceptor nucleus in this.prefab.nuclei) {
IReceptor clone = nucleus.CloneTo(null);
this._dynamicNuclei.Add(clone);
}
}
return this._dynamicNuclei;
}
}
public List<INucleus> _inputs = null;
public List<INucleus> inputs {
get {
this._inputs = new();
if (this.dynamicNuclei != null) {
foreach (IReceptor receptor in this.dynamicNuclei) {
if (receptor is INucleus nucleus)
this._inputs.Add(nucleus);
}
}
return this._inputs;
}
}
public INucleus output => this.dynamicNuclei[0] as INucleus;
public float3 outputValue => this.output.outputValue;
public IReceptor CloneTo(ClusterPrefab parent) {
Cluster clone = new(parent, this.prefab);
return clone;
}
public IReceptor Clone() {
Cluster clone = new(this.cluster, this.prefab);
return clone;
}
#region Properties
public string name {
get { return prefab.name; }
set { prefab.name = value; }
}
public bool isSleeping => lengthsq(this.outputValue) == 0;
public NucleusArray array { get; set; }
#endregion Properties
*/
} }

View File

@ -4,18 +4,11 @@ using UnityEngine;
[CreateAssetMenu(menuName = "Passer/Cluster")] [CreateAssetMenu(menuName = "Passer/Cluster")]
public class ClusterPrefab : ScriptableObject { public class ClusterPrefab : ScriptableObject {
//public virtual Cluster cluster {get;set;}
// The ScriptableObject asset from which the runtime object has been created // The ScriptableObject asset from which the runtime object has been created
//public Cluster asset;
[SerializeReference] [SerializeReference]
public List<IReceptor> nuclei = new(); public List<IReceptor> nuclei = new();
// public List<Cluster> subClusters = new();
// public void AddSubCluster(ClusterInstance subCluster) {
// this.nuclei.Add(subCluster);
// }
public virtual INucleus output => this.nuclei[0] as INucleus; public virtual INucleus output => this.nuclei[0] as INucleus;
@ -36,67 +29,6 @@ public class ClusterPrefab : ScriptableObject {
} }
} }
/*
// Deep clone a nucleus with its connections
public virtual ClusterPrefab Clone() {
ClusterPrefab clone = Instantiate(this);
clone.nuclei = new();
// foreach (IReceptor nucleus in this.nuclei)
// nucleus.CloneTo(clone);
IReceptor[] nucleiArray = this.nuclei.ToArray();
// first clone the nuclei without their connections
foreach (IReceptor nucleus in this.nuclei)
nucleus.ShallowCloneTo(clone);
IReceptor[] clonedNuclei = clone.nuclei.ToArray();
// Now clone the connections
for (int nucleusIx = 0; nucleusIx < nucleiArray.Length; nucleusIx++) {
IReceptor receptor = nucleiArray[nucleusIx];
IReceptor clonedReceptor = clonedNuclei[nucleusIx];
if (clonedReceptor == null)
continue;
// Copy the synapses
if (receptor is INucleus nucleus) {
foreach (Synapse synapse in nucleus.synapses) {
if (clonedReceptor is not INucleus clonedNucleus)
continue;
int ix = GetNucleusIndex(nucleiArray, synapse.nucleus);
if (ix < 0)
continue;
IReceptor clonedSynapseNucleus = clonedNuclei[ix];
if (clonedSynapseNucleus == null)
continue;
clonedNucleus.AddSynapse(clonedSynapseNucleus, synapse.weight);
}
}
// Copy the receivers
foreach (INucleus receiver in nucleiArray[nucleusIx].receivers) {
int ix = GetNucleusIndex(nucleiArray, receiver);
if (ix < 0)
continue;
if (clonedNuclei[ix] is not INucleus clonedReceiver)
continue;
clonedReceptor.AddReceiver(clonedReceiver);
}
}
return clone;
}
private int GetNucleusIndex(IReceptor[] nucleiArray, IReceptor nucleus) {
for (int i = 0; i < nucleiArray.Length; i++) {
if (nucleus == nucleiArray[i])
return i;
}
return -1;
}
*/
// Call this function to ensure that there is at least one nucleus // 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 // This is an invariant and should be ensured before the nucleus is used
// because output requires it. // because output requires it.

View File

@ -48,9 +48,7 @@ public interface IReceptor {
#endregion dynamic #endregion dynamic
//public IReceptor ShallowCloneTo(ClusterPrefab parent);
public IReceptor ShallowCloneTo(Cluster parent); public IReceptor ShallowCloneTo(Cluster parent);
//public IReceptor CloneTo(ClusterPrefab parent);
public IReceptor Clone(); public IReceptor Clone();
} }

View File

@ -287,10 +287,9 @@ public class Neuron : INucleus {
} }
public virtual void UpdateState(float3 inputValue) { public virtual void UpdateState(float3 inputValue) {
float3 sum = inputValue;//new(0, 0, 0); float3 sum = inputValue;
int n = 0; int n = 0;
Debug.Log($"{this.parent.name}.{this.name}: {inputValue}");
//Applying the weight factgors //Applying the weight factgors
foreach (Synapse synapse in this.synapses) { foreach (Synapse synapse in this.synapses) {
if (synapse.nucleus == this) { if (synapse.nucleus == this) {
@ -298,7 +297,7 @@ public class Neuron : INucleus {
synapse.weight = deltaTime; synapse.weight = deltaTime;
} }
sum += synapse.weight * synapse.nucleus.outputValue; sum += synapse.weight * synapse.nucleus.outputValue;
Debug.Log($" {synapse.weight} * {synapse.nucleus.outputValue}");
// Perhaps synapses should be removed when the output value goes to 0.... // Perhaps synapses should be removed when the output value goes to 0....
if (lengthsq(synapse.nucleus.outputValue) != 0) if (lengthsq(synapse.nucleus.outputValue) != 0)
n++; n++;
@ -337,6 +336,10 @@ public class Neuron : INucleus {
// } // }
this.outputValue = result; this.outputValue = result;
if (lengthsq(outputValue) != 0) {
Debug.Log($"{this.parent.name}.{this.name}: {this.outputValue}");
}
this.lastTime = Time.time; this.lastTime = Time.time;
foreach (INucleus receiver in this.receivers) foreach (INucleus receiver in this.receivers)
receiver.UpdateState(); receiver.UpdateState();

View File

@ -38,13 +38,9 @@ public class Receptor : IReceptor {
if (cluster == null) if (cluster == null)
return null; return null;
//Receptor receptor = new(cluster.prefab);
Receptor receptor = new(cluster); Receptor receptor = new(cluster);
//foreach (INucleus nucleus in cluster.prefab.inputs) {
foreach (INucleus nucleus in cluster.inputs) { foreach (INucleus nucleus in cluster.inputs) {
if (nucleus != null && nucleus.name == nucleusName) { if (nucleus != null && nucleus.name == nucleusName) {
// Receptor receptor = new(cluster, nucleus);
// return receptor;
receptor.AddReceiver(nucleus); receptor.AddReceiver(nucleus);
} }
} }