diff --git a/Assembly-CSharp-Editor.csproj b/Assembly-CSharp-Editor.csproj
index 94f9e7e..36cc367 100644
--- a/Assembly-CSharp-Editor.csproj
+++ b/Assembly-CSharp-Editor.csproj
@@ -43,7 +43,7 @@
6000.3.2f1
-
+
diff --git a/Assembly-CSharp.csproj b/Assembly-CSharp.csproj
index 891c3d0..771999b 100644
--- a/Assembly-CSharp.csproj
+++ b/Assembly-CSharp.csproj
@@ -43,7 +43,7 @@
6000.3.2f1
-
+
@@ -67,6 +67,7 @@
+
@@ -84,7 +85,6 @@
-
diff --git a/Assets/NanoBrain/Cluster.cs b/Assets/NanoBrain/Cluster.cs
index 0cf80dc..079279c 100644
--- a/Assets/NanoBrain/Cluster.cs
+++ b/Assets/NanoBrain/Cluster.cs
@@ -5,18 +5,26 @@ using static Unity.Mathematics.math;
[CreateAssetMenu(menuName = "Passer/Cluster")]
public class Cluster : ScriptableObject, INucleus {
-
+
public Cluster cluster => this;
[SerializeReference]
- public List nuclei = new();
+ public List nuclei = new();
- public INucleus output => this.nuclei[0];
+ public INucleus output => this.nuclei[0] as INucleus;
- //private readonly List _inputs = new();
- public List inputs { // = compare receptors in NanoBrain
- // for now all nuclei are inputs
- get { return this.nuclei; }
+ public List _inputs = null;
+ public List inputs {
+ get {
+ if (this._inputs == null) {
+ this._inputs = new();
+ foreach (IReceptor receptor in this.nuclei) {
+ if (receptor is INucleus nucleus)
+ this._inputs.Add(nucleus);
+ }
+ }
+ return this._inputs;
+ }
}
// The synapses of all inputs
@@ -35,9 +43,9 @@ public class Cluster : ScriptableObject, INucleus {
// This is an invariant and should be ensured before the nucleus is used
// because output requires it.
public void EnsureInitialization() {
- nuclei ??= new List();
+ nuclei ??= new List();
if (nuclei.Count == 0)
- new Neuroid(this, "Output"); // Every cluster should have at least 1 neuroid
+ new Neuron(this, "Output"); // Every cluster should have at least 1 neuron
}
public void AddReceiver(INucleus receiver) {
@@ -61,7 +69,7 @@ public class Cluster : ScriptableObject, INucleus {
HashSet visitedNuclei = new();
MarkNuclei(visitedNuclei, this.output);
//Debug.Log($"Garbage collection found {visitedNuclei.Count} Nuclei");
- this.nuclei.RemoveAll(nucleus => visitedNuclei.Contains(nucleus) == false);
+ this.nuclei.RemoveAll(nucleus => nucleus is INucleus n && visitedNuclei.Contains(n) == false);
//this.perceptei.RemoveAll(perceptoid => visitedNuclei.Contains(perceptoid) == false);
}
@@ -105,7 +113,7 @@ public class Cluster : ScriptableObject, INucleus {
}
public void UpdateNuclei() {
- foreach (INucleus nucleus in nuclei)
+ foreach (IReceptor nucleus in this.nuclei)
nucleus.UpdateNuclei();
}
diff --git a/Assets/NanoBrain/INucleus.cs b/Assets/NanoBrain/INucleus.cs
index c565c3e..3ff6947 100644
--- a/Assets/NanoBrain/INucleus.cs
+++ b/Assets/NanoBrain/INucleus.cs
@@ -23,7 +23,6 @@ public interface INucleus : IReceptor {
public void UpdateState();
- public void UpdateNuclei();
#endregion dynamic state
@@ -47,6 +46,7 @@ public interface IReceptor {
// float3 to prepare for SIMD
public float3 outputValue { get; }
+ public void UpdateNuclei();
public bool isSleeping { get; }
#endregion dynamic
diff --git a/Assets/NanoBrain/Neuroid.cs b/Assets/NanoBrain/Neuroid.cs
index a28583a..d4a64f2 100644
--- a/Assets/NanoBrain/Neuroid.cs
+++ b/Assets/NanoBrain/Neuroid.cs
@@ -1,9 +1,10 @@
+/*
using UnityEngine;
using Unity.Mathematics;
using static Unity.Mathematics.math;
[System.Serializable]
-public class Neuroid : Nucleus {
+public class Neuroid : Neuron {
public bool average = false;
@@ -78,3 +79,4 @@ public class Neuroid : Nucleus {
}
+*/
\ No newline at end of file
diff --git a/Assets/NanoBrain/Nucleus.cs b/Assets/NanoBrain/Neuron.cs
similarity index 70%
rename from Assets/NanoBrain/Nucleus.cs
rename to Assets/NanoBrain/Neuron.cs
index 65a30c7..67fed76 100644
--- a/Assets/NanoBrain/Nucleus.cs
+++ b/Assets/NanoBrain/Neuron.cs
@@ -5,7 +5,7 @@ using Unity.Mathematics;
using static Unity.Mathematics.math;
[Serializable]
-public class Nucleus : INucleus {
+public class Neuron : INucleus {
[SerializeField]
protected string _name;
@@ -49,6 +49,7 @@ public class Nucleus : INucleus {
}
public AnimationCurve curve;
public float curveMax = 1.0f;
+ public bool average = false;
public AnimationCurve GenerateCurve() {
switch (this.curvePreset) {
@@ -70,7 +71,7 @@ public class Nucleus : INucleus {
}
}
- public virtual void Deserialize(Nucleus nucleus) { }
+ public virtual void Deserialize(Neuron nucleus) { }
#endregion Serialization
@@ -103,17 +104,27 @@ public class Nucleus : INucleus {
#endregion Runtime state
- public Nucleus(string name) {
+ public Neuron(Cluster brain, string name) : this(name) {
+ this.cluster = brain;
+ if (this.cluster != null) {
+ this.cluster.nuclei.Add(this);
+ }
+ else
+ Debug.LogError("No neuroid network");
+ }
+
+ public Neuron(string name) {
this._name = name;
}
public virtual INucleus Clone() {
- Nucleus clone = new(this.name) {
+ Neuron clone = new(this.name) {
cluster = this.cluster,
array = this.array,
curve = this.curve,
curvePreset = this.curvePreset,
- curveMax = this.curveMax
+ curveMax = this.curveMax,
+ average = this.average
};
if (clone.cluster != null)
clone.cluster.nuclei.Add(clone);
@@ -140,14 +151,14 @@ public class Nucleus : INucleus {
public static void Delete(INucleus nucleus) {
foreach (Synapse synapse in nucleus.synapses) {
- if (synapse.nucleus is Nucleus synapse_nucleus) {
+ if (synapse.nucleus is Neuron synapse_nucleus) {
if (synapse_nucleus.receivers.Count > 1) {
// there is another nucleus feeding into this input nucleus
synapse_nucleus.receivers.RemoveAll(r => r == nucleus);
}
else {
// No other links, delete it.
- Nucleus.Delete(synapse_nucleus);
+ Neuron.Delete(synapse_nucleus);
}
}
}
@@ -168,8 +179,41 @@ public class Nucleus : INucleus {
return synapse;
}
- public virtual void UpdateState() { }
+ public virtual void UpdateState() {
+ float3 sum = new(0, 0, 0);
+ int n = 0;
+ //Applying the weight factgors
+ foreach (Synapse synapse in this.synapses) {
+ sum = sum + (synapse.weight * synapse.nucleus.outputValue);
+ if (lengthsq(synapse.nucleus.outputValue) != 0)
+ n++;
+ }
+ if (average)
+ sum /= n;
+
+ // Activation function
+ Vector3 result;
+ switch (this.curvePreset) {
+ case CurvePresets.Linear:
+ result = sum;
+ break;
+ case CurvePresets.Sqrt:
+ result = normalize(sum) * System.MathF.Sqrt(length(sum));
+ break;
+ case CurvePresets.Power:
+ result = normalize(sum) * System.MathF.Pow(length(sum), 2);
+ break;
+ case CurvePresets.Reciprocal:
+ result = normalize(sum) * (1 / length(sum));
+ break;
+ default:
+ float activatedValue = this.curve.Evaluate(length(sum));
+ result = normalize(sum) * activatedValue;
+ break;
+ }
+ UpdateResult(result);
+ }
public void UpdateResult(Vector3 result) {
// float d = Vector3.Distance(result, this.outputValue);
// if (d < 0.5f) {
diff --git a/Assets/NanoBrain/Nucleus.cs.meta b/Assets/NanoBrain/Neuron.cs.meta
similarity index 100%
rename from Assets/NanoBrain/Nucleus.cs.meta
rename to Assets/NanoBrain/Neuron.cs.meta
diff --git a/Assets/NanoBrain/NucleusArray.cs b/Assets/NanoBrain/NucleusArray.cs
index 3e133f1..27f8194 100644
--- a/Assets/NanoBrain/NucleusArray.cs
+++ b/Assets/NanoBrain/NucleusArray.cs
@@ -38,7 +38,7 @@ public class NucleusArray {
for (int i = 0; i < newLength; i++)
newPerceptei[i] = this.nuclei[i];
// Delete the last perception
- Nucleus.Delete(this.nuclei[newLength]);
+ Neuron.Delete(this.nuclei[newLength]);
this.nuclei = newPerceptei;
}
diff --git a/Assets/NanoBrain/Receptor.cs b/Assets/NanoBrain/Receptor.cs
index fe47dfb..69d3d46 100644
--- a/Assets/NanoBrain/Receptor.cs
+++ b/Assets/NanoBrain/Receptor.cs
@@ -1,3 +1,4 @@
+using System;
using System.Collections.Generic;
using UnityEngine;
using Unity.Mathematics;
@@ -24,15 +25,37 @@ public class Receptor : IReceptor {
receiverNucleus.synapses.RemoveAll(synapse => synapse.nucleus == this);
}
- public bool isSleeping => false;
+ //public bool isSleeping => false;
+ private int stale = 1000;
- public Vector3 localPosition;
+ private bool _isSleeping = false;
+ public bool isSleeping => _isSleeping;
+
+ public Vector3 localPosition {
+ set {
+ this.stale = 0;
+ this._isSleeping = false;
+ this._outputValue = value;
+
+ }
+ }
public float distanceResolution = 0.1f;
public float directionResolution = 5;
- public float3 outputValue => this.localPosition;
+ //public float3 outputValue => this.localPosition;
+ private float3 _outputValue;
+ public float3 outputValue {
+ get { return this._outputValue; }
+ set {
+ this.stale = 0;
+ this._isSleeping = false;
+ this._outputValue = value;
+ }
+ }
public Receptor(Cluster cluster, INucleus nucleus) {
+ if (cluster != null)
+ cluster.nuclei.Add(this);
this.AddReceiver(nucleus);
}
@@ -100,4 +123,11 @@ public class Receptor : IReceptor {
// selectedPerceptoid.name = selectedPerceptoid.baseName + " " + thingName;
// selectedPerceptoid.UpdateState();
}
+
+ public void UpdateNuclei() {
+ this.stale++;
+ this._isSleeping = this.stale > 2;
+ if (isSleeping)
+ this._outputValue = Vector3.zero;
+ }
}
\ No newline at end of file
diff --git a/Assets/NanoBrain/VisualEditor/Editor/ClusterInspector.cs b/Assets/NanoBrain/VisualEditor/Editor/ClusterInspector.cs
index c3744e6..f1109b9 100644
--- a/Assets/NanoBrain/VisualEditor/Editor/ClusterInspector.cs
+++ b/Assets/NanoBrain/VisualEditor/Editor/ClusterInspector.cs
@@ -228,7 +228,7 @@ public class ClusterInspector : Editor {
// This is used to 'scale' the output value colors of the nuclei
float maxValue = 0;
foreach (INucleus receiver in nucleus.receivers) {
- if (receiver is Neuroid neuroid) {
+ if (receiver is Neuron neuroid) {
float value = length(neuroid.outputValue);
if (value > maxValue)
maxValue = value;
@@ -263,29 +263,29 @@ public class ClusterInspector : Editor {
int neuronCount = 0;
List drawnArrays = new();
foreach (Synapse synapse in nucleus.synapses) {
- if (synapse.nucleus is Neuroid neuroid) {
+ if (synapse.nucleus is Neuron neuroid) {
if (drawnArrays.Contains(neuroid.array))
continue;
drawnArrays.Add(neuroid.array);
- neuronCount++;
- float value = length(neuroid.outputValue);
- if (value > maxValue)
- maxValue = value;
}
+ float value = length(synapse.nucleus.outputValue);
+ if (value > maxValue)
+ maxValue = value;
+ neuronCount++;
}
// Determine the spacing of the nuclei in the layer
- float spacing = 400f / neuronCount; //nodeCount;
+ float spacing = 400f / neuronCount;
float margin = 10 + spacing / 2;
int row = 0;
drawnArrays = new();
foreach (Synapse synapse in nucleus.synapses) {
- if (synapse.nucleus is Neuroid neuroid) {
- if (drawnArrays.Contains(neuroid.array))
+ if (synapse.nucleus is Neuron neuron) {
+ if (drawnArrays.Contains(neuron.array))
continue;
- drawnArrays.Add(neuroid.array);
+ drawnArrays.Add(neuron.array);
}
Vector3 pos = new(250, margin + row * spacing, 0.0f);
Handles.color = Color.white;
@@ -318,12 +318,12 @@ public class ClusterInspector : Editor {
normal = { textColor = Color.white },
fontStyle = FontStyle.Bold,
};
- if (nucleus is Nucleus perceptoid) {
- if (perceptoid.array == null || perceptoid.array.nuclei == null || perceptoid.array.nuclei.Length == 0)
- perceptoid.array = new NucleusArray(perceptoid);
+ if (nucleus is Neuron neuron) {
+ if (neuron.array == null || neuron.array.nuclei == null || neuron.array.nuclei.Length == 0)
+ neuron.array = new NucleusArray(neuron);
- if (perceptoid.array.nuclei.Length > 1) {
- Handles.Label(labelPosition, perceptoid.array.nuclei.Length.ToString(), style);
+ if (neuron.array.nuclei.Length > 1) {
+ Handles.Label(labelPosition, neuron.array.nuclei.Length.ToString(), style);
}
}
@@ -396,14 +396,14 @@ public class ClusterInspector : Editor {
return;
this.currentNucleus.name = EditorGUILayout.TextField(this.currentNucleus.name);
- if (this.currentNucleus is Nucleus neuroid) {
+ if (this.currentNucleus is Neuron neuroid) {
EditorGUILayout.BeginHorizontal();
EditorGUILayout.LabelField("Activation Curve", GUILayout.Width(150));
if (neuroid.curveMax > 0)
EditorGUILayout.CurveField(neuroid.curve, Color.cyan, new Rect(0, 0, 1, neuroid.curveMax));
else
EditorGUILayout.CurveField(neuroid.curve, Color.cyan, new Rect(0, neuroid.curveMax, 1, -neuroid.curveMax));
- neuroid.curvePreset = (Neuroid.CurvePresets)EditorGUILayout.EnumPopup(neuroid.curvePreset, GUILayout.Width(100));
+ neuroid.curvePreset = (Neuron.CurvePresets)EditorGUILayout.EnumPopup(neuroid.curvePreset, GUILayout.Width(100));
EditorGUILayout.EndHorizontal();
if (neuroid.array == null || neuroid.array.nuclei == null || neuroid.array.nuclei.Length == 0)
@@ -423,6 +423,7 @@ public class ClusterInspector : Editor {
EditorGUILayout.LabelField(" ");
if (this.currentNucleus.synapses.Count > 0) {
+ EditorGUILayout.LabelField("Synapses");
Synapse[] synapses = this.currentNucleus.synapses.ToArray();
foreach (Synapse synapse in synapses) {
if (synapse.nucleus != null) {
@@ -471,7 +472,7 @@ public class ClusterInspector : Editor {
}
protected virtual void AddInputNeuron(INucleus nucleus) {
- Neuroid newNeuroid = new(this.cluster.cluster, "New neuron");
+ Neuron newNeuroid = new(this.cluster.cluster, "New neuron");
newNeuroid.AddReceiver(nucleus);
this.currentNucleus = newNeuroid;
BuildLayers();
@@ -488,7 +489,7 @@ public class ClusterInspector : Editor {
break;
}
}
- Nucleus.Delete(nucleus);
+ Neuron.Delete(nucleus);
BuildLayers();
}
@@ -522,12 +523,12 @@ public class ClusterInspector : Editor {
// Nucleus n = this.currentNucleus.brain.nuclei[selectedIndex - perceptei.Count()];
// n.AddReceiver(this.currentNucleus);
// }
- INucleus n = cluster.nuclei[selectedIndex];
+ IReceptor n = cluster.nuclei[selectedIndex];
n.AddReceiver(this.currentNucleus);
}
}
- protected virtual void DisconnectNucleus(Nucleus nucleus) {
+ protected virtual void DisconnectNucleus(Neuron nucleus) {
if (this.currentNucleus.cluster == null)
return;
string[] names = this.currentNucleus.synapses.Select(synapse => synapse.nucleus.name).ToArray();
diff --git a/Assets/Scenes/Boids/New Cluster.asset b/Assets/Scenes/Boids/New Cluster.asset
deleted file mode 100644
index 57dc073..0000000
--- a/Assets/Scenes/Boids/New Cluster.asset
+++ /dev/null
@@ -1,60 +0,0 @@
-%YAML 1.1
-%TAG !u! tag:unity3d.com,2011:
---- !u!114 &11400000
-MonoBehaviour:
- m_ObjectHideFlags: 0
- m_CorrespondingSourceObject: {fileID: 0}
- m_PrefabInstance: {fileID: 0}
- m_PrefabAsset: {fileID: 0}
- m_GameObject: {fileID: 0}
- m_Enabled: 1
- m_EditorHideFlags: 0
- m_Script: {fileID: 11500000, guid: 60a957541c24c57e78018c202ebb1d9b, type: 3}
- m_Name: New Cluster
- m_EditorClassIdentifier: Assembly-CSharp::Cluster
- nuclei:
- - rid: 2243601034565648587
- references:
- version: 2
- RefIds:
- - rid: 2243601034565648587
- type: {class: Neuroid, ns: , asm: Assembly-CSharp}
- data:
- _name: Output
- _synapses: []
- _receivers: []
- _array:
- rid: 2243601034565648588
- _curvePreset: 0
- curve:
- serializedVersion: 2
- m_Curve:
- - serializedVersion: 3
- time: 0
- value: 0
- inSlope: 0
- outSlope: 1
- tangentMode: 0
- weightedMode: 0
- inWeight: 0
- outWeight: 0
- - serializedVersion: 3
- time: 1000
- value: 1000
- inSlope: 1
- outSlope: 0
- tangentMode: 0
- weightedMode: 0
- inWeight: 0
- outWeight: 0
- m_PreInfinity: 2
- m_PostInfinity: 2
- m_RotationOrder: 4
- curveMax: 1
- average: 0
- - rid: 2243601034565648588
- type: {class: NucleusArray, ns: , asm: Assembly-CSharp}
- data:
- nuclei:
- - rid: 2243601034565648587
- name: Output
diff --git a/Assets/Scenes/Boids/New Cluster.asset.meta b/Assets/Scenes/Boids/New Cluster.asset.meta
deleted file mode 100644
index db2e437..0000000
--- a/Assets/Scenes/Boids/New Cluster.asset.meta
+++ /dev/null
@@ -1,8 +0,0 @@
-fileFormatVersion: 2
-guid: 83e4ef8976534236989bcb1a9342dbf8
-NativeFormatImporter:
- externalObjects: {}
- mainObjectFileID: 11400000
- userData:
- assetBundleName:
- assetBundleVariant:
diff --git a/Assets/Scenes/Boids/NewSwarm.asset b/Assets/Scenes/Boids/NewSwarm.asset
index d64c329..3f97f61 100644
--- a/Assets/Scenes/Boids/NewSwarm.asset
+++ b/Assets/Scenes/Boids/NewSwarm.asset
@@ -13,62 +13,18 @@ MonoBehaviour:
m_Name: NewSwarm
m_EditorClassIdentifier: Assembly-CSharp::Cluster
nuclei:
- - rid: 2243601034565648442
- - rid: 2243601034565648443
+ - rid: 2243601062909444155
references:
version: 2
RefIds:
- - rid: 2243601034565648442
- type: {class: Neuroid, ns: , asm: Assembly-CSharp}
+ - rid: 2243601062909444155
+ type: {class: Neuron, ns: , asm: Assembly-CSharp}
data:
- id: 322343360
_name: Output
- _synapses:
- - nucleus:
- rid: 2243601034565648443
- cluster: {fileID: 0}
- weight: 1
- curveMax: 1
- _receivers: []
- nucleusType:
- _curvePreset: 0
- curve:
- serializedVersion: 2
- m_Curve:
- - serializedVersion: 3
- time: 0
- value: 0
- inSlope: 0
- outSlope: 1
- tangentMode: 0
- weightedMode: 0
- inWeight: 0
- outWeight: 0
- - serializedVersion: 3
- time: 1000
- value: 1000
- inSlope: 1
- outSlope: 0
- tangentMode: 0
- weightedMode: 0
- inWeight: 0
- outWeight: 0
- m_PreInfinity: 2
- m_PostInfinity: 2
- m_RotationOrder: 4
- curveMax: 1
- average: 0
- inverse: 0
- exponent: 1
- - rid: 2243601034565648443
- type: {class: Neuroid, ns: , asm: Assembly-CSharp}
- data:
- id: -1924138416
- _name: Avoidance
_synapses: []
- _receivers:
- - rid: 2243601034565648442
- nucleusType:
+ _receivers: []
+ _array:
+ rid: 2243601062909444156
_curvePreset: 0
curve:
serializedVersion: 2
@@ -96,5 +52,9 @@ MonoBehaviour:
m_RotationOrder: 4
curveMax: 1
average: 0
- inverse: 0
- exponent: 1
+ - rid: 2243601062909444156
+ type: {class: NucleusArray, ns: , asm: Assembly-CSharp}
+ data:
+ nuclei:
+ - rid: 2243601062909444155
+ name: Output
diff --git a/Assets/Scenes/Boids/NewSwarm.asset.meta b/Assets/Scenes/Boids/NewSwarm.asset.meta
index 575238a..db2e437 100644
--- a/Assets/Scenes/Boids/NewSwarm.asset.meta
+++ b/Assets/Scenes/Boids/NewSwarm.asset.meta
@@ -1,5 +1,5 @@
fileFormatVersion: 2
-guid: eddc759ede59e66cd936ad6ae2c55c46
+guid: 83e4ef8976534236989bcb1a9342dbf8
NativeFormatImporter:
externalObjects: {}
mainObjectFileID: 11400000
diff --git a/Assets/Scenes/Boids/Prefabs/Boid.prefab b/Assets/Scenes/Boids/Prefabs/Boid.prefab
index f4f2d9b..f364d47 100644
--- a/Assets/Scenes/Boids/Prefabs/Boid.prefab
+++ b/Assets/Scenes/Boids/Prefabs/Boid.prefab
@@ -179,4 +179,4 @@ MonoBehaviour:
m_Script: {fileID: 11500000, guid: 92f34a5e4027a1dc39efd8ce63cf6aba, type: 3}
m_Name:
m_EditorClassIdentifier: Assembly-CSharp::NanoBrainComponent
- defaultBrain: {fileID: 11400000, guid: eddc759ede59e66cd936ad6ae2c55c46, type: 2}
+ defaultBrain: {fileID: 11400000, guid: 83e4ef8976534236989bcb1a9342dbf8, type: 2}